PyXR

c:\projects\bitpim\src \ update.py



0001 ### BITPIM
0002 ###
0003 ### Copyright (C) 2005 Joe Pham <djpham@netzero.com>
0004 ###
0005 ### This program is free software; you can redistribute it and/or modify
0006 ### it under the terms of the BitPim license as detailed in the LICENSE file.
0007 ###
0008 ### $Id: update.py 4380 2007-08-29 00:17:07Z djpham $
0009 
0010 # system modules
0011 from __future__ import with_statement
0012 import copy
0013 import urllib2
0014 import xml.dom.minidom
0015 import webbrowser
0016 
0017 # site-packages
0018 import wx
0019 
0020 # BitPim modules
0021 import guihelper
0022 import version
0023 
0024 #-------------------------------------------------------------------------------
0025 class Download(object):
0026     def __init__(self, source, platform, flavor=None):
0027         self.__src=source
0028         self.__platform=platform
0029         self.__flavor=flavor
0030     def __get_src(self):
0031         return self.__src
0032     def __get_platform(self):
0033         return self.__platform
0034     def __get_flavor(self):
0035         return self.__flavor
0036     source=property(fget=__get_src)
0037     platform=property(fget=__get_platform)
0038     flavor=property(fget=__get_flavor)
0039 
0040 #-------------------------------------------------------------------------------
0041 class Version(object):
0042     def __init__(self, name, release_date, change_log):
0043         self.__name=name
0044         self.__release_date=release_date
0045         self.__change_log=change_log
0046         self.__downloads=[]
0047     def __get_name(self):
0048         return self.__name
0049     def __get_release_date(self):
0050         return self.__release_date
0051     def __get_change_log(self):
0052         return self.__change_log
0053     name=property(fget=__get_name)
0054     release_date=property(__get_release_date)
0055     change_log=property(__get_change_log)
0056 
0057     def add_download(self, download):
0058         self.__downloads.append(download)
0059     def get_download(self, platform, flavor=''):
0060         for n in self.__downloads:
0061             if n.platform==platform and n.flavor==flavor:
0062                 return n
0063         return None
0064 
0065 #-------------------------------------------------------------------------------
0066 class Update(object):
0067     def __init__(self, frm, to, priority, alert):
0068         self.__frm=frm
0069         self.__to=to
0070         self.__priority=priority
0071         self.__alert=alert
0072     def __get_info(self):
0073         return (self.__frm, self.__to, self.__priority, self.__alert)
0074     info=property(fget=__get_info)
0075     
0076 #-------------------------------------------------------------------------------
0077 class BitPimUpdate(object):
0078     def __init__(self):
0079         self.__xml_version='Unknown'
0080         self.__updates={}
0081         self.__versions={}
0082         self.__latest=None
0083     def __get_xml_version(self):
0084         return self.__xml_version
0085     xml_version=property(fget=__get_xml_version)
0086     def __get_versions(self):
0087         return copy.deepcopy(self.__versions, {})
0088     def __get_updates(self):
0089         return copy.deepcopy(self.__updates, {})
0090     def __get_latest_version(self):
0091         return self.__latest
0092     versions=property(fget=__get_versions)
0093     updates=property(fget=__get_updates)
0094     latest_version=property(fget=__get_latest_version)
0095 
0096     def __get_node_value(self, node, name):
0097         try:
0098             return node.getElementsByTagName(name)[0].firstChild.data
0099         except IndexError:
0100             # the tag does not exist
0101             return None
0102         except:
0103             if __debug__: raise
0104             return None
0105 
0106     __default_url='http://www.bitpim.org/updates.xml'
0107     def get_update_info(self, url=__default_url):
0108         # get the contents of the update file
0109         dom=xml.dom.minidom.parseString(urllib2.urlopen(url).read())
0110         # and extract the info
0111         bp_update=dom.getElementsByTagName('BitPimUpdate')[0]
0112         self.__xml_version=bp_update.getAttribute('version')
0113         self.__latest=bp_update.getAttribute('latest')
0114         
0115         updates=dom.getElementsByTagName('update')
0116         for n in updates:
0117             frm=n.getAttribute('from')
0118             self.__updates[frm]=Update(frm,
0119                                        self.__get_node_value(n, 'to'),
0120                                        self.__get_node_value(n, 'priority'),
0121                                        self.__get_node_value(n, 'alert'))
0122         versions=dom.getElementsByTagName('version')
0123         for n in versions:
0124             name=n.getAttribute('name')
0125             v=Version(name, self.__get_node_value(n, 'releasedate'),
0126                       n.getElementsByTagName('changelog')[0].getAttribute('src'))
0127             downloads=n.getElementsByTagName('download')
0128             for d in downloads:
0129                 v.add_download(Download(\
0130                     d.getAttribute('src'),
0131                     d.getAttribute('platform'),
0132                     d.getAttribute('flavor')))
0133             self.__versions[name]=v
0134 
0135     def display_update_info(self, current_version, platform, flavor):
0136         # find and display the update info based on current version & platform
0137         # find if there's a next version
0138         u=self.__updates.get(current_version, None)
0139         if u is None:
0140             # there're no next version, tell the user & bail
0141             return 'There are no updates to the current version: '+current_version
0142         # got the update, look for the version
0143         (frm, next_version, priority, alert)=u.info
0144         v=self.__versions.get(next_version, None)
0145         if v is None:
0146             # No info on this version, tell the user & bail
0147             return 'No download info on version '+next_version+' available.'
0148         dl=v.get_download(platform, flavor)
0149         if dl is None or not len(dl.source):
0150             # the next version is not available for this plaform, bail
0151             return 'Load '+next_version+' is not available on platform '+platform+'/'+flavor
0152         # everything's there, display them to the users
0153         lines=[]
0154         lines.append('Current Version: '+current_version)
0155         s='Platform: '+platform
0156         if flavor is not None and len(flavor):
0157             s+='/'+flavor
0158         lines.append(s)
0159         lines.append('Available for Upgrade:')
0160         lines.append('\tVersion: '+next_version)
0161         lines.append('\tRelease Date: '+v.release_date)
0162         if priority is not None and len(priority):
0163             lines.append('\tPriority: '+priority)
0164         if alert is not None and len(alert):
0165             lines.append('\tWarning: '+alert)
0166         lines.append('updates.xml Version: '+self.xml_version)
0167         lines.append('Latest BitPim Version: '+self.latest_version)
0168         with guihelper.WXDialogWrapper(UpdateDialog(None, dl.source, v.change_log, lines),
0169                                        True):
0170             pass
0171 
0172 #-------------------------------------------------------------------------------
0173 class UpdateDialog(wx.Dialog):
0174     def __init__(self, parent, source_url, change_log_url, lines,
0175                  _title='BitPim Update'):
0176         wx.Dialog.__init__(self, parent, -1, _title)
0177         self.__source_url=source_url
0178         self.__changelog_url=change_log_url
0179         vbs=wx.BoxSizer(wx.VERTICAL)
0180         for l in lines:
0181             vbs.Add(wx.StaticText(self, -1, l), 0, wx.EXPAND|wx.ALL, 5)
0182         vbs.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 5)
0183         change_log_btn=wx.Button(self, wx.NewId(), 'View Change Log')
0184         hbs=wx.BoxSizer(wx.HORIZONTAL)
0185         hbs.Add(change_log_btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
0186         get_update_btn=wx.Button(self, wx.NewId(), 'Download Update')
0187         hbs.Add(get_update_btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
0188         hbs.Add(wx.Button(self, wx.ID_CANCEL, 'Quit'), 0, wx.ALIGN_CENTRE|wx.ALL, 5)
0189         vbs.Add(hbs, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
0190         # event handlers
0191         wx.EVT_BUTTON(self, change_log_btn.GetId(), self.__OnChangelog)
0192         wx.EVT_BUTTON(self, get_update_btn.GetId(), self.__OnGetUpdate)
0193         # all done
0194         self.SetSizer(vbs)
0195         self.SetAutoLayout(True)
0196         vbs.Fit(self)
0197 
0198     def __OnChangelog(self, _):
0199         webbrowser.open(self.__changelog_url)
0200 
0201     def __OnGetUpdate(self, _):
0202         webbrowser.open(self.__source_url)
0203 
0204 #-------------------------------------------------------------------------------
0205 def check_update(update_url=None, current_version=None,
0206                  platform=None, flavor=''):
0207     # get info from current version
0208     if current_version is None:
0209         current_version=version.version
0210     # set flavor to blank for now, should be flavor=version.flavor
0211     if platform is None:
0212         if guihelper.IsMSWindows():
0213             platform='windows'
0214         elif guihelper.IsGtk():
0215             platform='linux'
0216         elif guihelper.IsMac():
0217             platform='mac'
0218         else:
0219             raise ValueError, 'Invalid platform'
0220     # todo: need to figure out how to do flavor, comment out for now
0221 ##    flavor=version.vendor
0222     # retrieve and parse update info
0223     print 'Checking update for BitPim ', current_version, ' running on ', \
0224           platform, '-', flavor
0225     with guihelper.WXDialogWrapper(wx.ProgressDialog('BitPim Update',
0226                                                      'Retrieving BitPim Update Information...',
0227                                                      style=wx.PD_AUTO_HIDE)) as dlg:
0228         bp_update=BitPimUpdate()
0229         s=None
0230         try:
0231             if update_url is None:
0232                 bp_update.get_update_info()
0233             else:
0234                 bp_update.get_update_info(update_url)
0235             dlg.Update(100)
0236         except:
0237             s='Failed to get BitPim update info.'
0238     if s is None:
0239         s=bp_update.display_update_info(current_version, platform, flavor)
0240         latest_version=bp_update.latest_version
0241     else:
0242         latest_version=''
0243     if s is not None:
0244         # error messages being return, display them
0245         guihelper.MessageDialog(None, s, 'BitPim Update', wx.OK|wx.ICON_INFORMATION)
0246     return latest_version
0247 
0248 #-------------------------------------------------------------------------------
0249 if __name__ == '__main__':
0250     import sys
0251     if len(sys.argv)==2 and (sys.argv[1]=='help' or sys.argv[1]=='-help' \
0252                              or sys.argv[1]=='-h'):
0253         print sys.argv[0], '<updates.xml URL> <current BitPim Version> <Platform> <Flavor>'
0254         sys.exit(0)
0255     app=wx.PySimpleApp()
0256     if len(sys.argv)==1:
0257         s=check_update()
0258     else:
0259         s=check_update(*sys.argv[1:])
0260     print 'The latest version is: ', s
0261 

Generated by PyXR 0.9.4