Introduce flask_arrest, fix dotenv loading (Apache), and new template macro "nl.jinja2"
This commit is contained in:
parent
910e01b691
commit
acf918f656
10 changed files with 80 additions and 118 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -7,8 +7,8 @@ site-*.conf
|
|||
run_8180.py
|
||||
.env
|
||||
alembic.ini
|
||||
venv/
|
||||
venv-*/
|
||||
venv
|
||||
venv-*
|
||||
.venv
|
||||
env
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ suitable as a community or team knowledge base.
|
|||
## Requirements
|
||||
|
||||
+ **Python** 3.6+.
|
||||
+ **Flask** web framework (and Flask-Login / Flask-WTF extensions).
|
||||
+ **Flask** web framework (and Flask-Login / Flask-WTF / Flask-Arrest extensions).
|
||||
+ **Peewee** ORM.
|
||||
+ **Markdown** for page rendering.
|
||||
+ **Python-I18n**.
|
||||
|
|
|
|||
22
app.py
22
app.py
|
|
@ -17,6 +17,7 @@ from flask import (
|
|||
render_template, send_from_directory)
|
||||
from flask_login import LoginManager, login_user, logout_user, current_user, login_required
|
||||
from flask_wtf import CSRFProtect
|
||||
#from flask_arrest import RestBlueprint, serialize_response
|
||||
from werkzeug.security import generate_password_hash, check_password_hash
|
||||
from werkzeug.routing import BaseConverter
|
||||
from peewee import *
|
||||
|
|
@ -46,9 +47,9 @@ PING_RE = r'(?<!\w)@(' + USERNAME_RE + r')'
|
|||
|
||||
#### GENERAL CONFIG ####
|
||||
|
||||
dotenv.load_dotenv()
|
||||
dotenv.load_dotenv(os.path.join(APP_BASE_DIR, '.env'))
|
||||
|
||||
CONFIG_FILE = os.getenv('SALVI_CONF', APP_BASE_DIR + '/site.conf')
|
||||
CONFIG_FILE = os.getenv('SALVI_CONF', os.path.join(APP_BASE_DIR, 'site.conf'))
|
||||
|
||||
# security check: one may specify only configuration files INSIDE
|
||||
# the code directory.
|
||||
|
|
@ -96,7 +97,6 @@ def render_paginated_template(template_name, query_name, **kwargs):
|
|||
template_name,
|
||||
page_n = page,
|
||||
total_count = query.count(),
|
||||
min=min,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
|
|
@ -143,12 +143,6 @@ class BaseModel(Model):
|
|||
class Meta:
|
||||
database = database
|
||||
|
||||
# Used for PagePolicy
|
||||
def _passphrase_hash(pp):
|
||||
pp_bin = pp.encode('utf-8')
|
||||
h = str(len(pp_bin)) + ':' + hashlib.sha256(pp_bin).hexdigest()
|
||||
return h
|
||||
|
||||
class User(BaseModel):
|
||||
username = CharField(32, unique=True)
|
||||
email = CharField(256, null=True)
|
||||
|
|
@ -324,6 +318,12 @@ class Page(BaseModel):
|
|||
except Exception:
|
||||
pass
|
||||
return ", ".join(kw)
|
||||
|
||||
#def ldjson(self):
|
||||
# return {
|
||||
# "@context": "https://www.w3.org/ns/activitystreams",
|
||||
#
|
||||
# }
|
||||
|
||||
|
||||
class PageText(BaseModel):
|
||||
|
|
@ -657,13 +657,13 @@ def _before_request():
|
|||
|
||||
@app.context_processor
|
||||
def _inject_variables():
|
||||
|
||||
return {
|
||||
'T': partial(get_string, _get_lang()),
|
||||
'app_name': os.getenv("APP_NAME") or _getconf('site', 'title'),
|
||||
'strong': lambda x:Markup('<strong>{0}</strong>').format(x),
|
||||
'app_version': __version__,
|
||||
'material_icons_url': _getconf('site', 'material_icons_url')
|
||||
'material_icons_url': _getconf('site', 'material_icons_url'),
|
||||
'min': min
|
||||
}
|
||||
|
||||
@login_manager.user_loader
|
||||
|
|
|
|||
|
|
@ -3,4 +3,6 @@ peewee
|
|||
markdown
|
||||
flask-login
|
||||
flask-wtf
|
||||
python-i18n
|
||||
python-i18n
|
||||
flask-arrest
|
||||
python-dotenv
|
||||
|
|
|
|||
|
|
@ -13,8 +13,11 @@
|
|||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
||||
{% endif %}
|
||||
{% block json_info %}{% endblock %}
|
||||
{% block ldjson %}{% endblock %}
|
||||
</head>
|
||||
<body {% if request.cookies.get('dark') == '1' %}class="dark"{% endif %}>
|
||||
<body {% if request.cookies.get('dark') == '1' -%}
|
||||
class="dark"
|
||||
{%- endif %}>
|
||||
<div id="__top"></div>
|
||||
<header class="header">
|
||||
<span class="header-app-name"><a href="/">{{ app_name }}</a></span>
|
||||
|
|
|
|||
|
|
@ -15,33 +15,9 @@
|
|||
<h2>{{ T('latest-notes') }}</h2>
|
||||
|
||||
<br style="clear:both">
|
||||
<ul class="nl-list">
|
||||
{% for n in new_notes %}
|
||||
<li>
|
||||
<a href="{{ n.get_url() }}" class="nl-title">{{ n.title }}</a>
|
||||
<p class="nl-desc">{{ n.short_desc() }}</p>
|
||||
{% if n.tags %}
|
||||
<p class="nl-tags">
|
||||
<span class="material-icons">tag</span>
|
||||
{{ T('tags') }}:
|
||||
{% for tag in n.tags %}
|
||||
{% set tn = tag.name %}
|
||||
<a href="/tags/{{ tn }}/" class="nl-tag">#{{ tn }}</a>
|
||||
{% endfor %}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if n.calendar %}
|
||||
<p class="nl-calendar">
|
||||
<span class="material-icons">calendar_today</span>
|
||||
<a href="/calendar/{{ n.calendar.year }}/{{ n.calendar.month }}">
|
||||
<time datetime="{{ n.calendar.isoformat() }}">{{ n.calendar.strftime('%B %-d, %Y') }}</time>
|
||||
</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
<li class="nl-next"><a href="/p/most_recent/">{{ T('show-all') }}</a></li>
|
||||
</ul>
|
||||
|
||||
{% from "macros/nl.jinja2" import nl_list with context %}
|
||||
{{ nl_list(new_notes) }}
|
||||
|
||||
</article>
|
||||
|
||||
|
|
|
|||
|
|
@ -4,39 +4,7 @@
|
|||
<article>
|
||||
<h1 id="firstHeading">Notes by date</h1>
|
||||
|
||||
<p class="nl-pagination">Showing results <strong>{{ page_n * 20 - 19 }}</strong> to <strong>{{ min(page_n * 20, total_count) }}</strong> of <strong>{{ total_count }}</strong> total.</p>
|
||||
|
||||
<ul class="nl-list">
|
||||
{% if page_n > 1 %}
|
||||
<li class="nl-prev"><a href="/p/most_recent/{{ page_n - 1 }}">« Previous page</a></li>
|
||||
{% endif %}
|
||||
{% for n in notes %}
|
||||
<li>
|
||||
<a href="{{ n.get_url() }}" class="nl-title">{{ n.title }}</a>
|
||||
<p class="nl-desc">{{ n.short_desc() }}</p>
|
||||
{% if n.tags %}
|
||||
<p class="nl-tags">
|
||||
<span class="material-icons">tag</span>
|
||||
{{ T('tags') }}:
|
||||
{% for tag in n.tags %}
|
||||
{% set tn = tag.name %}
|
||||
<a href="/tags/{{ tn }}/" class="nl-tag">#{{ tn }}</a>
|
||||
{% endfor %}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if n.calendar %}
|
||||
<p class="nl-calendar">
|
||||
<span class="material-icons">calendar_today</span>
|
||||
<a href="/calendar/{{ n.calendar.year }}/{{ n.calendar.month }}">
|
||||
<time datetime="{{ n.calendar.isoformat() }}">{{ n.calendar.strftime('%B %-d, %Y') }}</time>
|
||||
</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% if page_n <= total_count // 20 %}
|
||||
<li class="nl-next"><a href="/p/most_recent/{{ page_n + 1 }}/">Next page »</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% from "macros/nl.jinja2" import nl_list with context %}
|
||||
{{ nl_list(notes, page_n=page_n, total_count=total_count) }}
|
||||
</article>
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -8,42 +8,8 @@
|
|||
<div class="preview-subtitle">{{ T('notes-tagged') }}</div>
|
||||
|
||||
{% if total_count > 0 %}
|
||||
<p class="nl-pagination">Showing results <strong>{{ page_n * 20 - 19 }}</strong> to <strong>{{ min(page_n * 20, total_count) }}</strong> of <strong>{{ total_count }}</strong> total.</p>
|
||||
|
||||
<ul class="nl-list">
|
||||
{% if page_n > 1 %}
|
||||
<li class="nl-prev"><a href="/tags/{{ tagname }}/{{ page_n - 1 }}/">« Previous page</a></li>
|
||||
{% endif %}
|
||||
{% for n in tagged_notes %}
|
||||
<li>
|
||||
<a href="{{ n.get_url() }}" class="nl-title">{{ n.title }}</a>
|
||||
<p class="nl-desc">{{ n.short_desc() }}</p>
|
||||
<p class="nl-tags">
|
||||
<span class="material-icons">tag</span>
|
||||
{{ T('tags') }}:
|
||||
{% for tag in n.tags %}
|
||||
{% set tn = tag.name %}
|
||||
{% if tn == tagname %}
|
||||
<strong class="nl-tag-hl">#{{ tn }}</strong>
|
||||
{% else %}
|
||||
<a href="/tags/{{ tn }}/" class="nl-tag">#{{ tn }}</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if n.calendar %}
|
||||
<p class="nl-calendar">
|
||||
<span class="material-icons">calendar_today</span>
|
||||
<a href="/calendar/{{ n.calendar.year }}/{{ n.calendar.month }}">
|
||||
<time datetime="{{ n.calendar.isoformat() }}">{{ n.calendar.strftime('%B %-d, %Y') }}</time>
|
||||
</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
</p>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% if page_n < total_count // 20 %}
|
||||
<li class="nl-next"><a href="/tags/{{ tagname }}/{{ page_n + 1 }}/">Next page »</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% from "macros/nl.jinja2" import nl_list with context %}
|
||||
{{ nl_list(l, page_n=page_n, total_count=total_count, hl_tags=(tagname,)) }}
|
||||
{% else %}
|
||||
<p class="nl-placeholder">{{ T('notes-tagged-empty') }}</p>
|
||||
{% endif %}
|
||||
|
|
|
|||
50
templates/macros/nl.jinja2
Normal file
50
templates/macros/nl.jinja2
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
|
||||
|
||||
{% macro nl_list(l, page_n=None, total_count=None, hl_tags=(), other_url='p/most_recent') %}
|
||||
{% if page_n and total_count %}
|
||||
<p class="nl-pagination">
|
||||
Showing results <strong>{{ page_n * 20 - 19 }}</strong> to <strong>{{ min(page_n * 20, total_count) }}</strong>
|
||||
of <strong>{{ total_count }}</strong> total.</p>
|
||||
{% endif %}
|
||||
|
||||
<ul class="nl-list">
|
||||
{% if page_n and page_n > 1 %}
|
||||
<li class="nl-prev"><a href="/{{ other_url }}/?page={{ page_n - 1 }}">« Previous page</a></li>
|
||||
{% endif %}
|
||||
{% for n in l %}
|
||||
<li>
|
||||
<a href="{{ n.get_url() }}" class="nl-title">{{ n.title }}</a>
|
||||
<p class="nl-desc">{{ n.short_desc() }}</p>
|
||||
{% if n.tags %}
|
||||
<p class="nl-tags">
|
||||
<span class="material-icons">tag</span>
|
||||
{{ T('tags') }}:
|
||||
{% for tag in n.tags %}
|
||||
{% set tn = tag.name %}
|
||||
{% if tn in hl_tags %}
|
||||
<strong class="nl-tag-hl">#{{ tn }}</strong>
|
||||
{% else %}
|
||||
<a href="/tags/{{ tn }}/" class="nl-tag">#{{ tn }}</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if n.calendar %}
|
||||
<p class="nl-calendar">
|
||||
<span class="material-icons">calendar_today</span>
|
||||
<a href="/calendar/{{ n.calendar.year }}/{{ n.calendar.month }}">
|
||||
<time datetime="{{ n.calendar.isoformat() }}">{{ n.calendar.strftime('%B %-d, %Y') }}</time>
|
||||
</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
||||
{% if page_n is none %}
|
||||
<li class="nl-next"><a href="/{{ other_url }}/">{{ T('show-all') }}</a></li>
|
||||
{% elif page_n <= total_count // 20 %}
|
||||
<li class="nl-next"><a href="/{{ other_url }}/?page={{ page_n + 1 }}">Next page »</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endmacro %}
|
||||
|
||||
|
|
@ -21,11 +21,8 @@
|
|||
{% if results %}
|
||||
<h2>Search results for <em>{{ q }}</em></h2>
|
||||
|
||||
<ul class="nl-list">
|
||||
{% for n in results %}
|
||||
<li>{% include "includes/nl_item.jinja2" %}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% from "macros/nl.jinja2" import nl_list with context %}
|
||||
{{ nl_list(l, other_url=None) }}
|
||||
{% elif q %}
|
||||
<h2>{{ T('search-no-results') }} <em>{{ q }}</em></h2>
|
||||
{% else %}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue