switch more stuff to Peewee
Getty Ritter
3 years ago
46 | 46 | |
47 | 47 | |
48 | 48 | db = storage.DB() |
49 | PER_PAGE = 16 | |
49 | 50 | |
50 | 51 | |
51 | 52 | def main(func): |
100 | 101 | @main |
101 | 102 | def get_all_designs(): |
102 | 103 | page = int(flask.request.args.get("page") or 0) |
103 |
data = |
|
104 | data = model.Design.get_where(page=page) | |
104 | 105 | return "Designs", Templates.design_list(data) |
105 | 106 | |
106 | 107 | |
107 | 108 | @app.route("/category/") |
108 | 109 | @main |
109 | 110 | def get_all_categories(): |
110 | categories = db.all_categories() | |
111 | return "Category", Templates.text_list(categories) | |
111 | return "Category", Templates.text_list(model.Category.all()) | |
112 | 112 | |
113 | 113 | |
114 | 114 | @app.route("/category/<cat>/") |
115 | 115 | @main |
116 | 116 | def get_category(cat): |
117 | 117 | page = int(flask.request.args.get("page") or 0) |
118 |
data = |
|
118 | data = model.Design.get_where(category=cat, page=page) | |
119 | 119 | return cat.capitalize(), Templates.design_list(data) |
120 | 120 | |
121 | 121 | |
123 | 123 | @main |
124 | 124 | def get_category_with_tag(cat, tag): |
125 | 125 | page = int(flask.request.args.get("page") or 0) |
126 |
data = |
|
126 | data = model.Design.get_where(tag=tag, category=cat, page=page) | |
127 | 127 | return cat.capitalize(), Templates.design_list(data) |
128 | 128 | |
129 | 129 | |
130 | 130 | @app.route("/tag/") |
131 | 131 | @main |
132 | 132 | def get_all_tags(): |
133 | tags = db.get_all_tags() | |
134 | return "All Tags", Templates.text_list(tags) | |
133 | return "All Tags", Templates.text_list(model.Tag.all()) | |
135 | 134 | |
136 | 135 | |
137 | 136 | @app.route("/tag/<tag>/") |
138 | 137 | @main |
139 | 138 | def get_tag(tag): |
140 | 139 | page = int(flask.request.args.get("page") or 0) |
141 |
data = |
|
140 | data = model.Design.get_where(tag=tag, page=page) | |
142 | 141 | pretty_tag = " ".join(w.capitalize() for w in tag.split("_")) |
143 | 142 | return pretty_tag, Templates.design_list(data) |
144 | 143 | |
154 | 153 | @main |
155 | 154 | def edit_all_designs(): |
156 | 155 | page = int(flask.request.args.get("page") or 0) |
157 | min, max = db.max_page_ranges() | |
158 | data = db.get_all(offset=page) | |
156 | data = model.Design.get_where(page=page) | |
159 | 157 | return "Edit Mode", Templates.edit_design_list(data) |
160 | 158 | |
161 | 159 | |
169 | 167 | @main |
170 | 168 | def edit_design(id): |
171 | 169 | id = int(id) |
172 |
|
|
170 | # design = db.get_design(id) | |
171 | design = model.Design.get(id=id) | |
173 | 172 | return ( |
174 | 173 | "design", |
175 | 174 | Templates.edit_design( |
176 | 175 | { |
177 | 176 | "id": design.id, |
178 | 177 | "title": design.title, |
179 | "tags": " ".join(design.tags(db)), | |
180 | "categories": design.category_list(db), | |
181 | "description": design.description.source, | |
182 | "photos": design.images, | |
178 | "tags": " ".join(t.tag_name for t in design.tags), | |
179 | "categories": design.category_list(), | |
180 | "description": design.description, | |
181 | "photos": ({"image": d} for d in design.photos), | |
183 | 182 | "id_str": f"{design.id:05}", |
184 | 183 | } |
185 | 184 | ), |
190 | 189 | @main |
191 | 190 | def delete_design(id): |
192 | 191 | id = int(id) |
193 |
design = |
|
192 | design = model.Design.get(id=id) | |
194 | 193 | return ( |
195 | 194 | "delete design", |
196 | 195 | Templates.delete_design({"title": design.title, "id_str": f"{design.id:05}",}), |
1 | from dataclasses import dataclass | |
1 | 2 | import markdown |
2 | 3 | import peewee |
3 | 4 | import typing |
4 | 5 | |
5 | 6 | db = peewee.SqliteDatabase("new.db") |
7 | PER_PAGE = 16 | |
8 | ||
9 | def slugify(string): | |
10 | def process(char): | |
11 | if char in "- \n\t\f": | |
12 | return "-" | |
13 | elif char.isalpha(): | |
14 | return char.lower() | |
15 | else: | |
16 | return "" | |
17 | ||
18 | return "".join(process(c) for c in string)[:40] | |
6 | 19 | |
7 | 20 | |
8 | 21 | class Model(peewee.Model): |
14 | 27 | name = peewee.TextField() |
15 | 28 | nicename = peewee.TextField() |
16 | 29 | |
30 | @classmethod | |
31 | def all(klass): | |
32 | elements = ({"url": f"/category/{c.name}", "name": c.nicename} for c in klass.select()) | |
33 | return {"elements": elements} | |
34 | ||
17 | 35 | |
18 | 36 | class Design(Model): |
19 | 37 | visible_id = peewee.IntegerField() |
24 | 42 | def rendered(self): |
25 | 43 | return markdown.markdown(self.description) |
26 | 44 | |
45 | def id_str(self): | |
46 | return f'{self.visible_id:05}' | |
47 | ||
48 | def slug(self): | |
49 | return slugify(self.title) | |
50 | ||
51 | def thumbnail(self): | |
52 | return Photo.get(Photo.design==self).thumb() | |
53 | ||
54 | def category_list(self): | |
55 | categories = Category.select() | |
56 | return [ | |
57 | {"name": c.name, "selected": c == self.category} | |
58 | for c in categories | |
59 | ] | |
60 | ||
61 | @classmethod | |
62 | def get_all(klass, page=0): | |
63 | designs = klass.select().paginate(page, PER_PAGE) | |
64 | return Paginated.paginate( | |
65 | page, | |
66 | klass.select().count(), | |
67 | designs, | |
68 | ) | |
69 | ||
70 | @classmethod | |
71 | def get_where(klass, *, tag=None, category=None, page=0): | |
72 | query = klass.select(klass) | |
73 | if tag is not None: | |
74 | query = query.join(Tag).where(Tag.tag_name == tag) | |
75 | if category is not None: | |
76 | query = query.switch(klass).join(Category).where(Category.name == category) | |
77 | query = query.group_by(klass).order_by(klass.id) | |
78 | designs = query.paginate(page, PER_PAGE) | |
79 | return Paginated.paginate( | |
80 | page, | |
81 | query.count(), | |
82 | designs, | |
83 | ) | |
84 | ||
27 | 85 | |
28 | 86 | class Photo(Model): |
29 | 87 | filename = peewee.TextField() |
30 | 88 | design = peewee.ForeignKeyField(Design, backref="photos") |
89 | ||
90 | def thumb(self): | |
91 | return self.filename[:-4] + "_thumb" + self.filename[-4:] | |
31 | 92 | |
32 | 93 | |
33 | 94 | class Page(Model): |
43 | 104 | tag_name = peewee.TextField() |
44 | 105 | design = peewee.ForeignKeyField(Design, backref="tags") |
45 | 106 | |
107 | @classmethod | |
108 | def all(klass): | |
109 | elements = ({"url": f"/tag/{t.tag_name}", "name": t.tag_name} for t in klass.select(klass.tag_name).distinct().order_by(klass.tag_name)) | |
110 | return {"elements": elements} | |
111 | ||
112 | ||
46 | 113 | |
47 | 114 | class PageRef(typing.NamedTuple): |
48 | 115 | page: int |
51 | 118 | return [self] |
52 | 119 | |
53 | 120 | |
54 | class Paginated(typing.NamedTuple): | |
55 | next_page: typing.Optional[PageRef] | |
56 | prev_page: typing.Optional[PageRef] | |
121 | @dataclass | |
122 | class Paginated: | |
123 | next_page: typing.Optional[dict] | |
124 | prev_page: typing.Optional[dict] | |
57 | 125 | last_page: int |
58 | 126 | contents: typing.List[Design] |
127 | ||
128 | @classmethod | |
129 | def paginate( | |
130 | cls, offset: int, total: int, contents: typing.List[Design], | |
131 | ) -> "Paginated": | |
132 | last_page = (total // PER_PAGE) + 1 | |
133 | next_page = PageRef(page=offset + 1) if offset < last_page else None | |
134 | prev_page = PageRef(page=offset - 1) if offset > 1 else None | |
135 | return cls( | |
136 | next_page=next_page, | |
137 | prev_page=prev_page, | |
138 | last_page=last_page, | |
139 | contents=contents, | |
140 | ) | |
141 | ||
142 | ||
143 | # @dataclass | |
144 | # class Paginated: | |
145 | # next_page: typing.Optional[dict] | |
146 | # prev_page: typing.Optional[dict] | |
147 | # last_page: int | |
148 | # contents: typing.List[Design] | |
149 |