add the PRIORITY_CONNECTION optimization (closes #319)

This commit is contained in:
Romain Bignon 2010-11-11 14:12:59 +01:00
commit fd3ccda664
6 changed files with 174 additions and 13 deletions

View file

@ -140,7 +140,7 @@ class HaveSex(ReplApplication):
if params is None: if params is None:
params = {} params = {}
print 'Configuration of %s.%s' % (backend_name, optim_name) print 'Configuration of %s.%s' % (backend_name, optim_name)
print '-----------------%s.%s' % ('-' * len(backend_name), '-' * len(optim_name)) print '-----------------%s-%s' % ('-' * len(backend_name), '-' * len(optim_name))
for key, value in optim.CONFIG.iteritems(): for key, value in optim.CONFIG.iteritems():
params[key] = self.ask(value, default=params[key] if (key in params) else value.default) params[key] = self.ask(value, default=params[key] if (key in params) else value.default)
@ -170,11 +170,13 @@ class HaveSex(ReplApplication):
if function == 'start' and len(optim.CONFIG) > 0 and optim.get_config() is None: if function == 'start' and len(optim.CONFIG) > 0 and optim.get_config() is None:
self.edit_optims(backend.name, optim_name) self.edit_optims(backend.name, optim_name)
getattr(optim, function)() ret = getattr(optim, function)()
sys.stdout.write(' ' + backend.name) sys.stdout.write(' ' + backend.name)
if not ret:
sys.stdout.write('(failed)')
sys.stdout.flush() sys.stdout.flush()
if store: if store:
if function == 'start': if function == 'start' and ret:
storage_optim.add(backend.name) storage_optim.add(backend.name)
elif function == 'stop': elif function == 'stop':
try: try:
@ -228,7 +230,7 @@ class HaveSex(ReplApplication):
* edit configure an optimization service for a backend * edit configure an optimization service for a backend
* stop stop optimization services on a backend * stop stop optimization services on a backend
""" """
cmd, backend_name, optims_names = self.parseargs(line, 3, 1) cmd, backend_name, optims_names = self.parseargs(line, 3)
if backend_name == '*': if backend_name == '*':
backend_name = None backend_name = None
@ -243,7 +245,7 @@ class HaveSex(ReplApplication):
if cmd == 'edit': if cmd == 'edit':
self.edit_optims(backend_name, optims_names, stop=True) self.edit_optims(backend_name, optims_names, stop=True)
return return
if cmd == 'list': if cmd == 'list' or cmd is None:
if optims_names is not None: if optims_names is not None:
optims_names = optims_names.split() optims_names = optims_names.split()

View file

@ -59,6 +59,8 @@ class AntiSpam(object):
return False return False
if profile.description.find('belle dans la cam') >= 0: if profile.description.find('belle dans la cam') >= 0:
return False return False
if profile.description.find('pour montre ma cam') >= 0:
return False
if profile.description.find('show sex') >= 0: if profile.description.find('show sex') >= 0:
return False return False
if profile.description.find('un mec tres chaude') >= 0: if profile.description.find('un mec tres chaude') >= 0:
@ -71,6 +73,8 @@ class AntiSpam(object):
return False return False
if profile.description.find('une fille tres chaud') >= 0: if profile.description.find('une fille tres chaud') >= 0:
return False return False
if profile.description.find(u'tré chau') == 0:
return False
if profile.description.find('sa va bb') == 0: if profile.description.find('sa va bb') == 0:
return False return False
if profile.description.startswith('msn\n\n'): if profile.description.startswith('msn\n\n'):

View file

@ -39,6 +39,7 @@ from .browser import AuMBrowser
from .exceptions import AdopteWait from .exceptions import AdopteWait
from .optim.profiles_walker import ProfilesWalker from .optim.profiles_walker import ProfilesWalker
from .optim.visibility import Visibility from .optim.visibility import Visibility
from .optim.priority_connection import PriorityConnection
__all__ = ['AuMBackend'] __all__ = ['AuMBackend']
@ -55,6 +56,7 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
Value('password', label='Password', masked=True), Value('password', label='Password', masked=True),
ValueBool('antispam', label='Enable anti-spam', default=False)) ValueBool('antispam', label='Enable anti-spam', default=False))
STORAGE = {'profiles_walker': {'viewed': []}, STORAGE = {'profiles_walker': {'viewed': []},
'priority_connection': {'config': {}, 'fakes': {}},
'sluts': {}, 'sluts': {},
} }
BROWSER = AuMBrowser BROWSER = AuMBrowser
@ -82,6 +84,7 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
def init_optimizations(self): def init_optimizations(self):
self.add_optimization('PROFILE_WALKER', ProfilesWalker(self.weboob.scheduler, self.storage, self.browser)) self.add_optimization('PROFILE_WALKER', ProfilesWalker(self.weboob.scheduler, self.storage, self.browser))
self.add_optimization('VISIBILITY', Visibility(self.weboob.scheduler, self.browser)) self.add_optimization('VISIBILITY', Visibility(self.weboob.scheduler, self.browser))
self.add_optimization('PRIORITY_CONNECTION', PriorityConnection(self.weboob.scheduler, self.storage, self.browser))
def get_status(self): def get_status(self):
with self.browser: with self.browser:
@ -107,7 +110,7 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
if not contact.get_id(): if not contact.get_id():
continue continue
if self.antispam and not self.antispam.check(contact): if self.antispam and not self.antispam.check(contact):
self.logger.debug('Skipped a spam-thread from %s' % contact.get_name()) self.logger.info('Skipped a spam-thread from %s' % contact.get_name())
self.report_spam(contact.get_id(), contact.get_suppr_id()) self.report_spam(contact.get_id(), contact.get_suppr_id())
continue continue
thread = Thread(contact.get_id()) thread = Thread(contact.get_id())
@ -143,7 +146,7 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
for mail in mails: for mail in mails:
flags = 0 flags = 0
if self.antispam and not self.antispam.check(mail): if self.antispam and not self.antispam.check(mail):
self.logger.debug('Skipped a spam-mail from %s' % mail.sender) self.logger.info('Skipped a spam-mail from %s' % mail.sender)
self.report_spam(thread.id, contact and contact.get_suppr_id()) self.report_spam(thread.id, contact and contact.get_suppr_id())
break break
@ -154,7 +157,7 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
with self.browser: with self.browser:
profiles[mail.profile_link] = self.browser.get_profile(mail.profile_link) profiles[mail.profile_link] = self.browser.get_profile(mail.profile_link)
if self.antispam and not self.antispam.check(profiles[mail.profile_link]): if self.antispam and not self.antispam.check(profiles[mail.profile_link]):
self.logger.debug('Skipped a spam-mail-profile from %s' % mail.sender) self.logger.info('Skipped a spam-mail-profile from %s' % mail.sender)
self.report_spam(thread.id, contact and contact.get_suppr_id()) self.report_spam(thread.id, contact and contact.get_suppr_id())
break break
mail.signature += u'\n%s' % profiles[mail.profile_link].get_profile_text() mail.signature += u'\n%s' % profiles[mail.profile_link].get_profile_text()
@ -205,7 +208,7 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
if not contact.get_id(): if not contact.get_id():
continue continue
if self.antispam and not self.antispam.check(contact): if self.antispam and not self.antispam.check(contact):
self.logger.debug('Skipped a spam-unread-thread from %s' % contact.get_name()) self.logger.info('Skipped a spam-unread-thread from %s' % contact.get_name())
self.report_spam(contact.get_id(), contact.get_suppr_id()) self.report_spam(contact.get_id(), contact.get_suppr_id())
continue continue
slut = self._get_slut(contact.get_id()) slut = self._get_slut(contact.get_id())
@ -230,7 +233,7 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
if not profile or profile.get_id() == 0: if not profile or profile.get_id() == 0:
continue continue
if self.antispam and not self.antispam.check(profile): if self.antispam and not self.antispam.check(profile):
self.logger.debug('Skipped a spam-basket from %s' % profile.get_name()) self.logger.info('Skipped a spam-basket from %s' % profile.get_name())
self.report_spam(profile.get_id()) self.report_spam(profile.get_id())
continue continue

