home » zplus/dokk.org.git
Author zPlus <zplus@peers.community> 2023-09-16 05:47:59
Committer zPlus <zplus@peers.community> 2023-09-16 05:47:59
Commit f981b7a (patch)
Tree 248f1e8
Parent(s)

Add support for OPDS.


commits diff: 089aa59..f981b7a
4 files changed, 210 insertions, 0 deletionsdownload


Diffstat
-rwxr-xr-x app.py 29
-rw-r--r-- pages/templates/library/opds/books.tpl 76
-rw-r--r-- pages/templates/library/opds/others.tpl 77
-rw-r--r-- pages/templates/library/opds/root.tpl 28

Diff options
View
Side
Whitespace
Context lines
Inter-hunk lines
+29/-0 M   app.py
index dad8177..d896fb6
old size: 8K - new size: 9K
@@ -87,6 +87,35 @@ def static(filename):
87 87
88 88 return bottle.static_file(filename, root='./static/')
89 89
90 + @bottle.get('/library/opds.xml', name='library_opds')
91 + def library_opds():
92 + """
93 + Serve OPDS Atom RSS feeds
94 + """
95 +
96 + #response.content_type = 'text/xml; charset=utf-8'
97 + return template('templates/library/opds/root.tpl')
98 +
99 + @bottle.get('/library/opds/books.xml', name='library_opds_books')
100 + def library_opds_books():
101 + """
102 + Serve OPDS Atom RSS feeds.
103 + Items of type "books" only
104 + """
105 +
106 + #response.content_type = 'text/xml; charset=utf-8'
107 + return template('templates/library/opds/books.tpl')
108 +
109 + @bottle.get('/library/opds/others.xml', name='library_opds_others')
110 + def library_opds_others():
111 + """
112 + Serve OPDS Atom RSS feeds.
113 + Uncategorized items only
114 + """
115 +
116 + #response.content_type = 'text/xml; charset=utf-8'
117 + return template('templates/library/opds/others.tpl')
118 +
90 119 @bottle.get('/library/<item_id>', name='library_item')
91 120 def library_item(item_id):
92 121 """

+76/-0 A   pages/templates/library/opds/books.tpl
index 0000000..ca6f780
old size: 0B - new size: 2K
new file mode: -rw-r--r--
@@ -0,0 +1,76 @@
1 + <?xml version="1.0" encoding="UTF-8"?>
2 +
3 + {% set data = query("""
4 + PREFIX library: <dokk:library:>
5 + PREFIX license: <dokk:license:>
6 +
7 + CONSTRUCT {
8 + ?item library:title ?title;
9 + library:author ?author ;
10 + library:license ?license .
11 + ?license license:id ?license_id ;
12 + license:name ?license_name .
13 + }
14 + WHERE {
15 + ?item library:type 'book' ;
16 + library:title ?title ;
17 + library:author ?author ;
18 + library:license ?license .
19 +
20 + OPTIONAL {
21 + ?license license:id ?license_id_optional ;
22 + license:name ?license_name_optional .
23 + }
24 +
25 + BIND(COALESCE(?license_id_optional, SUBSTR(STR(?license), 14)) AS ?license_id)
26 + BIND(COALESCE(?license_name_optional, SUBSTR(STR(?license), 14)) AS ?license_name)
27 + }
28 + """,
29 + {
30 + '@context': {
31 + 'library': 'dokk:library:',
32 + 'license': 'dokk:license:',
33 + 'library:author': { '@container': '@set' },
34 + 'library:license': { '@container': '@set' }
35 + },
36 + 'library:title': {}
37 + })
38 + %}
39 +
40 + <feed xmlns="http://www.w3.org/2005/Atom"
41 + xmlns:dc="http://purl.org/dc/terms/"
42 + xmlns:opds="http://opds-spec.org/2010/catalog">
43 +
44 + <link rel="start" href="/library/opds.xml" type="application/atom+xml;profile=opds-catalog;kind=navigation"/>
45 + <link rel="self" href="/library/opds/books.xml" type="application/atom+xml;profile=opds-catalog;kind=acquisition"/>
46 +
47 + <id>urn:uuid:1ad42a21-f98f-44a9-b37a-7c4496ab661d</id>
48 + <title>DOKK Library Books</title>
49 + <updated>{{ now() }}</updated>
50 + <author>
51 + <name>DOKK</name>
52 + <uri>https://dokk.org</uri>
53 + </author>
54 +
55 + {% for item in data["@graph"]|sort(attribute="library:title") %}
56 + <entry>
57 + <title>{{ item['library:title'] }}</title>
58 +
59 + {% for author in item["library:author"]|sort() %}
60 + <author>
61 + <name>{{ author }}</name>
62 + </author>
63 + {% endfor%}
64 +
65 + {% for license in item["library:license"]|sort(attribute="license:id") %}
66 + <rights>{{ license['license:id'] }}</rights>
67 + {% endfor%}
68 +
69 + <updated></updated>
70 +
71 + <dc:language></dc:language>
72 + <dc:identifier></dc:identifier>
73 + <link rel="http://opds-spec.org/acquisition" href="https://blob.dokk.org/pdf/{{ item['@id'][8:] }}.pdf" type="application/pdf" />
74 + </entry>
75 + {% endfor %}
76 + </feed>

+77/-0 A   pages/templates/library/opds/others.tpl
index 0000000..d9429d2
old size: 0B - new size: 2K
new file mode: -rw-r--r--
@@ -0,0 +1,77 @@
1 + <?xml version="1.0" encoding="UTF-8"?>
2 +
3 + {% set data = query("""
4 + PREFIX library: <dokk:library:>
5 + PREFIX license: <dokk:license:>
6 +
7 + CONSTRUCT {
8 + ?item library:title ?title;
9 + library:author ?author ;
10 + library:license ?license .
11 + ?license license:id ?license_id ;
12 + license:name ?license_name .
13 + }
14 + WHERE {
15 + ?item library:title ?title ;
16 + library:author ?author ;
17 + library:license ?license .
18 +
19 + FILTER(NOT EXISTS { ?item library:type ?item_type })
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 + """,
30 + {
31 + '@context': {
32 + 'library': 'dokk:library:',
33 + 'license': 'dokk:license:',
34 + 'library:author': { '@container': '@set' },
35 + 'library:license': { '@container': '@set' }
36 + },
37 + 'library:title': {}
38 + })
39 + %}
40 +
41 + <feed xmlns="http://www.w3.org/2005/Atom"
42 + xmlns:dc="http://purl.org/dc/terms/"
43 + xmlns:opds="http://opds-spec.org/2010/catalog">
44 +
45 + <link rel="start" href="/library/opds.xml" type="application/atom+xml;profile=opds-catalog;kind=navigation"/>
46 + <link rel="self" href="/library/opds/others.xml" type="application/atom+xml;profile=opds-catalog;kind=acquisition"/>
47 +
48 + <id>urn:uuid:98d6aff1-0df9-4229-8c6e-2ab0ebece9e1</id>
49 + <title>DOKK Library Other Materials</title>
50 + <updated>{{ now() }}</updated>
51 + <author>
52 + <name>DOKK</name>
53 + <uri>https://dokk.org</uri>
54 + </author>
55 +
56 + {% for item in data["@graph"]|sort(attribute="library:title") %}
57 + <entry>
58 + <title>{{ item['library:title'] }}</title>
59 +
60 + {% for author in item["library:author"]|sort() %}
61 + <author>
62 + <name>{{ author }}</name>
63 + </author>
64 + {% endfor%}
65 +
66 + {% for license in item["library:license"]|sort(attribute="license:id") %}
67 + <rights>{{ license['license:id'] }}</rights>
68 + {% endfor%}
69 +
70 + <updated></updated>
71 +
72 + <dc:language></dc:language>
73 + <dc:identifier></dc:identifier>
74 + <link rel="http://opds-spec.org/acquisition" href="https://blob.dokk.org/pdf/{{ item['@id'][8:] }}.pdf" type="application/pdf" />
75 + </entry>
76 + {% endfor %}
77 + </feed>

+28/-0 A   pages/templates/library/opds/root.tpl
index 0000000..e4314a4
old size: 0B - new size: 1K
new file mode: -rw-r--r--
@@ -0,0 +1,28 @@
1 + <?xml version="1.0" encoding="UTF-8"?>
2 + <feed xmlns="http://www.w3.org/2005/Atom"
3 + xmlns:dc="http://purl.org/dc/terms/"
4 + xmlns:opds="http://opds-spec.org/2010/catalog">
5 +
6 + <id>urn:uuid:37a3bc53-cce9-47a2-b557-2c2d5b73d915</id>
7 + <title>DOKK Library</title>
8 + <updated>{{ now() }}</updated>
9 + <author>
10 + <name>DOKK</name>
11 + <uri>https://dokk.org</uri>
12 + </author>
13 +
14 + <link rel="start" href="/library/opds.xml" type="application/atom+xml;profile=opds-catalog;kind=navigation"/>
15 +
16 + <entry>
17 + <title>Books</title>
18 + <link rel="subsection" href="/library/opds/books.xml" type="application/atom+xml;profile=opds-catalog;kind=acquisition"/>
19 + <updated>{{ now() }}</updated>
20 + <id>urn:uuid:1ad42a21-f98f-44a9-b37a-7c4496ab661d</id>
21 + </entry>
22 + <entry>
23 + <title>Other Materials</title>
24 + <link rel="subsection" href="/library/opds/others.xml" type="application/atom+xml;profile=opds-catalog;kind=acquisition"/>
25 + <updated>{{ now() }}</updated>
26 + <id>urn:uuid:98d6aff1-0df9-4229-8c6e-2ab0ebece9e1</id>
27 + </entry>
28 + </feed>