1 """ FeedPropertiesDialog.py
3 Provides a module for handling the properties of a feed
5 __copyright__
= "Copyright (c) 2002-2005 Free Software Foundation, Inc."
7 Straw is free software; you can redistribute it and/or modify it under the
8 terms of the GNU General Public License as published by the Free Software
9 Foundation; either version 2 of the License, or (at your option) any later
12 Straw is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License along with
17 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18 Place - Suite 330, Boston, MA 02111-1307, USA. """
23 from error
import log
, logparam
, logtb
24 from xml
.sax
import saxutils
26 from gtk
.glade
import XML
35 from straw
import helpers
37 class FeedPropertyView(MVP
.GladeView
):
43 def _initialize(self
):
45 self
._defaults
= {'title':'','url':'','username':'','password':''}
46 self
._window
= self
._widget
.get_widget('feed_properties')
47 self
._title
= self
._widget
.get_widget('properties_title_entry')
48 self
._location
= self
._widget
.get_widget('properties_location_entry')
49 self
._username
= self
._widget
.get_widget('properties_username_entry')
50 self
._password
= self
._widget
.get_widget('properties_password_entry')
52 self
._next
_refresh
_label
= self
._widget
.get_widget('properties_next_refresh_label')
53 self
._previous
_refresh
_label
= self
._widget
.get_widget('properties_previous_refresh_label')
55 self
._restore
_button
= self
._widget
.get_widget('properties_reset_button')
56 self
._refresh
_spin
= self
._widget
.get_widget('properties_refresh_spin')
57 self
._articles
_spin
= self
._widget
.get_widget('properties_articles_spin')
58 self
._refresh
_default
_check
= self
._widget
.get_widget('properties_keep_refresh_default')
59 self
._articles
_default
_check
= self
._widget
.get_widget('properties_keep_articles_default')
61 self
._categories
_treeview
= self
._widget
.get_widget('feed_categories_treeview')
63 self
._feed
_info
_description
= self
._widget
.get_widget('feed_info_description')
64 self
._feed
_info
_copyright
= self
._widget
.get_widget('feed_info_copyright')
65 self
._feed
_info
_link
_box
= self
._widget
.get_widget('feed_info_link_box')
67 model
= gtk
.ListStore(gobject
.TYPE_STRING
, gobject
.TYPE_BOOLEAN
,
68 gobject
.TYPE_PYOBJECT
)
69 self
._categories
_treeview
.set_model(model
)
70 self
._categories
_treeview
.set_rules_hint(True)
72 r
= gtk
.CellRendererToggle()
73 r
.connect('toggled', self
.member_toggled
)
74 column
= gtk
.TreeViewColumn(_('Member'), r
, active
=self
.COLUMN_MEMBER
)
75 self
._categories
_treeview
.append_column(column
)
77 r
= gtk
.CellRendererText()
78 column
= gtk
.TreeViewColumn(_('Name'), r
, text
=self
.COLUMN_NAME
)
79 self
._categories
_treeview
.append_column(column
)
81 def set_feed(self
, feed
):
84 def member_toggled(self
, cell
, path
):
85 model
= self
._categories
_treeview
.get_model()
86 category
= model
[path
][self
.COLUMN_OBJECT
]
87 if self
._feed
in category
.feeds
:
88 category
.remove_feed(self
._feed
)
89 model
[path
][self
.COLUMN_MEMBER
] = False
91 category
.append_feed(self
._feed
, False)
92 model
[path
][self
.COLUMN_MEMBER
] = True
95 self
._initializing
_window
= True
96 self
.display_properties()
97 self
._window
.present()
98 self
._initializing
_window
= False
100 def hide(self
, *args
):
101 self
._presenter
.activate_deleter()
103 self
._window
.destroy()
105 def _on_feed_properties_delete_event(self
, *args
):
109 def _on_properties_close_button_clicked(self
, *args
):
113 def display_properties(self
):
114 """self._defaults['title'] = self._feed.title
115 loc, un, pw = "", "", ""#self._feed.access_info
116 self._defaults['url'] = loc
117 self._defaults['username'] = un
118 self._defaults['password'] = pw
119 self._defaults['frequency'] = self._feed.poll_frequency
120 self._defaults['stored'] = self._feed.number_of_items_stored
122 self._window.set_title(_("%s Properties") % self._feed.title)
123 self._title.set_text(self._feed.title)
124 self._location.set_text(self._feed.access_info[0])
126 config = Config.get_instance()
127 if self._feed.poll_frequency == feeds.Feed.DEFAULT:
128 freq = config.poll_frequency
130 self._refresh_keep = True
132 freq = self._feed.poll_frequency
134 self._refresh_keep = False
135 self._refresh_spin.set_value(float(freq / 60))
136 self._refresh_spin.set_sensitive(not fdefault)
137 self._refresh_default_check.set_active(fdefault)
138 if self._feed.number_of_items_stored == feeds.Feed.DEFAULT:
139 nitems = config.number_of_items_stored
141 self._articles_keep = True
143 nitems = self._feed.number_of_items_stored
145 self._articles_keep = False
146 self._articles_spin.set_value(float(nitems))
147 self._articles_spin.set_sensitive(not nidefault)
148 self._articles_default_check.set_active(nidefault)
151 self._username.set_text(un)
153 self._password.set_text(pw)
155 model = self._categories_treeview.get_model()
157 fclist = feeds.category_list
158 for c in fclist.user_categories:
159 iter = model.append()
161 self.COLUMN_NAME, c.title,
162 self.COLUMN_MEMBER, self._feed in c.feeds,
163 self.COLUMN_OBJECT, c)
165 self._previous_refresh_label.set_text(
166 helpers.format_date(time.gmtime(self._feed.last_poll)))
167 next = self._feed.next_refresh
169 self._next_refresh_label.set_text(
170 helpers.format_date(time.gmtime(next)))
171 self._next_refresh_label.show()
173 self._next_refresh_label.hide()"""
175 self
._display
_feed
_information
(self
._feed
)
176 self
._restore
_button
.set_sensitive(False)
178 def _display_feed_information(self
, feed
):
179 #title = helpers.convert_entities(feed.channel_title)
181 # title = feed.title or feed.channel_link
182 #title = title.strip()
184 #link = feed.channel_link.strip()
186 if not link
: link
= feed
.location
187 print "link = %s" % link
190 link_button
= gtk
.LinkButton(link
, link
)
191 self
._feed
_info
_link
_box
.pack_end(link_button
)
192 gtk
.link_button_set_uri_hook(self
._load
_uri
, link
)
193 self
._feed
_info
_link
_box
.show_all()
195 description
= helpers
.convert_entities(feed
.channel_description
.strip())
196 if description
and description
!= title
:
197 description
= read_text(description
, len(description
))
198 self
._feed
_info
_description
.set_text(helpers
.convert_entities(description
))
199 self
._feed
_info
_description
.show()
201 self
._feed
_info
_description
.hide()
203 copyright
= helpers
.convert_entities(feed
.channel_copyright
)
205 self
._feed
_info
_copyright
.set_text(copyright
)
206 self
._feed
_info
_copyright
.show()
208 self
._feed
_info
_copyright
.hide()
210 def _load_uri(self
, widget
, event
, data
):
211 helpers
.url_show(data
)
213 def restore_defaults(self
):
214 # FIXME: add frequency and number of items and the default flags
215 self
._feed
.title
= self
._defaults
['title']
216 self
._feed
.access_info
= (
217 self
._defaults
['url'], self
._defaults
['username'], self
._defaults
['password'])
218 self
._title
.set_text(self
._feed
.title
)
219 self
._location
.set_text(self
._feed
.location
)
220 self
._username
.set_text(self
._defaults
.get('username',''))
221 self
._password
.set_text(self
._defaults
.get('password',''))
222 self
._refresh
_default
_check
.set_active(self
._refresh
_keep
)
223 if not self
._refresh
_keep
:
224 self
._refresh
_spin
.set_value(float(self
._refresh
_default
))
225 self
._articles
_default
_check
.set_active(self
._articles
_keep
)
226 if not self
._articles
_keep
:
227 self
._articles
_spin
.set_value(float(self
._articles
_default
))
228 self
._restore
_button
.set_sensitive(False)
230 def _on_properties_title_entry_insert_text(self
, *args
):
231 if self
._initializing
_window
:
233 self
._restore
_button
.set_sensitive(True)
235 def _on_properties_title_entry_delete_text(self
, *args
):
236 if self
._initializing
_window
:
238 self
._restore
_button
.set_sensitive(True)
240 def _on_properties_title_entry_focus_out_event(self
, widget
, *args
):
241 self
._feed
.title
= widget
.get_text().strip()
243 def _on_properties_location_entry_insert_text(self
, *args
):
244 if self
._initializing
_window
:
246 self
._restore
_button
.set_sensitive(True)
248 def _on_properties_location_entry_delete_text(self
, *args
):
249 if self
._initializing
_window
:
251 self
._restore
_button
.set_sensitive(True)
253 def _on_properties_location_entry_focus_out_event(self
, widget
, *args
):
254 loc
, username
, pw
= self
._feed
.access_info
255 self
._feed
.access_info
= (widget
.get_text().strip(), username
, pw
)
257 def _on_properties_username_entry_insert_text(self
, *args
):
258 if self
._initializing
_window
:
260 self
._restore
_button
.set_sensitive(True)
262 def _on_properties_username_entry_delete_text(self
, *args
):
263 if self
._initializing
_window
:
265 self
._restore
_button
.set_sensitive(False)
267 def _on_properties_username_entry_focus_out_event(self
, widget
, *args
):
268 self
._presenter
.set_username(widget
.get_text().strip())
270 def _on_properties_password_entry_insert_text(self
, *args
):
271 if self
._initializing
_window
:
273 self
._restore
_button
.set_sensitive(True)
275 def _on_properties_password_entry_delete_text(self
, *args
):
276 if self
._initializing
_window
:
278 self
._restore
_button
.set_sensitive(False)
280 def _on_properties_password_entry_focus_out_event(self
, widget
, *args
):
281 self
._presenter
.set_password(widget
.get_text().strip())
283 def _on_properties_reset_button_clicked(self
, *args
):
284 self
.restore_defaults()
286 def _on_properties_refresh_spin_focus_out_event(self
, widget
, *args
):
288 value
= widget
.get_value_as_int()
289 self
._presenter
.set_poll_frequency(value
)
291 def _on_properties_articles_spin_focus_out_event(self
, widget
, *args
):
293 value
= widget
.get_value_as_int()
294 self
._presenter
.set_items_stored(value
)
296 def _on_properties_articles_spin_value_changed(self
, widget
, *args
):
297 if self
._initializing
_window
:
299 self
._restore
_button
.set_sensitive(True)
301 def _on_properties_refresh_spin_value_changed(self
, widget
, *args
):
302 if self
._initializing
_window
:
304 self
._restore
_button
.set_sensitive(True)
306 def _on_properties_keep_refresh_default_toggled(self
, widget
, *args
):
307 if self
._initializing
_window
:
309 isactive
= widget
.get_active()
311 self
._presenter
.set_poll_frequency(feeds
.Feed
.DEFAULT
)
312 self
._refresh
_spin
.set_value(float(Config
.get_instance().poll_frequency
/ 60))
314 self
._presenter
.set_poll_frequency(self
._refresh
_spin
.get_value_as_int() * 60)
316 self
._refresh
_spin
.set_sensitive(not isactive
)
317 self
._restore
_button
.set_sensitive(True)
319 def _on_properties_keep_articles_default_toggled(self
, widget
, *args
):
320 if self
._initializing
_window
:
322 isactive
= widget
.get_active()
324 self
._presenter
.set_items_stored(feeds
.Feed
.DEFAULT
)
325 self
._articles
_spin
.set_value(float(Config
.get_instance().number_of_items_stored
))
327 self
._presenter
.set_items_stored(self
._articles
_spin
.get_value_as_int())
328 self
._articles
_spin
.set_sensitive(not isactive
)
329 self
._restore
_button
.set_sensitive(True)
332 class FeedPropertyPresenter(MVP
.BasicPresenter
):
336 def _initialize(self
):
340 def set_deleter(self
, deleter
):
341 self
._deleter
= deleter
343 def activate_deleter(self
):
347 def set_feed(self
, feed
):
349 self
._view
.set_feed(self
._feed
)
351 def set_username(self
, username
):
352 loc
, uname
, pw
= self
._feed
.access_info
353 self
._feed
.access_info
= (loc
, username
, pw
)
355 def set_password(self
, password
):
356 loc
, uname
, pw
= self
._feed
.access_info
357 self
._feed
.access_info
= (loc
, uname
, password
)
359 def set_poll_frequency(self
, pf
):
360 if pf
!= self
._feed
.poll_frequency
:
361 self
._feed
.poll_frequency
= pf
* FeedPropertyPresenter
.TIME_INTERVAL
363 def set_items_stored(self
, nitems
):
364 if nitems
!= self
._feed
.number_of_items_stored
:
365 self
._feed
.number_of_items_stored
= nitems
368 def feed_properties_show(feed
):
370 class _dialogdeleter
:
371 def __init__(self
, feed
, hash):
378 dialog
= dialogs
.get(feed
, None)
381 gladefile
= XML(os
.path
.join(straw
.STRAW_DATA_DIR
, "feed-properties.glade"))
382 #idget_tree = gladefile.get_widget_tree('feed_properties')
383 dialog
= FeedPropertyPresenter(view
=FeedPropertyView(gladefile
))
384 dialog
.set_feed(feed
)
385 dialog
.set_deleter(_dialogdeleter(feed
, dialogs
))
386 dialogs
[feed
] = dialog
390 def read_text(fragment
, chars
):
391 """Read chars cdata characters from html fragment fragment"""
392 parser
= SummaryParser
.TitleImgParser()
393 parser
.feed(fragment
)
394 text
= parser
.get_text(chars
)