[okc] Contact support

This commit is contained in:
Roger Philibert 2012-03-17 20:13:56 +01:00 committed by Romain Bignon
commit 72fd993b3c
3 changed files with 127 additions and 85 deletions

View file

@ -30,14 +30,13 @@ from dateutil.parser import parse as _parse_dt
from weboob.capabilities.base import NotLoaded
from weboob.capabilities.messages import ICapMessages, ICapMessagesPost, Message, Thread
#from weboob.capabilities.dating import ICapDating, OptimizationNotFound, Event
#from weboob.capabilities.contact import ICapContact, ContactPhoto, Query, QueryError
from weboob.capabilities.contact import ICapContact, ContactPhoto, Query, QueryError
from weboob.tools.backend import BaseBackend, BackendConfig
from weboob.tools.browser import BrowserUnavailable
from weboob.tools.value import Value, ValuesDict, ValueBool, ValueBackendPassword
from weboob.tools.log import getLogger
from weboob.tools.misc import local2utc
#from .contact import Contact
from .browser import OkCBrowser
@ -63,7 +62,7 @@ def parse_dt(s):
d = _parse_dt(s)
return local2utc(d)
class OkCBackend(BaseBackend, ICapMessages):
class OkCBackend(BaseBackend, ICapMessages, ICapContact):
#, ICapMessagesPost, ICapContact):
NAME = 'okc'
MAINTAINER = 'Roger Philibert'
@ -133,9 +132,6 @@ class OkCBackend(BaseBackend, ICapMessages):
if not thread.title:
thread.title = u'Discussion with %s' % mails['member']['pseudo']
#self.storage.set('sluts', thread.id, 'status', mails['status'])
#self.storage.save()
for mail in mails['messages']:
flags = Message.IS_HTML
if parse_dt(mail['date']) > slut['lastmsg'] and mail['id_from'] != self.browser.get_my_name():
@ -233,18 +229,18 @@ class OkCBackend(BaseBackend, ICapMessages):
# ---- ICapContact methods ---------------------
#def fill_contact(self, contact, fields):
# if 'profile' in fields:
# contact = self.get_contact(contact)
# if contact and 'photos' in fields:
# for name, photo in contact.photos.iteritems():
# with self.browser:
# if photo.url and not photo.data:
# data = self.browser.openurl(photo.url).read()
# contact.set_photo(name, data=data)
# if photo.thumbnail_url and not photo.thumbnail_data:
# data = self.browser.openurl(photo.thumbnail_url).read()
# contact.set_photo(name, thumbnail_data=data)
def fill_contact(self, contact, fields):
if 'profile' in fields:
contact = self.get_contact(contact)
if contact and 'photos' in fields:
for name, photo in contact.photos.iteritems():
with self.browser:
if photo.url and not photo.data:
data = self.browser.openurl(photo.url).read()
contact.set_photo(name, data=data)
if photo.thumbnail_url and not photo.thumbnail_data:
data = self.browser.openurl(photo.thumbnail_url).read()
contact.set_photo(name, thumbnail_data=data)
#def fill_photo(self, photo, fields):
# with self.browser:
@ -254,29 +250,37 @@ class OkCBackend(BaseBackend, ICapMessages):
# photo.thumbnail_data = self.browser.readurl(photo.thumbnail_url)
# return photo
#def get_contact(self, contact):
# with self.browser:
# if isinstance(contact, Contact):
# _id = contact.id
# elif isinstance(contact, (int,long,basestring)):
# _id = contact
# else:
# raise TypeError("The parameter 'contact' isn't a contact nor a int/long/str/unicode: %s" % contact)
def get_contact(self, contact):
with self.browser:
if isinstance(contact, Contact):
_id = contact.id
elif isinstance(contact, (int,long,basestring)):
_id = contact
else:
raise TypeError("The parameter 'contact' isn't a contact nor a int/long/str/unicode: %s" % contact)
# profile = self.browser.get_profile(_id)
# if not profile:
# return None
profile = self.browser.get_profile(_id)
if not profile:
return None
# _id = profile['id']
_id = profile['id']
# if isinstance(contact, Contact):
# contact.id = _id
# contact.name = profile['pseudo']
# else:
# contact = Contact(_id, profile['pseudo'], Contact.STATUS_ONLINE)
# contact.url = self.browser.id2url(_id)
# contact.parse_profile(profile, self.browser.get_consts())
# return contact
if isinstance(contact, Contact):
contact.id = _id
contact.name = profile['id']
else:
contact = Contact(_id, profile['id'], Contact.STATUS_OFFLINE)
contact.url = 'http://%s/profile/%s' % (self.browser.DOMAIN, _id)
contact.profile = profile['data']
contact.summary = profile['summary']
if contact.profile['details']['last_online'].value == 'Online now!':
contact.status = Contact.STATUS_ONLINE
else:
contact.status = Contact.STATUS_OFFLINE
contact.status_msg = contact.profile['details']['last_online'].value
return contact
#def _get_partial_contact(self, contact):
# if contact.get('isBan', contact.get('dead', False)):
@ -290,7 +294,7 @@ class OkCBackend(BaseBackend, ICapMessages):
# else:
# s = Contact.STATUS_OFFLINE
# c = Contact(contact['id'], contact['pseudo'], s)
# c = Contact(contact['id'], contact['id'], s)
# c.url = self.browser.id2url(contact['id'])
# if 'birthday' in contact:
# birthday = _parse_dt(contact['birthday'])
@ -306,14 +310,14 @@ class OkCBackend(BaseBackend, ICapMessages):
# thumbnail_url=url % {'type': 'thumb0_'})
# return c
#def iter_contacts(self, status=Contact.STATUS_ALL, ids=None):
# with self.browser:
# threads = self.browser.get_threads_list(count=100)
def iter_contacts(self, status=Contact.STATUS_ALL, ids=None):
with self.browser:
threads = self.browser.get_threads_list(count=100)
# for thread in threads:
# c = self._get_partial_contact(thread['member'])
# if c and (c.status & status) and (not ids or c.id in ids):
# yield c
for thread in threads:
c = self._get_partial_contact(thread['member'])
if c and (c.status & status) and (not ids or c.id in ids):
yield c
#def send_query(self, id):
# if isinstance(id, Contact):
@ -350,6 +354,6 @@ class OkCBackend(BaseBackend, ICapMessages):
# self.storage.save()
OBJECTS = {Thread: fill_thread,
#Contact: fill_contact,
Contact: fill_contact,
#ContactPhoto: fill_photo
}

