SalOne22 / rimage

This is CLI tool inspired by squoosh!
Apache License 2.0
306 stars 19 forks source link

Add support for path-arg which end with "\" #67

Closed Mikachu2333 closed 7 months ago

Mikachu2333 commented 1 year ago

Description

Sorry for bother. Hope you could add support for file path which end with "\".

For example "D:\desktop\". Every time i use rimage and i need to delete the "\" manually, especially when i decide to use the program for different pics in different dirs... Besides, many programs likes to add a "\" after original path like "Everything" and so on.

Hope you could add a support for it!

Additional I made a GUI for rimage and since I am a bit confused about the double licenses you are using, I hope you can check if it meets the requirements. https://github.com/Mikachu2333/rimage_gui Thanks a thousand of time!

SalOne22 commented 1 year ago

I don't know exactly, but my guess is that it happens because of the clap library I use. It represents everything after "\" as a file path. So a simple way to fix this is to put the output directory at the end like this: rimage.exe .\input\*.jpg -f png -o .\output\

About license: You added the MIT license, so your project does not violate anything

Mikachu2333 commented 1 year ago

Thank you for your timely reply! And I will improve my program to support this as soon as possible.

Besides, I find that your software doesn't support uppercase letters as filename, for example the following pic. However, if i just write like this and do not change the original file name, it complete the task successfully...

图片 图片 图片

I tried the way you said, but still meets problems. (I have decided to change my gui and del every "\" after dir path to avoid this error)

By the way, because we Chinese often add spaces in dir path like "d:\课件 lesson 1\section1_pic1.Png", so it's necessary for me to add quotes to support it and avoid path error.

图片

SalOne22 commented 1 year ago

I added support for uppercase letters in extensions. About path in quotes, I will try to find replacement to my library that parses cli arguments.

Mikachu2333 commented 1 year ago

thanks very much!

SalOne22 commented 1 year ago

After some research, I found that a backslash at the end of a path wrapped in quotes is treated as an escape character in windows cmd. So there's no way I can fix it, sorry.

Here is some info about it - https://stackoverflow.com/questions/75848743/how-to-handle-paths-with-spaces-when-passing-arguments-to-a-rust-cli-program-on

Mikachu2333 commented 1 year ago

Thanks very much! After reading the answer of the webpage, I have modified my GUI logic and now it can perfectly avoid this problem! Besides, maybe you can add an explanation and example about the situation when spaces in the dirpath or filepath in ReadMe file, which may be very helpful for others to avoid the error.

Mikachu2333 commented 8 months ago

@SalOne22 I found a way to resolve this problem!

A short program is on the following as an example.

use regex::Regex;
use std::{env, fs, path::PathBuf};

fn main() {
    let mut args: Vec<String> = env::args().collect();
    if args.len() < 2 {
        println!(
            "\nRegex QQMusic Renamer    version 1.4\n\nUsage:\n{} <directory>\n{} <files>\n",
            &args[0], &args[0]
        );
        return;
    }

    let input_path: PathBuf = PathBuf::from(&args[1]);
    let (if_input_dir, checked_path) = check_path_dir(input_path);
    if if_input_dir {
        println!("Enum {:?}",checked_path);
        for files in fs::read_dir(&checked_path).unwrap() {
              rename_files(&files.unwrap().path());
        }
    } else {
        args.remove(0);
        for i in args {
            rename_files(&PathBuf::from(&i));
        }
    }
}

fn check_path_dir(mut path_to_check: PathBuf) -> (bool, PathBuf) {
    path_to_check = if path_to_check.ends_with("\"") {
        PathBuf::from(path_to_check.to_string_lossy().strip_suffix("\"").unwrap())
    } else {
        path_to_check
    };

    if !path_to_check.exists() {
        panic!("{:?} does not exist.", path_to_check.to_str());
    }

    (
        fs::metadata(&path_to_check).unwrap().is_dir(),
        path_to_check,
    )
}

fn get_new_name(regex: Regex, original_name: &str) -> &str {
    regex
        .captures(original_name)
        .unwrap()
        .get(2)
        .unwrap()
        .as_str()
}

fn rename_files(each_path: &PathBuf) {
    let reg = Regex::new(r"(.*) - (.*)( \[.*)").unwrap();
    //File name example: "HOYO-MiX - 枫丹 Fontaine [qmmc2].flac"
    if !fs::metadata(each_path).unwrap().is_dir() {
        let ext_list = ["ogg", "mp3", "flv", "flac", "wav", "mgg2", "mgg", "mflac"];
        let file_name = each_path.file_stem().unwrap().to_str().unwrap();
        let file_ext = each_path.extension().unwrap().to_str().unwrap();
        let dir_path = each_path.parent().unwrap().to_str().unwrap();

        if ext_list.contains(&file_ext) && reg.is_match(file_name) {
            let new_file_name = get_new_name(reg, file_name);
            let new_file_path =
                PathBuf::from(dir_path).join(new_file_name.to_string() + "." + file_ext);
            fs::rename(each_path, new_file_path).unwrap();
            println!("Renamed {} to {}", file_name, new_file_name);
        }
    }
}

The key of the code is

let path_to_check = if path_to_check.ends_with("\"") {
    PathBuf::from(path_to_check.to_string_lossy().strip_suffix("\"").unwrap())
}

As a roob in rust, and this is a program that only used by myself, there aren't ? or try and etc. to handle the errors the program might face, and the program is too silly to use for other people...

SalOne22 commented 8 months ago

Nice, I will reopen this issue to implement it in code