From f83f65358f4eaa67904859d0a8a431b0b8c61e17 Mon Sep 17 00:00:00 2001 From: Vitaliy Grabovets Date: Sun, 9 Jul 2023 23:07:30 +0300 Subject: [PATCH] read favourites file --- .github/workflows/ubuntu.yml | 2 +- .github/workflows/windows.yml | 2 +- Cargo.lock | 16 ++++++++++++--- Cargo.toml | 1 + PKGBUILD | 2 +- src/main.rs | 17 ++++++++++++---- src/scrubber.rs | 38 +++++++++++++++++++++++++++++++---- 7 files changed, 64 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 457a043f..e533c7d3 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -5,7 +5,7 @@ jobs: check: strategy: matrix: - os: [ubuntu-latest, ubuntu-20.04] + os: [ubuntu-20.04] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index edc9d621..64b374fb 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -5,7 +5,7 @@ jobs: check: strategy: matrix: - os: [windows-latest, windows-2019] + os: [windows-latest] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 diff --git a/Cargo.lock b/Cargo.lock index 3dd7c0b2..ff4dab1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -217,7 +217,7 @@ checksum = "6f6ca6f0c18c02c2fbfc119df551b8aeb8a385f6d5980f1475ba0255f1e97f1e" dependencies = [ "anyhow", "arrayvec 0.7.4", - "itertools", + "itertools 0.10.5", "log", "nom", "num-rational", @@ -2039,6 +2039,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.8" @@ -3192,7 +3201,7 @@ dependencies = [ [[package]] name = "oculante" -version = "0.6.68-dev1" +version = "0.6.68-dev2" dependencies = [ "anyhow", "arboard", @@ -3209,6 +3218,7 @@ dependencies = [ "gif", "gif-dispose", "image", + "itertools 0.11.0", "jxl-oxide", "kamadak-exif", "lexical-sort", @@ -3714,7 +3724,7 @@ dependencies = [ "cc", "cfg-if 1.0.0", "interpolate_name", - "itertools", + "itertools 0.10.5", "libc", "libfuzzer-sys", "log", diff --git a/Cargo.toml b/Cargo.toml index cd2e5c30..d8df0e2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,7 @@ fast_image_resize = "2.7" gif = "0.12" gif-dispose = "4" image = "0.24" +itertools = "0.11.0" kamadak-exif = "0.5" lexical-sort = "0.3" libavif-image = {version = "0.10", optional = true} diff --git a/PKGBUILD b/PKGBUILD index b8cc2b3c..3d10ecd7 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -23,4 +23,4 @@ package() { install -Dm644 res/oculante.desktop "${pkgdir}/usr/share/applications/${pkgname}.desktop" install -Dm644 LICENSE -t "${pkgdir}/usr/share/licenses/${pkgname}" install -Dm644 README.md -t "${pkgdir}/usr/share/doc/${pkgname}" -} +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index ce15ccd6..b9cbb0b2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use clap::Arg; use clap::Command; +use itertools::Itertools; use log::debug; use log::error; use log::info; @@ -48,6 +49,7 @@ mod image_editing; pub mod paint; pub const FONT: &[u8; 309828] = include_bytes!("../res/fonts/Inter-Regular.ttf"); +const FAVOURITES_FILE: &str = "favourites.txt"; #[notan_main] fn main() -> Result<(), String> { @@ -663,7 +665,7 @@ fn drawe(app: &mut App, gfx: &mut Graphics, plugins: &mut Plugins, state: &mut O // fill image sequence if state.folder_selected.is_none() { if let Some(p) = &state.current_path { - state.scrubber = scrubber::Scrubber::new(p, false, false); + state.scrubber = scrubber::Scrubber::new(p, None, false, false); state.scrubber.wrap = state.persistent_settings.wrap_folder; // debug!("{:#?} from {}", &state.scrubber, p.display()); @@ -1073,7 +1075,12 @@ fn browse_for_folder_path(state: &mut OculanteState) { _ = state.persistent_settings.save(); state.folder_selected = Option::from(folder_path.clone()); - state.scrubber = Scrubber::new(folder_path.as_path(), true, true); + state.scrubber = Scrubber::new( + folder_path.as_path(), + Some(FAVOURITES_FILE), + true, + true, + ); let current_path = state.scrubber.next(); state.is_loaded = false; @@ -1128,7 +1135,7 @@ fn add_to_favourites(state: &OculanteState) { state.folder_selected .as_ref() .unwrap_or(&img_path.parent().unwrap().to_path_buf()) - .join(Path::new("favourites.txt")) + .join(Path::new(FAVOURITES_FILE)) ) .expect("Unable to open file"); @@ -1137,7 +1144,9 @@ fn add_to_favourites(state: &OculanteState) { "{}", img_path.strip_prefix(state.folder_selected.as_ref().unwrap().as_path()) .unwrap() - .to_string_lossy() + .components() + .map(|component| component.as_os_str().to_str().unwrap()) + .join("\t") ).expect("Unable to write data"); } } diff --git a/src/scrubber.rs b/src/scrubber.rs index 7c970552..04d43b5d 100644 --- a/src/scrubber.rs +++ b/src/scrubber.rs @@ -2,6 +2,8 @@ use crate::utils::is_ext_compatible; use anyhow::{bail, Context, Result}; use log::debug; use rand::seq::SliceRandom; +use std::collections::HashSet; +use std::io::{BufRead, BufReader}; use std::path::{Path, PathBuf}; use walkdir::WalkDir; @@ -13,8 +15,8 @@ pub struct Scrubber { } impl Scrubber { - pub fn new(path: &Path, randomize: bool, walk_files: bool) -> Self { - let entries = get_image_filenames_for_directory(path, randomize, walk_files) + pub fn new(path: &Path, favourites_file: Option<&str>, randomize: bool, walk_files: bool) -> Self { + let entries = get_image_filenames_for_directory(path, favourites_file, randomize, walk_files) .unwrap_or_default(); let index = entries.iter().position(|p| p == path).unwrap_or_default(); Self { @@ -64,7 +66,7 @@ impl Scrubber { // Get sorted list of files in a folder // TODO: Should probably return an Result instead, but am too lazy to figure out + handle a dedicated error type here // TODO: Cache this result, instead of doing it each time we need to fetch another file from the folder -pub fn get_image_filenames_for_directory(folder_path: &Path, randomize: bool, walk_files: bool) -> Result> { +pub fn get_image_filenames_for_directory(folder_path: &Path, favourites_file: Option<&str>, randomize: bool, walk_files: bool) -> Result> { let mut folder_path = folder_path.to_path_buf(); if folder_path.is_file() { folder_path = folder_path @@ -73,6 +75,22 @@ pub fn get_image_filenames_for_directory(folder_path: &Path, randomize: bool, wa .context("Can't get parent")?; } + let mut _favourites: HashSet = Default::default(); + + if let Some(favourites_file) = favourites_file { + let favourites_path = folder_path.join(Path::new(favourites_file)); + if favourites_path.exists() { + let file = std::fs::File::open(favourites_path)?; + let reader = BufReader::new(file); + _favourites = reader + .lines() + .filter_map(|line| line.ok()) + .map(|file_str| folder_path.join(join_path_parts(file_str))) + .filter(|file| file.exists()) + .collect(); + } + } + let mut dir_files: Vec; if walk_files { @@ -91,6 +109,8 @@ pub fn get_image_filenames_for_directory(folder_path: &Path, randomize: bool, wa .collect::>(); } + debug!("number of files: {}", dir_files.len()); + // TODO: Are symlinks handled correctly? if randomize { @@ -118,9 +138,19 @@ pub fn find_first_image_in_directory(folder_path: &PathBuf) -> Result { if !folder_path.is_dir() { bail!("This is not a folder"); }; - get_image_filenames_for_directory(folder_path, false, false).map(|x| { + get_image_filenames_for_directory(folder_path, None, false, false).map(|x| { x.first() .cloned() .context("Folder does not have any supported images in it") })? } + +fn join_path_parts(path_with_tabs: String) -> PathBuf { + let mut path = PathBuf::new(); + + for part in path_with_tabs.split("\t") { + path.push(part); + } + + path +}