canvas_lms_sync/
lib.rs

1use std::collections::HashMap;
2
3use canvas_api::files::{FileResp, FolderResp};
4use download::DownloadTask;
5use path::sanitize_file_name;
6
7pub mod canvas_api;
8mod defer;
9pub mod download;
10mod path;
11pub mod sync;
12
13#[derive(Debug)]
14pub struct File {
15    pub folder_path: Vec<String>,
16    pub file_name: String,
17    pub size: i64,
18    pub created_at: String,
19    pub updated_at: String,
20    pub modified_at: String,
21    pub url: String,
22}
23
24impl Into<DownloadTask> for File {
25    fn into(self) -> DownloadTask {
26        DownloadTask {
27            path: self.local_path(),
28            url: self.url,
29        }
30    }
31}
32
33impl File {
34    pub fn set_folder_path(&mut self, folder_map: &HashMap<i64, FolderResp>, folder_id: i64) {
35        self.folder_path.clear();
36        let mut cur_folder = folder_id;
37        while cur_folder != 0 {
38            let folder = folder_map.get(&cur_folder).unwrap();
39            self.folder_path.push(folder.name.clone());
40            cur_folder = folder.parent_folder_id.unwrap_or(0);
41        }
42        self.folder_path.reverse();
43    }
44    pub fn local_file_matches(&self) -> Result<bool, std::io::Error> {
45        let path = self.local_path();
46        if !path.exists() {
47            return Ok(false);
48        }
49        let metadata = path.metadata()?;
50        if metadata.len() != self.size as u64 {
51            return Ok(false);
52        }
53        Ok(true)
54    }
55    pub fn local_path(&self) -> std::path::PathBuf {
56        let mut path = std::path::PathBuf::new();
57        for folder in self.sanitized_folder_path() {
58            path.push(folder);
59        }
60        path.push(self.sanitized_file_name());
61        path
62    }
63    pub fn sanitized_folder_path(&self) -> Vec<String> {
64        self.folder_path
65            .iter()
66            .map(|s| sanitize_file_name(s))
67            .collect::<Vec<_>>()
68    }
69    pub fn sanitized_file_name(&self) -> String {
70        sanitize_file_name(&self.file_name)
71    }
72}
73
74impl From<FileResp> for File {
75    fn from(value: FileResp) -> Self {
76        Self {
77            folder_path: Vec::new(),
78            file_name: value.display_name,
79            size: value.size,
80            created_at: value.created_at,
81            updated_at: value.updated_at,
82            modified_at: value.modified_at,
83            url: value.url,
84        }
85    }
86}