async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None: async with data.session_acm() as session: author = await data.find_author(session=session, required=True) if "banker" not in author.roles: raise rc.UserError( "Non hai permessi sufficienti per eseguire questo comando." ) user_arg = args[0] qty_arg = args[1] reason_arg = " ".join(args[2:]) if user_arg is None: raise rc.InvalidInputError( "Non hai specificato un destinatario!") user = await rbt.User.find(self.alchemy, session, user_arg) if user is None: raise rc.InvalidInputError("L'utente specificato non esiste!") if qty_arg is None: raise rc.InvalidInputError("Non hai specificato una quantità!") try: qty = int(qty_arg) except ValueError: raise rc.InvalidInputError( "La quantità specificata non è un numero!") if reason_arg == "": raise rc.InvalidInputError("Non hai specificato un motivo!") await FiorygiTransaction.spawn_fiorygi(user, qty, reason_arg, data=data, session=session)
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None: try: date_str, reminder_text = args.match(r"\[\s*([^]]+)\s*]\s*([^\n]+)\s*") except rc.InvalidInputError: date_str, reminder_text = args.match(r"\s*(.+?)\s*\n\s*([^\n]+)\s*") try: date: Optional[datetime.datetime] = dateparser.parse(date_str, settings={ "PREFER_DATES_FROM": "future" }) except OverflowError: date = None if date is None: await data.reply("⚠️ La data che hai inserito non è valida.") return if date <= datetime.datetime.now(): await data.reply("⚠️ La data che hai specificato è nel passato.") return await data.reply(f"✅ Promemoria impostato per [b]{date.strftime('%Y-%m-%d %H:%M:%S')}[/b]") if isinstance(self.serf, rst.TelegramSerf): interface_data = pickle.dumps(data.message.chat.id) elif isinstance(self.serf, rsd.DiscordSerf): interface_data = pickle.dumps(data.message.channel.id) else: raise rc.UnsupportedError("This command does not support the current interface.") async with data.session_acm() as session: creator = await data.find_author(session=session) reminder = self.alchemy.get(Reminder)(creator=creator, interface_name=self.serf.interface_name, interface_data=interface_data, datetime=date, message=reminder_text) self.serf.tasks.add(self._remind(reminder)) session.add(reminder) await ru.asyncify(session.commit)
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None: async with data.session_acm() as session: author = await data.find_author(session=session, required=True) if len(args) == 0: message = [] for obj in await self.get_updatables_of_user(session=session, user=author): async def change(attribute: str, value: Any): """A shortcut for self.__change.""" await self._change(session=session, obj=obj, attribute=attribute, new=value) await self.update(session=session, obj=obj, change=change) message.append(self.describe(obj)) if len(message) == 0: raise rc.UserError("Nessun account connesso.") await ru.asyncify(session.commit) await data.reply("\n".join(message)) else: created = await self.create(session=session, user=author, args=args, data=data) await ru.asyncify(session.commit) if created is not None: message = [ "🔗 Account collegato!", "", self.describe(created) ] await data.reply("\n".join(message))
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None: async with data.session_acm() as session: DiarioT = self.alchemy.get(Diario) entry: List[Diario] = await ru.asyncify( session.query(DiarioT).order_by( func.random()).limit(1).one_or_none) if entry is None: raise rc.CommandError("Nessuna riga del diario trovata.") await data.reply(f"ℹ️ {entry}")
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None: try: entry_id = int(args[0].lstrip("#")) except ValueError: raise rc.CommandError("L'id che hai specificato non è valido.") async with data.session_acm() as session: entry: Diario = await ru.asyncify( session.query(self.alchemy.get(Diario)).get, entry_id) if entry is None: raise rc.CommandError("Nessuna riga con quell'id trovata.") await data.reply(f"ℹ️ {entry}")
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None: async with data.session_acm() as session: author = await data.find_author(session=session, required=True) today = datetime.date.today() h = author.uid * hash(today) r = random.Random(x=h) message = r.sample(self._fortunes, 1)[0] await data.reply(message)
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None: async with data.session_acm() as session: user: rbt.User = await data.find_author(session=session, required=True) if "admin" not in user.roles: raise rc.CommandError( "Non sei autorizzato a eseguire codice arbitrario!\n" "(Sarebbe un po' pericoloso se te lo lasciassi eseguire, non trovi?)" ) try: result = eval(args.joined(require_at_least=1)) except Exception as e: raise rc.CommandError(f"Eval fallito: {e}") await data.reply(repr(result))
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None: BattleT = self.alchemy.get(DndBattle) line_args = args.joined(require_at_least=1).split("\n", 1) name = line_args[0] description = line_args[1] if len(line_args) > 1 else None async with data.session_acm() as session: battle = BattleT(name=name, description=description) session.add(battle) await ru.asyncify(session.commit) await data.reply( f"✅ Battle [b]{battle.name}[/b] (ID: {battle.id}) created!")
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None: faction = Faction[args[0].upper()] initiative_mod = int(args.optional(1, default="0")) async with data.session_acm() as session: DndBattleUnitT = self.alchemy.get(DndBattleUnit) active_battle = await get_active_battle(data=data, session=session) if active_battle is None: raise rc.CommandError("No battle is active in this chat.") active_character = await get_active_character(data=data, session=session) if active_character is None: raise rc.CommandError("You don't have an active character.") char: DndCharacter = active_character.character units_with_same_name = await ru.asyncify(session.query(DndBattleUnitT).filter_by( name=char.name, battle=active_battle.battle ).all) if len(units_with_same_name) != 0: raise rc.InvalidInputError("A unit with the same name already exists.") roll = random.randrange(1, 21) modifier = char.initiative + initiative_mod modifier_str = f"{modifier:+d}" if modifier != 0 else "" initiative = roll + modifier dbu = DndBattleUnitT( linked_character=char, initiative=initiative, faction=faction, name=char.name, health_string=f"{char.current_hp}/{char.max_hp}", armor_class=char.armor_class, battle=active_battle.battle ) session.add(dbu) await ru.asyncify(session.commit) await data.reply(f"{dbu}\n" f"joins the battle!\n" f"\n" f"🎲 1d20{modifier_str} = {roll}{modifier_str} = {initiative}")
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None: async with data.session_acm() as session: author = await data.find_author(session=session, required=True) user_arg = args[0] qty_arg = args[1] if user_arg is None: raise rc.InvalidInputError( "Non hai specificato un destinatario!") user = await rbt.User.find(alchemy=self.alchemy, session=session, identifier=user_arg) if user is None: raise rc.InvalidInputError("L'utente specificato non esiste!") if user.uid == author.uid: raise rc.InvalidInputError( "Non puoi inviare fiorygi a te stesso!") if qty_arg is None: raise rc.InvalidInputError("Non hai specificato una quantità!") try: qty = int(qty_arg) except ValueError: raise rc.InvalidInputError( "La quantità specificata non è un numero!") if qty <= 0: raise rc.InvalidInputError( "La quantità specificata deve essere almeno 1!") if author.fiorygi.fiorygi < qty: raise rc.InvalidInputError( "Non hai abbastanza fiorygi per effettuare la transazione!" ) await FiorygiTransaction.spawn_fiorygi( author, -qty, f"aver ceduto fiorygi a {user}", data=data, session=session) await FiorygiTransaction.spawn_fiorygi( user, qty, f"aver ricevuto fiorygi da {author}", data=data, session=session)
async def callback(data: rc.CommandData): async with data.session_acm() as session: # Find the user who clicked on the button user = await data.find_author(session=session, required=True) # Get the related MMEvent mmevent: MMEvent = await ru.asyncify( session.query(self._EventT).get, self.mmid) # Check if the user had already responded mmresponse: MMResponse = await ru.asyncify( session.query(self._ResponseT).filter_by( user=user, mmevent=mmevent).one_or_none) if mmresponse is None: # If they didn't respond, create a new MMResponse # noinspection PyArgumentList mmresponse = self._ResponseT(user=user, mmevent=mmevent, choice=choice) session.add(mmresponse) # Drop fiorygi if random.randrange(100) < self.command.config[ "matchmaking"]["fiorygi_award_chance"]: await FiorygiTransaction.spawn_fiorygi( user, 1, "aver risposto a un matchmaking", data=data, session=session) else: # Change their response mmresponse.choice = choice try: await ru.asyncify(session.commit) except psycopg2.Error: raise rc.UserError( "Hai già risposto nello stesso modo a questo matchmaking." ) await self.telegram_channel_message_update() await data.reply(f"{choice.value} Hai risposto al matchmaking!" )
async def callback(data: rc.CommandData): async with data.session_acm() as session: # Find the user who clicked on the button user = await data.find_author(session=session, required=True) # Get the related MMEvent mmevent: MMEvent = await ru.asyncify( session.query(self._EventT).get, self.mmid) # Ensure the user has the required roles to start the matchmaking if user != mmevent.creator and "admin" not in user.roles: raise rc.UserError( "Non hai i permessi per eliminare questo matchmaking!") # Interrupt the matchmaking with the MANUAL_DELETE reason await self.queue.put(Interrupts.MANUAL_START) await data.reply(f"🚩 Evento avviato!")
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None: target = args[0] async with data.session_acm() as session: units = await get_targets(target, data=data, session=session) if len(units) == 0: raise rc.InvalidInputError( f"No targets found matching [c]{target}[/c].") for unit in units: await self._change(unit, args[1:]) await session.commit() message = [] for unit in units: message.append(f"{unit}") await data.reply("\n\n".join(message))
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None: faction = Faction[args[0].upper()] name = args[1] initiative = int(args[2]) health = args[3] armor_class = int(args[4]) DndBattleUnitT = self.alchemy.get(DndBattleUnit) async with data.session_acm() as session: active_battle = await get_active_battle(session=session, data=data) if active_battle is None: raise rc.CommandError("No battle is active in this chat.") units_with_same_name = await ru.asyncify( session.query(DndBattleUnitT).filter_by( name=name, battle=active_battle.battle).all) if len(units_with_same_name) != 0: raise rc.InvalidInputError( "A unit with the same name already exists.") try: health = Health.from_text(health) except ValueError: raise rc.InvalidInputError("Invalid health string.") dbu = DndBattleUnitT(linked_character_id=None, initiative=initiative, faction=faction, name=name, health_string=health, armor_class=armor_class, battle=active_battle.battle) session.add(dbu) await ru.asyncify(session.commit) await data.reply(f"{dbu}\n" f"joins the battle!") if dbu.health.hidden: await data.delete_invoking()
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None: CvstatsT = self.alchemy.get(Cvstats) async with data.session_acm() as session: cvstats = session.query(CvstatsT).order_by( CvstatsT.timestamp.desc()).first() message = [ f"ℹ️ [b]Statistiche[/b]", f"Ultimo aggiornamento: [b]{cvstats.timestamp.strftime('%Y-%m-%d %H:%M')}[/b]", f"Utenti totali: [b]{cvstats.users_total}[/b]", f"Membri totali: [b]{cvstats.members_total}[/b]", f"Utenti online: [b]{cvstats.users_online}[/b]", f"Membri online: [b]{cvstats.members_online}[/b]", f"Utenti connessi: [b]{cvstats.users_connected}[/b]", f"Membri connessi: [b]{cvstats.members_connected}[/b]", f"Utenti in gioco: [b]{cvstats.users_playing}[/b]", f"Membri in gioco: [b]{cvstats.members_playing}[/b]" ] await data.reply("\n".join(message))
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None: TreasureT = self.alchemy.get(Treasure) async with data.session_acm() as session: author = await data.find_author(session=session, required=True) code = args[0].lower() treasure = await ru.asyncify(session.query(TreasureT).get, code) if treasure is None: raise rc.UserError( "Non esiste nessun Treasure con quel codice.") if treasure.redeemed_by is not None: raise rc.UserError( f"Quel tesoro è già stato riscattato da {treasure.redeemed_by}." ) treasure.redeemed_by = author await ru.asyncify(session.commit) await FiorygiTransaction.spawn_fiorygi( data, author, treasure.value, f'aver trovato il tesoro "{treasure.code}"') await data.reply("🤑 Tesoro riscattato!")
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None: """Handle a matchmaking command call.""" # Parse the arguments, either with the standard syntax or with the Proto syntax dt, title, description = self._parse_args(args) # Add the MMEvent to the database async with data.session_acm() as session: author = await data.find_author(session=session, required=True) mmevent: MMEvent = self.alchemy.get(MMEvent)( creator=author, datetime=dt, title=title, description=description, interface=self.serf.interface_name) session.add(mmevent) await ru.asyncify(session.commit) # Create and run a task for the newly created MMEvent task = MMTask(mmevent.mmid, command=self) task.start() await data.reply(f"🚩 Matchmaking creato!")
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None: arg = args.optional(0) async with data.session_acm() as session: if arg == "credits": await data.reply(f"ℹ️ [c]{self.serf.prefix}{self.name}[/c] di [i]Steffo[/i]\n" f"\n" f"Tutte le domande vengono dall'[b]Open Trivia Database[/b] di [i]Pixeltail Games[/i]," f" creatori di Tower Unite, e sono rilasciate sotto la licenza [b]CC BY-SA 4.0[/b].") return elif arg == "scores": trivia_scores = await ru.asyncify(session.query(self.alchemy.get(TriviaScore)).all) strings = ["🏆 [b]Trivia Leaderboards[/b]\n"] for index, ts in enumerate(sorted(trivia_scores, key=lambda ts: -ts.score)): if index > 3: index = 3 strings.append(f"{self._medal_emojis[index]} {ts.user.username}: [b]{ts.score:.0f}p[/b]" f" ({ts.correct_answers}/{ts.total_answers})") await data.reply("\n".join(strings)) return # if self._question_lock: # raise rc.CommandError("C'è già un'altra domanda attiva!") # self._question_lock = True # Fetch the question async with aiohttp.ClientSession() as ws: async with ws.get("https://opentdb.com/api.php?amount=1") as response: j = await response.json() # Parse the question if j["response_code"] != 0: raise rc.CommandError(f"OpenTDB returned an error response_code ({j['response_code']}).") question = j["results"][0] text = f'❓ [b]{question["category"]}[/b]\n' \ f'{html.unescape(question["question"])}' # Prepare answers correct_answer: str = question["correct_answer"] wrong_answers: List[str] = question["incorrect_answers"] answers: List[str] = [correct_answer, *wrong_answers] if question["type"] == "multiple": random.shuffle(answers) elif question["type"] == "boolean": answers.sort(key=lambda a: a) answers.reverse() else: raise NotImplementedError("Unknown question type") # Find the correct index for index, answer in enumerate(answers): if answer == correct_answer: correct_index = index break else: raise ValueError("correct_index not found") # Add emojis for index, answer in enumerate(answers): answers[index] = f"{self._letter_emojis[index]} {html.unescape(answers[index])}" # Create the question id question_id = uuid.uuid4() self._answerers[question_id] = {} # Create the correct and wrong functions async def correct(data: rc.CommandData): answerer_ = await data.find_author(session=session, required=True) try: self._answerers[question_id][answerer_.uid] = True except KeyError: raise rc.UserError("Tempo scaduto!") await data.reply("🆗 Hai risposto alla domanda. Ora aspetta un attimo per i risultati!") async def wrong(data: rc.CommandData): answerer_ = await data.find_author(session=session, required=True) try: self._answerers[question_id][answerer_.uid] = False except KeyError: raise rc.UserError("Tempo scaduto!") await data.reply("🆗 Hai risposto alla domanda. Ora aspetta un attimo per i risultati!") # Add question keyboard: List[rc.KeyboardKey] = [] for index, answer in enumerate(answers): if index == correct_index: keyboard.append(rc.KeyboardKey(short=self._letter_emojis[index], text=answers[index], callback=correct)) else: keyboard.append(rc.KeyboardKey(short=self._letter_emojis[index], text=answers[index], callback=wrong)) async with data.keyboard(text=text, keys=keyboard): await asyncio.sleep(self._answer_time) results = f"❗️ Tempo scaduto!\n" \ f"La risposta corretta era [b]{answers[correct_index]}[/b]!\n\n" for answerer_id in self._answerers[question_id]: answerer = session.query(self.alchemy.get(rbt.users.User)).get(answerer_id) if answerer.trivia_score is None: ts = self.alchemy.get(TriviaScore)(user=answerer) session.add(ts) await ru.asyncify(session.commit) previous_score = answerer.trivia_score.score if self._answerers[question_id][answerer_id]: results += self._correct_emoji answerer.trivia_score.correct_answers += 1 else: results += self._wrong_emoji answerer.trivia_score.wrong_answers += 1 current_score = answerer.trivia_score.score score_difference = current_score - previous_score results += f" {answerer}: [b]{current_score:.0f}p[/b] ({score_difference:+.0f}p)\n" await data.reply(results) del self._answerers[question_id] await ru.asyncify(session.commit)
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None: async with data.session_acm() as session: author = await data.find_author(session=session, required=False) if author is not None: raise rc.UserError(f"This account is already connected to {author}!") username = args[0] password = "******".join(args[1:]) user = await data.find_user(session=session, identifier=username) if user is None: raise rc.UserError("No such user.") try: successful = user.test_password(password) except ValueError: raise rc.UserError(f"User {user} has no password set!") if not successful: raise rc.InvalidInputError(f"Invalid password!") if rst is not None and isinstance(self.serf, rst.TelegramSerf): import telegram message: telegram.Message = data.message from_user: telegram.User = message.from_user TelegramT = self.alchemy.get(Telegram) tg_user: Telegram = await ru.asyncify( session.query(TelegramT).filter_by(tg_id=from_user.id).one_or_none ) if tg_user is None: # Create tg_user = TelegramT( user=user, tg_id=from_user.id, first_name=from_user.first_name, last_name=from_user.last_name, username=from_user.username ) session.add(tg_user) else: # Edit tg_user.first_name = from_user.first_name tg_user.last_name = from_user.last_name tg_user.username = from_user.username await ru.asyncify(session.commit) await data.reply(f"↔️ Account {tg_user} synced to {user}!") elif rsd is not None and isinstance(self.serf, rsd.DiscordSerf): import discord message: discord.Message = data.message ds_author: discord.User = message.author DiscordT = self.alchemy.get(Discord) ds_user: Discord = await ru.asyncify( session.query(DiscordT).filter_by(discord_id=ds_author.id).one_or_none ) if ds_user is None: # Create # noinspection PyProtectedMember ds_user = DiscordT( user=user, discord_id=ds_author.id, username=ds_author.name, discriminator=ds_author.discriminator, avatar_url=ds_author.avatar_url._url ) session.add(ds_user) else: # Edit ds_user.username = ds_author.name ds_user.discriminator = ds_author.discriminator ds_user.avatar_url = ds_author.avatar_url await ru.asyncify(session.commit) await data.reply(f"↔️ Account {ds_user} synced to {ds_author}!") else: raise rc.UnsupportedError(f"Unknown interface: {self.serf.__class__.__qualname__}")
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None: async with data.session_acm() as session: if isinstance(self.serf, rst.TelegramSerf): message: telegram.Message = data.message reply: telegram.Message = message.reply_to_message creator = await data.find_author(session=session, required=True) # noinspection PyUnusedLocal quoted: Optional[str] # noinspection PyUnusedLocal text: Optional[str] # noinspection PyUnusedLocal context: Optional[str] # noinspection PyUnusedLocal timestamp: datetime.datetime # noinspection PyUnusedLocal media_url: Optional[str] # noinspection PyUnusedLocal spoiler: bool if creator is None: await data.reply( "⚠️ Devi essere registrato a Royalnet per usare questo comando!" ) return if reply is not None: # Get the message text text = reply.text # Check if there's an image associated with the reply photosizes: Optional[List[ telegram.PhotoSize]] = reply.photo if photosizes: # Text is a caption text = reply.caption media_url = await to_imgur( self.config["Imgur"]["token"], photosizes, text if text is not None else "") else: media_url = None # Ensure there is a text or an image if not (text or media_url): raise rc.InvalidInputError( "Il messaggio a cui hai risposto non contiene testo o immagini." ) # Find the Royalnet account associated with the sender quoted_tg = await ru.asyncify( session.query(self.alchemy.get( rbt.Telegram)).filter_by( tg_id=reply.from_user.id).one_or_none) quoted_account = quoted_tg.user if quoted_tg is not None else None # Find the quoted name to assign quoted_user: telegram.User = reply.from_user quoted = quoted_user.full_name # Get the timestamp timestamp = reply.date # Set the other properties spoiler = False context = None else: # Get the current timestamp timestamp = datetime.datetime.now() # Get the message text raw_text = " ".join(args) # Check if there's an image associated with the reply photosizes: Optional[List[ telegram.PhotoSize]] = message.photo if photosizes: media_url = await to_imgur( self.config["Imgur"]["token"], photosizes, raw_text if raw_text is not None else "") else: media_url = None # Parse the text, if it exists if raw_text: # Pass the sentence through the diario regex match = re.match( r'(!)? *["«‘“‛‟❛❝〝"`]([^"]+)["»’”❜❞〞"`] *(?:(?:-{1,2}|—) *([^,]+))?(?:, *([^ ].*))?', raw_text) # Find the corresponding matches if match is not None: spoiler = bool(match.group(1)) text = match.group(2) quoted = match.group(3) context = match.group(4) # Otherwise, consider everything part of the text else: spoiler = False text = raw_text quoted = None context = None # Ensure there's a quoted if not quoted: quoted = None if not context: context = None # Find if there's a Royalnet account associated with the quoted name if quoted is not None: quoted_alias = await ru.asyncify( session.query(self.alchemy.get( rbt.Alias)).filter_by( alias=quoted.lower()).one_or_none) else: quoted_alias = None quoted_account = quoted_alias.user if quoted_alias is not None else None else: text = None quoted = None quoted_account = None spoiler = False context = None # Ensure there is a text or an image if not (text or media_url): raise rc.InvalidInputError( "Manca il testo o l'immagine da inserire nel diario." ) # Create the diario quote diario = self.alchemy.get(Diario)( creator=creator, quoted_account=quoted_account, quoted=quoted, text=text, context=context, timestamp=timestamp, media_url=media_url, spoiler=spoiler) session.add(diario) await ru.asyncify(session.commit) await data.reply(f"✅ {str(diario)}") else: # Find the creator of the quotes creator = await data.find_author(session=session, required=True) # Recreate the full sentence raw_text = " ".join(args) # Pass the sentence through the diario regex match = re.match( r'(!)? *["«‘“‛‟❛❝〝"`]([^"]+)["»’”❜❞〞"`] *(?:(?:-{1,2}|—) *([^,]+))?(?:, *([^ ].*))?', raw_text) # Find the corresponding matches if match is not None: spoiler = bool(match.group(1)) text = match.group(2) quoted = match.group(3) context = match.group(4) # Otherwise, consider everything part of the text else: spoiler = False text = raw_text quoted = None context = None timestamp = datetime.datetime.now() # Ensure there is some text if not text: raise rc.InvalidInputError( "Manca il testo o l'immagine da inserire nel diario.") # Or a quoted if not quoted: quoted = None if not context: context = None # Find if there's a Royalnet account associated with the quoted name if quoted is not None: quoted_account = await rbt.User.find( self.alchemy, session, quoted) else: quoted_account = None if quoted_account is None: raise rc.UserError( "Il nome dell'autore è ambiguo, quindi la riga non è stata aggiunta.\n" "Per piacere, ripeti il comando con un nome più specifico!" ) # Create the diario quote DiarioT = self.alchemy.get(Diario) diario = DiarioT(creator=creator, quoted_account=quoted_account, quoted=quoted, text=text, context=context, timestamp=timestamp, media_url=None, spoiler=spoiler) session.add(diario) await ru.asyncify(session.commit) await data.reply(f"✅ {str(diario)}")
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None: if name := args.optional(0) is not None: async with data.session_acm() as session: user = await User.find(alchemy=self.alchemy, session=session, identifier=name)