From 87d07ac5b9a4529199cb3f807e4ceff982c588c2 Mon Sep 17 00:00:00 2001 From: Benji Dial Date: Thu, 5 Sep 2024 21:16:43 -0400 Subject: new new version --- readme.txt | 154 ++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 111 insertions(+), 43 deletions(-) (limited to 'readme.txt') diff --git a/readme.txt b/readme.txt index c6c1e59..080d379 100644 --- a/readme.txt +++ b/readme.txt @@ -1,45 +1,113 @@ === bracket bot === -before you begin, you will need the following: -* a discord bot token - (see e.g. https://github.com/reactiflux/discord-irc/wiki/Creating-a-discord-bot-&-getting-a-token) -* the channel id of the channel where the polls should be posted - (see https://support.discord.com/hc/en-us/articles/206346498-Where-can-I-find-my-User-Server-Message-ID) -* a list of entries for your bracket - -to build the bracket bot, just run make. the bracket bot uses libcurl, -libsqlite3, and Niels Lohmann's json library. the json library is downloaded -at build time. the required packages to build on debian are the following: -* g++ -* libcurl-dev (this is a virtual package, satisfiable by a few options) -* libsqlite3-dev -* make -* wget - -when the bot is run, it expects the following environment variables: -* BOT_TOKEN: the bot token -* CHANNEL_ID: the channel id -* POLLS_PER_DAY: the number of polls to post each day -* POST_TIME_UTC: the number of seconds past midnight utc to post the polls - (for example, to post at midnight eastern daylight time, set this to 14400) -and it expects to find a list of entries, separated by newlines, in a file -named entries.txt in the directory where it is run. - -the bot creates a sqlite3 database in database.db, with the following tables: -* misc: this contains one column and one row with the current round number -* entries: a list of every entry - * name: the name of the entry - * round: if the entry has been eliminated, a zero. if the entry has passed - the current round, then the number of the next round. if the entry has not - appeared in a poll this round, or is in an active poll, then the number of - the current round. - * in_active_poll: if the entry is in an active poll, a one, otherwise a zero -* active_polls: a list of the message ids for the active polls -* past_polls: a list of every concluded poll - * round: the round where this poll happened - * entry_1: the name of the first entry - * entry_2: the name of the second entry - * users_1: the user ids of the users who voted - for the first entry, separated by commas - * users_2: the user ids of the users who voted - for the second entry, separated by commas + 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 -- cgit v1.2.3