#!/usr/bin/env python
import flask
import markdown
import pystache
import sys
import web
import model
import storage
web.template.ALLOWED_AST_NODES.append("Constant")
app = flask.Flask(__name__)
class Templates:
"""
Local module to contain mustache templates
"""
renderer = pystache.Renderer(
missing_tags=pystache.common.MissingTags.strict, search_dirs="templates",
)
def load_template(name):
with open(f"templates/{name}.mustache") as f:
parsed = pystache.parse(f.read())
return lambda stuff: Templates.renderer.render(parsed, stuff)
main = load_template("main")
design_page = load_template("design_page")
design_list = load_template("design_list")
text_list = load_template("text_list")
edit_design_list = load_template("edit_design_list")
edit_design = load_template("edit_design")
delete_design = load_template("delete_design")
photo_upload = load_template("photo_upload")
photo_list = load_template("photo_list")
photo_tile = load_template("photo_tile")
photo_delete = load_template("photo_delete")
view_photo = load_template("view_photo")
edit_pages = load_template("edit_pages")
edit_page = load_template("edit_page")
db = storage.DB()
PER_PAGE = 16
def main(func):
def new_func(*args, **kwargs):
title, content = func(*args, **kwargs)
return Templates.main({"title": title, "content": content})
new_func.__name__ = func.__name__
return new_func
@app.route("/")
@main
def index():
return "Frony Ritter Designs", model.Page.get(name="main").rendered()
@app.route("/design/<id>/<_slug>/")
@main
def get_design(id, _slug=None):
design = model.Design.get(visible_id=id)
return "Designs", Templates.design_page(design)
@app.route("/api/design/<int:id>/")
def api_get_design(id: int):
return flask.jsonify(model.Design.get(visible_id=id).to_json())
# @app.route('/design/<id>/<slug>', method=['POST'])
# def POST(self, id, slug='electric-boogaloo'):
# try:
# id = int(id)
# except:
# raise web.redirect('/')
# input = dict(web.input())
# if ('title' in input and
# 'description' in input and
# 'category' in input and
# 'tags' in input):
# db.put_design(id,
# input['title'],
# input['description'],
# input['category'])
# db.process_tag_list(id, input['tags'])
# if not slug:
# slug = slugify(input['title'])
# raise web.redirect('/edit/design/{0:05}/slug/'.format(id, slug))
@app.route("/design/")
@main
def get_all_designs():
page = int(flask.request.args.get("page") or 0)
data = model.Design.get_where(page=page)
return "Designs", Templates.design_list(data)
@app.route("/category/")
@main
def get_all_categories():
return "Category", Templates.text_list(model.Category.all())
@app.route("/category/<cat>/")
@main
def get_category(cat):
page = int(flask.request.args.get("page") or 0)
data = model.Design.get_where(category=cat, page=page)
return cat.capitalize(), Templates.design_list(data)
@app.route("/category/<cat>/tag/<tag>/")
@main
def get_category_with_tag(cat, tag):
page = int(flask.request.args.get("page") or 0)
data = model.Design.get_where(tag=tag, category=cat, page=page)
return cat.capitalize(), Templates.design_list(data)
@app.route("/tag/")
@main
def get_all_tags():
return "All Tags", Templates.text_list(model.Tag.all())
@app.route("/tag/<tag>/")
@main
def get_tag(tag):
page = int(flask.request.args.get("page") or 0)
data = model.Design.get_where(tag=tag, page=page)
pretty_tag = " ".join(w.capitalize() for w in tag.split("_"))
return pretty_tag, Templates.design_list(data)
@app.route("/<name>/")
@main
def get_page(name):
page = model.Page.get(name=name)
return page.title, markdown.markdown(page.text)
@app.route("/edit/design/")
@main
def edit_all_designs():
page = int(flask.request.args.get("page") or 0)
data = model.Design.get_where(page=page)
return "Edit Mode", Templates.edit_design_list(data)
@app.route("/edit/design/", methods=["POST"])
def post_new_design():
id = model.Design.make_new()
return flask.redirect(f"/edit/design/{id:05}/")
@app.route("/edit/design/<id>/")
@main
def edit_design(id):
id = int(id)
design = model.Design.get(visible_id=id)
return (
"design",
Templates.edit_design(
{
"id": design.visible_id,
"title": design.title,
"tags": design.tags,
"all_tags": model.Tag.select(model.Tag.tag_name)
.distinct()
.order_by(model.Tag.tag_name),
"categories": design.category_list(),
"description": design.description,
"photos": design.photos,
"id_str": f"{design.visible_id:05}",
}
),
)
@app.route("/edit/design/<id>/", methods=["POST"])
def update_design(id):
id = int(id)
model.Design.get(visible_id=id).update_with(flask.request.get_json())
return flask.jsonify({"status": "ok"})
@app.route("/edit/delete/<id>/")
@main
def delete_design(id):
id = int(id)
design = model.Design.get(visible_id=id)
return (
"delete design",
Templates.delete_design({"title": design.title, "id_str": f"{design.visible_id:05}",}),
)
@app.route("/edit/delete/<id>/", methods=["POST"])
def do_delete_design(id):
model.Design.get(visible_id=id).delete_instance()
return flask.redirect(f"/edit/design/")
@app.route("/edit/photo/")
@main
def add_photo():
if "id" in flask.request.args:
id = flask.request.args.get("id")
return f"Add photo for design {id}", Templates.photo_upload({"id": id})
else:
return "Add generic photo", Templates.photo_upload({"id": -1})
@app.route("/edit/photo/", methods=["POST"])
def do_add_photo():
if "file" not in flask.request.files or "id" not in flask.request.form:
return flask.redirect("/edit/photo")
id = int(flask.request.form["id"])
file = flask.request.files["file"]
photo_id = model.Photo.upload(file, id)
if id == -1:
return flask.redirect(f"/edit/view-photo/{photo_id}")
else:
return flask.redirect(f"/edit/design/{id}")
@app.route("/edit/photo/<id>/")
@main
def modify_photo(id):
design_id = flask.request.args.get('design_id', -1)
return "Delete Photo", Templates.photo_delete({
"id": id,
"design_id": design_id
})
@app.route("/edit/photo/<id>/", methods=["POST"])
def do_modify_photo(id):
model.Photo.get(filename=id).delete_instance()
if (d_id := int(flask.request.form.get('design_id', -1))) != -1:
return flask.redirect(f"/edit/design/{d_id}/")
else:
return flask.redirect(f"/edit/design/")
@app.route("/edit/view-photo/")
@main
def view_all_photos():
page = int(flask.request.args.get("page", 1))
photos, p_min, p_max = model.Photo.get_all(page=page)
return (
"Photos",
Templates.photo_list(
{
"photos": ({"photo": Templates.photo_tile(p)} for p in photos),
"page": page,
"prev_page": page - 1,
"next_page": page + 1,
"show_left": page > p_min,
"show_right": page < p_max,
"last_page": p_max,
}
),
)
@app.route("/edit/view-photo/<id>/")
@main
def view_photo(id):
photo = model.Photo.get(filename=id)
if photo:
return f"Viewing photo {id}", Templates.view_photo(photo)
else:
raise Exception(f"Unable to find photo {id}")
@app.route("/edit/pages/")
@main
def edit_page_list():
return "Edit Page List", Templates.edit_pages({"pages": model.Page.select()})
@app.route("/edit/pages/<slug>/")
@main
def edit_page(slug):
page = model.Page.get(name=slug)
return (
f"Edit Page {slug}",
Templates.edit_page({"name": slug, "title": page.title, "text": page.text,}),
)
@app.route("/edit/pages/<slug>/", methods=["POST"])
def do_edit_page(slug):
text = flask.request.form.get("text", "")
title = flask.request.form.get("title", slug.capitalize())
model.Page.update(title=title, text=text).where(model.Page.name == slug).execute()
return flask.redirect(f"/edit/pages/{slug}")
if __name__ == "__main__":
app.run()