Xml adapters now receive a Konsumer object instead of an input stream
This commit is contained in:
parent
655ab2bc83
commit
767662df59
@ -2,9 +2,9 @@ package com.readrops.api.localfeed
|
|||||||
|
|
||||||
import android.accounts.NetworkErrorException
|
import android.accounts.NetworkErrorException
|
||||||
import androidx.annotation.WorkerThread
|
import androidx.annotation.WorkerThread
|
||||||
|
import com.gitlab.mvysny.konsumexml.Konsumer
|
||||||
import com.gitlab.mvysny.konsumexml.konsumeXml
|
import com.gitlab.mvysny.konsumexml.konsumeXml
|
||||||
import com.readrops.api.localfeed.json.JSONFeedAdapter
|
import com.readrops.api.localfeed.json.JSONFeedAdapter
|
||||||
import com.readrops.api.localfeed.json.JSONItemsAdapter
|
|
||||||
import com.readrops.api.utils.ApiUtils
|
import com.readrops.api.utils.ApiUtils
|
||||||
import com.readrops.api.utils.AuthInterceptor
|
import com.readrops.api.utils.AuthInterceptor
|
||||||
import com.readrops.api.utils.exceptions.ParseException
|
import com.readrops.api.utils.exceptions.ParseException
|
||||||
@ -12,7 +12,6 @@ import com.readrops.api.utils.exceptions.UnknownFormatException
|
|||||||
import com.readrops.db.entities.Feed
|
import com.readrops.db.entities.Feed
|
||||||
import com.readrops.db.entities.Item
|
import com.readrops.db.entities.Item
|
||||||
import com.squareup.moshi.Moshi
|
import com.squareup.moshi.Moshi
|
||||||
import com.squareup.moshi.Types
|
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
@ -20,9 +19,7 @@ import okhttp3.Response
|
|||||||
import okio.Buffer
|
import okio.Buffer
|
||||||
import org.koin.core.component.KoinComponent
|
import org.koin.core.component.KoinComponent
|
||||||
import org.koin.core.component.get
|
import org.koin.core.component.get
|
||||||
import java.io.ByteArrayInputStream
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.InputStream
|
|
||||||
import java.net.HttpURLConnection
|
import java.net.HttpURLConnection
|
||||||
|
|
||||||
class LocalRSSDataSource(private val httpClient: OkHttpClient) : KoinComponent {
|
class LocalRSSDataSource(private val httpClient: OkHttpClient) : KoinComponent {
|
||||||
@ -41,34 +38,10 @@ class LocalRSSDataSource(private val httpClient: OkHttpClient): KoinComponent {
|
|||||||
|
|
||||||
return when {
|
return when {
|
||||||
response.isSuccessful -> {
|
response.isSuccessful -> {
|
||||||
val header = response.header(ApiUtils.CONTENT_TYPE_HEADER)
|
val pair = parseContent(response, url)
|
||||||
?: throw UnknownFormatException("Unable to get $url content-type")
|
|
||||||
|
|
||||||
val contentType = ApiUtils.parseContentType(header)
|
|
||||||
?: throw ParseException("Unable to parse $url content-type")
|
|
||||||
|
|
||||||
var type = LocalRSSHelper.getRSSType(contentType)
|
|
||||||
|
|
||||||
val bodyArray = response.peekBody(Long.MAX_VALUE).bytes()
|
|
||||||
val konsumer = ByteArrayInputStream(bodyArray).konsumeXml()
|
|
||||||
|
|
||||||
// if we can't guess type based on content-type header, we use the content
|
|
||||||
if (type == LocalRSSHelper.RSSType.UNKNOWN) {
|
|
||||||
val rootKonsumer = konsumer.nextElement(LocalRSSHelper.RSS_ROOT_NAMES)
|
|
||||||
|
|
||||||
if (rootKonsumer != null) {
|
|
||||||
type = LocalRSSHelper.guessRSSType(rootKonsumer)
|
|
||||||
konsumer.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if we can't guess type even with the content, we are unable to go further
|
|
||||||
if (type == LocalRSSHelper.RSSType.UNKNOWN) throw UnknownFormatException("Unable to guess $url RSS type")
|
|
||||||
|
|
||||||
val feed = parseFeed(ByteArrayInputStream(bodyArray), type, response)
|
|
||||||
val items = parseItems(ByteArrayInputStream(bodyArray), type)
|
|
||||||
|
|
||||||
response.body?.close()
|
response.body?.close()
|
||||||
Pair(feed, items)
|
pair
|
||||||
}
|
}
|
||||||
response.code == HttpURLConnection.HTTP_NOT_MODIFIED -> null
|
response.code == HttpURLConnection.HTTP_NOT_MODIFIED -> null
|
||||||
else -> throw NetworkErrorException("$url returned ${response.code} code : ${response.message}")
|
else -> throw NetworkErrorException("$url returned ${response.code} code : ${response.message}")
|
||||||
@ -115,18 +88,54 @@ class LocalRSSDataSource(private val httpClient: OkHttpClient): KoinComponent {
|
|||||||
return httpClient.newCall(requestBuilder.build()).execute()
|
return httpClient.newCall(requestBuilder.build()).execute()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseFeed(stream: InputStream, type: LocalRSSHelper.RSSType, response: Response): Feed {
|
private fun parseContent(response: Response, url: String): Pair<Feed, List<Item>> {
|
||||||
|
val header = response.header(ApiUtils.CONTENT_TYPE_HEADER)
|
||||||
|
?: throw UnknownFormatException("Unable to get $url content-type")
|
||||||
|
|
||||||
|
val contentType = ApiUtils.parseContentType(header)
|
||||||
|
?: throw ParseException("Unable to parse $url content-type")
|
||||||
|
|
||||||
|
var type = LocalRSSHelper.getRSSType(contentType)
|
||||||
|
|
||||||
|
var konsumer: Konsumer? = null
|
||||||
|
if (type != LocalRSSHelper.RSSType.JSONFEED)
|
||||||
|
konsumer = response.body!!.byteStream().konsumeXml()
|
||||||
|
|
||||||
|
var rootKonsumer: Konsumer? = null
|
||||||
|
// if we can't guess type based on content-type header, we use the content
|
||||||
|
if (type == LocalRSSHelper.RSSType.UNKNOWN) {
|
||||||
|
konsumer = response.body!!.byteStream().konsumeXml()
|
||||||
|
rootKonsumer = konsumer.nextElement(LocalRSSHelper.RSS_ROOT_NAMES)
|
||||||
|
|
||||||
|
if (rootKonsumer != null) {
|
||||||
|
type = LocalRSSHelper.guessRSSType(rootKonsumer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we can't guess type even with the content, we are unable to go further
|
||||||
|
if (type == LocalRSSHelper.RSSType.UNKNOWN) throw UnknownFormatException("Unable to guess $url RSS type")
|
||||||
|
|
||||||
|
val feed = parseFeed(rootKonsumer ?: konsumer, type, response)
|
||||||
|
//val items = parseItems(ByteArrayInputStream(bodyArray), type)
|
||||||
|
|
||||||
|
rootKonsumer?.finish()
|
||||||
|
konsumer?.close()
|
||||||
|
|
||||||
|
return Pair(feed, listOf())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun parseFeed(konsumer: Konsumer?, type: LocalRSSHelper.RSSType, response: Response): Feed {
|
||||||
val feed = if (type != LocalRSSHelper.RSSType.JSONFEED) {
|
val feed = if (type != LocalRSSHelper.RSSType.JSONFEED) {
|
||||||
val adapter = XmlAdapter.xmlFeedAdapterFactory(type)
|
val adapter = XmlAdapter.xmlFeedAdapterFactory(type)
|
||||||
|
|
||||||
adapter.fromXml(stream)
|
adapter.fromXml(konsumer!!)
|
||||||
} else {
|
} else {
|
||||||
val adapter = Moshi.Builder()
|
val adapter = Moshi.Builder()
|
||||||
.add(JSONFeedAdapter())
|
.add(JSONFeedAdapter())
|
||||||
.build()
|
.build()
|
||||||
.adapter(Feed::class.java)
|
.adapter(Feed::class.java)
|
||||||
|
|
||||||
adapter.fromJson(Buffer().readFrom(stream))!!
|
adapter.fromJson(Buffer().readFrom(response.body!!.byteStream()))!!
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSpecialCases(feed, type, response)
|
handleSpecialCases(feed, type, response)
|
||||||
@ -137,7 +146,7 @@ class LocalRSSDataSource(private val httpClient: OkHttpClient): KoinComponent {
|
|||||||
return feed
|
return feed
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseItems(stream: InputStream, type: LocalRSSHelper.RSSType): List<Item> {
|
/*private fun parseItems(stream: InputStream, type: LocalRSSHelper.RSSType): List<Item> {
|
||||||
return if (type != LocalRSSHelper.RSSType.JSONFEED) {
|
return if (type != LocalRSSHelper.RSSType.JSONFEED) {
|
||||||
val adapter = XmlAdapter.xmlItemsAdapterFactory(type)
|
val adapter = XmlAdapter.xmlItemsAdapterFactory(type)
|
||||||
|
|
||||||
@ -150,7 +159,7 @@ class LocalRSSDataSource(private val httpClient: OkHttpClient): KoinComponent {
|
|||||||
|
|
||||||
adapter.fromJson(Buffer().readFrom(stream))!!
|
adapter.fromJson(Buffer().readFrom(stream))!!
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
private fun handleSpecialCases(feed: Feed, type: LocalRSSHelper.RSSType, response: Response) {
|
private fun handleSpecialCases(feed: Feed, type: LocalRSSHelper.RSSType, response: Response) {
|
||||||
with(feed) {
|
with(feed) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.readrops.api.localfeed
|
package com.readrops.api.localfeed
|
||||||
|
|
||||||
|
import com.gitlab.mvysny.konsumexml.Konsumer
|
||||||
import com.readrops.api.localfeed.atom.ATOMFeedAdapter
|
import com.readrops.api.localfeed.atom.ATOMFeedAdapter
|
||||||
import com.readrops.api.localfeed.atom.ATOMItemsAdapter
|
import com.readrops.api.localfeed.atom.ATOMItemsAdapter
|
||||||
import com.readrops.api.localfeed.rss1.RSS1FeedAdapter
|
import com.readrops.api.localfeed.rss1.RSS1FeedAdapter
|
||||||
@ -8,11 +9,10 @@ import com.readrops.api.localfeed.rss2.RSS2FeedAdapter
|
|||||||
import com.readrops.api.localfeed.rss2.RSS2ItemsAdapter
|
import com.readrops.api.localfeed.rss2.RSS2ItemsAdapter
|
||||||
import com.readrops.db.entities.Feed
|
import com.readrops.db.entities.Feed
|
||||||
import com.readrops.db.entities.Item
|
import com.readrops.db.entities.Item
|
||||||
import java.io.InputStream
|
|
||||||
|
|
||||||
interface XmlAdapter<T> {
|
interface XmlAdapter<T> {
|
||||||
|
|
||||||
fun fromXml(inputStream: InputStream): T
|
fun fromXml(konsumer: Konsumer): T
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun xmlFeedAdapterFactory(type: LocalRSSHelper.RSSType): XmlAdapter<Feed> = when (type) {
|
fun xmlFeedAdapterFactory(type: LocalRSSHelper.RSSType): XmlAdapter<Feed> = when (type) {
|
||||||
|
@ -3,23 +3,22 @@ package com.readrops.api.localfeed.atom
|
|||||||
import com.gitlab.mvysny.konsumexml.Konsumer
|
import com.gitlab.mvysny.konsumexml.Konsumer
|
||||||
import com.gitlab.mvysny.konsumexml.Names
|
import com.gitlab.mvysny.konsumexml.Names
|
||||||
import com.gitlab.mvysny.konsumexml.allChildrenAutoIgnore
|
import com.gitlab.mvysny.konsumexml.allChildrenAutoIgnore
|
||||||
import com.gitlab.mvysny.konsumexml.konsumeXml
|
import com.readrops.api.localfeed.LocalRSSHelper
|
||||||
import com.readrops.api.localfeed.XmlAdapter
|
import com.readrops.api.localfeed.XmlAdapter
|
||||||
import com.readrops.api.utils.exceptions.ParseException
|
import com.readrops.api.utils.exceptions.ParseException
|
||||||
|
import com.readrops.api.utils.extensions.checkElement
|
||||||
import com.readrops.api.utils.extensions.nonNullText
|
import com.readrops.api.utils.extensions.nonNullText
|
||||||
import com.readrops.api.utils.extensions.nullableText
|
import com.readrops.api.utils.extensions.nullableText
|
||||||
import com.readrops.db.entities.Feed
|
import com.readrops.db.entities.Feed
|
||||||
import java.io.InputStream
|
|
||||||
|
|
||||||
class ATOMFeedAdapter : XmlAdapter<Feed> {
|
class ATOMFeedAdapter : XmlAdapter<Feed> {
|
||||||
|
|
||||||
override fun fromXml(inputStream: InputStream): Feed {
|
override fun fromXml(konsumer: Konsumer): Feed {
|
||||||
val konsume = inputStream.konsumeXml()
|
|
||||||
val feed = Feed()
|
val feed = Feed()
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
konsume.child("feed") {
|
konsumer.checkElement(LocalRSSHelper.ATOM_ROOT_NAME) {
|
||||||
allChildrenAutoIgnore(names) {
|
it.allChildrenAutoIgnore(names) {
|
||||||
with(feed) {
|
with(feed) {
|
||||||
when (tagName) {
|
when (tagName) {
|
||||||
"title" -> name = nonNullText()
|
"title" -> name = nonNullText()
|
||||||
@ -30,7 +29,7 @@ class ATOMFeedAdapter : XmlAdapter<Feed> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
konsume.close()
|
konsumer.close()
|
||||||
feed
|
feed
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
throw ParseException(e.message)
|
throw ParseException(e.message)
|
||||||
@ -38,7 +37,7 @@ class ATOMFeedAdapter : XmlAdapter<Feed> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun parseLink(konsume: Konsumer, feed: Feed) = with(konsume) {
|
private fun parseLink(konsume: Konsumer, feed: Feed) = with(konsume) {
|
||||||
val rel = attributes.getValueOpt("rel")
|
val rel = attributes.getValueOrNull("rel")
|
||||||
|
|
||||||
if (rel == "self")
|
if (rel == "self")
|
||||||
feed.url = attributes["href"]
|
feed.url = attributes["href"]
|
||||||
|
@ -3,7 +3,6 @@ package com.readrops.api.localfeed.atom
|
|||||||
import com.gitlab.mvysny.konsumexml.Konsumer
|
import com.gitlab.mvysny.konsumexml.Konsumer
|
||||||
import com.gitlab.mvysny.konsumexml.Names
|
import com.gitlab.mvysny.konsumexml.Names
|
||||||
import com.gitlab.mvysny.konsumexml.allChildrenAutoIgnore
|
import com.gitlab.mvysny.konsumexml.allChildrenAutoIgnore
|
||||||
import com.gitlab.mvysny.konsumexml.konsumeXml
|
|
||||||
import com.readrops.api.localfeed.XmlAdapter
|
import com.readrops.api.localfeed.XmlAdapter
|
||||||
import com.readrops.api.utils.*
|
import com.readrops.api.utils.*
|
||||||
import com.readrops.api.utils.exceptions.ParseException
|
import com.readrops.api.utils.exceptions.ParseException
|
||||||
@ -12,12 +11,10 @@ import com.readrops.api.utils.extensions.nullableText
|
|||||||
import com.readrops.api.utils.extensions.nullableTextRecursively
|
import com.readrops.api.utils.extensions.nullableTextRecursively
|
||||||
import com.readrops.db.entities.Item
|
import com.readrops.db.entities.Item
|
||||||
import org.joda.time.LocalDateTime
|
import org.joda.time.LocalDateTime
|
||||||
import java.io.InputStream
|
|
||||||
|
|
||||||
class ATOMItemsAdapter : XmlAdapter<List<Item>> {
|
class ATOMItemsAdapter : XmlAdapter<List<Item>> {
|
||||||
|
|
||||||
override fun fromXml(inputStream: InputStream): List<Item> {
|
override fun fromXml(konsumer: Konsumer): List<Item> {
|
||||||
val konsumer = inputStream.konsumeXml()
|
|
||||||
val items = arrayListOf<Item>()
|
val items = arrayListOf<Item>()
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
package com.readrops.api.localfeed.rss1
|
package com.readrops.api.localfeed.rss1
|
||||||
|
|
||||||
|
import com.gitlab.mvysny.konsumexml.Konsumer
|
||||||
import com.gitlab.mvysny.konsumexml.Names
|
import com.gitlab.mvysny.konsumexml.Names
|
||||||
import com.gitlab.mvysny.konsumexml.allChildrenAutoIgnore
|
import com.gitlab.mvysny.konsumexml.allChildrenAutoIgnore
|
||||||
import com.gitlab.mvysny.konsumexml.konsumeXml
|
import com.readrops.api.localfeed.LocalRSSHelper
|
||||||
import com.readrops.api.localfeed.XmlAdapter
|
import com.readrops.api.localfeed.XmlAdapter
|
||||||
import com.readrops.api.utils.exceptions.ParseException
|
import com.readrops.api.utils.exceptions.ParseException
|
||||||
|
import com.readrops.api.utils.extensions.checkElement
|
||||||
import com.readrops.api.utils.extensions.nonNullText
|
import com.readrops.api.utils.extensions.nonNullText
|
||||||
import com.readrops.api.utils.extensions.nullableText
|
import com.readrops.api.utils.extensions.nullableText
|
||||||
import com.readrops.db.entities.Feed
|
import com.readrops.db.entities.Feed
|
||||||
import java.io.InputStream
|
|
||||||
|
|
||||||
class RSS1FeedAdapter : XmlAdapter<Feed> {
|
class RSS1FeedAdapter : XmlAdapter<Feed> {
|
||||||
|
|
||||||
override fun fromXml(inputStream: InputStream): Feed {
|
override fun fromXml(konsumer: Konsumer): Feed {
|
||||||
val konsume = inputStream.konsumeXml()
|
|
||||||
val feed = Feed()
|
val feed = Feed()
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
konsume.child("RDF") {
|
konsumer.checkElement(LocalRSSHelper.RSS_1_ROOT_NAME) {
|
||||||
allChildrenAutoIgnore("channel") {
|
it.allChildrenAutoIgnore("channel") {
|
||||||
feed.url = attributes.getValueOpt("about",
|
feed.url = attributes.getValueOpt("about",
|
||||||
namespace = "http://www.w3.org/1999/02/22-rdf-syntax-ns#")
|
namespace = "http://www.w3.org/1999/02/22-rdf-syntax-ns#")
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ class RSS1FeedAdapter : XmlAdapter<Feed> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
konsume.close()
|
konsumer.close()
|
||||||
feed
|
feed
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
throw ParseException(e.message)
|
throw ParseException(e.message)
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package com.readrops.api.localfeed.rss1
|
package com.readrops.api.localfeed.rss1
|
||||||
|
|
||||||
|
import com.gitlab.mvysny.konsumexml.Konsumer
|
||||||
import com.gitlab.mvysny.konsumexml.Names
|
import com.gitlab.mvysny.konsumexml.Names
|
||||||
import com.gitlab.mvysny.konsumexml.allChildrenAutoIgnore
|
import com.gitlab.mvysny.konsumexml.allChildrenAutoIgnore
|
||||||
import com.gitlab.mvysny.konsumexml.konsumeXml
|
|
||||||
import com.readrops.api.localfeed.XmlAdapter
|
import com.readrops.api.localfeed.XmlAdapter
|
||||||
import com.readrops.api.localfeed.XmlAdapter.Companion.AUTHORS_MAX
|
import com.readrops.api.localfeed.XmlAdapter.Companion.AUTHORS_MAX
|
||||||
import com.readrops.api.utils.*
|
import com.readrops.api.utils.*
|
||||||
@ -12,12 +12,10 @@ import com.readrops.api.utils.extensions.nullableText
|
|||||||
import com.readrops.api.utils.extensions.nullableTextRecursively
|
import com.readrops.api.utils.extensions.nullableTextRecursively
|
||||||
import com.readrops.db.entities.Item
|
import com.readrops.db.entities.Item
|
||||||
import org.joda.time.LocalDateTime
|
import org.joda.time.LocalDateTime
|
||||||
import java.io.InputStream
|
|
||||||
|
|
||||||
class RSS1ItemsAdapter : XmlAdapter<List<Item>> {
|
class RSS1ItemsAdapter : XmlAdapter<List<Item>> {
|
||||||
|
|
||||||
override fun fromXml(inputStream: InputStream): List<Item> {
|
override fun fromXml(konsumer: Konsumer): List<Item> {
|
||||||
val konsumer = inputStream.konsumeXml()
|
|
||||||
val items = arrayListOf<Item>()
|
val items = arrayListOf<Item>()
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
|
@ -1,25 +1,25 @@
|
|||||||
package com.readrops.api.localfeed.rss2
|
package com.readrops.api.localfeed.rss2
|
||||||
|
|
||||||
|
import com.gitlab.mvysny.konsumexml.Konsumer
|
||||||
import com.gitlab.mvysny.konsumexml.Names
|
import com.gitlab.mvysny.konsumexml.Names
|
||||||
import com.gitlab.mvysny.konsumexml.allChildrenAutoIgnore
|
import com.gitlab.mvysny.konsumexml.allChildrenAutoIgnore
|
||||||
import com.gitlab.mvysny.konsumexml.konsumeXml
|
import com.readrops.api.localfeed.LocalRSSHelper
|
||||||
import com.readrops.api.localfeed.XmlAdapter
|
import com.readrops.api.localfeed.XmlAdapter
|
||||||
import com.readrops.api.utils.exceptions.ParseException
|
import com.readrops.api.utils.exceptions.ParseException
|
||||||
|
import com.readrops.api.utils.extensions.checkElement
|
||||||
import com.readrops.api.utils.extensions.nonNullText
|
import com.readrops.api.utils.extensions.nonNullText
|
||||||
import com.readrops.api.utils.extensions.nullableText
|
import com.readrops.api.utils.extensions.nullableText
|
||||||
import com.readrops.db.entities.Feed
|
import com.readrops.db.entities.Feed
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import java.io.InputStream
|
|
||||||
|
|
||||||
class RSS2FeedAdapter : XmlAdapter<Feed> {
|
class RSS2FeedAdapter : XmlAdapter<Feed> {
|
||||||
|
|
||||||
override fun fromXml(inputStream: InputStream): Feed {
|
override fun fromXml(konsumer: Konsumer): Feed {
|
||||||
val konsume = inputStream.konsumeXml()
|
|
||||||
val feed = Feed()
|
val feed = Feed()
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
konsume.child("rss") {
|
konsumer.checkElement(LocalRSSHelper.RSS_2_ROOT_NAME) {
|
||||||
child("channel") {
|
it.child("channel") {
|
||||||
allChildrenAutoIgnore(names) {
|
allChildrenAutoIgnore(names) {
|
||||||
with(feed) {
|
with(feed) {
|
||||||
when (tagName) {
|
when (tagName) {
|
||||||
@ -37,7 +37,7 @@ class RSS2FeedAdapter : XmlAdapter<Feed> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
konsume.close()
|
konsumer.close()
|
||||||
feed
|
feed
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
throw ParseException(e.message)
|
throw ParseException(e.message)
|
||||||
|
@ -10,12 +10,10 @@ import com.readrops.api.utils.extensions.nullableText
|
|||||||
import com.readrops.api.utils.extensions.nullableTextRecursively
|
import com.readrops.api.utils.extensions.nullableTextRecursively
|
||||||
import com.readrops.db.entities.Item
|
import com.readrops.db.entities.Item
|
||||||
import org.joda.time.LocalDateTime
|
import org.joda.time.LocalDateTime
|
||||||
import java.io.InputStream
|
|
||||||
|
|
||||||
class RSS2ItemsAdapter : XmlAdapter<List<Item>> {
|
class RSS2ItemsAdapter : XmlAdapter<List<Item>> {
|
||||||
|
|
||||||
override fun fromXml(inputStream: InputStream): List<Item> {
|
override fun fromXml(konsumer: Konsumer): List<Item> {
|
||||||
val konsumer = inputStream.konsumeXml()
|
|
||||||
val items = mutableListOf<Item>()
|
val items = mutableListOf<Item>()
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
|
@ -11,9 +11,11 @@ import com.readrops.api.services.nextcloudnews.adapters.NextNewsUserAdapter;
|
|||||||
import com.readrops.api.utils.ApiUtils;
|
import com.readrops.api.utils.ApiUtils;
|
||||||
import com.readrops.api.utils.exceptions.ConflictException;
|
import com.readrops.api.utils.exceptions.ConflictException;
|
||||||
import com.readrops.api.utils.exceptions.UnknownFormatException;
|
import com.readrops.api.utils.exceptions.UnknownFormatException;
|
||||||
|
import com.readrops.api.utils.extensions.KonsumerExtensionsKt;
|
||||||
import com.readrops.db.entities.Feed;
|
import com.readrops.db.entities.Feed;
|
||||||
import com.readrops.db.entities.Folder;
|
import com.readrops.db.entities.Folder;
|
||||||
import com.readrops.db.entities.Item;
|
import com.readrops.db.entities.Item;
|
||||||
|
import com.readrops.db.entities.account.Account;
|
||||||
import com.readrops.db.pojo.StarItem;
|
import com.readrops.db.pojo.StarItem;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -23,7 +25,8 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import okhttp3.ResponseBody;
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Request;
|
||||||
import retrofit2.Response;
|
import retrofit2.Response;
|
||||||
|
|
||||||
public class NextNewsDataSource {
|
public class NextNewsDataSource {
|
||||||
@ -40,14 +43,16 @@ public class NextNewsDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String login(String user) throws IOException {
|
public String login(OkHttpClient client, Account account) throws IOException {
|
||||||
Response<ResponseBody> response = api.getUser(user).execute();
|
Request request = new Request.Builder()
|
||||||
|
.url(account.getUrl() + "/ocs/v1.php/cloud/users/" + account.getLogin())
|
||||||
|
.addHeader("OCS-APIRequest", "true")
|
||||||
|
.build();
|
||||||
|
|
||||||
if (!response.isSuccessful()) {
|
okhttp3.Response response = client.newCall(request).execute();
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String displayName = new NextNewsUserAdapter().fromXml(response.body().byteStream());
|
String displayName = new NextNewsUserAdapter().fromXml(KonsumerExtensionsKt
|
||||||
|
.instantiateKonsumer(response.body().byteStream()));
|
||||||
response.body().close();
|
response.body().close();
|
||||||
|
|
||||||
return displayName;
|
return displayName;
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
package com.readrops.api.services.nextcloudnews.adapters
|
package com.readrops.api.services.nextcloudnews.adapters
|
||||||
|
|
||||||
|
import com.gitlab.mvysny.konsumexml.Konsumer
|
||||||
import com.gitlab.mvysny.konsumexml.allChildrenAutoIgnore
|
import com.gitlab.mvysny.konsumexml.allChildrenAutoIgnore
|
||||||
import com.gitlab.mvysny.konsumexml.konsumeXml
|
|
||||||
import com.readrops.api.localfeed.XmlAdapter
|
import com.readrops.api.localfeed.XmlAdapter
|
||||||
import com.readrops.api.utils.exceptions.ParseException
|
import com.readrops.api.utils.exceptions.ParseException
|
||||||
import com.readrops.api.utils.extensions.nonNullText
|
import com.readrops.api.utils.extensions.nonNullText
|
||||||
import java.io.InputStream
|
|
||||||
|
|
||||||
class NextNewsUserAdapter : XmlAdapter<String> {
|
class NextNewsUserAdapter : XmlAdapter<String> {
|
||||||
|
|
||||||
override fun fromXml(inputStream: InputStream): String {
|
override fun fromXml(konsumer: Konsumer): String {
|
||||||
val konsumer = inputStream.konsumeXml()
|
|
||||||
var displayName: String? = null
|
var displayName: String? = null
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
|
@ -2,8 +2,11 @@ package com.readrops.api.utils.extensions
|
|||||||
|
|
||||||
import com.gitlab.mvysny.konsumexml.Konsumer
|
import com.gitlab.mvysny.konsumexml.Konsumer
|
||||||
import com.gitlab.mvysny.konsumexml.Whitespace
|
import com.gitlab.mvysny.konsumexml.Whitespace
|
||||||
|
import com.gitlab.mvysny.konsumexml.konsumeXml
|
||||||
import com.gitlab.mvysny.konsumexml.textRecursively
|
import com.gitlab.mvysny.konsumexml.textRecursively
|
||||||
import com.readrops.api.utils.exceptions.ParseException
|
import com.readrops.api.utils.exceptions.ParseException
|
||||||
|
import java.io.InputStream
|
||||||
|
import java.util.stream.Stream
|
||||||
|
|
||||||
fun Konsumer.nonNullText(): String {
|
fun Konsumer.nonNullText(): String {
|
||||||
val text = text(whitespace = Whitespace.preserve)
|
val text = text(whitespace = Whitespace.preserve)
|
||||||
@ -26,3 +29,17 @@ fun Konsumer.checkRoot(name: String): Boolean = try {
|
|||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check is the element [name] is already loaded, loads it if it not the case and calls [block]
|
||||||
|
*/
|
||||||
|
fun Konsumer.checkElement(name: String, block: (Konsumer) -> Unit) {
|
||||||
|
if (checkRoot(name)) block(this)
|
||||||
|
else {
|
||||||
|
child(name) {
|
||||||
|
block(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun instantiateKonsumer(stream: InputStream) = stream.konsumeXml()
|
@ -12,7 +12,6 @@ import com.readrops.api.services.SyncResult;
|
|||||||
import com.readrops.api.services.SyncType;
|
import com.readrops.api.services.SyncType;
|
||||||
import com.readrops.api.services.nextcloudnews.NextNewsDataSource;
|
import com.readrops.api.services.nextcloudnews.NextNewsDataSource;
|
||||||
import com.readrops.api.services.nextcloudnews.NextNewsSyncData;
|
import com.readrops.api.services.nextcloudnews.NextNewsSyncData;
|
||||||
import com.readrops.api.services.nextcloudnews.adapters.NextNewsUserAdapter;
|
|
||||||
import com.readrops.api.utils.exceptions.UnknownFormatException;
|
import com.readrops.api.utils.exceptions.UnknownFormatException;
|
||||||
import com.readrops.app.addfeed.FeedInsertionResult;
|
import com.readrops.app.addfeed.FeedInsertionResult;
|
||||||
import com.readrops.app.addfeed.ParsingResult;
|
import com.readrops.app.addfeed.ParsingResult;
|
||||||
@ -37,8 +36,6 @@ import io.reactivex.Completable;
|
|||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import io.reactivex.Single;
|
import io.reactivex.Single;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
import okhttp3.Request;
|
|
||||||
import okhttp3.Response;
|
|
||||||
|
|
||||||
public class NextNewsRepository extends ARepository {
|
public class NextNewsRepository extends ARepository {
|
||||||
|
|
||||||
@ -58,22 +55,8 @@ public class NextNewsRepository extends ARepository {
|
|||||||
return Single.<String>create(emitter -> {
|
return Single.<String>create(emitter -> {
|
||||||
OkHttpClient httpClient = KoinJavaComponent.get(OkHttpClient.class);
|
OkHttpClient httpClient = KoinJavaComponent.get(OkHttpClient.class);
|
||||||
|
|
||||||
Request request = new Request.Builder()
|
String displayName = dataSource.login(httpClient, account);
|
||||||
.url(account.getUrl() + "/ocs/v1.php/cloud/users/" + account.getLogin())
|
|
||||||
.addHeader("OCS-APIRequest", "true")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Response response = httpClient.newCall(request).execute();
|
|
||||||
|
|
||||||
if (response.isSuccessful()) {
|
|
||||||
String displayName = new NextNewsUserAdapter().fromXml(response.body().byteStream());
|
|
||||||
response.body().close();
|
|
||||||
|
|
||||||
emitter.onSuccess(displayName);
|
emitter.onSuccess(displayName);
|
||||||
} else {
|
|
||||||
// TODO better error handling
|
|
||||||
emitter.onError(new Exception("Login exception : " + response.code() + " error"));
|
|
||||||
}
|
|
||||||
}).flatMapCompletable(displayName -> {
|
}).flatMapCompletable(displayName -> {
|
||||||
account.setDisplayedName(displayName);
|
account.setDisplayedName(displayName);
|
||||||
account.setCurrentAccount(true);
|
account.setCurrentAccount(true);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user