Mercurial > traipse_dev
view orpg/tools/updater.py @ 29:72f7c5904fbf traipse_dev
Update Manager moves into Beta 0.2 as the code is cleaned up some.
The Update Manager is nearly ready to be placed into Grumpy Goblin, though
it is not functioning 100%. It will provide users an opportunity to skip
the update process, grab new repos, and update by choice.
author | sirebral |
---|---|
date | Sun, 02 Aug 2009 00:37:23 -0500 |
parents | 6ef4bb8ee8ca |
children | 3769c8d6431e |
line wrap: on
line source
import wx import wx.html import webbrowser import urllib import zipfile import traceback import hashlib import orpg.dirpath from orpg.orpgCore import * import orpg.orpg_version import orpg.tools.orpg_log import orpg.orpg_xml import orpg.dirpath import orpg.tools.orpg_settings import orpg.tools.validate from mercurial import ui, hg, commands, repo, revlog, cmdutil dir_struct = open_rpg.get_component("dir_struct") u = ui.ui() r = hg.repository(u, ".") c = r.changectx('tip') #repo = hg.repository(ui.ui(), 'http://hg.assembla.com/traipse') #b = [] #b = commands.branches(u, r, True) #print b """ u = ui.ui() r = hg.repository(u, ".") l2 =[] b = r.branchtags() heads = dict.fromkeys(r.heads(), 1) l = [((n in heads), r.changelog.rev(n), n, t) for t, n in b.items()] l.sort() l.reverse() for ishead, r, n, t in l: l2.append(t) print l2 """ #print heads #b = [] #b = c.branch() #print c.branch() #print c.tags() ##Process #Pull #Gather Changeset Info #Display window with Branch + Changesets #Update from Branch -Revision. # -------------------- # | | | # | Change | Download | # | Log | List | # | |-----------| # | | butons | # ---------------------- # Buttons area includes, []Auto Update, <advanced> # class AboutHTMLWindow(wx.Panel): "Window used to display the About dialog box" # Init using the derived from class def __init__( self, parent, id): wx.Panel.__init__( self, parent, id, size=(400, -1)) def OnLinkClicked( self, ref ): "Open an external browser to resolve our About box links!!!" href = ref.GetHref() webbrowser.open( href ) class updaterFrame(wx.Frame): def __init__(self, parent, title, openrpg): ### Update Manager self.ui = ui.ui() self.repo = hg.repository(u, ".") self.c = self.repo.changectx('tip') self.openrpg = openrpg self.parent = parent self.log = self.openrpg.get_component("log") self.log.log("Enter updaterFrame", ORPG_DEBUG) wx.Frame.__init__(self, None, wx.ID_ANY, title, size=(640,480), style=wx.FRAME_NO_TASKBAR | wx.STAY_ON_TOP | wx.DEFAULT_FRAME_STYLE) self.SetBackgroundColour(wx.WHITE) self.CenterOnScreen() self.settings = openrpg.get_component('settings') self.xml = openrpg.get_component('xml') self.dir_struct = self.openrpg.get_component("dir_struct") self.sizer = wx.GridBagSizer(hgap=1, vgap=1) self.changelog = wx.TextCtrl(self, wx.ID_ANY, size=(400, -1), style=wx.TE_MULTILINE | wx.TE_READONLY) self.filelist = wx.TextCtrl(self, wx.ID_ANY, size=(250, 300), style=wx.TE_MULTILINE | wx.TE_READONLY) self.buttons = {} self.buttons['progress_bar'] = wx.Gauge(self, wx.ID_ANY, 100) self.buttons['auto_text'] = wx.StaticText(self, wx.ID_ANY, "Auto Update") self.buttons['auto_check'] = wx.CheckBox(self, wx.ID_ANY) self.buttons['advanced'] = wx.Button(self, wx.ID_ANY, "Package Select") self.buttons['update'] = wx.Button(self, wx.ID_ANY, "Update Now") self.buttons['finish'] = wx.Button(self, wx.ID_ANY, "Finish") self.sizer.Add(self.changelog, (0,0), span=(3,1), flag=wx.EXPAND) self.sizer.Add(self.filelist, (0,1), span=(1,3), flag=wx.EXPAND) self.sizer.Add(self.buttons['progress_bar'], (1,1), span=(1,3), flag=wx.EXPAND) self.sizer.Add(self.buttons['auto_text'], (2,1)) self.sizer.Add(self.buttons['auto_check'], (2,2), flag=wx.EXPAND) self.sizer.Add(self.buttons['advanced'], (2,3), flag=wx.EXPAND) self.sizer.Add(self.buttons['update'], (3,1), flag=wx.EXPAND) self.sizer.Add(self.buttons['finish'], (3,2), span=(1,2), flag=wx.EXPAND) self.sizer.AddGrowableCol(0) self.sizer.AddGrowableRow(0) self.SetSizer(self.sizer) self.SetAutoLayout(True) self.initPrefs() if self.package == None: wx.CallAfter(self.Advanced) #if self.autoupdate == "On": self.buttons['auto_check'].SetValue(True) ## Event Handlers self.Bind(wx.EVT_BUTTON, self.Update, self.buttons['update']) self.Bind(wx.EVT_BUTTON, self.Finish, self.buttons['finish']) self.Bind(wx.EVT_BUTTON, self.Advanced, self.buttons['advanced']) self.Bind(wx.EVT_CHECKBOX, self.ToggleAutoUpdate, self.buttons['auto_check']) try: self.check() except: self.buttons['finish'].Show() self.buttons['update'].Show() def showFinish(self): if self.Updated: self.filelist.SetValue(self.filelist.GetValue() + "Finished ... \n") self.buttons['finish'].Show() self.buttons['advanced'].Show() def initPrefs(self): #self.list_url = self.settings.get_setting("PackagesURL") #self.package_type = self.settings.get_setting("PackagesType") #self.package_name = self.settings.get_setting("PackagesName") self.SelectPackage = False #self.autoupdate = self.settings.get_setting("AutoUpdate") self.packages = None self.package = self.get_package() self.Updated = False self.Finished = False def isFinished(self): return self.Finished def ToggleAutoUpdate(self, event): if self.buttons['auto_check'].GetValue(): self.autoupdate = "On" #self.settings.set_setting("AutoUpdate", "On") #self.Update(None) else: self.autoupdate = "Off" #self.settings.set_setting("AutoUpdate", "Off") def check(self): self.buttons['finish'].Hide() self.buttons['update'].Hide() self.updatelist = [] wx.CallAfter(self.showFinish) #Do the MD5 Check & DL files = self.package._get_childNodes() self.buttons['progress_bar'].SetRange(len(files)) try: i = 1 for file in files: checksum = md5.new() self.buttons['progress_bar'].SetValue(i) if file._get_tagName() == 'file': file_name = file.getAttribute("name") file_url = file.getAttribute("url").replace(' ', '%20') + '/' + file_name file_path = file.getAttribute("path") read_type = file.getAttribute("read_type") file_checksum = file.getAttribute("checksum") full_path = self.dir_struct["home"].replace("\\","/") + file_path + os.sep + file_name full_path = full_path.replace("/", os.sep) if self.verify_file(full_path): if read_type == 'rb': f = open(full_path, "rb") else: f = open(full_path, "r") data = f.read() f.close() checksum.update(data) if(checksum.hexdigest() != file_checksum): self.log.log("Read Type: " + read_type, ORPG_DEBUG) self.log.log("Filename: " + file_name + "\n\tLocal Checksum:\t" + checksum.hexdigest() + "\n\tWeb Checksum:\t" + file_checksum, ORPG_DEBUG) self.updatelist.append((file_url, full_path, file_name, read_type)) else: self.updatelist.append((file_url, full_path, file_name, read_type)) elif file._get_tagName() == 'dir': dir_path = file.getAttribute("path") full_path = self.dir_struct['home'] + dir_path if not self.verify_file(full_path): self.filelist.SetValue(self.filelist.GetValue() + "Creating Directory " + dir_path + " ...\n") os.makedirs(full_path) i += 1 if len(self.updatelist) == 0: wx.CallAfter(self.Finish) return False except: #error handing update check. Likely no internet connection. skip update check self.log.log("[WARNING] Automatic update check failed.\n" + traceback.format_exc(), ORPG_GENERAL) self.filelist.SetValue("[WARNING] Automatic update check failed.\n" + traceback.format_exc()) return False dmsg = "A newer version is available.\n" for file in self.updatelist: dmsg += file[2] + " is out of date\n" dmsg += "Would you like to update Now?" self.filelist.SetValue(dmsg) data = urllib.urlretrieve(self.package.getAttribute("notes").replace(' ', '%20')) file = open(data[0]) changelog = file.read() file.close() self.changelog.SetPage(changelog) if self.autoupdate == "Off": self.buttons['update'].Show() if self.autoupdate == "On": wx.CallAfter(self.Update) return True def Update(self, evt=None): hg.clean(self.repo, self.current) """old code self.buttons['finish'].Hide() self.buttons['update'].Hide() self.buttons['advanced'].Hide() self.buttons['progress_bar'].SetRange(len(self.updatelist)) self.filelist.SetValue("") self.log.log("Starting Update Proccess!", ORPG_DEBUG) i = 1 for file in self.updatelist: self.downloadFile(file[0], file[1], file[2], i, file[3]) i += 1 self.Updated = True self.parent.updated = True wx.CallAfter(self.showFinish) if self.autoupdate == 'On': wx.CallAfter(self.Finish) """ def downloadFile(self, file_url, abs_path, file_name, i, read_type): self.buttons['progress_bar'].SetValue(i) self.buttons['finish'].Hide() self.log.log("Downloading " + file_name, ORPG_DEBUG) try: self.filelist.SetValue(self.filelist.GetValue() + "Downloading " + file_name + " ...\n") wx.Yield() checksum = md5.new() data = urllib.urlretrieve("http://openrpg.digitalxero.net/" + file_url) if read_type == 'rb': file = open(data[0], "rb") else: file = open(data[0], "r") file_data = file.read() file.close() checksum.update(file_data) self.log.log("Read Type: " + read_type, ORPG_DEBUG) self.log.log("Downloaded filename: " + file_name + "\n\tDownloaded Checksum:\t" + checksum.hexdigest(), ORPG_DEBUG) if read_type == 'rb': file = open(abs_path, 'wb') else: file = open(abs_path, 'w') file.write(file_data) file.close() #Debug Stuff checksum = md5.new() f = open(abs_path, read_type) file_data = f.read() f.close() checksum.update(file_data) self.log.log("Written filename: " + file_name + "\n\tWritten Checksum:\t" + checksum.hexdigest(), ORPG_DEBUG) except: self.log.log("Failed to download file: " + abs_path, ORPG_GENERAL) self.log.log(traceback.format_exc(), ORPG_GENERAL) def Finish(self, evt=None): #self.settings.updateIni() self.Finished = True self.Destroy() def Advanced(self, evt=None): dlg = wx.Dialog(self, wx.ID_ANY, "Package Selector", style=wx.DEFAULT_DIALOG_STYLE) icon = None if wx.Platform == '__WXMSW__': icon = wx.Icon(self.dir_struct["icon"]+'d20.ico', wx.BITMAP_TYPE_ICO) else: icon = wx.Icon(self.dir_struct["icon"]+"d20.xpm", wx.BITMAP_TYPE_XPM ) if icon != None: dlg.SetIcon(icon) dlgsizer = wx.GridBagSizer(hgap=1, vgap=1) Yes = wx.Button( dlg, wx.ID_OK, "Ok" ) Yes.SetDefault() rgroup = wx.RadioButton(dlg, wx.ID_ANY, "group_start", style=wx.RB_GROUP) rgroup.Hide() if self.packages == None: self.get_packages() if self.package_list == None: return types = self.package_list row=0 col=0 self.current = self.c.branch() self.package_type = self.current self.btnlist = {}; self.btn = {} self.id = 1 for t in types: self.btnName = str(t) self.btn[self.id] = wx.RadioButton(dlg, wx.ID_ANY, str(t), name=self.btnName) if self.btnName == self.current: self.btn[self.id].SetValue(True) self.btnlist[self.id] = self.btnName dlgsizer.Add(self.btn[self.id], (row, col)) row += 1; self.id += 1 dlgsizer.Add(Yes, (row+1,0)) dlg.SetAutoLayout( True ) dlg.SetSizer( dlgsizer ) dlgsizer.Fit( dlg ) dlg.Centre() dlg.Bind(wx.EVT_RADIOBUTTON, self.PackageSet) if dlg.ShowModal(): dlg.Destroy() if self.Updated: self.Updated = False self.filelist.SetValue('') wx.CallAfter(self.check) def PackageSet(self, event): for btn in self.btn: if self.btn[btn].GetValue() == True: self.current = self.btnlist[btn] branches = self.repo.branchtags() heads = dict.fromkeys(self.repo.heads(), 1) l = [((n in heads), self.repo.changelog.rev(n), n, t) for t, n in branches.items()] #l.sort() #l.reverse() #for ishead, r, n, t in l: self.package_list.append(t) if self.current != type: u = ui.ui() r = hg.repository(u, ".") #r = hg.islocal() c = r.changectx('tip') files = self.c.files() #print commands.log(u, r, c) #print r.changelog ### Cleaning up for dev build 0.1 ### The below material is for the Rev Log. You can run hg log to see what data it will pull. #cs = r.changectx(c.rev()).changeset() #get = util.cachefunc(lambda r: repo.changectx(r).changeset()) #changeiter, matchfn = cmdutil.walkchangerevs(u, r, 1, cs, 1) #for st, rev, fns in changeiter: # revbranch = get(rev)[5]['branch']; print revbranch heads = dict.fromkeys(self.repo.heads(), self.repo.branchtags()) branches = dict.copy(self.repo.branchtags()) self.filelist.SetValue('') self.filelist.AppendText("Files that will change\n\n") self.changelog.SetValue('') changelog = "This is Dev Build 0.1 of the Update Manager. It has limited functionality.\n\nThe full release will search your Revision log and show the contents here." self.changelog.AppendText(changelog + '\n') self.filelist.AppendText("Update to " + self.current + "\n\n The full release will show the files to be changed here.") #### Files works but not fully without the change log information, pulled for Dev 0.1 #for f in files: # fc = c[f] # self.filelist.AppendText(str(f + '\n')) def verify_file(self, abs_path): """Returns True if file or directory exists""" try: os.stat(abs_path) return True except OSError: self.log.log("Invalid File or Directory: " + abs_path, ORPG_GENERAL) return False def get_packages(self, type=None): #Fixed and ready for Test. Can be cleaner self.package_list = [] b = self.repo.branchtags() heads = dict.fromkeys(self.repo.heads(), 1) l = [((n in heads), self.repo.changelog.rev(n), n, t) for t, n in b.items()] l.sort() l.reverse() for ishead, r, n, t in l: self.package_list.append(t) def get_package(self): #Fixed and ready for test. if self.packages == None: self.get_packages() if self.package_list == None: return None return None def is_up2date(self, version, build): if self.package == None: self.SelectPackage == True return False vg = (version > self.package.getAttribute("version")) ve = (version == self.package.getAttribute("version")) b = (build >= self.package.getAttribute("build")) if vg: return True if (not ve) or (not b): return False return True class updateApp(wx.App): def OnInit(self): self.open_rpg = open_rpg self.log = orpg.tools.orpg_log.orpgLog(orpg.dirpath.dir_struct["user"] + "runlogs/") self.log.setLogToConsol(False) self.log.log("Updater Start", ORPG_NOTE) #Add the initial global components of the openrpg class #Every class should be passed openrpg self.open_rpg.add_component("log", self.log) self.open_rpg.add_component("xml", orpg.orpg_xml) self.open_rpg.add_component("dir_struct", orpg.dirpath.dir_struct) self.validate = orpg.tools.validate.Validate() self.open_rpg.add_component("validate", self.validate) #self.settings = orpg.tools.orpg_settings.orpgSettings(self.open_rpg) #self.open_rpg.add_component("settings", self.settings) #self.settings.updateIni() self.updater = updaterFrame(self, "OpenRPG Update Manager Beta 0.1", self.open_rpg) self.updated = False try: self.updater.Show() self.SetTopWindow(self.updater) self.updater.Fit() except: pass return True def OnExit(self): #self.settings.save() """ imported = ['orpg.orpgCore', 'orpg.orpg_wx', 'orpg.orpg_version', 'orpg.tools.orpg_log', 'orpg.orpg_xml', 'orpg.dirpath', 'orpg.tools.orpg_settings', 'orpg.tools.validate', 'orpg.pulldom', 'orpg.tools.NotebookCtrl', 'orpg.tools.config_update', 'orpg.systempath', 'orpg.minidom', 'orpg.dirpath.dirpath_tools', 'orpg.tools.rgbhex', 'orpg.orpg_windows'] for name in imported: if name in sys.modules: self.log.log("Unimported " + name, ORPG_DEBUG) del sys.modules[name] """ self.log.log("Updater Exit\n\n", ORPG_NOTE)