summaryrefslogtreecommitdiff
path: root/readme.txt
blob: 080d379ddd4f4abeac997a33f5b40107b3c9e3d6 (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
101
102
103
104
105
106
107
108
109
110
111
112
113
=== bracket bot ===

  this is a system for running a bracket in discord via polls

=== usage ===

  == requirements ==

    this project uses python with the requests library. assuming you have the
    pip and venv modules for python, you can set up an environment like so:

      python3 -m venv env
      env/bin/pip3 install -r requirements.txt

  == create database ==

    next, we need to make a csv file with a list of entries in our bracket.
    each line of the csv file corresponds to one entry. if a line has one
    column, the text in that column is the name of the entry. if a line has
    two columns, the text in the first column is the name of the entry, and
    the text in the second column is an associated emoji. this can be a unicode
    emoji (at time of writing, discord supports up to unicode 15.0), or it can
    be the id of a server emoji that your bot will have access to.

    now, use the make-db.py script to create the database. there are two
    positional arguments, first the path where the database will be created,
    and second the path to the csv file to read. there is one optional
    argument, "-s". if this argument is present, the entries are shuffled,
    and otherwise the order from the csv file is preserved.

    for example, if the csv file we made is in entries.csv, we want to put the
    database in database.db, and we want to shuffle the entries, we can run:

      python3 make-db.py database.db entries.csv -s

    we do not need to use our venv environment when we run this.

  == posting a poll ==

    to post a poll, use the post-poll.py script. this has three positional
    arguments. first, the path to the database. second, the id of the channel
    to post in. third, the number of hours to keep the poll open for. the
    script also expects an environment variable named TOKEN with the bot
    token. with the setup above, if we want a bot with token ABC123DEF456
    to post a 24-hour poll in a channel whose id is 1234567890, we can run:

      TOKEN=ABC123DEF456 env/bin/python3 post-poll.py database.db 1234567890 24

    the script finds two entries that have not been eliminated and are not
    currently in any (unprocessed) polls. entries are picked first preferring
    entries that have never been in a poll in the order from the database
    creation step, and then entries that have been in polls in the order that
    the most recent polls they were each in in occurred. for two entries that
    have the same most recent poll (i.e. ones where the most recent poll was a
    tie), the order from the database creation step is used. if there are not
    two qualified entries, the script just prints a message and quits.

  == processing polls ==

    to process the posted polls, use the process-polls.py script. this script
    has one positional argument, the path to the database. it also expects the
    environment variable TOKEN as above. with the setup above, to have the same
    bot process all of its polls, we can run:

      TOKEN=ABC123DEF456 env/bin/python3 process-polls.py database.db

    the script waits until every posted poll has both expired and finalized.

  == cron script ==

    it is recommended to call a script like this from a crontab once per day:

      start_time=$(date +%s)
      cd bracket-bot
      export TOKEN=ABC123DEF456
      env/bin/python3 process-polls.py database.db
      now_time=$(date +%s)
      hours=$(echo \($start_time + 86400 - $now_time\) / 3600 | bc)
      env/bin/python3 post-poll.py database.db 1234567890 $hours

    this script posts one poll that lasts as long as it can while expiring
    within 24 hours of this script starting. to post more than one poll per
    day, you can put the last three lines in a loop that runs some number of
    times. change the bot token, the channel, and the paths as needed.

=== database schema ===

  == table entries ==

    name TEXT UNIQUE NOT NULL - json string representing the name of the entry
    emoji TEXT - either null, a unicode emoji, or a discord emoji id
    status INT NOT NULL - 0 = safe, 1 = in poll, 2 = eliminated
    last_poll_number INT NOT NULL - poll_number for the last (or current) poll it was in, or 0 if none
    sort_number INT UNIQUE NOT NULL - a number used to sort the entries (the values don't matter, just the order)

  == table polls ==

    poll_number INT UNIQUE NOT NULL - what number poll it is (starts at 1)
    entry_1 TEXT NOT NULL - entries.name for first entry
    entry_2 TEXT NOT NULL - entries.name for second entry
    posted INT NOT NULL - unix timestamp of when poll was posted
    expires INT NOT NULL - unix timestamp of when poll expires / expired
    channel_id TEXT NOT NULL - discord channel with poll
    message_id TEXT NOT NULL - discord message with poll
    voters_1 TEXT - comma-separated user ids who voted for first entry, or null if active
    voters_2 TEXT - comma-separated user ids who voted for second entry, or null if active

  == table users ==

    id TEXT UNIQUE NOT NULL - discord id
    global_display TEXT NOT NULL - global display name, or username if there is none
    avatar_hash TEXT - the user's avatar hash on discord's cdn, or null if they haven't set one
    retrieved INT NOT NULL - unix timestamp of when this was last updated