ketcindyinstaller/
worker.rs1mod downloader;
2mod fetcher;
3
4use crate::package::PackageKind;
5
6use anyhow::Result;
7use anyhow::Context;
8
9pub(crate) async fn fetch_versions(package_kind: PackageKind) -> Result<Vec<String>> {
10 let versions = match package_kind {
11 PackageKind::KeTCindy => {
12 let releases = fetcher::fetch_from_github("ketpic", "ketcindy").await?;
13 releases.into_iter().map(|release| release.tag_name).collect()
14 },
15 PackageKind::Cinderella => {
16 let release = fetcher::fetch_from_homebrew("cinderella").await?;
17 vec![release.version]
18 },
19 PackageKind::R => {
20 let release = fetcher::fetch_from_homebrew("r").await?;
21 vec![release.version]
22 },
23 PackageKind::Maxima => {
24 let release = fetcher::fetch_from_homebrew("maxima").await?;
25 vec![release.version]
26 },
27 };
28
29 Ok(versions)
30}
31
32pub(crate) async fn download_package<F>(
33 package_kind: PackageKind,
34 version: &str,
35 progress_callback: F
36) -> Result<std::path::PathBuf>
37where
38 F: FnMut(f32) + Send,
39{
40 use url::Url;
41
42 let mut download_destination = directories::ProjectDirs::from("", "nxvzbgbfben", "ketcindyinstaller")
43 .context("Failed to create the project directory")?.data_dir().join("downloads");
44 std::fs::create_dir_all(&download_destination)?;
45
46 let download_url = match package_kind {
47 PackageKind::KeTCindy => {
48 download_destination.push(format!("{package_kind}_{version}.zip"));
49 Url::parse(&format!("https://github.com/ketpic/ketcindy/archive/refs/tags/{version}.zip"))?
50 },
51 PackageKind::Cinderella => {
52 if cfg!(target_os = "windows") {
53 download_destination.push(format!("{package_kind}_{version}.exe"));
54 Url::parse(&format!("https://beta.cinderella.de/Cinderella-{version}-64bit.exe"))?
55 } else if cfg!(target_os = "macos") {
56 download_destination.push(format!("{package_kind}_{version}.dmg"));
57 Url::parse(&format!("https://beta.cinderella.de/Cinderella-{version}.dmg"))?
58 } else {
59 unimplemented!()
60 }
61 },
62 PackageKind::R => {
63 if cfg!(target_os = "windows") {
64 download_destination.push(format!("{package_kind}_{version}.exe"));
65 Url::parse(&format!("https://cran.r-project.org/bin/windows/base/R-{version}-win.exe"))?
66 } else if cfg!(target_os = "macos") && cfg!(target_arch = "aarch64") {
67 download_destination.push(format!("{package_kind}_{version}.pkg"));
68 Url::parse(&format!("https://cran.r-project.org/bin/macosx/big-sur-arm64/base/R-{version}-arm64.pkg"))?
69 } else if cfg!(target_os = "macos") && cfg!(target_arch = "x86_64") {
70 download_destination.push(format!("{package_kind}_{version}.pkg"));
71 Url::parse(&format!("https://cran.r-project.org/bin/macosx/big-sur-x86_64/base/R-{version}-x86_64.pkg"))?
72 } else {
73 unimplemented!()
74 }
75 },
76 PackageKind::Maxima => {
77 if cfg!(target_os = "windows") {
78 download_destination.push(format!("{package_kind}_{version}.exe"));
79 Url::parse(&format!("https://sourceforge.net/projects/maxima/files/Maxima-Windows/{version}-Windows/maxima-{version}-win64.exe/download"))?
80 } else if cfg!(target_os = "macos") {
81 download_destination.push(format!("{package_kind}_{version}.dmg"));
82 Url::parse(&format!("https://sourceforge.net/projects/maxima/files/Maxima-MacOS/{version}-macOS/MacPorts-Maxima-{version}.dmg/download"))?
83 } else {
84 unimplemented!()
85 }
86 },
87 };
88
89 let package_path = downloader::download_file(download_url, download_destination, progress_callback).await?;
90
91 Ok(package_path)
92}