from os import environ import argparse import discord import sqlite3 import time ap = argparse.ArgumentParser() ap.add_argument('database', help='the file with the database') a = ap.parse_args() if 'TOKEN' not in environ: print('please set an environment variable TOKEN with the bot token') exit(1) token = environ['TOKEN'] dbcon = sqlite3.connect(a.database) cur = dbcon.cursor() rows = cur.execute(''' SELECT entry_1, entry_2, poll_number, expires, channel_id, message_id FROM polls WHERE voters_1 IS NULL ORDER BY expires ''').fetchall() s = discord.session(token) def get_all_voters(s, channel, message, answer): endpoint_base = f'/channels/{channel}/polls/{message}/answers/{answer}?limit=100' users = discord.get(s, endpoint_base)['users'] if len(users) < 100: return users while True: new_users = discord.get(s, endpoint_base + f'&after={users[-1]["id"]}')['users'] users += new_users if len(new_users) < 100: return users for row in rows: expires = row[3] sleep_for = expires - time.time() if sleep_for > 0: time.sleep(sleep_for) result = None time_to_sleep = 1 while True: result = discord.get(s, f'/channels/{row[4]}/messages/{row[5]}') if result['poll']['results']['is_finalized']: break time.sleep(time_to_sleep) time_to_sleep *= 2 answer_list_1 = list(filter(lambda x: x['poll_media']['text'] == row[0], result['poll']['answers'])) answer_list_2 = list(filter(lambda x: x['poll_media']['text'] == row[1], result['poll']['answers'])) if len(answer_list_1) != 1 or len(answer_list_2) != 1: exit(1) the_time = time.time() voters_1 = get_all_voters(s, row[4], row[5], answer_list_1[0]['answer_id']) voters_2 = get_all_voters(s, row[4], row[5], answer_list_2[0]['answer_id']) cur.executemany('INSERT OR REPLACE INTO users VALUES(?, ?, ?, ?)', list(map(lambda x: (x['id'], x['global_name'], x['avatar'], the_time), voters_1 + voters_2))) cur.execute(''' UPDATE polls SET voters_1 = ?, voters_2 = ? WHERE poll_number = ? LIMIT 1 ''', ( ','.join(map(lambda x: x['id'], voters_1)), ','.join(map(lambda x: x['id'], voters_2)), row[2] )) cur.executemany(''' UPDATE entries SET status = ? WHERE name = ? LIMIT 1 ''', [ (0 if len(voters_1) >= len(voters_2) else 2, row[0]), (0 if len(voters_2) >= len(voters_1) else 2, row[1]) ]) dbcon.commit()