From 4a519bbb854222e261511b8180e8c951b8ae2396 Mon Sep 17 00:00:00 2001 From: haskal Date: Thu, 30 May 2019 20:43:53 -0400 Subject: [PATCH] Add mdi, fake sessions, WIP db models (no migrations yet) --- .gitignore | 1 + .gitmodules | 3 ++ Makefile | 5 ++- README.md | 1 + material-design-icons | 1 + setup.py | 3 +- wikilain/__init__.py | 26 ++++++++--- wikilain/adapters/__init__.py | 0 wikilain/adapters/session_simple.py | 49 +++++++++++++++++++++ wikilain/adapters/templates/login_form.html | 14 ++++++ wikilain/markdown.py | 32 ++++++++++++++ wikilain/models.py | 41 +++++++++++++++-- wikilain/static/mdi | 1 + wikilain/static/style.css | 5 +++ wikilain/templates/article.html | 10 +++++ wikilain/templates/base.html | 35 +++++++++++++++ wikilain/templates/index.html | 10 +++++ 17 files changed, 226 insertions(+), 11 deletions(-) create mode 100644 .gitmodules create mode 160000 material-design-icons create mode 100644 wikilain/adapters/__init__.py create mode 100644 wikilain/adapters/session_simple.py create mode 100644 wikilain/adapters/templates/login_form.html create mode 100644 wikilain/markdown.py create mode 120000 wikilain/static/mdi create mode 100644 wikilain/static/style.css create mode 100644 wikilain/templates/article.html create mode 100644 wikilain/templates/base.html create mode 100644 wikilain/templates/index.html diff --git a/.gitignore b/.gitignore index 1ddb7da..460600a 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ __pycache__ .ycm_extra_conf.py postgres/ .envrc +.mypy_cache/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..c83e35d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "material-design-icons"] + path = material-design-icons + url = https://github.com/google/material-design-icons diff --git a/Makefile b/Makefile index 1b2beff..7e4a8d4 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,7 @@ -.PHONY: check install +.PHONY: setup check install + +setup: + ! [ -d wikilain/static/mdi ] && ln -s ../../material-design-icons/iconfont/ wikilain/static/mdi || true check: @mypy . || true diff --git a/README.md b/README.md index 6b8085e..ec30867 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ mistune mistune_contrib flask-sqlalchemy flask-migrate +pygments ``` ``` diff --git a/material-design-icons b/material-design-icons new file mode 160000 index 0000000..224895a --- /dev/null +++ b/material-design-icons @@ -0,0 +1 @@ +Subproject commit 224895a86501195e7a7ff3dde18e39f00b8e3d5a diff --git a/setup.py b/setup.py index 9c15bf9..45e7f2a 100644 --- a/setup.py +++ b/setup.py @@ -15,7 +15,8 @@ setup(name='wikilain', "mistune", "mistune_contrib", "flask-sqlalchemy", - "flask-migrate" + "flask-migrate", + "pygments" ], include_package_data=True, entry_points={ diff --git a/wikilain/__init__.py b/wikilain/__init__.py index b276726..0c8e17b 100644 --- a/wikilain/__init__.py +++ b/wikilain/__init__.py @@ -1,15 +1,29 @@ -from flask import Flask -from flask_sqlalchemy import SQLAlchemy -from flask_migrate import Migrate +from flask import Flask, render_template, g + +from .models import * +from .markdown import * +from .adapters.session_simple import session_provider app = Flask(__name__) -app.config["SQLALCHEMY_DATABASE_URI"] = 'sqlite:////tmp/test.db' +app.config["SECRET_KEY"] = "changeme" +app.config["SQLALCHEMY_DATABASE_URI"] = 'postgresql://@/wikilain_dev' app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False -from .models import db, migrate, User db.init_app(app) migrate.init_app(app, db) +app.register_blueprint(session_provider, url_prefix="/session") + + @app.route("/") def main_page(): - return "Hello and also world" + print(g.wl_user) + return render_template('index.html') + + +@app.route("/test") +def test_article(): + return render_template( + 'article.html', article_title="Sample Text", + article_content=md_render("# sample\n\nmeme and also\n\n\n---\nmeme $2+2$")) + diff --git a/wikilain/adapters/__init__.py b/wikilain/adapters/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/wikilain/adapters/session_simple.py b/wikilain/adapters/session_simple.py new file mode 100644 index 0000000..bf6661d --- /dev/null +++ b/wikilain/adapters/session_simple.py @@ -0,0 +1,49 @@ +from flask import Blueprint, session, request, render_template, redirect, g, flash +import secrets + +from ..models import User, db + +__all__ = ["session_provider"] + +session_provider = Blueprint("session_simple", __name__, template_folder='templates') + +@session_provider.before_app_request +def get_session_user(): + if session.get("username", None) is not None: + g.wl_user = User.query.filter_by(username=session["username"]).first() + else: + g.wl_user = None + + +@session_provider.route("/login", methods=["GET", "POST"]) +def login(): + old_csrf = session.get("_csrf", None) + csrf = secrets.token_urlsafe(32) + session["_csrf"] = csrf + + if g.wl_user is not None: + return redirect("/", code=302) + + if request.method == 'GET': + return render_template("login_form.html", csrf=csrf) + else: + if not request.form["username"]: + flash("Must provide username", "error") + return render_template("login_form.html", csrf=csrf) + if old_csrf != request.form["_csrf"]: + flash("Invalid request", "error") + return render_template("login_form.html", csrf=csrf) + user = User.query.filter_by(username=request.form["username"]).first() + if not user: + db.session.add(User(username=request.form["username"], email=secrets.token_hex(8) + "@example.com")) + db.session.commit() + session["username"] = request.form["username"] + del session["_csrf"] + return redirect("/", code=302) + + +@session_provider.route("/logout", methods=["POST"]) +def logout(): + del session["username"] + del session["_csrf"] + return redirect("/", code=302) diff --git a/wikilain/adapters/templates/login_form.html b/wikilain/adapters/templates/login_form.html new file mode 100644 index 0000000..a1a7087 --- /dev/null +++ b/wikilain/adapters/templates/login_form.html @@ -0,0 +1,14 @@ +{% extends 'base.html' %} + +{% block title %} +Log In +{% endblock %} + +{% block content %} +

