diff --git a/db.py b/db.py index 3243cd88..4465a896 100644 --- a/db.py +++ b/db.py @@ -1,7 +1,7 @@ import time from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker, relationship -from sqlalchemy import Column, BigInteger, Integer, String, Numeric, DateTime, ForeignKey, Float, Enum, create_engine +from sqlalchemy import Column, BigInteger, Integer, String, Numeric, DateTime, ForeignKey, Float, Enum, create_engine, UniqueConstraint import requests from errors import RequestError, NotFoundError import re @@ -27,6 +27,13 @@ class Royal(Base): id = Column(Integer, primary_key=True) username = Column(String, unique=True, nullable=False) + @staticmethod + def get_or_create(username): + r = session.query(Royal).filter_by(username=username).first() + if r is not None: + return r + return Royal(username=username) + def __repr__(self): return f"" @@ -61,8 +68,8 @@ class Steam(Base): royal = relationship("Royal") steam_id = Column(String, primary_key=True) - persona_name = Column(String) - avatar_hex = Column(String) + persona_name = Column(String, nullable=False) + avatar_hex = Column(String, nullable=False) trade_token = Column(String) def __repr__(self): @@ -88,12 +95,12 @@ class Steam(Base): s = Steam(royal_id=royal_id, steam_id=steam_id, persona_name=j["response"]["players"][0]["personaname"], - avatar_hex=re.search("https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/../(.+).jpg", j["response"]["players"][0]["avatar"]).group(1)) + avatar_hex=re.search(r"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/../(.+).jpg", j["response"]["players"][0]["avatar"]).group(1)) return s @staticmethod def find_trade_token(trade_url): - return re.search("https://steamcommunity\.com/tradeoffer/new/\?partner=[0-9]+&token=(.{8})", trade_url).group(1) + return re.search(r"https://steamcommunity\.com/tradeoffer/new/\?partner=[0-9]+&token=(.{8})", trade_url).group(1) @staticmethod def to_steam_id_2(steam_id): @@ -116,7 +123,7 @@ class Steam(Base): raise RequestError(f"Steam returned {r.status_code}") j = r.json() self.persona_name = j["response"]["players"][0]["personaname"] - self.avatar_hex = re.search("https://steamcdn-a\.akamaihd\.net/steamcommunity/public/images/avatars/../(.+).jpg", j["response"]["players"][0]["avatar"]).group(1) + self.avatar_hex = re.search(r"https://steamcdn-a\.akamaihd\.net/steamcommunity/public/images/avatars/../(.+).jpg", j["response"]["players"][0]["avatar"]).group(1) class RocketLeague(Base): @@ -227,8 +234,8 @@ class Dota(Base): solo_mmr = Column(Integer) party_mmr = Column(Integer) - wins = Column(Integer) - losses = Column(Integer) + wins = Column(Integer, nullable=False) + losses = Column(Integer, nullable=False) @staticmethod def get_or_create(steam_id): @@ -292,7 +299,7 @@ class LeagueOfLegends(Base): royal = relationship("Royal") summoner_id = Column(BigInteger, primary_key=True) - summoner_name = Column(String) + summoner_name = Column(String, nullable=False) level = Column(Integer, nullable=False) solo_division = Column(Enum(LeagueOfLegendsRanks)) @@ -372,11 +379,11 @@ class LeagueOfLegends(Base): class Osu(Base): __tablename__ = "osu" - royal_id = Column(Integer, ForeignKey("royals.id")) + royal_id = Column(Integer, ForeignKey("royals.id"), nullable=False) royal = relationship("Royal") osu_id = Column(Integer, primary_key=True) - osu_name = Column(String) + osu_name = Column(String, nullable=False) std_pp = Column(Float) taiko_pp = Column(Float) @@ -385,7 +392,7 @@ class Osu(Base): @staticmethod def get_or_create(royal_id, osu_name): - o = session.query(Osu).filter(Osu.royal_id == royal_id).first() + o = session.query(Osu).filter(Osu.osu_name == osu_name).first() if o is not None: return o r0 = requests.get(f"https://osu.ppy.sh/api/get_user?k={config['Osu!']['ppy_api_key']}&u={osu_name}&m=0") @@ -426,6 +433,92 @@ class Osu(Base): self.mania_pp = j3["pp_raw"] +class Discord(Base): + __tablename__ = "discord" + __table_args__ = tuple(UniqueConstraint("name", "discriminator")) + + royal_id = Column(Integer, ForeignKey("royals.id"), nullable=False) + royal = relationship("Royal") + + discord_id = Column(BigInteger, primary_key=True) + name = Column(String, nullable=False) + discriminator = Column(Integer, nullable=False) + avatar_hex = Column(String) + + def __str__(self): + return f"{self.username}#{self.discriminator}" + + def __repr__(self): + return f"" + + def mention(self): + return f"<@{self.id}>" + + def avatar_url(self, size=256): + if self.avatar_hex is None: + return "https://discordapp.com/assets/6debd47ed13483642cf09e832ed0bc1b.png" + return f"https://cdn.discordapp.com/avatars/{self.id}/{self.avatar}.png?size={size}" + + +class Overwatch(Base): + __tablename__ = "overwatch" + + royal_id = Column(Integer, ForeignKey("royals.id"), nullable=False) + royal = relationship("Royal") + + battletag = Column(String, primary_key=True) + discriminator = Column(Integer, primary_key=True) + icon = Column(String, nullable=False) + + level = Column(Integer, nullable=False) + rank = Column(Integer) + + def __str__(self, separator="#"): + return f"{self.battletag}{separator}{self.discriminator}" + + def __repr__(self): + return f"" + + @staticmethod + def get_or_create(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() + if o is not None: + return o + r = requests.get(f"https://owapi.net/api/v3/u/{battletag}-{discriminator}/stats", headers={ + "User-Agent": "Royal-Bot/4.0", + "From": "ste.pigozzi@gmail.com" + }) + if r.status_code != 200: + raise RequestError(f"OWAPI.net returned {r.status_code}") + try: + j = r.json()["eu"]["stats"]["quickplay"]["overall_stats"] + except TypeError: + raise RequestError("Something went wrong when retrieving the stats.") + o = Overwatch(royal_id=royal_id, + battletag=battletag, + discriminator=discriminator, + icon=re.search(r"https://.+\.cloudfront\.net/game/unlocks/(0x[0-9A-F]+)\.png", j["avatar"]).group(1), + level=j["prestige"] * 100 + j["level"], + rank=j["comprank"]) + return o + + def update(self): + r = requests.get(f"https://owapi.net/api/v3/u/{self.battletag}-{self.discriminator}/stats", headers={ + "User-Agent": "Royal-Bot/4.0", + "From": "ste.pigozzi@gmail.com" + }) + if r.status_code != 200: + raise RequestError(f"OWAPI.net returned {r.status_code}") + try: + j = r.json()["eu"]["stats"]["quickplay"]["overall_stats"] + except TypeError: + raise RequestError("Something went wrong when retrieving the stats.") + self.icon = re.search(r"https://.+\.cloudfront\.net/game/unlocks/(0x[0-9A-F]+)\.png", j["avatar"]).group(1) + self.level = j["prestige"] * 100 + j["level"] + self.rank = j["comprank"] + # If run as script, create all the tables in the db if __name__ == "__main__": - Base.metadata.create_all(bind=engine) + Base.metadata.create_all(bind=engine) \ No newline at end of file diff --git a/flaskserver.py b/flaskserver.py deleted file mode 100644 index 3ed520b7..00000000 --- a/flaskserver.py +++ /dev/null @@ -1,23 +0,0 @@ -import db -from flask import Flask, render_template - -app = Flask(__name__) - -@app.route("/ladder") -def page_dota_ladder(): - session = db.Session() - dota = session.execute("SELECT royals.username, dota.solo_mmr, dota.party_mmr, dota.wins FROM royals JOIN steam ON royals.id = steam.royal_id JOIN dota ON steam.steam_id = dota.steam_id ORDER BY dota.solo_mmr DESC;") - rl = session.execute("SELECT royals.username, " - "rocketleague.single_rank, rocketleague.single_div, rocketleague.single_mmr, " - "rocketleague.doubles_rank, rocketleague.doubles_div, rocketleague.doubles_mmr, " - "rocketleague.standard_rank, rocketleague.standard_div, rocketleague.standard_mmr, " - "rocketleague.solo_std_rank, rocketleague.solo_std_div, rocketleague.solo_std_mmr " - "FROM royals JOIN steam ON royals.id = steam.royal_id " - "JOIN rocketleague ON steam.steam_id = rocketleague.steam_id " - "ORDER BY rocketleague.doubles_rank DESC;") - osu = session.execute("SELECT royals.username, osu.std_pp, osu.taiko_pp, osu.catch_pp, osu.mania_pp FROM royals JOIN osu ON royals.id = osu.royal_id ORDER BY osu.std_pp DESC;") - return render_template("main.htm", dota=dota, rl=rl, osu=osu) - - -if __name__ == "__main__": - app.run(host="0.0.0.0", port=1234) \ No newline at end of file diff --git a/newuser.py b/newuser.py new file mode 100644 index 00000000..287e2482 --- /dev/null +++ b/newuser.py @@ -0,0 +1,45 @@ +import db + +session = db.Session() + +while True: + user = db.Royal.get_or_create(input("Nome account: ")) + session.add(user) + session.commit() + try: + steam = db.Steam.get_or_create(user.id, input("Steam ID 1: ")) + except KeyboardInterrupt: + pass + else: + session.add(steam) + try: + dota = db.Dota.get_or_create(steam.steam_id) + except KeyboardInterrupt: + pass + else: + session.add(dota) + try: + rl = db.RocketLeague.get_or_create(steam.steam_id) + except KeyboardInterrupt: + pass + else: + session.add(rl) + try: + osu = db.Osu.get_or_create(user.id, input("Osu! username: ")) + except KeyboardInterrupt: + pass + else: + session.add(osu) + try: + overwatch = db.Overwatch.get_or_create(user.id, input("Battle.net battletag: ")) + except KeyboardInterrupt: + pass + else: + session.add(overwatch) + try: + lol = db.LeagueOfLegends.get_or_create(user.id, input("League summoner name: ")) + except KeyboardInterrupt: + pass + else: + session.add(lol) + session.commit() \ No newline at end of file diff --git a/templates/main.htm b/templates/main.htm deleted file mode 100644 index 75d73d7d..00000000 --- a/templates/main.htm +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - Ladders - - - - -
-

- Dota 2 -

- {% with query=dota %} - {% include 'table.htm' %} - {% endwith %} -

- Rocket League -

- {% with query=rl %} - {% include 'rl_table.htm' %} - {% endwith %} -

- Osu! -

- {% with query=osu %} - {% include 'table.htm' %} - {% endwith %} -
- - \ No newline at end of file diff --git a/templates/rl_table.htm b/templates/rl_table.htm deleted file mode 100644 index a7482ef0..00000000 --- a/templates/rl_table.htm +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - {% for record in query %} - - - - - - - - {% endfor %} - -
- Username - - Singolo 1v1 - - Doppio 2v2 - - Standard 3v3 - - Solo Standard Solo 3v3 -
- {{ record[0] }} - - {% if record[1] %} - - - {{ record[3] }} - - {% else %} - - {% endif %} - - {% if record[4] %} - - - {{ record[6] }} - - {% else %} - - {% endif %} - - {% if record[7] %} - - - {{ record[9] }} - - {% else %} - - {% endif %} - - {% if record[10] %} - - - {{ record[12] }} - - {% else %} - - {% endif %} -
\ No newline at end of file diff --git a/templates/table.htm b/templates/table.htm deleted file mode 100644 index 781ac858..00000000 --- a/templates/table.htm +++ /dev/null @@ -1,24 +0,0 @@ - - - - {% for column in query.keys() %} - - {% endfor %} - - - - {% for record in query %} - - {% for column in record %} - - {% endfor %} - - {% endfor %} - -
- {{ column }} -
- {% if column %} - {{ column }} - {% endif %} -
\ No newline at end of file diff --git a/update.py b/update.py index 7b145d9a..368b9192 100644 --- a/update.py +++ b/update.py @@ -77,7 +77,20 @@ try: print("OK") finally: time.sleep(1) - + # Update Overwatch + print("OVERWATCH") + for user in session.query(db.Overwatch).all(): + 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: + time.sleep(1) except KeyboardInterrupt: pass finally: