always load the local configuration file
[enigma2-curlytx.git] / src / AtomFeed.py
index 07a6345f030c13f78bc70205fbff29dccbccfd84..51da7f8249cd352fec76aba95b91b69e620c7758 100644 (file)
@@ -1,15 +1,42 @@
+# -*- coding: utf-8 -*-
+# CurlyTx Atom feed parser
+# Copyright (C) 2011 Christian Weiske <cweiske@cweiske.de>
+# License: GPLv3 or later
+
 from twisted.web.client import getPage
-from xml.etree.cElementTree import fromstring
+from xml.etree.cElementTree import fromstring, ParseError
+
+import os
 
 class AtomFeed:
-    """Simple XML parser that extracts pages from a atom feed
-    """
+    """ Simple XML parser that extracts pages from a atom feed """
     ns = "{http://www.w3.org/2005/Atom}"
-    def __init__(self, url, callback):
-        getPage(url).addCallback(self.parse, callback)
+    errorCallback = None
+
+    def __init__(self, url, callback, errorCallback):
+        """ Fetches the URL
+
+        Parsed pages are sent back to callback by parse()
+        """
+        self.errorCallback = errorCallback
+        if (url.startswith('file://')):
+            file = url[7:]
+            if not os.path.exists(file):
+                errorCallback('Settings atom feed file does not exist: ' + file)
+                return
+
+            with open(file, 'r') as f:
+                self.parse(f.read(), callback)
+        else:
+            getPage(url).addCallback(self.parse, callback).addErrback(self.onError)
 
     def parse(self, data, callback):
-        xml = fromstring(data)
+        """ Parse atom feed data into pages list and run callback """
+        try:
+            xml = fromstring(data)
+        except ParseError:
+            return self.errorCallback("Invalid XML")
+
         pages = []
         for entry in xml.findall("{0}entry".format(self.ns)):
             titleE = entry.find("{0}title".format(self.ns))
@@ -20,6 +47,7 @@ class AtomFeed:
         callback(pages)
 
     def bestLink(self, list):
+        """ Fetch the best matching link from an atom feed entry """
         foundLevel = -1
         foundHref = None
         for link in list:
@@ -33,9 +61,18 @@ class AtomFeed:
         return foundHref
 
     def level(self, link):
+        """ Determines the level of a link
+
+        "text/plain" type links are best, links without type are second.
+        All others have the lowest level 1.
+        """
         type = link.get("type")
         if type == "text/plain":
             return 3
         elif type == "":
             return 2
         return 1
+
+    def onError(self, error):
+        """ Pass the error message only """
+        self.errorCallback(error.getErrorMessage())