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:
params = {}
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():
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:
self.edit_optims(backend.name, optim_name)
getattr(optim, function)()
ret = getattr(optim, function)()
sys.stdout.write(' ' + backend.name)
if not ret:
sys.stdout.write('(failed)')
sys.stdout.flush()
if store:
if function == 'start':
if function == 'start' and ret:
storage_optim.add(backend.name)
elif function == 'stop':
try:
@ -228,7 +230,7 @@ class HaveSex(ReplApplication):
* edit configure an optimization service for 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 == '*':
backend_name = None
@ -243,7 +245,7 @@ class HaveSex(ReplApplication):
if cmd == 'edit':
self.edit_optims(backend_name, optims_names, stop=True)
return
if cmd == 'list':
if cmd == 'list' or cmd is None:
if optims_names is not None:
optims_names = optims_names.split()

View file

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

View file

@ -39,6 +39,7 @@ from .browser import AuMBrowser
from .exceptions import AdopteWait
from .optim.profiles_walker import ProfilesWalker
from .optim.visibility import Visibility
from .optim.priority_connection import PriorityConnection
__all__ = ['AuMBackend']
@ -55,6 +56,7 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
Value('password', label='Password', masked=True),
ValueBool('antispam', label='Enable anti-spam', default=False))
STORAGE = {'profiles_walker': {'viewed': []},
'priority_connection': {'config': {}, 'fakes': {}},
'sluts': {},
}
BROWSER = AuMBrowser
@ -82,6 +84,7 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
def init_optimizations(self):
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('PRIORITY_CONNECTION', PriorityConnection(self.weboob.scheduler, self.storage, self.browser))
def get_status(self):
with self.browser:
@ -107,7 +110,7 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
if not contact.get_id():
continue
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())
continue
thread = Thread(contact.get_id())
@ -143,7 +146,7 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
for mail in mails:
flags = 0
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())
break
@ -154,7 +157,7 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh
with self.browser:
profiles[mail.profile_link] = self.browser.get_profile(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())
break
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():
continue
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())
continue
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:
continue
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())
continue

View file

@ -184,6 +184,12 @@ class AuMBrowser(BaseBrowser):
self.home()
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
def get_baskets(self):
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")
return 0
def nb_available_charms(self):
def __get_home_indicator(self, pos, what):
tables = self.document.getElementsByTagName('table')
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':
@ -44,7 +45,13 @@ class HomePage(PageBase):
for font in fonts:
if font.hasAttribute('color') and font.getAttribute('color') == '#ff0198':
i += 1
if i == 3:
if i == pos:
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
def nb_available_charms(self):
return self.__get_home_indicator(3, 'available charms')
def nb_godchilds(self):
return self.__get_home_indicator(2, 'godchilds')