Ejemplo n.º 1
0
def init_object_registries():
    """Initializes RPC and tracker objects registries with settings
    from configuration file.

    :return:
    """
    LOGGER.debug('Initializing objects registries from configuration file ...')
    cfg = config.load()

    settings_to_registry_map = {
        'rpc': RPCClassesRegistry,
        'notifiers': NotifierClassesRegistry,
        'bots': BotClassesRegistry,
    }

    for settings_entry, registry_cls in settings_to_registry_map.items():

        for alias, settings in cfg[settings_entry].items():
            registry_obj = registry_cls.get(alias)
            registry_obj and registry_obj.spawn_with_settings(settings).register()

    # Special case for trackers to initialize public trackers automatically.
    for alias, tracker_cls in TrackerClassesRegistry.get().items():

        settings = cfg['trackers'].get(alias)

        if settings is None:

            if issubclass(tracker_cls, GenericPrivateTracker):
                # No use in registering a private tracker without credentials.
                continue

            # Considered public tracker. Use default settings.

        tracker_cls.spawn_with_settings(settings or {}).register()
Ejemplo n.º 2
0
def init_object_registries():
    """Initializes RPC and tracker objects registries with settings
    from configuration file.

    :return:
    """
    LOGGER.debug('Initializing objects registries from configuration file ...')
    cfg = TorrtConfig.load()

    for alias, rpc_settings in cfg['rpc'].items():
        rpc = RPCClassesRegistry.get(alias)
        if rpc is not None:
            obj = rpc.spawn_with_settings(rpc_settings)
            obj.register()

    for domain, tracker_settings in cfg['trackers'].items():
        tracker = TrackerClassesRegistry.get(domain)
        if tracker is not None:
            obj = tracker.spawn_with_settings(tracker_settings)
            obj.register()
Ejemplo n.º 3
0
def init_object_registries():
    """Initializes RPC and tracker objects registries with settings
    from configuration file.

    :return:
    """
    LOGGER.debug('Initializing objects registries from configuration file ...')
    cfg = TorrtConfig.load()

    for alias, rpc_settings in cfg['rpc'].items():
        rpc = RPCClassesRegistry.get(alias)
        if rpc is not None:
            obj = rpc.spawn_with_settings(rpc_settings)
            obj.register()

    for domain, tracker_settings in cfg['trackers'].items():
        tracker = TrackerClassesRegistry.get(domain)
        if tracker is not None:
            obj = tracker.spawn_with_settings(tracker_settings)
            obj.register()
Ejemplo n.º 4
0
def configure_tracker(tracker_alias, settings_dict):
    """Configures tracker using given settings.
    Saves successful configuration.

    :param tracker_alias: tracker alias
    :param settings_dict: settings dictionary to configure tracker with
    :return:
    """
    LOGGER.info('Configuring `%s` tracker ...', tracker_alias)

    tracker_class = TrackerClassesRegistry.get(tracker_alias)
    if tracker_class is not None:
        tracker_obj = tracker_class.spawn_with_settings(settings_dict)
        configured = tracker_obj.test_configuration()
        if configured:
            tracker_obj.save_settings()
            LOGGER.info('Tracker `%s` is configured', tracker_alias)
        else:
            LOGGER.error('Tracker `%s` configuration failed. Check your settings', tracker_alias)
    else:
        LOGGER.error('Tracker `%s` is unknown', tracker_alias)
Ejemplo n.º 5
0
def configure_tracker(tracker_alias, settings_dict):
    """Configures tracker using given settings.
    Saves successful configuration.

    :param tracker_alias: tracker alias
    :param settings_dict: settings dictionary to configure tracker with
    :return:
    """
    LOGGER.info('Configuring `%s` tracker ...', tracker_alias)

    tracker_class = TrackerClassesRegistry.get(tracker_alias)
    if tracker_class is not None:
        tracker_obj = tracker_class.spawn_with_settings(settings_dict)
        configured = tracker_obj.test_configuration()
        if configured:
            tracker_obj.save_settings()
            LOGGER.info('Tracker `%s` is configured', tracker_alias)
        else:
            LOGGER.error('Tracker `%s` configuration failed. Check your settings', tracker_alias)
    else:
        LOGGER.error('Tracker `%s` is unknown', tracker_alias)
