comparison src/plugins/deprecated_misc_cs.py @ 594:e629371a28d3

Fix pep8 support in src/plugins.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Fri, 18 Jan 2013 17:55:35 +0100
parents beaf6bec2fcd
children 84a6e83157c2
comparison
equal deleted inserted replaced
593:70bae685d05c 594:e629371a28d3
38 import webbrowser 38 import webbrowser
39 39
40 from BeautifulSoup import BeautifulSoup 40 from BeautifulSoup import BeautifulSoup
41 import re 41 import re
42 42
43
44 PLUGIN_INFO = { 43 PLUGIN_INFO = {
45 "name": "CouchSurfing plugin", 44 "name": "CouchSurfing plugin",
46 "import_name": "CS", 45 "import_name": "CS",
47 "type": "Misc", 46 "type": "Misc",
48 "protocols": [], 47 "protocols": [],
49 "dependencies": [], 48 "dependencies": [],
50 "main": "CS_Plugin", 49 "main": "CS_Plugin",
51 "handler": "no", 50 "handler": "no",
52 "description": _(u"""This plugin allow to manage your CouchSurfing account throught your SàT frontend""") 51 "description": _(u"""This plugin allow to manage your CouchSurfing account throught your SàT frontend""")
53 } 52 }
54 53
55 AGENT = 'Salut à Toi XMPP/CS Plugin' 54 AGENT = 'Salut à Toi XMPP/CS Plugin'
55
56 56
57 class CS_Plugin(object): 57 class CS_Plugin(object):
58 58
59 params = """ 59 params = """
60 <params> 60 <params>
71 info(_("Plugin CS initialization")) 71 info(_("Plugin CS initialization"))
72 self.host = host 72 self.host = host
73 #parameters 73 #parameters
74 host.memory.importParams(CS_Plugin.params) 74 host.memory.importParams(CS_Plugin.params)
75 #menu 75 #menu
76 host.importMenu(_("Plugin"), "CouchSurfing", self.menuSelected, help_string = _("Launch CoushSurfing management interface")) 76 host.importMenu(_("Plugin"), "CouchSurfing", self.menuSelected, help_string=_("Launch CoushSurfing management interface"))
77 self.data={} #TODO: delete cookies/data after a while 77 self.data = {} # TODO: delete cookies/data after a while
78 self.host.registerGeneralCB("plugin_CS_sendMessage", self.sendMessage) 78 self.host.registerGeneralCB("plugin_CS_sendMessage", self.sendMessage)
79 self.host.registerGeneralCB("plugin_CS_showUnreadMessages", self.showUnreadMessages) 79 self.host.registerGeneralCB("plugin_CS_showUnreadMessages", self.showUnreadMessages)
80 80
81 def profileConnected(self, profile): 81 def profileConnected(self, profile):
82 self.data[profile] = PersistentBinaryDict("plugin_CS", profile) 82 self.data[profile] = PersistentBinaryDict("plugin_CS", profile)
83
83 def dataLoaded(ignore): 84 def dataLoaded(ignore):
84 if not self.data[profile]: 85 if not self.data[profile]:
85 self.data[profile] = {'cookies':{}} 86 self.data[profile] = {'cookies': {}}
86 87
87 self.data[profile].load().addCallback(dataLoaded) 88 self.data[profile].load().addCallback(dataLoaded)
88 89
89 def profileDisconnected(self, profile): 90 def profileDisconnected(self, profile):
90 del self.data[profile] 91 del self.data[profile]
91 92
92 def erroCB(self, e, id): 93 def erroCB(self, e, id):
93 """Called when something is going wrong when contacting CS website""" 94 """Called when something is going wrong when contacting CS website"""
94 #pdb.set_trace() 95 #pdb.set_trace()
95 message_data={"reason": "connection error", "message":_(u"Impossible to contact CS website, please check your login/password, connection or try again later")} 96 message_data = {"reason": "connection error", "message": _(u"Impossible to contact CS website, please check your login/password, connection or try again later")}
96 self.host.bridge.actionResult("ERROR", id, message_data) 97 self.host.bridge.actionResult("ERROR", id, message_data)
97 98
98 def menuSelected(self, id, profile): 99 def menuSelected(self, id, profile):
99 """Called when the couchsurfing menu item is selected""" 100 """Called when the couchsurfing menu item is selected"""
100 login = self.host.memory.getParamA("Login", "CouchSurfing", profile_key=profile) 101 login = self.host.memory.getParamA("Login", "CouchSurfing", profile_key=profile)
101 password = self.host.memory.getParamA("Password", "CouchSurfing", profile_key=profile) 102 password = self.host.memory.getParamA("Password", "CouchSurfing", profile_key=profile)
102 if not login or not password: 103 if not login or not password:
103 message_data={"reason": "uncomplete", "message":_(u"You have to fill your CouchSurfing login & password in parameters before using this interface")} 104 message_data = {"reason": "uncomplete", "message": _(u"You have to fill your CouchSurfing login & password in parameters before using this interface")}
104 self.host.bridge.actionResult("ERROR", id, message_data) 105 self.host.bridge.actionResult("ERROR", id, message_data)
105 return 106 return
106 107
107 post_data = urllib.urlencode({'auth_login[un]':login,'auth_login[pw]':password,'auth_login[action]':'Login...'}) 108 post_data = urllib.urlencode({'auth_login[un]': login, 'auth_login[pw]': password, 'auth_login[action]': 'Login...'})
108 109
109 self.data[profile]['cookies'] = {} 110 self.data[profile]['cookies'] = {}
110 111
111 d = getPage('http://www.couchsurfing.org/login.html', method='POST', postdata=post_data, headers={'Content-Type':'application/x-www-form-urlencoded'} , agent=AGENT, cookies=self.data[profile]['cookies']) 112 d = getPage('http://www.couchsurfing.org/login.html', method='POST', postdata=post_data, headers={'Content-Type': 'application/x-www-form-urlencoded'}, agent=AGENT, cookies=self.data[profile]['cookies'])
112 d.addCallback(self.__connectionCB, id, profile) 113 d.addCallback(self.__connectionCB, id, profile)
113 d.addErrback(self.erroCB, id) 114 d.addErrback(self.erroCB, id)
114 115
115 #self.host.bridge.actionResult("SUPPRESS", id, {}) 116 #self.host.bridge.actionResult("SUPPRESS", id, {})
116 117
117
118 #pages parsing callbacks 118 #pages parsing callbacks
119
119 def savePage(self, name, html): 120 def savePage(self, name, html):
120 f = open ('/tmp/CS_'+name+'.html','w') 121 f = open('/tmp/CS_' + name + '.html', 'w')
121 f.write(html) 122 f.write(html)
122 f.close() 123 f.close()
123 print "page [%s] sauvee" % name 124 print "page [%s] sauvee" % name
124 #pdb.set_trace() 125 #pdb.set_trace()
125 126
126 def __connectionCB(self, html, id, profile): 127 def __connectionCB(self, html, id, profile):
127 print 'Response received' 128 print 'Response received'
128 #self.savePage('principale',html) 129 #self.savePage('principale',html)
129 soup = BeautifulSoup(html) 130 soup = BeautifulSoup(html)
130 self.data[profile]['user_nick'] = soup.find('a','item_link',href='/home.html').contents[0] 131 self.data[profile]['user_nick'] = soup.find('a', 'item_link', href='/home.html').contents[0]
131 self.data[profile]['user_name'] = soup.html.head.title.string.split(' - ')[1] 132 self.data[profile]['user_name'] = soup.html.head.title.string.split(' - ')[1]
132 #unread messages 133 #unread messages
133 try: 134 try:
134 self.data[profile]['unread_messages'] = int(soup.find(lambda tag: tag.name=='div' and ('class','item_bubble') in tag.attrs and tag.find('a', href="/messages.html?message_status=inbox")).find(text=True)) 135 self.data[profile]['unread_messages'] = int(soup.find(lambda tag: tag.name == 'div' and ('class', 'item_bubble') in tag.attrs and tag.find('a', href="/messages.html?message_status=inbox")).find(text=True))
135 except: 136 except:
136 self.data[profile]['unread_messages'] = 0 137 self.data[profile]['unread_messages'] = 0
137 #unread couchrequest messages 138 #unread couchrequest messages
138 try: 139 try:
139 self.data[profile]['unread_CR_messages'] = int(soup.find(lambda tag: tag.name=='div' and ('class','item_bubble') in tag.attrs and tag.find('a', href="/couchmanager")).find(text=True)) 140 self.data[profile]['unread_CR_messages'] = int(soup.find(lambda tag: tag.name == 'div' and ('class', 'item_bubble') in tag.attrs and tag.find('a', href="/couchmanager")).find(text=True))
140 except: 141 except:
141 self.data[profile]['unread_CR_messages'] = 0 142 self.data[profile]['unread_CR_messages'] = 0
142 143
143 #if we have already the list of friend, no need to make new requests 144 #if we have already the list of friend, no need to make new requests
144 if not self.data[profile].has_key('friends'): 145 if 'friends' not in self.data[profile]:
145 self.data[profile]['friends'] = {} 146 self.data[profile]['friends'] = {}
146 d = getPage('http://www.couchsurfing.org/connections.html?type=myfriends&show=10000', agent=AGENT, cookies=self.data[profile]['cookies']) 147 d = getPage('http://www.couchsurfing.org/connections.html?type=myfriends&show=10000', agent=AGENT, cookies=self.data[profile]['cookies'])
147 d.addCallback(self.__friendsPageCB, id=id, profile=profile) 148 d.addCallback(self.__friendsPageCB, id=id, profile=profile)
148 d.addErrback(self.erroCB, id) 149 d.addErrback(self.erroCB, id)
149 else: 150 else:
150 self.host.bridge.actionResult("XMLUI", id, {"type":"window", "xml":self.__buildUI(self.data[profile])}) 151 self.host.bridge.actionResult("XMLUI", id, {"type": "window", "xml": self.__buildUI(self.data[profile])})
151 152
152 def __buildUI(self, data): 153 def __buildUI(self, data):
153 """Build the XML UI of the plugin 154 """Build the XML UI of the plugin
154 @param data: data store for the profile""" 155 @param data: data store for the profile"""
155 user_nick = data['user_nick'] 156 user_nick = data['user_nick']
156 user_name = data['user_name'] 157 user_name = data['user_name']
157 unread_mess = data['unread_messages'] 158 unread_mess = data['unread_messages']
158 unread_CR_mess = data['unread_CR_messages'] 159 unread_CR_mess = data['unread_CR_messages']
159 friends_list = data['friends'].keys() 160 friends_list = data['friends'].keys()
160 friends_list.sort() 161 friends_list.sort()
161 interface = XMLUI('window','tabs', title='CouchSurfing management') 162 interface = XMLUI('window', 'tabs', title='CouchSurfing management')
162 interface.addCategory(_("Messages"), "vertical") 163 interface.addCategory(_("Messages"), "vertical")
163 interface.addText(_("G'day %(name)s, you have %(nb_message)i unread message%(plural_mess)s and %(unread_CR_mess)s unread couch request message%(plural_CR)s\nIf you want to send a message, select the recipient(s) in the list below") % {'name':user_name, 'nb_message':unread_mess, 'plural_mess':'s' if unread_mess>1 else '', 'unread_CR_mess': unread_CR_mess, 'plural_CR':'s' if unread_CR_mess>1 else ''}) 164 interface.addText(_("G'day %(name)s, you have %(nb_message)i unread message%(plural_mess)s and %(unread_CR_mess)s unread couch request message%(plural_CR)s\nIf you want to send a message, select the recipient(s) in the list below") % {'name': user_name, 'nb_message': unread_mess, 'plural_mess': 's' if unread_mess > 1 else '', 'unread_CR_mess': unread_CR_mess, 'plural_CR': 's' if unread_CR_mess > 1 else ''})
164 if unread_mess: 165 if unread_mess:
165 interface.addButton('plugin_CS_showUnreadMessages', 'showUnreadMessages', _('Show unread message%(plural)s in external web browser') % {'plural':'s' if unread_mess>1 else ''}) 166 interface.addButton('plugin_CS_showUnreadMessages', 'showUnreadMessages', _('Show unread message%(plural)s in external web browser') % {'plural': 's' if unread_mess > 1 else ''})
166 interface.addList(friends_list, 'friends', style=['multi']) 167 interface.addList(friends_list, 'friends', style=['multi'])
167 interface.changeLayout('pairs') 168 interface.changeLayout('pairs')
168 interface.addLabel(_("Subject")) 169 interface.addLabel(_("Subject"))
169 interface.addString('subject') 170 interface.addString('subject')
170 interface.changeLayout('vertical') 171 interface.changeLayout('vertical')
171 interface.addLabel(_("Message")) 172 interface.addLabel(_("Message"))
172 interface.addText("(use %name% for contact name and %firstname% for guessed first name)") 173 interface.addText("(use %name% for contact name and %firstname% for guessed first name)")
173 interface.addTextBox('message') 174 interface.addTextBox('message')
174 interface.addButton('plugin_CS_sendMessage', 'sendMessage', _('send'), fields_back=['friends','subject','message']) 175 interface.addButton('plugin_CS_sendMessage', 'sendMessage', _('send'), fields_back=['friends', 'subject', 'message'])
175 #interface.addCategory(_("Events"), "vertical") #TODO: coming soon, hopefuly :) 176 #interface.addCategory(_("Events"), "vertical") #TODO: coming soon, hopefuly :)
176 #interface.addCategory(_("Couch search"), "vertical") 177 #interface.addCategory(_("Couch search"), "vertical")
177 return interface.toXml() 178 return interface.toXml()
178 179
179 def __meetingPageCB(self, html): 180 def __meetingPageCB(self, html):
180 """Called when the meeting page has been received""" 181 """Called when the meeting page has been received"""
181 182
182 def __friendsPageCB(self, html, id, profile): 183 def __friendsPageCB(self, html, id, profile):
183 """Called when the friends list page has been received""" 184 """Called when the friends list page has been received"""
184 self.savePage('friends',html) 185 self.savePage('friends', html)
185 soup = BeautifulSoup(html.replace('"formtable width="400','"formtable" width="400"')) #CS html fix #TODO: report the bug to CS dev team 186 soup = BeautifulSoup(html.replace('"formtable width="400', '"formtable" width="400"')) # CS html fix #TODO: report the bug to CS dev team
186 friends = self.data[profile]['friends'] 187 friends = self.data[profile]['friends']
187 for _tr in soup.findAll('tr', {'class':re.compile("^msgRow*")}): #we parse the row with friends infos 188 for _tr in soup.findAll('tr', {'class': re.compile("^msgRow*")}): # we parse the row with friends infos
188 _nobr = _tr.find('nobr') #contain the friend name 189 _nobr = _tr.find('nobr') # contain the friend name
189 friend_name = unicode(_nobr.string) 190 friend_name = unicode(_nobr.string)
190 friend_link = u'http://www.couchsurfing.org'+_nobr.parent['href'] 191 friend_link = u'http://www.couchsurfing.org' + _nobr.parent['href']
191 regex_href = re.compile(r'/connections\.html\?id=([^&]+)') 192 regex_href = re.compile(r'/connections\.html\?id=([^&]+)')
192 a_tag = _tr.find('a',href=regex_href) 193 a_tag = _tr.find('a', href=regex_href)
193 friend_id = regex_href.search(unicode(a_tag)).groups()[0] 194 friend_id = regex_href.search(unicode(a_tag)).groups()[0]
194 195
195 debug(_("CS friend found: %(friend_name)s (id: %(friend_id)s, link: %(friend_link)s)") % {'friend_name':friend_name, 'friend_id':friend_id, 'friend_link':friend_link}) 196 debug(_("CS friend found: %(friend_name)s (id: %(friend_id)s, link: %(friend_link)s)") % {'friend_name': friend_name, 'friend_id': friend_id, 'friend_link': friend_link})
196 friends[friend_name] = {'link':friend_link,'id':friend_id} 197 friends[friend_name] = {'link': friend_link, 'id': friend_id}
197 a = soup.find('td','barmiddle next').a #is there several pages ? 198 a = soup.find('td', 'barmiddle next').a # is there several pages ?
198 if a: 199 if a:
199 #yes, we parse the next page 200 #yes, we parse the next page
200 d = getPage('http://www.couchsurfing.org/'+str(a['href']), agent=AGENT, cookies=self.data[profile]['cookies']) 201 d = getPage('http://www.couchsurfing.org/' + str(a['href']), agent=AGENT, cookies=self.data[profile]['cookies'])
201 d.addCallback(self.__friendsPageCB, id=id, profile=profile) 202 d.addCallback(self.__friendsPageCB, id=id, profile=profile)
202 d.addErrback(self.erroCB, id) 203 d.addErrback(self.erroCB, id)
203 else: 204 else:
204 #no, we show the result 205 #no, we show the result
205 self.host.bridge.actionResult("XMLUI", id, {"type":"window", "xml":self.__buildUI(self.data[profile])}) 206 self.host.bridge.actionResult("XMLUI", id, {"type": "window", "xml": self.__buildUI(self.data[profile])})
206 207
207 def __sendMessage(self, answer, subject, message, data, recipient_list, id, profile): 208 def __sendMessage(self, answer, subject, message, data, recipient_list, id, profile):
208 """Send actually the message 209 """Send actually the message
209 @param subject: subject of the message 210 @param subject: subject of the message
210 @param message: body of the message 211 @param message: body of the message
222 recipient = recipient_list.pop() 223 recipient = recipient_list.pop()
223 try: 224 try:
224 friend_id = data['friends'][recipient]['id'] 225 friend_id = data['friends'][recipient]['id']
225 except KeyError: 226 except KeyError:
226 error('INTERNAL ERROR: unknown friend') 227 error('INTERNAL ERROR: unknown friend')
227 return #send an error to the frontend 228 return # send an error to the frontend
228 mess = message.replace('%name%',recipient).replace('%firstname%',recipient.split(' ')[0]) 229 mess = message.replace('%name%', recipient).replace('%firstname%', recipient.split(' ')[0])
229 info(_('Sending message to %s') % recipient) 230 info(_('Sending message to %s') % recipient)
230 debug(_("\nsubject: %(subject)s\nmessage: \n---\n%(message)s\n---\n\n") % {'subject':subject,'message':mess}) 231 debug(_("\nsubject: %(subject)s\nmessage: \n---\n%(message)s\n---\n\n") % {'subject': subject, 'message': mess})
231 post_data = urllib.urlencode({'email[subject]':subject.encode('utf-8'),'email[body]':mess.encode('utf-8'),'email[id]':friend_id,'email[action]':'Send Message','email[replied_id]':'','email[couchsurf]':'','email[directions_to_add]':''}) 232 post_data = urllib.urlencode({'email[subject]': subject.encode('utf-8'), 'email[body]': mess.encode('utf-8'), 'email[id]': friend_id, 'email[action]': 'Send Message', 'email[replied_id]': '', 'email[couchsurf]': '', 'email[directions_to_add]': ''})
232 d = getPage("http://www.couchsurfing.org/send_message.html", method='POST', postdata=post_data, headers={'Content-Type':'application/x-www-form-urlencoded'} , agent=AGENT, cookies=data['cookies']) 233 d = getPage("http://www.couchsurfing.org/send_message.html", method='POST', postdata=post_data, headers={'Content-Type': 'application/x-www-form-urlencoded'}, agent=AGENT, cookies=data['cookies'])
233 d.addCallback(self.__sendMessage, subject, message, data, recipient_list, id, profile) 234 d.addCallback(self.__sendMessage, subject, message, data, recipient_list, id, profile)
234 d.addErrback(self.erroCB, id) 235 d.addErrback(self.erroCB, id)
235 else: 236 else:
236 interface = XMLUI('window', title=_('Message sent')) #TODO: create particular actionResult for alerts ? 237 interface = XMLUI('window', title=_('Message sent')) # TODO: create particular actionResult for alerts ?
237 interface.addText(_('The message has been sent to every recipients')) 238 interface.addText(_('The message has been sent to every recipients'))
238 self.host.bridge.actionResult("XMLUI", id, {"type":"window", "xml":interface.toXml()}) 239 self.host.bridge.actionResult("XMLUI", id, {"type": "window", "xml": interface.toXml()})
239 240
240 def sendMessage(self, id, data, profile): 241 def sendMessage(self, id, data, profile):
241 """Called to send a message to a friend 242 """Called to send a message to a friend
242 @param data: dict with the following keys: 243 @param data: dict with the following keys:
243 friend: name of the recipient 244 friend: name of the recipient
245 message: body of the message, with the following special keywords: 246 message: body of the message, with the following special keywords:
246 - %name%: name of the friend 247 - %name%: name of the friend
247 - %firstname%: guessed first name of the friend (currently the first part of the name) 248 - %firstname%: guessed first name of the friend (currently the first part of the name)
248 """ 249 """
249 if not data['friends']: 250 if not data['friends']:
250 message_data={"reason": "bad data", "message":_(u"There is not recipient selected for this message !")} 251 message_data = {"reason": "bad data", "message": _(u"There is not recipient selected for this message !")}
251 self.host.bridge.actionResult("ERROR", id, message_data) 252 self.host.bridge.actionResult("ERROR", id, message_data)
252 return 253 return
253 friends = data['friends'].split('\t') 254 friends = data['friends'].split('\t')
254 subject = data['subject'] 255 subject = data['subject']
255 message = data['message'] 256 message = data['message']
256 info(_("sending message to %(friends)s with subject [%(subject)s]" % {'friends':friends, 'subject':subject})) 257 info(_("sending message to %(friends)s with subject [%(subject)s]" % {'friends': friends, 'subject': subject}))
257 self.__sendMessage(None, subject, message, self.data[profile], friends, id, profile) 258 self.__sendMessage(None, subject, message, self.data[profile], friends, id, profile)
258 259
259 def __showUnreadMessages2(self, html, id, profile): 260 def __showUnreadMessages2(self, html, id, profile):
260 """Called when the inbox page has been received""" 261 """Called when the inbox page has been received"""
261 #FIXME: that's really too fragile, only works if the unread messages are in the first page, and it would be too resources consuming for the website to DL each time all pages. In addition, the show attribute doesn't work as expected. 262 #FIXME: that's really too fragile, only works if the unread messages are in the first page, and it would be too resources consuming for the website to DL each time all pages. In addition, the show attribute doesn't work as expected.
262 soup = BeautifulSoup(html) 263 soup = BeautifulSoup(html)
263 for tag in soup.findAll(lambda tag: tag.name=='strong' and tag.a and tag.a['href'].startswith('messages.html?message_status=inbox')): 264 for tag in soup.findAll(lambda tag: tag.name == 'strong' and tag.a and tag.a['href'].startswith('messages.html?message_status=inbox')):
264 link = "http://www.couchsurfing.org/"+str(tag.a['href']) 265 link = "http://www.couchsurfing.org/" + str(tag.a['href'])
265 webbrowser.open_new_tab(link) #TODO: the web browser need to already have CS cookies (i.e. already be opened & logged on CS, or be permanently loggued), a warning to the user should be sent/or a balloon-tip 266 webbrowser.open_new_tab(link) # TODO: the web browser need to already have CS cookies (i.e. already be opened & logged on CS, or be permanently loggued), a warning to the user should be sent/or a balloon-tip
266 267
267 def showUnreadMessages(self, id, data, profile): 268 def showUnreadMessages(self, id, data, profile):
268 """Called when user want to see all unread messages in the external browser""" 269 """Called when user want to see all unread messages in the external browser"""
269 d = getPage("http://www.couchsurfing.org/messages.html?message_status=inbox&show=10000", agent=AGENT, cookies=self.data[profile]['cookies']) 270 d = getPage("http://www.couchsurfing.org/messages.html?message_status=inbox&show=10000", agent=AGENT, cookies=self.data[profile]['cookies'])
270 d.addCallback(self.__showUnreadMessages2, id, profile) 271 d.addCallback(self.__showUnreadMessages2, id, profile)
271 d.addErrback(self.erroCB, id) 272 d.addErrback(self.erroCB, id)
272