|
@@ -0,0 +1,80 @@
|
|
|
|
|
+#! /usr/bin/env python3
|
|
|
|
|
+
|
|
|
|
|
+from pathlib import Path
|
|
|
|
|
+import argparse
|
|
|
|
|
+import logging
|
|
|
|
|
+import sys
|
|
|
|
|
+import os
|
|
|
|
|
+import json
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+DEFAULT_CONFIG = {
|
|
|
|
|
+ 'trashes': [
|
|
|
|
|
+ '$HOME/trash/',
|
|
|
|
|
+ ]
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def parse_args():
|
|
|
|
|
+ parser = argparse.ArgumentParser()
|
|
|
|
|
+ parser.add_argument('names', nargs='+')
|
|
|
|
|
+ return parser.parse_args()
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def lowest_mount(path: Path) -> Path:
|
|
|
|
|
+ """Find lowest level mount point of given path"""
|
|
|
|
|
+ while not path.is_mount() and path.parent != path:
|
|
|
|
|
+ return lowest_mount(path.parent)
|
|
|
|
|
+
|
|
|
|
|
+ return path
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def getconfig():
|
|
|
|
|
+ config_file = Path('~/.config/trash.json').expanduser()
|
|
|
|
|
+ config = DEFAULT_CONFIG
|
|
|
|
|
+ if config_file.is_file():
|
|
|
|
|
+ with open(config_file) as f:
|
|
|
|
|
+ config.update(json.load(f))
|
|
|
|
|
+ return config
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def main():
|
|
|
|
|
+ args = parse_args()
|
|
|
|
|
+ logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
|
|
|
|
|
+
|
|
|
|
|
+ config = getconfig()
|
|
|
|
|
+ logging.debug(config)
|
|
|
|
|
+
|
|
|
|
|
+ trashes = []
|
|
|
|
|
+ for trashdir in config['trashes']:
|
|
|
|
|
+ trashdir = Path(os.path.expandvars(trashdir)).expanduser().resolve()
|
|
|
|
|
+ if not trashdir.is_dir():
|
|
|
|
|
+ logging.info(f'new trash created at {trashdir}.')
|
|
|
|
|
+ trashdir.mkdir()
|
|
|
|
|
+ trashes.append(trashdir)
|
|
|
|
|
+
|
|
|
|
|
+ for name in args.names:
|
|
|
|
|
+ name = Path(os.path.expandvars(name))
|
|
|
|
|
+
|
|
|
|
|
+ if not (name.is_file() or name.is_dir()):
|
|
|
|
|
+ logging.warning(f'{name} is not a file nor directory')
|
|
|
|
|
+ continue
|
|
|
|
|
+
|
|
|
|
|
+ name = name.absolute()
|
|
|
|
|
+
|
|
|
|
|
+ trashed = False
|
|
|
|
|
+ for trashdir in trashes:
|
|
|
|
|
+ try:
|
|
|
|
|
+ if lowest_mount(trashdir) == lowest_mount(name):
|
|
|
|
|
+ logging.info(f'Will move {name} to {trashdir}')
|
|
|
|
|
+ trashed = True
|
|
|
|
|
+ break
|
|
|
|
|
+ except ValueError:
|
|
|
|
|
+ pass
|
|
|
|
|
+
|
|
|
|
|
+ if not trashed:
|
|
|
|
|
+ logging.warning(f'Unable to trash {name}')
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+if __name__ == '__main__':
|
|
|
|
|
+ main()
|