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, environ
15 logger = logging.getLogger(__name__)
18 debugging.init(dot_directory=".feedingit", program_name="feedingit-web")
20 CONFIGDIR = environ.get("HOME", "/home/user") + "/.feedingit"
21 #CONFIGDIR = "/home/user/.feedingit/"
24 #commands = [("addFeed","httpwww"), ("openFeed", "xxxx"), ("openArticle", ("feedid","artid"))]
34 return unichr(int(text[3:-1], 16))
36 return unichr(int(text[2:-1]))
42 text = unichr(name2codepoint[text[1:-1]])
45 return text # leave as is
46 return sub("&#?\w+;", fixup, text)
49 from cgi import escape
50 return escape(text).encode('ascii', 'xmlcharrefreplace')
54 listing = Listing(config, CONFIGDIR)
55 httpd = BaseHTTPServer.HTTPServer(("127.0.0.1", PORT), Handler)
59 def addFeed(self, url):
60 commands.append(("addFeed",url))
65 def openFeed(self, key):
66 commands.append( ("openFeed", key) )
68 def openArticle(self, key, id):
69 commands.append( ("openArticle", key, id) )
71 def automaticUpdate(self):
72 commands.append(("updateAll",))
73 # for cat in listing.getListOfCategories():
74 # for feed in listing.getSortedListOfKeys("Manual", category=cat):
76 # download = Download(listing, feeds)
79 class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
81 for cat in listing.getListOfCategories():
82 for feed in listing.getSortedListOfKeys("Manual", category=cat):
83 listing.updateFeed(feed)
85 def openTaskSwitch(self):
87 subprocess.Popen("dbus-send /com/nokia/hildon_desktop com.nokia.hildon_desktop.exit_app_view", shell=True)
89 def getCommands(self):
90 commandXml = "<commands>"
92 if item[0]=="addFeed":
93 commandXml += "<command c='addFeed'>%s</command>" %(sanitize(item[1]))
94 if item[0]=="openFeed":
96 cat = str(listing.getFeedCategory(key))
97 commandXml += "<command c='openFeed' cat='%s'>%s</command>" % (sanitize(cat), sanitize(key) )
98 if item[0]=="openArticle":
100 cat = str(listing.getFeedCategory(key))
102 commandXml += "<command c='openArticle' cat='%s' key='%s'>%s</command>" %(sanitize(cat), sanitize(key), sanitize(articleid) )
103 if item[0]=="updateAll":
105 commands.remove(item)
106 commandXml += "</commands>"
109 def getConfigXml(self):
110 xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><xml>"
111 xml += "<hideReadFeed>True</hideReadFeed>"
112 xml += "<hideReadArticles>True</hideReadArticles>"
116 def generateCategoryXml(self):
117 xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><xml>"
118 for cat in listing.getListOfCategories():
120 xml += "<catname>%s</catname>" %sanitize(listing.getCategoryTitle(cat))
121 xml += "<catid>%s</catid>" % cat
126 def fix_title(self, title):
127 return escape(unescape(title).replace("<em>","").replace("</em>","").replace("<nobr>","").replace("</nobr>","").replace("<wbr>","").replace("—","-"))
129 def generateFeedsXml(self, catid):
130 xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><xml>"
131 for key in listing.getSortedListOfKeys("Manual", category=catid):
133 xml += "<feedname>%s</feedname>" %sanitize(listing.getFeedTitle(key))
134 xml += "<feedid>%s</feedid>" %key
135 xml += "<unread>%s</unread>" %listing.getFeedNumberOfUnreadItems(key)
136 xml += "<updatedDate>%s</updatedDate>" %listing.getFeedUpdateTime(key)
137 xml += "<icon>%s</icon>" %listing.getFavicon(key)
138 if key in updatingFeeds:
139 xml += "<updating>True</updating>"
141 xml += "<updating>False</updating>"
146 def generateArticlesXml(self, key, onlyUnread, markAllAsRead):
147 feed = listing.getFeed(key)
148 if markAllAsRead=="True":
150 listing.updateUnread(key)
151 xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><xml>"
152 if onlyUnread == "False":
154 for id in feed.getIds(onlyUnread):
156 xml += "<title>%s</title>" %self.fix_title(feed.getTitle(id))
157 xml += "<articleid>%s</articleid>" %id
158 xml += "<unread>%s</unread>" %str(feed.isEntryRead(id))
159 xml += "<updatedDate>%s</updatedDate>" %feed.getDateStamp(id)
160 xml += "<path>%s</path>" %feed.getContentLink(id)
166 (req, sep, arg) = self.path.partition("?")
167 request = req.split("/")
170 args = arg.split("&")
173 arguments[ele[0]] = ele[1]
174 if request[1] == "categories":
175 xml = self.generateCategoryXml()
176 elif request[1] == "feeds":
178 xml = self.generateFeedsXml(catid)
179 elif request[1] == "articles":
181 onlyUnread = arguments.get("onlyUnread","False")
182 markAllAsRead = arguments.get("markAllAsRead", "False")
183 xml = self.generateArticlesXml(key, onlyUnread, markAllAsRead)
184 elif request[1] == "html":
187 feed = listing.getFeed(key)
189 file = open(feed.getContentLink(article))
190 html = file.read().replace("body", "body bgcolor='#ffffff'", 1)
193 html = "<html><body>Error retrieving article</body></html>"
194 self.send_response(200)
195 self.send_header("Content-type", "text/html")
197 self.wfile.write(html)
198 #listing.updateUnread(key)
200 elif request[1] == "isUpdating":
203 if (key in updatingFeeds) or ((key=="") and (len(updatingFeeds)>0)):
204 xml += "<updating>True</updating>"
206 xml += "<updating>False</updating>"
207 xml += self.getCommands()
209 elif request[1] == "read":
212 feed = listing.getFeed(key)
213 feed.setEntryRead(article)
214 listing.updateUnread(key)
215 self.send_response(200)
216 self.send_header("Content-type", "text/html")
218 self.wfile.write("OK")
220 elif request[1] == "config":
221 xml = self.getConfigXml()
222 elif request[1] == "home":
223 file = open(self.path)
224 self.send_response(200)
225 self.send_header("Content-type", "text/html")
227 self.wfile.write(file.read())
230 elif request[1] == "task":
231 self.openTaskSwitch()
232 xml = "<xml>OK</xml>"
233 elif request[1] == "deleteCat":
235 listing.removeCategory(key)
236 xml = "<xml>OK</xml>"
237 elif request[1] == "deleteFeed":
239 listing.removeFeed(key)
240 xml = "<xml>OK</xml>"
241 elif request[1] == "addFeed":
244 url = arguments.get("url","")
245 listing.addFeed(name, url, category=cat)
246 xml = "<xml>OK</xml>"
247 elif request[1] == "updateFeed":
249 download = Download(listing, [key,])
251 xml = "<xml>OK</xml>"
252 elif request[1]=="updateAll":
253 #app.automaticUpdate()
255 xml = "<xml>OK</xml>"
256 elif request[1] == "addCat":
258 listing.addCategory(catName)
259 xml = "<xml>OK</xml>"
261 self.send_error(404, "File not found")
263 self.send_response(200)
264 self.send_header("Content-type", "text/xml")
266 self.wfile.write(xml.encode("utf-8"))
270 if not isdir(CONFIGDIR):
274 logger.error("Error: Can't create configuration directory")
278 from config import Config
279 config = Config(None,CONFIGDIR+"config.ini")
285 # Initialize the glib mainloop, for dbus purposes
286 from feedingitdbus import ServerObject
287 from updatedbus import UpdateServerObject
290 gobject.threads_init()
291 import dbus.mainloop.glib
292 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
295 from jobmanager import JobManager
299 dbusHandler = ServerObject(app)
301 # Start the HTTP server in a new thread
302 thread.start_new_thread(start_server, ())
304 mainloop = gobject.MainLoop()