Password protection of admin pages, publish-switch and small fixes
This commit is contained in:
parent
149a5d4b24
commit
c3b0ce9537
@ -2,11 +2,13 @@ from flask import Flask
|
|||||||
from flask_bootstrap import Bootstrap
|
from flask_bootstrap import Bootstrap
|
||||||
from flaskext.markdown import Markdown
|
from flaskext.markdown import Markdown
|
||||||
from flask_sqlalchemy import SQLAlchemy
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
|
from flask_basicauth import BasicAuth
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.config.from_object('config')
|
app.config.from_object('config')
|
||||||
Bootstrap(app)
|
Bootstrap(app)
|
||||||
Markdown(app)
|
Markdown(app)
|
||||||
|
basic_auth = BasicAuth(app)
|
||||||
db = SQLAlchemy(app)
|
db = SQLAlchemy(app)
|
||||||
|
|
||||||
from . import views, models
|
from . import views, models
|
||||||
|
@ -10,11 +10,13 @@ class PageForm(FlaskForm):
|
|||||||
title = StringField('Title', validators=[DataRequired()])
|
title = StringField('Title', validators=[DataRequired()])
|
||||||
description = TextAreaField('Beskrivning')
|
description = TextAreaField('Beskrivning')
|
||||||
endpoint = BooleanField('Produkt')
|
endpoint = BooleanField('Produkt')
|
||||||
|
published = BooleanField('Publicerad')
|
||||||
thumbnail = QuerySelectField('Bild', get_label=lambda p: '{} ({})'.format(p.alt, p.id))
|
thumbnail = QuerySelectField('Bild', get_label=lambda p: '{} ({})'.format(p.alt, p.id))
|
||||||
photos = QuerySelectMultipleField('Galleri',
|
photos = QuerySelectMultipleField('Galleri',
|
||||||
option_widget=widgets.CheckboxInput(),
|
option_widget=widgets.CheckboxInput(),
|
||||||
widget=widgets.ListWidget(prefix_label=False),
|
widget=widgets.ListWidget(prefix_label=False),
|
||||||
get_label = lambda p: '<img src="/thumbnail/{}">'.format(p.id))
|
get_label = lambda p: '<img src="/thumbnail/{}">'.format(p.id))
|
||||||
|
parent = QuerySelectField('Kategori', get_label = lambda p: '{} - {}'.format(p.permalink, p.title))
|
||||||
submit = SubmitField('Ok')
|
submit = SubmitField('Ok')
|
||||||
|
|
||||||
class PhotoForm(FlaskForm):
|
class PhotoForm(FlaskForm):
|
||||||
|
@ -32,7 +32,8 @@ class Page(db.Model):
|
|||||||
thumbnail = db.relationship('Photo', secondary=thumbnails, uselist=False)
|
thumbnail = db.relationship('Photo', secondary=thumbnails, uselist=False)
|
||||||
photos = db.relationship('Photo', secondary=photos)
|
photos = db.relationship('Photo', secondary=photos)
|
||||||
|
|
||||||
endpoint = db.Column(db.Boolean)
|
endpoint = db.Column(db.Boolean, default=False)
|
||||||
|
published = db.Column(db.Boolean, default=False)
|
||||||
|
|
||||||
|
|
||||||
def update_permalink(self, name=None, parent_id=None):
|
def update_permalink(self, name=None, parent_id=None):
|
||||||
|
@ -40,6 +40,9 @@
|
|||||||
{% macro delete_button(type, title, id) -%}
|
{% macro delete_button(type, title, id) -%}
|
||||||
<button type="button" class="btn btn-danger" data-toggle="modal" data-target="#deletemodal" data-type="{{type}}" data-id="{{id}}" data-title="{{title}}"><span class="glyphicon glyphicon-remove"></button>
|
<button type="button" class="btn btn-danger" data-toggle="modal" data-target="#deletemodal" data-type="{{type}}" data-id="{{id}}" data-title="{{title}}"><span class="glyphicon glyphicon-remove"></button>
|
||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
|
{% macro glyphicon(icon) -%}
|
||||||
|
<span class="glyphicon glyphicon-{{icon}}"></span>
|
||||||
|
{%- endmacro %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="modal fade" id="deletemodal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"><!-- Delete modal -->
|
<div class="modal fade" id="deletemodal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"><!-- Delete modal -->
|
||||||
@ -73,6 +76,11 @@
|
|||||||
{% for page in pages recursive %}
|
{% for page in pages recursive %}
|
||||||
<div class="list-group-item">
|
<div class="list-group-item">
|
||||||
/{{ page.permalink }} - {{ page.title }}
|
/{{ page.permalink }} - {{ page.title }}
|
||||||
|
{% if page.published %}
|
||||||
|
<span class="glyphicon glyphicon-eye-open"></span>
|
||||||
|
{% else %}
|
||||||
|
<span class="glyphicon glyphicon-eye-close"></span>
|
||||||
|
{% endif %}
|
||||||
<a href="{{url_for('admin_page', id=page.id)}}" class="btn btn-default"><span class="glyphicon glyphicon-pencil"></a>
|
<a href="{{url_for('admin_page', id=page.id)}}" class="btn btn-default"><span class="glyphicon glyphicon-pencil"></a>
|
||||||
{% if page.endpoint %}
|
{% if page.endpoint %}
|
||||||
{% else %}
|
{% else %}
|
||||||
@ -145,17 +153,17 @@
|
|||||||
<script>
|
<script>
|
||||||
$('#deletemodal').on('show.bs.modal', function (event) {
|
$('#deletemodal').on('show.bs.modal', function (event) {
|
||||||
var button = $(event.relatedTarget)
|
var button = $(event.relatedTarget)
|
||||||
var type = button.data('type')
|
, type = button.data('type')
|
||||||
var id = button.data('id')
|
, id = button.data('id')
|
||||||
var title = button.data('title')
|
, title = button.data('title')
|
||||||
|
|
||||||
var modal = $(this)
|
var modal = $(this)
|
||||||
if(type == 'page') {
|
if(type == 'page') {
|
||||||
var message = 'Vill du verkligen ta bort sidan - ' + title + '?'
|
var message = 'Vill du verkligen ta bort sidan - ' + title + '?'
|
||||||
var href = '/admin/delpage/' + id
|
, href = '/admin/delpage/' + id
|
||||||
} else {
|
} else {
|
||||||
var message = 'Vill du verkligen ta bort bilden - ' + title + '?'
|
var message = 'Vill du verkligen ta bort bilden - ' + title + '?'
|
||||||
var href = '/admin/delphoto/' + id
|
, href = '/admin/delphoto/' + id
|
||||||
}
|
}
|
||||||
modal.find('.modal-body p').text(message)
|
modal.find('.modal-body p').text(message)
|
||||||
modal.find('.modal-footer a').attr('href', href)
|
modal.find('.modal-footer a').attr('href', href)
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
{{ wtf.form_field(form.title, form_type="horizontal") }}
|
{{ wtf.form_field(form.title, form_type="horizontal") }}
|
||||||
|
|
||||||
|
{{ wtf.form_field(form.parent, form_type="horizontal") }}
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-lg-2" for="description">Beskrivning</label>
|
<label class="control-label col-lg-2" for="description">Beskrivning</label>
|
||||||
<div class="col-lg-10">
|
<div class="col-lg-10">
|
||||||
@ -22,6 +24,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ wtf.form_field(form.endpoint, form_type="horizontal") }}
|
{{ wtf.form_field(form.endpoint, form_type="horizontal") }}
|
||||||
|
{{ wtf.form_field(form.published, form_type="horizontal") }}
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-lg-2" for="thumbnail">Bild</label>
|
<label class="control-label col-lg-2" for="thumbnail">Bild</label>
|
||||||
|
@ -44,14 +44,14 @@
|
|||||||
<div class="col-md-6 col-sm-12"> <!-- Content -->
|
<div class="col-md-6 col-sm-12"> <!-- Content -->
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="panel-title"> <h2>{{ page.title }}</h2> </div>
|
<!-- <div class="panel-title"> <h2>{{ page.title }}</h2> </div> -->
|
||||||
{{ page.description | markdown }}
|
{{ page.description | markdown }}
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-footer">
|
|
||||||
{% if page.endpoint %}
|
{% if page.endpoint %}
|
||||||
|
<div class="panel-footer">
|
||||||
<a href="mailto:order@designbyloven.se" class="btn btn-default"><span class="glyphicon glyphicon-envelope"></span> Beställ</a>
|
<a href="mailto:order@designbyloven.se" class="btn btn-default"><span class="glyphicon glyphicon-envelope"></span> Beställ</a>
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div> <!-- Content -->
|
</div> <!-- Content -->
|
||||||
</div> <!-- Content row -->
|
</div> <!-- Content row -->
|
||||||
@ -75,6 +75,7 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<div class="row"> <!-- Subsection list !-->
|
<div class="row"> <!-- Subsection list !-->
|
||||||
{% for c in page.children %}
|
{% for c in page.children %}
|
||||||
|
{% if c.published %}
|
||||||
<div class="col-xs-6 col-md-3">
|
<div class="col-xs-6 col-md-3">
|
||||||
<div class="thumbnail">
|
<div class="thumbnail">
|
||||||
<div class="caption" style="padding: 0;">
|
<div class="caption" style="padding: 0;">
|
||||||
@ -83,6 +84,7 @@
|
|||||||
<a href="{{ c.permalink }}"><img src="{{ c.thumbnail.thumbnail }}" class="img-responsive"></a>
|
<a href="{{ c.permalink }}"><img src="{{ c.thumbnail.thumbnail }}" class="img-responsive"></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div> <!-- Subsection list -->
|
</div> <!-- Subsection list -->
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
21
app/views.py
21
app/views.py
@ -1,7 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
from flask import render_template, send_from_directory, redirect, url_for, request, render_template_string
|
from flask import render_template, send_from_directory, redirect, url_for, request, render_template_string
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
from . import app, db
|
from . import app, db, basic_auth
|
||||||
from .models import Page, Photo
|
from .models import Page, Photo
|
||||||
from .forms import PageForm, PhotoForm
|
from .forms import PageForm, PhotoForm
|
||||||
|
|
||||||
@ -32,24 +32,37 @@ def favicon():
|
|||||||
|
|
||||||
|
|
||||||
@app.route('/admin')
|
@app.route('/admin')
|
||||||
|
@basic_auth.required
|
||||||
def admin():
|
def admin():
|
||||||
pages = [Page.query.first()]
|
pages = [Page.query.first()]
|
||||||
photos = Photo.query.all()
|
photos = Photo.query.all()
|
||||||
return render_template("admin.html", pages=pages, photos=photos)
|
return render_template("admin.html", pages=pages, photos=photos)
|
||||||
|
|
||||||
@app.route('/admin/page/<id>', methods=['GET', 'POST'])
|
@app.route('/admin/page/<id>', methods=['GET', 'POST'])
|
||||||
|
@basic_auth.required
|
||||||
def admin_page(id):
|
def admin_page(id):
|
||||||
page = Page.query.filter_by(id=id).first_or_404()
|
page = Page.query.filter_by(id=id).first_or_404()
|
||||||
form = PageForm(obj=page)
|
form = PageForm(obj=page)
|
||||||
form.thumbnail.query = form.photos.query = Photo.query.all()
|
form.thumbnail.query = form.photos.query = Photo.query.all()
|
||||||
|
form.parent.query = Page.query.filter_by(endpoint = False)
|
||||||
|
# print(form.parent.query)
|
||||||
|
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
|
print((form.parent.data))
|
||||||
|
if form.parent.data == page:
|
||||||
|
if page.id == 1:
|
||||||
|
print("Clearing")
|
||||||
|
form.parent.data = None
|
||||||
|
else:
|
||||||
|
print("Setting root")
|
||||||
|
form.parent.data = Page.query.filter_by(id=1).first()
|
||||||
form.populate_obj(page)
|
form.populate_obj(page)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return redirect(url_for('admin'))
|
return redirect(url_for('admin'))
|
||||||
else:
|
else:
|
||||||
return render_template('admin_page.html', page=page, form=form)
|
return render_template('admin_page.html', page=page, form=form)
|
||||||
@app.route('/admin/newpage/<parent>')
|
@app.route('/admin/newpage/<parent>')
|
||||||
|
@basic_auth.required
|
||||||
def admin_newpage(parent):
|
def admin_newpage(parent):
|
||||||
parent = Page.query.filter_by(id=parent).first_or_404()
|
parent = Page.query.filter_by(id=parent).first_or_404()
|
||||||
new = Page(name="child_{}".format(len(parent.children)+1), title="Ny sida", endpoint=True, parent=parent, parent_id=parent.id)
|
new = Page(name="child_{}".format(len(parent.children)+1), title="Ny sida", endpoint=True, parent=parent, parent_id=parent.id)
|
||||||
@ -59,6 +72,7 @@ def admin_newpage(parent):
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
return redirect(url_for('admin'))
|
return redirect(url_for('admin'))
|
||||||
@app.route('/admin/delpage/<id>')
|
@app.route('/admin/delpage/<id>')
|
||||||
|
@basic_auth.required
|
||||||
def admin_delpage(id):
|
def admin_delpage(id):
|
||||||
page = Page.query.filter_by(id=id).first_or_404()
|
page = Page.query.filter_by(id=id).first_or_404()
|
||||||
root = Page.query.filter_by(id=1).first()
|
root = Page.query.filter_by(id=1).first()
|
||||||
@ -70,6 +84,7 @@ def markdown():
|
|||||||
return render_template_string('{{ md | markdown }}', md=request.form['md'])
|
return render_template_string('{{ md | markdown }}', md=request.form['md'])
|
||||||
|
|
||||||
@app.route('/admin/upload', methods=['POST'])
|
@app.route('/admin/upload', methods=['POST'])
|
||||||
|
@basic_auth.required
|
||||||
def upload():
|
def upload():
|
||||||
from PIL import Image, ImageOps
|
from PIL import Image, ImageOps
|
||||||
def genimg(img, imgout, size):
|
def genimg(img, imgout, size):
|
||||||
@ -95,12 +110,13 @@ def upload():
|
|||||||
slide = os.path.join('app', 'photos', 'slides', filename)
|
slide = os.path.join('app', 'photos', 'slides', filename)
|
||||||
img.save(imgpath, 'JPEG')
|
img.save(imgpath, 'JPEG')
|
||||||
genimg(img, imgpath, img.size)
|
genimg(img, imgpath, img.size)
|
||||||
genimg(img, thumb, (171, 180))
|
|
||||||
genimg(img, slide, (550, 400))
|
genimg(img, slide, (550, 400))
|
||||||
|
genimg(img, thumb, (171, 180))
|
||||||
os.remove(tempname)
|
os.remove(tempname)
|
||||||
|
|
||||||
return redirect(url_for('admin'))
|
return redirect(url_for('admin'))
|
||||||
@app.route('/admin/delphoto/<id>')
|
@app.route('/admin/delphoto/<id>')
|
||||||
|
@basic_auth.required
|
||||||
def admin_delphoto(id):
|
def admin_delphoto(id):
|
||||||
photo = Photo.query.filter_by(id=id).first_or_404()
|
photo = Photo.query.filter_by(id=id).first_or_404()
|
||||||
db.session.delete(photo)
|
db.session.delete(photo)
|
||||||
@ -114,6 +130,7 @@ def admin_delphoto(id):
|
|||||||
os.remove(slide)
|
os.remove(slide)
|
||||||
return redirect(url_for('admin'))
|
return redirect(url_for('admin'))
|
||||||
@app.route('/admin/photo/<id>', methods=['GET', 'POST'])
|
@app.route('/admin/photo/<id>', methods=['GET', 'POST'])
|
||||||
|
@basic_auth.required
|
||||||
def admin_photo(id):
|
def admin_photo(id):
|
||||||
photo = Photo.query.filter_by(id=id).first_or_404()
|
photo = Photo.query.filter_by(id=id).first_or_404()
|
||||||
form = PhotoForm(obj=photo)
|
form = PhotoForm(obj=photo)
|
||||||
|
40
db_create.py
40
db_create.py
@ -4,32 +4,34 @@ from app import db, models
|
|||||||
|
|
||||||
db.create_all()
|
db.create_all()
|
||||||
|
|
||||||
ph1 = models.Photo(alt="Kuvertbody superman")
|
ph1 = models.Photo(alt="Design by Lovén")
|
||||||
ph2 = models.Photo(alt="Kuvertbody linjer")
|
# ph2 = models.Photo(alt="Kuvertbody linjer")
|
||||||
ph3 = models.Photo(alt="Kuvertbody Hedvig")
|
# ph3 = models.Photo(alt="Kuvertbody Hedvig")
|
||||||
|
|
||||||
index = models.Page(name="", title="Design by Lovén", description="Välkommen till *Design* by **Lovén**")
|
index = models.Page(name="", title="Design by Lovén", description="Välkommen till Design by Lovén.", thumbnail=ph1, published=True)
|
||||||
|
|
||||||
kuvertbody = models.Page(name="kuvertbody", title="Kuvertbody", description="An praktisk body som man kan dra av neråt", thumbnail=ph1)
|
# kuvertbody = models.Page(name="kuvertbody", title="Kuvertbody", description="An praktisk body som man kan dra av neråt", thumbnail=ph1)
|
||||||
linjer = models.Page(name="linjer", title="Kuvertbody - Linjer", description="Raka sömmar på framsidan", photos=[ph2, ph3], thumbnail=ph2, endpoint = True)
|
# linjer = models.Page(name="linjer", title="Kuvertbody - Linjer", description="Raka sömmar på framsidan", photos=[ph2, ph3], thumbnail=ph2, endpoint = True)
|
||||||
superman = models.Page(name="superman", title="Kuvertbody - Superman", description="Alla barn är superhjältar", photos=[ph1], thumbnail=ph1, endpoint = True)
|
# superman = models.Page(name="superman", title="Kuvertbody - Superman", description="Alla barn är superhjältar", photos=[ph1], thumbnail=ph1, endpoint = True)
|
||||||
|
|
||||||
index.children = [kuvertbody]
|
# index.children = [kuvertbody]
|
||||||
kuvertbody.children.append(linjer)
|
# kuvertbody.children.append(linjer)
|
||||||
kuvertbody.children.append(superman)
|
# kuvertbody.children.append(superman)
|
||||||
|
|
||||||
ph1.link = superman
|
# ph1.link = superman
|
||||||
ph2.link = linjer
|
# ph2.link = linjer
|
||||||
ph3.link = linjer
|
# ph3.link = linjer
|
||||||
|
|
||||||
|
|
||||||
db.session.add(ph1)
|
# db.session.add(ph1)
|
||||||
db.session.add(ph2)
|
# db.session.add(ph2)
|
||||||
db.session.add(ph3)
|
# db.session.add(ph3)
|
||||||
db.session.add(index)
|
db.session.add(index)
|
||||||
db.session.add(kuvertbody)
|
# db.session.add(kuvertbody)
|
||||||
db.session.add(linjer)
|
# db.session.add(linjer)
|
||||||
db.session.add(superman)
|
# db.session.add(superman)
|
||||||
|
db.session.commit()
|
||||||
|
index.name = "/"
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user