2015-04-03 17:45:48 +02:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import shutil
from twiggy import quickSetup , log
2015-04-04 19:21:57 +02:00
import argparse
2015-04-03 17:45:48 +02:00
class KittenGroomerError ( Exception ) :
def __init__ ( self , message ) :
2015-04-04 18:44:17 +02:00
'''
Base KittenGroomer exception handler .
'''
2015-04-03 17:45:48 +02:00
super ( KittenGroomerError , self ) . __init__ ( message )
self . message = message
class ImplementationRequired ( KittenGroomerError ) :
2015-04-04 18:44:17 +02:00
'''
Implementation required error
'''
2015-04-03 17:45:48 +02:00
pass
class FileBase ( object ) :
def __init__ ( self , src_path , dst_path ) :
2015-04-04 18:44:17 +02:00
'''
Contains base information for a file on the source USB key ,
initialised with expected src and dest path
'''
2015-04-03 17:45:48 +02:00
self . src_path = src_path
self . dst_path = dst_path
self . log_details = { ' filepath ' : self . src_path }
self . log_string = ' '
def add_log_details ( self , key , value ) :
2015-04-04 18:44:17 +02:00
'''
Add an entry in the log dictionary
'''
2015-04-03 17:45:48 +02:00
self . log_details [ key ] = value
def make_dangerous ( self ) :
2015-04-04 18:44:17 +02:00
'''
This file should be considered as dangerous and never run .
Prepending and appending DANGEROUS to the destination
file name avoid double - click of death
'''
2015-04-03 17:45:48 +02:00
self . log_details [ ' dangerous ' ] = True
path , filename = os . path . split ( self . dst_path )
self . dst_path = os . path . join ( path , ' DANGEROUS_ {} _DANGEROUS ' . format ( filename ) )
def make_unknown ( self ) :
2015-04-04 18:44:17 +02:00
'''
This file has an unknown type and it was not possible to take
a decision . Theuser will have to decide what to do .
Prepending UNKNOWN
'''
2015-04-03 17:45:48 +02:00
self . log_details [ ' unknown ' ] = True
path , filename = os . path . split ( self . dst_path )
self . dst_path = os . path . join ( path , ' UNKNOWN_ {} ' . format ( filename ) )
def make_binary ( self ) :
2015-04-04 18:44:17 +02:00
'''
This file is a binary , and should probably not be run .
Appending . bin avoir double click of death but the user
will have to decide by itself .
'''
2015-04-03 17:45:48 +02:00
self . log_details [ ' binary ' ] = True
path , filename = os . path . split ( self . dst_path )
self . dst_path = os . path . join ( path , ' {} .bin ' . format ( filename ) )
class KittenGroomerBase ( object ) :
def __init__ ( self , root_src , root_dst ) :
2015-04-04 18:44:17 +02:00
'''
Setup the base options of the copy / convert setup
'''
2015-04-03 17:45:48 +02:00
self . src_root_dir = root_src
self . dst_root_dir = root_dst
self . log_root_dir = os . path . join ( self . dst_root_dir , ' logs ' )
self . log_processing = os . path . join ( self . log_root_dir , ' processing.log ' )
# quickSetup(file=self.log_processing)
quickSetup ( )
self . log_name = log . name ( ' files ' )
self . cur_file = None
# ##### Helpers #####
def _safe_rmtree ( self , directory ) :
2015-04-04 18:44:17 +02:00
''' Remove a directory tree if it exists '''
2015-04-03 17:45:48 +02:00
if os . path . exists ( directory ) :
shutil . rmtree ( directory )
def _safe_remove ( self , filepath ) :
2015-04-04 18:44:17 +02:00
''' Remove a file if it exists '''
2015-04-03 17:45:48 +02:00
if os . path . exists ( filepath ) :
os . remove ( filepath )
def _safe_mkdir ( self , directory ) :
2015-04-04 18:44:17 +02:00
''' Remove a directory if it exists '''
2015-04-03 17:45:48 +02:00
if not os . path . exists ( directory ) :
os . makedirs ( directory )
def _safe_copy ( self ) :
2015-04-04 18:44:17 +02:00
''' Copy a file and create directory if needed '''
2015-04-03 17:45:48 +02:00
try :
dst_path , filename = os . path . split ( self . cur_file . dst_path )
self . _safe_mkdir ( dst_path )
shutil . copy ( self . cur_file . src_path , self . cur_file . dst_path )
return True
except Exception as e :
# TODO: Logfile
print ( e )
return False
def _list_all_files ( self , directory ) :
2015-04-04 18:44:17 +02:00
''' Generate an iterator over all the files in a directory tree '''
2015-04-03 17:45:48 +02:00
for root , dirs , files in os . walk ( directory ) :
for filename in files :
filepath = os . path . join ( root , filename )
yield filepath
def _print_log ( self ) :
2015-04-04 17:00:38 +02:00
'''
2015-04-04 18:44:17 +02:00
Print log , should be called after each file .
2015-04-04 17:00:38 +02:00
You probably want to reimplement it in the subclass
'''
tmp_log = self . log_name . fields ( * * self . cur_file . log_details )
tmp_log . info ( ' It did a thing. ' )
2015-04-03 17:45:48 +02:00
#######################
def processdir ( self , src_dir = None , dst_dir = None ) :
2015-04-04 18:44:17 +02:00
'''
Main function doing the work , you have to implement it yourself .
'''
2015-04-03 17:45:48 +02:00
raise ImplementationRequired ( ' You have to implement the result processdir. ' )
2015-04-04 19:21:57 +02:00
def main ( kg_implementation ) :
parser = argparse . ArgumentParser ( prog = ' KittenGroomer ' , description = ' Call the KittenGroomer implementation to do things on files present in the source directory to the destination directory ' )
parser . add_argument ( ' -s ' , ' --source ' , type = str , help = ' Source directory ' )
parser . add_argument ( ' -d ' , ' --destination ' , type = str , help = ' Destination directory ' )
args = parser . parse_args ( )
kg = kg_implementation ( args . source , args . destination )
kg . processdir ( )