mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-27 13:34:28 +00:00
Megaupdate
This commit is contained in:
parent
2e0b2f498a
commit
a646761c9a
12 changed files with 214 additions and 185 deletions
35
bots.py
35
bots.py
|
@ -1,8 +1,8 @@
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
import os
|
|
||||||
import telegrambot
|
import telegrambot
|
||||||
import discordbot
|
import discordbot
|
||||||
import redditbot
|
import redditbot
|
||||||
|
import statsupdater
|
||||||
import time
|
import time
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
@ -13,38 +13,53 @@ 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)
|
reddit = multiprocessing.Process(target=redditbot.process, daemon=True)
|
||||||
|
stats = multiprocessing.Process(target=statsupdater.process, daemon=True)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
logging.info("Starting Discord process...")
|
logging.info("Starting Discord Bot process...")
|
||||||
discord.start()
|
discord.start()
|
||||||
logging.info("Starting Telegram process...")
|
logging.info("Starting Telegram Bot process...")
|
||||||
telegram.start()
|
telegram.start()
|
||||||
logging.info("Starting Reddit process...")
|
logging.info("Starting Reddit Bot process...")
|
||||||
reddit.start()
|
reddit.start()
|
||||||
|
logging.info("Starting StatsUpdater process...")
|
||||||
|
stats.start()
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
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("Restarting Discord process...")
|
logging.info("Restarting Discord Bot 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 {telegram.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("Restarting Telegram process...")
|
logging.info("Restarting Telegram Bot process...")
|
||||||
telegram.start()
|
telegram.start()
|
||||||
if reddit.exitcode is not None:
|
if reddit.exitcode is not None:
|
||||||
logging.warning(f"Reddit Bot exited with {reddit.exitcode}")
|
logging.warning(f"Reddit Bot exited with {reddit.exitcode}")
|
||||||
del reddit
|
del reddit
|
||||||
reddit = multiprocessing.Process(target=redditbot.process, daemon=True)
|
reddit = multiprocessing.Process(target=redditbot.process, daemon=True)
|
||||||
logging.info("Restarting Reddit process...")
|
logging.info("Restarting Reddit Bot process...")
|
||||||
telegram.start()
|
reddit.start()
|
||||||
|
if stats.exitcode is not None:
|
||||||
|
logging.warning(f"StatsUpdater exited with {stats.exitcode}")
|
||||||
|
del stats
|
||||||
|
stats = multiprocessing.Process(target=statsupdater.process, daemon=True)
|
||||||
|
logging.info("Restarting StatsUpdater process...")
|
||||||
|
stats.start()
|
||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
logging.info("Now stopping...")
|
logging.info("Now stopping...")
|
||||||
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 Bot process to stop...")
|
||||||
time.sleep(30)
|
discord.join()
|
||||||
|
logging.info("Waiting for Telegram Bot process to stop...")
|
||||||
|
telegram.join()
|
||||||
|
logging.info("Waiting for Reddit Bot process to stop...")
|
||||||
|
reddit.join()
|
||||||
|
logging.info("Waiting for StatsUpdater process to stop...")
|
||||||
|
stats.join()
|
||||||
|
|
23
cast.py
23
cast.py
|
@ -1,6 +1,5 @@
|
||||||
import random
|
import random
|
||||||
import math
|
import math
|
||||||
import dice
|
|
||||||
|
|
||||||
|
|
||||||
def cast(spell_name: str, target_name: str, platform: str) -> str:
|
def cast(spell_name: str, target_name: str, platform: str) -> str:
|
||||||
|
@ -40,6 +39,17 @@ def cast(spell_name: str, target_name: str, platform: str) -> str:
|
||||||
else:
|
else:
|
||||||
crit_msg = ""
|
crit_msg = ""
|
||||||
if platform == "telegram":
|
if platform == "telegram":
|
||||||
|
if dmg_dice == 10 and dmg_max == 100 and dmg_mod == 20:
|
||||||
|
return f"❇️‼️ Ho lanciato <b>{spell}</b> su " \
|
||||||
|
f"<i>{target_name}</i>.\n" \
|
||||||
|
f"Una grande luce illumina il cielo, seguita poco dopo da un fungo di fumo nel luogo" \
|
||||||
|
f" in cui si trovava <i>{target_name}</i>.\n" \
|
||||||
|
f"Il fungo si espande a velocità smodata, finchè il fumo non ricopre la Terra intera e le tenebre" \
|
||||||
|
f" cadono su di essa.\n" \
|
||||||
|
f"Dopo qualche minuto, la temperatura ambiente raggiunge gli 0 °C, e continua a diminuire.\n" \
|
||||||
|
f"L'Apocalisse Nucleare è giunta, e tutto per polverizzare <i>{target_name}</i>" \
|
||||||
|
f" con <b>{spell}</b>.\n" \
|
||||||
|
f"<i>{target_name}</i> subisce 10d100+20=<b>1020</b> danni apocalittici!"
|
||||||
return f"❇️ Ho lanciato <b>{spell}</b> su " \
|
return f"❇️ Ho lanciato <b>{spell}</b> su " \
|
||||||
f"<i>{target_name}</i>.\n" \
|
f"<i>{target_name}</i>.\n" \
|
||||||
f"{crit_msg}" \
|
f"{crit_msg}" \
|
||||||
|
@ -48,6 +58,17 @@ def cast(spell_name: str, target_name: str, platform: str) -> str:
|
||||||
f"{'×' + str(crit) if crit > 1 else ''}" \
|
f"{'×' + str(crit) if crit > 1 else ''}" \
|
||||||
f"=<b>{total if total > 0 else 0}</b> danni {dmg_type}!"
|
f"=<b>{total if total > 0 else 0}</b> danni {dmg_type}!"
|
||||||
elif platform == "discord":
|
elif platform == "discord":
|
||||||
|
if dmg_dice == 10 and dmg_max == 100 and dmg_mod == 20:
|
||||||
|
return f"❇️‼️ Ho lanciato **{spell}** su " \
|
||||||
|
f"_{target_name}_.\n" \
|
||||||
|
f"Una grande luce illumina il cielo, seguita poco dopo da un fungo di fumo nel luogo" \
|
||||||
|
f" in cui si trovava _{target_name}_.\n" \
|
||||||
|
f"Il fungo si espande a velocità smodata, finchè il fumo non ricopre la Terra intera e le tenebre" \
|
||||||
|
f" cadono su di essa.\n" \
|
||||||
|
f"Dopo qualche minuto, la temperatura ambiente raggiunge gli 0 °C, e continua a diminuire.\n" \
|
||||||
|
f"L'Apocalisse Nucleare è giunta, e tutto per polverizzare _{target_name}_" \
|
||||||
|
f" con **{spell}**.\n" \
|
||||||
|
f"_{target_name}_ subisce 10d100+20=**1020** danni apocalittici!"
|
||||||
return f"❇️ Ho lanciato **{spell}** su " \
|
return f"❇️ Ho lanciato **{spell}** su " \
|
||||||
f"_{target_name}_.\n" \
|
f"_{target_name}_.\n" \
|
||||||
f"{crit_msg}" \
|
f"{crit_msg}" \
|
||||||
|
|
73
db.py
73
db.py
|
@ -39,7 +39,7 @@ class Royal(Base):
|
||||||
return Royal(username=username)
|
return Royal(username=username)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<Royal {self.username}>"
|
return f"<db.Royal {self.username}>"
|
||||||
|
|
||||||
|
|
||||||
class Telegram(Base):
|
class Telegram(Base):
|
||||||
|
@ -71,7 +71,7 @@ class Telegram(Base):
|
||||||
username=telegram_user.username)
|
username=telegram_user.username)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<Telegram {self.telegram_id}>"
|
return f"<db.Telegram {self.telegram_id}>"
|
||||||
|
|
||||||
def mention(self):
|
def mention(self):
|
||||||
if self.username is not None:
|
if self.username is not None:
|
||||||
|
@ -101,7 +101,9 @@ class Steam(Base):
|
||||||
most_played_game_id = Column(BigInteger)
|
most_played_game_id = Column(BigInteger)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<Steam {self.steam_id}>"
|
if not self.persona_name:
|
||||||
|
return f"<db.Steam {self.steam_id}>"
|
||||||
|
return f"<db.Steam {self.persona_name}>"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.persona_name is not None:
|
if self.persona_name is not None:
|
||||||
|
@ -196,7 +198,7 @@ class RocketLeague(Base):
|
||||||
wins = Column(Integer)
|
wins = Column(Integer)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<RocketLeague {self.steam_id}>"
|
return f"<db.RocketLeague {self.steam_id}>"
|
||||||
|
|
||||||
def update(self, data=None):
|
def update(self, data=None):
|
||||||
raise NotImplementedError("rlstats API is no longer available.")
|
raise NotImplementedError("rlstats API is no longer available.")
|
||||||
|
@ -243,6 +245,9 @@ class Dota(Base):
|
||||||
|
|
||||||
most_played_hero = Column(Integer)
|
most_played_hero = Column(Integer)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<db.Dota {self.steam_id}>"
|
||||||
|
|
||||||
def get_rank_icon_url(self):
|
def get_rank_icon_url(self):
|
||||||
# Rank icon is determined by the first digit of the rank tier
|
# Rank icon is determined by the first digit of the rank tier
|
||||||
return f"https://www.opendota.com/assets/images/dota2/rank_icons/rank_icon_{str(self.rank_tier)[0] if self.rank_tier is not None else '0'}.png"
|
return f"https://www.opendota.com/assets/images/dota2/rank_icons/rank_icon_{str(self.rank_tier)[0] if self.rank_tier is not None else '0'}.png"
|
||||||
|
@ -293,7 +298,7 @@ class Dota(Base):
|
||||||
new_record.update()
|
new_record.update()
|
||||||
return new_record
|
return new_record
|
||||||
|
|
||||||
def update(self) -> None:
|
def update(self) -> bool:
|
||||||
r = requests.get(f"https://api.opendota.com/api/players/{Steam.to_steam_id_3(self.steam_id)}")
|
r = requests.get(f"https://api.opendota.com/api/players/{Steam.to_steam_id_3(self.steam_id)}")
|
||||||
if r.status_code != 200:
|
if r.status_code != 200:
|
||||||
raise RequestError("OpenDota / returned {r.status_code}")
|
raise RequestError("OpenDota / returned {r.status_code}")
|
||||||
|
@ -306,10 +311,12 @@ class Dota(Base):
|
||||||
if r.status_code != 200:
|
if r.status_code != 200:
|
||||||
raise RequestError("OpenDota /heroes returned {r.status_code}")
|
raise RequestError("OpenDota /heroes returned {r.status_code}")
|
||||||
heroes = r.json()
|
heroes = r.json()
|
||||||
|
changed = self.rank_tier != data["rank_tier"]
|
||||||
self.rank_tier = data["rank_tier"]
|
self.rank_tier = data["rank_tier"]
|
||||||
self.wins = wl["win"]
|
self.wins = wl["win"]
|
||||||
self.losses = wl["lose"]
|
self.losses = wl["lose"]
|
||||||
self.most_played_hero = heroes[0]["hero_id"]
|
self.most_played_hero = heroes[0]["hero_id"]
|
||||||
|
return changed
|
||||||
|
|
||||||
|
|
||||||
class LeagueOfLegendsRanks(enum.Enum):
|
class LeagueOfLegendsRanks(enum.Enum):
|
||||||
|
@ -349,6 +356,11 @@ class LeagueOfLegends(Base):
|
||||||
|
|
||||||
highest_mastery_champ = Column(Integer)
|
highest_mastery_champ = Column(Integer)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
if not self.summoner_name:
|
||||||
|
return f"<LeagueOfLegends {self.summoner_id}>"
|
||||||
|
return f"<LeagueOfLegends {(''.join([x if x.isalnum else '' for x in self.summoner_name]))}>"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create(session: Session, royal_id, summoner_name=None, summoner_id=None):
|
def create(session: Session, royal_id, summoner_name=None, summoner_id=None):
|
||||||
if summoner_name:
|
if summoner_name:
|
||||||
|
@ -374,18 +386,18 @@ class LeagueOfLegends(Base):
|
||||||
lol.update()
|
lol.update()
|
||||||
return lol
|
return lol
|
||||||
|
|
||||||
def update(self):
|
def update(self) -> bool:
|
||||||
r = requests.get(f"https://euw1.api.riotgames.com/lol/summoner/v3/summoners/{self.summoner_id}?api_key={config['League of Legends']['riot_api_key']}")
|
r = requests.get(f"https://euw1.api.riotgames.com/lol/summoner/v3/summoners/{self.summoner_id}?api_key={config['League of Legends']['riot_api_key']}")
|
||||||
if r.status_code != 200:
|
if r.status_code != 200:
|
||||||
return RequestError(f"League of Legends API /summoner returned {r.status_code}")
|
raise RequestError(f"League of Legends API /summoner returned {r.status_code}")
|
||||||
data = r.json()
|
data = r.json()
|
||||||
r = requests.get(f"https://euw1.api.riotgames.com/lol/league/v3/positions/by-summoner/{self.summoner_id}?api_key={config['League of Legends']['riot_api_key']}")
|
r = requests.get(f"https://euw1.api.riotgames.com/lol/league/v3/positions/by-summoner/{self.summoner_id}?api_key={config['League of Legends']['riot_api_key']}")
|
||||||
if r.status_code != 200:
|
if r.status_code != 200:
|
||||||
return RequestError(f"League of Legends API /league returned {r.status_code}")
|
raise RequestError(f"League of Legends API /league returned {r.status_code}")
|
||||||
rank = r.json()
|
rank = r.json()
|
||||||
r = requests.get(f"https://euw1.api.riotgames.com/lol/champion-mastery/v3/champion-masteries/by-summoner/{self.summoner_id}?api_key={config['League of Legends']['riot_api_key']}")
|
r = requests.get(f"https://euw1.api.riotgames.com/lol/champion-mastery/v3/champion-masteries/by-summoner/{self.summoner_id}?api_key={config['League of Legends']['riot_api_key']}")
|
||||||
if r.status_code != 200:
|
if r.status_code != 200:
|
||||||
return RequestError(f"League of Legends API /champion-mastery returned {r.status_code}")
|
raise RequestError(f"League of Legends API /champion-mastery returned {r.status_code}")
|
||||||
mastery = r.json()
|
mastery = r.json()
|
||||||
solo_rank = None
|
solo_rank = None
|
||||||
flex_rank = None
|
flex_rank = None
|
||||||
|
@ -477,6 +489,11 @@ class Osu(Base):
|
||||||
self.catch_pp = j2["pp_raw"]
|
self.catch_pp = j2["pp_raw"]
|
||||||
self.mania_pp = j3["pp_raw"]
|
self.mania_pp = j3["pp_raw"]
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
if not self.osu_name:
|
||||||
|
return f"<db.Osu {self.osu_id}>"
|
||||||
|
return f"<db.Osu {self.osu_name}>"
|
||||||
|
|
||||||
|
|
||||||
class Discord(Base):
|
class Discord(Base):
|
||||||
__tablename__ = "discord"
|
__tablename__ = "discord"
|
||||||
|
@ -494,7 +511,7 @@ class Discord(Base):
|
||||||
return f"{self.name}#{self.discriminator}"
|
return f"{self.name}#{self.discriminator}"
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<Discord user {self.discord_id}>"
|
return f"<db.Discord {self.discord_id}>"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create(session: Session, royal_username, discord_user: DiscordUser):
|
def create(session: Session, royal_username, discord_user: DiscordUser):
|
||||||
|
@ -542,7 +559,7 @@ class Overwatch(Base):
|
||||||
return f"{self.battletag}{separator}{self.discriminator}"
|
return f"{self.battletag}{separator}{self.discriminator}"
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<Overwatch {self}>"
|
return f"<db.Overwatch {self}>"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create(session: Session, royal_id, battletag, discriminator=None):
|
def create(session: Session, royal_id, battletag, discriminator=None):
|
||||||
|
@ -614,7 +631,7 @@ class Diario(Base):
|
||||||
text = Column(String)
|
text = Column(String)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<Diario {self.id}>"
|
return f"<db.Diario {self.id}>"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.id} - {self.timestamp} - {self.author}: {self.text}"
|
return f"{self.id} - {self.timestamp} - {self.author}: {self.text}"
|
||||||
|
@ -668,7 +685,7 @@ class BaluRage(Base):
|
||||||
reason = Column(String)
|
reason = Column(String)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<BaluRage {self.id}>"
|
return f"<db.BaluRage {self.id}>"
|
||||||
|
|
||||||
|
|
||||||
class PlayedMusic(Base):
|
class PlayedMusic(Base):
|
||||||
|
@ -681,7 +698,7 @@ class PlayedMusic(Base):
|
||||||
timestamp = Column(DateTime, nullable=False)
|
timestamp = Column(DateTime, nullable=False)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<PlayedMusic {self.filename}>"
|
return f"<db.PlayedMusic {self.filename}>"
|
||||||
|
|
||||||
|
|
||||||
class VoteQuestion(Base):
|
class VoteQuestion(Base):
|
||||||
|
@ -694,7 +711,7 @@ class VoteQuestion(Base):
|
||||||
open = Column(Boolean, default=True)
|
open = Column(Boolean, default=True)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<Vote {self.id}>"
|
return f"<db.Vote {self.id}>"
|
||||||
|
|
||||||
def generate_text(self, session: Session):
|
def generate_text(self, session: Session):
|
||||||
text = f"<b>{self.question}</b>\n\n"
|
text = f"<b>{self.question}</b>\n\n"
|
||||||
|
@ -746,7 +763,7 @@ class VoteAnswer(Base):
|
||||||
__table_args__ = (PrimaryKeyConstraint("question_id", "user_id"),)
|
__table_args__ = (PrimaryKeyConstraint("question_id", "user_id"),)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<VoteAnswer {self.question_id} {self.user} {self.choice}>"
|
return f"<db.VoteAnswer {self.question_id} {self.user} {self.choice}>"
|
||||||
|
|
||||||
|
|
||||||
class ProfileData(Base):
|
class ProfileData(Base):
|
||||||
|
@ -758,6 +775,9 @@ class ProfileData(Base):
|
||||||
css = Column(Text)
|
css = Column(Text)
|
||||||
bio = Column(Text)
|
bio = Column(Text)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<ProfileData for {self.royal.username}>"
|
||||||
|
|
||||||
|
|
||||||
class WikiEntry(Base):
|
class WikiEntry(Base):
|
||||||
__tablename__ = "wikientries"
|
__tablename__ = "wikientries"
|
||||||
|
@ -765,6 +785,9 @@ class WikiEntry(Base):
|
||||||
key = Column(String, primary_key=True)
|
key = Column(String, primary_key=True)
|
||||||
content = Column(Text, nullable=False)
|
content = Column(Text, nullable=False)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<WikiEntry {self.key}>"
|
||||||
|
|
||||||
|
|
||||||
class WikiLog(Base):
|
class WikiLog(Base):
|
||||||
__tablename__ = "wikilog"
|
__tablename__ = "wikilog"
|
||||||
|
@ -777,6 +800,9 @@ class WikiLog(Base):
|
||||||
timestamp = Column(DateTime, nullable=False)
|
timestamp = Column(DateTime, nullable=False)
|
||||||
reason = Column(Text)
|
reason = Column(Text)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<WikiLog {self.edit_id}>"
|
||||||
|
|
||||||
|
|
||||||
class Event(Base):
|
class Event(Base):
|
||||||
__tablename__ = "events"
|
__tablename__ = "events"
|
||||||
|
@ -798,6 +824,9 @@ class Event(Base):
|
||||||
raise TypeError("time_left should be a datetime.timedelta")
|
raise TypeError("time_left should be a datetime.timedelta")
|
||||||
self.time = datetime.datetime.now() + value
|
self.time = datetime.datetime.now() + value
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<Event {self.name}>"
|
||||||
|
|
||||||
|
|
||||||
class Reddit(Base):
|
class Reddit(Base):
|
||||||
__tablename__ = "reddit"
|
__tablename__ = "reddit"
|
||||||
|
@ -808,6 +837,9 @@ class Reddit(Base):
|
||||||
username = Column(String, primary_key=True)
|
username = Column(String, primary_key=True)
|
||||||
karma = Column(BigInteger)
|
karma = Column(BigInteger)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<Reddit u/{self.username}>"
|
||||||
|
|
||||||
|
|
||||||
class GameLog(Base):
|
class GameLog(Base):
|
||||||
__tablename__ = "gamelog"
|
__tablename__ = "gamelog"
|
||||||
|
@ -822,6 +854,9 @@ class GameLog(Base):
|
||||||
completed_games = Column(Integer)
|
completed_games = Column(Integer)
|
||||||
mastered_games = Column(Integer)
|
mastered_games = Column(Integer)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<GameLog {self.username}>"
|
||||||
|
|
||||||
|
|
||||||
class ParsedRedditPost(Base):
|
class ParsedRedditPost(Base):
|
||||||
__tablename__ = "parsedredditposts"
|
__tablename__ = "parsedredditposts"
|
||||||
|
@ -830,6 +865,9 @@ class ParsedRedditPost(Base):
|
||||||
|
|
||||||
author_username = Column(String)
|
author_username = Column(String)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<ParsedRedditPost {self.id}>"
|
||||||
|
|
||||||
|
|
||||||
class LoginToken(Base):
|
class LoginToken(Base):
|
||||||
__tablename__ = "logintoken"
|
__tablename__ = "logintoken"
|
||||||
|
@ -840,6 +878,9 @@ class LoginToken(Base):
|
||||||
token = Column(String, primary_key=True)
|
token = Column(String, primary_key=True)
|
||||||
expiration = Column(DateTime, nullable=False)
|
expiration = Column(DateTime, nullable=False)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<LoginToken for {self.royal.username}>"
|
||||||
|
|
||||||
|
|
||||||
# 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__":
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
# noinspection PyPackageRequirements
|
|
||||||
import discord
|
import discord
|
||||||
# noinspection PyPackageRequirements
|
|
||||||
import discord.opus
|
import discord.opus
|
||||||
# noinspection PyPackageRequirements
|
|
||||||
import discord.voice_client
|
import discord.voice_client
|
||||||
import functools
|
import functools
|
||||||
import sys
|
import sys
|
||||||
|
@ -15,7 +12,6 @@ import typing
|
||||||
import os
|
import os
|
||||||
import asyncio
|
import asyncio
|
||||||
import configparser
|
import configparser
|
||||||
import subprocess
|
|
||||||
import async_timeout
|
import async_timeout
|
||||||
import raven
|
import raven
|
||||||
import logging
|
import logging
|
||||||
|
@ -25,6 +21,7 @@ import sqlalchemy.exc
|
||||||
|
|
||||||
logging.getLogger().setLevel(level=logging.ERROR)
|
logging.getLogger().setLevel(level=logging.ERROR)
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
logger.addHandler(logging.StreamHandler())
|
||||||
logger.setLevel(level=logging.DEBUG)
|
logger.setLevel(level=logging.DEBUG)
|
||||||
|
|
||||||
# Queue emojis
|
# Queue emojis
|
||||||
|
@ -194,6 +191,7 @@ def command(func):
|
||||||
result = await func(self, channel=channel, author=author, params=params, *args, **kwargs)
|
result = await func(self, channel=channel, author=author, params=params, *args, **kwargs)
|
||||||
except Exception:
|
except Exception:
|
||||||
ei = sys.exc_info()
|
ei = sys.exc_info()
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
await channel.send(f"☢ **ERRORE DURANTE L'ESECUZIONE DEL COMANDO {params[0]}**\n"
|
await channel.send(f"☢ **ERRORE DURANTE L'ESECUZIONE DEL COMANDO {params[0]}**\n"
|
||||||
f"Il comando è stato ignorato.\n"
|
f"Il comando è stato ignorato.\n"
|
||||||
|
@ -283,7 +281,7 @@ class RoyalDiscordBot(discord.Client):
|
||||||
self.inactivity_timer = 0
|
self.inactivity_timer = 0
|
||||||
asyncio.ensure_future(self.queue_predownload_videos())
|
asyncio.ensure_future(self.queue_predownload_videos())
|
||||||
asyncio.ensure_future(self.queue_play_next_video())
|
asyncio.ensure_future(self.queue_play_next_video())
|
||||||
asyncio.ensure_future(self.inactivity_timer())
|
asyncio.ensure_future(self.inactivity_countdown())
|
||||||
|
|
||||||
async def on_ready(self):
|
async def on_ready(self):
|
||||||
# Get the main channel
|
# Get the main channel
|
||||||
|
@ -461,7 +459,7 @@ class RoyalDiscordBot(discord.Client):
|
||||||
while True:
|
while True:
|
||||||
# Fun things will happen with multiple voice clients!
|
# Fun things will happen with multiple voice clients!
|
||||||
for voice_client in self.voice_clients:
|
for voice_client in self.voice_clients:
|
||||||
if not voice_client.is_connected() or not voice_client.is_done():
|
if not voice_client.is_connected() or not voice_client.is_playing():
|
||||||
continue
|
continue
|
||||||
if len(self.video_queue) == 0:
|
if len(self.video_queue) == 0:
|
||||||
self.now_playing = None
|
self.now_playing = None
|
||||||
|
@ -508,8 +506,8 @@ class RoyalDiscordBot(discord.Client):
|
||||||
continue
|
continue
|
||||||
for voice_client in self.voice_clients:
|
for voice_client in self.voice_clients:
|
||||||
if voice_client.is_connected():
|
if voice_client.is_connected():
|
||||||
voice_client.disconnect()
|
await voice_client.disconnect()
|
||||||
self.send_message(self.main_channel, "💤 Mi sono disconnesso dalla cv per inattività.")
|
await self.main_channel.send("💤 Mi sono disconnesso dalla cv per inattività.")
|
||||||
|
|
||||||
async def add_video_from_url(self, url, index: typing.Optional[int] = None, enqueuer: discord.Member = None):
|
async def add_video_from_url(self, url, index: typing.Optional[int] = None, enqueuer: discord.Member = None):
|
||||||
# Retrieve info
|
# Retrieve info
|
||||||
|
@ -816,12 +814,9 @@ def process(users_connection=None):
|
||||||
logger.info("Logging in...")
|
logger.info("Logging in...")
|
||||||
loop.run_until_complete(bot.login(config["Discord"]["bot_token"], bot=True))
|
loop.run_until_complete(bot.login(config["Discord"]["bot_token"], bot=True))
|
||||||
logger.info("Connecting...")
|
logger.info("Connecting...")
|
||||||
try:
|
|
||||||
loop.run_until_complete(bot.connect())
|
loop.run_until_complete(bot.connect())
|
||||||
except KeyboardInterrupt:
|
|
||||||
logger.info("Now stopping...")
|
logger.info("Now stopping...")
|
||||||
loop.run_until_complete(bot.logout())
|
loop.run_until_complete(bot.logout())
|
||||||
exit(0)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
class RequestError(Exception):
|
class RequestError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class NotFoundError(Exception):
|
class NotFoundError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class AlreadyExistingError(Exception):
|
class AlreadyExistingError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -6,7 +6,6 @@ import telegram
|
||||||
import time
|
import time
|
||||||
import raven
|
import raven
|
||||||
import os
|
import os
|
||||||
import subprocess
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
# Init the config reader
|
# Init the config reader
|
||||||
|
@ -15,6 +14,7 @@ config.read("config.ini")
|
||||||
|
|
||||||
logging.getLogger().setLevel(level=logging.ERROR)
|
logging.getLogger().setLevel(level=logging.ERROR)
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
logger.addHandler(logging.StreamHandler())
|
||||||
logger.setLevel(level=logging.DEBUG)
|
logger.setLevel(level=logging.DEBUG)
|
||||||
|
|
||||||
sentry = raven.Client(config["Sentry"]["token"],
|
sentry = raven.Client(config["Sentry"]["token"],
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
discord.py[rewrite]
|
|
||||||
python-telegram-bot
|
python-telegram-bot
|
||||||
flask
|
flask
|
||||||
sqlalchemy
|
sqlalchemy
|
||||||
|
|
|
@ -42,4 +42,4 @@ listona = ["della secca", "del seccatore", "del secchiello", "del secchio", "del
|
||||||
"della scatola", "del supercalifragilistichespiralidoso", "del sale", "del salame", "di (Town of) Salem",
|
"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",
|
"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",
|
"delle Skullgirls", "di Sonic", "di Spiral (Knights)", "di Spore", "di Starbound", "di SimCity", "di Sensei",
|
||||||
"di Ssssssssssssss... Boom! E' esploso il dizionario", "della scala"]
|
"di Ssssssssssssss... Boom! E' esploso il dizionario", "della scala", "di Sakura"]
|
||||||
|
|
88
statsupdater.py
Normal file
88
statsupdater.py
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
import db
|
||||||
|
import time
|
||||||
|
import logging
|
||||||
|
import raven
|
||||||
|
import configparser
|
||||||
|
import os
|
||||||
|
import typing
|
||||||
|
import telegram
|
||||||
|
import sys
|
||||||
|
|
||||||
|
logging.getLogger().setLevel(level=logging.ERROR)
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
logger.addHandler(logging.StreamHandler())
|
||||||
|
logger.setLevel(level=logging.DEBUG)
|
||||||
|
|
||||||
|
# Init the config reader
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read("config.ini")
|
||||||
|
|
||||||
|
# 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=[])
|
||||||
|
|
||||||
|
telegram_bot = telegram.Bot(config["Telegram"]["bot_token"])
|
||||||
|
|
||||||
|
|
||||||
|
def update_block(block: list, delay: float=0, change_callback: typing.Callable=None):
|
||||||
|
for item in block:
|
||||||
|
logger.debug(f"Updating {repr(item)}.")
|
||||||
|
t = time.clock()
|
||||||
|
try:
|
||||||
|
change = item.update()
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error {sys.exc_info()} while updating {repr(item)}.")
|
||||||
|
sentry.extra_context({
|
||||||
|
"item": repr(item)
|
||||||
|
})
|
||||||
|
sentry.captureException()
|
||||||
|
continue
|
||||||
|
if change:
|
||||||
|
change_callback(item)
|
||||||
|
sleep_time = delay - time.clock() + t
|
||||||
|
time.sleep(sleep_time if sleep_time > 0 else 0)
|
||||||
|
|
||||||
|
|
||||||
|
def new_dota_rank(item: db.Dota):
|
||||||
|
try:
|
||||||
|
telegram_bot.send_message(config["Telegram"]["main_group"],
|
||||||
|
f"✳️ {item.steam.royal.username} è salito a"
|
||||||
|
f" {item.get_rank_name()} {item.get_rank_number()} su Dota 2!")
|
||||||
|
except Exception:
|
||||||
|
logger.warning(f"Couldn't notify on Telegram: {item}")
|
||||||
|
|
||||||
|
|
||||||
|
def new_lol_rank(item: db.LeagueOfLegends):
|
||||||
|
try:
|
||||||
|
telegram_bot.send_message(config["Telegram"]["main_group"],
|
||||||
|
f"✳️ {item.royal.username} è salito di rank su League of Legends!")
|
||||||
|
except Exception:
|
||||||
|
logger.warning(f"Couldn't notify on Telegram: {item}")
|
||||||
|
|
||||||
|
|
||||||
|
def process():
|
||||||
|
while True:
|
||||||
|
session = db.Session()
|
||||||
|
#logger.info("Now updating Steam data.")
|
||||||
|
#update_block(session.query(db.Steam).all())
|
||||||
|
#session.commit()
|
||||||
|
#logger.info("Now updating Dota data.")
|
||||||
|
#update_block(session.query(db.Dota).all(), delay=1, change_callback=new_dota_rank)
|
||||||
|
#session.commit()
|
||||||
|
#logger.info("Now updating League of Legends data.")
|
||||||
|
#update_block(session.query(db.LeagueOfLegends).all(), delay=0.3, change_callback=new_lol_rank)
|
||||||
|
#session.commit()
|
||||||
|
#logger.info("Now updating osu! data.")
|
||||||
|
#update_block(session.query(db.Osu).all(), delay=0.3)
|
||||||
|
#session.commit()
|
||||||
|
logger.info("Now updating Overwatch data.")
|
||||||
|
update_block(session.query(db.Overwatch).all(), delay=1)
|
||||||
|
session.commit()
|
||||||
|
logger.info("Pausing for 30 minutes.")
|
||||||
|
time.sleep(1800)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
process()
|
|
@ -27,6 +27,7 @@ except Exception:
|
||||||
|
|
||||||
logging.getLogger().setLevel(level=logging.ERROR)
|
logging.getLogger().setLevel(level=logging.ERROR)
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
logger.addHandler(logging.StreamHandler())
|
||||||
logger.setLevel(level=logging.DEBUG)
|
logger.setLevel(level=logging.DEBUG)
|
||||||
|
|
||||||
# Init the config reader
|
# Init the config reader
|
||||||
|
@ -605,18 +606,9 @@ def process(arg_discord_connection):
|
||||||
u.dispatcher.add_handler(CommandHandler("exception", cmd_exception))
|
u.dispatcher.add_handler(CommandHandler("exception", cmd_exception))
|
||||||
u.dispatcher.add_handler(CallbackQueryHandler(on_callback_query))
|
u.dispatcher.add_handler(CallbackQueryHandler(on_callback_query))
|
||||||
logger.info("Handlers registered.")
|
logger.info("Handlers registered.")
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
u.start_polling()
|
u.start_polling()
|
||||||
logger.info("Polling started.")
|
logger.info("Polling started.")
|
||||||
u.idle()
|
u.idle()
|
||||||
except telegram.error.TimedOut:
|
|
||||||
logger.warning("Timed out, restarting in 1 minute.")
|
|
||||||
time.sleep(60)
|
|
||||||
logger.info("Now restarting...")
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
logger.info("Now stopping...")
|
|
||||||
break
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
126
update.py
126
update.py
|
@ -1,126 +0,0 @@
|
||||||
import db
|
|
||||||
import errors
|
|
||||||
import time
|
|
||||||
|
|
||||||
session = None
|
|
||||||
# Stop updating if Ctrl-C is pressed
|
|
||||||
try:
|
|
||||||
while True:
|
|
||||||
session = db.Session()
|
|
||||||
# Update Steam
|
|
||||||
print("STEAM")
|
|
||||||
for user in session.query(db.Steam).all():
|
|
||||||
t = time.clock()
|
|
||||||
print(f"Updating {user.royal.username}", end="\t\t", flush=True)
|
|
||||||
try:
|
|
||||||
user.update()
|
|
||||||
except errors.RequestError:
|
|
||||||
print("Request Error")
|
|
||||||
except errors.NotFoundError:
|
|
||||||
print("Not Found Error (?)")
|
|
||||||
else:
|
|
||||||
print("OK")
|
|
||||||
finally:
|
|
||||||
sleep_time = 1 - time.clock() + t
|
|
||||||
time.sleep(sleep_time if sleep_time > 0 else 0)
|
|
||||||
# Update Rocket League
|
|
||||||
# print("ROCKET LEAGUE")
|
|
||||||
# for user in session.query(db.RocketLeague).all():
|
|
||||||
# t = time.clock()
|
|
||||||
# print(f"Updating {user.steam.royal.username}", end="\t\t", flush=True)
|
|
||||||
# try:
|
|
||||||
# user.update()
|
|
||||||
# except errors.RequestError:
|
|
||||||
# print("Request Error")
|
|
||||||
# except errors.NotFoundError:
|
|
||||||
# print("Not Found Error (?)")
|
|
||||||
# else:
|
|
||||||
# print("OK")
|
|
||||||
# finally:
|
|
||||||
# sleep_time = 1 - time.clock() + t
|
|
||||||
# time.sleep(sleep_time if sleep_time > 0 else 0)
|
|
||||||
# Update Dota 2
|
|
||||||
print("DOTA 2")
|
|
||||||
for user in session.query(db.Dota).all():
|
|
||||||
t = time.clock()
|
|
||||||
print(f"Updating {user.steam.royal.username}", end="\t\t", flush=True)
|
|
||||||
try:
|
|
||||||
user.update()
|
|
||||||
except errors.RequestError:
|
|
||||||
print("Request Error")
|
|
||||||
except errors.NotFoundError:
|
|
||||||
print("Not Found Error (?)")
|
|
||||||
else:
|
|
||||||
print("OK")
|
|
||||||
finally:
|
|
||||||
sleep_time = 1 - time.clock() + t
|
|
||||||
time.sleep(sleep_time if sleep_time > 0 else 0)
|
|
||||||
# Update League of Legends
|
|
||||||
print("LEAGUE OF LEGENDS")
|
|
||||||
for user in session.query(db.LeagueOfLegends).all():
|
|
||||||
t = time.clock()
|
|
||||||
print(f"Updating {user.royal.username}", end="\t\t", flush=True)
|
|
||||||
try:
|
|
||||||
user.update()
|
|
||||||
except errors.RequestError:
|
|
||||||
print("Request Error")
|
|
||||||
except errors.NotFoundError:
|
|
||||||
print("Not Found Error (?)")
|
|
||||||
else:
|
|
||||||
print("OK")
|
|
||||||
finally:
|
|
||||||
sleep_time = 1 - time.clock() + t
|
|
||||||
time.sleep(sleep_time if sleep_time > 0 else 0)
|
|
||||||
# Update Osu!
|
|
||||||
print("OSU!")
|
|
||||||
for user in session.query(db.Osu).all():
|
|
||||||
t = time.clock()
|
|
||||||
print(f"Updating {user.royal.username}", end="\t\t", flush=True)
|
|
||||||
try:
|
|
||||||
user.update()
|
|
||||||
except errors.RequestError:
|
|
||||||
print("Request Error")
|
|
||||||
except errors.NotFoundError:
|
|
||||||
print("Not Found Error (?)")
|
|
||||||
else:
|
|
||||||
print("OK")
|
|
||||||
finally:
|
|
||||||
sleep_time = 1 - time.clock() + t
|
|
||||||
time.sleep(sleep_time if sleep_time > 0 else 0)
|
|
||||||
# Update Overwatch
|
|
||||||
print("OVERWATCH")
|
|
||||||
for user in session.query(db.Overwatch).all():
|
|
||||||
t = time.clock()
|
|
||||||
print(f"Updating {user.royal.username}", end="\t\t", flush=True)
|
|
||||||
try:
|
|
||||||
user.update()
|
|
||||||
except errors.RequestError:
|
|
||||||
print("Request Error")
|
|
||||||
except errors.NotFoundError:
|
|
||||||
print("Not Found Error (?)")
|
|
||||||
else:
|
|
||||||
print("OK")
|
|
||||||
finally:
|
|
||||||
sleep_time = 1 - time.clock() + t
|
|
||||||
time.sleep(sleep_time if sleep_time > 0 else 0)
|
|
||||||
print("Committing...", end="\t\t")
|
|
||||||
session.commit()
|
|
||||||
print("OK")
|
|
||||||
print("Closing...", end="\n\n")
|
|
||||||
session.close()
|
|
||||||
print("OK")
|
|
||||||
print("Waiting 1800s...", end="\t\t")
|
|
||||||
for i in range(0, 20):
|
|
||||||
time.sleep(90)
|
|
||||||
print("█", end="")
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
pass
|
|
||||||
finally:
|
|
||||||
print("Committing...", end="\t\t")
|
|
||||||
session.commit()
|
|
||||||
print("OK")
|
|
||||||
print("Closing...")
|
|
||||||
try:
|
|
||||||
session.close()
|
|
||||||
except Exception:
|
|
||||||
print("Maybe")
|
|
|
@ -88,6 +88,7 @@ def page_profile(name: str):
|
||||||
ow = db_session.query(db.Overwatch).filter_by(royal=user).one_or_none()
|
ow = db_session.query(db.Overwatch).filter_by(royal=user).one_or_none()
|
||||||
tg = db_session.query(db.Telegram).filter_by(royal=user).one_or_none()
|
tg = db_session.query(db.Telegram).filter_by(royal=user).one_or_none()
|
||||||
discord = db_session.execute(query_discord_music.one_query, {"royal": user.id}).fetchone()
|
discord = db_session.execute(query_discord_music.one_query, {"royal": user.id}).fetchone()
|
||||||
|
gamelog = db_session.query(db.GameLog).filter_by(royal=user).one_or_none()
|
||||||
db_session.close()
|
db_session.close()
|
||||||
if css is not None:
|
if css is not None:
|
||||||
converted_bio = Markup(markdown2.markdown(css.bio.replace("<", "<"),
|
converted_bio = Markup(markdown2.markdown(css.bio.replace("<", "<"),
|
||||||
|
@ -95,7 +96,7 @@ def page_profile(name: str):
|
||||||
else:
|
else:
|
||||||
converted_bio = ""
|
converted_bio = ""
|
||||||
return render_template("profile.html", ryg=user, css=css, osu=osu, dota=dota, lol=lol, steam=steam, ow=ow,
|
return render_template("profile.html", ryg=user, css=css, osu=osu, dota=dota, lol=lol, steam=steam, ow=ow,
|
||||||
tg=tg, discord=discord, rygconf=config, bio=converted_bio)
|
tg=tg, discord=discord, rygconf=config, bio=converted_bio, gamelog=gamelog)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/login")
|
@app.route("/login")
|
||||||
|
@ -205,7 +206,8 @@ def page_game(name: str):
|
||||||
query = db_session.query(db.Dota).join(db.Steam).order_by(db.Dota.rank_tier.desc().nullslast()).all()
|
query = db_session.query(db.Dota).join(db.Steam).order_by(db.Dota.rank_tier.desc().nullslast()).all()
|
||||||
elif name == "lol":
|
elif name == "lol":
|
||||||
game_name = "League of Legends"
|
game_name = "League of Legends"
|
||||||
query = db_session.query(db.LeagueOfLegends).order_by(db.LeagueOfLegends.solo_division.desc().nullslast()).all()
|
query = db_session.query(db.LeagueOfLegends).order_by(db.LeagueOfLegends.solo_division.desc().nullslast(),
|
||||||
|
db.LeagueOfLegends.solo_rank).all()
|
||||||
elif name == "osu":
|
elif name == "osu":
|
||||||
game_name = "osu!"
|
game_name = "osu!"
|
||||||
query = db_session.query(db.Osu).order_by(db.Osu.mania_pp.desc().nullslast()).all()
|
query = db_session.query(db.Osu).order_by(db.Osu.mania_pp.desc().nullslast()).all()
|
||||||
|
|
Loading…
Reference in a new issue