Ejemplo n.º 6
0
Archivo: main.py Proyecto: riorao/torrt
def process_commands():

    def settings_dict_from_list(lst):
        settings_dict = {}
        for s in lst:
            splitted = s.split('=')
            settings_dict[splitted[0]] = splitted[1]
        return settings_dict

    arg_parser = argparse.ArgumentParser('torrt', description='Automates torrent updates for you.', version='.'.join(map(str, VERSION)))
    arg_parser.add_argument('--verbose', help='Switch to show debug messages', dest='verbose', action='store_true')

    subp_main = arg_parser.add_subparsers(title='Supported commands', dest='command')

    subp_main.add_parser('list_rpc', help='Shows known RPCs aliases')
    subp_main.add_parser('list_trackers', help='Shows known trackers aliases')
    subp_main.add_parser('list_torrents', help='Shows torrents registered for updates')

    parser_configure_tracker = subp_main.add_parser('configure_tracker', help='Sets torrent tracker settings (login credentials, etc.)', description='E.g.: configure_tracker rutracker.org username=idle password=pSW0rt')
    parser_configure_tracker.add_argument('tracker_alias', help='Tracker alias (usually domain) to apply settings to')
    parser_configure_tracker.add_argument('settings', help='Settings string, format: setting1=val1 setting2=val2. Supported settings (any of): username, password', nargs='*')

    parser_configure_rpc = subp_main.add_parser('configure_rpc', help='Sets RPCs settings (login credentials, etc.)', description='E.g.: configure_rpc transmission user=idle password=pSW0rt')
    parser_configure_rpc.add_argument('rpc_alias', help='RPC alias to apply settings to')
    parser_configure_rpc.add_argument('settings', help='Settings string, format: setting1=val1 setting2=val2. Supported settings (any of): url, host, port, user, password', nargs='*')

    parser_walk = subp_main.add_parser('walk', help='Walks through registered torrents and performs automatic updates')
    parser_walk.add_argument('-f', help='Forces walk. Forced walks do not respect walk interval settings', dest='forced', action='store_true')

    parser_set_interval = subp_main.add_parser('set_walk_interval', help='Sets an interval *in hours* between consecutive torrent updates checks')
    parser_set_interval.add_argument('walk_interval', help='Interval *in hours* between consecutive torrent updates checks')

    parser_enable_rpc = subp_main.add_parser('enable_rpc', help='Enables RPC by its alias')
    parser_enable_rpc.add_argument('alias', help='Alias of RPC to enable')

    parser_disable_rpc = subp_main.add_parser('disable_rpc', help='Disables RPC by its alias')
    parser_disable_rpc.add_argument('alias', help='Alias of RPC to disable')

    parser_add_torrent = subp_main.add_parser('add_torrent', help='Adds torrent from an URL both to torrt and torrent clients')
    parser_add_torrent.add_argument('url', help='URL to download torrent from')
    parser_add_torrent.add_argument('-d', help='Destination path to download torrent contents into (in filesystem where torrent client daemon works)', dest='download_to', default=None)

    parser_remove_torrent = subp_main.add_parser('remove_torrent', help='Removes torrent by its hash both from torrt and torrent clients')
    parser_remove_torrent.add_argument('hash', help='Torrent identifying hash')
    parser_remove_torrent.add_argument('-d', help='If set data downloaded for torrent will also be removed', dest='delete_data', action='store_true')

    parser_register_torrent = subp_main.add_parser('register_torrent', help='Registers torrent within torrt by its hash (for torrents already existing at torrent clients)')
    parser_register_torrent.add_argument('hash', help='Torrent identifying hash')

    parser_unregister_torrent = subp_main.add_parser('unregister_torrent', help='Unregisters torrent from torrt by its hash')
    parser_unregister_torrent.add_argument('hash', help='Torrent identifying hash')

    args = arg_parser.parse_args()
    args = vars(args)

    loggin_level = logging.INFO
    if args['verbose']:
        loggin_level = logging.DEBUG

    configure_logging(loggin_level)
    bootstrap()

    if args['command'] == 'enable_rpc':
        toggle_rpc(args['alias'], True)

    elif args['command'] == 'disable_rpc':
        toggle_rpc(args['alias'], False)

    elif args['command'] == 'list_trackers':

        for tracker_alias, tracker in TrackerClassesRegistry.get().items():
            LOGGER.info(tracker_alias)

    elif args['command'] == 'list_rpc':
        rpc_statuses = {}

        for rpc_alias, rpc in RPCClassesRegistry.get().items():
            rpc_statuses[rpc_alias] = 'unconfigured'

        for rpc_alias, rpc in RPCObjectsRegistry.get().items():
            rpc_statuses[rpc_alias] = 'enabled' if rpc.enabled else 'disabled'

        for rpc_alias, rpc_status in rpc_statuses.items():
            LOGGER.info('%s\t status=%s' % (rpc_alias, rpc_status))

    elif args['command'] == 'list_torrents':
        for torrent_hash, torrent_data in get_registerd_torrents().items():
            LOGGER.info('%s\t%s' % (torrent_hash, torrent_data['name']))

    elif args['command'] == 'walk':
        walk(forced=args['forced'], silent=True)

    elif args['command'] == 'set_walk_interval':
        set_walk_interval(args['walk_interval'])

    elif args['command'] == 'add_torrent':
        add_torrent_from_url(args['url'], args['download_to'])

    elif args['command'] == 'remove_torrent':
        remove_torrent(args['hash'], args['delete_data'])

    elif args['command'] == 'register_torrent':
        register_torrent(args['hash'])

    elif args['command'] == 'unregister_torrent':
        unregister_torrent(args['hash'])

    elif args['command'] == 'configure_rpc':
        configure_rpc(args['rpc_alias'], settings_dict_from_list(args['settings']))

    elif args['command'] == 'configure_tracker':
        configure_tracker(args['tracker_alias'], settings_dict_from_list(args['settings']))
Ejemplo n.º 7
0
        }

    def before_download(self, url):
        """Used to perform some required actions right before .torrent download."""
        self.cookies['bb_dl'] = self.get_id_from_link(
            url)  # A check that user himself have visited torrent's page ;)

    def get_download_link(self, url):
        """Tries to find .torrent file download link at forum thread page and return that one."""
        page_soup = self.get_response(url,
                                      referer=url,
                                      cookies=self.cookies,
                                      query_string=self.query_string,
                                      as_soup=True)
        page_links = self.find_links(url, page_soup)
        download_link = None
        for page_link in page_links:
            if 'dl.rutracker.org' in page_link:
                download_link = page_link
                if 'guest' in download_link:
                    download_link = None
                    LOGGER.debug('Login is required to download torrent file')
                    if self.login():
                        download_link = self.get_download_link(url)
                break
        return download_link


# With that one we tell torrt to handle links to `rutracker.org` domain with RutrackerHandler class.
TrackerClassesRegistry.add(RuTrackerTracker)
Ejemplo n.º 8
0
                url, referer=url, cookies=self.cookies, query_string=self.query_string, as_soup=True
            )
        download_link = self.find_links(url, page_soup, r'dl\.php')
        self.form_token = self.get_form_token(page_soup)
        return download_link

    def get_form_token(self, page_soup):
        form_token_lines = [line for line in page_soup.text.split('\n\t') if line.startswith('form_token')]
        try:
            return form_token_lines[0].split(':')[1][2:-2]
        except IndexError:
            return

    def download_torrent(self, url, referer=None):
        LOGGER.debug('Downloading torrent file from %s ...', url)
        self.before_download(url)
        # rutracker require POST action to download torrent file
        if self.form_token:
            form_data = {'form_token': self.form_token}
        else:
            form_data = None
        response = self.get_response(
            url, form_data=form_data, cookies=self.cookies, query_string=self.get_auth_query_string(), referer=referer
        )
        if response is None:
            return None
        return response.content

# With that one we tell torrt to handle links to `rutracker.org` domain with RutrackerHandler class.
TrackerClassesRegistry.add(RuTrackerTracker)
Ejemplo n.º 9
0
def process_commands():
    def settings_dict_from_list(lst):
        settings_dict = {}
        for s in lst:
            splitted = s.split('=')
            settings_dict[splitted[0]] = splitted[1]
        return settings_dict

    arg_parser = argparse.ArgumentParser(
        'torrt', description='Automates torrent updates for you.')
    arg_parser.add_argument('--version',
                            action='version',
                            version='%(prog)s ' + '.'.join(map(str, VERSION)))

    subp_main = arg_parser.add_subparsers(title='Supported commands',
                                          dest='command')

    subp_main.add_parser('list_rpc', help='Shows known RPCs aliases')
    subp_main.add_parser('list_trackers', help='Shows known trackers aliases')
    subp_main.add_parser('list_torrents',
                         help='Shows torrents registered for updates')
    subp_main.add_parser('list_notifiers', help='Shows configured notifiers')

    parser_configure_tracker = subp_main.add_parser(
        'configure_tracker',
        help='Sets torrent tracker settings (login credentials, etc.)',
        description=
        'E.g.: configure_tracker rutracker.org username=idle password=pSW0rt')
    parser_configure_tracker.add_argument(
        'tracker_alias',
        help='Tracker alias (usually domain) to apply settings to')
    parser_configure_tracker.add_argument(
        'settings',
        help='Settings string, format: setting1=val1 setting2=val2. '
        'Supported settings (any of): username, password',
        nargs='*')

    parser_configure_rpc = subp_main.add_parser(
        'configure_rpc',
        help='Sets RPCs settings (login credentials, etc.)',
        description='E.g.: configure_rpc transmission user=idle password=pSW0rt'
    )
    parser_configure_rpc.add_argument('rpc_alias',
                                      help='RPC alias to apply settings to')
    parser_configure_rpc.add_argument(
        'settings',
        help='Settings string, format: setting1=val1 setting2=val2. '
        'Supported settings (any of): url, host, port, user, password',
        nargs='*')

    parser_configure_notifier = subp_main.add_parser(
        'configure_notifier',
        help='Sets Notifiers settings (smtp credentials, etc.)',
        description=
        'E.g.: configure_notifier email [email protected] user=idle password=pSW0rt'
    )
    parser_configure_notifier.add_argument(
        'notifier_alias', help='Notifier alias to apply settings to')
    parser_configure_notifier.add_argument(
        'settings',
        help='Settings string, format: setting1=val1 setting2=val2. '
        'Supported settings for email notifier (any of): email, host, port, use_tls, user, password.'
        'Supported settings for telegram notifier: token, chat_id.',
        nargs='*')

    parser_configure_bot = subp_main.add_parser(
        'configure_bot',
        help='Sets Bot settings (token, etc.)',
        description='E.g.: configure_bot telegram token=YourBotSuperToken')
    parser_configure_bot.add_argument('bot_alias',
                                      help='Bot alias to apply settings to')
    parser_configure_bot.add_argument(
        'settings',
        help='Settings string, format: setting1=val1 setting2=val2. '
        'Supported settings for telegram bot: token.',
        nargs='*')

    parser_walk = subp_main.add_parser(
        'walk',
        help='Walks through registered torrents and performs automatic updates'
    )
    parser_walk.add_argument(
        '-f',
        help='Forces walk. Forced walks do not respect walk interval settings',
        dest='forced',
        action='store_true')
    parser_walk.add_argument(
        '--dump',
        help=
        'Dump web pages scraped by torrt into current or a given directory',
        dest='dump')

    parser_run_bots = subp_main.add_parser('run_bots',
                                           help='Run registered bots')
    parser_run_bots.add_argument('aliases',
                                 help='Bots to run aliases',
                                 nargs='*')

    parser_set_interval = subp_main.add_parser(
        'set_walk_interval',
        help=
        'Sets an interval *in hours* between consecutive torrent updates checks'
    )
    parser_set_interval.add_argument(
        'walk_interval',
        help='Interval *in hours* between consecutive torrent updates checks')

    parser_enable_rpc = subp_main.add_parser('enable_rpc',
                                             help='Enables RPC by its alias')
    parser_enable_rpc.add_argument('alias', help='Alias of RPC to enable')

    parser_disable_rpc = subp_main.add_parser('disable_rpc',
                                              help='Disables RPC by its alias')
    parser_disable_rpc.add_argument('alias', help='Alias of RPC to disable')

    parser_add_torrent = subp_main.add_parser(
        'add_torrent',
        help='Adds torrent from an URL both to torrt and torrent clients')
    parser_add_torrent.add_argument('url', help='URL to download torrent from')
    parser_add_torrent.add_argument(
        '-d',
        help=
        'Destination path to download torrent contents into (in filesystem where torrent client daemon works)',
        dest='download_to',
        default=None)
    parser_add_torrent.add_argument(
        '--dump',
        help=
        'Dump web pages scraped by torrt into current or a given directory',
        dest='dump')

    parser_remove_torrent = subp_main.add_parser(
        'remove_torrent',
        help='Removes torrent by its hash both from torrt and torrent clients')
    parser_remove_torrent.add_argument('hash', help='Torrent identifying hash')
    parser_remove_torrent.add_argument(
        '-d',
        help='If set data downloaded for torrent will also be removed',
        dest='delete_data',
        action='store_true')

    parser_register_torrent = subp_main.add_parser(
        'register_torrent',
        help=
        'Registers torrent within torrt by its hash (for torrents already existing at torrent clients)'
    )
    parser_register_torrent.add_argument('hash',
                                         help='Torrent identifying hash')
    parser_register_torrent.add_argument('-u',
                                         dest='url',
                                         default=None,
                                         help='URL to download torrent from')

    parser_unregister_torrent = subp_main.add_parser(
        'unregister_torrent',
        help='Unregisters torrent from torrt by its hash')
    parser_unregister_torrent.add_argument('hash',
                                           help='Torrent identifying hash')

    parser_remove_notifier = subp_main.add_parser(
        'remove_notifier', help='Remove configured notifier by its alias')
    parser_remove_notifier.add_argument('alias',
                                        help='Alias of notifier to remove')

    for parser in subp_main.choices.values():
        parser.add_argument('--verbose',
                            help='Switch to show debug messages',
                            dest='verbose',
                            action='store_true')

    args = arg_parser.parse_args()
    args = vars(args)

    configure_logging(logging.DEBUG if args.get('verbose') else logging.INFO)

    bootstrap()

    dump_into = args.get('dump')

    if dump_into:
        GlobalParam.set('dump_into', path.abspath(dump_into))

    if args['command'] == 'enable_rpc':
        toggle_rpc(args['alias'], True)

    elif args['command'] == 'disable_rpc':
        toggle_rpc(args['alias'], False)

    elif args['command'] == 'list_trackers':

        for tracker_alias, _ in TrackerClassesRegistry.get().items():
            LOGGER.info(tracker_alias)

    elif args['command'] == 'list_rpc':
        rpc_statuses = {}

        for rpc_alias, rpc in RPCClassesRegistry.get().items():
            rpc_statuses[rpc_alias] = 'unconfigured'

        for rpc_alias, rpc in RPCObjectsRegistry.get().items():
            rpc_statuses[rpc_alias] = 'enabled' if rpc.enabled else 'disabled'

        for rpc_alias, rpc_status in rpc_statuses.items():
            LOGGER.info(f'{rpc_alias}\t status={rpc_status}')

    elif args['command'] == 'list_torrents':
        for torrent_hash, torrent_data in get_registered_torrents().items():
            LOGGER.info(f"{torrent_hash}\t{torrent_data['name']}")

    elif args['command'] == 'list_notifiers':
        notifiers = {}
        for notifier_alias in NotifierClassesRegistry.get().keys():
            notifiers[notifier_alias] = 'unconfigured'

        for notifier_alias in NotifierObjectsRegistry.get().keys():
            notifiers[notifier_alias] = 'enabled'

        for notifier_alias, notifier_status in notifiers.items():
            LOGGER.info(f"{notifier_alias}\t status={notifier_status}")

    elif args['command'] == 'walk':
        walk(forced=args['forced'], silent=True)

    elif args['command'] == 'set_walk_interval':
        set_walk_interval(args['walk_interval'])

    elif args['command'] == 'add_torrent':
        add_torrent_from_url(args['url'], args['download_to'])

    elif args['command'] == 'remove_torrent':
        remove_torrent(args['hash'], args['delete_data'])

    elif args['command'] == 'register_torrent':
        register_torrent(args['hash'], url=args['url'])

    elif args['command'] == 'unregister_torrent':
        unregister_torrent(args['hash'])

    elif args['command'] == 'configure_rpc':
        configure_rpc(args['rpc_alias'],
                      settings_dict_from_list(args['settings']))

    elif args['command'] == 'configure_tracker':
        configure_tracker(args['tracker_alias'],
                          settings_dict_from_list(args['settings']))

    elif args['command'] == 'configure_notifier':
        configure_notifier(args['notifier_alias'],
                           settings_dict_from_list(args['settings']))

    elif args['command'] == 'remove_notifier':
        remove_notifier(args['alias'])

    elif args['command'] == 'configure_bot':
        configure_bot(args['bot_alias'],
                      settings_dict_from_list(args['settings']))

    elif args['command'] == 'run_bots':
        run_bots(args['aliases'])
