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.getint, "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.get, "feedsort", "Manual"))
248 for fetcher, name, default in values:
250 v = fetcher(section, name)
252 logger.exception("Reading config variable %s", name)
254 self.config[name] = v
256 def saveConfig(self):
257 configParser = RawConfigParser()
258 configParser.add_section(section)
259 configParser.set(section, 'fontSize', str(self.config["fontSize"]))
260 configParser.set(section, 'artFontSize', str(self.config["artFontSize"]))
261 configParser.set(section, 'expiry', str(self.config["expiry"]))
262 configParser.set(section, 'autoupdate', str(self.config["autoupdate"]))
263 configParser.set(section, 'updateInterval', str(self.config["updateInterval"]))
264 configParser.set(section, 'woodchuck', str(self.config["woodchuck"]))
265 configParser.set(section, 'askedAboutWoodchuck', str(self.config["askedAboutWoodchuck"]))
266 configParser.set(section, 'orientation', str(self.config["orientation"]))
267 configParser.set(section, 'imageCache', str(self.config["imageCache"]))
268 configParser.set(section, 'proxy', str(self.config["proxy"]))
269 configParser.set(section, 'hidereadfeeds', str(self.config["hidereadfeeds"]))
270 configParser.set(section, 'hidereadarticles', str(self.config["hidereadarticles"]))
271 configParser.set(section, 'extBrowser', str(self.config["extBrowser"]))
272 configParser.set(section, 'feedsort', str(self.config["feedsort"]))
274 # Writing our configuration file
275 file = open(self.configFilename, 'wb')
276 configParser.write(file)
279 def create_selector(self, choices, setting):
282 from gobject import idle_add
283 #self.pickerDialog = hildon.PickerDialog(self.parent)
284 selector = hildon.TouchSelector(text=True)
287 iter = selector.append_text(str(item))
288 if str(self.config[setting]) == str(item):
289 selector.set_active(0, index)
291 selector.connect("changed", self.selection_changed, setting)
292 #self.pickerDialog.set_selector(selector)
294 #self.pickerDialog.show_all()
296 def getFontSize(self):
297 return self.config["fontSize"]
298 def getArtFontSize(self):
299 return self.config["artFontSize"]
301 return self.config["expiry"]
302 def isAutoUpdateEnabled(self):
303 return self.config["autoupdate"]
304 def getWoodchuckEnabled(self):
305 return self.config["woodchuck"]
306 def getAskedAboutWoodchuck(self):
307 return self.config["askedAboutWoodchuck"]
308 def setAskedAboutWoodchuck(self, value):
309 self.config["askedAboutWoodchuck"] = value
311 def getUpdateInterval(self):
312 return float(self.config["updateInterval"])
313 def getReadFont(self):
314 return "sans italic %s" % self.config["fontSize"]
315 def getUnreadFont(self):
316 return "sans %s" % self.config["fontSize"]
317 def getOrientation(self):
318 return ranges["orientation"].index(self.config["orientation"])
319 def getImageCache(self):
320 return self.config["imageCache"]
323 if self.config["proxy"] == False:
325 if client_get_default().get_bool('/system/http_proxy/use_http_proxy'):
326 port = client_get_default().get_int('/system/http_proxy/port')
327 http = client_get_default().get_string('/system/http_proxy/host')
328 proxy = ProxyHandler( {"http":"http://%s:%s/"% (http,port)} )
331 def getHideReadFeeds(self):
332 return self.config["hidereadfeeds"]
333 def getHideReadArticles(self):
334 return self.config["hidereadarticles"]
335 def getOpenInExternalBrowser(self):
336 return self.config["extBrowser"]
337 def getFeedSortOrder(self):
338 return self.config["feedsort"]