home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Freeware / Miro 1.0 / Miro_Installer.exe / xulrunner / python / subscription.py < prev    next >
Encoding:
Python Source  |  2007-11-12  |  5.7 KB  |  176 lines

  1. # Miro - an RSS based video player application
  2. # Copyright (C) 2005-2007 Participatory Culture Foundation
  3. #
  4. # This program is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation; either version 2 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  17.  
  18. import cgi
  19. import re
  20. import util
  21. import urllib2
  22. import urlparse
  23. import xml.dom.minidom
  24.  
  25. """
  26. This place's waiting for a little bit of documentation
  27. """
  28.  
  29. # =========================================================================
  30.  
  31. reflexiveAutoDiscoveryOpener = urllib2.urlopen
  32.  
  33. def parseFile(path):
  34.     try:
  35.         subscriptionFile = open(path, "r")
  36.         content = subscriptionFile.read()
  37.         subscriptionFile.close()
  38.         return parseContent(content)
  39.     except:
  40.         pass
  41.  
  42. def parseContent(content):
  43.     try:
  44.         dom = xml.dom.minidom.parseString(content)
  45.         root = dom.documentElement
  46.         if root.nodeName == "rss":
  47.             urls = _getSubscriptionsFromRSSChannel(root)
  48.         elif root.nodeName == "feed":
  49.             urls = _getSubscriptionsFromAtomFeed(root)
  50.         elif root.nodeName == "opml":
  51.             urls = _getSubscriptionsFromOPMLOutline(root)
  52.         else:
  53.             urls = None
  54.         dom.unlink()
  55.         return urls
  56.     except:
  57.         import traceback
  58.         if util.chatter:
  59.             print "WARNING: Error parsing OPML content..."
  60.             traceback.print_exc()
  61.         return None
  62.  
  63. def get_urls_from_query(query):
  64.     urls = []
  65.     for key, value in cgi.parse_qs(query).items():
  66.         if re.match(r'url\d+$', key):
  67.             urls.append(value[0])
  68.     return urls
  69.  
  70. def findSubscribeLinks(url):
  71.     """Given a URL, test if it's trying to subscribe the user using
  72.     subscribe.getdemocracy.com.  Returns the list of parsed URLs.
  73.     """
  74.     try:
  75.         scheme, host, path, params, query, frag = urlparse.urlparse(url)
  76.     except:
  77.         return 'none', []
  78.     if host not in ('subscribe.getdemocracy.com', 'subscribe.getmiro.com'):
  79.         return 'none', []
  80.     if path in ('/', '/opml.php'):
  81.         return 'feed', get_urls_from_query(query)
  82.     elif path in ('/download.php','/download','/download/'):
  83.         return 'download', get_urls_from_query(query)
  84.     elif path in ('/channelguide.php', '/channelguide', '/channelguide/'):
  85.         return 'guide', get_urls_from_query(query)
  86.     else:
  87.         return 'feed', [urllib2.unquote(path[1:])]
  88.  
  89. # =========================================================================
  90.  
  91. def _getSubscriptionsFromRSSChannel(root):
  92.     try:
  93.         channel = root.getElementsByTagName("channel").pop()
  94.         urls = _getSubscriptionsFromAtomLinkConstruct(channel)
  95.         if urls is not None:
  96.             return urls
  97.         else:
  98.             link = channel.getElementsByTagName("link").pop()
  99.             href = link.firstChild.data
  100.             return _getSubscriptionsFromReflexiveAutoDiscovery(href, "application/rss+xml")
  101.     except:
  102.         pass
  103.  
  104. def _getSubscriptionsFromAtomFeed(root):
  105.     try:
  106.         urls = _getSubscriptionsFromAtomLinkConstruct(root)
  107.         if urls is not None:
  108.             return urls
  109.         else:
  110.             link = _getAtomLink(root)
  111.             rel = link.getAttribute("rel")
  112.             if rel == "alternate":
  113.                 href = link.getAttribute("href")
  114.                 return _getSubscriptionsFromReflexiveAutoDiscovery(href, "application/atom+xml")
  115.     except:
  116.         pass
  117.  
  118. def _getSubscriptionsFromAtomLinkConstruct(node):
  119.     try:
  120.         link = _getAtomLink(node)
  121.         if link.getAttribute("rel") in ("self", "start"):
  122.             href = link.getAttribute("href")
  123.             return [href]
  124.     except:
  125.         pass
  126.  
  127. def _getSubscriptionsFromReflexiveAutoDiscovery(url, ltype):
  128.     try:
  129.         urls = list()
  130.         html = reflexiveAutoDiscoveryOpener(url).read()
  131.         for match in re.findall("<link[^>]+>", html):
  132.             altMatch = re.search("rel=\"alternate\"", match)
  133.             typeMatch = re.search("type=\"%s\"" % re.escape(ltype), match)
  134.             hrefMatch = re.search("href=\"([^\"]*)\"", match)
  135.             if None not in (altMatch, typeMatch, hrefMatch):
  136.                 href = hrefMatch.group(1)
  137.                 urls.append(href)
  138.     except:
  139.         urls = None
  140.     else:
  141.         if len(urls) == 0:
  142.             urls = None
  143.     return urls
  144.  
  145. def _getAtomLink(node):
  146.     return node.getElementsByTagNameNS("http://www.w3.org/2005/Atom", "link").pop()
  147.  
  148. # =========================================================================
  149.  
  150. def _getSubscriptionsFromOPMLOutline(root):
  151.     try:
  152.         urls = list()
  153.         body = root.getElementsByTagName("body").pop()
  154.         _searchOPMLNodeRecursively(body, urls)
  155.     except:
  156.         urls = None
  157.     else:
  158.         if len(urls) == 0:
  159.             urls = None
  160.     return urls
  161.  
  162. def _searchOPMLNodeRecursively(node, urls):
  163.     try:
  164.         children = node.childNodes
  165.         for child in children:
  166.             if hasattr(child, 'getAttribute'):
  167.                 if child.hasAttribute("xmlUrl"):
  168.                     url = child.getAttribute("xmlUrl")
  169.                     urls.append(url)
  170.                 else:
  171.                     _searchOPMLNodeRecursively(child, urls)
  172.     except:
  173.         pass
  174.  
  175. # =========================================================================
  176.