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

The Fiorygi Update

This commit is contained in:
Steffo 2018-09-05 19:48:34 +02:00
parent 15e94bbd83
commit f63fd1d5dc
12 changed files with 207 additions and 29 deletions

17
bots.py
View file

@ -2,8 +2,8 @@ import multiprocessing
import os import os
import telegrambot import telegrambot
import discordbot import discordbot
import redditbot
import time import time
import platform
import logging import logging
logging.getLogger().setLevel(level=logging.ERROR) logging.getLogger().setLevel(level=logging.ERROR)
@ -12,6 +12,7 @@ logging.getLogger(__name__).setLevel(level=logging.DEBUG)
discord_telegram_pipe = multiprocessing.Pipe() discord_telegram_pipe = multiprocessing.Pipe()
discord = multiprocessing.Process(target=discordbot.process, args=(discord_telegram_pipe[0],), daemon=True) discord = multiprocessing.Process(target=discordbot.process, args=(discord_telegram_pipe[0],), daemon=True)
telegram = multiprocessing.Process(target=telegrambot.process, args=(discord_telegram_pipe[1],), daemon=True) telegram = multiprocessing.Process(target=telegrambot.process, args=(discord_telegram_pipe[1],), daemon=True)
reddit = multiprocessing.Process(target=redditbot.process, daemon=True)
if __name__ == "__main__": if __name__ == "__main__":
logging.info("Starting Discord process...") logging.info("Starting Discord process...")
@ -23,20 +24,24 @@ if __name__ == "__main__":
if discord.exitcode is not None: if discord.exitcode is not None:
logging.warning(f"Discord Bot exited with {discord.exitcode}") logging.warning(f"Discord Bot exited with {discord.exitcode}")
del discord del discord
logging.info("Starting Discord process...") logging.info("Restarting Discord process...")
discord = multiprocessing.Process(target=discordbot.process, args=(discord_telegram_pipe[0],), daemon=True) discord = multiprocessing.Process(target=discordbot.process, args=(discord_telegram_pipe[0],), daemon=True)
discord.start() discord.start()
if telegram.exitcode is not None: if telegram.exitcode is not None:
logging.warning(f"Telegram Bot exited with {discord.exitcode}") logging.warning(f"Telegram Bot exited with {telegram.exitcode}")
del telegram del telegram
telegram = multiprocessing.Process(target=telegrambot.process, args=(discord_telegram_pipe[1],), daemon=True) telegram = multiprocessing.Process(target=telegrambot.process, args=(discord_telegram_pipe[1],), daemon=True)
logging.info("Starting Telegram process...") logging.info("Restarting Telegram process...")
telegram.start()
if reddit.exitcode is not None:
logging.warning(f"Reddit Bot exited with {reddit.exitcode}")
del reddit
reddit = multiprocessing.Process(target=redditbot.process, daemon=True)
logging.info("Restarting Reddit process...")
telegram.start() telegram.start()
time.sleep(10) time.sleep(10)
except KeyboardInterrupt: except KeyboardInterrupt:
logging.info("Now stopping...") logging.info("Now stopping...")
if platform.system() == "Linux":
os.system("reset")
logging.info("Asking Discord process to stop...") logging.info("Asking Discord process to stop...")
discord_telegram_pipe[0].send("stop") discord_telegram_pipe[0].send("stop")
logging.info("Waiting for Discord process to stop...") logging.info("Waiting for Discord process to stop...")

10
cast.py
View file

@ -10,6 +10,12 @@ def cast(spell_name: str, target_name: str, platform: str) -> str:
dmg_dice = random.randrange(1, 11) dmg_dice = random.randrange(1, 11)
dmg_max = random.sample([4, 6, 8, 10, 12, 20, 100], 1)[0] dmg_max = random.sample([4, 6, 8, 10, 12, 20, 100], 1)[0]
dmg_mod = random.randrange(math.floor(-dmg_max / 5), math.ceil(dmg_max / 5) + 1) dmg_mod = random.randrange(math.floor(-dmg_max / 5), math.ceil(dmg_max / 5) + 1)
dmg_type = random.sample(["da fuoco", "da freddo", "elettrici", "sonici", "necrotici", "magici",
"da acido", "divini", "nucleari", "psichici", "fisici", "puri", "da taglio",
"da perforazione", "da impatto", "da caduta", "gelato", "onnipotenti", "oscuri",
"di luce", "da velocità", "da cactus", "meta", "dannosi", "da radiazione",
"tuamammici", "da maledizione", "pesanti", "leggeri", "immaginari", "da laser",
"da neutrini", "galattici", "cerebrali", "ritardati", "ritardanti"], 1)[0]
# Reseed the rng with a random value # Reseed the rng with a random value
# so that the dice roll always deals a different damage # so that the dice roll always deals a different damage
random.seed() random.seed()
@ -39,7 +45,7 @@ def cast(spell_name: str, target_name: str, platform: str) -> str:
f"<i>{target_name}</i> subisce {dmg_dice}d{dmg_max}" \ f"<i>{target_name}</i> subisce {dmg_dice}d{dmg_max}" \
f"{'+' if dmg_mod > 0 else ''}{str(dmg_mod) if dmg_mod != 0 else ''}" \ f"{'+' if dmg_mod > 0 else ''}{str(dmg_mod) if dmg_mod != 0 else ''}" \
f"{'×' + str(crit) if crit > 1 else ''}" \ f"{'×' + str(crit) if crit > 1 else ''}" \
f"=<b>{total if total > 0 else 0}</b> danni!" f"=<b>{total if total > 0 else 0}</b> danni {dmg_type}!"
elif platform == "discord": elif platform == "discord":
return f"❇️ Ho lanciato **{spell}** su " \ return f"❇️ Ho lanciato **{spell}** su " \
f"_{target_name}_.\n" \ f"_{target_name}_.\n" \
@ -47,4 +53,4 @@ def cast(spell_name: str, target_name: str, platform: str) -> str:
f"_{target_name}_ subisce {dmg_dice}d{dmg_max}" \ f"_{target_name}_ subisce {dmg_dice}d{dmg_max}" \
f"{'+' if dmg_mod > 0 else ''}{str(dmg_mod) if dmg_mod != 0 else ''}" \ f"{'+' if dmg_mod > 0 else ''}{str(dmg_mod) if dmg_mod != 0 else ''}" \
f"{'×' + str(crit) if crit > 1 else ''}" \ f"{'×' + str(crit) if crit > 1 else ''}" \
f"=**{total if total > 0 else 0}** danni!" f"=**{total if total > 0 else 0}** danni {dmg_type}!"

7
db.py
View file

@ -799,6 +799,13 @@ class Event(Base):
self.time = datetime.datetime.now() + value self.time = datetime.datetime.now() + value
class ParsedRedditPost(Base):
__tablename__ = "parsedredditposts"
id = Column(String, primary_key=True)
# If run as script, create all the tables in the db # If run as script, create all the tables in the db
if __name__ == "__main__": if __name__ == "__main__":
print("Creating new tables...") print("Creating new tables...")

View file