View file

@ -32,7 +32,7 @@ except ImportError:
from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword, BrowserUnavailable
from weboob.tools.ordereddict import OrderedDict
from .pages import LoginPage, ThreadPage, MessagesPage
from .pages import LoginPage, ThreadPage, MessagesPage, ProfilePage
__all__ = ['OkCBrowser']
@ -48,6 +48,7 @@ class OkCBrowser(BaseBrowser):
('https://%s/login.*' % DOMAIN, LoginPage),
('http://%s/messages' % DOMAIN, ThreadPage),
('http://%s/messages\?.*' % DOMAIN, MessagesPage),
('http://%s/profile/.*' % DOMAIN, ProfilePage),
))
@ -71,7 +72,8 @@ class OkCBrowser(BaseBrowser):
return func(self, *args, **kwargs)
return inner
#def get_consts(self):
def get_consts(self):
return { 'conts' : 'blah' }
# if self.consts is not None:
# return self.consts
@ -197,39 +199,10 @@ class OkCBrowser(BaseBrowser):
# ids = [s['id'] for s in r['result']['search']]
# return set(ids)
#@url2id
#def get_profile(self, id, with_pics=True):
# r = self.api_request('member', 'view', data={'id': id})
# if not 'result' in r:
# print r
# profile = r['result']['member']
# # Calculate distance in km.
# profile['dist'] = 0.0
# if 'lat' in profile and 'lng' in profile:
# coords = (float(profile['lat']), float(profile['lng']))
# R = 6371
# lat1 = math.radians(self.my_coords[0])
# lat2 = math.radians(coords[0])
# lon1 = math.radians(self.my_coords[1])
# lon2 = math.radians(coords[1])
# dLat = lat2 - lat1
# dLong = lon2 - lon1
# a= pow(math.sin(dLat/2), 2) + math.cos(lat1) * math.cos(lat2) * pow(math.sin(dLong/2), 2)
# c= 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
# profile['dist'] = R * c
# if with_pics:
# r = self.api_request('member', 'pictures', data={'id': id})
# profile['pictures'] = []
# for pic in r['result']['pictures']:
# d = {'hidden': False}
# d.update(pic)
# profile['pictures'].append(d)
# return profile
@check_login
def get_profile(self, id, with_pics=True):
self.location(self.absurl('/profile/%s' % id))
return self.page.get_profile()
#def _get_chat_infos(self):
# try:

