Add all the code

master
Raoul Snyman 2021-11-04 20:58:35 -07:00
parent 105934eccb
commit 2e2ea9a72c
11 changed files with 212 additions and 0 deletions

View File

@ -0,0 +1,3 @@
from libertywiki.app import get_app
__all__ = ['get_app']

View File

@ -0,0 +1,5 @@
#!/usr/bin/env python3
from libertywiki import get_app
if __name__ == "__main__":
get_app().run(port=8080, debug=True)

26
libertywiki/app.py 100644
View File

@ -0,0 +1,26 @@
from flask import Flask
from rst2html import rst2html
from libertywiki.db import db
from libertywiki.views import wiki
def get_app():
"""Create and configure the application object"""
app = Flask(__name__)
db.init_app(app)
with app.app_context():
db.create_all()
@app.template_filter('rst2html')
def rst2html_filter(text):
html, warning = rst2html(text)
print(html)
print(warning)
return html
app.register_blueprint(wiki)
return app

17
libertywiki/db.py 100644
View File

@ -0,0 +1,17 @@
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
Model = db.Model
Boolean = db.Boolean
Column = db.Column
DateTime = db.DateTime
Float = db.Float
ForeignKey = db.ForeignKey
Integer = db.Integer
LargeBinary = db.LargeBinary
Table = db.Table
String = db.String
Text = db.Text
relationship = db.relationship
inspect = db.inspect
session = db.session

View File

@ -0,0 +1,45 @@
from datetime import datetime
from sqlalchemy.ext.hybrid import hybrid_property
from libertywiki.db import Model, Column, ForeignKey, DateTime, Integer, String, Text
from libertywiki.utils import bcrypt
class Page(Model):
"""
Page model
"""
__tablename__ = 'pages'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('users.id'))
title = Column(String(255), nullable=False)
body = Column(Text)
slug = Column(String(255), nullable=False, index=True, unique=True)
created = Column(DateTime, default=datetime.now())
modified = Column(DateTime, default=datetime.now())
def __str__(self):
return self.title
class User(Model):
"""
User model
"""
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(255))
email = Column(String(255), nullable=False, index=True, unique=True)
_password = Column('password', String(255), nullable=False)
activation_code = Column(String(255))
@hybrid_property
def password(self):
return self.password
@password.setter
def password(self, value):
self._password = bcrypt.generate_password_hash(value)

View File

@ -0,0 +1,32 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Wiki</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<style type="text/css">
body {
min-height: 75rem;
padding-top: 4.5rem;
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
<div class="container">
<a class="navbar-brand d-flex" href="/">Wiki</a>
<form class="d-flex">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</nav>
<main class="container">
{% block content %}{% endblock %}
</main>
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</body>
</html>

View File

@ -0,0 +1,18 @@
{% extends 'base.html' %}
{% block content %}
<article class="edit-page">
<form action="{{ request.root_path + request.path }}" method="post">
<div class="mb-3">
<label for="page-title" class="form-label">Title</label>
<input type="text" class="form-control" id="page-title" name="page-title" aria-describedby="page-title-help" value="{{ page.title }}">
<div id="page-title-help" class="form-text">The title of the page</div>
</div>
<div class="mb-3">
<label for="page-body" class="form-label">Body</label>
<textarea id="page-body" name="page-body" class="form-control font-monospace" aria-describedby="page-body-help">{% if page.body %}{{ page.body }}{% endif %}</textarea>
<div id="page-body-help" class="form-text">The content of the page, in reStructuredText</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</article>
{% endblock %}

View File

@ -0,0 +1,19 @@
{% extends 'base.html' %}
{% block content %}
<article class="{{page.slug}}">
<ul class="nav nav-tabs">
<li class="nav-item">
<span class="nav-link active" aria-current="page">Article</span>
</li>
<li class="nav-item">
<a class="nav-link" href="/{{page.slug}}/edit">Edit</a>
</li>
</ul>
<h1 class="display-6 border-bottom">{{ page.title }}</h1>
<div class="row">
<div class="col">
{{ page.body | rst2html | safe }}
</div>
</div>
</article>
{% endblock %}

View File

@ -0,0 +1,6 @@
from flask_bcrypt import Bcrypt
bcrypt = Bcrypt()
__all__ = ['bcrypt']

View File

@ -0,0 +1,39 @@
from datetime import datetime
from flask import Blueprint, request, render_template, redirect
from libertywiki.db import session
from libertywiki.models import Page
wiki = Blueprint('wiki', __name__, url_prefix='')
@wiki.route('/', defaults={'path': 'Main_Page'}, methods=['GET'])
@wiki.route('/<path:path>', methods=['GET'])
def index(path=None):
page = Page.query.filter_by(slug=path).first()
if not page:
return redirect('/{}/edit'.format(path))
return render_template('page.html', page=page)
@wiki.route('/<path:path>/edit', methods=['GET'])
def edit(path):
page = Page.query.filter_by(slug=path).first()
if not page:
page = Page(title=path.replace('_', ' '))
return render_template('edit.html', page=page)
@wiki.route("/<path:path>/edit", methods=['POST'])
def save(path):
page = Page.query.filter_by(slug=path).first()
if not page:
page = Page()
page.title = request.form.get('page-title')
page.body = request.form.get('page-body')
page.slug = page.title.replace(' ', '_')
page.modified = datetime.now()
session.add(page)
session.commit()
return redirect('/{}'.format(page.slug))

2
setup.cfg 100644
View File

@ -0,0 +1,2 @@
[flake8]
max-line-length = 120