Ejemplo n.º 10
0
class KinozalTracker(GenericPrivateTracker):
    """This class implements .torrent files downloads for http://kinozal.tv/ tracker."""

    alias = 'kinozal.tv'
    login_url = 'http://%(domain)s/takelogin.php'
    auth_cookie_name = 'uid'
    mirrors = ['kinozal.me']
    encoding = 'cp1251'

    def get_login_form_data(self, login, password):
        """Returns a dictionary with data to be pushed to authorization form."""
        return {'username': login, 'password': password, 'returnto': ''}

    def get_id_from_link(self, url):
        """Returns forum thread identifier from full thread URL."""
        return url.split('=')[1]

    def get_download_link(self, url):
        """Tries to find .torrent file download link at forum thread page and return that one."""

        response = self.get_response(url, cookies=self.cookies)

        page_soup = self.make_page_soup(response.text)
        expected_link = '/download.+\=%s' % self.get_id_from_link(url)
        download_link = self.find_links(url, page_soup, definite=expected_link)
        return download_link


TrackerClassesRegistry.add(KinozalTracker)
Ejemplo n.º 11
0
            quality_divs = page_soup.select('div.torrent > div.torrent_c > div')
            for quality_div in quality_divs:
                available_qualities.append(quality_div['id'])

            LOGGER.debug('Available in qualities: %s' % ', '.join(available_qualities))

            if available_qualities:

                prefered_qualities = [quality for quality in self.quality_prefs if quality in available_qualities]
                if not prefered_qualities:
                    LOGGER.debug('Torrent is not available in preferred qualities: %s' % ', '.join(self.quality_prefs))
                else:
                    target_quality = prefered_qualities[0]
                    LOGGER.debug('Trying to get torrent in `%s` quality ...' % target_quality)

                    target_links = page_soup.select('div#%s div.torrent_h a' % target_quality)
                    if target_links:
                        if isinstance(target_links, list):
                            download_link = target_links[0]['href']
                        else:
                            download_link = target_links['href']
                        download_link = self.expand_link(url, download_link)
                    else:
                        LOGGER.debug('Unable to find a link for `%s` quality' % target_quality)

        return download_link


TrackerClassesRegistry.add(AniDUBTracker)
Ejemplo n.º 12
0
                prefered_qualities = [
                    quality for quality in self.quality_prefs
                    if quality in available_qualities
                ]
                if not prefered_qualities:
                    LOGGER.debug(
                        'Torrent is not available in preferred qualities: %s',
                        ', '.join(self.quality_prefs))
                else:
                    target_quality = prefered_qualities[0]
                    LOGGER.debug('Trying to get torrent in `%s` quality ...',
                                 target_quality)

                    target_links = page_soup.select('div#%s div.torrent_h a' %
                                                    target_quality)
                    if target_links:
                        if isinstance(target_links, list):
                            download_link = target_links[0]['href']
                        else:
                            download_link = target_links['href']
                        download_link = self.expand_link(url, download_link)
                    else:
                        LOGGER.debug('Unable to find a link for `%s` quality',
                                     target_quality)

        return download_link


TrackerClassesRegistry.add(AniDUBTracker)
Ejemplo n.º 13
0
                    url,
                    div.select('div.torrent-fourth-col a.torrent-download-link'
                               )[0]['href'])
                available_qualities[quality] = link
            else:
                LOGGER.warning('Cannot extract quality from `%s`', quality_str)

        LOGGER.debug('Available in qualities: %s',
                     ', '.join(available_qualities.keys()))

        if available_qualities:
            preferred_qualities = [
                quality for quality in self.quality_prefs
                if quality in available_qualities
            ]
            if not preferred_qualities:
                LOGGER.debug(
                    'Torrent is not available in preferred qualities: %s',
                    ', '.join(self.quality_prefs))
            else:
                target_quality = preferred_qualities[0]
                LOGGER.debug('Trying to get torrent in `%s` quality ...',
                             target_quality)

                return available_qualities[target_quality]

        return None


TrackerClassesRegistry.add(AnilibriaTracker)
Ejemplo n.º 14
0
    def get_login_form_data(self, login, password):
        index_page = self.get_response(url=(self.login_url % {'domain': self.alias}))
        soup_response = self.make_page_soup(index_page.text)
        sid = soup_response.find(attrs={'name': 'sid'}).get('value')
        self.cookies = index_page.cookies
        self.login_url += '&sid=%s' % sid
        return {'username': login, 'password': password, 'autologin': '******',
                'redirect': 'index.php', 'sid': sid, 'login': six.u('Вход')}

    def get_download_link(self, url):
        """Tries to find .torrent file download link at forum thread page and return that one."""
        page_soup = self.get_response(
            url, referer=url, cookies=self.cookies, query_string=self.query_string, as_soup=True
        )

        domain = self.extract_domain(url)
        is_anonymous = self.find_links(url, page_soup, r'\./ucp\.php\?mode=login') is not None

        if not self.logged_in or is_anonymous:
            self.logged_in = False
            self.login(domain)
            page_soup = self.get_response(
                url, referer=url, cookies=self.cookies, query_string=self.query_string, as_soup=True
            )
        download_tag = page_soup.find('a', text='Скачать торрент')
        if download_tag:
            return self.expand_link(url, download_tag['href'])


