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

wiki is back

This commit is contained in:
Steffo 2020-02-11 19:53:18 +01:00
parent 2d44594f6c
commit c49c24bf16
16 changed files with 226 additions and 161 deletions

49
poetry.lock generated
View file

@ -145,6 +145,14 @@ pytz = "*"
regex = "*"
tzlocal = "*"
[[package]]
category = "main"
description = "Decorators for Humans"
name = "decorator"
optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*"
version = "4.4.1"
[[package]]
category = "main"
description = "A library to handle automated deprecations"
@ -178,7 +186,7 @@ description = "Python audio data toolkit (ID3 and MP3)"
name = "eyed3"
optional = false
python-versions = "*"
version = "0.9"
version = "0.9.2"
[package.dependencies]
deprecation = "*"
@ -271,10 +279,10 @@ description = "HTTP/2 State-Machine based protocol implementation"
name = "h2"
optional = false
python-versions = "*"
version = "3.1.1"
version = "3.2.0"
[package.dependencies]
hpack = ">=2.3,<4"
hpack = ">=3.0,<4"
hyperframe = ">=5.2.0,<6"
[[package]]
@ -300,7 +308,7 @@ description = "Human friendly output for text interfaces using Python"
name = "humanfriendly"
optional = false
python-versions = "*"
version = "5.0"
version = "6.1"
[package.dependencies]
pyreadline = "*"
@ -511,11 +519,12 @@ description = "We have made you a wrapper you can't refuse"
name = "python-telegram-bot"
optional = false
python-versions = "*"
version = "12.3.0"
version = "12.4.2"
[package.dependencies]
certifi = "*"
cryptography = "*"
decorator = ">=4.4.0"
future = ">=0.16.0"
tornado = ">=5.1"
@ -577,7 +586,7 @@ description = "A multipurpose bot and web framework"
name = "royalnet"
optional = false
python-versions = ">=3.8,<4.0"
version = "5.5a3"
version = "5.5a5"
[package.dependencies]
dateparser = ">=0.7.2,<0.8.0"
@ -858,7 +867,7 @@ python-versions = "*"
version = "2020.1.24"
[metadata]
content-hash = "7cb56343d564bb2209fbc1624f64ab008088537a3b23aeb3f93497ff0cebca63"
content-hash = "03b83f374f0113316752e6df25d265ec5d45a2f932f73de1422c92ba06621f66"
python-versions = "^3.8"
[metadata.files]
@ -981,6 +990,10 @@ dateparser = [
{file = "dateparser-0.7.2-py2.py3-none-any.whl", hash = "sha256:983d84b5e3861cb0aa240cad07f12899bb10b62328aae188b9007e04ce37d665"},
{file = "dateparser-0.7.2.tar.gz", hash = "sha256:e1eac8ef28de69a554d5fcdb60b172d526d61924b1a40afbbb08df459a36006b"},
]
decorator = [
{file = "decorator-4.4.1-py2.py3-none-any.whl", hash = "sha256:5d19b92a3c8f7f101c8dd86afd86b0f061a8ce4540ab8cd401fa2542756bce6d"},
{file = "decorator-4.4.1.tar.gz", hash = "sha256:54c38050039232e1db4ad7375cfce6748d7b41c29e95a081c8a6d2c30364a2ce"},
]
deprecation = [
{file = "deprecation-2.0.7-py2.py3-none-any.whl", hash = "sha256:dc9b4f252b7aca8165ce2764a71da92a653b5ffbf7a389461d7a640f6536ecb2"},
{file = "deprecation-2.0.7.tar.gz", hash = "sha256:c0392f676a6146f0238db5744d73e786a43510d54033f80994ef2f4c9df192ed"},
@ -989,9 +1002,9 @@ deprecation = [
{file = "discord.py-1.3.1-py3-none-any.whl", hash = "sha256:8bfe5628d31771744000f19135c386c74ac337479d7282c26cc1627b9d31f360"},
]
eyed3 = [
{file = "eyeD3-0.9-py2.py3-none-any.whl", hash = "sha256:6015669333df2115809102ccf1b29585115b5c233cf4530d9f995ad562634819"},
{file = "eyeD3-0.9-py3.8.egg", hash = "sha256:8e3a7a2ce2932260f77c6234d624737807cdb4404f5bac3c5348c1f9da3d7250"},
{file = "eyeD3-0.9.tar.gz", hash = "sha256:8874762fd4fd93fa64676185ccaa77ea8b3396aea65ba86bca7325f1136f9c8a"},
{file = "eyeD3-0.9.2-py2.py3-none-any.whl", hash = "sha256:14d387e74097b03163c15d071448924d6e9b700bf8b51276a2d7af4ea21cbe0a"},
{file = "eyeD3-0.9.2-py3.8.egg", hash = "sha256:d6562a4a260f5085ee2c469a1904f358f6358e830ad84118032778befec8552e"},
{file = "eyeD3-0.9.2.tar.gz", hash = "sha256:96f1dc92d29da529bf5a0caac6b62a3da2dae319409678491eb7f3e3e1c0359a"},
]
ffmpeg-python = [
{file = "ffmpeg-python-0.2.0.tar.gz", hash = "sha256:65225db34627c578ef0e11c8b1eb528bb35e024752f6f10b78c011f6f64c4127"},
@ -1059,8 +1072,8 @@ h11 = [
{file = "h11-0.9.0.tar.gz", hash = "sha256:33d4bca7be0fa039f4e84d50ab00531047e53d6ee8ffbc83501ea602c169cae1"},
]
h2 = [
{file = "h2-3.1.1-py2.py3-none-any.whl", hash = "sha256:ac377fcf586314ef3177bfd90c12c7826ab0840edeb03f0f24f511858326049e"},
{file = "h2-3.1.1.tar.gz", hash = "sha256:b8a32bd282594424c0ac55845377eea13fa54fe4a8db012f3a198ed923dc3ab4"},
{file = "h2-3.2.0-py2.py3-none-any.whl", hash = "sha256:61e0f6601fa709f35cdb730863b4e5ec7ad449792add80d1410d4174ed139af5"},
{file = "h2-3.2.0.tar.gz", hash = "sha256:875f41ebd6f2c44781259005b157faed1a5031df3ae5aa7bcb4628a6c0782f14"},
]
hpack = [
{file = "hpack-3.0.0-py2.py3-none-any.whl", hash = "sha256:0edd79eda27a53ba5be2dfabf3b15780928a0dff6eb0c60a3d6767720e970c89"},
@ -1070,8 +1083,8 @@ httptools = [
{file = "httptools-0.0.13.tar.gz", hash = "sha256:e00cbd7ba01ff748e494248183abc6e153f49181169d8a3d41bb49132ca01dfc"},
]
humanfriendly = [
{file = "humanfriendly-5.0-py2.py3-none-any.whl", hash = "sha256:eee2e57dea6185fee19914c7d8ba8bc3e488aee2a3c96a7668ce355e2ae275ae"},
{file = "humanfriendly-5.0.tar.gz", hash = "sha256:b166d90b0fd2e7deafc5d20f64ddfdd4251189a1a6bdc5ed32c6678c79b546d5"},
{file = "humanfriendly-6.1-py2.py3-none-any.whl", hash = "sha256:5a57c973dd28a24f45ab723521c84b111fbe79e9d9fcdca6f9aeb668c18a0f40"},
{file = "humanfriendly-6.1.tar.gz", hash = "sha256:b77d1aa8d73b6fe7e8860fa516fbc0e2aa85bff159d7525b0213353817cf1cfc"},
]
hyperframe = [
{file = "hyperframe-5.2.0-py2.py3-none-any.whl", hash = "sha256:5187962cb16dcc078f23cb5a4b110098d546c3f41ff2d4038a9896893bbd0b40"},
@ -1255,8 +1268,8 @@ python-multipart = [
{file = "python-multipart-0.0.5.tar.gz", hash = "sha256:f7bb5f611fc600d15fa47b3974c8aa16e93724513b49b5f95c81e6624c83fa43"},
]
python-telegram-bot = [
{file = "python-telegram-bot-12.3.0.tar.gz", hash = "sha256:41608512a3025a04ff7472efcaae344ad7533a77ae207685bb10fc2fc8282f7b"},
{file = "python_telegram_bot-12.3.0-py2.py3-none-any.whl", hash = "sha256:5e2156f829402e41bb5ea7196e450bf7f121c5689c5100ae180507d72f3777f5"},
{file = "python-telegram-bot-12.4.2.tar.gz", hash = "sha256:0a97cbca638f949582b4ee326170d2f8d7f4bf559a4e511132bb2203623e04ad"},
{file = "python_telegram_bot-12.4.2-py2.py3-none-any.whl", hash = "sha256:d3cffd020af4094d07c11783f875e5c682072ba7f5bc21ce89ff0222f4e6d742"},
]
pytz = [
{file = "pytz-2019.3-py2.py3-none-any.whl", hash = "sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d"},
@ -1294,8 +1307,8 @@ riotwatcher = [
{file = "riotwatcher-2.7.1.tar.gz", hash = "sha256:5349271c7e00637b7619491a6070e66603705db60558ea2a690e7016f6e6d9a4"},
]
royalnet = [
{file = "royalnet-5.5a3-py3-none-any.whl", hash = "sha256:26bb171a55913a42f06a06759df32cccf9edc18b41c9edfeb6022b230f4f85fb"},
{file = "royalnet-5.5a3.tar.gz", hash = "sha256:8c362af1fde43fd67420ef6dc905527044cf0f3e8fc40d298c2a63afd52c92fe"},
{file = "royalnet-5.5a5-py3-none-any.whl", hash = "sha256:f913ec05849c56885bc2a455c6589d960e5af124aacc703bbd3a0e1f004d26b8"},
{file = "royalnet-5.5a5.tar.gz", hash = "sha256:cbb22f322f6bc8ec0a6404a14d3faf046ad3fb74971917e4f87c16bb2aa300f7"},
]
royalspells = [
{file = "royalspells-3.2.tar.gz", hash = "sha256:2bd4a9a66514532e35c02c3907425af48c7cb292364c4843c795719a82b25dfe"},

View file

@ -25,7 +25,7 @@
steam = "^0.9.1"
[tool.poetry.dependencies.royalnet]
version = "^5.5a3"
version = "^5.5a6"
# Maybe... there is a way to make these selectable?
extras = [
"telegram",

View file

@ -0,0 +1,70 @@
POST http://localhost:44445/api/login/royalnet/v1
Content-Type: application/json
{
"username": "Steffo",
"password": "ciao"
}
###
POST http://localhost:44445/api/token/create/v1
Content-Type: application/json
{
"token": "NFFU4qg6-WxfAWMN-IW6dexEjNcLzNQNZJko2_pbTsE",
"duration": 31536000
}
###
GET http://localhost:44445/api/bio/get/v1
Content-Type: application/json
{
"token": "NFFU4qg6-WxfAWMN-IW6dexEjNcLzNQNZJko2_pbTsE",
"id": 1
}
###
POST http://localhost:44445/api/bio/set/v1
Content-Type: application/json
{
"token": "NFFU4qg6-WxfAWMN-IW6dexEjNcLzNQNZJko2_pbTsE",
"contents": "Ciao!"
}
###
GET http://localhost:44445/api/wiki/list/v1
###
POST http://localhost:44445/api/wiki/edit/v1
Content-Type: application/json
{
"token": "NFFU4qg6-WxfAWMN-IW6dexEjNcLzNQNZJko2_pbTsE",
"title": "Prova!",
"contents": "Questa è una pagina wiki di prova.",
"format": "text",
"theme": "default"
}
###
POST http://localhost:44445/api/wiki/edit/v1
Content-Type: application/json
{
"id": "80d54849-fab1-4458-9d89-2429773118ef",
"token": "NFFU4qg6-WxfAWMN-IW6dexEjNcLzNQNZJko2_pbTsE",
"title": "Prova2",
"contents": "Questa è una pagina wiki di prova2.",
"format": "text",
"theme": "default"
}
###

View file

@ -1,21 +1,27 @@
# Imports go here!
from .api_bio_get import ApiBioGetStar
from .api_bio_set import ApiBioSetStar
from .api_diario_get import ApiDiarioGetStar
from .api_diario_list import ApiDiarioListStar
from .api_user_list import ApiUserListStar
from .api_user_get import ApiUserGetStar
from .api_discord_cv import ApiDiscordCvStar
from .api_discord_play import ApiDiscordPlayStar
from .api_wiki_edit import ApiWikiEditStar
from .api_wiki_get import ApiWikiGetStar
from .api_wiki_list import ApiWikiListStar
# Enter the PageStars of your Pack here!
available_page_stars = [
ApiBioGetStar,
ApiBioSetStar,
ApiDiarioGetStar,
ApiDiarioListStar,
ApiDiscordCvStar,
ApiDiscordPlayStar,
ApiUserGetStar,
ApiUserListStar,
ApiWikiEditStar,
ApiWikiGetStar,
ApiWikiListStar,
]

View file

@ -0,0 +1,14 @@
from royalnet.utils import *
from royalnet.backpack.tables import *
from royalnet.constellation.api import *
from ..utils import find_user_api
class ApiBioGetStar(ApiStar):
path = "/api/bio/get/v1"
async def api(self, data: ApiData) -> dict:
user = await find_user_api(data["id"], self.alchemy, data.session)
if user.bio is None:
raise NotFoundError("User has no bio set.")
return user.bio.json()

View file

@ -0,0 +1,23 @@
import royalnet.utils as ru
from royalnet.backpack.tables import *
from royalnet.constellation.api import *
from ..tables import Bio
class ApiBioSetStar(ApiStar):
path = "/api/bio/set/v1"
methods = ["POST"]
async def api(self, data: ApiData) -> ru.JSON:
contents = data["contents"]
BioT = self.alchemy.get(Bio)
user = await data.user()
bio = user.bio
if bio is None:
bio = BioT(user=user, contents=contents)
data.session.add(bio)
else:
bio.contents = contents
await data.session_commit()
return bio.json()

View file

@ -0,0 +1,50 @@
import uuid
import royalnet.utils as ru
from royalnet.backpack.tables import *
from royalnet.constellation.api import *
from ..tables import WikiPage
class ApiWikiEditStar(ApiStar):
path = "/api/wiki/edit/v1"
methods = ["POST"]
async def api(self, data: ApiData) -> ru.JSON:
page_id = data.get("id")
title = data["title"]
contents = data["contents"]
format = data["format"]
theme = data["theme"]
WikiPageT = self.alchemy.get(WikiPage)
user = await data.user()
if not (user.role == "Admin" or user.role == "Member" or user.role == "Bot"):
raise ForbiddenError("You do not have sufficient permissions to edit this page.")
if page_id is None:
page = WikiPageT(
page_id=uuid.uuid4(),
title=title,
contents=contents,
format=format,
theme=theme
)
data.session.add(page)
else:
page = await ru.asyncify(
data.session
.query(WikiPageT)
.filter_by(page_id=uuid.UUID(page_id))
.one_or_none
)
if page is None:
raise NotFoundError(f"No page with the id {repr(page_id)} found.")
page.title = title
page.contents = contents
page.format = format
page.theme = theme
await data.session_commit()
return page.json_full()

View file

@ -7,7 +7,7 @@ from ..tables import *
from royalnet.constellation.api import *
class ApiWikiListStar(ApiData):
class ApiWikiListStar(ApiStar):
path = "/api/wiki/list/v1"
async def api(self, data: ApiData) -> dict:

View file

@ -1,12 +1,9 @@
# Imports go here!
from .diario import Diario
from .wikipages import WikiPage
from .wikirevisions import WikiRevision
from .bios import Bio
from .reminders import Reminder
from .triviascores import TriviaScore
from .mmevents import MMEvent
from .mmresponse import MMResponse
from .leagueoflegends import LeagueOfLegends
from .fiorygi import Fiorygi
from .steam import Steam
@ -17,12 +14,9 @@ from .fiorygitransactions import FiorygiTransaction
available_tables = [
Diario,
WikiPage,
WikiRevision,
Bio,
Reminder,
TriviaScore,
MMEvent,
MMResponse,
LeagueOfLegends,
Fiorygi,
Steam,

View file

@ -10,19 +10,24 @@ class Bio:
__tablename__ = "bios"
@declared_attr
def royal_id(self):
def user_id(self):
return Column(Integer, ForeignKey("users.uid"), primary_key=True)
@declared_attr
def royal(self):
def user(self):
return relationship("User", backref=backref("bio", uselist=False))
@declared_attr
def contents(self):
return Column(Text, nullable=False, default="")
def json(self) -> dict:
return {
"contents": self.contents
}
def __repr__(self):
return f"<Bio of {self.royal}>"
return f"<Bio of {self.user}>"
def __str__(self):
return self.contents

View file

@ -1,52 +0,0 @@
import pickle
from sqlalchemy import *
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declared_attr
class MMEvent:
__tablename__ = "mmevents"
@declared_attr
def creator_id(self):
return Column(Integer, ForeignKey("users.uid"), nullable=False)
@declared_attr
def creator(self):
return relationship("User", backref="mmevents_created")
@declared_attr
def mmid(self):
return Column(Integer, primary_key=True)
@declared_attr
def datetime(self):
return Column(DateTime, nullable=False)
@declared_attr
def title(self):
return Column(String, nullable=False)
@declared_attr
def description(self):
return Column(Text, nullable=False, default="")
@declared_attr
def interface(self):
return Column(String, nullable=False)
@declared_attr
def raw_interface_data(self):
# The default is a pickled None
return Column(Binary, nullable=False, default=b'\x80\x03N.')
@property
def interface_data(self):
return pickle.loads(self.raw_interface_data)
@interface_data.setter
def interface_data(self, value):
self.raw_interface_data = pickle.dumps(value)
def __repr__(self):
return f"<MMEvent {self.mmid}: {self.title}>"

View file

@ -1,31 +0,0 @@
from sqlalchemy import *
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declared_attr
from ..utils import MMChoice
class MMResponse:
__tablename__ = "mmresponse"
@declared_attr
def user_id(self):
return Column(Integer, ForeignKey("users.uid"), primary_key=True)
@declared_attr
def user(self):
return relationship("User", backref="mmresponses_given")
@declared_attr
def mmevent_id(self):
return Column(Integer, ForeignKey("mmevents.mmid"), primary_key=True)
@declared_attr
def mmevent(self):
return relationship("MMEvent", backref="responses")
@declared_attr
def choice(self):
return Column(Enum(MMChoice), nullable=False)
def __repr__(self):
return f"<MMResponse of {self.user}: {self.choice}>"

View file

@ -31,7 +31,7 @@ class WikiPage:
@declared_attr
def theme(self):
return Column(String)
return Column(String, nullable=False, default="default")
@property
def page_short_id(self):

View file

@ -1,48 +0,0 @@
from sqlalchemy import Column, \
Integer, \
Text, \
DateTime, \
ForeignKey
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declared_attr
class WikiRevision:
"""A wiki page revision.
Warning:
Requires PostgreSQL!"""
__tablename__ = "wikirevisions"
@declared_attr
def revision_id(self):
return Column(UUID(as_uuid=True), primary_key=True)
@declared_attr
def page_id(self):
return Column(UUID(as_uuid=True), ForeignKey("wikipages.page_id"), nullable=False)
@declared_attr
def page(self):
return relationship("WikiPage", foreign_keys=self.page_id, backref="revisions")
@declared_attr
def author_id(self):
return Column(Integer, ForeignKey("users.uid"), nullable=False)
@declared_attr
def author(self):
return relationship("User", foreign_keys=self.author_id, backref="wiki_contributions")
@declared_attr
def timestamp(self):
return Column(DateTime, nullable=False)
@declared_attr
def reason(self):
return Column(Text)
@declared_attr
def diff(self):
return Column(Text)

View file

@ -7,6 +7,7 @@ from .royalqueue import RoyalQueue
from .dotamedal import DotaMedal
from .dotastars import DotaStars
from .dotarank import DotaRank
from .finduser import find_user_api
__all__ = [
"MMChoice",
@ -19,4 +20,5 @@ __all__ = [
"DotaMedal",
"DotaStars",
"DotaRank",
"find_user_api",
]

View file

@ -0,0 +1,19 @@
from typing import *
from royalnet.constellation.api import *
from royalnet.backpack.tables.users import User
from royalnet.utils import asyncify
async def find_user_api(input: Union[int, str], alchemy, session):
if isinstance(input, int):
user_id = input
elif isinstance(input, str):
try:
user_id = int(input)
except ValueError:
raise InvalidParameterError(f"Invalid user id passed to {find_user_api.__name__}")
else:
raise TypeError(f"Invalid input type passed to {find_user_api.__name__}")
user: User = await asyncify(session.query(alchemy.get(User)).get, user_id)
if user is None:
raise NotFoundError("No such user.")
return user