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