TrackerClassesRegistry.add(CasstudioTracker)
Ejemplo n.º 15
0
def process_commands():
    def settings_dict_from_list(lst):
        settings_dict = {}
        for s in lst:
            splitted = s.split('=')
            settings_dict[splitted[0]] = splitted[1]
        return settings_dict

    arg_parser = argparse.ArgumentParser(
        'torrt',
        description='Automates torrent updates for you.',
        version='.'.join(map(str, VERSION)))
    arg_parser.add_argument('--verbose',
                            help='Switch to show debug messages',
                            dest='verbose',
                            action='store_true')

    subp_main = arg_parser.add_subparsers(title='Supported commands',
                                          dest='command')

    subp_main.add_parser('list_rpc', help='Shows known RPCs aliases')
    subp_main.add_parser('list_trackers', help='Shows known trackers aliases')
    subp_main.add_parser('list_torrents',
                         help='Shows torrents registered for updates')

    parser_configure_tracker = subp_main.add_parser(
        'configure_tracker',
        help='Sets torrent tracker settings (login credentials, etc.)',
        description=
        'E.g.: configure_tracker rutracker.org username=idle password=pSW0rt')
    parser_configure_tracker.add_argument(
        'tracker_alias',
        help='Tracker alias (usually domain) to apply settings to')
    parser_configure_tracker.add_argument(
        'settings',
        help='Settings string, format: setting1=val1 setting2=val2. '
        'Supported settings (any of): username, password',
        nargs='*')

    parser_configure_rpc = subp_main.add_parser(
        'configure_rpc',
        help='Sets RPCs settings (login credentials, etc.)',
        description='E.g.: configure_rpc transmission user=idle password=pSW0rt'
    )
    parser_configure_rpc.add_argument('rpc_alias',
                                      help='RPC alias to apply settings to')
    parser_configure_rpc.add_argument(
        'settings',
        help='Settings string, format: setting1=val1 setting2=val2. '
        'Supported settings (any of): url, host, port, user, password',
        nargs='*')

    parser_walk = subp_main.add_parser(
        'walk',
        help='Walks through registered torrents and performs automatic updates'
    )
    parser_walk.add_argument(
        '-f',
        help='Forces walk. Forced walks do not respect walk interval settings',
        dest='forced',
        action='store_true')

    parser_set_interval = subp_main.add_parser(
        'set_walk_interval',
        help=
        'Sets an interval *in hours* between consecutive torrent updates checks'
    )
    parser_set_interval.add_argument(
        'walk_interval',
        help='Interval *in hours* between consecutive torrent updates checks')

    parser_enable_rpc = subp_main.add_parser('enable_rpc',
                                             help='Enables RPC by its alias')
    parser_enable_rpc.add_argument('alias', help='Alias of RPC to enable')

    parser_disable_rpc = subp_main.add_parser('disable_rpc',
                                              help='Disables RPC by its alias')
    parser_disable_rpc.add_argument('alias', help='Alias of RPC to disable')

    parser_add_torrent = subp_main.add_parser(
        'add_torrent',
        help='Adds torrent from an URL both to torrt and torrent clients')
    parser_add_torrent.add_argument('url', help='URL to download torrent from')
    parser_add_torrent.add_argument(
        '-d',
        help=
        'Destination path to download torrent contents into (in filesystem where torrent client daemon works)',
        dest='download_to',
        default=None)

    parser_remove_torrent = subp_main.add_parser(
        'remove_torrent',
        help='Removes torrent by its hash both from torrt and torrent clients')
    parser_remove_torrent.add_argument('hash', help='Torrent identifying hash')
    parser_remove_torrent.add_argument(
        '-d',
        help='If set data downloaded for torrent will also be removed',
        dest='delete_data',
        action='store_true')

    parser_register_torrent = subp_main.add_parser(
        'register_torrent',
        help=
        'Registers torrent within torrt by its hash (for torrents already existing at torrent clients)'
    )
    parser_register_torrent.add_argument('hash',
                                         help='Torrent identifying hash')

    parser_unregister_torrent = subp_main.add_parser(
        'unregister_torrent',
        help='Unregisters torrent from torrt by its hash')
    parser_unregister_torrent.add_argument('hash',
                                           help='Torrent identifying hash')

    args = arg_parser.parse_args()
    args = vars(args)

    loggin_level = logging.INFO
    if args['verbose']:
        loggin_level = logging.DEBUG

    configure_logging(loggin_level)
    bootstrap()

    if args['command'] == 'enable_rpc':
        toggle_rpc(args['alias'], True)

    elif args['command'] == 'disable_rpc':
        toggle_rpc(args['alias'], False)

    elif args['command'] == 'list_trackers':

        for tracker_alias, _ in TrackerClassesRegistry.get().items():
            LOGGER.info(tracker_alias)

    elif args['command'] == 'list_rpc':
        rpc_statuses = {}

        for rpc_alias, rpc in RPCClassesRegistry.get().items():
            rpc_statuses[rpc_alias] = 'unconfigured'

        for rpc_alias, rpc in RPCObjectsRegistry.get().items():
            rpc_statuses[rpc_alias] = 'enabled' if rpc.enabled else 'disabled'

        for rpc_alias, rpc_status in rpc_statuses.items():
            LOGGER.info('%s\t status=%s', rpc_alias, rpc_status)

    elif args['command'] == 'list_torrents':
        for torrent_hash, torrent_data in get_registerd_torrents().items():
            LOGGER.info('%s\t%s', torrent_hash, torrent_data['name'])

    elif args['command'] == 'walk':
        walk(forced=args['forced'], silent=True)

    elif args['command'] == 'set_walk_interval':
        set_walk_interval(args['walk_interval'])

    elif args['command'] == 'add_torrent':
        add_torrent_from_url(args['url'], args['download_to'])

    elif args['command'] == 'remove_torrent':
        remove_torrent(args['hash'], args['delete_data'])

    elif args['command'] == 'register_torrent':
        register_torrent(args['hash'])

    elif args['command'] == 'unregister_torrent':
        unregister_torrent(args['hash'])

    elif args['command'] == 'configure_rpc':
        configure_rpc(args['rpc_alias'],
                      settings_dict_from_list(args['settings']))

    elif args['command'] == 'configure_tracker':
        configure_tracker(args['tracker_alias'],
                          settings_dict_from_list(args['settings']))
Ejemplo n.º 16
0

class NNMClubTracker(GenericPrivateTracker):
    """This class implements .torrent files downloads for http://nnm-club.me tracker."""

    alias = "nnm-club.me"
    login_url = "http://nnm-club.me/forum/login.php"
    auth_qs_param_name = "sid"

    def get_login_form_data(self, login, password):
        """Returns a dictionary with data to be pushed to authorization form."""
        return {"username": login, "password": password, "autologin": 1, "redirect": "", "login": "******"}

    def get_download_link(self, url):
        """Tries to find .torrent file download link at forum thread page and return that one."""
        page_soup = self.get_response(
            url, referer=url, cookies=self.cookies, query_string=self.get_auth_query_string(), as_soup=True
        )
        download_link = self.find_links(url, page_soup, definite="download\.php")

        if download_link is None:
            LOGGER.debug("Login is required to download torrent file")
            if self.login():
                download_link = self.get_download_link(url)

        return download_link


