home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / xbmc-9.11.exe / scripts / RSS Editor / resources / lib / xmlParser.py < prev   
Encoding:
Python Source  |  2009-11-24  |  6.3 KB  |  147 lines

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