changeset 14:e8260c6cb309 grumpy-goblin

Traipse 'OpenRPG' {090806-00} Traipse is a distribution of OpenRPG that is designed to be easy to setup and go. Traipse also makes it easy for developers to work on code without fear of sacrifice. 'Grumpy-Goblin' was created as a stablizing branch in an effort to remove bugs from core code. Update Summary: This build introduces Update Manager. Update Manager is a powerful tool in open beta that allows users more control over their Mercurial updates.
author sirebral
date Thu, 06 Aug 2009 18:09:36 -0500
parents 211ac836b6a0
children b6c6ec28ba8a
files orpg/main.py orpg/orpg_version.py orpg/templates/default_ignorelist.txt orpg/templates/default_manifest.xml start_developer.py start_noupdate.py start_release.py upmana/ReadMe.txt upmana/__init__.py upmana/default_ignorelist.txt upmana/default_manifest.xml upmana/manifest.py upmana/updatemana.py upmana/validate.py upmana/xmltramp.py
diffstat 13 files changed, 1144 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/orpg/main.py	Fri Jul 31 15:22:11 2009 -0500
+++ b/orpg/main.py	Thu Aug 06 18:09:36 2009 -0500
@@ -53,6 +53,8 @@
 import orpg.networking.gsclient
 import orpg.mapper.map
 import orpg.mapper.images
+import upmana.updatemana
+import upmana.manifest as manifest
 import wx.py
 
 ####################################
@@ -125,6 +127,12 @@
         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
         self.log.log("Exit orpgFrame", ORPG_DEBUG)
 
+        #Load Update Manager
+        open_rpg.add_component('updatemana', self.updateMana)
+        self.log.log("update manager reloaded", ORPG_DEBUG)
+        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
+        self.log.log("Exit orpgFrame", ORPG_DEBUG)
+
     def post_show_init(self):
         """Some Actions need to be done after the main fram is drawn"""
         self.log.log("Enter orpgFrame->post_show_init(self)", ORPG_DEBUG)
@@ -235,10 +243,20 @@
         self.pluginMenu = wx.Menu()
         item = wx.MenuItem(self.pluginMenu, wx.ID_ANY, "Control Panel", "Control Panel")
         self.Bind(wx.EVT_MENU, self.OnMB_PluginControlPanel, item)
+
         self.pluginMenu.AppendItem(item)
         self.pluginMenu.AppendSeparator()
         self.mainmenu.Insert(2, self.pluginMenu, "&Plugins")
-        self.log.log("Exit orpgFrame->build_menu()", ORPG_DEBUG)       
+        self.log.log("Exit orpgFrame->build_menu()", ORPG_DEBUG)
+
+        self.updateMana = wx.Menu()
+        mana = wx.MenuItem(self.updateMana, wx.ID_ANY, "Update Manager", "Update Manager")
+        self.Bind(wx.EVT_MENU, self.OnMB_UpdateManagerPanel, mana)
+
+        self.updateMana.AppendItem(mana)
+        self.mainmenu.Insert(5, self.updateMana, "&Update Manager")
+        self.log.log("Exit orpgFrame->build_menu()", ORPG_DEBUG)
+       
 
     #################################
     ## All Menu Events
@@ -449,6 +467,12 @@
         else: self.pluginsFrame.Show()
         self.log.log("Exit orpgFrame->OnMB_ToolsPlugins(self)", ORPG_DEBUG)
 
+    def OnMB_UpdateManagerPanel(self, evt):
+        self.log.log("Enter orpgFrame->OnMB_ToolsPlugins(self)", ORPG_DEBUG)
+        if self.updateMana.IsShown() == True: self.updateMana.Hide()
+        else: self.updateMana.Show()
+        self.log.log("Exit orpgFrame->OnMB_ToolsPlugins(self)", ORPG_DEBUG)
+
     def OnMB_ToolsLoggingLevelDebug(self):
         self.log.log("Enter orpgFrame->OnMB_ToolsLoggingLevelDebug(self)", ORPG_DEBUG)
         lvl = self.log.getLogLevel()
@@ -535,7 +559,7 @@
         self._mgr.Update()
         self.log.log("Exit orpgFrame->OnMB_ToolsMapBar(self)", ORPG_DEBUG)
 
