1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-23 19:44:20 +00:00
royalnet/telegrambot.py

763 lines
34 KiB
Python
Raw Normal View History

2018-01-25 14:24:17 +00:00
import datetime
2017-11-11 17:55:13 +00:00
import random
2018-07-23 17:34:41 +00:00
import typing
2017-10-30 09:46:37 +00:00
import db
import errors
2018-01-25 14:24:17 +00:00
import stagismo
2019-01-29 13:48:53 +00:00
from sqlalchemy.sql import text
2019-01-02 20:10:54 +00:00
# python-telegram-bot has a different name
# noinspection PyPackageRequirements
2018-03-14 10:53:26 +00:00
from telegram import Bot, Update, InlineKeyboardMarkup, InlineKeyboardButton
2019-01-02 20:10:54 +00:00
# noinspection PyPackageRequirements
2018-03-14 10:53:26 +00:00
from telegram.ext import Updater, CommandHandler, CallbackQueryHandler
2019-01-25 20:27:51 +00:00
from telegram.error import TimedOut, Unauthorized
2018-09-11 00:02:09 +00:00
import dice
2018-09-13 16:38:21 +00:00
import sys
2018-04-09 17:56:43 +00:00
import os
import cast
2018-05-31 20:14:50 +00:00
import re
2018-08-08 19:59:47 +00:00
import logging
import configparser
import markovify
2018-09-13 16:38:21 +00:00
import raven
2018-09-17 22:26:01 +00:00
import coloredlogs
2019-01-25 14:28:47 +00:00
import strings
s = strings.safely_format_string
2018-08-08 19:59:47 +00:00
# Markov model
try:
with open("markovmodel.json") as file:
model = markovify.Text.from_json(file.read())
except Exception:
model = None
2018-09-18 22:02:39 +00:00
logging.getLogger().disabled = True
2018-08-16 17:46:07 +00:00
logger = logging.getLogger(__name__)
2018-09-18 22:13:41 +00:00
os.environ["COLOREDLOGS_LOG_FORMAT"] = "%(asctime)s %(levelname)s %(name)s %(message)s"
2018-09-17 22:26:01 +00:00
coloredlogs.install(level="DEBUG", logger=logger)
2017-10-30 09:46:37 +00:00
# Init the config reader
config = configparser.ConfigParser()
config.read("config.ini")
2017-11-11 17:55:13 +00:00
discord_connection = None
2018-09-13 16:38:21 +00:00
# Init the Sentry client
sentry = raven.Client(config["Sentry"]["token"],
release=raven.fetch_git_sha(os.path.dirname(__file__)),
install_logging_hook=False,
hook_libraries=[])
2018-09-13 21:11:56 +00:00
def catch_and_report(func: "function"):
def new_func(bot: Bot, update: Update):
2018-09-13 16:38:21 +00:00
# noinspection PyBroadException
try:
2018-09-13 21:11:56 +00:00
return func(bot, update)
2019-01-25 14:28:47 +00:00
except TimedOut:
logger.warning(f"Telegram timed out in {update}")
2018-09-13 16:38:21 +00:00
except Exception:
2019-01-28 21:55:55 +00:00
if __debug__:
raise
2018-09-13 21:11:56 +00:00
logger.error(f"Critical error: {sys.exc_info()}")
# noinspection PyBroadException
try:
bot.send_message(int(config["Telegram"]["main_group"]),
2019-01-28 21:55:55 +00:00
s(strings.TELEGRAM.ERRORS.CRITICAL_ERROR, exc_info=sys.exc_info()),
2019-01-28 22:37:01 +00:00
parse_mode="HTML")
2018-09-13 21:11:56 +00:00
except Exception:
logger.error(f"Double critical error: {sys.exc_info()}")
2019-01-23 22:11:17 +00:00
sentry.user_context({
"id": update.effective_user.id,
"telegram": {
"username": update.effective_user.username,
"first_name": update.effective_user.first_name,
"last_name": update.effective_user.last_name
}
})
sentry.extra_context({
"update": update.to_dict()
})
sentry.captureException()
2018-09-13 21:11:56 +00:00
return new_func
2019-01-02 21:19:25 +00:00
@catch_and_report
def cmd_ping(bot: Bot, update: Update):
2019-01-28 21:55:55 +00:00
bot.send_message(update.message.chat.id, s(strings.PONG))
2019-01-02 21:19:25 +00:00
2018-09-13 21:11:56 +00:00
@catch_and_report
2017-10-30 09:46:37 +00:00
def cmd_register(bot: Bot, update: Update):
session = db.Session()
try:
2019-01-28 21:55:55 +00:00
try:
username = update.message.text.split(" ", 1)[1]
except IndexError:
2019-01-28 22:37:01 +00:00
bot.send_message(update.message.chat.id, s(strings.LINKING.ERRORS.INVALID_SYNTAX),
parse_mode="HTML")
2019-01-28 21:55:55 +00:00
session.close()
return
try:
t = db.Telegram.create(session,
royal_username=username,
telegram_user=update.message.from_user)
except errors.NotFoundError:
2019-01-28 22:37:01 +00:00
bot.send_message(update.message.chat.id, s(strings.LINKING.ERRORS.NOT_FOUND),
parse_mode="HTML")
2019-01-28 21:55:55 +00:00
session.close()
return
except errors.AlreadyExistingError:
2019-01-28 22:37:01 +00:00
bot.send_message(update.message.chat.id, s(strings.LINKING.ERRORS.ALREADY_EXISTING),
parse_mode="HTML")
2019-01-28 21:55:55 +00:00
session.close()
return
session.add(t)
session.commit()
2019-01-28 22:37:01 +00:00
bot.send_message(update.message.chat.id, s(strings.LINKING.SUCCESSFUL),
parse_mode="HTML")
2019-01-28 21:55:55 +00:00
finally:
2018-01-25 14:24:17 +00:00
session.close()
2017-10-30 09:46:37 +00:00
2017-10-30 12:45:38 +00:00
2018-09-13 21:11:56 +00:00
@catch_and_report
2017-10-30 12:45:38 +00:00
def cmd_discord(bot: Bot, update: Update):
2018-01-20 14:28:04 +00:00
if discord_connection is None:
2018-06-13 22:10:57 +00:00
bot.send_message(update.message.chat.id, "⚠ Il bot non è collegato a Discord al momento.")
2018-01-20 14:28:04 +00:00
return
2018-12-29 00:26:30 +00:00
# dirty hack as usual
if update.message.text.endswith("full"):
discord_connection.send("get cv full")
else:
discord_connection.send("get cv")
2018-08-28 13:48:12 +00:00
message = discord_connection.recv()
2018-09-18 23:04:48 +00:00
bot.send_message(update.message.chat.id, message, disable_web_page_preview=True, parse_mode="HTML")
2017-10-30 12:45:38 +00:00
2018-09-13 21:11:56 +00:00
@catch_and_report
2017-11-11 17:55:13 +00:00
def cmd_cast(bot: Bot, update: Update):
try:
spell: str = update.message.text.split(" ", 1)[1]
2017-11-11 17:55:13 +00:00
except IndexError:
bot.send_message(update.message.chat.id, "⚠️ Non hai specificato nessun incantesimo!\n"
2018-09-13 21:36:56 +00:00
"Sintassi corretta: `/cast <nome_incantesimo>`", parse_mode="Markdown")
2017-11-11 17:55:13 +00:00
return
# Open a new db session
session = db.Session()
# Find a target for the spell
target = random.sample(session.query(db.Telegram).all(), 1)[0]
# Close the session
session.close()
2018-10-08 22:51:57 +00:00
# END
2018-11-03 17:42:56 +00:00
bot.send_message(update.message.chat.id, cast.cast(spell_name=spell,
target_name=target.username if target.username is not None
else target.first_name, platform="telegram"),
parse_mode="HTML")
2018-01-25 14:24:17 +00:00
2018-09-13 21:11:56 +00:00
@catch_and_report
2018-01-25 14:24:17 +00:00
def cmd_color(bot: Bot, update: Update):
2018-10-07 15:19:42 +00:00
bot.send_message(update.message.chat.id, "I am sorry, unknown error occured during working with your request,"
" Admin were notified")
2018-01-25 14:24:17 +00:00
2018-09-13 21:11:56 +00:00
@catch_and_report
2018-01-25 14:24:17 +00:00
def cmd_smecds(bot: Bot, update: Update):
ds = random.sample(stagismo.listona, 1)[0]
bot.send_message(update.message.chat.id, f"Secondo me, è colpa {ds}.")
2018-09-13 21:11:56 +00:00
@catch_and_report
2018-01-25 14:24:17 +00:00
def cmd_ciaoruozi(bot: Bot, update: Update):
if update.message.from_user.username.lstrip("@") == "MeStakes":
bot.send_message(update.message.chat.id, "Ciao me!")
else:
bot.send_message(update.message.chat.id, "Ciao Ruozi!")
2018-09-13 21:11:56 +00:00
@catch_and_report
2018-01-25 14:24:17 +00:00
def cmd_ahnonlosoio(bot: Bot, update: Update):
2019-01-02 20:10:54 +00:00
if update.message.reply_to_message is not None and update.message.reply_to_message.text in [
"/ahnonlosoio", "/ahnonlosoio@royalgamesbot", "Ah, non lo so io!", "Ah, non lo so neppure io!"
]:
2018-01-25 14:24:17 +00:00
bot.send_message(update.message.chat.id, "Ah, non lo so neppure io!")
else:
bot.send_message(update.message.chat.id, "Ah, non lo so io!")
2018-09-13 21:11:56 +00:00
@catch_and_report
2018-01-25 14:24:17 +00:00
def cmd_balurage(bot: Bot, update: Update):
session = db.Session()
try:
user = session.query(db.Telegram).filter_by(telegram_id=update.message.from_user.id).one_or_none()
if user is None:
2019-01-02 20:10:54 +00:00
bot.send_message(update.message.chat.id,
"⚠ Il tuo account Telegram non è registrato al RYGdb!\n\n"
"Registrati con `/register@royalgamesbot <nomeutenteryg>`.",
parse_mode="Markdown")
2018-01-25 14:24:17 +00:00
return
try:
reason = update.message.text.split(" ", 1)[1]
except IndexError:
reason = None
br = db.BaluRage(royal_id=user.royal_id, reason=reason)
session.add(br)
session.commit()
bot.send_message(update.message.chat.id, f"😡 Stai sfogando la tua ira sul bot!")
2018-03-14 10:53:26 +00:00
except Exception:
2018-01-25 14:24:17 +00:00
raise
finally:
session.close()
2018-09-13 21:11:56 +00:00
@catch_and_report
2018-01-25 14:24:17 +00:00
def cmd_diario(bot: Bot, update: Update):
session = db.Session()
try:
user = session.query(db.Telegram).filter_by(telegram_id=update.message.from_user.id).one_or_none()
if user is None:
2018-09-13 21:36:56 +00:00
bot.send_message(update.message.chat.id, "⚠ Il tuo account Telegram non è registrato al RYGdb!"
" Registrati con `/register@royalgamesbot <nomeutenteryg>`.",
parse_mode="Markdown")
2018-01-25 14:24:17 +00:00
return
try:
text = update.message.text.split(" ", 1)[1]
author = session.query(db.Telegram).filter_by(telegram_id=update.message.from_user.id).one_or_none()
saver = author
except IndexError:
if update.message.reply_to_message is None:
2019-01-02 20:10:54 +00:00
bot.send_message(update.message.chat.id,
f"⚠ Non hai specificato cosa aggiungere al diario!\n\n"
f"Puoi rispondere `/diario@royalgamesbot` al messaggio che vuoi salvare nel diario"
f" oppure scrivere `/diario@royalgamesbot <messaggio>`"
f" per aggiungere quel messaggio nel diario.",
parse_mode="Markdown")
2018-01-25 14:24:17 +00:00
return
text = update.message.reply_to_message.text
2019-01-02 20:10:54 +00:00
author = session.query(db.Telegram)\
.filter_by(telegram_id=update.message.reply_to_message.from_user.id)\
.one_or_none()
2018-01-25 14:24:17 +00:00
saver = session.query(db.Telegram).filter_by(telegram_id=update.message.from_user.id).one_or_none()
if text is None:
bot.send_message(update.message.chat.id, f"⚠ Il messaggio a cui hai risposto non contiene testo.")
return
diario = db.Diario(timestamp=datetime.datetime.now(),
saver=saver,
author=author,
text=text)
session.add(diario)
session.commit()
2018-10-03 22:24:50 +00:00
bot.send_message(update.message.chat.id,
f"✅ Riga [#{diario.id}](https://ryg.steffo.eu/diario#entry-{diario.id}) aggiunta al diario!",
parse_mode="Markdown", disable_web_page_preview=True)
2018-01-25 14:24:17 +00:00
except Exception:
raise
finally:
session.close()
2017-11-11 17:55:13 +00:00
2018-09-13 21:11:56 +00:00
@catch_and_report
2018-03-14 10:53:26 +00:00
def cmd_vote(bot: Bot, update: Update):
session = db.Session()
try:
user = session.query(db.Telegram).filter_by(telegram_id=update.message.from_user.id).one_or_none()
if user is None:
bot.send_message(update.message.chat.id,
2018-07-24 17:23:19 +00:00
"⚠ Il tuo account Telegram non è registrato al RYGdb!"
2018-09-13 21:36:56 +00:00
" Registrati con `/register@royalgamesbot <nomeutenteryg>`.", parse_mode="Markdown")
2018-03-14 10:53:26 +00:00
return
try:
_, mode, question = update.message.text.split(" ", 2)
except IndexError:
bot.send_message(update.message.chat.id,
"⚠ Non hai specificato tutti i parametri necessari!"
2018-09-13 21:36:56 +00:00
"Sintassi: `/vote@royalgamesbot <public|secret> <domanda>`", parse_mode="Markdown")
2018-03-14 10:53:26 +00:00
return
if mode == "public":
vote = db.VoteQuestion(question=question, anonymous=False)
elif mode == "secret":
vote = db.VoteQuestion(question=question, anonymous=True)
else:
bot.send_message(update.message.chat.id,
"⚠ Non hai specificato una modalità valida!"
2018-09-13 21:36:56 +00:00
"Sintassi: `/vote@royalgamesbot <public|secret> <domanda>`", parse_mode="Markdown")
2018-03-14 10:53:26 +00:00
return
session.add(vote)
session.flush()
inline_keyboard = InlineKeyboardMarkup([[InlineKeyboardButton("🔵 Sì", callback_data="vote_yes")],
[InlineKeyboardButton("🔴 No", callback_data="vote_no")],
[InlineKeyboardButton("⚫️ Astieniti", callback_data="vote_abstain")]])
2019-01-02 20:10:54 +00:00
message = bot.send_message(update.message.chat.id, vote.generate_text(session=session),
reply_markup=inline_keyboard,
2018-03-14 10:53:26 +00:00
parse_mode="HTML")
vote.message_id = message.message_id
session.commit()
2019-01-23 22:11:17 +00:00
finally:
session.close()
2019-01-28 22:37:01 +00:00
2019-01-28 21:15:19 +00:00
@catch_and_report
def cmd_cerca(bot: Bot, update: Update):
2019-01-28 21:15:19 +00:00
session = db.Session()
try:
2019-01-28 22:37:01 +00:00
try:
2019-01-29 13:46:33 +00:00
queryText = update.message.text.split(" ", 1)[1]
2019-01-28 22:37:01 +00:00
except IndexError:
bot.send_message(update.message.chat.id, s(strings.DIARIO_SEARCH.ERRORS.INVALID_SYNTAX))
2019-01-28 21:15:19 +00:00
return
2019-01-29 13:46:33 +00:00
queryText = queryText.replace('%', '\\%').replace('_', '\\_')
2019-01-29 13:48:53 +00:00
entries = session.query(db.Diario).filter(text(f"text ~* '(?:[^\w\d]+{queryText}[^\w\d]+|^{queryText}[^\w\d]+|^{queryText}$|[^\w\d]+{queryText}$)'")).order_by(db.Diario.id).all()
cerca_message(bot, update, queryText, entries)
finally:
session.close()
def cerca_message (bot: Bot, update: Update, queryText, entries):
msg = f"Risultati della ricerca di {queryText}:\n"
for entry in entries[:5]:
msg += f'<a href="https://ryg.steffo.eu/diario#entry-{entry.id}">#{entry.id}</a> di {entry.author or "Anonimo"}\n{entry.text}\n\n'
2019-01-28 22:37:01 +00:00
if len(entries) > 5:
msg += "I termini comapiono anche nelle righe:\n"
2019-01-28 21:15:19 +00:00
for entry in entries[5:]:
2019-01-28 22:37:01 +00:00
msg += f'<a href="https://ryg.steffo.eu/diario#entry-{entry.id}">#{entry.id}</a> '
bot.send_message(update.message.chat.id, msg, parse_mode="HTML")
2019-01-28 22:37:01 +00:00
2019-01-23 22:11:17 +00:00
@catch_and_report
def cmd_mm(bot: Bot, update: Update):
session = db.Session()
try:
user = session.query(db.Telegram).filter_by(telegram_id=update.message.from_user.id).one_or_none()
if user is None:
2019-01-28 22:02:50 +00:00
bot.send_message(update.message.chat.id, s(strings.TELEGRAM.ERRORS.TELEGRAM_NOT_LINKED), parse_mode="Markdown")
2019-01-23 22:11:17 +00:00
return
match = re.match(r"/(?:mm|matchmaking)(?:@royalgamesbot)?(?: (?:([0-9]+)-)?([0-9]+))? (?:per )?([A-Za-z0-9!\-_\. ]+)(?:.*\n(.+))?",
update.message.text)
if match is None:
bot.send_message(update.message.chat.id,
2019-01-25 14:28:47 +00:00
"")
2019-01-23 22:11:17 +00:00
return
min_players, max_players, match_name, match_desc = match.group(1, 2, 3, 4)
db_match = db.Match(timestamp=datetime.datetime.now(),
match_title=match_name,
match_desc=match_desc,
min_players=min_players,
max_players=max_players,
creator=user)
session.add(db_match)
session.flush()
2019-01-28 22:02:50 +00:00
inline_keyboard = InlineKeyboardMarkup([([InlineKeyboardButton(s(strings.MATCHMAKING.BUTTONS[key]),
2019-01-25 14:28:47 +00:00
callback_data=key)])
for key in strings.MATCHMAKING.BUTTONS])
2019-01-24 00:42:48 +00:00
message = bot.send_message(config["Telegram"]["announcement_group"], db_match.generate_text(session=session),
2019-01-23 22:11:17 +00:00
parse_mode="HTML",
reply_markup=inline_keyboard)
db_match.message_id = message.message_id
session.commit()
2018-03-14 10:53:26 +00:00
finally:
session.close()
2018-09-13 21:11:56 +00:00
@catch_and_report
2018-03-14 10:53:26 +00:00
def on_callback_query(bot: Bot, update: Update):
if update.callback_query.data.startswith("vote_"):
2019-01-23 22:11:17 +00:00
if update.callback_query.data == "vote_yes":
status = db.VoteChoices.YES
emoji = "🔵"
elif update.callback_query.data == "vote_no":
status = db.VoteChoices.NO
emoji = "🔴"
elif update.callback_query.data == "vote_abstain":
status = db.VoteChoices.ABSTAIN
emoji = "⚫️"
else:
raise NotImplementedError()
2018-03-14 10:53:26 +00:00
session = db.Session()
try:
user = session.query(db.Telegram).filter_by(telegram_id=update.callback_query.from_user.id).one_or_none()
if user is None:
bot.answer_callback_query(update.callback_query.id, show_alert=True,
2019-01-28 22:02:50 +00:00
text=s(strings.TELEGRAM.ERRORS.TELEGRAM_NOT_LINKED),
2018-09-15 17:00:33 +00:00
parse_mode="Markdown")
2018-03-14 10:53:26 +00:00
return
2019-01-02 20:10:54 +00:00
question = session.query(db.VoteQuestion)\
.filter_by(message_id=update.callback_query.message.message_id)\
.one()
2018-03-14 10:53:26 +00:00
answer = session.query(db.VoteAnswer).filter_by(question=question, user=user).one_or_none()
if answer is None:
2019-01-23 22:11:17 +00:00
answer = db.VoteAnswer(question=question, choice=status, user=user)
2018-03-14 10:53:26 +00:00
session.add(answer)
2018-09-15 17:00:33 +00:00
bot.answer_callback_query(update.callback_query.id, text=f"Hai votato {emoji}.", cache_time=1)
2019-01-23 22:11:17 +00:00
elif answer.choice == status:
2018-09-15 17:00:33 +00:00
session.delete(answer)
bot.answer_callback_query(update.callback_query.id, text=f"Hai ritratto il tuo voto.", cache_time=1)
2018-03-14 10:53:26 +00:00
else:
2019-01-23 22:11:17 +00:00
answer.choice = status
2018-09-15 17:00:33 +00:00
bot.answer_callback_query(update.callback_query.id, text=f"Hai cambiato il tuo voto in {emoji}.",
cache_time=1)
2018-03-14 10:53:26 +00:00
session.commit()
2019-01-02 20:10:54 +00:00
inline_keyboard = InlineKeyboardMarkup([[InlineKeyboardButton("🔵 Sì",
callback_data="vote_yes")],
[InlineKeyboardButton("🔴 No",
callback_data="vote_no")],
[InlineKeyboardButton("⚫️ Astieniti",
callback_data="vote_abstain")]])
bot.edit_message_text(message_id=update.callback_query.message.message_id,
chat_id=update.callback_query.message.chat.id,
text=question.generate_text(session),
reply_markup=inline_keyboard,
2018-03-14 10:53:26 +00:00
parse_mode="HTML")
2019-01-23 22:11:17 +00:00
finally:
session.close()
elif update.callback_query.data.startswith("match_"):
session = db.Session()
try:
user = session.query(db.Telegram).filter_by(telegram_id=update.callback_query.from_user.id).one_or_none()
if user is None:
2019-01-25 14:28:47 +00:00
bot.answer_callback_query(update.callback_query.id,
show_alert=True,
2019-01-28 21:55:55 +00:00
text=strings.TELEGRAM.ERRORS.TELEGRAM_NOT_LINKED,
2019-01-23 22:11:17 +00:00
parse_mode="Markdown")
return
match = session.query(db.Match).filter_by(message_id=update.callback_query.message.message_id).one()
2019-01-25 14:28:47 +00:00
if update.callback_query.data == "match_close":
if match.creator != user:
bot.answer_callback_query(update.callback_query.id,
show_alert=True,
text=strings.MATCHMAKING.ERRORS.NOT_ADMIN)
2019-01-23 22:11:17 +00:00
return
2019-01-25 14:28:47 +00:00
match.closed = True
2019-01-25 20:27:51 +00:00
failed_send = []
2019-01-25 14:28:47 +00:00
for player in match.players:
if player.status >= 1:
2019-01-25 20:27:51 +00:00
try:
bot.send_message(player.user.telegram_id,
s(strings.MATCHMAKING.GAME_START[player.status],
2019-01-25 20:29:38 +00:00
**match.format_dict()),
parse_mode="HTML")
2019-01-25 20:27:51 +00:00
except Unauthorized:
failed_send.append(player)
if failed_send:
2019-01-25 20:29:38 +00:00
for player in failed_send:
2019-01-25 20:27:51 +00:00
bot.send_message(int(config["Telegram"]["main_group"]),
s(strings.MATCHMAKING.ERRORS.UNAUTHORIZED, mention=player.user.mention()))
2019-01-25 14:38:00 +00:00
elif update.callback_query.data == "match_cancel":
2019-01-25 14:42:08 +00:00
if not (match.creator == user or user.telegram_id == 25167391):
2019-01-25 14:38:00 +00:00
bot.answer_callback_query(update.callback_query.id,
show_alert=True,
text=strings.MATCHMAKING.ERRORS.NOT_ADMIN)
return
match.closed = True
status = {
"match_ready": db.MatchmakingStatus.READY,
"match_wait_for_me": db.MatchmakingStatus.WAIT_FOR_ME,
"match_someone_else": db.MatchmakingStatus.SOMEONE_ELSE,
"match_maybe": db.MatchmakingStatus.MAYBE,
"match_ignore": db.MatchmakingStatus.IGNORED,
"match_close": None,
"match_cancel": None,
}.get(update.callback_query.data)
2019-01-23 22:11:17 +00:00
if status:
if match.closed:
2019-01-25 14:28:47 +00:00
bot.answer_callback_query(update.callback_query.id,
show_alert=True,
text=strings.MATCHMAKING.ERRORS.MATCH_CLOSED)
2019-01-23 22:11:17 +00:00
return
player = session.query(db.MatchPartecipation).filter_by(match=match, user=user).one_or_none()
if player is None:
player = db.MatchPartecipation(match=match, status=status.value, user=user)
session.add(player)
else:
player.status = status.value
session.commit()
2019-01-25 14:28:47 +00:00
bot.answer_callback_query(update.callback_query.id,
2019-01-25 20:27:51 +00:00
text=strings.MATCHMAKING.TICKER_TEXT[update.callback_query.data],
2019-01-25 14:28:47 +00:00
cache_time=1)
2019-01-23 22:11:17 +00:00
if not match.closed:
2019-01-25 14:28:47 +00:00
inline_keyboard = InlineKeyboardMarkup([([InlineKeyboardButton(strings.MATCHMAKING.BUTTONS[key],
callback_data=key)])
for key in strings.MATCHMAKING.BUTTONS])
2019-01-23 22:11:17 +00:00
else:
inline_keyboard = None
bot.edit_message_text(message_id=update.callback_query.message.message_id,
2019-01-24 00:42:48 +00:00
chat_id=config["Telegram"]["announcement_group"],
2019-01-23 22:11:17 +00:00
text=match.generate_text(session),
reply_markup=inline_keyboard,
parse_mode="HTML")
2018-03-14 10:53:26 +00:00
finally:
session.close()
2018-09-13 21:11:56 +00:00
@catch_and_report
def cmd_eat(bot: Bot, update: Update):
try:
food: str = update.message.text.split(" ", 1)[1].capitalize()
except IndexError:
bot.send_message(update.message.chat.id, "⚠️ Non hai specificato cosa mangiare!\n"
2018-09-13 21:36:56 +00:00
"Sintassi corretta: `/eat <cibo>`", parse_mode="Markdown")
return
2018-06-04 09:58:27 +00:00
if "tonnuooooooro" in food.lower():
2018-05-29 21:50:47 +00:00
bot.send_message(update.message.chat.id, "👻 Il pesce che hai mangiato era posseduto.\n"
"Spooky!")
return
bot.send_message(update.message.chat.id, f"🍗 Hai mangiato {food}!")
2018-09-13 21:11:56 +00:00
@catch_and_report
2018-05-31 20:14:50 +00:00
def cmd_ship(bot: Bot, update: Update):
try:
_, name_one, name_two = update.message.text.split(" ", 2)
except ValueError:
2018-05-31 20:14:50 +00:00
bot.send_message(update.message.chat.id, "⚠️ Non hai specificato correttamente i due nomi!\n"
2018-09-13 21:36:56 +00:00
"Sintassi corretta: `/ship <nome> <nome>`", parse_mode="Markdown")
2018-05-31 20:14:50 +00:00
return
name_one = name_one.lower()
name_two = name_two.lower()
part_one = re.search(r"^[A-Za-z][^aeiouAEIOU]*[aeiouAEIOU]?", name_one)
part_two = re.search(r"[^aeiouAEIOU]*[aeiouAEIOU]?[A-Za-z]$", name_two)
try:
mixed = part_one.group(0) + part_two.group(0)
2019-01-02 20:10:54 +00:00
except Exception:
2018-05-31 20:14:50 +00:00
bot.send_message(update.message.chat.id, "⚠ I nomi specificati non sono validi.\n"
"Riprova con dei nomi diversi!")
return
if part_one is None or part_two is None:
bot.send_message(update.message.chat.id, "⚠ I nomi specificati non sono validi.\n"
"Riprova con dei nomi diversi!")
return
bot.send_message(update.message.chat.id, f"💕 {name_one.capitalize()} + {name_two.capitalize()} ="
f" {mixed.capitalize()}")
2018-09-13 21:11:56 +00:00
@catch_and_report
2018-06-04 20:54:12 +00:00
def cmd_profile(bot: Bot, update: Update):
session = db.Session()
user = session.query(db.Telegram).filter_by(telegram_id=update.message.from_user.id).join(db.Royal).one_or_none()
session.close()
if user is None:
bot.send_message(update.message.chat.id, "⚠ Non sei connesso a Royalnet!\n"
"Per registrarti, utilizza il comando /register.")
return
2018-06-04 21:20:08 +00:00
bot.send_message(update.message.chat.id, f"👤 [Profilo di {user.royal.username}]"
2018-06-27 20:16:54 +00:00
f"(http://ryg.steffo.eu/profile/{user.royal.username})\n"
f"Attualmente, hai **{user.royal.fiorygi}** fiorygi.",
2018-06-04 21:18:50 +00:00
parse_mode="Markdown")
2018-06-04 20:54:12 +00:00
2018-09-13 21:11:56 +00:00
@catch_and_report
2018-06-13 22:10:57 +00:00
def cmd_bridge(bot: Bot, update: Update):
try:
data = update.message.text.split(" ", 1)[1]
except IndexError:
2019-01-02 20:10:54 +00:00
bot.send_message(update.message.chat.id,
"⚠ Non hai specificato un comando!\n"
"Sintassi corretta: `/bridge <comando> <argomenti>`",
parse_mode="Markdown")
return
2018-06-13 22:10:57 +00:00
discord_connection.send(f"!{data}")
result = discord_connection.recv()
if result == "error":
2018-08-28 13:48:12 +00:00
bot.send_message(update.message.chat.id, "⚠ Il comando specificato non esiste.")
2018-06-13 22:10:57 +00:00
if result == "success":
bot.send_message(update.message.chat.id, "⏩ Comando eseguito su Discord.")
2018-07-23 17:34:41 +00:00
def parse_timestring(timestring: str) -> typing.Union[datetime.timedelta, datetime.datetime]:
# Unix time
try:
unix_timestamp = float(timestring)
return datetime.datetime.fromtimestamp(unix_timestamp)
except ValueError:
pass
# Dashed time
try:
split_date = timestring.split("-")
now = datetime.datetime.now()
if len(split_date) == 5:
# yyyy-mm-dd-hh-mm
2018-07-24 17:31:33 +00:00
return datetime.datetime(year=int(split_date[0]),
month=int(split_date[1]),
day=int(split_date[2]),
hour=int(split_date[3]),
minute=int(split_date[4]))
2018-07-23 17:34:41 +00:00
elif len(split_date) == 4:
return now.replace(month=int(split_date[0]),
day=int(split_date[1]),
hour=int(split_date[2]),
minute=int(split_date[3]))
elif len(split_date) == 3:
return now.replace(day=int(split_date[0]),
hour=int(split_date[1]),
minute=int(split_date[2]))
elif len(split_date) == 2:
return now.replace(hour=int(split_date[0]),
minute=int(split_date[1]))
except (IndexError, ValueError):
pass
# Simple time from now
try:
if timestring.endswith("w"):
return datetime.timedelta(weeks=float(timestring[:-1]))
elif timestring.endswith("d"):
return datetime.timedelta(days=float(timestring[:-1]))
elif timestring.endswith("h"):
return datetime.timedelta(hours=float(timestring[:-1]))
elif timestring.endswith("m"):
return datetime.timedelta(minutes=float(timestring[:-1]))
except Exception:
pass
# Nothing found
raise ValueError("Nothing was found.")
2018-09-13 21:11:56 +00:00
@catch_and_report
2018-07-23 17:34:41 +00:00
def cmd_newevent(bot: Bot, update: Update):
try:
_, timestring, name_desc = update.message.text.split(" ", 2)
2018-09-14 22:51:25 +00:00
except ValueError:
2018-07-23 17:34:41 +00:00
bot.send_message(update.message.chat.id, "⚠️ Sintassi del comando non valida.\n"
"Sintassi corretta:\n"
"```/newevent <timestamp|[[[anno-]mese-]giorno-]ore-minuti"
"|{numero}{w|d|h|m}> <nome>\n"
2018-09-13 21:36:56 +00:00
"[descrizione]```", parse_mode="Markdown")
2018-07-23 17:34:41 +00:00
return
try:
2018-07-24 17:29:34 +00:00
name, description = name_desc.split("\n", 1)
2018-09-14 22:51:25 +00:00
except ValueError:
2018-07-23 17:34:41 +00:00
name = name_desc
description = None
# Parse the timestring
try:
parsed_time = parse_timestring(timestring)
2019-01-03 17:01:43 +00:00
if parsed_time < datetime.datetime.now():
2019-01-03 17:13:05 +00:00
raise errors.PastDateError()
2018-07-23 17:34:41 +00:00
except ValueError:
bot.send_message(update.message.chat.id, "⚠ Non è stato possibile leggere la data.\n"
"Sintassi corretta:\n"
"```/newevent <timestamp|[[[anno-]mese-]giorno-]ore-minuti"
"|{numero}{w|d|h|m}> <nome>\n"
2018-09-13 21:36:56 +00:00
"[descrizione]```", parse_mode="Markdown")
2018-07-23 17:34:41 +00:00
return
2019-01-03 17:13:05 +00:00
except errors.PastDateError:
2019-01-03 17:01:43 +00:00
bot.send_message(update.message.chat.id, "⚠ La data inserita è una data passata.\n"
"per favore inserisci una data futura.\n", parse_mode="Markdown")
return
2018-07-23 17:34:41 +00:00
# Create the event
session = db.Session()
2019-01-02 20:10:54 +00:00
telegram_user = session.query(db.Telegram)\
.filter_by(telegram_id=update.message.from_user.id)\
.join(db.Royal)\
.one_or_none()
2018-07-23 17:34:41 +00:00
event = db.Event(author=telegram_user.royal,
name=name,
description=description,
time=datetime.datetime.fromtimestamp(0))
# Set the time
if isinstance(parsed_time, datetime.datetime):
event.time = parsed_time
else:
event.time_left = parsed_time
# Save the event
session.add(event)
session.commit()
session.close()
bot.send_message(update.message.chat.id, "✅ Evento aggiunto al Calendario Royal Games!")
2018-09-13 21:11:56 +00:00
@catch_and_report
2018-07-24 17:23:19 +00:00
def cmd_calendar(bot: Bot, update: Update):
session = db.Session()
next_events = session.query(db.Event).filter(db.Event.time > datetime.datetime.now()).order_by(db.Event.time).all()
session.close()
msg = "📆 Prossimi eventi\n"
for event in next_events:
if event.time_left.days >= 1:
msg += event.time.strftime('%Y-%m-%d %H:%M')
else:
msg += f"{int(event.time_left.total_seconds() // 3600)}h" \
f" {int((event.time_left.total_seconds() % 3600) // 60)}m"
msg += f" <b>{event.name}</b>\n"
msg += '\nPer ulteriori dettagli, visita <a href="https://ryg.steffo.eu">Royalnet</a>'
bot.send_message(update.message.chat.id, msg, parse_mode="HTML", disable_web_page_preview=True)
2018-09-13 21:11:56 +00:00
@catch_and_report
2018-08-08 19:59:47 +00:00
def cmd_markov(bot: Bot, update: Update):
if model is None:
2019-01-28 19:45:31 +00:00
bot.send_message(update.message.chat.id, strings.MARKOV.ERRORS.NO_MODEL)
2018-08-08 19:59:47 +00:00
return
try:
2019-01-28 19:45:31 +00:00
first_word = update.message.text.split(" ")[1]
except IndexError:
# Any word
2018-08-08 19:59:47 +00:00
sentence = model.make_sentence(tries=1000)
if sentence is None:
2019-01-28 19:45:31 +00:00
bot.send_message(update.message.chat.id, strings.MARKOV.ERRORS.GENERATION_FAILED)
2018-08-08 19:59:47 +00:00
return
bot.send_message(update.message.chat.id, sentence)
2019-01-28 19:45:31 +00:00
return
# Specific word
try:
2018-08-08 19:59:47 +00:00
sentence = model.make_sentence_with_start(first_word, tries=1000)
2019-01-28 19:45:31 +00:00
except KeyError:
bot.send_message(update.message.chat.id, strings.MARKOV.ERRORS.MISSING_WORD)
return
if sentence is None:
bot.send_message(update.message.chat.id, strings.MARKOV.ERRORS.SPECIFIC_WORD_FAILED)
return
bot.send_message(update.message.chat.id, sentence)
2018-08-08 19:59:47 +00:00
2018-09-13 21:11:56 +00:00
@catch_and_report
2018-09-11 00:02:09 +00:00
def cmd_roll(bot: Bot, update: Update):
dice_string = update.message.text.split(" ", 1)[1]
try:
2018-09-13 16:38:21 +00:00
result = dice.roll(f"{dice_string}t")
2018-09-11 00:02:09 +00:00
except dice.DiceBaseException:
bot.send_message(update.message.chat.id, "⚠ Il tiro dei dadi è fallito. Controlla la sintassi!")
return
2018-09-11 00:07:29 +00:00
bot.send_message(update.message.chat.id, f"🎲 {result}")
2018-09-11 00:02:09 +00:00
2017-11-11 17:55:13 +00:00
def process(arg_discord_connection):
2018-01-20 14:28:04 +00:00
if arg_discord_connection is not None:
global discord_connection
discord_connection = arg_discord_connection
2018-09-11 00:02:09 +00:00
logger.info("Creating updater...")
2017-10-30 12:45:38 +00:00
u = Updater(config["Telegram"]["bot_token"])
2018-09-11 00:02:09 +00:00
logger.info("Registering handlers...")
2019-01-02 21:19:25 +00:00
u.dispatcher.add_handler(CommandHandler("ping", cmd_ping))
2017-10-30 12:45:38 +00:00
u.dispatcher.add_handler(CommandHandler("register", cmd_register))
u.dispatcher.add_handler(CommandHandler("discord", cmd_discord))
2018-08-28 13:49:29 +00:00
u.dispatcher.add_handler(CommandHandler("cv", cmd_discord))
2017-11-11 17:55:13 +00:00
u.dispatcher.add_handler(CommandHandler("cast", cmd_cast))
2018-01-25 14:24:17 +00:00
u.dispatcher.add_handler(CommandHandler("color", cmd_color))
u.dispatcher.add_handler(CommandHandler("smecds", cmd_smecds))
u.dispatcher.add_handler(CommandHandler("ciaoruozi", cmd_ciaoruozi))
u.dispatcher.add_handler(CommandHandler("ahnonlosoio", cmd_ahnonlosoio))
u.dispatcher.add_handler(CommandHandler("balurage", cmd_balurage))
u.dispatcher.add_handler(CommandHandler("diario", cmd_diario))
2018-11-08 11:46:53 +00:00
u.dispatcher.add_handler(CommandHandler("spaggia", cmd_diario))
2018-03-14 10:53:26 +00:00
u.dispatcher.add_handler(CommandHandler("vote", cmd_vote))
u.dispatcher.add_handler(CommandHandler("eat", cmd_eat))
2018-05-31 20:14:50 +00:00
u.dispatcher.add_handler(CommandHandler("ship", cmd_ship))
2018-06-04 20:54:12 +00:00
u.dispatcher.add_handler(CommandHandler("profile", cmd_profile))
2018-06-13 22:10:57 +00:00
u.dispatcher.add_handler(CommandHandler("bridge", cmd_bridge))
2018-07-23 17:34:41 +00:00
u.dispatcher.add_handler(CommandHandler("newevent", cmd_newevent))
2018-07-24 17:23:19 +00:00
u.dispatcher.add_handler(CommandHandler("calendar", cmd_calendar))
2018-08-08 19:59:47 +00:00
u.dispatcher.add_handler(CommandHandler("markov", cmd_markov))
2018-09-11 00:02:09 +00:00
u.dispatcher.add_handler(CommandHandler("roll", cmd_roll))
u.dispatcher.add_handler(CommandHandler("r", cmd_roll))
2019-01-23 22:11:17 +00:00
u.dispatcher.add_handler(CommandHandler("mm", cmd_mm))
u.dispatcher.add_handler(CommandHandler("matchmaking", cmd_mm))
u.dispatcher.add_handler(CommandHandler("cerca", cmd_cerca))
2019-01-29 12:45:11 +00:00
u.dispatcher.add_handler(CommandHandler("search", cmd_cerca))
u.dispatcher.add_handler(CommandHandler("diariosearch", cmd_cerca))
2018-03-14 10:53:26 +00:00
u.dispatcher.add_handler(CallbackQueryHandler(on_callback_query))
2018-08-16 17:46:07 +00:00
logger.info("Handlers registered.")
2018-09-17 22:07:00 +00:00
u.start_polling()
logger.info("Polling started.")
u.idle()
2018-01-20 14:28:04 +00:00
2018-01-20 14:28:04 +00:00
if __name__ == "__main__":
2018-08-28 15:38:17 +00:00
process(None)