wall_rs/
wall.rs

1use crate::config::Config;
2use crate::error::Error;
3use crate::showroom;
4use crate::source::Source;
5use path_absolutize::*;
6use rand::prelude::*;
7use std::fs;
8use std::path::PathBuf;
9use std::process::exit;
10use std::str::FromStr;
11
12#[derive(Debug)]
13pub struct Wall {
14    pub config: Option<Config>,
15}
16
17impl Wall {
18    pub fn new(config: Option<Config>) -> Wall {
19        Wall { config }
20    }
21
22    pub fn absolute(&self, path: PathBuf) -> PathBuf {
23        match path.absolutize() {
24            Ok(p) => p.to_path_buf(),
25            Err(_) => {
26                eprintln!("Can't not absolutize the path.");
27                exit(1);
28            }
29        }
30    }
31
32    pub fn set(&self, path: PathBuf) {
33        let binding = self.absolute(path.clone());
34
35        let path = match binding.to_str() {
36            Some(p) => p,
37            None => {
38                eprintln!("Well, you passed wrong path");
39                exit(1);
40            }
41        };
42
43        if wallpaper::set_from_path(path).is_ok() {
44            println!("Voila!");
45        }
46    }
47
48    fn get_pics(dir: &PathBuf) -> Result<Vec<PathBuf>, Error> {
49        let mut result: Vec<PathBuf> = Vec::new();
50
51        if dir.is_dir() {
52            let read_dir = match fs::read_dir(dir) {
53                Ok(e) => e,
54                Err(err) => return Err(Error::ReadDirError(err)),
55            };
56
57            for entry in read_dir {
58                let entry = entry.unwrap();
59                let path = entry.path();
60
61                if path.is_dir() {
62                    match Self::get_pics(&path) {
63                        Ok(p) => p,
64                        Err(_) => {
65                            return Err(Error::NotListableDirectory(String::from(
66                                path.to_str().unwrap(),
67                            )))
68                        }
69                    };
70                } else {
71                    let check = path.to_str().unwrap();
72                    if check.ends_with(".png") || check.ends_with(".jpg") {
73                        result.push(path)
74                    }
75                }
76            }
77        }
78
79        Ok(result)
80    }
81
82    pub fn random(&self, path: Option<PathBuf>) {
83        let mut rng = thread_rng();
84        let mut location = PathBuf::new();
85
86        if let Some(c) = &self.config {
87            location = match PathBuf::from_str(&c.path) {
88                Ok(p) => p,
89                Err(e) => {
90                    eprintln!("Can't parse the path: {}", e);
91                    exit(1);
92                }
93            }
94        }
95
96        if path.is_some() {
97            location = path.unwrap()
98        }
99
100        location = self.absolute(location.clone());
101
102        if location.to_str().unwrap().is_empty() {
103            eprintln!(
104                "Seems like we couldn't find config either you didn't pass path to assets folder..."
105            );
106            exit(1);
107        }
108
109        let mut pics = showroom!(Self::get_pics(&location));
110
111        pics.shuffle(&mut rng);
112
113        let first = match pics.first() {
114            Some(p) => p,
115            None => {
116                eprintln!("Seems like there were no pictures!");
117                exit(1)
118            }
119        };
120
121        self.set(first.to_owned())
122    }
123
124    pub async fn install(&mut self, url: Option<String>) -> Result<(), Error> {
125        let mut target = String::new();
126        let source = Source::new(None);
127
128        // Download link:
129        // https://github.com/akumarujon/wall-rs-mirror/releases/tag/v0.0.3
130        // https://github.com/akumarujon/wall-rs-mirror/releases/download/v0.0.3/assets.zip
131
132        match url {
133            Some(l) => target.push_str(&l),
134            None => {
135                let mut versions = source.get_latest_version().await.unwrap();
136                versions = format!(
137                    "https://github.com/akumarujon/wall-rs-mirror/releases/download/{}/assets.zip",
138                    versions
139                );
140
141                match self.config.as_mut() {
142                    Some(c) => c.set_version(versions.clone()),
143                    None => (),
144                };
145
146                target.push_str(&versions)
147            }
148        };
149
150        const FILENAME: &str = "assets.zip";
151
152        source
153            .download_file(target, FILENAME.to_string())
154            .await
155            .unwrap();
156
157        source.extract_file(FILENAME).unwrap();
158
159        Ok(())
160    }
161
162    pub fn exit(&self) {
163        self.config.as_ref().unwrap().write("").unwrap()
164    }
165}
166
167#[cfg(test)]
168mod tests {
169    use crate::config::Config;
170    use crate::wall::Wall;
171
172    #[test]
173    fn test_random() {
174        let config = match Config::from_local_conf() {
175            Ok(c) => Some(c),
176            Err(_) => None,
177        };
178        let wall = Wall::new(config);
179
180        wall.random(None);
181    }
182}