-    #Help Menu
+    #Help Menu #Needs a custom Dialog because it is ugly on Windows
     def OnMB_HelpAbout(self):
 
         description = """OpenRPG is a Virtual Game Table that allows users to connect via a network and play table
@@ -612,6 +636,18 @@
         self.SetDimensions(posx, posy, w, h)
         self.log.log("Dimensions Set", ORPG_DEBUG)
 
+        #Update Manager
+        self.manifest = manifest.ManifestChanges()
+        self.updateMana = upmana.updatemana.updaterFrame(self, "OpenRPG Update Manager Beta 0.6.7", open_rpg, self.manifest, True)
+        self.log.log("Menu Created", ORPG_DEBUG)
+        h = int(xml_dom.getAttribute("height"))
+        w = int(xml_dom.getAttribute("width"))
+        posx = int(xml_dom.getAttribute("posx"))
+        posy = int(xml_dom.getAttribute("posy"))
+        maximized = int(xml_dom.getAttribute("maximized"))
+        self.SetDimensions(posx, posy, w, h)
+        self.log.log("Dimensions Set", ORPG_DEBUG)
+
         # Sound Manager
         self.sound_player = orpg.tools.orpg_sound.orpgSound(self)
         open_rpg.add_component("sound", self.sound_player)
@@ -1092,6 +1128,7 @@
         self.log = orpg.tools.orpg_log.orpgLog(orpg.dirpath.dir_struct["user"] + "runlogs/")
         self.log.setLogToConsol(False)
         self.log.log("Main Application Start", ORPG_DEBUG)
+        self.manifest = manifest.ManifestChanges()
         #Add the initial global components of the openrpg class
         #Every class should be passed openrpg
         open_rpg.add_component("log", self.log)
--- a/orpg/orpg_version.py	Fri Jul 31 15:22:11 2009 -0500
+++ b/orpg/orpg_version.py	Thu Aug 06 18:09:36 2009 -0500
@@ -4,7 +4,7 @@
 #BUILD NUMBER FORMAT: "YYMMDD-##" where ## is the incremental daily build index (if needed)
 DISTRO = "Traipse"
 DIS_VER = "Grumpy Goblin"
-BUILD = "090731-00"
+BUILD = "090806-00"
 
 # This version is for network capability.
 PROTOCOL_VERSION = "1.2"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/orpg/templates/default_manifest.xml	Thu Aug 06 18:09:36 2009 -0500
@@ -0,0 +1,1 @@
+<manifest></manifest>
--- a/start_developer.py	Fri Jul 31 15:22:11 2009 -0500
+++ b/start_developer.py	Thu Aug 06 18:09:36 2009 -0500
@@ -1,16 +1,15 @@
 #!/usr/bin/env python
 
-import sys
-import os
-
 import pyver
 pyver.checkPyVersion()
 
+#Update Manager
+from orpg.orpg_wx import *
+import upmana.updatemana
+app = upmana.updatemana.updateApp(0)
+app.MainLoop()
 
-for key in sys.modules.keys():
-    if 'orpg' in key:
-        del sys.modules[key]
-
+#Main Program
 from orpg.orpg_wx import *
 import orpg.main
 
--- a/start_noupdate.py	Fri Jul 31 15:22:11 2009 -0500
+++ b/start_noupdate.py	Thu Aug 06 18:09:36 2009 -0500
@@ -1,19 +1,15 @@
 #!/usr/bin/env python
 
-import sys
-import os
-
-#HG = os.environ["HG"]
-
 import pyver
 pyver.checkPyVersion()
 
-#os.system(HG + ' pull "http://hg.assembla.com/traipse"')
+#Update Manager
+from orpg.orpg_wx import *
+import upmana.updatemana
+app = upmana.updatemana.updateApp(0)
+app.MainLoop()
 
-for key in sys.modules.keys():
-    if 'orpg' in key:
-        del sys.modules[key]
-
+#Main Program
 from orpg.orpg_wx import *
 import orpg.main
 
--- a/start_release.py	Fri Jul 31 15:22:11 2009 -0500
+++ b/start_release.py	Thu Aug 06 18:09:36 2009 -0500
@@ -1,21 +1,15 @@
 #!/usr/bin/env python
 
-import sys
-import os
-
-HG = os.environ["HG"]
-
 import pyver
 pyver.checkPyVersion()
 
-
-os.system(HG + ' pull "http://hg.assembla.com/traipse"')
-os.system(HG + " update -C grumpy-goblin")
+#Update Manager
+from orpg.orpg_wx import *
+import upmana.updatemana
+app = upmana.updatemana.updateApp(0)
+app.MainLoop()
 
-for key in sys.modules.keys():
-    if 'orpg' in key:
-        del sys.modules[key]
-
+#Main Program
 from orpg.orpg_wx import *
 import orpg.main
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/upmana/ReadMe.txt	Thu Aug 06 18:09:36 2009 -0500
@@ -0,0 +1,18 @@
+Welcome to Update Manager 0.6.7!!!
+
+This is the first isntallment of Update Manager for the OpenRPG Virtual Game Table.  The package includes several files that allow users to install Update Manager as a package into other softwares that use Mercurial.  The package itself includes
+
+updatemana.py ## The Update Manager
+manfiest.py ## A clone of the Plugin Database file (plugindb.py) from the OpenRPG Project
+validate.py ## Currently unused but it is here for future packaging, from the OpenRPG Project
+xmltramp.py  ## From the OpenRPG Project
+__init__.py ## So you can copy the upmana folder and import updatemana.py anywhere
+tmp folder ## Used to protect files during a repository update
+default_ignorelist.txt ## An empty txt, needed in case users cannot create their own ignorelist.txt
+default_manifest.xml ## A nearly empty XML file.  Used to hold Update Manager information.
+
+The code is incomplete in this version, but the pieces that are missing have notes in remarks on how to complete them.
+
+So what can you do with Update Manager? If you have a project that you want to serve to users and user Mercurial as a way to deliver updates, Update Manager allows you to deliver those updates without the fear of creating a problem with user sentiment.  Users will be able to (when completed) access their Control tab and update to any revision or any branch that has been served via a repoistory.  Users also have the option to protect files from being overwritten during updates, or not update at all!
+
+If you have a development team you can use Update Manager as a speedy way to surf through your branches and revisions.  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/upmana/__init__.py	Thu Aug 06 18:09:36 2009 -0500
@@ -0,0 +1,1 @@
+__all__ = ['upmana', 'manifest']
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/upmana/default_manifest.xml	Thu Aug 06 18:09:36 2009 -0500
@@ -0,0 +1,1 @@
+<manifest></manifest>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/upmana/manifest.py	Thu Aug 06 18:09:36 2009 -0500
@@ -0,0 +1,185 @@
+import xmltramp
+import orpg.dirpath
+import orpg.tools.validate
+from os import sep
+from types import *
+
+class ManifestChanges:
+    def __init__(self, filename="updatemana.xml"):
+        self.filename = orpg.dirpath.dir_struct["home"] + 'upmana' + sep + filename
+        orpg.tools.validate.Validate(orpg.dirpath.dir_struct["home"] + 'upmana' + sep).config_file(filename,"default_manifest.xml")
+        self.xml_dom = self.LoadDoc()
+
+    def GetString(self, plugname, strname, defaultval, verbose=0):
+        strname = self.safe(strname)
+        for plugin in self.xml_dom:
+            if plugname == plugin._name:
+                for child in plugin._dir:
+                    if child._name == strname:
+                        #str() on this to make sure it's ASCII, not unicode, since orpg can't handle unicode.
+                        if verbose: print "successfully found the value"
+                        if len(child): return str( self.normal(child[0]) )
+                        else: return ""
+        else:
+            if verbose:
+                print "manifest: no value has been stored for " + strname + " in " + plugname + " so the default has been returned"
+            return defaultval
+
+    def SetString(self, plugname, strname, val):
+        #Set Node, <repo, name, description, value>
+        #Set Setting, <setting, value>
+        val = self.safe(val)
+        strname = self.safe(strname)
+        for plugin in self.xml_dom:
+        ##this isn't absolutely necessary, but it saves the trouble of sending a parsed object instead of a simple string.
+            if plugname == plugin._name:
+                plugin[strname] = val
+                plugin[strname]._attrs["type"] = "string"
+                self.SaveDoc()
+                return "found plugin"
+        else:
+            self.xml_dom[plugname] = xmltramp.parse("<" + strname + " type=\"string\">" + val + "</" + strname + ">")
+            self.SaveDoc()
+            return "added plugin"
+
+
+    def FetchList(self, parent):
+        retlist = []
+        if not len(parent): return []
+        for litem in parent[0]._dir:
+            if len(litem):
+                if litem._attrs["type"] == "int": retlist += [int(litem[0])]
+                elif litem._attrs["type"] == "long": retlist += [long(litem[0])]
+                elif litem._attrs["type"] == "float": retlist += [float(litem[0])]
+                elif litem._attrs["type"] == "list": retlist += [self.FetchList(litem)]
+                elif litem._attrs["type"] == "dict": retlist += [self.FetchDict(litem)]
+                else: retlist += [str( self.normal(litem[0]) )]
+            else: retlist += [""]
+        return retlist
+
+    def GetList(self, plugname, listname, defaultval, verbose=0):
+        listname = self.safe(listname)
+        for plugin in self.xml_dom:
+            if plugname == plugin._name:
+                for child in plugin._dir:
+                    if child._name == listname and child._attrs["type"] == "list":
+                        retlist = self.FetchList(child)
+                        if verbose: print "successfully found the value"
+                        return retlist
+        else:
+            if verbose:
+                print "plugindb: no value has been stored for " + listname + " in " + plugname + " so the default has been returned"
+            return defaultval
+
+    def BuildList(self, val):
+        listerine = "<list>"
+        for item in val:
+            if isinstance(item, basestring):#it's a string
+                listerine += "<lobject type=\"str\">" + self.safe(item) + "</lobject>"
+            elif isinstance(item, IntType):#it's an int
+                listerine += "<lobject type=\"int\">" + str(item) + "</lobject>"
+            elif isinstance(item, FloatType):#it's a float
+                listerine += "<lobject type=\"float\">" + str(item) + "</lobject>"
+            elif isinstance(item, LongType):#it's a long
+                listerine += "<lobject type=\"long\">" + str(item) + "</lobject>"
+            elif isinstance(item, ListType):#it's a list
+                listerine += "<lobject type=\"list\">" + self.BuildList(item) + "</lobject>"
+            elif isinstance(item, DictType):#it's a dictionary
+                listerine += "<lobject type=\"dict\">" + self.BuildDict(item) + "</lobject>"
+            else: return "type unknown"
+        listerine += "</list>"
+        return listerine
+
+    def SetList(self, plugname, listname, val):
+        listname = self.safe(listname)
+        list = xmltramp.parse(self.BuildList(val))
+        for plugin in self.xml_dom:
+            if plugname == plugin._name:
+                plugin[listname] = list
+                plugin[listname]._attrs["type"] = "list"
+                self.SaveDoc()
+                return "found plugin"
+        else:
+            self.xml_dom[plugname] = xmltramp.parse("<" + listname + "></" + listname + ">")
+            self.xml_dom[plugname][listname] = list
+            self.xml_dom[plugname][listname]._attrs["type"] = "list"
+            self.SaveDoc()
+            return "added plugin"
+
+    def BuildDict(self, val):
+        dictator = "<dict>"
+        for item in val.keys():
+            if isinstance(val[item], basestring):
+                dictator += "<dobject name=\"" + self.safe(item) + "\" type=\"str\">" + self.safe(val[item]) + "</dobject>"
+            elif isinstance(val[item], IntType):#it's an int
+                dictator += "<dobject name=\"" + self.safe(item) + "\" type=\"int\">" + str(val[item]) + "</dobject>"
+            elif isinstance(val[item], FloatType):#it's a float
+                dictator += "<dobject name=\"" + self.safe(item) + "\" type=\"float\">" + str(val[item]) + "</dobject>"
+            elif isinstance(val[item], LongType):#it's a long
+                dictator += "<dobject name=\"" + self.safe(item) + "\" type=\"long\">" + str(val[item]) + "</dobject>"
+            elif isinstance(val[item], DictType):#it's a dictionary
+                dictator += "<dobject name=\"" + self.safe(item) + "\" type=\"dict\">" + self.BuildDict(val[item]) + "</dobject>"
+            elif isinstance(val[item], ListType):#it's a list
+                dictator += "<dobject name=\"" + self.safe(item) + "\" type=\"list\">" + self.BuildList(val[item]) + "</dobject>"
+            else: return str(val[item]) + ": type unknown"
+        dictator += "</dict>"
+        return dictator
+
+    def SetDict(self, plugname, dictname, val, file="plugindb.xml"):
+        dictname = self.safe(dictname)
+        dict = xmltramp.parse(self.BuildDict(val))
+        for plugin in self.xml_dom:
+            if plugname == plugin._name:
+                plugin[dictname] = dict
+                plugin[dictname]._attrs["type"] = "dict"
+                self.SaveDoc()
+                return "found plugin"
+        else:
+            self.xml_dom[plugname] = xmltramp.parse("<" + dictname + "></" + dictname + ">")
+            self.xml_dom[plugname][dictname] = dict
+            self.xml_dom[plugname][dictname]._attrs["type"] = "dict"
+            self.SaveDoc()
+            return "added plugin"
+
+    def FetchDict(self, parent):
+        retdict = {}
+        if not len(parent): return {}
+        for ditem in parent[0]._dir:
+            if len(ditem):
+                ditem._attrs["name"] = self.normal(ditem._attrs["name"])
+                if ditem._attrs["type"] == "int": retdict[ditem._attrs["name"]] = int(ditem[0])
+                elif ditem._attrs["type"] == "long": retdict[ditem._attrs["name"]] = long(ditem[0])
+                elif ditem._attrs["type"] == "float": retdict[ditem._attrs["name"]] = float(ditem[0])
+                elif ditem._attrs["type"] == "list": retdict[ditem._attrs["name"]] = self.FetchList(ditem)
+                elif ditem._attrs["type"] == "dict": retdict[ditem._attrs["name"]] = self.FetchDict(ditem)
+                else: retdict[ditem._attrs["name"]] = str( self.normal(ditem[0]) )
+            else: retdict[ditem._attrs["name"]] = ""
+        return retdict
+
+    def GetDict(self, plugname, dictname, defaultval, verbose=0):
+        dictname = self.safe(dictname)
+        for plugin in self.xml_dom:
+            if plugname == plugin._name:
+                for child in plugin._dir:
+                    if child._name == dictname and child._attrs["type"] == "dict": return self.FetchDict(child)
+        else:
+            if verbose:
+                print "plugindb: no value has been stored for " + dictname + " in " + plugname + " so the default has been returned"
+            return defaultval
+
+    def safe(self, string):
+        return string.replace("<", "$$lt$$").replace(">", "$$gt$$").replace("&","$$amp$$").replace('"',"$$quote$$")
+
+    def normal(self, string):
+        return string.replace("$$lt$$", "<").replace("$$gt$$", ">").replace("$$amp$$","&").replace("$$quote$$",'"')
+
+    def SaveDoc(self):
+        f = open(self.filename, "w")
+        f.write(self.xml_dom.__repr__(1, 1))
+        f.close()
+
+    def LoadDoc(self):
+        xml_file = open(self.filename)
+        manifest = xml_file.read()
+        xml_file.close()
+        return xmltramp.parse(manifest)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/upmana/updatemana.py	Thu Aug 06 18:09:36 2009 -0500
@@ -0,0 +1,531 @@
+import wx
+import manifest
+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.validate
+import tempfile
+import shutil
+from mercurial import ui, hg, commands, repo, revlog, cmdutil
+
+
+class Updater(wx.Panel):
+    def __init__(self, parent, open_rpg, manifest):
+        wx.Panel.__init__(self, parent)
+
+        ### Update Manager
+        self.ui = ui.ui()
+        self.repo = hg.repository(self.ui, ".")
+        self.c = self.repo.changectx('tip')
+        self.manifest = manifest
+        self.xml = open_rpg.get_component('xml')
+        self.dir_struct = open_rpg.get_component("dir_struct")
+        self.parent = parent
+        self.log = open_rpg.get_component("log")
+        self.log.log("Enter updaterFrame", ORPG_DEBUG)
+        self.SetBackgroundColour(wx.WHITE)
+        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['no_text'] = wx.StaticText(self, wx.ID_ANY, "No Update")
+        self.buttons['no_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=(4,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['no_text'], (3,1))
+        self.sizer.Add(self.buttons['no_check'], (3,2), flag=wx.EXPAND)
+        self.sizer.Add(self.buttons['advanced'], (2,3), flag=wx.EXPAND)
+        self.sizer.Add(self.buttons['update'], (3,3), flag=wx.EXPAND)
+        self.sizer.Add(self.buttons['finish'], (4,3), flag=wx.EXPAND)
+        self.buttons['finish'].Disable()
+        self.sizer.AddGrowableCol(0)
+        self.sizer.AddGrowableRow(0)
+        self.SetSizer(self.sizer)
+        self.SetAutoLayout(True)
+        self.get_package
+
+        self.current = self.repo.dirstate.branch()
+        self.BranchInfo(self.current)
+
+        if self.manifest.GetString("updatemana", "no_update", "") == 'on': self.buttons['no_check'].SetValue(True)
+        else: self.buttons['no_check'].SetValue(False)
+        if self.manifest.GetString("updatemana", "auto_update", "") == 'on': self.buttons['auto_check'].SetValue(True)
+        else: self.buttons['auto_check'].SetValue(False)
+
+        ## 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.ChooseBranch, self.buttons['advanced'])
+        self.Bind(wx.EVT_CHECKBOX, self.ToggleAutoUpdate, self.buttons['auto_check'])
+        self.Bind(wx.EVT_CHECKBOX, self.ToggleNoUpdate, self.buttons['no_check'])
+
+    def ToggleAutoUpdate(self, event):
+        if self.buttons['auto_check'].GetValue() == True:
+            if self.buttons['no_check'].GetValue() == True: 
+                self.buttons['no_check'].SetValue(False)
+                self.manifest.SetString("updatemana", "no_update", "off")
+            self.manifest.SetString("updatemana", "auto_update", "on")
+        else: self.manifest.SetString("updatemana", "auto_update", "off")
+
+    def ToggleNoUpdate(self, event):
+        if self.buttons['no_check'].GetValue() == True:
+            if self.buttons['auto_check'].GetValue() == True: 
+                self.buttons['auto_check'].SetValue(False)
+                self.manifest.SetString("updatemana", "auto_update", "off")
+            self.manifest.SetString("updatemana", "no_update", "on")
+        else: self.manifest.SetString("updatemana", "no_update", "off")
+
+    def Update(self, evt=None):
+        self.ui = ui.ui()
+        self.repo = hg.repository(self.ui, ".")
+        self.c = self.repo.changectx('tip')
+
+        filename = 'ignorelist.txt'
+        self.filename = orpg.dirpath.dir_struct["home"] + 'upmana' + os.sep + filename
+        orpg.tools.validate.Validate(orpg.dirpath.dir_struct["home"] + 'upmana' + os.sep).config_file(filename, "default_ignorelist.txt")
+        self.mana = self.LoadDoc()
+        for ignore in self.ignorelist:
+            shutil.copy(ignore, orpg.dirpath.dir_struct["home"] + 'upmana' + os.sep + 'tmp' + os.sep)
+        hg.clean(self.repo, self.current)
+        for ignore in self.ignorelist:
+            shutil.copyfile(orpg.dirpath.dir_struct["home"] + 'upmana' + os.sep + 'tmp' + os.sep + ignore.split('/')[len(ignore.split('/')) - 1], ignore)
+            os.remove(orpg.dirpath.dir_struct["home"] + 'upmana' + os.sep + 'tmp' + os.sep + ignore.split('/')[len(ignore.split('/')) - 1])
+
+    def LoadDoc(self):
+        ignore = open(self.filename)
+        self.ignorelist = []
+        for i in ignore: self.ignorelist.append(str(i [:len(i)-1]))
+        manifest = ignore.readlines()
+        ignore.close()
+
+    def Finish(self, evt=None):
+        try: self.parent.Destroy()
+        except:
+            print 'Fail'; exit()
+
+    def ChooseBranch(self, evt=None):
+        dlg = wx.Dialog(self, wx.ID_ANY, "Package Selector", style=wx.DEFAULT_DIALOG_STYLE)
+        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 )
+        dlg.SetIcon(icon)
+
+        self.ui = ui.ui()
+        self.repo = hg.repository(self.ui, ".")
+        self.c = self.repo.changectx('tip')
+
+        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()
+
+        self.get_packages()
+        if self.package_list == None: return
+        types = self.package_list
+        row=0; col=0
+        self.current = self.repo.dirstate.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))
+            col += 1; self.id += 1
+            if col == 3: row += 1; col = 0
+
+        dlgsizer.Add(Yes, (row+1,col/2))
+        dlgsizer.AddGrowableCol(0)
+        dlgsizer.AddGrowableRow(0)
+        dlg.SetAutoLayout( True )
+        dlg.SetSizer( dlgsizer )
+        dlgsizer.Fit( dlg )
+        dlg.Centre()
+        dlg.Bind(wx.EVT_RADIOBUTTON, self.PackageSet)
+        if dlg.ShowModal(): dlg.Destroy()
+
+    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:
+            #r = hg.islocal()
+            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.BranchInfo(self.current)
+
+    def BranchInfo(self, branch):
+        self.filelist.SetValue('')
+        self.filelist.AppendText("Files that will change\n\n")
+        self.changelog.SetValue('')
+        changelog = "Traipse 'OpenRPG' Update Manager.\n\nThis is Dev Build 0.6.9(stable) of the Update Manager. This version is nearly 100% functional. Users can now add repositories of OpenRPG, choose from different branches available from those repositories, and add files to an ignore list.\n\nThe Update Manager is divided into tabs, Updater, Repos, Manifest, and Control. \n\nUpdater: Set your update type on startup; Auto, None. Select a package of changes from a branch and update.\n\nRepos: Collect repositories of different projects. Set a name then assign it a URL. Refresh repositories in your list or delete them from your list.\n\nManifest: A complete list of all the files in your current change set. Check files off that you want to be safe from future updates.\n\nControl: Incomplete. Future revisions will allow users to update to specific revision branchs and delete branches from their computer.\n\nThis is a good start. Enjoy the freedom!!"
+        self.changelog.AppendText(changelog + '\n')
+        self.filelist.AppendText("Traipse 'OpenRPG'\n\n Currently selected branch: " + branch + "\n\nFile List: When Control is completed this field will display a list of files that will be affected by your selection of branch.  The window to the left will display the description of the branch.\n\nDescription: Stable releases will have a formated Description that displays the Build Number, a summary of the branch, and a summary of the changes in the selected changeset.")
+
+        #### 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 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.
+        self.get_packages()
+        if self.package_list == None: return None
+        return None
+
+class Repos(wx.Panel):
+    def __init__(self, parent, openrpg, manifest):
+        wx.Panel.__init__(self, parent)
+
+        ### Update Manager
+        self.ui = ui.ui()
+        self.r = hg.repository(self.ui, ".")
+        self.c = self.r.changectx('tip')
+
+        #mainpanel = self
+        self.openrpg = openrpg
+        self.manifest = manifest
+        self.buttons = {}
+        self.texts = {}
+
+        ## Section Sizers (with frame edges and text captions)
+        self.box_sizers = {}
+        self.box_sizers["newbutton"] = wx.StaticBox(self, -1)
+
+        ## Layout Sizers
+        self.sizers = {}
+        self.sizers["main"] = wx.GridBagSizer(hgap=2, vgap=2)
+        self.sizers["button"] = wx.GridBagSizer(hgap=2, vgap=2)
+
+        #Button Layout
+        self.sizers["newbutton"] = wx.StaticBoxSizer(self.box_sizers["newbutton"], wx.VERTICAL)
+        self.sizers["newrepo_layout"] = wx.FlexGridSizer(rows=1, cols=2, hgap=2, vgap=5)
+        empty = wx.StaticText(self, -1, "")
+        reponame = wx.StaticText(self, -1, "Name:")
+        self.texts["reponame"] = wx.TextCtrl(self, -1, '')
+        self.buttons['addrepo'] = wx.Button(self, wx.ID_NEW)
+
+        ##Build Button
+        self.sizers["newrepo_layout"].Add(self.buttons['addrepo'], -1, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL)
+        self.sizers["newrepo_layout"].Add(empty, -1)
+        self.sizers["newrepo_layout"].Add(reponame, -1, wx.ALIGN_CENTER|wx.ALIGN_CENTER_VERTICAL|wx.ALL)
+        self.sizers["newrepo_layout"].Add(self.texts["reponame"], -1, wx.EXPAND)
+        self.sizers["newrepo_layout"].AddGrowableCol(1)
+        self.sizers["newbutton"].Add(self.sizers["newrepo_layout"], -1, wx.EXPAND)
+        #Repo List Panel
+        self.repopanel = wx.ScrolledWindow(self)
+        self.repopanel.SetScrollbars(20,20,55,40)
+        self.repopanel.Scroll(50,10)
+        self.box_sizers["repolist"] = wx.StaticBox(self.repopanel, -1, "Current Repo List")
+        self.sizers["repolist"] = wx.StaticBoxSizer(self.box_sizers["repolist"], wx.VERTICAL)
+        self.sizers["repo"] = wx.GridBagSizer(hgap=2, vgap=2)
+        self.sizers["repolist_layout"] = wx.FlexGridSizer(rows=1, cols=1, hgap=2, vgap=5)
+        self.manifest = manifest
+
+        self.NewRepoList(None)
+        self.BuildRepoList(None)
+
+        self.sizers["repolist_layout"].AddGrowableCol(0)
+        self.sizers["repolist"].Add(self.sizers["repolist_layout"], -1, wx.EXPAND)
+        self.sizers["repo"].Add(self.sizers["repolist"], (0,0), flag=wx.EXPAND)
+        self.sizers["repo"].AddGrowableCol(0)
+        self.sizers['repo'].AddGrowableRow(0)
+        self.sizers['repo'].AddGrowableRow(1)
+        self.repopanel.SetSizer(self.sizers['repo'])
+        self.repopanel.SetAutoLayout(True)
+
+        #Build Main Sizer
+        self.sizers["main"].Add(self.sizers["newbutton"], (0,0), flag=wx.EXPAND)
+        self.sizers["main"].Add(self.repopanel, (1,0), flag=wx.EXPAND)
+        self.sizers["main"].AddGrowableCol(0)
+        self.sizers["main"].AddGrowableCol(1)
+        self.sizers["main"].AddGrowableRow(1)
+        self.SetSizer(self.sizers["main"])
+        self.SetAutoLayout(True)
+        self.Fit()
+        self.Bind(wx.EVT_BUTTON, self.AddRepo, self.buttons['addrepo'])
+
+    def NewRepoList(self, event):
+        self.id = -1; self.box = {}; self.box_name= {}; self.main = {}; self.container = {}; self.layout = {}
+        self.name = {}; self.url = {}; self.url_list = {}; self.pull = {}; self.uri = {}; self.delete = {}
+        self.defaultcheck = {}; self.default = {}; self.repotrac = {}
+        self.pull_list = {}; self.delete_list = {}; self.defchecklist = {}
+
+    def BuildRepoList(self, event):
+        self.repolist = self.manifest.GetList('UpdateManifest', 'repolist', '')
+        try: self.repolist = self.repo
+        except: pass
+
+        #wx.Yeild()  For future refrence.
+
+        for repo in self.repolist:
+            self.id += 1
+            #Build Constructs
+            self.box[self.id] = wx.StaticBox(self.repopanel, -1, str(repo))
+            self.main[self.id] = wx.GridBagSizer(hgap=2, vgap=2)
+            self.container[self.id] = wx.StaticBoxSizer(self.box[self.id], wx.VERTICAL)
+            self.layout[self.id] = wx.FlexGridSizer(rows=1, cols=4, hgap=2, vgap=5)
+            self.name[self.id] = wx.StaticText(self.repopanel, -1, 'URL')
+            self.uri[self.id] = self.manifest.GetString('updaterepo', repo, '')
+            self.url[self.id] = wx.TextCtrl(self.repopanel, -1, self.uri[self.id])
+            self.pull[self.id] = wx.Button(self.repopanel, wx.ID_REFRESH)
+            self.delete[self.id] = wx.Button(self.repopanel, wx.ID_DELETE)
+            self.delete_list[self.delete[self.id]] = self.id
+            self.defaultcheck[self.id] = wx.CheckBox(self.repopanel, -1)
+            self.default[self.id] = wx.StaticText(self.repopanel, -1, 'Default')
+            #Build Retraceables
+            self.box_name[self.id] = str(repo)
+            self.pull_list[self.pull[self.id]] = self.id
+            self.defchecklist[self.defaultcheck[self.id]] = self.id
+            #Build Layout
+            self.layout[self.id].Add(self.name[self.id], -1, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL)
+            self.layout[self.id].Add(self.url[self.id], -1, wx.EXPAND)
+            self.layout[self.id].Add(self.pull[self.id], -1, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALL)
+            self.layout[self.id].Add(self.delete[self.id], -1, wx.EXPAND)
+            self.layout[self.id].Add(self.defaultcheck[self.id], -1, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALL)
+            self.layout[self.id].Add(self.default[self.id], -1, wx.EXPAND)
+            self.layout[self.id].AddGrowableCol(1)
+            self.container[self.id].Add(self.layout[self.id], -1, wx.EXPAND)
+            #Button Events
+            self.Bind(wx.EVT_BUTTON, self.RefreshRepo, self.pull[self.id])
+            self.Bind(wx.EVT_BUTTON, self.DelRepo, self.delete[self.id])
+            self.Bind(wx.EVT_CHECKBOX, self.SetDefault, self.defaultcheck[self.id])
+            self.sizers["repolist_layout"].Insert(0, self.container[self.id], -1, wx.EXPAND)
+            self.sizers['repolist_layout'].Layout()
+
+        #Set Default Repo Button
+        capture = self.manifest.GetString('updaterepo', 'default', '')
+        if capture != '':
+            for caught in self.uri:
+                if capture == self.uri[caught]: self.id = caught; pass
+                else: continue
+            self.defaultcheck[self.id].SetValue(True)
+
+    def AddRepo(self, event):
+        repo = self.texts['reponame'].GetValue(); repo = repo.replace(' ', '_'); repo = 'repo-' + repo
+        self.manifest.SetString('updaterepo', repo, ''); self.repo = repo.split(',')
+        repolist = self.manifest.GetList('UpdateManifest', 'repolist', '')
+        if repolist == '': pass
+        else: repolist = repolist + self.repo
+        self.manifest.SetList('UpdateManifest', 'repolist', repolist)
+        self.BuildRepoList(None)
+
+    def DelRepo(self, event):
+        self.id = self.delete_list[event.GetEventObject()]
+        self.sizers["repolist_layout"].Hide(self.container[self.id])
+        try: del self.box_name[self.id]
+        except: pass
+        self.manifest.SetList('UpdateManifest', 'repolist', list(self.box_name.values()))
+        self.sizers['repolist_layout'].Layout()
+
+    def RefreshRepo(self, event):
+        self.id = self.pull_list[event.GetEventObject()]
+        self.manifest.SetString('updaterepo', str(self.box_name[self.id]), self.url[self.id].GetValue())
+        try: commands.pull(self.ui, self.r, self.url[self.id].GetValue(), rev='', update=False, force=True)
+        except: pass
+
+    def SetDefault(self, event):
+        self.id = self.defchecklist[event.GetEventObject()]
+        self.manifest.SetString('updaterepo', 'default', self.uri[self.id])
+        for all in self.defaultcheck:
+            self.defaultcheck[all].SetValue(False)
+        self.defaultcheck[self.id].SetValue(True)
+
+class Manifest(wx.Panel):
+    def __init__(self, parent):
+        wx.Panel.__init__(self, parent)
+        self.ui = ui.ui()
+        self.repo = hg.repository(self.ui, ".")
+        self.c = self.repo.changectx('tip')
+        self.manifestlist = []
+        self.manifestlist = self.c.manifest().keys()
+        for mana in self.manifestlist: mana = os.sep + 'orpg' + os.sep + mana
+        self.manifestlist.sort()
+        self.SetBackgroundColour(wx.WHITE)
+        self.sizer = wx.GridBagSizer(hgap=1, vgap=1)
+        self.manifestlog = wx.CheckListBox( self, -1, wx.DefaultPosition, wx.DefaultSize, self.manifestlist, 
+            wx.LC_REPORT|wx.SUNKEN_BORDER|wx.EXPAND|wx.LC_HRULES)
+        filename = 'ignorelist.txt'
+        self.filename = orpg.dirpath.dir_struct["home"] + 'upmana' + os.sep + filename
+        orpg.tools.validate.Validate(orpg.dirpath.dir_struct["home"] + 'upmana' + os.sep).config_file(filename, "default_ignorelist.txt")
+        self.mana = self.LoadDoc()
+        self.manifestlog.Bind(wx.EVT_CHECKLISTBOX, self.GetChecked)
+        self.sizer.Add(self.manifestlog, (0,0), flag=wx.EXPAND)
+        self.sizer.AddGrowableCol(0)
+        self.sizer.AddGrowableRow(0)
+        self.SetSizer(self.sizer)
+        self.SetAutoLayout(True)
+
+    def GetChecked(self, event):
+        self.mana = []
+        for manifest in self.manifestlog.GetChecked(): self.mana.append(self.manifestlist[manifest])
+        self.SaveDoc()
+
+    def SaveDoc(self):
+        f = open(self.filename, "w")
+        for mana in self.mana: f.write(mana+'\n')
+        f.close()
+
+    def LoadDoc(self):
+        ignore = open(self.filename)
+        ignorelist = []
+        for i in ignore: ignorelist.append(str(i [:len(i)-1]))
+        for i in ignorelist: #Adds previously ignored files to manifestlistlog if they are not in changesets.
+            if self.c.manifest().has_key(i): continue
+            else: self.manifestlist.append(i); self.manifestlist.sort()
+        self.manifestlog.SetCheckedStrings(ignorelist)
+        manifest = ignore.readlines()
+        ignore.close()
+
+class Control(wx.Panel):
+    def __init__(self, parent):
+        wx.Panel.__init__(self, parent)
+
+
+class updaterFrame(wx.Frame):
+    def __init__(self, parent, title, openrpg, manifest, main):
+        wx.Frame.__init__(self, None, wx.ID_ANY, title, size=(700,480), 
+            style=wx.FRAME_NO_TASKBAR | wx.STAY_ON_TOP | wx.DEFAULT_FRAME_STYLE)
+        self.CenterOnScreen()
+
+        self.main = main
+        ####### Panel Stuff ######
+        p = wx.Panel(self)
+        nb = wx.Notebook(p)
+
+        # create the page windows as children of the notebook
+        page1 = Updater(nb, openrpg, manifest)
+        page2 = Repos(nb, openrpg, manifest)
+        page3 = Manifest(nb)
+        page4 = Control(nb)
+
+        # add the pages to the notebook with the label to show on the tab
+        nb.AddPage(page1, "Updater")
+        nb.AddPage(page2, "Repos")
+        nb.AddPage(page3, "Manifest")
+        nb.AddPage(page4, "Control")
+
+        # finally, put the notebook in a sizer for the panel to manage
+        # the layout
+        sizer = wx.BoxSizer()
+        sizer.Add(nb, 1, wx.EXPAND)
+        p.SetSizer(sizer)
+        self.Bind(wx.EVT_CLOSE, self.OnClose)
+
+    def OnClose(self, event):
+        if self.main == False: self.Destroy()
+        if self.main == True: self.Hide() #self.Hide()
+        #continue
+
+class updateApp(wx.App):
+    def OnInit(self):
+        self.open_rpg = open_rpg
+        self.main = False
+        self.log = orpg.tools.orpg_log.orpgLog(orpg.dirpath.dir_struct["user"] + "runlogs/")
+        self.log.setLogToConsol(False)
+        self.log.log("Updater Start", ORPG_NOTE)
+        self.manifest = manifest.ManifestChanges()
+        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.updater = updaterFrame(self, "OpenRPG Update Manager 0.6.9 (open beta)", self.open_rpg, self.manifest, self.main)
+        if self.manifest.GetString("updatemana", "auto_update", "") == 'on' and self.main == False:
+            self.AutoUpdate(); self.OnExit()
+        else: pass
+        if self.manifest.GetString('updatemana', 'no_update', '') == 'on' and self.main == False: 
+            self.OnExit()
+        else: pass
+        try:
+            self.updater.Show()
+            #self.SetTopWindow(self.updater)
+            self.updater.Fit()
+        except: pass
+        return True
+
+    def AutoUpdate(self):
+        self.ui = ui.ui()
+        self.repo = hg.repository(self.ui, ".")
+        self.c = self.repo.changectx('tip')
+        self.current = self.repo.dirstate.branch()
+
+        capture = self.manifest.GetString('updaterepo', 'default', '')
+        if capture != '':
+            commands.pull(self.ui, self.repo, capture, rev='', update=False, force=True)
+            filename = 'ignorelist.txt'
+            self.filename = orpg.dirpath.dir_struct["home"] + 'upmana' + os.sep + filename
+            orpg.tools.validate.Validate(orpg.dirpath.dir_struct["home"] + 'upmana' + os.sep).config_file(filename, "default_ignorelist.txt")
+            self.mana = self.LoadDoc()
+            for ignore in self.ignorelist: #Checked or not, if it is here, it is ignored.
+                try: shutil.copy(ignore, orpg.dirpath.dir_struct["home"] + 'upmana' + os.sep + 'tmp' + os.sep)
+                except: pass
+            hg.clean(self.repo, self.current)
+            for ignore in self.ignorelist:
+                try: shutil.copyfile(orpg.dirpath.dir_struct["home"] + 'upmana' + os.sep + 'tmp' + os.sep + ignore.split('/')[len(ignore.split('/')) - 1], ignore)
+                except: pass
+                try: os.remove(orpg.dirpath.dir_struct["home"] + 'upmana' + os.sep + 'tmp' + os.sep + ignore.split('/')[len(ignore.split('/')) - 1])
+                except: pass
+        else: print 'No default repository set, skipping Auto Update!'
+
+    def LoadDoc(self):
+        ignore = open(self.filename)
+        self.ignorelist = []
+        for i in ignore: self.ignorelist.append(str(i [:len(i)-1]))
+        manifest = ignore.readlines()
+        ignore.close()
+
+    def OnExit(self):
+        imported = ['manifest', 'orpg.dirpath', 'orpg.orpgCore', 'orpg.orpg_version', 'orpg.tools.orpg_log', 'orpg.tools.orpg_log', 'orpg.orpg_xml', 'orpg.dirpath', 'orpg.dirpath', 'orpg.tools.validate', 'mercurial.ui', 'mercurial.hg', 'mercurial.commands', 'mercurial.repo', 'mercurial.revlog', 'mercurial.cmdutil', 'shutil']
+        for name in imported:
+            if name in sys.modules: del sys.modules[name]
+
+        try: self.updater.Destroy()
+        except: pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/upmana/validate.py	Thu Aug 06 18:09:36 2009 -0500
@@ -0,0 +1,37 @@
+# file: config_files.py
+#
+# Author: Todd Faris (Snowdog)
+# Date:   5/10/2005
+#
+# Misc. config file service methods
+#
+
+import orpg.dirpath
+import os
+
+class Validate:
+    def __init__(self, userpath=None):
+        if userpath is None:
+            userpath = orpg.dirpath.dir_struct["user"]
+        self.__loadUserPath = userpath
+
+    def config_file(self, user_file, template_file):
+        #STEP 1: verify the template exists
+        if (not os.path.exists(orpg.dirpath.dir_struct["template"] + template_file)):
+            return 0
+
+        #STEP 2: verify the user file exists. If it doesn't then create it from template
+        if (not os.path.exists(self.__loadUserPath + user_file)):
+            default = open(orpg.dirpath.dir_struct["template"] + template_file,"r")
+            file = default.read()
+            newfile = open(self.__loadUserPath + user_file,"w")
+            newfile.write(file)
+            default.close()
+            newfile.close()
+            return 2  #returning 2 (True) so calling method will know if file was created
+
+        #STEP 3: user file exists (is openable) return 1 indicating no-create operation required
+        else: return 1
+
+    def ini_entry(self, entry_name, ini_file):
+        pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/upmana/xmltramp.py	Thu Aug 06 18:09:36 2009 -0500
@@ -0,0 +1,312 @@
+"""xmltramp: Make XML documents easily accessible."""
+
+__version__ = "2.16"
+__author__ = "Aaron Swartz"
+__credits__ = "Many thanks to pjz, bitsko, and DanC."
+__copyright__ = "(C) 2003 Aaron Swartz. GNU GPL 2."
+
+if not hasattr(__builtins__, 'True'): True, False = 1, 0
+def isstr(f): return isinstance(f, type('')) or isinstance(f, type(u''))
+def islst(f): return isinstance(f, type(())) or isinstance(f, type([]))
+
+empty = {'http://www.w3.org/1999/xhtml': ['img', 'br', 'hr', 'meta', 'link', 'base', 'param', 'input', 'col', 'area']}
+
+def quote(x, elt=True):
+    if elt and '<' in x and len(x) > 24 and x.find(']]>') == -1: return "<![CDATA["+x+"]]>"
+    else: x = x.replace('&', '&amp;').replace('<', '&lt;').replace(']]>', ']]&gt;')
+    if not elt: x = x.replace('"', '&quot;')
+    return x
+
+class Element:
+    def __init__(self, name, attrs=None, children=None, prefixes=None):
+        if islst(name) and name[0] == None: name = name[1]
+        if attrs:
+            na = {}
+            for k in attrs.keys():
+                if islst(k) and k[0] == None: na[k[1]] = attrs[k]
+                else: na[k] = attrs[k]
+            attrs = na
+        self._name = name
+        self._attrs = attrs or {}
+        self._dir = children or []
+        prefixes = prefixes or {}
+        self._prefixes = dict(zip(prefixes.values(), prefixes.keys()))
+        if prefixes: self._dNS = prefixes.get(None, None)
+        else: self._dNS = None
+
+    def __repr__(self, recursive=0, multiline=0, inprefixes=None):
+        def qname(name, inprefixes):
+            if islst(name):
+                if inprefixes[name[0]] is not None: return inprefixes[name[0]]+':'+name[1]
+                else: return name[1]
+            else: return name
+
+        def arep(a, inprefixes, addns=1):
+            out = ''
+            for p in self._prefixes.keys():
+                if not p in inprefixes.keys():
+                    if addns: out += ' xmlns'
+                    if addns and self._prefixes[p]: out += ':'+self._prefixes[p]
+                    if addns: out += '="'+quote(p, False)+'"'
+                    inprefixes[p] = self._prefixes[p]
+            for k in a.keys():
+                out += ' ' + qname(k, inprefixes)+ '="' + quote(a[k], False) + '"'
+            return out
+        inprefixes = inprefixes or {u'http://www.w3.org/XML/1998/namespace':'xml'}
+
+        # need to call first to set inprefixes:
+        attributes = arep(self._attrs, inprefixes, recursive)
+        out = '<' + qname(self._name, inprefixes)  + attributes
+        if not self._dir and (self._name[0] in empty.keys()
+          and self._name[1] in empty[self._name[0]]):
+            out += ' />'
+            return out
+        out += '>'
+        if recursive:
+            content = 0
+            for x in self._dir: 
+                if isinstance(x, Element): content = 1
+            pad = '\n' + ('\t' * recursive)
+            for x in self._dir:
+                if multiline and content: out +=  pad
+                if isstr(x): out += quote(x)
+                elif isinstance(x, Element): out += x.__repr__(recursive+1, multiline, inprefixes.copy())
+                else: raise TypeError, "I wasn't expecting "+`x`+"."
+            if multiline and content: out += '\n' + ('\t' * (recursive-1))
+        else: 
+            if self._dir: out += '...'
+        out += '</'+qname(self._name, inprefixes)+'>'
+        return out
+
+    def __unicode__(self):
+        text = ''
+        for x in self._dir: text += unicode(x)
+        return ' '.join(text.split())
+
+    def __str__(self):
+        return self.__unicode__().encode('utf-8')
+
+    def __getattr__(self, n):
+        if n[0] == '_': raise AttributeError, "Use foo['"+n+"'] to access the child element."
+        if self._dNS: n = (self._dNS, n)
+        for x in self._dir:
+            if isinstance(x, Element) and x._name == n: return x
+        raise AttributeError, 'No child element named \''+n+"'"
+
+    def __hasattr__(self, n):
+        for x in self._dir:
+            if isinstance(x, Element) and x._name == n: return True
+        return False
+
+    def __setattr__(self, n, v):
+        if n[0] == '_': self.__dict__[n] = v
+        else: self[n] = v
+
+    def __getitem__(self, n):
+        if isinstance(n, type(0)): # d[1] == d._dir[1]
+            return self._dir[n]
+        elif isinstance(n, slice(0).__class__):
+            # numerical slices
+            if isinstance(n.start, type(0)): return self._dir[n.start:n.stop]
+            # d['foo':] == all <foo>s
+            n = n.start
+            if self._dNS and not islst(n): n = (self._dNS, n)
+            out = []
+            for x in self._dir:
+                if isinstance(x, Element) and x._name == n: out.append(x)
+            return out
+        else: # d['foo'] == first <foo>
+            if self._dNS and not islst(n): n = (self._dNS, n)
+            for x in self._dir:
+                if isinstance(x, Element) and x._name == n: return x
+            raise KeyError
+
+    def __setitem__(self, n, v):
+        if isinstance(n, type(0)): # d[1]
+            self._dir[n] = v
+        elif isinstance(n, slice(0).__class__):
+            # d['foo':] adds a new foo
+            n = n.start
+            if self._dNS and not islst(n): n = (self._dNS, n)
+            nv = Element(n)
+            self._dir.append(nv)
+
+        else: # d["foo"] replaces first <foo> and dels rest
+            if self._dNS and not islst(n): n = (self._dNS, n)
+            nv = Element(n); nv._dir.append(v)
+            replaced = False
+            todel = []
+            for i in range(len(self)):
+                if self[i]._name == n:
+                    if replaced:
+                        todel.append(i)
+                    else:
+                        self[i] = nv
+                        replaced = True
+            if not replaced: self._dir.append(nv)
+            for i in todel: del self[i]
+
+    def __delitem__(self, n):
+        if isinstance(n, type(0)): del self._dir[n]
+        elif isinstance(n, slice(0).__class__):
+            # delete all <foo>s
+            n = n.start
+            if self._dNS and not islst(n): n = (self._dNS, n)
+            for i in range(len(self)):
+                if self[i]._name == n: del self[i]
+        else:
+            # delete first foo
+            for i in range(len(self)):
+                if self[i]._name == n: del self[i]
+                break
+
+    def __call__(self, *_pos, **_set):
+        if _set:
+            for k in _set.keys(): self._attrs[k] = _set[k]
+        if len(_pos) > 1:
+            for i in range(0, len(_pos), 2): self._attrs[_pos[i]] = _pos[i+1]
+        if len(_pos) == 1 is not None: return self._attrs[_pos[0]]
+        if len(_pos) == 0: return self._attrs
+
+    def __len__(self): return len(self._dir)
+
+class Namespace:
+    def __init__(self, uri): self.__uri = uri
+    def __getattr__(self, n): return (self.__uri, n)
+    def __getitem__(self, n): return (self.__uri, n)
+
+from xml.sax.handler import EntityResolver, DTDHandler, ContentHandler, ErrorHandler
+
+class Seeder(EntityResolver, DTDHandler, ContentHandler, ErrorHandler):
+    def __init__(self):
+        self.stack = []
+        self.ch = ''
+        self.prefixes = {}
+        ContentHandler.__init__(self)
+
+    def startPrefixMapping(self, prefix, uri):
+        if not self.prefixes.has_key(prefix): self.prefixes[prefix] = []
+        self.prefixes[prefix].append(uri)
+    def endPrefixMapping(self, prefix):
+        self.prefixes[prefix].pop()
+
+    def startElementNS(self, name, qname, attrs):
+        ch = self.ch; self.ch = ''
+        if ch and not ch.isspace(): self.stack[-1]._dir.append(ch)
+        attrs = dict(attrs)
+        newprefixes = {}
+        for k in self.prefixes.keys(): newprefixes[k] = self.prefixes[k][-1]
+        self.stack.append(Element(name, attrs, prefixes=newprefixes.copy()))
+
+    def characters(self, ch):
+        self.ch += ch
+
+    def endElementNS(self, name, qname):
+        ch = self.ch; self.ch = ''
+        if ch and not ch.isspace(): self.stack[-1]._dir.append(ch)
+        element = self.stack.pop()
+        if self.stack: self.stack[-1]._dir.append(element)
+        else: self.result = element
+
+from xml.sax import make_parser
+from xml.sax.handler import feature_namespaces
+
+def seed(fileobj):
+    seeder = Seeder()
+    parser = make_parser()
+    parser.setFeature(feature_namespaces, 1)
+    parser.setContentHandler(seeder)
+    parser.parse(fileobj)
+    return seeder.result
+
+def parse(text):
+    from StringIO import StringIO
+    return seed(StringIO(text))
+
+def load(url):
+    import urllib
+    return seed(urllib.urlopen(url))
+
+def unittest():
+    parse('<doc>a<baz>f<b>o</b>ob<b>a</b>r</baz>a</doc>').__repr__(1,1) == \
+      '<doc>\n\ta<baz>\n\t\tf<b>o</b>ob<b>a</b>r\n\t</baz>a\n</doc>'
+    assert str(parse("<doc />")) == ""
+    assert str(parse("<doc>I <b>love</b> you.</doc>")) == "I love you."
+    assert parse("<doc>\nmom\nwow\n</doc>")[0].strip() == "mom\nwow"
+    assert str(parse('<bing>  <bang> <bong>center</bong> </bang>  </bing>')) == "center"
+    assert str(parse('<doc>\xcf\x80</doc>')) == '\xcf\x80'
+    d = Element('foo', attrs={'foo':'bar'}, children=['hit with a', Element('bar'), Element('bar')])
+
+    try:
+        d._doesnotexist
+        raise "ExpectedError", "but found success. Damn."
+    except AttributeError: pass
+    assert d.bar._name == 'bar'
+    try:
+        d.doesnotexist
+        raise "ExpectedError", "but found success. Damn."
+    except AttributeError: pass
+    assert hasattr(d, 'bar') == True
+    assert d('foo') == 'bar'
+    d(silly='yes')
+    assert d('silly') == 'yes'
+    assert d() == d._attrs
+    assert d[0] == 'hit with a'
+    d[0] = 'ice cream'
+    assert d[0] == 'ice cream'
+    del d[0]
+    assert d[0]._name == "bar"
+    assert len(d[:]) == len(d._dir)
+    assert len(d[1:]) == len(d._dir) - 1
+    assert len(d['bar':]) == 2
+    d['bar':] = 'baz'
+    assert len(d['bar':]) == 3
+    assert d['bar']._name == 'bar'
+    d = Element('foo')
+    doc = Namespace("http://example.org/bar")
+    bbc = Namespace("http://example.org/bbc")
+    dc = Namespace("http://purl.org/dc/elements/1.1/")
+    d = parse("""<doc version="2.7182818284590451"
+      xmlns="http://example.org/bar"
+      xmlns:dc="http://purl.org/dc/elements/1.1/"
+      xmlns:bbc="http://example.org/bbc">
+            <author>John Polk and John Palfrey</author>
+            <dc:creator>John Polk</dc:creator>
+            <dc:creator>John Palfrey</dc:creator>
+            <bbc:show bbc:station="4">Buffy</bbc:show>
+    </doc>""")
+    assert repr(d) == '<doc version="2.7182818284590451">...</doc>'
+    assert d.__repr__(1) == '<doc xmlns:bbc="http://example.org/bbc" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns="http://example.org/bar" version="2.7182818284590451"><author>John Polk and John Palfrey</author><dc:creator>John Polk</dc:creator><dc:creator>John Palfrey</dc:creator><bbc:show bbc:station="4">Buffy</bbc:show></doc>'
+    assert d.__repr__(1,1) == '<doc xmlns:bbc="http://example.org/bbc" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns="http://example.org/bar" version="2.7182818284590451">\n\t<author>John Polk and John Palfrey</author>\n\t<dc:creator>John Polk</dc:creator>\n\t<dc:creator>John Palfrey</dc:creator>\n\t<bbc:show bbc:station="4">Buffy</bbc:show>\n</doc>'
+    assert repr(parse("<doc xml:lang='en' />")) == '<doc xml:lang="en"></doc>'
+    assert str(d.author) == str(d['author']) == "John Polk and John Palfrey"
+    assert d.author._name == doc.author
+    assert str(d[dc.creator]) == "John Polk"
+    assert d[dc.creator]._name == dc.creator
+    assert str(d[dc.creator:][1]) == "John Palfrey"
+    d[dc.creator] = "Me!!!"
+    assert str(d[dc.creator]) == "Me!!!"
+    assert len(d[dc.creator:]) == 1
+    d[dc.creator:] = "You!!!"
+    assert len(d[dc.creator:]) == 2
+    assert d[bbc.show](bbc.station) == "4"
+    d[bbc.show](bbc.station, "5")
+    assert d[bbc.show](bbc.station) == "5"
+    e = Element('e')
+    e.c = '<img src="foo">'
+    assert e.__repr__(1) == '<e><c>&lt;img src="foo"></c></e>'
+    e.c = '2 > 4'
+    assert e.__repr__(1) == '<e><c>2 > 4</c></e>'
+    e.c = 'CDATA sections are <em>closed</em> with ]]>.'
+    assert e.__repr__(1) == '<e><c>CDATA sections are &lt;em>closed&lt;/em> with ]]&gt;.</c></e>'
+    e.c = parse('<div xmlns="http://www.w3.org/1999/xhtml">i<br /><span></span>love<br />you</div>')
+    assert e.__repr__(1) == '<e><c><div xmlns="http://www.w3.org/1999/xhtml">i<br /><span></span>love<br />you</div></c></e>'
+    e = Element('e')
+    e('c', 'that "sucks"')
+    assert e.__repr__(1) == '<e c="that &quot;sucks&quot;"></e>'
+    assert quote("]]>") == "]]&gt;"
+    assert quote('< dkdkdsd dkd sksdksdfsd fsdfdsf]]> kfdfkg >') == '&lt; dkdkdsd dkd sksdksdfsd fsdfdsf]]&gt; kfdfkg >'
+    assert parse('<x a="&lt;"></x>').__repr__(1) == '<x a="&lt;"></x>'
+    assert parse('<a xmlns="http://a"><b xmlns="http://b"/></a>').__repr__(1) == '<a xmlns="http://a"><b xmlns="http://b"></b></a>'
+
+if __name__ == '__main__': unittest()