Use new adapters configuration in LocalRSSDataSource
This commit is contained in:
parent
0ac0a1c347
commit
6025202346
@ -12,6 +12,7 @@ import com.readrops.api.utils.exceptions.UnknownFormatException
|
||||
import com.readrops.db.entities.Feed
|
||||
import com.readrops.db.entities.Item
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.Types
|
||||
import okhttp3.Headers
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
@ -20,6 +21,7 @@ import okio.Buffer
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.get
|
||||
import java.io.IOException
|
||||
import java.lang.Exception
|
||||
import java.net.HttpURLConnection
|
||||
|
||||
class LocalRSSDataSource(private val httpClient: OkHttpClient) : KoinComponent {
|
||||
@ -38,7 +40,7 @@ class LocalRSSDataSource(private val httpClient: OkHttpClient) : KoinComponent {
|
||||
|
||||
return when {
|
||||
response.isSuccessful -> {
|
||||
val pair = parseContent(response, url)
|
||||
val pair = parseResponse(response, url)
|
||||
|
||||
response.body?.close()
|
||||
pair
|
||||
@ -68,9 +70,13 @@ class LocalRSSDataSource(private val httpClient: OkHttpClient) : KoinComponent {
|
||||
|
||||
if (type == LocalRSSHelper.RSSType.UNKNOWN) {
|
||||
val konsumer = response.body!!.byteStream().konsumeXml().apply {
|
||||
val rootKonsumer = nextElement(LocalRSSHelper.RSS_ROOT_NAMES)
|
||||
try {
|
||||
val rootKonsumer = nextElement(LocalRSSHelper.RSS_ROOT_NAMES)
|
||||
rootKonsumer?.let { type = LocalRSSHelper.guessRSSType(rootKonsumer) }
|
||||
} catch (e: Exception) {
|
||||
throw UnknownFormatException(e.message)
|
||||
}
|
||||
|
||||
rootKonsumer?.let { type = LocalRSSHelper.guessRSSType(rootKonsumer) }
|
||||
}
|
||||
|
||||
konsumer.close()
|
||||
@ -88,7 +94,7 @@ class LocalRSSDataSource(private val httpClient: OkHttpClient) : KoinComponent {
|
||||
return httpClient.newCall(requestBuilder.build()).execute()
|
||||
}
|
||||
|
||||
private fun parseContent(response: Response, url: String): Pair<Feed, List<Item>> {
|
||||
private fun parseResponse(response: Response, url: String): Pair<Feed, List<Item>> {
|
||||
val header = response.header(ApiUtils.CONTENT_TYPE_HEADER)
|
||||
?: throw UnknownFormatException("Unable to get $url content-type")
|
||||
|
||||
@ -104,73 +110,64 @@ class LocalRSSDataSource(private val httpClient: OkHttpClient) : KoinComponent {
|
||||
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)
|
||||
try {
|
||||
konsumer = response.body!!.byteStream().konsumeXml()
|
||||
rootKonsumer = konsumer.nextElement(LocalRSSHelper.RSS_ROOT_NAMES)
|
||||
|
||||
if (rootKonsumer != null) {
|
||||
type = LocalRSSHelper.guessRSSType(rootKonsumer)
|
||||
if (rootKonsumer != null) {
|
||||
type = LocalRSSHelper.guessRSSType(rootKonsumer)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
throw UnknownFormatException(e.message)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 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)
|
||||
val pair = parseFeed(rootKonsumer ?: konsumer, type, response)
|
||||
|
||||
rootKonsumer?.finish()
|
||||
konsumer?.close()
|
||||
|
||||
return Pair(feed, listOf())
|
||||
return pair
|
||||
}
|
||||
|
||||
private fun parseFeed(konsumer: Konsumer?, type: LocalRSSHelper.RSSType, response: Response): Feed {
|
||||
val feed = if (type != LocalRSSHelper.RSSType.JSONFEED) {
|
||||
private fun parseFeed(konsumer: Konsumer?, type: LocalRSSHelper.RSSType, response: Response): Pair<Feed, List<Item>> {
|
||||
val pair = if (type != LocalRSSHelper.RSSType.JSONFEED) {
|
||||
val adapter = XmlAdapter.xmlFeedAdapterFactory(type)
|
||||
|
||||
adapter.fromXml(konsumer!!)
|
||||
} else {
|
||||
val pairType = Types.newParameterizedType(Pair::class.java, Feed::class.java,
|
||||
Types.newParameterizedType(List::class.java, Item::class.java))
|
||||
|
||||
val adapter = Moshi.Builder()
|
||||
.add(JSONFeedAdapter())
|
||||
.add(pairType, JSONFeedAdapter())
|
||||
.build()
|
||||
.adapter(Feed::class.java)
|
||||
.adapter<Pair<Feed, List<Item>>>(pairType)
|
||||
|
||||
adapter.fromJson(Buffer().readFrom(response.body!!.byteStream()))!!
|
||||
}
|
||||
|
||||
handleSpecialCases(feed, type, response)
|
||||
handleSpecialCases(pair.first, type, response)
|
||||
|
||||
feed.etag = response.header(ApiUtils.ETAG_HEADER)
|
||||
feed.lastModified = response.header(ApiUtils.LAST_MODIFIED_HEADER)
|
||||
pair.first.etag = response.header(ApiUtils.ETAG_HEADER)
|
||||
pair.first.lastModified = response.header(ApiUtils.LAST_MODIFIED_HEADER)
|
||||
|
||||
return feed
|
||||
return pair
|
||||
}
|
||||
|
||||
/*private fun parseItems(stream: InputStream, type: LocalRSSHelper.RSSType): List<Item> {
|
||||
return if (type != LocalRSSHelper.RSSType.JSONFEED) {
|
||||
val adapter = XmlAdapter.xmlItemsAdapterFactory(type)
|
||||
|
||||
adapter.fromXml(stream)
|
||||
} else {
|
||||
val adapter = Moshi.Builder()
|
||||
.add(Types.newParameterizedType(MutableList::class.java, Item::class.java), JSONItemsAdapter())
|
||||
.build()
|
||||
.adapter<List<Item>>(Types.newParameterizedType(MutableList::class.java, Item::class.java))
|
||||
|
||||
adapter.fromJson(Buffer().readFrom(stream))!!
|
||||
}
|
||||
}*/
|
||||
|
||||
private fun handleSpecialCases(feed: Feed, type: LocalRSSHelper.RSSType, response: Response) {
|
||||
with(feed) {
|
||||
if (type == LocalRSSHelper.RSSType.RSS_2) {
|
||||
// if an atom:link element was parsed, we still replace its value as it is unreliable,
|
||||
// otherwise we just add the rss url
|
||||
url = response.request.url.toString()
|
||||
} else if (type == LocalRSSHelper.RSSType.ATOM || type == LocalRSSHelper.RSSType.RSS_1) {
|
||||
if (url == null) url = response.request.url.toString()
|
||||
if (siteUrl == null) siteUrl = response.request.url.scheme + "://" + response.request.url.host
|
||||
private fun handleSpecialCases(feed: Feed, type: LocalRSSHelper.RSSType, response: Response) =
|
||||
with(feed) {
|
||||
if (type == LocalRSSHelper.RSSType.RSS_2) {
|
||||
// if an atom:link element was parsed, we still replace its value as it is unreliable,
|
||||
// otherwise we just add the rss url
|
||||
url = response.request.url.toString()
|
||||
} else if (type == LocalRSSHelper.RSSType.ATOM || type == LocalRSSHelper.RSSType.RSS_1) {
|
||||
if (url == null) url = response.request.url.toString()
|
||||
if (siteUrl == null) siteUrl = response.request.url.scheme + "://" + response.request.url.host
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
package com.readrops.api.localfeed
|
||||
|
||||
import com.gitlab.mvysny.konsumexml.Konsumer
|
||||
import com.readrops.api.localfeed.atom.ATOMFeedAdapter
|
||||
import com.readrops.api.localfeed.rss1.RSS1FeedAdapter
|
||||
import com.readrops.api.localfeed.rss2.RSS2FeedAdapter
|
||||
import com.readrops.db.entities.Feed
|
||||
import com.readrops.db.entities.Item
|
||||
|
||||
@ -9,21 +12,13 @@ interface XmlAdapter<T> {
|
||||
fun fromXml(konsumer: Konsumer): T
|
||||
|
||||
companion object {
|
||||
fun xmlFeedAdapterFactory(type: LocalRSSHelper.RSSType): XmlAdapter<Feed> = when (type) {
|
||||
//LocalRSSHelper.RSSType.RSS_1 -> RSS1FeedAdapter()
|
||||
//LocalRSSHelper.RSSType.RSS_2 -> RSS2FeedAdapter()
|
||||
//LocalRSSHelper.RSSType.ATOM -> ATOMFeedAdapter()
|
||||
fun xmlFeedAdapterFactory(type: LocalRSSHelper.RSSType): XmlAdapter<Pair<Feed, List<Item>>> = when (type) {
|
||||
LocalRSSHelper.RSSType.RSS_1 -> RSS1FeedAdapter()
|
||||
LocalRSSHelper.RSSType.RSS_2 -> RSS2FeedAdapter()
|
||||
LocalRSSHelper.RSSType.ATOM -> ATOMFeedAdapter()
|
||||
else -> throw IllegalArgumentException("Unknown RSS type : $type")
|
||||
}
|
||||
|
||||
fun xmlItemsAdapterFactory(type: LocalRSSHelper.RSSType): XmlAdapter<List<Item>> =
|
||||
when (type) {
|
||||
//LocalRSSHelper.RSSType.RSS_1 -> RSS1ItemsAdapter()
|
||||
//LocalRSSHelper.RSSType.RSS_2 -> RSS2ItemsAdapter()
|
||||
//LocalRSSHelper.RSSType.ATOM -> ATOMItemAdapter()
|
||||
else -> throw IllegalArgumentException("Unknown RSS type : $type")
|
||||
}
|
||||
|
||||
const val AUTHORS_MAX = 4
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,10 @@
|
||||
package com.readrops.api.localfeed
|
||||
|
||||
import com.readrops.api.localfeed.atom.ATOMFeedAdapter
|
||||
import com.readrops.api.localfeed.rss1.RSS1FeedAdapter
|
||||
import com.readrops.api.localfeed.rss2.RSS2FeedAdapter
|
||||
import junit.framework.Assert.assertTrue
|
||||
import org.junit.Assert.assertThrows
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.ExpectedException
|
||||
@ -11,21 +16,12 @@ class XmlAdapterTest {
|
||||
|
||||
@Test
|
||||
fun xmlFeedAdapterFactoryTest() {
|
||||
//assertTrue(XmlAdapter.xmlFeedAdapterFactory(LocalRSSHelper.RSSType.RSS_1) is RSS1FeedAdapter)
|
||||
//assertTrue(XmlAdapter.xmlFeedAdapterFactory(LocalRSSHelper.RSSType.RSS_2) is RSS2FeedAdapter)
|
||||
//assertTrue(XmlAdapter.xmlFeedAdapterFactory(LocalRSSHelper.RSSType.ATOM) is ATOMFeedAdapter)
|
||||
assertTrue(XmlAdapter.xmlFeedAdapterFactory(LocalRSSHelper.RSSType.RSS_1) is RSS1FeedAdapter)
|
||||
assertTrue(XmlAdapter.xmlFeedAdapterFactory(LocalRSSHelper.RSSType.RSS_2) is RSS2FeedAdapter)
|
||||
assertTrue(XmlAdapter.xmlFeedAdapterFactory(LocalRSSHelper.RSSType.ATOM) is ATOMFeedAdapter)
|
||||
|
||||
expectedException.expect(IllegalArgumentException::class.java)
|
||||
XmlAdapter.xmlFeedAdapterFactory(LocalRSSHelper.RSSType.UNKNOWN)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun xmlItemsAdapterFactoryTest() {
|
||||
//assertTrue(XmlAdapter.xmlItemsAdapterFactory(LocalRSSHelper.RSSType.RSS_1) is RSS1ItemsAdapter)
|
||||
//assertTrue(XmlAdapter.xmlItemsAdapterFactory(LocalRSSHelper.RSSType.RSS_2) is RSS2ItemsAdapter)
|
||||
//assertTrue(XmlAdapter.xmlItemsAdapterFactory(LocalRSSHelper.RSSType.ATOM) is ATOMItemAdapter)
|
||||
|
||||
expectedException.expect(IllegalArgumentException::class.java)
|
||||
XmlAdapter.xmlItemsAdapterFactory(LocalRSSHelper.RSSType.UNKNOWN)
|
||||
assertThrows(java.lang.IllegalArgumentException::class.java) {
|
||||
XmlAdapter.xmlFeedAdapterFactory(LocalRSSHelper.RSSType.UNKNOWN)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user