<s> import datetime <EOL> import fnmatch <EOL> import os <EOL> import re <EOL> import sublime <EOL> import sys <EOL> import tempfile <EOL> if sys . version < '<STR_LIT:3>' : <EOL> from ftpsynccommon import Types <EOL> else : <EOL> from FTPSync . ftpsynccommon import Types <EOL> nestingLimit = <NUM_LIT:30> <EOL> triples = { <EOL> '<STR_LIT>' : <NUM_LIT:0> , <EOL> '<STR_LIT>' : <NUM_LIT:1> , <EOL> '<STR_LIT>' : <NUM_LIT:1> , <EOL> '<STR_LIT>' : <NUM_LIT:1> , <EOL> '<STR_LIT>' : <NUM_LIT:2> , <EOL> '<STR_LIT>' : <NUM_LIT:3> , <EOL> '<STR_LIT>' : <NUM_LIT:3> , <EOL> '<STR_LIT>' : <NUM_LIT:3> , <EOL> '<STR_LIT>' : <NUM_LIT:4> , <EOL> '<STR_LIT>' : <NUM_LIT:5> , <EOL> '<STR_LIT>' : <NUM_LIT:5> , <EOL> '<STR_LIT>' : <NUM_LIT:5> , <EOL> '<STR_LIT>' : <NUM_LIT:6> , <EOL> '<STR_LIT>' : <NUM_LIT:7> , <EOL> '<STR_LIT>' : <NUM_LIT:7> , <EOL> '<STR_LIT>' : <NUM_LIT:7> , <EOL> } <EOL> def isString ( var ) : <EOL> var_type = type ( var ) <EOL> if sys . version [ <NUM_LIT:0> ] == '<STR_LIT:3>' : <EOL> return var_type is str or var_type is bytes <EOL> else : <EOL> return var_type is str or var_type is unicode <EOL> class Metafile : <EOL> def __init__ ( self , name , isDir , lastModified , filesize , path = None , permissions = None ) : <EOL> self . name = name <EOL> self . isDir = bool ( isDir ) <EOL> self . lastModified = lastModified <EOL> if self . lastModified is not None : <EOL> self . lastModified = float ( self . lastModified ) <EOL> self . filesize = filesize <EOL> if self . filesize is not None : <EOL> self . filesize = float ( self . filesize ) <EOL> self . path = path <EOL> self . permissions = permissions <EOL> def getName ( self ) : <EOL> return self . name <EOL> def getPath ( self ) : <EOL> return self . path <EOL> def getFilepath ( self ) : <EOL> return self . path + "<STR_LIT:/>" + self . name <EOL> def getPermissions ( self ) : <EOL> return self . permissions <EOL> def getPermissionsNumeric ( self ) : <EOL> symbolic = self . permissions <EOL> numeric = "<STR_LIT:0>" <EOL> numeric += str ( triples [ symbolic [ <NUM_LIT:0> : <NUM_LIT:3> ] ] ) <EOL> numeric += str ( triples [ symbolic [ <NUM_LIT:3> : <NUM_LIT:6> ] ] ) <EOL> numeric += str ( triples [ symbolic [ <NUM_LIT:6> : <NUM_LIT:9> ] ] ) <EOL> return numeric <EOL> def isDirectory ( self ) : <EOL> return self . isDir <EOL> def getLastModified ( self ) : <EOL> return self . lastModified <EOL> def getLastModifiedFormatted ( self , format = '<STR_LIT>' ) : <EOL> return formatTimestamp ( self . lastModified , format ) <EOL> def getFilesize ( self ) : <EOL> return self . filesize <EOL> def getHumanFilesize ( self ) : <EOL> if self . filesize < <NUM_LIT> : <EOL> return str ( self . filesize ) + "<STR_LIT>" <EOL> if self . filesize < <NUM_LIT> * <NUM_LIT> : <EOL> return str ( round ( self . filesize / <NUM_LIT> , <NUM_LIT:2> ) ) + "<STR_LIT>" <EOL> if self . filesize < <NUM_LIT> * <NUM_LIT> * <NUM_LIT> : <EOL> return str ( round ( self . filesize / <NUM_LIT> / <NUM_LIT> , <NUM_LIT:2> ) ) + "<STR_LIT>" <EOL> return str ( round ( self . filesize / <NUM_LIT> / <NUM_LIT> / <NUM_LIT> , <NUM_LIT:2> ) ) + "<STR_LIT>" <EOL> def isSameFilepath ( self , filepath ) : <EOL> return os . path . realpath ( self . getPath ( ) ) == os . path . realpath ( filepath ) <EOL> def isNewerThan ( self , compared_file ) : <EOL> if self . lastModified is None : <EOL> return False <EOL> if isString ( compared_file ) : <EOL> if os . path . exists ( compared_file ) is False : <EOL> return False <EOL> lastModified = os . path . getmtime ( compared_file ) <EOL> elif isinstance ( compared_file , Metafile ) : <EOL> lastModified = compared_file . getLastModified ( ) <EOL> else : <EOL> raise TypeError ( "<STR_LIT>" ) <EOL> return self . lastModified > lastModified <EOL> def isDifferentSizeThan ( self , compared_file ) : <EOL> if self . filesize is None : <EOL> return False <EOL> if isString ( compared_file ) : <EOL> if os . path . exists ( compared_file ) is False : <EOL> return False <EOL> lastModified = os . path . getsize ( compared_file ) <EOL> elif isinstance ( compared_file , Metafile ) : <EOL> lastModified = compared_file . getLastModified ( ) <EOL> else : <EOL> raise TypeError ( "<STR_LIT>" ) <EOL> return self . filesize != os . path . getsize ( compared_file ) <EOL> def to_unicode_or_bust ( obj , encoding = '<STR_LIT:utf-8>' ) : <EOL> if isinstance ( obj , basestring ) : <EOL> if not isinstance ( obj , unicode ) : <EOL> obj = unicode ( obj , encoding ) <EOL> return obj <EOL> def fileToMetafile ( file_path ) : <EOL> if sys . version [ <NUM_LIT:0> ] < '<STR_LIT:3>' and type ( file_path ) is str : <EOL> file_path = file_path . decode ( '<STR_LIT:utf-8>' ) <EOL> elif type ( file_path ) is bytes : <EOL> file_path = file_path . decode ( '<STR_LIT:utf-8>' ) <EOL> name = os . path . basename ( file_path ) <EOL> path = file_path <EOL> isDir = os . path . isdir ( file_path ) <EOL> lastModified = os . path . getmtime ( file_path ) <EOL> filesize = os . path . getsize ( file_path ) <EOL> return Metafile ( name , isDir , lastModified , filesize , path ) <EOL> def formatTimestamp ( timestamp , format = '<STR_LIT>' ) : <EOL> if timestamp is None : <EOL> return "<STR_LIT:->" <EOL> return datetime . datetime . fromtimestamp ( int ( timestamp ) ) . strftime ( format ) <EOL> def getFolders ( file_path ) : <EOL> if file_path is None : <EOL> return [ ] <EOL> folders = [ file_path ] <EOL> limit = nestingLimit <EOL> while True : <EOL> split = os . path . split ( file_path ) <EOL> if len ( split ) == <NUM_LIT:0> : <EOL> break <EOL> file_path = split [ <NUM_LIT:0> ] <EOL> limit -= <NUM_LIT:1> <EOL> if len ( split [ <NUM_LIT:1> ] ) == <NUM_LIT:0> or limit < <NUM_LIT:0> : <EOL> break <EOL> folders . append ( split [ <NUM_LIT:0> ] ) <EOL> return folders <EOL> def findFile ( folders , file_name ) : <EOL> if folders is None : <EOL> return None <EOL> for folder in folders : <EOL> if isString ( folder ) is False : <EOL> folder = folder . decode ( '<STR_LIT:utf-8>' ) <EOL> if os . path . exists ( os . path . join ( folder , file_name ) ) is True : <EOL> return folder <EOL> return None <EOL> def getFiles ( paths , getConfigFile ) : <EOL> if paths is None : <EOL> return [ ] <EOL> files = [ ] <EOL> fileNames = [ ] <EOL> for target in paths : <EOL> if target not in fileNames : <EOL> fileNames . append ( target ) <EOL> files . append ( [ target . encode ( '<STR_LIT:utf-8>' ) , getConfigFile ( target . encode ( '<STR_LIT:utf-8>' ) ) ] ) <EOL> return files <EOL> def gatherMetafiles ( pattern , root ) : <EOL> if pattern is None : <EOL> return [ ] <EOL> result = { } <EOL> file_names = [ ] <EOL> for subroot , dirnames , filenames in os . walk ( root ) : <EOL> for filename in fnmatch . filter ( filenames , pattern ) : <EOL> target = os . path . join ( subroot , filename ) . encode ( '<STR_LIT:utf-8>' ) <EOL> if target not in file_names : <EOL> file_names . append ( target ) <EOL> result [ target ] = fileToMetafile ( target ) <EOL> for folder in dirnames : <EOL> result . update ( gatherMetafiles ( pattern , os . path . join ( root , folder ) ) . items ( ) ) <EOL> return result <EOL> def getChangedFiles ( metafilesBefore , metafilesAfter ) : <EOL> changed = [ ] <EOL> for file_path in metafilesAfter : <EOL> if file_path in metafilesBefore and metafilesAfter [ file_path ] . isNewerThan ( metafilesBefore [ file_path ] ) : <EOL> changed . append ( metafilesAfter [ file_path ] ) <EOL> return changed <EOL> def replace ( source , destination ) : <EOL> destinationTemp = destination + '<STR_LIT>' <EOL> try : <EOL> os . rename ( source , destination ) <EOL> except OSError : <EOL> os . rename ( destination , destinationTemp ) <EOL> try : <EOL> os . rename ( source , destination ) <EOL> os . unlink ( destinationTemp ) <EOL> except OSError as e : <EOL> os . rename ( destinationTemp , destination ) <EOL> raise <EOL> def viaTempfile ( file_path , operation , permissions , mode ) : <EOL> if permissions is None : <EOL> permissions = '<STR_LIT>' <EOL> exceptionOccured = None <EOL> directory = os . path . dirname ( file_path ) <EOL> if os . path . exists ( directory ) is False : <EOL> os . makedirs ( directory , int ( permissions , <NUM_LIT:8> ) ) <EOL> temp = tempfile . NamedTemporaryFile ( mode , suffix = '<STR_LIT>' , dir = directory , delete = False ) <EOL> try : <EOL> operation ( temp ) <EOL> except Exception as exp : <EOL> exceptionOccured = exp <EOL> finally : <EOL> temp . flush ( ) <EOL> temp . close ( ) <EOL> if exceptionOccured is None : <EOL> if os . path . exists ( file_path ) is False : <EOL> created = open ( file_path , '<STR_LIT>' ) <EOL> created . close ( ) <EOL> replace ( temp . name , file_path ) <EOL> if os . path . exists ( temp . name ) : <EOL> os . unlink ( temp . name ) <EOL> if exceptionOccured is not None : <EOL> raise exceptionOccured <EOL> def isTextFile ( file_path , asciiWhitelist ) : <EOL> fileName , fileExtension = os . path . splitext ( file_path ) <EOL> if fileExtension and fileExtension [ <NUM_LIT:1> : ] in asciiWhitelist : <EOL> return True <EOL> return False <EOL> def addLinks ( contents , parentPath ) : <EOL> hasSelf = False <EOL> hasUp = False <EOL> single = None <EOL> for entry in contents : <EOL> if entry . getName ( ) == '<STR_LIT:.>' : <EOL> hasSelf = True <EOL> elif entry . getName ( ) == '<STR_LIT:..>' : <EOL> hasUp = True <EOL> if hasSelf and hasUp : <EOL> return contents <EOL> else : <EOL> single = entry <EOL> path = parentPath <EOL> if single is not None : <EOL> path = single . getPath ( ) <EOL> if hasSelf == False : <EOL> entrySelf = Metafile ( '<STR_LIT:.>' , True , None , None , path , None ) <EOL> contents . append ( entrySelf ) <EOL> if hasUp == False : <EOL> entryUp = Metafile ( '<STR_LIT:..>' , True , None , None , path , None ) <EOL> contents . append ( entryUp ) <EOL> return contents <EOL> def relpath ( path , start ) : <EOL> relpath = os . path . relpath ( path , start ) <EOL> if start == '<STR_LIT:/>' and relpath [ <NUM_LIT:0> : <NUM_LIT:2> ] == '<STR_LIT:..>' : <EOL> relpath = relpath [ <NUM_LIT:3> : ] <EOL> return relpath </s>
