Example #1
0
 def __init__(self):
     logger.debug("class init")
     self.peg_perco_names = []
     self.weboob = Weboob()
     self.weboob.load_backends(CapBank)
     logger.debug('backends loaded: %s' % list(self.weboob.iter_backends()))
     self.investments = {}
Example #2
0
def retrieve_accounts(bank_name):
    w = Weboob()
    w.load_backends(caps=(CapBank, ))
    bank_backend = w.get_backend(bank_name)
    if bank_backend:
        bank = Bank.get_or_create(name=bank_name)
        accounts = bank_backend.iter_accounts()
        for account in accounts:
            logger.info(
                f'[Accounts] Retrieving account {account.label} - {account.balance} from {bank_name}'
            )

            db_account = Account.get_or_none(bank=bank[0],
                                             account_id=account.id)
            if db_account is None:
                db_account = Account.create(bank=bank[0],
                                            account_id=account.id,
                                            user=1,
                                            label=account.label,
                                            balance=account.balance)
            else:
                db_account.label = account.label
                db_account.balance = account.balance
                db_account.save()
            transactions = bank_backend.iter_history(account)
            for transaction in transactions:
                db_transanction = Transaction.get_or_create(
                    account=db_account.id,
                    label=transaction.label,
                    category=transaction.category,
                    amount=transaction.amount,
                    date=transaction.date)
Example #3
0
    def get_app_dictionary(self):
        if self.enabled:
            # we wan't to update every VALUES_UPDATE_INTERVAL minutes
            if self.status is None or timezone.now(
            ) >= self.last_activity + timedelta(
                    minutes=settings.VALUES_UPDATE_INTERVAL):
                # Weboob 1.2 example http://dev.weboob.org/
                weboob = Weboob()
                weboob.load_backends(CapParcel)
                for backend in list(weboob.iter_backends()):
                    if backend.name == self.parcel_carrier:
                        parcel = backend.get_parcel_tracking(self.parcel)
                        parcel_dict = parcel.to_dict()
                        self.status = parcel_dict['status']
                        if parcel_dict['arrival'] == 'Not loaded':
                            self.arrival = None
                        else:
                            pass
                            #parcel_dict['arrival']
                        self.url = parcel_dict['url']
                        self.info = parcel_dict['info']
                        self.save()

        return {
            'parcel': self.parcel,
            'parcel_carrier': self.parcel_carrier,
            'arrival': self.arrival,
            'status': self.status,
            'info': self.info
        }
Example #4
0
    def update(self):
        """
        Update Weboob modules.
        """
        # Weboob has an offending print statement when it "Rebuilds index",
        # which happen at every run if the user has a local repository. We need
        # to silence it, hence the temporary redirect of stdout.
        sys.stdout = open(os.devnull, "w")
        try:
            self.weboob.update(progress=DummyProgress())
        except ConnectionError as exc:
            # Do not delete the repository if there is a connection error.
            raise exc
        except Exception:
            # Try to remove the data directory, to see if it changes a thing.
            # This is especially useful when a new version of Weboob is
            # published and/or the keyring changes.
            shutil.rmtree(self.weboob_data_path)
            os.makedirs(self.weboob_data_path)

            # Recreate the Weboob object as the directories are created
            # on creating the Weboob object.
            self.weboob = Weboob(workdir=self.weboob_data_path,
                                 datadir=self.weboob_data_path)

            # Rewrite sources.list file
            self.write_weboob_sources_list()

            # Retry update
            self.weboob.update(progress=DummyProgress())
        finally:
            # Restore stdout
            sys.stdout = sys.__stdout__
Example #5
0
def main(filename):
    weboob = Weboob()
    try:
        hds = weboob.build_backend('hds')
    except ModuleLoadError, e:
        print >>sys.stderr, 'Unable to load "hds" module: %s' % e
        return 1
Example #6
0
 def __init__(self, backend_name, download_directory, links_directory):
     self.download_directory = download_directory
     self.links_directory = links_directory
     self.backend_name = backend_name
     self.backend = None
     self.weboob = Weboob()
     self.weboob.load_backends(modules=[self.backend_name])
     self.backend=self.weboob.get_backend(self.backend_name)
Example #7
0
class BackendTest(TestCase):
    MODULE = None

    def __init__(self, *args, **kwargs):
        super(BackendTest, self).__init__(*args, **kwargs)

        self.backends = {}
        self.backend_instance = None
        self.backend = None
        self.weboob = Weboob()

        # Skip tests when passwords are missing
        self.weboob.requests.register('login', self.login_cb)

        if self.weboob.load_backends(modules=[self.MODULE]):
            # provide the tests with all available backends
            self.backends = self.weboob.backend_instances

    def login_cb(self, backend_name, value):
        raise SkipTest('missing config \'%s\' is required for this test' %
                       value.label)

    def run(self, result):
        """
        Call the parent run() for each backend instance.
        Skip the test if we have no backends.
        """
        # This is a hack to fix an issue with nosetests running
        # with many tests. The default is 1000.
        sys.setrecursionlimit(10000)
        try:
            if not len(self.backends):
                self.backend = self.weboob.build_backend(self.MODULE,
                                                         nofail=True)
                TestCase.run(self, result)
            else:
                # Run for all backend
                for backend_instance in self.backends.keys():
                    print(backend_instance)
                    self.backend = self.backends[backend_instance]
                    TestCase.run(self, result)
        finally:
            self.weboob.deinit()

    def shortDescription(self):
        """
        Generate a description with the backend instance name.
        """
        # do not use TestCase.shortDescription as it returns None
        return '%s [%s]' % (str(self), self.backend_instance)

    def is_backend_configured(self):
        """
        Check if the backend is in the user configuration file
        """
        return self.weboob.backends_config.backend_exists(
            self.backend.config.instname)
    def weboob_download(self, credentials, logs):
        logger.info(
            'Start weboob operations with module %s',
            self.weboob_module_id.name)
        w = Weboob()
        back = w.build_backend(
            self.weboob_module_id.name, params=credentials, name='odoo')

        try:
            sub = back.iter_subscription().next()
        except BrowserIncorrectPassword:
            logs['msg'].append(_('Wrong password.'))
            logs['result'] = 'failure'
            return []

        bills = back.iter_bills(sub)
        start_date = self.download_start_date
        invoices = []
        for bill in bills:
            logger.debug('bill.id=%s, bill.fullid=%s', bill.id, bill.fullid)
            inv_details = bill.to_dict()
            logger.info('bill.to_dict=%s', inv_details)
            # bill.to_dict=OrderedDict([
            # ('id', u'60006530609_216421161'),
            # ('url', u'https://api.bouyguestelecom.fr/comptes-facturat...'),
            # ('date', date(2018, 7, 16)),
            # ('format', u'pdf'),
            # ('label', u'Juillet 2018'),
            # ('type', u'bill'),
            # ('transactions', []),
            # ('price', Decimal('30.99')),
            # ('currency', u'EUR'),
            # ('vat', NotLoaded),
            # ('duedate', NotLoaded), ('startdate', NotLoaded),
            # ('finishdate', NotLoaded), ('income', False)])
            # Do we have invoice number here ? NO
            logger.info("Found invoice dated %s", inv_details.get('date'))
            if (
                    start_date and
                    inv_details.get('date') and
                    fields.Date.to_string(inv_details['date']) < start_date):
                logger.info(
                    'Skipping invoice %s dated %s dated before '
                    'download_start_date %s',
                    inv_details.get('label'), inv_details['date'], start_date)
                continue

            logger.info('Start to download bill with full ID %s', bill.fullid)
            pdf_inv = back.download_document(bill.id)
            filename = 'invoice_%s_%s.%s' % (
                self.weboob_module_id.name,
                inv_details.get('label') and
                inv_details['label'].replace(' ', '_'),
                inv_details.get('format', 'pdf'))
            invoices.append((pdf_inv.encode('base64'), filename))
        return invoices
 def __init__(self, name, backend_name, my_download_directory,
              my_links_directory):
     self.download_directory = my_download_directory
     self.links_directory = my_links_directory
     self.backend_name = backend_name
     self.backend = None
     self.weboob = Weboob()
     self.weboob.load_backends(modules=self.backend_name, )
     self.backend = self.weboob.get_backend(self.backend_name)
     self.name = name
Example #10
0
class BackendTest(TestCase):
    MODULE = None

    def __init__(self, *args, **kwargs):
        super(BackendTest, self).__init__(*args, **kwargs)

        self.backends = {}
        self.backend_instance = None
        self.backend = None
        self.weboob = Weboob()

        # Skip tests when passwords are missing
        self.weboob.requests.register('login', self.login_cb)

        if self.weboob.load_backends(modules=[self.MODULE]):
            # provide the tests with all available backends
            self.backends = self.weboob.backend_instances

    def login_cb(self, backend_name, value):
        raise SkipTest('missing config \'%s\' is required for this test' % value.label)

    def run(self, result):
        """
        Call the parent run() for each backend instance.
        Skip the test if we have no backends.
        """
        # This is a hack to fix an issue with nosetests running
        # with many tests. The default is 1000.
        sys.setrecursionlimit(10000)
        try:
            if not len(self.backends):
                self.backend = self.weboob.build_backend(self.MODULE, nofail=True)
                TestCase.run(self, result)
            else:
                # Run for all backend
                for backend_instance in self.backends.keys():
                    print(backend_instance)
                    self.backend = self.backends[backend_instance]
                    TestCase.run(self, result)
        finally:
            self.weboob.deinit()

    def shortDescription(self):
        """
        Generate a description with the backend instance name.
        """
        # do not use TestCase.shortDescription as it returns None
        return '%s [%s]' % (str(self), self.backend_instance)

    def is_backend_configured(self):
        """
        Check if the backend is in the user configuration file
        """
        return self.weboob.backends_config.backend_exists(self.backend.config.instname)
