3 from rss_sqlite import Listing
7 from htmlentitydefs import name2codepoint
8 from gconf import client_get_default
9 from urllib2 import ProxyHandler
10 from threading import Thread
11 from os.path import isfile, isdir, exists
12 from os import mkdir, remove, stat
14 CONFIGDIR = "/home/user/.feedingit/"
17 #commands = [("addFeed","httpwww"), ("openFeed", "xxxx"), ("openArticle", ("feedid","artid"))]
18 commands = [("openFeed", "1,", "61ac1458d761423344998dc76770e36e")]
27 return unichr(int(text[3:-1], 16))
29 return unichr(int(text[2:-1]))
35 text = unichr(name2codepoint[text[1:-1]])
38 return text # leave as is
39 return sub("&#?\w+;", fixup, text)
42 from cgi import escape
43 return escape(text).encode('ascii', 'xmlcharrefreplace')
47 listing = Listing(CONFIGDIR)
48 httpd = BaseHTTPServer.HTTPServer(("127.0.0.1", PORT), Handler)
52 def addFeed(self, url):
53 commands.append(("addFeed",url))
58 def openFeed(self, key):
59 cat = listing.getFeedCategory(key)
60 commands.append( ("openFeed", cat, key) )
62 def OpenArticle(self, key, id):
63 cat = listing.getFeedCategory(key)
64 commands.append( ("openArticle", (cat, key, id)) )
66 class Download(Thread):
67 def __init__(self, listing, keys):
69 self.listing = listing
74 print "Start update: %s" % key
75 updatingFeeds.append(key)
76 (use_proxy, proxy) = config.getProxy()
79 self.listing.updateFeed(key, proxy=proxy, imageCache=config.getImageCache() )
81 self.listing.updateFeed(key, imageCache=config.getImageCache() )
83 print "Error updating feed: %s" %key
84 updatingFeeds.remove(key)
85 print "End update: %s" % key
87 class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
88 def openTaskSwitch(self):
90 subprocess.Popen("dbus-send /com/nokia/hildon_desktop com.nokia.hildon_desktop.exit_app_view", shell=True)
94 subprocess.Popen("FeedingIt update", shell=True)
96 def getCommands(self):
98 commandXml = "<commands>"
100 if item[0]=="addFeed":
101 commandXml += "<command c='addFeed'>%s</command>" %(sanitize(item[1]))
102 if item[0]=="openFeed":
103 commandXml += "<command c='openFeed' cat='%s'>%s</command>" % (sanitize(item[1]), sanitize(item[2]) )
104 if item[0]=="openArticle":
105 commandXml += "<command c='openArticle' cat='%s' key='%s'>%s</command>" %(sanitize(item[1], sanitize(item[2][0]), sanitize(item[2][1])) )
106 commands.remove(item)
107 commandXml += "</commands>"
110 def getConfigXml(self):
111 xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><xml>"
112 xml += "<hideReadFeed>True</hideReadFeed>"
113 xml += "<hideReadArticles>True</hideReadArticles>"
117 def generateCategoryXml(self):
118 xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><xml>"
119 for cat in listing.getListOfCategories():
121 xml += "<catname>%s</catname>" %listing.getCategoryTitle(cat)
122 xml += "<catid>%s</catid>" % cat
127 def fix_title(self, title):
128 return escape(unescape(title).replace("<em>","").replace("</em>","").replace("<nobr>","").replace("</nobr>","").replace("<wbr>","").replace("—","-"))
130 def generateFeedsXml(self, catid):
131 xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><xml>"
132 for key in listing.getSortedListOfKeys("Manual", category=catid):
134 xml += "<feedname>%s</feedname>" %listing.getFeedTitle(key)
135 xml += "<feedid>%s</feedid>" %key
136 xml += "<unread>%s</unread>" %listing.getFeedNumberOfUnreadItems(key)
137 xml += "<updatedDate>%s</updatedDate>" %listing.getFeedUpdateTime(key)
138 xml += "<icon>%s</icon>" %listing.getFavicon(key)
139 if key in updatingFeeds:
140 xml += "<updating>True</updating>"
142 xml += "<updating>False</updating>"
147 def generateArticlesXml(self, key, onlyUnread, markAllAsRead):
148 feed = listing.getFeed(key)
149 if markAllAsRead=="True":
151 listing.updateUnread(key)
152 xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><xml>"
153 if onlyUnread == "False":
155 for id in feed.getIds(onlyUnread):
157 xml += "<title>%s</title>" %self.fix_title(feed.getTitle(id))
158 xml += "<articleid>%s</articleid>" %id
159 xml += "<unread>%s</unread>" %str(feed.isEntryRead(id))
160 xml += "<updatedDate>%s</updatedDate>" %feed.getDateStamp(id)
161 xml += "<path>%s</path>" %feed.getContentLink(id)
167 (req, sep, arg) = self.path.partition("?")
168 request = req.split("/")
171 args = arg.split("&")
174 arguments[ele[0]] = ele[1]
175 if request[1] == "categories":
176 xml = self.generateCategoryXml()
177 elif request[1] == "feeds":
179 xml = self.generateFeedsXml(catid)
180 elif request[1] == "articles":
182 onlyUnread = arguments.get("onlyUnread","False")
183 markAllAsRead = arguments.get("markAllAsRead", "False")
184 xml = self.generateArticlesXml(key, onlyUnread, markAllAsRead)
185 elif request[1] == "html":
188 feed = listing.getFeed(key)
190 file = open(feed.getContentLink(article))
191 html = file.read().replace("body", "body bgcolor='#ffffff'", 1)
194 html = "<html><body>Error retrieving article</body></html>"
195 self.send_response(200)
196 self.send_header("Content-type", "text/html")
198 self.wfile.write(html)
199 #listing.updateUnread(key)
201 elif request[1] == "isUpdating":
204 if (key in updatingFeeds) or ((key=="") and (len(updatingFeeds)>0)):
205 xml += "<updating>True</updating>"
207 xml += "<updating>False</updating>"
208 xml += self.getCommands()
210 elif request[1] == "read":
213 feed = listing.getFeed(key)
214 feed.setEntryRead(article)
215 listing.updateUnread(key)
216 self.send_response(200)
217 self.send_header("Content-type", "text/html")
219 self.wfile.write("OK")
221 elif request[1] == "config":
222 xml = self.getConfigXml()
223 elif request[1] == "home":
224 file = open(self.path)
225 self.send_response(200)
226 self.send_header("Content-type", "text/html")
228 self.wfile.write(file.read())
231 elif request[1] == "task":
232 self.openTaskSwitch()
233 xml = "<xml>OK</xml>"
234 elif request[1] == "deleteCat":
236 listing.removeCategory(key)
237 xml = "<xml>OK</xml>"
238 elif request[1] == "deleteFeed":
240 listing.removeFeed(key)
241 xml = "<xml>OK</xml>"
242 elif request[1] == "addFeed":
245 url = arguments.get("url","")
246 listing.addFeed(name, url, category=cat)
247 xml = "<xml>OK</xml>"
248 elif request[1] == "updateFeed":
250 download = Download(listing, [key,])
252 xml = "<xml>OK</xml>"
253 elif request[1]=="updateAll":
255 for cat in listing.getListOfCategories():
256 for feed in listing.getSortedListOfKeys("Manual", category=cat):
259 download = Download(listing, feeds)
261 xml = "<xml>OK</xml>"
262 elif request[1] == "addCat":
264 listing.addCategory(catName)
265 xml = "<xml>OK</xml>"
267 self.send_error(404, "File not found")
269 self.send_response(200)
270 self.send_header("Content-type", "text/xml")
272 self.wfile.write(xml.encode("utf-8"))
276 if not isdir(CONFIGDIR):
280 print "Error: Can't create configuration directory"
284 from config import Config
285 config = Config(None,CONFIGDIR+"config.ini")
289 #print "serving at port", PORT
290 thread.start_new_thread(start_server, ())
292 from feedingitdbus import ServerObject
293 #from updatedbus import UpdateServerObject, get_lock
295 gobject.threads_init()
296 import dbus.mainloop.glib
297 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
299 mainloop = gobject.MainLoop()