Separated category and feed properties.
[straw.git] / straw / feedproperties.py
blob2c38ef2ef07843132ce9f1df5f4507b97d276213
1 """
2 Provides a module for handling the properties of a Feed.
3 """
4 __copyright__ = "Copyright (c) 2002-2005 Free Software Foundation, Inc."
5 __license__ = """
6 Straw is free software; you can redistribute it and/or modify it under the
7 terms of the GNU General Public License as published by the Free Software
8 Foundation; either version 2 of the License, or (at your option) any later
9 version.
11 Straw is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17 Place - Suite 330, Boston, MA 02111-1307, USA. """
19 from error import log, logparam, logtb
20 from gtk.glade import XML
21 from straw import helpers
22 from xml.sax import saxutils
23 import Config
24 import MVP
25 import SummaryParser
26 import gettext
27 import gobject
28 import gtk
29 import os, os.path
30 import straw.defs
31 import time
33 class FeedPropertyView(MVP.GladeView):
35 COLUMN_NAME = 0
36 COLUMN_MEMBER = 1
37 COLUMN_OBJECT = 2
39 def _initialize(self):
40 self._feed = None
41 self._defaults = {'title':'','url':'','username':'','password':''}
42 self._window = self._widget.get_widget('feed_properties')
44 self._title_entry = self._widget.get_widget('title_entry')
45 self._location_entry = self._widget.get_widget('location_entry')
46 self._website_entry = self._widget.get_widget('website_entry')
47 self._description_label = self._widget.get_widget('description_label')
48 self._copyright_label = self._widget.get_widget('copyright_label')
50 self._username = self._widget.get_widget('properties_username_entry')
51 self._password = self._widget.get_widget('properties_password_entry')
53 self._next_refresh_label = self._widget.get_widget('properties_next_refresh_label')
54 self._previous_refresh_label = self._widget.get_widget('properties_previous_refresh_label')
56 self._restore_button = self._widget.get_widget('properties_reset_button')
57 self._refresh_spin = self._widget.get_widget('properties_refresh_spin')
58 self._articles_spin = self._widget.get_widget('properties_articles_spin')
59 self._refresh_default_check = self._widget.get_widget('properties_keep_refresh_default')
60 self._articles_default_check = self._widget.get_widget('properties_keep_articles_default')
62 def set_feed(self, feed):
63 self._feed = feed
65 def show(self):
66 self._initializing_window = True
67 self.display_properties()
68 self._window.present()
69 self._initializing_window = False
71 def hide(self, *args):
72 self._window.hide()
73 self._window.destroy()
75 def _on_feed_properties_delete_event(self, *args):
76 self.hide()
77 return True
79 def _on_properties_close_button_clicked(self, *args):
80 self.hide()
81 return
83 def _on_location_button_clicked(self, *args):
84 helpers.url_show(self._location_entry.get_text())
86 def _on_website_button_clicked(self, *args):
87 helpers.url_show(self._website_entry.get_text())
89 def display_properties(self):
90 self._window.set_title(_("%s Properties") % self._feed.title)
92 self._title_entry.set_text(self._feed.title)
93 self._location_entry.set_text(self._feed.location)
95 self._website_entry.set_text(self._feed.link)
97 for key in ("description", "copyright", "category", "generator",
98 "creator", "webmaster", "ttl"):
99 label = self._widget.get_widget("%s_label" % key)
100 input = self._widget.get_widget("%s_input" % key)
102 value = None
104 if hasattr(self._feed, key):
105 value = getattr(self._feed, key)
106 elif self._feed.pdict.has_key(key):
107 value = self._feed.pdict[key]
109 if value:
110 label.show()
111 input.set_text(value)
112 input.show()
114 window = self._widget.get_widget("%s_window" % key)
116 if window:
117 window.show()
119 """self._defaults['title'] = self._feed.title
120 loc, un, pw = "", "", ""#self._feed.access_info
121 self._defaults['url'] = loc
122 self._defaults['username'] = un
123 self._defaults['password'] = pw
124 self._defaults['frequency'] = self._feed.poll_frequency
125 self._defaults['stored'] = self._feed.number_of_items_stored
127 self._title.set_text(self._feed.title)
128 self._location.set_text(self._feed.access_info[0])
130 config = Config.get_instance()
131 if self._feed.poll_frequency == feeds.Feed.DEFAULT:
132 freq = config.poll_frequency
133 fdefault = True
134 self._refresh_keep = True
135 else:
136 freq = self._feed.poll_frequency
137 fdefault = False
138 self._refresh_keep = False
139 self._refresh_spin.set_value(float(freq / 60))
140 self._refresh_spin.set_sensitive(not fdefault)
141 self._refresh_default_check.set_active(fdefault)
142 if self._feed.number_of_items_stored == feeds.Feed.DEFAULT:
143 nitems = config.number_of_items_stored
144 nidefault = True
145 self._articles_keep = True
146 else:
147 nitems = self._feed.number_of_items_stored
148 nidefault = False
149 self._articles_keep = False
150 self._articles_spin.set_value(float(nitems))
151 self._articles_spin.set_sensitive(not nidefault)
152 self._articles_default_check.set_active(nidefault)
154 if un:
155 self._username.set_text(un)
156 if pw:
157 self._password.set_text(pw)
159 model = self._categories_treeview.get_model()
160 model.clear()
161 fclist = feeds.category_list
162 for c in fclist.user_categories:
163 iter = model.append()
164 model.set(iter,
165 self.COLUMN_NAME, c.title,
166 self.COLUMN_MEMBER, self._feed in c.feeds,
167 self.COLUMN_OBJECT, c)
169 self._previous_refresh_label.set_text(
170 helpers.format_date(time.gmtime(self._feed.last_poll)))
171 next = self._feed.next_refresh
172 if next:
173 self._next_refresh_label.set_text(
174 helpers.format_date(time.gmtime(next)))
175 self._next_refresh_label.show()
176 else:
177 self._next_refresh_label.hide()
179 description = helpers.convert_entities(feed.channel_description.strip())
180 if description and description != title:
181 description = read_text(description, len(description))
182 self._feed_info_description.set_text(helpers.convert_entities(description))
183 self._feed_info_description.show()
184 else:
185 self._feed_info_description.hide()
187 copyright = helpers.convert_entities(feed.channel_copyright)
188 if copyright:
189 self._feed_info_copyright.set_text(copyright)
190 self._feed_info_copyright.show()
191 else:
192 self._feed_info_copyright.hide()"""
194 def _load_uri(self, widget, event):
195 helpers.url_show(widget.get_uri())
197 def restore_defaults(self):
198 # FIXME: add frequency and number of items and the default flags
199 self._feed.title = self._defaults['title']
200 self._feed.access_info = (
201 self._defaults['url'], self._defaults['username'], self._defaults['password'])
202 self._title.set_text(self._feed.title)
203 self._location.set_text(self._feed.location)
204 self._username.set_text(self._defaults.get('username',''))
205 self._password.set_text(self._defaults.get('password',''))
206 self._refresh_default_check.set_active(self._refresh_keep)
207 if not self._refresh_keep:
208 self._refresh_spin.set_value(float(self._refresh_default))
209 self._articles_default_check.set_active(self._articles_keep)
210 if not self._articles_keep:
211 self._articles_spin.set_value(float(self._articles_default))
212 self._restore_button.set_sensitive(False)
214 def _on_close_button_clicked(self, *args):
215 self.hide()
217 def _on_properties_title_entry_insert_text(self, *args):
218 if self._initializing_window:
219 return
220 self._restore_button.set_sensitive(True)
222 def _on_properties_title_entry_delete_text(self, *args):
223 if self._initializing_window:
224 return
225 self._restore_button.set_sensitive(True)
227 def _on_properties_title_entry_focus_out_event(self, widget, *args):
228 self._feed.title = widget.get_text().strip()
230 def _on_properties_location_entry_insert_text(self, *args):
231 if self._initializing_window:
232 return
233 self._restore_button.set_sensitive(True)
235 def _on_properties_location_entry_delete_text(self, *args):
236 if self._initializing_window:
237 return
238 self._restore_button.set_sensitive(True)
240 def _on_properties_location_entry_focus_out_event(self, widget, *args):
241 loc, username, pw = self._feed.access_info
242 self._feed.access_info = (widget.get_text().strip(), username, pw)
244 def _on_properties_username_entry_insert_text(self, *args):
245 if self._initializing_window:
246 return
247 self._restore_button.set_sensitive(True)
249 def _on_properties_username_entry_delete_text(self, *args):
250 if self._initializing_window:
251 return
252 self._restore_button.set_sensitive(False)
254 def _on_properties_username_entry_focus_out_event(self, widget, *args):
255 self._presenter.set_username(widget.get_text().strip())
257 def _on_properties_password_entry_insert_text(self, *args):
258 if self._initializing_window:
259 return
260 self._restore_button.set_sensitive(True)
262 def _on_properties_password_entry_delete_text(self, *args):
263 if self._initializing_window:
264 return
265 self._restore_button.set_sensitive(False)
267 def _on_properties_password_entry_focus_out_event(self, widget, *args):
268 self._presenter.set_password(widget.get_text().strip())
270 def _on_properties_reset_button_clicked(self, *args):
271 self.restore_defaults()
273 def _on_properties_refresh_spin_focus_out_event(self, widget, *args):
274 widget.update()
275 value = widget.get_value_as_int()
276 self._presenter.set_poll_frequency(value)
278 def _on_properties_articles_spin_focus_out_event(self, widget, *args):
279 widget.update()
280 value = widget.get_value_as_int()
281 self._presenter.set_items_stored(value)
283 def _on_properties_articles_spin_value_changed(self, widget, *args):
284 if self._initializing_window:
285 return
286 self._restore_button.set_sensitive(True)
288 def _on_properties_refresh_spin_value_changed(self, widget, *args):
289 if self._initializing_window:
290 return
291 self._restore_button.set_sensitive(True)
293 def _on_properties_keep_refresh_default_toggled(self, widget, *args):
294 if self._initializing_window:
295 return
296 isactive = widget.get_active()
297 if isactive:
298 self._presenter.set_poll_frequency(feeds.Feed.DEFAULT)
299 self._refresh_spin.set_value(float(Config.get_instance().poll_frequency / 60))
300 else:
301 self._presenter.set_poll_frequency(self._refresh_spin.get_value_as_int() * 60)
303 self._refresh_spin.set_sensitive(not isactive)
304 self._restore_button.set_sensitive(True)
306 def _on_properties_keep_articles_default_toggled(self, widget, *args):
307 if self._initializing_window:
308 return
309 isactive = widget.get_active()
310 if isactive:
311 self._presenter.set_items_stored(feeds.Feed.DEFAULT)
312 self._articles_spin.set_value(float(Config.get_instance().number_of_items_stored))
313 else:
314 self._presenter.set_items_stored(self._articles_spin.get_value_as_int())
315 self._articles_spin.set_sensitive(not isactive)
316 self._restore_button.set_sensitive(True)
318 class FeedPropertyPresenter(MVP.BasicPresenter):
320 TIME_INTERVAL = 60
322 def _initialize(self):
323 self._feed = None
325 def set_feed(self, feed):
326 self._feed = feed
327 self._view.set_feed(self._feed)
329 def set_username(self, username):
330 loc, uname, pw = self._feed.access_info
331 self._feed.access_info = (loc, username, pw)
333 def set_password(self, password):
334 loc, uname, pw = self._feed.access_info
335 self._feed.access_info = (loc, uname, password)
337 def set_poll_frequency(self, pf):
338 if pf != self._feed.poll_frequency:
339 self._feed.poll_frequency = pf * FeedPropertyPresenter.TIME_INTERVAL
341 def set_items_stored(self, nitems):
342 if nitems != self._feed.number_of_items_stored:
343 self._feed.number_of_items_stored = nitems
345 def show(feed):
346 gladefile = XML(os.path.join(straw.defs.STRAW_DATA_DIR, "node-properties.glade"))
347 dialog = FeedPropertyPresenter(view=FeedPropertyView(gladefile))
348 dialog.set_feed(feed)
350 dialog.view.show()
352 def read_text(fragment, chars):
353 """Read chars cdata characters from html fragment fragment"""
354 parser = SummaryParser.TitleImgParser()
355 parser.feed(fragment)
356 text = parser.get_text(chars)
357 parser.close()
358 return text