upgrade.py :  » Issue-Tracker » IssueTracker » IssueTrackerProduct » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Issue Tracker » IssueTracker 
IssueTracker » IssueTrackerProduct » upgrade.py
#!/usr/bin/env python

"""
  The upgrade script downloads the latest IssueTrackerProduct
  from www.issuetrackerproduct.com and upgrades and installs the new
  files.
  
  Peter Bengtsson, mail@peterbe.com, (c) 2005
"""



__changes__='''
  1.2   July 2005    Ability to create a new IssueTrackerProduct if not found 
  
  1.1   July 2005    First CVSed version
'''
__version__='1.2'


import os, sys, glob, gzip, tarfile
from cStringIO import StringIO
from urllib import urlopen
import urllib2

latest_versionnr_url = "http://www.issuetrackerproduct.com/Download/getLatestVersionNumber"
latest_versionurl_url = "http://www.issuetrackerproduct.com/Download/getLatestVersionURL"

CVS_ANON_LOGIN = "cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/issuetracker login"
CVS_ANON_CHECKOUT = "cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/issuetracker co IssueTrackerProduct"



class VersionController:
    
    def __init__(self, home_path='.', verbose=False):
        self.home_path = home_path
        self.latest_version = _getLatestVersion()
        self.this_version = _getCurrentVersion(home_path)
        self.latest_version_url = _getLatestVersionURL()
        self.verbose = verbose
        
    def isUsingCVS(self):
        """ return true if in the home_path there is a CVS dir """
        poss_path = os.path.join(self.home_path, 'CVS')
        return os.path.exists(poss_path)
    
    def cvsUpdate(self):
        """ try to do a CVS update """
        _update = 1
        if self.verbose:
            _update = raw_input("Upgrade %s [Y/n] " % shortname)
            if _update.lower().strip() not in ('y',''):
                _update = 0
        
        if _update:
            _prev = os.path.abspath(os.curdir)
            os.chdir('..')
            os.system(CVS_ANON_LOGIN)
            os.system(CVS_ANON_CHECKOUT)
            os.chdir(_prev)
        
    def canUpgrade(self):
        """ return true if there is a newer version to download and install """
        return self.this_version != self.latest_version
    
    def upgrade(self, pretend=False):
        return self._installURL(self.latest_version_url, pretend=pretend)
    
    def _installURL(self, URL, pretend=False):
        """ given a URL to a gzipped file, download it and replace the existing 
        stuff """
        assert URL.endswith('.tgz') or URL.endswith('.tar.gz')
        
        filename = URL.split('/')[-1]
        
        # download it
        downloadfile = open(filename, 'wb')
        req = urllib2.Request(URL)
        req.add_header('User-agent', 'Upgrade script (www.issuetrackerproduct.com)')
        furl = urllib2.urlopen(req)
        downloadfile.write(furl.read())
        downloadfile.close()
        
        tar = tarfile.open(filename)
        _current_files = _listdir_fullpaths_filtered(self.home_path)
        _current_folders = _filter_whatispaths(_current_files)
        
        _current_files_copy = _current_files[:]
        for tarinfo in tar:
            
            assert tarinfo.name.startswith('IssueTrackerProduct'), \
                   "Incorrectly gzipped file"

            shortname = tarinfo.name.replace('IssueTrackerProduct/','')
            if not shortname:
                continue
            if shortname in _current_folders or \
                shortname[:-1] in _current_folders:
                continue # directories aren't important
            elif shortname.find('mainbuttons') > -1 or \
                 shortname.find('actionbuttons') > -1:
                # old crap that might be in the tgz
                continue
                
            if shortname in _current_files:
                # the default value depends on if the file has changed
                
                shortname_path = os.path.abspath(os.path.join(self.home_path, shortname))
                if tarinfo.size > 1000:
                    if tarinfo.size == len(open(shortname_path).read()):
                        _upgrade = 0
                    else:
                        _upgrade = 1
                else:
                    # if the file is less than 1000 bytes, don't do a size comparison 
                    # because it can fail with really small files like 'version.txt' 
                    # whose content can change from "0.6.12" to "0.6.13" which is the same
                    # length but different in content. Larger files and larger probability
                    # that the changes also change the total file length.
                    extracted_content = tar.extractfile(tarinfo).read()
                    if extracted_content == open(shortname_path).read():
                        _upgrade = 0
                    else:
                        _upgrade = 1                
                
                
                # if verbose, ask about each
                if self.verbose and _upgrade:
                    _upgrade = raw_input("Upgrade %s [Y/n] " % shortname)
                    if _upgrade.lower().strip() not in ('y',''):
                        _upgrade = 0
                
                if _upgrade:
                    print "U %s" % shortname
                    tar.extract(tarinfo, os.path.join(self.home_path, '..'))
            else:
                _install = 1
                if self.verbose:
                    _install = raw_input("Install %s [Y/n] " % shortname)
                    if _install.lower().strip() not in ('y',''):
                        _install = 0
                
                if _install:
                    print "I %s" % tarinfo.name.replace('IssueTrackerProduct','')
                    tar.extract(tarinfo, os.path.join(self.home_path, '..'))
                    
            if shortname in _current_files_copy:
                _current_files_copy.remove(shortname)

        this_script_filename = globals()['__file__']
        if this_script_filename in _current_files_copy:
            _current_files_copy.remove(this_script_filename)
        elif this_script_filename.replace('./','') in _current_files_copy:
            _current_files_copy.remove(this_script_filename.replace('./',''))

        if self.verbose:
            if _current_files_copy:
                print >>sys.stderr, "The following files are not needed anymore"
            for f in _current_files_copy:
                print >>sys.stderr, f
                _delete = raw_input("\tDelete %s [y/N] " % f)
                if _delete.lower().strip() not in ('y',''):
                    _delete = 1
                if _delete:
                    os.remove(f)
        
                
                    

def _filter_whatispaths(files):
    """ return a list of what is directories from a list of 
    files and directories """
    dirs = {}
    for v in files:
        splitted = os.path.split(v)
        if splitted[0]:
            dirs[splitted[0]] = 1
    return dirs.keys()
        
def _listdir_fullpaths_filtered(root, relpath=True):
    """ return a list of filepaths similar to os.path but open each
    directory. """
    all = []
    def _rejectFile(f):
        if f[-3:] in ('pyc','bak'):
            return True
        if f.endswith('~'):
            return True
        if f.startswith('#') or f.startswith('.#'):
            return True
        return False
    
    for base, dirs, files in os.walk(root):
        if base.endswith('CVS'):
            continue
        for file in files:
            if not _rejectFile(file):
                _path = os.path.join(base, file)
                
                if relpath:
                    _path = _path.replace(root,'')
                    if _path.startswith('/'):
                        _path = _path[1:]
                all.append(_path)
        
    return all
        

def _getCurrentVersion(home_path=None):
    if home_path:
        f = os.path.join(home_path, 'version.txt')
    else:
        f = 'version.txt'
    return open(f).read().strip()

def _getLatestVersion():    
    return urlopen(latest_versionnr_url).read().strip()

def _getLatestVersionURL():    
    return urlopen(latest_versionurl_url).read().strip()

#-------------------------------------------------------------------------------    



    
    
    
    

    
def cli():
    from optparse import OptionParser

    parser = OptionParser()
    parser.add_option("-v", "--verbose",
                      action="store_true", dest="verbose",
                      help="Each step is confirmed by the user"
                      )
  #  parser.add_option(
    options, args = parser.parse_args()
    verbose = not not options.verbose
    
    if os.path.abspath('.').endswith('IssueTrackerProduct'):
        home_path = os.path.abspath('.')
    elif 'IssueTrackerProduct' in os.listdir('.'):
        home_path = os.path.abspath(os.path.join('.','IssueTrackerProduct'))
    elif sys.argv[1:] and (sys.argv[1].endswith('IssueTrackerProduct') or sys.argv[1].endswith('IssueTrackerProduct/')):
        home_path = sys.argv[1]
    else:
        # perhaps they just want to download it!
        _mkdir = raw_input("IssueTrackerProduct folder can't be found. Create? [y/N] ")
        if _mkdir.lower().strip() in ('n',''):
            raise OSError, "IssueTrackerProduct can't be found. See(k) help."
        else:
            os.mkdir('IssueTrackerProduct')
            home_path = os.path.abspath(os.path.join('.','IssueTrackerProduct'))
            open(os.path.join(home_path, 'version.txt'),'w').write('0.0.0')
                
    vc = VersionController(home_path, 
                           verbose=verbose)
    if vc.isUsingCVS():
        vc.cvsUpdate()
    elif vc.canUpgrade():
        vc.upgrade()
    else:
        print >>sys.stderr, "Latest version (%s) already installed" % vc.latest_version
    
    return 0 # everything went fine


if __name__=='__main__':
    sys.exit(cli())
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.