Author | zPlus <zplus@peers.community> 2022-07-30 10:20:46 |
Committer | zPlus <zplus@peers.community> 2022-07-30 10:20:46 |
Commit | e587546 (patch) |
Tree | 3ea873a |
Parent(s) |
-rw-r--r-- | static/css/clif.css | 19 | ||
-rw-r--r-- | templates/mailing_list/emails.html | 23 | ||
-rw-r--r-- | web.py | 41 |
index be2516c..cf4bc31 | |||
old size: 5K - new size: 6K | |||
@@ -31,6 +31,10 @@ blockquote cite:before { | |||
31 | 31 | content: "\2014 \2009"; | |
32 | 32 | } | |
33 | 33 | ||
34 | + | details > summary { | |
35 | + | cursor: pointer; | |
36 | + | } | |
37 | + | ||
34 | 38 | p { | |
35 | 39 | margin: 0 0 10px 0; | |
36 | 40 | } | |
@@ -199,7 +203,7 @@ div.threads { | |||
199 | 203 | } | |
200 | 204 | ||
201 | 205 | div.threads div.title { | |
202 | - | font-weight: bold; | |
206 | + | ||
203 | 207 | } | |
204 | 208 | ||
205 | 209 | div.threads div.subtitle { | |
@@ -215,6 +219,19 @@ div.threads { | |||
215 | 219 | padding: .1rem .5rem; | |
216 | 220 | } | |
217 | 221 | ||
222 | + | /* Filters in a mailing list page. */ | |
223 | + | .filters { | |
224 | + | margin-bottom: 1rem; | |
225 | + | } | |
226 | + | ||
227 | + | .filters .tag { | |
228 | + | margin-top: .1rem; | |
229 | + | } | |
230 | + | ||
231 | + | .filters .buttons { | |
232 | + | margin-top: 1rem; | |
233 | + | } | |
234 | + | ||
218 | 235 | .thread { | |
219 | 236 | } | |
220 | 237 |
index ac36efc..4d957db | |||
old size: 760B - new size: 2K | |||
@@ -1,7 +1,27 @@ | |||
1 | 1 | {% extends "mailing_list/mailing_list.html" %} | |
2 | 2 | ||
3 | 3 | {% block content %} | |
4 | - | ||
4 | + | ||
5 | + | <details class="filters"> | |
6 | + | <summary>Filters</summary> | |
7 | + | ||
8 | + | <form action="" method="get"> | |
9 | + | {% for tag in tags %} | |
10 | + | <div class="tag"> | |
11 | + | <b>{{ tag }}:</b> | |
12 | + | {% for value in tags[tag] %} | |
13 | + | <label><input type="checkbox" name="{{ tag }}" value="{{ value }}" {{ 'checked' if value in query_tags[tag] }} /> {{ value }}</label> | |
14 | + | {% endfor %} | |
15 | + | </div> | |
16 | + | {% endfor %} | |
17 | + | ||
18 | + | <div class="buttons"> | |
19 | + | <input type="submit" value="Filter threads" /> | |
20 | + | <a href="{{ url('threads', repository=repository[:-10]) }}">Remove all</a> | |
21 | + | </div> | |
22 | + | </form> | |
23 | + | </details> | |
24 | + | ||
5 | 25 | <div class="threads"> | |
6 | 26 | {% for thread in threads %} | |
7 | 27 | <div> | |
@@ -10,6 +30,7 @@ | |||
10 | 30 | </div> | |
11 | 31 | <div class="subtitle"> | |
12 | 32 | #{{ thread.id }} | |
33 | + | ||
13 | 34 | Created {{ thread.datetime|ago }} | |
14 | 35 | ||
15 | 36 | {% if 'label' in thread['tags'] %} |
index 662f336..86d3073 | |||
old size: 22K - new size: 22K | |||
@@ -586,6 +586,9 @@ def threads(repository): | |||
586 | 586 | :param repository: Match repository name NOT ending with ".git" | |
587 | 587 | """ | |
588 | 588 | ||
589 | + | # List of seletected tags, retrieved from the query string | |
590 | + | query_tags = { k: request.query.getall(k) for k in request.query.keys() } | |
591 | + | ||
589 | 592 | repository += '.mlist.git' | |
590 | 593 | path = os.path.join(GITOLITE_REPOSITORIES_ROOT, repository) | |
591 | 594 | list_address = '{}@{}'.format(repository[:-10], INSTANCE_DOMAIN) | |
@@ -597,34 +600,48 @@ def threads(repository): | |||
597 | 600 | tree = repo.revparse_single('HEAD').tree | |
598 | 601 | ||
599 | 602 | threads_list = [] | |
603 | + | tags = {} | |
600 | 604 | ||
601 | 605 | for obj in tree: | |
602 | 606 | if obj.type != pygit2.GIT_OBJ_TREE: | |
603 | 607 | continue | |
604 | 608 | ||
605 | - | threads_list.append(obj) | |
606 | - | ||
607 | - | for i in range(0, len(threads_list)): | |
608 | - | thread_date, thread_time, thread_id, thread_title = threads_list[i].name.split(' ', 3) | |
609 | + | thread_date, thread_time, thread_id, thread_title = obj.name.split(' ', 3) | |
609 | 610 | ||
610 | 611 | thread_tags = {} | |
611 | 612 | try: | |
612 | - | thread_tags = parse_thread_tags(threads_list[i]['tags'].data.decode('UTF-8')) | |
613 | + | thread_tags = parse_thread_tags(obj['tags'].data.decode('UTF-8')) | |
614 | + | ||
615 | + | # Collect tags for filters | |
616 | + | for k, v in thread_tags.items(): | |
617 | + | tags[k] = tags.get(k, []) + v | |
613 | 618 | except: | |
614 | 619 | pass | |
615 | 620 | ||
616 | - | threads_list[i] = { | |
617 | - | 'datetime': thread_date + ' ' + thread_time, | |
618 | - | 'id': thread_id, | |
619 | - | 'title': thread_title, | |
620 | - | 'tags': thread_tags | |
621 | - | } | |
621 | + | # Check if we should filter out this thread from the list | |
622 | + | keep = True | |
623 | + | for key in query_tags.keys(): | |
624 | + | for value in query_tags[key]: | |
625 | + | if value not in thread_tags.get(key, []): | |
626 | + | keep = False | |
627 | + | break | |
628 | + | ||
629 | + | if not keep: break | |
630 | + | ||
631 | + | if keep: | |
632 | + | threads_list.append({ | |
633 | + | 'datetime': thread_date + ' ' + thread_time, | |
634 | + | 'id': thread_id, | |
635 | + | 'title': thread_title, | |
636 | + | 'tags': thread_tags | |
637 | + | }) | |
622 | 638 | ||
623 | 639 | threads_list.reverse() | |
624 | 640 | ||
625 | 641 | return template('mailing_list/emails.html', threads=threads_list, | |
626 | 642 | list_address=list_address, | |
627 | - | repository=repository) | |
643 | + | repository=repository, | |
644 | + | tags=tags, query_tags=query_tags) | |
628 | 645 | ||
629 | 646 | @bottle.get('/<repository:path>.mlist/<thread_id>', name='thread') | |
630 | 647 | def thread(repository, thread_id): |