Log In

+
+ + + +
+{% endblock %} diff --git a/wikilain/markdown.py b/wikilain/markdown.py new file mode 100644 index 0000000..fe57848 --- /dev/null +++ b/wikilain/markdown.py @@ -0,0 +1,32 @@ +from mistune import Markdown, Renderer, InlineLexer, BlockLexer, BlockGrammar +from mistune_contrib.highlight import HighlightMixin +from mistune_contrib.math import MathBlockMixin, MathInlineMixin, MathRendererMixin +from flask import Markup + + +class WlInlineLexer(InlineLexer, MathInlineMixin): + def __init__(self, *args, **kwargs): + super(WlInlineLexer, self).__init__(*args, **kwargs) + self.enable_math() + + +class WlBlockLexer(BlockLexer, MathBlockMixin): + def __init__(self, *args, **kwargs): + super(WlBlockLexer, self).__init__(*args, **kwargs) + self.enable_math() + + +class WlRenderer(Renderer, MathRendererMixin, HighlightMixin): + def __init__(self): + super(WlRenderer, self).__init__(escape=True, use_xhtml=True) + + +renderer = WlRenderer() +inline = WlInlineLexer(renderer) +block = WlBlockLexer(BlockGrammar()) +markdown = Markdown(renderer=renderer, inline=inline, block=block) + +__all__ = ["md_render"] + +def md_render(*args, **kwargs): + return Markup(markdown(*args, **kwargs)) diff --git a/wikilain/models.py b/wikilain/models.py index f222048..e350808 100644 --- a/wikilain/models.py +++ b/wikilain/models.py @@ -5,9 +5,44 @@ db = SQLAlchemy() migrate = Migrate(None, db) class User(db.Model): + __tablename__ = "users" id = db.Column(db.Integer, primary_key=True) - username = db.Column(db.String(80), unique=True, nullable=False) - email = db.Column(db.String(120), unique=True, nullable=False) + username = db.Column(db.String, unique=True, nullable=False) + email = db.Column(db.String, unique=True, nullable=False) + avatar = db.Column(db.String, nullable=True) def __repr__(self): - return '' % self.username + return f"" + +class Section(db.Model): + __tablename__ = "sections" + id = db.Column(db.Integer, primary_key=True) + title = db.Column(db.String, unique=True, nullable=False) + articles = db.relationship("Article", backref="section", lazy=True) + + def __repr__(self): + return f"
" + +DEFAULT_SECTION = 1 + +class Article(db.Model): + __tablename__ = "articles" + id = db.Column(db.Integer, primary_key=True) + title = db.Column(db.String, unique=True, nullable=False) + section_id = db.Column(db.Integer, db.ForeignKey("sections.id"), nullable=False) + revisions = db.relationship("ArticleRevision", backref="article", lazy=True) + + def __repr__(self): + return f"
" + +class ArticleRevision(db.Model): + __tablename__ = "articlerevisions" + id = db.Column(db.Integer, primary_key=True) + article_id = db.Column(db.Integer, db.ForeignKey("articles.id"), nullable=False) + date = db.Column(db.DateTime, nullable=False) + user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False) + user = db.relationship("User", lazy=True) + content = db.Column(db.Text, nullable=False) + + def __repr__(self): + return f"" diff --git a/wikilain/static/mdi b/wikilain/static/mdi new file mode 120000 index 0000000..d6ee876 --- /dev/null +++ b/wikilain/static/mdi @@ -0,0 +1 @@ +../../material-design-icons/iconfont/ \ No newline at end of file diff --git a/wikilain/static/style.css b/wikilain/static/style.css new file mode 100644 index 0000000..599c8da --- /dev/null +++ b/wikilain/static/style.css @@ -0,0 +1,5 @@ +body { + height: 100%; + margin: 0; + padding: 0; +} diff --git a/wikilain/templates/article.html b/wikilain/templates/article.html new file mode 100644 index 0000000..9da3580 --- /dev/null +++ b/wikilain/templates/article.html @@ -0,0 +1,10 @@ +{% extends 'base.html' %} + +{% block title %} + {{ article_title }} +{% endblock %} + +{% block content %} +

{{ article_title }}

+ {{ article_content }} +{% endblock %} diff --git a/wikilain/templates/base.html b/wikilain/templates/base.html new file mode 100644 index 0000000..dcc6bec --- /dev/null +++ b/wikilain/templates/base.html @@ -0,0 +1,35 @@ + + + + + {% block title %}{% endblock %} - WikiLain + + + + + + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} +
+ {% for category, message in messages %} +
{{ message }}
+ {% endfor %} +
+ {% endif %} + {% endwith %} +
+ {% block content %}{% endblock %} +
+ + diff --git a/wikilain/templates/index.html b/wikilain/templates/index.html new file mode 100644 index 0000000..bf1c158 --- /dev/null +++ b/wikilain/templates/index.html @@ -0,0 +1,10 @@ +{% extends 'base.html' %} + +{% block title %} +Main Page +{% endblock %} + +{% block content %} +

Welcome to WikiLain

+

Sample and also text

+{% endblock %}