示例#1
0
def notify_completed(bot: Bot, _):
    logger.info('executing completed job')

    completed = qb.torrents(filter='completed')

    for t in completed:
        if completed_torrents.is_new(t.hash):
            torrent = qb.torrent(t.hash)

            if config.qbittorrent.get('pause_completed_torrents', False):
                logger.info('pausing %s (%s)', torrent.name, torrent.hash)
                torrent.pause()

            if not dont_notify_torrents.send_notification(t.hash):
                logger.info('we will not send a notification about %s (%s)', t.hash, t.name)
                continue

            text = '<code>{}</code> completed ({})'.format(u.html_escape(torrent.name), torrent.size_pretty)

            send_message_kwargs = dict(
                text=text,
                parse_mode=ParseMode.HTML,
                disable_web_page_preview=True,
                disable_notification=True
            )

            if config.telegram.get('completed_torrents_notification', None):
                # don't send the message in private if there's a notifications channel set
                bot.send_message(config.telegram.completed_torrents_notification, **send_message_kwargs)
            else:
                bot.send_message(
                    config.telegram.admins[0],
                    reply_markup=torrent.short_markup(force_resume_button=False),
                    **send_message_kwargs
                )
    def _enrich_torrent_dict(self):
        if 'progress' in self._torrent_dict:
            self._torrent_dict['eta'] = 0 if self._torrent_dict['progress'] == 1 else self._torrent_dict['eta']  # set eta = 0 for completed torrents
            self._torrent_dict['progress_bar'] = u.build_progress_bar(self._torrent_dict['progress'])
        if 'hash' in self._torrent_dict:
            self._torrent_dict['manage_deeplink'] = 'https://t.me/{}?start=manage{}'.format(
                self._qbt._bot_username,
                self._torrent_dict['hash']
            )
            self._torrent_dict['info_deeplink'] = 'https://t.me/{}?start=info{}'.format(
                self._qbt._bot_username,
                self._torrent_dict['hash']
            )

        self._torrent_dict['short_name'] = self._torrent_dict['name']
        if len(self._torrent_dict['name']) > 51:
            self._torrent_dict['short_name'] = self._torrent_dict['name'][:51].strip() + '...'
        self._torrent_dict['short_name_escaped'] = u.html_escape(self._torrent_dict['short_name'])

        self._torrent_dict['generic_speed'] = self._torrent_dict['dlspeed']
        icon = '▼'
        if self._torrent_dict['state'] in ('uploading', 'forcedUP', 'stalledUP'):
            self._torrent_dict['generic_speed'] = self._torrent_dict['upspeed']
            icon = '▲'
        generic_speed_human_readable = u.get_human_readable(self._torrent_dict['generic_speed'])
        self._torrent_dict['traffic_direction_icon'] = f"{icon}"

        for k, v in NEW_ATTRS.items():
            try:
                self._torrent_dict[k] = v(self._torrent_dict)
            except KeyError:
                # it might be that one of the lambdas uses a key that is not available in the torrent dict,
                # eg. when get_additional_torrent_properties is not True
                continue
示例#3
0
def ask_confirm_delete_with_files_cb(_, update, groups):
    logger.info('delete with files inline button')

    torrent_hash = groups[0]
    logger.info('torrent hash: %s', torrent_hash)

    torrent = qb.torrent(torrent_hash)
    # torrent.delete(with_files=True)

    update.callback_query.edit_message_text(
        '你确定要删除吗 {}, <b>连同文件一起删除</b>?'.format(u.html_escape(torrent.name)),
        reply_markup=kb.confirm_delete(torrent.hash),
        parse_mode=ParseMode.HTML)
    update.callback_query.answer('请再次确认')
示例#4
0
def ask_confirm_delete_with_files_cb(_, update, groups):
    logger.info('delete with files inline button')

    torrent_hash = groups[0]
    logger.info('torrent hash: %s', torrent_hash)

    torrent = qb.torrent(torrent_hash)
    # torrent.delete(with_files=True)

    update.callback_query.edit_message_text(
        'Are you sure you want to delete {}, <b>with all the connected files included</b>?'
        .format(u.html_escape(torrent.name)),
        reply_markup=kb.confirm_delete(torrent.hash),
        parse_mode=ParseMode.HTML)
    update.callback_query.answer('Confirmation needed')
示例#5
0
def see_trackers_cb(_, update, groups):
    logger.info('trackers inline button')

    torrent_hash = groups[0]
    logger.info('torrent hash: %s', torrent_hash)

    torrent = qb.torrent(torrent_hash)
    trackers = torrent.trackers()

    strings_list = [
        '<b>{status}:</b> {url} <b>({num_peers})</b>'.format(
            **{k: u.html_escape(str(v))
               for k, v in tracker.items()}) for tracker in trackers
    ]
    text = '\n'.join(strings_list)

    if len(text) > MAX_MESSAGE_LENGTH:
        trackers_info = dict()
        for tracker in trackers:
            if not trackers_info.get(tracker['status'], None):
                trackers_info[tracker['status']] = dict(count=0, num_peers=0)

            trackers_info[tracker['status']]['count'] += 1
            trackers_info[
                tracker['status']]['num_peers'] += tracker['num_peers']

        lines_list = list()
        for status, status_counts in trackers_info.items():
            lines_list.append('<b>{}</b>: {} trackers, {} peers'.format(
                status, status_counts['count'], status_counts['num_peers']))

        text = '\n'.join(lines_list)

    update.callback_query.edit_message_text(
        text or 'No trackers',
        reply_markup=torrent.actions_keyboard,
        parse_mode=ParseMode.HTML,
        disable_web_page_preview=True)
    update.callback_query.answer('Trackers list')
