The branch, dharma has been updated
       via  a8e7870c0700d4115f071b24f67dd39ea9023d95 (commit)
      from  372190e60e6f1d1e41ef176510c09ce014fb23a1 (commit)

- Log -----------------------------------------------------------------
http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/plugins;a=commit;h=a8e7870c0700d4115f071b24f67dd39ea9023d95

commit a8e7870c0700d4115f071b24f67dd39ea9023d95
Author: spiff <sp...@xbmc.org>
Date:   Tue Jan 4 22:05:58 2011 +0100

    [plugin.audio.podcatcher] updated to version 0.1.0

diff --git a/plugin.audio.podcatcher/README-DE 
b/plugin.audio.podcatcher/README-DE
index 85a075f..48fd9cd 100644
--- a/plugin.audio.podcatcher/README-DE
+++ b/plugin.audio.podcatcher/README-DE
@@ -1,9 +1,9 @@
 Um das PodCatcher-Plugin auszuführen braucht es im Userbezogene 
Pluginverzeichniss (<XBMC-Home>/userdata/addon_data/plugin.audio.PodCatcher/) 
eine Datei namens opml.xml. Diese sollte am besten mittels eines Feedreaders 
erstellt werden. Das sparrt arbeit! Das Podcatcher Addon unterstützt folgende 
OPML - Outline Attribute:
   * xmlUrl = link zum Feed
-  * type = art des Feeds (momentan nur RSS)
+  * type = art des Feeds
   * text = (userdefinierter) Title des Feeds
   * fetchInterval = Angabe der Zeit in Minuten die zwischen 2 Aktualisierungen 
vergehen muss. Alternativangaben: hourly,daily,weekly,monthly
-  * maxArticleAge = maximales Alter eines Artikel 
+  * maxArticleAge = maximales Alter eines Artikel in tagen
   * maxArticleNumber = maximale Anzahl an Topics in einem Feed
 
 Die letzten beiden Angaben beinflussen nicht die Menge an Daten die "geladen" 
und geparsed wird. Sie beinflusst aber die Menge an Daten die lokal gespeichert 
werden. Hällt man diese Dateien klein, reagiert das Plugin sehr flott.
\ No newline at end of file
diff --git a/plugin.audio.podcatcher/README-EN 
b/plugin.audio.podcatcher/README-EN
index e1d232f..9081ff7 100644
--- a/plugin.audio.podcatcher/README-EN
+++ b/plugin.audio.podcatcher/README-EN
@@ -1,10 +1,10 @@
 To run the plugin a user-related opml.xml is needed to be placed in 
<XBMC-Home>/userdata/addon_data/plugin.audio.PodCatcher/. Use your default 
rss-reader to generate this file, this saves time;) 
 This Plugin supports following OPML - Outline attributes:
   * xmlUrl = the kink to the feed
-  * type = feed-type (currently RSS only)
+  * type = feed-type
   * text = userdefined feed-title
   * fetchInterval = time in minutes between two refreshes. alternative: 
hourly,daily,weekly,monthly
-  * maxArticleAge = 
-  * maxArticleNumber = 
+  * maxArticleAge = number of days how old a article maximal can be
+  * maxArticleNumber = maximal amount of articles
 
 the last both attributes don't affect the amount of bytes loaded or parsed. 
They affect how much is displayed an localy cached. Keep this files small and 
all runs fast ;)
diff --git a/plugin.audio.podcatcher/addon.xml 
b/plugin.audio.podcatcher/addon.xml
index 39e1ada..573b57b 100644
--- a/plugin.audio.podcatcher/addon.xml
+++ b/plugin.audio.podcatcher/addon.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <addon
   id="plugin.audio.podcatcher"
-  version="0.0.8"
+  version="0.1.0"
   name="AudioPodcaster"
   provider-name="Raptor 2101 [raptor2...@gmx.de]">
   <requires>