View file

@ -19,6 +19,9 @@
from weboob.tools.browser import BasePage, BrokenPageError
from weboob.tools.ordereddict import OrderedDict
from weboob.tools.misc import html2text
from weboob.capabilities.contact import ProfileNode
class LoginPage(BasePage):
def login(self, username, password):
@ -64,3 +67,65 @@ class MessagesPage(BasePage):
})
return mails
class ProfilePage(BasePage):
def get_profile(self):
title = self.parser.select(self.document.getroot(), 'title', 1)
if title.text == 'OkCupid: Account Not Found':
return None
profile = {}
profile['id'] = title.text[len('OkCupid: '):]
profile['data'] = OrderedDict()
profile_p = self.parser.select(self.document.getroot(), "//div[@id='page_content']//p", method='xpath')
profile['data']['infos'] = ProfileNode('infos', 'Informations', OrderedDict(), flags=ProfileNode.SECTION)
info = {
'age' : profile_p[1].text.split(' / ')[0],
'sex' : profile_p[1].text.split(' / ')[1],
'orientation' : profile_p[1].text.split(' / ')[2],
'relationship' : profile_p[1].text.split(' / ')[3],
}
for key, val in info.iteritems():
profile['data']['infos'].value[key] = ProfileNode(key, key.capitalize(), val)
div_essays = self.parser.select(self.document.getroot(), "//div[@class='essay']", method='xpath')
h3_essays = self.parser.select(self.document.getroot(), "//div[@id='page_content']//h3", method='xpath')
essays = dict(zip(h3_essays, div_essays))
profile['summary'] = div_essays[0].text.strip()
profile['data']['essays'] = ProfileNode('essays', 'Essays', OrderedDict(), flags=ProfileNode.SECTION)
for label, val in essays.iteritems():
label = unicode(label.text).strip()
val = unicode(val.text).strip()
key = label.replace(' ', '_')
profile['data']['essays'].value[key] = ProfileNode(key, label, val)
#profile['data']['look_for'].value['orientation'] = ProfileNode('orientation', 'Orientation', div_essays[9].getchildren()[0].getchildren()[0].text.strip())
#profile['data']['look_for'].value['location'] = ProfileNode('location', 'Location', div_essays[9].getchildren()[0].getchildren()[2].text.strip())
#profile['data']['look_for'].value['relationship'] = ProfileNode('relationship', 'Relationship', div_essays[9].getchildren()[0].getchildren()[3].text.strip())
#profile['data']['look_for'].value['what_for'] = ProfileNode('what_for', 'What for', div_essays[9].getchildren()[0].getchildren()[4].text.split('\n')[1].strip().split(', '))
#age = div_essays[9].getchildren()[0].getchildren()[1].text[5:].strip().split(u'')
#profile['data']['look_for'].value['age_min'] = ProfileNode('age_min', 'Age min', int(age[0]))
#profile['data']['look_for'].value['age_max'] = ProfileNode('age_max', 'Age max', int(age[1]))
#div_essays = div_essays[1:-1]
#h3_essays = h3_essays[1:-1]
#for i, title in enumerate(h3_essays):
# profile['data']['essays'].value['essay_%i' % i] = ProfileNode('essay_%i' % i, title.text, div_essays[i].text.strip())
details_div = self.parser.select(self.document.getroot(), "//div[@id='details']//li", method='xpath')
profile['data']['details'] = ProfileNode('details', 'Details', OrderedDict(), flags=ProfileNode.SECTION)
for elem in details_div:
label = elem.getchildren()[0].text.strip()
key = label.lower().replace(' ', '_')
val = elem.getchildren()[1].text.strip()
profile['data']['details'].value[key] = ProfileNode(key, label, val)
return profile