summaryrefslogtreecommitdiff
path: root/src/net/http_packages.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/http_packages.rs')
-rw-r--r--src/net/http_packages.rs240
1 files changed, 0 insertions, 240 deletions
diff --git a/src/net/http_packages.rs b/src/net/http_packages.rs
deleted file mode 100644
index 05b2ac6..0000000
--- a/src/net/http_packages.rs
+++ /dev/null
@@ -1,240 +0,0 @@
-use crate::cfg::config::Config;
-use crate::pkgtoolkit::pkgtools::Package;
-use indicatif::{ProgressBar, ProgressStyle};
-use reqwest;
-use serde::Deserialize;
-use std::collections::HashMap;
-use std::path::Path;
-use tokio::fs::File;
-use tokio::io::AsyncWriteExt;
-use futures_util::stream::TryStreamExt;
-
-pub struct HTTPPackage {
- config: Config,
- index_packages: Option<HashMap<String, Package>>,
-}
-
-#[derive(Deserialize, Debug)]
-struct IndexData {
- packages: Vec<Package>,
-}
-
-impl HTTPPackage {
- /// Creates a new HTTPPackage object with the given configuration.
- ///
- /// # Returns
- ///
- /// A new HTTPPackage object with the given configuration.
- pub fn new(config: Config) -> Self {
- HTTPPackage {
- config,
- index_packages: None,
- }
- }
-
- /// Downloads the INDEX.tar.gz file from the configured repository
- /// and stores it in the configured cache directory with a progress bar.
- ///
- /// # Errors
- ///
- /// Returns an error if the request fails, if the response status is not successful, or if there's an issue while reading or writing the file.
- pub async fn fetch_index_http(&mut self) -> Result<bool, Box<dyn std::error::Error>> {
- let repo_url_str = &self.config.repo.repo_url;
- let cache_dir = &self.config.paths.cache_dir;
-
- let index_url = if repo_url_str.ends_with(".tar.gz") {
- repo_url_str.clone()
- } else {
- format!("{}/INDEX.tar.gz", repo_url_str.trim_end_matches('/'))
- };
-
- let client = reqwest::Client::new();
-
- // Make a HEAD request to get the content length for the progress bar
- let head_response = client.head(&index_url).send().await?;
- let content_length: u64 = head_response
- .headers()
- .get(reqwest::header::CONTENT_LENGTH)
- .and_then(|ct_len| ct_len.to_str().ok())
- .and_then(|ct_len| ct_len.parse().ok())
- .unwrap_or(0);
-
- // Create progress bar
- let pb = if content_length > 0 {
- let pb = ProgressBar::new(content_length);
- pb.set_style(
- ProgressStyle::default_bar()
- .template("{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {bytes}/{total_bytes} ({eta})")?
- .progress_chars("#>-"),
- );
- pb
- } else {
- let pb = ProgressBar::new_spinner();
- pb.set_style(
- ProgressStyle::default_spinner()
- .template("{spinner:.green} [{elapsed_precise}] Fetching INDEX.tar.gz...")?
- );
- pb
- };
-
- // Send GET request and stream the response body
- let response = client.get(&index_url).send().await?;
- if !response.status().is_success() {
- return Err(format!("HTTP Error: {}", response.status()).into());
- }
-
- let mut stream = response.bytes_stream();
- let file_path = Path::new(cache_dir).join("INDEX.tar.gz");
-
- let mut file = File::create(&file_path).await?;
- let mut downloaded: u64 = 0;
-
- while let Some(chunk) = stream.try_next().await? {
- file.write_all(&chunk).await?;
- let chunk_len = chunk.len() as u64;
- downloaded += chunk_len;
- pb.set_position(downloaded);
- }
-
- pb.finish_with_message("INDEX.tar.gz download finished");
-
- // --- Извлечение и парсинг INDEX.toml ---
- log::info!("Extracting INDEX.tar.gz to cache directory...");
- Package::extract_archive(&file_path.to_string_lossy())?; // Используем существующую функцию из pkgtoolkit
-
- let index_toml_path = Path::new(cache_dir).join("INDEX.toml");
- if !index_toml_path.exists() {
- log::warn!("INDEX.toml not found in INDEX.tar.gz. Proceeding without index data.");
- self.index_packages = Some(HashMap::new());
- return Ok(true);
- }
-
- let index_content = tokio::fs::read_to_string(&index_toml_path).await?;
- let index_data: IndexData = toml::from_str(&index_content)?;
-
- let mut package_map = HashMap::new();
- for pkg in index_data.packages {
- // PKG_URL = /repo/package.mesk
- // FULL URL = "http://mesk.anthrill.i2p/i2p/repo/pkg.mesk"
- let base_url = url::Url::parse(&self.config.repo.repo_url)?;
- let full_url = base_url.join(&pkg.url)?;
- let mut pkg_clone = pkg.clone();
- pkg_clone.url = full_url.to_string();
-
- package_map.insert(pkg_clone.name.clone(), pkg_clone);
- }
-
- self.index_packages = Some(package_map.clone());
- log::info!("Index loaded successfully, {} packages found.", package_map.len());
-
- Ok(true)
- }
-
- /// An internal auxiliary function for downloading data and writing it to a file with a progress display.
- ///
- /// # Arguments
- /// * `url` - The URL to download from.
- /// * `file_path` - The path to the file to write the data to.
- /// * `description` - Description of the operation for the progress bar.
- ///
- /// # Errors
- ///
- /// Returns an error if the request fails, if the response status is not successful, or if there's an issue while writing the file.
- async fn download_file_with_progress(
- client: &reqwest::Client,
- url: &str,
- file_path: &Path,
- description: &str,
- ) -> Result<(), Box<dyn std::error::Error>> {
- // Make a HEAD request to get the content length for the progress bar
- let head_response = client.head(url).send().await?;
- let content_length: u64 = head_response
- .headers()
- .get(reqwest::header::CONTENT_LENGTH)
- .and_then(|ct_len| ct_len.to_str().ok())
- .and_then(|ct_len| ct_len.parse().ok())
- .unwrap_or(0);
- let pb = if content_length > 0 {
- let pb = ProgressBar::new(content_length);
- pb.set_style(
- ProgressStyle::default_bar()
- .template(&format!(
- "{{spinner:.green}} [{{elapsed_precise}}] [{{bar:40.cyan/blue}}] {{bytes}}/{{total_bytes}} ({} {{eta}})",
- description
- ))?
- .progress_chars("#>-"),
- );
- pb
- } else {
- let pb = ProgressBar::new_spinner();
- pb.set_style(
- ProgressStyle::default_spinner()
- .template(&format!("{{spinner:.green}} [{{elapsed_precise}}] {}...", description))?
- );
- pb
- };
-
- // Send GET request and stream the response body
- let response = client.get(url).send().await?;
- if !response.status().is_success() {
- return Err(format!("HTTP Error: {}", response.status()).into());
- }
-
- let mut stream = response.bytes_stream();
- let mut file = File::create(&file_path).await?;
- let mut downloaded: u64 = 0;
-
- while let Some(chunk) = stream.try_next().await? {
- file.write_all(&chunk).await?;
- let chunk_len = chunk.len() as u64;
- downloaded += chunk_len;
- pb.set_position(downloaded);
- }
-
- pb.finish_with_message(format!("{} download finished", description));
- Ok(())
- }
-
- /// Fetches a specific package identified by `package_name`.
- /// Assumes `fetch_index_http` has been called and `self.index_packages` is populated to get the URL.
- /// Downloads the package file (.mesk) to the cache directory with a progress bar.
- ///
- /// # Errors
- ///
- /// Returns an error if the index is not loaded, the package is not found in the index,
- /// the package URL is invalid, the request fails, or if there's an issue writing the file.
- pub async fn fetch_package_http(&self, package_name: &str) -> Result<bool, Box<dyn std::error::Error>> {
- let package_info = self.fetch_package_info(package_name)?;
- let url = &package_info.url;
-
- let client = reqwest::Client::new();
-
- let file_name = Path::new(url)
- .file_name()
- .ok_or("Could not determine filename from URL")?
- .to_str()
- .ok_or("Filename is not valid UTF-8")?;
- let cache_dir = &self.config.paths.cache_dir;
- let file_path = Path::new(cache_dir).join(file_name);
-
- Self::download_file_with_progress(&client, url, &file_path, file_name).await?;
-
- log::info!(
- "Package '{}' downloaded successfully to {:?}",
- package_name,
- file_path
- );
- Ok(true)
- }
-
- /// Fetches a specific package identified by `index` (likely the package name).
- /// Assumes `fetch_index_http` has been called and `self.index_packages` is populated.
- pub fn fetch_package_info(&self, package_name: &str) -> Result<&Package, Box<dyn std::error::Error>> {
- let packages = self.index_packages.as_ref()
- .ok_or("Index not loaded. Call fetch_index_http first.")?;
- let pkg_info = packages
- .get(package_name)
- .ok_or(format!("Package '{}' not found in index.", package_name))?;
- Ok(pkg_info)
- }
-} \ No newline at end of file