diff --git a/weboob/applications/havesex/havesex.py b/weboob/applications/havesex/havesex.py index b1b00ce8..1c5dbf08 100644 --- a/weboob/applications/havesex/havesex.py +++ b/weboob/applications/havesex/havesex.py @@ -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() diff --git a/weboob/backends/aum/antispam.py b/weboob/backends/aum/antispam.py index 5fac8e9b..0f82f770 100644 --- a/weboob/backends/aum/antispam.py +++ b/weboob/backends/aum/antispam.py @@ -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'): diff --git a/weboob/backends/aum/backend.py b/weboob/backends/aum/backend.py index b1114e69..fbdbfc1a 100644 --- a/weboob/backends/aum/backend.py +++ b/weboob/backends/aum/backend.py @@ -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 diff --git a/weboob/backends/aum/browser.py b/weboob/backends/aum/browser.py index 6033ac5d..5ffd1202 100644 --- a/weboob/backends/aum/browser.py +++ b/weboob/backends/aum/browser.py @@ -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') diff --git a/weboob/backends/aum/optim/priority_connection.py b/weboob/backends/aum/optim/priority_connection.py new file mode 100644 index 00000000..7c79df71 --- /dev/null +++ b/weboob/backends/aum/optim/priority_connection.py @@ -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)) diff --git a/weboob/backends/aum/pages/home.py b/weboob/backends/aum/pages/home.py index 1ad7a601..1037c607 100644 --- a/weboob/backends/aum/pages/home.py +++ b/weboob/backends/aum/pages/home.py @@ -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')