gdritter repos frony-ritter-designs / 12a9bee
Auto-format code Getty Ritter 4 years ago
2 changed file(s) with 209 addition(s) and 216 deletion(s). Collapse all Expand all
77
88 import storage
99
10 web.template.ALLOWED_AST_NODES.append('Constant')
10 web.template.ALLOWED_AST_NODES.append("Constant")
1111
1212 app = flask.Flask(__name__)
1313
1414
1515 class Templates:
16 '''
16 """
1717 Local module to contain mustache templates
18 '''
18 """
19
1920 renderer = pystache.Renderer(
20 missing_tags=pystache.common.MissingTags.strict,
21 search_dirs='templates',
21 missing_tags=pystache.common.MissingTags.strict, search_dirs="templates",
2222 )
2323
2424 def load_template(name):
2626 parsed = pystache.parse(f.read())
2727 return lambda stuff: Templates.renderer.render(parsed, stuff)
2828
29 main = load_template('main')
30 design_page = load_template('design_page')
31 design_tile = load_template('design_tile')
32 design_list = load_template('design_list')
29 main = load_template("main")
30 design_page = load_template("design_page")
31 design_tile = load_template("design_tile")
32 design_list = load_template("design_list")
3333
3434
3535 def slugify(string):
3636 def process(char):
37 if char in '- \n\t\f':
38 return '-'
37 if char in "- \n\t\f":
38 return "-"
3939 elif char.isalpha():
4040 return char.lower()
4141 else:
42 return ''
43 return ''.join(process(c) for c in string)[:40]
42 return ""
43
44 return "".join(process(c) for c in string)[:40]
4445
4546
4647 def thumb(img):
4849
4950
5051 def five(n):
51 return '{0:05}'.format(n)
52 return "{0:05}".format(n)
5253
5354
5455 db = storage.DB()
55 render = web.template.render('old_templates/',
56 globals=dict(markdown=markdown.markdown,
57 slugify=slugify,
58 all_categories=db.all_categories,
59 thumb=thumb,
60 five=five))
56 render = web.template.render(
57 "old_templates/",
58 globals=dict(
59 markdown=markdown.markdown,
60 slugify=slugify,
61 all_categories=db.all_categories,
62 thumb=thumb,
63 five=five,
64 ),
65 )
6166
6267
6368 def snip(text):
6469 if len(text) < 256:
6570 return text
6671 else:
67 return text[:256] + '...'
72 return text[:256] + "..."
6873
6974
7075 def main(func):
7176 def new_func(*args, **kwargs):
7277 title, content = func(*args, **kwargs)
73 return Templates.main({'title': title, 'content': content})
78 return Templates.main({"title": title, "content": content})
79
7480 new_func.__name__ = func.__name__
7581 return new_func
7682
7783
78 @app.route('/')
84 @app.route("/")
7985 @main
8086 def index():
81 pg = db.get_page('main')
82 return 'Frony Ritter Designs', markdown.markdown(pg.text)
83
84
85 @app.route('/design/<id>/<slug>/')
87 pg = db.get_page("main")
88 return "Frony Ritter Designs", markdown.markdown(pg.text)
89
90
91 @app.route("/design/<id>/<slug>/")
8692 @main
8793 def get_design(id, slug=None):
8894 design = db.get_design(int(id))
89 return 'Designs', Templates.design_page(design)
95 return "Designs", Templates.design_page(design)
96
9097
9198 # @app.route('/design/<id>/<slug>', method=['POST'])
9299 # def POST(self, id, slug='electric-boogaloo'):
109116 # raise web.redirect('/edit/design/{0:05}/slug/'.format(id, slug))
110117
111118
112 @app.route('/design/')
119 @app.route("/design/")
113120 @main
114121 def get_all_designs():
115 page = int(flask.request.args.get('page') or 0)
122 page = int(flask.request.args.get("page") or 0)
116123 data = db.get_all(page)
117 return ('Designs', Templates.design_list(data))
118
119
120 @app.route('/category/')
124 return ("Designs", Templates.design_list(data))
125
126
127 @app.route("/category/")
121128 @main
122129 def get_all_categories():
123130 categories = db.all_categories()
124 return 'Category', render.select_category(categories)
125
126
127 @app.route('/category/<cat>/')
131 return "Category", render.select_category(categories)
132
133
134 @app.route("/category/<cat>/")
128135 @main
129136 def get_category(cat):
130 page = int(flask.request.args.get('page') or 0)
137 page = int(flask.request.args.get("page") or 0)
131138 data = db.get_designs_by_category(cat, page)
132139 return (cat.capitalize(), Templates.design_list(data))
133140
134141
135 @app.route('/category/<cat>/tag/<tag>/')
142 @app.route("/category/<cat>/tag/<tag>/")
136143 @main
137144 def get_category_with_tag(cat, tag):
138 page = int(flask.request.args.get('page') or 0)
145 page = int(flask.request.args.get("page") or 0)
139146 data = db.get_designs_by_category_and_tag(cat, tag, page)
140147 return (cat.capitalize(), Templates.design_list(data))
141148
142149
143 @app.route('/tag/')
150 @app.route("/tag/")
144151 @main
145152 def get_all_tags():
146 tags = (
147 (t.tag, t.pretty(), t.count)
148 for t in sorted(db.get_all_tags()))
149 return 'All Tags', render.select_tag(tags)
150
151
152 @app.route('/tag/<tag>/')
153 tags = ((t.tag, t.pretty(), t.count) for t in sorted(db.get_all_tags()))
154 return "All Tags", render.select_tag(tags)
155
156
157 @app.route("/tag/<tag>/")
153158 @main
154159 def get_tag(tag):
155 pg_num = int(flask.request.args.get('page') or 0)
160 pg_num = int(flask.request.args.get("page") or 0)
156161 data = db.get_designs_by_tag(tag, pg_num)
157162 pg_min, pg_max = db.max_page_range_for_tag(tag)
158 pretty_tag = ' '.join(w.capitalize()
159 for w in tag.split('_'))
160 return (pretty_tag,
161 render.by_tag_list(
162 tag,
163 (render.design_tile(name, pics, 0, id)
164 for name, pics, desc, cat, id in data),
165 pg_num,
166 pg_num > pg_min,
167 pg_num < pg_max))
168
169
170 @app.route('/<name>/')
163 pretty_tag = " ".join(w.capitalize() for w in tag.split("_"))
164 return (
165 pretty_tag,
166 render.by_tag_list(
167 tag,
168 (
169 render.design_tile(name, pics, 0, id)
170 for name, pics, desc, cat, id in data
171 ),
172 pg_num,
173 pg_num > pg_min,
174 pg_num < pg_max,
175 ),
176 )
177
178
179 @app.route("/<name>/")
171180 @main
172181 def get_page(name):
173182 page = db.get_page(name)
404413 # app = web.application(urls, globals())
405414 # # web.wsgi.runwsgi = lambda func, addr=None: web.wsgi.runfcgi(func, addr)
406415
407 if __name__ == '__main__':
416 if __name__ == "__main__":
408417 app.run()
77
88 PER_PAGE = 16
99
10
1011 def slugify(string):
1112 def process(char):
12 if char in '- \n\t\f':
13 return '-'
13 if char in "- \n\t\f":
14 return "-"
1415 elif char.isalpha():
1516 return char.lower()
1617 else:
17 return ''
18 return ''.join(process(c) for c in string)[:40]
18 return ""
19
20 return "".join(process(c) for c in string)[:40]
1921
2022
2123 class Image(typing.NamedTuple):
2224 image: str
2325
2426 def thumb(self):
25 return self.image[:-4] + '_thumb' + self.image[-4:]
27 return self.image[:-4] + "_thumb" + self.image[-4:]
2628
2729
2830 class PageContent:
3638 if len(self.source) < 256:
3739 return self.source
3840 else:
39 return self.source[:256] + '...'
41 return self.source[:256] + "..."
4042
4143
4244 class PageRef(typing.NamedTuple):
6466 return self.images[0].thumb()
6567
6668 @classmethod
67 def list(cls, query_results) -> typing.List['Design']:
69 def list(cls, query_results) -> typing.List["Design"]:
6870 return [
6971 cls(
7072 title=d.title,
7274 description=d.description,
7375 category=d.cat_name,
7476 id=d.id,
75 ) for d in query_results]
77 )
78 for d in query_results
79 ]
7680
7781
7882 class Paginated(typing.NamedTuple):
8387
8488 @classmethod
8589 def paginate(
86 cls,
87 offset: int,
88 total: int,
89 contents: typing.List[Design],
90 ) -> 'Paginated':
90 cls, offset: int, total: int, contents: typing.List[Design],
91 ) -> "Paginated":
9192 last_page = total // PER_PAGE
92 next_page = PageRef(page=offset+1) if offset < last_page else None
93 prev_page = PageRef(page=offset-1) if offset > 0 else None
93 next_page = PageRef(page=offset + 1) if offset < last_page else None
94 prev_page = PageRef(page=offset - 1) if offset > 0 else None
9495 return cls(
9596 next_page=next_page,
9697 prev_page=prev_page,
104105 count: int
105106
106107 def pretty(self):
107 return ' '.join(w.capitalize() for w in self.tag.split())
108 return " ".join(w.capitalize() for w in self.tag.split())
108109
109110
110111 THUMB_SIZE = (100, 100)
111112
112113
113114 class DB:
114
115115 def __init__(self, per_page=16):
116 self._db = web.database(dbn='sqlite', db='frony.db')
116 self._db = web.database(dbn="sqlite", db="frony.db")
117117 self.per_page = PER_PAGE
118118 self.categories = {}
119119 self.photo_num = self.get_max_photo_num() + 1
120120
121121 def get_max_photo_num(self):
122122 n = 0
123 for file in os.listdir(os.path.join('static', 'photos')):
123 for file in os.listdir(os.path.join("static", "photos")):
124124 try:
125125 n = max(int(file[:5]), n)
126126 except:
128128 return n
129129
130130 def get_category_id(self, nm):
131 id = list(self._db.where('categories', name=nm))
131 id = list(self._db.where("categories", name=nm))
132132 return id and id[0].id
133133
134134 def all_categories(self):
135 categories = self._db.select('categories')
135 categories = self._db.select("categories")
136136 return [(c.name, c.id, c.nicename) for c in categories]
137137
138138 def get_category_name(self, id):
139139 if id in self.categories:
140140 return self.categories[id]
141141 else:
142 nm = list(self._db.where('categories', id=id))
142 nm = list(self._db.where("categories", id=id))
143143 if nm:
144144 self.categories[id] = nm[0].name
145 return nm and nm[0].name or 'unknown'
145 return nm and nm[0].name or "unknown"
146146
147147 def get_design(self, id):
148 d = list(self._db.where('designs', id=id))
148 d = list(self._db.where("designs", id=id))
149149 if not d:
150150 return None
151151 else:
152152 d = d[0]
153 return Design(title=d.title,
154 images=self.get_all_photos_for_design(d.id),
155 description=PageContent(d.description),
156 category=self.get_category_name(d.category),
157 id=d.id)
153 return Design(
154 title=d.title,
155 images=self.get_all_photos_for_design(d.id),
156 description=PageContent(d.description),
157 category=self.get_category_name(d.category),
158 id=d.id,
159 )
158160
159161 def put_design(self, id, title, description, category):
160 description = description.replace('\r\n', '\n')
162 description = description.replace("\r\n", "\n")
161163 self._db.update(
162 'designs',
163 where='id = $id',
164 "designs",
165 where="id = $id",
164166 vars=dict(id=id),
165167 title=title,
166168 description=description,
167 category=category
169 category=category,
168170 )
169171
170172 def get_photo_by_id(self, id):
171173 try:
172 return self._db.where('photos', id=id)[0].filename
174 return self._db.where("photos", id=id)[0].filename
173175 except:
174176 return None
175177
176178 def get_picture(self, id):
177179 try:
178 return Image((self._db.where('photos', design_id=id,
179 limit=1))[0].filename)
180 return Image((self._db.where("photos", design_id=id, limit=1))[0].filename)
180181 except:
181182 return None
182183
184185 if not pp:
185186 pp = self.per_page
186187 return [
187 Image(l) for l
188 in self._db.select('photos',
189 offset=offset * pp,
190 limit=pp,
191 order='id DESC')
188 Image(l)
189 for l in self._db.select(
190 "photos", offset=offset * pp, limit=pp, order="id DESC"
191 )
192192 ]
193193
194194 def get_all_photos_for_design(self, id):
195 return list(Image(d.filename) for d in self._db.where('photos',
196 design_id=id))
195 return list(Image(d.filename) for d in self._db.where("photos", design_id=id))
197196
198197 def get_all(self, offset=0):
199198 ds = self._db.query(
200 '''select d.title, d.description, d.id, c.name as cat_name,
199 """select d.title, d.description, d.id, c.name as cat_name,
201200 (select filename from photos where photos.design_id = d.id limit 1) as image
202201 from designs d, categories c
203202 where d.category = c.id
204203 order by d.id desc
205 limit $per_page offset $offset''',
204 limit $per_page offset $offset""",
206205 vars={"per_page": PER_PAGE, "offset": offset},
207206 )
208 total = self._db.query('select count(*) as c from designs')
207 total = self._db.query("select count(*) as c from designs")
209208 return Paginated.paginate(offset, total[0].c, Design.list(ds))
210209
211210 def get_designs_by_category(self, cat, offset=0):
212211 ds = self._db.query(
213 '''select d.title, d.description, d.id, c.name as cat_name,
212 """select d.title, d.description, d.id, c.name as cat_name,
214213 (select filename from photos where photos.design_id = d.id limit 1) as image
215214 from designs d, categories c
216215 where d.category = c.id
217216 and c.name = $cat
218217 order by d.id desc
219 limit $per_page offset $offset''',
218 limit $per_page offset $offset""",
220219 vars={"cat": cat, "per_page": PER_PAGE, "offset": offset},
221220 )
222221 total = self._db.query(
223 '''select count(*) as c from designs d, categories c
224 where d.category = c.id and c.name = $cat''',
225 vars={"cat": cat})
222 """select count(*) as c from designs d, categories c
223 where d.category = c.id and c.name = $cat""",
224 vars={"cat": cat},
225 )
226226 return Paginated.paginate(offset, total[0].c, Design.list(ds))
227227
228228 def get_designs_by_category_and_tag(self, cat, tag, offset=0):
229229 ds = self._db.query(
230 '''select d.title, d.description, d.id, c.name as cat_name,
230 """select d.title, d.description, d.id, c.name as cat_name,
231231 (select filename from photos where photos.design_id = d.id limit 1) as image
232232 from designs d, tags t, categories c
233233 where t.tag_name = $tag
235235 and c.name = $cat
236236 and d.id = t.design_id
237237 order by d.id desc
238 limit $per_page offset $offset''',
239 vars=dict(tag=tag,
240 cat=cat,
241 offset=offset * self.per_page,
242 per_page=self.per_page))
238 limit $per_page offset $offset""",
239 vars=dict(
240 tag=tag, cat=cat, offset=offset * self.per_page, per_page=self.per_page
241 ),
242 )
243243 total = self._db.query(
244 '''select count(*) as c from designs, tags, categories
244 """select count(*) as c from designs, tags, categories
245245 where designs.category = categories.id
246246 and categories.name = $cat
247247 and tags.tag_name = $tag
248 and designs.id = tags.design_id''',
249 vars=dict(tag=tag, cat=cat))
248 and designs.id = tags.design_id""",
249 vars=dict(tag=tag, cat=cat),
250 )
250251 return Paginated.paginate(offset, total[0].c, Design.list(ds))
251252
252253 def new_design(self):
253 new_id = self._db.query(
254 'select max(id) as n from designs')[0].n + 1
254 new_id = self._db.query("select max(id) as n from designs")[0].n + 1
255255 self._db.insert(
256 'designs',
257 id=new_id,
258 title='New Design',
259 description='',
260 category=0)
256 "designs", id=new_id, title="New Design", description="", category=0
257 )
261258 return new_id
262259
263260 def delete_design(self, id):
264 self._db.delete(
265 'designs',
266 where='id = $id',
267 vars=dict(id=id))
261 self._db.delete("designs", where="id = $id", vars=dict(id=id))
268262
269263 def add_file(self, file):
270 new_id = (self._db.query('select max(id) as n from files')[0].n + 1)
264 new_id = self._db.query("select max(id) as n from files")[0].n + 1
271265 extn = file.filename.split()[-1]
272 name = '{0:05}.{1}'.format(new_id, extn)
273 path = '/' + os.path.join('srv', 'http', 'frd',
274 'static', 'files', name)
266 name = "{0:05}.{1}".format(new_id, extn)
267 path = "/" + os.path.join("srv", "http", "frd", "static", "files", name)
275268 self.file_num = self.get_max_file_num() + 1
276 with open(path, 'rb') as f:
269 with open(path, "rb") as f:
277270 f.write(file.file)
278271 return new_id
279272
280273 def all_files(self):
281 return list(self._db.where(''))
274 return list(self._db.where(""))
282275
283276 def add_photo(self, file, d_id):
284277 self.photo_num = self.get_max_photo_num() + 1
285 new_id = (self._db.query(
286 'select max(id) as n from photos')[0].n + 1)
278 new_id = self._db.query("select max(id) as n from photos")[0].n + 1
287279 new_num = self.photo_num
288280 self.photo_num += 1
289281 extension = file.filename[-3:]
290 name = '{0:05}.{1}'.format(new_num, extension)
291 thumb = '{0:05}_thumb.{1}'.format(new_num, extension)
282 name = "{0:05}.{1}".format(new_num, extension)
283 thumb = "{0:05}_thumb.{1}".format(new_num, extension)
292284 img = Image.open(file.file)
293285 img.thumbnail((400, 400), Image.ANTIALIAS)
294 img.save('/' + os.path.join('srv', 'http',
295 'frd', 'static', 'photos', name))
286 img.save("/" + os.path.join("srv", "http", "frd", "static", "photos", name))
296287 img.thumbnail(THUMB_SIZE, Image.ANTIALIAS)
297 img.save(os.path.join('static', 'photos', thumb))
298 self._db.insert(
299 'photos',
300 id=new_id,
301 filename=name,
302 design_id=d_id)
288 img.save(os.path.join("static", "photos", thumb))
289 self._db.insert("photos", id=new_id, filename=name, design_id=d_id)
303290 return new_id
304291
305292 def delete_photo(self, photo_name):
306293 self._db.delete(
307 'photos',
308 where='filename = $filename',
309 vars=dict(filename=photo_name))
294 "photos", where="filename = $filename", vars=dict(filename=photo_name)
295 )
310296
311297 def max_photo_page_ranges(self):
312 num_designs = self._db.query(
313 'select count(*) as n from photos')[0].n
298 num_designs = self._db.query("select count(*) as n from photos")[0].n
314299 return (0, (num_designs // self.per_page))
315300
316301 def max_page_ranges(self):
317 num_designs = self._db.query(
318 'select count(*) as n from designs')[0].n
302 num_designs = self._db.query("select count(*) as n from designs")[0].n
319303 return (0, (num_designs // self.per_page))
320304
321305 def max_page_range_for_category(self, cat):
322306 cat_id = self.get_category_id(cat)
323307 num_designs = self._db.query(
324 'select count(*) as n from designs where category = $cat',
325 vars=dict(cat=cat_id))[0].n
308 "select count(*) as n from designs where category = $cat",
309 vars=dict(cat=cat_id),
310 )[0].n
326311 return (0, 1 + (num_designs // self.per_page))
327312
328313 def get_all_tags(self):
329314 return [
330 Tag(t.tag_name, t.n) for t in
331 self._db.query('select t.tag_name, count(*) as n '
332 'from designs d, tags t '
333 'where d.id = t.design_id '
334 'group by t.tag_name')
315 Tag(t.tag_name, t.n)
316 for t in self._db.query(
317 "select t.tag_name, count(*) as n "
318 "from designs d, tags t "
319 "where d.id = t.design_id "
320 "group by t.tag_name"
321 )
335322 ]
336323
337324 def get_designs_by_tag(self, tag, offset=0):
338325 ds = self._db.query(
339 '''select * from designs, tags
326 """select * from designs, tags
340327 where tags.tag_name = $tag
341328 and designs.id = tags.design_id
342329 order by designs.id desc
343 limit $per_page offset $offset''',
344 vars=dict(tag=tag,
345 offset=offset * self.per_page,
346 per_page=self.per_page))
347
348 return ((d.title,
349 self.get_picture(d.design_id),
350 d.description,
351 self.get_category_name(d.category),
352 d.design_id) for d in ds)
330 limit $per_page offset $offset""",
331 vars=dict(tag=tag, offset=offset * self.per_page, per_page=self.per_page),
332 )
333
334 return (
335 (
336 d.title,
337 self.get_picture(d.design_id),
338 d.description,
339 self.get_category_name(d.category),
340 d.design_id,
341 )
342 for d in ds
343 )
353344
354345 def get_tags_for_design(self, design_id):
355346 return [
356 t.tag_name for t in
357 self._db.select(
358 'tags',
359 what='tag_name',
360 where='design_id = $d_id',
361 vars=dict(d_id=design_id))]
347 t.tag_name
348 for t in self._db.select(
349 "tags",
350 what="tag_name",
351 where="design_id = $d_id",
352 vars=dict(d_id=design_id),
353 )
354 ]
362355
363356 def process_tag_list(self, design_id, tag_string):
364357 new_tag_id = (
365 lambda: (self._db.query(
366 'select max(id) as n from tags')[0].n or 0) + 1)
358 lambda: (self._db.query("select max(id) as n from tags")[0].n or 0) + 1
359 )
367360 tag_list = tag_string.lower().split()
368 self._db.delete(
369 'tags', where='design_id = $d_id',
370 vars=dict(d_id=design_id))
361 self._db.delete("tags", where="design_id = $d_id", vars=dict(d_id=design_id))
371362 for t in tag_list:
372 self._db.insert(
373 'tags',
374 id=new_tag_id(),
375 tag_name=t,
376 design_id=design_id)
363 self._db.insert("tags", id=new_tag_id(), tag_name=t, design_id=design_id)
377364
378365 def max_page_range_for_tag(self, tag):
379366 num_designs = self._db.query(
380 'select count(*) as n from tags where tag_name = $t',
381 vars=dict(t=tag))[0].n
367 "select count(*) as n from tags where tag_name = $t", vars=dict(t=tag)
368 )[0].n
382369 return (0, (num_designs // self.per_page))
383370
384371 def num_for_tag(self, tag):
385372 return self._db.query(
386 'select count(*) as n from tags where tag_name = $t',
387 vars={'t': tag})[0].n
373 "select count(*) as n from tags where tag_name = $t", vars={"t": tag}
374 )[0].n
388375
389376 def get_about_text(self):
390 return self._db.where('pages', name='about')[0].text
377 return self._db.where("pages", name="about")[0].text
391378
392379 def set_about_text(self, text):
393 self._db.update('pages', where='name = \'about\'',
394 text=text)
380 self._db.update("pages", where="name = 'about'", text=text)
395381
396382 def get_page_list(self):
397 return self._db.query('select * from pages')
383 return self._db.query("select * from pages")
398384
399385 def add_page(self, name, title):
400 self._db.insert('pages', name=name, title=title, text='')
386 self._db.insert("pages", name=name, title=title, text="")
401387
402388 def get_page(self, name):
403 pg = list(self._db.where('pages', name=name))
389 pg = list(self._db.where("pages", name=name))
404390 if pg:
405391 return pg[0]
406392 else:
407 raise Exception('No page named {0}'.format(name))
393 raise Exception("No page named {0}".format(name))
408394
409395 def set_page(self, name, title, text):
410 self._db.update('pages',
411 where='name = $name',
412 title=title,
413 text=text,
414 vars={'name': name})
396 self._db.update(
397 "pages", where="name = $name", title=title, text=text, vars={"name": name}
398 )
415399
416400 def get_clacker(self, new_visitor=None):
417401 if new_visitor is not None:
418402 exists = self._db.query(
419 'select count(*) as n from visits where visitor = $v',
420 vars={'v': new_visitor})[0].n
403 "select count(*) as n from visits where visitor = $v",
404 vars={"v": new_visitor},
405 )[0].n
421406 else:
422407 exists = 1
423 total = self._db.query('select count(*) as n from visits')[0].n
408 total = self._db.query("select count(*) as n from visits")[0].n
424409 if exists == 0 and new_visitor:
425 self._db.insert('visits',
426 visitor=new_visitor)
410 self._db.insert("visits", visitor=new_visitor)
427411 return total + 1
428412 else:
429413 return total