psa: more fixes if wc unavailable
[feedingit] / psa_harmattan / feedingit / deb_dist / feedingit-0.1.0 / 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             xml += "<category>"
53             xml += "<catname>%s</catname>" %sanitize(self.listing.getCategoryTitle(cat))
54             xml += "<catid>%s</catid>" % cat
55             xml += "<unread>%s</unread>" % self.listing.getCategoryUnread(cat)
56             xml += "</category>"
57         xml += "</xml>"
58         return xml
59
60     def fix_title(self, title):
61         return escape(unescape(title).replace("<em>","").replace("</em>","").replace("<nobr>","").replace("</nobr>","").replace("<wbr>","").replace("&mdash;","-"))
62     
63     def generateFeedsXml(self, catid):
64         xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><xml>"
65         for key in self.listing.getSortedListOfKeys("Manual", category=catid):
66             xml += "<feed>"
67             xml += "<feedname>%s</feedname>" %sanitize(self.listing.getFeedTitle(key))
68             xml += "<feedid>%s</feedid>" %key
69             xml += "<unread>%s</unread>" %self.listing.getFeedNumberOfUnreadItems(key)
70             xml += "<updatedDate>%s</updatedDate>" %self.listing.getFeedUpdateTime(key)
71             xml += "<icon>%s</icon>" %self.listing.getFavicon(key)
72             # xml += "<updating>True</updating>"
73             xml += "<updating>False</updating>"
74             xml += "</feed>"
75         xml += "</xml>"
76         return xml
77     
78     def generateArticlesXml(self, key, onlyUnread):
79         feed = self.listing.getFeed(key)
80         xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><xml>"
81         if onlyUnread == "False":
82             onlyUnread = False
83         for id in feed.getIds(onlyUnread):
84             xml += "<article>"
85             xml += "<title>%s</title>" %self.fix_title(feed.getTitle(id))
86             xml += "<articleid>%s</articleid>" %id
87             xml += "<unread>%s</unread>" %str(feed.isEntryRead(id))
88             xml += "<updatedDate>%s</updatedDate>" %feed.getDateStamp(id)
89             xml += "<path>%s</path>" %feed.getContentLink(id)
90             xml += "</article>"
91         xml += "</xml>"
92         return xml
93
94     def do_GET(self):
95         (req, sep, arg) = self.path.partition("?")
96         request = req.split("/")
97         arguments = {}
98         if arg != "":
99             args = arg.split("&")
100             for arg in args:
101                 ele = arg.split("=")
102                 arguments[ele[0]] = ele[1]
103         if request[1] == "categories":
104             xml = self.generateCategoryXml()
105         elif request[1] == "feeds":
106             catid = request[2]
107             xml = self.generateFeedsXml(catid)
108         elif request[1] == "articles":
109             key = request[2]
110             onlyUnread = arguments.get("onlyUnread","False")
111             markAllAsRead = arguments.get("markAllAsRead", "False")
112             xml = self.generateArticlesXml(key, onlyUnread, markAllAsRead)
113         elif request[1] == "html":
114             key = request[2]
115             article = request[3]
116             feed = listing.getFeed(key)
117             try:
118                 file = open(feed.getContentLink(article))
119                 html = file.read().replace("body", "body bgcolor='#ffffff'", 1)
120                 file.close()
121             except:
122                 html = "<html><body>Error retrieving article</body></html>"
123             self.send_response(200)
124             self.send_header("Content-type", "text/html")
125             self.end_headers()
126             self.wfile.write(html)
127             #listing.updateUnread(key)
128             return
129         elif request[1] == "isUpdating":
130             xml = "<xml>"
131             key = request[2]
132             if (key in updatingFeeds) or ((key=="") and (len(updatingFeeds)>0)):
133                 xml += "<updating>True</updating>"
134             else:
135                 xml += "<updating>False</updating>"
136             xml += self.getCommands()
137             xml += "</xml>"
138         elif request[1] == "read":
139             key = request[2]
140             article = request[3]
141             feed = listing.getFeed(key)
142             feed.setEntryRead(article)
143             listing.updateUnread(key)
144             self.send_response(200)
145             self.send_header("Content-type", "text/html")
146             self.end_headers()
147             self.wfile.write("OK")
148             return
149         elif request[1] == "config":
150             xml = self.getConfigXml()
151         elif request[1] == "home":
152             file = open(self.path)
153             self.send_response(200)
154             self.send_header("Content-type", "text/html")
155             self.end_headers()
156             self.wfile.write(file.read())
157             file.close()
158             return
159         elif request[1] == "task":
160             self.openTaskSwitch()
161             xml = "<xml>OK</xml>"
162         elif request[1] == "deleteCat":
163             key = request[2]
164             listing.removeCategory(key)
165             xml = "<xml>OK</xml>"
166         elif request[1] == "deleteFeed":
167             key = request[3]
168             listing.removeFeed(key)
169             xml = "<xml>OK</xml>"
170         elif request[1] == "addFeed":
171             cat = request[2]
172             name = request[3]
173             url = arguments.get("url","")
174             listing.addFeed(name, url, category=cat)
175             xml = "<xml>OK</xml>"
176         elif request[1] == "updateFeed":
177             key = request[2]
178             listing.updateFeed (key, priority=-1)
179             #download = Download(listing, [key,])
180             #download.start()
181             xml = "<xml>OK</xml>"
182         elif request[1]=="updateAll":
183             #app.automaticUpdate()
184             self.updateAll()
185             xml = "<xml>OK</xml>"
186         elif request[1] == "addCat":
187             catName = request[2]
188             listing.addCategory(catName)
189             xml = "<xml>OK</xml>"
190         else:
191             self.send_error(404, "File not found")
192             return
193         self.send_response(200)
194         self.send_header("Content-type", "text/xml")
195         self.end_headers()
196         self.wfile.write(xml.encode("utf-8"))