Advertisement
Guest User

Backup

a guest
Apr 19th, 2013
33
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.42 KB | None | 0 0
  1. #AFS Backup
  2. #2013, #astropheed
  3. #Usage:
  4. #   /s - Silent
  5. #   /l - No Logging
  6. #   /d - Detailed Logging (If logging is enabled)
  7. #   /r - No Retries
  8. #   /a - Archive prior to backup
  9. #   /ao - Only run the Archive Operation and skip the Backup
  10.  
  11. import datetime
  12. import os
  13. import sys
  14. import shutil
  15. import time
  16.  
  17. class Backup:
  18.     def __init__(self):
  19.         #Get Location List
  20.         if len(sys.argv) == 1:
  21.             print("\nKCE AFS Backup Script")
  22.             print("Copyright 2013, Ricky Hopfe\n")
  23.             print("Usage:")
  24.             print("Run from Command with appropriate switches")
  25.             print("Argument 1: Source Location")
  26.             print("Argument 2: Destination Location")
  27.             print("Switches:")
  28.             print("\t/a - Enable Archive before backup")
  29.             print("\t/d - Enable Details in log (only if /l is not used)")
  30.             print("\t/l - Disable Logging")
  31.             print("\t/s - Enable Silent Operation")
  32.             print("\t/r - Disable Retry on bad files")
  33.             print("\t/ao - Only run the Archive Operation and skip the Backup")
  34.             print("\n\nExample: 'python backup.py C:/ D:/ /s /d /a'")
  35.             print("This would first archive contents of D:/ and then copy C:/")
  36.             print("to the D:/ with no on-screen information. The log file")
  37.             print("will contain a detailed report of everything that happened")
  38.             sys.exit("\n\nSystem Exit: No Arguments")
  39.         self.reporting = True
  40.         self.detail_report = False
  41.         self.silence = False
  42.         self.retries = True
  43.         self.cancel_backup = False
  44.         self.files_updated = 0
  45.         self.files_created = 0
  46.         self.files_ignored = 0
  47.         self.start_time = time.strftime("%H:%M:%S on %d/%m/%Y")
  48.         self.cstart_time = time.time()
  49.         self.sls = [[sys.argv[1], sys.argv[2]]]
  50.         dow = datetime.date.today().weekday()
  51.         #Run backup methods
  52.         self.switches()
  53.         if not self.cancel_backup:
  54.             self.backup()
  55.  
  56.     def switches(self):
  57.         if len(sys.argv) >= 3:
  58.             if "/s" in sys.argv[3:]: self.silence = True
  59.             if "/l" in sys.argv[3:]: self.reporting = False
  60.             if "/d" in sys.argv[3:]: self.detail_report = True
  61.             if "/r" in sys.argv[3:]: self.retries = False
  62.             if "/ao" in sys.argv[3:]: self.cancel_backup = True
  63.             if "/a" or "/ao" in sys.argv[3:]:
  64.                 self.archive_loc = sys.argv[2][:3]+"/ARCHIVE/"
  65.                 self.archive()
  66.  
  67.     def wlog(self, text, detail=False):
  68.         if detail:
  69.             if not self.detail_report:
  70.                 return 0
  71.         if self.reporting:
  72.             backup_location = "C:/backup_logs/"
  73.             if not os.path.isdir(backup_location):
  74.                 os.makedirs(backup_location)
  75.             log_date = time.strftime("%Y_%m_%d")
  76.             log_time = time.strftime("%H:%M:%S")
  77.             self.log = open("%slog_%s.txt"%(backup_location, log_date),"a")
  78.             self.log.write("[%s]\t%s\n" % (log_time, text))
  79.             self.log.close()
  80.         else:
  81.             pass
  82.  
  83.     def wprint(self, *arg, **kw):
  84.         if not self.silence:
  85.             print(*arg, **kw)
  86.  
  87.     def calculate_time(self):
  88.         #Calculate a time between two times in certain formats
  89.         total_time_temp = self.cend_time - self.cstart_time
  90.  
  91.         #86400 seconds in a Day
  92.         if total_time_temp >= 86400:
  93.             self.total_time = '{0:.3g}'.format(total_time_temp / 86400)
  94.             self.total_time_format = "Days"
  95.  
  96.         #1440 Seconds in an hour
  97.         elif total_time_temp >= 1440:
  98.             self.total_time = '{0:.3g}'.format(total_time_temp / 1440)
  99.             self.total_time_format = "Hours"
  100.  
  101.         #60 Seconds in a minute
  102.         elif total_time_temp >= 60:
  103.             self.total_time = '{0:.3g}'.format(total_time_temp / 60)
  104.             self.total_time_format = "Minutes"
  105.  
  106.         #Must be less than a minute, Seconds it is
  107.         else:
  108.             self.total_time = '{0:.3g}'.format(total_time_temp)
  109.             self.total_time_format = "Seconds"
  110.  
  111.     def archive(self):
  112.         stamp = "Save_Set_%s" % time.strftime("%Y_%m_%d")
  113.         save_set = "%s%s" % (self.archive_loc, stamp)
  114.         if os.path.isdir(save_set):
  115.             self.wlog("Error: Archive already run today, skipped")
  116.             return 0
  117.  
  118.         self.wlog("Archive Operation Started")
  119.         last_error = ""
  120.         file_count = 0
  121.         if not os.path.isdir(save_set):
  122.             os.makedirs(save_set)
  123.         for (path, _, __) in os.walk(self.archive_loc[:3]):
  124.             if path[:len(self.archive_loc)-1] not in self.archive_loc:
  125.                 if path not in self.archive_loc[:3]+'$RECYCLE.BIN':
  126.                     self.wprint(path, self.archive_loc)
  127.                     for i in __: file_count += 1
  128.                     try:
  129.                         shutil.move(path, save_set)
  130.                         file_count += 1
  131.                         os.system('cls')
  132.                         self.wprint("Currently running Archive Operation:")
  133.                         self.wprint("Moved: %s things" % file_count)
  134.                     except Exception as e:
  135.                         last_error = "Last Error: %s" % e
  136.                         self.wlog(last_error)
  137.                         pass
  138.  
  139.         if not self.silence: os.system('cls')
  140.         self.wprint("Archive Operation completed successfully.")
  141.         self.wlog("Archive Operation completed")
  142.         self.wprint("Moved: %s files" % file_count)
  143.         self.wlog("Moved: %s files" % file_count, True)
  144.         self.wprint(last_error)
  145.  
  146.     def compare(self, p_src, p_dest, file):
  147.         f_src = p_src+file
  148.         f_dest = p_dest+file
  149.  
  150.         try:
  151.             f_src_time = os.path.getmtime(f_src)
  152.         except:
  153.             self.wlog("Source File Error: %s%s" % (p_src, file))
  154.             return 0
  155.         else:
  156.             try:
  157.                 f_dest_time = os.path.getmtime(f_dest)
  158.             except:
  159.                 #Destination doesn't exist
  160.                 self.files_created += 1
  161.                 return 1
  162.             else:
  163.                 if f_src_time == f_dest_time:
  164.                     self.files_ignored += 1
  165.                     self.wlog("File Ignored: %s%s" % (p_src, file), True)
  166.                     return 0
  167.                 elif f_src_time > f_dest_time:
  168.                     self.files_updated += 1
  169.                     return 1
  170.                 else:
  171.                     #DEST is newer
  172.                     self.files_ignored += 1
  173.                     self.wlog("File Ignored: %s%s" % (p_src, file), True)
  174.                     return 0
  175.  
  176.     def retry_backup(self, n, first = False):
  177.         bad_files = 0
  178.         good_files = 0
  179.         if not first:
  180.             if not self.silence: os.system('cls')
  181.             self.wprint("Currently running Backup Operation (Retry):")
  182.             self.wprint("Waiting 60 Seconds until next Retry:")
  183.             self.wprint("")
  184.             self.wprint("")
  185.             self.wprint("")
  186.             self.wprint("Remaining issues: %s:" % self.file_errors)
  187.             time.sleep(60)
  188.         if n > 0:
  189.             wlog("Attempting to Retry(%s) bad files" % n)
  190.             for src, dest in self.retry:
  191.                 if not os.path.isfile(dest):
  192.                     if not self.silence: os.system('cls')
  193.                     self.wprint("Retrying Bad Files (%s tries remain):" % n)
  194.                     self.wprint("Processed: %s files" % file_count)
  195.                     self.wprint("Current file: %s%s" % (src))
  196.                     self.wprint("Destination:  %s%s" % (dest))
  197.                     self.wprint("")
  198.                     self.wprint("Remaining issues: %s:" % self.file_errors)
  199.                     self.wprint("Successes: %s" % good_files)
  200.                     self.wprint("Failures: %s" % bad_files)
  201.                     try:
  202.                         shutil.copy(src, dest)
  203.                         self.wlog("%s *finally* copied to %s"%(src,dest), True)
  204.                         good_files += 1
  205.                         self.new_files += 1
  206.                         self.file_errors -= 1
  207.                     except:
  208.                         self.wlog("Unfortunately %s would not copy!" % src)
  209.                         bad_files += 1
  210.             if bad_files > 0:
  211.                 self.retry_backup(n-1)
  212.  
  213.     def backup(self, limit=0):
  214.         self.wlog("Backup Operation started at %s" % self.start_time)
  215.         self.retry = []
  216.         file_count = 0
  217.         dobreak = False
  218.         self.new_files = 0
  219.         self.file_errors = 0
  220.  
  221.         for loc in self.sls:
  222.             if dobreak: break
  223.             loc[0] = loc[0] if loc[0][-1] is "/" else loc[0]+"/"
  224.             for (path, dirs, files) in os.walk(loc[0]):
  225.                 if dobreak: break
  226.                 ext = path[len(loc[0]):] + "/"
  227.                 for dr in dirs:
  228.                     try:
  229.                         dest = loc[1] if loc[1][-1] is "/" else loc[1]+"/"
  230.                         dxt = ext if len(ext) > 1 else ""
  231.                         if not os.path.isdir(dest+dxt+dr):
  232.                             os.makedirs(dest+dxt+dr)
  233.                             self.wlog("Directory created: %s"%dest+dxt+dr,True)
  234.                     except:
  235.                         self.wlog("Failed to create directory: %s" % dr)
  236.  
  237.                 for file in files:
  238.                     if file_count > limit and limit > 0: dobreak = True
  239.                     if dobreak: break
  240.                     file_count += 1
  241.                     p_src = path if path[-1] is "/" else path+"/"
  242.                     p_dest = loc[1] if loc[1][-1] is "/" else loc[1]+"/"
  243.                     if not self.silence: os.system('cls')
  244.                     self.wprint("Currently running Backup Operation:")
  245.                     self.wprint("Processed: %s files" % file_count)
  246.                     self.wprint("Current file: %s%s" % (p_src,file))
  247.                     self.wprint("Destination:  %s%s" % (p_dest+ext,file))
  248.  
  249.                     if self.compare(p_src, p_dest+ext, file):
  250.                         try:
  251.                             if not os.path.isdir(p_dest+ext):
  252.                                 os.makedirs(p_dest+ext)
  253.                                 self.wlog("Directory created: %s"%p_dest+ext,
  254.                                   True)
  255.                         except:
  256.                             pass
  257.                         try:
  258.                             shutil.copy(p_src+file, p_dest+ext+file)
  259.                             self.wlog("%s copied to %s" % (p_src+file,
  260.                                                            p_dest+ext+file),
  261.                                                            True)
  262.                             self.new_files += 1
  263.                         except:
  264.                             self.file_errors += 1
  265.                             self.retry.append([p_src+file, p_dest+ext+file])
  266.                             self.wlog("File Error: %s" % p_src+file)
  267.                             self.wlog("Destination Error: %s"%p_dest+ext+file)
  268.  
  269.         if self.retries:
  270.             if self.file_errors > 0:
  271.                 self.retry_backup(3, True)
  272.         if not self.silence: os.system('cls')
  273.         end_time = time.strftime("%H:%M:%S on %d/%m/%Y")
  274.         self.cend_time = time.time()
  275.         self.calculate_time()
  276.         self.wprint("Backup Operation started at %s" % self.start_time)
  277.         self.wprint("Backup Operation completed successfully at %s" % end_time)
  278.         self.wprint("Time required: %s %s" % (self.total_time,
  279.                                               self.total_time_format))
  280.         self.wprint("")
  281.         self.wprint("Processed: %s files" % file_count)
  282.         self.wprint("")
  283.         self.wprint("Files created: %s" % self.files_created)
  284.         self.wprint("Files updated: %s" % self.files_updated)
  285.         self.wprint("Files ignored: %s" % self.files_ignored)
  286.         self.wprint("Files with errors: %s" % self.file_errors)
  287.         self.wlog("Backup Operation completed successfully at %s" % end_time)
  288.         self.wlog("Time required: %s %s" % (self.total_time,
  289.                                             self.total_time_format))
  290.         self.wlog("Processed: %s files" % file_count)
  291.         self.wlog("Files created: %s" % self.files_created)
  292.         self.wlog("Files updated: %s" % self.files_updated)
  293.         self.wlog("Files ignored: %s" % self.files_ignored)
  294.         self.wlog("Files with errors: %s" % self.file_errors)
  295. Backup()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement