Advertisement
uriid1

Trash CLI [python 3.10]

Jul 1st, 2022
772
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.67 KB | None
  1. #!/usr/bin/env python3.10
  2.  
  3. ####--------------------------------####
  4. #--# Author:   by uriid1            #--#
  5. #--# License:  GNU GPL              #--#
  6. #--# Telegram: @foxdacam            #--#
  7. #--# Mail:     appdurov@gmail.com   #--#
  8. ####--------------------------------####
  9.  
  10. # libs
  11. import sys
  12. import time
  13. import os.path, os
  14. import shutil
  15. from datetime import datetime
  16. from urllib.parse import unquote, quote
  17.  
  18. # Path to trash
  19. # Constans
  20. HOME = os.path.expanduser("~")
  21. TRASH_PATH       = os.path.join(HOME, '.local', 'share', 'Trash')
  22. TRASH_PATH2FILES = os.path.join(TRASH_PATH, 'files')
  23. TRASH_PATH2INFO  = os.path.join(TRASH_PATH, 'info')
  24.  
  25. # Help text :)
  26. help_text = '''Discription:
  27.    Managing the Trash from the Command Line.
  28.    ------------------------------------
  29.        Author:   by uriid1
  30.        License:  GNU GPL
  31.        Telegram: @main_moderator
  32.        Mail:     appdurov@gmail.com
  33.    ------------------------------------
  34.    -P, --put
  35.        Sending one or more files to the trash.
  36.        The '*' operator is supported to send all
  37.        files from the specified directory.
  38.        Example: trash --put *
  39.    -L, --list
  40.        show the content of the Trash.
  41.        Example: trash --list
  42.    -RM, --remove
  43.        Deleting one or more files from the trash.
  44.        Example: trash -RM foo bar
  45.    -E, --empty
  46.        Emptying the Trash.
  47.        Use the -y option to delete without confirmation.
  48.        Example: trash -E -y
  49.    -RS, --restore
  50.        Restoring one or more files.
  51.        Example: trash -RS foo bar
  52.    -RSA, --restore-all
  53.        Restoring all files.
  54.        Example: trash --restore-all
  55. '''
  56.  
  57.  
  58. ################################
  59. # Auxiliary functions
  60. ################################
  61.  
  62. # Console color print
  63. c_warn   = [192, 57, 43]
  64. c_info   = [246, 116, 0]
  65. c_folder = [61, 174, 233]
  66. c_file   = [28, 220, 154]
  67. def colored(color, text):
  68.     return "\033[38;2;{};{};{}m{}\033[38;2;255;255;255m".format(color[0], color[1], color[2], text)
  69.  
  70. # Confirmation for further interaction
  71. def confirm(text):
  72.     confirm = input(text)
  73.     return confirm == 'y' or confirm == 'Y'
  74.  
  75. # Get current date and time in format dd-mm-YYTH:M:S
  76. def make_date_and_time():
  77.     now = datetime.now()
  78.     dt_string = now.strftime("%Y-%m-%dT%H:%M:%S")
  79.     return dt_string
  80.  
  81. # Info file according to the specification
  82. def make_trash_info(target_name, path):
  83.     info = "[Trash Info]\nPath={}\nDeletionDate={}".format(quote(path), make_date_and_time())
  84.     with open(os.path.join(TRASH_PATH2INFO, target_name+'.trashinfo'), 'a') as out:
  85.         out.write(info)
  86.  
  87. # Checking if a file or directory exists
  88. def is_exists(path):
  89.     return os.path.isfile(path) or os.path.isdir(path)
  90.  
  91.  
  92. ################################
  93. # Main functions
  94. ################################
  95.  
  96. # Put in Trash
  97. def put(target):
  98.     # Target check
  99.     path_target = os.path.join(os.getcwd(), target)
  100.     if not is_exists(path_target):
  101.         print(colored(c_warn, target)+' is not a file or directory')
  102.         return
  103.  
  104.     # Check file exists in trash
  105.     target_name = target
  106.     if is_exists(os.path.join(TRASH_PATH2FILES, target)):
  107.         old_target_name = target
  108.         date = make_date_and_time()
  109.         target_prop = os.path.splitext(target)
  110.         target_name = target_prop[0]+'_[{}]'.format(date)+target_prop[1]
  111.         print('{} is exists in Trash. Rename to {}'.format(colored(c_info, target), colored(c_info, target_name)))
  112.  
  113.     # Move target
  114.     shutil.move(target, os.path.join(TRASH_PATH2FILES, target_name))
  115.  
  116.     # Make trash info
  117.     make_trash_info(target_name, path_target)
  118.  
  119.     # Inform
  120.     print('{} has been moved to {}'.format(colored(c_info, target_name), colored(c_info, 'Trash')))
  121.  
  122. # List files/dirs from Trash
  123. def list():
  124.     files = os.scandir(TRASH_PATH2FILES)
  125.     for f in files:
  126.         status = os.stat(f)
  127.         if f.is_dir():
  128.             print(colored(c_info, time.ctime(status.st_ctime)), colored(c_folder, f.name)+'/')
  129.         else:
  130.             print(colored(c_info, time.ctime(status.st_ctime)), colored(c_file, f.name))
  131.  
  132. # Remove file or dir from Trash
  133. def rm(path, target):
  134.     if not is_exists(path):
  135.         print('{} is not exists in Trash'.format(colored(c_warn, target)))
  136.         return
  137.  
  138.     # Remove target
  139.     if os.path.isfile(path) or os.path.islink(path):
  140.         # remove the file
  141.         os.remove(path)
  142.     elif os.path.isdir(path):
  143.         # remove dir and all contains
  144.         shutil.rmtree(path)
  145.  
  146.     # Remove info file
  147.     info_file = os.path.join(TRASH_PATH2INFO, target+'.trashinfo')
  148.     if os.path.isfile(info_file):
  149.         os.remove(info_file)
  150.  
  151.     # Inform
  152.     print('{} successfully deleted'.format(colored(c_info, target)))
  153.  
  154. # Restore file
  155. def restore(path, target):
  156.     if not is_exists(path):
  157.         print('{} is not exists in Trash'.format(colored(c_warn, target)))
  158.         return
  159.  
  160.     # Check info file
  161.     path_info_file = os.path.join(TRASH_PATH2INFO, target+'.trashinfo')
  162.     if not is_exists(path_info_file):
  163.         print('{} - info file is not exists in Trash'.format(colored(c_warn, target)))
  164.         return
  165.  
  166.     # Parse restore path
  167.     with open(path_info_file, "r") as f:
  168.         text = f.readlines()
  169.         restore_path = unquote(text[1].split('=')[1].replace('\n', ''))
  170.  
  171.     # File exists
  172.     if is_exists(restore_path):
  173.         if not confirm("[File exists on the restore path. Overwrite? Y/n]: "):
  174.             return
  175.  
  176.     # Move file
  177.     shutil.move(path, restore_path)
  178.  
  179.     # Delete info file
  180.     os.remove(path_info_file)
  181.  
  182.     # Inform
  183.     print('Restored '+colored(c_info, restore_path))
  184.  
  185.  
  186. ################################
  187. # Functions exec by a given key
  188. ################################
  189.  
  190. # Checking the entered arguments for some keys
  191. def args_count_check(argv):
  192.     args_len = len(argv)
  193.  
  194.     if args_len == 2:
  195.         print(colored(c_warn, "No argument specified. Use: trash -help"))
  196.         return False
  197.  
  198.     if args_len > 3:
  199.         return True
  200.  
  201.     return False
  202.  
  203. # Exec a function by key -P, --put
  204. def exec_put(argv):
  205.     # Put all files
  206.     if args_count_check(argv):
  207.         if confirm("[Move all files to the trash? Y/n]: "):
  208.             for i in range(2, len(argv)):
  209.                 put(argv[i])
  210.         return
  211.  
  212.     # Put one file
  213.     put(sys.argv[2])
  214.  
  215. # Exec a function by key -L, --list
  216. def exec_list():
  217.     list()
  218.  
  219. # Exec a function by key -RM, --remove
  220. def exec_rm(argv):
  221.     # Delete multiple files
  222.     if args_count_check(argv):
  223.         for i in range(2, len(argv)):
  224.             rm(os.path.join(TRASH_PATH2FILES, argv[i]), argv[i])
  225.         return
  226.  
  227.     # Delete one file
  228.     rm(os.path.join(TRASH_PATH2FILES, argv[2]), argv[2])
  229.  
  230. # Exec a function by key -E, --empty
  231. def exec_empty(argv):
  232.     # Without confirm
  233.     if len(argv) == 3:
  234.         if argv[2] == '-y':
  235.             files = os.listdir(TRASH_PATH2FILES)
  236.             for f in files:
  237.                  rm(os.path.join(TRASH_PATH2FILES, f), f)
  238.             return
  239.  
  240.     # With confirm
  241.     if confirm("[Empty trash. Are you sure? Y/n]: "):
  242.         files = os.listdir(TRASH_PATH2FILES)
  243.         for f in files:
  244.              rm(os.path.join(TRASH_PATH2FILES, f), f)
  245.  
  246.  
  247. # Exec a function by key -RE, --restore
  248. def exec_restore(argv):
  249.      # Restore multiple files
  250.     if args_count_check(argv):
  251.         for i in range(2, len(sys.argv)):
  252.             restore(os.path.join(TRASH_PATH2FILES, argv[i]), argv[i])
  253.         return
  254.  
  255.     # Restore target
  256.     restore(os.path.join(TRASH_PATH2FILES, argv[2]), argv[2])
  257.  
  258. # Exec a function by key -RSA, --restore-all
  259. def exec_restore_all():
  260.     if confirm("[Restore trash. Are you sure? Y/n]: "):
  261.         files = os.listdir(TRASH_PATH2FILES)
  262.         for f in files:
  263.             restore(os.path.join(TRASH_PATH2FILES, f), f)
  264.  
  265. def main():
  266.     # Checking for the existence of arguments
  267.     if len(sys.argv) == 1:
  268.         print(colored(c_warn, "No argument specified"))
  269.         return
  270.  
  271.     # Args switch-case
  272.     match sys.argv[1]:
  273.         case '-L' | '--list':
  274.             exec_list()
  275.        
  276.         case '-P' | '--put':
  277.             exec_put(sys.argv)
  278.        
  279.         case '-E' | '--empty':
  280.             exec_empty(sys.argv)
  281.  
  282.         case '-RM' | '--remove':
  283.             exec_rm(sys.argv)
  284.        
  285.         case '-RS' | '--restore':
  286.             exec_restore(sys.argv)
  287.        
  288.         case '-RSA' | '--restore-all':
  289.             exec_restore_all()
  290.  
  291.         case '-h' | '-H' | '-help' | '--help':
  292.             print(help_text)
  293.  
  294.         case _:
  295.             print(colored(c_warn, "Argument not found. Use: trash -help"))
  296.  
  297. # Standard boilerplate to call the main() function to begin
  298. # the program
  299. if __name__ == '__main__':
  300.     main()
Advertisement
RAW Paste Data Copied
Advertisement