Example #11
0
    def __init__(self, *args, **kwargs):
        TestCase.__init__(self, *args, **kwargs)

        self.backends = {}
        self.backend_instance = None
        self.backend = None
        self.weboob = Weboob()

        if self.weboob.load_backends(modules=[self.BACKEND]):
            # provide the tests with all available backends
            self.backends = self.weboob.backend_instances
            # chose one backend (enough for most tests)
            self.backend_instance = choice(self.backends.keys())
            self.backend = self.backends[self.backend_instance]
Example #12
0
    def __init__(self, *args, **kwargs):
        super(BackendTest, self).__init__(*args, **kwargs)

        self.backends = {}
        self.backend_instance = None
        self.backend = None
        self.weboob = Weboob()

        # Skip tests when passwords are missing
        self.weboob.requests.register('login', self.login_cb)

        if self.weboob.load_backends(modules=[self.MODULE]):
            # provide the tests with all available backends
            self.backends = self.weboob.backend_instances
Example #13
0
def get_accounts(bname):
    w = Weboob()

    w.load_backends(names=[bname])
    backend = w.get_backend(bname)

    results = {}
    for account in backend.iter_accounts():
        # a unicode bigger than 8 characters used as key of the table make some bugs in the C++ code
        # convert to string before to use it
        results[str(account.id)] = {'name':    account.label,
                               'balance': int(account.balance * 100),
                               'type':    int(account.type),
                              }
    return results
Example #14
0
    def __init__(self):
        self.ind = appindicator.Indicator.new(APPINDICATOR_ID,
                                              os.path.abspath(resource_filename('boobank_indicator.data',
                                                                                'indicator-boobank.png')),
                                              appindicator.IndicatorCategory.APPLICATION_STATUS)

        self.menu = Gtk.Menu()
        self.ind.set_menu(self.menu)

        logging.basicConfig()
        if 'weboob_path' in os.environ:
            self.weboob = Weboob(os.environ['weboob_path'])
        else:
            self.weboob = Weboob()

        self.weboob.load_backends(CapBank)
Example #15
0
 def update_module_list(self):
     w = Weboob()
     logger.info('Weboob: calling update_repositories')
     w.repositories.update_repositories()
     weboob_modules = w.repositories.get_all_modules_info('CapDocument')
     module_name2obj = {}
     for module in self.search_read([], ['name']):
         module_name2obj[module['name']] = self.browse(module['id'])
     for name, info in weboob_modules.iteritems():
         vals = {
             'name': name,
             'maintainer': info.maintainer,
             'license': info.license,
             'description': info.description,
             'available_version': info.version,
             'state': 'uninstalled',
         }
         if info.is_installed():
             vals.update({
                 'has_parameters': self.has_parameter(w, name),
                 'state': 'installed',
                 'installed_version': info.version,
             })
         if name in module_name2obj:
             module_name2obj[name].write(vals)
         else:
             self.create(vals)
Example #16
0
    def update(self):
        """
        Update Weboob modules.
        """
        self.copy_fakemodules()

        # Weboob has an offending print statement when it "Rebuilds index",
        # which happen at every run if the user has a local repository. We need
        # to silence it, hence the temporary redirect of stdout.
        sys.stdout = open(os.devnull, "w")
        try:
            self.weboob.update(progress=DummyProgress())
        except ConnectionError as exc:
            # Do not delete the repository if there is a connection error.
            raise exc
        except Exception:
            # Try to remove the data directory, to see if it changes a thing.
            # This is especially useful when a new version of Weboob is
            # published and/or the keyring changes.
            shutil.rmtree(self.weboob_data_path)
            os.makedirs(self.weboob_data_path)

            # Recreate the Weboob object as the directories are created
            # on creating the Weboob object.
            self.weboob = Weboob(workdir=self.weboob_data_path,
                                 datadir=self.weboob_data_path)

            # Rewrite sources.list file
            self.write_weboob_sources_list()

            # Retry update
            self.weboob.update(progress=DummyProgress())
        finally:
            # Restore stdout
            sys.stdout = sys.__stdout__
Example #17
0
def get_accounts(bname):
    w = Weboob()

    w.load_backends(names=[bname])
    backend = w.get_backend(bname)

    results = {}
    for account in backend.iter_accounts():
        # a unicode bigger than 8 characters used as key of the table make some bugs in the C++ code
        # convert to string before to use it
        results[str(account.id)] = {
            'name': account.label,
            'balance': int(account.balance * 100),
            'type': int(account.type),
        }
    return results
Example #18
0
    def update(self):
        """
        Update Weboob modules.
        """
        self.copy_fakemodules()

        # Weboob has an offending print statement when it "Rebuilds index",
        # which happen at every run if the user has a local repository. We need
        # to silence it, hence the temporary redirect of stdout.
        sys.stdout = open(os.devnull, "w")

        # Create the backup before doing anything.
        self.backup_data_dir()

        try:
            self.weboob.update(progress=DummyProgress())
        except (ConnectionError, HTTPError) as exc:
            # Do not delete the repository if there is a connection error or the repo has problems.
            raise exc
        except Exception:
            # Try to remove the data directory, to see if it changes a thing.
            # This is especially useful when a new version of Weboob is
            # published and/or the keyring changes.
            shutil.rmtree(self.weboob_data_path)
            os.makedirs(self.weboob_data_path)

            # Recreate the Weboob object as the directories are created
            # on creating the Weboob object.
            self.weboob = Weboob(workdir=self.weboob_data_path,
                                 datadir=self.weboob_data_path)

            # Rewrite sources.list file
            self.write_weboob_sources_list()

            # Retry update
            try:
                self.weboob.update(progress=DummyProgress())
            except Exception as exc:
                # If it still fails, just restore the previous state.
                self.restore_data_dir()
                # Re-throw the exception so that the user is warned of the problem.
                raise exc
        finally:
            # Restore stdout
            sys.stdout = sys.__stdout__
            # Clean the backup.
            self.clean_data_dir_backup()
Example #19
0
def get_transactions(bname, accid, maximum):
    w = Weboob()

    w.load_backends(names=[bname])
    backend = w.get_backend(bname)

    acc = backend.get_account(accid)
    results = {}
    results['id'] = acc.id
    results['name'] = acc.label
    results['balance'] = int(acc.balance * 100)
    results['type'] = int(acc.type)
    results['transactions'] = []

    try:
        count = int(maximum)
        if count < 1:
            count = 0
    except:
        count = 0
    i = 0
    first = True
    rewriteid = False
    seen = set()
    for tr in backend.iter_history(acc):
        if first:
            if tr.id == u'0' or tr.id == u'':
                rewriteid = True
            first = False
        if rewriteid:
            tr.id = tr.unique_id(seen)
        t = {
            'id': tr.id,
            'date': tr.date.strftime('%Y-%m-%d'),
            'rdate': tr.rdate.strftime('%Y-%m-%d'),
            'type': int(tr.type),
            'raw': tr.raw,
            'category': tr.category,
            'label': tr.label,
            'amount': int(tr.amount * 100),
        }
        results['transactions'].append(t)
        i += 1
        if count != 0 and i >= count:
            break

    return results
Example #20
0
def get_transactions(bname, accid, maximum):
    w = Weboob()

    w.load_backends(names=[bname])
    backend = w.get_backend(bname)

    acc = backend.get_account(accid)
    results = {}
    results['id'] = acc.id
    results['name'] = acc.label
    results['balance'] = int(acc.balance * 100)
    results['type'] = int(acc.type)
    results['transactions'] = []

    try:
        count = int(maximum)
        if count < 1:
            count = 0
    except:
        count = 0
    i = 0
    first = True
    rewriteid = False
    seen = set()
    for tr in backend.iter_history(acc):
        if first:
            if tr.id == u'0' or tr.id == u'':
                rewriteid = True
            first = False
        if rewriteid:
            tr.id = tr.unique_id(seen)
        t = {'id':          tr.id,
             'date':        tr.date.strftime('%Y-%m-%d'),
             'rdate':       tr.rdate.strftime('%Y-%m-%d'),
             'type':        int(tr.type),
             'raw':         tr.raw,
             'category':    tr.category,
             'label':       tr.label,
             'amount':      int(tr.amount * 100),
        }
        results['transactions'].append(t)
        i += 1
        if count != 0 and i >= count:
            break

    return results
Example #21
0
    def __init__(self, *args, **kwargs):
        TestCase.__init__(self, *args, **kwargs)

        self.backend = None
        self.weboob = Weboob()

        if self.weboob.load_backends(modules=[self.BACKEND]):
            self.backend = choice(self.weboob.backend_instances.values())
Example #22
0
    def _get_all_transactions(self):

        weboob = Weboob()
        backend = weboob.load_backends(
            names=['bp'])['bp']  # TODO Make it generic

        account_transactions = []
        for account in backend.iter_accounts():
            if account.label != 'COMPTE BANCAIRE':  # TODO Make it generic
                continue
            for weboob_transaction in backend.iter_history(account):
                transaction = Transaction(date=weboob_transaction.date,
                                          amount=float(
                                              weboob_transaction.amount),
                                          label=weboob_transaction.label)
                account_transactions.append(transaction)
        return account_transactions
Example #23
0
 def __init__(self, backend_name, download_directory, links_directory):
     self.download_directory = download_directory
     self.links_directory = links_directory
     self.backend_name = backend_name
     self.backend = None
     self.weboob = Weboob()
     self.weboob.load_backends(modules=[self.backend_name])
     self.backend=self.weboob.get_backend(self.backend_name)
Example #24
0
def new_jobs():
    w = Weboob()
    w.load_backends(CapJob)
    #w['popolemploi']
    words = u'python'
    jobs = w.search_job(words)
    jobs = list(jobs)
    Poleemploi.query.delete()
    for job in jobs:
        new = Poleemploi(society_name=job.society_name,
                         place=job.place,
                         title=job.title,
                         contract_type=job.contract_type,
                         publication_date=job.publication_date)
        db.session.add(new)
        db.session.commit()
    return redirect(url_for('jobs_index'))
Example #25
0
    def __init__(self, weboob_data_path, fakemodules_path,
                 sources_list_content, is_prod):
        """
        Create a Weboob instance.

        :param weboob_data_path: Weboob path to use.
        :param fakemodules_path: Path to the fake modules directory in user
        data.
        :param sources_list_content: Optional content of the sources.list file,
        as an array of lines, or None if not present.
        :param is_prod: whether we're running in production or not.
        """
        # By default, consider we don't need to update the repositories.
        self.needs_update = False

        self.fakemodules_path = fakemodules_path
        self.sources_list_content = sources_list_content

        if not os.path.isdir(weboob_data_path):
            os.makedirs(weboob_data_path)

        # Set weboob data directory and sources.list file.
        self.weboob_data_path = weboob_data_path
        self.weboob_backup_path = os.path.normpath('%s.bak' % weboob_data_path)
        self.write_weboob_sources_list()

        # Create a Weboob object.
        self.weboob = Weboob(workdir=weboob_data_path,
                             datadir=weboob_data_path)
        self.backend = None
        self.storage = None

        # To make development more pleasant, always copy the fake modules in
        # non-production modes.
        if not is_prod:
            self.copy_fakemodules()

        # To make development more pleasant, always copy the fake modules in
        # non-production modes.
        if not is_prod:
            self.copy_fakemodules()

        # Update the weboob repos only if new repos are included.
        if self.needs_update:
            self.update()
Example #26
0
def bank_connection_and_load_transactions(request, pk):
    bank = get_object_or_404(Banks, pk=pk)
    w = Weboob()

    # TODO: Vérifier que les champs ne sont pas vide avant de lancer la connexion
    # TODO: si erreur de connexion, alors raise une erreur et revenir vers une autre page ?
    # TODO: affecter un owner_of_account lorsqu'un account est créé

    if request.method == 'POST':
        form = BankConnectionForm(instance=bank, data=request.POST)

        if form.is_valid():
            # TODO: vérifier que le mot de passe est identique à celui stocké en base if any (sous forme cryptée)
            logger.warning(
                '============= bank_connection_and_load_transactions __ bank.module_weboob.name_of_module = :: %s',
                bank.module_weboob.name_of_module)
            wb = w.load_backend(
                bank.module_weboob.name_of_module, bank.name_of_bank, {
                    'login': form.cleaned_data['bank_login'],
                    'password': form.cleaned_data['bank_password']
                })

            # Get list of available account(s) in the bank
            list_of_accounts = list(wb.iter_accounts())

            # Get list of transactions coming from bank history
            context = load_transactions(request, wb, bank, list_of_accounts)
            return render(request,
                          'ManageGesfi/load_transactions_from_account.html',
                          context)

    else:
        form = BankConnectionForm(instance=bank)

    context = {
        'bank': bank,
        'form': form,
    }
    return render(
        request, 'banksandaccounts/bank_connection_and_load_transactions.html',
        context)
Example #27
0
def load_list_of_modules_in_database(request):
    '''
    function to load list of weboob modules in database
    :param request:
    :return:
    '''
    w = Weboob()
    w.update()

    listbanks = w.repositories.get_all_modules_info(CapBank)

    db_wm_list = WeboobModules.objects.all()

    list_of_db_modules = []
    for key in db_wm_list:
        list_of_db_modules.append(key.name_of_module)

    list_of_banks = []
    for key, val in listbanks.items():
        wm = WeboobModules()
        data_bank = {}

        data_bank['module'] = key
        wm.name_of_module = key

        data_bank['description'] = val.description
        wm.description_of_module = val.description

        list_of_banks.append(data_bank)
        if wm.name_of_module not in list_of_db_modules:
            wm.save()

    list_of_banks.sort(key=lambda k: k['module'])

    db_wm_list = WeboobModules.objects.all()


    # context = {'list_of_banks': list_of_banks}
    context = {'list_of_banks': db_wm_list, 'load': True}

    return render(request, 'ManageWeboob/list_of_available_modules.html', context)
Example #28
0
class BackendTest(TestCase):
    MODULE = None

    def __init__(self, *args, **kwargs):
        TestCase.__init__(self, *args, **kwargs)

        self.backends = {}
        self.backend_instance = None
        self.backend = None
        self.weboob = Weboob()

        if self.weboob.load_backends(modules=[self.MODULE]):
            # provide the tests with all available backends
            self.backends = self.weboob.backend_instances
            # chose one backend (enough for most tests)
            self.backend_instance = choice(self.backends.keys())
            self.backend = self.backends[self.backend_instance]

    def run(self, result):
        """
        Call the parent run() for each backend instance.
        Skip the test if we have no backends.
        """
        # This is a hack to fix an issue with nosetests running
        # with many tests. The default is 1000.
        sys.setrecursionlimit(10000)
        try:
            if not len(self.backends):
                result.startTest(self)
                result.stopTest(self)
                raise SkipTest('No backends configured for this module.')
            TestCase.run(self, result)
        finally:
            self.weboob.deinit()

    def shortDescription(self):
        """
        Generate a description with the backend instance name.
        """
        # do not use TestCase.shortDescription as it returns None
        return '%s [%s]' % (str(self), self.backend_instance)
Example #29
0
    def banks_supported():
        """
        Return all the banks supported by weboob.
        :return: [(module_name, Module_description)]
        """
        banks_supported = []
        weboob = Weboob()
        modules = weboob.repositories.get_all_modules_info(CapBank)
        for bank_module_name, info in modules.items():
            banks_supported.append((bank_module_name, info.description))

        return banks_supported
Example #30
0
class Boobpeg:
    """ Class that performs requests using weboob capabitilities """
    def __init__(self):
        logger.debug("class init")
        self.peg_perco_names = []
        self.weboob = Weboob()
        self.weboob.load_backends(CapBank)
        logger.debug('backends loaded: %s' % list(self.weboob.iter_backends()))
        self.investments = {}

    def set_peg_perco_names(self, peg_perco_names):
        logger.debug("set_peg_perco_names(): peg_perco_names: %s" %
                     peg_perco_names)
        self.peg_perco_names = peg_perco_names

    def retrieve_investments(self, account):
        logger.debug("retrieve_investments(): account: %s" % account)
        account_investments = {}
        for investment in list(self.weboob.iter_investment(account)):
            account_investments[investment.code] = str(investment.unitvalue)
        logger.debug("retrieve_investments(): return: %s" %
                     account_investments)
        return account_investments

    def update_investments(self):
        logger.debug("update_investments()")
        accounts = list(self.weboob.iter_accounts())
        logger.debug("update_investments(): accounts: %s" % accounts)
        for account in accounts:
            if account.label in self.peg_perco_names:
                logger.debug('update_investments(): account "%s" is in the '
                             'account list to check' % account.label)
                self.investments.update(self.retrieve_investments(account))
            else:
                logger.debug('update_investments(): account "%s" is NOT in the'
                             ' account list to check' % account.label)

        logger.debug("update_investments(): return: %s" % self.investments)
        return self.investments
Example #31
0
def get_backends():
    w = Weboob()

    result = {}
    for instance_name, name, params in sorted(
            w.backends_config.iter_backends()):
        module = w.modules_loader.get_or_load_module(name)
        if not module.has_caps(CapBank):
            continue

        result[instance_name] = {'module': name}

    return result
Example #32
0
    def __init__(self, *args, **kwargs):
        super(BackendTest, self).__init__(*args, **kwargs)

        self.backends = {}
        self.backend_instance = None
        self.backend = None
        self.weboob = Weboob()

        # Skip tests when passwords are missing
        self.weboob.requests.register('login', self.login_cb)

        if self.weboob.load_backends(modules=[self.MODULE]):
            # provide the tests with all available backends
            self.backends = self.weboob.backend_instances
