diff --git a/.gitignore b/.gitignore index 13fbe3e..792f7d9 100644 --- a/.gitignore +++ b/.gitignore @@ -139,3 +139,4 @@ TODO.txt sql_tester.py conf outputs +dakiny.db \ No newline at end of file diff --git a/classes/election_cycle.py b/classes/election_cycle.py index 5d4a9e8..854a86a 100644 --- a/classes/election_cycle.py +++ b/classes/election_cycle.py @@ -6,8 +6,10 @@ from datetime import datetime, timedelta import nextcord from nextcord.ext import commands +from sqlalchemy.orm import Session from config import DakinyConfig +from database.sql_data_classes import ElectionInformation, engine from utils import get_datetime @@ -105,7 +107,6 @@ class ElectionCycle: Function checks current date to see if something needs to be run. """ today = datetime.today() - print("checking the date") # check all dates if action is needed if today.date() == self.election_start.date(): @@ -120,26 +121,26 @@ class ElectionCycle: await self.term_start_action() elif today.date() == self.term_end.date(): await self.term_end_action() - else: - print("today was not a special date") - print(today) async def election_start_action(self) -> None: """ Performs required actions for when the election cycle starts. """ - print("election cycle has started") # create new channel for election category: nextcord.CategoryChannel = self.bot.get_channel(self.config.params.active_category_id) - quarter_name: str = str(datetime.today().year) + "-" + self.elecion_cycle.name + "-election" - # TODO need to store this id in the sqlite database + quarter_name: str = self.get_election_cycle_name() + + # create new entry into database. election_channel = await category.create_text_channel(quarter_name) + with Session(engine) as session: + new_cycle = ElectionInformation(ElectionCycle=quarter_name, ElectionChannel=election_channel.id) + session.add(new_cycle) + session.commit() # post message announcing election # election start message is returned as an array of string because it is too long. send each string # individually. messages = self.build_election_announcement() - for message in messages: await election_channel.send(message) @@ -180,3 +181,13 @@ class ElectionCycle: """ imcompiling: nextcord.User = await self.bot.fetch_user(206602713511886849) await imcompiling.send(msg) + + def get_election_cycle_name(self) -> str: + """ + Builds the unique name of the current election cycle + + Returns: + str: the name of the election cycle + """ + + return f"{self.election_start.year} {self.elecion_cycle.name} election" diff --git a/dakiny_bot.py b/dakiny_bot.py index 56df5f6..1cf8a18 100644 --- a/dakiny_bot.py +++ b/dakiny_bot.py @@ -6,6 +6,7 @@ import nextcord from hydra.core.config_store import ConfigStore from nextcord.ext import commands +import database.create_database as create_database from config import DakinyConfig cs = ConfigStore.instance() @@ -38,6 +39,7 @@ def main(cfg: DakinyConfig): async def on_ready(): """When Discord is connected""" assert bot.user is not None + create_database # pylint: disable=pointless-statement print(f"{bot.user.name} has connected to Discord!") # Run Discord bot diff --git a/database/create_database.py b/database/create_database.py new file mode 100644 index 0000000..427f3ea --- /dev/null +++ b/database/create_database.py @@ -0,0 +1,15 @@ +""" +Small script to create the database if it doesn't already exist. +""" + +import sqlite3 +from os.path import exists + +if not exists("dakiny.db"): + with sqlite3.connect("dakiny.db") as con: + cur = con.cursor() + + with open("database/database.sql", mode="r", encoding="utf-8") as file: + database_script = file.read() + cur.executescript(database_script) + con.commit() diff --git a/database/database.sql b/database/database.sql new file mode 100644 index 0000000..dcb53fa --- /dev/null +++ b/database/database.sql @@ -0,0 +1,27 @@ +-- CREATE DATABASE dakiny; +-- use dakiny; + +CREATE TABLE ElectionInformation( + ElectionCycle varchar(30) not null unique, + ElectionChannel bigint unsigned not null, + PRIMARY KEY (ElectionCycle) +); + +CREATE TABLE CouncilMembers( + ElectionCycle varchar(30) not null unique, + MemberId bigint unsigned not null, + Elected boolean DEFAULT false, + HighCouncilElect boolean DEFAULT false, + DiscordManager boolean DEFAULT false, + ClanLeader boolean DEFAULT false, + FOREIGN KEY (ElectionCycle) REFERENCES ElectionInformation(ElectionCycle), + PRIMARY KEY (ElectionCycle, MemberId) +); + +CREATE TABLE Votes( + ElectionCycle varchar(30) not null unique, + VoterId bigint unsigned not null, + VotedForId bigint unsigned not null, + FOREIGN KEY (ElectionCycle) REFERENCES ElectionInformation(ElectionCycle), + PRIMARY KEY (ElectionCycle, VoterId) +); \ No newline at end of file diff --git a/database/sql_data_classes.py b/database/sql_data_classes.py new file mode 100644 index 0000000..cbee89d --- /dev/null +++ b/database/sql_data_classes.py @@ -0,0 +1,16 @@ +""" +Simple file to set up the sqlalchemy connection to database. +""" +from sqlalchemy import create_engine +from sqlalchemy.ext.automap import automap_base + +# connect with sql alchemy and autoload schema +URL = "sqlite+pysqlite:///dakiny.db" +engine = create_engine(URL) +Base = automap_base() +Base.prepare(autoload_with=engine) + +# define the classes +ElectionInformation = Base.classes.ElectionInformation +CouncilMembers = Base.classes.CouncilMembers +Votes = Base.classes.Votes diff --git a/requirements.txt b/requirements.txt index 2f6f7c1..3d5d68b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ nextcord==2.4.2 python-dotenv==1.0.0 pytz==2022.7.1 -hydra-core==1.3.2 \ No newline at end of file +hydra-core==1.3.2 +sqlalchemy<2.0 \ No newline at end of file