~iptq/garbage-old

ref: 8d6e5eadc7bbbf7b99ae62c79e2c8e68c25cfc03 garbage-old/src/main.rs -rw-r--r-- 3.6 KiB
8d6e5eadMichael Zhang rename 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;

mod errors;
mod ops;
mod dir;
mod info;

use std::fs;
use std::io;
use std::path::PathBuf;

use structopt::StructOpt;
use xdg::BaseDirectories;

use crate::errors::Error;
use crate::dir::TrashDir;

lazy_static! {
    static ref XDG: BaseDirectories = BaseDirectories::new().unwrap();
}

#[derive(StructOpt)]
enum Command {
    #[structopt(name = "empty")]
    Empty {
        /// Only list the files that are to be deleted, without
        /// actually deleting anything.
        #[structopt(long = "dry")]
        dry: bool,

        /// Delete all files older than (this number) of days.
        /// Removes everything if this option is not specified
        days: Option<u32>,
    },

    #[structopt(name = "list")]
    List,

    #[structopt(name = "put")]
    Put {
        /// The target path to be trashed
        #[structopt(parse(from_os_str))]
        paths: Vec<PathBuf>,

        /// Trashes directories recursively
        #[structopt(long = "recursive", short = "r")]
        recursive: bool,

        /// -f to stay compatible with GNU rm
        #[structopt(long = "force", short = "f")]
        _force: bool,
    },

    #[structopt(name = "restore")]
    Restore,
}

fn main() -> Result<(), Error> {
    env_logger::init();

    let cmd = Command::from_args();
    match cmd {
        Command::Empty { dry, days } => match crate::ops::empty(dry, days) {
            Ok(_) => (),
            Err(err) => error!("error: {:?}", err),
        },
        Command::List => {
            let home_trash = TrashDir::get_home_trash();
            for info in home_trash.iter().unwrap() {
                let info = match info {
                    Ok(info) => info,
                    Err(err) => {
                        warn!("failed to get file info: {:?}", err);
                        continue;
                    }
                };
                println!("{}\t{}", info.deletion_date, info.path.to_str().unwrap());
            }
        }
        Command::Put {
            paths, recursive, ..
        } => {
            for path in paths {
                match crate::ops::put(path, recursive) {
                    Ok(_) => (),
                    Err(err) => error!("error: {:?}", err),
                }
            }
        }
        Command::Restore => {
            let home_trash = TrashDir::get_home_trash();
            let files = home_trash
                .iter()
                .unwrap()
                .filter_map(|entry| match entry {
                    Ok(info) => Some(info),
                    Err(err) => {
                        warn!("failed to get file info: {:?}", err);
                        None
                    }
                })
                .collect::<Vec<_>>();
            for (i, info) in files.iter().enumerate() {
                println!(
                    "[{}]\t{}\t{}",
                    i,
                    info.deletion_date,
                    info.path.to_str().unwrap()
                );
            }

            let stdin = io::stdin();
            let mut s = String::new();
            println!("which file to restore? [0..{}]", files.len() - 1);
            stdin.read_line(&mut s).unwrap();

            match s.trim_end().parse::<usize>() {
                Ok(i) if i < files.len() => {
                    let info = files.get(i).unwrap();
                    println!("moving {:?} to {:?}", &info.deleted_path, &info.path);
                    fs::rename(&info.deleted_path, &info.path)?;
                }
                _ => println!("Invalid number."),
            }
        }
    }

    Ok(())
}