@ -89,8 +89,8 @@ song_special_messages = {
# noinspection PyUnreachableCode # noinspection PyUnreachableCode
if __debug__: if __debug__:
version = "discord-py-rewrite" version = "Dev"
commit_msg = "_Aggiornamento di Discordbot all'APIv6_" commit_msg = "_in sviluppo_"
else: else:
# Find the latest git tag # Find the latest git tag
old_wd = os.getcwd() old_wd = os.getcwd()
@ -331,6 +331,10 @@ class RoyalDiscordBot(discord.Client):
if data[0] not in self.commands: if data[0] not in self.commands:
await message.channel.send(":warning: Comando non riconosciuto.") await message.channel.send(":warning: Comando non riconosciuto.")
return return
sentry.extra_context({
"command": data[0],
"message": message
})
await self.commands[data[0]](channel=message.channel, await self.commands[data[0]](channel=message.channel,
author=message.author, author=message.author,
params=data) params=data)
@ -430,7 +434,7 @@ class RoyalDiscordBot(discord.Client):
continue continue
await self.main_channel.send(f"{msg}\n" await self.main_channel.send(f"{msg}\n"
f"_(da Telegram)_") f"_(da Telegram)_")
await self.commands[data[0]](channel=self.get_channel(config["Discord"]["main_channel"]), await self.commands[data[0]](channel=self.main_channel,
author=None, author=None,
params=data) params=data)
connection.send("success") connection.send("success")

87
redditbot.py Normal file
View file

@ -0,0 +1,87 @@
import praw
import configparser
import db
import logging
import telegram
import time
import raven
import os
import subprocess
import sys
# Init the config reader
config = configparser.ConfigParser()
config.read("config.ini")
logging.getLogger().setLevel(level=logging.ERROR)
logger = logging.getLogger(__name__)
logger.setLevel(level=logging.DEBUG)
# noinspection PyUnreachableCode
if __debug__:
version = "Dev"
commit_msg = "_in sviluppo_"
else:
# Find the latest git tag
old_wd = os.getcwd()
try:
os.chdir(os.path.dirname(__file__))
version = str(subprocess.check_output(["git", "describe", "--tags"]), encoding="utf8").strip()
commit_msg = str(subprocess.check_output(["git", "log", "-1", "--pretty=%B"]), encoding="utf8").strip()
except Exception:
version = ""
finally:
os.chdir(old_wd)
sentry = raven.Client(config["Sentry"]["token"],
release=version,
install_logger_hook=False,
hook_libraries=[])
def process():
logger.info("Retrieving parsed posts...")
session = db.Session()
results = session.query(db.ParsedRedditPost).all()
parsed_post_ids = [x.id for x in results]
session.close()
logger.info("Posts retrieved successfully.")
logger.info("Logging in to reddit...")
reddit = praw.Reddit(client_id=config["reddit"]["client_id"],
client_secret=config["reddit"]["client_secret"],
password=config["reddit"]["password"],
user_agent='Royal-Bot/4.1',
username=config["reddit"]["username"])
logger.info(f"Login as {reddit.user.me()} successful!")
logger.info(f"Logging in to Telegram...")
telegram_bot = telegram.Bot(config["Telegram"]["bot_token"])
logger.info(f"Login successful.")
r_royalgames = reddit.subreddit("royalgames")
for submission in r_royalgames.stream.submissions():
try:
if submission.id not in parsed_post_ids:
logger.info(f"New post found: {submission.id}")
logger.debug(f"Creating new db session...")
session = db.Session()
new_post = db.ParsedRedditPost(id=submission.id)
session.add(new_post)
logger.debug(f"Committing...")
session.commit()
session.close()
logger.debug("Sending Telegram notification...")
while True:
try:
telegram_bot.send_message(config["Telegram"]["main_group"],
f'Nuovo post su r/RoyalGames:\n'
f'<a href="https://reddit.com{submission.permalink}">{submission.title}</a>\n'
f'da u/{submission.author}',
parse_mode="HTML", disable_notification=True)
except telegram.error.TimedOut:
time.sleep(1)
else:
break
except Exception:
sentry.captureException(exc_info=sys.exc_info())

View file

@ -1,4 +1,4 @@
discord.py==1.0.0a1504+gf06563c discord.py[rewrite]
python-telegram-bot python-telegram-bot
flask flask
sqlalchemy sqlalchemy
@ -12,3 +12,4 @@ bcrypt
markdown2 markdown2
pygments pygments
markovify markovify
praw

View file

@ -1 +1,45 @@
listona = ["della secca", "del seccatore", "del secchiello", "del secchio", "del secchione", "del secondino", "del sedano", "del sedativo", "della sedia", "del sedicente", "del sedile", "della sega", "del segale", "della segatura", "della seggiola", "del seggiolino", "della seggiovia", "della segheria", "del seghetto", "del segnalibro", "del segnaposto", "del segno", "del segretario", "della segreteria", "del seguace", "del segugio", "della selce", "della sella", "della selz", "della selva", "della selvaggina", "del semaforo", "del seme", "del semifreddo", "del seminario", "della seminarista", "della semola", "del semolino", "del semplicione", "della senape", "del senatore", "del seno", "del sensore", "della sentenza", "della sentinella", "del sentore", "della seppia", "del sequestratore", "della serenata", "del sergente", "del sermone", "della serpe", "del serpente", "della serpentina", "della serra", "del serraglio", "del serramanico", "della serranda", "della serratura", "del servitore", "della servitù", "del servizievole", "del servo", "del set", "della seta", "della setola", "del sidecar", "del siderurgico", "del sidro", "della siepe", "del sifone", "della sigaretta", "del sigaro", "del sigillo", "della signora", "della signorina", "del silenziatore", "della silhouette", "del silicio", "del silicone", "del siluro", "della sinagoga", "della sindacalista", "del sindacato", "del sindaco", "della sindrome", "della sinfonia", "del sipario", "del sire", "della sirena", "della siringa", "del sismografo", "del sobborgo", "del sobillatore", "del sobrio", "del soccorritore", "del socio", "del sociologo", "della soda", "del sofà", "della soffitta", "del software", "dello sogghignare", "del soggiorno", "della sogliola", "del sognatore", "della soia", "del solaio", "del solco", "del soldato", "del soldo", "del sole", "della soletta", "della solista", "del solitario", "del sollazzare", "del sollazzo", "del sollecito", "del solleone", "del solletico", "del sollevare", "del sollievo", "del solstizio", "del solubile", "del solvente", "della soluzione", "del somaro", "del sombrero", "del sommergibile", "del sommo", "della sommossa", "del sommozzatore", "del sonar", "della sonda", "del sondaggio", "del sondare", "del sonnacchioso", "del sonnambulo", "del sonnellino", "del sonnifero", "del sonno", "della sonnolenza", "del sontuoso", "del soppalco", "del soprabito", "del sopracciglio", "del sopraffare", "del sopraffino", "del sopraluogo", "del sopramobile", "del soprannome", "del soprano", "del soprappensiero", "del soprassalto", "del soprassedere", "del sopravvento", "del sopravvivere", "del soqquadro", "del sorbetto", "del sordido", "della sordina", "del sordo", "della sorella", "della sorgente", "del sornione", "del sorpasso", "della sorpresa", "del sorreggere", "del sorridere", "della sorsata", "del sorteggio", "del sortilegio", "del sorvegliante", "del sorvolare", "del sosia", "del sospettoso", "del sospirare", "della sosta", "della sostanza", "del sostegno", "del sostenitore", "del sostituto", "del sottaceto", "della sottana", "del sotterfugio", "del sotterraneo", "del sottile", "del sottilizzare", "del sottintendere", "del sottobanco", "del sottobosco", "del sottomarino", "del sottopassaggio", "del sottoposto", "del sottoscala", "della sottoscrizione", "del sottostare", "del sottosuolo", "del sottotetto", "del sottotitolo", "del sottovalutare", "del sottovaso", "della sottoveste", "del sottovuoto", "del sottufficiale", "della soubrette", "del souvenir", "del soverchiare", "del sovrano", "del sovrapprezzo", "della sovvenzione", "del sovversivo", "del sozzo", "dello suadente", "del sub", "del subalterno", "del subbuglio", "del subdolo", "del sublime", "del suburbano", "del successore", "del succo", "della succube", "del succulento", "della succursale", "del sudario", "della sudditanza", "del suddito", "del sudicio", "del suffisso", "del suffragio", "del suffumigio", "del suggeritore", "del sughero", "del sugo", "del suino", "della suite", "del sulfureo", "del sultano", "di Steffo", "di Spaggia", "di Sabrina", "del sas", "del ses", "del sis", "del sos", "del sus", "della supremazia", "del Santissimo", "della scatola", "del supercalifragilistichespiralidoso", "del sale", "del salame", "di (Town of) Salem", "di Stronghold", "di SOMA", "dei Saints", "di S.T.A.L.K.E.R.", "di Sanctum", "dei Sims", "di Sid", "delle Skullgirls", "di Sonic", "di Spiral (Knights)", "di Spore", "di Starbound", "di SimCity", "di Sensei", "di Ssssssssssssss... Boom! E' esploso il dizionario", "della scala"] listona = ["della secca", "del seccatore", "del secchiello", "del secchio", "del secchione", "del secondino",
"del sedano", "del sedativo", "della sedia", "del sedicente", "del sedile", "della sega", "del segale",
"della segatura", "della seggiola", "del seggiolino", "della seggiovia", "della segheria", "del seghetto",
"del segnalibro", "del segnaposto", "del segno", "del segretario", "della segreteria", "del seguace",
"del segugio", "della selce", "della sella", "della selz", "della selva", "della selvaggina", "del semaforo",
"del seme", "del semifreddo", "del seminario", "della seminarista", "della semola", "del semolino",
"del semplicione", "della senape", "del senatore", "del seno", "del sensore", "della sentenza",
"della sentinella", "del sentore", "della seppia", "del sequestratore", "della serenata", "del sergente",
"del sermone", "della serpe", "del serpente", "della serpentina", "della serra", "del serraglio",
"del serramanico", "della serranda", "della serratura", "del servitore", "della servitù", "del servizievole",
"del servo", "del set", "della seta", "della setola", "del sidecar", "del siderurgico", "del sidro",
"della siepe", "del sifone", "della sigaretta", "del sigaro", "del sigillo", "della signora",
"della signorina", "del silenziatore", "della silhouette", "del silicio", "del silicone", "del siluro",
"della sinagoga", "della sindacalista", "del sindacato", "del sindaco", "della sindrome", "della sinfonia",
"del sipario", "del sire", "della sirena", "della siringa", "del sismografo", "del sobborgo",
"del sobillatore", "del sobrio", "del soccorritore", "del socio", "del sociologo", "della soda", "del sofà",
"della soffitta", "del software", "dello sogghignare", "del soggiorno", "della sogliola", "del sognatore",
"della soia", "del solaio", "del solco", "del soldato", "del soldo", "del sole", "della soletta",
"della solista", "del solitario", "del sollazzare", "del sollazzo", "del sollecito", "del solleone",
"del solletico", "del sollevare", "del sollievo", "del solstizio", "del solubile", "del solvente",
"della soluzione", "del somaro", "del sombrero", "del sommergibile", "del sommo", "della sommossa",
"del sommozzatore", "del sonar", "della sonda", "del sondaggio", "del sondare", "del sonnacchioso",
"del sonnambulo", "del sonnellino", "del sonnifero", "del sonno", "della sonnolenza", "del sontuoso",
"del soppalco", "del soprabito", "del sopracciglio", "del sopraffare", "del sopraffino", "del sopraluogo",
"del sopramobile", "del soprannome", "del soprano", "del soprappensiero", "del soprassalto",
"del soprassedere", "del sopravvento", "del sopravvivere", "del soqquadro", "del sorbetto", "del sordido",
"della sordina", "del sordo", "della sorella", "della sorgente", "del sornione", "del sorpasso",
"della sorpresa", "del sorreggere", "del sorridere", "della sorsata", "del sorteggio", "del sortilegio",
"del sorvegliante", "del sorvolare", "del sosia", "del sospettoso", "del sospirare", "della sosta",
"della sostanza", "del sostegno", "del sostenitore", "del sostituto", "del sottaceto", "della sottana",
"del sotterfugio", "del sotterraneo", "del sottile", "del sottilizzare", "del sottintendere",
"del sottobanco", "del sottobosco", "del sottomarino", "del sottopassaggio", "del sottoposto",
"del sottoscala", "della sottoscrizione", "del sottostare", "del sottosuolo", "del sottotetto",
"del sottotitolo", "del sottovalutare", "del sottovaso", "della sottoveste", "del sottovuoto",
"del sottufficiale", "della soubrette", "del souvenir", "del soverchiare", "del sovrano", "del sovrapprezzo",
"della sovvenzione", "del sovversivo", "del sozzo", "dello suadente", "del sub", "del subalterno",
"del subbuglio", "del subdolo", "del sublime", "del suburbano", "del successore", "del succo",
"della succube", "del succulento", "della succursale", "del sudario", "della sudditanza", "del suddito",
"del sudicio", "del suffisso", "del suffragio", "del suffumigio", "del suggeritore", "del sughero",
"del sugo", "del suino", "della suite", "del sulfureo", "del sultano", "di Steffo", "di Spaggia",
"di Sabrina", "del sas", "del ses", "del sis", "del sos", "del sus", "della supremazia", "del Santissimo",
"della scatola", "del supercalifragilistichespiralidoso", "del sale", "del salame", "di (Town of) Salem",
"di Stronghold", "di SOMA", "dei Saints", "di S.T.A.L.K.E.R.", "di Sanctum", "dei Sims", "di Sid",
"delle Skullgirls", "di Sonic", "di Spiral (Knights)", "di Spore", "di Starbound", "di SimCity", "di Sensei",
"di Ssssssssssssss... Boom! E' esploso il dizionario", "della scala"]

View file

@ -1,12 +1,9 @@
[Database] [Database]
database_uri = database_uri = postgres://
[Steam] [Steam]
api_key = api_key =
[Rocket League]
rlstats_api_key =
[League of Legends] [League of Legends]
riot_api_key = riot_api_key =
@ -18,20 +15,25 @@ bot_token =
server_id = server_id =
main_channel = main_channel =
afk_timer = 10 afk_timer = 10
invite_link = radio_messages_every = 5
[Telegram] [Telegram]
bot_token = bot_token =
main_group = main_group =
invite_link =
[YouTube] [YouTube]
username =
password =
max_duration = 7200 max_duration = 7200
predownload_videos = 5
download_timeout = 30
[Sentry] [Sentry]
token = token =
[Flask] [Flask]
secret_key = secret_key =
[reddit]
client_id =
client_secret =
username =
password =

View file

@ -19,4 +19,7 @@
<input id="input-password" name="password" type="password"> <input id="input-password" name="password" type="password">
<input type="submit" value="Login"> <input type="submit" value="Login">
</form> </form>
<p>
Se ti sei dimenticato la password, chiedi a Steffo di resettarla!
</p>
{% endblock %} {% endblock %}

View file

@ -1,7 +1,7 @@
<div class="game-panel"> <div class="game-panel">
<div class="game-grid ryg"> <div class="game-grid ryg">
<div class="player"> <div class="player">
<span class="player-name">{{ record.username }}</span> <span class="player-name"><a href="https://ryg.steffo.eu/profile/{{ record.username }}">{{ record.username }}</a></span>
</div> </div>
<div class="member-status"> <div class="member-status">
<span class="role">{{ record.role }}</span> dal <span class="member-since">{% if record.member_since %}{{ record.member_since }}{% else %}????-??-??{% endif %}</span> <span class="role">{{ record.role }}</span> dal <span class="member-since">{% if record.member_since %}{{ record.member_since }}{% else %}????-??-??{% endif %}</span>

View file

@ -7,6 +7,8 @@ import markdown2
import datetime import datetime
import telegram import telegram
import query_discord_music import query_discord_music
import random
import difflib
app = Flask(__name__) app = Flask(__name__)
@ -139,6 +141,7 @@ def page_password():
user = db_session.query(db.Royal).filter_by(id=user_id).one() user = db_session.query(db.Royal).filter_by(id=user_id).one()
if user.password is None: if user.password is None:
user.password = bcrypt.hashpw(bytes(new_password, encoding="utf8"), bcrypt.gensalt()) user.password = bcrypt.hashpw(bytes(new_password, encoding="utf8"), bcrypt.gensalt())
user.fiorygi += 1
db_session.commit() db_session.commit()
db_session.close() db_session.close()
return redirect(url_for("page_main")) return redirect(url_for("page_main"))
@ -234,12 +237,26 @@ def page_wiki(key: str):
if user_id is None: if user_id is None:
db_session.close() db_session.close()
return redirect(url_for("page_login")) return redirect(url_for("page_login"))
new_content = request.form.get("content")
# Create new page
if wiki_page is None: if wiki_page is None:
wiki_page = db.WikiEntry(key=key, content=request.form.get("content")) difference = len(new_content)
wiki_page = db.WikiEntry(key=key, content=new_content)
db_session.add(wiki_page) db_session.add(wiki_page)
db_session.flush() db_session.flush()
# Edit existing page
else: else:
wiki_page.content = request.form.get("content") difference = len(new_content) - len(wiki_page.content)
wiki_page.content = new_content
# Award fiorygi
if difference > 50:
fioryg_chance = -(5000/difference) + 100
fioryg_roll = random.randrange(0, 100)
if fioryg_roll > fioryg_chance:
user.fiorygi += 1
else:
fioryg_chance = -1
fioryg_roll = -2
edit_reason = request.form.get("reason") edit_reason = request.form.get("reason")
new_log = db.WikiLog(editor=user, edited_key=key, timestamp=datetime.datetime.now(), reason=edit_reason) new_log = db.WikiLog(editor=user, edited_key=key, timestamp=datetime.datetime.now(), reason=edit_reason)
db_session.add(new_log) db_session.add(new_log)
@ -248,8 +265,10 @@ def page_wiki(key: str):
telegram_bot.send_message(config["Telegram"]["main_group"], telegram_bot.send_message(config["Telegram"]["main_group"],
f' La pagina wiki <a href="https://ryg.steffo.eu/wiki/{key}">{key}</a> è stata' f' La pagina wiki <a href="https://ryg.steffo.eu/wiki/{key}">{key}</a> è stata'
f' modificata da' f' modificata da'
f' <a href="https://ryg.steffo.eu/profile/{user.username}">{user.username}</a>:' f' <a href="https://ryg.steffo.eu/profile/{user.username}">{user.username}</a>'
f' {"<i>Nessun motivo specificato.</i>" if not edit_reason else edit_reason}\n', f' {"(" + edit_reason + ")" if edit_reason else ""}'
f' [{"+" if difference > 0}{difference}]\n'
f' {"<b>" + user.username + " è stato premiato con 1 fioryg!</b>" if fioryg_roll > fioryg_chance else ""}',
parse_mode="HTML", disable_web_page_preview=True, disable_notification=True) parse_mode="HTML", disable_web_page_preview=True, disable_notification=True)
except Exception: except Exception:
pass pass