changeset 809:22c6f6a3d0a0

admin: Add ability to upload page assets.
author Ludovic Chabant <ludovic@chabant.com>
date Sat, 17 Dec 2016 19:55:10 -0800
parents 8f2d32f90095
children 1952e2caeb64
files piecrust/admin/templates/edit_page.html piecrust/admin/views/edit.py piecrust/data/assetor.py
diffstat 3 files changed, 93 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/piecrust/admin/templates/edit_page.html	Sat Dec 17 19:54:52 2016 -0800
+++ b/piecrust/admin/templates/edit_page.html	Sat Dec 17 19:55:10 2016 -0800
@@ -16,7 +16,7 @@
 
     <div class="row">
         <div class="col-sm-6 col-sm-offset-1 col-xs-8">
-            <button type="submit" formtarget="_blank" name="do_preview" class="btn btn-info">Preview</button>
+            <a class="btn btn-info" href="{{url_preview}}">Preview</a>
             <a class="btn btn-danger" href="{{url_cancel}}">Cancel</a>
         </div>
         <div class="col-sm-4 col-xs-4">
@@ -57,5 +57,43 @@
         </div>
     </div>
 </form>
+
+<div class="row">
+    <div class="col-sm-10 col-sm-offset-1">
+        <h3>Assets</h3>
+        <p>Here are the assets you can use on this page with the <code>{%raw%}{{assets.foo}}{%endraw%}</code> syntax.</p>
+        {% if assets %}
+        <ul>
+        {% for a in assets %}
+            <li><a href="{{a.url}}">{{a.name}}</a></li>
+        {% endfor %}
+        </ul>
+        {% else %}
+        <p>...no assets...</p>
+        {% endif %}
+    </div>
+</div>
+
+<form action="{{url_upload_asset}}" method="POST" enctype="multipart/form-data" class="ft-upload-form" id="ft-upload-form">
+    <div class="row">
+        <div class="col-lg-6 col-sm-offset-1">
+            <p>Upload a new asset:</p>
+            <div class="form-group">
+                <div class="input-group">
+                    <input name="ft-asset-file" type="file"/>
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="input-group">
+                    <span class="input-group-addon" id="ft-label-asset-name">Name</span>
+                    <input name="ft-asset-name" type="text" class="form-control" placeholder="Optional asset name" aria-describedby="ft-label-asset-name"/>
+                </div>
+            </div>
+            <div class="form-group">
+                <input type="submit" value="Upload!" />
+            </div>
+        </div>
+    </div>
+</form>
 {% endblock %}
 
--- a/piecrust/admin/views/edit.py	Sat Dec 17 19:54:52 2016 -0800
+++ b/piecrust/admin/views/edit.py	Sat Dec 17 19:55:10 2016 -0800
@@ -1,8 +1,10 @@
 import os.path
 import logging
+from werkzeug.utils import secure_filename
 from flask import (
-        g, request, abort, render_template, url_for, flash)
+        g, request, abort, render_template, url_for, redirect, flash)
 from flask.ext.login import login_required
+from piecrust.data.assetor import Assetor
 from piecrust.rendering import (
         PageRenderingContext, render_page)
 from piecrust.serving.util import get_requested_page
@@ -30,8 +32,7 @@
         if request.form['is_dos_nl'] == '0':
             page_text = page_text.replace('\r\n', '\n')
 
-        if 'do_preview' in request.form or 'do_save' in request.form or \
-                'do_save_and_commit' in request.form:
+        if 'do_save' in request.form or 'do_save_and_commit' in request.form:
             logger.debug("Writing page: %s" % page.path)
             with open(page.path, 'w', encoding='utf8', newline='') as fp:
                 fp.write(page_text)
@@ -46,31 +47,67 @@
             if site.scm:
                 site.scm.commit([page.path], message)
 
-        if 'do_preview' in request.form:
-            return _preview_page(page)
-
         if 'do_save' in request.form or 'do_save_and_commit' in request.form:
-            return _edit_page_form(page)
+            return _edit_page_form(page, slug, site.name)
 
         abort(400)
 
-    return _edit_page_form(page)
+    return _edit_page_form(page, slug, site.name)
 
 
-def _preview_page(page):
-    render_ctx = PageRenderingContext(page, force_render=True)
-    rp = render_page(render_ctx)
-    return rp.content
+@foodtruck_bp.route('/upload/<path:slug>', methods=['POST'])
+def upload_page_asset(slug):
+    if 'ft-asset-file' not in request.files:
+        return redirect(url_for('.edit_page', slug=slug))
+
+    asset_file = request.files['ft-asset-file']
+    if asset_file.filename == '':
+        return redirect(url_for('.edit_page', slug=slug))
+
+    site = g.site
+    site_app = site.piecrust_app
+    rp = get_requested_page(site_app,
+                            '/site/%s/%s' % (g.sites.current_site, slug))
+    page = rp.qualified_page
+    if page is None:
+        abort(404)
+
+    filename = asset_file.filename
+    if request.form['ft-asset-name']:
+        _, ext = os.path.splitext(filename)
+        filename = request.form['ft-asset-name'] + ext
+    filename = secure_filename(filename)
+    dirname, _ = os.path.splitext(page.path)
+    dirname += '-assets'
+    if not os.path.exists(dirname):
+        os.makedirs(dirname)
+
+    asset_path = os.path.join(dirname, filename)
+    logger.info("Uploading file to: %s" % asset_path)
+    asset_file.save(asset_path)
+    return redirect(url_for('.edit_page', slug=slug))
 
 
-def _edit_page_form(page):
+def _edit_page_form(page, slug, sitename):
     data = {}
     data['is_new_page'] = False
-    data['url_cancel'] = url_for('.list_source', source_name=page.source.name)
+    data['url_postback'] = url_for('.edit_page', slug=slug)
+    data['url_upload_asset'] = url_for('.upload_page_asset', slug=slug)
+    data['url_preview'] = page.getUri()
+    data['url_cancel'] = url_for(
+        '.list_source', source_name=page.source.name)
     with open(page.path, 'r', encoding='utf8', newline='') as fp:
         data['page_text'] = fp.read()
     data['is_dos_nl'] = "1" if '\r\n' in data['page_text'] else "0"
 
+    page.app.env.base_asset_url_format = \
+        page.app.config.get('site/root') + '_asset/%path%'
+    assetor = Assetor(page, 'blah')
+    assets_data = []
+    for n in assetor.allNames():
+        assets_data.append({'name': n, 'url': assetor[n]})
+    data['assets'] = assets_data
+
     with_menu_context(data)
     return render_template('edit_page.html', **data)
 
--- a/piecrust/data/assetor.py	Sat Dec 17 19:54:52 2016 -0800
+++ b/piecrust/data/assetor.py	Sat Dec 17 19:55:10 2016 -0800
@@ -57,9 +57,9 @@
         self._cacheAssets()
         return map(lambda i: i[0], self._cache.values())
 
-    def _getFilenames(self):
-        assert self._cache is not None
-        return map(lambda i: i[1], self._cache.values())
+    def allNames(self):
+        self._cacheAssets()
+        return list(self._cache.keys())
 
     def _debugRenderAssetNames(self):
         self._cacheAssets()