41167cb4e9769f0113e57a7b714460731efc878b
[feedingit] / psa_harmattan / feedingit / pysrc / XmlHandler.py
1 import sys
2 from rss_sqlite import Listing
3 from xml import sax
4 from cgi import escape
5 from re import sub
6 from htmlentitydefs import name2codepoint
7 from gconf import client_get_default
8
9 import logging
10 logger = logging.getLogger(__name__)
11
12 def unescape(text):
13     def fixup(m):
14         text = m.group(0)
15         if text[:2] == "&#":
16             # character reference
17             try:
18                 if text[:3] == "&#x":
19                     return unichr(int(text[3:-1], 16))
20                 else:
21                     return unichr(int(text[2:-1]))
22             except ValueError:
23                 pass
24         else:
25             # named entity
26             try:
27                 text = unichr(name2codepoint[text[1:-1]])
28             except KeyError:
29                 pass
30         return text # leave as is
31     return sub("&#?\w+;", fixup, text)
32
33 def sanitize(text):
34     from cgi import escape
35     return escape(text).encode('ascii', 'xmlcharrefreplace')
36     
37 class XmlHandler():
38
39     def __init__(self, listing):
40         self.listing=listing
41     
42     def getConfigXml(self):
43         xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><xml>"
44         xml += "<hideReadFeed>True</hideReadFeed>"
45         xml += "<hideReadArticles>True</hideReadArticles>"
46         xml += "</xml>"
47         return xml
48     
49     def generateCategoryXml(self):
50         xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><xml>"
51         for cat in self.listing.getListOfCategories():
52             print cat
53             xml += "<category>"
54             xml += "<catname>%s</catname>" %sanitize(self.listing.getCategoryTitle(cat))
55             xml += "<catid>%s</catid>" % cat
56             xml += "<unread>%s</unread>" % self.listing.getCategoryUnread(cat)
57             xml += "</category>"
58         xml += "</xml>"
59         return xml
60
61     def fix_title(self, title):
62         return escape(unescape(title).replace("<em>","").replace("</em>","").replace("<nobr>","").replace("</nobr>","").replace("<wbr>","").replace("&mdash;","-"))
63     
64     def generateFeedsXml(self, catid):
65         xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><xml>"
66         for key in self.listing.getSortedListOfKeys("Manual", category=catid):
67             xml += "<feed>"
68             xml += "<feedname>%s</feedname>" %sanitize(self.listing.getFeedTitle(key))
69             xml += "<feedid>%s</feedid>" %key
70             xml += "<unread>%s</unread>" %self.listing.getFeedNumberOfUnreadItems(key)
71             xml += "<updatedDate>%s</updatedDate>" %self.listing.getFeedUpdateTime(key)
72             xml += "<icon>%s</icon>" %self.listing.getFavicon(key)
73             # xml += "<updating>True</updating>"
74             xml += "<updating>False</updating>"
75             xml += "</feed>"
76         xml += "</xml>"
77         return xml
78     
79     def generateArticlesXml(self, key, onlyUnread):
80         feed = self.listing.getFeed(key)
81         xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><xml>"
82         if onlyUnread == "False":
83             onlyUnread = False
84         for id in feed.getIds(onlyUnread):
85             xml += "<article>"
86             xml += "<title>%s</title>" %self.fix_title(feed.getTitle(id))
87             xml += "<articleid>%s</articleid>" %id
88             xml += "<unread>%s</unread>" %str(feed.isEntryRead(id))
89             xml += "<updatedDate>%s</updatedDate>" %feed.getDateStamp(id)
90             xml += "<path>%s</path>" %feed.getContentLink(id)
91             xml += "</article>"
92         xml += "</xml>"
93         return xml
94
95     def do_GET(self):
96         (req, sep, arg) = self.path.partition("?")
97         request = req.split("/")
98         arguments = {}
99         if arg != "":
100             args = arg.split("&")
101             for arg in args:
102                 ele = arg.split("=")
103                 arguments[ele[0]] = ele[1]
104         if request[1] == "categories":
105             xml = self.generateCategoryXml()
106         elif request[1] == "feeds":
107             catid = request[2]
108             xml = self.generateFeedsXml(catid)
109         elif request[1] == "articles":
110             key = request[2]
111             onlyUnread = arguments.get("onlyUnread","False")
112             markAllAsRead = arguments.get("markAllAsRead", "False")
113             xml = self.generateArticlesXml(key, onlyUnread, markAllAsRead)
114         elif request[1] == "html":
115             key = request[2]
116             article = request[3]
117             feed = listing.getFeed(key)
118             try:
119                 file = open(feed.getContentLink(article))
120                 html = file.read().replace("body", "body bgcolor='#ffffff'", 1)
121                 file.close()
122             except:
123                 html = "<html><body>Error retrieving article</body></html>"
124             self.send_response(200)
125             self.send_header("Content-type", "text/html")
126             self.end_headers()
127             self.wfile.write(html)
128             #listing.updateUnread(key)
129             return
130         elif request[1] == "isUpdating":
131             xml = "<xml>"
132             key = request[2]
133             if (key in updatingFeeds) or ((key=="") and (len(updatingFeeds)>0)):
134                 xml += "<updating>True</updating>"
135             else:
136                 xml += "<updating>False</updating>"
137             xml += self.getCommands()
138             xml += "</xml>"
139         elif request[1] == "read":
140             key = request[2]
141             article = request[3]
142             feed = listing.getFeed(key)
143             feed.setEntryRead(article)
144             listing.updateUnread(key)
145             self.send_response(200)
146             self.send_header("Content-type", "text/html")
147             self.end_headers()
148             self.wfile.write("OK")
149             return
150         elif request[1] == "config":
151             xml = self.getConfigXml()
152         elif request[1] == "home":
153             file = open(self.path)
154             self.send_response(200)
155             self.send_header("Content-type", "text/html")
156             self.end_headers()
157             self.wfile.write(file.read())
158             file.close()
159             return
160         elif request[1] == "task":
161             self.openTaskSwitch()
162             xml = "<xml>OK</xml>"
163         elif request[1] == "deleteCat":
164             key = request[2]
165             listing.removeCategory(key)
166             xml = "<xml>OK</xml>"
167         elif request[1] == "deleteFeed":
168             key = request[3]
169             listing.removeFeed(key)
170             xml = "<xml>OK</xml>"
171         elif request[1] == "addFeed":
172             cat = request[2]
173             name = request[3]
174             url = arguments.get("url","")
175             listing.addFeed(name, url, category=cat)
176             xml = "<xml>OK</xml>"
177         elif request[1] == "updateFeed":
178             key = request[2]
179             listing.updateFeed (key, priority=-1)
180             #download = Download(listing, [key,])
181             #download.start()
182             xml = "<xml>OK</xml>"
183         elif request[1]=="updateAll":
184             #app.automaticUpdate()
185             self.updateAll()
186             xml = "<xml>OK</xml>"
187         elif request[1] == "addCat":
188             catName = request[2]
189             listing.addCategory(catName)
190             xml = "<xml>OK</xml>"
191         else:
192             self.send_error(404, "File not found")
193             return
194         self.send_response(200)
195         self.send_header("Content-type", "text/xml")
196         self.end_headers()
197         self.wfile.write(xml.encode("utf-8"))