# With that one we tell torrt to handle links to `nnm-club.me` domain with NNMClubTracker class.
TrackerClassesRegistry.add(NNMClubTracker)
Ejemplo n.º 17
0
            else:
                target_quality = preferred_qualities[0]
                LOGGER.debug('Trying to get torrent in `%s` quality ...', target_quality)

                return available_qualities[target_quality]

        return None

    @staticmethod
    def sanitize_quality(quality_str):
        """
        Turn passed quality_str into common format in order to simplify comparison.
        Examples:

        * `sanitize_quality('WEBRip 1080p')` -> 'webrip1080p'
        * `sanitize_quality('WEBRip-1080p')` -> 'webrip1080p'
        * `sanitize_quality('WEBRip_1080p')` -> 'webrip1080p'
        * `sanitize_quality('')` -> ''
        * `sanitize_quality(None)` -> ''

        :type quality_str: Optional[str]
        :param quality_str: originally extracted quality string with non-word characters
        :return: quality string without non-word characters in lower-case
        """
        if quality_str:
            return REGEX_NON_WORD.sub('', quality_str).lower()
        return ''


TrackerClassesRegistry.add(AnilibriaTracker)
Ejemplo n.º 18
0
        return {
            'username': login,
            'password': password,
            'autologin': 1,
            'redirect': '',
            'login': '******'
        }

    def get_download_link(self, url):
        """Tries to find .torrent file download link at forum thread page and return that one."""
        page_soup = self.get_response(
            url,
            referer=url,
            cookies=self.cookies,
            query_string=self.get_auth_query_string(),
            as_soup=True)
        download_link = self.find_links(url,
                                        page_soup,
                                        definite='download\.php')

        if download_link is None:
            LOGGER.debug('Login is required to download torrent file')
            if self.login():
                download_link = self.get_download_link(url)

        return download_link


