a42137d3d079db1b6f4dde1552becce895953a74
[feedingit] / src / 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 = "52"
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         button = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
120         button.set_label("Automatically update feeds")
121         button.set_active(self.config["autoupdate"])
122         button.connect("toggled", self.button_toggled, "autoupdate")
123         vbox.pack_start(button, expand=False)
124         add_setting('updateInterval')
125         add_setting('expiry')
126
127         heading('Network')
128         button = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
129         button.set_label('Cache images')
130         button.set_active(self.config["imageCache"])
131         button.connect("toggled", self.button_toggled, "imageCache")
132         vbox.pack_start(button, expand=False)
133
134         button = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
135         button.set_label("Use HTTP proxy")
136         button.set_active(self.config["proxy"])
137         button.connect("toggled", self.button_toggled, "proxy")
138         vbox.pack_start(button, expand=False)
139         
140         button = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
141         button.set_label('Open links in external browser')
142         button.set_active(self.config["extBrowser"])
143         button.connect("toggled", self.button_toggled, "extBrowser")
144         vbox.pack_start(button, expand=False)
145         
146         panArea.add_with_viewport(vbox)
147         
148         self.window.vbox.add(panArea)
149         self.window.connect("destroy", self.onExit)
150         #self.window.add(self.vbox)
151         self.window.set_default_size(-1, 600)
152         self.window.show_all()
153         return self.window
154
155     def button_tips_clicked(self, *widget):
156         import dbus
157         bus = dbus.SessionBus()
158         proxy = bus.get_object("com.nokia.osso_browser", "/com/nokia/osso_browser/request")
159         iface = dbus.Interface(proxy, 'com.nokia.osso_browser')
160         iface.open_new_window("http://feedingit.marcoz.org/news/?page_id=%s" % VERSION)
161
162     def onExit(self, *widget):
163         # When the dialog is closed without hitting
164         # the "Save" button, restore the configuration
165         if self.do_restore_backup:
166             logger.debug('Restoring configuration')
167             self.config = self.config_backup
168
169         self.saveConfig()
170         self.window.destroy()
171
172     def button_toggled(self, widget, configName):
173         #print "widget", widget.get_active()
174         if (widget.get_active()):
175             self.config[configName] = True
176         else:
177             self.config[configName] = False
178         #print "autoup",  self.autoupdate
179         self.saveConfig()
180         
181     def selection_changed(self, selector, button, setting):
182         from gobject import idle_add
183         current_selection = selector.get_current_text()
184         if current_selection:
185             self.config[setting] = current_selection
186         idle_add(self.updateButton, setting)
187         self.saveConfig()
188         
189     def updateButton(self, setting):
190         self.buttons[setting].set_text(titles[setting], subtitles[setting] % self.config[setting])
191         
192     def loadConfig(self):
193         self.config = {}
194
195         configParser = RawConfigParser()
196         try:
197             configParser.read(self.configFilename)
198         except Exception:
199             logger.exception("Reading %s", self.configFilename)
200
201         # The function to use to fetch the parameter, the parameter's
202         # name and the default value.
203         values = ((configParser.getint, "fontSize", 17),
204                   (configParser.getint, "artFontSize", 14),
205                   (configParser.getint, "expiry", 24),
206                   (configParser.getboolean, "autoupdate", False),
207                   (configParser.getint, "updateInterval", 4),
208                   (configParser.get, "orientation", "Automatic"),
209                   (configParser.getboolean, "imageCache", False),
210                   (configParser.getboolean, "proxy", True),
211                   (configParser.getboolean, "hidereadfeeds", False),
212                   (configParser.getboolean, "hidereadarticles", False),
213                   (configParser.getboolean, "extBrowser", False),
214                   (configParser.get, "feedsort", "Manual"))
215
216         for fetcher, name, default in values:
217             try:
218                 v = fetcher(section, name)
219             except Exception:
220                 logger.exception("Reading config variable %s", name)
221                 v = default
222             self.config[name] = v
223
224     def saveConfig(self):
225         configParser = RawConfigParser()
226         configParser.add_section(section)
227         configParser.set(section, 'fontSize', str(self.config["fontSize"]))
228         configParser.set(section, 'artFontSize', str(self.config["artFontSize"]))
229         configParser.set(section, 'expiry', str(self.config["expiry"]))
230         configParser.set(section, 'autoupdate', str(self.config["autoupdate"]))
231         configParser.set(section, 'updateInterval', str(self.config["updateInterval"]))
232         configParser.set(section, 'orientation', str(self.config["orientation"]))
233         configParser.set(section, 'imageCache', str(self.config["imageCache"]))
234         configParser.set(section, 'proxy', str(self.config["proxy"]))
235         configParser.set(section, 'hidereadfeeds', str(self.config["hidereadfeeds"]))
236         configParser.set(section, 'hidereadarticles', str(self.config["hidereadarticles"]))
237         configParser.set(section, 'extBrowser', str(self.config["extBrowser"]))
238         configParser.set(section, 'feedsort', str(self.config["feedsort"]))
239
240         # Writing our configuration file
241         file = open(self.configFilename, 'wb')
242         configParser.write(file)
243         file.close()
244
245     def create_selector(self, choices, setting):
246         import gtk
247         import hildon
248         from gobject import idle_add
249         #self.pickerDialog = hildon.PickerDialog(self.parent)
250         selector = hildon.TouchSelector(text=True)
251         index = 0
252         for item in choices:
253             iter = selector.append_text(str(item))
254             if str(self.config[setting]) == str(item): 
255                 selector.set_active(0, index)
256             index += 1
257         selector.connect("changed", self.selection_changed, setting)
258         #self.pickerDialog.set_selector(selector)
259         return selector
260         #self.pickerDialog.show_all()
261
262     def getFontSize(self):
263         return self.config["fontSize"]
264     def getArtFontSize(self):
265         return self.config["artFontSize"]
266     def getExpiry(self):
267         return self.config["expiry"]
268     def isAutoUpdateEnabled(self):
269         return self.config["autoupdate"]
270     def getUpdateInterval(self):
271         return float(self.config["updateInterval"])
272     def getReadFont(self):
273         return "sans italic %s" % self.config["fontSize"]
274     def getUnreadFont(self):
275         return "sans %s" % self.config["fontSize"]
276     def getOrientation(self):
277         return ranges["orientation"].index(self.config["orientation"])
278     def getImageCache(self):
279         return self.config["imageCache"]
280     @mainthread
281     def getProxy(self):
282         if self.config["proxy"] == False:
283             return (False, None)
284         if client_get_default().get_bool('/system/http_proxy/use_http_proxy'):
285             port = client_get_default().get_int('/system/http_proxy/port')
286             http = client_get_default().get_string('/system/http_proxy/host')
287             proxy = ProxyHandler( {"http":"http://%s:%s/"% (http,port)} )
288             return (True, proxy)
289         return (False, None)
290     def getHideReadFeeds(self):
291         return self.config["hidereadfeeds"]
292     def getHideReadArticles(self):
293         return self.config["hidereadarticles"]
294     def getOpenInExternalBrowser(self):
295         return self.config["extBrowser"]
296     def getFeedSortOrder(self):
297         return self.config["feedsort"]