ovs: implement ICapContact.get_contact

This commit is contained in:
Vincent A 2013-11-11 15:32:10 +01:00 committed by Florent
commit e3d440d359
4 changed files with 77 additions and 12 deletions

View file

@ -21,6 +21,7 @@ from weboob.tools.backend import BaseBackend, BackendConfig
from weboob.tools.browser import BrowserForbidden
from weboob.tools.value import Value, ValueBackendPassword
from weboob.capabilities.messages import ICapMessages, ICapMessagesPost, Message
from weboob.capabilities.contact import ICapContact
from .browser import OvsBrowser
@ -31,7 +32,7 @@ __all__ = ['OvsBackend']
CITIES = {u'agen': u'Agen', u'ajaccio': u'Ajaccio', u'albi': u'Albi', u'amiens': u'Amiens', u'angers': u'Angers', u'angouleme': u'Angoul\xeame', u'annecy': u'Annecy', u'aurillac': u'Aurillac', u'auxerre': u'Auxerre', u'avignon': u'Avignon', u'bastia': u'Bastia', u'beauvais': u'Beauvais', u'belfort': u'Belfort', u'bergerac': u'Bergerac', u'besancon': u'Besan\xe7on', u'beziers': u'B\xe9ziers', u'biarritz': u'Biarritz', u'blois': u'Blois', u'bordeaux': u'Bordeaux', u'bourg-en-bresse': u'M\xe2con', u'bourges': u'Bourges', u'brest': u'Brest', u'brive-la-gaillarde': u'Brive', u'bruxelles': u'Bruxelles', u'caen': u'Caen', u'calais': u'Boulogne', u'carcassonne': u'Carcassonne', u'chalon-sur-saone': u'Chalon', u'chambery': u'Albertville', u'chantilly': u'Chantilly', u'charleroi': u'Charleroi', u'charleville-mezieres': u'Charleville', u'chartres': u'Chartres', u'chateauroux': u'Ch\xe2teauroux', u'cherbourg': u'Cherbourg', u'cholet': u'Cholet', u'clermont-ferrand': u'Clt-Ferrand', u'compiegne': u'Compi\xe8gne', u'dieppe': u'Dieppe', u'dijon': u'Dijon', u'dunkerque': u'Dunkerque', u'evreux': u'Evreux', u'frejus': u'Fr\xe9jus', u'gap': u'Gap', u'geneve': u'Gen\xe8ve', u'grenoble': u'Grenoble', u'la-roche-sur-yon': u'La Roche/Yon', u'la-rochelle': u'La Rochelle', u'lausanne': u'Lausanne', u'laval': u'Laval', u'le-havre': u'Le Havre', u'le-mans': u'Alen\xe7on', u'liege': u'Li\xe8ge', u'lille': u'Lille', u'limoges': u'Limoges', u'lorient': u'Lorient', u'luxembourg': u'Luxembourg', u'lyon': u'Lyon', u'marseille': u'Aix', u'metz': u'Metz', u'mons': u'Mons', u'mont-de-marsan': u'Mont de Marsan', u'montauban': u'Montauban', u'montlucon': u'Montlu\xe7on', u'montpellier': u'Montpellier', u'mulhouse': u'Colmar', u'namur': u'Namur', u'nancy': u'Nancy', u'nantes': u'Nantes', u'nevers': u'Nevers', u'nice': u'Cannes', u'nimes': u'N\xeemes', u'niort': u'Niort', u'orleans': u'Orl\xe9ans', u'paris': u'PARIS', u'pau': u'Pau', u'perigueux': u'P\xe9rigueux', u'perpignan': u'Perpignan', u'poitiers': u'Poitiers', u'quimper': u'Quimper', u'reims': u'Reims', u'rennes': u'Rennes', u'roanne': u'Roanne', u'rodez': u'Rodez', u'rouen': u'Rouen', u'saint-brieuc': u'St-Brieuc', u'saint-etienne': u'St-Etienne', u'saint-malo': u'St-Malo', u'saint-nazaire': u'St-Nazaire', u'saint-quentin': u'St-Quentin', u'saintes': u'Saintes', u'strasbourg': u'Strasbourg', u'tarbes': u'Tarbes', u'toulon': u'Toulon', u'toulouse': u'Toulouse', u'tours': u'Tours', u'troyes': u'Troyes', u'valence': u'Mont\xe9limar', u'vannes': u'Vannes', u'zurich': u'Zurich'}
class OvsBackend(BaseBackend, ICapMessages, ICapMessagesPost):
class OvsBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapContact):
NAME = 'ovs'
DESCRIPTION = u'OnVaSortir website. Handles private messages only'
MAINTAINER = u'Vincent A'
@ -52,6 +53,7 @@ class OvsBackend(BaseBackend, ICapMessages, ICapMessagesPost):
self.config['password'].get(),
parser='raw')
# ICapMessages
def iter_threads(self):
with self.browser:
for thread in self.browser.iter_threads_list():
@ -85,6 +87,7 @@ class OvsBackend(BaseBackend, ICapMessages, ICapMessagesPost):
self.storage.set('seen', message.full_id, True)
self.storage.save()
# ICapMessagesPost
def post_message(self, message):
if not self.browser.username:
raise BrowserForbidden()
@ -99,6 +102,10 @@ class OvsBackend(BaseBackend, ICapMessages, ICapMessagesPost):
# ovs.<recipient>@*
self.browser.create_thread(thread.id, message.title, message.content)
# ICapContact
def get_contact(self, id):
return self.browser.get_contact(id)
# FIXME known bug: parsing is done in "boosted mode" which is automatically disable after some time, the "boosted mode" should be re-toggled often
# TODO support outing comments, forum messages

