ketcindyinstaller/
worker.rs

1mod 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}