Example #33
0
 def install(self):
     w = Weboob()
     for module in self:
         if module.state == 'uninstalled':
             logger.info('Starting to install weboob module %s',
                         module.name)
             w.repositories.install(module.name)
             has_parameter = self.has_parameter(w, module.name)
             module.write({
                 'state': 'installed',
                 'installed_version': module.available_version,
                 'has_parameter': has_parameter,
             })
             logger.info('Weboob module %s is now installed', module.name)
Example #34
0
    def __init__(self, *args, **kwargs):
        TestCase.__init__(self, *args, **kwargs)

        self.backends = {}
        self.backend_instance = None
        self.backend = None
        self.weboob = Weboob()

        if self.weboob.load_backends(modules=[self.BACKEND]):
            # provide the tests with all available backends
            self.backends = self.weboob.backend_instances
            # chose one backend (enough for most tests)
            self.backend_instance = choice(self.backends.keys())
            self.backend = self.backends[self.backend_instance]
class RboorrentDownload(object):
    def __init__(self, _id, no_tracker):
        self.id, self.backend_name = _id.split("@")
        self.no_tracker = no_tracker
        self.weboob = Weboob()
        self.backend = self.weboob.load_backends(
            modules=[self.backend_name])[self.backend_name]

    def get_magnet(self, torrent):
        if self.no_tracker:
            return "&".join([
                _ for _ in torrent.magnet.split("&") if not _.startswith("tr=")
            ])
        else:
            return torrent.magnet

    def write_meta(self, torrent):
        dest = "meta-%s-%s.torrent" % (torrent.id, torrent.name)
        magnet = self.get_magnet(torrent)
        buf = "d10:magnet-uri%d:%se" % (len(magnet), magnet)
        try:
            with open(dest, 'w') as f:
                f.write(buf)
        except IOError as e:
            print('Unable to write "%s": %s' % (dest, e.message))

    def write_torrent(self, torrent):
        dest = "%s-%s.torrent" % (torrent.id, torrent.name)
        try:
            buf = self.backend.get_torrent_file(torrent.id)
            if buf:
                try:
                    with open(dest, 'w') as f:
                        f.write(buf)
                except IOError as e:
                    print('Unable to write "%s": %s' % (dest, e))
        except Exception as e:
            print("Could not get torrent file for %s@%s" %
                  (self.id, self.backend_name))

    def run(self):
        try:
            torrent = self.backend.get_torrent(self.id)
            if torrent.magnet:
                self.write_meta(torrent)
            else:
                self.write_torrent(torrent)
        except HTTPNotFound:
            print("Could not find %s@%s" % (self.id, self.backend_name))
Example #36
0
def bank_create_with_weboob_module(request, pk):

    w = Weboob()

    if request.method == 'POST':
        form = BankForm(data=request.POST)
        if form.is_valid():
            bank = form.save(commit=False)
            bank.bank_password = make_password(
                form.cleaned_data['bank_password'])
            bank.save()

            w.load_backend(
                bank.module_weboob.name_of_module, bank.name_of_bank, {
                    'login': form.cleaned_data['bank_login'],
                    'password': form.cleaned_data['bank_password']
                })

            # Get list of available account(s) in the bank
            list_of_accounts = list(w.iter_accounts())

            # Get list of transactions coming from bank history
            context = load_transactions(request, w, bank, list_of_accounts)
            return render(request,
                          'ManageGesfi/load_transactions_from_account.html',
                          context)

    else:
        form = BankForm()

    context = {
        'form': form,
        'create': True
        # TODO: ajouter un flag "create with weboob" pour rediriger vers load_transactions (et créer les comptes)
    }
    return render(request, 'banksandaccounts/bank_edit.html', context)
Example #37
0
    def __init__(self, weboob_data_path):
        """
        Create a Weboob instance.

        :param weboob_data_path: Weboob path to use.
        """
        # By default, consider we don't need to update the repositories.
        self.needs_update = False

        if not os.path.isdir(weboob_data_path):
            os.makedirs(weboob_data_path)

        # Set weboob data directory and sources.list file.
        self.weboob_data_path = weboob_data_path
        self.write_weboob_sources_list()

        # Create a Weboob object.
        self.weboob = Weboob(workdir=weboob_data_path,
                             datadir=weboob_data_path)
        self.backends = collections.defaultdict(dict)

        # Update the weboob repos only if new repos are included.
        if self.needs_update:
            self.update()
Example #38
0
class RboorrentDownload(object):
    def __init__(self, _id, no_tracker):
        self.id, self.backend_name = _id.split("@")
        self.no_tracker = no_tracker
        self.weboob = Weboob()
        self.backend = self.weboob.load_backends(modules=[self.backend_name])[self.backend_name]

    def get_magnet(self, torrent):
        if self.no_tracker:
            return "&".join([_ for _ in torrent.magnet.split("&") if not _.startswith("tr=")])
        else:
            return torrent.magnet

    def write_meta(self, torrent):
        dest = "meta-%s-%s.torrent" % (torrent.id, torrent.name)
        magnet = self.get_magnet(torrent)
        buf = "d10:magnet-uri%d:%se" % (len(magnet), magnet)
        try:
            with open(dest, 'w') as f:
                f.write(buf)
        except IOError as e:
            print('Unable to write "%s": %s' % (dest, e.message))

    def write_torrent(self, torrent):
        dest = "%s-%s.torrent" % (torrent.id, torrent.name)
        try:
            buf = self.backend.get_torrent_file(torrent.id)
            if buf:
                try:
                    with open(dest, 'w') as f:
                        f.write(buf)
                except IOError as e:
                    print('Unable to write "%s": %s' % (dest, e))
        except Exception as e:
            print("Could not get torrent file for %s@%s" % (self.id, self.backend_name))

    def run(self):
        try:
            torrent = self.backend.get_torrent(self.id)
            if torrent.magnet:
                self.write_meta(torrent)
            else:
                self.write_torrent(torrent)
        except HTTPNotFound:
            print("Could not find %s@%s" % (self.id, self.backend_name))
Example #39
0
class BackendTest(TestCase):
    BACKEND = None

    def __init__(self, *args, **kwargs):
        TestCase.__init__(self, *args, **kwargs)

        self.backend = None
        self.weboob = Weboob()

        if self.weboob.load_backends(modules=[self.BACKEND]):
            self.backend = choice(self.weboob.backend_instances.values())

    def run(self, result):
        if not self.backend:
            result.startTest(self)
            result.stopTest(self)
            raise SkipTest()

        return TestCase.run(self, result)
 def weboob_module_id_change(self):
     if self.weboob_module_id and self.weboob_module_id.has_parameters:
         w = Weboob()
         bmod = w.modules_loader.get_or_load_module(
             self.weboob_module_id.name)
         new_params = self.env['weboob.parameter']
         for key, value in bmod.config.iteritems():
             if key not in ['login', 'password']:
                 note = value.label or ''
                 if value.choices:
                     options = ', '.join([
                         "'%s' (%s)" % (key_opt, help_opt)
                         for (key_opt, help_opt) in value.choices.items()])
                     note = _("%s. Possible values: %s.") % (note, options)
                 param = new_params.new({
                     'key': key,
                     'note': note,
                     })
                 new_params += param
         self.weboob_parameter_ids = new_params
Example #41
0
    def __init__(self, weboob_data_path, fakemodules_path, sources_list_content, is_prod):
        """
        Create a Weboob instance.

        :param weboob_data_path: Weboob path to use.
        :param fakemodules_path: Path to the fake modules directory in user
        data.
        :param sources_list_content: Optional content of the sources.list file,
        as an array of lines, or None if not present.
        :param is_prod: whether we're running in production or not.
        """
        # By default, consider we don't need to update the repositories.
        self.needs_update = False

        self.fakemodules_path = fakemodules_path
        self.sources_list_content = sources_list_content

        if not os.path.isdir(weboob_data_path):
            os.makedirs(weboob_data_path)

        # Set weboob data directory and sources.list file.
        self.weboob_data_path = weboob_data_path
        self.write_weboob_sources_list()

        # Create a Weboob object.
        self.weboob = Weboob(workdir=weboob_data_path,
                             datadir=weboob_data_path)
        self.backend = None
        self.storage = None

        # To make development more pleasant, always copy the fake modules in
        # non-production modes.
        if not is_prod:
            self.copy_fakemodules()

        # Update the weboob repos only if new repos are included.
        if self.needs_update:
            self.update()
