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 button = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
120 button.set_label("Widget Based Automatic Update\n"
121 + "(See FeedingIt widget for options)")
122 #button.set_active(self.config["autoupdate"])
123 #button.connect("toggled", self.button_toggled, "autoupdate")
124 vbox.pack_start(button, expand=False)
125 button = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
126 button.set_label("Woodchuck-Based Automatic Update")
127 button.set_active(self.config["woodchuck"])
128 button.connect("toggled", self.button_toggled, "woodchuck")
129 vbox.pack_start(button, expand=False)
133 woodchuck_installed = True
135 woodchuck_installed = False
137 if not woodchuck_installed:
138 def install_woodchuck_clicked(button):
139 from FeedingIt import open_in_browser
140 open_in_browser("http://maemo.org/downloads/product/raw/Maemo5/murmeltier?get_installfile")
142 button = hildon.Button(gtk.HILDON_SIZE_FINGER_HEIGHT, hildon.BUTTON_ARRANGEMENT_VERTICAL)
143 button.set_label("Install Woodchuck")
144 button.connect("clicked", install_woodchuck_clicked)
145 button.set_alignment(0,0,1,1)
146 vbox.pack_start(button, expand=False)
148 add_setting('updateInterval')
149 add_setting('expiry')
152 button = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
153 button.set_label('Cache images')
154 button.set_active(self.config["imageCache"])
155 button.connect("toggled", self.button_toggled, "imageCache")
156 vbox.pack_start(button, expand=False)
158 button = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
159 button.set_label("Use HTTP proxy")
160 button.set_active(self.config["proxy"])
161 button.connect("toggled", self.button_toggled, "proxy")
162 vbox.pack_start(button, expand=False)
164 button = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
165 button.set_label('Open links in external browser')
166 button.set_active(self.config["extBrowser"])
167 button.connect("toggled", self.button_toggled, "extBrowser")
168 vbox.pack_start(button, expand=False)
170 panArea.add_with_viewport(vbox)
172 self.window.vbox.add(panArea)
173 self.window.connect("destroy", self.onExit)
174 #self.window.add(self.vbox)
175 self.window.set_default_size(-1, 600)
176 self.window.show_all()
179 def button_tips_clicked(self, *widget):
181 bus = dbus.SessionBus()
182 proxy = bus.get_object("com.nokia.osso_browser", "/com/nokia/osso_browser/request")
183 iface = dbus.Interface(proxy, 'com.nokia.osso_browser')
184 iface.open_new_window("http://feedingit.marcoz.org/news/?page_id=%s" % VERSION)
186 def onExit(self, *widget):
187 # When the dialog is closed without hitting
188 # the "Save" button, restore the configuration
189 if self.do_restore_backup:
190 logger.debug('Restoring configuration')
191 self.config = self.config_backup
194 self.window.destroy()
196 def button_toggled(self, widget, configName):
197 #print "widget", widget.get_active()
198 if (widget.get_active()):
199 self.config[configName] = True
201 self.config[configName] = False
202 #print "autoup", self.autoupdate
204 if configName == 'woodchuck':
206 from wc import wc_disable_set
207 wc_disable_set(not self.config['woodchuck'])
209 logger.exception("Disabling Woodchuck")
213 def selection_changed(self, selector, button, setting):
214 from gobject import idle_add
215 current_selection = selector.get_current_text()
216 if current_selection:
217 self.config[setting] = current_selection
218 idle_add(self.updateButton, setting)
221 def updateButton(self, setting):
222 self.buttons[setting].set_text(titles[setting], subtitles[setting] % self.config[setting])
224 def loadConfig(self):
227 configParser = RawConfigParser()
229 configParser.read(self.configFilename)
231 logger.exception("Reading %s", self.configFilename)
233 # The function to use to fetch the parameter, the parameter's
234 # name and the default value.
235 values = ((configParser.getint, "fontSize", 17),
236 (configParser.getint, "artFontSize", 14),
237 (configParser.getint, "expiry", 24),
238 (configParser.getboolean, "autoupdate", False),
239 (configParser.getboolean, "woodchuck", True),
240 (configParser.getboolean, "askedAboutWoodchuck", False),
241 (configParser.getint, "updateInterval", 4),
242 (configParser.get, "orientation", "Automatic"),
243 (configParser.getboolean, "imageCache", False),
244 (configParser.getboolean, "proxy", True),
245 (configParser.getboolean, "hidereadfeeds", False),
246 (configParser.getboolean, "hidereadarticles", False),
247 (configParser.getboolean, "extBrowser", False),
248 (configParser.get, "feedsort", "Manual"))
250 for fetcher, name, default in values:
252 v = fetcher(section, name)
254 logger.exception("Reading config variable %s", name)
256 self.config[name] = v
258 def saveConfig(self):
259 configParser = RawConfigParser()
260 configParser.add_section(section)
261 configParser.set(section, 'fontSize', str(self.config["fontSize"]))
262 configParser.set(section, 'artFontSize', str(self.config["artFontSize"]))
263 configParser.set(section, 'expiry', str(self.config["expiry"]))
264 configParser.set(section, 'autoupdate', str(self.config["autoupdate"]))
265 configParser.set(section, 'updateInterval', str(self.config["updateInterval"]))
266 configParser.set(section, 'woodchuck', str(self.config["woodchuck"]))
267 configParser.set(section, 'askedAboutWoodchuck', str(self.config["askedAboutWoodchuck"]))
268 configParser.set(section, 'orientation', str(self.config["orientation"]))
269 configParser.set(section, 'imageCache', str(self.config["imageCache"]))
270 configParser.set(section, 'proxy', str(self.config["proxy"]))
271 configParser.set(section, 'hidereadfeeds', str(self.config["hidereadfeeds"]))
272 configParser.set(section, 'hidereadarticles', str(self.config["hidereadarticles"]))
273 configParser.set(section, 'extBrowser', str(self.config["extBrowser"]))
274 configParser.set(section, 'feedsort', str(self.config["feedsort"]))
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 isAutoUpdateEnabled(self):
305 return self.config["autoupdate"]
306 def getWoodchuckEnabled(self):
307 return self.config["woodchuck"]
308 def getAskedAboutWoodchuck(self):
309 return self.config["askedAboutWoodchuck"]
310 def setAskedAboutWoodchuck(self, value):
311 self.config["askedAboutWoodchuck"] = value
313 def getUpdateInterval(self):
314 return float(self.config["updateInterval"])
315 def getReadFont(self):
316 return "sans italic %s" % self.config["fontSize"]
317 def getUnreadFont(self):
318 return "sans %s" % self.config["fontSize"]
319 def getOrientation(self):
320 return ranges["orientation"].index(self.config["orientation"])
321 def getImageCache(self):
322 return self.config["imageCache"]
325 if self.config["proxy"] == False:
327 if client_get_default().get_bool('/system/http_proxy/use_http_proxy'):
328 port = client_get_default().get_int('/system/http_proxy/port')
329 http = client_get_default().get_string('/system/http_proxy/host')
330 proxy = ProxyHandler( {"http":"http://%s:%s/"% (http,port)} )
333 def getHideReadFeeds(self):
334 return self.config["hidereadfeeds"]
335 def getHideReadArticles(self):
336 return self.config["hidereadarticles"]
337 def getOpenInExternalBrowser(self):
338 return self.config["extBrowser"]
339 def getFeedSortOrder(self):
340 return self.config["feedsort"]