1 #!/usr/bin/env python2.5
4 # Copyright (c) 2007-2008 INdT.
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Lesser General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU Lesser General Public License for more details.
15 # You should have received a copy of the GNU Lesser General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # ============================================================================
21 # Author : Yves Marcoz
23 # Description : Simple RSS Reader
24 # ============================================================================
26 from os.path import isfile
27 from os.path import isdir
34 CONFIGDIR="/home/user/.feedingit/"
37 return md5.new(string).hexdigest()
40 # Contains all the info about a single feed (articles, ...), and expose the data
41 def __init__(self, name, url):
48 self.updateTime = "Never"
50 def getFontSize(self):
58 file = open(CONFIGDIR+getId(self.name), "w")
59 pickle.dump(self, file )
63 tmp=feedparser.parse(self.url)
64 # Check if the parse was succesful (number of entries > 0, else do nothing)
65 if len(tmp["entries"])>0:
66 self.tmpReadItems = self.readItems
68 self.updateTime = time.asctime()
69 self.entries = tmp["entries"]
71 # Initialize the new articles to unread
72 for index in range(self.getNumberOfEntries()):
73 if not self.tmpReadItems.has_key(self.getUniqueId(index)):
74 self.readItems[self.getUniqueId(index)] = False
76 self.readItems[self.getUniqueId(index)] = self.tmpReadItems[self.getUniqueId(index)]
77 if self.readItems[self.getUniqueId(index)]==False:
78 self.countUnread = self.countUnread + 1
82 def setEntryRead(self, index):
83 if self.readItems[self.getUniqueId(index)]==False:
84 self.countUnread = self.countUnread - 1
85 self.readItems[self.getUniqueId(index)] = True
87 def isEntryRead(self, index):
88 return self.readItems[self.getUniqueId(index)]
90 def getTitle(self, index):
91 return self.entries[index]["title"]
93 def getUniqueId(self,index):
94 entry = self.entries[index]
95 if entry.has_key("updated_parsed"):
96 return getId(time.strftime("%a, %d %b %Y %H:%M:%S",entry["updated_parsed"]) + entry["title"])
97 elif entry.has_key("link"):
98 return getId(entry["link"] + entry["title"])
100 return getId(entry["title"])
102 def getUpdateTime(self):
103 return self.updateTime
105 def getEntries(self):
111 def getNumberOfUnreadItems(self):
112 return self.countUnread
114 def getNumberOfEntries(self):
115 return len(self.entries)
117 def getItem(self, index):
119 return self.entries[index]
123 def getContent(self, index):
124 entry = self.entries[index]
125 if entry.has_key('content'):
126 content = entry.content[0].value
128 content = entry.get('summary', '')
131 def getArticle(self, index):
132 self.setEntryRead(index)
133 entry = self.entries[index]
134 title = entry.get('title', 'No title')
135 #content = entry.get('content', entry.get('summary_detail', {}))
136 content = self.getContent(index)
138 link = entry.get('link', 'NoLink')
139 if entry.has_key("updated_parsed"):
140 date = time.strftime("%a, %d %b %Y %H:%M:%S",entry["updated_parsed"])
141 elif entry.has_key("published_parsed"):
142 date = time.strftime("%a, %d %b %Y %H:%M:%S", entry["published_parsed"])
145 #text = '''<div style="color: black; background-color: white;">'''
146 text = '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>'
147 text += '<div><a href=\"' + link + '\">' + title + "</a>"
148 text += "<BR /><small><i>Date: " + date + "</i></small></div>"
149 text += "<BR /><BR />"
155 # Lists all the feeds in a dictionary, and expose the data
158 if isfile(CONFIGDIR+"feeds.pickle"):
159 file = open(CONFIGDIR+"feeds.pickle")
160 self.listOfFeeds = pickle.load(file)
163 self.listOfFeeds = {getId("Slashdot"):{"title":"Slashdot", "url":"http://rss.slashdot.org/Slashdot/slashdot"}, }
164 if not self.listOfFeeds.has_key("font"):
166 if self.listOfFeeds.has_key("feedingit-order"):
167 self.sortedKeys = self.listOfFeeds["feedingit-order"]
169 self.sortedKeys = self.listOfFeeds.keys()
170 if "font" in self.sortedKeys:
171 self.sortedKeys.remove("font")
172 self.sortedKeys.sort(key=lambda obj: self.getFeedTitle(obj))
173 for key in self.sortedKeys:
177 self.sortedKeys.remove(key)
180 def getFontSize(self):
181 return self.listOfFeeds["font"]
183 def getReadFont(self):
184 return "sans %s" % self.listOfFeeds["font"]
186 def getUnreadFont(self):
187 return "sans bold %s" % self.listOfFeeds["font"]
189 def setFont(self, fontname):
190 self.listOfFeeds["font"] = fontname
192 def loadFeed(self, key):
193 if isfile(CONFIGDIR+key):
194 file = open(CONFIGDIR+key)
195 self.feeds[key] = pickle.load(file)
198 title = self.listOfFeeds[key]["title"]
199 url = self.listOfFeeds[key]["url"]
200 self.feeds[key] = Feed(title, url)
202 def updateFeeds(self):
203 for key in self.getListOfFeeds():
204 self.feeds[key].updateFeed()
206 def updateFeed(self, key):
207 self.feeds[key].updateFeed()
209 def getFeed(self, key):
210 return self.feeds[key]
212 def getFeedUpdateTime(self, key):
213 return self.feeds[key].getUpdateTime()
215 def getFeedNumberOfUnreadItems(self, key):
216 return self.feeds[key].getNumberOfUnreadItems()
218 def getFeedTitle(self, key):
219 return self.listOfFeeds[key]["title"]
221 def getFeedUrl(self, key):
222 return self.listOfFeeds[key]["url"]
224 def getListOfFeeds(self):
225 return self.sortedKeys
227 def addFeed(self, title, url):
228 if not self.listOfFeeds.has_key(getId(title)):
229 self.listOfFeeds[getId(title)] = {"title":title, "url":url}
230 self.sortedKeys.append(getId(title))
232 self.feeds[getId(title)] = Feed(title, url)
234 def removeFeed(self, key):
235 del self.listOfFeeds[key]
236 self.sortedKeys.remove(key)
238 if isfile(CONFIGDIR+key):
239 remove(CONFIGDIR+key)
241 def saveConfig(self):
242 self.listOfFeeds["feedingit-order"] = self.sortedKeys
243 file = open(CONFIGDIR+"feeds.pickle", "w")
244 pickle.dump(self.listOfFeeds, file)
247 def moveUp(self, key):
248 index = self.sortedKeys.index(key)
249 self.sortedKeys[index] = self.sortedKeys[index-1]
250 self.sortedKeys[index-1] = key
252 def moveDown(self, key):
253 index = self.sortedKeys.index(key)
254 index2 = (index+1)%len(self.sortedKeys)
255 self.sortedKeys[index] = self.sortedKeys[index2]
256 self.sortedKeys[index2] = key