View file

@ -184,6 +184,12 @@ class AuMBrowser(BaseBrowser):
self.home() self.home()
return self.page.nb_available_charms() return self.page.nb_available_charms()
@pageaccess
def nb_godchilds(self, reload=False):
if reload or not self.is_on_page(HomePage):
self.home()
return self.page.nb_godchilds()
@pageaccess @pageaccess
def get_baskets(self): def get_baskets(self):
self.location('/mails.php?type=1') self.location('/mails.php?type=1')

View file

@ -0,0 +1,139 @@
# -*- coding: utf-8 -*-
# Copyright(C) 2010 Romain Bignon
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
from __future__ import with_statement
import random
#from weboob.tools.browser import BrowserUnavailable
from weboob.capabilities.dating import Optimization
from weboob.capabilities.account import AccountRegisterError
from weboob.tools.log import getLogger
from weboob.tools.value import Value, ValuesDict, ValueInt
from weboob.backends.aum.captcha import CaptchaError
from weboob.backends.aum.exceptions import AdopteWait
from weboob.backends.aum.browser import AuMBrowser
__all__ = ['PriorityConnection']
class PriorityConnection(Optimization):
CONFIG = ValuesDict(ValueInt('minimal', label='Minimal of godchilds', default=5),
Value('domain', label='Domain to use for fake accounts emails', default='aum.example.com'),
Value('interval', label='Interval of checks (seconds)', default=3600)
)
def __init__(self, sched, storage, browser):
self.sched = sched
self.storage = storage
self.browser = browser
self.logger = getLogger('walker', browser.logger)
self.config = storage.get('priority_connection', 'config', default=None)
if self.config == {}:
self.config = None
self.cron = None
def save(self):
self.storage.set('profiles_walker', 'viewed', list(self.visited_profiles))
self.storage.save()
def start(self):
if self.config is None:
return False
self.cron = self.sched.repeat(self.config['interval'], self.check_godchilds)
return True
def stop(self):
self.sched.cancel(self.cron)
self.cron = None
return True
def is_running(self):
return self.cron is not None
def set_config(self, params):
self.config = params
self.storage.set('priority_connection', 'config', self.config)
self.storage.save()
def get_config(self):
return self.config
def generate_name(self):
login = u''
for x in xrange(8):
if x % 2:
login += random.choice(u'aeiou')
else:
login += random.choice(u'bcdfghjklmnprstv')
fakes = self.storage.get('priority_connection', 'fakes')
while ('%s@%s' % (login, self.config['domain'])) in fakes.iterkeys():
login += '_'
return login
def generate_password(self):
return '%08x' % random.randint(1, int('ffffffff', 16))
def check_godchilds(self):
with self.browser:
my_id = self.browser.get_my_id()
try:
nb_godchilds = self.browser.nb_godchilds()
except AdopteWait:
nb_godchilds = 0
missing_godchilds = self.config['minimal'] - nb_godchilds
if missing_godchilds <= 0:
return
self.logger.info('Missing godchilds: %s' % missing_godchilds)
for i in xrange(missing_godchilds):
registered = False
while not registered:
name = self.generate_name()
password = self.generate_password()
browser = AuMBrowser('%s@%s' % (name, self.config['domain']))
try:
browser.register(password= password,
sex= 1, #slut
birthday_d= random.randint(1,28),
birthday_m= random.randint(1,12),
birthday_y= random.randint(1970, 1990),
zipcode= 75001,
country= 'fr',
godfather= my_id)
except AccountRegisterError, e:
self.logger.warning('Unable to register account: %s' % e)
except CaptchaError:
self.logger.warning('Unable to solve captcha... Retrying')
else:
registered = True
browser.set_nickname(name.strip('_').capitalize())
fake = {'username': browser.username,
'password': password}
self.storage.set('priority_connection', 'fakes', name, fake)
self.storage.save()
self.logger.info('Fake account "%s" created (godfather=%s)' % (name, my_id))

View file

@ -35,7 +35,8 @@ class HomePage(PageBase):
error("Error: Unable to find my ID") error("Error: Unable to find my ID")
return 0 return 0
def nb_available_charms(self): def __get_home_indicator(self, pos, what):
tables = self.document.getElementsByTagName('table') tables = self.document.getElementsByTagName('table')
for table in tables: for table in tables:
if table.hasAttribute('style') and table.getAttribute('style') == 'background-color:black;background-image:url(http://s.adopteunmec.com/img/barmec.gif);background-repeat:no-repeat': if table.hasAttribute('style') and table.getAttribute('style') == 'background-color:black;background-image:url(http://s.adopteunmec.com/img/barmec.gif);background-repeat:no-repeat':
@ -44,7 +45,13 @@ class HomePage(PageBase):
for font in fonts: for font in fonts:
if font.hasAttribute('color') and font.getAttribute('color') == '#ff0198': if font.hasAttribute('color') and font.getAttribute('color') == '#ff0198':
i += 1 i += 1
if i == 3: if i == pos:
return int(font.firstChild.data) return int(font.firstChild.data)
warning(u'Could not parse number of charms available') warning(u'Could not parse number of %s' % what)
return 0 return 0
def nb_available_charms(self):
return self.__get_home_indicator(3, 'available charms')
def nb_godchilds(self):
return self.__get_home_indicator(2, 'godchilds')