<s> """<STR_LIT>""" <EOL> import os <EOL> import stat <EOL> import fnmatch <EOL> import xdg . BaseDirectory <EOL> import xdg . Xocale <EOL> from xml . dom import Node , minidom , XML_NAMESPACE <EOL> FREE_NS = '<STR_LIT>' <EOL> types = { } <EOL> exts = None <EOL> globs = None <EOL> literals = None <EOL> magic = None <EOL> def _get_node_data ( node ) : <EOL> """<STR_LIT>""" <EOL> return '<STR_LIT>' . join ( [ n . nodeValue for n in node . childNodes ] ) . strip ( ) <EOL> def lookup ( media , subtype = None ) : <EOL> "<STR_LIT>" <EOL> if subtype is None and '<STR_LIT:/>' in media : <EOL> media , subtype = media . split ( '<STR_LIT:/>' , <NUM_LIT:1> ) <EOL> if ( media , subtype ) not in types : <EOL> types [ ( media , subtype ) ] = MIMEtype ( media , subtype ) <EOL> return types [ ( media , subtype ) ] <EOL> class MIMEtype : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , media , subtype ) : <EOL> "<STR_LIT>" <EOL> assert media and '<STR_LIT:/>' not in media <EOL> assert subtype and '<STR_LIT:/>' not in subtype <EOL> assert ( media , subtype ) not in types <EOL> self . media = media <EOL> self . subtype = subtype <EOL> self . _comment = None <EOL> def _load ( self ) : <EOL> "<STR_LIT>" <EOL> resource = os . path . join ( '<STR_LIT>' , self . media , self . subtype + '<STR_LIT>' ) <EOL> for path in xdg . BaseDirectory . load_data_paths ( resource ) : <EOL> doc = minidom . parse ( path ) <EOL> if doc is None : <EOL> continue <EOL> for comment in doc . documentElement . getElementsByTagNameNS ( FREE_NS , '<STR_LIT>' ) : <EOL> lang = comment . getAttributeNS ( XML_NAMESPACE , '<STR_LIT>' ) or '<STR_LIT>' <EOL> goodness = <NUM_LIT:1> + ( lang in xdg . Xocale . langs ) <EOL> if goodness > self . _comment [ <NUM_LIT:0> ] : <EOL> self . _comment = ( goodness , _get_node_data ( comment ) ) <EOL> if goodness == <NUM_LIT:2> : return <EOL> def get_comment ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . _comment is None : <EOL> self . _comment = ( <NUM_LIT:0> , str ( self ) ) <EOL> self . _load ( ) <EOL> return self . _comment [ <NUM_LIT:1> ] <EOL> def __str__ ( self ) : <EOL> return self . media + '<STR_LIT:/>' + self . subtype <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % ( self , self . _comment or '<STR_LIT>' ) <EOL> class MagicRule : <EOL> def __init__ ( self , f ) : <EOL> self . next = None <EOL> self . prev = None <EOL> ind = '<STR_LIT>' <EOL> while True : <EOL> c = f . read ( <NUM_LIT:1> ) <EOL> if c == '<STR_LIT:>>' : <EOL> break <EOL> ind += c <EOL> if not ind : <EOL> self . nest = <NUM_LIT:0> <EOL> else : <EOL> self . nest = int ( ind ) <EOL> start = '<STR_LIT>' <EOL> while True : <EOL> c = f . read ( <NUM_LIT:1> ) <EOL> if c == '<STR_LIT:=>' : <EOL> break <EOL> start += c <EOL> self . start = int ( start ) <EOL> hb = f . read ( <NUM_LIT:1> ) <EOL> lb = f . read ( <NUM_LIT:1> ) <EOL> self . lenvalue = ord ( lb ) + ( ord ( hb ) << <NUM_LIT:8> ) <EOL> self . value = f . read ( self . lenvalue ) <EOL> c = f . read ( <NUM_LIT:1> ) <EOL> if c == '<STR_LIT:&>' : <EOL> self . mask = f . read ( self . lenvalue ) <EOL> c = f . read ( <NUM_LIT:1> ) <EOL> else : <EOL> self . mask = None <EOL> if c == '<STR_LIT>' : <EOL> w = '<STR_LIT>' <EOL> while c != '<STR_LIT:+>' and c != '<STR_LIT:\n>' : <EOL> c = f . read ( <NUM_LIT:1> ) <EOL> if c == '<STR_LIT:+>' or c == '<STR_LIT:\n>' : <EOL> break <EOL> w += c <EOL> self . word = int ( w ) <EOL> else : <EOL> self . word = <NUM_LIT:1> <EOL> if c == '<STR_LIT:+>' : <EOL> r = '<STR_LIT>' <EOL> while c != '<STR_LIT:\n>' : <EOL> c = f . read ( <NUM_LIT:1> ) <EOL> if c == '<STR_LIT:\n>' : <EOL> break <EOL> r += c <EOL> self . range = int ( r ) <EOL> else : <EOL> self . range = <NUM_LIT:1> <EOL> if c != '<STR_LIT:\n>' : <EOL> raise '<STR_LIT>' <EOL> def getLength ( self ) : <EOL> return self . start + self . lenvalue + self . range <EOL> def appendRule ( self , rule ) : <EOL> if self . nest < rule . nest : <EOL> self . next = rule <EOL> rule . prev = self <EOL> elif self . prev : <EOL> self . prev . appendRule ( rule ) <EOL> def match ( self , buffer ) : <EOL> if self . match0 ( buffer ) : <EOL> if self . next : <EOL> return self . next . match ( buffer ) <EOL> return True <EOL> def match0 ( self , buffer ) : <EOL> l = len ( buffer ) <EOL> for o in range ( self . range ) : <EOL> s = self . start + o <EOL> e = s + self . lenvalue <EOL> if l < e : <EOL> return False <EOL> if self . mask : <EOL> test = '<STR_LIT>' <EOL> for i in range ( self . lenvalue ) : <EOL> c = ord ( buffer [ s + i ] ) & ord ( self . mask [ i ] ) <EOL> test += chr ( c ) <EOL> else : <EOL> test = buffer [ s : e ] <EOL> if test == self . value : <EOL> return True <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % ( self . nest , <EOL> self . start , <EOL> self . lenvalue , <EOL> ` self . value ` , <EOL> ` self . mask ` , <EOL> self . word , <EOL> self . range ) <EOL> class MagicType : <EOL> def __init__ ( self , mtype ) : <EOL> self . mtype = mtype <EOL> self . top_rules = [ ] <EOL> self . last_rule = None <EOL> def getLine ( self , f ) : <EOL> nrule = MagicRule ( f ) <EOL> if nrule . nest and self . last_rule : <EOL> self . last_rule . appendRule ( nrule ) <EOL> else : <EOL> self . top_rules . append ( nrule ) <EOL> self . last_rule = nrule <EOL> return nrule <EOL> def match ( self , buffer ) : <EOL> for rule in self . top_rules : <EOL> if rule . match ( buffer ) : <EOL> return self . mtype <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % self . mtype <EOL> class MagicDB : <EOL> def __init__ ( self ) : <EOL> self . types = { } <EOL> self . maxlen = <NUM_LIT:0> <EOL> def mergeFile ( self , fname ) : <EOL> f = file ( fname , '<STR_LIT:r>' ) <EOL> line = f . readline ( ) <EOL> if line != '<STR_LIT>' : <EOL> raise '<STR_LIT>' <EOL> while True : <EOL> shead = f . readline ( ) <EOL> if not shead : <EOL> break <EOL> if shead [ <NUM_LIT:0> ] != '<STR_LIT:[>' or shead [ - <NUM_LIT:2> : ] != '<STR_LIT>' : <EOL> raise '<STR_LIT>' <EOL> pri , tname = shead [ <NUM_LIT:1> : - <NUM_LIT:2> ] . split ( '<STR_LIT::>' ) <EOL> pri = int ( pri ) <EOL> mtype = lookup ( tname ) <EOL> try : <EOL> ents = self . types [ pri ] <EOL> except : <EOL> ents = [ ] <EOL> self . types [ pri ] = ents <EOL> magictype = MagicType ( mtype ) <EOL> c = f . read ( <NUM_LIT:1> ) <EOL> f . seek ( - <NUM_LIT:1> , <NUM_LIT:1> ) <EOL> while c and c != '<STR_LIT:[>' : <EOL> rule = magictype . getLine ( f ) <EOL> if rule and rule . getLength ( ) > self . maxlen : <EOL> self . maxlen = rule . getLength ( ) <EOL> c = f . read ( <NUM_LIT:1> ) <EOL> f . seek ( - <NUM_LIT:1> , <NUM_LIT:1> ) <EOL> ents . append ( magictype ) <EOL> if not c : <EOL> break <EOL> def match_data ( self , data , max_pri = <NUM_LIT:100> , min_pri = <NUM_LIT:0> ) : <EOL> pris = self . types . keys ( ) <EOL> pris . sort ( lambda a , b : - cmp ( a , b ) ) <EOL> for pri in pris : <EOL> if pri > max_pri : <EOL> continue <EOL> if pri < min_pri : <EOL> break <EOL> for type in self . types [ pri ] : <EOL> m = type . match ( data ) <EOL> if m : <EOL> return m <EOL> def match ( self , path , max_pri = <NUM_LIT:100> , min_pri = <NUM_LIT:0> ) : <EOL> try : <EOL> buf = file ( path , '<STR_LIT:r>' ) . read ( self . maxlen ) <EOL> return self . match_data ( buf , max_pri , min_pri ) <EOL> except : <EOL> pass <EOL> return None <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % self . types <EOL> text = lookup ( '<STR_LIT:text>' , '<STR_LIT>' ) <EOL> inode_block = lookup ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> inode_char = lookup ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> inode_dir = lookup ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> inode_fifo = lookup ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> inode_socket = lookup ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> inode_symlink = lookup ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> inode_door = lookup ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> app_exe = lookup ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> _cache_uptodate = False <EOL> def _cache_database ( ) : <EOL> global exts , globs , literals , magic , _cache_uptodate <EOL> _cache_uptodate = True <EOL> exts = { } <EOL> globs = [ ] <EOL> literals = { } <EOL> magic = MagicDB ( ) <EOL> def _import_glob_file ( path ) : <EOL> """<STR_LIT>""" <EOL> for line in file ( path ) : <EOL> if line . startswith ( '<STR_LIT:#>' ) : continue <EOL> line = line [ : - <NUM_LIT:1> ] <EOL> type_name , pattern = line . split ( '<STR_LIT::>' , <NUM_LIT:1> ) <EOL> mtype = lookup ( type_name ) <EOL> if pattern . startswith ( '<STR_LIT>' ) : <EOL> rest = pattern [ <NUM_LIT:2> : ] <EOL> if not ( '<STR_LIT:*>' in rest or '<STR_LIT:[>' in rest or '<STR_LIT:?>' in rest ) : <EOL> exts [ rest ] = mtype <EOL> continue <EOL> if '<STR_LIT:*>' in pattern or '<STR_LIT:[>' in pattern or '<STR_LIT:?>' in pattern : <EOL> globs . append ( ( pattern , mtype ) ) <EOL> else : <EOL> literals [ pattern ] = mtype <EOL> for path in xdg . BaseDirectory . load_data_paths ( os . path . join ( '<STR_LIT>' , '<STR_LIT>' ) ) : <EOL> _import_glob_file ( path ) <EOL> for path in xdg . BaseDirectory . load_data_paths ( os . path . join ( '<STR_LIT>' , '<STR_LIT>' ) ) : <EOL> magic . mergeFile ( path ) <EOL> globs . sort ( lambda a , b : cmp ( len ( b [ <NUM_LIT:0> ] ) , len ( a [ <NUM_LIT:0> ] ) ) ) <EOL> def get_type_by_name ( path ) : <EOL> """<STR_LIT>""" <EOL> if not _cache_uptodate : <EOL> _cache_database ( ) <EOL> leaf = os . path . basename ( path ) <EOL> if leaf in literals : <EOL> return literals [ leaf ] <EOL> lleaf = leaf . lower ( ) <EOL> if lleaf in literals : <EOL> return literals [ lleaf ] <EOL> ext = leaf <EOL> while <NUM_LIT:1> : <EOL> p = ext . find ( '<STR_LIT:.>' ) <EOL> if p < <NUM_LIT:0> : break <EOL> ext = ext [ p + <NUM_LIT:1> : ] <EOL> if ext in exts : <EOL> return exts [ ext ] <EOL> ext = lleaf <EOL> while <NUM_LIT:1> : <EOL> p = ext . find ( '<STR_LIT:.>' ) <EOL> if p < <NUM_LIT:0> : break <EOL> ext = ext [ p + <NUM_LIT:1> : ] <EOL> if ext in exts : <EOL> return exts [ ext ] <EOL> for ( glob , mime_type ) in globs : <EOL> if fnmatch . fnmatch ( leaf , glob ) : <EOL> return mime_type <EOL> if fnmatch . fnmatch ( lleaf , glob ) : <EOL> return mime_type <EOL> return None <EOL> def get_type_by_contents ( path , max_pri = <NUM_LIT:100> , min_pri = <NUM_LIT:0> ) : <EOL> """<STR_LIT>""" <EOL> if not _cache_uptodate : <EOL> _cache_database ( ) <EOL> return magic . match ( path , max_pri , min_pri ) <EOL> def get_type_by_data ( data , max_pri = <NUM_LIT:100> , min_pri = <NUM_LIT:0> ) : <EOL> """<STR_LIT>""" <EOL> if not _cache_uptodate : <EOL> _cache_database ( ) <EOL> return magic . match_data ( data , max_pri , min_pri ) <EOL> def get_type ( path , follow = <NUM_LIT:1> , name_pri = <NUM_LIT:100> ) : <EOL> """<STR_LIT>""" <EOL> if not _cache_uptodate : <EOL> _cache_database ( ) <EOL> try : <EOL> if follow : <EOL> st = os . stat ( path ) <EOL> else : <EOL> st = os . lstat ( path ) <EOL> except : <EOL> t = get_type_by_name ( path ) <EOL> return t or text <EOL> if stat . S_ISREG ( st . st_mode ) : <EOL> t = get_type_by_contents ( path , min_pri = name_pri ) <EOL> if not t : t = get_type_by_name ( path ) <EOL> if not t : t = get_type_by_contents ( path , max_pri = name_pri ) <EOL> if t is None : <EOL> if stat . S_IMODE ( st . st_mode ) & <NUM_LIT:0> <NUM_LIT> : <EOL> return app_exe <EOL> else : <EOL> return text <EOL> return t <EOL> elif stat . S_ISDIR ( st . st_mode ) : return inode_dir <EOL> elif stat . S_ISCHR ( st . st_mode ) : return inode_char <EOL> elif stat . S_ISBLK ( st . st_mode ) : return inode_block <EOL> elif stat . S_ISFIFO ( st . st_mode ) : return inode_fifo <EOL> elif stat . S_ISLNK ( st . st_mode ) : return inode_symlink <EOL> elif stat . S_ISSOCK ( st . st_mode ) : return inode_socket <EOL> return inode_door <EOL> def install_mime_info ( application , package_file ) : <EOL> """<STR_LIT>""" <EOL> application += '<STR_LIT>' <EOL> new_data = file ( package_file ) . read ( ) <EOL> package_dir = os . path . join ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> resource = os . path . join ( package_dir , application ) <EOL> for x in xdg . BaseDirectory . load_data_paths ( resource ) : <EOL> try : <EOL> old_data = file ( x ) . read ( ) <EOL> except : <EOL> continue <EOL> if old_data == new_data : <EOL> return <EOL> global _cache_uptodate <EOL> _cache_uptodate = False <EOL> new_file = os . path . join ( xdg . BaseDirectory . save_data_path ( package_dir ) , application ) <EOL> file ( new_file , '<STR_LIT:w>' ) . write ( new_data ) <EOL> command = '<STR_LIT>' <EOL> if os . spawnlp ( os . P_WAIT , command , command , xdg . BaseDirectory . save_data_path ( '<STR_LIT>' ) ) : <EOL> os . unlink ( new_file ) <EOL> raise Exception ( "<STR_LIT>" "<STR_LIT>" "<STR_LIT>" ) % command </s>