diff --git a/plugin.audio.podcatcher/changelog.txt 
b/plugin.audio.podcatcher/changelog.txt
index 1e8ee7e..ef03d11 100644
--- a/plugin.audio.podcatcher/changelog.txt
+++ b/plugin.audio.podcatcher/changelog.txt
@@ -1,3 +1,7 @@
+version 0.1.0 - Bugfixing, Hardening and so on ...
+                opml-file to load is now changeable by addon-settings
+                additional caching to support large opml files
+Version 0.0.9 - Added experimental Atom - Reading
 Version 0.0.8 - Rewrite the Caching-Algorithm. Moving from XML files to 
"pickle"-Files. The opml-file won't be changed enymore.
                 If a publishing-date is given, it will be displayed in the menu
                 minor bugfixes
@@ -13,4 +17,4 @@ Version 0.0.3 - Complete Code-Rewrite
     - Implemention of a more intelligent "loading algoritm". Additional 
(extern) feed-files are only readed if needed and will be cached. Refreshtimes 
can be defined per feed.
   * Add "Play all unread" - ok that should be in 0.0.2 but i missed it ;)
   * thge plugin take care of all possible media-info (but xbmc doesn't)
-Version 0.0.2 - Initial Release
\ No newline at end of file
+Version 0.0.2 - Initial Release
diff --git a/plugin.audio.podcatcher/default.py 
b/plugin.audio.podcatcher/default.py
index a9dc526..efd9ff2 100644
--- a/plugin.audio.podcatcher/default.py
+++ b/plugin.audio.podcatcher/default.py
@@ -19,7 +19,7 @@
  A plugin to organize audio-podcast
 """
 
-import sys, os, xbmcaddon
+import sys, os, xbmcaddon,xbmc
 from feedreader.opml import OpmlFile
 from feedreader.archivefile import ArchiveFile
 
@@ -60,7 +60,7 @@ __language__ = __settings__.getLocalizedString
 
 gui = SimpleXbmcGui(path);
 
-DIR_HOME = __settings__.getAddonInfo("profile")
+DIR_HOME = xbmc.translatePath(__settings__.getAddonInfo("profile"))
 if not os.path.exists(DIR_HOME):
   os.mkdir(DIR_HOME);
 
@@ -70,14 +70,16 @@ if not os.path.exists(DIR_ARCHIVES):
 ArchiveFile.setArchivePath(DIR_ARCHIVES);
 
 
-PATH_FILE_OPML = os.path.join(DIR_HOME, 'opml.xml')
+PATH_FILE_OPML = __settings__.getSetting("opmlFile")
+if (PATH_FILE_OPML == ""):
+  PATH_FILE_OPML = os.path.join(DIR_HOME,"opml.xml");
 if not os.path.exists(PATH_FILE_OPML):
   gui.errorOK(__language__(1040),__language__(1041));
 else:
   gui.log(PATH_FILE_OPML)
   
   
-  opmlFile = OpmlFile(PATH_FILE_OPML, gui);
+  opmlFile = OpmlFile(PATH_FILE_OPML, DIR_HOME, gui);
   
   if not path:
     path = ""
diff --git a/plugin.audio.podcatcher/feedreader/__init__.py 
b/plugin.audio.podcatcher/feedreader/__init__.py
index 17c58af..a7fabb2 100644
--- a/plugin.audio.podcatcher/feedreader/__init__.py
+++ b/plugin.audio.podcatcher/feedreader/__init__.py
@@ -17,7 +17,10 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 import time,urllib,re;
 from archivefile import ArchiveFile
+regex_mediaLink = re.compile("(http|ftp)://.*?\\.(mp3|mpeg|asx|wmv|ogg|mov)");
 regex_dateString = re.compile("\\d{2} ((\\w{3})|(\\d{2})) \\d{4}");
+regex_shortdateString = re.compile("\\d{4}-(\\d{2})-\\d{2}");
+regex_replaceUnusableChar = re.compile("[:/ \\.]")
 month_replacements = {
     "Jan":"01",
     "Feb":"02",
@@ -49,8 +52,12 @@ class FeedItem(object):
     self.size = None;
     
 class Feed(object):
-  def loadOpmlNode(self,opmlNode):
+  def loadFromNode(self, opmlNode, gui):
+    self.gui = gui;
+    self.feedUrl = opmlNode.getAttribute("xmlUrl");
     self.objectId = opmlNode.getAttribute("id");
+    if(self.objectId == ""):
+      self.objectId = regex_replaceUnusableChar.sub("_",self.feedUrl);
     self.archiveFile=ArchiveFile(self.objectId);
     
     self.feedItems = self.archiveFile.feedItems;
@@ -58,15 +65,45 @@ class Feed(object):
       self.gui.log(feedItem.title);
     self.lastLoad = self.archiveFile.lastLoad;
     
-    self.feedUrl = opmlNode.getAttribute("xmlUrl");
-    self.fetchInterval = 
self.parseFetchInterval(opmlNode.getAttribute("fetchInterval"));
+    
+    
     self.title = opmlNode.getAttribute("text");
-    self.maxArticleAge = int(opmlNode.getAttribute("maxArticleAge"));
-    self.maxArticleNumber = int(opmlNode.getAttribute("maxArticleNumber"));
     
+    try:
+      self.fetchInterval = 
self.parseFetchInterval(opmlNode.getAttribute("fetchInterval"));
+    except:
+      self.fetchInterval = 0;
+    
+    try:
+      self.maxArticleAge = int(opmlNode.getAttribute("maxArticleAge"));
+    except:
+      self.maxArticleAge = 99;
+    
+    try:
+      self.maxArticleNumber = int(opmlNode.getAttribute("maxArticleNumber"));
+    except:
+      self.maxArticleNumber = 99;
+    
+  def loadFromState(self, stateObject, gui):
+    self.gui = gui;
+    self.feedUrl = stateObject.feedUrl
+    self.objectId = stateObject.objectId
+    self.archiveFile=ArchiveFile(self.objectId);
+    
+    self.feedItems = self.archiveFile.feedItems;
+    for feedItem in self.feedItems:
+      self.gui.log(feedItem.title);
+    self.lastLoad = self.archiveFile.lastLoad;
+    
+    
+    
+    self.title = stateObject.title
+    self.fetchInterval = stateObject.fetchInterval
+    self.maxArticleAge = stateObject.maxArticleAge
+    self.maxArticleNumber = stateObject.maxArticleNumber
     
-  
   def saveChanges(self):
+    self.gui.log(self.archiveFile.archiveFile);
     self.archiveFile.save();
   
   def hasUnreadItems(self):
@@ -118,7 +155,7 @@ class Feed(object):
       self.saveChanges();
     else:
       self.gui.play(self);
-      self.markRead();
+      #self.markRead();
     
       
   def markRead(self, path = []):
@@ -165,10 +202,18 @@ class Feed(object):
       return "";
   
   def parseDate(self,dateString):
-    dateString = regex_dateString.search(dateString).group();
-    for month in month_replacements.keys():
-      dateString = dateString.replace(month,month_replacements[month]);
-    return time.strptime(dateString,"%d %m %Y");
+    dateMatch = regex_dateString.search(dateString);
+    if(dateMatch is not None):
+      dateString = dateMatch.group();
+      for month in month_replacements.keys():
+        dateString = dateString.replace(month,month_replacements[month]);
+      return time.strptime(dateString,"%d %m %Y");
+    else: 
+     dateMatch = regex_shortdateString.search(dateString)
+     if(dateMatch is not None):
+       dateString = dateMatch.group();
+       return time.strptime(dateString,"%Y-%m-%d");
+    return 0;
     
   def writeDate(self, date):
     return time.strftime("%d %m %Y",date);
@@ -179,6 +224,14 @@ class Feed(object):
     else:
       return False;
   
+  def parseIndirectItem(self, targetUrl):
+    self.gui.log(targetUrl);
+    htmlPage = self.loadPage(targetUrl);
+    link = regex_mediaLink.search(htmlPage).group();
+    self.gui.log(link);
+    
+    return link;
+  
   def writeBoolean(self, boolean):
     if(boolean):
       return "True";
@@ -200,6 +253,4 @@ class Feed(object):
       else:
         return ''
     except:
-      return ''
-      
-    
\ No newline at end of file
+      return ''
\ No newline at end of file
diff --git a/plugin.audio.podcatcher/feedreader/archivefile.py 
b/plugin.audio.podcatcher/feedreader/archivefile.py
index 628d35f..264e0c9 100644
--- a/plugin.audio.podcatcher/feedreader/archivefile.py
+++ b/plugin.audio.podcatcher/feedreader/archivefile.py
@@ -1,8 +1,64 @@
 # -*- coding: utf-8 -*-
+#-------------LicenseHeader--------------
+# plugin.audio.podcatcher - A plugin to play Podcasts
+# Copyright (C) 2010  Raptor 2101 [raptor2...@gmx.de]
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 import xbmcaddon, os, pickle;
 from xml.dom import minidom
 
+class FeedState(object):
+  def __init__(self, feed):
+    self.feedUrl = feed.feedUrl;
+    self.objectId = feed.objectId;
+    self.title = feed.title;
+    self.fetchInterval = feed.fetchInterval
+    self.maxArticleAge = feed.maxArticleAge
+    self.maxArticleNumber = feed.maxArticleNumber
+    self.feedVersion = feed.feedVersion
+    
+class OpmlFolderState(object):
+  def __init__(self, opmlFolder):
+    self.title = opmlFolder.title;
+    self.elements = [];
+    for subFolder in opmlFolder.elements:
+      if(type(subFolder).__name__ == "OpmlFolder"):
+        element = OpmlFolderState(subFolder);
+      else:
+        element = FeedState(subFolder);
+      self.elements.append(element);
 
+class OpmlArchiveFile(object):
+  def save(self, opmlFolder, filePath):
+    archiveFile = open(filePath,"wb");
+    state = OpmlFolderState(opmlFolder);
+    pickle.dump(state, archiveFile);
+  save = classmethod(save)
+  
+  def load(self,filePath):
+    archiveFile = open(filePath,"rb");
+    return pickle.load(archiveFile);
+  load = classmethod(load);
+  
+  def updateNeeded(self, sourceFile, archiveFile):
+    if(not os.path.exists(archiveFile)):
+      return True;
+    sourceChanged = os.stat(sourceFile)[8];
+    archiveChanged = os.stat(archiveFile)[8];
+    return sourceChanged>archiveChanged
+  updateNeeded = classmethod(updateNeeded);
+  
 class ArchiveFile(object):
   def __init__(self, itemId):
     global __archiveDir__;
@@ -10,13 +66,13 @@ class ArchiveFile(object):
     self.feedItems = [];
     self.lastLoad = 0;
     
-    self.archiveFile = os.path.join(__archiveDir__,itemId);
+    self.archiveFile = os.path.join(__archiveDir__,itemId+".archive");
     
     if os.path.exists(self.archiveFile):
-      input = open(self.archiveFile, 'r')
+      input = open(self.archiveFile, 'rb')
       unsortedObject = pickle.load(input);
       self.feedItems = sorted(unsortedObject, key = lambda item:item.date, 
reverse=True);
-      self.lastLoad = stats = os.stat(self.archiveFile)[8];
+      self.lastLoad = os.stat(self.archiveFile)[8];
   
   @classmethod
   def setArchivePath(self, path):
@@ -24,5 +80,5 @@ class ArchiveFile(object):
     __archiveDir__ = path;
   
   def save(self):
-    output = open(self.archiveFile, 'w')
+    output = open(self.archiveFile, 'wb')
     pickle.dump(self.feedItems, output);
\ No newline at end of file
diff --git a/plugin.audio.podcatcher/feedreader/feedfactory.py 
b/plugin.audio.podcatcher/feedreader/feedfactory.py
index eb451b4..a492473 100644
--- a/plugin.audio.podcatcher/feedreader/feedfactory.py
+++ b/plugin.audio.podcatcher/feedreader/feedfactory.py
@@ -16,9 +16,26 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 from rss import RssFeed;
+from atom import AtomFeed;
 class FeedFactory:
-  def getFeed(self, feedNode, gui):
+  def getFeedFromNode(self, feedNode, gui):
     feedVersion = feedNode.getAttribute("type")
     if(feedVersion == "rss"):
-      return RssFeed(feedNode, gui);
-  getFeed = classmethod(getFeed)
\ No newline at end of file
+      feed = RssFeed();
+    if(feedVersion == "atom"):
+      feed = AtomFeed();
+    feed.loadFromNode(feedNode, gui);
+    feed.feedVersion = feedVersion
+    return feed;
+  getFeedFromNode = classmethod(getFeedFromNode)
+  
+  def getFeedFromState(self, feedState, gui):
+    feedVersion = feedState.feedVersion
+    if(feedVersion == "rss"):
+      feed = RssFeed();
+    if(feedVersion == "atom"):
+      feed = AtomFeed();
+    feed.loadFromState(feedState,gui);
+    feed.feedVersion = feedVersion
+    return feed;
+  getFeedFromState = classmethod(getFeedFromState)
\ No newline at end of file
diff --git a/plugin.audio.podcatcher/feedreader/opml.py 
b/plugin.audio.podcatcher/feedreader/opml.py
index 4c066ea..5a82948 100644
--- a/plugin.audio.podcatcher/feedreader/opml.py
+++ b/plugin.audio.podcatcher/feedreader/opml.py
@@ -16,26 +16,45 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 
-import shutil,os,urllib2;
+import shutil,os,urllib2,pickle;
 from xml.dom import minidom;
 from xml.dom import Node;
 from feedfactory import FeedFactory;
-
+from html import transformHtmlCodes;
+from archivefile import OpmlArchiveFile;
     
 class OpmlFolder(object):
-  def __init__(self,rootNode, gui):
-    self.rootNode = rootNode;
+  def loadFromNode(self, rootNode, gui):
     self.gui = gui;
     self.elements = [];
-    self.title = rootNode.getAttribute('text');
+    self.title = transformHtmlCodes(rootNode.getAttribute('text'));
         
-    for node in self.rootNode.childNodes:
-      if node.hasChildNodes() and node.firstChild.tagName == "outline":
-        element = OpmlFolder(node, self.gui);
-      else:
-        element = FeedFactory.getFeed(node, self.gui)
-      self.elements.append(element);
-    
+    for node in rootNode.childNodes:
+      try:
+        if node.hasChildNodes() and node.firstChild.tagName == "outline":
+          element = OpmlFolder();
+          element.loadFromNode(node, self.gui);
+        else:
+          element = FeedFactory.getFeedFromNode(node, self.gui)
+        self.elements.append(element);
+      except:
+        self.gui.log("Something goes wrong while processing the node 
%s"%rootNode.getAttribute('text'));
+  
+  def loadFromState(self, stateObject, gui):
+    self.gui = gui;
+    self.elements = [];
+    self.title = stateObject.title;
+    for stateElement in stateObject.elements:
+      try:
+        if(type(stateElement).__name__ == "OpmlFolderState"):
+          element = OpmlFolder()
+          element.loadFromState(stateElement,self.gui);
+        else:
+          element = FeedFactory.getFeedFromState(stateElement, self.gui)
+        self.elements.append(element);
+      except:
+        self.gui.log("Something goes wrong while processing the node 
%s"%stateObject.title);
+      
   def displayMenu(self, path):
     if len(path) > 0:
       index = int(path.pop(0));
@@ -86,16 +105,22 @@ class OpmlFolder(object):
       element.getAllItems(items);
     
 class OpmlFile:
-  def __init__(self, path, gui):
-    self.path = path;
+  def __init__(self, opmlFile, archivePath, gui):
     self.gui = gui;
-    self.xmlDoc = minidom.parse(path)
-    
-    self.cleanupNodes(self.xmlDoc.documentElement);
-    self.xmlDoc.documentElement.normalize() 
-    
-    for bodyNode in  self.xmlDoc.getElementsByTagName('body'):
-      self.opmlFolder = OpmlFolder(bodyNode, self.gui )
+    self.opmlFolder = OpmlFolder();
+    archiveFile = os.path.join(archivePath,"opml.archive");
+    if(OpmlArchiveFile.updateNeeded(opmlFile, archiveFile)):
+      self.xmlDoc = minidom.parse(opmlFile)
+      self.cleanupNodes(self.xmlDoc.documentElement);
+      self.xmlDoc.documentElement.normalize() 
+      
+      for bodyNode in  self.xmlDoc.getElementsByTagName('body'):
+        self.opmlFolder.loadFromNode(bodyNode, self.gui )
+      
+      OpmlArchiveFile.save(self.opmlFolder, archiveFile);
+    else:
+      state = OpmlArchiveFile.load(archiveFile);
+      self.opmlFolder.loadFromState(state,self.gui);
   
   def cleanupNodes(self, rootNode):
     for node in rootNode.childNodes:
@@ -118,4 +143,4 @@ class OpmlFile:
   
   def reload(self, path):
     self.opmlFolder.reload(path);
-    
\ No newline at end of file
+    
diff --git a/plugin.audio.podcatcher/feedreader/rss.py 
b/plugin.audio.podcatcher/feedreader/rss.py
index 8a20756..f6648af 100644
--- a/plugin.audio.podcatcher/feedreader/rss.py
+++ b/plugin.audio.podcatcher/feedreader/rss.py
@@ -23,63 +23,68 @@ findPicLink = re.compile("src=\".*?\"");
 
 
 class RssFeed (Feed):
-  def __init__(self, opmlNode, gui):
-    self.gui = gui;
-    self.loadOpmlNode(opmlNode);
-          
   def updateFeed(self):
-    self.gui.log("Load: "+self.feedUrl);
-    xmlPage = self.loadPage(self.feedUrl);
-    xmlDocument = minidom.parseString(xmlPage);
-    counter = 0;
-    for itemNode in xmlDocument.getElementsByTagName("item"):
-      feedItem = FeedItem();
-      feedItem.guid = self.readText(itemNode,"guid");
-      feedItem.title = self.readText(itemNode,"title");
-      feedItem.subTitle = self.readText(itemNode,"itunes:subtitle");
-      
-      dateString = self.readText(itemNode,"pubDate");
-      feedItem.date = self.parseDate(dateString);
-      
-      if(not self.checkArticleAge(feedItem.date)):
-        break;
-      
-      eject = False;      
-      for i in range(counter,len(self.feedItems)):
-        storedItem = self.feedItems[i];
-        if(not storedItem.date < feedItem.date):
-          eject =True;
-          break;
-      
-      if(eject == True):
-        break;
-      
-      feedItem.author = self.readText(itemNode,"itunes:author");
-      feedItem.duration = 
self.readText(itemNode,"itunes:duration").replace("00:","");
-      
-      enclosureNode = itemNode.getElementsByTagName("enclosure")[0];
-      
-      feedItem.link = enclosureNode.getAttribute("url");
-      feedItem.size = int(enclosureNode.getAttribute("length"));
-      
-      descriptionNode = itemNode.getElementsByTagName("itunes:summary");
-      if(len(descriptionNode)>0):
-        descriptionNode = descriptionNode[0];
-      else:
-        descriptionNode = itemNode.getElementsByTagName("description")[0];
-      
-      feedItem.description = descriptionNode.firstChild.data;
-      
-      link = findPicLink.search(feedItem.description)
-      if(link is not None):
-        link = link.group().replace("src=","").replace("\"","");
-        feedItem.picture = link;
-      else:
-        feedItem.picture = "";
+    try:    
+      xmlPage = self.loadPage(self.feedUrl);
+      xmlDocument = minidom.parseString(xmlPage);
+      counter = 0;
+      for itemNode in xmlDocument.getElementsByTagName("item"):
+        try:      
+          feedItem = FeedItem();
+          feedItem.guid = self.readText(itemNode,"guid");
+          feedItem.title = self.readText(itemNode,"title");
+          feedItem.subTitle = self.readText(itemNode,"itunes:subtitle");
+          
+          dateString = self.readText(itemNode,"pubDate");
+          feedItem.date = self.parseDate(dateString);
+          
+          if(not self.checkArticleAge(feedItem.date)):
+            break;
+          
+          eject = False;      
+          for i in range(counter,len(self.feedItems)):
+            storedItem = self.feedItems[i];
+            if(not storedItem.date < feedItem.date):
+              eject =True;
+              break;
+          
+          if(eject == True):
+            break;
+          
+          feedItem.author = self.readText(itemNode,"itunes:author");
+          feedItem.duration = 
self.readText(itemNode,"itunes:duration").replace("00:","");
+          enclosures = itemNode.getElementsByTagName("enclosure")
+          if(len(enclosures) > 0):
+            enclosureNode = itemNode.getElementsByTagName("enclosure")[0];
+          
+            feedItem.link = enclosureNode.getAttribute("url");
+            feedItem.size = int(enclosureNode.getAttribute("length"));
+          else:
+            feedItem.size = 0;
+            feedItem.link = 
self.parseIndirectItem(self.readText(itemNode,"link"));
+          
+          descriptionNode = itemNode.getElementsByTagName("itunes:summary");
+          if(len(descriptionNode)>0):
+            descriptionNode = descriptionNode[0];
+          else:
+            descriptionNode = itemNode.getElementsByTagName("description")[0];
+          
+          feedItem.description = descriptionNode.firstChild.data;
+          
+          link = findPicLink.search(feedItem.description)
+          if(link is not None):
+            link = link.group().replace("src=","").replace("\"","");
+            feedItem.picture = link;
+          else:
+            feedItem.picture = "";
 
-      feedItem.readed = False;
-      self.insertFeedItem(feedItem);
-      counter += 1;
-      if(counter>self.maxArticleNumber):
-        break;
-    self.shrinkFeedItems();
\ No newline at end of file
+          feedItem.readed = False;
+          self.insertFeedItem(feedItem);
+          counter += 1;
+          if(counter>self.maxArticleNumber):
+            break;
+        except:
+          self.gui.log("Error while parsing item: %s"%itemNode.toxml());
+    except:
+      self.gui.log("Error while processing %s"%self.feedUrl)          
+    self.shrinkFeedItems();
diff --git a/plugin.audio.podcatcher/resources/language/English/strings.xml 
b/plugin.audio.podcatcher/resources/language/English/strings.xml
index b3f72a8..9a74e31 100644
--- a/plugin.audio.podcatcher/resources/language/English/strings.xml
+++ b/plugin.audio.podcatcher/resources/language/English/strings.xml
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<!-- English strings.xml by bootsy (bootsycollin...@gmail.com) -->
 <strings>
-    <!-- Main -->
+    <string id="1000">OPML-File</string>
     <string id="1010">Mark all as read</string>
     <string id="1011">Play all unreaded</string>
     <string id="1020">Mark as read</string>
diff --git a/plugin.audio.podcatcher/resources/language/German/strings.xml 
b/plugin.audio.podcatcher/resources/language/German/strings.xml
index 6d07f6f..41b5d1e 100644
--- a/plugin.audio.podcatcher/resources/language/German/strings.xml
+++ b/plugin.audio.podcatcher/resources/language/German/strings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <strings>
-    <!-- Main -->
+    <string id="1000">OPML-Datei</string>
     <string id="1010">Alles als gelesen markieren</string>
     <string id="1011">Alles ungelesene abspielen</string>
     <string id="1020">Als gelesen markieren</string>
diff --git a/plugin.audio.podcatcher/simplexbmc.py 
b/plugin.audio.podcatcher/simplexbmc.py
index 967f8a5..26aab7d 100644
--- a/plugin.audio.podcatcher/simplexbmc.py
+++ b/plugin.audio.podcatcher/simplexbmc.py
@@ -18,12 +18,13 @@
 import xbmc, xbmcgui, xbmcplugin,xbmcaddon, sys, urllib, urllib2, 
os,re,math,time
 __plugin__ = "PodCatcher"
 
+regex_decimal = re.compile("\\d+");
+regex_duration = re.compile("(\\d+:){0,2}\\d+");
+settings = xbmcaddon.Addon(id='plugin.audio.podcatcher')
+translation = settings.getLocalizedString
+
 class SimpleXbmcGui(object):
   def __init__(self,path):
-    self.regex_decimal = re.compile("\\d+");
-    self.regex_duration = re.compile("(\\d+:){0,2}\\d+");
-    self.settings = xbmcaddon.Addon(id='plugin.audio.podcatcher')
-    self.translation = self.settings.getLocalizedString
     self.path = path;
     
   def log(self, msg):
@@ -72,7 +73,7 @@ class SimpleXbmcGui(object):
       liz = self.buildMediaItem(menuElement,True);
       
       
-      
liz.addContextMenuItems([(self.translation(1020),"XBMC.RunPlugin(%s?path=%s&action=markRead)"%(sys.argv[0],path))],True)
+      
liz.addContextMenuItems([(translation(1020),"XBMC.RunPlugin(%s?path=%s&action=markRead)"%(sys.argv[0],path))],True)
       u = "%s?path=%s&action=play&guid=%s" % 
(sys.argv[0],path,menuElement.guid)
       
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz,isFolder=True)
       
@@ -83,9 +84,9 @@ class SimpleXbmcGui(object):
         title = "%s"%(menuElement.title);
       liz=xbmcgui.ListItem(title, "")
       contextMenuEntries = [
-        
(self.translation(1010),"XBMC.RunPlugin(%s?path=%s&action=markRead)"%(sys.argv[0],path)),
-        
(self.translation(1011),"XBMC.RunPlugin(%s?path=%s&action=play)"%(sys.argv[0],path)),
-        
(self.translation(1030),"XBMC.RunPlugin(%s?path=%s&action=reload)"%(sys.argv[0],path))
+        
(translation(1010),"XBMC.RunPlugin(%s?path=%s&action=markRead)"%(sys.argv[0],path)),
+        
(translation(1011),"XBMC.RunPlugin(%s?path=%s&action=play)"%(sys.argv[0],path)),
+        
(translation(1030),"XBMC.RunPlugin(%s?path=%s&action=reload)"%(sys.argv[0],path))
         ]
       liz.addContextMenuItems(contextMenuEntries,True)
       u = "%s?path=%s&action=browse" % (sys.argv[0],path)
@@ -120,8 +121,8 @@ class SimpleXbmcGui(object):
     xbmc.executebuiltin("Container.Refresh")
     
   def durationStringToSec(self, durationString):
-    if(self.regex_duration.match(durationString) is not None):
-      decimalArray = self.regex_decimal.findall(durationString);
+    if(durationString is not None and regex_duration.match(durationString) is 
not None):
+      decimalArray = regex_decimal.findall(durationString);
       if(len(decimalArray)==3):
         return int(decimalArray[0])*3600 + int(decimalArray[1])*60 
+int(decimalArray[2])
       elif(len(decimalArray)==2):

-----------------------------------------------------------------------

Summary of changes:
 plugin.audio.podcatcher/README-DE                  |    4 +-
 plugin.audio.podcatcher/README-EN                  |    6 +-
 plugin.audio.podcatcher/addon.xml                  |    2 +-
 plugin.audio.podcatcher/changelog.txt              |    6 +-
 plugin.audio.podcatcher/default.py                 |   10 +-
 plugin.audio.podcatcher/feedreader/__init__.py     |   79 +++++++++++---
 plugin.audio.podcatcher/feedreader/archivefile.py  |   64 ++++++++++-
 plugin.audio.podcatcher/feedreader/atom.py         |   72 ++++++++++++
 plugin.audio.podcatcher/feedreader/feedfactory.py  |   23 ++++-
 plugin.audio.podcatcher/feedreader/opml.py         |   69 ++++++++----
 plugin.audio.podcatcher/feedreader/rss.py          |  121 ++++++++++----------
 .../html.py                                        |    2 +-
 .../resources/language/English/strings.xml         |    3 +-
 .../resources/language/German/strings.xml          |    2 +-
 plugin.audio.podcatcher/resources/settings.xml     |    3 +
 plugin.audio.podcatcher/simplexbmc.py              |   21 ++--
 16 files changed, 361 insertions(+), 126 deletions(-)
 create mode 100644 plugin.audio.podcatcher/feedreader/atom.py
 copy {plugin.video.mediathek => plugin.audio.podcatcher}/html.py (91%)
 create mode 100644 plugin.audio.podcatcher/resources/settings.xml


hooks/post-receive
-- 
Plugins

------------------------------------------------------------------------------
Learn how Oracle Real Application Clusters (RAC) One Node allows customers
to consolidate database storage, standardize their database environment, and, 
should the need arise, upgrade to a full multi-node Oracle RAC database 
without downtime or disruption
http://p.sf.net/sfu/oracle-sfdevnl
_______________________________________________
Xbmc-addons mailing list
Xbmc-addons@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/xbmc-addons

Reply via email to