def see_trackers_cb(update: Update, context: CallbackContext):
    logger.info('trackers inline button')

    torrent_hash = context.match[1]
    logger.info('torrent hash: %s', torrent_hash)

    torrent = qb.torrent(torrent_hash)
    trackers = torrent.trackers()

    strings_list = [
        '<b>{status}:</b> {url} <b>({num_peers} peers)</b>'.format(
            **{k: u.html_escape(str(v))
               for k, v in tracker.items()}) for tracker in trackers
    ]
    text = '\n'.join(strings_list)

    if len(text) > MAX_MESSAGE_LENGTH:
        trackers_info = dict()
        for tracker in trackers:
            tracker_status = tracker['status']
            if not trackers_info.get(tracker_status, None):
                trackers_info[tracker_status] = dict(count=0, num_peers=0)

            trackers_info[tracker_status]['count'] += 1
            trackers_info[tracker_status]['num_peers'] += tracker['num_peers']

        lines_list = list()
        for status, status_counts in trackers_info.items():
            lines_list.append(
                f"<b>{status}</b>: {status_counts['count']} trackers, {status_counts['num_peers']} peers"
            )

        text = '\n'.join(lines_list)

    update.callback_query.edit_message_text(
        text or 'No trackers',
        reply_markup=torrent.actions_keyboard,
        parse_mode=ParseMode.HTML)
    update.callback_query.answer('Trackers list')
示例#7
0
def notify_completed(context: CallbackContext):
    logger.info('executing completed job')

    completed = qb.torrents(filter='completed')

    for t in completed:
        if not completed_torrents.is_new(t.hash):
            continue

        torrent = qb.torrent(t.hash)

        logger.info('completed: %s (%s)', torrent.hash, torrent.name)

        if not config.telegram.get('completed_torrents_notification', None):
            continue

        if not dont_notify_torrents.send_notification(t.hash):
            logger.info('notification disabled for torrent %s (%s)', t.hash,
                        t.name)
            continue

        tags_lower = [tag.lower() for tag in torrent.tags]
        if config.telegram.get(
                "no_notification_tag", None
        ) and config.telegram.no_notification_tag.lower() in tags_lower:
            continue

        drive_free_space = u.free_space(qb.save_path)
        text = '<code>{}</code> completed ({}, free space: {})'.format(
            u.html_escape(torrent.name), torrent.size_pretty, drive_free_space)

        context.bot.send_message(
            chat_id=config.telegram.completed_torrents_notification,
            text=text,
            parse_mode=ParseMode.HTML,
            disable_web_page_preview=True,
            disable_notification=True)
    'forcedDL': 'forced download',
    'checkingResumeData': 'startup: checking data',
    'moving': 'moving',
    'unknown': 'unknown status'
}

# https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#get-torrent-list
# https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#get-torrent-generic-properties
NEW_ATTRS = {
    'state_pretty': lambda t: STATES_DICT.get(t['state'], t['state']),
    'size_pretty': lambda t: u.get_human_readable(t['total_size']),  # already a string apparently
    'dl_speed_pretty': lambda t: u.get_human_readable(t['dl_speed']),
    'up_speed_pretty': lambda t: u.get_human_readable(t['up_speed']),
    'dlspeed_pretty': lambda t: u.get_human_readable(t['dlspeed']),
    'upspeed_pretty': lambda t: u.get_human_readable(t['upspeed']),
    'name_escaped': lambda t: u.html_escape(t['name']),
    'generic_speed_pretty': lambda t: u.get_human_readable(t['generic_speed']),
    'progress_pretty': lambda t: math.floor(t['progress'] * 100),  # eg. 99.9% should be rounded to 99%
    'eta_pretty': lambda t: str(datetime.timedelta(seconds=t['eta'])),  # apparently it's already a string?
    'time_elapsed_pretty': lambda t: str(datetime.timedelta(seconds=t['time_elapsed'])),
    'force_start_pretty': lambda t: 'yes' if t['force_start'] else 'no',
    'share_ratio_rounded': lambda t: round(t['ratio'], 2),
    'dl_limit_pretty': lambda t: 'no limit' if t['dl_limit'] == -1 else u.get_human_readable(t['dl_limit']),
    'auto_tmm_string': lambda t: 'yes' if t['auto_tmm'] else 'no',
}

TORRENT_STRING = """<code>{name_escaped}</code>
  {progress_bar} {progress_pretty}%
  <b>state</b>: {state_pretty}
  <b>size</b>: {size_pretty}
  <b>dl/up speed</b>: {dl_speed_pretty}/s, {up_speed_pretty}/s