From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from pigeon.gentoo.org ([208.92.234.80] helo=lists.gentoo.org) by finch.gentoo.org with esmtp (Exim 4.60) (envelope-from ) id 1SZlTK-0005lD-P2 for garchives@archives.gentoo.org; Wed, 30 May 2012 16:10:07 +0000 Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id CDA44E07A4; Wed, 30 May 2012 16:09:59 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) by pigeon.gentoo.org (Postfix) with ESMTP id 8C7F9E07A4 for ; Wed, 30 May 2012 16:09:59 +0000 (UTC) Received: from hornbill.gentoo.org (hornbill.gentoo.org [94.100.119.163]) (using TLSv1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id B76671B4025 for ; Wed, 30 May 2012 16:09:58 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by hornbill.gentoo.org (Postfix) with ESMTP id 6C9ABE543A for ; Wed, 30 May 2012 16:09:56 +0000 (UTC) From: "André Erdmann" To: gentoo-commits@lists.gentoo.org Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "André Erdmann" Message-ID: <1338394110.0ab8e34e33388ff12025c4a05969a891a9dcb8c4.dywi@gentoo> Subject: [gentoo-commits] proj/R_overlay:master commit in: roverlay/ X-VCS-Repository: proj/R_overlay X-VCS-Files: roverlay/fileio.py X-VCS-Directories: roverlay/ X-VCS-Committer: dywi X-VCS-Committer-Name: André Erdmann X-VCS-Revision: 0ab8e34e33388ff12025c4a05969a891a9dcb8c4 X-VCS-Branch: master Date: Wed, 30 May 2012 16:09:56 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: quoted-printable X-Archives-Salt: 5edb46df-811a-4c43-a95e-c4bd0d3cda6f X-Archives-Hash: 7c6ba9ebc057c9e3c03abb502298c245 commit: 0ab8e34e33388ff12025c4a05969a891a9dcb8c4 Author: Andre Erdmann mailerd de> AuthorDate: Wed May 30 16:08:30 2012 +0000 Commit: Andr=C3=A9 Erdmann mailerd de> CommitDate: Wed May 30 16:08:30 2012 +0000 URL: http://git.overlays.gentoo.org/gitweb/?p=3Dproj/R_overlay.git= ;a=3Dcommit;h=3D0ab8e34e roverlay, fileio: refactored and @classmethod decorators removed --- roverlay/fileio.py | 457 +++++++++++++++++++++++++---------------------= ------ 1 files changed, 223 insertions(+), 234 deletions(-) diff --git a/roverlay/fileio.py b/roverlay/fileio.py index 295d904..7c89356 100644 --- a/roverlay/fileio.py +++ b/roverlay/fileio.py @@ -15,217 +15,13 @@ from roverlay import tmpconst as const class DescriptionReader: """Description Reader""" =20 - @classmethod def __init__ ( self ): """Initializes a DESCRIPTION file reader.""" pass =20 - @classmethod - def _get_fields_with_flag ( self, flag, foce_update=3DFalse ): + # --- end of __init__ (...) --- =20 - matching_fields =3D [] =20 - field =3D None - for field in const.DESCRIPTION_FIELD_MAP.keys(): - if flag is None: - matching_fields.append ( field ) - - elif 'flags' in const.DESCRIPTION_FIELD_MAP [field]: - if flag in const.DESCRIPTION_FIELD_MAP [field] ['flags']: - matching_fields.append ( field ) - - del field - return matching_fields - - - @classmethod - def _find_field ( self , field_identifier ): - """Determines the real name of a field. - - arguments: - * field_identifier -- name of the field as it appears in the DESCRIPTI= ON file - - At first, it is checked whether field_identifier matches the name of - a field listed in DESCRIPTION_FIELD_MAP (any match results in immediat= e return). - Then, a new iteration over the field map compares field_identifier - with all aliases until the first case-(in)sensitive match (-> immediat= e return). - None will be returned if none of the above searches succeed. - - In other words: this method decides whether a field_identifier will be= used and if so, - with which name. - """ - - # save some time by prevent searching if field_id is empty - if not field_identifier: - return None - - # search for real field names first - for field in const.DESCRIPTION_FIELD_MAP.keys(): - if field_identifier =3D=3D field: - return field - - field_id_lower =3D field_identifier.lower() - - for field in const.DESCRIPTION_FIELD_MAP.keys(): - - # does extra information (-> alias(es)) for this field exist? - if 'alias' in const.DESCRIPTION_FIELD_MAP [field]: - - if 'withcase' in const.DESCRIPTION_FIELD_MAP [field] ['alias']: - for alias in const.DESCRIPTION_FIELD_MAP [field] ['alias'] ['withca= se']: - if field_identifier =3D=3D alias: - return field - - if 'nocase' in const.DESCRIPTION_FIELD_MAP [field] ['alias']: - for alias in const.DESCRIPTION_FIELD_MAP [field] ['alias'] ['nocase= ']: - if field_id_lower =3D=3D alias.lower(): - return field - - #if 'other_alias_type' in const.DESCRIPTION_FIELD_MAP [field] ['alia= s']: - - # returning None if no valid field identifier matches - return None - - @classmethod - def _make_values ( self, value_str, field_context=3DNone ): - """Extracts relevant data from value_str and returns them as list. - - arguments: - * value_str -- string that represents the (just read) values - * field_context -- field name the value belongs to; optional, defaults= to None - - It's useful to set field_context 'cause several fields ('Depends') hav= e - multiple values arranged in a list (dep0, dep1 [, depK]*). - """ - - svalue_str =3D value_str.strip() - - if not svalue_str: - # empty value(s) - return [] - - elif field_context is None: - # default return if no context given - return [ svalue_str ] - - elif self._check_fieldflag ( field_context ): - # value str is not empty and have flags for field_context, check thes= e - - if self._check_fieldflag ( field_context, 'isList' ): - # split up this list (that is separated by commata and/or semicolon= s) - return re.split (const.DESCRIPTION_LIST_SPLIT_REGEX, svalue_str, 0) - - elif self._check_fieldflag ( field_context, 'isWhitespaceList' ): - # split up this list (that is separated whitespace) - return re.split ( '\s+', svalue_str, 0 ) - - - # default return - return [ svalue_str ] - - @classmethod - def _check_fieldflag ( self, field, flag_to_check=3DNone ): - """Checks if the given field has the specified flag and returns a bool= . - - arguments: - * field -- name of the field that should be checked - * flag_to_check -- name of the flag to check; optional, defaults to No= ne - - This method acts as 'field has any flags?' if flag_to_check is None (i= ts default value). - """ - - if field in const.DESCRIPTION_FIELD_MAP: - if 'flags' in const.DESCRIPTION_FIELD_MAP [field]: - if flag_to_check in const.DESCRIPTION_FIELD_MAP [field] ['flags']: - return True - elif flag_to_check is None: - # 'flags' exist, return true - return True - - return False - - @staticmethod - def _get_desc_from_file ( filepath, pkg_name=3D'.' ): - """Reads a file returns the description data. - - arguments: - * filepath -- file to read (str; path to tarball or file) - * pkg_name -- name of the package, in tarballs the description file - is located in / and thus this argument is requ= ired. - Defaults to '.', set to None to disable. - - All exceptions are passed to the caller (TarError, IOErr, ). - can either be a tarball in which case the real DESCRIPTION - file is read (/DESCRIPTION) or a normal file. - """ - - logging.write ( "Starting to read file '" + str ( filepath ) + "' ...\= n" ) - - if not ( isinstance ( filepath, str ) and filepath ): - raise Exception ( "bad usage" ) - - # read describes how to import the lines from a file (e.g. rstrip()) - # fh, th are file/tar handles - read =3D th =3D fh =3D None - - if tarfile.is_tarfile ( filepath ): - # filepath is a tarball, open tar handle + file handle - th =3D tarfile.open ( filepath, 'r' ) - if pkg_name: - fh =3D th.extractfile ( os.path.join ( pkg_name, const.DESCRIPTION_F= ILE_NAME ) ) - else: - fh =3D th.extractfile ( const.DESCRIPTION_FILE_NAME ) - - # have to decode the lines - read =3D lambda lines : [ line.decode().rstrip() for line in lines ] - else: - # open file handle only - fh =3D open ( filepath, 'r' ) - read =3D lambda lines : [ line.rstrip() for line in lines ] - - x =3D None - read_lines =3D read ( fh.readlines() ) - del x, read - - fh.close() - if not th is None: th.close() - del fh, th - - return read_lines - - @staticmethod - def _get_fileinfo ( filepath ): - """Returns some info about the given filepath as dict whose contents a= re - the file path, the file name ([as package_file with suffix and] - as filename with tarball suffix removed), the package name - and the package_version. - - arguments: - * filepath -- - """ - - package_file =3D os.path.basename ( filepath ) - - filename =3D re.sub ( const.RPACKAGE_SUFFIX_REGEX + '$', '', package_f= ile ) - - # todo move that separator to const - package_name, sepa, package_version =3D filename.partition ( '_' ) - - if not sepa: - # file name unexpected, tarball extraction will (probably) fail - #raise Exception ("file name unexpected") - logging.write ( "unexpected file name '" + filename + "'.\n" ) - - return dict ( - filepath =3D filepath, - filename =3D filename, - package_file =3D package_file, - package_name =3D package_name, - #package_origin =3D ?, - package_version =3D package_version, - ) - - @classmethod def _parse_read_data ( self, read_data ): """Verifies and parses/fixes read data. =20 @@ -233,16 +29,25 @@ class DescriptionReader: * read_data -- data from file, will be modified """ =20 - def stats ( data ): - """Temporary function that prints some info about the given data.""" + def get_fields_with_flag ( flag, foce_update=3DFalse ): + + matching_fields =3D [] + field =3D None - logging.write ( "=3D=3D=3D this is the list of read data =3D=3D=3D\n"= ) - for field in read_data.keys(): - logging.write ( field + " =3D " + str ( read_data [field] ) + "\n" ) - logging.write ( "=3D=3D=3D end of list =3D=3D=3D\n" ) + for field in const.DESCRIPTION_FIELD_MAP.keys(): + if flag is None: + matching_fields.append ( field ) + + elif 'flags' in const.DESCRIPTION_FIELD_MAP [field]: + if flag in const.DESCRIPTION_FIELD_MAP [field] ['flags']: + matching_fields.append ( field ) + del field + return matching_fields =20 - def _value_in_strlist ( _val, _list, case_insensitive=3DTrue ): + # --- end of get_fields_with_flag (...) --- + + def value_in_strlist ( _val, _list, case_insensitive=3DTrue ): """Returns true if value is in the given list.""" el =3D None if case_insensitive: @@ -258,9 +63,7 @@ class DescriptionReader: =20 del el return False - - - stats ( read_data ) + # --- end of value_in_strlist (...) --- =20 field =3D None =20 @@ -270,14 +73,14 @@ class DescriptionReader: read_data [field] =3D const.DESCRIPTION_FIELD_MAP [field] ['default_= value'] =20 # join values to a single string - for field in self._get_fields_with_flag ( 'joinValues' ): + for field in get_fields_with_flag ( 'joinValues' ): if field in read_data.keys(): read_data [field] =3D ' ' . join ( read_data [field] ) =20 # ensure that all mandatory fields are set missing_fields =3D list() =20 - for field in self._get_fields_with_flag ( 'mandatory' ): + for field in get_fields_with_flag ( 'mandatory' ): if field in read_data: if not len (read_data [field]): missing_fields.append ( field ) @@ -294,15 +97,10 @@ class DescriptionReader: # skip _fileinfo if field !=3D '_fileinfo': if 'allowed_values' in const.DESCRIPTION_FIELD_MAP [field]: - if not _value_in_strlist ( read_data [field], + if not value_in_strlist ( read_data [field], const.DESCRIPTION_FIELD_MAP [field] ['allowed_values'] ): unsuitable_fields.append ( field ) =20 - - stats ( read_data ) - - - valid =3D True =20 if len ( missing_fields ): @@ -328,8 +126,8 @@ class DescriptionReader: del field =20 return valid + # --- end of _parse_read_data (...) --- =20 - @classmethod def readfile ( self, filepath ): """Reads a DESCRIPTION file and returns the read data if successful, e= lse None. =20 @@ -347,15 +145,205 @@ class DescriptionReader: e.g. if OS_TYPE is not unix). """ =20 - read_data =3D dict () - fileinfo =3D DescriptionReader._get_fileinfo ( filepath ) + def get_fileinfo ( filepath ): + """Returns some info about the given filepath as dict whose contents = are + the file path, the file name ([as package_file with suffix and] + as filename with tarball suffix removed), the package name + and the package_version. =20 + arguments: + * filepath -- + """ =20 - try: - desc_lines =3D DescriptionReader._get_desc_from_file ( - filepath, fileinfo ['package_name'] + package_file =3D os.path.basename ( filepath ) + + filename =3D re.sub ( const.RPACKAGE_SUFFIX_REGEX + '$', '', package_= file ) + + # todo move that separator to const + package_name, sepa, package_version =3D filename.partition ( '_' ) + + if not sepa: + # file name unexpected, tarball extraction will (probably) fail + #raise Exception ("file name unexpected") + logging.write ( "unexpected file name '" + filename + "'.\n" ) + + return dict ( + filepath =3D filepath, + filename =3D filename, + package_file =3D package_file, + package_name =3D package_name, + #package_origin =3D ?, + package_version =3D package_version, ) =20 + # --- end of get_fileinfo (...) --- + + + def make_values ( value_str, field_context=3DNone ): + """Extracts relevant data from value_str and returns them as list. + + arguments: + * value_str -- string that represents the (just read) values + * field_context -- field name the value belongs to; optional, default= s to None + + It's useful to set field_context 'cause several fields ('Depends') ha= ve + multiple values arranged in a list (dep0, dep1 [, depK]*). + """ + + def check_fieldflag ( field, flag_to_check=3DNone ): + """Checks if the given field has the specified flag and returns a bo= ol. + + arguments: + * field -- name of the field that should be checked + * flag_to_check -- name of the flag to check; optional, defaults to = None + + This method acts as 'field has any flags?' if flag_to_check is None = (its default value). + """ + + if field in const.DESCRIPTION_FIELD_MAP: + if 'flags' in const.DESCRIPTION_FIELD_MAP [field]: + if flag_to_check in const.DESCRIPTION_FIELD_MAP [field] ['flags']: + return True + elif flag_to_check is None: + # 'flags' exist, return true + return True + + return False + # --- end of check_fieldflag (...) --- + + svalue_str =3D value_str.strip() + + if not svalue_str: + # empty value(s) + return [] + + elif field_context is None: + # default return if no context given + return [ svalue_str ] + + elif check_fieldflag ( field_context ): + # value str is not empty and have flags for field_context, check the= se + + if check_fieldflag ( field_context, 'isList' ): + # split up this list (that is separated by commata and/or semicolo= ns) + return re.split (const.DESCRIPTION_LIST_SPLIT_REGEX, svalue_str, 0= ) + + elif check_fieldflag ( field_context, 'isWhitespaceList' ): + # split up this list (that is separated whitespace) + return re.split ( '\s+', svalue_str, 0 ) + + + # default return + return [ svalue_str ] + + # --- end of make_values (...) --- + + def get_desc_from_file ( filepath, pkg_name=3D'.' ): + """Reads a file returns the description data. + + arguments: + * filepath -- file to read (str; path to tarball or file) + * pkg_name -- name of the package, in tarballs the description file + is located in / and thus this argument is required. + Defaults to '.', set to None to disable. + + All exceptions are passed to the caller (TarError, IOErr, ). + can either be a tarball in which case the real DESCRIPTION + file is read (/DESCRIPTION) or a normal file. + """ + + logging.write ( "Starting to read file '" + str ( filepath ) + "' ...= \n" ) + + if not ( isinstance ( filepath, str ) and filepath ): + raise Exception ( "bad usage" ) + + # read describes how to import the lines from a file (e.g. rstrip()) + # fh, th are file/tar handles + read =3D th =3D fh =3D None + + if tarfile.is_tarfile ( filepath ): + # filepath is a tarball, open tar handle + file handle + th =3D tarfile.open ( filepath, 'r' ) + if pkg_name: + fh =3D th.extractfile ( os.path.join ( pkg_name, const.DESCRIPTION_= FILE_NAME ) ) + else: + fh =3D th.extractfile ( const.DESCRIPTION_FILE_NAME ) + + # have to decode the lines + read =3D lambda lines : [ line.decode().rstrip() for line in lines ] + else: + # open file handle only + fh =3D open ( filepath, 'r' ) + read =3D lambda lines : [ line.rstrip() for line in lines ] + + x =3D None + read_lines =3D read ( fh.readlines() ) + del x, read + + fh.close() + if not th is None: th.close() + del fh, th + + return read_lines + + # --- end of get_desc_from_file (...) --- + + def find_field ( field_identifier ): + """Determines the real name of a field. + + arguments: + * field_identifier -- name of the field as it appears in the DESCRIPT= ION file + + At first, it is checked whether field_identifier matches the name of + a field listed in DESCRIPTION_FIELD_MAP (any match results in immedia= te return). + Then, a new iteration over the field map compares field_identifier + with all aliases until the first case-(in)sensitive match (-> immedia= te return). + None will be returned if none of the above searches succeed. + + In other words: this method decides whether a field_identifier will b= e used and if so, + with which name. + """ + + # save some time by prevent searching if field_id is empty + if not field_identifier: + return None + + # search for real field names first + for field in const.DESCRIPTION_FIELD_MAP.keys(): + if field_identifier =3D=3D field: + return field + + field_id_lower =3D field_identifier.lower() + + for field in const.DESCRIPTION_FIELD_MAP.keys(): + + # does extra information (-> alias(es)) for this field exist? + if 'alias' in const.DESCRIPTION_FIELD_MAP [field]: + + if 'withcase' in const.DESCRIPTION_FIELD_MAP [field] ['alias']: + for alias in const.DESCRIPTION_FIELD_MAP [field] ['alias'] ['withc= ase']: + if field_identifier =3D=3D alias: + return field + + if 'nocase' in const.DESCRIPTION_FIELD_MAP [field] ['alias']: + for alias in const.DESCRIPTION_FIELD_MAP [field] ['alias'] ['nocas= e']: + if field_id_lower =3D=3D alias.lower(): + return field + + #if 'other_alias_type' in const.DESCRIPTION_FIELD_MAP [field] ['ali= as']: + + # returning None if no valid field identifier matches + return None + + # --- end of find_field (...) --- + + + read_data =3D dict () + fileinfo =3D get_fileinfo ( filepath ) + + + try: + desc_lines =3D get_desc_from_file ( filepath, fileinfo ['package_name= '] ) =20 except IOError as err: # @@ -378,7 +366,7 @@ class DescriptionReader: if field_context: # context is set =3D> append values =20 - for val in self._make_values ( sline, field_context ): + for val in make_values ( sline, field_context ): read_data [field_context] . append ( val ) else: # no valid context =3D> ignore line @@ -392,7 +380,7 @@ class DescriptionReader: =20 if line_components [1]: # line contains a field separator, set field context - field_context =3D self._find_field ( line_components [0] ) + field_context =3D find_field ( line_components [0] ) =20 if field_context: # create a new empty list for field_context @@ -400,7 +388,7 @@ class DescriptionReader: =20 # add values to read_data # no need to check line_components [2] 'cause [1] was a true str - for val in self._make_values ( line_components [2], field_context = ): + for val in make_values ( line_components [2], field_context ): read_data [field_context] . append ( val ) =20 else: @@ -424,8 +412,8 @@ class DescriptionReader: =20 =20 if self._parse_read_data ( read_data ): - logging.write ( '## success ##\n' ) - logging.write ( ( str ( read_data ) ) ) + #logging.write ( '## success ##\n' ) + #logging.write ( ( str ( read_data ) ) ) return dict ( fileinfo =3D fileinfo, description_data =3D read_data @@ -434,3 +422,4 @@ class DescriptionReader: logging.write ( '## fail ##\n' ) return None =20 + # --- end of readfile (...) ---