def fetch_rutracker_meta(torrents):
    # first, fetch topic ids by infohash
    hashes = {torrent_hash(torrent_dict): torrent_dict for torrent_dict in torrents}
    thread_ids = api.get_topic_id(hashes.keys())
    for infohash, torrent_dict in hashes.iteritems():
        if infohash in thread_ids and thread_ids[infohash] is not None:
            torrent_dict[RUTRACKER_META_KEY] = {"thread_id": thread_ids[infohash]}
        else:
            torrent_dict[RUTRACKER_META_KEY] = 0

    # remove torrents that has no corresponding thread at tracker
    unrelated_indices = [i for i in range(0, len(torrents)) if isinstance(torrents[i][RUTRACKER_META_KEY], int)]
    for i in reversed(unrelated_indices):
        del torrents[i]

    # fetch threads details
    thread_ids = {str(torrent_dict[RUTRACKER_META_KEY]["thread_id"]): torrent_dict for torrent_dict in torrents}
    thread_details = api.get_tor_topic_data(thread_ids.keys())
    for thread_id, torrent_dict in thread_ids.iteritems():
        torrent_dict[RUTRACKER_META_KEY]["thread_details"] = thread_details[thread_id]
    local_strong = [str(tpl[0]) for tpl in stat.local.items() if tpl[1].avg() > 2.5]
    remote_dying = [str(tpl[0]) for tpl in stat.remote.items() if tpl[1].avg() < 1]

    local_strong = [sha1.lower() for sha1 in api.get_tor_hash(local_strong).values() if sha1]
    remote_dying = api.get_tor_hash(remote_dying)

    local_strong = [sha1 for sha1 in local_strong if qbt.is_torrent_exists(sha1)]
    remote_dying = [kv[0] for kv in remote_dying.iteritems() if not qbt.is_torrent_exists(kv[1])]

    print "Weak local: {}".format(sum(int(tpl[1].avg() < 1) for tpl in stat.local.items()))
    print "Strong local: {}".format(len(local_strong))
    print "Dying remote: {}".format(len(remote_dying))
    continue

    qbt.remove_torrents(local_strong)

    for i in range(0, len(remote_dying)):
        print 'processing {} out of {}'.format(i, len(remote_dying))
        id = remote_dying[i]
        with open('/tmp/dl/{}.torrent'.format(id), 'wb') as f:
            api.reliable_download_torrent(f, config.keeper_user_id, config.keeper_api_key, id)

torrents = config.torrents_source(*config.torrents_source_args)
torrents_meta = []

infohashes = [os.path.splitext(os.path.basename(torrent_fname))[0] for torrent_fname in torrents]
thread_ids = api.get_topic_id(infohashes)
orphaned_local = [sha1 for sha1 in thread_ids.keys() if thread_ids[sha1] is None]
print 'Orphaned local: {}'.format(len(orphaned_local))

def compact_torrent_stats(stats):
    return {
        's0': [thread_id for thread_id in stats.keys() if stats[thread_id] == 0],
        's1': [thread_id for thread_id in stats.keys() if stats[thread_id] == 1],
        's2': [thread_id for thread_id in stats.keys() if stats[thread_id] == 2],
        's3m': [thread_id for thread_id in stats.keys() if stats[thread_id] >= 3]
    }

torrents = config.torrents_source(*config.torrents_source_args)
torrents_meta = []

# first, fetch topic ids by infohash
infohashes = [os.path.splitext(os.path.basename(torrent_fname))[0] for torrent_fname in torrents]
thread_ids = set(api.get_topic_id(infohashes).values())

db_record = {
    'ts': datetime.datetime.now(),
    'forums': {}
}

# fetch torrents' stats from server
for forum_id in config.keeped_forums:
    torrents_stats = api.get_forum_torrents_status(forum_id)
    torrents_stats = { int(id): torrents_stats[id] for id in torrents_stats.keys() }

    # form stat for local torrents
    local_torrents = { thread_id: torrents_stats[thread_id][1]
        for thread_id in thread_ids
        if thread_id in torrents_stats and len(torrents_stats[thread_id]) > 1