home » zplus/dokk.org.git
Author zPlus <zplus@peers.community> 2023-11-26 07:39:37
Committer zPlus <zplus@peers.community> 2023-11-26 07:39:37
Commit a2024a5 (patch)
Tree 779e6e0
Parent(s)

Add library filters. Add filters for searching the library.


commits diff: 69bf847..a2024a5
2 files changed, 120 insertions, 38 deletionsdownload


Diffstat
-rwxr-xr-x app.py 90
-rw-r--r-- pages/library.html 68

Diff options
View
Side
Whitespace
Context lines
Inter-hunk lines
+90/-0 M   app.py
index cf85123..9f6b722
old size: 9K - new size: 12K
@@ -87,6 +87,95 @@ def static(filename):
87 87
88 88 return bottle.static_file(filename, root='./static/')
89 89
90 + @bottle.route('/library', method=['GET', 'POST'], name='library')
91 + def library():
92 + """
93 + Library index
94 + """
95 +
96 + # Get a list of authors for searching
97 + authors = query("""
98 + PREFIX library: <dokk:library:>
99 + PREFIX license: <dokk:license:>
100 +
101 + SELECT DISTINCT ?name
102 + WHERE {
103 + [] library:author ?name
104 + }
105 + ORDER BY ?name
106 + """)['results']['bindings']
107 +
108 + # Get a list of licenses for searching
109 + licenses = query("""
110 + PREFIX library: <dokk:library:>
111 + PREFIX license: <dokk:license:>
112 +
113 + SELECT DISTINCT ?id
114 + WHERE {
115 + [] library:license [
116 + license:id ?id
117 + ] .
118 + }
119 + ORDER BY ?id
120 + """)['results']['bindings']
121 +
122 + # Retrieve filters selected by the user
123 + filters_author = []
124 + filters_license = []
125 + query_filters = ''
126 + if request.method == 'POST':
127 + filters_author = request.forms.getall('author')
128 + filters_license = request.forms.getall('license')
129 +
130 + if len(filters_author) > 0:
131 + query_filters_author = ','.join([ '"'+i.replace('"', '\\"')+'"' for i in filters_author ])
132 + query_filters += f'FILTER(?author IN ({query_filters_author}))'
133 +
134 + if len(filters_license) > 0:
135 + query_filters_license = ','.join([ '"'+i.replace('"', '\\"')+'"' for i in filters_license ])
136 + query_filters += f'FILTER(?license_id IN ({query_filters_license}))'
137 +
138 + items = query(f"""
139 + PREFIX library: <dokk:library:>
140 + PREFIX license: <dokk:license:>
141 +
142 + CONSTRUCT {{
143 + ?item library:title ?title;
144 + library:author ?author ;
145 + library:license ?license .
146 + ?license license:id ?license_id ;
147 + license:name ?license_name .
148 + }}
149 + WHERE {{
150 + ?item library:title ?title ;
151 + library:author ?author ;
152 + library:license ?license .
153 +
154 + OPTIONAL {{
155 + ?license license:id ?license_id_optional ;
156 + license:name ?license_name_optional .
157 + }}
158 +
159 + BIND(COALESCE(?license_id_optional, SUBSTR(STR(?license), 14)) AS ?license_id)
160 + BIND(COALESCE(?license_name_optional, SUBSTR(STR(?license), 14)) AS ?license_name)
161 +
162 + {query_filters}
163 + }}
164 + ORDER BY UCASE(?title)
165 + """,
166 + {
167 + '@context': {
168 + 'library': 'dokk:library:',
169 + 'license': 'dokk:license:',
170 + 'library:author': { '@container': '@set' },
171 + 'library:license': { '@container': '@set' }
172 + },
173 + 'library:title': {}
174 + })
175 +
176 + return template('library.html', authors=authors, licenses=licenses, items=items,
177 + filters_author=filters_author, filters_license=filters_license)
178 +
90 179 @bottle.get('/library/opds.xml', name='library_opds')
91 180 def library_opds():
92 181 """
@@ -329,6 +418,7 @@ def articles():
329 418
330 419 return template('templates/articles.tpl', pages=pages)
331 420
421 + # TODO Make this obsolete. Replace with controllers
332 422 @bottle.get('/', name='homepage')
333 423 @bottle.get('/<page:path>', name='page')
334 424 def article(page=''):

+30/-38 M   pages/library.html
index 9b23f71..570f7d1
old size: 2K - new size: 2K
@@ -2,43 +2,6 @@
2 2
3 3 {% block title %}Library{% endblock %}
4 4
5 - {% set data = query("""
6 - PREFIX library: <dokk:library:>
7 - PREFIX license: <dokk:license:>
8 -
9 - CONSTRUCT {
10 - ?item library:title ?title;
11 - library:author ?author ;
12 - library:license ?license .
13 - ?license license:id ?license_id ;
14 - license:name ?license_name .
15 - }
16 - WHERE {
17 - ?item library:title ?title ;
18 - library:author ?author ;
19 - library:license ?license .
20 -
21 - OPTIONAL {
22 - ?license license:id ?license_id_optional ;
23 - license:name ?license_name_optional .
24 - }
25 -
26 - BIND(COALESCE(?license_id_optional, SUBSTR(STR(?license), 14)) AS ?license_id)
27 - BIND(COALESCE(?license_name_optional, SUBSTR(STR(?license), 14)) AS ?license_name)
28 - }
29 - ORDER BY UCASE(?title)
30 - """,
31 - {
32 - '@context': {
33 - 'library': 'dokk:library:',
34 - 'license': 'dokk:license:',
35 - 'library:author': { '@container': '@set' },
36 - 'library:license': { '@container': '@set' }
37 - },
38 - 'library:title': {}
39 - })
40 - %}
41 -
42 5 {% block body %}
43 6
44 7 <div class="library">
@@ -46,7 +9,36 @@
46 9 <b>The library is also available via OPDS. Add this link to your OPDS client: https://dokk.org/library/opds.xml</b>
47 10 <br /><br /><br />
48 11
49 - {% for item in data["@graph"]|sort(attribute="library:title") %}
12 + <details>
13 + <summary>Filters</summary>
14 +
15 + <form action="" method="post">
16 + <br />
17 +
18 + Author:
19 + <br />
20 + <select name="author" multiple size=10>
21 + {% for author in authors %}
22 + <option value="{{ author['name']['value'] }}" {{ 'selected' if author['name']['value'] in filters_author }}>{{ author['name']['value'] }}</option>
23 + {% endfor %}
24 + </select>
25 +
26 + <br /><br />
27 +
28 + License:
29 + <br />
30 + <select name="license" multiple size=10>
31 + {% for license in licenses %}
32 + <option value="{{ license['id']['value'] }}" {{ 'selected' if license['id']['value'] in filters_license }}>{{ license['id']['value'] }}</option>
33 + {% endfor %}
34 + </select>
35 +
36 + <br /><br />
37 + <input type="submit" value="Search" />
38 + </form>
39 + </details>
40 +
41 + {% for item in items["@graph"]|sort(attribute="library:title") %}
50 42 <p>
51 43 <div>
52 44 <a href="/library/{{ item['@id'][8:] }}">{{ item['library:title'] }}</a>