Create and use of User object, fix of notif, start of multi languages support and start help on commands and errors
This commit is contained in:
parent
b2ba8aecaf
commit
fde9cdaf4e
5 changed files with 123 additions and 120 deletions
|
@ -16,7 +16,8 @@ class Calendar(ics.Calendar):
|
|||
self.events = events
|
||||
self.timeline = Timeline(self)
|
||||
|
||||
def _url(self, time: str, url: list, pass_week: bool):
|
||||
@staticmethod
|
||||
def _url(time: str, url: list, pass_week: bool):
|
||||
now = datetime.datetime.now(datetime.timezone.utc).astimezone(tz=None)
|
||||
if now.isoweekday() in [6, 7] and pass_week:
|
||||
now += datetime.timedelta(days=(7 - (now.isoweekday() - 1)))
|
||||
|
@ -43,7 +44,6 @@ class Calendar(ics.Calendar):
|
|||
return msg
|
||||
|
||||
|
||||
|
||||
class Event(ics.Event):
|
||||
def __init__(self, event: ics.Event):
|
||||
super().__init__()
|
||||
|
@ -57,8 +57,8 @@ class Event(ics.Event):
|
|||
def __str__(self):
|
||||
return markdown.text(
|
||||
markdown.bold(f"<{str(self.begin.date())[5:]}>"),
|
||||
markdown.code(f"📓[{self.name}]:"),
|
||||
markdown.text(f"⌚️ {str(self.begin.time())[:-3]} -> {str(self.end.time())[:-3]}"),
|
||||
markdown.italic(f"📍 {self.location} 👨🏫 {self.organizer}"),
|
||||
markdown.code(f"\uD83D\uDCD3[{self.name}]:"),
|
||||
markdown.text(f"\u231A{str(self.begin.time())[:-3]} -> {str(self.end.time())[:-3]}"),
|
||||
markdown.italic(f"\uD83D\uDCCD{self.location} \uD83D\uDC68\u200D\uD83C\uDFEB{self.organizer}"),
|
||||
sep="\n"
|
||||
)
|
||||
) # surrogates not allowed
|
||||
|
|
16
EDTuser.py
Normal file
16
EDTuser.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
from EDTcalendar import Calendar
|
||||
import datetime
|
||||
|
||||
|
||||
class User:
|
||||
def __init__(self, user_id: int, language: str):
|
||||
self.id = user_id
|
||||
self.language = language
|
||||
self.resources = None
|
||||
self.nt = False
|
||||
self.nt_time = 20
|
||||
self.nt_cooldown = 20
|
||||
self.nt_last = datetime.datetime.now(datetime.timezone.utc).astimezone(tz=None)
|
||||
|
||||
def calendar(self, time: str = "", pass_week: bool = False):
|
||||
return Calendar(time, self.resources, pass_week=pass_week)
|
15
Languages/en.json
Normal file
15
Languages/en.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"welcome": "\uD83D\uDCA0 *Welcome to the TelegramEDT bot !* \uD83D\uDCA0\n\uD83D\uDD39Please use the command /setedt to set your calendar\n\uD83D\uDD39Use /notif to configure events notification\n\u2139And /help for more commands",
|
||||
"help": "\u2139 *Commands help* \u2139\n\uD83D\uDCC5/edt, show your next events\n\uD83D\uDD14/notif, set your events notifications\n\u2699/setedt, set your calendar",
|
||||
"edt_err_set": "Your EDT is not set ! \u274C\n\u2139Use /setedt to fix that",
|
||||
"edt_err_choice": "Invalid choice ! \u274C\n\u2139You can choose between: `day`, `next`, `week`, `next week`",
|
||||
"setedt_err_res": "Invalid resources ! \u274C",
|
||||
"setedt": "EDT set \u2705",
|
||||
"getedt_err": "No EDT set ! \u274C",
|
||||
"notif_set": "Notifications set on `{}` ! \u2705",
|
||||
"notif_err_num": "Invalid number ! \u274C",
|
||||
"notif_time_cooldown": "Notification `{}` set to `{}` ! \u2705",
|
||||
"notif_info": "_Notification_\n*State:* {}\n*Time:* {}\n*Cooldown:* {}",
|
||||
"notif_help": "\u2139 *Notif help* \u2139\n\uD83D\uDD39`toggle` to switch on/off notifications\n\uD83D\uDD39`time` to set time in minutes between notification and event\n\uD83D\uDD39`cooldown` set time in minutes between notification",
|
||||
"notif_err_act": "Invalid action ! \u274C\n\u2139Use /notif to see help"
|
||||
}
|
191
bot.py
191
bot.py
|
@ -13,6 +13,8 @@ from aiogram.types import InlineQuery, InputTextMessageContent, InlineQueryResul
|
|||
from aiogram.utils import markdown
|
||||
from aiogram.utils.exceptions import MessageIsTooLong
|
||||
from EDTcalendar import Calendar
|
||||
from EDTuser import User
|
||||
from lang import lang
|
||||
from ics.parse import ParseError
|
||||
from requests.exceptions import ConnectionError, InvalidSchema, MissingSchema
|
||||
|
||||
|
@ -40,14 +42,19 @@ dp = Dispatcher(bot)
|
|||
dbL = RLock()
|
||||
|
||||
|
||||
def get_now():
|
||||
return datetime.datetime.now(datetime.timezone.utc).astimezone(tz=None)
|
||||
|
||||
|
||||
def calendar(time: str, user_id: int):
|
||||
with dbL:
|
||||
with shelve.open("edt", writeback=True) as db:
|
||||
if str(user_id) not in db or "resources" not in db[str(user_id)]:
|
||||
return markdown.bold("Your EDT is not set ! ❌")
|
||||
user = db[str(user_id)]
|
||||
if not user.resources:
|
||||
return lang(user, "edt_err_set")
|
||||
elif time not in TIMES:
|
||||
return markdown.bold("Invalid choice ! ❌")
|
||||
return str(Calendar(time, db[str(user_id)]["resources"]))
|
||||
return lang(user, "edt_err_choice")
|
||||
return str(user.calendar(time))
|
||||
|
||||
|
||||
async def notif():
|
||||
|
@ -55,16 +62,13 @@ async def notif():
|
|||
with dbL:
|
||||
with shelve.open("edt", writeback=True) as db:
|
||||
for u in db:
|
||||
if ("resources" in db[u]) and ("notif" in db[u]) and (db[u]["notif"]["state"]):
|
||||
logger.info(f"notif check for {u}")
|
||||
now = datetime.datetime.now(datetime.timezone.utc).astimezone(tz=None)
|
||||
c = Calendar("day", db[u]["resources"], pass_week=False)
|
||||
if db[u].resources and db[u].nt:
|
||||
now = get_now()
|
||||
c = db[u].calendar(pass_week=True)
|
||||
for e in c.timeline:
|
||||
logger.info(f"{(e.begin - now).total_seconds().__abs__()//60.} <= {db[u]['notif']['time']} and {(now - db[u]['notif']['last']).total_seconds()//60} | >= {db[u]['notif']['cooldown']}")
|
||||
logger.info(f"{(e.begin - now).total_seconds().__abs__()//60 <= db[u]['notif']['time']} and {(now - db[u]['notif']['last']).total_seconds()//60 >= db[u]['notif']['cooldown']}")
|
||||
if (e.begin - now).total_seconds().__abs__()//60 <= db[u]["notif"]["time"] and\
|
||||
(now - db[u]["notif"]["last"]).total_seconds()//60 >= db[u]["notif"]["cooldown"]:
|
||||
db[u]["notif"]["last"] = now
|
||||
if 0 <= (e.begin - now).total_seconds().__abs__()//60 <= db[u].nt_time and \
|
||||
0 <= (now - db[u].nt_last).total_seconds()//60 >= db[u].nt_cooldown:
|
||||
db[u].nt_last = get_now()
|
||||
await bot.send_message(int(u), e, parse_mode=ParseMode.MARKDOWN)
|
||||
await sleep(60)
|
||||
|
||||
|
@ -83,49 +87,30 @@ async def inline_edt(inline_query: InlineQuery):
|
|||
await bot.answer_inline_query(inline_query.id, results=[item], cache_time=1)
|
||||
|
||||
|
||||
@dp.message_handler(commands=["start", "help"])
|
||||
async def send_welcome(message: types.Message):
|
||||
@dp.message_handler(commands="Start")
|
||||
async def start(message: types.Message):
|
||||
user_id = str(message.from_user.id)
|
||||
await message.chat.do(types.ChatActions.TYPING)
|
||||
logger.info(f"{message.from_user.username} do start/help command: {message.text}")
|
||||
logger.info(f"{message.from_user.username} start : {message.text}")
|
||||
with dbL:
|
||||
with shelve.open("edt", writeback=True) as db:
|
||||
if str(message.from_user.id) not in db:
|
||||
db[str(message.from_user.id)] = dict()
|
||||
logger.info(f"db creation for {message.from_user.username}")
|
||||
|
||||
msg = markdown.text(
|
||||
markdown.text("💠 Welcome to the TelegramEDT, a calendar bot for the Lyon 1 University ! 💠\n"),
|
||||
markdown.text(
|
||||
markdown.text("🗓"),
|
||||
markdown.code("/edt [day | next | week | next week]"),
|
||||
markdown.text(", for show your next course")
|
||||
),
|
||||
markdown.text(
|
||||
markdown.text("🔔"),
|
||||
markdown.code("/notif <set | info | time number | cooldown number>"),
|
||||
markdown.text(", setup notifications")
|
||||
),
|
||||
markdown.text(
|
||||
markdown.text("⚙️"),
|
||||
markdown.code("/setedt <resources>"),
|
||||
markdown.text(", to setup your calendar\nThe resources can be get on the url of exported calendar")
|
||||
),
|
||||
markdown.text(
|
||||
markdown.text("🔗"),
|
||||
markdown.code("/getedt"),
|
||||
markdown.text(", to get your calendar url")
|
||||
),
|
||||
markdown.text(
|
||||
markdown.text("ℹ️"),
|
||||
markdown.code("/help"),
|
||||
markdown.text(", to show this command")
|
||||
),
|
||||
sep="\n"
|
||||
)
|
||||
await message.reply(msg, parse_mode=ParseMode.MARKDOWN)
|
||||
if user_id not in db:
|
||||
db[user_id] = User(int(user_id), message.from_user.locale.language)
|
||||
user = db[user_id]
|
||||
await message.reply(lang(user, "welcome"), parse_mode=ParseMode.MARKDOWN)
|
||||
|
||||
|
||||
@dp.message_handler(commands=["edt"])
|
||||
@dp.message_handler(commands="help")
|
||||
async def send_welcome(message: types.Message):
|
||||
await message.chat.do(types.ChatActions.TYPING)
|
||||
logger.info(f"{message.from_user.username} do help command: {message.text}")
|
||||
with dbL:
|
||||
with shelve.open("edt", writeback=True) as db:
|
||||
user = db[str(message.from_user.id)]
|
||||
await message.reply(lang(user, "help"), parse_mode=ParseMode.MARKDOWN)
|
||||
|
||||
|
||||
@dp.message_handler(commands="edt")
|
||||
@dp.message_handler(lambda msg: msg.text.lower() in TIMES[1:])
|
||||
async def edt_cmd(message: types.Message):
|
||||
await message.chat.do(types.ChatActions.TYPING)
|
||||
|
@ -142,111 +127,89 @@ async def edt_cmd(message: types.Message):
|
|||
await message.reply(resp, parse_mode=ParseMode.MARKDOWN, reply_markup=key)
|
||||
|
||||
|
||||
@dp.message_handler(commands=["setedt"])
|
||||
@dp.message_handler(commands="setedt")
|
||||
async def edt_set(message: types.Message):
|
||||
user_id = str(message.from_user.id)
|
||||
await message.chat.do(types.ChatActions.TYPING)
|
||||
logger.info(f"{message.from_user.username} do setedt command: {message.text}")
|
||||
resources = message.text[8:]
|
||||
|
||||
try:
|
||||
Calendar("", int(resources))
|
||||
except (ParseError, ConnectionError, InvalidSchema, MissingSchema, ValueError):
|
||||
msg = markdown.bold("Invalid resources ! ❌")
|
||||
else:
|
||||
with dbL:
|
||||
with shelve.open("edt", writeback=True) as db:
|
||||
db[str(message.from_user.id)]["resources"] = int(resources)
|
||||
msg = markdown.text("EDT set ✅")
|
||||
with dbL:
|
||||
with shelve.open("edt", writeback=True) as db:
|
||||
try:
|
||||
Calendar("", int(resources))
|
||||
except (ParseError, ConnectionError, InvalidSchema, MissingSchema, ValueError):
|
||||
msg = lang(db[user_id], "setedt_err_res")
|
||||
else:
|
||||
db[user_id].resources = int(resources)
|
||||
msg = lang(db[user_id], "setedt")
|
||||
|
||||
await message.reply(msg, parse_mode=ParseMode.MARKDOWN)
|
||||
await message.reply(msg, parse_mode=ParseMode.MARKDOWN)
|
||||
|
||||
|
||||
@dp.message_handler(commands=["getedt"])
|
||||
@dp.message_handler(commands="getedt")
|
||||
async def edt_geturl(message: types.Message):
|
||||
user_id = str(message.from_user.id)
|
||||
await message.chat.do(types.ChatActions.TYPING)
|
||||
logger.info(f"{message.from_user.username} do getedt command: {message.text}")
|
||||
with dbL:
|
||||
with shelve.open("edt", writeback=True) as db:
|
||||
if (str(message.from_user.id) in db) and ("resources" in db[str(message.from_user.id)]):
|
||||
await message.reply(db[str(message.from_user.id)]["resources"])
|
||||
if db[user_id].resources:
|
||||
await message.reply(db[user_id].resources)
|
||||
else:
|
||||
await message.reply("No EDT set ! ❌")
|
||||
await message.reply(lang(db[user_id], "getedt_err"))
|
||||
|
||||
|
||||
@dp.message_handler(commands=["notif"])
|
||||
@dp.message_handler(commands="notif")
|
||||
async def notif_cmd(message: types.Message):
|
||||
user_id = str(message.from_user.id)
|
||||
await message.chat.do(types.ChatActions.TYPING)
|
||||
logger.info(f"{message.from_user.username} do notif command: {message.text}")
|
||||
with dbL:
|
||||
with shelve.open("edt", writeback=True) as db:
|
||||
if "notif" not in db[str(message.from_user.id)]:
|
||||
db[str(message.from_user.id)]["notif"] = dict()
|
||||
db[str(message.from_user.id)]["notif"]["state"] = False
|
||||
db[str(message.from_user.id)]["notif"]["time"] = 20
|
||||
db[str(message.from_user.id)]["notif"]["cooldown"] = 20
|
||||
last = datetime.datetime.now(datetime.timezone.utc).astimezone(tz=None) - datetime.timedelta(minutes=20)
|
||||
db[str(message.from_user.id)]["notif"]["last"] = last
|
||||
|
||||
if message.text[7:10] == "set":
|
||||
if db[str(message.from_user.id)]["notif"]["state"]:
|
||||
if message.text[7:10] == "toggle":
|
||||
if db[user_id].nt:
|
||||
res = False
|
||||
else:
|
||||
res = True
|
||||
|
||||
db[str(message.from_user.id)]["notif"]["state"] = res
|
||||
db[user_id].nt = res
|
||||
msg = lang(db[user_id], "notif_set").format(res)
|
||||
|
||||
msg = markdown.text(
|
||||
markdown.text("Notifications set on "),
|
||||
markdown.code(res),
|
||||
markdown.text("✅")
|
||||
)
|
||||
elif message.text[7:11] == "time" or message.text[7:15] == "cooldown":
|
||||
cut = 11 if message.text[7:11] == "time" else 15
|
||||
try:
|
||||
int(message.text[cut+1:])
|
||||
except ValueError:
|
||||
msg = markdown.bold("Invalid number ! ❌")
|
||||
msg = lang(db[user_id], "notif_err_num")
|
||||
else:
|
||||
db[str(message.from_user.id)]["notif"][message.text[7:cut]] = int(message.text[cut+1:])
|
||||
if cut == 11:
|
||||
db[user_id]["notif"].nt_time = int(message.text[cut+1:])
|
||||
else:
|
||||
db[user_id]["notif"].nt_cooldown = int(message.text[cut + 1:])
|
||||
|
||||
msg = lang(db(user_id), "notif_time_cooldown").format(message.text[7:cut], message.text[cut + 1:])
|
||||
|
||||
msg = markdown.text(
|
||||
markdown.text("Notification"),
|
||||
markdown.code(message.text[7:cut]),
|
||||
markdown.text("set to"),
|
||||
markdown.bold(message.text[cut+1:]),
|
||||
markdown.text("✅")
|
||||
)
|
||||
elif message.text[7:11] == "info":
|
||||
msg = markdown.text(
|
||||
markdown.code("Notification:"),
|
||||
markdown.text(
|
||||
markdown.bold("State:"),
|
||||
markdown.text(db[str(message.from_user.id)]["notif"]["state"])
|
||||
),
|
||||
markdown.text(
|
||||
markdown.bold("Time:"),
|
||||
markdown.text(db[str(message.from_user.id)]["notif"]["time"])
|
||||
),
|
||||
markdown.text(
|
||||
markdown.bold("Cooldown:"),
|
||||
markdown.text(db[str(message.from_user.id)]["notif"]["cooldown"])
|
||||
),
|
||||
sep="\n"
|
||||
)
|
||||
msg = lang(db[user_id], "notif_info").format(db[user_id].nt, db[user_id].nt_time,
|
||||
db[user_id].nt_cooldown)
|
||||
|
||||
elif message.text[7:] == "":
|
||||
msg = lang(db[user_id], "notif_help")
|
||||
else:
|
||||
msg = markdown.bold("Invalid action ! ❌")
|
||||
msg = lang(db[user_id], "notif_err_act")
|
||||
|
||||
await message.reply(msg, parse_mode=ParseMode.MARKDOWN)
|
||||
|
||||
|
||||
@dp.message_handler(commands=["getid"])
|
||||
@dp.message_handler(commands="getid")
|
||||
async def get_id(message: types.Message):
|
||||
await message.chat.do(types.ChatActions.TYPING)
|
||||
logger.info(f"{message.from_user.username} do getid command: {message.text}")
|
||||
await message.reply(message.from_user.id)
|
||||
|
||||
|
||||
@dp.message_handler(commands=["getlogs"])
|
||||
@dp.message_handler(commands="getlogs")
|
||||
async def get_logs(message: types.Message):
|
||||
logger.info(f"{message.from_user.username} do getlog command: {message.text}")
|
||||
if message.from_user.id == ADMIN_ID:
|
||||
|
@ -272,7 +235,7 @@ async def get_logs(message: types.Message):
|
|||
await message.reply(markdown.bold("Too much logs ! ❌"))
|
||||
|
||||
|
||||
@dp.message_handler(commands=["getdb"])
|
||||
@dp.message_handler(commands="getdb")
|
||||
async def get_db(message: types.Message):
|
||||
logger.info(f"{message.from_user.username} do getdb command: {message.text}")
|
||||
if message.from_user.id == ADMIN_ID:
|
||||
|
@ -286,8 +249,8 @@ async def get_db(message: types.Message):
|
|||
await message.reply(msg, parse_mode=ParseMode.MARKDOWN)
|
||||
|
||||
|
||||
@dp.message_handler(commands=["eval"])
|
||||
async def get_db(message: types.Message):
|
||||
@dp.message_handler(commands="eval")
|
||||
async def eval_cmd(message: types.Message):
|
||||
logger.info(f"{message.from_user.username} do eval command: {message.text}")
|
||||
if message.from_user.id == ADMIN_ID:
|
||||
msg = markdown.text(
|
||||
|
|
9
lang.py
Normal file
9
lang.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
import json
|
||||
from EDTuser import User
|
||||
|
||||
LANG = ["en"]
|
||||
|
||||
|
||||
def lang(user: User, message: str):
|
||||
language = user.language if user.language in LANG else LANG[0]
|
||||
return json.loads(open(f"Languages/{language}.json", "r").read())[message]
|
Reference in a new issue