1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-27 13:34:28 +00:00

Merge branch 'master' into primo

# Conflicts:
#	grandbot.py
This commit is contained in:
Steffo 2017-03-27 13:07:07 +02:00
commit 78c0b5446c
3 changed files with 163 additions and 30 deletions

View file

@ -3,7 +3,7 @@ import json
import random import random
import aiohttp import aiohttp
import async_timeout import async_timeout
import extra_discord import royaldiscord
import markovify import markovify
import database import database
import royalbotconfig import royalbotconfig
@ -12,17 +12,26 @@ import datetime
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
b = telegram.Bot(royalbotconfig.telegram_token) b = telegram.Bot(royalbotconfig.telegram_token)
d = extra_discord.ExtraClient(royalbotconfig.discord_token) d = royaldiscord.ExtraClient(royalbotconfig.discord_token)
def currently_logged_in(update): def currently_logged_in(thing):
"""Trova l'utente connesso all'account di Telegram che ha mandato l'update.""" """Trova l'utente connesso all'account di Telegram che ha mandato l'update."""
# Create a new database session
session = database.Session() session = database.Session()
user = session.query(database.User).filter_by(telegram_id=update.message.sent_from.user_id).first() # Check if thing is a Telegram update
if isinstance(thing, telegram.Update):
user = session.query(database.User).filter_by(telegram_id=thing.message.sent_from.user_id).first()
# Check if thing is a Discord message
elif isinstance(thing, royaldiscord.discord.Message):
user = session.query(database.User).filter_by(discord_id=thing.author.id).first()
# I don't know what thing is.
else:
raise TypeError("thing must be either a telegram.Update or a discord.Message")
return user return user
async def start(bot, update, arguments): async def start_telegram(bot, update, arguments):
user = currently_logged_in(update) user = currently_logged_in(update)
if user is None: if user is None:
await update.message.reply(bot, f"Ciao!\n_Non hai eseguito l'accesso al RYGdb._", parse_mode="Markdown") await update.message.reply(bot, f"Ciao!\n_Non hai eseguito l'accesso al RYGdb._", parse_mode="Markdown")
@ -32,7 +41,7 @@ async def start(bot, update, arguments):
await update.message.reply(bot, f"Ciao!\nHai eseguito l'accesso come `{user}`.\nAttualmente hai {user.coins} .\n\n*Account collegati:*\n{telegram_status} Telegram\n{discord_status} Discord", parse_mode="Markdown") await update.message.reply(bot, f"Ciao!\nHai eseguito l'accesso come `{user}`.\nAttualmente hai {user.coins} .\n\n*Account collegati:*\n{telegram_status} Telegram\n{discord_status} Discord", parse_mode="Markdown")
async def diario(bot, update, arguments): async def diario_telegram(bot, update, arguments):
"""Aggiungi una frase al diario Royal Games. """Aggiungi una frase al diario Royal Games.
Devi essere un Royal per poter eseguire questo comando. Devi essere un Royal per poter eseguire questo comando.
@ -69,7 +78,44 @@ Sintassi: `/diario <frase>`"""
await update.message.reply(bot, "✅ Aggiunto al diario!") await update.message.reply(bot, "✅ Aggiunto al diario!")
async def leggi(bot, update, arguments): async def diario_discord(bot, message, arguments):
"""Aggiungi una frase al diario Royal Games.
Devi essere un Royal per poter eseguire questo comando.
Sintassi: `!diario <frase>`"""
# Check if the user is logged in
if not currently_logged_in(message):
bot.send_message(message.channel, "⚠ Non hai ancora eseguito l'accesso! Usa `!sync`.")
return
# Check if the currently logged in user is a Royal Games member
if not currently_logged_in(message).royal:
bot.send_message(message.channel, "⚠ Non sei autorizzato a eseguire questo comando.")
return
# Check the command syntax
if len(arguments) == 0:
bot.send_message(message.channel, "⚠ Sintassi del comando non valida.\n`!diario <random | markov | numerofrase>`")
return
# Check for non-ASCII characters
entry = " ".join(arguments)
if not entry.isprintable():
bot.send_message(message.channel, "⚠ La frase che stai provando ad aggiungere contiene caratteri non ASCII, quindi non è stata aggiunta.\nToglili e riprova!")
return
# Remove endlines
entry = entry.replace("\n", " ")
# TODO: check if a end-of-file character can be sent on Discord
# Generate a timestamp
time = message.timestamp
# Write on the diario file
file = open("diario.txt", "a", encoding="utf8")
file.write(f"{int(time)}|{entry}\n")
file.close()
del file
# Answer on Telegram
bot.send_message(message.channel, "✅ Aggiunto al diario!")
async def leggi_telegram(bot, update, arguments):
"""Leggi una frase dal diario Royal Games. """Leggi una frase dal diario Royal Games.
Puoi visualizzare il diario [qui](https://royal.steffo.me/diario.htm), leggere una frase casuale scrivendo `/leggi random` o leggere una frase specifica scrivendo `/leggi <numero>`. Puoi visualizzare il diario [qui](https://royal.steffo.me/diario.htm), leggere una frase casuale scrivendo `/leggi random` o leggere una frase specifica scrivendo `/leggi <numero>`.
@ -79,7 +125,7 @@ Sintassi: `/leggi <random | numerofrase>`"""
await update.message.reply(bot, "⚠ Sintassi del comando non valida.\n`/leggi <random | numerofrase>`", parse_mode="Markdown") await update.message.reply(bot, "⚠ Sintassi del comando non valida.\n`/leggi <random | numerofrase>`", parse_mode="Markdown")
return return
# Open the file # Open the file
file = open("diario.txt", "r") file = open("diario.txt", "r", encoding="utf8")
# Split the data in lines # Split the data in lines
entries = file.read().split("\n") entries = file.read().split("\n")
file.close() file.close()
@ -89,11 +135,13 @@ Sintassi: `/leggi <random | numerofrase>`"""
entry_number = random.randrange(len(entries)) entry_number = random.randrange(len(entries))
else: else:
# ...or a specific one # ...or a specific one
entry_number = arguments[0] # TODO: check if the entry actually exists
# TODO: check if the first argument is a number
entry_number = int(arguments[0])
# Split the timestamp from the text # Split the timestamp from the text
entry = entries[entry_number].split("|", 1) entry = entries[entry_number].split("|", 1)
# Parse the timestamp # Parse the timestamp
date = datetime.datetime.fromtimestamp(entry[0]).isoformat() date = datetime.datetime.fromtimestamp(int(entry[0])).isoformat()
# Get the text # Get the text
text = entry[1] text = entry[1]
# Sanitize the text to prevent TelegramErrors # Sanitize the text to prevent TelegramErrors
@ -101,7 +149,41 @@ Sintassi: `/leggi <random | numerofrase>`"""
await update.message.reply(bot, f"Frase #{entry_number} | {date}\n{text}", parse_mode="Markdown") await update.message.reply(bot, f"Frase #{entry_number} | {date}\n{text}", parse_mode="Markdown")
async def markov(bot, update, arguments): async def leggi_discord(bot, message, arguments):
"""Leggi una frase dal diario Royal Games.
Puoi visualizzare il diario [qui](https://royal.steffo.me/diario.htm), leggere una frase casuale scrivendo `/leggi random` o leggere una frase specifica scrivendo `/leggi <numero>`.
Sintassi: `!leggi <random | numerofrase>`"""
if len(arguments) == 0 or len(arguments) > 1:
await bot.send_message(message.channel, "⚠ Sintassi del comando non valida.\n`!leggi <random | numerofrase>`")
return
# Open the file
file = open("diario.txt", "r", encoding="utf8")
# Split the data in lines
entries = file.read().split("\n")
file.close()
# Choose an entry
if arguments[0] == "random":
# either randomly...
entry_number = random.randrange(len(entries))
else:
# ...or a specific one
# TODO: check if the entry actually exists
# TODO: check if the first argument is a number
entry_number = int(arguments[0])
# Split the timestamp from the text
entry = entries[entry_number].split("|", 1)
# Parse the timestamp
date = datetime.datetime.fromtimestamp(int(entry[0])).isoformat()
# Get the text
text = entry[1]
# Sanitize the text to prevent TelegramErrors
text = text.replace("_", "\_").replace("*", "\*").replace("`", "\`").replace("[", "\[")
await bot.send_message(message.channel, f"Frase #{entry_number} | {date}\n{text}")
async def markov_telegram(bot, update, arguments):
"""Genera una frase del diario utilizzando le catene di Markov. """Genera una frase del diario utilizzando le catene di Markov.
Puoi specificare con che parole (massimo 2) deve iniziare la frase generata. Puoi specificare con che parole (massimo 2) deve iniziare la frase generata.
@ -139,7 +221,7 @@ Sintassi: `/markov [inizio]`"""
await update.message.reply(bot, f"⚠ Il bot non è riuscito a generare una nuova frase.\nSe è la prima volta che vedi questo errore, riprova, altrimenti prova a cambiare configurazione.") await update.message.reply(bot, f"⚠ Il bot non è riuscito a generare una nuova frase.\nSe è la prima volta che vedi questo errore, riprova, altrimenti prova a cambiare configurazione.")
async def help_cmd(bot, update, arguments): async def help_telegram(bot, update, arguments):
"""Visualizza la descrizione di un comando. """Visualizza la descrizione di un comando.
Sintassi: `/help [comando]`""" Sintassi: `/help [comando]`"""
@ -149,12 +231,27 @@ Sintassi: `/help [comando]`"""
await update.message.reply(bot, "⚠ Sintassi del comando non valida.\n`/help [comando]`", parse_mode="Markdown") await update.message.reply(bot, "⚠ Sintassi del comando non valida.\n`/help [comando]`", parse_mode="Markdown")
else: else:
if arguments[0] in b.commands: if arguments[0] in b.commands:
await update.message.reply(bot, b.commands[arguments[0]].__doc__, parse_mode="Markdown") await update.message.reply(bot, b.commands[arguments[0] + "_telegram"].__doc__, parse_mode="Markdown")
else: else:
await update.message.reply(bot, "⚠ Il comando specificato non esiste.") await update.message.reply(bot, "⚠ Il comando specificato non esiste.")
async def discord(bot, update, arguments): async def help_discord(bot, message, arguments):
"""Visualizza la descrizione di un comando.
Sintassi: `!help [comando]`"""
if len(arguments) == 0:
bot.send_message(message.channel, help.__doc__)
elif len(arguments) > 1:
bot.send_message(message.channel, "⚠ Sintassi del comando non valida.\n`!help [comando]`")
else:
if arguments[0] in b.commands:
bot.send_message(message.channel, b.commands[arguments[0] + "_discord"].__doc__)
else:
bot.send_message(message.channel, "⚠ Il comando specificato non esiste.")
async def discord_telegram(bot, update, arguments):
"""Manda un messaggio a #chat di Discord. """Manda un messaggio a #chat di Discord.
Sintassi: `/discord <messaggio>`""" Sintassi: `/discord <messaggio>`"""
@ -256,7 +353,7 @@ Sintassi: `!sync <username> <password>`"""
await bot.send_message(message.channel, "⚠ Username o password non validi.") await bot.send_message(message.channel, "⚠ Username o password non validi.")
async def changepassword(bot, update, arguments): async def changepassword_telegram(bot, update, arguments):
"""Cambia la tua password del Database Royal Games. """Cambia la tua password del Database Royal Games.
Sintassi: `/changepassword <newpassword>`""" Sintassi: `/changepassword <newpassword>`"""
@ -274,7 +371,7 @@ Sintassi: `/changepassword <newpassword>`"""
await update.message.reply(bot, "⚠ Username o password non validi.", parse_mode="Markdown") await update.message.reply(bot, "⚠ Username o password non validi.", parse_mode="Markdown")
async def cv(bot, update, arguments): async def cv_telegram(bot, update, arguments):
"""Visualizza lo stato attuale della chat vocale Discord. """Visualizza lo stato attuale della chat vocale Discord.
Sintassi: `/cv`""" Sintassi: `/cv`"""
@ -354,7 +451,7 @@ Sintassi: `/cv`"""
await update.message.reply(bot, to_send, parse_mode="Markdown", disable_web_page_preview=1) await update.message.reply(bot, to_send, parse_mode="Markdown", disable_web_page_preview=1)
async def buycoins(bot, update, arguments): async def buycoins_telegram(bot, update, arguments):
"""Compra nuovi ! """Compra nuovi !
Sintassi: /buycoins""" Sintassi: /buycoins"""
@ -392,20 +489,50 @@ Sintassi: /buycoins"""
f"NOTA LEGALE: @Steffo non si assume responsabilità per il contenuto delle app sponsorizzate. Fate attenzione!", parse_mode="Markdown") f"NOTA LEGALE: @Steffo non si assume responsabilità per il contenuto delle app sponsorizzate. Fate attenzione!", parse_mode="Markdown")
async def roll_telegram(bot, update, arguments):
"""Lancia un dado a N facce.
Sintassi: `/roll <max>`"""
# Check the command syntax
if len(arguments) != 1:
await update.message.reply(bot, "⚠ Sintassi del comando non valida.\n`/roll <max>`",
parse_mode="Markdown")
return
# Roll the dice!
await update.message.reply(bot, f"*Numero generato:* {random.randrange(0, int(arguments[0])) + 1}")
async def roll_discord(bot, message, arguments):
"""Lancia un dado a N facce.
Sintassi: `!roll <max>`"""
# Check the command syntax
if len(arguments) != 1:
await bot.send_message(message.channel, "⚠ Sintassi del comando non valida.\n`!roll <max>`")
return
# Roll the dice!
await bot.send_message(message.channel, f"*Numero generato:* {random.randrange(0, int(arguments[0])) + 1}")
if __name__ == "__main__": if __name__ == "__main__":
# Init Telegram bot commands # Init Telegram bot commands
b.commands["start"] = start b.commands["start"] = start_telegram
b.commands["leggi"] = leggi b.commands["leggi"] = leggi_telegram
b.commands["diario"] = diario b.commands["diario"] = diario_telegram
b.commands["discord"] = discord b.commands["discord"] = discord_telegram
b.commands["sync"] = sync_telegram b.commands["sync"] = sync_telegram
b.commands["changepassword"] = changepassword b.commands["changepassword"] = changepassword_telegram
b.commands["help"] = help_cmd b.commands["help"] = help_telegram
b.commands["markov"] = markov b.commands["markov"] = markov_telegram
b.commands["cv"] = cv b.commands["cv"] = cv_telegram
b.commands["buycoins"] = buycoins b.commands["roll"] = roll_telegram
b.commands["buycoins"] = buycoins_telegram
# Init Discord bot commands # Init Discord bot commands
d.commands["sync"] = sync_discord d.commands["sync"] = sync_discord
d.commands["roll"] = roll_discord
d.commands["help"] = help_discord
d.commands["leggi"] = leggi_discord
d.commands["diario"] = diario_discord
# Init Telegram bot # Init Telegram bot
loop.create_task(b.run()) loop.create_task(b.run())
print("Telegram bot start scheduled!") print("Telegram bot start scheduled!")

