[okc] Contact support
This commit is contained in:
parent
bf17245f90
commit
72fd993b3c
3 changed files with 127 additions and 85 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue