7 |
import straw |
import straw |
8 |
from error import log |
from error import log |
9 |
|
|
10 |
busy_cursor = gtk.gdk.Cursor(gtk.gdk.WATCH) |
|
11 |
ready_cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR) |
def set_busy_cursor(): |
12 |
|
rw = gtk.gdk.get_default_root_window() |
13 |
|
rw.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) |
14 |
|
del rw |
15 |
|
|
16 |
|
def set_ready_cursor(): |
17 |
|
rw = gtk.gdk.get_default_root_window() |
18 |
|
rw.set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)) |
19 |
|
del rw |
20 |
|
|
21 |
class SubscribeDialog: |
class SubscribeDialog: |
22 |
COLUMN_URL = 0 |
COLUMN_SUBSCRIBE = 0 |
23 |
COLUMN_TITLE = 1 |
COLUMN_TITLE = 1 |
24 |
COLUMN_DESCRIPTION = 2 |
COLUMN_DESCRIPTION = 2 |
25 |
COLUMN_FEED = 3 |
COLUMN_FEED = 3 |
26 |
COLUMN_PARSEDSUMMARY = 4 |
COLUMN_PARSEDSUMMARY = 4 |
27 |
|
COLUMN_STATUS_FLAG = 5 |
28 |
|
COLUMN_URL = 6 |
29 |
|
|
30 |
def __init__(self, xml): |
def __init__(self, xml): |
31 |
self._window = xml.get_widget("subscribe_dialog") |
self._window = xml.get_widget("subscribe_dialog") |
32 |
self._window.set_transient_for(straw.main_window.get_window()) |
self._window.set_transient_for(straw.main_window.get_window()) |
|
self._feed_url = "" |
|
|
self._feed_count = 0 |
|
|
self._feed_is_parsed = bool(0) |
|
33 |
|
|
34 |
self._find_assistant = xml.get_widget("find_assistant") |
self._feeds = {} |
35 |
|
self._url = "" |
36 |
|
self._err = bool(0) |
37 |
|
|
38 |
|
self._find_assistant = xml.get_widget("find_assistant") |
39 |
self._start_page = xml.get_widget("start_page") |
self._start_page = xml.get_widget("start_page") |
40 |
self._location_page = xml.get_widget("location_page") |
self._location_page = xml.get_widget("location_page") |
41 |
self._last_page = xml.get_widget("last_page") |
self._last_page = xml.get_widget("last_page") |
44 |
self._subscribe_multiple_match_view = xml.get_widget("subscribe_multiple_match_view") |
self._subscribe_multiple_match_view = xml.get_widget("subscribe_multiple_match_view") |
45 |
|
|
46 |
nameFuncMap = {} |
nameFuncMap = {} |
47 |
|
|
48 |
for key in dir(self.__class__): |
for key in dir(self.__class__): |
49 |
if key[:3] == 'on_': |
if key[:3] == 'on_': |
50 |
nameFuncMap[key] = getattr(self, key) |
nameFuncMap[key] = getattr(self, key) |
51 |
|
|
52 |
xml.signal_autoconnect(nameFuncMap) |
xml.signal_autoconnect(nameFuncMap) |
53 |
|
|
54 |
model = gtk.ListStore( |
model = gtk.ListStore(gobject.TYPE_OBJECT, gobject.TYPE_STRING, |
55 |
gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, |
gobject.TYPE_STRING, gobject.TYPE_PYOBJECT, |
56 |
gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT) |
gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN, |
57 |
|
gobject.TYPE_STRING) |
58 |
|
|
59 |
self._subscribe_multiple_match_view.set_model(model) |
self._subscribe_multiple_match_view.set_model(model) |
60 |
self.create_columns(self._subscribe_multiple_match_view) |
self.create_columns(self._subscribe_multiple_match_view) |
61 |
|
|
62 |
def on_start_page_next(self, widget, data): |
def on_start_page_next(self, *args): |
63 |
self._find_assistant.set_page(self._location_page) |
self._find_assistant.set_page(self._location_page) |
64 |
|
|
65 |
if self._feed_url == "" or self._feed_url is None: |
if self._url == "": |
66 |
self.disable_button(next=gtk.FALSE) |
self._subscribe_site_entry.set_text("") |
67 |
|
self._find_assistant.set_buttons_sensitive(gtk.TRUE, gtk.FALSE, gtk.TRUE, gtk.TRUE) |
68 |
|
|
69 |
return gtk.TRUE |
return gtk.TRUE |
70 |
|
|
71 |
def on_start_page_cancel(self, widget, data): |
def on_start_page_cancel(self, *args): |
72 |
self.hide() |
self.hide() |
73 |
|
|
74 |
def on_location_page_next(self, widget, data): |
def on_location_page_next(self, widget, data): |
75 |
url = self._subscribe_site_entry.get_text() |
url = self._subscribe_site_entry.get_text().strip() |
76 |
if self._feed_url == url: |
if self._url == url: |
77 |
if self._feed_count > 1: |
if (len(self._feeds) > 1): |
78 |
self._find_assistant.set_page(self._multiple_feed_page) |
self._find_assistant.set_page(self._multiple_feed_page) |
79 |
else: |
else: |
80 |
self._find_assistant.set_page(self._last_page) |
self._find_assistant.set_page(self._last_page) |
81 |
|
if self._err: |
82 |
|
self._find_assistant.set_show_finish(gtk.FALSE) |
83 |
else: |
else: |
84 |
rw = gtk.gdk.get_default_root_window() |
set_busy_cursor() |
85 |
rw.set_cursor(busy_cursor) |
self._err = self.find_site(url) |
86 |
self.find_site(url) |
set_ready_cursor() |
87 |
rw.set_cursor(ready_cursor) |
self._url = url |
|
self._feed_url = url |
|
88 |
|
|
89 |
return gtk.TRUE |
return gtk.TRUE |
90 |
|
|
95 |
self.hide() |
self.hide() |
96 |
|
|
97 |
def on_multiple_feed_page_next(self, *args): |
def on_multiple_feed_page_next(self, *args): |
98 |
selection = self._subscribe_multiple_match_view.get_selection() |
self._find_assistant.set_page(self._last_page) |
99 |
model, iter = selection.get_selected() |
self.display_selected_feeds() |
100 |
index = model.get_path(iter)[0] |
return gtk.TRUE |
|
f = model[index][self.COLUMN_FEED] |
|
|
ps = model[index][self.COLUMN_PARSEDSUMMARY] |
|
|
self.display_selected_feed(f, ps) |
|
101 |
|
|
102 |
def on_last_page_back(self, widget, data): |
def on_last_page_back(self, widget, data): |
103 |
if self._feed_count > 1: |
if (not self._err) and (len(self._feeds) > 1): |
104 |
self._find_assistant.set_page(self._multiple_feed_page) |
self._find_assistant.set_page(self._multiple_feed_page) |
105 |
else: |
else: |
106 |
self._find_assistant.set_page(self._location_page) |
self._find_assistant.set_page(self._location_page) |
|
|
|
107 |
return gtk.TRUE |
return gtk.TRUE |
108 |
|
|
109 |
def on_last_page_finish(self, *args): |
def on_last_page_finish(self, *args): |
110 |
feed = self._new_feed[0] |
if (len(self._feeds) == 1): |
111 |
ps = self._new_feed[1] |
for f in self._feeds: |
112 |
straw.config.feeds.append(feed) |
feed, ps = self._feeds[f] |
113 |
feed.router.route_all(None, ps) |
straw.config.feeds.append(feed) |
114 |
feed.poll_done() |
feed.router.route_all(None, ps) |
115 |
|
feed.poll_done() |
116 |
|
else: |
117 |
|
iter = self._feeds.itervalues() |
118 |
|
for f in self._feeds: |
119 |
|
feed, ps = iter.next() |
120 |
|
straw.config.feeds.append(feed) |
121 |
|
feed.router.route_all(None, ps) |
122 |
|
feed.poll_done() |
123 |
|
|
124 |
self.hide() |
self.hide() |
125 |
|
|
126 |
def on_last_page_cancel(self, *args): |
def on_last_page_cancel(self, *args): |
127 |
self.hide() |
self.hide() |
128 |
|
|
129 |
|
def on_last_page_prepare(self, *args): |
130 |
|
if self._err: |
131 |
|
self.display_error(_("Feed Not Found"),(_("No feed was found in %s. Please make sure you typed the correct location.") % url)) |
132 |
|
self._find_assistant.set_show_finish(gtk.FALSE) |
133 |
|
else: |
134 |
|
self.display_selected_feeds() |
135 |
|
return gtk.TRUE |
136 |
|
|
137 |
def on_subscribe_site_entry_delete_text(self, widget, start, end): |
def on_subscribe_site_entry_delete_text(self, widget, start, end): |
138 |
gtk.timeout_add(1, self.entry_delete) |
gtk.timeout_add(1, self.entry_delete) |
|
return |
|
139 |
|
|
140 |
def entry_delete(self): |
def entry_delete(self): |
141 |
text = self._subscribe_site_entry.get_text() |
text = self._subscribe_site_entry.get_text() |
142 |
if text == "": |
if text == "": |
143 |
# FIXME: gtk.Entry.set_text("") emits a delete_text signal :( |
self._find_assistant.set_buttons_sensitive(gtk.TRUE, gtk.FALSE, gtk.TRUE, gtk.FALSE) |
144 |
#self._find_assistant.set_buttons_sensitive(gtk.TRUE, gtk.FALSE, gtk.TRUE, gtk.FALSE) |
|
145 |
return |
def on_subscribe_site_entry_paste_clipboard(self, *args): |
146 |
|
self._find_assistant.set_buttons_sensitive(gtk.TRUE, gtk.TRUE, gtk.TRUE, gtk.TRUE) |
147 |
|
return gtk.TRUE |
148 |
|
|
149 |
def on_subscribe_site_entry_key_press_event(self, widget, event): |
def on_subscribe_site_entry_key_press_event(self, widget, event): |
150 |
self.disable_button(next=gtk.TRUE) |
self._find_assistant.set_buttons_sensitive(gtk.TRUE, gtk.TRUE, gtk.TRUE, gtk.TRUE) |
151 |
if event.keyval == gtk.keysyms.Return: |
if event.keyval == gtk.keysyms.Return: |
152 |
url = self._subscribe_site_entry.get_text() |
url = self._subscribe_site_entry.get_text().strip() |
153 |
if self._feed_url == url: |
if self._url == url: |
154 |
if self._feed_count > 1: |
if (len(self._feeds > 1)): |
155 |
self._find_assistant.set_page(self._multiple_feed_page) |
self._find_assistant.set_page(self._multiple_feed_page) |
156 |
else: |
else: |
157 |
self._find_assistant.set_page(self._last_page) |
self._find_assistant.set_page(self._last_page) |
158 |
else: |
else: |
159 |
rw = gtk.gdk.get_default_root_window() |
set_busy_cursor() |
|
rw.set_cursor(busy_cursor) |
|
160 |
self.find_site(url) |
self.find_site(url) |
161 |
rw.set_cursor(ready_cursor) |
set_ready_cursor() |
162 |
self._feed_url = url |
self._url = url |
163 |
|
|
164 |
return gtk.TRUE |
return gtk.TRUE |
165 |
|
|
167 |
self.hide() |
self.hide() |
168 |
return gtk.TRUE |
return gtk.TRUE |
169 |
|
|
|
def disable_button(self, back=gtk.TRUE, next=gtk.TRUE, cancel=gtk.TRUE, help=gtk.TRUE ): |
|
|
# next will be synonymous to finish |
|
|
self._find_assistant.set_buttons_sensitive(back, next, cancel, help) |
|
|
|
|
170 |
def show(self, url): |
def show(self, url): |
171 |
self._start_page.show() |
self._start_page.show() |
172 |
self._last_page.show() |
self._last_page.show() |
175 |
self.find_site(url) |
self.find_site(url) |
176 |
|
|
177 |
def hide(self): |
def hide(self): |
178 |
self._new_feed = None |
self._url = "" |
179 |
self._find_assistant.set_page(self._start_page) |
self._feeds.clear() |
180 |
self._subscribe_site_entry.set_text("") |
self._err = bool(0) |
|
self._feed_url = "" |
|
|
self._feed_count = 0 |
|
|
self._feed_is_parsed = bool(0) |
|
181 |
|
|
182 |
self._window.hide() |
self._window.hide() |
183 |
self._start_page.hide() |
self._start_page.hide() |
184 |
self._last_page.hide() |
self._last_page.hide() |
185 |
|
self._find_assistant.set_page(self._start_page) |
186 |
|
|
187 |
def create_columns(self, treeview): |
def create_columns(self, treeview): |
188 |
for cname, cnum in [('URL', self.COLUMN_URL), |
renderer = gtk.CellRendererToggle() |
189 |
(_('Title'), self.COLUMN_TITLE), |
column = gtk.TreeViewColumn(_('Subscribe'), renderer, |
190 |
(_('Description'), self.COLUMN_DESCRIPTION)]: |
active=self.COLUMN_STATUS_FLAG) |
191 |
|
treeview.append_column(column) |
192 |
|
renderer.connect('toggled', self.sticky_toggled) |
193 |
|
|
194 |
|
for cname, cnum in [(_('Title'), self.COLUMN_TITLE), |
195 |
|
(_('Description'), self.COLUMN_DESCRIPTION), |
196 |
|
(_('URL'), self.COLUMN_URL),]: |
197 |
renderer = gtk.CellRendererText() |
renderer = gtk.CellRendererText() |
198 |
column = gtk.TreeViewColumn(cname, renderer, text = cnum) |
column = gtk.TreeViewColumn(cname, renderer, text = cnum) |
199 |
treeview.append_column(column) |
treeview.append_column(column) |
200 |
|
|
201 |
def display_selected_feed(self, feed=None, ps=None): |
def sticky_toggled(self, cell, path): |
202 |
#self._subscribe_feed_found_url.set_text(feed.access_info[0]) |
model = self._subscribe_multiple_match_view.get_model() |
203 |
if feed is not None and ps is not None: |
iter = model.get_iter((int(path),)) |
204 |
self._find_assistant.set_page(self._last_page) |
feed = model.get_value(iter, self.COLUMN_FEED) |
205 |
|
ps = model.get_value(iter, self.COLUMN_PARSEDSUMMARY) |
206 |
|
feed.sticky = not feed.sticky |
207 |
|
id = feed.id |
208 |
|
|
209 |
|
if feed.sticky: |
210 |
|
self.add_feed(id, feed, ps) |
211 |
|
else: |
212 |
|
self.remove_feed(id) |
213 |
|
|
214 |
|
model.set(iter, self.COLUMN_STATUS_FLAG, feed.sticky) |
215 |
|
|
216 |
|
|
217 |
|
def add_feed(self, id, feed, summary): |
218 |
|
self._feeds[id] = (feed, summary) |
219 |
|
|
220 |
|
def remove_feed(self, id): |
221 |
|
del self._feeds[id] |
222 |
|
|
223 |
|
def display_selected_feeds(self): |
224 |
|
self._find_assistant.set_page(self._last_page) |
225 |
|
if (len(self._feeds) == 1): |
226 |
|
for f in self._feeds: |
227 |
|
feed, ps = self._feeds[f] |
228 |
|
title = ps.title |
229 |
|
description = ps.description |
230 |
|
|
231 |
text = _("Press the Apply button if you want to subscribe to the feed below.\n\n") |
text = _("Press the Apply button if you want to subscribe to the feed below.\n\n") |
232 |
if len(feed.title): |
text += _("Title: %s \n") % title |
233 |
text += _("Title: %s \n") % feed.title |
|
234 |
if len(feed.channel_description): |
if (len(description)): |
235 |
text += _("Description: %s \n") % feed.channel_description |
text += _("Description: %s \n") % description |
236 |
|
else: |
237 |
|
text = _("Press the Apply button if you want to subscribe to the following feeds:\n\n") |
238 |
|
iter = self._feeds.itervalues() |
239 |
|
for f in self._feeds: |
240 |
|
text += _("\t%s\n") % iter.next()[0].title |
241 |
|
|
242 |
self._last_page.set_title(_("Feed Found")) |
self._last_page.set_title(_("Feed Found")) |
243 |
self._last_page.set_text(text) |
self._last_page.set_text(text) |
244 |
|
|
245 |
|
return gtk.TRUE |
246 |
|
|
|
self._new_feed = (feed, ps) |
|
247 |
def parse_feed(self, data, feed): |
def parse_feed(self, data, feed): |
248 |
try: |
try: |
|
parsed = straw.SummaryParser().parse(data, feed) |
|
|
except straw.RSSParseException, e: |
|
249 |
parsed = straw.SummaryParserMP().parse(data, feed) |
parsed = straw.SummaryParserMP().parse(data, feed) |
|
parsed.invalid_rss = 1 |
|
250 |
except Exception, e: |
except Exception, e: |
251 |
log("parse_feed: caught exception ", e) |
log("parse_feed: caught exception ", e) |
252 |
traceback.print_exc() |
traceback.print_exc() |
253 |
return None |
self.display_error(_("Fatal Error"), |
254 |
self._feed_is_parsed = bool(1) |
_("A fatal error occurred while processing this operation. Please report it to the maintainer. Error: %s") % e) |
255 |
|
return |
256 |
|
|
257 |
return parsed |
return parsed |
258 |
|
|
259 |
def display_feed_choices(self, feeds): |
def display_feed_choices(self, feeds): |
261 |
model.clear() |
model.clear() |
262 |
for feed, ps in feeds: |
for feed, ps in feeds: |
263 |
iter = model.append() |
iter = model.append() |
264 |
model.set(iter, self.COLUMN_URL, feed.access_info[0], |
model.set(iter, self.COLUMN_TITLE, feed.title, |
|
self.COLUMN_TITLE, feed.title, |
|
265 |
self.COLUMN_DESCRIPTION, feed.channel_description, |
self.COLUMN_DESCRIPTION, feed.channel_description, |
266 |
self.COLUMN_FEED, feed, self.COLUMN_PARSEDSUMMARY, ps) |
self.COLUMN_FEED, feed, self.COLUMN_PARSEDSUMMARY, ps, |
267 |
|
self.COLUMN_STATUS_FLAG, feed.sticky, |
268 |
|
self.COLUMN_URL, feed.access_info[0]) |
269 |
self._find_assistant.set_page(self._multiple_feed_page) |
self._find_assistant.set_page(self._multiple_feed_page) |
270 |
|
|
271 |
def display_error(self, title, body): |
def display_error(self, title, body): |
272 |
|
self._err = bool(1) |
273 |
self._find_assistant.set_page(self._last_page) |
self._find_assistant.set_page(self._last_page) |
274 |
self._last_page.set_title(title) |
self._last_page.set_title(title) |
275 |
self._last_page.set_text("%s" % body) |
self._last_page.set_text("%s" % body) |
|
self.disable_button(next=gtk.FALSE) |
|
|
return |
|
|
|
|
276 |
|
|
277 |
def find_site(self, site): |
def find_site(self, site): |
278 |
while gtk.events_pending(): |
self._feeds.clear() |
279 |
gtk.mainiteration() |
|
280 |
try: |
try: |
281 |
feeds = straw.rssfinder.getFeeds(site) |
feeds = straw.rssfinder.getFeeds(site) |
282 |
except IOError, e: |
except IOError, e: |
283 |
self.display_error(_("Cannot Find Host"),(_("Straw cannot find %s. Please check your connection then try again") % site)) |
return 1 |
|
return |
|
284 |
except Exception, e: |
except Exception, e: |
285 |
log("caught an exception: ", e) |
log("caught an exception: ", e) |
286 |
traceback.print_exc() |
traceback.print_exc() |
287 |
self.display_error(_("Fatal Error"),_("A fatal error occurred while processing this feed. Please report it to the maintainer")) |
return 1 |
|
return |
|
288 |
|
|
289 |
len_feeds = len(feeds) |
len_feeds = len(feeds) |
|
self._feed_count = int(len_feeds) |
|
290 |
|
|
291 |
if len_feeds < 1: |
if len_feeds < 1: |
292 |
self.display_error(_("Feed Not Found"),(_("No feed was found in %s. Please make sure you typed the correct location.") % site)) |
return 1 |
|
return |
|
293 |
if len_feeds == 1: |
if len_feeds == 1: |
294 |
feed = straw.Feed("temporary feed", feeds[0][0]) |
feed = straw.Feed("temporary feed", feeds[0][0]) |
295 |
ps = self.parse_feed(feeds[0][1], feed) |
ps = self.parse_feed(feeds[0][1], feed) |
296 |
feed.title = ps.title |
feed.title = ps.title |
297 |
feed.channel_description = ps.description |
feed.channel_description = ps.description |
298 |
self.display_selected_feed(feed, ps) |
self.add_feed(feed.id, feed, ps) |
299 |
|
self.display_selected_feeds() |
300 |
else: |
else: |
301 |
dfeeds = [] |
dfeeds = [] |
302 |
for url, data in feeds: |
for url, data in feeds: |
304 |
ps = self.parse_feed(data, feed) |
ps = self.parse_feed(data, feed) |
305 |
feed.title = ps.title |
feed.title = ps.title |
306 |
feed.channel_description = ps.description |
feed.channel_description = ps.description |
307 |
|
feed.sticky = 0 |
308 |
dfeeds.append((feed, ps)) |
dfeeds.append((feed, ps)) |
309 |
self.display_feed_choices(dfeeds) |
self.display_feed_choices(dfeeds) |
310 |
|
|