Example #42
0
class BoobankChecker():
    def __init__(self):
        self.ind = appindicator.Indicator.new(APPINDICATOR_ID,
                                              os.path.abspath(resource_filename('boobank_indicator.data',
                                                                                'indicator-boobank.png')),
                                              appindicator.IndicatorCategory.APPLICATION_STATUS)

        self.menu = Gtk.Menu()
        self.ind.set_menu(self.menu)

        logging.basicConfig()
        if 'weboob_path' in os.environ:
            self.weboob = Weboob(os.environ['weboob_path'])
        else:
            self.weboob = Weboob()

        self.weboob.load_backends(CapBank)

    def clean_menu(self, menu):
        for i in menu.get_children():
            submenu = i.get_submenu()
            if submenu:
                self.clean_menu(i)
            menu.remove(i)

    def check_boobank(self):
        self.ind.set_status(appindicator.IndicatorStatus.ACTIVE)
        self.clean_menu(self.menu)

        total = 0
        currency = ''
        threads = []

        try:
            for account in self.weboob.do('iter_accounts'):

                balance = account.balance
                if account.coming:
                    balance += account.coming

                if account.type != Account.TYPE_LOAN:
                    total += balance
                    image = "green_light.png" if balance > 0 else "red_light.png"
                else:
                    image = "personal-loan.png"

                currency = account.currency_text
                label = "%s: %s%s" % (account.label, balance, account.currency_text)
                account_item = create_image_menu_item(label, image)
                thread = BoobankTransactionsChecker(self.weboob, account_item, account)
                thread.start()
                threads.append(thread)

        except CallErrors as errors:
            self.bcall_errors_handler(errors)

        for thread in threads:
            thread.join()

        for thread in threads:
            self.menu.append(thread.menu)
            thread.menu.show()

        if len(self.menu.get_children()) == 0:
            Notify.Notification.new('<b>Boobank</b>',
                                    'No Bank account found\n Please configure one by running boobank',
                                    'notification-message-im').show()

        sep = Gtk.SeparatorMenuItem()
        self.menu.append(sep)
        sep.show()

        total_item = Gtk.MenuItem("%s: %s%s" % ("Total", total, currency))
        self.menu.append(total_item)
        total_item.show()

        sep = Gtk.SeparatorMenuItem()
        self.menu.append(sep)
        sep.show()

        btnQuit = Gtk.ImageMenuItem()
        image = Gtk.Image()
        image.set_from_stock(Gtk.STOCK_QUIT, Gtk.IconSize.BUTTON)
        btnQuit.set_image(image)
        btnQuit.set_label('Quit')
        btnQuit.set_always_show_image(True)
        btnQuit.connect("activate", self.quit)
        self.menu.append(btnQuit)
        btnQuit.show()

    def quit(self, widget):
        Gtk.main_quit()

    def bcall_errors_handler(self, errors):
        """
        Handler for the CallErrors exception.
        """
        self.ind.set_status(appindicator.IndicatorStatus.ATTENTION)
        for backend, error, backtrace in errors.errors:
            notify = True
            if isinstance(error, BrowserIncorrectPassword):
                msg = 'invalid login/password.'
            elif isinstance(error, BrowserSSLError):
                msg = '/!\ SERVER CERTIFICATE IS INVALID /!\\'
            elif isinstance(error, BrowserForbidden):
                msg = unicode(error) or 'Forbidden'
            elif isinstance(error, BrowserUnavailable):
                msg = unicode(error)
                if not msg:
                    msg = 'website is unavailable.'
            elif isinstance(error, NotImplementedError):
                notify = False
            elif isinstance(error, UserError):
                msg = unicode(error)
            elif isinstance(error, MoreResultsAvailable):
                notify = False
            else:
                msg = unicode(error)

            if notify:
                Notify.Notification.new('<b>Error Boobank: %s</b>' % backend.name,
                                        msg,
                                        'notification-message-im').show()

    def main(self):
        self.check_boobank()
        GObject.timeout_add(PING_FREQUENCY * 1000, self.check_boobank)
        Gtk.main()
Example #43
0
def main(filename):
    weboob = Weboob()
    try:
        hds = weboob.build_backend('hds')
    except ModuleLoadError as e:
        print('Unable to load "hds" module: %s' % e, file=sys.stderr)
        return 1

    try:
        db = sqlite.connect(database=filename, timeout=10.0)
    except sqlite.OperationalError as err:
        print('Unable to open %s database: %s' % (filename, err), file=sys.stderr)
        return 1

    sys.stdout.write('Reading database... ')
    sys.stdout.flush()
    try:
        results = db.execute('SELECT id, author FROM stories')
    except sqlite.OperationalError as err:
        print('fail!\nUnable to read database: %s' % err, file=sys.stderr)
        return 1

    stored = set()
    authors = set()
    for r in results:
        stored.add(r[0])
        authors.add(r[1])
    stored_authors = set([s[0] for s in db.execute('SELECT name FROM authors')])
    sys.stdout.write('ok\n')

    br = hds.browser
    to_fetch = set()
    sys.stdout.write('Getting stories list from website... ')
    sys.stdout.flush()
    for story in br.iter_stories():
        if int(story.id) in stored:
            break
        to_fetch.add(story.id)
        authors.add(story.author.name)
    sys.stdout.write(' ok\n')

    sys.stdout.write('Getting %d new storiese... ' % len(to_fetch))
    sys.stdout.flush()
    for id in to_fetch:
        story = br.get_story(id)
        if not story:
            logging.warning('Story #%d unavailable' % id)
            continue

        db.execute("""INSERT INTO stories (id, title, date, category, author, body)
                             VALUES (?, ?, ?, ?, ?, ?)""",
                   (story.id, story.title, story.date, story.category,
                    story.author.name, story.body))
        db.commit()
    sys.stdout.write('ok\n')

    authors = authors.difference(stored_authors)
    sys.stdout.write('Getting %d new authors... ' % len(authors))
    sys.stdout.flush()
    for a in authors:
        author = br.get_author(a)
        if not author:
            logging.warning('Author %s unavailable\n' % id)
            continue

        db.execute("INSERT INTO authors (name, sex, description) VALUES (?, ?, ?)",
                   (a, author.sex, author.description))
        db.commit()
    sys.stdout.write(' ok\n')
    return 0
Example #44
0
class MyThread(Thread):
    daemon = True

    def __init__(self, bot):
        Thread.__init__(self)
        self.weboob = Weboob(storage=StandardStorage(STORAGE_FILE))
        self.weboob.load_backends()
        self.bot = bot
        self.bot.set_weboob(self.weboob)

    def run(self):
        for ev in self.bot.joined.itervalues():
            ev.wait()

        self.weboob.repeat(300, self.check_board)
        self.weboob.repeat(600, self.check_dlfp)
        self.weboob.repeat(600, self.check_twitter)

        self.weboob.loop()

    def find_keywords(self, text):
        for word in [
            'weboob', 'videoob', 'havesex', 'havedate', 'monboob', 'boobmsg',
            'flatboob', 'boobill', 'pastoob', 'radioob', 'translaboob', 'traveloob', 'handjoob',
            'boobathon', 'boobank', 'boobtracker', 'comparoob', 'wetboobs',
            'webcontentedit', 'weboorrents', 'assnet', 'budget insight', 'budget-insight', 'budgetinsight', 'budgea']:
            if word in text.lower():
                return word
        return None

    def check_twitter(self):
        nb_tweets = 10

        for backend in self.weboob.iter_backends(module='twitter'):
            for thread in list(itertools.islice(backend.iter_resources(None, ['search', 'weboob']),
                                                0,
                                                nb_tweets)):

                if not backend.storage.get('lastpurge'):
                    backend.storage.set('lastpurge', datetime.now() - timedelta(days=60))
                    backend.storage.save()

                if thread.id not in backend.storage.get('seen', default={}) and\
                   thread.date > backend.storage.get('lastpurge'):
                    _item = thread.id.split('#')
                    url = 'https://twitter.com/%s/status/%s' % (_item[0], _item[1])
                    for msg in self.bot.on_url(url):
                        self.bot.send_message('%s: %s' % (_item[0], url))
                        self.bot.send_message(msg)

                    backend.set_message_read(backend.fill_thread(thread, ['root']).root)

    def check_dlfp(self):
        for msg in self.weboob.do('iter_unread_messages', backends=['dlfp']):
            word = self.find_keywords(msg.content)
            if word is not None:
                url = msg.signature[msg.signature.find('https://linuxfr'):]
                self.bot.send_message('[DLFP] %s talks about %s: %s' % (
                    msg.sender, word, url))
            self.weboob[msg.backend].set_message_read(msg)

    def check_board(self):
        def iter_messages(backend):
            with backend.browser:
                return backend.browser.iter_new_board_messages()

        for msg in self.weboob.do(iter_messages, backends=['dlfp']):
            word = self.find_keywords(msg.message)
            if word is not None and msg.login != 'moules':
                message = msg.message.replace(word, '\002%s\002' % word)
                self.bot.send_message('[DLFP] <%s> %s' % (msg.login, message))

    def stop(self):
        self.weboob.want_stop()
        self.weboob.deinit()
Example #45
0
 def __init__(self, bot):
     Thread.__init__(self)
     self.weboob = Weboob(storage=StandardStorage(STORAGE_FILE))
     self.weboob.load_backends()
     self.bot = bot
     self.bot.set_weboob(self.weboob)
