mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-23 19:44:20 +00:00
publish: 5.7.12
This commit is contained in:
parent
9c704bb535
commit
32019a15ae
4 changed files with 133 additions and 55 deletions
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "royalpack"
|
name = "royalpack"
|
||||||
version = "5.7.11"
|
version = "5.7.12"
|
||||||
description = "A Royalnet command pack for the Royal Games community"
|
description = "A Royalnet command pack for the Royal Games community"
|
||||||
authors = ["Stefano Pigozzi <ste.pigozzi@gmail.com>"]
|
authors = ["Stefano Pigozzi <ste.pigozzi@gmail.com>"]
|
||||||
license = "AGPL-3.0+"
|
license = "AGPL-3.0+"
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
|
from typing import *
|
||||||
import datetime
|
import datetime
|
||||||
import re
|
import re
|
||||||
import dateparser
|
import dateparser
|
||||||
import typing
|
import typing
|
||||||
import random
|
import random
|
||||||
|
import enum
|
||||||
|
import asyncio as aio
|
||||||
from telegram import Bot as PTBBot
|
from telegram import Bot as PTBBot
|
||||||
from telegram import Message as PTBMessage
|
from telegram import Message as PTBMessage
|
||||||
from telegram import InlineKeyboardMarkup as InKM
|
from telegram import InlineKeyboardMarkup as InKM
|
||||||
from telegram import InlineKeyboardButton as InKB
|
from telegram import InlineKeyboardButton as InKB
|
||||||
from telegram.error import TelegramError
|
from telegram.error import TelegramError
|
||||||
from royalnet.commands import *
|
import royalnet.commands as rc
|
||||||
from royalnet.serf.telegram import TelegramSerf as TelegramBot
|
from royalnet.serf.telegram import TelegramSerf as TelegramBot
|
||||||
from royalnet.serf.telegram import escape as telegram_escape
|
from royalnet.serf.telegram import escape as telegram_escape
|
||||||
from royalnet.utils import asyncify, sleep_until, sentry_async_wrap
|
from royalnet.utils import asyncify, sleep_until, sentry_async_wrap
|
||||||
|
@ -17,7 +20,13 @@ from ..tables import MMEvent, MMResponse, FiorygiTransaction
|
||||||
from ..types import MMChoice, MMInterfaceDataTelegram
|
from ..types import MMChoice, MMInterfaceDataTelegram
|
||||||
|
|
||||||
|
|
||||||
class MatchmakingCommand(Command):
|
class Interrupts(enum.Enum):
|
||||||
|
TIME_RAN_OUT = enum.auto()
|
||||||
|
MANUAL_START = enum.auto()
|
||||||
|
MANUAL_DELETE = enum.auto()
|
||||||
|
|
||||||
|
|
||||||
|
class MatchmakingCommand(rc.Command):
|
||||||
name: str = "matchmaking"
|
name: str = "matchmaking"
|
||||||
|
|
||||||
description: str = "Cerca persone per una partita a qualcosa!"
|
description: str = "Cerca persone per una partita a qualcosa!"
|
||||||
|
@ -28,7 +37,7 @@ class MatchmakingCommand(Command):
|
||||||
|
|
||||||
tables = {MMEvent, MMResponse}
|
tables = {MMEvent, MMResponse}
|
||||||
|
|
||||||
def __init__(self, interface: CommandInterface):
|
def __init__(self, interface: rc.CommandInterface):
|
||||||
super().__init__(interface)
|
super().__init__(interface)
|
||||||
# Find all relevant MMEvents and run them
|
# Find all relevant MMEvents and run them
|
||||||
session = self.alchemy.Session()
|
session = self.alchemy.Session()
|
||||||
|
@ -36,21 +45,25 @@ class MatchmakingCommand(Command):
|
||||||
session
|
session
|
||||||
.query(self.alchemy.get(MMEvent))
|
.query(self.alchemy.get(MMEvent))
|
||||||
.filter(self.alchemy.get(MMEvent).interface == self.interface.name,
|
.filter(self.alchemy.get(MMEvent).interface == self.interface.name,
|
||||||
self.alchemy.get(MMEvent).datetime > datetime.datetime.now())
|
self.alchemy.get(MMEvent).datetime > datetime.datetime.now(),
|
||||||
|
self.alchemy.get(MMEvent).interrupted == False)
|
||||||
.all()
|
.all()
|
||||||
)
|
)
|
||||||
|
self.tasks_created = {}
|
||||||
|
self.queue: Dict[int, aio.queues.Queue] = {}
|
||||||
for mmevent in mmevents:
|
for mmevent in mmevents:
|
||||||
self.interface.loop.create_task(self._run_mmevent(mmevent.mmid))
|
task = self.interface.loop.create_task(self._run_mmevent(mmevent.mmid))
|
||||||
|
self.tasks_created[mmevent.mmid] = task
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
# Create a new MMEvent and run it
|
# Create a new MMEvent and run it
|
||||||
if self.interface.name != "telegram":
|
if self.interface.name != "telegram":
|
||||||
raise UnsupportedError(f"{self.interface.prefix}matchmaking funziona solo su Telegram. Per ora.")
|
raise rc.UnsupportedError(f"{self.interface.prefix}matchmaking funziona solo su Telegram. Per ora.")
|
||||||
author = await data.get_author(error_if_none=True)
|
author = await data.get_author(error_if_none=True)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
timestring, title, description = args.match(r"\[\s*([^]]+)\s*]\s*([^\n]+)\s*\n?\s*(.+)?\s*", re.DOTALL)
|
timestring, title, description = args.match(r"\[\s*([^]]+)\s*]\s*([^\n]+)\s*\n?\s*(.+)?\s*", re.DOTALL)
|
||||||
except InvalidInputError:
|
except rc.InvalidInputError:
|
||||||
timestring, title, description = args.match(r"\s*(.+?)\s*\n\s*([^\n]+)\s*\n?\s*(.+)?\s*", re.DOTALL)
|
timestring, title, description = args.match(r"\s*(.+?)\s*\n\s*([^\n]+)\s*\n?\s*(.+)?\s*", re.DOTALL)
|
||||||
try:
|
try:
|
||||||
dt: typing.Optional[datetime.datetime] = dateparser.parse(timestring, settings={
|
dt: typing.Optional[datetime.datetime] = dateparser.parse(timestring, settings={
|
||||||
|
@ -59,12 +72,13 @@ class MatchmakingCommand(Command):
|
||||||
except OverflowError:
|
except OverflowError:
|
||||||
dt = None
|
dt = None
|
||||||
if dt is None:
|
if dt is None:
|
||||||
raise InvalidInputError("⚠️ La data che hai specificato non è valida.")
|
raise rc.InvalidInputError("La data che hai specificato non è valida.")
|
||||||
if dt <= datetime.datetime.now():
|
if dt <= datetime.datetime.now():
|
||||||
raise InvalidInputError("⚠️ La data che hai specificato è nel passato.")
|
raise rc.InvalidInputError("La data che hai specificato è nel passato.")
|
||||||
if dt - datetime.datetime.now() >= datetime.timedelta(days=366):
|
if dt - datetime.datetime.now() >= datetime.timedelta(days=366):
|
||||||
raise InvalidInputError("⚠️ Hai specificato una data tra più di un anno!\n"
|
raise rc.InvalidInputError("Hai specificato una data tra più di un anno!\n"
|
||||||
"Se volevi scrivere un'orario, ricordati che le ore sono separati ")
|
"Se volevi scrivere un'orario, ricordati che le ore sono separate da due punti"
|
||||||
|
" (:) e non da punto semplice!")
|
||||||
mmevent: MMEvent = self.alchemy.get(MMEvent)(creator=author,
|
mmevent: MMEvent = self.alchemy.get(MMEvent)(creator=author,
|
||||||
datetime=dt,
|
datetime=dt,
|
||||||
title=title,
|
title=title,
|
||||||
|
@ -117,6 +131,10 @@ class MatchmakingCommand(Command):
|
||||||
[
|
[
|
||||||
InKB(f"{MMChoice.YES.value} Ci sarò!",
|
InKB(f"{MMChoice.YES.value} Ci sarò!",
|
||||||
callback_data=f"mm{mmevent.mmid}_YES"),
|
callback_data=f"mm{mmevent.mmid}_YES"),
|
||||||
|
InKB(f"{MMChoice.MAYBE.value} Forse...",
|
||||||
|
callback_data=f"mm{mmevent.mmid}_MAYBE"),
|
||||||
|
InKB(f"{MMChoice.NO.value} Non mi interessa.",
|
||||||
|
callback_data=f"mm{mmevent.mmid}_NO"),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
InKB(f"{MMChoice.LATE_SHORT.value} 10 min",
|
InKB(f"{MMChoice.LATE_SHORT.value} 10 min",
|
||||||
|
@ -127,10 +145,10 @@ class MatchmakingCommand(Command):
|
||||||
callback_data=f"mm{mmevent.mmid}_LATE_LONG"),
|
callback_data=f"mm{mmevent.mmid}_LATE_LONG"),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
InKB(f"{MMChoice.MAYBE.value} Forse...",
|
InKB(f"🗑 Elimina",
|
||||||
callback_data=f"mm{mmevent.mmid}_MAYBE"),
|
callback_data=f"mm{mmevent.mmid}_DELETE"),
|
||||||
InKB(f"{MMChoice.NO.value} Non mi interessa.",
|
InKB(f"🚩 Inizia",
|
||||||
callback_data=f"mm{mmevent.mmid}_NO"),
|
callback_data=f"mm{mmevent.mmid}_START"),
|
||||||
]
|
]
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -147,9 +165,8 @@ class MatchmakingCommand(Command):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _gen_mm_telegram_callback(self, client: PTBBot, mmid: int, choice: MMChoice):
|
def _gen_mm_telegram_callback(self, client: PTBBot, mmid: int, choice: MMChoice):
|
||||||
async def callback(data: CommandData):
|
async def callback(data: rc.CommandData):
|
||||||
author = await data.get_author(error_if_none=True)
|
author = await data.get_author(error_if_none=True)
|
||||||
# Find the MMEvent with the current session
|
|
||||||
mmevent: MMEvent = await asyncify(data.session.query(self.alchemy.get(MMEvent)).get, mmid)
|
mmevent: MMEvent = await asyncify(data.session.query(self.alchemy.get(MMEvent)).get, mmid)
|
||||||
mmresponse: MMResponse = await asyncify(
|
mmresponse: MMResponse = await asyncify(
|
||||||
data.session.query(self.alchemy.get(MMResponse)).filter_by(user=author, mmevent=mmevent).one_or_none)
|
data.session.query(self.alchemy.get(MMResponse)).filter_by(user=author, mmevent=mmevent).one_or_none)
|
||||||
|
@ -163,9 +180,33 @@ class MatchmakingCommand(Command):
|
||||||
await data.session_commit()
|
await data.session_commit()
|
||||||
await self._update_telegram_mm_message(client, mmevent)
|
await self._update_telegram_mm_message(client, mmevent)
|
||||||
await data.reply(f"{choice.value} Messaggio ricevuto!")
|
await data.reply(f"{choice.value} Messaggio ricevuto!")
|
||||||
|
|
||||||
return callback
|
return callback
|
||||||
|
|
||||||
|
def _gen_mm_telegram_delete(self, client, mmid: int):
|
||||||
|
async def callback(data: rc.CommandData):
|
||||||
|
author = await data.get_author(error_if_none=True)
|
||||||
|
mmevent: MMEvent = await asyncify(data.session.query(self.alchemy.get(MMEvent)).get, mmid)
|
||||||
|
if author != mmevent.creator:
|
||||||
|
raise rc.UserError("Non sei il creatore di questo matchmaking!")
|
||||||
|
await self.queue[mmid].put(Interrupts.MANUAL_DELETE)
|
||||||
|
await data.reply(f"🗑 Evento eliminato!")
|
||||||
|
return callback
|
||||||
|
|
||||||
|
def _gen_mm_telegram_start(self, client, mmid: int):
|
||||||
|
async def callback(data: rc.CommandData):
|
||||||
|
author = await data.get_author(error_if_none=True)
|
||||||
|
mmevent: MMEvent = await asyncify(data.session.query(self.alchemy.get(MMEvent)).get, mmid)
|
||||||
|
if author != mmevent.creator:
|
||||||
|
raise rc.UserError("Non sei il creatore di questo matchmaking!")
|
||||||
|
await self.queue[mmid].put(Interrupts.MANUAL_START)
|
||||||
|
await data.reply(f"🚩 Evento avviato!")
|
||||||
|
return callback
|
||||||
|
|
||||||
|
async def _set_event_after(self, mmid: int, dt: datetime.datetime):
|
||||||
|
await sleep_until(dt)
|
||||||
|
if mmid in self.queue:
|
||||||
|
await self.queue[mmid].put(Interrupts.TIME_RAN_OUT)
|
||||||
|
|
||||||
def _gen_event_start_message(self, mmevent: MMEvent):
|
def _gen_event_start_message(self, mmevent: MMEvent):
|
||||||
text = f"🚩 L'evento [b]{mmevent.title}[/b] è iniziato!\n\n"
|
text = f"🚩 L'evento [b]{mmevent.title}[/b] è iniziato!\n\n"
|
||||||
for response in sorted(mmevent.responses, key=lambda r: -self._mmchoice_values[r.choice]):
|
for response in sorted(mmevent.responses, key=lambda r: -self._mmchoice_values[r.choice]):
|
||||||
|
@ -181,6 +222,8 @@ class MatchmakingCommand(Command):
|
||||||
@sentry_async_wrap()
|
@sentry_async_wrap()
|
||||||
async def _run_mmevent(self, mmid: int):
|
async def _run_mmevent(self, mmid: int):
|
||||||
"""Run a MMEvent."""
|
"""Run a MMEvent."""
|
||||||
|
# Create the event in the dict
|
||||||
|
self.queue[mmid] = aio.Queue()
|
||||||
# Open a new Alchemy Session
|
# Open a new Alchemy Session
|
||||||
session = self.alchemy.Session()
|
session = self.alchemy.Session()
|
||||||
# Find the MMEvent with the current session
|
# Find the MMEvent with the current session
|
||||||
|
@ -213,51 +256,67 @@ class MatchmakingCommand(Command):
|
||||||
message_id=message.message_id)
|
message_id=message.message_id)
|
||||||
await asyncify(session.commit)
|
await asyncify(session.commit)
|
||||||
else:
|
else:
|
||||||
raise UnsupportedError()
|
raise rc.UnsupportedError()
|
||||||
# Register handlers for the keyboard events
|
# Register handlers for the keyboard events
|
||||||
if self.interface.name == "telegram":
|
if self.interface.name == "telegram":
|
||||||
bot: TelegramBot = self.interface.serf
|
bot: TelegramBot = self.interface.serf
|
||||||
client: PTBBot = bot.client
|
client: PTBBot = bot.client
|
||||||
bot.register_keyboard_key(f"mm{mmevent.mmid}_YES", key=KeyboardKey(
|
bot.register_keyboard_key(f"mm{mmevent.mmid}_YES", key=rc.KeyboardKey(
|
||||||
interface=self.interface,
|
interface=self.interface,
|
||||||
short=f"{MMChoice.YES.value}",
|
short=f"{MMChoice.YES.value}",
|
||||||
text="Ci sarò!",
|
text="Ci sarò!",
|
||||||
callback=self._gen_mm_telegram_callback(client, mmid, MMChoice.YES)
|
callback=self._gen_mm_telegram_callback(client, mmid, MMChoice.YES)
|
||||||
))
|
))
|
||||||
bot.register_keyboard_key(f"mm{mmevent.mmid}_LATE_SHORT", key=KeyboardKey(
|
bot.register_keyboard_key(f"mm{mmevent.mmid}_LATE_SHORT", key=rc.KeyboardKey(
|
||||||
interface=self.interface,
|
interface=self.interface,
|
||||||
short=f"{MMChoice.LATE_SHORT.value}",
|
short=f"{MMChoice.LATE_SHORT.value}",
|
||||||
text="10 min",
|
text="10 min",
|
||||||
callback=self._gen_mm_telegram_callback(client, mmid, MMChoice.LATE_SHORT)
|
callback=self._gen_mm_telegram_callback(client, mmid, MMChoice.LATE_SHORT)
|
||||||
))
|
))
|
||||||
bot.register_keyboard_key(f"mm{mmevent.mmid}_LATE_MEDIUM", key=KeyboardKey(
|
bot.register_keyboard_key(f"mm{mmevent.mmid}_LATE_MEDIUM", key=rc.KeyboardKey(
|
||||||
interface=self.interface,
|
interface=self.interface,
|
||||||
short=f"{MMChoice.LATE_MEDIUM.value}",
|
short=f"{MMChoice.LATE_MEDIUM.value}",
|
||||||
text="30 min",
|
text="30 min",
|
||||||
callback=self._gen_mm_telegram_callback(client, mmid, MMChoice.LATE_MEDIUM)
|
callback=self._gen_mm_telegram_callback(client, mmid, MMChoice.LATE_MEDIUM)
|
||||||
))
|
))
|
||||||
bot.register_keyboard_key(f"mm{mmevent.mmid}_LATE_LONG", key=KeyboardKey(
|
bot.register_keyboard_key(f"mm{mmevent.mmid}_LATE_LONG", key=rc.KeyboardKey(
|
||||||
interface=self.interface,
|
interface=self.interface,
|
||||||
short=f"{MMChoice.LATE_LONG.value}",
|
short=f"{MMChoice.LATE_LONG.value}",
|
||||||
text="60 min",
|
text="60 min",
|
||||||
callback=self._gen_mm_telegram_callback(client, mmid, MMChoice.LATE_LONG)
|
callback=self._gen_mm_telegram_callback(client, mmid, MMChoice.LATE_LONG)
|
||||||
))
|
))
|
||||||
bot.register_keyboard_key(f"mm{mmevent.mmid}_MAYBE", key=KeyboardKey(
|
bot.register_keyboard_key(f"mm{mmevent.mmid}_MAYBE", key=rc.KeyboardKey(
|
||||||
interface=self.interface,
|
interface=self.interface,
|
||||||
short=f"{MMChoice.MAYBE.value}",
|
short=f"{MMChoice.MAYBE.value}",
|
||||||
text="Forse...",
|
text="Forse...",
|
||||||
callback=self._gen_mm_telegram_callback(client, mmid, MMChoice.MAYBE)
|
callback=self._gen_mm_telegram_callback(client, mmid, MMChoice.MAYBE)
|
||||||
))
|
))
|
||||||
bot.register_keyboard_key(f"mm{mmevent.mmid}_NO", key=KeyboardKey(
|
bot.register_keyboard_key(f"mm{mmevent.mmid}_NO", key=rc.KeyboardKey(
|
||||||
interface=self.interface,
|
interface=self.interface,
|
||||||
short=f"{MMChoice.NO.value}",
|
short=f"{MMChoice.NO.value}",
|
||||||
text="Non mi interessa.",
|
text="Non mi interessa.",
|
||||||
callback=self._gen_mm_telegram_callback(client, mmid, MMChoice.NO)
|
callback=self._gen_mm_telegram_callback(client, mmid, MMChoice.NO)
|
||||||
))
|
))
|
||||||
|
bot.register_keyboard_key(f"mm{mmevent.mmid}_DELETE", key=rc.KeyboardKey(
|
||||||
|
interface=self.interface,
|
||||||
|
short=f"🗑",
|
||||||
|
text="Elimina",
|
||||||
|
callback=self._gen_mm_telegram_delete(client, mmid)
|
||||||
|
))
|
||||||
|
bot.register_keyboard_key(f"mm{mmevent.mmid}_START", key=rc.KeyboardKey(
|
||||||
|
interface=self.interface,
|
||||||
|
short=f"🚩",
|
||||||
|
text="Inizia",
|
||||||
|
callback=self._gen_mm_telegram_start(client, mmid)
|
||||||
|
))
|
||||||
else:
|
else:
|
||||||
raise UnsupportedError()
|
raise rc.UnsupportedError()
|
||||||
# Sleep until the time of the event
|
# Sleep until something interrupts
|
||||||
await sleep_until(mmevent.datetime)
|
self.loop.create_task(self._set_event_after(mmid, mmevent.datetime))
|
||||||
|
interrupt = await self.queue[mmid].get()
|
||||||
|
mmevent.interrupted = True
|
||||||
|
await asyncify(session.commit)
|
||||||
|
del self.queue[mmid]
|
||||||
# Notify the positive answers of the event start
|
# Notify the positive answers of the event start
|
||||||
if self.interface.name == "telegram":
|
if self.interface.name == "telegram":
|
||||||
bot: TelegramBot = self.interface.serf
|
bot: TelegramBot = self.interface.serf
|
||||||
|
@ -268,7 +327,10 @@ class MatchmakingCommand(Command):
|
||||||
bot.unregister_keyboard_key(f"mm{mmevent.mmid}_LATE_MEDIUM")
|
bot.unregister_keyboard_key(f"mm{mmevent.mmid}_LATE_MEDIUM")
|
||||||
bot.unregister_keyboard_key(f"mm{mmevent.mmid}_LATE_LONG")
|
bot.unregister_keyboard_key(f"mm{mmevent.mmid}_LATE_LONG")
|
||||||
bot.unregister_keyboard_key(f"mm{mmevent.mmid}_NO")
|
bot.unregister_keyboard_key(f"mm{mmevent.mmid}_NO")
|
||||||
|
bot.unregister_keyboard_key(f"mm{mmevent.mmid}_DELETE")
|
||||||
|
bot.unregister_keyboard_key(f"mm{mmevent.mmid}_START")
|
||||||
|
|
||||||
|
if interrupt == Interrupts.TIME_RAN_OUT or interrupt == Interrupts.MANUAL_START:
|
||||||
await asyncify(client.send_message,
|
await asyncify(client.send_message,
|
||||||
chat_id=self.config["Telegram"]["main_group_id"],
|
chat_id=self.config["Telegram"]["main_group_id"],
|
||||||
text=telegram_escape(self._gen_event_start_message(mmevent)),
|
text=telegram_escape(self._gen_event_start_message(mmevent)),
|
||||||
|
@ -285,17 +347,29 @@ class MatchmakingCommand(Command):
|
||||||
parse_mode="HTML",
|
parse_mode="HTML",
|
||||||
disable_webpage_preview=True)
|
disable_webpage_preview=True)
|
||||||
except TelegramError:
|
except TelegramError:
|
||||||
await self.interface.serf.api_call(client.send_message,
|
await self.interface.serf.api_call(
|
||||||
|
client.send_message,
|
||||||
chat_id=self.config["Telegram"]["main_group_id"],
|
chat_id=self.config["Telegram"]["main_group_id"],
|
||||||
text=telegram_escape(self._gen_unauth_message(response.user)),
|
text=telegram_escape(self._gen_unauth_message(response.user)),
|
||||||
parse_mode="HTML",
|
parse_mode="HTML",
|
||||||
disable_webpage_preview=True)
|
disable_webpage_preview=True
|
||||||
else:
|
)
|
||||||
raise UnsupportedError()
|
|
||||||
# Delete the event message
|
elif interrupt == Interrupts.MANUAL_DELETE:
|
||||||
if self.interface.name == "telegram":
|
await self.interface.serf.api_call(
|
||||||
|
client.send_message,
|
||||||
|
chat_id=self.config["Telegram"]["main_group_id"],
|
||||||
|
text=telegram_escape(f"🗑 L'evento [b]{mmevent.title}[/b] è stato annullato."),
|
||||||
|
parse_mode="HTML",
|
||||||
|
disable_webpage_preview=True
|
||||||
|
)
|
||||||
|
|
||||||
await self.interface.serf.api_call(client.delete_message,
|
await self.interface.serf.api_call(client.delete_message,
|
||||||
chat_id=mmevent.interface_data.chat_id,
|
chat_id=mmevent.interface_data.chat_id,
|
||||||
message_id=mmevent.interface_data.message_id)
|
message_id=mmevent.interface_data.message_id)
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise rc.UnsupportedError()
|
||||||
# The end!
|
# The end!
|
||||||
await asyncify(session.close)
|
await asyncify(session.close)
|
||||||
|
del self.tasks_created[mmid]
|
||||||
|
|
|
@ -48,5 +48,9 @@ class MMEvent:
|
||||||
def interface_data(self, value):
|
def interface_data(self, value):
|
||||||
self.raw_interface_data = pickle.dumps(value)
|
self.raw_interface_data = pickle.dumps(value)
|
||||||
|
|
||||||
|
@declared_attr
|
||||||
|
def interrupted(self):
|
||||||
|
return Column(Boolean, nullable=False, default=False)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<MMEvent {self.mmid}: {self.title}>"
|
return f"<MMEvent {self.mmid}: {self.title}>"
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
semantic = "5.7.11"
|
semantic = "5.7.12"
|
||||||
|
|
Loading…
Reference in a new issue