pub fn download_linked_content(
    state: &mut ProjectState,
    ui_handler: &mut dyn ChandlerUiHandler,
) -> Result<(), ChandlerError> {
    state.new_links.append(&mut state.failed_links);

    // Report download start.
    ui_handler.event(&UiEvent::DownloadStart {
        file_count: state.new_links.len() as u32,
    });

    let mut files_processed: u32 = 0;
    let mut files_downloaded: u32 = 0;
    let mut files_failed: u32 = 0;

    let download_path = &state.root_path;
    let new_links = &mut state.new_links;
    let failed_links = &mut state.failed_links;

    loop {
        // If cancellation has been requested, break out immediately.
        if ui_handler.is_cancelled() {
            break;
        }

        if new_links.is_empty() {
            break;
        }

        let link_info = new_links.remove(0);

        let url = &link_info.url;
        let path = download_path.join(&link_info.path);

        if let Some(parent_path) = path.parent() {
            fs::create_dir_all(parent_path).map_err(|err| {
                ChandlerError::Other(format!("Error creating path: {}: {err}", parent_path.display()).into())
            })?;
        }

        let mut if_modified_since: Option<DateTime<Utc>> = None;

        // If the file already exists, try to get its modification time
        // so that we can pass it to the request's If-Modified-Since header.
        if path.exists() {
            if let Ok(m) = fs::metadata(&path) {
                if let Ok(st) = m.modified() {
                    if_modified_since = Some(st.into());
                }
            }
        }

        let success = match download_file(url, &path, if_modified_since, ui_handler) {
            Ok(r) => match r {
                DownloadResult::Success { .. } => true,
                DownloadResult::NotModified => true,
                DownloadResult::NotFound => {
                    error!("File not found: {}", url);
                    false
                }
                DownloadResult::OtherHttpError {
                    status_code,
                    description,
                } => {
                    error!("Server returned HTTP error: {} {}", status_code, description);
                    false
                }
            },
            Err(err) => {
                error!("Error downloading link: {}", err.to_string());
                false
            }
        };

        files_processed += 1;

        if success {
            files_downloaded += 1;
        } else {
            failed_links.push(link_info);
            files_failed += 1;
        }

        // Report download progress.
        ui_handler.event(&UiEvent::DownloadProgress { files_processed });
    }

    // Report download complete.
    ui_handler.event(&UiEvent::DownloadComplete {
        files_downloaded,
        files_failed,
    });

    Ok(())
}
/// Download all links for this project.
Download all links for this project.
Download all links for this project .
pub fn download_linked_content(
    state: &mut ProjectState,
    ui_handler: &mut dyn ChandlerUiHandler,
) -> Result<(), ChandlerError> {
    state.new_links.append(&mut state.failed_links);
    // Report download start.
    ui_handler.event(&UiEvent::DownloadStart {
        file_count: state.new_links.len() as u32,
    });
    let mut files_processed: u32 = 0;
    let mut files_downloaded: u32 = 0;
    let mut files_failed: u32 = 0;
    let download_path = &state.root_path;
    let new_links = &mut state.new_links;
    let failed_links = &mut state.failed_links;
    loop {
        // If cancellation has been requested, break out immediately.
        if ui_handler.is_cancelled() {
            break;
        }
        if new_links.is_empty() {
            break;
        }
        let link_info = new_links.remove(0);
        let url = &link_info.url;
        let path = download_path.join(&link_info.path);
        if let Some(parent_path) = path.parent() {
            fs::create_dir_all(parent_path).map_err(|err| {
                ChandlerError::Other(format!("Error creating path: {}: {err}", parent_path.display()).into())
            })?;
        }
        let mut if_modified_since: Option<DateTime<Utc>> = None;
        // If the file already exists, try to get its modification time
        // so that we can pass it to the request's If-Modified-Since header.
        if path.exists() {
            if let Ok(m) = fs::metadata(&path) {
                if let Ok(st) = m.modified() {
                    if_modified_since = Some(st.into());
                }
            }
        }
        let success = match download_file(url, &path, if_modified_since, ui_handler) {
            Ok(r) => match r {
                DownloadResult::Success { .. } => true,
                DownloadResult::NotModified => true,
                DownloadResult::NotFound => {
                    error!("File not found: {}", url);
                    false
                }
                DownloadResult::OtherHttpError {
                    status_code,
                    description,
                } => {
                    error!("Server returned HTTP error: {} {}", status_code, description);
                    false
                }
            },
            Err(err) => {
                error!("Error downloading link: {}", err.to_string());
                false
            }
        };
        files_processed += 1;
        if success {
            files_downloaded += 1;
        } else {
            failed_links.push(link_info);
            files_failed += 1;
        }
        // Report download progress.
        ui_handler.event(&UiEvent::DownloadProgress { files_processed });
    }
    // Report download complete.
    ui_handler.event(&UiEvent::DownloadComplete {
        files_downloaded,
        files_failed,
    });
    Ok(())
}
pub fn download_linked_content ( state : & mut ProjectState , ui_handler : & mut dyn ChandlerUiHandler , ) -> Result < ( ) , ChandlerError > { state . new_links . append ( & mut state . failed_links ) ; // Report download start. ui_handler . event ( & UiEvent :: DownloadStart { file_count : state . new_links . len ( ) as u32 , } ) ; let mut files_processed : u32 = 0 ; let mut files_downloaded : u32 = 0 ; let mut files_failed : u32 = 0 ; let download_path = & state . root_path ; let new_links = & mut state . new_links ; let failed_links = & mut state . failed_links ; loop { // If cancellation has been requested, break out immediately. if ui_handler . is_cancelled ( ) { break ; } if new_links . is_empty ( ) { break ; } let link_info = new_links . remove ( 0 ) ; let url = & link_info . url ; let path = download_path . join ( & link_info . path ) ; if let Some ( parent_path ) = path . parent ( ) { fs :: create_dir_all ( parent_path ) . map_err ( | err | { ChandlerError :: Other ( format ! ( " " parent_path display ( ) ) . into ( ) ) } ) ? ; } let mut if_modified_since : Option < DateTime < Utc > > = None ; // If the file already exists, try to get its modification time // so that we can pass it to the request's If-Modified-Since header. if path . exists ( ) { if let Ok ( m ) = fs :: metadata ( & path ) { if let Ok ( st ) = m . modified ( ) { if_modified_since = Some ( st . into ( ) ) ; } } } let success = match download_file ( url , & path , if_modified_since , ui_handler ) { Ok ( r ) => match r { DownloadResult :: Success { .. } => true , DownloadResult :: NotModified => true , DownloadResult :: NotFound => { error ! ( " " url ) ; false } DownloadResult :: OtherHttpError { status_code , description , } => { error ! ( " " status_code description ) ; false } } , Err ( err ) => { error ! ( " " err to_string ( ) ) ; false } } ; files_processed += 1 ; if success { files_downloaded += 1 ; } else { failed_links . push ( link_info ) ; files_failed += 1 ; } // Report download progress. ui_handler . event ( & UiEvent :: DownloadProgress { files_processed } ) ; } // Report download complete. ui_handler . event ( & UiEvent :: DownloadComplete { files_downloaded , files_failed , } ) ; Ok ( ( ) ) }
Download all links for this project.
Download all links for this project .
state
&mut ProjectState
ui_handler
&mut dyn ChandlerUiHandler