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
33 import FeedCategoryList
37 class FeedPropertiesDialog(object):
42 def __init__(self
, parent
, feed
, deleter
):
43 gladef
= utils
.find_glade_file()
44 xml
= gtk
.glade
.XML(gladef
, 'feed_properties_dialog', gettext
.textdomain())
45 self
._window
= xml
.get_widget('feed_properties_dialog')
46 self
._window
.set_transient_for(parent
)
47 self
._title
= xml
.get_widget('properties_title_entry')
48 self
._location
= xml
.get_widget('properties_location_entry')
49 self
._username
= xml
.get_widget('properties_username_entry')
50 self
._password
= xml
.get_widget('properties_password_entry')
51 self
._username
_title
= xml
.get_widget('properties_username_label')
52 self
._password
_title
= xml
.get_widget('properties_password_label')
53 self
._restore
_button
= xml
.get_widget('properties_reset_button')
54 self
._refresh
_spin
= xml
.get_widget('properties_refresh_spin')
55 self
._articles
_spin
= xml
.get_widget('properties_articles_spin')
56 self
._refresh
_default
_check
= xml
.get_widget(
57 'properties_keep_refresh_default')
58 self
._articles
_default
_check
= xml
.get_widget(
59 'properties_keep_articles_default')
60 self
._next
_refresh
_label
= xml
.get_widget(
61 'properties_next_refresh_label')
62 self
._previous
_refresh
_label
= xml
.get_widget(
63 'properties_previous_refresh_label')
64 self
._categories
_treeview
= xml
.get_widget('feed_categories_treeview')
65 self
._feed
_info
_href
_container
= xml
.get_widget(
66 'feed_info_href_container')
67 self
._feed
_info
_description
= xml
.get_widget('feed_info_description')
68 self
._feed
_info
_copyright
= xml
.get_widget('feed_info_copyright')
70 self
._feed
_info
_href
= gnome
.ui
.HRef(url
='', text
='')
71 self
._feed
_info
_href
_container
.pack_start(
72 self
._feed
_info
_href
, expand
=False, fill
=False)
74 self
._title
_default
= ''
75 self
._url
_default
= ''
79 self
._size
_group
= gtk
.SizeGroup(gtk
.SIZE_GROUP_HORIZONTAL
)
80 self
._size
_group
.add_widget(xml
.get_widget('properties_title_label'))
81 self
._size
_group
.add_widget(xml
.get_widget('properties_location_label'))
82 self
._size
_group
.add_widget(xml
.get_widget('properties_username_label'))
83 self
._size
_group
.add_widget(xml
.get_widget('properties_password_label'))
85 model
= gtk
.ListStore(gobject
.TYPE_STRING
, gobject
.TYPE_BOOLEAN
,
86 gobject
.TYPE_PYOBJECT
)
87 self
._categories
_treeview
.set_model(model
)
88 self
._categories
_treeview
.set_rules_hint(True)
90 r
= gtk
.CellRendererToggle()
91 r
.connect('toggled', self
.member_toggled
)
92 column
= gtk
.TreeViewColumn(_('Member'), r
, active
=self
.COLUMN_MEMBER
)
93 self
._categories
_treeview
.append_column(column
)
95 r
= gtk
.CellRendererText()
96 column
= gtk
.TreeViewColumn(_('Name'), r
, text
=self
.COLUMN_NAME
)
97 self
._categories
_treeview
.append_column(column
)
100 for key
in dir(self
.__class
__):
102 nameFuncMap
[key
] = getattr(self
, key
)
103 xml
.signal_autoconnect(nameFuncMap
)
105 self
._initializing
_window
= False
107 self
.deleter
= deleter
110 return self
._window
.window
.get_state()
113 self
._initializing
_window
= True
114 self
.display_properties()
115 self
._window
.present()
116 self
._initializing
_window
= False
118 def hide(self
, *args
):
121 self
._window
.destroy()
123 def on_feed_properties_dialog_delete_event(self
, *args
):
127 def on_feed_properties_close_button_clicked(self
, *args
):
131 def member_toggled(self
, cell
, path
):
132 model
= self
._categories
_treeview
.get_model()
133 category
= model
[path
][self
.COLUMN_OBJECT
]
134 if self
._feed
in category
.feeds
:
135 category
.remove_feed(self
._feed
)
136 model
[path
][self
.COLUMN_MEMBER
] = False
138 category
.append_feed(self
._feed
, False)
139 model
[path
][self
.COLUMN_MEMBER
] = True
141 def display_properties(self
):
142 self
._title
_default
= self
._feed
.title
143 loc
, un
, pw
= self
._feed
.access_info
144 self
._url
_default
= loc
145 self
._un
_default
= un
146 self
._pw
_default
= pw
147 self
._refresh
_default
= self
._feed
.poll_frequency
148 self
._articles
_default
= self
._feed
.number_of_items_stored
149 self
._window
.set_title(_("%s Properties") % self
._feed
.title
)
150 self
._title
.set_text(self
._feed
.title
)
151 self
._location
.set_text(self
._feed
.access_info
[0])
152 config
= Config
.get_instance()
153 if self
._feed
.poll_frequency
== Feed
.Feed
.DEFAULT
:
154 freq
= config
.poll_frequency
156 self
._refresh
_keep
= True
158 freq
= self
._feed
.poll_frequency
160 self
._refresh
_keep
= False
161 self
._refresh
_spin
.set_value(float(freq
/ 60))
162 self
._refresh
_spin
.set_sensitive(not fdefault
)
163 self
._refresh
_default
_check
.set_active(fdefault
)
164 if self
._feed
.number_of_items_stored
== Feed
.Feed
.DEFAULT
:
165 nitems
= config
.number_of_items_stored
167 self
._articles
_keep
= True
169 nitems
= self
._feed
.number_of_items_stored
171 self
._articles
_keep
= False
172 self
._articles
_spin
.set_value(float(nitems
))
173 self
._articles
_spin
.set_sensitive(not nidefault
)
174 self
._articles
_default
_check
.set_active(nidefault
)
177 self
._username
.set_text(un
)
178 self
._password
.set_text(pw
)
180 model
= self
._categories
_treeview
.get_model()
182 fclist
= FeedCategoryList
.get_instance()
183 for c
in fclist
.user_categories
:
184 iter = model
.append()
186 self
.COLUMN_NAME
, c
.title
,
187 self
.COLUMN_MEMBER
, self
._feed
in c
.feeds
,
188 self
.COLUMN_OBJECT
, c
)
190 self
._previous
_refresh
_label
.set_text(
191 utils
.format_date(time
.gmtime(self
._feed
.last_poll
)))
192 next
= self
._feed
.next_refresh
194 self
._next
_refresh
_label
.set_text(
195 utils
.format_date(time
.gmtime(next
)))
196 self
._next
_refresh
_label
.show()
198 self
._next
_refresh
_label
.hide()
200 self
._display
_feed
_information
(self
._feed
)
201 self
._restore
_button
.set_sensitive(False)
203 def _display_feed_information(self
, feed
):
204 title
= utils
.convert_entities(feed
.channel_title
)
208 title
= feed
.channel_link
209 title
= title
.strip()
211 link
= feed
.channel_link
.strip()
212 if len(link
) < 1: link
= feed
.location
215 self
._feed
_info
_href
.set_text(saxutils
.escape(title
))
216 self
._feed
_info
_href
.set_url(link
)
217 self
._feed
_info
_href
.set_sensitive(len(link
) > 0)
218 self
._feed
_info
_href
.show()
220 self
._feed
_info
_href
.hide()
222 description
= utils
.convert_entities(feed
.channel_description
.strip())
223 size
= len(description
)
224 if size
and description
!= title
:
225 description
= read_text(description
, size
)
226 self
._feed
_info
_description
.set_text(utils
.convert_entities(description
))
227 self
._feed
_info
_description
.show()
229 self
._feed
_info
_description
.hide()
231 copyright
= utils
.convert_entities(feed
.channel_copyright
)
232 self
._feed
_info
_copyright
.set_text(copyright
)
234 self
._feed
_info
_copyright
.show()
236 self
._feed
_info
_copyright
.hide()
238 def restore_defaults(self
):
239 # FIXME: add frequency and number of items and the default flags
240 self
._feed
.title
= self
._title
_default
241 self
._feed
.access_info
= (
242 self
._url
_default
, self
._un
_default
, self
._pw
_default
)
243 self
._title
.set_text(self
._title
_default
)
244 self
._location
.set_text(self
._url
_default
)
245 if self
._un
_default
is not None:
246 self
._username
.set_text(self
._un
_default
)
248 self
._username
.set_text("")
249 if self
._pw
_default
is not None:
250 self
._password
.set_text(self
._pw
_default
)
252 self
._password
.set_text("")
253 self
._refresh
_default
_check
.set_active(self
._refresh
_keep
)
254 if not self
._refresh
_keep
:
255 self
._refresh
_spin
.set_value(float(self
._refresh
_default
))
256 self
._articles
_default
_check
.set_active(self
._articles
_keep
)
257 if not self
._articles
_keep
:
258 self
._articles
_spin
.set_value(float(self
._articles
_default
))
259 self
._restore
_button
.set_sensitive(False)
261 def on_properties_title_entry_insert_text(self
, *args
):
262 if self
._initializing
_window
:
264 self
._restore
_button
.set_sensitive(True)
266 def on_properties_title_entry_delete_text(self
, *args
):
267 if self
._initializing
_window
:
269 self
._restore
_button
.set_sensitive(True)
271 def on_properties_title_entry_focus_out_event(self
, widget
, *args
):
272 self
._feed
.title
= widget
.get_text().strip()
274 def on_properties_location_entry_insert_text(self
, *args
):
275 if self
._initializing
_window
:
277 self
._restore
_button
.set_sensitive(True)
279 def on_properties_location_entry_delete_text(self
, *args
):
280 if self
._initializing
_window
:
282 self
._restore
_button
.set_sensitive(True)
284 def on_properties_location_entry_focus_out_event(self
, widget
, *args
):
285 loc
, username
, pw
= self
._feed
.access_info
286 self
._feed
.access_info
= (widget
.get_text().strip(), username
, pw
)
288 def on_properties_username_entry_insert_text(self
, *args
):
289 if self
._initializing
_window
:
291 self
._restore
_button
.set_sensitive(True)
293 def on_properties_username_entry_delete_text(self
, *args
):
294 if self
._initializing
_window
:
296 self
._restore
_button
.set_sensitive(False)
298 def on_properties_username_entry_focus_out_event(self
, widget
, *args
):
299 loc
, username
, pw
= self
._feed
.access_info
300 text
= widget
.get_text().strip()
303 self
._feed
.access_info
= (loc
, text
, pw
)
305 def on_properties_password_entry_insert_text(self
, *args
):
306 if self
._initializing
_window
:
308 self
._restore
_button
.set_sensitive(True)
310 def on_properties_password_entry_delete_text(self
, *args
):
311 if self
._initializing
_window
:
313 self
._restore
_button
.set_sensitive(False)
315 def on_properties_password_entry_focus_out_event(self
, widget
, *args
):
316 loc
, username
, pw
= self
._feed
.access_info
317 text
= widget
.get_text().strip()
320 self
._feed
.access_info
= (loc
, username
, text
)
322 def on_properties_reset_button_clicked(self
, *args
):
323 self
.restore_defaults()
325 def on_properties_refresh_spin_focus_out_event(self
, widget
, *args
):
327 value
= widget
.get_value_as_int()
328 if value
!= self
._feed
.poll_frequency
:
329 self
._feed
.poll_frequency
= value
* 60
331 def on_properties_articles_spin_focus_out_event(self
, widget
, *args
):
333 value
= widget
.get_value_as_int()
334 if value
!= self
._feed
.number_of_items_stored
:
335 self
._feed
.number_of_items_stored
= value
337 def on_properties_articles_spin_value_changed(self
, widget
, *args
):
338 if self
._initializing
_window
:
340 self
._restore
_button
.set_sensitive(True)
342 def on_properties_refresh_spin_value_changed(self
, widget
, *args
):
343 if self
._initializing
_window
:
345 self
._restore
_button
.set_sensitive(True)
347 def on_properties_keep_refresh_default_toggled(self
, widget
, *args
):
348 if self
._initializing
_window
:
350 if widget
.get_active():
351 self
._feed
.poll_frequency
= Feed
.Feed
.DEFAULT
352 self
._refresh
_spin
.set_sensitive(False)
353 self
._refresh
_spin
.set_value(float(Config
.get_instance().poll_frequency
/ 60))
355 self
._feed
.poll_frequency
= self
._refresh
_spin
.get_value_as_int() * 60
356 self
._refresh
_spin
.set_sensitive(True)
357 self
._restore
_button
.set_sensitive(True)
359 def on_properties_keep_articles_default_toggled(self
, widget
, *args
):
360 if self
._initializing
_window
:
362 if widget
.get_active():
363 self
._feed
.number_of_items_stored
= Feed
.Feed
.DEFAULT
364 self
._articles
_spin
.set_value(float(Config
.get_instance().number_of_items_stored
))
365 self
._articles
_spin
.set_sensitive(False)
367 self
._feed
.number_of_items_stored
= self
._articles
_spin
.get_value_as_int()
368 self
._articles
_spin
.set_sensitive(True)
369 self
._restore
_button
.set_sensitive(True)
372 def show_feed_properties(cls
, parent
, feed
):
373 class _dialogdeleter
:
374 def __init__(self
, feed
, hash):
381 dialog
= cls
.dialogs
.get(feed
, None)
383 dialog
= cls(parent
,feed
,_dialogdeleter(feed
, cls
.dialogs
))
384 cls
.dialogs
[feed
] = dialog
387 show_feed_properties
= classmethod(show_feed_properties
)
389 def read_text(fragment
, chars
):
390 """Read chars cdata characters from html fragment fragment"""
391 parser
= SummaryParser
.TitleImgParser()
392 parser
.feed(fragment
)
393 text
= parser
.get_text(chars
)