Add adapter for parsing atom entries

This commit is contained in:
Shinokuni 2020-09-14 19:41:10 +02:00
parent 5c342a45b6
commit 0c48bd2adb
7 changed files with 259 additions and 0 deletions

View File

@ -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&amp;u=c56b216e8d128d0ec217062feeace9faca4dc893&amp;v=4"/>
<author>
<name>Shinokuni</name>
<uri>https://github.com/Shinokuni</uri>
</author>
<summary>Summary</summary>
<content type="html">
&lt;pre style=&#39;white-space:pre-wrap;width:81ex&#39;&gt;Add an option to open item url in custom tab&lt;/pre&gt;
</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&amp;u=c56b216e8d128d0ec217062feeace9faca4dc893&amp;v=4"/>
<author>
<name>Shinokuni</name>
<uri>https://github.com/Shinokuni</uri>
</author>
<content type="html">
&lt;pre style=&#39;white-space:pre-wrap;width:81ex&#39;&gt;Use gradle parallel builds&lt;/pre&gt;
</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&amp;u=c56b216e8d128d0ec217062feeace9faca4dc893&amp;v=4"/>
<author>
<name>Shinokuni</name>
<uri>https://github.com/Shinokuni</uri>
</author>
<content type="html">
&lt;pre style=&#39;white-space:pre-wrap;width:81ex&#39;&gt;Use clear text mode for the feed url text input in AddFeedActivity&lt;/pre&gt;
</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&amp;u=c56b216e8d128d0ec217062feeace9faca4dc893&amp;v=4"/>
<author>
<name>Shinokuni</name>
<uri>https://github.com/Shinokuni</uri>
</author>
<content type="html">
&lt;pre style=&#39;white-space:pre-wrap;width:81ex&#39;&gt;Use project level okhttp client with glide&lt;/pre&gt;
</content>
</entry>
</feed>

View File

@ -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&amp;u=c56b216e8d128d0ec217062feeace9faca4dc893&amp;v=4"/>
<author>
<name>Shinokuni</name>
<uri>https://github.com/Shinokuni</uri>
</author>
<summary>Summary</summary>
<content type="html">
&lt;pre style=&#39;white-space:pre-wrap;width:81ex&#39;&gt;Add an option to open item url in custom tab&lt;/pre&gt;
</content>
</entry>
</feed>

View File

@ -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&amp;u=c56b216e8d128d0ec217062feeace9faca4dc893&amp;v=4"/>
<author>
<name>Shinokuni</name>
<uri>https://github.com/Shinokuni</uri>
</author>
<summary>Summary</summary>
<content type="html">
&lt;pre style=&#39;white-space:pre-wrap;width:81ex&#39;&gt;Add an option to open item url in custom tab&lt;/pre&gt;
</content>
</entry>
</feed>

View File

@ -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&amp;u=c56b216e8d128d0ec217062feeace9faca4dc893&amp;v=4"/>
<author>
<name>Shinokuni</name>
<uri>https://github.com/Shinokuni</uri>
</author>
<summary>Summary</summary>
<content type="html">
&lt;pre style=&#39;white-space:pre-wrap;width:81ex&#39;&gt;Add an option to open item url in custom tab&lt;/pre&gt;
</content>
</entry>
</feed>

View File

@ -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) }
}
}

View File

@ -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")
} }
} }

View File

@ -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")
}
}