1 #!/usr/bin/env python2.5
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.
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.
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/>.
19 # ============================================================================
21 # Author : Yves Marcoz
23 # Description : PyGtk Example
24 # ============================================================================
34 from os.path import isfile, isdir
42 class AddWidgetWizard(hildon.WizardDialog):
44 def __init__(self, parent):
46 self.notebook = gtk.Notebook()
48 self.nameEntry = hildon.Entry(gtk.HILDON_SIZE_AUTO)
49 self.nameEntry.set_placeholder("Enter Feed Name")
51 self.urlEntry = hildon.Entry(gtk.HILDON_SIZE_AUTO)
53 self.urlEntry.set_placeholder("Enter a URL")
55 labelEnd = gtk.Label("Success")
57 self.notebook.append_page(self.nameEntry, None)
58 self.notebook.append_page(self.urlEntry, None)
59 self.notebook.append_page(labelEnd, None)
61 hildon.WizardDialog.__init__(self, parent, "Add Feed", self.notebook)
63 # Set a handler for "switch-page" signal
64 #self.notebook.connect("switch_page", self.on_page_switch, self)
66 # Set a function to decide if user can go to next page
67 self.set_forward_page_func(self.some_page_func)
73 return (self.nameEntry.get_text(), self.urlEntry.get_text())
75 def on_page_switch(self, notebook, page, num, dialog):
76 print >>sys.stderr, "Page %d" % num
79 def some_page_func(self, nb, current, userdata):
80 # Validate data for 1st page
83 entry = nb.get_nth_page(current)
84 # Check the name is not null
85 return len(entry.get_text()) != 0
87 entry = nb.get_nth_page(current)
88 # Check the url is not null, and starts with http
89 print ( (len(entry.get_text()) != 0) and (entry.get_text().startswith("http")) )
90 return ( (len(entry.get_text()) != 0) and (entry.get_text().startswith("http")) )
99 self.window = hildon.StackableWindow()
100 menu = hildon.AppMenu()
101 # Create a button and add it to the menu
102 button = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
103 button.set_label("Update All Feeds")
104 button.connect("clicked", self.button_update_clicked, "All")
106 button = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
107 button.set_label("Add Feed")
108 button.connect("clicked", self.button_add_clicked)
111 self.window.set_app_menu(menu)
114 self.feedWindow = hildon.StackableWindow()
115 self.articleWindow = hildon.StackableWindow()
117 self.listing = Listing()
118 #self.listing.downloadFeeds()
119 self.displayListing()
121 #self.window.show_all()
122 #self.displayFeed(self.listing.getFeed(0))
124 def button_add_clicked(self, button):
125 wizard = AddWidgetWizard(self.window)
128 (title, url) = wizard.getData()
129 if (not title == '') and (not url == ''):
130 self.listing.addFeed(title, url)
132 self.displayListing()
134 def button_update_clicked(self, button, key):
135 hildon.hildon_gtk_window_set_progress_indicator(self.window, 1)
137 self.listing.updateFeeds()
139 self.listing.getFeed(key).updateFeed()
140 self.displayListing()
141 hildon.hildon_gtk_window_set_progress_indicator(self.window, 0)
143 def displayListing(self):
145 self.window.remove(self.pannableListing)
148 self.vboxListing = gtk.VBox(False,10)
149 self.pannableListing = hildon.PannableArea()
150 self.pannableListing.add_with_viewport(self.vboxListing)
152 for key in self.listing.getListOfFeeds():
153 #button = gtk.Button(item)
154 button = hildon.Button(gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT,
155 hildon.BUTTON_ARRANGEMENT_VERTICAL)
156 button.set_text(self.listing.getFeedTitle(key), self.listing.getFeedUpdateTime(key))
157 button.set_alignment(0,0,1,1)
158 #label = button.child
159 #label.modify_font(pango.FontDescription("sans 10"))
160 button.connect("clicked", self.buttonFeedClicked, self, self.window, key)
161 self.vboxListing.pack_start(button, expand=False)
162 self.window.add(self.pannableListing)
163 self.window.show_all()
165 def displayFeed(self, key):
166 # Initialize the feed panel
167 self.vboxFeed = gtk.VBox(False, 10)
168 self.pannableFeed = hildon.PannableArea()
169 self.pannableFeed.add_with_viewport(self.vboxFeed)
172 for item in self.listing.getFeed(key).getEntries():
173 #button = hildon.Button(gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT,
174 # hildon.BUTTON_ARRANGEMENT_HORIZONTAL)
175 #button.set_text(item["title"], time.strftime("%a, %d %b %Y %H:%M:%S",item["updated_parsed"]))
176 #button.set_text(item["title"], time.asctime(item["updated_parsed"]))
177 #button.set_text(item["title"],"")
178 #button.set_alignment(0,0,1,1)
179 #button.set_markup(True)
180 button = gtk.Button(item["title"])
181 button.set_alignment(0,0)
183 #label.set_markup(item["title"])
184 label.modify_font(pango.FontDescription("sans 16"))
185 button.connect("clicked", self.button_clicked, self, self.window, key, index)
187 self.vboxFeed.pack_start(button, expand=False)
190 self.feedWindow.add(self.pannableFeed)
191 self.feedWindow.show_all()
193 def displayArticle(self, key, index):
194 text = self.listing.getFeed(key).getArticle(index)
195 self.articleWindow = hildon.StackableWindow()
197 # Init the article display
198 self.view = gtkhtml2.View()
199 self.pannable_article = hildon.PannableArea()
200 self.pannable_article.add(self.view)
201 self.document = gtkhtml2.Document()
202 self.view.set_document(self.document)
204 self.document.clear()
205 self.document.open_stream("text/html")
206 self.document.write_stream(text)
207 self.document.close_stream()
209 self.articleWindow.add(self.pannable_article)
211 self.articleWindow.show_all()
213 self.document.connect("link_clicked", self._signal_link_clicked)
214 self.document.connect("request-url", self._signal_request_url)
216 self.document.open_stream("text/html")
217 self.document.write_stream(text)
218 self.document.close_stream()
223 # def _signal_on_url(self, object, url):
224 # if url == None: url = ""
225 # else: url = self._complete_url(url)
226 #self.emit("status_changed", url)
228 def _signal_link_clicked(self, object, link):
229 webbrowser.open(link)
231 def _signal_request_url(self, object, url, stream):
232 f = urllib2.urlopen(url)
233 stream.write(f.read())
236 # def _complete_url(self, url):
237 # import string, urlparse, urllib
238 # url = urllib.quote(url, safe=string.punctuation)
239 # if urlparse.urlparse(url)[0] == '':
240 # return urlparse.urljoin(self.location, url)
244 # def _open_url(self, url, headers=[]):
246 # opener = urllib2.build_opener()
247 # opener.addheaders = [('User-agent', 'Wikitin')]+headers
248 # return opener.open(url)
250 # def _fetch_url(self, url, headers=[]):
251 # return self._open_url(url, headers).read()
254 def button_clicked(widget, button, app, window, key, index):
255 app.displayArticle(key, index)
257 def buttonFeedClicked(widget, button, app, window, key):
261 self.window.connect("destroy", gtk.main_quit)
262 #self.window.show_all()
265 if __name__ == "__main__":
266 if not isdir(CONFIGDIR):
270 print "Error: Can't create configuration directory"