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. """
21 from error
import log
, logparam
, logtb
22 from xml
.sax
import saxutils
31 import FeedCategoryList
36 class FeedPropertyView(MVP
.GladeView
):
42 def _initialize(self
):
44 self
._defaults
= {'title':'','url':'','username':'','password':''}
45 self
._window
= self
._widget
.get_widget('feed_properties')
46 self
._title
= self
._widget
.get_widget('properties_title_entry')
47 self
._location
= self
._widget
.get_widget('properties_location_entry')
48 self
._username
= self
._widget
.get_widget('properties_username_entry')
49 self
._password
= self
._widget
.get_widget('properties_password_entry')
50 self
._username
_title
= self
._widget
.get_widget('properties_username_label')
51 self
._password
_title
= self
._widget
.get_widget('properties_password_label')
52 self
._restore
_button
= self
._widget
.get_widget('properties_reset_button')
53 self
._refresh
_spin
= self
._widget
.get_widget('properties_refresh_spin')
54 self
._articles
_spin
= self
._widget
.get_widget('properties_articles_spin')
55 self
._refresh
_default
_check
= self
._widget
.get_widget('properties_keep_refresh_default')
56 self
._articles
_default
_check
= self
._widget
.get_widget('properties_keep_articles_default')
57 self
._next
_refresh
_label
= self
._widget
.get_widget('properties_next_refresh_label')
58 self
._previous
_refresh
_label
= self
._widget
.get_widget('properties_previous_refresh_label')
59 self
._categories
_treeview
= self
._widget
.get_widget('feed_categories_treeview')
60 self
._feed
_info
_href
_container
= self
._widget
.get_widget('feed_info_href_container')
61 self
._feed
_info
_description
= self
._widget
.get_widget('feed_info_description')
62 self
._feed
_info
_copyright
= self
._widget
.get_widget('feed_info_copyright')
63 self
._feed
_info
_href
= self
._widget
.get_widget('properties_link')
65 model
= gtk
.ListStore(gobject
.TYPE_STRING
, gobject
.TYPE_BOOLEAN
,
66 gobject
.TYPE_PYOBJECT
)
67 self
._categories
_treeview
.set_model(model
)
68 self
._categories
_treeview
.set_rules_hint(True)
70 r
= gtk
.CellRendererToggle()
71 r
.connect('toggled', self
.member_toggled
)
72 column
= gtk
.TreeViewColumn(_('Member'), r
, active
=self
.COLUMN_MEMBER
)
73 self
._categories
_treeview
.append_column(column
)
75 r
= gtk
.CellRendererText()
76 column
= gtk
.TreeViewColumn(_('Name'), r
, text
=self
.COLUMN_NAME
)
77 self
._categories
_treeview
.append_column(column
)
79 def set_feed(self
, feed
):
82 def set_parent(self
, parent
):
83 self
._window
.set_transient_for(parent
)
85 def member_toggled(self
, cell
, path
):
86 model
= self
._categories
_treeview
.get_model()
87 category
= model
[path
][self
.COLUMN_OBJECT
]
88 if self
._feed
in category
.feeds
:
89 category
.remove_feed(self
._feed
)
90 model
[path
][self
.COLUMN_MEMBER
] = False
92 category
.append_feed(self
._feed
, False)
93 model
[path
][self
.COLUMN_MEMBER
] = True
96 self
._initializing
_window
= True
97 self
.display_properties()
99 self
._initializing
_window
= False
101 def hide(self
, *args
):
102 self
._presenter
.activate_deleter()
104 self
._window
.destroy()
106 def _on_feed_properties_delete_event(self
, *args
):
110 def _on_properties_close_button_clicked(self
, *args
):
114 def display_properties(self
):
115 self
._defaults
['title'] = self
._feed
.title
116 loc
, un
, pw
= self
._feed
.access_info
117 self
._defaults
['url'] = loc
118 self
._defaults
['username'] = un
119 self
._defaults
['password'] = pw
120 self
._defaults
['frequency'] = self
._feed
.poll_frequency
121 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])
125 config
= Config
.get_instance()
126 if self
._feed
.poll_frequency
== Feed
.Feed
.DEFAULT
:
127 freq
= config
.poll_frequency
129 self
._refresh
_keep
= True
131 freq
= self
._feed
.poll_frequency
133 self
._refresh
_keep
= False
134 self
._refresh
_spin
.set_value(float(freq
/ 60))
135 self
._refresh
_spin
.set_sensitive(not fdefault
)
136 self
._refresh
_default
_check
.set_active(fdefault
)
137 if self
._feed
.number_of_items_stored
== Feed
.Feed
.DEFAULT
:
138 nitems
= config
.number_of_items_stored
140 self
._articles
_keep
= True
142 nitems
= self
._feed
.number_of_items_stored
144 self
._articles
_keep
= False
145 self
._articles
_spin
.set_value(float(nitems
))
146 self
._articles
_spin
.set_sensitive(not nidefault
)
147 self
._articles
_default
_check
.set_active(nidefault
)
150 self
._username
.set_text(un
)
151 self
._password
.set_text(pw
)
153 model
= self
._categories
_treeview
.get_model()
155 fclist
= FeedCategoryList
.get_instance()
156 for c
in fclist
.user_categories
:
157 iter = model
.append()
159 self
.COLUMN_NAME
, c
.title
,
160 self
.COLUMN_MEMBER
, self
._feed
in c
.feeds
,
161 self
.COLUMN_OBJECT
, c
)
163 self
._previous
_refresh
_label
.set_text(
164 utils
.format_date(time
.gmtime(self
._feed
.last_poll
)))
165 next
= self
._feed
.next_refresh
167 self
._next
_refresh
_label
.set_text(
168 utils
.format_date(time
.gmtime(next
)))
169 self
._next
_refresh
_label
.show()
171 self
._next
_refresh
_label
.hide()
173 self
._display
_feed
_information
(self
._feed
)
174 self
._restore
_button
.set_sensitive(False)
176 def _display_feed_information(self
, feed
):
177 title
= utils
.convert_entities(feed
.channel_title
)
181 title
= feed
.channel_link
182 title
= title
.strip()
184 link
= feed
.channel_link
.strip()
185 if len(link
) < 1: link
= feed
.location
188 #self._feed_info_href.set_text(saxutils.escape(title))
189 self
._feed
_info
_href
.set_uri(link
)
190 self
._feed
_info
_href
.set_sensitive(len(link
) > 0)
191 self
._feed
_info
_href
.show()
193 self
._feed
_info
_href
.hide()
195 description
= utils
.convert_entities(feed
.channel_description
.strip())
196 size
= len(description
)
197 if size
and description
!= title
:
198 description
= read_text(description
, size
)
199 self
._feed
_info
_description
.set_text(utils
.convert_entities(description
))
200 self
._feed
_info
_description
.show()
202 self
._feed
_info
_description
.hide()
204 copyright
= utils
.convert_entities(feed
.channel_copyright
)
205 self
._feed
_info
_copyright
.set_text(copyright
)
207 self
._feed
_info
_copyright
.show()
209 self
._feed
_info
_copyright
.hide()
211 def restore_defaults(self
):
212 # FIXME: add frequency and number of items and the default flags
213 self
._feed
.title
= self
._defaults
['title']
214 self
._feed
.access_info
= (
215 self
._defaults
['url'], self
._defaults
['username'], self
._defaults
['password'])
216 self
._title
.set_text(self
._feed
.title
)
217 self
._location
.set_text(self
._feed
.location
)
218 self
._username
.set_text(self
._defaults
.get('username',''))
219 self
._password
.set_text(self
._defaults
.get('password',''))
220 self
._refresh
_default
_check
.set_active(self
._refresh
_keep
)
221 if not self
._refresh
_keep
:
222 self
._refresh
_spin
.set_value(float(self
._refresh
_default
))
223 self
._articles
_default
_check
.set_active(self
._articles
_keep
)
224 if not self
._articles
_keep
:
225 self
._articles
_spin
.set_value(float(self
._articles
_default
))
226 self
._restore
_button
.set_sensitive(False)
228 def _on_properties_title_entry_insert_text(self
, *args
):
229 if self
._initializing
_window
:
231 self
._restore
_button
.set_sensitive(True)
233 def _on_properties_title_entry_delete_text(self
, *args
):
234 if self
._initializing
_window
:
236 self
._restore
_button
.set_sensitive(True)
238 def _on_properties_title_entry_focus_out_event(self
, widget
, *args
):
239 self
._feed
.title
= widget
.get_text().strip()
241 def _on_properties_location_entry_insert_text(self
, *args
):
242 if self
._initializing
_window
:
244 self
._restore
_button
.set_sensitive(True)
246 def _on_properties_location_entry_delete_text(self
, *args
):
247 if self
._initializing
_window
:
249 self
._restore
_button
.set_sensitive(True)
251 def _on_properties_location_entry_focus_out_event(self
, widget
, *args
):
252 loc
, username
, pw
= self
._feed
.access_info
253 self
._feed
.access_info
= (widget
.get_text().strip(), username
, pw
)
255 def _on_properties_username_entry_insert_text(self
, *args
):
256 if self
._initializing
_window
:
258 self
._restore
_button
.set_sensitive(True)
260 def _on_properties_username_entry_delete_text(self
, *args
):
261 if self
._initializing
_window
:
263 self
._restore
_button
.set_sensitive(False)
265 def _on_properties_username_entry_focus_out_event(self
, widget
, *args
):
266 self
._presenter
.set_username(widget
.get_text().strip())
268 def _on_properties_password_entry_insert_text(self
, *args
):
269 if self
._initializing
_window
:
271 self
._restore
_button
.set_sensitive(True)
273 def _on_properties_password_entry_delete_text(self
, *args
):
274 if self
._initializing
_window
:
276 self
._restore
_button
.set_sensitive(False)
278 def _on_properties_password_entry_focus_out_event(self
, widget
, *args
):
279 self
._presenter
.set_password(widget
.get_text().strip())
281 def _on_properties_reset_button_clicked(self
, *args
):
282 self
.restore_defaults()
284 def _on_properties_refresh_spin_focus_out_event(self
, widget
, *args
):
286 value
= widget
.get_value_as_int()
287 self
._presenter
.set_poll_frequency(value
)
289 def _on_properties_articles_spin_focus_out_event(self
, widget
, *args
):
291 value
= widget
.get_value_as_int()
292 self
._presenter
.set_items_stored(value
)
294 def _on_properties_articles_spin_value_changed(self
, widget
, *args
):
295 if self
._initializing
_window
:
297 self
._restore
_button
.set_sensitive(True)
299 def _on_properties_refresh_spin_value_changed(self
, widget
, *args
):
300 if self
._initializing
_window
:
302 self
._restore
_button
.set_sensitive(True)
304 def _on_properties_keep_refresh_default_toggled(self
, widget
, *args
):
305 if self
._initializing
_window
:
307 isactive
= widget
.get_active()
309 self
._presenter
.set_poll_frequency(Feed
.Feed
.DEFAULT
)
310 self
._refresh
_spin
.set_value(float(Config
.get_instance().poll_frequency
/ 60))
312 self
._presenter
.set_poll_frequency(self
._refresh
_spin
.get_value_as_int() * 60)
314 self
._refresh
_spin
.set_sensitive(isactive
)
315 self
._restore
_button
.set_sensitive(True)
317 def _on_properties_keep_articles_default_toggled(self
, widget
, *args
):
318 if self
._initializing
_window
:
320 isactive
= widget
.get_active()
322 self
._presenter
.set_items_stored(Feed
.Feed
.DEFAULT
)
323 self
._articles
_spin
.set_value(float(Config
.get_instance().number_of_items_stored
))
325 self
._presenter
.set_items_stored(self
._articles
_spin
.get_value_as_int())
326 self
._articles
_spin
.set_sensitive(isactive
)
327 self
._restore
_button
.set_sensitive(True)
330 class FeedPropertyPresenter(MVP
.BasicPresenter
):
334 def _initialize(self
):
338 def set_deleter(self
, deleter
):
339 self
._deleter
= deleter
341 def activate_deleter(self
):
345 def set_feed(self
, feed
):
347 self
._view
.set_feed(self
._feed
)
349 def set_username(self
, username
):
350 loc
, uname
, pw
= self
._feed
.access_info
351 self
._feed
.access_info
= (loc
, username
, pw
)
353 def set_password(self
, password
):
354 loc
, uname
, pw
= self
._feed
.access_info
355 self
._feed
.access_info
= (loc
, uname
, password
)
357 def set_poll_frequency(self
, pf
):
358 if pf
!= self
._feed
.poll_frequency
:
359 self
._feed
.poll_frequency
= value
* TIME_INTERVAL
361 def set_items_stored(self
, nitems
):
362 if nitems
!= self
._feed
.number_of_items_stored
:
363 self
._feed
.number_of_items_stored
= nitems
366 def show_feed_properties(parent
, feed
):
368 class _dialogdeleter
:
369 def __init__(self
, feed
, hash):
376 dialog
= dialogs
.get(feed
, None)
378 widget_tree
= MVP
.get_widget_tree('feed_properties')
379 dialog
= FeedPropertyPresenter(view
=FeedPropertyView(widget_tree
))
380 dialog
.view
.set_parent(parent
)
381 dialog
.set_feed(feed
)
382 dialog
.set_deleter(_dialogdeleter(feed
, dialogs
))
383 dialogs
[feed
] = dialog
387 def read_text(fragment
, chars
):
388 """Read chars cdata characters from html fragment fragment"""
389 parser
= SummaryParser
.TitleImgParser()
390 parser
.feed(fragment
)
391 text
= parser
.get_text(chars
)