[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.base import NotLoaded
|
||||||
from weboob.capabilities.messages import ICapMessages, ICapMessagesPost, Message, Thread
|
from weboob.capabilities.messages import ICapMessages, ICapMessagesPost, Message, Thread
|
||||||
#from weboob.capabilities.dating import ICapDating, OptimizationNotFound, Event
|
#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.backend import BaseBackend, BackendConfig
|
||||||
from weboob.tools.browser import BrowserUnavailable
|
from weboob.tools.browser import BrowserUnavailable
|
||||||
from weboob.tools.value import Value, ValuesDict, ValueBool, ValueBackendPassword
|
from weboob.tools.value import Value, ValuesDict, ValueBool, ValueBackendPassword
|
||||||
from weboob.tools.log import getLogger
|
from weboob.tools.log import getLogger
|
||||||
from weboob.tools.misc import local2utc
|
from weboob.tools.misc import local2utc
|
||||||
|
|
||||||
#from .contact import Contact
|
|
||||||
from .browser import OkCBrowser
|
from .browser import OkCBrowser
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -63,7 +62,7 @@ def parse_dt(s):
|
||||||
d = _parse_dt(s)
|
d = _parse_dt(s)
|
||||||
return local2utc(d)
|
return local2utc(d)
|
||||||
|
|
||||||
class OkCBackend(BaseBackend, ICapMessages):
|
class OkCBackend(BaseBackend, ICapMessages, ICapContact):
|
||||||
#, ICapMessagesPost, ICapContact):
|
#, ICapMessagesPost, ICapContact):
|
||||||
NAME = 'okc'
|
NAME = 'okc'
|
||||||
MAINTAINER = 'Roger Philibert'
|
MAINTAINER = 'Roger Philibert'
|
||||||
|
|
@ -133,9 +132,6 @@ class OkCBackend(BaseBackend, ICapMessages):
|
||||||
if not thread.title:
|
if not thread.title:
|
||||||
thread.title = u'Discussion with %s' % mails['member']['pseudo']
|
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']:
|
for mail in mails['messages']:
|
||||||
flags = Message.IS_HTML
|
flags = Message.IS_HTML
|
||||||
if parse_dt(mail['date']) > slut['lastmsg'] and mail['id_from'] != self.browser.get_my_name():
|
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 ---------------------
|
# ---- ICapContact methods ---------------------
|
||||||
|
|
||||||
#def fill_contact(self, contact, fields):
|
def fill_contact(self, contact, fields):
|
||||||
# if 'profile' in fields:
|
if 'profile' in fields:
|
||||||
# contact = self.get_contact(contact)
|
contact = self.get_contact(contact)
|
||||||
# if contact and 'photos' in fields:
|
if contact and 'photos' in fields:
|
||||||
# for name, photo in contact.photos.iteritems():
|
for name, photo in contact.photos.iteritems():
|
||||||
# with self.browser:
|
with self.browser:
|
||||||
# if photo.url and not photo.data:
|
if photo.url and not photo.data:
|
||||||
# data = self.browser.openurl(photo.url).read()
|
data = self.browser.openurl(photo.url).read()
|
||||||
# contact.set_photo(name, data=data)
|
contact.set_photo(name, data=data)
|
||||||
# if photo.thumbnail_url and not photo.thumbnail_data:
|
if photo.thumbnail_url and not photo.thumbnail_data:
|
||||||
# data = self.browser.openurl(photo.thumbnail_url).read()
|
data = self.browser.openurl(photo.thumbnail_url).read()
|
||||||
# contact.set_photo(name, thumbnail_data=data)
|
contact.set_photo(name, thumbnail_data=data)
|
||||||
|
|
||||||
#def fill_photo(self, photo, fields):
|
#def fill_photo(self, photo, fields):
|
||||||
# with self.browser:
|
# with self.browser:
|
||||||
|
|
@ -254,29 +250,37 @@ class OkCBackend(BaseBackend, ICapMessages):
|
||||||
# photo.thumbnail_data = self.browser.readurl(photo.thumbnail_url)
|
# photo.thumbnail_data = self.browser.readurl(photo.thumbnail_url)
|
||||||
# return photo
|
# return photo
|
||||||
|
|
||||||
#def get_contact(self, contact):
|
def get_contact(self, contact):
|
||||||
# with self.browser:
|
with self.browser:
|
||||||
# if isinstance(contact, Contact):
|
if isinstance(contact, Contact):
|
||||||
# _id = contact.id
|
_id = contact.id
|
||||||
# elif isinstance(contact, (int,long,basestring)):
|
elif isinstance(contact, (int,long,basestring)):
|
||||||
# _id = contact
|
_id = contact
|
||||||
# else:
|
else:
|
||||||
# raise TypeError("The parameter 'contact' isn't a contact nor a int/long/str/unicode: %s" % contact)
|
raise TypeError("The parameter 'contact' isn't a contact nor a int/long/str/unicode: %s" % contact)
|
||||||
|
|
||||||
# profile = self.browser.get_profile(_id)
|
profile = self.browser.get_profile(_id)
|
||||||
# if not profile:
|
if not profile:
|
||||||
# return None
|
return None
|
||||||
|
|
||||||
# _id = profile['id']
|
_id = profile['id']
|
||||||
|
|
||||||
# if isinstance(contact, Contact):
|
if isinstance(contact, Contact):
|
||||||
# contact.id = _id
|
contact.id = _id
|
||||||
# contact.name = profile['pseudo']
|
contact.name = profile['id']
|
||||||
# else:
|
else:
|
||||||
# contact = Contact(_id, profile['pseudo'], Contact.STATUS_ONLINE)
|
contact = Contact(_id, profile['id'], Contact.STATUS_OFFLINE)
|
||||||
# contact.url = self.browser.id2url(_id)
|
contact.url = 'http://%s/profile/%s' % (self.browser.DOMAIN, _id)
|
||||||
# contact.parse_profile(profile, self.browser.get_consts())
|
contact.profile = profile['data']
|
||||||
# return contact
|
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):
|
#def _get_partial_contact(self, contact):
|
||||||
# if contact.get('isBan', contact.get('dead', False)):
|
# if contact.get('isBan', contact.get('dead', False)):
|
||||||
|
|
@ -290,7 +294,7 @@ class OkCBackend(BaseBackend, ICapMessages):
|
||||||
# else:
|
# else:
|
||||||
# s = Contact.STATUS_OFFLINE
|
# 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'])
|
# c.url = self.browser.id2url(contact['id'])
|
||||||
# if 'birthday' in contact:
|
# if 'birthday' in contact:
|
||||||
# birthday = _parse_dt(contact['birthday'])
|
# birthday = _parse_dt(contact['birthday'])
|
||||||
|
|
@ -306,14 +310,14 @@ class OkCBackend(BaseBackend, ICapMessages):
|
||||||
# thumbnail_url=url % {'type': 'thumb0_'})
|
# thumbnail_url=url % {'type': 'thumb0_'})
|
||||||
# return c
|
# return c
|
||||||
|
|
||||||
#def iter_contacts(self, status=Contact.STATUS_ALL, ids=None):
|
def iter_contacts(self, status=Contact.STATUS_ALL, ids=None):
|
||||||
# with self.browser:
|
with self.browser:
|
||||||
# threads = self.browser.get_threads_list(count=100)
|
threads = self.browser.get_threads_list(count=100)
|
||||||
|
|
||||||
# for thread in threads:
|
for thread in threads:
|
||||||
# c = self._get_partial_contact(thread['member'])
|
c = self._get_partial_contact(thread['member'])
|
||||||
# if c and (c.status & status) and (not ids or c.id in ids):
|
if c and (c.status & status) and (not ids or c.id in ids):
|
||||||
# yield c
|
yield c
|
||||||
|
|
||||||
#def send_query(self, id):
|
#def send_query(self, id):
|
||||||
# if isinstance(id, Contact):
|
# if isinstance(id, Contact):
|
||||||
|
|
@ -350,6 +354,6 @@ class OkCBackend(BaseBackend, ICapMessages):
|
||||||
# self.storage.save()
|
# self.storage.save()
|
||||||
|
|
||||||
OBJECTS = {Thread: fill_thread,
|
OBJECTS = {Thread: fill_thread,
|
||||||
#Contact: fill_contact,
|
Contact: fill_contact,
|
||||||
#ContactPhoto: fill_photo
|
#ContactPhoto: fill_photo
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ except ImportError:
|
||||||
from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword, BrowserUnavailable
|
from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword, BrowserUnavailable
|
||||||
from weboob.tools.ordereddict import OrderedDict
|
from weboob.tools.ordereddict import OrderedDict
|
||||||
|
|
||||||
from .pages import LoginPage, ThreadPage, MessagesPage
|
from .pages import LoginPage, ThreadPage, MessagesPage, ProfilePage
|
||||||
|
|
||||||
__all__ = ['OkCBrowser']
|
__all__ = ['OkCBrowser']
|
||||||
|
|
||||||
|
|
@ -48,6 +48,7 @@ class OkCBrowser(BaseBrowser):
|
||||||
('https://%s/login.*' % DOMAIN, LoginPage),
|
('https://%s/login.*' % DOMAIN, LoginPage),
|
||||||
('http://%s/messages' % DOMAIN, ThreadPage),
|
('http://%s/messages' % DOMAIN, ThreadPage),
|
||||||
('http://%s/messages\?.*' % DOMAIN, MessagesPage),
|
('http://%s/messages\?.*' % DOMAIN, MessagesPage),
|
||||||
|
('http://%s/profile/.*' % DOMAIN, ProfilePage),
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -71,7 +72,8 @@ class OkCBrowser(BaseBrowser):
|
||||||
return func(self, *args, **kwargs)
|
return func(self, *args, **kwargs)
|
||||||
return inner
|
return inner
|
||||||
|
|
||||||
#def get_consts(self):
|
def get_consts(self):
|
||||||
|
return { 'conts' : 'blah' }
|
||||||
# if self.consts is not None:
|
# if self.consts is not None:
|
||||||
# return self.consts
|
# return self.consts
|
||||||
|
|
||||||
|
|
@ -197,39 +199,10 @@ class OkCBrowser(BaseBrowser):
|
||||||
# ids = [s['id'] for s in r['result']['search']]
|
# ids = [s['id'] for s in r['result']['search']]
|
||||||
# return set(ids)
|
# return set(ids)
|
||||||
|
|
||||||
#@url2id
|
@check_login
|
||||||
#def get_profile(self, id, with_pics=True):
|
def get_profile(self, id, with_pics=True):
|
||||||
# r = self.api_request('member', 'view', data={'id': id})
|
self.location(self.absurl('/profile/%s' % id))
|
||||||
# if not 'result' in r:
|
return self.page.get_profile()
|
||||||
# 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
|
|
||||||
|
|
||||||
#def _get_chat_infos(self):
|
#def _get_chat_infos(self):
|
||||||
# try:
|
# try:
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,9 @@
|
||||||
|
|
||||||
|
|
||||||
from weboob.tools.browser import BasePage, BrokenPageError
|
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):
|
class LoginPage(BasePage):
|
||||||
def login(self, username, password):
|
def login(self, username, password):
|
||||||
|
|
@ -64,3 +67,65 @@ class MessagesPage(BasePage):
|
||||||
})
|
})
|
||||||
|
|
||||||
return mails
|
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