fix calls to URLFetch.http_results which accepts two params only, fixed bug 439144...
[straw.git] / src / lib / subscribe.py
blob604ae719ed8aa4a2c691a92861ceb616f6fce27e
1 """ subscribe.py
3 Module for handling feed subscription process.
4 """
5 __copyright__ = "Copyright (c) 2002-2005 Free Software Foundation, Inc."
6 __license__ = """ GNU General Public License
8 This program is free software; you can redistribute it and/or modify it under the
9 terms of the GNU General Public License as published by the Free Software
10 Foundation; either version 2 of the License, or (at your option) any later
11 version.
13 This program is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along with
18 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 Place - Suite 330, Boston, MA 02111-1307, USA. """
22 import urlparse
23 import urllib
24 import pygtk
25 pygtk.require('2.0')
26 import gtk
27 import gtk.glade
28 import gettext
29 from Feed import Feed
30 import FeedList
31 import error
32 import Event
33 import utils
34 import SummaryParser
35 import ParsedSummary
36 import dialogs
37 import time
38 import URLFetch
39 import MVP
40 import Config
42 class SubscribeView(MVP.GladeView):
43 def _initialize(self):
44 self._window = self._widget.get_widget('subscribe_dialog')
45 self._location_entry = self._widget.get_widget('feed_location_entry')
46 self._username_entry = self._widget.get_widget('username_entry')
47 self._password_entry = self._widget.get_widget('password_entry')
48 self._error_text = self._widget.get_widget('error_text')
49 self._error_box = self._widget.get_widget('error_box')
50 self._location_entry.grab_focus()
52 def _on_ok_clicked(self, *args):
53 location = self._location_entry.get_text()
54 if not location:
55 self.display_error(_("Feed Location must not be empty"))
56 return
57 username = self._username_entry.get_text()
58 username = username.strip()
59 password = self._password_entry.get_text()
60 password = password.strip()
62 config = Config.get_instance()
63 if config.offline:
64 self._window.hide()
65 response = dialogs.report_offline_status(self._window)
66 if response == gtk.RESPONSE_CANCEL:
67 self.show()
68 return
69 config.offline = not config.offline
70 self._presenter.subscribe(location, username, password)
72 def _clear_entries(self):
73 self._location_entry.delete_text(0,-1)
74 self._username_entry.delete_text(0,-1)
75 self._password_entry.delete_text(0,-1)
77 def show(self):
78 self._clear_entries()
79 self._error_box.set_property('visible',False)
80 self._window.show()
82 def display_error(self, text):
83 self._error_box.set_property('visible',True)
84 self._error_text.set_text(text)
86 def set_location_entry(self, location):
87 self._location_entry.set_text(location)
89 def set_parent(self, parent):
90 self._window.set_transient_for(parent)
92 def _on_close_clicked(self, *args):
93 self._window.hide()
95 def _on_feed_location_entry_key_press_event(self, widget, event):
96 if event.keyval == gtk.keysyms.Return:
97 self._presenter.subscribe(self._location_entry.get_text())
99 class SubscribePresenter(MVP.BasicPresenter):
101 def _normalize(self, url):
102 u = urlparse.urlsplit(url.strip())
103 # we check if 'scheme' is not empty here because URIs like
104 # "google.com" IS valid but, in this case, 'scheme' is empty because
105 # urlsplit() expects urls are in the format of scheme://netloc/...
106 if not u[0] or (u[0] != "http" and u[0] != "feed"):
107 return None
108 if u[0] == 'feed':
109 u = urlparse.urlsplit(u[2])
110 # .. if that happens then we munge the url by adding a // and assume
111 # that 'http' is the scheme.
112 if u[1] == '':
113 u = urlparse.urlsplit("//" + url, 'http')
114 return u
116 def subscribe(self, location, username=None, password=None):
117 self._username = username
118 self._password = password
119 self._location = location
121 consumer = SubscribeConsumer(self)
123 try:
124 URLFetch.get_instance().request(location, consumer,
125 user=username, password=password)
126 except Exception, e:
127 consumer.http_failed(e)
129 def set_parent(self, parent):
130 self.view.set_parent(parent)
132 def get_credential(self):
133 return (self._location, self._username, self._password)
135 def show(self, url):
136 if url:
137 self.view.set_location_entry(url)
138 self.view.show()
140 # def set_url_dnd(self, url):
141 # self._window.show()
142 # self._feed_location_presenter.view.find_feed(url)
144 def set_location_from_clipboard(self):
145 def _clipboard_cb(cboard, url, data=None):
146 if url:
147 url = self._normalize(url)
148 if url and url[0] == "http":
149 url = urlparse.urlunsplit(url)
150 self.view.set_location_entry(url)
151 clipboard = gtk.clipboard_get(selection="CLIPBOARD")
152 clipboard.request_text(_clipboard_cb, None)
155 class SubscribeConsumer:
157 def __init__(self, presenter):
158 self._presenter = presenter
160 def http_results(self, status, data):
161 url, user, password = self._presenter.get_credential()
162 feed = Feed.create_new_feed("", url, user, password)
163 parsed = SummaryParser.parse(data, feed)
164 if parsed.title == "":
165 # store url loc in title in case it's empty
166 parsed.title = urlparse.urlsplit(url.strip())[1]
167 feed.title = utils.convert_entities(parsed.title)
168 feed.channel_description = utils.convert_entities(parsed.description)
169 feed.access_info = (url, user, password)
170 feed.last_poll = int(time.time())
171 category = None # Add to 'All' category
172 FeedList.get_instance().append(category, feed)
173 feed.router.route_all(parsed)
174 feed.poll_done()
176 def http_failed(self, exception):
177 # XXX signal to the user that subscription failed? incl. erros
178 print "subscribe failed", exception
180 def operation_stopped(self):
181 # XXX signal that it stopped, why it stopped, and stop all progress
182 # bars, etc...
183 print "subscribe operation stopped"
185 def display_window(url=None, parent=None):
186 dialog = _get_instance()
187 dialog.set_parent(parent)
188 dialog.set_location_from_clipboard()
189 dialog.show(url)
191 instance = None
192 def _get_instance():
193 global instance
194 if instance is None:
195 widget_tree = MVP.get_widget_tree('subscribe_dialog')
196 instance = SubscribePresenter(view=SubscribeView(widget_tree))
197 return instance