<s> '''<STR_LIT>''' <EOL> from __future__ import absolute_import , print_function <EOL> import logging <EOL> import os <EOL> import re <EOL> import stat <EOL> import shutil <EOL> import sys <EOL> import time <EOL> from subprocess import Popen , PIPE <EOL> try : <EOL> import grp <EOL> import pwd <EOL> except ImportError : <EOL> pass <EOL> import salt . ext . six as six <EOL> import salt . utils <EOL> import salt . defaults . exitcodes <EOL> from salt . utils . filebuffer import BufferedReader <EOL> log = logging . getLogger ( __name__ ) <EOL> _REQUIRES_PATH = <NUM_LIT:1> <EOL> _REQUIRES_STAT = <NUM_LIT:2> <EOL> _REQUIRES_CONTENTS = <NUM_LIT:4> <EOL> _FILE_TYPES = { '<STR_LIT:b>' : stat . S_IFBLK , <EOL> '<STR_LIT:c>' : stat . S_IFCHR , <EOL> '<STR_LIT:d>' : stat . S_IFDIR , <EOL> '<STR_LIT:f>' : stat . S_IFREG , <EOL> '<STR_LIT:l>' : stat . S_IFLNK , <EOL> '<STR_LIT:p>' : stat . S_IFIFO , <EOL> '<STR_LIT:s>' : stat . S_IFSOCK , <EOL> stat . S_IFBLK : '<STR_LIT:b>' , <EOL> stat . S_IFCHR : '<STR_LIT:c>' , <EOL> stat . S_IFDIR : '<STR_LIT:d>' , <EOL> stat . S_IFREG : '<STR_LIT:f>' , <EOL> stat . S_IFLNK : '<STR_LIT:l>' , <EOL> stat . S_IFIFO : '<STR_LIT:p>' , <EOL> stat . S_IFSOCK : '<STR_LIT:s>' } <EOL> _INTERVAL_REGEX = re . compile ( r'''<STR_LIT>''' , <EOL> flags = re . VERBOSE ) <EOL> def _parse_interval ( value ) : <EOL> '''<STR_LIT>''' <EOL> match = _INTERVAL_REGEX . match ( str ( value ) ) <EOL> if match is None : <EOL> raise ValueError ( '<STR_LIT>' . format ( value ) ) <EOL> result = <NUM_LIT:0> <EOL> resolution = None <EOL> for name , multiplier in [ ( '<STR_LIT>' , <NUM_LIT:1> ) , <EOL> ( '<STR_LIT>' , <NUM_LIT> ) , <EOL> ( '<STR_LIT>' , <NUM_LIT> * <NUM_LIT> ) , <EOL> ( '<STR_LIT>' , <NUM_LIT> * <NUM_LIT> * <NUM_LIT> ) , <EOL> ( '<STR_LIT>' , <NUM_LIT> * <NUM_LIT> * <NUM_LIT> * <NUM_LIT:7> ) ] : <EOL> if match . group ( name ) is not None : <EOL> result += float ( match . group ( name ) ) * multiplier <EOL> if resolution is None : <EOL> resolution = multiplier <EOL> return result , resolution , match . group ( '<STR_LIT>' ) <EOL> def _parse_size ( value ) : <EOL> scalar = value . strip ( ) <EOL> if scalar . startswith ( ( '<STR_LIT:->' , '<STR_LIT:+>' ) ) : <EOL> style = scalar [ <NUM_LIT:0> ] <EOL> scalar = scalar [ <NUM_LIT:1> : ] <EOL> else : <EOL> style = '<STR_LIT:=>' <EOL> if len ( scalar ) > <NUM_LIT:0> : <EOL> multiplier = { '<STR_LIT:b>' : <NUM_LIT:2> ** <NUM_LIT:0> , <EOL> '<STR_LIT:k>' : <NUM_LIT:2> ** <NUM_LIT:10> , <EOL> '<STR_LIT:m>' : <NUM_LIT:2> ** <NUM_LIT:20> , <EOL> '<STR_LIT:g>' : <NUM_LIT:2> ** <NUM_LIT:30> , <EOL> '<STR_LIT:t>' : <NUM_LIT:2> ** <NUM_LIT> } . get ( scalar [ - <NUM_LIT:1> ] . lower ( ) ) <EOL> if multiplier : <EOL> scalar = scalar [ : - <NUM_LIT:1> ] . strip ( ) <EOL> else : <EOL> multiplier = <NUM_LIT:1> <EOL> else : <EOL> multiplier = <NUM_LIT:1> <EOL> try : <EOL> num = int ( scalar ) * multiplier <EOL> except ValueError : <EOL> try : <EOL> num = int ( float ( scalar ) * multiplier ) <EOL> except ValueError : <EOL> raise ValueError ( '<STR_LIT>' . format ( value ) ) <EOL> if style == '<STR_LIT:->' : <EOL> min_size = <NUM_LIT:0> <EOL> max_size = num <EOL> elif style == '<STR_LIT:+>' : <EOL> min_size = num <EOL> max_size = six . MAXSIZE <EOL> else : <EOL> min_size = num <EOL> max_size = num + multiplier - <NUM_LIT:1> <EOL> return min_size , max_size <EOL> class Option ( object ) : <EOL> '''<STR_LIT>''' <EOL> def requires ( self ) : <EOL> return _REQUIRES_PATH <EOL> class NameOption ( Option ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , key , value ) : <EOL> self . regex = re . compile ( value . replace ( '<STR_LIT:.>' , '<STR_LIT>' ) <EOL> . replace ( '<STR_LIT:?>' , '<STR_LIT>' ) <EOL> . replace ( '<STR_LIT:*>' , '<STR_LIT>' ) + '<STR_LIT:$>' ) <EOL> def match ( self , dirname , filename , fstat ) : <EOL> return self . regex . match ( filename ) <EOL> class InameOption ( Option ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , key , value ) : <EOL> self . regex = re . compile ( value . replace ( '<STR_LIT:.>' , '<STR_LIT>' ) <EOL> . replace ( '<STR_LIT:?>' , '<STR_LIT>' ) <EOL> . replace ( '<STR_LIT:*>' , '<STR_LIT>' ) + '<STR_LIT:$>' , <EOL> re . IGNORECASE ) <EOL> def match ( self , dirname , filename , fstat ) : <EOL> return self . regex . match ( filename ) <EOL> class RegexOption ( Option ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , key , value ) : <EOL> try : <EOL> self . regex = re . compile ( value ) <EOL> except re . error : <EOL> raise ValueError ( '<STR_LIT>' . format ( value ) ) <EOL> def match ( self , dirname , filename , fstat ) : <EOL> return self . regex . match ( filename ) <EOL> class IregexOption ( Option ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , key , value ) : <EOL> try : <EOL> self . regex = re . compile ( value , re . IGNORECASE ) <EOL> except re . error : <EOL> raise ValueError ( '<STR_LIT>' . format ( value ) ) <EOL> def match ( self , dirname , filename , fstat ) : <EOL> return self . regex . match ( filename ) <EOL> class TypeOption ( Option ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , key , value ) : <EOL> value = "<STR_LIT>" . join ( value . strip ( ) . replace ( '<STR_LIT:U+002C>' , '<STR_LIT>' ) . split ( ) ) <EOL> self . ftypes = set ( ) <EOL> for ftype in value : <EOL> try : <EOL> self . ftypes . add ( _FILE_TYPES [ ftype ] ) <EOL> except KeyError : <EOL> raise ValueError ( '<STR_LIT>' . format ( ftype ) ) <EOL> def requires ( self ) : <EOL> return _REQUIRES_STAT <EOL> def match ( self , dirname , filename , fstat ) : <EOL> return stat . S_IFMT ( fstat [ stat . ST_MODE ] ) in self . ftypes <EOL> class OwnerOption ( Option ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , key , value ) : <EOL> self . uids = set ( ) <EOL> for name in value . replace ( '<STR_LIT:U+002C>' , '<STR_LIT:U+0020>' ) . split ( ) : <EOL> if name . isdigit ( ) : <EOL> self . uids . add ( int ( name ) ) <EOL> else : <EOL> try : <EOL> self . uids . add ( pwd . getpwnam ( value ) . pw_uid ) <EOL> except KeyError : <EOL> raise ValueError ( '<STR_LIT>' . format ( name ) ) <EOL> def requires ( self ) : <EOL> return _REQUIRES_STAT <EOL> def match ( self , dirname , filename , fstat ) : <EOL> return fstat [ stat . ST_UID ] in self . uids <EOL> class GroupOption ( Option ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , key , value ) : <EOL> self . gids = set ( ) <EOL> for name in value . replace ( '<STR_LIT:U+002C>' , '<STR_LIT:U+0020>' ) . split ( ) : <EOL> if name . isdigit ( ) : <EOL> self . gids . add ( int ( name ) ) <EOL> else : <EOL> try : <EOL> self . gids . add ( grp . getgrnam ( value ) . gr_gid ) <EOL> except KeyError : <EOL> raise ValueError ( '<STR_LIT>' . format ( name ) ) <EOL> def requires ( self ) : <EOL> return _REQUIRES_STAT <EOL> def match ( self , dirname , filename , fstat ) : <EOL> return fstat [ stat . ST_GID ] in self . gids <EOL> class SizeOption ( Option ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , key , value ) : <EOL> self . min_size , self . max_size = _parse_size ( value ) <EOL> def requires ( self ) : <EOL> return _REQUIRES_STAT <EOL> def match ( self , dirname , filename , fstat ) : <EOL> return self . min_size <= fstat [ stat . ST_SIZE ] <= self . max_size <EOL> class MtimeOption ( Option ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , key , value ) : <EOL> secs , resolution , modifier = _parse_interval ( value ) <EOL> self . mtime = time . time ( ) - int ( secs / resolution ) * resolution <EOL> self . modifier = modifier <EOL> def requires ( self ) : <EOL> return _REQUIRES_STAT <EOL> def match ( self , dirname , filename , fstat ) : <EOL> if self . modifier == '<STR_LIT:->' : <EOL> return fstat [ stat . ST_MTIME ] >= self . mtime <EOL> else : <EOL> return fstat [ stat . ST_MTIME ] <= self . mtime <EOL> class GrepOption ( Option ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , key , value ) : <EOL> try : <EOL> self . regex = re . compile ( value ) <EOL> except re . error : <EOL> raise ValueError ( '<STR_LIT>' . format ( value ) ) <EOL> def requires ( self ) : <EOL> return _REQUIRES_CONTENTS | _REQUIRES_STAT <EOL> def match ( self , dirname , filename , fstat ) : <EOL> if not stat . S_ISREG ( fstat [ stat . ST_MODE ] ) : <EOL> return None <EOL> dfilename = os . path . join ( dirname , filename ) <EOL> with BufferedReader ( dfilename , mode = '<STR_LIT:rb>' ) as bread : <EOL> for chunk in bread : <EOL> if self . regex . search ( chunk ) : <EOL> return dfilename <EOL> return None <EOL> class PrintOption ( Option ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , key , value ) : <EOL> self . need_stat = False <EOL> self . print_title = False <EOL> self . fmt = [ ] <EOL> for arg in value . replace ( '<STR_LIT:U+002C>' , '<STR_LIT:U+0020>' ) . split ( ) : <EOL> self . fmt . append ( arg ) <EOL> if arg not in [ '<STR_LIT:name>' , '<STR_LIT:path>' ] : <EOL> self . need_stat = True <EOL> if len ( self . fmt ) == <NUM_LIT:0> : <EOL> self . fmt . append ( '<STR_LIT:path>' ) <EOL> def requires ( self ) : <EOL> return _REQUIRES_STAT if self . need_stat else _REQUIRES_PATH <EOL> def execute ( self , fullpath , fstat , test = False ) : <EOL> result = [ ] <EOL> for arg in self . fmt : <EOL> if arg == '<STR_LIT:path>' : <EOL> result . append ( fullpath ) <EOL> elif arg == '<STR_LIT:name>' : <EOL> result . append ( os . path . basename ( fullpath ) ) <EOL> elif arg == '<STR_LIT:size>' : <EOL> result . append ( fstat [ stat . ST_SIZE ] ) <EOL> elif arg == '<STR_LIT:type>' : <EOL> result . append ( <EOL> _FILE_TYPES . get ( stat . S_IFMT ( fstat [ stat . ST_MODE ] ) , '<STR_LIT:?>' ) <EOL> ) <EOL> elif arg == '<STR_LIT>' : <EOL> result . append ( int ( oct ( fstat [ stat . ST_MODE ] ) [ - <NUM_LIT:3> : ] ) ) <EOL> elif arg == '<STR_LIT>' : <EOL> result . append ( fstat [ stat . ST_MTIME ] ) <EOL> elif arg == '<STR_LIT:user>' : <EOL> uid = fstat [ stat . ST_UID ] <EOL> try : <EOL> result . append ( pwd . getpwuid ( uid ) . pw_name ) <EOL> except KeyError : <EOL> result . append ( uid ) <EOL> elif arg == '<STR_LIT>' : <EOL> gid = fstat [ stat . ST_GID ] <EOL> try : <EOL> result . append ( grp . getgrgid ( gid ) . gr_name ) <EOL> except KeyError : <EOL> result . append ( gid ) <EOL> elif arg == '<STR_LIT>' : <EOL> if stat . S_ISREG ( fstat [ stat . ST_MODE ] ) : <EOL> md5digest = salt . utils . get_hash ( fullpath , '<STR_LIT>' ) <EOL> result . append ( md5digest ) <EOL> else : <EOL> result . append ( '<STR_LIT>' ) <EOL> if len ( result ) == <NUM_LIT:1> : <EOL> return result [ <NUM_LIT:0> ] <EOL> else : <EOL> return result <EOL> class DeleteOption ( TypeOption ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , key , value ) : <EOL> if '<STR_LIT:a>' in value : <EOL> value = '<STR_LIT>' <EOL> super ( self . __class__ , self ) . __init__ ( key , value ) <EOL> def execute ( self , fullpath , fstat , test = False ) : <EOL> if test : <EOL> return fullpath <EOL> try : <EOL> if os . path . isfile ( fullpath ) or os . path . islink ( fullpath ) : <EOL> os . remove ( fullpath ) <EOL> elif os . path . isdir ( fullpath ) : <EOL> shutil . rmtree ( fullpath ) <EOL> except ( OSError , IOError ) as exc : <EOL> return None <EOL> return fullpath <EOL> class ExecOption ( Option ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , key , value ) : <EOL> self . command = value <EOL> def execute ( self , fullpath , fstat , test = False ) : <EOL> try : <EOL> command = self . command . replace ( '<STR_LIT:{}>' , fullpath ) <EOL> print ( salt . utils . shlex_split ( command ) ) <EOL> p = Popen ( salt . utils . shlex_split ( command ) , <EOL> stdout = PIPE , <EOL> stderr = PIPE ) <EOL> ( out , err ) = p . communicate ( ) <EOL> if err : <EOL> log . error ( <EOL> '<STR_LIT>' . format ( <EOL> command , <EOL> salt . utils . to_str ( err ) ) ) <EOL> return "<STR_LIT>" . format ( command , salt . utils . to_str ( out ) ) <EOL> except Exception as e : <EOL> log . error ( <EOL> '<STR_LIT>' . format ( <EOL> command , <EOL> e ) ) <EOL> return '<STR_LIT>' . format ( fullpath ) <EOL> class Finder ( object ) : <EOL> def __init__ ( self , options ) : <EOL> self . actions = [ ] <EOL> self . maxdepth = None <EOL> self . mindepth = <NUM_LIT:0> <EOL> self . test = False <EOL> criteria = { _REQUIRES_PATH : list ( ) , <EOL> _REQUIRES_STAT : list ( ) , <EOL> _REQUIRES_CONTENTS : list ( ) } <EOL> if '<STR_LIT>' in options : <EOL> self . mindepth = options [ '<STR_LIT>' ] <EOL> del options [ '<STR_LIT>' ] <EOL> if '<STR_LIT>' in options : <EOL> self . maxdepth = options [ '<STR_LIT>' ] <EOL> del options [ '<STR_LIT>' ] <EOL> if '<STR_LIT:test>' in options : <EOL> self . test = options [ '<STR_LIT:test>' ] <EOL> del options [ '<STR_LIT:test>' ] <EOL> for key , value in six . iteritems ( options ) : <EOL> if key . startswith ( '<STR_LIT:_>' ) : <EOL> continue <EOL> if value is None or len ( str ( value ) ) == <NUM_LIT:0> : <EOL> raise ValueError ( '<STR_LIT>' . format ( key ) ) <EOL> try : <EOL> obj = globals ( ) [ key . title ( ) + "<STR_LIT>" ] ( key , value ) <EOL> except KeyError : <EOL> raise ValueError ( '<STR_LIT>' . format ( key ) ) <EOL> if hasattr ( obj , '<STR_LIT>' ) : <EOL> requires = obj . requires ( ) <EOL> if requires & _REQUIRES_CONTENTS : <EOL> criteria [ _REQUIRES_CONTENTS ] . append ( obj ) <EOL> elif requires & _REQUIRES_STAT : <EOL> criteria [ _REQUIRES_STAT ] . append ( obj ) <EOL> else : <EOL> criteria [ _REQUIRES_PATH ] . append ( obj ) <EOL> if hasattr ( obj , '<STR_LIT>' ) : <EOL> self . actions . append ( obj ) <EOL> if len ( self . actions ) == <NUM_LIT:0> : <EOL> self . actions . append ( PrintOption ( '<STR_LIT>' , '<STR_LIT>' ) ) <EOL> self . criteria = criteria [ _REQUIRES_PATH ] + criteria [ _REQUIRES_STAT ] + criteria [ _REQUIRES_CONTENTS ] <EOL> def find ( self , path ) : <EOL> '''<STR_LIT>''' <EOL> for dirpath , dirs , files in os . walk ( path ) : <EOL> depth = dirpath [ len ( path ) + len ( os . path . sep ) : ] . count ( os . path . sep ) <EOL> if depth >= self . mindepth : <EOL> for name in dirs + files : <EOL> fstat = None <EOL> matches = True <EOL> fullpath = None <EOL> for criterion in self . criteria : <EOL> if fstat is None and criterion . requires ( ) & _REQUIRES_STAT : <EOL> fullpath = os . path . join ( dirpath , name ) <EOL> fstat = os . stat ( fullpath ) <EOL> if not criterion . match ( dirpath , name , fstat ) : <EOL> matches = False <EOL> break <EOL> if matches : <EOL> if fullpath is None : <EOL> fullpath = os . path . join ( dirpath , name ) <EOL> for action in self . actions : <EOL> if ( fstat is None and <EOL> action . requires ( ) & _REQUIRES_STAT ) : <EOL> fstat = os . stat ( fullpath ) <EOL> result = action . execute ( fullpath , fstat , test = self . test ) <EOL> if result is not None : <EOL> yield result <EOL> if depth == self . maxdepth : <EOL> dirs [ : ] = [ ] <EOL> def find ( path , options ) : <EOL> '''<STR_LIT>''' <EOL> finder = Finder ( options ) <EOL> for path in finder . find ( path ) : <EOL> yield path <EOL> def _main ( ) : <EOL> if len ( sys . argv ) < <NUM_LIT:2> : <EOL> sys . stderr . write ( '<STR_LIT>' . format ( sys . argv [ <NUM_LIT:0> ] ) ) <EOL> sys . exit ( salt . defaults . exitcodes . EX_USAGE ) <EOL> path = sys . argv [ <NUM_LIT:1> ] <EOL> criteria = { } <EOL> for arg in sys . argv [ <NUM_LIT:2> : ] : <EOL> key , value = arg . split ( '<STR_LIT:=>' ) <EOL> criteria [ key ] = value <EOL> try : <EOL> finder = Finder ( criteria ) <EOL> except ValueError as ex : <EOL> sys . stderr . write ( '<STR_LIT>' . format ( ex ) ) <EOL> sys . exit ( salt . defaults . exitcodes . EX_GENERIC ) <EOL> for result in finder . find ( path ) : <EOL> print ( result ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> _main ( ) </s>