class DownloadBoob(object):
    """
        Search and download
        :param name:
        :param backend_name:
        :param my_download_directory:
        :param my_links_directory:
    """

    def __init__(self, name, backend_name, my_download_directory,
                 my_links_directory):
        self.download_directory = my_download_directory
        self.links_directory = my_links_directory
        self.backend_name = backend_name
        self.backend = None
        self.weboob = Weboob()
        self.weboob.load_backends(modules=self.backend_name, )
        self.backend = self.weboob.get_backend(self.backend_name)
        self.name = name

    def get_filename(self, video, relative=False, m3u=False):
        """
            Generate filename for the video
            :param relative:
            :param m3u:
            :param video:
            :rtype : string
        """
        if relative:
            directory = os.path.join("..", DOWNLOAD_DIRECTORY,
                                     self.backend_name)
        else:
            directory = os.path.join(self.download_directory, self.backend_name)
            if not os.path.exists(directory.encode('utf8')):
                os.makedirs(directory.encode('utf8'))
        if not m3u:
            ext = video.ext
            if not ext:
                ext = 'avi'
        else:
            ext = 'm3u'
        return "%s/%s.%s" % (directory, removenonascii(video.id), ext)

    def get_linkname(self, video, m3u=False):
        """
            Generate filename for the link
            :param m3u:
            :param video:
            :rtype : string
        """
        if not os.path.exists(self.links_directory.encode('utf8')):
            os.makedirs(self.links_directory.encode('utf8'))
        if not m3u:
            ext = video.ext
            if not ext:
                ext = 'avi'
        else:
            ext = 'm3u'
        if not kodi:
            misc = video.date.strftime("%y-%m-%d")
            if not misc:
                misc = video.id
            return "%s/%s (%s).%s" % (self.links_directory,
                                      removespecial(video.title),
                                      removespecial(misc), ext)
        else:
            return "%s/%s.%s" % (self.links_directory,
                                 removespecial(video.title), ext)

    def is_downloaded(self, video):
        """
            Check if the video has already been downloaded
            :param video:
            :rtype : bool
        """
        if (os.path.isfile(self.get_filename(video).encode('utf8')) or
            os.path.isfile(self.get_filename(video,
                                             m3u=True).encode('utf8'))):
            logging.info("%s Already downloaded : %s" %
                         (video.id, video.title))
            return True
        logging.debug("%s To be downloaded : %s" %
                      (video.id, video.title))
        return False

    def init_dir(self):
        """
            create directory
        """
        if not os.path.isdir(self.links_directory.encode('utf8')):
            logging.debug("  create link directory : %s" % self.links_directory)
            os.makedirs(self.links_directory.encode('utf8'))
        else:
            logging.debug("  existing link directory : %s" % self.links_directory)
        if kodi:
            file_name = os.path.join(self.links_directory, 'tvshow.nfo')
            show_name = self.links_directory.split("/")[-1]
            if not os.path.isfile(file_name.encode('utf8')):
                logging.debug("  create %s" % file_name)
                f = codecs.open(file_name, "w", "utf-8")
                f.write(u"<tvshow>\n")
                f.write(u"  <title>" + show_name + u"</title>\n")
                f.write(u"</tvshow>\n")
                f.close()
            else:
                logging.debug("  existing %s" % file_name)

    def do_search(self,
                  pattern=None,
                  pattern_type="search",
                  sortby=CapVideo.SEARCH_RELEVANCE,
                  nsfw=False):
        """
            Search for videos
            :param pattern:
            :param pattern_type:
            :param sortby:
            :param nsfw:
            :return:
        """
        logging.debug("  Searching for videos for %s" % self.name)
        list_videos = []
        if pattern_type == "search":
            list_videos = self.backend.search_videos(pattern, sortby, nsfw)
        elif pattern_type == "ls":
            sys.path.insert(
                0, backend_directory + "/" + self.backend.name + "/"
            )  # HACK
            if 'video' in sys.modules:
                del sys.modules['video']
            if self.backend.name == "arte":
                from video import ArteVideo as Video_Init
            elif self.backend.name == "canalplus":
                from video import CanalplusVideo as Video_Init
            elif self.backend.name == "arretsurimages":
                from video import ArretSurImagesVideo as Video_Init
            elif self.backend.name == "dailymotion":
                from video import DailymotionVideo as Video_Init
            elif self.backend.name == "nolifetv":
                from video import NolifeTVVideo as Video_Init
            elif self.backend.name == "youtube":
                from video import YoutubeVideo as Video_Init
            else:
                from weboob.capabilities.video import BaseVideo as Video_Init  # END OF HACK
            for videoid in videoob_list_rep(pattern, self.backend):
                list_videos.append(Video_Init(videoid))
        if list_videos:
            logging.debug("  found videos for %s" % self.name)
        else:
            logging.error("  did not found videos for %s" % self.name)
        return list_videos

    def filter_list(self, list_videos, title_regexp, id_regexp, author_regexp,
                    title_exclude, max_results):
        """
            Filter the list after the search
            :param list_videos:
            :param title_regexp:
            :param id_regexp:
            :param author_regexp:
            :param title_exclude:
            :param max_results:
            :return:
        """
        logging.debug("  filtering list of found video for %s" % self.name)
        videos = []
        num_videos = 0
        for video in list_videos:
            if is_ok(video, title_regexp, id_regexp, author_regexp,
                     title_exclude):
                if not self.is_downloaded(video):
                    videoob_get_info(self.backend, video)
                    if not video:
                        logging.error('Error in Video: %s' % video)
                    elif not video.url:
                        logging.error(
                            'Error: the URL is not available : %s (%s)' %
                            (video.url, video.id))
                    else:
                        if is_ok(video, title_regexp, id_regexp, author_regexp,
                                 title_exclude):
                            num_videos += 1
                            if not self.is_downloaded(video):
                                videos.append(video)
                                print("New Video :  %s" % video.title)
                                print("    Description:%s" % video.description)
                                print("    Author:%s" % video.author)
                                print("    Id:%s" % video.id)
                                print("    Duration:%s" % video.duration)
                                print("    Date:%s" % video.date)
                            if num_videos == max_results:
                                break
        return videos

    def write_m3u(self, video):
        """
            Write m3u file for streaming files
            :param video:
            :return:
        """
        logging.debug("  Write m3u for %s" % video.title)
        if video.ext == "m3u" or video.ext == "m3u8":
            return do_download(video, self.get_filename(video))
        else:
            if matched(video.url, "\.m3u") or matched(video.url, "\.m3u8"):
                return do_download(video, self.get_filename(video))
            else:
                dest = self.get_filename(video, m3u=True)
                show_name = self.links_directory.split("/")[-1]
                logging.debug("  create %s" % dest)
                f = codecs.open(dest, "w", "utf-8")
                f.write("#EXTINF: ")
                if video.duration:
                    f.write(str(video.duration))
                else:
                    f.write(str(-1))
                f.write(", " + show_name + " - " + video.title + "\n")
                f.write(video.url)
                f.close()
                return 0

    def set_link(self, video, m3u=False):
        """
            Create link file
            :param video:
            :param m3u:
        """
        linkname = self.get_linkname(video, m3u=m3u)
        idname = self.get_filename(video, relative=True, m3u=m3u)
        absolute_idname = self.get_filename(video, m3u=m3u)
        if not os.path.islink(linkname.encode('utf8')) and os.path.isfile(absolute_idname.encode('utf8')):
            logging.info("  %s -> %s" % (linkname, idname))
            os.symlink(idname.encode('utf8'), linkname.encode('utf8'))
        else:
            logging.debug("  Not generating link for %s" % video.title)

    def do_mv(self, video, m3u=False):
        """
            move video file after download
            :param video:
            :param m3u:
        """
        linkname = self.get_linkname(video, m3u=m3u)
        absolute_idname = self.get_filename(video, m3u=m3u)
        if not os.path.isfile(linkname.encode('utf8')) and os.path.isfile(absolute_idname.encode('utf8')):
            logging.info("  %s => %s" % (absolute_idname, linkname))
            os.rename(absolute_idname.encode('utf8'), linkname.encode('utf8'))
            open(absolute_idname, 'w').close()
        else:
            logging.debug("  Not moving file %s" % linkname)

    def download(self,
                 pattern=None,
                 sortby=CapVideo.SEARCH_RELEVANCE,
                 nsfw=False,
                 max_results=20,
                 title_regexp=None,
                 id_regexp=None,
                 pattern_type="search",
                 author_regexp=None,
                 title_exclude=None):
        # create directory for links
        """
            Main process
            :param pattern:
            :param sortby:
            :param nsfw:
            :param max_results:
            :param title_regexp:
            :param id_regexp:
            :param pattern_type:
            :param author_regexp:
            :param title_exclude:
        """
        self.init_dir()

        # search for videos
        list_videos = self.do_search(pattern, pattern_type, sortby, nsfw)

        # Filter the list of videos
        videos = self.filter_list(list_videos, title_regexp, id_regexp,
                                  author_regexp, title_exclude, max_results)

        # download videos
        if videos:
            for video in videos:
                print("Downloading... " + video.title)
                if kodi:  # THE "TITLE" BECOME "S00E00 - TITLE (ID)"
                    rewrite_title(video)
                if down_live:  # CREATE LIVE STREAM
                    ret = self.write_m3u(video)
                else:  # DOWNLOAD VIDEO
                    ret = do_download(video, self.get_filename(video)
                                      )  # FOR DIRECT LINKS
                    if not ret:
                        ret = do_conv(video, self.get_filename(video)
                                      )  # FOR INDIRECT LINKS
                if not ret:
                    if not kodi:
                        self.set_link(
                            video
                        )  # CREATE LINKS FOR A BEAUTIFULL LIBRARY
                    else:
                        self.do_mv(video)  # MOVE FILES FOR A BEAUTIFULL LIBRARY
                        # CREATE NFO FILES FOR KODI
                        write_nfo(self.get_linkname(video),
                                  self.links_directory, self.backend_name,
                                  video)
                    print("Downloaded : " + video.title)
                else:
                    assert isinstance(video.title, basestring)
                    print("Failed download :" + video.title)
