summaryrefslogtreecommitdiff
path: root/src/commands/update.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/commands/update.rs')
-rw-r--r--src/commands/update.rs50
1 files changed, 15 insertions, 35 deletions
diff --git a/src/commands/update.rs b/src/commands/update.rs
index 85630f5..eba5e91 100644
--- a/src/commands/update.rs
+++ b/src/commands/update.rs
@@ -1,10 +1,6 @@
1use std::{io::{Error, ErrorKind, Write}, fs::File}; 1use std::io::{Error, ErrorKind};
2 2
3use reqwest::Client; 3use crate::{config::Cfg, modrinth::{projects, Project, versions, extract_current_version, Version}, get_current_list, db::{userlist_get_all_ids, mods_get_versions, userlist_get_applicable_versions, userlist_change_versions}, List, input::Input, download_file};
4
5use futures_util::StreamExt;
6
7use crate::{config::Cfg, modrinth::{projects, Project, versions, extract_current_version, Version}, get_current_list, db::{userlist_get_all_ids, mods_get_versions, userlist_get_applicable_versions, userlist_change_versions}, List, input::Input};
8 4
9pub async fn update(config: Cfg, input: Input) -> Result<(), Box<dyn std::error::Error>> { 5pub async fn update(config: Cfg, input: Input) -> Result<(), Box<dyn std::error::Error>> {
10 6
@@ -29,16 +25,16 @@ pub async fn update(config: Cfg, input: Input) -> Result<(), Box<dyn std::error:
29 25
30 //Adding to stack if not the same versions in the list OR if clean == true 26 //Adding to stack if not the same versions in the list OR if clean == true
31 if input.clone().clean || (project.versions.join("|") != current_version.versions) { 27 if input.clone().clean || (project.versions.join("|") != current_version.versions) {
32 updatestack.push(match specific_update(config.clone(), input.clone(), current_list.clone(), project).await { 28 updatestack.push(match specific_update(config.clone(), input.clone(), current_list.clone(), project.clone()).await {
33 Ok(ver) => ver, 29 Ok(ver) => ver,
34 //TODO handle errors (only continue on "NO_UPDATE_AVAILABLE") 30 //TODO handle errors (only continue on "NO_UPDATE_AVAILABLE")
35 Err(_) => { continue; }, 31 Err(_) => { println!("({}) No new version found for the specified minecraft version", project.title); continue; },
36 }); 32 });
33 } else {
34 println!("({}) No new version found", project.title);
37 }; 35 };
38 }; 36 };
39 //println!("{:?}", updatestack); 37
40
41
42 if input.clean { 38 if input.clean {
43 let dl_path = &current_list.download_folder; 39 let dl_path = &current_list.download_folder;
44 println!("Cleaning {}", dl_path); 40 println!("Cleaning {}", dl_path);
@@ -47,8 +43,8 @@ pub async fn update(config: Cfg, input: Input) -> Result<(), Box<dyn std::error:
47 std::fs::remove_file(entry.path())?; 43 std::fs::remove_file(entry.path())?;
48 } 44 }
49 } 45 }
50 46
51 download_updates(config, current_list, updatestack).await?; 47 if input.direct_download { download_updates(current_list, updatestack).await?; };
52 48
53 Ok(()) 49 Ok(())
54} 50}
@@ -82,41 +78,25 @@ async fn specific_update(config: Cfg, input: Input, list: List, project: Project
82 Ok(current[0].clone()) 78 Ok(current[0].clone())
83} 79}
84 80
85async fn download_updates(config: Cfg, current_list: List, versions: Vec<Version>) -> Result<String, Box<dyn std::error::Error>> { 81async fn download_updates(current_list: List, versions: Vec<Version>) -> Result<String, Box<dyn std::error::Error>> {
86 82
87 let dl_path = String::from(&current_list.download_folder); 83 let dl_path = String::from(&current_list.download_folder);
88 84
89 for ver in versions { 85 for ver in versions {
90 let primary_file = ver.files.into_iter().find(|file| file.primary).unwrap(); 86 let primary_file = ver.files.into_iter().find(|file| file.primary).unwrap();
91 let dl_path_file = format!("{}/{}", config.downloads, primary_file.filename); 87 download_file(primary_file.url, current_list.clone().download_folder, primary_file.filename).await?;
92 println!("Downloading {}", primary_file.url);
93
94 let res = Client::new()
95 .get(String::from(&primary_file.url))
96 .send()
97 .await
98 .or(Err(format!("Failed to GET from '{}'", &primary_file.url)))?;
99
100 // download chunks
101 let mut file = File::create(String::from(&dl_path_file)).or(Err(format!("Failed to create file '{}'", dl_path_file)))?;
102 let mut stream = res.bytes_stream();
103
104 while let Some(item) = stream.next().await {
105 let chunk = item.or(Err("Error while downloading file"))?;
106 file.write_all(&chunk)
107 .or(Err("Error while writing to file"))?;
108 }
109 } 88 }
110 89
90
111 Ok(dl_path) 91 Ok(dl_path)
112} 92}
113 93
114#[tokio::test] 94#[tokio::test]
115async fn download_updates_test() { 95async fn download_updates_test() {
116 96
117 use crate::{modrinth::{Version, VersionFile, Hash, VersionType}, config::{Cfg, Apis}}; 97 use crate::{modrinth::{Version, VersionFile, Hash, VersionType}, Modloader, List};
118 98
119 let config = Cfg { data: "...".to_string(), clean_remove: false, downloads: "./dl".to_string(), apis: Apis { modrinth: "...".to_string() } }; 99 let current_list = List { id: String::from("..."), mc_version: String::from("..."), modloader: Modloader::Forge, download_folder: String::from("./dl") };
120 100
121 let versions = vec![Version { 101 let versions = vec![Version {
122 id: "dEqtGnT9".to_string(), 102 id: "dEqtGnT9".to_string(),
@@ -148,5 +128,5 @@ async fn download_updates_test() {
148 "fabric".to_string() 128 "fabric".to_string()
149 ] 129 ]
150 }]; 130 }];
151 assert_eq!(download_updates(config, versions).await.unwrap(), "./dl") 131 assert!(download_updates(current_list, versions).await.is_ok())
152} 132}