#NEWLINE# def parseGlob( filename ) : #NEWLINE# #INDENT# "Parse a Gs filename or a filename pattern. Handle escape of '*' and '/'.\n\n  Args:\n    filename: a filename or filename pattern.\n      filename must be a valid gs filepath in the format of\n      '/gs/bucket/filename'. filename pattern has format '/gs/bucket/prefix*'.\n      filename pattern represents filenames with the given prefix in the bucket.\n      Please escape '*' and '' with '' if your filename contains them. We\n      recommend using Python raw string to simplify escape expressions.\n\n  Returns:\n    A (string, string) tuple if filename is a pattern. The first string is\n    the bucket name, second is the prefix or '' if prefix doesn't exist.\n    Properly escaped filename if filename is not a pattern.\n\n    example\n      '/gs/bucket1/file1' => '/gs/bucket1/file1'\n      '/gs/bucket2/*' => ('gs/bucket2', '') all files under bucket2\n      '/gs/bucket3/p*' => ('gs/bucket2', 'p') files under bucket3 with\n          a prefix 'p' in its name\n      r'/gs/bucket/file\\*' => '/gs/bucket/file*'\n      r'/gs/bucket/file\\*' => ('/gs/bucket', r'file') all files under bucket\n          with prefix r'file'\n      r'/gs/bucket/file\\\\*' => '/gs/bucket/file\\*'\n      r'/gs/bucket/file\\**' => ('/gs/bucket', 'file*') all files under bucket\n          with prefix 'file*'\n\n  Raises:\n    google.appengine.api.files.InvalidFileNameError if filename is illegal.\n  " #NEWLINE# if ( not filename ) : #NEWLINE# #INDENT# raise files . InvalidFileNameError ( 'filename is None.' ) #NEWLINE# #UNINDENT# if ( not isinstance ( filename , basestring ) ) : #NEWLINE# #INDENT# raise files . InvalidFileNameError ( ( 'filename %s should be of type string' % filename ) ) #NEWLINE# #UNINDENT# match = _GS_FILEPATH_REGEX . match ( filename ) #NEWLINE# if ( not match ) : #NEWLINE# #INDENT# raise files . InvalidFileNameError ( 'filename %s should start with/gs/bucketname' , filename ) #NEWLINE# #UNINDENT# bucketname = match . group ( 0 ) #NEWLINE# rest = filename [ len ( bucketname ) : ] #NEWLINE# if ( ( not rest ) or ( ( len ( rest ) == 1 ) and ( rest [ 0 ] == '/' ) ) ) : #NEWLINE# #INDENT# return ( bucketname , '' ) #NEWLINE# #UNINDENT# if ( not rest . startswith ( '/' ) ) : #NEWLINE# #INDENT# raise files . InvalidFileNameError ( ( 'Expect / to separate bucketname and filename in %s' % filename ) ) #NEWLINE# #UNINDENT# i = 1 #NEWLINE# prefix = False #NEWLINE# processed = '' #NEWLINE# while ( i < len ( rest ) ) : #NEWLINE# #INDENT# char = rest [ i ] #NEWLINE# if ( char == '\\' ) : #NEWLINE# #INDENT# if ( ( i + 1 ) == len ( rest ) ) : #NEWLINE# #INDENT# processed += char #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# processed += rest [ ( i + 1 ) ] #NEWLINE# i += 1 #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( char == '*' ) : #NEWLINE# #INDENT# if ( ( i + 1 ) != len ( rest ) ) : #NEWLINE# #INDENT# raise files . InvalidFileNameError ( '* as a wildcard is not the last.' ) #NEWLINE# #UNINDENT# prefix = True #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# processed += char #NEWLINE# #UNINDENT# #UNINDENT# i += 1 #NEWLINE# #UNINDENT# if prefix : #NEWLINE# #INDENT# return ( bucketname , processed ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# return ( ( bucketname + '/' ) + processed )