Example #47
0
class Downloadboob(object):

    def __init__(self, backend_name, download_directory, links_directory):
        self.download_directory = download_directory
        self.links_directory = links_directory
        self.backend_name = backend_name
        self.backend = None
        self.weboob = Weboob()
        self.weboob.load_backends(modules=[self.backend_name])
        self.backend=self.weboob.get_backend(self.backend_name)

    def purge(self):
        if not os.path.isdir(self.links_directory):
            return
        dirList=os.listdir(self.links_directory)
        for local_link_name in dirList:
            link_name = self.links_directory + "/" + local_link_name
            if not self.check_link(link_name):
                print u"Remove %s" % link_name
                os.remove(link_name)
            else:
                print u"Keep %s" % link_name

    def check_link(self, link_name):
        if os.path.islink(link_name):
            file_name = os.readlink(link_name)
            absolute_file_name = os.path.join(self.links_directory, file_name)
            if os.path.isfile(absolute_file_name):
                return True
            return False
        else:
            return True

    def download(self, pattern=None, sortby=CapVideo.SEARCH_RELEVANCE, nsfw=False, max_results=None, title_exclude=[], id_regexp=None):
        print "For backend %s, search for '%s'" % (backend_name, pattern)

        # create directory for links
        print "  create link to %s" % self.links_directory
        if not os.path.isdir(self.links_directory):
            os.makedirs(self.links_directory)

        # search for videos
        videos = []
        for i, video in enumerate(self.backend.search_videos(pattern, sortby, nsfw)):
            if i == max_results:
                break

            if not self.is_downloaded(video):
                self.backend.fill_video(video, ('url','title', 'url', 'duration'))
                if not(self.is_excluded(video.title, title_exclude)) and self.id_regexp_matched(video.id, id_regexp):
                    print "  %s\n    Id:%s\n    Duration:%s" % (video.title, video.id, video.duration)
                    videos.append(video)
            else:
                print "Already downloaded, check %s" % video.id
                self.backend.fill_video(video, ('url','title', 'url', 'duration'))
                linkname = self.get_linkname(video)
                if not os.path.exists(linkname):
                    self.remove_download(video)

        # download videos
        print "Downloading..."
        for video in videos:
            self.do_download(video)

    def is_excluded(self, title, title_exclude):
        for exclude in title_exclude:
            if title.find(exclude) > -1:
                return True
        return False

    def id_regexp_matched(self, video_id, id_regexp):
        if id_regexp:
            return re.search(id_regexp, video_id) is not None
        return True

    def get_filename(self, video, relative=False):
        if relative:
            directory = os.path.join("..", DOWNLOAD_DIRECTORY, self.backend_name)
        else:
            directory = os.path.join(self.download_directory, self.backend_name)
            if not os.path.exists(directory):
                os.makedirs(directory)

        ext = video.ext
        if not ext:
            ext = 'avi'

        return u"%s/%s.%s" % (directory, removeNonAscii(video.id), ext)

    def get_linkname(self, video):
        if not os.path.exists(self.links_directory):
            os.makedirs(self.links_directory)

        ext = video.ext
        if not ext:
            ext = 'avi'

        misc = video.date
        if not misc:
            misc = video.id

        return u"%s/%s (%s).%s" % (self.links_directory, removeSpecial(video.title), removeSpecial(misc), ext)

    def is_downloaded(self, video):
        # check if the file is 0 byte
        return os.path.isfile(self.get_filename(video))

    def remove_download(self, video):
        path = self.get_filename(video)
        if os.stat(path).st_size == 0:
            # already empty
            return

        print 'Remove video %s' % video.title

        # Empty it to keep information we have already downloaded it.
        with open(path, 'w'):
            pass

    def set_linkname(self, video):
        linkname = self.get_linkname(video)
        idname = self.get_filename(video, relative=True)
        absolute_idname = self.get_filename(video, relative=False)
        if not os.path.islink(linkname) and os.path.isfile(absolute_idname):
            print "%s -> %s" % (linkname, idname)
            os.symlink(idname, linkname)

    def do_download(self, video):
        if not video:
            print >>sys.stderr, 'Video not found: %s' %  video
            return 3

        if not video.url:
            print >>sys.stderr, 'Error: the direct URL is not available.'
            return 4

        def check_exec(executable):
            with open('/dev/null', 'w') as devnull:
                process = subprocess.Popen(['which', executable], stdout=devnull)
                if process.wait() != 0:
                    print >>sys.stderr, 'Please install "%s"' % executable
                    return False
            return True

        dest = self.get_filename(video)

        if video.url.startswith('rtmp'):
            if not check_exec('rtmpdump'):
                return 1
            args = ('rtmpdump', '-e', '-r', video.url, '-o', dest)
        elif video.url.startswith('mms'):
            if not check_exec('mimms'):
                return 1
            args = ('mimms', video.url, dest)
        else:
            if not check_exec('wget'):
                return 1
            args = ('wget', video.url, '-O', dest)

        os.spawnlp(os.P_WAIT, args[0], *args)
        self.set_linkname(video)
Example #48
0
 def __init__(self, _id, no_tracker):
     self.id, self.backend_name = _id.split("@")
     self.no_tracker = no_tracker
     self.weboob = Weboob()
     self.backend = self.weboob.load_backends(modules=[self.backend_name])[self.backend_name]
