<s> from kitt . interfaces import moduleProvides , IDroneDService <EOL> moduleProvides ( IDroneDService ) <EOL> from kitt . util import dictwrapper <EOL> import config <EOL> SERVICENAME = '<STR_LIT>' <EOL> SERVICECONFIG = dictwrapper ( { <EOL> '<STR_LIT>' : { <EOL> config . LOG_DIR : [ <EOL> ( '<STR_LIT>' , int ( <NUM_LIT:7> * len ( config . AUTOSTART_SERVICES ) ) ) , <EOL> ] , <EOL> } <EOL> } ) <EOL> import os , re , time <EOL> from twisted . application . service import Service <EOL> from twisted . internet import defer , task <EOL> from droned . logging import logWithContext <EOL> from kitt . decorators import synchronizedDeferred , deferredAsThread <EOL> import copy <EOL> __doc__ = """<STR_LIT>""" <EOL> log = logWithContext ( type = SERVICENAME ) <EOL> def ageCompare ( f1 , f2 ) : <EOL> t1 = os . path . getmtime ( f1 ) <EOL> t2 = os . path . getmtime ( f2 ) <EOL> if t1 > t2 : return <NUM_LIT:1> <EOL> if t2 == t2 : return <NUM_LIT:0> <EOL> if t2 < t2 : return - <NUM_LIT:1> <EOL> class Janitizer ( Service ) : <EOL> minute = property ( lambda foo : <NUM_LIT> ) <EOL> hour = property ( lambda foo : <NUM_LIT> ) <EOL> day = property ( lambda foo : <NUM_LIT> ) <EOL> week = property ( lambda f : <NUM_LIT> ) <EOL> oldfiles = { } <EOL> watchDict = property ( lambda s : SERVICECONFIG . wrapped . get ( '<STR_LIT>' , { } ) ) <EOL> busy = defer . DeferredLock ( ) <EOL> def update ( self , watchDict ) : <EOL> """<STR_LIT>""" <EOL> tmp = copy . deepcopy ( self . watchDict ) <EOL> tmp . update ( watchDict ) <EOL> SERVICECONFIG . JANITIZE = tmp <EOL> @ synchronizedDeferred ( busy ) <EOL> @ deferredAsThread <EOL> def garbageCheck ( self ) : <EOL> """<STR_LIT>""" <EOL> watchDict = copy . deepcopy ( self . watchDict ) <EOL> for directory , garbageList in watchDict . iteritems ( ) : <EOL> if not os . path . exists ( directory ) : continue <EOL> for pattern , limit in garbageList : <EOL> self . cleanupLinks ( directory ) <EOL> files = [ os . path . join ( directory , f ) for f in os . listdir ( directory ) if re . search ( pattern , f ) ] <EOL> files = sorted ( files ) <EOL> if len ( files ) > int ( limit ) : <EOL> log ( '<STR_LIT>' % '<STR_LIT>' . join ( files ) ) <EOL> while len ( files ) > int ( limit ) : <EOL> oldfile = files . pop ( <NUM_LIT:0> ) <EOL> log ( '<STR_LIT>' % oldfile ) <EOL> if os . path . islink ( oldfile ) : continue <EOL> if os . path . isdir ( oldfile ) : <EOL> for base , dirs , myfiles in os . walk ( oldfile , topdown = False ) : <EOL> for name in myfiles : <EOL> os . remove ( os . path . join ( base , name ) ) <EOL> for name in dirs : <EOL> os . rmdir ( os . path . join ( base , name ) ) <EOL> os . rmdir ( oldfile ) <EOL> else : os . unlink ( oldfile ) <EOL> self . cleanupLinks ( directory ) <EOL> def cleanupLinks ( self , directory ) : <EOL> """<STR_LIT>""" <EOL> files = [ os . path . join ( directory , f ) for f in os . listdir ( directory ) ] <EOL> for f in files [ : ] : <EOL> if not os . path . exists ( f ) : <EOL> log ( '<STR_LIT>' % f ) <EOL> os . unlink ( f ) <EOL> files . remove ( f ) <EOL> return files <EOL> def clean_old_files ( self , directory , age , recurse = True ) : <EOL> """<STR_LIT>""" <EOL> self . oldfiles [ directory ] = ( age , recurse ) <EOL> @ synchronizedDeferred ( busy ) <EOL> @ deferredAsThread <EOL> def clean_elderly ( self ) : <EOL> """<STR_LIT>""" <EOL> for directory in self . oldfiles : <EOL> self . recursive_clean ( directory , * self . oldfiles [ directory ] ) <EOL> def recursive_clean ( self , directory , age , recurse ) : <EOL> """<STR_LIT>""" <EOL> try : data = map ( lambda n : os . path . join ( directory , n ) , os . listdir ( directory ) ) <EOL> except : <EOL> log ( '<STR_LIT>' % directory ) <EOL> return <EOL> for node in data : <EOL> if os . path . isdir ( node ) and recurse : <EOL> empty = self . recursive_clean ( node , age , recurse ) <EOL> if empty : <EOL> try : os . rmdir ( node ) <EOL> except : log ( '<STR_LIT>' % node ) <EOL> continue <EOL> if os . path . isdir ( node ) : continue <EOL> if ( time . time ( ) - os . stat ( node ) . st_mtime ) > age : <EOL> try : os . remove ( node ) <EOL> except : log ( '<STR_LIT>' % node ) <EOL> return bool ( os . listdir ( directory ) ) <EOL> def startService ( self ) : <EOL> """<STR_LIT>""" <EOL> self . GARBAGE_CHECK = task . LoopingCall ( self . garbageCheck ) <EOL> self . ELDERLY_CHECK = task . LoopingCall ( self . clean_elderly ) <EOL> Service . startService ( self ) <EOL> self . GARBAGE_CHECK . start ( self . minute * <NUM_LIT:20> ) <EOL> self . ELDERLY_CHECK . start ( self . minute ) <EOL> def stopService ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> if self . GARBAGE_CHECK . running : <EOL> self . GARBAGE_CHECK . stop ( ) <EOL> if self . ELDERLY_CHECK . running : <EOL> self . ELDERLY_CHECK . stop ( ) <EOL> except : pass <EOL> Service . stopService ( self ) <EOL> parentService = None <EOL> service = None <EOL> def update ( watchDict ) : <EOL> global service <EOL> if not running ( ) : <EOL> raise AssertionError ( '<STR_LIT>' ) <EOL> return service . update ( watchDict ) <EOL> def install ( _parentService ) : <EOL> global parentService <EOL> parentService = _parentService <EOL> def start ( ) : <EOL> global service <EOL> if not running ( ) : <EOL> service = Janitizer ( ) <EOL> service . setName ( SERVICENAME ) <EOL> service . setServiceParent ( parentService ) <EOL> def stop ( ) : <EOL> global service <EOL> if running ( ) : <EOL> service . disownServiceParent ( ) <EOL> service . stopService ( ) <EOL> service = None <EOL> def running ( ) : <EOL> return bool ( service ) and service . running <EOL> __all__ = [ '<STR_LIT>' , '<STR_LIT:start>' , '<STR_LIT>' , '<STR_LIT>' ] </s>
