Merge migrations, pull schedules daily

pull/131/head
stijndcl 2022-09-17 19:22:27 +02:00
parent ac24688a73
commit 8fea65e4ad
23 changed files with 337 additions and 566 deletions

3
.gitignore vendored
View File

@ -157,3 +157,6 @@ cython_debug/
# Debugging files
debug.py
# Schedule .ics files
/files/schedules/

View File

@ -1,39 +0,0 @@
"""Deadlines
Revision ID: 08d21b2d1a0a
Revises: 3962636f3a3d
Create Date: 2022-08-12 23:44:13.947011
"""
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision = "08d21b2d1a0a"
down_revision = "3962636f3a3d"
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"deadlines",
sa.Column("deadline_id", sa.Integer(), nullable=False),
sa.Column("course_id", sa.Integer(), nullable=True),
sa.Column("name", sa.Text(), nullable=False),
sa.Column("deadline", sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(
["course_id"],
["ufora_courses.course_id"],
),
sa.PrimaryKeyConstraint("deadline_id"),
)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("deadlines")
# ### end Alembic commands ###

View File

@ -1,56 +0,0 @@
"""Initial currency models
Revision ID: 0d03c226d881
Revises: b2d511552a1f
Create Date: 2022-06-30 20:02:27.284759
"""
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision = "0d03c226d881"
down_revision = "b2d511552a1f"
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table("users", sa.Column("user_id", sa.BigInteger(), nullable=False), sa.PrimaryKeyConstraint("user_id"))
op.create_table(
"bank",
sa.Column("bank_id", sa.Integer(), nullable=False),
sa.Column("user_id", sa.BigInteger(), nullable=True),
sa.Column("dinks", sa.BigInteger(), server_default="0", nullable=False),
sa.Column("interest_level", sa.Integer(), server_default="1", nullable=False),
sa.Column("capacity_level", sa.Integer(), server_default="1", nullable=False),
sa.Column("rob_level", sa.Integer(), server_default="1", nullable=False),
sa.ForeignKeyConstraint(
["user_id"],
["users.user_id"],
),
sa.PrimaryKeyConstraint("bank_id"),
)
op.create_table(
"nightly_data",
sa.Column("nightly_id", sa.Integer(), nullable=False),
sa.Column("user_id", sa.BigInteger(), nullable=True),
sa.Column("last_nightly", sa.Date, nullable=True),
sa.Column("count", sa.Integer(), server_default="0", nullable=False),
sa.ForeignKeyConstraint(
["user_id"],
["users.user_id"],
),
sa.PrimaryKeyConstraint("nightly_id"),
)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("nightly_data")
op.drop_table("bank")
op.drop_table("users")
# ### end Alembic commands ###

View File

@ -1,38 +0,0 @@
"""Add birthdays
Revision ID: 1716bfecf684
Revises: 581ae6511b98
Create Date: 2022-07-19 21:46:42.796349
"""
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision = "1716bfecf684"
down_revision = "581ae6511b98"
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"birthdays",
sa.Column("birthday_id", sa.Integer(), nullable=False),
sa.Column("user_id", sa.BigInteger(), nullable=True),
sa.Column("birthday", sa.Date, nullable=False),
sa.ForeignKeyConstraint(
["user_id"],
["users.user_id"],
),
sa.PrimaryKeyConstraint("birthday_id"),
)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("birthdays")
# ### end Alembic commands ###

View File

@ -1,36 +0,0 @@
"""Create tasks
Revision ID: 346b408c362a
Revises: 1716bfecf684
Create Date: 2022-07-23 19:41:07.029482
"""
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision = "346b408c362a"
down_revision = "1716bfecf684"
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"tasks",
sa.Column("task_id", sa.Integer(), nullable=False),
sa.Column("task", sa.Enum("BIRTHDAYS", "UFORA_ANNOUNCEMENTS", name="tasktype"), nullable=False),
sa.Column("previous_run", sa.DateTime(), nullable=True),
sa.PrimaryKeyConstraint("task_id"),
sa.UniqueConstraint("task"),
)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("tasks")
sa.Enum("BIRTHDAYS", "UFORA_ANNOUNCEMENTS", name="tasktype").drop(op.get_bind())
# ### end Alembic commands ###

View File