Example #49
0
class Connector(object):

    """
    Connector is a tool that connects to common websites like bank website,
    phone operator website... and that grabs personal data from there.
    Credentials are required to make this operation.

    Technically, connectors are weboob backend wrappers.
    """

    @staticmethod
    def version():
        """
        Get the version of the installed Weboob.
        """
        return Weboob.VERSION

    def __init__(self, weboob_data_path, fakemodules_path, sources_list_content, is_prod):
        """
        Create a Weboob instance.

        :param weboob_data_path: Weboob path to use.
        :param fakemodules_path: Path to the fake modules directory in user
        data.
        :param sources_list_content: Optional content of the sources.list file,
        as an array of lines, or None if not present.
        :param is_prod: whether we're running in production or not.
        """
        # By default, consider we don't need to update the repositories.
        self.needs_update = False

        self.fakemodules_path = fakemodules_path
        self.sources_list_content = sources_list_content

        if not os.path.isdir(weboob_data_path):
            os.makedirs(weboob_data_path)

        # Set weboob data directory and sources.list file.
        self.weboob_data_path = weboob_data_path
        self.write_weboob_sources_list()

        # Create a Weboob object.
        self.weboob = Weboob(workdir=weboob_data_path,
                             datadir=weboob_data_path)
        self.backend = None
        self.storage = None

        # To make development more pleasant, always copy the fake modules in
        # non-production modes.
        if not is_prod:
            self.copy_fakemodules()

        # Update the weboob repos only if new repos are included.
        if self.needs_update:
            self.update()

    def copy_fakemodules(self):
        """
        Copies the fake modules files into the default fakemodules user-data
        directory.

        When Weboob updates modules, it might want to write within the
        fakemodules directory, which might not be writable by the current
        user. To prevent this, first copy the fakemodules directory in
        a directory we have write access to, and then use that directory
        in the sources list file.
        """
        fakemodules_src = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'fakemodules')
        if os.path.isdir(self.fakemodules_path):
            shutil.rmtree(self.fakemodules_path)
        shutil.copytree(fakemodules_src, self.fakemodules_path)

    def write_weboob_sources_list(self):
        """
        Ensure the Weboob sources.list file contains the required entries from
        Kresus.
        """
        sources_list_path = os.path.join(self.weboob_data_path, 'sources.list')

        # Determine the new content of the sources.list file.
        new_sources_list_content = []
        if self.sources_list_content is not None:
            new_sources_list_content = self.sources_list_content
        else:
            # Default content of the sources.list file.
            new_sources_list_content = [
                unicode('https://updates.weboob.org/%(version)s/main/'),
                unicode('file://%s' % self.fakemodules_path)
            ]

        # Read the content of existing sources.list, if it exists.
        original_sources_list_content = []
        if os.path.isfile(sources_list_path):
            with io.open(sources_list_path, encoding="utf-8") as fh:
                original_sources_list_content = fh.read().splitlines()

        # Update the source.list content and update the repository, only if the
        # content has changed.
        if set(original_sources_list_content) != set(new_sources_list_content):
            with io.open(sources_list_path, 'w', encoding="utf-8") as sources_list_file:
                sources_list_file.write('\n'.join(new_sources_list_content))
            self.needs_update = True

    def update(self):
        """
        Update Weboob modules.
        """
        self.copy_fakemodules()

        # Weboob has an offending print statement when it "Rebuilds index",
        # which happen at every run if the user has a local repository. We need
        # to silence it, hence the temporary redirect of stdout.
        sys.stdout = open(os.devnull, "w")
        try:
            self.weboob.update(progress=DummyProgress())
        except ConnectionError as exc:
            # Do not delete the repository if there is a connection error.
            raise exc
        except Exception:
            # Try to remove the data directory, to see if it changes a thing.
            # This is especially useful when a new version of Weboob is
            # published and/or the keyring changes.
            shutil.rmtree(self.weboob_data_path)
            os.makedirs(self.weboob_data_path)

            # Recreate the Weboob object as the directories are created
            # on creating the Weboob object.
            self.weboob = Weboob(workdir=self.weboob_data_path,
                                 datadir=self.weboob_data_path)

            # Rewrite sources.list file
            self.write_weboob_sources_list()

            # Retry update
            self.weboob.update(progress=DummyProgress())
        finally:
            # Restore stdout
            sys.stdout = sys.__stdout__

    def create_backend(self, modulename, parameters, session):
        """
        Create a Weboob backend for a given module, ready to be used to fetch
        data.

        :param modulename: The name of the module from which backend should be
        created.
        :param parameters: A dict of parameters to pass to the module. It
        should at least contain ``login`` and ``password`` fields, but can
        contain additional values depending on the module.
        :param session: an object representing the browser state.
        """
        # Install the module if required.
        repositories = self.weboob.repositories
        minfo = repositories.get_module_info(modulename)
        if (
                minfo is not None and not minfo.is_installed() and
                not minfo.is_local()
        ):
            # We cannot install a locally available module, this would
            # result in a ModuleInstallError.
            try:
                repositories.install(minfo, progress=DummyProgress())
            except ModuleInstallError:
                fail(
                    GENERIC_EXCEPTION,
                    "Unable to install module %s." % modulename,
                    traceback.format_exc()
                )

        # Initialize the Storage.
        self.storage = DictStorage(session)

        # Initialize the backend.
        self.backend = self.weboob.build_backend(
            modulename,
            parameters,
            storage=self.storage
        )

    def delete_backend(self):
        """
        Delete a created backend for the given module.
        """
        if self.backend:
            with self.backend:
                self.backend.deinit()

        self.backend = None
        self.storage = None

    def get_accounts(self):
        """
        Fetch accounts data from Weboob.

        :param backend: The Weboob built backend to fetch data from.

        :returns: A list of dicts representing the available accounts.
        """
        results = []
        with self.backend:
            for account in list(self.backend.iter_accounts()):
                # The minimum dict keys for an account are :
                # 'id', 'label', 'balance' and 'type'
                # Retrieve extra information for the account.
                account = self.backend.fillobj(account, ['iban', 'currency'])

                iban = None
                if not empty(account.iban):
                    iban = account.iban
                currency = None
                if not empty(account.currency):
                    currency = unicode(account.currency)

                results.append({
                    'vendorAccountId': account.id,
                    'label': account.label,
                    'balance': account.balance,
                    'iban': iban,
                    'currency': currency,
                    'type': account.type,
                })

        return results

    def get_operations(self):
        """
        Fetch operations data from Weboob.

        :param backend: The Weboob built backend to fetch data from.

        :returns: A list of dicts representing the available operations.
        """
        results = []
        with self.backend:
            for account in list(self.backend.iter_accounts()):
                # Get all operations for this account.
                nyi_methods = []
                operations = []

                try:
                    operations += list(self.backend.iter_history(account))
                except NotImplementedError:
                    nyi_methods.append('iter_history')

                try:
                    operations += [
                        op for op in self.backend.iter_coming(account)
                        if op.type in [
                            Transaction.TYPE_DEFERRED_CARD,
                            Transaction.TYPE_CARD_SUMMARY
                        ]
                    ]
                except NotImplementedError:
                    nyi_methods.append('iter_coming')

                for method_name in nyi_methods:
                    logging.error(
                        ('%s not implemented for this account: %s.'),
                        method_name,
                        account.id
                    )

                # Build an operation dict for each operation.
                for operation in operations:
                    label = None
                    if not empty(operation.label):
                        label = unicode(operation.label)

                    raw_label = None
                    if not empty(operation.raw):
                        raw_label = unicode(operation.raw)
                    elif label:
                        raw_label = label

                    if raw_label and not label:
                        label = raw_label

                    # Handle date
                    if operation.rdate:
                        # Use date of the payment (real date) if available.
                        date = operation.rdate
                    elif operation.date:
                        # Otherwise, use debit date, on the bank statement.
                        date = operation.date
                    else:
                        logging.error(
                            'No known date property in operation line: %s.',
                            raw_label or "no label"
                        )
                        date = datetime.now()

                    isodate = date.isoformat()
                    debit_date = operation.date.isoformat()

                    results.append({
                        'account': account.id,
                        'amount': operation.amount,
                        'rawLabel': raw_label,
                        'type': operation.type,
                        'date': isodate,
                        'debit_date': debit_date,
                        'label': label
                    })

        return results

    def fetch(self, which):
        """
        Wrapper to fetch data from the Weboob connector.

        This wrapper fetches the required data from Weboob and returns it. It
        handles the translation between Weboob exceptions and Kresus error
        codes stored in the JSON response.

        :param which: The type of data to fetch. Can be either ``accounts`` or
        ``operations``.

        :param modulename: The name of the module from which data should be
        fetched. Optional, if not provided all available backends are used.

        :param login: The login to further filter on the available backends.
        Optional, if not provided all matching backends are used.

        :returns: A dict of the fetched data, in a ``values`` keys. Errors are
        described under ``error_code``, ``error_short`` and ``error_message``
        keys.
        """
        results = {}
        try:
            if which == 'accounts':
                results['values'] = self.get_accounts()
            elif which == 'operations':
                results['values'] = self.get_operations()
            else:
                raise Exception('Invalid fetch command.')

        except NoAccountsException:
            results['error_code'] = NO_ACCOUNTS
        except ModuleLoadError:
            results['error_code'] = UNKNOWN_MODULE
        except BrowserPasswordExpired:
            results['error_code'] = EXPIRED_PASSWORD
        except BrowserQuestion:
            results['error_code'] = BROWSER_QUESTION
        except AuthMethodNotImplemented:
            results['error_code'] = AUTH_METHOD_NYI
        except ActionNeeded as exc:
            # This `except` clause is not in alphabetic order and cannot be,
            # because BrowserPasswordExpired and AuthMethodNotImplemented
            # (above) inherits from it in Weboob 1.4.
            results['error_code'] = ACTION_NEEDED
            results['error_message'] = unicode(exc)
        except BrowserIncorrectPassword:
            # This `except` clause is not in alphabetic order and cannot be,
            # because BrowserPasswordExpired (above) inherits from it in
            # Weboob 1.3.
            results['error_code'] = INVALID_PASSWORD
        except Module.ConfigError as exc:
            results['error_code'] = INVALID_PARAMETERS
            results['error_message'] = unicode(exc)
        except ConnectionError as exc:
            results['error_code'] = CONNECTION_ERROR
            results['error_message'] = unicode(exc)
        except Exception as exc:
            fail(
                GENERIC_EXCEPTION,
                'Unknown error: %s.' % unicode(exc),
                traceback.format_exc()
            )

        # Return session information for future use.
        results['session'] = self.storage.dump()

        return results
Example #50
0
class MyThread(Thread):
    daemon = True

    def __init__(self, bot):
        Thread.__init__(self)
        self.weboob = Weboob(storage=StandardStorage(STORAGE_FILE))
        self.weboob.load_backends()
        self.bot = bot
        self.bot.set_weboob(self.weboob)

    def run(self):
        for ev in self.bot.joined.itervalues():
            ev.wait()

        self.weboob.repeat(300, self.check_board)
        self.weboob.repeat(600, self.check_dlfp)

        self.weboob.loop()

    def find_keywords(self, text):
        for word in [
            'weboob', 'videoob', 'havesex', 'havedate', 'monboob', 'boobmsg',
            'flatboob', 'boobill', 'pastoob', 'radioob', 'translaboob', 'traveloob', 'handjoob',
            'boobathon', 'boobank', 'boobtracker', 'comparoob', 'wetboobs',
            'webcontentedit', 'weboorrents', u'sàt', u'salut à toi', 'assnet',
                'budget insight', 'budget-insight', 'budgetinsight', 'budgea']:
            if word in text.lower():
                return word
        return None

    def check_dlfp(self):
        for backend, msg in self.weboob.do('iter_unread_messages', backends=['dlfp']):
            word = self.find_keywords(msg.content)
            if word is not None:
                url = msg.signature[msg.signature.find('https://linuxfr'):]
                self.bot.send_message('[DLFP] %s talks about %s: %s' % (
                    msg.sender, word, url))
            backend.set_message_read(msg)

    def check_board(self):
        def iter_messages(backend):
            with backend.browser:
                return backend.browser.iter_new_board_messages()

        for backend, msg in self.weboob.do(iter_messages, backends=['dlfp']):
            word = self.find_keywords(msg.message)
            if word is not None and msg.login != 'moules':
                message = msg.message.replace(word, '\002%s\002' % word)
                self.bot.send_message('[DLFP] <%s> %s' % (msg.login, message))

    def stop(self):
        self.weboob.want_stop()
        self.weboob.deinit()