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
|
||||
|
||||
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.RSSItemsAdapter
|
||||
import com.readrops.db.entities.Feed
|
||||
|
@ -23,6 +24,7 @@ interface XmlAdapter<T> {
|
|||
fun xmlItemsAdapterFactory(type: LocalRSSHelper.RSSType): XmlAdapter<List<Item>> {
|
||||
return when (type) {
|
||||
LocalRSSHelper.RSSType.RSS_2 -> RSSItemsAdapter()
|
||||
LocalRSSHelper.RSSType.ATOM -> ATOMItemsAdapter()
|
||||
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