1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-23 19:44:20 +00:00

Wikiview blueprint (#63, #39)

* start work on wiki

* more progress

* wikiprogress, but not yet

* Complete wikiview

* Get rid of required tables

* Restructure the db
This commit is contained in:
Steffo 2019-06-06 14:24:32 +02:00 committed by GitHub
parent 332fd763e6
commit c64f528ecf
16 changed files with 290 additions and 11 deletions

58
data.txt Normal file

File diff suppressed because one or more lines are too long

View file

@ -14,3 +14,4 @@ sphinx_rtd_theme>=0.4.3
PyNaCl>=1.3.0
werkzeug>=0.15.4
flask>=1.0.3
markdown2>=2.3.8

View file

@ -2,9 +2,11 @@ from .royals import Royal
from .telegram import Telegram
from .diario import Diario
from .aliases import Alias
from .activekvgroup import ActiveKvGroup
from .keyvalue import Keyvalue
from .keygroup import Keygroup
from .activekvgroups import ActiveKvGroup
from .keyvalues import Keyvalue
from .keygroups import Keygroup
from .discord import Discord
from .wikipages import WikiPage
from .wikirevisions import WikiRevision
__all__ = ["Royal", "Telegram", "Diario", "Alias", "ActiveKvGroup", "Keyvalue", "Keygroup", "Discord"]
__all__ = ["Royal", "Telegram", "Diario", "Alias", "ActiveKvGroup", "Keyvalue", "Keygroup", "Discord", "WikiPage", "WikiRevision"]

View file

@ -7,7 +7,7 @@ from sqlalchemy.ext.declarative import declared_attr
# noinspection PyUnresolvedReferences
from .royals import Royal
# noinspection PyUnresolvedReferences
from .keygroup import Keygroup
from .keygroups import Keygroup
class ActiveKvGroup:

View file

@ -4,7 +4,7 @@ from sqlalchemy import Column, \
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declared_attr
# noinspection PyUnresolvedReferences
from .keygroup import Keygroup
from .keygroups import Keygroup
class Keyvalue:

View file

@ -0,0 +1,25 @@
from sqlalchemy import Column, \
Text, \
String
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.ext.declarative import declared_attr
class WikiPage:
"""Wiki page properties.
Warning:
Requires PostgreSQL!"""
__tablename__ = "wikipages"
@declared_attr
def page_id(self):
return Column(UUID(as_uuid=True), primary_key=True)
@declared_attr
def title(self):
return Column(String, nullable=False)
@declared_attr
def content(self):
return Column(Text)

View file

@ -0,0 +1,52 @@
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
# noinspection PyUnresolvedReferences
from .wikipages import WikiPage
# noinspection PyUnresolvedReferences
from .royals import Royal
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("royals.uid"), nullable=False)
@declared_attr
def author(self):
return relationship("Royal", 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

@ -1,14 +1,13 @@
import os
from .web import create_app
from .web.blueprints import home
from .web.blueprints import home, wikiview
class TestConfig:
DB_PATH = os.environ["DB_PATH"]
REQUIRED_TABLES = set()
app = create_app(TestConfig, [home])
app = create_app(TestConfig, [home, wikiview])
if __name__ == "__main__":

View file

@ -0,0 +1,32 @@
import os
import re
import datetime
import difflib
import uuid
from royalnet.database import Alchemy
from royalnet.database.tables import Royal, WikiPage, WikiRevision
if __name__ == "__main__":
alchemy = Alchemy(os.environ["DB_PATH"], {Royal, WikiPage, WikiRevision})
with open(r"data.txt") as file, alchemy.session_cm() as session:
for line in file.readlines():
match = re.match("^([^\t]+)\t([^\t]+)\t([tf])$", line)
if match is None:
continue
title = match.group(1)
content = match.group(2).replace(r"\r\n", "\n").replace(r"\t", "\t")
page = alchemy.WikiPage(page_id=uuid.uuid4(),
title=title,
content=content)
session.flush()
revision = alchemy.WikiRevision(revision_id=uuid.uuid4(),
page=page,
author_id=31, # Royalbot
timestamp=datetime.datetime.now(),
reason="Imported from 'four' database",
diff="\n".join(difflib.unified_diff([], content.split("\n"))))
session.add(page)
session.add(revision)
print(f"{title} done.")
session.commit()

View file

@ -1,5 +1,6 @@
from .helloworld import bp as helloworld
from .testing import bp as testing
from .home import bp as home
from .wikiview import bp as wikiview
__all__ = ["helloworld", "testing", "home"]
__all__ = ["helloworld", "testing", "home", "wikiview"]

View file

@ -0,0 +1,59 @@
import flask as f
import markdown2
import re
import uuid
from ... import Royalprint
from ....database.tables import Royal, WikiPage, WikiRevision
bp = Royalprint("wikiview", __name__, url_prefix="/wikiview", template_folder="templates",
required_tables={Royal, WikiPage, WikiRevision})
def prepare_page(page):
converted_md = markdown2.markdown(page.content.replace("<", "&lt;"),
extras=["spoiler", "tables", "smarty-pants", "fenced-code-blocks"])
converted_md = re.sub(r"{https?://(?:www\.)?(?:youtube\.com/watch\?.*?&?v=|youtu.be/)([0-9A-Za-z-]+).*?}",
r'<div class="youtube-embed">'
r' <iframe src="https://www.youtube-nocookie.com/embed/\1?rel=0&amp;showinfo=0"'
r' frameborder="0"'
r' allow="autoplay; encrypted-media"'
r' allowfullscreen'
r' width="640px"'
r' height="320px">'
r' </iframe>'
r'</div>', converted_md)
converted_md = re.sub(r"{https?://clyp.it/([a-z0-9]+)}",
r'<div class="clyp-embed">'
r' <iframe width="100%" height="160" src="https://clyp.it/\1/widget" frameborder="0">'
r' </iframe>'
r'</div>', converted_md)
return converted_md
@bp.route("/")
def wikiview_index():
from ...alchemyhandler import alchemy, alchemy_session
pages = alchemy_session.query(alchemy.WikiPage).all()
return f.render_template("wikiview_index.html", pages=pages)
@bp.route("/id/<page_id>")
def wikiview_by_id(page_id: str):
from ...alchemyhandler import alchemy, alchemy_session
page_uuid = uuid.UUID(page_id)
page = alchemy_session.query(alchemy.WikiPage).filter(alchemy.WikiPage.page_id == page_uuid).one_or_none()
if page is None:
return "No such page", 404
parsed_content = prepare_page(page)
return f.render_template("wikiview_page.html", page=page, parsed_content=f.Markup(parsed_content))
@bp.route("/title/<title>")
def wikiview_by_title(title: str):
from ...alchemyhandler import alchemy, alchemy_session
page = alchemy_session.query(alchemy.WikiPage).filter(alchemy.WikiPage.title == title).one_or_none()
if page is None:
return "No such page", 404
parsed_content = prepare_page(page)
return f.render_template("wikiview_page.html", page=page, parsed_content=f.Markup(parsed_content))

View file

@ -0,0 +1,22 @@
{% extends "base.html" %}
{% block title %}
Indice RYGwiki
{% endblock %}
{% block content %}
<div class="doublebox">
<div class="top">
<span class="left">
Wiki index
</span>
</div>
<div class="bot">
<ul>
{% for page in pages %}
<li><a href="{{ url_for("wikiview.wikiview_by_id", page_id=page.page_id|string) }}">{{ page.title }}</a></li>
{% endfor %}
</ul>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,26 @@
{% extends "base.html" %}
{% block title %}
{{ page.title }} - RYGwiki
{% endblock %}
{% block content %}
<div class="doublebox">
<div class="top">
<span class="left">
Wiki page
</span>
<span class="right">
<a class="permalink no-icon" href="{{ url_for("wikiview.wikiview_by_id", page_id=page.page_id|string) }}">#</a>
</span>
</div>
<div class="bot">
<h1>
{{ page.title }}
</h1>
<div>
{{ parsed_content }}
</div>
</div>
</div>
{% endblock %}

View file

@ -21,8 +21,10 @@
</span>
</div>
<div class="h-container">
<div class="main-container">
{% block content %}{% endblock %}
</div>
</div>
<div id="foot-scripts">
{% block footscripts %}{% endblock %}
</div>