@ -1,37 +0,0 @@
"""Meme templates
Revision ID: 36300b558ef1
Revises: 08d21b2d1a0a
Create Date: 2022-08-25 01:34:22.845955
"""
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision = "36300b558ef1"
down_revision = "08d21b2d1a0a"
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"meme",
sa.Column("meme_id", sa.Integer(), nullable=False),
sa.Column("name", sa.Text(), nullable=False),
sa.Column("template_id", sa.Integer(), nullable=False),
sa.Column("field_count", sa.Integer(), nullable=False),
sa.PrimaryKeyConstraint("meme_id"),
sa.UniqueConstraint("name"),
sa.UniqueConstraint("template_id"),
)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("meme")
# ### end Alembic commands ###

View File

@ -1,63 +0,0 @@
"""Wordle
Revision ID: 38b7c29f10ee
Revises: 36300b558ef1
Create Date: 2022-08-29 20:21:02.413631
"""
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision = "38b7c29f10ee"
down_revision = "36300b558ef1"
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"wordle_word",
sa.Column("word_id", sa.Integer(), nullable=False),
sa.Column("word", sa.Text(), nullable=False),
sa.Column("day", sa.Date(), nullable=False),
sa.PrimaryKeyConstraint("word_id"),
sa.UniqueConstraint("day"),
)
op.create_table(
"wordle_guesses",
sa.Column("wordle_guess_id", sa.Integer(), nullable=False),
sa.Column("user_id", sa.BigInteger(), nullable=True),
sa.Column("guess", sa.Text(), nullable=False),
sa.ForeignKeyConstraint(
["user_id"],
["users.user_id"],
),
sa.PrimaryKeyConstraint("wordle_guess_id"),
)
op.create_table(
"wordle_stats",
sa.Column("wordle_stats_id", sa.Integer(), nullable=False),
sa.Column("user_id", sa.BigInteger(), nullable=True),
sa.Column("last_win", sa.Date(), nullable=True),
sa.Column("games", sa.Integer(), server_default="0", nullable=False),
sa.Column("wins", sa.Integer(), server_default="0", nullable=False),
sa.Column("current_streak", sa.Integer(), server_default="0", nullable=False),
sa.Column("highest_streak", sa.Integer(), server_default="0", nullable=False),
sa.ForeignKeyConstraint(
["user_id"],
["users.user_id"],
),
sa.PrimaryKeyConstraint("wordle_stats_id"),
)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("wordle_stats")
op.drop_table("wordle_guesses")
op.drop_table("wordle_word")
# ### end Alembic commands ###

View File

@ -1,35 +0,0 @@
"""Add custom links
Revision ID: 3962636f3a3d
Revises: 346b408c362a
Create Date: 2022-08-10 00:54:05.668255
"""
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision = "3962636f3a3d"
down_revision = "346b408c362a"
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"links",
sa.Column("link_id", sa.Integer(), nullable=False),
sa.Column("name", sa.Text(), nullable=False),
sa.Column("url", sa.Text(), nullable=False),
sa.PrimaryKeyConstraint("link_id"),
sa.UniqueConstraint("name"),
)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("links")
# ### end Alembic commands ###

View File

@ -1,63 +0,0 @@
"""Initial migration
Revision ID: 4ec79dd5b191
Revises:
Create Date: 2022-06-19 00:31:58.384360
"""
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision = "4ec79dd5b191"
down_revision = None
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"ufora_courses",
sa.Column("course_id", sa.Integer(), nullable=False),
sa.Column("name", sa.Text(), nullable=False),
sa.Column("code", sa.Text(), nullable=False),
sa.Column("year", sa.Integer(), nullable=False),
sa.Column("log_announcements", sa.Boolean(), nullable=False),
sa.PrimaryKeyConstraint("course_id"),
sa.UniqueConstraint("code"),
sa.UniqueConstraint("name"),
)
op.create_table(
"ufora_announcements",
sa.Column("announcement_id", sa.Integer(), nullable=False),
sa.Column("course_id", sa.Integer(), nullable=True),
sa.Column("publication_date", sa.Date, nullable=True),
sa.ForeignKeyConstraint(
["course_id"],
["ufora_courses.course_id"],
),
sa.PrimaryKeyConstraint("announcement_id"),
)
op.create_table(
"ufora_course_aliases",
sa.Column("alias_id", sa.Integer(), nullable=False),
sa.Column("alias", sa.Text(), nullable=False),
sa.Column("course_id", sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(
["course_id"],
["ufora_courses.course_id"],
),
sa.PrimaryKeyConstraint("alias_id"),
sa.UniqueConstraint("alias"),
)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("ufora_course_aliases")
op.drop_table("ufora_announcements")
op.drop_table("ufora_courses")
# ### end Alembic commands ###

View File

@ -1,33 +0,0 @@
"""Add dad jokes
Revision ID: 581ae6511b98
Revises: 632b69cdadde
Create Date: 2022-07-15 23:37:08.147611
"""
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision = "581ae6511b98"
down_revision = "632b69cdadde"
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"dad_jokes",
sa.Column("dad_joke_id", sa.Integer(), nullable=False),
sa.Column("joke", sa.Text(), nullable=False),
sa.PrimaryKeyConstraint("dad_joke_id"),
)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("dad_jokes")
# ### end Alembic commands ###

