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

Aggiunta wiki, miglioramenti ai bot

This commit is contained in:
Steffo 2018-07-15 14:41:42 +02:00
parent b75f0c32df
commit 5a3158535b
8 changed files with 197 additions and 38 deletions

49
db.py
View file

@ -45,7 +45,7 @@ class Telegram(Base):
__tablename__ = "telegram"
royal_id = Column(Integer, ForeignKey("royals.id"), nullable=False)
royal = relationship("Royal", lazy="joined")
royal = relationship("Royal", backref="telegram", lazy="joined")
telegram_id = Column(BigInteger, primary_key=True)
first_name = Column(String, nullable=False)
@ -91,7 +91,7 @@ class Steam(Base):
__tablename__ = "steam"
royal_id = Column(Integer, ForeignKey("royals.id"), nullable=False)
royal = relationship("Royal", lazy="joined")
royal = relationship("Royal", backref="steam", lazy="joined")
steam_id = Column(String, primary_key=True)
persona_name = Column(String)
@ -172,7 +172,7 @@ class RocketLeague(Base):
__tablename__ = "rocketleague"
steam_id = Column(String, ForeignKey("steam.steam_id"), primary_key=True)
steam = relationship("Steam", lazy="joined")
steam = relationship("Steam", backref="rl", lazy="joined")
season = Column(Integer)
@ -299,7 +299,7 @@ class Dota(Base):
__tablename__ = "dota"
steam_id = Column(String, ForeignKey("steam.steam_id"), primary_key=True)
steam = relationship("Steam", lazy="joined")
steam = relationship("Steam", backref="dota", lazy="joined")
rank_tier = Column(Integer)
@ -398,7 +398,7 @@ class LeagueOfLegends(Base):
__tablename__ = "leagueoflegends"
royal_id = Column(Integer, ForeignKey("royals.id"), nullable=False)
royal = relationship("Royal", lazy="joined")
royal = relationship("Royal", backref="lol", lazy="joined")
summoner_id = Column(BigInteger, primary_key=True)
summoner_name = Column(String, nullable=False)
@ -482,7 +482,7 @@ class Osu(Base):
__tablename__ = "osu"
royal_id = Column(Integer, ForeignKey("royals.id"), nullable=False)
royal = relationship("Royal", lazy="joined")
royal = relationship("Royal", backref="osu", lazy="joined")
osu_id = Column(Integer, primary_key=True)
osu_name = Column(String, nullable=False)
@ -540,7 +540,7 @@ class Discord(Base):
__table_args__ = tuple(UniqueConstraint("name", "discriminator"))
royal_id = Column(Integer, ForeignKey("royals.id"), nullable=False)
royal = relationship("Royal", lazy="joined")
royal = relationship("Royal", backref="discord", lazy="joined")
discord_id = Column(BigInteger, primary_key=True)
name = Column(String, nullable=False)
@ -584,7 +584,7 @@ class Overwatch(Base):
__tablename__ = "overwatch"
royal_id = Column(Integer, ForeignKey("royals.id"), nullable=False)
royal = relationship("Royal", lazy="joined")
royal = relationship("Royal", backref="overwatch", lazy="joined")
battletag = Column(String, primary_key=True)
discriminator = Column(Integer, primary_key=True)
@ -669,9 +669,9 @@ class Diario(Base):
id = Column(Integer, primary_key=True)
timestamp = Column(DateTime, nullable=False)
saver_id = Column(Integer, ForeignKey("telegram.telegram_id"))
saver = relationship("Telegram", foreign_keys=saver_id, lazy="joined")
saver = relationship("Telegram", foreign_keys=saver_id, backref="diario_saves", lazy="joined")
author_id = Column(Integer, ForeignKey("telegram.telegram_id"))
author = relationship("Telegram", foreign_keys=author_id, lazy="joined")
author = relationship("Telegram", foreign_keys=author_id, backref="diario_authored", lazy="joined")
text = Column(String)
def __repr__(self):
@ -725,7 +725,7 @@ class BaluRage(Base):
id = Column(Integer, primary_key=True)
royal_id = Column(Integer, ForeignKey("royals.id"))
royal = relationship("Royal", lazy="joined")
royal = relationship("Royal", backref="times_raged", lazy="joined")
reason = Column(String)
def __repr__(self):
@ -737,7 +737,7 @@ class PlayedMusic(Base):
id = Column(Integer, primary_key=True)
enqueuer_id = Column(BigInteger, ForeignKey("discord.discord_id"))
enqueuer = relationship("Discord", lazy="joined")
enqueuer = relationship("Discord", backref="music_played", lazy="joined")
filename = Column(String)
def __repr__(self):
@ -798,9 +798,9 @@ class VoteAnswer(Base):
__tablename__ = "voteanswer"
question_id = Column(Integer, ForeignKey("votequestion.id"))
question = relationship("VoteQuestion")
question = relationship("VoteQuestion", backref="answers", lazy="joined")
user_id = Column(BigInteger, ForeignKey("telegram.telegram_id"))
user = relationship("Telegram")
user = relationship("Telegram", backref="votes_cast", lazy="joined")
choice = Column(Enum(VoteChoices), nullable=False)
__table_args__ = (PrimaryKeyConstraint("question_id", "user_id"),)
@ -827,8 +827,27 @@ class CustomCSS(Base):
css = Column(Text, nullable=False)
class WikiEntry(Base):
__tablename__ = "wikientries"
key = Column(String, primary_key=True)
content = Column(Text, nullable=False)
class WikiLog(Base):
__tablename__ = "wikilog"
edit_id = Column(Integer, primary_key=True)
editor_id = Column(Integer, ForeignKey("royals.id"), nullable=False)
editor = relationship("Royal", backref="wiki_edits", lazy="joined")
edited_key = Column(String, ForeignKey("wikientries.key"), nullable=False)
edited = relationship("WikiEntry", backref="edit_logs", lazy="joined")
timestamp = Column(DateTime, nullable=False)
reason = Column(Text)
# If run as script, create all the tables in the db
if __name__ == "__main__":
print("Creating new tables...")
Base.metadata.create_all(bind=engine)
print("Done!")
print("Done!")

