home *** CD-ROM | disk | FTP | other *** search
- # Copyright 2001 (C) ActiveState Tool Corp., All Rights Reserved.
- #
- import os,sys,string,whrandom
- import xml.dom.minidom
-
- from types import *
- # imports the trace object, the formatter object
- # and bunch of exceptions
- from ppmerrors import *
-
- whrandom.seed()
-
- def get_softpack_node(NodeList):
- for node in NodeList:
- if node.nodeType == node.ELEMENT_NODE and node.tagName == "INSTPPD":
- subnode = node
- for node in subnode.childNodes:
- if node.nodeType == node.ELEMENT_NODE and node.tagName == "SOFTPKG":
- return node
- raise NodeNotFound
-
- def get_package_name(softpkgnode):
- try:
- return str(softpkgnode.getAttribute('NAME'))
- except KeyError, e:
- ppmerrors.Error("Can not find the name of the package!: %s" % e)
- return ''
-
- def get_package_version(softpkgnode):
- try:
- return string.replace(softpkgnode.getAttribute('VERSION'),',','.')
- except KeyError, e:
- ppmerrors.Error("Can not find the version of the package: %s " % e)
- return ''
-
- def get_node_attr(node,attrname):
- try:
- return str(node.getAttribute(string.upper(attrname)))
- except KeyError, e:
- #caused a lot of useless messages. So, it is disabled for now
- #errorreporter.Warn( "Can not find the specified attribute: %s " % e)
- pass
- return None
-
- def get_package_cdata(softpkgnode, nodename):
- for node in softpkgnode.childNodes:
- if node.nodeType == node.ELEMENT_NODE and node.tagName == string.upper(nodename):
- return get_text(node.childNodes)
- return ""
-
- def get_package_codebase(softpkgnode):
- myhash = {}
- for node in softpkgnode.childNodes:
- if node.nodeType == node.ELEMENT_NODE and node.tagName == 'CODEBASE':
- myhash['href'] = get_node_attr(node,'href')
- myhash['filename'] = get_node_attr(node,'filename')
- return myhash
- return myhash
-
- def get_package_dependency(element):
- myhash = {}
- for node in element.childNodes:
- if node.nodeType == node.ELEMENT_NODE and node.tagName == 'DEPENDENCY':
- key = get_node_attr(node,'name')
- value = get_node_attr(node,'version')
- if key and value:
- myhash[key] = value
- return myhash
-
- def get_text(NodeList):
- """get all the text nodes values in an element and
- return the concatonated text values"""
- rc = ""
- for node in NodeList:
- if node.nodeType == node.TEXT_NODE:
- rc += node.data
- return str(rc)
-
- def get_array(NodeList):
- rc = []
- for node in NodeList:
- if node.nodeType == node.TEXT_NODE:
- if string.find(node.data , ';'):
- rc += string.split(node.data , ';')
- return rc
-
- def parse_location(location):
- import urlparse
- parsed_loco = urlparse.urlparse(location)
- namespace = str(parsed_loco[4])
- location = urlparse.urlunparse(parsed_loco[0:3]+('','',''))
- return (location , namespace)
-
- def get_ppmconfig_filename():
- try:
- fname = os.environ['PYPPM_DAT']
- if os.path.isfile(fname) and not os.path.isdir(fname):
- return fname
- else:
- raise KeyError
- except KeyError:
- pass
- fname = os.path.join(sys.exec_prefix,'lib','pyppm.xml')
- if os.path.isfile(fname):
- return fname
- fname = os.path.join(os.curdir,'pyppm.xml')
- if os.path.isfile(fname):
- return fname
- raise BadConfigFile("No config file. Try 'genconfig' command.")
-
- def get_bool_values(AttrValue):
- try:
- return int(str(AttrValue))
- except ValueError:
- return 0
-
- def get_str_values(AttrValue):
- return str(AttrValue)
-
- class Repository:
- def __init__(self,name,namespace,uri,username,passwd):
- self.name = name
- self.namespace = namespace
- self.uri = uri
- self.username = username
- self.passwd = passwd
- def __repr__(self):
- return self.uri
- __str__ = __repr__
-
- class BasicImplementation:
- def __init__(self,ImpElement):
- """This class encapsulates the information of the implementation section(of a PPD) of
- the packages which are already installed."""
- self._node = ImpElement
- self.dependencies = get_package_dependency(self._node)
- # this is a hash with 'href' or 'filename'
- self.codebase = get_package_codebase(self._node)
- # if the following is specified, Distutils setup.py is not going to
- # be used and instead it uses the followings
- self.installer = get_package_cdata(self._node , 'install')
- if self.installer == '':
- try: self.installer = get_node_attr(self._node.getElementsByTagName("INSTALL")[0] , 'EXEC')
- except IndexError: self.installer = ''
-
- class Implementation(BasicImplementation):
-
- def __init__(self,node):
- """This class encapsulates the information of the implementation section(of a PPD) of
- a python package"""
- BasicImplementation.__init__(self,node)
- self._node = node
- try:
- self.python_version = get_package_version(self._node.getElementsByTagName("PYTHONCORE")[0])
- except Exception, e:
- self.python_version = None
- errorreporter.LowError("'PYTHONCORE' tag can not be found: %s" % e)
- self.oss = map((lambda x: get_node_attr(x,'value')) ,
- self._node.getElementsByTagName("OS"))
- # this is out dated tag attribute but it is still supported
- if None in self.oss:
- self.oss = map((lambda x: get_node_attr(x,'name')) ,
- self._node.getElementsByTagName("OS"))
- if len(self.oss)==1:
- try:
- self.osversion = get_node_attr(self._node.getElementsByTagName("OSVERSION")[0],'version')
- except IndexError:
- self.osversion = 0
- self.processors = map((lambda x: get_node_attr(x,'value')) ,
- self._node.getElementsByTagName("PROCESSOR"))
- self.architectures = map((lambda x: get_node_attr(x,'value')) ,
- self._node.getElementsByTagName("ARCHITECTURE"))
-
- def __repr__(self):
- return 'Implementaion Object -> codebase: '+str(self.codebase)
- __str__ = __repr__
-
- class Package:
-
- def __init__(self,softpack):
- """Package definition as conformed with PPD.DTD.
- This function takes a softpack dom element."""
- self._node = softpack
- self.ppd = self._node.toxml()
- self.name = get_package_name(self._node)
- self.version = get_package_version (self._node)
- self.title = get_package_cdata(self._node , 'title')
- self.abstract = get_package_cdata(self._node , 'abstract')
- self.implementations = map((lambda x: Implementation(x)) , self._node.getElementsByTagName("IMPLEMENTATION"))
-
- def __repr__(self):
- return errorreporter.formatter.formatPackage(self)
- __str__ = __repr__
-
-
- class InstalledPackage(Package):
-
- def __init__(self,instpack):
- """Installed packages as conformed with PPM Configuration DTD.
- This function takes an installed package (with <PACKAGE> tag)
- dom element in."""
- Package.__init__(self,get_softpack_node(instpack.childNodes))
- self._node = instpack
- self.primname = get_node_attr(self._node , 'name')
- self.author = get_text(self._node.getElementsByTagName('AUTHOR')[0].childNodes)
- self.location = get_text(self._node.getElementsByTagName('LOCATION')[0].childNodes)
- self.instpacklist = get_text(self._node.getElementsByTagName('INSTPACKLIST')[0].childNodes)
- self.instroot = get_text(self._node.getElementsByTagName('INSTROOT')[0].childNodes)
- self.instdate = get_text(self._node.getElementsByTagName('INSTDATE')[0].childNodes)
-
- class PPMConfig:
-
- def __init__(self, config_file_name=None):
- if config_file_name:
- self.config_file_name = config_file_name
- else:
- self.config_file_name = get_ppmconfig_filename()
- #configuration file is another XML file
- #so, we parse it like another PPD file.
- try:
- self.config_file = open(self.config_file_name , 'r+')
- except Exception, e:
- raise BadConfigFile('-- Config file not found, or you do not have write permission.')
- self._locations =[]
- self.required_packages = []
- self._have_run = {}
- self.options = {}
- self.dom = xml.dom.minidom.parse(self.config_file)
- try:
- self.ppmconfignode = self.dom.getElementsByTagName('PPMCONFIG')[0]
- except IndexError:
- raise BadConfgFile('No PPMCONFIG tag')
- self.get_version()
- try:
- self.get_options()
- except IndexError:
- raise BadConfigFile(' No OPTIONS tag.')
- # tracer object is imported from the 'ppmerrors.py' module
- # XXX
- # XXXX
-
- # XXX
- # XXX
- # XXX
- # XXX
- tracefile = self.options['tracefile']
- errorreporter.tracer.SetLogName(tracefile)
- errorreporter.tracer.tl = int(self.options['trace'])
- if using_gui():
- errorreporter.tracer.displayer = Win32ErrorDisplay()
- errorreporter.tracer.verbose = 0
- sys.stderr=sys.stdout=open(tracefile,"a")
- else:
- errorreporter.tracer.displayer = StderrErrorDisplay()
-
- try:
- errorreporter.tracer.verbose = int(self.options['verbose'])
- except (AttributeError, ValueError):
- errorreporter.tracer.verbose = 1
-
- def refresh(self):
- """writes the dom to the configfile"""
- self.config_file.close()
- self.config_file = open(self.config_file_name, 'w')
- self.config_file.write(self.dom.toxml())
- self.config_file.flush()
-
- def get_version(self):
- try:
- self._have_run['version']
- return self.version
- except KeyError:
- self.version = get_text(self.dom.getElementsByTagName("PPMVER")[0].childNodes)
- self.version = string.replace(self.version,',','.')
- if len(self.version)>=5: self.version = self.version[0:5]
- self._have_run['version']=1
- return self.version
-
- def get_repository_info(self):
- try:
- self._have_run['repository_info']
- return self._locations
- except KeyError:
- for node in self.dom.getElementsByTagName("REPOSITORY"):
- name = node.getAttribute('NAME')
- loco = node.getAttribute('LOCATION')
- uri , namespace = parse_location(loco)
- try:
- username = node.getAttribute('USERNAME')
- except AttributeError:
- username = ''
- try:
- password = node.getAttribute('PASSWORD')
- except AttributeError:
- password = ''
- repository = Repository(name,namespace,uri,username,password)
- self._locations.append(repository)
- self._have_run['repository_info'] = 1
- return self._locations
-
- def get_required_packages(self):
- try:
- self._have_run['reqpackages']
- return self.required_packages
- except KeyError:
- self.required_packages = get_array(self.dom.getElementsByTagName("PPMPRECIOUS")[0].childNodes)
- self._have_run['reqpackages']=1
- return self.required_packages
-
- def get_platform_info(self):
- try:
- self._have_run['platform_info']
- return [self.cpu , self.os_value , self.os_version , self.lang]
- except KeyError:
- PlatNode = self.dom.getElementsByTagName("PLATFORM")[0]
- self.cpu = get_str_values(PlatNode.getAttribute('CPU') )
- self.os_value = get_str_values(PlatNode.getAttribute('OSVALUE'))
- self.os_version = get_bool_values(PlatNode.getAttribute('OSVERSION'))
- self.lang = get_str_values(PlatNode.getAttribute('LANGUAGE'))
- self._have_run['platform_info'] = 1
- return [self.cpu , self.os_value , self.os_version , self.lang]
-
- def get_options(self):
- try:
- self._have_run['options']
- return self.options
- except KeyError:
- OptionNode = self.dom.getElementsByTagName("OPTIONS")[0]
- self.options['clean'] = get_bool_values(OptionNode.getAttribute('CLEAN'))
- self.options['ignorecase'] = get_bool_values(OptionNode.getAttribute('IGNORECASE'))
- self.options['confirm'] = get_bool_values(OptionNode.getAttribute('CONFIRM'))
- self.options['forceinstall'] = get_bool_values(OptionNode.getAttribute('FORCEINSTALL'))
- self.options['verbose'] = get_bool_values(OptionNode.getAttribute('VERBOSE'))
-
- self.options['downloadstatus'] = get_bool_values(OptionNode.getAttribute('DOWNLOADSTATUS'))
- self.options['trace'] = get_bool_values(OptionNode.getAttribute('TRACE'))
-
- self.builddir = get_str_values(OptionNode.getAttribute('BUILDDIR'))
-
- if not self.builddir:
- self.builddir = os.path.join(sys.exec_prefix,'Downloads')
- self.options['root'] = get_str_values(OptionNode.getAttribute('ROOT'))
- self.options['tracefile'] = str(OptionNode.getAttribute('TRACEFILE'))
- if not self.options['tracefile']:
- default = os.path.join(sys.exec_prefix,'PPM.LOG')
- self.options['tracefile'] = default
- self._have_run['options'] = 1
- return self.options
-
- def get_installed_packages(self):
- InstPackages = self.ppmconfignode.getElementsByTagName("PACKAGE")
- self.InstPackages = map((lambda x: InstalledPackage(x)) , InstPackages)
- return self.InstPackages
-
- #def add_repository(self,location,username="", passwd=""):
- # uri, nm = parse_location(location)
- # rep = 'new'+str(whrandom.randint(1,100))
- # repository = Repository(rep,nm,uri,username,passwd)
- # self._locations.append(repository)
-
- def add_package(self,package,location):
- from PyPMHelps import InstPackXML
- import time
- if isinstance(location,Repository):
- URL = location.uri+'?'+location.namespace
- elif type(location) is StringType:
- # check to see if this is a path or a filename
- if location[-1]!='/':
- URL = location[:string.rfind(location,'/')]
- else:
- URL = location
- Date = time.strftime('%a %b %d %H:%M',time.localtime(time.time()))
- InstPackXML = InstPackXML % (str(package.name) , str(URL) , Date)
- doc = xml.dom.minidom.parseString(InstPackXML)
- InstPackNode = doc.getElementsByTagName('PACKAGE')[0]
- InstPPDNode = InstPackNode.getElementsByTagName('INSTPPD')[0]
- InstPPDNode.appendChild(package._node)
- self.ppmconfignode.appendChild(InstPackNode)
- self.refresh()
-
- # becarefull when calling this method. The attribute InstPackages should
- # already be initialized prior to calling this method, unless it won't
- # remove anything from the database
- def remove_package(self,package):
- def ispackage(package,InstPackages):
- for pac in InstPackages:
- if package.name == pac.name:
- return 1, pac
- return 0, None
-
- r , inst_p = ispackage(package,self.InstPackages)
- if r:
- self.ppmconfignode.removeChild(inst_p._node)
- self.refresh()
- inst_p._node.unlink()
-
- #save the options to the configuration file
- def save_options(self):
- import PyPMHelps
- Str = string.replace(PyPMHelps.OptString,'\n','')
- L = self.options.keys()
- L.sort()
- A = []
- for l in L: A.append(self.options[l])
- Str = Str % ((self.builddir,)+tuple(A))
- doc = xml.dom.minidom.parseString(Str)
- NewOptNode = doc.getElementsByTagName('OPTIONS')[0]
- self.ppmconfignode = self.dom.getElementsByTagName('PPMCONFIG')[0]
- OldOptNode = self.ppmconfignode.getElementsByTagName('OPTIONS')[0]
- self.ppmconfignode.removeChild(OldOptNode)
- self.ppmconfignode.appendChild(NewOptNode)
- OldOptNode.unlink()
- self.refresh()
-
- def using_gui():
- try:
- import win32api, pywintypes
- except ImportError:
- return 0 # not Windows
-
- try:
- win32api.GetConsoleTitle()
- return 0
- except pywintypes.error:
- return 1
-