mirror of https://github.com/readrops/Readrops.git
Add adapter for parsing atom entries
This commit is contained in:
parent
5c342a45b6
commit
0c48bd2adb
|
@ -0,0 +1,71 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xml:lang="en-US">
|
||||||
|
<id>tag:github.com,2008:/readrops/Readrops/commits/develop</id>
|
||||||
|
<link type="text/html" rel="alternate" href="https://github.com/readrops/Readrops/commits/develop"/>
|
||||||
|
<link type="application/atom+xml" rel="self" href="https://github.com/readrops/Readrops/commits/develop.atom"/>
|
||||||
|
<title>Recent Commits to Readrops:develop</title>
|
||||||
|
<updated>2020-09-06T21:09:59Z</updated>
|
||||||
|
<entry>
|
||||||
|
<id>tag:github.com,2008:Grit::Commit/c15f093a1bc4211e85f8d1817c9073e307afe5ac</id>
|
||||||
|
<link type="text/html" rel="alternate" href="https://github.com/readrops/Readrops/commit/c15f093a1bc4211e85f8d1817c9073e307afe5ac"/>
|
||||||
|
<title>Add an option to open item url in custom tab</title>
|
||||||
|
<updated>2020-09-06T21:09:59Z</updated>
|
||||||
|
<media:thumbnail height="30" width="30" url="https://avatars2.githubusercontent.com/u/18555673?s=30&u=c56b216e8d128d0ec217062feeace9faca4dc893&v=4"/>
|
||||||
|
<author>
|
||||||
|
<name>Shinokuni</name>
|
||||||
|
<uri>https://github.com/Shinokuni</uri>
|
||||||
|
</author>
|
||||||
|
<summary>Summary</summary>
|
||||||
|
<content type="html">
|
||||||
|
<pre style='white-space:pre-wrap;width:81ex'>Add an option to open item url in custom tab</pre>
|
||||||
|
</content>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<id>tag:github.com,2008:Grit::Commit/e0945823eecf269e5beea646ac5d7e630e08afbf</id>
|
||||||
|
<link type="text/html" rel="alternate" href="https://github.com/readrops/Readrops/commit/e0945823eecf269e5beea646ac5d7e630e08afbf"/>
|
||||||
|
<title>
|
||||||
|
Use gradle parallel builds
|
||||||
|
</title>
|
||||||
|
<updated>2020-09-05T13:28:23Z</updated>
|
||||||
|
<media:thumbnail height="30" width="30" url="https://avatars2.githubusercontent.com/u/18555673?s=30&u=c56b216e8d128d0ec217062feeace9faca4dc893&v=4"/>
|
||||||
|
<author>
|
||||||
|
<name>Shinokuni</name>
|
||||||
|
<uri>https://github.com/Shinokuni</uri>
|
||||||
|
</author>
|
||||||
|
<content type="html">
|
||||||
|
<pre style='white-space:pre-wrap;width:81ex'>Use gradle parallel builds</pre>
|
||||||
|
</content>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<id>tag:github.com,2008:Grit::Commit/85fcf03e64d8b482e4d2af8c2bcd1509d946944f</id>
|
||||||
|
<link type="text/html" rel="alternate" href="https://github.com/readrops/Readrops/commit/85fcf03e64d8b482e4d2af8c2bcd1509d946944f"/>
|
||||||
|
<title>
|
||||||
|
Use clear text mode for the feed url text input in AddFeedActivity
|
||||||
|
</title>
|
||||||
|
<updated>2020-09-05T12:23:48Z</updated>
|
||||||
|
<media:thumbnail height="30" width="30" url="https://avatars2.githubusercontent.com/u/18555673?s=30&u=c56b216e8d128d0ec217062feeace9faca4dc893&v=4"/>
|
||||||
|
<author>
|
||||||
|
<name>Shinokuni</name>
|
||||||
|
<uri>https://github.com/Shinokuni</uri>
|
||||||
|
</author>
|
||||||
|
<content type="html">
|
||||||
|
<pre style='white-space:pre-wrap;width:81ex'>Use clear text mode for the feed url text input in AddFeedActivity</pre>
|
||||||
|
</content>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<id>tag:github.com,2008:Grit::Commit/d59e38ee9d11da186131b602425231eff0896956</id>
|
||||||
|
<link type="text/html" rel="alternate" href="https://github.com/readrops/Readrops/commit/d59e38ee9d11da186131b602425231eff0896956"/>
|
||||||
|
<title>
|
||||||
|
Use project level okhttp client with glide
|
||||||
|
</title>
|
||||||
|
<updated>2020-09-05T12:05:16Z</updated>
|
||||||
|
<media:thumbnail height="30" width="30" url="https://avatars2.githubusercontent.com/u/18555673?s=30&u=c56b216e8d128d0ec217062feeace9faca4dc893&v=4"/>
|
||||||
|
<author>
|
||||||
|
<name>Shinokuni</name>
|
||||||
|
<uri>https://github.com/Shinokuni</uri>
|
||||||
|
</author>
|
||||||
|
<content type="html">
|
||||||
|
<pre style='white-space:pre-wrap;width:81ex'>Use project level okhttp client with glide</pre>
|
||||||
|
</content>
|
||||||
|
</entry>
|
||||||
|
</feed>
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xml:lang="en-US">
|
||||||
|
<id>tag:github.com,2008:/readrops/Readrops/commits/develop</id>
|
||||||
|
<link type="text/html" rel="alternate" href="https://github.com/readrops/Readrops/commits/develop"/>
|
||||||
|
<link type="application/atom+xml" rel="self" href="https://github.com/readrops/Readrops/commits/develop.atom"/>
|
||||||
|
<title>Recent Commits to Readrops:develop</title>
|
||||||
|
<updated>2020-09-06T21:09:59Z</updated>
|
||||||
|
<entry>
|
||||||
|
<id>tag:github.com,2008:Grit::Commit/c15f093a1bc4211e85f8d1817c9073e307afe5ac</id>
|
||||||
|
<title>Add an option to open item url in custom tab</title>
|
||||||
|
<link type="text/html" rel="alternate" href="https://github.com/readrops/Readrops/commit/c15f093a1bc4211e85f8d1817c9073e307afe5ac"/>
|
||||||
|
<media:thumbnail height="30" width="30" url="https://avatars2.githubusercontent.com/u/18555673?s=30&u=c56b216e8d128d0ec217062feeace9faca4dc893&v=4"/>
|
||||||
|
<author>
|
||||||
|
<name>Shinokuni</name>
|
||||||
|
<uri>https://github.com/Shinokuni</uri>
|
||||||
|
</author>
|
||||||
|
<summary>Summary</summary>
|
||||||
|
<content type="html">
|
||||||
|
<pre style='white-space:pre-wrap;width:81ex'>Add an option to open item url in custom tab</pre>
|
||||||
|
</content>
|
||||||
|
</entry>
|
||||||
|
</feed>
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xml:lang="en-US">
|
||||||
|
<id>tag:github.com,2008:/readrops/Readrops/commits/develop</id>
|
||||||
|
<link type="text/html" rel="alternate" href="https://github.com/readrops/Readrops/commits/develop"/>
|
||||||
|
<link type="application/atom+xml" rel="self" href="https://github.com/readrops/Readrops/commits/develop.atom"/>
|
||||||
|
<title>Recent Commits to Readrops:develop</title>
|
||||||
|
<updated>2020-09-06T21:09:59Z</updated>
|
||||||
|
<entry>
|
||||||
|
<id>tag:github.com,2008:Grit::Commit/c15f093a1bc4211e85f8d1817c9073e307afe5ac</id>
|
||||||
|
<title>Add an option to open item url in custom tab</title>
|
||||||
|
<updated>2020-09-06T21:09:59Z</updated>
|
||||||
|
<media:thumbnail height="30" width="30" url="https://avatars2.githubusercontent.com/u/18555673?s=30&u=c56b216e8d128d0ec217062feeace9faca4dc893&v=4"/>
|
||||||
|
<author>
|
||||||
|
<name>Shinokuni</name>
|
||||||
|
<uri>https://github.com/Shinokuni</uri>
|
||||||
|
</author>
|
||||||
|
<summary>Summary</summary>
|
||||||
|
<content type="html">
|
||||||
|
<pre style='white-space:pre-wrap;width:81ex'>Add an option to open item url in custom tab</pre>
|
||||||
|
</content>
|
||||||
|
</entry>
|
||||||
|
</feed>
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xml:lang="en-US">
|
||||||
|
<id>tag:github.com,2008:/readrops/Readrops/commits/develop</id>
|
||||||
|
<link type="text/html" rel="alternate" href="https://github.com/readrops/Readrops/commits/develop"/>
|
||||||
|
<link type="application/atom+xml" rel="self" href="https://github.com/readrops/Readrops/commits/develop.atom"/>
|
||||||
|
<title>Recent Commits to Readrops:develop</title>
|
||||||
|
<updated>2020-09-06T21:09:59Z</updated>
|
||||||
|
<entry>
|
||||||
|
<id>tag:github.com,2008:Grit::Commit/c15f093a1bc4211e85f8d1817c9073e307afe5ac</id>
|
||||||
|
<link type="text/html" rel="alternate" href="https://github.com/readrops/Readrops/commit/c15f093a1bc4211e85f8d1817c9073e307afe5ac"/>
|
||||||
|
<updated>2020-09-06T21:09:59Z</updated>
|
||||||
|
<media:thumbnail height="30" width="30" url="https://avatars2.githubusercontent.com/u/18555673?s=30&u=c56b216e8d128d0ec217062feeace9faca4dc893&v=4"/>
|
||||||
|
<author>
|
||||||
|
<name>Shinokuni</name>
|
||||||
|
<uri>https://github.com/Shinokuni</uri>
|
||||||
|
</author>
|
||||||
|
<summary>Summary</summary>
|
||||||
|
<content type="html">
|
||||||
|
<pre style='white-space:pre-wrap;width:81ex'>Add an option to open item url in custom tab</pre>
|
||||||
|
</content>
|
||||||
|
</entry>
|
||||||
|
</feed>
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.readrops.api.localfeed.atom
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
|
import com.readrops.api.utils.DateUtils
|
||||||
|
import com.readrops.api.utils.ParseException
|
||||||
|
import junit.framework.TestCase.assertEquals
|
||||||
|
import junit.framework.TestCase.assertNotNull
|
||||||
|
import org.junit.Assert
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class ATOMItemsAdapterTest {
|
||||||
|
|
||||||
|
private val context: Context = InstrumentationRegistry.getInstrumentation().context
|
||||||
|
|
||||||
|
private val adapter = ATOMItemsAdapter()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun normalCasesTest() {
|
||||||
|
val stream = context.resources.assets.open("localfeed/atom/atom_items.xml")
|
||||||
|
|
||||||
|
val items = adapter.fromXml(stream)
|
||||||
|
val item = items[0]
|
||||||
|
|
||||||
|
assertEquals(items.size, 4)
|
||||||
|
assertEquals(item.title, "Add an option to open item url in custom tab")
|
||||||
|
assertEquals(item.link, "https://github.com/readrops/Readrops/commit/c15f093a1bc4211e85f8d1817c9073e307afe5ac")
|
||||||
|
assertEquals(item.pubDate, DateUtils.stringToLocalDateTime("2020-09-06T21:09:59Z"))
|
||||||
|
assertEquals(item.author, "Shinokuni")
|
||||||
|
assertEquals(item.description, "Summary")
|
||||||
|
assertEquals(item.guid, "tag:github.com,2008:Grit::Commit/c15f093a1bc4211e85f8d1817c9073e307afe5ac")
|
||||||
|
assertNotNull(item.content)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun noTitleTest() {
|
||||||
|
val stream = context.resources.assets.open("localfeed/atom/atom_items_no_title.xml")
|
||||||
|
|
||||||
|
Assert.assertThrows("Item title is required", ParseException::class.java) { adapter.fromXml(stream) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun noLinkTest() {
|
||||||
|
val stream = context.resources.assets.open("localfeed/atom/atom_items_no_link.xml")
|
||||||
|
|
||||||
|
Assert.assertThrows("Item link is required", ParseException::class.java) { adapter.fromXml(stream) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun noDateTest() {
|
||||||
|
val stream = context.resources.assets.open("localfeed/atom/atom_items_no_date.xml")
|
||||||
|
|
||||||
|
Assert.assertThrows("Item date is required", ParseException::class.java) { adapter.fromXml(stream) }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package com.readrops.api.localfeed
|
package com.readrops.api.localfeed
|
||||||
|
|
||||||
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.rss.RSSFeedAdapter
|
import com.readrops.api.localfeed.rss.RSSFeedAdapter
|
||||||
import com.readrops.api.localfeed.rss.RSSItemsAdapter
|
import com.readrops.api.localfeed.rss.RSSItemsAdapter
|
||||||
import com.readrops.db.entities.Feed
|
import com.readrops.db.entities.Feed
|
||||||
|
@ -23,6 +24,7 @@ interface XmlAdapter<T> {
|
||||||
fun xmlItemsAdapterFactory(type: LocalRSSHelper.RSSType): XmlAdapter<List<Item>> {
|
fun xmlItemsAdapterFactory(type: LocalRSSHelper.RSSType): XmlAdapter<List<Item>> {
|
||||||
return when (type) {
|
return when (type) {
|
||||||
LocalRSSHelper.RSSType.RSS_2 -> RSSItemsAdapter()
|
LocalRSSHelper.RSSType.RSS_2 -> RSSItemsAdapter()
|
||||||
|
LocalRSSHelper.RSSType.ATOM -> ATOMItemsAdapter()
|
||||||
else -> throw Exception("Unknown RSS type : $type")
|
else -> throw Exception("Unknown RSS type : $type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
package com.readrops.api.localfeed.atom
|
||||||
|
|
||||||
|
import com.gitlab.mvysny.konsumexml.Names
|
||||||
|
import com.gitlab.mvysny.konsumexml.allChildrenAutoIgnore
|
||||||
|
import com.gitlab.mvysny.konsumexml.konsumeXml
|
||||||
|
import com.readrops.api.localfeed.XmlAdapter
|
||||||
|
import com.readrops.api.utils.DateUtils
|
||||||
|
import com.readrops.api.utils.ParseException
|
||||||
|
import com.readrops.api.utils.nonNullText
|
||||||
|
import com.readrops.api.utils.nullableText
|
||||||
|
import com.readrops.db.entities.Item
|
||||||
|
import java.io.InputStream
|
||||||
|
|
||||||
|
class ATOMItemsAdapter : XmlAdapter<List<Item>> {
|
||||||
|
|
||||||
|
override fun fromXml(inputStream: InputStream): List<Item> {
|
||||||
|
val konsume = inputStream.konsumeXml()
|
||||||
|
val items = arrayListOf<Item>()
|
||||||
|
|
||||||
|
return try {
|
||||||
|
konsume.child("feed") {
|
||||||
|
allChildrenAutoIgnore("entry") {
|
||||||
|
val item = Item().apply {
|
||||||
|
allChildrenAutoIgnore(names) {
|
||||||
|
when (tagName) {
|
||||||
|
"title" -> title = nonNullText()
|
||||||
|
"id" -> guid = nullableText()
|
||||||
|
"updated" -> pubDate = DateUtils.stringToLocalDateTime(nonNullText())
|
||||||
|
"link" -> if (attributes["rel"] == "alternate") link = attributes["href"]
|
||||||
|
"author" -> allChildrenAutoIgnore("name") { author = text() }
|
||||||
|
"summary" -> description = nullableText()
|
||||||
|
"content" -> content = nullableText()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
validateItem(item)
|
||||||
|
if (item.guid == null) item.guid = item.link
|
||||||
|
|
||||||
|
items += item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
konsume.close()
|
||||||
|
items
|
||||||
|
} catch (e: Exception) {
|
||||||
|
throw ParseException(e.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun validateItem(item: Item) {
|
||||||
|
when {
|
||||||
|
item.title == null -> throw ParseException("Item title is required")
|
||||||
|
item.link == null -> throw ParseException("Item link is required")
|
||||||
|
item.pubDate == null -> throw ParseException("Item date id required")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val names = Names.of("title", "id", "updated", "link", "author", "summary", "content")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue