You've already forked photo-importer
							
							
				mirror of
				https://github.com/sashacmc/photo-importer.git
				synced 2025-10-30 23:37:37 +02:00 
			
		
		
		
	File moving in separate module. Status refactored. run.py added.
This commit is contained in:
		
							
								
								
									
										12
									
								
								config.py
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								config.py
									
									
									
									
									
								
							| @@ -17,13 +17,13 @@ class Config(object): | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     def __init__(self, create=False): | ||||
|     def __init__(self, filename=None, create=False): | ||||
|         if filename is None: | ||||
|             filename = self.DEFAULT_CONFIG_FILE | ||||
|  | ||||
|         self.__config = configparser.ConfigParser() | ||||
|         self.__config.read_dict(self.DEFAULTS) | ||||
|         self.__config.read([ | ||||
|             'photo-importer.cfg', | ||||
|             '/etc/photo-importer.cfg', | ||||
|             self.DEFAULT_CONFIG_FILE]) | ||||
|         self.__config.read([filename, ]) | ||||
|  | ||||
|         if create: | ||||
|             self.__create_if_not_exists() | ||||
| @@ -40,4 +40,4 @@ class Config(object): | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     Config(True) | ||||
|     Config(create=True) | ||||
|   | ||||
| @@ -159,5 +159,5 @@ class FileProp(object): | ||||
| if __name__ == '__main__': | ||||
|     import sys | ||||
|  | ||||
|     fp = FileProp(config.Config(False), sys.argv[1]) | ||||
|     fp = FileProp(config.Config(), sys.argv[1]) | ||||
|     print(fp.type(), fp.time(), fp.ok()) | ||||
|   | ||||
							
								
								
									
										94
									
								
								importer.py
									
									
									
									
									
								
							
							
						
						
									
										94
									
								
								importer.py
									
									
									
									
									
								
							| @@ -1,13 +1,12 @@ | ||||
