Merge branch 'master' of ssh://scm.schwerkraft.elitedvb.net/scmrepos/git/enigma2...
[enigma2-plugins.git] / curlytx / src / AtomFeed.py
1 # -*- coding: utf-8 -*-
2 # CurlyTx Atom feed parser
3 # Copyright (C) 2011 Christian Weiske <cweiske@cweiske.de>
4 # License: GPLv3 or later
5
6 from twisted.web.client import getPage
7 from xml.etree.cElementTree import fromstring
8
9 class AtomFeed:
10     """ Simple XML parser that extracts pages from a atom feed """
11     ns = "{http://www.w3.org/2005/Atom}"
12     def __init__(self, url, callback, errorCallback):
13         """ Fetches the URL
14
15         Parsed pages are sent back to callback by parse()
16         """
17         getPage(url).addCallback(self.parse, callback).addErrback(errorCallback)
18
19     def parse(self, data, callback):
20         """ Parse atom feed data into pages list and run callback """
21         xml = fromstring(data)
22         pages = []
23         for entry in xml.findall("{0}entry".format(self.ns)):
24             titleE = entry.find("{0}title".format(self.ns))
25             url   = self.bestLink(entry.findall("{0}link".format(self.ns)))
26             if titleE != None and titleE.text != "" and url != None:
27                 pages.append({"title": titleE.text, "url": url})
28
29         callback(pages)
30
31     def bestLink(self, list):
32         """ Fetch the best matching link from an atom feed entry """
33         foundLevel = -1
34         foundHref = None
35         for link in list:
36             if link.get("rel") != "alternate" and link.get("rel") != "":
37                 continue
38             level = self.level(link)
39             if foundLevel > level:
40                 continue
41             foundLevel = level
42             foundHref = link.get("href")
43         return foundHref
44
45     def level(self, link):
46         """ Determines the level of a link
47
48         "text/plain" type links are best, links without type are second.
49         All others have the lowest level 1.
50         """
51         type = link.get("type")
52         if type == "text/plain":
53             return 3
54         elif type == "":
55             return 2
56         return 1