# With that one we tell torrt to handle links to `nnm-club.me` domain with NNMClubTracker class.
TrackerClassesRegistry.add(NNMClubTracker)
Ejemplo n.º 19
0
def process_commands():
    def settings_dict_from_list(lst):
        settings_dict = {}
        for s in lst:
            splitted = s.split('=')
            settings_dict[splitted[0]] = splitted[1]
        return settings_dict

    arg_parser = argparse.ArgumentParser('torrt', description='Automates torrent updates for you.')
    arg_parser.add_argument('--version', action='version', version='%(prog)s ' + '.'.join(map(str, VERSION)))

    subp_main = arg_parser.add_subparsers(title='Supported commands', dest='command')

    subp_main.add_parser('list_rpc', help='Shows known RPCs aliases')
    subp_main.add_parser('list_trackers', help='Shows known trackers aliases')
    subp_main.add_parser('list_torrents', help='Shows torrents registered for updates')
    subp_main.add_parser('list_notifiers', help='Shows configured notifiers')

    parser_configure_tracker = subp_main.add_parser(
        'configure_tracker', help='Sets torrent tracker settings (login credentials, etc.)',
        description='E.g.: configure_tracker rutracker.org username=idle password=pSW0rt')
    parser_configure_tracker.add_argument(
        'tracker_alias', help='Tracker alias (usually domain) to apply settings to')
    parser_configure_tracker.add_argument(
        'settings',
        help='Settings string, format: setting1=val1 setting2=val2. '
             'Supported settings (any of): username, password',
        nargs='*')

    parser_configure_rpc = subp_main.add_parser(
        'configure_rpc', help='Sets RPCs settings (login credentials, etc.)',
        description='E.g.: configure_rpc transmission user=idle password=pSW0rt')
    parser_configure_rpc.add_argument(
        'rpc_alias', help='RPC alias to apply settings to')
    parser_configure_rpc.add_argument(
        'settings',
        help='Settings string, format: setting1=val1 setting2=val2. '
             'Supported settings (any of): url, host, port, user, password',
        nargs='*')

    parser_configure_notifier = subp_main.add_parser(
        'configure_notifier', help='Sets Notifiers settings (smtp credentials, etc.)',
        description='E.g.: configure_notifier email [email protected] user=idle password=pSW0rt')
    parser_configure_notifier.add_argument(
        'notifier_alias', help='Notifier alias to apply settings to')
    parser_configure_notifier.add_argument(
        'settings',
        help='Settings string, format: setting1=val1 setting2=val2. '
             'Supported settings for email notifier (any of): email, host, port, use_tls, user, password.'
             'Supported settings for telegram notifier: token, chat_id.',
        nargs='*')

    parser_configure_bot = subp_main.add_parser(
        'configure_bot', help='Sets Bot settings (token, etc.)',
        description='E.g.: configure_bot telegram token=YourBotSuperToken')
    parser_configure_bot.add_argument(
        'bot_alias', help='Bot alias to apply settings to')
    parser_configure_bot.add_argument(
        'settings',
        help='Settings string, format: setting1=val1 setting2=val2. '
             'Supported settings for telegram bot: token.',
        nargs='*')

    parser_walk = subp_main.add_parser(
        'walk', help='Walks through registered torrents and performs automatic updates')
    parser_walk.add_argument(
        '-f', help='Forces walk. Forced walks do not respect walk interval settings', dest='forced',
        action='store_true')
    parser_walk.add_argument(
        '--dump', help='Dump web pages scraped by torrt into current or a given directory', dest='dump')

    parser_run_bots = subp_main.add_parser(
        'run_bots', help='Run registered bots')
    parser_run_bots.add_argument(
        'aliases', help='Bots to run aliases',
        nargs='*')

    parser_set_interval = subp_main.add_parser(
        'set_walk_interval', help='Sets an interval *in hours* between consecutive torrent updates checks')
    parser_set_interval.add_argument(
        'walk_interval', help='Interval *in hours* between consecutive torrent updates checks')

    parser_enable_rpc = subp_main.add_parser('enable_rpc', help='Enables RPC by its alias')
    parser_enable_rpc.add_argument('alias', help='Alias of RPC to enable')

    parser_disable_rpc = subp_main.add_parser('disable_rpc', help='Disables RPC by its alias')
    parser_disable_rpc.add_argument('alias', help='Alias of RPC to disable')

    parser_add_torrent = subp_main.add_parser(
        'add_torrent', help='Adds torrent from an URL both to torrt and torrent clients')
    parser_add_torrent.add_argument(
        'url', help='URL to download torrent from')
    parser_add_torrent.add_argument(
        '-d',
        help='Destination path to download torrent contents into (in filesystem where torrent client daemon works)',
        dest='download_to', default=None)

    parser_remove_torrent = subp_main.add_parser(
        'remove_torrent', help='Removes torrent by its hash both from torrt and torrent clients')
    parser_remove_torrent.add_argument(
        'hash', help='Torrent identifying hash')
    parser_remove_torrent.add_argument(
        '-d', help='If set data downloaded for torrent will also be removed',
        dest='delete_data', action='store_true')

    parser_register_torrent = subp_main.add_parser(
        'register_torrent',
        help='Registers torrent within torrt by its hash (for torrents already existing at torrent clients)')
    parser_register_torrent.add_argument(
        'hash', help='Torrent identifying hash')
    parser_register_torrent.add_argument(
        '-u', dest='url', default=None, help='URL to download torrent from')

    parser_unregister_torrent = subp_main.add_parser(
        'unregister_torrent', help='Unregisters torrent from torrt by its hash')
    parser_unregister_torrent.add_argument(
        'hash', help='Torrent identifying hash')

    parser_remove_notifier = subp_main.add_parser(
        'remove_notifier', help='Remove configured notifier by its alias')
    parser_remove_notifier.add_argument('alias', help='Alias of notifier to remove')

    for parser in subp_main.choices.values():
        parser.add_argument('--verbose', help='Switch to show debug messages', dest='verbose', action='store_true')

    args = arg_parser.parse_args()
    args = vars(args)

    configure_logging(logging.DEBUG if args.get('verbose') else logging.INFO)

    bootstrap()

    if args['command'] == 'enable_rpc':
        toggle_rpc(args['alias'], True)

    elif args['command'] == 'disable_rpc':
        toggle_rpc(args['alias'], False)

    elif args['command'] == 'list_trackers':

        for tracker_alias, _ in TrackerClassesRegistry.get().items():
            LOGGER.info(tracker_alias)

    elif args['command'] == 'list_rpc':
        rpc_statuses = {}

        for rpc_alias, rpc in RPCClassesRegistry.get().items():
            rpc_statuses[rpc_alias] = 'unconfigured'

        for rpc_alias, rpc in RPCObjectsRegistry.get().items():
            rpc_statuses[rpc_alias] = 'enabled' if rpc.enabled else 'disabled'

        for rpc_alias, rpc_status in rpc_statuses.items():
            LOGGER.info('%s\t status=%s', rpc_alias, rpc_status)

    elif args['command'] == 'list_torrents':
        for torrent_hash, torrent_data in get_registered_torrents().items():
            LOGGER.info('%s\t%s', torrent_hash, torrent_data['name'])

    elif args['command'] == 'list_notifiers':
        notifiers = {}
        for notifier_alias in NotifierClassesRegistry.get().keys():
            notifiers[notifier_alias] = 'unconfigured'

        for notifier_alias in NotifierObjectsRegistry.get().keys():
            notifiers[notifier_alias] = 'enabled'

        for notifier_alias, notifier_status in notifiers.items():
            LOGGER.info('%s\t status=%s', notifier_alias, notifier_status)

    elif args['command'] == 'walk':
        dump_into = args.get('dump')

        if dump_into:
            GlobalParam.set('dump_into', path.abspath(dump_into))

        walk(forced=args['forced'], silent=True)

    elif args['command'] == 'set_walk_interval':
        set_walk_interval(args['walk_interval'])

    elif args['command'] == 'add_torrent':
        add_torrent_from_url(args['url'], args['download_to'])

    elif args['command'] == 'remove_torrent':
        remove_torrent(args['hash'], args['delete_data'])

    elif args['command'] == 'register_torrent':
        register_torrent(args['hash'], url=args['url'])

    elif args['command'] == 'unregister_torrent':
        unregister_torrent(args['hash'])

    elif args['command'] == 'configure_rpc':
        configure_rpc(args['rpc_alias'], settings_dict_from_list(args['settings']))

    elif args['command'] == 'configure_tracker':
        configure_tracker(args['tracker_alias'], settings_dict_from_list(args['settings']))

    elif args['command'] == 'configure_notifier':
        configure_notifier(args['notifier_alias'], settings_dict_from_list(args['settings']))

    elif args['command'] == 'remove_notifier':
        remove_notifier(args['alias'])

    elif args['command'] == 'configure_bot':
        configure_bot(args['bot_alias'], settings_dict_from_list(args['settings']))

    elif args['command'] == 'run_bots':
        run_bots(args['aliases'])