comparison 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
comparison
equal deleted inserted replaced
586:59268b4d8c71 587:d4a01a023998
1 import os
2 import os.path
3 import logging
4 from flask import (
5 g, request,
6 render_template, url_for, redirect, make_response)
7 from flask.ext.login import login_user, logout_user, login_required
8 from piecrust.configuration import parse_config_header
9 from piecrust.rendering import QualifiedPage
10 from piecrust.uriutil import split_uri
11 from ..views import with_menu_context
12 from ..web import app, load_user, after_this_request
13
14
15 logger = logging.getLogger(__name__)
16
17
18 @app.route('/')
19 @login_required
20 def index():
21 data = {}
22 site_name = request.cookies.get('foodtruck_site_name')
23 site = g.sites.get(site_name)
24 assert site is not None
25
26 fs_endpoints = {}
27 data['sources'] = []
28 for source in site.piecrust_app.sources:
29 if source.is_theme_source:
30 continue
31 facs = source.getPageFactories()
32 src_data = {
33 'name': source.name,
34 'list_url': url_for('list_source', source_name=source.name),
35 'page_count': len(facs)}
36 data['sources'].append(src_data)
37
38 fe = getattr(source, 'fs_endpoint', None)
39 if fe:
40 fs_endpoints[fe] = source
41
42 st = site.scm.getStatus()
43 data['new_pages'] = []
44 for p in st.new_files:
45 pd = _getWipData(p, site, fs_endpoints)
46 if pd:
47 data['new_pages'].append(pd)
48 data['edited_pages'] = []
49 for p in st.edited_files:
50 pd = _getWipData(p, site, fs_endpoints)
51 if pd:
52 data['edited_pages'].append(pd)
53
54 data['site_name'] = site.name
55 data['url_bake'] = url_for('bake_site')
56 data['url_preview'] = url_for('preview_site_root', sitename=site.name)
57
58 data['sites'] = []
59 for k, v in g.config.get('sites').items():
60 data['sites'].append({
61 'name': k,
62 'display_name': v.get('name', k),
63 'url': url_for('index', site_name=site_name)
64 })
65 data['url_switch'] = url_for('switch_site')
66
67 with_menu_context(data)
68 return render_template('dashboard.html', **data)
69
70
71 def _getWipData(path, site, fs_endpoints):
72 source = None
73 for endpoint, s in fs_endpoints.items():
74 if path.startswith(endpoint):
75 source = s
76 break
77 if source is None:
78 return None
79
80 fac = source.buildPageFactory(os.path.join(site.root_dir, path))
81 route = site.piecrust_app.getRoute(
82 source.name, fac.metadata, skip_taxonomies=True)
83 if not route:
84 return None
85
86 qp = QualifiedPage(fac.buildPage(), route, fac.metadata)
87 uri = qp.getUri()
88 _, slug = split_uri(site.piecrust_app, uri)
89
90 with open(fac.path, 'r', encoding='utf8') as fp:
91 raw_text = fp.read()
92
93 preferred_length = 100
94 max_length = 150
95 header, offset = parse_config_header(raw_text)
96 extract = raw_text[offset:offset + preferred_length]
97 if len(raw_text) > offset + preferred_length:
98 for i in range(offset + preferred_length,
99 min(offset + max_length, len(raw_text))):
100 c = raw_text[i]
101 if c not in [' ', '\t', '\r', '\n']:
102 extract += c
103 else:
104 extract += '...'
105 break
106
107 return {
108 'title': qp.config.get('title'),
109 'slug': slug,
110 'url': url_for('edit_page', slug=slug),
111 'text': extract
112 }
113
114
115 @login_required
116 @app.route('/switch_site', methods=['POST'])
117 def switch_site():
118 site_name = request.form.get('site_name')
119 if not site_name:
120 return redirect(url_for('index'))
121
122 @after_this_request
123 def _save_site(resp):
124 resp.set_cookie('foodtruck_site_name', site_name)
125
126 return redirect(url_for('index'))
127
128
129 @app.route('/login', methods=['GET', 'POST'])
130 def login():
131 data = {}
132
133 if request.method == 'POST':
134 username = request.form.get('username')
135 password = request.form.get('password')
136 remember = request.form.get('remember')
137
138 user = load_user(username)
139 if user is not None and app.bcrypt:
140 if app.bcrypt.check_password_hash(user.password, password):
141 login_user(user, remember=bool(remember))
142 return redirect(url_for('index'))
143 data['message'] = (
144 "User '%s' doesn't exist or password is incorrect." %
145 username)
146
147 return render_template('login.html', **data)
148
149
150 @app.route('/logout')
151 @login_required
152 def logout():
153 logout_user()
154 return redirect(url_for('index'))
155