From c1436ffa059d1bae39523687d8d66fc5e0df11fa Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Mon, 30 Oct 2017 10:46:37 +0100 Subject: [PATCH] Risolto il problema delle sessioni! --- db.py | 43 ++++++++++++++++++++++++++++++------------- discordbot.py | 12 ++++++++---- errors.py | 2 +- newuser.py | 35 ++++++++++++++++++----------------- telegrambot.py | 36 ++++++++++++++++++++++++++++++++++++ update.py | 18 +++++++++--------- webserver.py | 18 ++++++++++-------- 7 files changed, 112 insertions(+), 52 deletions(-) create mode 100644 telegrambot.py diff --git a/db.py b/db.py index 5cec329a..f2c0b70d 100644 --- a/db.py +++ b/db.py @@ -8,6 +8,7 @@ from errors import RequestError, NotFoundError, AlreadyExistingError import re import enum from discord import User as DiscordUser +from telegram import User as TelegramUser # Init the config reader import configparser @@ -19,9 +20,6 @@ engine = create_engine(config["Database"]["database_uri"]) Base = declarative_base(bind=engine) Session = sessionmaker(bind=engine) -# Create a new default session -session = Session() - class Royal(Base): __tablename__ = "royals" @@ -29,7 +27,7 @@ class Royal(Base): username = Column(String, unique=True, nullable=False) @staticmethod - def create(username): + def create(session: Session, username: str): r = session.query(Royal).filter_by(username=username).first() if r is not None: raise AlreadyExistingError(repr(r)) @@ -50,6 +48,24 @@ class Telegram(Base): last_name = Column(String) username = Column(String) + @staticmethod + def create(session: Session, royal_username, telegram_user: TelegramUser): + t = session.query(Telegram).filter_by(telegram_id=telegram_user.id).first() + if t is not None: + raise AlreadyExistingError(repr(t)) + r = session.query(Royal).filter(Royal.username == royal_username).first() + if r is None: + raise NotFoundError("No Royal exists with that username") + t = session.query(Telegram).filter(Telegram.royal_id == r.id).first() + if t is not None: + raise AlreadyExistingError(repr(t)) + return Telegram(royal=r, + telegram_id=telegram_user.id, + first_name=telegram_user.first_name, + last_name=telegram_user.last_name, + username=telegram_user.username) + + def __repr__(self): return f"" @@ -86,7 +102,7 @@ class Steam(Base): return f"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/{self.avatar_hex[0:2]}/{self.avatar_hex}.jpg" @staticmethod - def create(royal_id, steam_id): + def create(session: Session, royal_id: int, steam_id: str): s = session.query(Steam).get(steam_id) if s is not None: raise AlreadyExistingError(repr(s)) @@ -160,7 +176,7 @@ class RocketLeague(Base): return f"" @staticmethod - def create(steam_id): + def create(session: Session, steam_id: str): rl = session.query(RocketLeague).get(steam_id) if rl is not None: raise AlreadyExistingError(repr(rl)) @@ -242,7 +258,7 @@ class Dota(Base): losses = Column(Integer, nullable=False) @staticmethod - def create(steam_id): + def create(session: Session, steam_id: int): d = session.query(Dota).get(steam_id) if d is not None: raise AlreadyExistingError(repr(d)) @@ -314,7 +330,7 @@ class LeagueOfLegends(Base): twtr_rank = Column(Enum(RomanNumerals)) @staticmethod - def create(royal_id, summoner_name=None, summoner_id=None): + def create(session: Session, royal_id, summoner_name=None, summoner_id=None): if summoner_name: lol = session.query(LeagueOfLegends).filter(LeagueOfLegends.summoner_name == summoner_name).first() elif summoner_id: @@ -395,7 +411,7 @@ class Osu(Base): mania_pp = Column(Float) @staticmethod - def create(royal_id, osu_name): + def create(session: Session, royal_id, osu_name): o = session.query(Osu).filter(Osu.osu_name == osu_name).first() if o is not None: raise AlreadyExistingError(repr(o)) @@ -456,7 +472,7 @@ class Discord(Base): return f"" @staticmethod - def create(royal_username, discord_user: DiscordUser): + def create(session: Session, royal_username, discord_user: DiscordUser): d = session.query(Discord).filter(Discord.discord_id == discord_user.id).first() if d is not None: raise AlreadyExistingError(repr(d)) @@ -502,7 +518,7 @@ class Overwatch(Base): return f"" @staticmethod - def create(royal_id, battletag, discriminator=None): + def create(session: Session, royal_id, battletag, discriminator=None): if discriminator is None: battletag, discriminator = battletag.split("#", 1) o = session.query(Overwatch).filter_by(battletag=battletag, discriminator=discriminator).first() @@ -565,6 +581,7 @@ class Diario(Base): @staticmethod def import_from_json(file): import json + session = Session() file = open(file, "r") j = json.load(file) for entry in j: @@ -578,9 +595,9 @@ class Diario(Base): print(d) session.add(d) session.commit() + session.close() # If run as script, create all the tables in the db if __name__ == "__main__": - Base.metadata.create_all(bind=engine) - session.close() \ No newline at end of file + Base.metadata.create_all(bind=engine) \ No newline at end of file diff --git a/discordbot.py b/discordbot.py index 40cd9177..d5b93196 100644 --- a/discordbot.py +++ b/discordbot.py @@ -13,6 +13,9 @@ import configparser config = configparser.ConfigParser() config.read("config.ini") +# Open a new postgres session +session = db.Session() + # Init the discord bot client = discord.Client() @@ -25,14 +28,15 @@ async def on_message(message: discord.Message): await client.send_message(message.channel, "⚠️ Non hai specificato un username!") return try: - d = db.Discord.create(royal_username=username, + d = db.Discord.create(session, + royal_username=username, discord_user=message.author) except errors.AlreadyExistingError: await client.send_message(message.channel, "⚠ Il tuo account Discord è già collegato a un account RYG o l'account RYG che hai specificato è già collegato a un account Discord.") return - db.session.add(d) - db.session.commit() + session.add(d) + session.commit() await client.send_message(message.channel, "✅ Sincronizzazione completata!") client.run(config["Discord"]["bot_token"]) -db.session.close() \ No newline at end of file +session.close() \ No newline at end of file diff --git a/errors.py b/errors.py index ef5d5127..022ca7ec 100644 --- a/errors.py +++ b/errors.py @@ -5,4 +5,4 @@ class NotFoundError(Exception): pass class AlreadyExistingError(Exception): - pass \ No newline at end of file + pass diff --git a/newuser.py b/newuser.py index 3c809889..072ec291 100644 --- a/newuser.py +++ b/newuser.py @@ -1,43 +1,44 @@ import db -user = db.Royal.create(input("Nome account: ")) -db.session.add(user) -db.session.commit() +session = db.Session() +user = db.Royal.create(session, input("Nome account: ")) +session.add(user) +session.commit() try: - steam = db.Steam.create(user.id, input("Steam ID 1: ")) + steam = db.Steam.create(session, user.id, input("Steam ID 1: ")) except Exception as e: print(e) else: - db.session.add(steam) + session.add(steam) try: - dota = db.Dota.create(steam.steam_id) + dota = db.Dota.create(session, steam.steam_id) except Exception as e: print(e) else: - db.session.add(dota) + session.add(dota) try: - rl = db.RocketLeague.create(steam.steam_id) + rl = db.RocketLeague.create(session, steam.steam_id) except Exception as e: print(e) else: - db.session.add(rl) + session.add(rl) try: - osu = db.Osu.create(user.id, input("Osu! username: ")) + osu = db.Osu.create(session, user.id, input("Osu! username: ")) except Exception as e: print(e) else: - db.session.add(osu) + session.add(osu) try: - overwatch = db.Overwatch.create(user.id, input("Battle.net battletag: ")) + overwatch = db.Overwatch.create(session, user.id, input("Battle.net battletag: ")) except Exception as e: print(e) else: - db.session.add(overwatch) + session.add(overwatch) try: - lol = db.LeagueOfLegends.create(user.id, input("League summoner name: ")) + lol = db.LeagueOfLegends.create(session, user.id, input("League summoner name: ")) except Exception as e: print(e) else: - db.session.add(lol) -db.session.commit() -db.session.close() \ No newline at end of file + session.add(lol) +session.commit() +session.close() \ No newline at end of file diff --git a/telegrambot.py b/telegrambot.py new file mode 100644 index 00000000..669fcb20 --- /dev/null +++ b/telegrambot.py @@ -0,0 +1,36 @@ +import db +import errors +from telegram import Bot, Update, Message +from telegram.ext import Updater, CommandHandler + +# Init the config reader +import configparser +config = configparser.ConfigParser() +config.read("config.ini") + +def cmd_register(bot: Bot, update: Update): + session = db.Session() + try: + username = update.message.text.split(" ", 1)[1] + except IndexError: + bot.send_message(update.message.chat.id, "⚠️ Non hai specificato un username!") + return + try: + t = db.Telegram.create(session, + royal_username=username, + telegram_user=update.message.from_user) + except errors.AlreadyExistingError: + bot.send_message(update.message.chat.id, "⚠ Il tuo account Telegram è già collegato a un account RYG o l'account RYG che hai specificato è già collegato a un account Telegram.") + return + session.add(t) + session.commit() + bot.send_message(update.message.chat.id, "✅ Sincronizzazione completata!") + session.close() + +u = Updater(config["Telegram"]["bot_token"]) +u.dispatcher.add_handler(CommandHandler("register", cmd_register)) +u.start_polling() +try: + u.idle() +except KeyboardInterrupt: + pass \ No newline at end of file diff --git a/update.py b/update.py index 5c8b8829..51c9c8dd 100644 --- a/update.py +++ b/update.py @@ -2,11 +2,12 @@ import db import errors import time +session = db.Session() # Stop updating if Ctrl-C is pressed try: # Update Steam print("STEAM") - for user in db.session.query(db.Steam).all(): + for user in session.query(db.Steam).all(): t = time.clock() print(f"Updating {user.royal.username}", end="\t\t", flush=True) try: @@ -22,7 +23,7 @@ try: time.sleep(sleep_time if sleep_time > 0 else 0) # Update Rocket League print("ROCKET LEAGUE") - for user in db.session.query(db.RocketLeague).all(): + for user in session.query(db.RocketLeague).all(): t = time.clock() print(f"Updating {user.steam.royal.username}", end="\t\t", flush=True) try: @@ -38,7 +39,7 @@ try: time.sleep(sleep_time if sleep_time > 0 else 0) # Update Dota 2 print("DOTA 2") - for user in db.session.query(db.Dota).all(): + for user in session.query(db.Dota).all(): t = time.clock() print(f"Updating {user.steam.royal.username}", end="\t\t", flush=True) try: @@ -54,7 +55,7 @@ try: time.sleep(sleep_time if sleep_time > 0 else 0) # Update League of Legends print("LEAGUE OF LEGENDS") - for user in db.session.query(db.LeagueOfLegends).all(): + for user in session.query(db.LeagueOfLegends).all(): t = time.clock() print(f"Updating {user.royal.username}", end="\t\t", flush=True) try: @@ -70,7 +71,7 @@ try: time.sleep(sleep_time if sleep_time > 0 else 0) # Update Osu! print("OSU!") - for user in db.session.query(db.Osu).all(): + for user in session.query(db.Osu).all(): t = time.clock() print(f"Updating {user.royal.username}", end="\t\t", flush=True) try: @@ -86,7 +87,7 @@ try: time.sleep(sleep_time if sleep_time > 0 else 0) # Update Overwatch print("OVERWATCH") - for user in db.session.query(db.Overwatch).all(): + for user in session.query(db.Overwatch).all(): t = time.clock() print(f"Updating {user.royal.username}", end="\t\t", flush=True) try: @@ -104,6 +105,5 @@ except KeyboardInterrupt: pass finally: print("Committing...\t\t") - db.session.commit() - print("OK") - db.session.close() \ No newline at end of file + session.commit() + print("OK") \ No newline at end of file diff --git a/webserver.py b/webserver.py index f329a363..5ef1e72c 100644 --- a/webserver.py +++ b/webserver.py @@ -1,5 +1,6 @@ from flask import Flask, render_template -from db import session, Royal, Steam, RocketLeague, Dota, Osu, Overwatch, LeagueOfLegends +from db import Session, Royal, Steam, RocketLeague, Dota, Osu, Overwatch, LeagueOfLegends +from sqlalchemy.orm import joinedload app = Flask(__name__) @@ -8,16 +9,17 @@ app.jinja_env.lstrip_blocks = True @app.route("/leaderboards") def page_leaderboards(): - dota_data = session.query(Dota).join(Steam).join(Royal).all() - rl_data = session.query(RocketLeague).join(Steam).join(Royal).all() - ow_data = session.query(Overwatch).join(Royal).all() - osu_data = session.query(Osu).join(Royal).all() - lol_data = session.query(LeagueOfLegends).join(Royal).all() + session = Session() + dota_data = session.query(Dota).options(joinedload(Dota.steam).joinedload(Steam.royal)).join(Steam).join(Royal).all() + rl_data = session.query(RocketLeague).options(joinedload(RocketLeague.steam).joinedload(Steam.royal)).join(Steam).join(Royal).all() + ow_data = session.query(Overwatch).options(joinedload(Overwatch.royal)).join(Royal).all() + osu_data = session.query(Osu).options(joinedload(Osu.royal)).join(Royal).all() + lol_data = session.query(LeagueOfLegends).options(joinedload(LeagueOfLegends.royal)).join(Royal).all() + session.close() return render_template("leaderboards.html", dota_data=dota_data, rl_data=rl_data, ow_data=ow_data, osu_data=osu_data, lol_data=lol_data) if __name__ == "__main__": try: app.run(host="0.0.0.0", port=1234, debug=True) except KeyboardInterrupt: - pass - session.close() \ No newline at end of file + pass \ No newline at end of file