View file

@ -260,7 +260,7 @@ def command(func):
return new_func
def requires_cv(func):
def requires_voice_client(func):
"Decorator. Ensures the voice client is connected before running the command."
async def new_func(channel: discord.Channel, author: discord.Member, params: typing.List[str], *args, **kwargs):
global voice_client
@ -331,7 +331,7 @@ async def add_video_from_file(file):
@command
@requires_cv
@requires_voice_client
async def cmd_play(channel: discord.Channel, author: discord.Member, params: typing.List[str]):
if len(params) < 2:
await client.send_message(channel, "⚠ Non hai specificato una canzone da riprodurre!\n"
@ -365,7 +365,7 @@ async def cmd_play(channel: discord.Channel, author: discord.Member, params: typ
@command
@requires_cv
@requires_voice_client
async def cmd_skip(channel: discord.Channel, author: discord.Member, params: typing.List[str]):
global voice_player
if voice_player is None:
@ -376,7 +376,7 @@ async def cmd_skip(channel: discord.Channel, author: discord.Member, params: typ
@command
@requires_cv
@requires_voice_client
async def cmd_remove(channel: discord.Channel, author: discord.Member, params: typing.List[str]):
if len(voice_queue) == 0:
await client.send_message(channel, "⚠ Non c'è nessun video in coda.")
@ -443,7 +443,7 @@ async def cmd_queue(channel: discord.Channel, author: discord.Member, params: ty
@command
@requires_cv
@requires_voice_client
async def cmd_shuffle(channel: discord.Channel, author: discord.Member, params: typing.List[str]):
if len(voice_queue) == 0:
await client.send_message(channel, "⚠ Non ci sono video in coda!")
@ -453,7 +453,7 @@ async def cmd_shuffle(channel: discord.Channel, author: discord.Member, params:
@command
@requires_cv
@requires_voice_client
async def cmd_clear(channel: discord.Channel, author: discord.Member, params: typing.List[str]):
global voice_queue
if len(voice_queue) == 0:
@ -463,6 +463,15 @@ async def cmd_clear(channel: discord.Channel, author: discord.Member, params: ty
await client.send_message(channel, ":regional_indicator_x: Tutti i video in coda rimossi.")
@command
@requires_voice_client
async def cmd_dump_voice_player_error(channel: discord.Channel, author: discord.Member, params: typing.List[str]):
global voice_player
if voice_player is None:
return
await client.send_message(channel, f"```\n{str(voice_player.error)}\n```")
async def queue_predownload_videos():
while True:
for index, video in enumerate(voice_queue[:int(config["YouTube"]["predownload_videos"])].copy()):
@ -522,7 +531,8 @@ async def queue_play_next_video():
voice_player = await now_playing.create_player()
voice_player.start()
await client.change_presence(game=discord.Game(name=now_playing.plain_text(), type=2))
await client.send_message(client.get_channel(config["Discord"]["main_channel"]), f":arrow_forward: Ora in riproduzione: {str(now_playing)}")
await client.send_message(client.get_channel(config["Discord"]["main_channel"]),
f":arrow_forward: Ora in riproduzione: {str(now_playing)}")
del voice_queue[0]
@ -540,7 +550,8 @@ commands = {
"!queue": cmd_queue,
"!q": cmd_queue,
"!shuffle": cmd_shuffle,
"!clear": cmd_clear
"!clear": cmd_clear,
"!dump_vp": cmd_dump_voice_player_error
}

View file

@ -8,4 +8,5 @@ psycopg2-binary
PyNaCl
async_timeout
raven
bcrypt
bcrypt
markdown

View file

@ -23,6 +23,36 @@ input[type="text"], input[type="password"] {
font-family: sans-serif;
}
textarea {
background-color: rgba(red(@text-color), green(@text-color), blue(@text-color), 0.1);
color: @text-color;
font-size: small;
font-family: "Consolas", "Source Code Pro", monospace;
padding: 2px;
margin: 1px;
border: 1px dotted @text-color;
width: 100%;
}
button, input[type="submit"] {
background-color: rgba(red(@text-color), green(@text-color), blue(@text-color), 0.1);
border-radius: 0;
border: 1px solid @text-color;
color: @text-color;
padding: 2px;
padding-left: 8px;
padding-right: 8px;
margin: 1px;
font-size: medium;
font-family: sans-serif;
}
button:hover, input[type="submit"]:hover {
background-color: rgba(red(@text-color), green(@text-color), blue(@text-color), 0.3);
color: @accent-color;
border: 1px solid @accent-color;
}
.input-grid {
display: grid;
@ -442,6 +472,16 @@ input[type="text"], input[type="password"] {
}
}
.wiki {
.wiki-log {
font-family: "Consolas", "Source Code Pro", monospace;
.last-reason {
font-style: italic;
}
}
}
#edit-css {
font-size: medium;
}

View file

@ -451,7 +451,6 @@ def cmd_wheel(bot: Bot, update: Update):
session.close()
def process(arg_discord_connection):
print("Telegrambot starting...")
if arg_discord_connection is not None:

View file

@ -9,14 +9,28 @@
Royal Games
</h1>
<p>
Benvenuto al sito web della Royal Games! E' ancora un po' triste e spoglio, ma spero che collaboriate a migliorarlo!
</p>
<p>
Attualmente, sto sviluppando i <b>profili RYG</b>!
Benvenuto al sito web della Royal Games! Sta lentamente migliorando, ma spero che comunque collaboriate a migliorarlo!
</p>
<h2>Profili</h2>
<ul>
{% for user in royals %}
<li><a href="/profile/{{ user.username }}">{{ user.username }}</a></li>
<li><a href="profile/{{ user.username }}">{{ user.username }}</a></li>
{% endfor %}
</ul>
<h2>Giochi</h2>
<ul>
<li><a href="game/ryg">Royal Games</a></li>
<li><a href="game/steam">Steam</a></li>
<li><a href="game/dota">Dota 2</a></li>
<li><a href="game/rl">Rocket League</a></li>
<li><a href="game/lol">League of Legends</a></li>
<li><a href="game/ow">Overwatch</a></li>
<li><a href="game/osu">osu!</a></li>
</ul>
<h2>Wiki</h2>
<ul>
{% for key in wiki_pages %}
<li><a href="wiki/{{ key }}">{{ key }}</a></li>
{% endfor %}
</ul>
{% endblock %}

31
templates/wiki.html Normal file
View file

@ -0,0 +1,31 @@
{% extends 'base.html' %}
{% block pagetitle %}
{{ key }}
{% endblock %}
{% block body %}
<div class="wiki">
<h1>
{{ key }}
</h1>
{% if wiki_page %}
<div class="wiki-content">
{{ converted_md }}
</div>
<div class="wiki-log">
Ultima modifica di <span class="last-author"><a href="/profile/{{ wiki_log.editor.username }}">{{ wiki_log.editor.username }}</a></span> alle <span class="last-timestamp">{{ wiki_log.timestamp.isoformat() }}</span>{% if wiki_log.reason %}, motivo: <span class="last-reason">{{ wiki_log.reason }}</span>{% endif %}
</div>
{% endif %}
{% if session.get('user_id', '') %}
<h4>Modifica</h4>
<div class="wiki-edit">
<form action="{{ url_for('page_wiki', key=key) }}" method="POST">
<textarea class="content" name="content" placeholder="Inserisci il Markdown per la pagina qui.">{% if wiki_page %}{{ wiki_page.content }}{% endif %}</textarea><br>
<input class="reason" name="reason" type="text" placeholder="Motivo per la modifica"><br>
<input class="submit" type="submit" value="Invia">
</form>
</div>
{% endif %}
</div>
{% endblock %}

View file

@ -1,8 +1,11 @@
from flask import Flask, render_template, request, abort, redirect, url_for
from flask import Flask, render_template, request, abort, redirect, url_for, Markup, escape
from flask import session as fl_session
import db
import bcrypt
import configparser
import markdown
import datetime
import telegram
app = Flask(__name__)
@ -14,6 +17,7 @@ config.read("config.ini")
app.secret_key = config["Flask"]["secret_key"]
telegram_bot = telegram.Bot(config["Telegram"]["bot_token"])
@app.route("/")
def page_main():
@ -57,7 +61,7 @@ def page_loggedin():
user = db_session.query(db.Royal).filter_by(username=username).one_or_none()
db_session.close()
if user is None:
abort(403)
abort(401)
return
if user.password is None:
fl_session["user_id"] = user.id
@ -66,7 +70,7 @@ def page_loggedin():
fl_session["user_id"] = user.id
return redirect(url_for("page_main"))
else:
abort(403)
abort(401)
return
@ -75,7 +79,7 @@ def page_password():
user_id = fl_session.get("user_id")
if request.method == "GET":
if user_id is None:
abort(403)
abort(401)
return
return render_template("password.html")
elif request.method == "POST":
@ -89,7 +93,7 @@ def page_password():
return redirect(url_for("page_main"))
else:
db_session.close()
abort(403)
abort(401)
return
@ -101,12 +105,12 @@ def page_setcss():
if request.method == "GET":
db_session.close()
if user_id is None:
abort(403)
abort(401)
return
return render_template("setcss.html", css=ccss.css)
elif request.method == "POST":
if user_id is None:
abort(403)
abort(401)
return
css = request.form.get("css", "")
if "</style" in css:
@ -150,8 +154,48 @@ def page_game(name: str):
db_session.close()
return render_template("game.html", minis=query, game_name=game_name, game_short_name=name)
@app.route("/wiki/<key>", methods=["GET", "POST"])
def page_wiki(key: str):
db_session = db.Session()
wiki_page = db_session.query(db.WikiEntry).filter_by(key=key).one_or_none()
if request.method == "GET":
wiki_latest_edit = db_session.query(db.WikiLog).filter_by(edited_key=key) \
.order_by(db.WikiLog.timestamp.desc()).first()
db_session.close()
if wiki_page is None:
return render_template("wiki.html", key=key)
converted_md = Markup(markdown.markdown(escape(wiki_page.content)))
return render_template("wiki.html", key=key, wiki_page=wiki_page, converted_md=converted_md,
wiki_log=wiki_latest_edit)
elif request.method == "POST":
user_id = fl_session.get('user_id')
user = db_session.query(db.Royal).filter_by(id=user_id).one()
if user_id is None:
db_session.close()
abort(401)
return
if wiki_page is None:
wiki_page = db.WikiEntry(key=key, content=request.form.get("content"))
db_session.add(wiki_page)
db_session.flush()
else:
wiki_page.content = request.form.get("content")
edit_reason = request.form.get("reason")
new_log = db.WikiLog(editor=user, edited_key=key, timestamp=datetime.datetime.now(), reason=edit_reason)
db_session.add(new_log)
db_session.commit()
telegram_bot.send_message(config["Telegram"]["main_group"],
f' La pagina wiki <a href="https://ryg.steffo.eu/wiki/{key}">{key}</a> è stata'
f' modificata da'
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}',
parse_mode="HTML")
return redirect(url_for("page_wiki", key=key))
if __name__ == "__main__":
try:
app.run(host="0.0.0.0", port=1234, debug=__debug__)
app.run(host="0.0.0.0", port=1235, debug=__debug__)
except KeyboardInterrupt:
pass