View File

@ -1,28 +0,0 @@
"""Add missing defaults
Revision ID: 632b69cdadde
Revises: 8c4ad0a1d699
Create Date: 2022-07-03 16:29:07.387011
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '632b69cdadde'
down_revision = '8c4ad0a1d699'
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###

View File

@ -1,32 +0,0 @@
"""Move dinks over to Bank & add invested amount
Revision ID: 8c4ad0a1d699
Revises: 0d03c226d881
Create Date: 2022-07-03 16:27:11.330746
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '8c4ad0a1d699'
down_revision = '0d03c226d881'
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('bank', schema=None) as batch_op:
batch_op.add_column(sa.Column('invested', sa.BigInteger(), server_default='0', nullable=False))
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('bank', schema=None) as batch_op:
batch_op.drop_column('invested')
# ### end Alembic commands ###

View File

@ -1,57 +0,0 @@
"""Add custom commands
Revision ID: b2d511552a1f
Revises: 4ec79dd5b191
Create Date: 2022-06-21 22:10:05.590846
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'b2d511552a1f'
down_revision = '4ec79dd5b191'
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('custom_commands',
sa.Column('command_id', sa.Integer(), nullable=False),
sa.Column('name', sa.Text(), nullable=False),
sa.Column('indexed_name', sa.Text(), nullable=False),
sa.Column('response', sa.Text(), nullable=False),
sa.PrimaryKeyConstraint('command_id'),
sa.UniqueConstraint('name')
)
with op.batch_alter_table('custom_commands', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_custom_commands_indexed_name'), ['indexed_name'], unique=False)
op.create_table('custom_command_aliases',
sa.Column('alias_id', sa.Integer(), nullable=False),
sa.Column('alias', sa.Text(), nullable=False),
sa.Column('indexed_alias', sa.Text(), nullable=False),
sa.Column('command_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['command_id'], ['custom_commands.command_id'], ),
sa.PrimaryKeyConstraint('alias_id'),
sa.UniqueConstraint('alias')
)
with op.batch_alter_table('custom_command_aliases', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_custom_command_aliases_indexed_alias'), ['indexed_alias'], unique=False)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('custom_command_aliases', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_custom_command_aliases_indexed_alias'))
op.drop_table('custom_command_aliases')
with op.batch_alter_table('custom_commands', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_custom_commands_indexed_name'))
op.drop_table('custom_commands')
# ### end Alembic commands ###

View File

@ -0,0 +1,244 @@
"""Initial migration
Revision ID: ea9811f060aa
Revises:
Create Date: 2022-09-17 17:31:20.593318
"""
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision = "ea9811f060aa"
down_revision = None
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"custom_commands",
sa.Column("command_id", sa.Integer(), nullable=False),
sa.Column("name", sa.Text(), nullable=False),
sa.Column("indexed_name", sa.Text(), nullable=False),
sa.Column("response", sa.Text(), nullable=False),
sa.PrimaryKeyConstraint("command_id"),
sa.UniqueConstraint("name"),
)
with op.batch_alter_table("custom_commands", schema=None) as batch_op:
batch_op.create_index(batch_op.f("ix_custom_commands_indexed_name"), ["indexed_name"], unique=False)
op.create_table(
"dad_jokes",
sa.Column("dad_joke_id", sa.Integer(), nullable=False),
sa.Column("joke", sa.Text(), nullable=False),
sa.PrimaryKeyConstraint("dad_joke_id"),
)
op.create_table(
"links",
sa.Column("link_id", sa.Integer(), nullable=False),
sa.Column("name", sa.Text(), nullable=False),
sa.Column("url", sa.Text(), nullable=False),
sa.PrimaryKeyConstraint("link_id"),
sa.UniqueConstraint("name"),
)
op.create_table(
"meme",
sa.Column("meme_id", sa.Integer(), nullable=False),
sa.Column("name", sa.Text(), nullable=False),
sa.Column("template_id", sa.Integer(), nullable=False),
sa.Column("field_count", sa.Integer(), nullable=False),
sa.PrimaryKeyConstraint("meme_id"),
sa.UniqueConstraint("name"),
sa.UniqueConstraint("template_id"),
)
op.create_table(
"tasks",
sa.Column("task_id", sa.Integer(), nullable=False),
sa.Column("task", sa.Enum("BIRTHDAYS", "SCHEDULES", "UFORA_ANNOUNCEMENTS", name="tasktype"), nullable=False),
sa.Column("previous_run", sa.DateTime(timezone=True), nullable=True),
sa.PrimaryKeyConstraint("task_id"),
sa.UniqueConstraint("task"),
)
op.create_table(
"ufora_courses",
sa.Column("course_id", sa.Integer(), nullable=False),
sa.Column("name", sa.Text(), nullable=False),
sa.Column("code", sa.Text(), nullable=False),
sa.Column("year", sa.Integer(), nullable=False),
sa.Column("compulsory", sa.Boolean(), server_default="1", nullable=False),
sa.Column("role_id", sa.Integer(), nullable=True),
sa.Column("log_announcements", sa.Boolean(), server_default="0", nullable=False),
sa.PrimaryKeyConstraint("course_id"),
sa.UniqueConstraint("code"),
sa.UniqueConstraint("name"),
)
op.create_table("users", sa.Column("user_id", sa.BigInteger(), nullable=False), sa.PrimaryKeyConstraint("user_id"))
op.create_table(
"wordle_word",
sa.Column("word_id", sa.Integer(), nullable=False),
sa.Column("word", sa.Text(), nullable=False),
sa.Column("day", sa.Date(), nullable=False),
sa.PrimaryKeyConstraint("word_id"),
sa.UniqueConstraint("day"),
)
op.create_table(
"bank",
sa.Column("bank_id", sa.Integer(), nullable=False),
sa.Column("user_id", sa.BigInteger(), nullable=True),
sa.Column("dinks", sa.BigInteger(), server_default="0", nullable=False),
sa.Column("invested", sa.BigInteger(), server_default="0", nullable=False),
sa.Column("interest_level", sa.Integer(), server_default="1", nullable=False),
sa.Column("capacity_level", sa.Integer(), server_default="1", nullable=False),
sa.Column("rob_level", sa.Integer(), server_default="1", nullable=False),
sa.ForeignKeyConstraint(
["user_id"],
["users.user_id"],
),
sa.PrimaryKeyConstraint("bank_id"),
)
op.create_table(
"birthdays",
sa.Column("birthday_id", sa.Integer(), nullable=False),
sa.Column("user_id", sa.BigInteger(), nullable=True),
sa.Column("birthday", sa.Date(), nullable=False),
sa.ForeignKeyConstraint(
["user_id"],
["users.user_id"],
),
sa.PrimaryKeyConstraint("birthday_id"),
)
op.create_table(
"bookmarks",
sa.Column("bookmark_id", sa.Integer(), nullable=False),
sa.Column("label", sa.Text(), nullable=False),
sa.Column("jump_url", sa.Text(), nullable=False),
sa.Column("user_id", sa.BigInteger(), nullable=True),
sa.ForeignKeyConstraint(
["user_id"],
["users.user_id"],
),
sa.PrimaryKeyConstraint("bookmark_id"),
sa.UniqueConstraint("user_id", "label"),
)
op.create_table(
"custom_command_aliases",
sa.Column("alias_id", sa.Integer(), nullable=False),
sa.Column("alias", sa.Text(), nullable=False),
sa.Column("indexed_alias", sa.Text(), nullable=False),
sa.Column("command_id", sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(
["command_id"],
["custom_commands.command_id"],
),
sa.PrimaryKeyConstraint("alias_id"),
sa.UniqueConstraint("alias"),
)
with op.batch_alter_table("custom_command_aliases", schema=None) as batch_op:
batch_op.create_index(batch_op.f("ix_custom_command_aliases_indexed_alias"), ["indexed_alias"], unique=False)
op.create_table(
"deadlines",
sa.Column("deadline_id", sa.Integer(), nullable=False),
sa.Column("course_id", sa.Integer(), nullable=True),
sa.Column("name", sa.Text(), nullable=False),
sa.Column("deadline", sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(
["course_id"],
["ufora_courses.course_id"],
),
sa.PrimaryKeyConstraint("deadline_id"),
)
op.create_table(
"nightly_data",
sa.Column("nightly_id", sa.Integer(), nullable=False),
sa.Column("user_id", sa.BigInteger(), nullable=True),
sa.Column("last_nightly", sa.Date(), nullable=True),
sa.Column("count", sa.Integer(), server_default="0", nullable=False),
sa.ForeignKeyConstraint(
["user_id"],
["users.user_id"],
),
sa.PrimaryKeyConstraint("nightly_id"),
)
op.create_table(
"ufora_announcements",
sa.Column("announcement_id", sa.Integer(), nullable=False),
sa.Column("course_id", sa.Integer(), nullable=True),
sa.Column("publication_date", sa.Date(), nullable=True),
sa.ForeignKeyConstraint(
["course_id"],
["ufora_courses.course_id"],
),
sa.PrimaryKeyConstraint("announcement_id"),
)
op.create_table(
"ufora_course_aliases",
sa.Column("alias_id", sa.Integer(), nullable=False),
sa.Column("alias", sa.Text(), nullable=False),
sa.Column("course_id", sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(
["course_id"],
["ufora_courses.course_id"],
),
sa.PrimaryKeyConstraint("alias_id"),
sa.UniqueConstraint("alias"),
)
op.create_table(
"wordle_guesses",
sa.Column("wordle_guess_id", sa.Integer(), nullable=False),
sa.Column("user_id", sa.BigInteger(), nullable=True),
sa.Column("guess", sa.Text(), nullable=False),
sa.ForeignKeyConstraint(
["user_id"],
["users.user_id"],
),
sa.PrimaryKeyConstraint("wordle_guess_id"),
)
op.create_table(
"wordle_stats",
sa.Column("wordle_stats_id", sa.Integer(), nullable=False),
sa.Column("user_id", sa.BigInteger(), nullable=True),
sa.Column("last_win", sa.Date(), nullable=True),
sa.Column("games", sa.Integer(), server_default="0", nullable=False),
sa.Column("wins", sa.Integer(), server_default="0", nullable=False),
sa.Column("current_streak", sa.Integer(), server_default="0", nullable=False),
sa.Column("highest_streak", sa.Integer(), server_default="0", nullable=False),
sa.ForeignKeyConstraint(
["user_id"],
["users.user_id"],
),
sa.PrimaryKeyConstraint("wordle_stats_id"),
)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("wordle_stats")
op.drop_table("wordle_guesses")
op.drop_table("ufora_course_aliases")
op.drop_table("ufora_announcements")
op.drop_table("nightly_data")
op.drop_table("deadlines")
with op.batch_alter_table("custom_command_aliases", schema=None) as batch_op:
batch_op.drop_index(batch_op.f("ix_custom_command_aliases_indexed_alias"))
op.drop_table("custom_command_aliases")
op.drop_table("bookmarks")
op.drop_table("birthdays")
op.drop_table("bank")
op.drop_table("wordle_word")
op.drop_table("users")
op.drop_table("ufora_courses")
op.drop_table("tasks")
op.drop_table("meme")
op.drop_table("links")
op.drop_table("dad_jokes")
with op.batch_alter_table("custom_commands", schema=None) as batch_op:
batch_op.drop_index(batch_op.f("ix_custom_commands_indexed_name"))
op.drop_table("custom_commands")
# ### end Alembic commands ###

View File

@ -1,40 +0,0 @@
"""Bookmarks
Revision ID: f5da771a155d
Revises: 38b7c29f10ee
Create Date: 2022-08-30 01:08:54.323883
"""
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision = "f5da771a155d"
down_revision = "38b7c29f10ee"
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"bookmarks",
sa.Column("bookmark_id", sa.Integer(), nullable=False),
sa.Column("label", sa.Text(), nullable=False),
sa.Column("jump_url", sa.Text(), nullable=False),
sa.Column("user_id", sa.BigInteger(), nullable=True),
sa.ForeignKeyConstraint(
["user_id"],
["users.user_id"],
),
sa.PrimaryKeyConstraint("bookmark_id"),
sa.UniqueConstraint("user_id", "label"),
)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("bookmarks")
# ### end Alembic commands ###

View File

@ -10,4 +10,5 @@ class TaskType(enum.IntEnum):
"""Enum for the different types of tasks"""
BIRTHDAYS = enum.auto()
SCHEDULES = enum.auto()
UFORA_ANNOUNCEMENTS = enum.auto()

View File

@ -197,6 +197,8 @@ class UforaCourse(Base):
name: str = Column(Text, nullable=False, unique=True)
code: str = Column(Text, nullable=False, unique=True)
year: int = Column(Integer, nullable=False)
compulsory: bool = Column(Boolean, server_default="1", nullable=False)
role_id: Optional[int] = Column(Integer, nullable=True, unique=False)
log_announcements: bool = Column(Boolean, server_default="0", nullable=False)
announcements: list[UforaAnnouncement] = relationship(

View File

View File

@ -41,6 +41,7 @@ class Tasks(commands.Cog):
self._tasks = {
"birthdays": self.check_birthdays,
"schedules": self.pull_schedules,
"ufora": self.pull_ufora_announcements,
"remove_ufora": self.remove_old_ufora_announcements,
"wordle": self.reset_wordle_word,
@ -59,6 +60,7 @@ class Tasks(commands.Cog):
# Start other tasks
self.reset_wordle_word.start()
self.pull_schedules.start()
@overrides
def cog_unload(self) -> None:
@ -110,6 +112,32 @@ class Tasks(commands.Cog):
async def _before_check_birthdays(self):
await self.client.wait_until_ready()
@tasks.loop(time=DAILY_RESET_TIME)
@timed_task(enums.TaskType.SCHEDULES)
async def pull_schedules(self, **kwargs):
"""Task that pulls the schedules & saves the files locally
Schedules are then parsed & cached in memory
"""
_ = kwargs
for data in settings.SCHEDULE_DATA:
if data.schedule_url is None:
return
async with self.client.http_session.get(data.schedule_url) as response:
# If a schedule couldn't be fetched, log it and move on
if response.status != 200:
await self.client.log_warning(
f"Unable to fetch schedule {data.name} (status {response.status}).", log_to_discord=False
)
continue
# Write the content to a file
content = await response.text()
with open(f"files/schedules/{data.name}.ics", "w+") as fp:
fp.write(content)
@tasks.loop(minutes=10)
@timed_task(enums.TaskType.UFORA_ANNOUNCEMENTS)
async def pull_ufora_announcements(self, **kwargs):
@ -166,3 +194,4 @@ async def setup(client: Didier):
cog = Tasks(client)
await client.add_cog(cog)
await cog.reset_wordle_word()
await cog.pull_schedules()

View File

@ -1,6 +1,6 @@
# The year in which we were in 1Ba
import settings
# The year in which we were in 1Ba
FIRST_YEAR = 2019
# Year to use when adding the current year of our education
# to find the academic year

View File

@ -1,5 +1,6 @@
import logging
import os
import pathlib
import discord
from aiohttp import ClientSession
@ -59,6 +60,9 @@ class Didier(commands.Bot):
This hook is called once the bot is initialised
"""
# Create directories that are ignored on GitHub
self._create_ignored_directories()
# Load the Wordle dictionary
self._load_wordle_words()
@ -67,19 +71,26 @@ class Didier(commands.Bot):
async with self.postgres_session as session:
await self.database_caches.initialize_caches(session)
# Create aiohttp session
self.http_session = ClientSession()
# Load extensions
await self._load_initial_extensions()
await self._load_directory_extensions("didier/cogs")
# Create aiohttp session
self.http_session = ClientSession()
# Configure channel to send errors to
if settings.ERRORS_CHANNEL is not None:
self.error_channel = self.get_channel(settings.ERRORS_CHANNEL)
else:
self.error_channel = self.get_user(self.owner_id)
def _create_ignored_directories(self):
"""Create directories that store ignored data"""
ignored = ["files/schedules"]
for directory in ignored:
pathlib.Path(directory).mkdir(exist_ok=True, parents=True)
async def _load_initial_extensions(self):
"""Load all extensions that should be loaded before the others"""
for extension in self.initial_extensions:
@ -138,13 +149,27 @@ class Didier(commands.Bot):
"""Add an X to a message"""
await message.add_reaction("")
async def log_error(self, message: str, log_to_discord: bool = True):
"""Send an error message to the logs, and optionally the configured channel"""
logger.error(message)
async def _log(self, level: int, message: str, log_to_discord: bool = True):
"""Log a message to the logging file, and optionally to the configured channel"""
methods = {
logging.ERROR: logger.error,
logging.WARNING: logger.warning,
}
methods.get(level, logger.error)(message)
if log_to_discord:
# TODO pretty embed
# different colours per level?
await self.error_channel.send(message)
async def log_error(self, message: str, log_to_discord: bool = True):
"""Log an error message"""
await self._log(logging.ERROR, message, log_to_discord)
async def log_warning(self, message: str, log_to_discord: bool = True):
"""Log a warning message"""
await self._log(logging.WARNING, message, log_to_discord)
async def on_ready(self):
"""Event triggered when the bot is ready"""
print(settings.DISCORD_READY_MESSAGE)