View file

@ -63,6 +63,7 @@ class OvsBrowser(BaseBrowser):
kw['parser'] = SoupParser()
BaseBrowser.__init__(self, username, password, *a, **kw)
self.city = city
def iter_threads_list(self):
self.location('/vue_messages_recus.php')
@ -103,6 +104,11 @@ class OvsBrowser(BaseBrowser):
assert self.is_on_page(PageUserProfile)
self.page.create_thread(recipient, subject, body)
def get_contact(self, id):
self.location('/profil_read.php?%s' % id.encode(self.ENCODING)) # FIXME
assert self.is_on_page(PageUserProfile)
return self.page.get_contact()
def get_french_cities(self):
self.location('http://www.onvasortir.com')
assert self.is_on_page(PageCityList)

View file

@ -19,7 +19,6 @@
import BeautifulSoup
import datetime
def nearest_parent(node, expected):
@ -39,15 +38,6 @@ def all_next_siblings(node):
node = node.nextSibling
return ret
def parse_date_from_site(sitedate):
parts = sitedate.split() # [d, m, Y, '-', 'H:M:S']
if len(parts[0]) == 1:
parts[0] = '0%s' % parts[0]
months = {'january': '01', 'february': '02', 'march': '03', 'april': '04', 'may': '05', 'june': '06', 'july': '07', 'august': '08', 'september': '09', 'october': '10', 'november': '11', 'december': '12'}
parts[1] = months[parts[1].lower()]
del parts[3]
return datetime.datetime.strptime(' '.join(parts), '%d %m %Y %H:%M:%S')
def image_to_text(src):
smileys = {'chat/e/grin.gif': ':D',
'chat/e/unsure.gif': ':s',

View file

@ -24,6 +24,8 @@ import urllib
from urlparse import urlsplit
from weboob.tools.browser import BasePage
from weboob.capabilities.messages import Message, Thread
from weboob.capabilities.contact import Contact, ProfileNode
from weboob.tools.date import parse_french_date
import ovsparse
@ -104,7 +106,7 @@ class PagePrivateThread(OvsPage):
# date will be used as id
sitedate = profile_a.findParent('div').find(text=re.compile(',.*')).replace(', ', '')
sysdate = ovsparse.parse_date_from_site(sitedate)
sysdate = parse_french_date(sitedate)
compactdate = datetime.datetime.strftime(sysdate, '%Y%m%dT%H%M%S')
# but make it unique
@ -172,6 +174,66 @@ class PageUserProfile(OvsPage):
#~ self.browser['Message'] = body.encode(self.browser.ENCODING)
#~ self.browser.submit()
def get_contact(self):
profile_a = self.document.find('a', href=re.compile(r'profil_read.php\?.*'))
_id = re.search(r'\?(.*)', profile_a['href']).group(1)
# not available in the 'boosted' version
contact = Contact(_id, _id, Contact.STATUS_OFFLINE)
contact.url = self.url
contact.profile = {}
thumbnail_url = 'http://photos.onvasortir.com/%s/photos/%s_resize.png' % (self.browser.city, _id)
if self.document.find('img', attrs={'src': thumbnail_url}):
photo_url = thumbnail_url.replace('_resize', '')
contact.set_photo('main', thumbnail_url=thumbnail_url, url=photo_url, hidden=False)
location_a = self.document.find('a', href=re.compile(r'vue_profil_carte\.php\?'))
if location_a:
lat = float(re.search(r'Lat=([\d.]+)', location_a['href']).group(1))
self._set_profile(contact, 'latitude', lat)
lng = float(re.search(r'Lng=([\d.]+)', location_a['href']).group(1))
self._set_profile(contact, 'longitude', lng)
div = self.document.find('div', attrs={'class': 'PADtitreBlanc_txt'}, text=re.compile('Personal Info'))
td = div.findParent('tr').findNextSibling('tr').td
infos_text = td.getText(separator='\n').strip()
it = iter(infos_text.split('\n'))
infos = dict(zip(it, it))
if infos['Sex :'] == 'Man':
self._set_profile(contact, 'sex', 'M')
elif infos['Sex :'] == 'Woman':
self._set_profile(contact, 'sex', 'F')
if infos['Birthday :'] != 'Unknown':
self._set_profile(contact, 'birthday', parse_french_date(re.search(r'(\d+ \w+ \d+)', infos['Birthday :']).group(1)))
self._try_attr(contact, infos, 'First Name :', 'first_name')
self._try_attr(contact, infos, 'Status :', 'marriage')
self._try_attr(contact, infos, 'Area :', 'area')
div = self.document.find('div', attrs={'class': 'PADtitreBlanc_txt'}, text=re.compile('A few words'))
td = div.findParent('tr').findNextSibling('tr').td
summary = td.getText(separator='\n').strip()
if summary == 'Unknown':
contact.summary = u''
else:
contact.summary = summary
div = self.document.find('div', style=re.compile('dashed'))
if div:
# TODO handle html, links and smileys
contact.status_msg = div.getText()
else:
contact.status_msg = u''
return contact
def _set_profile(self, contact, key, value):
contact.profile[key] = ProfileNode(key, key.capitalize(), value)
def _try_attr(self, contact, infos, html_attr, obj_attr):
if infos[html_attr] != 'Unknown':
self._set_profile(contact, obj_attr, infos[html_attr].strip())
class PageCityList(DummyPage):
def get_cities(self, master_domain='onvasortir.com'):