Skip to content

Commit

Permalink
Update database to use sqlite peewee
Browse files Browse the repository at this point in the history
  • Loading branch information
Saverio976 committed Sep 19, 2024
1 parent e705ece commit 19b1fb5
Show file tree
Hide file tree
Showing 6 changed files with 327 additions and 80 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ COPY pyproject.toml uv.lock /app
WORKDIR /app
RUN uv sync --frozen
COPY . /app
CMD [ "uv", "run", "./worldtimezone/__main__.py" ]
CMD [ "uv", "run", "python", "-O", "./worldtimezone/__main__.py" ]
4 changes: 3 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ requires-python = ">=3.12"
dependencies = [
"apscheduler>=3.10.4",
"hikari-lightbulb>=2.3.5.post0",
"hikari>=2.0.0",
"hikari[speedups]>=2.0.0",
"peewee>=3.17.6",
"pytz>=2024.1",
'uvloop>=0.20.0 ; platform_system != "Windows"',
]
193 changes: 191 additions & 2 deletions uv.lock

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions worldtimezone/__main__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import asyncio
import os

import hikari
import lightbulb
from hikari import Intents
from lightbulb.ext import tasks

if os.name != "nt":
import uvloop

asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())

INTENTS = Intents.GUILD_MEMBERS | Intents.GUILDS

