+++ /dev/null
-#!/usr/bin/python
-
-import sys, os, string
-
-if len(sys.argv) == 1:
- print """
- dfuzz : easy and light streaming tool
-
- Copyright (c) 2006 Guillaume Pellerin <yomguy@altern.org>
- distributed under the terms of the GNU Public License v2
-
- depends : ezstream (patched), icecast2, python,
-
- Usage : dfuzz $1 $2 $3 $4 $5
- where $1 : station name
- $2 : type (mp3 or ogg)
- $3 : number of sub-channels
- $4 : working directory
- $5 : audio directory
- $6 : icecast2 server name
- $7 : icecast2 port
- """
- sys.exit('')
-
-radio_name = sys.argv[1]
-nb_ch = int(sys.argv[3])
-type = sys.argv[2]
-work_dir = sys.argv[4]
-audio_dir = sys.argv[5]
-server = sys.argv[6]
-port = sys.argv[7]
-radio_description_file = work_dir+os.sep+radio_name+'.xml'
-dfuzz_dir = '/usr/local/share/d-fuzz'
-ez_tools_file = dfuzz_dir+os.sep+'d-fuzz_tools.py'
-
-f_descr = open(radio_description_file,'r')
-l_descr = f_descr.readlines()
-f_descr.close()
-
-f_ez_tools = open(ez_tools_file,'r')
-l_tools = f_ez_tools.readlines()
-f_ez_tools.close()
-
-for i in range(1,nb_ch+1):
- ch_name_i = radio_name+'_'+type+'_'+str(i)
- ch_ice_name_i = radio_name+'_'+str(i)
- ch_pre_i = work_dir+os.sep+ch_name_i
- fi_xml = open(ch_pre_i+'.xml','w')
- fi_xml.write('<ezstream>\n')
- fi_xml.write('<url>http://'+server+':'+port+'/'+ch_ice_name_i+'.'+type+'</url>\n')
- fi_xml.write('<format>'+string.upper(type)+'</format>\n')
- fi_xml.write('<filetype>script</filetype>\n')
- fi_xml.write('<filename>'+ch_pre_i+'.py</filename>\n')
- for line in l_descr:
- fi_xml.write(line)
- fi_xml.write('</ezstream>')
- fi_xml.close()
- fi_py = open(ch_pre_i+'.py','w')
- fi_py.write('#!/usr/bin/python\n\n')
- fi_py.write('import sys, os, random\n\n')
- fi_py.write('Playdir="'+audio_dir+os.sep+'"\n')
- fi_py.write('IndexFile="'+ch_pre_i+'_index.txt"\n')
- fi_py.write('RandomIndexListFile="'+ch_pre_i+'_random_index_list.txt"\n')
- fi_py.write('PlaylistLengthOrigFile="'+ch_pre_i+'_playlist_length.txt"\n\n')
- for line in l_tools:
- fi_py.write(line)
- fi_py.close()
- os.chmod(work_dir+os.sep+ch_name_i+'.py',0755)
- os.system('d-fuzz_loop '+ch_pre_i+' &')
- sys.exit(ch_pre_i+' started !')
-
-
-
+++ /dev/null
-#!/bin/sh
-ulimit -c unlimited
-while true; do
-ezstream -c $1.xml > /dev/null;
-sleep 3
-done
+++ /dev/null
-<sourcepassword>xxxxxxxxx</sourcepassword>
-<svrinfoname>Your title here</svrinfoname>
-<svrinfourl>Your URL here</svrinfourl>
-<svrinfogenre>Your genre here</svrinfogenre>
-<svrinfodescription>Your station description here</svrinfodescription>
-<svrinfobitrate>You nominal bitrate here</svrinfobitrate>
-<!-- Quality is only applicable to ogg vorbis streams -->
-<!-- <svrinfoquality>1.0</svrinfoquality> -->
-<svrinfochannels>The number of voices per channel</svrinfochannels>
-<svrinfosamplerate>The samplerate</svrinfosamplerate>
-<svrinfopublic>1</svrinfopublic>
+++ /dev/null
-#!/usr/bin/python
-
-#import sys, os, random
-
-#Playdir='/home/cellar/Cellar_playlist/'
-#IndexFile='/home/cellar/stream/d-fuzz_1_index.txt'
-#RandomIndexListFile='/home/cellar/stream/d-fuzz_1_random_index_list.txt'
-#PlaylistLengthOrigFile='/home/cellar/stream/d-fuzz_1_playlist_length.txt'
-
-def randrange(start, stop):
- values = range(start, stop)
- random.shuffle(values)
- while values:
- yield values.pop()
- raise StopIteration
-
-if not os.path.exists(IndexFile):
- fi=open(IndexFile,'w')
- fi.write("%d\n" % 0)
- fi.close()
-if not os.path.exists(RandomIndexListFile):
- fil=open(RandomIndexListFile,'w')
- fil.write("%d\n" % 0)
- fil.close()
-if not os.path.exists(PlaylistLengthOrigFile):
- fill=open(PlaylistLengthOrigFile,'w')
- fill.write("%d\n" % 0)
- fill.close()
-
-playlist = os.listdir(Playdir)
-nf = len(playlist)
-#print nf
-
-fill=open(PlaylistLengthOrigFile,'rw')
-
-nforig=int(fill.readline())
-
-if not nf == nforig:
- fil=open(RandomIndexListFile,'w')
- ril=randrange(0,nf)
- #print ril
- k=1
- for i in ril:
- fil.write("%d\n" % (i))
-# fil.close()
-
-fi=open(IndexFile,'rw')
-fil=open(RandomIndexListFile,'rw')
-
-#print nforig
-if nforig < nf:
- nforig = nf
-
-f_index=int(fi.readline())
-
-#tmpil = fil.readlines()
-f_index_list = range(nforig)
-j = 0
-for i in fil.readlines():
- f_index_list[j] = int(i)
- j+=1
- #print f_index_list[j]
-
-fi.close()
-fil.close()
-fill.close()
-
-if f_index == nf or f_index > nf:
- f_index = 0
-
-#print f_index_list[f_index]
-#print f_index
-print Playdir + playlist[f_index_list[f_index]]
-
-f_index+=1
-
-fi = open(IndexFile,'w')
-fi.write("%d" % (f_index))
-fi.close()
-
-fill=open(PlaylistLengthOrigFile,'w')
-fill.write("%d" % (nf))
-fill.close()
-
-
+++ /dev/null
-#!/usr/bin/env python
-
-# Easily import simple XML data to Python dictionary
-# http://www.gmta.info/publications/parsing-simple-xml-structure-to-a-python-dictionary
-
-import xml.dom.minidom
-
-def haschilds(dom):
-
- # Checks whether an element has any childs
- # containing real tags opposed to just text.
-
- for childnode in dom.childNodes:
- if childnode.nodeName != "#text" and childnode.nodeName != "#cdata-section":
- return True
-
- return False
-
-def indexchilds(dom, enc):
-
- childsdict = dict()
-
- for childnode in dom.childNodes:
-
- name = childnode.nodeName.encode(enc)
-
- if name == "#text" or name == "#cdata-section":
- # ignore whitespaces
- continue
-
- if haschilds(childnode):
- v = indexchilds(childnode, enc)
- else:
- v = childnode.childNodes[0].nodeValue.encode(enc)
-
- if name in childsdict:
-
- if isinstance(childsdict[name], dict):
- # there is multiple instances of this node - convert to list
- childsdict[name] = [childsdict[name]]
-
- childsdict[name].append(v)
-
- else:
-
- childsdict[name] = v
-
- return childsdict
-
-def xmltodict(data, enc=None):
-
- dom = xml.dom.minidom.parseString(data.strip())
- return indexchilds(dom, enc)
-
-
--- /dev/null
+#!/usr/bin/env python
+
+# Easily import simple XML data to Python dictionary
+# http://www.gmta.info/publications/parsing-simple-xml-structure-to-a-python-dictionary
+
+import xml.dom.minidom
+
+def haschilds(dom):
+
+ # Checks whether an element has any childs
+ # containing real tags opposed to just text.
+
+ for childnode in dom.childNodes:
+ if childnode.nodeName != "#text" and \
+ childnode.nodeName != "#cdata-section":
+ return True
+
+ return False
+
+def indexchilds(dom, enc):
+ childsdict = dict()
+
+ for childnode in dom.childNodes:
+ name = childnode.nodeName.encode(enc)
+ if name == "#text" or name == "#cdata-section":
+ # ignore whitespaces
+ continue
+
+ if haschilds(childnode):
+ v = indexchilds(childnode, enc)
+ else:
+ v = childnode.childNodes[0].nodeValue.encode(enc)
+
+ if name in childsdict:
+ if isinstance(childsdict[name], dict):
+ # there is multiple instances of this node - convert to list
+ childsdict[name] = [childsdict[name]]
+ childsdict[name].append(v)
+ else:
+ childsdict[name] = v
+
+ return childsdict
+
+def xmltodict(data, enc=None):
+ dom = xml.dom.minidom.parseString(data.strip())
+ return indexchilds(dom, enc)
+
+
--- /dev/null
+# -*- coding: utf-8 -*-
+""" xmltodict(): convert xml into tree of Python dicts.
+
+This was copied and modified from John Bair's recipe at aspn.activestate.com:
+ http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/149368
+"""
+import os
+import string
+import locale
+from xml.parsers import expat
+
+# If we're in Dabo, get the default encoding.
+#import dabo
+#import dabo.lib.DesignerUtils as desUtil
+#from dabo.dLocalize import _
+#from dabo.lib.utils import resolvePath
+#app = dabo.dAppRef
+#if app is not None:
+ #default_encoding = app.Encoding
+#else:
+ #enc = locale.getlocale()[1]
+ #if enc is None:
+ #enc = dabo.defaultEncoding
+ #default_encoding = enc
+
+# Python seems to need to compile code with \n linesep:
+code_linesep = "\n"
+eol = os.linesep
+
+
+class Xml2Obj:
+ """XML to Object"""
+ def __init__(self):
+ self.root = None
+ self.nodeStack = []
+ self.attsToSkip = []
+ self._inCode = False
+ self._mthdName = ""
+ self._mthdCode = ""
+ self._codeDict = None
+ self._inProp = False
+ self._propName = ""
+ self._propData = ""
+ self._propDict = None
+ self._currPropAtt = ""
+ self._currPropDict = None
+
+
+ def StartElement(self, name, attributes):
+ """SAX start element even handler"""
+ if name == "code":
+ # This is code for the parent element
+ self._inCode = True
+ parent = self.nodeStack[-1]
+ if not parent.has_key("code"):
+ parent["code"] = {}
+ self._codeDict = parent["code"]
+
+ elif name == "properties":
+ # These are the custom property definitions
+ self._inProp = True
+ self._propName = ""
+ self._propData = ""
+ parent = self.nodeStack[-1]
+ if not parent.has_key("properties"):
+ parent["properties"] = {}
+ self._propDict = parent["properties"]
+
+ else:
+ if self._inCode:
+ self._mthdName = name.encode()
+ elif self._inProp:
+ if self._propName:
+ # In the middle of a prop definition
+ self._currPropAtt = name.encode()
+ else:
+ self._propName = name.encode()
+ self._currPropDict = {}
+ self._currPropAtt = ""
+ else:
+ element = {"name": name.encode()}
+ if len(attributes) > 0:
+ for att in self.attsToSkip:
+ if attributes.has_key(att):
+ del attributes[att]
+ element["attributes"] = attributes
+
+ # Push element onto the stack and make it a child of parent
+ if len(self.nodeStack) > 0:
+ parent = self.nodeStack[-1]
+ if not parent.has_key("children"):
+ parent["children"] = []
+ parent["children"].append(element)
+ else:
+ self.root = element
+ self.nodeStack.append(element)
+
+
+ def EndElement(self, name):
+ """SAX end element event handler"""
+ if self._inCode:
+ if name == "code":
+ self._inCode = False
+ self._codeDict = None
+ else:
+ # End of an individual method
+ mth = self._mthdCode.strip()
+ if not mth.endswith("\n"):
+ mth += "\n"
+ self._codeDict[self._mthdName] = mth
+ self._mthdName = ""
+ self._mthdCode = ""
+ elif self._inProp:
+ if name == "properties":
+ self._inProp = False
+ self._propDict = None
+ elif name == self._propName:
+ # End of an individual prop definition
+ self._propDict[self._propName] = self._currPropDict
+ self._propName = ""
+ else:
+ # end of a property attribute
+ self._currPropDict[self._currPropAtt] = self._propData
+ self._propData = self._currPropAtt = ""
+ else:
+ self.nodeStack = self.nodeStack[:-1]
+
+
+ def CharacterData(self, data):
+ """SAX character data event handler"""
+ if self._inCode or data.strip():
+ data = data.replace("<", "<")
+ data = data.encode()
+ if self._inCode:
+ if self._mthdCode:
+ self._mthdCode += data
+ else:
+ self._mthdCode = data
+ elif self._inProp:
+ self._propData += data
+ else:
+ element = self.nodeStack[-1]
+ if not element.has_key("cdata"):
+ element["cdata"] = ""
+ element["cdata"] += data
+
+
+ def Parse(self, xml):
+ # Create a SAX parser
+ Parser = expat.ParserCreate()
+ # SAX event handlers
+ Parser.StartElementHandler = self.StartElement
+ Parser.EndElementHandler = self.EndElement
+ Parser.CharacterDataHandler = self.CharacterData
+ # Parse the XML File
+ ParserStatus = Parser.Parse(xml, 1)
+ return self.root
+
+
+ def ParseFromFile(self, filename):
+ return self.Parse(open(filename,"r").read())
+
+
+def xmltodict(xml, attsToSkip=[], addCodeFile=False):
+ """Given an xml string or file, return a Python dictionary."""
+ parser = Xml2Obj()
+ parser.attsToSkip = attsToSkip
+ isPath = os.path.exists(xml)
+ errmsg = ""
+ if eol not in xml and isPath:
+ # argument was a file
+ try:
+ ret = parser.ParseFromFile(xml)
+ except expat.ExpatError, e:
+ errmsg = _("The XML in '%s' is not well-formed and cannot be parsed: %s") % (xml, e)
+ else:
+ # argument must have been raw xml:
+ if not xml.strip().startswith("<?xml "):
+ # it's a bad file name
+ errmsg = _("The file '%s' could not be found") % xml
+ else:
+ try:
+ ret = parser.Parse(xml)
+ except expat.ExpatError:
+ errmsg = _("An invalid XML string was encountered")
+ if errmsg:
+ raise dabo.dException.XmlException, errmsg
+ if addCodeFile and isPath:
+ # Get the associated code file, if any
+ codePth = "%s-code.py" % os.path.splitext(xml)[0]
+ if os.path.exists(codePth):
+ try:
+ codeDict = desUtil.parseCodeFile(open(codePth).read())
+ desUtil.addCodeToClassDict(ret, codeDict)
+ except StandardError, e:
+ print "Failed to parse code file:", e
+ return ret
+
+
+def escQuote(val, noEscape=False, noQuote=False):
+ """Add surrounding quotes to the string, and escape
+ any illegal XML characters.
+ """
+ if not isinstance(val, basestring):
+ val = str(val)
+ if not isinstance(val, unicode):
+ val = unicode(val, default_encoding)
+ if noQuote:
+ qt = ''
+ else:
+ qt = '"'
+ slsh = "\\"
+# val = val.replace(slsh, slsh+slsh)
+ if not noEscape:
+ # First escape internal ampersands. We need to double them up due to a
+ # quirk in wxPython and the way it displays this character.
+ val = val.replace("&", "&&")
+ # Escape any internal quotes
+ val = val.replace('"', '"').replace("'", "'")
+ # Escape any high-order characters
+ chars = []
+ for pos, char in enumerate(list(val)):
+ if ord(char) > 127:
+ chars.append("&#%s;" % ord(char))
+ else:
+ chars.append(char)
+ val = "".join(chars)
+ val = val.replace("<", "<").replace(">", ">")
+ return "%s%s%s" % (qt, val, qt)
+
+
+def dicttoxml(dct, level=0, header=None, linesep=None):
+ """Given a Python dictionary, return an xml string.
+
+ The dictionary must be in the format returned by dicttoxml(), with keys
+ on "attributes", "code", "cdata", "name", and "children".
+
+ Send your own XML header, otherwise a default one will be used.
+
+ The linesep argument is a dictionary, with keys on levels, allowing the
+ developer to add extra whitespace depending on the level.
+ """
+ att = ""
+ ret = ""
+
+ if dct.has_key("attributes"):
+ for key, val in dct["attributes"].items():
+ # Some keys are already handled.
+ noEscape = key in ("sizerInfo",)
+ val = escQuote(val, noEscape)
+ att += " %s=%s" % (key, val)
+ ret += "%s<%s%s" % ("\t" * level, dct["name"], att)
+
+ if (not dct.has_key("cdata") and not dct.has_key("children")
+ and not dct.has_key("code") and not dct.has_key("properties")):
+ ret += " />%s" % eol
+ else:
+ ret += ">"
+ if dct.has_key("cdata"):
+ ret += "%s" % dct["cdata"].replace("<", "<")
+
+ if dct.has_key("code"):
+ if len(dct["code"].keys()):
+ ret += "%s%s<code>%s" % (eol, "\t" * (level+1), eol)
+ methodTab = "\t" * (level+2)
+ for mthd, cd in dct["code"].items():
+ # Convert \n's in the code to eol:
+ cd = eol.join(cd.splitlines())
+
+ # Make sure that the code ends with a linefeed
+ if not cd.endswith(eol):
+ cd += eol
+
+ ret += "%s<%s><![CDATA[%s%s]]>%s%s</%s>%s" % (methodTab,
+ mthd, eol, cd, eol,
+ methodTab, mthd, eol)
+ ret += "%s</code>%s" % ("\t" * (level+1), eol)
+
+ if dct.has_key("properties"):
+ if len(dct["properties"].keys()):
+ ret += "%s%s<properties>%s" % (eol, "\t" * (level+1), eol)
+ currTab = "\t" * (level+2)
+ for prop, val in dct["properties"].items():
+ ret += "%s<%s>%s" % (currTab, prop, eol)
+ for propItm, itmVal in val.items():
+ itmTab = "\t" * (level+3)
+ ret += "%s<%s>%s</%s>%s" % (itmTab, propItm, itmVal,
+ propItm, eol)
+ ret += "%s</%s>%s" % (currTab, prop, eol)
+ ret += "%s</properties>%s" % ("\t" * (level+1), eol)
+
+ if dct.has_key("children") and len(dct["children"]) > 0:
+ ret += eol
+ for child in dct["children"]:
+ ret += dicttoxml(child, level+1, linesep=linesep)
+ indnt = ""
+ if ret.endswith(eol):
+ # Indent the closing tag
+ indnt = ("\t" * level)
+ ret += "%s</%s>%s" % (indnt, dct["name"], eol)
+
+ if linesep:
+ ret += linesep.get(level, "")
+
+ if level == 0:
+ if header is None:
+ header = '<?xml version="1.0" encoding="%s" standalone="no"?>%s' \
+ % (default_encoding, eol)
+ ret = header + ret
+
+ return ret
+
+
+def flattenClassDict(cd, retDict=None):
+ """Given a dict containing a series of nested objects such as would
+ be created by restoring from a cdxml file, returns a dict with all classIDs
+ as keys, and a dict as the corresponding value. The dict value will have
+ keys for the attributes and/or code, depending on what was in the original
+ dict. The end result is to take a nested dict structure and return a flattened
+ dict with all objects at the top level.
+ """
+ if retDict is None:
+ retDict = {}
+ atts = cd.get("attributes", {})
+ props = cd.get("properties", {})
+ kids = cd.get("children", [])
+ code = cd.get("code", {})
+ classID = atts.get("classID", "")
+ classFile = resolvePath(atts.get("designerClass", ""))
+ superclass = resolvePath(atts.get("superclass", ""))
+ superclassID = atts.get("superclassID", "")
+ if superclassID and os.path.exists(superclass):
+ # Get the superclass info
+ superCD = xmltodict(superclass, addCodeFile=True)
+ flattenClassDict(superCD, retDict)
+ if classID:
+ if os.path.exists(classFile):
+ # Get the class info
+ classCD = xmltodict(classFile, addCodeFile=True)
+ classAtts = classCD.get("attributes", {})
+ classProps = classCD.get("properties", {})
+ classCode = classCD.get("code", {})
+ classKids = classCD.get("children", [])
+ currDict = retDict.get(classID, {})
+ retDict[classID] = {"attributes": classAtts, "code": classCode,
+ "properties": classProps}
+ retDict[classID].update(currDict)
+ # Now update the child objects in the dict
+ for kid in classKids:
+ flattenClassDict(kid, retDict)
+ else:
+ # Not a file; most likely just a component in another class
+ currDict = retDict.get(classID, {})
+ retDict[classID] = {"attributes": atts, "code": code,
+ "properties": props}
+ retDict[classID].update(currDict)
+ if kids:
+ for kid in kids:
+ flattenClassDict(kid, retDict)
+ return retDict
+
+
+def addInheritedInfo(src, super, updateCode=False):
+ """Called recursively on the class container structure, modifying
+ the attributes to incorporate superclass information. When the
+ 'updateCode' parameter is True, superclass code is added to the
+ object's code
+ """
+ atts = src.get("attributes", {})
+ props = src.get("properties", {})
+ kids = src.get("children", [])
+ code = src.get("code", {})
+ classID = atts.get("classID", "")
+ if classID:
+ superInfo = super.get(classID, {"attributes": {}, "code": {}, "properties": {}})
+ src["attributes"] = superInfo["attributes"].copy()
+ src["attributes"].update(atts)
+ src["properties"] = superInfo.get("properties", {}).copy()
+ src["properties"].update(props)
+ if updateCode:
+ src["code"] = superInfo["code"].copy()
+ src["code"].update(code)
+ if kids:
+ for kid in kids:
+ addInheritedInfo(kid, super, updateCode)
+
+
+
+#if __name__ == "__main__":
+ #test_dict = {"name": "test", "attributes":{"path": "c:\\temp\\name",
+ #"problemChars": "Welcome to <Jos\xc3\xa9's \ Stuff!>\xc2\xae".decode("latin-1")}}
+ #print "test_dict:", test_dict
+ #xml = dicttoxml(test_dict)
+ #print "xml:", xml
+ #test_dict2 = xmltodict(xml)
+ #print "test_dict2:", test_dict2
+ #print "same?:", test_dict == test_dict2
+++ /dev/null
-#!/usr/bin/env python
-
-# Easily import simple XML data to Python dictionary
-# http://www.gmta.info/publications/parsing-simple-xml-structure-to-a-python-dictionary
-
-import xml.dom.minidom
-
-def haschilds(dom):
-
- # Checks whether an element has any childs
- # containing real tags opposed to just text.
-
- for childnode in dom.childNodes:
- if childnode.nodeName != "#text" and \
- childnode.nodeName != "#cdata-section":
- return True
-
- return False
-
-def indexchilds(dom, enc):
- childsdict = dict()
-
- for childnode in dom.childNodes:
- name = childnode.nodeName.encode(enc)
- if name == "#text" or name == "#cdata-section":
- # ignore whitespaces
- continue
-
- if haschilds(childnode):
- v = indexchilds(childnode, enc)
- else:
- v = childnode.childNodes[0].nodeValue.encode(enc)
-
- if name in childsdict:
- if isinstance(childsdict[name], dict):
- # there is multiple instances of this node - convert to list
- childsdict[name] = [childsdict[name]]
- childsdict[name].append(v)
- else:
- childsdict[name] = v
-
- return childsdict
-
-def xmltodict(data, enc=None):
- dom = xml.dom.minidom.parseString(data.strip())
- return indexchilds(dom, enc)
-
-
+++ /dev/null
-# -*- coding: utf-8 -*-
-""" xmltodict(): convert xml into tree of Python dicts.
-
-This was copied and modified from John Bair's recipe at aspn.activestate.com:
- http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/149368
-"""
-import os
-import string
-import locale
-from xml.parsers import expat
-
-# If we're in Dabo, get the default encoding.
-#import dabo
-#import dabo.lib.DesignerUtils as desUtil
-#from dabo.dLocalize import _
-#from dabo.lib.utils import resolvePath
-#app = dabo.dAppRef
-#if app is not None:
- #default_encoding = app.Encoding
-#else:
- #enc = locale.getlocale()[1]
- #if enc is None:
- #enc = dabo.defaultEncoding
- #default_encoding = enc
-
-# Python seems to need to compile code with \n linesep:
-code_linesep = "\n"
-eol = os.linesep
-
-
-class Xml2Obj:
- """XML to Object"""
- def __init__(self):
- self.root = None
- self.nodeStack = []
- self.attsToSkip = []
- self._inCode = False
- self._mthdName = ""
- self._mthdCode = ""
- self._codeDict = None
- self._inProp = False
- self._propName = ""
- self._propData = ""
- self._propDict = None
- self._currPropAtt = ""
- self._currPropDict = None
-
-
- def StartElement(self, name, attributes):
- """SAX start element even handler"""
- if name == "code":
- # This is code for the parent element
- self._inCode = True
- parent = self.nodeStack[-1]
- if not parent.has_key("code"):
- parent["code"] = {}
- self._codeDict = parent["code"]
-
- elif name == "properties":
- # These are the custom property definitions
- self._inProp = True
- self._propName = ""
- self._propData = ""
- parent = self.nodeStack[-1]
- if not parent.has_key("properties"):
- parent["properties"] = {}
- self._propDict = parent["properties"]
-
- else:
- if self._inCode:
- self._mthdName = name.encode()
- elif self._inProp:
- if self._propName:
- # In the middle of a prop definition
- self._currPropAtt = name.encode()
- else:
- self._propName = name.encode()
- self._currPropDict = {}
- self._currPropAtt = ""
- else:
- element = {"name": name.encode()}
- if len(attributes) > 0:
- for att in self.attsToSkip:
- if attributes.has_key(att):
- del attributes[att]
- element["attributes"] = attributes
-
- # Push element onto the stack and make it a child of parent
- if len(self.nodeStack) > 0:
- parent = self.nodeStack[-1]
- if not parent.has_key("children"):
- parent["children"] = []
- parent["children"].append(element)
- else:
- self.root = element
- self.nodeStack.append(element)
-
-
- def EndElement(self, name):
- """SAX end element event handler"""
- if self._inCode:
- if name == "code":
- self._inCode = False
- self._codeDict = None
- else:
- # End of an individual method
- mth = self._mthdCode.strip()
- if not mth.endswith("\n"):
- mth += "\n"
- self._codeDict[self._mthdName] = mth
- self._mthdName = ""
- self._mthdCode = ""
- elif self._inProp:
- if name == "properties":
- self._inProp = False
- self._propDict = None
- elif name == self._propName:
- # End of an individual prop definition
- self._propDict[self._propName] = self._currPropDict
- self._propName = ""
- else:
- # end of a property attribute
- self._currPropDict[self._currPropAtt] = self._propData
- self._propData = self._currPropAtt = ""
- else:
- self.nodeStack = self.nodeStack[:-1]
-
-
- def CharacterData(self, data):
- """SAX character data event handler"""
- if self._inCode or data.strip():
- data = data.replace("<", "<")
- data = data.encode()
- if self._inCode:
- if self._mthdCode:
- self._mthdCode += data
- else:
- self._mthdCode = data
- elif self._inProp:
- self._propData += data
- else:
- element = self.nodeStack[-1]
- if not element.has_key("cdata"):
- element["cdata"] = ""
- element["cdata"] += data
-
-
- def Parse(self, xml):
- # Create a SAX parser
- Parser = expat.ParserCreate()
- # SAX event handlers
- Parser.StartElementHandler = self.StartElement
- Parser.EndElementHandler = self.EndElement
- Parser.CharacterDataHandler = self.CharacterData
- # Parse the XML File
- ParserStatus = Parser.Parse(xml, 1)
- return self.root
-
-
- def ParseFromFile(self, filename):
- return self.Parse(open(filename,"r").read())
-
-
-def xmltodict(xml, attsToSkip=[], addCodeFile=False):
- """Given an xml string or file, return a Python dictionary."""
- parser = Xml2Obj()
- parser.attsToSkip = attsToSkip
- isPath = os.path.exists(xml)
- errmsg = ""
- if eol not in xml and isPath:
- # argument was a file
- try:
- ret = parser.ParseFromFile(xml)
- except expat.ExpatError, e:
- errmsg = _("The XML in '%s' is not well-formed and cannot be parsed: %s") % (xml, e)
- else:
- # argument must have been raw xml:
- if not xml.strip().startswith("<?xml "):
- # it's a bad file name
- errmsg = _("The file '%s' could not be found") % xml
- else:
- try:
- ret = parser.Parse(xml)
- except expat.ExpatError:
- errmsg = _("An invalid XML string was encountered")
- if errmsg:
- raise dabo.dException.XmlException, errmsg
- if addCodeFile and isPath:
- # Get the associated code file, if any
- codePth = "%s-code.py" % os.path.splitext(xml)[0]
- if os.path.exists(codePth):
- try:
- codeDict = desUtil.parseCodeFile(open(codePth).read())
- desUtil.addCodeToClassDict(ret, codeDict)
- except StandardError, e:
- print "Failed to parse code file:", e
- return ret
-
-
-def escQuote(val, noEscape=False, noQuote=False):
- """Add surrounding quotes to the string, and escape
- any illegal XML characters.
- """
- if not isinstance(val, basestring):
- val = str(val)
- if not isinstance(val, unicode):
- val = unicode(val, default_encoding)
- if noQuote:
- qt = ''
- else:
- qt = '"'
- slsh = "\\"
-# val = val.replace(slsh, slsh+slsh)
- if not noEscape:
- # First escape internal ampersands. We need to double them up due to a
- # quirk in wxPython and the way it displays this character.
- val = val.replace("&", "&&")
- # Escape any internal quotes
- val = val.replace('"', '"').replace("'", "'")
- # Escape any high-order characters
- chars = []
- for pos, char in enumerate(list(val)):
- if ord(char) > 127:
- chars.append("&#%s;" % ord(char))
- else:
- chars.append(char)
- val = "".join(chars)
- val = val.replace("<", "<").replace(">", ">")
- return "%s%s%s" % (qt, val, qt)
-
-
-def dicttoxml(dct, level=0, header=None, linesep=None):
- """Given a Python dictionary, return an xml string.
-
- The dictionary must be in the format returned by dicttoxml(), with keys
- on "attributes", "code", "cdata", "name", and "children".
-
- Send your own XML header, otherwise a default one will be used.
-
- The linesep argument is a dictionary, with keys on levels, allowing the
- developer to add extra whitespace depending on the level.
- """
- att = ""
- ret = ""
-
- if dct.has_key("attributes"):
- for key, val in dct["attributes"].items():
- # Some keys are already handled.
- noEscape = key in ("sizerInfo",)
- val = escQuote(val, noEscape)
- att += " %s=%s" % (key, val)
- ret += "%s<%s%s" % ("\t" * level, dct["name"], att)
-
- if (not dct.has_key("cdata") and not dct.has_key("children")
- and not dct.has_key("code") and not dct.has_key("properties")):
- ret += " />%s" % eol
- else:
- ret += ">"
- if dct.has_key("cdata"):
- ret += "%s" % dct["cdata"].replace("<", "<")
-
- if dct.has_key("code"):
- if len(dct["code"].keys()):
- ret += "%s%s<code>%s" % (eol, "\t" * (level+1), eol)
- methodTab = "\t" * (level+2)
- for mthd, cd in dct["code"].items():
- # Convert \n's in the code to eol:
- cd = eol.join(cd.splitlines())
-
- # Make sure that the code ends with a linefeed
- if not cd.endswith(eol):
- cd += eol
-
- ret += "%s<%s><![CDATA[%s%s]]>%s%s</%s>%s" % (methodTab,
- mthd, eol, cd, eol,
- methodTab, mthd, eol)
- ret += "%s</code>%s" % ("\t" * (level+1), eol)
-
- if dct.has_key("properties"):
- if len(dct["properties"].keys()):
- ret += "%s%s<properties>%s" % (eol, "\t" * (level+1), eol)
- currTab = "\t" * (level+2)
- for prop, val in dct["properties"].items():
- ret += "%s<%s>%s" % (currTab, prop, eol)
- for propItm, itmVal in val.items():
- itmTab = "\t" * (level+3)
- ret += "%s<%s>%s</%s>%s" % (itmTab, propItm, itmVal,
- propItm, eol)
- ret += "%s</%s>%s" % (currTab, prop, eol)
- ret += "%s</properties>%s" % ("\t" * (level+1), eol)
-
- if dct.has_key("children") and len(dct["children"]) > 0:
- ret += eol
- for child in dct["children"]:
- ret += dicttoxml(child, level+1, linesep=linesep)
- indnt = ""
- if ret.endswith(eol):
- # Indent the closing tag
- indnt = ("\t" * level)
- ret += "%s</%s>%s" % (indnt, dct["name"], eol)
-
- if linesep:
- ret += linesep.get(level, "")
-
- if level == 0:
- if header is None:
- header = '<?xml version="1.0" encoding="%s" standalone="no"?>%s' \
- % (default_encoding, eol)
- ret = header + ret
-
- return ret
-
-
-def flattenClassDict(cd, retDict=None):
- """Given a dict containing a series of nested objects such as would
- be created by restoring from a cdxml file, returns a dict with all classIDs
- as keys, and a dict as the corresponding value. The dict value will have
- keys for the attributes and/or code, depending on what was in the original
- dict. The end result is to take a nested dict structure and return a flattened
- dict with all objects at the top level.
- """
- if retDict is None:
- retDict = {}
- atts = cd.get("attributes", {})
- props = cd.get("properties", {})
- kids = cd.get("children", [])
- code = cd.get("code", {})
- classID = atts.get("classID", "")
- classFile = resolvePath(atts.get("designerClass", ""))
- superclass = resolvePath(atts.get("superclass", ""))
- superclassID = atts.get("superclassID", "")
- if superclassID and os.path.exists(superclass):
- # Get the superclass info
- superCD = xmltodict(superclass, addCodeFile=True)
- flattenClassDict(superCD, retDict)
- if classID:
- if os.path.exists(classFile):
- # Get the class info
- classCD = xmltodict(classFile, addCodeFile=True)
- classAtts = classCD.get("attributes", {})
- classProps = classCD.get("properties", {})
- classCode = classCD.get("code", {})
- classKids = classCD.get("children", [])
- currDict = retDict.get(classID, {})
- retDict[classID] = {"attributes": classAtts, "code": classCode,
- "properties": classProps}
- retDict[classID].update(currDict)
- # Now update the child objects in the dict
- for kid in classKids:
- flattenClassDict(kid, retDict)
- else:
- # Not a file; most likely just a component in another class
- currDict = retDict.get(classID, {})
- retDict[classID] = {"attributes": atts, "code": code,
- "properties": props}
- retDict[classID].update(currDict)
- if kids:
- for kid in kids:
- flattenClassDict(kid, retDict)
- return retDict
-
-
-def addInheritedInfo(src, super, updateCode=False):
- """Called recursively on the class container structure, modifying
- the attributes to incorporate superclass information. When the
- 'updateCode' parameter is True, superclass code is added to the
- object's code
- """
- atts = src.get("attributes", {})
- props = src.get("properties", {})
- kids = src.get("children", [])
- code = src.get("code", {})
- classID = atts.get("classID", "")
- if classID:
- superInfo = super.get(classID, {"attributes": {}, "code": {}, "properties": {}})
- src["attributes"] = superInfo["attributes"].copy()
- src["attributes"].update(atts)
- src["properties"] = superInfo.get("properties", {}).copy()
- src["properties"].update(props)
- if updateCode:
- src["code"] = superInfo["code"].copy()
- src["code"].update(code)
- if kids:
- for kid in kids:
- addInheritedInfo(kid, super, updateCode)
-
-
-
-#if __name__ == "__main__":
- #test_dict = {"name": "test", "attributes":{"path": "c:\\temp\\name",
- #"problemChars": "Welcome to <Jos\xc3\xa9's \ Stuff!>\xc2\xae".decode("latin-1")}}
- #print "test_dict:", test_dict
- #xml = dicttoxml(test_dict)
- #print "xml:", xml
- #test_dict2 = xmltodict(xml)
- #print "test_dict2:", test_dict2
- #print "same?:", test_dict == test_dict2