View File

@ -6,6 +6,7 @@ discord.py==2.0.1
git+https://github.com/Rapptz/discord-ext-menus@8686b5d
environs==9.5.0
feedparser==6.0.10
ics==0.7.2
markdownify==0.11.2
overrides==6.1.0
pydantic==1.9.1

View File

@ -1,3 +1,4 @@
from dataclasses import dataclass
from typing import Optional
from environs import Env
@ -22,10 +23,13 @@ __all__ = [
"DISCORD_BOOS_REACT",
"DISCORD_CUSTOM_COMMAND_PREFIX",
"UFORA_ANNOUNCEMENTS_CHANNEL",
"BA3_ROLE",
"UFORA_RSS_TOKEN",
"URBAN_DICTIONARY_TOKEN",
"IMGFLIP_NAME",
"IMGFLIP_PASSWORD",
"BA3_SCHEDULE_URL",
"SCHEDULE_DATA",
]
@ -35,6 +39,7 @@ TESTING: bool = env.bool("TESTING", False)
LOGFILE: str = env.str("LOGFILE", "didier.log")
SEMESTER: int = env.int("SEMESTER", 2)
YEAR: int = env.int("YEAR", 3)
MENU_TIMEOUT: int = env.int("MENU_TIMEOUT", 30)
"""Database"""
# PostgreSQL
@ -56,11 +61,29 @@ BIRTHDAY_ANNOUNCEMENT_CHANNEL: Optional[int] = env.int("BIRTHDAY_ANNOUNCEMENT_CH
ERRORS_CHANNEL: Optional[int] = env.int("ERRORS_CHANNEL", None)
UFORA_ANNOUNCEMENTS_CHANNEL: Optional[int] = env.int("UFORA_ANNOUNCEMENTS_CHANNEL", None)
""""General config"""
MENU_TIMEOUT: int = env.int("MENU_TIMEOUT", 30)
"""Discord Role ID's"""
BA3_ROLE: Optional[int] = env.int("BA3_ROLE", 891743208248324196)
"""API Keys"""
UFORA_RSS_TOKEN: Optional[str] = env.str("UFORA_RSS_TOKEN", None)
URBAN_DICTIONARY_TOKEN: Optional[str] = env.str("URBAN_DICTIONARY_TOKEN", None)
IMGFLIP_NAME: Optional[str] = env.str("IMGFLIP_NAME", None)
IMGFLIP_PASSWORD: Optional[str] = env.str("IMGFLIP_PASSWORD", None)
"""Schedule URLs"""
BA3_SCHEDULE_URL: Optional[str] = env.str("BA3_SCHEDULE_URL", None)
"""Computed properties"""
@dataclass
class ScheduleInfo:
"""Dataclass to hold and combine some information about schedule-related settings"""
role_id: Optional[int]
schedule_url: Optional[str]
name: Optional[str] = None
SCHEDULE_DATA = [ScheduleInfo(name="ba3", role_id=BA3_ROLE, schedule_url=BA3_SCHEDULE_URL)]