support new API (closes #871,#900,#902)
This commit is contained in:
parent
3e21a76119
commit
c383960729
5 changed files with 205 additions and 333 deletions
|
|
@ -30,7 +30,7 @@ class AntiSpam(object):
|
|||
# Check if there is an email address in the offer.
|
||||
if re.match('^[\w\d\.\-_]+@[\w\d\.]+ vous offre la pos', resume):
|
||||
return False
|
||||
if thread['member']['pseudo'] == 'Ekaterina':
|
||||
if thread['who']['pseudo'] == 'Ekaterina':
|
||||
return False
|
||||
|
||||
return True
|
||||
|
|
@ -39,13 +39,13 @@ class AntiSpam(object):
|
|||
# The name of profile is in form #123456789
|
||||
if profile['pseudo'] == '':
|
||||
return False
|
||||
if profile['about1'].startswith('salut! je te donne mon msn'):
|
||||
if profile['announce'].startswith('salut! je te donne mon msn'):
|
||||
return False
|
||||
if profile['about2'].startswith('cam to cam'):
|
||||
if profile['shopping_list'].startswith('cam to cam'):
|
||||
return False
|
||||
if profile['about2'].startswith('je suis une femme tres tres belle et je recherche un homme qui aime le sexe'):
|
||||
if profile['shopping_list'].startswith('je suis une femme tres tres belle et je recherche un homme qui aime le sexe'):
|
||||
return False
|
||||
if profile['about2'].endswith('mmmmmmmmmmmmmmmm'):
|
||||
if profile['shopping_list'].endswith('mmmmmmmmmmmmmmmm'):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,8 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
|
|||
CONFIG = BackendConfig(Value('username', label='Username'),
|
||||
ValueBackendPassword('password', label='Password'),
|
||||
ValueBool('antispam', label='Enable anti-spam', default=False),
|
||||
ValueBool('baskets', label='Get baskets with new messages', default=True))
|
||||
ValueBool('baskets', label='Get baskets with new messages', default=True),
|
||||
Value('search_query', label='Search query', default=''))
|
||||
STORAGE = {'profiles_walker': {'viewed': []},
|
||||
'queries_queue': {'queue': []},
|
||||
'sluts': {},
|
||||
|
|
@ -83,11 +84,14 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
|
|||
self.antispam = None
|
||||
|
||||
def create_default_browser(self):
|
||||
return self.create_browser(self.config['username'].get(), self.config['password'].get())
|
||||
return self.create_browser(self.config['username'].get(),
|
||||
self.config['password'].get(),
|
||||
self.config['search_query'].get())
|
||||
|
||||
def report_spam(self, id):
|
||||
with self.browser:
|
||||
self.browser.delete_thread(id)
|
||||
pass
|
||||
#self.browser.delete_thread(id)
|
||||
# Do not report fakes to website, to let them to other guys :)
|
||||
#self.browser.report_fake(id)
|
||||
|
||||
|
|
@ -106,15 +110,12 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
|
|||
all_events[u'visits'] = (self.browser.get_visits, 'Visited by %s')
|
||||
for type, (events, message) in all_events.iteritems():
|
||||
for event in events():
|
||||
try:
|
||||
e = Event(event['%sid' % type[0]])
|
||||
except KeyError:
|
||||
e = Event(event['id'])
|
||||
e = Event(event['who']['id'])
|
||||
|
||||
e.date = parse_dt(event['date'])
|
||||
e.type = type
|
||||
if 'member' in event:
|
||||
e.contact = self._get_partial_contact(event['member'])
|
||||
if 'who' in event:
|
||||
e.contact = self._get_partial_contact(event['who'])
|
||||
else:
|
||||
e.contact = self._get_partial_contact(event)
|
||||
|
||||
|
|
@ -134,17 +135,17 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
|
|||
threads = self.browser.get_threads_list()
|
||||
|
||||
for thread in threads:
|
||||
if thread['member'].get('isBan', thread['member'].get('dead', False)):
|
||||
with self.browser:
|
||||
self.browser.delete_thread(thread['member']['id'])
|
||||
continue
|
||||
#if thread['member'].get('isBan', thread['member'].get('dead', False)):
|
||||
# with self.browser:
|
||||
# self.browser.delete_thread(thread['member']['id'])
|
||||
# continue
|
||||
if self.antispam and not self.antispam.check_thread(thread):
|
||||
self.logger.info('Skipped a spam-thread from %s' % thread['pseudo'])
|
||||
self.report_spam(thread['member']['id'])
|
||||
self.report_spam(thread['who']['id'])
|
||||
continue
|
||||
t = Thread(int(thread['member']['id']))
|
||||
t = Thread(int(thread['who']['id']))
|
||||
t.flags = Thread.IS_DISCUSSION
|
||||
t.title = u'Discussion with %s' % to_unicode(thread['member']['pseudo'])
|
||||
t.title = u'Discussion with %s' % to_unicode(thread['who']['pseudo'])
|
||||
yield t
|
||||
|
||||
def get_thread(self, id, contacts=None, get_profiles=False):
|
||||
|
|
@ -176,15 +177,15 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
|
|||
contacts = {}
|
||||
|
||||
if not thread.title:
|
||||
thread.title = u'Discussion with %s' % mails['member']['pseudo']
|
||||
thread.title = u'Discussion with %s' % mails['who']['pseudo']
|
||||
|
||||
self.storage.set('sluts', int(thread.id), 'status', mails['status'])
|
||||
self.storage.save()
|
||||
|
||||
for mail in mails['messages']:
|
||||
for mail in mails['results']:
|
||||
flags = 0
|
||||
if self.antispam and not self.antispam.check_mail(mail):
|
||||
self.logger.info('Skipped a spam-mail from %s' % mails['member']['pseudo'])
|
||||
self.logger.info('Skipped a spam-mail from %s' % mails['who']['pseudo'])
|
||||
self.report_spam(thread.id)
|
||||
break
|
||||
|
||||
|
|
@ -192,31 +193,31 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
|
|||
flags |= Message.IS_UNREAD
|
||||
|
||||
if get_profiles:
|
||||
if not mail['id_from'] in contacts:
|
||||
if not mail['from'] in contacts:
|
||||
with self.browser:
|
||||
contacts[mail['id_from']] = self.get_contact(mail['id_from'])
|
||||
if self.antispam and not self.antispam.check_contact(contacts[mail['id_from']]):
|
||||
self.logger.info('Skipped a spam-mail-profile from %s' % mails['member']['pseudo'])
|
||||
contacts[mail['from']] = self.get_contact(mail['from'])
|
||||
if self.antispam and not self.antispam.check_contact(contacts[mail['from']]):
|
||||
self.logger.info('Skipped a spam-mail-profile from %s' % mails['who']['pseudo'])
|
||||
self.report_spam(thread.id)
|
||||
break
|
||||
|
||||
if int(mail['id_from']) == self.browser.my_id:
|
||||
if int(mails['remoteStatus']) == 0 and msg is None:
|
||||
if int(mail['from']) == self.browser.my_id:
|
||||
if mails['remote_status'] == 'new' and msg is None:
|
||||
flags |= Message.IS_NOT_RECEIVED
|
||||
else:
|
||||
flags |= Message.IS_RECEIVED
|
||||
|
||||
signature = u''
|
||||
if mail.get('src', None):
|
||||
signature += u'Sent from my %s\n\n' % mail['src']
|
||||
if mail['id_from'] in contacts:
|
||||
signature += contacts[mail['id_from']].get_text()
|
||||
#if mail.get('src', None):
|
||||
# signature += u'Sent from my %s\n\n' % mail['src']
|
||||
if mail['from'] in contacts:
|
||||
signature += contacts[mail['from']].get_text()
|
||||
|
||||
msg = Message(thread=thread,
|
||||
id=int(time.strftime('%Y%m%d%H%M%S', parse_dt(mail['date']).timetuple())),
|
||||
title=thread.title,
|
||||
sender=to_unicode(my_name if int(mail['id_from']) == self.browser.my_id else mails['member']['pseudo']),
|
||||
receivers=[to_unicode(my_name if int(mail['id_from']) != self.browser.my_id else mails['member']['pseudo'])],
|
||||
sender=to_unicode(my_name if int(mail['from']) == self.browser.my_id else mails['who']['pseudo']),
|
||||
receivers=[to_unicode(my_name if int(mail['from']) != self.browser.my_id else mails['who']['pseudo'])],
|
||||
date=parse_dt(mail['date']),
|
||||
content=to_unicode(unescape(mail['message'] or '').strip()),
|
||||
signature=signature,
|
||||
|
|
@ -246,17 +247,17 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
|
|||
with self.browser:
|
||||
threads = self.browser.get_threads_list()
|
||||
for thread in threads:
|
||||
if thread['member'].get('isBan', thread['member'].get('dead', False)):
|
||||
with self.browser:
|
||||
self.browser.delete_thread(int(thread['member']['id']))
|
||||
continue
|
||||
#if thread['member'].get('isBan', thread['member'].get('dead', False)):
|
||||
# with self.browser:
|
||||
# self.browser.delete_thread(int(thread['member']['id']))
|
||||
# continue
|
||||
if self.antispam and not self.antispam.check_thread(thread):
|
||||
self.logger.info('Skipped a spam-unread-thread from %s' % thread['member']['pseudo'])
|
||||
self.logger.info('Skipped a spam-unread-thread from %s' % thread['who']['pseudo'])
|
||||
self.report_spam(thread['member']['id'])
|
||||
continue
|
||||
slut = self._get_slut(thread['member']['id'])
|
||||
if parse_dt(thread['date']) > slut['lastmsg'] or int(thread['status']) != int(slut['status']):
|
||||
t = self.get_thread(thread['member']['id'], contacts, get_profiles=True)
|
||||
slut = self._get_slut(thread['who']['id'])
|
||||
if parse_dt(thread['date']) > slut['lastmsg'] or thread['status'] != slut['status']:
|
||||
t = self.get_thread(thread['who']['id'], contacts, get_profiles=True)
|
||||
for m in t.iter_all_messages():
|
||||
if m.flags & m.IS_UNREAD:
|
||||
yield m
|
||||
|
|
@ -275,7 +276,7 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
|
|||
baskets = self.browser.get_baskets()
|
||||
my_name = self.browser.get_my_name()
|
||||
for basket in baskets:
|
||||
if basket['isBan'] or parse_dt(basket['date']) <= slut['lastmsg']:
|
||||
if parse_dt(basket['date']) <= slut['lastmsg']:
|
||||
continue
|
||||
contact = self.get_contact(basket['id'])
|
||||
if self.antispam and not self.antispam.check_contact(contact):
|
||||
|
|
@ -321,12 +322,12 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
|
|||
sluts = self.storage.get('sluts')
|
||||
if not sluts or not id in sluts:
|
||||
slut = {'lastmsg': datetime.datetime(1970,1,1),
|
||||
'status': 0}
|
||||
'status': None}
|
||||
else:
|
||||
slut = self.storage.get('sluts', id)
|
||||
|
||||
slut['lastmsg'] = slut.get('lastmsg', datetime.datetime(1970,1,1)).replace(tzinfo=tz.tzutc())
|
||||
slut['status'] = int(slut.get('status', 0))
|
||||
slut['status'] = slut.get('status', None)
|
||||
return slut
|
||||
|
||||
# ---- ICapMessagesPost methods ---------------------
|
||||
|
|
@ -383,31 +384,24 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
|
|||
return contact
|
||||
|
||||
def _get_partial_contact(self, contact):
|
||||
if contact.get('isBan', contact.get('dead', False)):
|
||||
with self.browser:
|
||||
self.browser.delete_thread(int(contact['id']))
|
||||
return None
|
||||
|
||||
s = 0
|
||||
if contact.get('isOnline', False):
|
||||
if contact.get('online', False):
|
||||
s = Contact.STATUS_ONLINE
|
||||
else:
|
||||
s = Contact.STATUS_OFFLINE
|
||||
|
||||
c = Contact(contact['id'], to_unicode(contact['pseudo']), s)
|
||||
c.url = self.browser.id2url(contact['id'])
|
||||
if 'birthday' in contact:
|
||||
birthday = _parse_dt(contact['birthday'])
|
||||
age = int((datetime.datetime.now() - birthday).days / 365.25)
|
||||
c.status_msg = u'%s old, %s' % (age, contact['city'])
|
||||
if contact['cover'].isdigit() and int(contact['cover']) > 0:
|
||||
url = u'http://s%s.adopteunmec.com/%s%%(type)s%s.jpg' % (contact['shard'], contact['path'], contact['cover'])
|
||||
if 'age' in contact:
|
||||
c.status_msg = u'%s old, %s' % (contact['age'], contact['city'])
|
||||
if contact['cover'] is not None:
|
||||
url = contact['cover'] + '/%(type)s'
|
||||
else:
|
||||
url = u'http://s.adopteunmec.com/www/img/thumb0.gif'
|
||||
url = u'http://s.adopteunmec.com/www/img/thumb0.jpg'
|
||||
|
||||
c.set_photo(u'image%s' % contact['cover'],
|
||||
url=url % {'type': 'image'},
|
||||
thumbnail_url=url % {'type': 'thumb0_'})
|
||||
url=url % {'type': 'full'},
|
||||
thumbnail_url=url % {'type': 'small'})
|
||||
return c
|
||||
|
||||
def iter_contacts(self, status=Contact.STATUS_ALL, ids=None):
|
||||
|
|
@ -415,7 +409,7 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
|
|||
threads = self.browser.get_threads_list(count=100)
|
||||
|
||||
for thread in threads:
|
||||
c = self._get_partial_contact(thread['member'])
|
||||
c = self._get_partial_contact(thread['who'])
|
||||
if c and (c.status & status) and (not ids or c.id in ids):
|
||||
yield c
|
||||
|
||||
|
|
@ -547,7 +541,6 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
|
|||
StatusField('score', 'Score', self.browser.score()),
|
||||
StatusField('avcharms', 'Available charms', self.browser.nb_available_charms()),
|
||||
StatusField('newvisits', 'New visits', self.browser.nb_new_visites()),
|
||||
StatusField('godchilds', 'Number of godchilds', self.browser.nb_godchilds()),
|
||||
)
|
||||
|
||||
OBJECTS = {Thread: fill_thread,
|
||||
|
|
|
|||
|
|
@ -20,15 +20,12 @@
|
|||
|
||||
import math
|
||||
import re
|
||||
import datetime
|
||||
import random
|
||||
import urllib
|
||||
|
||||
from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword, BrowserUnavailable
|
||||
from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword, BrowserHTTPNotFound
|
||||
from weboob.tools.json import json
|
||||
|
||||
from weboob.capabilities.base import UserError
|
||||
from weboob.capabilities.chat import ChatException, ChatMessage
|
||||
from weboob.capabilities.messages import CantSendMessage
|
||||
|
||||
|
||||
|
|
@ -63,16 +60,24 @@ class AuMException(UserError):
|
|||
self.code = code
|
||||
|
||||
class AuMBrowser(BaseBrowser):
|
||||
DOMAIN = 'api.adopteunmec.com'
|
||||
DOMAIN = 'www.adopteunmec.com'
|
||||
APIKEY = 'fb0123456789abcd'
|
||||
|
||||
consts = None
|
||||
search_query = None
|
||||
my_sex = 0
|
||||
my_id = 0
|
||||
my_name = u''
|
||||
my_coords = (0,0)
|
||||
|
||||
def __init__(self, username, password, search_query, *args, **kwargs):
|
||||
kwargs['get_home'] = False
|
||||
BaseBrowser.__init__(self, username, password, *args, **kwargs)
|
||||
|
||||
self.add_password('http://www.adopteunmec.com/api/', self.username, self.password)
|
||||
self.home()
|
||||
|
||||
self.search_query = search_query
|
||||
|
||||
def id2url(self, id):
|
||||
return u'http://www.adopteunmec.com/index.php/profile/%s' % id
|
||||
|
||||
|
|
@ -88,7 +93,7 @@ class AuMBrowser(BaseBrowser):
|
|||
return func(self, id, *args, **kwargs)
|
||||
return inner
|
||||
|
||||
def api_request(self, command, action, parameter='', data=None, nologin=False):
|
||||
def api0_request(self, command, action, parameter='', data=None, nologin=False):
|
||||
if data is None:
|
||||
# Always do POST requests.
|
||||
data = ''
|
||||
|
|
@ -97,11 +102,13 @@ class AuMBrowser(BaseBrowser):
|
|||
elif isinstance(data, unicode):
|
||||
data = data.encode('utf-8')
|
||||
|
||||
url = self.buildurl(self.absurl('/api.php'), S=self.APIKEY,
|
||||
url = self.buildurl('http://api.adopteunmec.com/api.php',
|
||||
S=self.APIKEY,
|
||||
C=command,
|
||||
A=action,
|
||||
P=parameter,
|
||||
O='json')
|
||||
|
||||
buf = self.openurl(url, data).read()
|
||||
|
||||
try:
|
||||
|
|
@ -109,232 +116,162 @@ class AuMBrowser(BaseBrowser):
|
|||
except ValueError:
|
||||
raise ValueError(buf)
|
||||
|
||||
#pprint(r)
|
||||
|
||||
if 'errors' in r and r['errors'] != '0' and len(r['errors']) > 0:
|
||||
code = r['errors'][0]
|
||||
if code in (u'0.0.2', u'1.1.1', u'1.1.2'):
|
||||
if not nologin:
|
||||
self.login()
|
||||
return self.api_request(command, action, parameter, data, nologin=True)
|
||||
return self.api0_request(command, action, parameter, data, nologin=True)
|
||||
else:
|
||||
raise BrowserIncorrectPassword(AuMException.ERRORS[code])
|
||||
else:
|
||||
raise AuMException(code)
|
||||
return r
|
||||
|
||||
def logout(self):
|
||||
self._ua_handlers["_cookies"].cookiejar.clear()
|
||||
return r
|
||||
|
||||
def login(self):
|
||||
r = self.api_request('me', 'login', data={'login': self.username,
|
||||
'pass': self.password,
|
||||
}, nologin=True)
|
||||
self.my_sex = r['result']['me']['sex']
|
||||
self.my_id = int(r['result']['me']['id'])
|
||||
self.my_name = r['result']['me']['pseudo']
|
||||
r = self.api0_request('me', 'login', data={'login': self.username,
|
||||
'pass': self.password,
|
||||
}, nologin=True)
|
||||
self.my_coords = (float(r['result']['me']['lat']), float(r['result']['me']['lng']))
|
||||
if not self.search_query:
|
||||
self.search_query = 'region=%s' % r['result']['me']['region']
|
||||
|
||||
|
||||
def api_request(self, command, **kwargs):
|
||||
if 'data' in kwargs:
|
||||
data = kwargs.pop('data').encode('utf-8', 'replace')
|
||||
else:
|
||||
data = None
|
||||
|
||||
url = self.buildurl(self.absurl('/api/%s' % command), **kwargs)
|
||||
buf = self.openurl(url, data).read()
|
||||
|
||||
try:
|
||||
r = json.loads(buf)
|
||||
except ValueError:
|
||||
raise ValueError(buf)
|
||||
|
||||
return r
|
||||
|
||||
#def register(self, password, sex, birthday_d, birthday_m, birthday_y, zipcode, country, godfather=None):
|
||||
# if not self.is_on_page(RegisterPage):
|
||||
# self.location('http://www.adopteunmec.com/register2.php')
|
||||
# self.page.register(password, sex, birthday_d, birthday_m, birthday_y, zipcode, country)
|
||||
# if godfather:
|
||||
# if not self.is_on_page(AccountPage):
|
||||
# self.location('http://www.adopteunmec.com/account.php')
|
||||
# self.page.set_godfather(godfather)
|
||||
def home(self):
|
||||
r = self.api_request('home/')
|
||||
self.my_sex = r['user']['sex']
|
||||
self.my_id = int(r['user']['id'])
|
||||
self.my_name = r['user']['pseudo']
|
||||
|
||||
#@pageaccess
|
||||
#def add_photo(self, name, f):
|
||||
# if not self.is_on_page(EditPhotoPage):
|
||||
# self.location('/edit.php?type=1')
|
||||
# return self.page.add_photo(name, f)
|
||||
|
||||
#@pageaccess
|
||||
#def set_nickname(self, nickname):
|
||||
# if not self.is_on_page(EditAnnouncePage):
|
||||
# self.location('/edit.php?type=2')
|
||||
# return self.page.set_nickname(nickname)
|
||||
|
||||
#@pageaccess
|
||||
#def set_announce(self, title=None, description=None, lookingfor=None):
|
||||
# if not self.is_on_page(EditAnnouncePage):
|
||||
# self.location('/edit.php?type=2')
|
||||
# return self.page.set_announce(title, description, lookingfor)
|
||||
|
||||
#@pageaccess
|
||||
#def set_description(self, **args):
|
||||
# if not self.is_on_page(EditDescriptionPage):
|
||||
# self.location('/edit.php?type=3')
|
||||
# return self.page.set_description(**args)
|
||||
|
||||
def check_login(func):
|
||||
def inner(self, *args, **kwargs):
|
||||
if self.my_id == 0:
|
||||
self.login()
|
||||
return func(self, *args, **kwargs)
|
||||
return inner
|
||||
return r
|
||||
|
||||
def get_consts(self):
|
||||
if self.consts is not None:
|
||||
return self.consts
|
||||
|
||||
self.consts = []
|
||||
for i in xrange(2):
|
||||
r = self.api_request('me', 'all_values', data={'sex': i})
|
||||
self.consts.append(r['result']['values'])
|
||||
self.consts = [{}, {}]
|
||||
for key, sexes in self.api_request('values').iteritems():
|
||||
for sex, values in sexes.iteritems():
|
||||
if sex in ('boy', 'both'):
|
||||
self.consts[0][key] = values
|
||||
if sex in ('girl', 'both'):
|
||||
self.consts[1][key] = values
|
||||
|
||||
return self.consts
|
||||
|
||||
@check_login
|
||||
def score(self):
|
||||
r = self.api_request('member', 'view', data={'id': self.my_id})
|
||||
return int(r['result']['member']['popu']['popu'])
|
||||
r = self.home()
|
||||
return int(r['user']['points'])
|
||||
|
||||
@check_login
|
||||
def get_my_name(self):
|
||||
return self.my_name
|
||||
|
||||
@check_login
|
||||
def get_my_id(self):
|
||||
return self.my_id
|
||||
|
||||
@check_login
|
||||
def nb_new_mails(self):
|
||||
r = self.api_request('me', '[default]')
|
||||
return r['result']['news']['newMails']
|
||||
r = self.home()
|
||||
return r['counters']['new_mails']
|
||||
|
||||
@check_login
|
||||
def nb_new_baskets(self):
|
||||
r = self.api_request('me', '[default]')
|
||||
return r['result']['news']['newBaskets']
|
||||
r = self.home()
|
||||
return r['counters']['new_baskets']
|
||||
|
||||
@check_login
|
||||
def nb_new_visites(self):
|
||||
r = self.api_request('me', '[default]')
|
||||
return r['result']['news']['newVisits']
|
||||
r = self.home()
|
||||
return r['counters']['new_visits']
|
||||
|
||||
@check_login
|
||||
def nb_available_charms(self):
|
||||
r = self.login()
|
||||
return r['result']['flashs']
|
||||
r = self.home()
|
||||
return r['subscription']['flashes_stock']
|
||||
|
||||
@check_login
|
||||
def nb_godchilds(self):
|
||||
r = self.api_request('member', 'view', data={'id': self.my_id})
|
||||
return int(r['result']['member']['popu']['invits'])
|
||||
|
||||
@check_login
|
||||
def get_baskets(self):
|
||||
r = self.api_request('me', 'basket')
|
||||
return r['result']['basket']
|
||||
r = self.api_request('basket', count=30, offset=0)
|
||||
return r['results']
|
||||
|
||||
@check_login
|
||||
def get_flashs(self):
|
||||
r = self.api_request('me', 'flashs')
|
||||
return r['result']['all']
|
||||
r = self.api_request('charms/', count=30, offset=0)
|
||||
return r['results']
|
||||
|
||||
@check_login
|
||||
def get_visits(self):
|
||||
# display three pages
|
||||
for i in xrange(3):
|
||||
r = self.api_request('me', 'visits', data={'page': i})
|
||||
for p in (r['result']['news'] + r['result']['olds']):
|
||||
yield p
|
||||
r = self.api_request('visits', count=30, offset=0)
|
||||
return r['results']
|
||||
|
||||
@check_login
|
||||
def get_threads_list(self, count=30):
|
||||
r = self.api_request('message', '[default]', '%d,0' % count)
|
||||
return r['result']['threads']
|
||||
r = self.api_request('threads', count=count, offset=0)
|
||||
return r['results']
|
||||
|
||||
@check_login
|
||||
@url2id
|
||||
def get_thread_mails(self, id, count=30):
|
||||
r = self.api_request('message', 'thread', data={'memberId': id, 'count': count})
|
||||
return r['result']['thread']
|
||||
r = self.api_request('threads/%s' % id, count=count, offset=0)
|
||||
return r
|
||||
|
||||
@check_login
|
||||
@url2id
|
||||
def post_mail(self, id, content):
|
||||
# It seems it is not needed anymore.
|
||||
#new_content = u''
|
||||
#for c in content:
|
||||
# try:
|
||||
# new_content += '&%s;' % codepoint2name[ord(c)]
|
||||
# except KeyError:
|
||||
# new_content += c
|
||||
|
||||
content = content.replace('\n', '\r\n').encode('utf-8', 'replace')
|
||||
content = content.replace('\n', '\r\n')
|
||||
|
||||
try:
|
||||
self.api_request('message', 'new', data={'memberId': id, 'message': content})
|
||||
except AuMException, e:
|
||||
raise CantSendMessage(unicode(e))
|
||||
self.api_request('threads/%s' % id, data=content)
|
||||
except BrowserHTTPNotFound:
|
||||
raise CantSendMessage('Unable to send message.')
|
||||
|
||||
@check_login
|
||||
@url2id
|
||||
def delete_thread(self, id):
|
||||
r = self.api_request('message', 'delete', data={'id_user': id})
|
||||
self.logger.debug('Thread deleted: %r' % r)
|
||||
|
||||
@check_login
|
||||
@url2id
|
||||
def send_charm(self, id):
|
||||
try:
|
||||
self.api_request('member', 'addBasket', data={'id': id})
|
||||
except AuMException:
|
||||
self.api_request('users/%s/charms' % id, data='')
|
||||
except BrowserHTTPNotFound:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
@check_login
|
||||
@url2id
|
||||
def add_basket(self, id):
|
||||
try:
|
||||
self.api_request('member', 'addBasket', data={'id': id})
|
||||
except AuMException:
|
||||
self.api_request('basket/%s' % id, data='')
|
||||
except BrowserHTTPNotFound:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
@url2id
|
||||
def deblock(self, id):
|
||||
self.readurl('http://www.adopteunmec.com/fajax_postMessage.php?action=deblock&to=%s' % id)
|
||||
return True
|
||||
|
||||
@url2id
|
||||
def report_fake(self, id):
|
||||
return self.readurl('http://www.adopteunmec.com/fake.php', 'id=%s' % id)
|
||||
|
||||
@url2id
|
||||
def rate(self, id, what, rating):
|
||||
result = self.openurl('http://www.adopteunmec.com/fajax_vote.php', 'member=%s&what=%s&rating=%s' % (id, what, rating)).read()
|
||||
return float(result)
|
||||
|
||||
def search_profiles(self, **kwargs):
|
||||
if self.search_query is None:
|
||||
r = self.api_request('searchs', '[default]')
|
||||
self.search_query = r['result']['search']
|
||||
if not self.search_query:
|
||||
# retrieve query
|
||||
self.login()
|
||||
|
||||
params = {}
|
||||
for key, value in json.loads(self.search_query['query']).iteritems():
|
||||
if isinstance(value, dict):
|
||||
for k, v in value.iteritems():
|
||||
params['%s%s' % (key, k.capitalize())] = v
|
||||
else:
|
||||
params[key] = value or ''
|
||||
r = self.api_request('searchs', 'advanced', '60,0', params)
|
||||
ids = [s['id'] for s in r['result']['search']]
|
||||
r = self.api_request('users?count=60&offset=0&%s' % self.search_query)
|
||||
ids = [s['id'] for s in r['results']]
|
||||
return set(ids)
|
||||
|
||||
@url2id
|
||||
def get_profile(self, id, with_pics=True):
|
||||
r = self.api_request('member', 'view', data={'id': id})
|
||||
r = self.api0_request('member', 'view', data={'id': id})
|
||||
if not 'result' in r:
|
||||
print r
|
||||
profile = r['result']['member']
|
||||
|
||||
profile.update(self.api_request('users/%s' % id))
|
||||
|
||||
# Calculate distance in km.
|
||||
profile['dist'] = 0.0
|
||||
|
|
@ -352,56 +289,4 @@ class AuMBrowser(BaseBrowser):
|
|||
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):
|
||||
try:
|
||||
data = json.load(self.openurl('http://www.adopteunmec.com/1.1_cht_get.php?anticache=%f' % random.random()))
|
||||
except ValueError:
|
||||
raise BrowserUnavailable()
|
||||
|
||||
if data['error']:
|
||||
raise ChatException(u'Error while getting chat infos. json:\n%s' % data)
|
||||
return data
|
||||
|
||||
def iter_contacts(self):
|
||||
def iter_dedupe(contacts):
|
||||
yielded_ids = set()
|
||||
for contact in contacts:
|
||||
if contact['id'] not in yielded_ids:
|
||||
yield contact
|
||||
yielded_ids.add(contact['id'])
|
||||
|
||||
data = self._get_chat_infos()
|
||||
return iter_dedupe(data['contacts'])
|
||||
|
||||
def iter_chat_messages(self, _id=None):
|
||||
data = self._get_chat_infos()
|
||||
if data['messages'] is not None:
|
||||
for message in data['messages']:
|
||||
yield ChatMessage(id_from=message['id_from'], id_to=message['id_to'], message=message['message'], date=message['date'])
|
||||
|
||||
def send_chat_message(self, _id, message):
|
||||
url = 'http://www.adopteunmec.com/1.1_cht_send.php?anticache=%f' % random.random()
|
||||
data = dict(id=_id, message=message)
|
||||
headers = {
|
||||
'Content-type': 'application/x-www-form-urlencoded',
|
||||
'Accept': 'text/plain',
|
||||
'Referer': 'http://www.adopteunmec.com/chat.php',
|
||||
'Origin': 'http://www.adopteunmec.com',
|
||||
}
|
||||
request = self.request_class(url, urllib.urlencode(data), headers)
|
||||
response = self.openurl(request).read()
|
||||
try:
|
||||
datetime.datetime.strptime(response, '%Y-%m-%d %H:%M:%S')
|
||||
return True
|
||||
except ValueError:
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -95,9 +95,9 @@ class FieldOld(FieldBase):
|
|||
return int((datetime.now() - birthday).days / 365.25)
|
||||
|
||||
|
||||
class FieldSplit(FieldBase):
|
||||
class FieldList(FieldBase):
|
||||
def get_value(self, profile, consts):
|
||||
return [html2text(s).strip() for s in profile[self.key].split(self.key2) if len(s.strip()) > 0]
|
||||
return profile[self.key]
|
||||
|
||||
|
||||
class FieldBMI(FieldBase):
|
||||
|
|
@ -126,24 +126,19 @@ class FieldBMI(FieldBase):
|
|||
return 'obese'
|
||||
|
||||
|
||||
class FieldFlags(FieldBase):
|
||||
class FieldConst(FieldBase):
|
||||
def get_value(self, profile, consts):
|
||||
i = int(profile[self.key])
|
||||
labels = []
|
||||
for d in consts[self.key]:
|
||||
if i & (1 << int(d['value'])):
|
||||
labels.append(html2text(d['label']).strip())
|
||||
return labels
|
||||
|
||||
|
||||
class FieldList(FieldBase):
|
||||
def get_value(self, profile, consts):
|
||||
i = int(profile[self.key])
|
||||
for d in consts[self.key]:
|
||||
if i == int(d['value']):
|
||||
return html2text(d['label']).strip()
|
||||
return ''
|
||||
|
||||
v = profile[self.key]
|
||||
if isinstance(v, (basestring,int)):
|
||||
try:
|
||||
return consts[self.key][str(v)]
|
||||
except KeyError:
|
||||
return ''
|
||||
elif isinstance(v, (tuple,list)):
|
||||
labels = []
|
||||
for i in v:
|
||||
labels.append(consts[self.key][i])
|
||||
return labels
|
||||
|
||||
class Contact(_Contact):
|
||||
TABLE = OrderedDict((
|
||||
|
|
@ -165,7 +160,7 @@ class Contact(_Contact):
|
|||
('bonus', FieldPopu('bonus')),
|
||||
('score', FieldPopu('popu')),
|
||||
('ratio', FieldPopuRatio('mails', 'flashs')),
|
||||
('mailable', FieldBool('mailable')),
|
||||
('mailable', FieldBool('can_mail')),
|
||||
))),
|
||||
('details', OrderedDict((
|
||||
('old', FieldOld('birthday')),
|
||||
|
|
@ -175,69 +170,64 @@ class Contact(_Contact):
|
|||
('distance', FieldDist('dist')),
|
||||
('country', FieldStr('country')),
|
||||
('phone', FieldStr('phone')),
|
||||
('eyes', FieldList('eyes')),
|
||||
('hair_color', FieldList('hair_color')),
|
||||
('hair_size', FieldList('hair_size')),
|
||||
('height', FieldList('size')),
|
||||
('weight', FieldList('weight')),
|
||||
('eyes', FieldConst('eyes_color')),
|
||||
('hair_color', FieldConst('hair_color')),
|
||||
('hair_size', FieldConst('hair_size')),
|
||||
('height', FieldConst('size')),
|
||||
('weight', FieldConst('weight')),
|
||||
('BMI', FieldBMI('size', 'weight')),
|
||||
('fat', FieldBMI('size', 'weight', fat=True)),
|
||||
('shape', FieldList('shape')),
|
||||
('origins', FieldList('origins')),
|
||||
('signs', FieldFlags('checks1')),
|
||||
('shape', FieldConst('shape')),
|
||||
('origins', FieldConst('origins')),
|
||||
('signs', FieldConst('features')),
|
||||
('job', FieldStr('job')),
|
||||
('style', FieldList('style')),
|
||||
('food', FieldList('food')),
|
||||
('drink', FieldList('drink')),
|
||||
('smoke', FieldList('smoke')),
|
||||
('style', FieldConst('style')),
|
||||
('food', FieldConst('diet')),
|
||||
('drink', FieldConst('alcohol')),
|
||||
('smoke', FieldConst('tobacco')),
|
||||
))),
|
||||
('tastes', OrderedDict((
|
||||
('hobbies', FieldStr('hobbies')),
|
||||
('music', FieldSplit('music', '<br>')),
|
||||
('cinema', FieldSplit('cinema', '<br>')),
|
||||
('books', FieldSplit('books', '<br>')),
|
||||
('tv', FieldSplit('tvs', '<br>')),
|
||||
('music', FieldList('music')),
|
||||
('cinema', FieldList('cinema')),
|
||||
('books', FieldList('books')),
|
||||
('tv', FieldList('tvs')),
|
||||
))),
|
||||
('sex', OrderedDict((
|
||||
('underwear', FieldFlags('checks7')),
|
||||
('practices', FieldFlags('checks5')),
|
||||
('favorite', FieldFlags('checks3')),
|
||||
('toys', FieldFlags('checks6')),
|
||||
('+sex', OrderedDict((
|
||||
('underwear', FieldConst('underwear')),
|
||||
('practices', FieldConst('sexgames')),
|
||||
('favorite', FieldConst('arousing')),
|
||||
('toys', FieldConst('sextoys')),
|
||||
))),
|
||||
('personality', OrderedDict((
|
||||
('snap', FieldStr('texts1')),
|
||||
('exciting', FieldStr('texts2')),
|
||||
('hate', FieldStr('texts3')),
|
||||
('vices', FieldStr('texts4')),
|
||||
('assets', FieldStr('texts6')),
|
||||
('fantasies', FieldStr('texts5')),
|
||||
('is', FieldFlags('checks2')),
|
||||
('+personality', OrderedDict((
|
||||
('snap', FieldStr('fall_for')),
|
||||
('exciting', FieldStr('turned_on_by')),
|
||||
('hate', FieldStr('cant_stand')),
|
||||
('vices', FieldStr('vices')),
|
||||
('assets', FieldStr('assets')),
|
||||
('fantasies', FieldStr('fantasies')),
|
||||
('is', FieldConst('character')),
|
||||
)))
|
||||
))
|
||||
|
||||
def parse_profile(self, profile, consts):
|
||||
cat = int(profile.get('cat', 3))
|
||||
if cat == 1:
|
||||
if profile['online']:
|
||||
self.status = Contact.STATUS_ONLINE
|
||||
self.status_msg = u'online'
|
||||
self.status_msg = u'since %s' % profile['last_cnx']
|
||||
elif cat == 2:
|
||||
self.status = Contact.STATUS_AWAY
|
||||
self.status_msg = u'away'
|
||||
self.status_msg = u'connection at %s' % profile['last_cnx']
|
||||
elif cat == 3:
|
||||
else:
|
||||
self.status = Contact.STATUS_OFFLINE
|
||||
self.status_msg = u'last connection %s' % profile['last_cnx']
|
||||
|
||||
self.summary = html2text(profile.get('about1', '')).strip().replace('\n\n', '\n')
|
||||
if len(profile.get('about2', '')) > 0:
|
||||
self.summary += u'\n\nLooking for:\n%s' % html2text(profile['about2']).strip().replace('\n\n', '\n')
|
||||
self.summary = html2text(profile.get('announce', '')).strip().replace('\n\n', '\n')
|
||||
if len(profile.get('shopping_list', '')) > 0:
|
||||
self.summary += u'\n\nLooking for:\n%s' % html2text(profile['shopping_list']).strip().replace('\n\n', '\n')
|
||||
|
||||
for photo in profile['pictures']:
|
||||
self.set_photo(photo['url'].split('/')[-1],
|
||||
url=photo['url'],
|
||||
thumbnail_url=photo['url'].replace('image', 'thumb1_'),
|
||||
hidden=photo['hidden'])
|
||||
for photo in profile['pics']:
|
||||
self.set_photo(photo.split('/')[-1],
|
||||
url=photo + '/full',
|
||||
thumbnail_url=photo + '/small',
|
||||
hidden=False)
|
||||
self.profile = OrderedDict()
|
||||
|
||||
if 'sex' in profile:
|
||||
|
|
@ -245,7 +235,12 @@ class Contact(_Contact):
|
|||
flags = ProfileNode.SECTION
|
||||
if section.startswith('_'):
|
||||
flags |= ProfileNode.HEAD
|
||||
section = section.lstrip('_')
|
||||
if (section.startswith('+') and int(profile['sex']) != 1) or \
|
||||
(section.startswith('-') and int(profile['sex']) != 0):
|
||||
continue
|
||||
|
||||
section = section.lstrip('_+-')
|
||||
|
||||
s = ProfileNode(section, section.capitalize(), OrderedDict(), flags=flags)
|
||||
|
||||
for key, builder in d.iteritems():
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ class Visibility(Optimization):
|
|||
def reconnect(self):
|
||||
try:
|
||||
with self.browser:
|
||||
self.browser.logout()
|
||||
self.browser.login()
|
||||
except BrowserUnavailable, e:
|
||||
print str(e)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue