summaryrefslogtreecommitdiff
path: root/process-polls.py
blob: cd64764826610dbf03f2e7d4335e84dd34ad4600 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
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()