This repository has been archived on 2020-04-11. You can view files and clone it, but cannot push or open issues or pull requests.
music-sync/src/registry.rs

111 lines
3.6 KiB
Rust

use cursive::utils::Counter;
use failure::Error;
use std::collections::HashSet;
use std::fs::File;
use std::io::prelude::*;
use std::path::PathBuf;
use walkdir::{DirEntry, WalkDir};
#[derive(Default)]
pub struct Registry {
pub device: String,
pub base_path: PathBuf,
pub albums_fs: HashSet<PathBuf>,
pub albums_list: HashSet<PathBuf>,
pub selected_albums: HashSet<PathBuf>,
}
impl Registry {
pub fn load_albums_fs(&mut self, counter: &Counter) -> Result<(), Error> {
let dir_walker = WalkDir::new(self.base_path.clone())
.sort_by(|a, b| a.path().cmp(b.path()))
.min_depth(2)
.max_depth(2);
let dir_filter = |entry: &DirEntry| {
// The entry should be a directory and its name should not start with "extra"
entry.metadata().map(|e| e.is_dir()).unwrap_or(false)
&& !entry
.file_name()
.to_str()
.map(|s| s.starts_with("extra"))
.unwrap_or(true)
};
for entry in dir_walker.into_iter().filter_entry(dir_filter) {
self.albums_fs.insert(PathBuf::from(
entry?
.path()
.strip_prefix(self.base_path.clone())?
.to_str()
.unwrap(),
));
counter.tick(1);
}
counter.set(self.albums_fs.len());
Ok(())
}
pub fn load_albums_file(&mut self) -> Result<(), Error> {
let mut file = File::open(format!("{}.list", self.device))?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
let line_filter = |line: &&str| line.ends_with("***");
for line in contents.lines().filter(line_filter) {
let path = line.trim_left_matches('#').trim_right_matches("/***");
if !line.starts_with('#') {
self.selected_albums.insert(PathBuf::from(path));
}
self.albums_list.insert(PathBuf::from(path));
}
Ok(())
}
pub fn save_albums_file(&self) -> Result<(), Error> {
let mut file = File::create(format!("{}.list.new", self.device))?;
let mut cur_parent = PathBuf::new();
let mut albums: Vec<&PathBuf> = self.albums_fs.iter().collect();
albums.sort();
for album in albums {
let parent = album.parent().unwrap();
if parent != cur_parent {
writeln!(file, "{}/", parent.to_str().unwrap());
cur_parent = parent.to_path_buf();
}
if self.selected_albums.contains(album) {
writeln!(file, "{}/***", album.to_str().unwrap());
} else {
writeln!(file, "#{}/***", album.to_str().unwrap());
}
}
Ok(())
}
pub fn added_albums(&self) -> Vec<&PathBuf> {
let mut result: Vec<&PathBuf> = self.albums_fs.difference(&self.albums_list).collect();
result.sort();
result
}
pub fn existing_albums(&self) -> Vec<&PathBuf> {
let mut result: Vec<&PathBuf> = self.albums_fs.intersection(&self.albums_list).collect();
result.sort();
result
}
pub fn removed_albums(&self) -> Vec<&PathBuf> {
let mut result: Vec<&PathBuf> = self.albums_list.difference(&self.albums_fs).collect();
result.sort();
result
}
pub fn select_album(&mut self, album_path: &PathBuf, result: bool) {
if result {
self.selected_albums.insert(album_path.clone());
} else {
self.selected_albums.remove(album_path);
}
}
}