9
9
10
10
package org.readium.r2.opds
11
11
12
- import com.github.kittinunf.fuel.Fuel
13
12
import nl.komponents.kovenant.Promise
14
13
import nl.komponents.kovenant.then
15
14
import org.joda.time.DateTime
@@ -18,10 +17,14 @@ import org.readium.r2.shared.extensions.toMap
18
17
import org.readium.r2.shared.opds.*
19
18
import org.readium.r2.shared.parser.xml.ElementNode
20
19
import org.readium.r2.shared.parser.xml.XmlParser
21
- import org.readium.r2.shared.promise
22
20
import org.readium.r2.shared.publication.*
23
21
import org.readium.r2.shared.toJSON
24
22
import org.readium.r2.shared.util.Href
23
+ import org.readium.r2.shared.util.Try
24
+ import org.readium.r2.shared.util.http.DefaultHttpClient
25
+ import org.readium.r2.shared.util.http.HttpClient
26
+ import org.readium.r2.shared.util.http.HttpRequest
27
+ import org.readium.r2.shared.util.http.fetchWithDecoder
25
28
import java.net.URL
26
29
27
30
enum class OPDSParserError {
@@ -45,18 +48,38 @@ object Namespaces {
45
48
class OPDS1Parser {
46
49
companion object {
47
50
51
+ suspend fun parseUrlString (url : String , client : HttpClient = DefaultHttpClient ()): Try <ParseData , Exception > {
52
+ return client.fetchWithDecoder(HttpRequest (url)) {
53
+ this .parse(it.body, URL (url))
54
+ }
55
+ }
56
+
57
+ suspend fun parseRequest (request : HttpRequest , client : HttpClient = DefaultHttpClient ()): Try <ParseData , Exception > {
58
+ return client.fetchWithDecoder(request) {
59
+ this .parse(it.body, URL (request.url))
60
+ }
61
+ }
62
+
63
+ @Deprecated(
64
+ " Use `parseRequest` or `parseUrlString` with coroutines instead" ,
65
+ ReplaceWith (" OPDS1Parser.parseUrlString(url)" ),
66
+ DeprecationLevel .WARNING
67
+ )
48
68
fun parseURL (url : URL ): Promise <ParseData , Exception > {
49
- return Fuel .get(url.toString(), null ).promise() then {
50
- val (_, _, result) = it
51
- this .parse(xmlData = result, url = url)
69
+ return DefaultHttpClient ().fetchPromise(HttpRequest (url.toString())) then {
70
+ this .parse(xmlData = it.body, url = url)
52
71
}
53
72
}
54
73
74
+ @Deprecated(
75
+ " Use `parseRequest` or `parseUrlString` with coroutines instead" ,
76
+ ReplaceWith (" OPDS1Parser.parseUrlString(url)" ),
77
+ DeprecationLevel .WARNING
78
+ )
55
79
@Suppress(" unused" )
56
80
fun parseURL (headers : MutableMap <String ,String >, url : URL ): Promise <ParseData , Exception > {
57
- return Fuel .get(url.toString(), null ).header(headers).promise() then {
58
- val (_, _, result) = it
59
- this .parse(xmlData = result, url = url)
81
+ return DefaultHttpClient ().fetchPromise(HttpRequest (url = url.toString(), headers = headers)) then {
82
+ this .parse(xmlData = it.body, url = url)
60
83
}
61
84
}
62
85
@@ -178,6 +201,67 @@ class OPDS1Parser {
178
201
return MimeTypeParameters (type = type, parameters = params)
179
202
}
180
203
204
+ @Suppress(" unused" )
205
+ suspend fun retrieveOpenSearchTemplate (feed : Feed ): Try <String ?, Exception > {
206
+
207
+ var openSearchURL: URL ? = null
208
+ var selfMimeType: String? = null
209
+
210
+ for (link in feed.links) {
211
+ if (link.rels.contains(" self" )) {
212
+ if (link.type != null ) {
213
+ selfMimeType = link.type
214
+ }
215
+ } else if (link.rels.contains(" search" )) {
216
+ openSearchURL = URL (link.href)
217
+ }
218
+ }
219
+
220
+ val unwrappedURL = openSearchURL?.let {
221
+ return @let it
222
+ }
223
+
224
+ return DefaultHttpClient ().fetchWithDecoder(HttpRequest (unwrappedURL.toString())) {
225
+
226
+ val document = XmlParser ().parse(it.body.inputStream())
227
+
228
+ val urls = document.get(" Url" , Namespaces .Search )
229
+
230
+ var typeAndProfileMatch: ElementNode ? = null
231
+ var typeMatch: ElementNode ? = null
232
+
233
+ selfMimeType?.let { s ->
234
+
235
+ val selfMimeParams = parseMimeType(mimeTypeString = s)
236
+ for (url in urls) {
237
+ val urlMimeType = url.getAttr(" type" ) ? : continue
238
+ val otherMimeParams = parseMimeType(mimeTypeString = urlMimeType)
239
+ if (selfMimeParams.type == otherMimeParams.type) {
240
+ if (typeMatch == null ) {
241
+ typeMatch = url
242
+ }
243
+ if (selfMimeParams.parameters[" profile" ] == otherMimeParams.parameters[" profile" ]) {
244
+ typeAndProfileMatch = url
245
+ break
246
+ }
247
+ }
248
+ }
249
+ val match = typeAndProfileMatch ? : (typeMatch ? : urls[0 ])
250
+ val template = match.getAttr(" template" )
251
+
252
+ template
253
+
254
+ }
255
+ null
256
+ }
257
+
258
+ }
259
+
260
+ @Deprecated(
261
+ " Use `retrieveOpenSearchTemplate` with coroutines instead" ,
262
+ ReplaceWith (" OPDS1Parser.retrieveOpenSearchTemplate(feed)" ),
263
+ DeprecationLevel .WARNING
264
+ )
181
265
@Suppress(" unused" )
182
266
fun fetchOpenSearchTemplate (feed : Feed ): Promise <String ?, Exception > {
183
267
@@ -198,10 +282,9 @@ class OPDS1Parser {
198
282
return @let it
199
283
}
200
284
201
- return Fuel .get(unwrappedURL.toString(), null ).promise() then {
202
- val (_, _, result) = it
285
+ return DefaultHttpClient ().fetchPromise(HttpRequest (unwrappedURL.toString())) then {
203
286
204
- val document = XmlParser ().parse(result .inputStream())
287
+ val document = XmlParser ().parse(it.body .inputStream())
205
288
206
289
val urls = document.get(" Url" , Namespaces .Search )
207
290
0 commit comments