home *** CD-ROM | disk | FTP | other *** search
/ Clickx 96 / Clickx 96.iso / software / tools / tool / xbmc-10.1.exe / addons / script.rss.editor / resources / lib / xmlParser.py < prev   
Encoding:
Python Source  |  2011-03-08  |  6.4 KB  |  148 lines

  1. import os, sys
  2. from xml.dom.minidom import parse, Document, _write_data, Node, Element
  3. import xbmcaddon
  4.  
  5. try:
  6.     import xbmc
  7.     import xbmcgui
  8. except:
  9.     xbmc = None
  10.  
  11.  
  12. def writexml(self, writer, indent="", addindent="", newl=""):
  13.     #credit: http://ronrothman.com/public/leftbraned/xml-dom-minidom-toprettyxml-and-silly-whitespace/
  14.     writer.write(indent+"<" + self.tagName)
  15.     attrs = self._get_attributes()
  16.     a_names = attrs.keys()
  17.     a_names.sort()
  18.     for a_name in a_names:
  19.         writer.write(" %s=\"" % a_name)
  20.         _write_data(writer, attrs[a_name].value)
  21.         writer.write("\"")
  22.     if self.childNodes:
  23.         if len(self.childNodes) == 1 \
  24.           and self.childNodes[0].nodeType == Node.TEXT_NODE:
  25.             writer.write(">")
  26.             self.childNodes[0].writexml(writer, "", "", "")
  27.             writer.write("</%s>%s" % (self.tagName, newl))
  28.             return
  29.         writer.write(">%s" % (newl))
  30.         for node in self.childNodes:
  31.             node.writexml(writer, indent+addindent, addindent, newl)
  32.         writer.write("%s</%s>%s" % (indent, self.tagName, newl))
  33.     else:
  34.         writer.write("/>%s" % (newl))
  35.  
  36. # monkey patch to fix whitespace issues with toprettyxml
  37. Element.writexml = writexml
  38. #enable localization
  39. getLS = sys.modules[ "__main__" ].__language__
  40.  
  41.  
  42. class XMLParser:
  43.  
  44.     def __init__(self):
  45.         if xbmc:
  46.             self.RssFeedsPath = xbmc.translatePath('special://userdata/RssFeeds.xml')
  47.         else:
  48.             self.RssFeedsPath = r'C:\Documents and Settings\Xerox\Application Data\XBMC\userdata\RssFeeds.xml'
  49.         sane = self.checkRssFeedPathSanity()
  50.         if sane:
  51.             try:
  52.                 self.feedsTree = parse(self.RssFeedsPath)
  53.             except:
  54.                 print '[script] RSS Editor --> Failed to parse ' + self.RssFeedsPath
  55.                 regen = xbmcgui.Dialog().yesno(getLS(40), getLS(51), getLS(52), getLS(53))
  56.                 if regen:
  57.                     print '[script] RSS Editor --> Attempting to Regenerate RssFeeds.xml'
  58.                     xml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<rssfeeds>\n\
  59.                     <!-- RSS feeds. To have multiple feeds, just add a feed to the set. You can also have multiple sets.     !-->\n\
  60.                     <!-- To use different sets in your skin, each must be called from skin with a unique id.                 !-->\n\
  61.                     <set id="1">\n    <feed updateinterval="30">http://feeds.feedburner.com/xbmc</feed>\n  </set>\n</rssfeeds>'
  62.                     f = open(self.RssFeedsPath, 'w')
  63.                     f.write(xml)
  64.                     f.close()
  65.                     self.__init__()
  66.                 else:
  67.                     print '[script] RSS Editor --> User opted to not regenerate RssFeeds.xml.  Script Exiting'
  68.                     self.feedsTree = False
  69.             if self.feedsTree:
  70.                 self.feedsList = self.getCurrentRssFeeds()
  71.         else:
  72.             self.feedsList = False
  73.             print '[SCRIPT] RSS Editor --> Could not open ' + self.RssFeedsPath +'. Either the file does not exist, or its\
  74.                 size is zero.'
  75.  
  76.     def checkRssFeedPathSanity(self):
  77.         if os.path.isfile(self.RssFeedsPath):
  78.             #If the filesize is zero, the parsing will fail.  XBMC creates 
  79.             if os.path.getsize(self.RssFeedsPath):
  80.                 return True
  81.  
  82.     def getCurrentRssFeeds(self):
  83.         feedsList = dict()
  84.         sets = self.feedsTree.getElementsByTagName('set')
  85.         for s in sets:
  86.             setName = 'set'+s.attributes["id"].value
  87.             feedsList[setName] = {'feedslist':list(), 'attrs':dict()}
  88.             #get attrs
  89.             for attrib in s.attributes.keys():
  90.                 feedsList[setName]['attrs'][attrib] = s.attributes[attrib].value
  91.             #get feedslist
  92.             feeds = s.getElementsByTagName('feed')
  93.             for feed in feeds:
  94.                 feedsList[setName]['feedslist'].append({'url':feed.firstChild.toxml(), 'updateinterval':feed.attributes['updateinterval'].value})
  95.         return feedsList
  96.  
  97.     def formXml(self):
  98.         """Form the XML to be written to RssFeeds.xml"""
  99.         #create the document
  100.         doc = Document()
  101.         #create root element
  102.         rssfeedsTag = doc.createElement('rssfeeds')
  103.         doc.appendChild(rssfeedsTag)
  104.         #create comments
  105.         c1Tag = doc.createComment('RSS feeds. To have multiple feeds, just add a feed to the set. You can also have multiple sets.')
  106.         c2Tag = doc.createComment('To use different sets in your skin, each must be called from skin with a unique id.')
  107.         rssfeedsTag.appendChild(c1Tag)
  108.         rssfeedsTag.appendChild(c2Tag)
  109.         for setNum in sorted(self.feedsList.keys()):
  110.             #create sets
  111.             setTag = doc.createElement('set')
  112.             #create attributes
  113.             setTag.setAttribute('id', self.feedsList[setNum]['attrs']['id'])
  114.             #only write rtl tags if they've been explicitly set
  115.             if 'rtl' in self.feedsList[setNum]['attrs']:
  116.                 setTag.setAttribute('rtl', self.feedsList[setNum]['attrs']['rtl'])
  117.             rssfeedsTag.appendChild(setTag)
  118.             #create feed elements
  119.             for feed in self.feedsList[setNum]['feedslist']:
  120.                 feedTag = doc.createElement('feed')
  121.                 feedTag.setAttribute('updateinterval', feed['updateinterval'])
  122.                 feedUrl = doc.createTextNode(feed['url'])
  123.                 feedTag.appendChild(feedUrl)
  124.                 setTag.appendChild(feedTag)
  125.         return doc.toprettyxml(indent = '  ', encoding = 'UTF-8')
  126.  
  127.     def writeXmlToFile(self):
  128.         print '[SCRIPT] RSS Editor --> writing to %s' % (self.RssFeedsPath)
  129.         xml = self.formXml()
  130.         #hack for standalone attribute, minidom doesn't support DOM3
  131.         xmlHeaderEnd = xml.find('?>')
  132.         xml = xml[:xmlHeaderEnd]+' standalone="yes"'+xml[xmlHeaderEnd:]
  133.         try:
  134.             RssFeedsFile = open(self.RssFeedsPath, 'w')
  135.             RssFeedsFile.write(xml)
  136.             RssFeedsFile.close()
  137.             print '[SCRIPT] RSS Editor --> write success'
  138.             self.refreshFeed()
  139.         except IOError, error:
  140.             print '[SCRIPT] RSS Editor --> write failed', error
  141.  
  142.     def refreshFeed(self):
  143.         """Refresh XBMC's rss feed so changes can be seen immediately"""
  144.         if xbmc:
  145.             xbmc.executebuiltin('refreshrss()')
  146.         else:
  147.             print 'kthx'
  148.