| #!/usr/bin/python3 | ||||
|  | ||||
| import os | ||||
| import shutil | ||||
| import logging | ||||
| import threading | ||||
|  | ||||
| import mover | ||||
| import config | ||||
| import rotator | ||||
| import fileprop | ||||
|  | ||||
|  | ||||
| class Importer(threading.Thread): | ||||
| @@ -16,23 +15,26 @@ class Importer(threading.Thread): | ||||
|         self.__config = config | ||||
|         self.__input_path = input_path | ||||
|         self.__output_path = output_path | ||||
|         self.__move_mode = int(config['main']['move_mode']) | ||||
|         self.__remove_garbage = int(config['main']['remove_garbage']) | ||||
|         self.__rot = None | ||||
|         self.__stat = {} | ||||
|         self.__stat = {'stage': ''} | ||||
|  | ||||
|     def run(self): | ||||
|         logging.info( | ||||
|             'Start: %s -> %s' % | ||||
|             (self.__input_path, self.__output_path)) | ||||
|  | ||||
|         self.__stat['stage'] = 'scan' | ||||
|         filenames = self.__scan_files(self.__input_path) | ||||
|         logging.info('Found %s files' % len(filenames)) | ||||
|  | ||||
|         self.__stat['stage'] = 'move' | ||||
|         new_filenames = self.__move_files(filenames) | ||||
|         logging.info('Processed %s files' % len(new_filenames)) | ||||
|  | ||||
|         self.__stat['stage'] = 'rotate' | ||||
|         self.__rotate_files(new_filenames) | ||||
|  | ||||
|         self.__stat['stage'] = 'done' | ||||
|         logging.info('Done') | ||||
|  | ||||
|     def __scan_files(self, input_path): | ||||
| @@ -50,78 +52,28 @@ class Importer(threading.Thread): | ||||
|         logging.error('Scan files error: %s' % err) | ||||
|  | ||||
|     def __move_files(self, filenames): | ||||
|         self.__stat['moved'] = 0 | ||||
|         self.__stat['copied'] = 0 | ||||
|         self.__stat['removed'] = 0 | ||||
|         self.__stat['skipped'] = 0 | ||||
|         self.__stat['processed'] = 0 | ||||
|         self.__stat['errors'] = 0 | ||||
|         res = [] | ||||
|         for fname in filenames: | ||||
|             try: | ||||
|                 new_fname = self.__move_file(fname) | ||||
|                 if new_fname: | ||||
|                     res.append(new_fname) | ||||
|             except Exception as ex: | ||||
|                 logging.error('Move files exception: %s' % ex) | ||||
|                 self.__stat['errors'] += 1 | ||||
|         self.__mov = mover.Mover( | ||||
|             self.__config, | ||||
|             self.__input_path, | ||||
|             self.__output_path, | ||||
|             filenames) | ||||
|  | ||||
|             self.__stat['processed'] += 1 | ||||
|         return res | ||||
|  | ||||
|     def __move_file(self, fname): | ||||
|         prop = fileprop.FileProp(self.__config, fname) | ||||
|  | ||||
|         if prop.type() == prop.GARBAGE: | ||||
|             if self.__remove_garbage: | ||||
|                 os.remove(fname) | ||||
|                 logging.info('removed "%s"' % fname) | ||||
|                 self.__stat['removed'] += 1 | ||||
|             else: | ||||
|                 self.__stat['skipped'] += 1 | ||||
|             return None | ||||
|  | ||||
|         if prop.type() == prop.OTHER or prop.time() is None: | ||||
|             self.__stat['skipped'] += 1 | ||||
|             return None | ||||
|  | ||||
|         if self.__output_path: | ||||
|             subdir = prop.time().strftime( | ||||
|                 self.__config['main']['out_date_format']) | ||||
|  | ||||
|             path = os.path.join(self.__output_path, subdir) | ||||
|             if not os.path.isdir(path): | ||||
|                 os.makedirs(path) | ||||
|  | ||||
|             fullname = prop.out_name_full(path) | ||||
|             if self.__move_mode: | ||||
|                 shutil.move(fname, fullname) | ||||
|                 logging.info('"%s" moved "%s"' % (fname, fullname)) | ||||
|                 self.__stat['moved'] += 1 | ||||
|             else: | ||||
|                 shutil.copy2(fname, fullname) | ||||
|                 logging.info('"%s" copied "%s"' % (fname, fullname)) | ||||
|                 self.__stat['copied'] += 1 | ||||
|  | ||||
|             return fullname | ||||
|         else: | ||||
|             if prop.ok(): | ||||
|                 self.__stat['skipped'] += 1 | ||||
|                 return fname | ||||
|             else: | ||||
|                 new_fname = prop.out_name_full() | ||||
|                 os.rename(fname, new_fname) | ||||
|                 logging.info('"%s" renamed "%s"' % (fname, new_fname)) | ||||
|                 self.__stat['moved'] += 1 | ||||
|                 return new_fname | ||||
|         return self.__mov.run() | ||||
|  | ||||
|     def __rotate_files(self, filenames): | ||||
|         self.__rot = rotator.Rotator(self.__config, filenames) | ||||
|         self.__rot = rotator.Rotator( | ||||
|             self.__config, | ||||
|             filenames) | ||||
|  | ||||
|         self.__rot.run() | ||||
|  | ||||
|     def status(self): | ||||
|         if self.__mov: | ||||
|             self.__stat['move'] = self.__mov.status() | ||||
|  | ||||
|         if self.__rot: | ||||
|             self.__stat['rotation'] = self.__rot.status() | ||||
|             self.__stat['rotate'] = self.__rot.status() | ||||
|  | ||||
|         return self.__stat | ||||
|  | ||||
|  | ||||
| @@ -131,7 +83,7 @@ if __name__ == '__main__': | ||||
|  | ||||
|     log.initLogger() | ||||
|  | ||||
|     imp = Importer(config.Config(False), sys.argv[1], sys.argv[2]) | ||||
|     imp = Importer(config.Config(), sys.argv[1], sys.argv[2]) | ||||
|     imp.start() | ||||
|     imp.join() | ||||
|  | ||||
|   | ||||
							
								
								
									
										87
									
								
								mover.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										87
									
								
								mover.py
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,87 @@ | ||||
| #!/usr/bin/python3 | ||||
|  | ||||
| import os | ||||
| import shutil | ||||
| import logging | ||||
|  | ||||
| import fileprop | ||||
|  | ||||
|  | ||||
| class Mover(object): | ||||
|     def __init__(self, config, input_path, output_path, filenames): | ||||
|         self.__config = config | ||||
|         self.__input_path = input_path | ||||
|         self.__output_path = output_path | ||||
|         self.__filenames = filenames | ||||
|         self.__move_mode = int(config['main']['move_mode']) | ||||
|         self.__remove_garbage = int(config['main']['remove_garbage']) | ||||
|         self.__stat = {'total': len(filenames)} | ||||
|  | ||||
|     def run(self): | ||||
|         self.__stat['moved'] = 0 | ||||
|         self.__stat['copied'] = 0 | ||||
|         self.__stat['removed'] = 0 | ||||
|         self.__stat['skipped'] = 0 | ||||
|         self.__stat['processed'] = 0 | ||||
|         self.__stat['errors'] = 0 | ||||
|         res = [] | ||||
|         for fname in self.__filenames: | ||||
|             try: | ||||
|                 new_fname = self.__move_file(fname) | ||||
|                 if new_fname: | ||||
|                     res.append(new_fname) | ||||
|             except Exception as ex: | ||||
|                 logging.error('Move files exception: %s' % ex) | ||||
|                 self.__stat['errors'] += 1 | ||||
|  | ||||
|             self.__stat['processed'] += 1 | ||||
|         return res | ||||
|  | ||||
|     def __move_file(self, fname): | ||||
|         prop = fileprop.FileProp(self.__config, fname) | ||||
|  | ||||
|         if prop.type() == prop.GARBAGE: | ||||
|             if self.__remove_garbage: | ||||
|                 os.remove(fname) | ||||
|                 logging.info('removed "%s"' % fname) | ||||
|                 self.__stat['removed'] += 1 | ||||
|             else: | ||||
|                 self.__stat['skipped'] += 1 | ||||
|             return None | ||||
|  | ||||
|         if prop.type() == prop.OTHER or prop.time() is None: | ||||
|             self.__stat['skipped'] += 1 | ||||
|             return None | ||||
|  | ||||
|         if self.__output_path: | ||||
|             subdir = prop.time().strftime( | ||||
|                 self.__config['main']['out_date_format']) | ||||
|  | ||||
|             path = os.path.join(self.__output_path, subdir) | ||||
|             if not os.path.isdir(path): | ||||
|                 os.makedirs(path) | ||||
|  | ||||
|             fullname = prop.out_name_full(path) | ||||
|             if self.__move_mode: | ||||
|                 shutil.move(fname, fullname) | ||||
|                 logging.info('"%s" moved "%s"' % (fname, fullname)) | ||||
|                 self.__stat['moved'] += 1 | ||||
|             else: | ||||
|                 shutil.copy2(fname, fullname) | ||||
|                 logging.info('"%s" copied "%s"' % (fname, fullname)) | ||||
|                 self.__stat['copied'] += 1 | ||||
|  | ||||
|             return fullname | ||||
|         else: | ||||
|             if prop.ok(): | ||||
|                 self.__stat['skipped'] += 1 | ||||
|                 return fname | ||||
|             else: | ||||
|                 new_fname = prop.out_name_full() | ||||
|                 os.rename(fname, new_fname) | ||||
|                 logging.info('"%s" renamed "%s"' % (fname, new_fname)) | ||||
|                 self.__stat['moved'] += 1 | ||||
|                 return new_fname | ||||
|  | ||||
|     def status(self): | ||||
|         return self.__stat | ||||
| @@ -71,7 +71,7 @@ class Rotator(object): | ||||
| if __name__ == '__main__': | ||||
|     import sys | ||||
|  | ||||
|     rot = Rotator(config.Config(False), sys.argv[1:]) | ||||
|     rot = Rotator(config.Config(), sys.argv[1:]) | ||||
|     rot.run() | ||||
|  | ||||
|     print(rot.status()) | ||||
|   | ||||
							
								
								
									
										79
									
								
								run.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										79
									
								
								run.py
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| #!/usr/bin/python3 | ||||
|  | ||||
| import sys | ||||
| import log | ||||
| import time | ||||
| import argparse | ||||
| import threading | ||||
| import progressbar | ||||
|  | ||||
| import config | ||||
| import importer | ||||
|  | ||||
|  | ||||
| class ProgressBar(threading.Thread): | ||||
|     def __init__(self, imp): | ||||
|         threading.Thread.__init__(self) | ||||
|         self.__imp = imp | ||||
|         self.__pbar = None | ||||
|  | ||||
|     def __create(self, name, count): | ||||
|         if self.__pbar: | ||||
|             self.__pbar.finish() | ||||
|             self.__pbar = None | ||||
|  | ||||
|         self.__pbar = progressbar.ProgressBar( | ||||
|             maxval=count, | ||||
|             widgets=[ | ||||
|                 name, ' ', | ||||
|                 progressbar.Percentage(), ' ', | ||||
|                 progressbar.Bar(), ' ', | ||||
|                 progressbar.ETA()]).start() | ||||
|  | ||||
|     def run(self): | ||||
|         stage = '' | ||||
|         while True: | ||||
|             time.sleep(0.1) | ||||
|             stat = self.__imp.status() | ||||
|  | ||||
|             if stage != stat['stage']: | ||||
|                 stage = stat['stage'] | ||||
|                 if stage == 'scan': | ||||
|                     print('Scan...') | ||||
|                     continue | ||||
|                 if stage == 'move': | ||||
|                     self.__create('Import:', stat['total']) | ||||
|                     continue | ||||
|                 if stage == 'rotate': | ||||
|                     self.__create('Rotate:', stat['total']) | ||||
|                     continue | ||||
|                 if stage == 'done': | ||||
|                     if self.__pbar: | ||||
|                         self.__pbar.finish() | ||||
|                     break | ||||
|  | ||||
|             if stage == 'move' or stage == 'rotate': | ||||
|                 self.__pbar.update(stat[stage]['processed']) | ||||
|  | ||||
|  | ||||
| def args_parse(): | ||||
|     parser = argparse.ArgumentParser() | ||||
|     parser.add_argument("echo", help="echo the string you use here") | ||||
|     return parser.parse_args() | ||||
|  | ||||
|  | ||||
| def main(): | ||||
|     # args = args_parse() | ||||
|  | ||||
|     log.initLogger('log.txt') | ||||
|  | ||||
|     imp = importer.Importer(config.Config(), sys.argv[1], sys.argv[2]) | ||||
|     pbar = ProgressBar(imp) | ||||
|     imp.start() | ||||
|     pbar.start() | ||||
|     imp.join() | ||||
|     pbar.join() | ||||
|  | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|     main() | ||||
		Reference in New Issue
	
	Block a user