Show
Ignore:
Timestamp:
06/08/06 12:54:49 (7 years ago)
Author:
mk
Message:

Moved unzip_package and untar_package out of Cheesecake class to _util module.
Logfile is only left if package scoring failed.
Added doctest for isiterable().
Fixed download_pkg() check for HTTP 404 error.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/mk/cheesecake/cheesecake_index.py

    r43 r44  
    1919 
    2020import os, sys, re, shutil 
    21 import tarfile, zipfile 
    2221import tempfile 
    2322from optparse import OptionParser 
     
    2625from math import ceil 
    2726 
    28 from _util import run_cmd, pad_with_dots, pad_left_spaces, pad_msg, pad_line, command_successful 
     27from _util import pad_with_dots, pad_left_spaces, pad_msg, pad_line 
     28from _util import run_cmd, command_successful 
     29from _util import unzip_package, untar_package 
    2930from _util import StdoutRedirector 
    3031import logger 
     
    4344 
    4445def isiterable(obj): 
    45     return hasattr(obj, '__iter__') 
     46    """Check whether object is iterable. 
     47 
     48    >>> isiterable([1,2,3]) 
     49    True 
     50    >>> isiterable("string") 
     51    True 
     52    >>> isiterable(object) 
     53    False 
     54    """ 
     55    return hasattr(obj, '__iter__') or isinstance(obj, basestring) 
    4656 
    4757def has_extension(filename, ext): 
     
    571581 
    572582    def reset_rules(self, rules): 
    573         if isiterable(rules): 
     583        if isinstance(rules, basestring): 
     584            pass 
     585        elif isiterable(rules): 
    574586            for rule in rules: 
    575587                self.reset_rules(rule) 
     
    785797        self.quiet = quiet 
    786798 
    787         self.package_types = ["tar.gz", "tgz", "zip"] 
     799        self.package_types = { 
     800            "tar.gz": untar_package, 
     801            "tgz": untar_package, 
     802            "zip": unzip_package, 
     803        } 
     804 
    788805        self.sandbox_pkg_file = "" 
    789806        self.sandbox_pkg_dir = "" 
     
    810827        Don't use logging, since it can be called before logging has been setup. 
    811828        """ 
    812         self.cleanup() 
    813         os.unlink(os.path.join(self.sandbox, self.logfile)) 
     829        self.cleanup(remove_log_file=False) 
    814830 
    815831        msg += "\n" + pad_msg("CHEESECAKE INDEX", 0) 
     832        msg += "\nDetailed info available in log file %s" % self.logfile 
     833 
    816834        raise CheesecakeError(msg) 
    817   
    818     def cleanup(self): 
     835 
     836    def cleanup(self, remove_log_file=True): 
    819837        """Delete temporary directories and files that were created 
    820838        in the sandbox. At the end delete the sandbox itself. 
     
    831849 
    832850        delete_dir(self.sandbox) 
     851 
     852        if remove_log_file: 
     853            os.unlink(os.path.join(self.sandbox, self.logfile)) 
    833854 
    834855    def set_defaults(self): 
     
    873894        """Default settings for logging. 
    874895 
    875         If verbose, log goes to console, else it goes to logfile 
    876         log.debug goes to logfile 
    877         log.info goes to console 
    878         log.warn and log.error go to both logfile and stdout 
     896        If verbose, log goes to console, else it goes to logfile. 
     897        log.debug and log.info goes to logfile. 
     898        log.warn and log.error go to both logfile and stdout. 
    879899        """ 
    880900        if logfile: 
     
    891911        else: 
    892912            self.log = logger.MultipleProducer('cheesecake logfile') 
    893         if self.quiet: 
    894             self.log.info = logger.MultipleProducer('cheesecake logfile') 
    895         else: 
    896             self.log.info = logger.MultipleProducer('cheesecake console') 
     913 
     914        self.log.info = logger.MultipleProducer('cheesecake logfile') 
    897915        self.log.debug = logger.MultipleProducer('cheesecake logfile') 
    898916        self.log.warn = logger.MultipleProducer('cheesecake console') 
    899917        self.log.error = logger.MultipleProducer('cheesecake console') 
    900  
    901         self.log.debug("package = ", self.short_pkg_name) 
    902918 
    903919    def retrieve_pkg(self): 
     
    908924        else: 
    909925            self.copy_pkg() 
    910  
    911     def get_package_from_url(self): 
    912         """Use ``urlparse`` to obtain package path from URL. 
    913         """ 
    914         (scheme,location,path,param,query,fragment_id) = urlparse(self.url) 
    915         return self.get_package_from_path(path)         
    916  
    917     def get_package_from_path(self, path): 
    918         """Get package name as file portion of path. 
    919         """ 
    920         dir, file = os.path.split(path) 
    921         self.short_pkg_name = file 
    922         for package_type in self.package_types: 
    923             s = re.search("(.+)\.%s" % package_type, file) 
    924             if s: 
    925                 self.short_pkg_name = s.group(1) 
    926                 break 
    927         return file 
    928926 
    929927    def get_pkg_from_pypi(self): 
     
    10021000        #self.log("Downloaded package %s to %s" % (self.package, downloaded_filename)) 
    10031001 
    1004         if re.search("Content-Type: details/html", str(headers))
     1002        if headers.gettype() in ["text/html"]
    10051003            f = open(downloaded_filename) 
    10061004            if re.search("404 Not Found", "".join(f.readlines())): 
     
    10221020    def unpack_pkg(self): 
    10231021        """Unpack the package in the sandbox directory. 
    1024          
    1025         Currently supported archive types: 
    1026  
    1027         * .tar.gz (handled with ``tarfile`` module) 
    1028         * .zip (handled with ``zipfile`` module) 
     1022 
     1023        Check `package_types` attribute for list of currently supported 
     1024        archive types. 
    10291025 
    10301026        :Ivariables: 
     
    10331029        self.package_type = "" 
    10341030 
    1035         for type in self.package_types
     1031        for type in self.package_types.keys()
    10361032            s = re.search(r"(.+)\.%s" % type, self.package) 
    10371033            if s: 
     
    10511047            shutil.rmtree(self.sandbox_pkg_dir) 
    10521048 
    1053         if self.package_type in ["tar.gz", "tgz"]: 
    1054             self.untar_pkg() 
    1055         elif self.package_type == "zip": 
    1056             self.unzip_pkg() 
     1049        # Call appropriate function to unpack the package. 
     1050        unpack = self.package_types[self.package_type] 
     1051        self.unpack_dir = unpack(self.sandbox_pkg_file, self.sandbox) 
     1052 
     1053        if self.unpack_dir is None: 
     1054            self.raise_exception("Could not unpack package %s ... exiting" % \ 
     1055                                 self.sandbox_pkg_file) 
     1056 
     1057        self.unpacked = True 
    10571058 
    10581059        if self.unpack_dir != self.package_name: 
    10591060            self.original_package_name = self.package_name 
    10601061            self.package_name = self.unpack_dir 
    1061  
    1062         if not self.quiet: 
    1063             self.log.info("Detailed info available in log file %s" % self.logfile) 
    1064  
    1065     def untar_pkg(self): 
    1066         """Untar the package in the sandbox directory. 
    1067  
    1068         Uses tarfile module. 
    1069         """ 
    1070         try: 
    1071             t = tarfile.open(self.sandbox_pkg_file) 
    1072         except tarfile.ReadError, e: 
    1073             self.raise_exception("Could not read tar file %s ... exiting" % self.sandbox_pkg_file) 
    1074  
    1075         for member in t.getmembers(): 
    1076             t.extract(member, self.sandbox) 
    1077  
    1078         tarinfo = t.members[0] 
    1079         self.unpack_dir = tarinfo.name.split(os.sep)[0] 
    1080  
    1081         self.unpacked = True 
    1082              
    1083     def unzip_pkg(self): 
    1084         """Unzip the package in the sandbox directory. 
    1085  
    1086         Uses zipfile module. 
    1087         """ 
    1088         try: 
    1089             z = zipfile.ZipFile(self.sandbox_pkg_file) 
    1090         except zipfile.error: 
    1091             self.raise_exception("Error unzipping file %s ... exiting" % self.sandbox_pkg_file) 
    1092  
    1093         # Get directory structure from zip and create it in sandbox 
    1094         for name in z.namelist(): 
    1095             (dir, file) = os.path.split(name) 
    1096             unpack_dir = dir 
    1097             target_dir = os.path.join(self.sandbox, dir) 
    1098             if not os.path.exists(target_dir): 
    1099                 os.makedirs(target_dir) 
    1100  
    1101         # Extract files to directory structure 
    1102         for i, name in enumerate(z.namelist()): 
    1103             if not name.endswith('/'): 
    1104                 outfile = open(os.path.join(self.sandbox, name), 'wb') 
    1105                 outfile.write(z.read(name)) 
    1106                 outfile.flush() 
    1107                 outfile.close() 
    1108  
    1109         self.unpack_dir = unpack_dir.split(os.sep)[0] 
    1110  
    1111         self.unpacked = True 
    11121062 
    11131063    def walk_pkg(self): 
     
    12021152        return cheesecake_index 
    12031153 
     1154################################################################################ 
     1155## Command line. 
     1156################################################################################ 
    12041157 
    12051158def process_cmdline_args(): 
    1206     """ 
    1207     Parse command-line options 
     1159    """Parse command-line options. 
    12081160    """ 
    12091161    parser = OptionParser() 
     
    12331185 
    12341186def main(): 
    1235     """ 
    1236     Display Cheesecake index for package specified via command-line options 
     1187    """Display Cheesecake index for package specified via command-line options. 
    12371188    """ 
    12381189    options = process_cmdline_args()