diff foodtruck/views/main.py @ 587:d4a01a023998

admin: Add "FoodTruck" admin panel from the side experiment project.
author Ludovic Chabant <ludovic@chabant.com>
date Sat, 16 Jan 2016 14:24:35 -0800
parents
children 8f9cf1bcbe76
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/foodtruck/views/main.py	Sat Jan 16 14:24:35 2016 -0800
@@ -0,0 +1,155 @@
+import os
+import os.path
+import logging
+from flask import (
+        g, request,
+        render_template, url_for, redirect, make_response)
+from flask.ext.login import login_user, logout_user, login_required
+from piecrust.configuration import parse_config_header
+from piecrust.rendering import QualifiedPage
+from piecrust.uriutil import split_uri
+from ..views import with_menu_context
+from ..web import app, load_user, after_this_request
+
+
+logger = logging.getLogger(__name__)
+
+
+@app.route('/')
+@login_required
+def index():
+    data = {}
+    site_name = request.cookies.get('foodtruck_site_name')
+    site = g.sites.get(site_name)
+    assert site is not None
+
+    fs_endpoints = {}
+    data['sources'] = []
+    for source in site.piecrust_app.sources:
+        if source.is_theme_source:
+            continue
+        facs = source.getPageFactories()
+        src_data = {
+                'name': source.name,
+                'list_url': url_for('list_source', source_name=source.name),
+                'page_count': len(facs)}
+        data['sources'].append(src_data)
+
+        fe = getattr(source, 'fs_endpoint', None)
+        if fe:
+            fs_endpoints[fe] = source
+
+    st = site.scm.getStatus()
+    data['new_pages'] = []
+    for p in st.new_files:
+        pd = _getWipData(p, site, fs_endpoints)
+        if pd:
+            data['new_pages'].append(pd)
+    data['edited_pages'] = []
+    for p in st.edited_files:
+        pd = _getWipData(p, site, fs_endpoints)
+        if pd:
+            data['edited_pages'].append(pd)
+
+    data['site_name'] = site.name
+    data['url_bake'] = url_for('bake_site')
+    data['url_preview'] = url_for('preview_site_root', sitename=site.name)
+
+    data['sites'] = []
+    for k, v in g.config.get('sites').items():
+        data['sites'].append({
+            'name': k,
+            'display_name': v.get('name', k),
+            'url': url_for('index', site_name=site_name)
+            })
+    data['url_switch'] = url_for('switch_site')
+
+    with_menu_context(data)
+    return render_template('dashboard.html', **data)
+
+
+def _getWipData(path, site, fs_endpoints):
+    source = None
+    for endpoint, s in fs_endpoints.items():
+        if path.startswith(endpoint):
+            source = s
+            break
+    if source is None:
+        return None
+
+    fac = source.buildPageFactory(os.path.join(site.root_dir, path))
+    route = site.piecrust_app.getRoute(
+            source.name, fac.metadata, skip_taxonomies=True)
+    if not route:
+        return None
+
+    qp = QualifiedPage(fac.buildPage(), route, fac.metadata)
+    uri = qp.getUri()
+    _, slug = split_uri(site.piecrust_app, uri)
+
+    with open(fac.path, 'r', encoding='utf8') as fp:
+        raw_text = fp.read()
+
+    preferred_length = 100
+    max_length = 150
+    header, offset = parse_config_header(raw_text)
+    extract = raw_text[offset:offset + preferred_length]
+    if len(raw_text) > offset + preferred_length:
+        for i in range(offset + preferred_length,
+                       min(offset + max_length, len(raw_text))):
+            c = raw_text[i]
+            if c not in [' ', '\t', '\r', '\n']:
+                extract += c
+            else:
+                extract += '...'
+                break
+
+    return {
+            'title': qp.config.get('title'),
+            'slug': slug,
+            'url': url_for('edit_page', slug=slug),
+            'text': extract
+            }
+
+
+@login_required
+@app.route('/switch_site', methods=['POST'])
+def switch_site():
+    site_name = request.form.get('site_name')
+    if not site_name:
+        return redirect(url_for('index'))
+
+    @after_this_request
+    def _save_site(resp):
+        resp.set_cookie('foodtruck_site_name', site_name)
+
+    return redirect(url_for('index'))
+
+
+@app.route('/login', methods=['GET', 'POST'])
+def login():
+    data = {}
+
+    if request.method == 'POST':
+        username = request.form.get('username')
+        password = request.form.get('password')
+        remember = request.form.get('remember')
+
+        user = load_user(username)
+        if user is not None and app.bcrypt:
+            if app.bcrypt.check_password_hash(user.password, password):
+                login_user(user, remember=bool(remember))
+                return redirect(url_for('index'))
+        data['message'] = (
+                "User '%s' doesn't exist or password is incorrect." %
+                username)
+
+    return render_template('login.html', **data)
+
+
+@app.route('/logout')
+@login_required
+def logout():
+    logout_user()
+    return redirect(url_for('index'))
+