100 lines
2.5 KiB
Python
100 lines
2.5 KiB
Python
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'])
|
|
|
|
def user_to_params(user):
|
|
name = user['global_name']
|
|
if name is None:
|
|
name = user['username']
|
|
return (user['id'], name, user['avatar'], the_time)
|
|
|
|
cur.executemany('INSERT OR REPLACE INTO users VALUES(?, ?, ?, ?)',
|
|
list(map(user_to_params, 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()
|