1 #!/usr/bin/env python2.5
4 # Copyright (c) 2007-2008 INdT.
5 # Copyright (c) 2011 Neal H. Walfield.
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU Lesser General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU Lesser General Public License for more details.
16 # You should have received a copy of the GNU Lesser General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 # ============================================================================
22 # Author : Yves Marcoz
24 # Description : Simple RSS Reader
25 # ============================================================================
29 # from gobject import idle_add
33 from ConfigParser import RawConfigParser
34 from gconf import client_get_default
35 from urllib2 import ProxyHandler
36 from mainthread import mainthread
38 logger = logging.getLogger(__name__)
43 ranges = { "updateInterval":[0.5, 1, 2, 4, 8, 12, 24], "expiry":[24, 48, 72, 144, 288], "fontSize":range(12,24), "orientation":["Automatic", "Landscape", "Portrait"], "artFontSize":[10, 12, 14, 16, 18, 20], "feedsort":["Manual", "Most unread", "Least unread", "Most recent", "Least recent"] }
44 titles = {"updateInterval":"Auto-update interval", "expiry":"Delete articles", "fontSize":"List font size", "orientation":"Display orientation", "artFontSize":"Article font size","feedsort":"Feed sort order"}
45 subtitles = {"updateInterval":"Every %s hours", "expiry":"After %s hours", "fontSize":"%s pixels", "orientation":"%s", "artFontSize":"%s pixels", "feedsort":"%s"}
48 def __init__(self, parent, configFilename):
49 self.configFilename = configFilename
54 # Backup current settings for later restore
55 self.config_backup = dict(self.config)
56 self.do_restore_backup = True
58 def on_save_button_clicked(self, button):
59 self.do_restore_backup = False
62 def createDialog(self):
65 from gobject import idle_add
66 self.window = gtk.Dialog("Settings", self.parent)
67 self.window.set_geometry_hints(min_height=600)
69 save_button = self.window.add_button(gtk.STOCK_SAVE, gtk.RESPONSE_OK)
70 save_button.connect('clicked', self.on_save_button_clicked)
71 #self.window.set_default_size(-1, 600)
72 panArea = hildon.PannableArea()
74 vbox = gtk.VBox(False, 2)
79 l.set_size_request(-1, 6)
80 vbox.pack_start(l, expand=False)
81 vbox.pack_start(gtk.Frame(text), expand=False)
83 def add_setting(setting):
84 picker = hildon.PickerButton(gtk.HILDON_SIZE_FINGER_HEIGHT, hildon.BUTTON_ARRANGEMENT_VERTICAL)
85 selector = self.create_selector(ranges[setting], setting)
86 picker.set_selector(selector)
87 picker.set_title(titles[setting])
88 picker.set_text(titles[setting], subtitles[setting] % self.config[setting])
89 picker.set_name('HildonButton-finger')
90 picker.set_alignment(0,0,1,1)
91 self.buttons[setting] = picker
92 vbox.pack_start(picker, expand=False)
94 button = hildon.Button(gtk.HILDON_SIZE_FINGER_HEIGHT, hildon.BUTTON_ARRANGEMENT_VERTICAL)
95 button.set_label("View Known Issues and Tips")
96 button.connect("clicked", self.button_tips_clicked)
97 button.set_alignment(0,0,1,1)
98 vbox.pack_start(button, expand=False)
101 add_setting('fontSize')
102 add_setting('artFontSize')
103 add_setting('orientation')
104 add_setting('feedsort')
105 button = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
106 button.set_label("Hide read feeds")
107 button.set_active(self.config["hidereadfeeds"])
108 button.connect("toggled", self.button_toggled, "hidereadfeeds")
109 vbox.pack_start(button, expand=False)
111 button = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
112 button.set_label("Hide read articles")
113 button.set_active(self.config["hidereadarticles"])
114 button.connect("toggled", self.button_toggled, "hidereadarticles")
115 vbox.pack_start(button, expand=False)
119 label = gtk.Label(gtk.HILDON_SIZE_FINGER_HEIGHT)
120 label.set_label("Use Woodchuck network daemon, or the home-screen widget for automatic updates.")
121 label.set_line_wrap(True)
122 vbox.pack_start(label, expand=False)
126 woodchuck_installed = True
128 woodchuck_installed = False
130 if not woodchuck_installed:
131 def install_woodchuck_clicked(button):
132 from FeedingIt import open_in_browser
133 open_in_browser("http://maemo.org/downloads/product/raw/Maemo5/murmeltier?get_installfile")
135 button = hildon.Button(gtk.HILDON_SIZE_FINGER_HEIGHT, hildon.BUTTON_ARRANGEMENT_VERTICAL)
136 button.set_label("Install Woodchuck")
137 button.connect("clicked", install_woodchuck_clicked)
138 button.set_alignment(0,0,1,1)
139 vbox.pack_start(button, expand=False)
141 button = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
142 button.set_label("Woodchuck-Based Automatic Update")
143 button.set_active(self.config["woodchuck"])
144 button.connect("toggled", self.button_toggled, "woodchuck")
145 vbox.pack_start(button, expand=False)
146 add_setting('updateInterval')
147 add_setting('expiry')
150 button = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
151 button.set_label('Cache images')
152 button.set_active(self.config["imageCache"])
153 button.connect("toggled", self.button_toggled, "imageCache")
154 vbox.pack_start(button, expand=False)
156 button = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
157 button.set_label("Use HTTP proxy")
158 button.set_active(self.config["proxy"])
159 button.connect("toggled", self.button_toggled, "proxy")
160 vbox.pack_start(button, expand=False)
162 button = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
163 button.set_label('Open links in external browser')
164 button.set_active(self.config["extBrowser"])
165 button.connect("toggled", self.button_toggled, "extBrowser")
166 vbox.pack_start(button, expand=False)
168 panArea.add_with_viewport(vbox)
170 self.window.vbox.add(panArea)
171 self.window.connect("destroy", self.onExit)
172 #self.window.add(self.vbox)
173 self.window.set_default_size(-1, 600)
174 self.window.show_all()
177 def button_tips_clicked(self, *widget):
179 bus = dbus.SessionBus()
180 proxy = bus.get_object("com.nokia.osso_browser", "/com/nokia/osso_browser/request")
181 iface = dbus.Interface(proxy, 'com.nokia.osso_browser')
182 iface.open_new_window("http://feedingit.marcoz.org/news/?page_id=%s" % VERSION)
184 def onExit(self, *widget):
185 # When the dialog is closed without hitting
186 # the "Save" button, restore the configuration
187 if self.do_restore_backup:
188 logger.debug('Restoring configuration')
189 self.config = self.config_backup
192 self.window.destroy()
194 def button_toggled(self, widget, configName):
195 #print "widget", widget.get_active()
196 if (widget.get_active()):
197 self.config[configName] = True
199 self.config[configName] = False
200 #print "autoup", self.autoupdate
202 if configName == 'woodchuck':
204 from wc import wc_disable_set
205 wc_disable_set(not self.config['woodchuck'])
207 logger.exception("Disabling Woodchuck")
211 def selection_changed(self, selector, button, setting):
212 from gobject import idle_add
213 current_selection = selector.get_current_text()
214 if current_selection:
215 self.config[setting] = current_selection
216 idle_add(self.updateButton, setting)
219 def updateButton(self, setting):
220 self.buttons[setting].set_text(titles[setting], subtitles[setting] % self.config[setting])
222 def loadConfig(self):
225 configParser = RawConfigParser()
227 configParser.read(self.configFilename)
229 logger.exception("Reading %s", self.configFilename)
231 # The function to use to fetch the parameter, the parameter's
232 # name and the default value.
233 values = ((configParser.getint, "fontSize", 17),
234 (configParser.getint, "artFontSize", 24),
235 (configParser.getint, "expiry", 24),
236 (configParser.getboolean, "autoupdate", False),
237 (configParser.getboolean, "woodchuck", True),
238 (configParser.getboolean, "askedAboutWoodchuck", False),
239 (configParser.getfloat, "updateInterval", 4),
240 (configParser.get, "orientation", "Automatic"),
241 (configParser.getboolean, "imageCache", False),
242 (configParser.getboolean, "proxy", True),
243 (configParser.getboolean, "hidereadfeeds", False),
244 (configParser.getboolean, "hidereadarticles", False),
245 (configParser.getboolean, "extBrowser", False),
246 (configParser.getboolean, "theme", True),
247 (configParser.get, "feedsort", "Manual"))
250 for fetcher, name, default in values:
252 v = fetcher(section, name)
255 logger.exception("Reading config variable %s", name)
257 self.config[name] = v
261 def saveConfig(self):
262 configParser = RawConfigParser()
263 configParser.add_section(section)
264 configParser.set(section, 'fontSize', str(self.config["fontSize"]))
265 configParser.set(section, 'artFontSize', str(self.config["artFontSize"]))
266 configParser.set(section, 'expiry', str(self.config["expiry"]))
267 configParser.set(section, 'autoupdate', str(self.config["autoupdate"]))
268 configParser.set(section, 'updateInterval', str(self.config["updateInterval"]))
269 configParser.set(section, 'woodchuck', str(self.config["woodchuck"]))
270 configParser.set(section, 'askedAboutWoodchuck', str(self.config["askedAboutWoodchuck"]))
271 configParser.set(section, 'orientation', str(self.config["orientation"]))
272 configParser.set(section, 'imageCache', str(self.config["imageCache"]))
273 configParser.set(section, 'proxy', str(self.config["proxy"]))
274 configParser.set(section, 'hidereadfeeds', str(self.config["hidereadfeeds"]))
275 configParser.set(section, 'hidereadarticles', str(self.config["hidereadarticles"]))
276 configParser.set(section, 'extBrowser', str(self.config["extBrowser"]))
277 configParser.set(section, 'feedsort', str(self.config["feedsort"]))
278 configParser.set(section, 'theme', str(self.config["theme"]))
280 # Writing our configuration file
281 file = open(self.configFilename, 'wb')
282 configParser.write(file)
285 def create_selector(self, choices, setting):
288 from gobject import idle_add
289 #self.pickerDialog = hildon.PickerDialog(self.parent)
290 selector = hildon.TouchSelector(text=True)
293 iter = selector.append_text(str(item))
294 if str(self.config[setting]) == str(item):
295 selector.set_active(0, index)
297 selector.connect("changed", self.selection_changed, setting)
298 #self.pickerDialog.set_selector(selector)
300 #self.pickerDialog.show_all()
302 def getFontSize(self):
303 return self.config["fontSize"]
304 def setFontSize(self, value):
305 self.config["fontSize"] = value
306 def getArtFontSize(self):
307 return self.config["artFontSize"]
308 def setArtFontSize(self, value):
309 self.config["artFontSize"] = value
311 return self.config["expiry"]
312 def setExpiry(self, expiry):
313 self.config["expiry"] = expiry
314 def isAutoUpdateEnabled(self):
315 return self.config["autoupdate"]
316 def setAutoUpdateEnabled(self, value):
317 self.config["autoupdate"] = value
318 def getWoodchuckEnabled(self):
319 return self.config["woodchuck"]
320 def getAskedAboutWoodchuck(self):
321 return self.config["askedAboutWoodchuck"]
322 def setAskedAboutWoodchuck(self, value):
323 self.config["askedAboutWoodchuck"] = value
325 def getUpdateInterval(self):
326 return float(self.config["updateInterval"])
327 def getReadFont(self):
328 return "sans italic %s" % self.config["fontSize"]
329 def getUnreadFont(self):
330 return "sans %s" % self.config["fontSize"]
331 def getOrientation(self):
332 return ranges["orientation"].index(self.config["orientation"])
333 def getOrientationChoices(self):
334 return ranges["orientation"]
335 def setOrientation(self, choice):
336 self.config["orientation"] = index
337 def getImageCache(self):
338 return self.config["imageCache"]
339 def setImageCache(self, cache):
340 self.config["imageCache"] = bool(cache)
343 if self.config["proxy"] == False:
345 if client_get_default().get_bool('/system/http_proxy/use_http_proxy'):
346 port = client_get_default().get_int('/system/http_proxy/port')
347 http = client_get_default().get_string('/system/http_proxy/host')
348 proxy = ProxyHandler( {"http":"http://%s:%s/"% (http,port)} )
351 def getHideReadFeeds(self):
352 return self.config["hidereadfeeds"]
353 def setHideReadFeeds(self, setting):
354 self.config["hidereadfeeds"] = bool(setting)
355 def getHideReadArticles(self):
356 return self.config["hidereadarticles"]
357 def setHideReadArticles(self, setting):
358 self.config["hidereadarticles"] = bool(setting)
359 def getOpenInExternalBrowser(self):
360 return self.config["extBrowser"]
361 def getFeedSortOrder(self):
362 return self.config["feedsort"]
363 def getFeedSortOrderChoices(self):
364 return ranges["feedsort"]
365 def setFeedSortOrder(self, setting):
366 self.config["feedsort"] = setting
368 return self.config["theme"]
369 def setTheme(self, theme):
370 self.config["theme"] = bool(theme)