bot = lightbulb.BotApp(
Expand Down
36 changes: 22 additions & 14 deletions worldtimezone/extensions/edit_world_clock.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@

@tasks.task(m=5, auto_start=True, pass_app=True)
async def edit_world_clock(bot: lightbulb.BotApp) -> None:
def create_embed(guild_id, u, tz):
user_ = bot.cache.get_member(guild_id, int(u))
await bot.wait_for(hikari.StartedEvent, timeout=None)

def create_embed(guild_id, member_id, tz):
print("guild_id", guild_id, "member_id", member_id)
user_ = bot.cache.get_member(guild_id, int(member_id))
if user_ is None:
return None
embed = (
hikari.Embed(
title=f"WorldTimeClock - {user_.display_name}",
Expand All @@ -26,19 +31,22 @@ def create_embed(guild_id, u, tz):
embed.add_field("Time", f"{new_now}", inline=False)
return embed

for guild_id in bot.d.data.get_guilds_list():
for guild in bot.d.data.get_guilds_list():
embeds = []
guild_world_clock = bot.d.data.get_world_clock(guild_id)
channel_world_clock = guild_world_clock["channel_id"]
message_world_clock = guild_world_clock["message_id"]

for u in bot.d.data.get_members_list(guild_id):
member = bot.d.data.get_member(guild_id, u)
if "tz" in member:
embeds.append(create_embed(guild_id, u, member["tz"]))
await bot.rest.edit_message(
channel_world_clock, message_world_clock, None, embeds=embeds
)
channel_world_clock = guild.channel_id
message_world_clock = guild.message_id

for u in bot.d.data.get_members_list(guild.discord_id) or []:
if u.tz != "":
embed = create_embed(guild.discord_id, u.discord_id, u.tz)
if embed is not None:
embeds.append(embed)
else:
print(f"Failed user: {guild.discord_id} {u.discord_id}")
if len(embeds) != 0:
await bot.rest.edit_message(
channel_world_clock, message_world_clock, None, embeds=embeds
)


def load(bot: lightbulb.BotApp):
Expand Down
166 changes: 104 additions & 62 deletions worldtimezone/extensions/world_clock_data.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import json
import os
from typing import Optional

import peewee
import pytz

FILE_INFO = ".data/tz_v2.json"
FILE_INFO_V2 = ".data/tz_v2.json"
FILE_SQLITE_DB = ".data/tz_v3.db"

db = peewee.SqliteDatabase(FILE_SQLITE_DB)


COMMON_TIMEZONES = [
Expand All @@ -28,73 +33,110 @@
]


class DBBaseModel(peewee.Model):
class Meta:
database = db


class DBGuild(DBBaseModel):
discord_id = peewee.CharField(unique=True)
channel_id = peewee.CharField(default="")
message_id = peewee.CharField(default="")


class DBMember(DBBaseModel):
discord_id = peewee.CharField()
tz = peewee.CharField(default="")
guild = peewee.ForeignKeyField(DBGuild, backref="members")


class WorldClockData:
def __init__(self):
try:
with open(FILE_INFO) as f:
file = json.load(f)
except FileNotFoundError:
with open(FILE_INFO, mode="w") as f:
file = {}
json.dump(file, f)
self._data = file

def get_guilds_list(self) -> list:
return list(self._data)

def get_member(self, guild_id, user_id) -> dict:
guild_id = f"{guild_id}"
user_id = f"{user_id}"
if guild_id not in self._data:
return {}
if user_id not in self._data[guild_id]["members"]:
return {}
member = self._data[guild_id]["members"][user_id]
return member

def get_members_list(self, guild_id) -> list:
guild_id = f"{guild_id}"
if guild_id not in self._data:
return []
if "members" not in self._data[guild_id]:
return []
return list(self._data[guild_id]["members"].keys())
db.connect()
db.create_tables([DBGuild, DBMember])
# START Transform old format to new
if os.path.isfile(FILE_INFO_V2):
import json

def set_member_tz(self, guild_id, user_id, tz) -> str:
if tz not in pytz.all_timezones:
return False
guild_id = f"{guild_id}"
user_id = f"{user_id}"
tz = f"{tz}"
if guild_id not in self._data:
self._data[guild_id] = {}
if "members" not in self._data[guild_id]:
self._data[guild_id]["members"] = {}
if user_id not in self._data[guild_id]["members"]:
self._data[guild_id]["members"][user_id] = {}
self._data[guild_id]["members"][user_id]["tz"] = tz
with open(FILE_INFO, mode="w") as f:
json.dump(self._data, f)
return True
with open(FILE_INFO_V2) as f:
data = json.load(f)
for guild_id, guild_value in data.items():
new_guild = DBGuild(discord_id=guild_id)
if (
"worldclockchannel" in guild_value
and "channel_id" in guild_value["worldclockchannel"]
and "message_id" in guild_value["worldclockchannel"]
):
new_guild.channel_id = guild_value["worldclockchannel"][
"channel_id"
]
new_guild.message_id = guild_value["worldclockchannel"][
"message_id"
]
new_guild.save()
if "members" in guild_value:
for member_id, member_value in guild_value["members"].items():
new_member = DBMember(
discord_id=member_id,
guild=new_guild,
)
if "tz" in member_value:
new_member.tz = member_value["tz"]
new_member.save()
os.remove(FILE_INFO_V2)
# END Transform old format to new

# Guild

def set_world_clock(self, guild_id, channel_id, message_id) -> bool:
def get_guild(self, guild_id) -> Optional[DBGuild]:
guild_id = f"{guild_id}"
try:
return DBGuild.select().where(DBGuild.discord_id == guild_id).get()
except DBGuild.DoesNotExist:
return None

def get_guilds_list(self) -> list[DBGuild]:
guilds = DBGuild.select()
print(guilds)
for g in guilds:
print("abc::", g.discord_id)
return list(guilds)

def set_guild_world_clock(self, guild: DBGuild, channel_id, message_id) -> bool:
channel_id = f"{channel_id}"
message_id = f"{message_id}"
if guild_id not in self._data:
self._data[guild_id] = {}
if "worldclockchannel" not in self._data[guild_id]:
self._data[guild_id]["worldclockchannel"] = {}
self._data[guild_id]["worldclockchannel"]["channel_id"] = channel_id
self._data[guild_id]["worldclockchannel"]["message_id"] = message_id
with open(FILE_INFO, mode="w") as f:
json.dump(self._data, f)
guild.channel_id = channel_id
guild.message_id = message_id
guild.save()
return True

def get_world_clock(self, guild_id) -> dict:
# Member

def get_member(self, guild_id, user_id) -> Optional[DBMember]:
guild_id = f"{guild_id}"
if guild_id not in self._data:
return {}
if "worldclockchannel" not in self._data[guild_id]:
return {}
return self._data[guild_id]["worldclockchannel"]
user_id = f"{user_id}"
try:
return (
DBMember.select()
.where(
(DBMember.discord_id == user_id)
& (DBMember.guild.discord_id == guild_id)
)
.get()
)
except DBMember.DoesNotExist:
return None

def get_members_list(self, guild_id) -> Optional[list[DBMember]]:
guild_id = f"{guild_id}"
try:
return DBGuild.select().where(DBGuild.discord_id == guild_id).get().members
except DBGuild.DoesNotExist:
return None

def set_member_tz(self, member: DBMember, tz: str) -> str:
if tz not in pytz.all_timezones:
return False
member.tz = tz
member.save()
return True

0 comments on commit 19b1fb5

Please sign in to comment.