ed080b3a4c4af0451563cca4e3522001a83fa398
[feedingit] / src / feedingit_widget.py
1 #!/usr/bin/env python2.5
2
3
4 # Copyright (c) 2007-2008 INdT.
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Lesser General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 #  This program is distributed in the hope that it will be useful,
11 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 #  GNU Lesser General Public License for more details.
14 #
15 #  You should have received a copy of the GNU Lesser General Public License
16 #  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 #
18
19 # ============================================================================
20 # Name        : FeedingIt.py
21 # Author      : Yves Marcoz
22 # Version     : 0.5.4
23 # Description : Simple RSS Reader
24 # ============================================================================
25 #import sys
26 #sys.path.insert(0, '/opt/FeedingIt')
27 #sys.path.insert(0, '/home/user/workspace/feedingit/src/')
28
29 import gtk, pickle, gobject, dbus
30 import hildondesktop, hildon
31 #from rss import Listing
32
33 # Create a session bus.
34 import dbus
35 from dbus.mainloop.glib import DBusGMainLoop
36 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
37 bus = dbus.SessionBus()
38
39 CONFIGDIR="/home/user/.feedingit/"
40
41 class FeedingItHomePlugin(hildondesktop.HomePluginItem):
42     def __init__(self):
43       try:
44         hildondesktop.HomePluginItem.__init__(self)
45         self.set_settings(True)
46         self.connect("show-settings", self.show_settings)
47         self.feed_list = {}
48         
49         vbox = gtk.VBox(False, 0)
50         
51         button = gtk.Button("Update")
52         button.connect("clicked", self.update_list)
53         button.show_all()
54         vbox.pack_start(button)        
55         
56         #for feed in ["Slashdot", "Engadget", "Cheez"]:
57         #    self.treestore.append([feed, "0"])
58         self.treeview = gtk.TreeView()
59         self.update_list()
60         self.treeview.append_column(gtk.TreeViewColumn('Feed Name', gtk.CellRendererText(), text = 0))
61         self.treeview.append_column(gtk.TreeViewColumn('Unread Items', gtk.CellRendererText(), text = 1))
62         #self.treeview.get_selection().set_mode(gtk.SELECTION_NONE)
63         #hildon.hildon_gtk_tree_view_set_ui_mode(self.treeview, gtk.HILDON_UI_MODE_NORMAL)
64         
65         vbox.pack_start(self.treeview)
66         
67         self.add(vbox)
68         self.treeview.connect("row-activated", self.row_activated)
69         vbox.show_all()
70         #self.setupDbus()
71         gobject.timeout_add_seconds(30*60, self.update_list)
72       except:
73           import traceback
74           file = open("/home/user/.feedingit/feedingit_widget.log", "w")
75           traceback.print_exc(file=file)
76
77     def row_activated(self, treeview, treepath, column):
78         (model, iter) = self.treeview.get_selection().get_selected()
79         key = model.get_value(iter, 2)
80         # Create an object that will proxy for a particular remote object.
81         remote_object = bus.get_object("org.maemo.feedingit", # Connection name
82                                "/org/maemo/feedingit" # Object's path
83                               )
84         iface = dbus.Interface(remote_object, 'org.maemo.feedingit')
85         iface.OpenFeed(key)
86
87     def update_list(self, *widget):
88         #listing = Listing(CONFIGDIR)
89         treestore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
90         
91         if self.feed_list == {}:
92             self.load_config()
93
94         list = []
95         #for key in listOfFeeds["feedingit-order"]:
96         for key in self.feed_list.keys():
97             try:
98                 file = open(CONFIGDIR+key+".d/unread", "r")
99                 readItems = pickle.load( file )
100                 file.close()
101                 countUnread = 0
102                 for id in readItems.keys():
103                     if readItems[id]==False:
104                         countUnread = countUnread + 1
105                 list.append([self.feed_list[key], countUnread, key])
106             except:
107                 pass
108         list = sorted(list, key=lambda item: item[1], reverse=True)
109         for item in list[0:8]:
110             treestore.append(item)
111         self.treeview.set_model(treestore)
112         self.treeview.get_selection().unselect_all()
113         return True
114         
115     def show_settings(self, widget):
116         file = open(CONFIGDIR+"feeds.pickle")
117         listOfFeeds = pickle.load(file)
118         file.close()
119         dialog = gtk.Dialog("Settings", None, gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR, (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
120
121         self.pannableArea = hildon.PannableArea()
122         
123         #self.treestore_settings = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
124         self.treeview_settings = gtk.TreeView()
125         
126         self.treeview_settings.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
127         hildon.hildon_gtk_tree_view_set_ui_mode(self.treeview_settings, gtk.HILDON_UI_MODE_EDIT)
128         dialog.vbox.pack_start(self.pannableArea)
129         
130         self.treeview_settings.append_column(gtk.TreeViewColumn('Feed Name', gtk.CellRendererText(), text = 0))
131         self.treestore_settings = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
132         self.treeview_settings.set_model(self.treestore_settings)
133         
134         for key in listOfFeeds["feedingit-order"]:
135             title = listOfFeeds[key]["title"]
136             item = self.treestore_settings.append([title, key])
137             if key in self.feed_list:
138                 self.treeview_settings.get_selection().select_iter(item)
139             
140         self.pannableArea.add(self.treeview_settings)
141         self.pannableArea.show_all()
142         dialog.set_default_size(-1, 600)
143         dialog.show_all()
144         response = dialog.run()
145         print response
146         if response == gtk.RESPONSE_ACCEPT:
147             self.feed_list = self.getItems()
148         dialog.destroy()
149         self.update_list()
150         #self.treeview_settings.get_selection().select_all()
151         
152     def getItems(self):
153         list = {}
154         treeselection = self.treeview_settings.get_selection()
155         (model, pathlist) = treeselection.get_selected_rows()
156         for path in pathlist:
157             list[model.get_value(model.get_iter(path),1)] = model.get_value(model.get_iter(path),0)
158         return list
159         
160     def setupDbus(self):
161         
162         #from dbus.mainloop.glib import DBusGMainLoop
163         #dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
164         #import gobject
165         #loop = gobject.MainLoop()
166         #bus = dbus.Bus(dbus.Bus.TYPE_SESSION)
167         #bus = dbus.SessionBus(mainloop=loop)
168         #bus = dbus.Bus.get_system()
169         #bus = dbus.Bus.get_session(True)
170         #bus.set_exit_on_disconnect(False)
171         
172         remote_object = bus.get_object("org.maemo.feedingit", # Connection name
173                                "/org/maemo/feedingit" # Object's path
174                               )
175         iface = dbus.Interface(remote_object, 'org.maemo.feedingit')
176         iface.connect_to_signal("ArticleCountUpdated", self.update_list)
177
178         #bus.add_signal_receiver(self.update_list,
179         #                dbus_interface="org.maemo.feedingit",
180         #                signal_name="ArticleCountUpdated",
181         #                path="/org/maemo/feedingit")
182         
183     def save_config(self):
184             if not isdir(CONFIGDIR):
185                 mkdir(CONFIGDIR)
186             file = open(CONFIGDIR+"widget", "w")
187             pickle.dump(self.feed_list, file )
188             file.close()
189             
190     def load_config(self):
191             try:
192                 file = open(CONFIGDIR+"widget", "r")
193                 self.feed_list = pickle.load( file )
194                 file.close()
195             except:
196                 file = open(CONFIGDIR+"feeds.pickle")
197                 listOfFeeds = pickle.load(file)
198                 file.close()
199             
200                 #self.feed_list = listOfFeeds["feedingit-order"]
201                 for key in listOfFeeds["feedingit-order"]:
202                     self.feed_list[key] = listOfFeeds[key]["title"]
203                 del listOfFeeds
204
205
206 hd_plugin_type = FeedingItHomePlugin
207
208 # The code below is just for testing purposes.
209 # It allows to run the widget as a standalone process.
210 if __name__ == "__main__":
211     import gobject
212     gobject.type_register(hd_plugin_type)
213     obj = gobject.new(hd_plugin_type, plugin_id="plugin_id")
214     obj.show_all()
215     gtk.main()