psa: using 2 flickables
[feedingit] / psa_harmattan / feedingit / deb_dist / feedingit-0.1.0 / pysrc / config.py
1 #!/usr/bin/env python2.5
2
3
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.
10 #
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.
15 #
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/>.
18 #
19
20 # ============================================================================
21 # Name        : FeedingIt.py
22 # Author      : Yves Marcoz
23 # Version     : 0.6.1
24 # Description : Simple RSS Reader
25 # ============================================================================
26 #try:
27 #    import gtk
28 #    import hildon
29 #    from gobject import idle_add
30 #except:
31 #    pass
32
33 from ConfigParser import RawConfigParser
34 from gconf import client_get_default
35 from urllib2 import ProxyHandler
36 from mainthread import mainthread
37 import logging
38 logger = logging.getLogger(__name__)
39
40 VERSION = "120"
41
42 section = "FeedingIt"
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"}
46
47 class Config():
48     def __init__(self, parent, configFilename):
49         self.configFilename = configFilename
50         self.parent = parent
51         # Load config
52         self.loadConfig()
53
54         # Backup current settings for later restore
55         self.config_backup = dict(self.config)
56         self.do_restore_backup = True
57
58     def on_save_button_clicked(self, button):
59         self.do_restore_backup = False
60         self.window.destroy()
61
62     def createDialog(self):
63         import gtk
64         import hildon
65         from gobject import idle_add
66         self.window = gtk.Dialog("Settings", self.parent)
67         self.window.set_geometry_hints(min_height=600)
68
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()
73         
74         vbox = gtk.VBox(False, 2)
75         self.buttons = {}
76
77         def heading(text):
78             l = gtk.Label()
79             l.set_size_request(-1, 6)
80             vbox.pack_start(l, expand=False)
81             vbox.pack_start(gtk.Frame(text), expand=False)
82
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)
93
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)  
99
100         heading('Display')
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)
110
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)
116
117
118         heading('Updating')
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)
123
124         try:
125             import woodchuck
126             woodchuck_installed = True
127         except ImportError:
128             woodchuck_installed = False
129
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")
134
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)
140         else:
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')
148
149         heading('Network')
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)
155
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)
161         
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)
167         
168         panArea.add_with_viewport(vbox)
169         
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()
175         return self.window
176
177     def button_tips_clicked(self, *widget):
178         import dbus
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)
183
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
190
191         self.saveConfig()
192         self.window.destroy()
193
194     def button_toggled(self, widget, configName):
195         #print "widget", widget.get_active()
196         if (widget.get_active()):
197             self.config[configName] = True
198         else:
199             self.config[configName] = False
200         #print "autoup",  self.autoupdate
201
202         if configName == 'woodchuck':
203             try:
204                 from wc import wc_disable_set
205                 wc_disable_set(not self.config['woodchuck'])
206             except Exception:
207                 logger.exception("Disabling Woodchuck")
208
209         self.saveConfig()
210         
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)
217         self.saveConfig()
218         
219     def updateButton(self, setting):
220         self.buttons[setting].set_text(titles[setting], subtitles[setting] % self.config[setting])
221         
222     def loadConfig(self):
223         self.config = {}
224
225         configParser = RawConfigParser()
226         try:
227             configParser.read(self.configFilename)
228         except Exception:
229             logger.exception("Reading %s", self.configFilename)
230
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"))
248
249         newSetting = False
250         for fetcher, name, default in values:
251             try:
252                 v = fetcher(section, name)
253             except Exception:
254                 newSetting = True
255                 logger.exception("Reading config variable %s", name)
256                 v = default
257             self.config[name] = v
258         if newSetting:
259             self.saveConfig()
260
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"]))
279
280         # Writing our configuration file
281         file = open(self.configFilename, 'wb')
282         configParser.write(file)
283         file.close()
284
285     def create_selector(self, choices, setting):
286         import gtk
287         import hildon
288         from gobject import idle_add
289         #self.pickerDialog = hildon.PickerDialog(self.parent)
290         selector = hildon.TouchSelector(text=True)
291         index = 0
292         for item in choices:
293             iter = selector.append_text(str(item))
294             if str(self.config[setting]) == str(item): 
295                 selector.set_active(0, index)
296             index += 1
297         selector.connect("changed", self.selection_changed, setting)
298         #self.pickerDialog.set_selector(selector)
299         return selector
300         #self.pickerDialog.show_all()
301
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
310     def getExpiry(self):
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
324         self.saveConfig()
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) 
341     @mainthread
342     def getProxy(self):
343         if self.config["proxy"] == False:
344             return (False, None)
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)} )
349             return (True, proxy)
350         return (False, None)
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
367     def getTheme(self):
368         return self.config["theme"]
369     def setTheme(self, theme):
370         self.config["theme"] = bool(theme)