View file

@ -139,11 +139,13 @@ class Bot:
# Send the request to the Telegram API # Send the request to the Telegram API
token = self.token token = self.token
async with session.request("GET", f"https://api.telegram.org/bot{token}/{endpoint}", params=params) as response: async with session.request("GET", f"https://api.telegram.org/bot{token}/{endpoint}", params=params) as response:
# Check for errors in the request
if response.status != 200:
raise TelegramAPIError(f"Request returned {response.status} {response.reason}\n{response.text()}")
# Parse the json data as soon it's ready # Parse the json data as soon it's ready
data = await response.json() data = await response.json()
# Check for errors in the request
if "description" in data:
error = data["description"]
if response.status != 200:
raise TelegramAPIError(f"Request returned {response.status} {response.reason}")
# Check for errors in the response # Check for errors in the response
if not data["ok"]: if not data["ok"]:
error = data["description"] error = data["description"]
@ -229,7 +231,11 @@ class Chat:
# TODO: This could give problems if a class inherits Bot # TODO: This could give problems if a class inherits Bot
if not isinstance(bot, Bot): if not isinstance(bot, Bot):
raise TypeError("bot is not an instance of Bot.") raise TypeError("bot is not an instance of Bot.")
# Catch TelegramAPI exceptions
try:
await bot.api_request("sendMessage", text=text, chat_id=self.chat_id, **params) await bot.api_request("sendMessage", text=text, chat_id=self.chat_id, **params)
except TelegramAPIError as e:
print(f"[Telegram] sendMessage failed: {e.args[0]}")
class User: class User: