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", 14),
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"))
249 for fetcher, name, default in values:
251 v = fetcher(section, name)
253 logger.exception("Reading config variable %s", name)
255 self.config[name] = v
257 def saveConfig(self):
258 configParser = RawConfigParser()
259 configParser.add_section(section)
260 configParser.set(section, 'fontSize', str(self.config["fontSize"]))
261 configParser.set(section, 'artFontSize', str(self.config["artFontSize"]))
262 configParser.set(section, 'expiry', str(self.config["expiry"]))
263 configParser.set(section, 'autoupdate', str(self.config["autoupdate"]))
264 configParser.set(section, 'updateInterval', str(self.config["updateInterval"]))
265 configParser.set(section, 'woodchuck', str(self.config["woodchuck"]))
266 configParser.set(section, 'askedAboutWoodchuck', str(self.config["askedAboutWoodchuck"]))
267 configParser.set(section, 'orientation', str(self.config["orientation"]))
268 configParser.set(section, 'imageCache', str(self.config["imageCache"]))
269 configParser.set(section, 'proxy', str(self.config["proxy"]))
270 configParser.set(section, 'hidereadfeeds', str(self.config["hidereadfeeds"]))
271 configParser.set(section, 'hidereadarticles', str(self.config["hidereadarticles"]))
272 configParser.set(section, 'extBrowser', str(self.config["extBrowser"]))
273 configParser.set(section, 'feedsort', str(self.config["feedsort"]))
274 configParser.set(section, 'theme', str(self.config["theme"]))
276 # Writing our configuration file
277 file = open(self.configFilename, 'wb')
278 configParser.write(file)
281 def create_selector(self, choices, setting):
284 from gobject import idle_add
285 #self.pickerDialog = hildon.PickerDialog(self.parent)
286 selector = hildon.TouchSelector(text=True)
289 iter = selector.append_text(str(item))
290 if str(self.config[setting]) == str(item):
291 selector.set_active(0, index)
293 selector.connect("changed", self.selection_changed, setting)
294 #self.pickerDialog.set_selector(selector)
296 #self.pickerDialog.show_all()
298 def getFontSize(self):
299 return self.config["fontSize"]
300 def getArtFontSize(self):
301 return self.config["artFontSize"]
303 return self.config["expiry"]
304 def setExpiry(self, expiry):
305 self.config["expiry"] = expiry
306 def isAutoUpdateEnabled(self):
307 return self.config["autoupdate"]
308 def setAutoUpdateEnabled(self, value):
309 self.config["autoupdate"] = value
310 def getWoodchuckEnabled(self):
311 return self.config["woodchuck"]
312 def getAskedAboutWoodchuck(self):
313 return self.config["askedAboutWoodchuck"]
314 def setAskedAboutWoodchuck(self, value):
315 self.config["askedAboutWoodchuck"] = value
317 def getUpdateInterval(self):
318 return float(self.config["updateInterval"])
319 def getReadFont(self):
320 return "sans italic %s" % self.config["fontSize"]
321 def getUnreadFont(self):
322 return "sans %s" % self.config["fontSize"]
323 def getOrientation(self):
324 return ranges["orientation"].index(self.config["orientation"])
325 def getOrientationChoices(self):
326 return ranges["orientation"]
327 def setOrientation(self, choice):
328 self.config["orientation"] = index
329 def getImageCache(self):
330 return self.config["imageCache"]
331 def setImageCache(self, cache):
332 self.config["imageCache"] = bool(cache)
335 if self.config["proxy"] == False:
337 if client_get_default().get_bool('/system/http_proxy/use_http_proxy'):
338 port = client_get_default().get_int('/system/http_proxy/port')
339 http = client_get_default().get_string('/system/http_proxy/host')
340 proxy = ProxyHandler( {"http":"http://%s:%s/"% (http,port)} )
343 def getHideReadFeeds(self):
344 return self.config["hidereadfeeds"]
345 def setHideReadFeeds(self, setting):
346 self.config["hidereadfeeds"] = bool(setting)
347 def getHideReadArticles(self):
348 return self.config["hidereadarticles"]
349 def setHideReadArticles(self, setting):
350 self.config["hidereadarticles"] = bool(setting)
351 def getOpenInExternalBrowser(self):
352 return self.config["extBrowser"]
353 def getFeedSortOrder(self):
354 return self.config["feedsort"]
355 def getFeedSortOrderChoices(self):
356 return ranges["feedsort"]
357 def setFeedSortOrder(self, setting):
358 self.config["feedsort"] = setting
360 return self.config["theme"]
361 def setTheme(self, theme):
362 self.config["theme"] = bool(theme)