diff --git a/db.py b/db.py
index 5b34a15c..f16d5964 100644
--- a/db.py
+++ b/db.py
@@ -1,7 +1,7 @@
import datetime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship
-from sqlalchemy import Column, BigInteger, Integer, String, DateTime, ForeignKey, Float, Enum, create_engine, UniqueConstraint, PrimaryKeyConstraint, Boolean, or_
+from sqlalchemy import Column, BigInteger, Integer, String, DateTime, ForeignKey, Float, Enum, create_engine, UniqueConstraint, PrimaryKeyConstraint, Boolean, or_, LargeBinary
import requests
from errors import RequestError, NotFoundError, AlreadyExistingError
import re
@@ -25,6 +25,8 @@ class Royal(Base):
id = Column(Integer, primary_key=True)
username = Column(String, unique=True, nullable=False)
+ password = Column(LargeBinary)
+ fiorygi = Column(Integer, default=0)
@staticmethod
def create(session: Session, username: str):
diff --git a/requirements.txt b/requirements.txt
index 4643bba1..637c8e29 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -7,4 +7,5 @@ requests
psycopg2
PyNaCl
async_timeout
-raven
\ No newline at end of file
+raven
+bcrypt
\ No newline at end of file
diff --git a/static/nryg.css b/static/nryg.css
new file mode 100644
index 00000000..d367808b
--- /dev/null
+++ b/static/nryg.css
@@ -0,0 +1,9 @@
+body {
+ font-family: sans-serif;
+ color: #a0ccff;
+ background-color: #0d193b;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ color: #fff;
+}
diff --git a/templates/base.html b/templates/base.html
new file mode 100644
index 00000000..35d2dbe7
--- /dev/null
+++ b/templates/base.html
@@ -0,0 +1,13 @@
+
+
+
+
+ {% block pagetitle %}{% endblock %} - Royal Games
+ {% block prehead %}{% endblock %}
+
+ {% block posthead %}{% endblock %}
+
+
+ {% block body %}{% endblock %}
+
+
\ No newline at end of file
diff --git a/templates/login.html b/templates/login.html
new file mode 100644
index 00000000..125e3a50
--- /dev/null
+++ b/templates/login.html
@@ -0,0 +1,22 @@
+{% extends 'base.html' %}
+
+{% block pagetitle %}
+ Royal Games
+{% endblock %}
+
+{% block body %}
+
+ Login
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/templates/password.html b/templates/password.html
new file mode 100644
index 00000000..1bcbc806
--- /dev/null
+++ b/templates/password.html
@@ -0,0 +1,20 @@
+
+
+
+
+ Login
+
+
+
+
+
\ No newline at end of file
diff --git a/webserver.py b/webserver.py
index a4923569..a72c6c67 100644
--- a/webserver.py
+++ b/webserver.py
@@ -1,12 +1,20 @@
-from flask import Flask, render_template
-from db import Session, Royal, Steam, RocketLeague, Dota, Osu, Overwatch, LeagueOfLegends, Diario, Telegram, PlayedMusic, Discord
-from sqlalchemy import func
+from flask import Flask, render_template, request, abort, redirect, url_for
+from flask import session as fl_session
+import db
+from sqlalchemy import func, alias
+import bcrypt
+import configparser
app = Flask(__name__)
app.jinja_env.trim_blocks = True
app.jinja_env.lstrip_blocks = True
+config = configparser.ConfigParser()
+config.read("config.ini")
+
+app.secret_key = config["Flask"]["secret_key"]
+
@app.route("/")
def page_index():
@@ -15,33 +23,82 @@ def page_index():
@app.route("/diario")
def page_diario():
- session = Session()
- diario_data = session.query(Diario).outerjoin((Telegram, Diario.author), aliased=True).outerjoin(Royal, aliased=True).outerjoin((Telegram, Diario.saver), aliased=True).outerjoin(Royal, aliased=True).all()
- session.close()
+ db_session = db.Session()
+ diario_data = db_session.query(db.Diario).outerjoin((db.Telegram, db.Diario.author), aliased=True).outerjoin(db.Royal, aliased=True).outerjoin((db.Telegram, db.Diario.saver), aliased=True).outerjoin(db.Royal, aliased=True).all()
+ db_session.close()
return render_template("diario.html", diario_data=diario_data)
@app.route("/leaderboards")
def page_leaderboards():
- session = Session()
- dota_data = session.query(Dota).join(Steam).join(Royal).order_by(Dota.rank_tier).all()
- rl_data = session.query(RocketLeague).join(Steam).join(Royal).order_by(RocketLeague.doubles_mmr).all()
- ow_data = session.query(Overwatch).join(Royal).order_by(Overwatch.rank).all()
- osu_data = session.query(Osu).join(Royal).order_by(Osu.std_pp).all()
- lol_data = session.query(LeagueOfLegends).join(Royal).order_by(LeagueOfLegends.summoner_name).all()
- session.close()
+ db_session = db.Session()
+ dota_data = db_session.query(db.Dota).join(db.Steam).join(db.Royal).order_by(db.Dota.rank_tier).all()
+ rl_data = db_session.query(db.RocketLeague).join(db.Steam).join(db.Royal).order_by(db.RocketLeague.doubles_mmr).all()
+ ow_data = db_session.query(db.Overwatch).join(db.Royal).order_by(db.Overwatch.rank).all()
+ osu_data = db_session.query(db.Osu).join(db.Royal).order_by(db.Osu.std_pp).all()
+ lol_data = db_session.query(db.LeagueOfLegends).join(db.Royal).order_by(db.LeagueOfLegends.summoner_name).all()
+ db_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)
@app.route("/music")
def page_music():
- session = Session()
- music_counts = session.query(PlayedMusic.filename, func.count(PlayedMusic.filename)).group_by(PlayedMusic.filename).all()
- music_last = session.query(PlayedMusic).join(Discord).join(Royal).order_by(PlayedMusic.id.desc()).limit(50).all()
- session.close()
+ db_session = db.Session()
+ music_counts = db_session.query(db.PlayedMusic.filename, alias(func.count(db.PlayedMusic.filename), "count")).order_by("count").group_by(db.PlayedMusic.filename).all()
+ music_last = db_session.query(db.PlayedMusic).join(db.Discord).join(db.Royal).order_by(db.PlayedMusic.id.desc()).limit(50).all()
+ db_session.close()
return render_template("music.html", music_counts=music_counts, music_last=music_last)
+@app.route("/login")
+def page_login():
+ return render_template("login.html")
+
+
+@app.route("/loggedin", methods=["GET", "POST"])
+def page_loggedin():
+ if request.method == "GET":
+ username = fl_session.get("username")
+ if username is None:
+ return "Not logged in"
+ else:
+ return username
+ elif request.method == "POST":
+ username = request.form["username"]
+ password = request.form["password"]
+ db_session = db.Session()
+ user = db_session.query(db.Royal).filter_by(username=username).one_or_none()
+ db_session.close()
+ if bcrypt.checkpw(bytes(password, encoding="utf8"), user.password):
+ fl_session["username"] = username
+ return username
+ else:
+ abort(403)
+ return
+
+
+@app.route("/password", methods=["GET", "POST"])
+def page_password():
+ username = fl_session.get("username")
+ if request.method == "GET":
+ if username is None:
+ abort(403)
+ return
+ return render_template("password.html")
+ elif request.method == "POST":
+ old_password = request.form["old"]
+ new_password = request.form["new"]
+ db_session = db.Session()
+ user = db_session.query(db.Royal).filter_by(username=username).one_or_none()
+ if bcrypt.checkpw(bytes(old_password, encoding="utf8"), user.password):
+ user.password = bcrypt.hashpw(bytes(new_password, encoding="utf8"), bcrypt.gensalt())
+ db_session.commit()
+ db_session.close()
+ return "Password changed"
+ else:
+ db_session.close()
+ abort(403)
+
if __name__ == "__main__":
try:
app.run(host="0.0.0.0", port=1234)