Fallback to current date time if it is missing for RSS1 and ATOM items

This commit is contained in:
Shinokuni 2020-10-02 18:53:52 +02:00
parent 10a7b99e59
commit 5c4cc81628
4 changed files with 43 additions and 37 deletions

View File

@ -5,8 +5,7 @@ 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 junit.framework.TestCase.*
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
@ -35,24 +34,28 @@ class ATOMItemsAdapterTest {
assertNotNull(item.content)
}
@Test
fun noDateTest() {
val stream = context.resources.assets.open("localfeed/atom/atom_items_no_date.xml")
val item = adapter.fromXml(stream).first()
assertNotNull(item.pubDate)
}
@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) }
val exception = Assert.assertThrows(ParseException::class.java) { adapter.fromXml(stream) }
assertTrue(exception.message!!.contains("Item title is required"))
}
@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) }
val exception = Assert.assertThrows(ParseException::class.java) { adapter.fromXml(stream) }
assertTrue(exception.message!!.contains("Item link is required"))
}
@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

@ -5,8 +5,7 @@ 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 junit.framework.TestCase.*
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
@ -48,24 +47,27 @@ class RSS1ItemsAdapterTest {
"that-told-time-now-tells-the-time-remaining?utm_source=rss1.0mainlinkanon&utm_medium=feed")
}
@Test
fun nullDateTest() {
val stream = context.resources.assets.open("localfeed/rss1/rss1_items_no_date.xml")
val item = adapter.fromXml(stream).first()
assertNotNull(item.pubDate)
}
@Test
fun nullTitleTest() {
val stream = context.resources.assets.open("localfeed/rss1/rss1_items_no_title.xml")
Assert.assertThrows(ParseException::class.java) { adapter.fromXml(stream) }
val exception = Assert.assertThrows(ParseException::class.java) { adapter.fromXml(stream) }
assertTrue(exception.message!!.contains("Item title is required"))
}
@Test
fun nullLinkTest() {
val stream = context.resources.assets.open("localfeed/rss1/rss1_items_no_link.xml")
Assert.assertThrows(ParseException::class.java) { adapter.fromXml(stream) }
}
@Test
fun nullDateTest() {
val stream = context.resources.assets.open("localfeed/rss1/rss1_items_no_date.xml")
Assert.assertThrows(ParseException::class.java) { adapter.fromXml(stream) }
val exception = Assert.assertThrows(ParseException::class.java) { adapter.fromXml(stream) }
assertTrue(exception.message!!.contains("RSS1 link or about element is required"))
}
}

View File

@ -7,50 +7,53 @@ import com.gitlab.mvysny.konsumexml.konsumeXml
import com.readrops.api.localfeed.XmlAdapter
import com.readrops.api.utils.*
import com.readrops.db.entities.Item
import org.joda.time.LocalDateTime
import java.io.InputStream
class ATOMItemsAdapter : XmlAdapter<List<Item>> {
override fun fromXml(inputStream: InputStream): List<Item> {
val konsume = inputStream.konsumeXml()
val konsumer = inputStream.konsumeXml()
val items = arrayListOf<Item>()
return try {
konsume.child("feed") {
konsumer.child("feed") {
allChildrenAutoIgnore("entry") {
val item = Item().apply {
allChildrenAutoIgnore(names) {
when (tagName) {
"title" -> title = nonNullText()
"id" -> guid = nullableText()
"updated" -> pubDate = DateUtils.parse(nonNullText())
"updated" -> pubDate = DateUtils.parse(nullableText())
"link" -> parseLink(this, this@apply)
"author" -> allChildrenAutoIgnore("name") { author = nullableText() }
"summary" -> description = nullableTextRecursively()
"content" -> content = nullableTextRecursively()
else -> skipContents()
}
}
}
validateItem(item)
if (item.pubDate == null) item.pubDate = LocalDateTime.now()
if (item.guid == null) item.guid = item.link
items += item
}
}
konsume.close()
konsumer.close()
items
} catch (e: Exception) {
throw ParseException(e.message)
}
}
private fun parseLink(konsume: Konsumer, item: Item) {
konsume.apply {
private fun parseLink(konsumer: Konsumer, item: Item) {
konsumer.apply {
if (attributes.getValueOpt("rel") == null ||
attributes["rel"] == "alternate")
item.link = attributes["href"]
item.link = attributes.getValueOpt("href")
}
}
@ -59,7 +62,6 @@ class ATOMItemsAdapter : XmlAdapter<List<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")
}
}

View File

@ -7,16 +7,17 @@ import com.readrops.api.localfeed.XmlAdapter
import com.readrops.api.localfeed.XmlAdapter.Companion.AUTHORS_MAX
import com.readrops.api.utils.*
import com.readrops.db.entities.Item
import org.joda.time.LocalDateTime
import java.io.InputStream
class RSS1ItemsAdapter : XmlAdapter<List<Item>> {
override fun fromXml(inputStream: InputStream): List<Item> {
val konsume = inputStream.konsumeXml()
val konsumer = inputStream.konsumeXml()
val items = arrayListOf<Item>()
return try {
konsume.child("RDF") {
konsumer.child("RDF") {
allChildrenAutoIgnore("item") {
val authors = arrayListOf<String?>()
val about = attributes.getValueOpt("about",
@ -27,7 +28,7 @@ class RSS1ItemsAdapter : XmlAdapter<List<Item>> {
when (tagName) {
"title" -> title = nonNullText()
"link" -> link = nullableText()
"dc:date" -> pubDate = DateUtils.parse(nonNullText())
"dc:date" -> pubDate = DateUtils.parse(nullableText())
"dc:creator" -> authors += nullableText()
"description" -> description = nullableTextRecursively()
"content:encoded" -> content = nullableTextRecursively()
@ -36,6 +37,7 @@ class RSS1ItemsAdapter : XmlAdapter<List<Item>> {
}
}
if (item.pubDate == null) item.pubDate = LocalDateTime.now()
if (item.link == null) item.link = about
?: throw ParseException("RSS1 link or about element is required")
item.guid = item.link
@ -49,7 +51,7 @@ class RSS1ItemsAdapter : XmlAdapter<List<Item>> {
}
}
konsume.close()
konsumer.close()
items
} catch (e: Exception) {
throw ParseException(e.message)
@ -57,10 +59,7 @@ class RSS1ItemsAdapter : XmlAdapter<List<Item>> {
}
private fun validateItem(item: Item) {
when {
item.title == null -> throw ParseException("Item title is required")
item.pubDate == null -> throw ParseException("Item date is required")
}
if (item.title == null) throw ParseException("Item title is required")
}
companion object {