Skip to content

Commit

Permalink
Changed feed parsing library to Gofeed
Browse files Browse the repository at this point in the history
Replaced Rome with https://github.com/mmcdole/gofeed instead.

This has greater compatibility with broken feeds.
  • Loading branch information
spacecowboy authored Mar 7, 2024
1 parent 54df2bf commit ef92b20
Show file tree
Hide file tree
Showing 51 changed files with 1,905 additions and 2,233 deletions.
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +0,0 @@
[submodule "rome"]
path = rome
url = https://gitlab.com/spacecowboy/rome.git
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
package com.nononsenseapps.feeder.model

import com.nononsenseapps.feeder.di.networkModule
import com.nononsenseapps.feeder.model.gofeed.GoFeedAdapter
import com.nononsenseapps.feeder.util.getOrElse
import com.nononsenseapps.jsonfeed.cachingHttpClient
import kotlinx.coroutines.runBlocking
import okhttp3.MediaType.Companion.toMediaTypeOrNull
Expand Down Expand Up @@ -41,9 +43,11 @@ class FeedParserTest : DIAware {
import(networkModule)
}

private val exp = GoFeedAdapter()

@Test
@Ignore
fun getAlternateLinksHandlesYoutube() {
fun getAlternateLinksHandlesYoutubeOnline() {
// I want this to be an Online test to make sure that I notice if/when Youtube changes something which breaks it
runBlocking {
val feeds =
Expand All @@ -58,6 +62,30 @@ class FeedParserTest : DIAware {
}
}

@Test
fun canParseUkrnet() {
runBlocking {
readResource("rss_ukrnet.xml") {
// val feed = exp.parseBody(it)
//

// assertEquals(20, feed?.items?.size, "Expected 20 items")

val feed =
feedParser.parseFeedResponse(
URL("https://suspilne.media/rss/ukrnet.rss"),
it,
)

feed.leftOrNull()?.throwable?.let { t ->
throw t
}

assertEquals(20, feed.getOrNull()?.items?.size, "Expected 20 items")
}
}
}

@Test
fun anime2youHasThumbnails() {
runBlocking {
Expand All @@ -66,7 +94,6 @@ class FeedParserTest : DIAware {
feedParser.parseFeedResponse(
URL("https://www.anime2you.de/feed/"),
it,
null,
)

val item = feed.getOrNull()?.items!!.first()
Expand Down Expand Up @@ -95,7 +122,6 @@ class FeedParserTest : DIAware {
feedParser.parseFeedResponse(
URL("http://https://www.openstreetmap.org/diary/rss"),
it,
null,
)
val item = feed.getOrNull()?.items!!.first()

Expand All @@ -113,7 +139,6 @@ class FeedParserTest : DIAware {
"http://hnapp.com/rss?q=type%3Astory%20score%3E36%20-bitcoin%20-ethereum%20-cryptocurrency%20-blockchain%20-snowden%20-hiring%20-ask",
),
it,
null,
)

val item = feed.getOrNull()?.items!![0]
Expand All @@ -140,7 +165,6 @@ class FeedParserTest : DIAware {
feedParser.parseFeedResponse(
URL("http://www.lemonde.fr/rss/une.xml"),
it,
null,
)

val item = feed.getOrNull()?.items!![0]
Expand All @@ -159,7 +183,6 @@ class FeedParserTest : DIAware {
feedParser.parseFeedResponse(
URL("http://www.youtube.com/feeds/videos.xml"),
it,
null,
)
}

Expand All @@ -177,7 +200,7 @@ class FeedParserTest : DIAware {
runBlocking {
val feed =
readResource("rss_peertube.xml") {
feedParser.parseFeedResponse(URL("https://framatube.org/feeds/videos.xml"), it, null)
feedParser.parseFeedResponse(URL("https://framatube.org/feeds/videos.xml"), it)
}

val item = feed.getOrNull()?.items!!.first()
Expand All @@ -200,7 +223,6 @@ class FeedParserTest : DIAware {
feedParser.parseFeedResponse(
URL("https://rutube.ru/mrss/video/person/11234072/"),
it,
null,
)
}

Expand All @@ -221,7 +243,6 @@ class FeedParserTest : DIAware {
feedParser.parseFeedResponse(
URL("https://myanimelist.net/rss/news.xml"),
it,
null,
)
}

Expand All @@ -241,7 +262,6 @@ class FeedParserTest : DIAware {
feedParser.parseFeedResponse(
URL("https://www.theguardian.com/world/rss"),
it,
null,
)
}

Expand All @@ -261,7 +281,6 @@ class FeedParserTest : DIAware {
feedParser.parseFeedResponse(
URL("https://nitter.weiler.rocks/lawnchairapp/rss"),
it,
null,
)
}

Expand Down Expand Up @@ -391,7 +410,6 @@ class FeedParserTest : DIAware {
feedParser.parseFeedResponse(
URL("http://cowboyprogrammer.org/feed.atom"),
atomRelative,
null,
)
assertTrue { feed.isRight() }

Expand All @@ -406,7 +424,6 @@ class FeedParserTest : DIAware {
feedParser.parseFeedResponse(
URL("http://cowboyprogrammer.org/feed.atom"),
atomRelativeNoBase,
null,
)
assertTrue { feed.isRight() }

Expand Down Expand Up @@ -511,8 +528,9 @@ class FeedParserTest : DIAware {
}

@Test
fun doesNotFetchVideos(): Unit =
fun doesNotFetchVideoContentType(): Unit =
runBlocking {
// This request uses a feed but the content type is video and should be ignored
val result = videoResponse.use { feedParser.parseFeedResponse(it) }
assertTrue {
result.isLeft()
Expand All @@ -522,6 +540,15 @@ class FeedParserTest : DIAware {
}
}

@Test
fun fetchesNullContentType(): Unit =
runBlocking {
val result = nullContentTypeResponse.use { feedParser.parseFeedResponse(it) }
assertTrue {
result.isRight()
}
}

@Test
@Throws(Exception::class)
fun cyklist() =
Expand Down Expand Up @@ -617,7 +644,7 @@ class FeedParserTest : DIAware {
item.image?.url,
)

assertEquals<List<Any>?>(emptyList(), item.attachments)
assertEquals<List<Any>?>(emptyList(), item.attachments ?: emptyList())
}

@Test
Expand All @@ -627,7 +654,7 @@ class FeedParserTest : DIAware {
val feed = cornucopiaAtom.use { feedParser.parseFeedResponse(it) }.getOrNull()!!

assertEquals("http://cornucopia.cornubot.se/", feed.home_page_url)
assertEquals("http://www.blogger.com/feeds/8354057230547055221/posts/default", feed.feed_url)
assertEquals("https://cornucopia.cornubot.se/feeds/posts/default", feed.feed_url)

assertEquals(25, feed.items!!.size)
val item = feed.items!!.first()
Expand All @@ -651,7 +678,7 @@ class FeedParserTest : DIAware {
item.image?.url,
)

assertEquals<List<Any>?>(emptyList(), item.attachments)
assertEquals<List<Any>?>(emptyList(), item.attachments ?: emptyList())
}

@Test
Expand Down Expand Up @@ -696,11 +723,49 @@ class FeedParserTest : DIAware {
)
}

@Test
fun testSlashdot() =
runBlocking {
val feed = slashdotResponse.use { feedParser.parseFeedResponse(it) }.getOrElse { throw it.throwable!! }

assertEquals("https://slashdot.org/", feed.home_page_url)
assertEquals("https://rss.slashdot.org/Slashdot/slashdotMain", feed.feed_url)

assertEquals(15, feed.items!!.size)
val item = feed.items!!.first()

assertEquals(
"https://a.fsdn.com/sd/topics/topicslashdot.gif",
feed.icon,
)

assertEquals(
"https://yro.slashdot.org/story/24/03/02/071229/ransomware-attack-hampers-prescription-drug-sales-at-90-of-us-pharmacies?utm_source=rss1.0mainlinkanon&utm_medium=feed",
item.url,
)

assertEquals(
"Ransomware Attack Hampers Prescription Drug Sales at 90% of US Pharmacies",
item.title,
)

assertEquals(
"\"A ransomware gang once thought to have been crippled by law enforcement has snarled prescription processing for millions of Americans over the past week...\" reports the Washington Post. \"The hackers ",
item.summary,
)

assertNull(item.image, "No image should be present")
}

@Test
@Throws(Exception::class)
fun londoner() =
runBlocking {
val feed = londoner.use { feedParser.parseFeedResponse(it) }.getOrNull()!!
val feed =
londoner.use { feedParser.parseFeedResponse(it) }.getOrElse {
System.err.println(it)
throw it.throwable!!
}

assertEquals("http://londonist.com/", feed.home_page_url)
assertEquals("http://londonist.com/feed", feed.feed_url)
Expand Down Expand Up @@ -755,13 +820,11 @@ class FeedParserTest : DIAware {
@Test
@Throws(Exception::class)
@Ignore
fun cowboyAuthenticated() =
fun cowboyAuthenticatedOnline() =
runBlocking {
runBlocking {
val feed =
feedParser.parseFeedUrl(URL("https://test:[email protected]/auth_basic/index.xml"))
assertEquals("Cowboy Programmer", feed.getOrNull()?.title)
}
val feed =
feedParser.parseFeedUrl(URL("https://test:[email protected]/auth_basic/index.xml"))
assertEquals("Cowboy Programmer", feed.getOrNull()?.title)
}

@Test
Expand All @@ -780,13 +843,11 @@ class FeedParserTest : DIAware {

@Test
@Ignore
@Throws(Exception::class)
fun fz() =
fun fzImgUrl() =
runBlocking {
val feed = fz.use { feedParser.parseFeedResponse(it) }.getOrNull()!!

assertEquals("http://www.fz.se/nyheter/", feed.home_page_url)
assertNull(feed.feed_url)

assertEquals(20, feed.items!!.size)
val item = feed.items!!.first()
Expand Down Expand Up @@ -817,6 +878,9 @@ class FeedParserTest : DIAware {
runBlocking {
val feed = contentTypeHtml.use { feedParser.parseFeedResponse(it) }

val gofeed = contentTypeHtml.use { exp.parseBody(it.body?.string() ?: "") }
print(gofeed)

val item = feed.getOrNull()?.items!!.single()

assertFalse(
Expand All @@ -835,11 +899,13 @@ class FeedParserTest : DIAware {
feedParser.parseFeedResponse(
URL("http://cowboyprogrammer.org"),
rssWithHtmlEscapedDescription,
null,
)

val item = feed.getOrNull()?.items!!.single()

val gofeed = exp.parseBody(rssWithHtmlEscapedDescription)
print(gofeed)

assertEquals(
"http://cowboyprogrammer.org/hello.jpg&cached=true",
item.image?.url,
Expand All @@ -857,7 +923,6 @@ class FeedParserTest : DIAware {
feedParser.parseFeedResponse(
URL("http://cowboyprogrammer.org"),
atomWithHtmlEscapedContents,
null,
)

val text = feed.getOrNull()?.items!!.first()
Expand Down Expand Up @@ -886,7 +951,7 @@ class FeedParserTest : DIAware {
xhtml.image?.url,
)
assertTrue("Actual:\n${xhtml.content_html}") {
"<img src=\"hello.jpg&amp;cached=true\" />" in xhtml.content_html!!
"<img src=\"hello.jpg&amp;cached=true\"/>" in xhtml.content_html!!
}
}

Expand All @@ -897,7 +962,6 @@ class FeedParserTest : DIAware {
feedParser.parseFeedResponse(
URL("https://gemini.circumlunar.space"),
atomWithUnknownProtocol,
null,
)

assertEquals(8, feed.getOrNull()?.items!!.size)
Expand Down Expand Up @@ -944,6 +1008,9 @@ class FeedParserTest : DIAware {
"http://utdelningsseglaren.blogspot.com/feeds/posts/default",
)

private val slashdotResponse: Response
get() = bytesToResponse("rdf_slashdot.xml", "https://rss.slashdot.org/Slashdot/slashdotMain")

private val lineageosRss: Response
get() = bytesToResponse("rss_lineageos.xml", "https://lineageos.org/feed.xml")

Expand Down Expand Up @@ -1003,6 +1070,14 @@ class FeedParserTest : DIAware {
"video/mp4",
)

private val nullContentTypeResponse: Response
get() =
bytesToResponse(
"rss_nixers_newsletter.xml",
"https://foo.bar/feed.xml",
null,
)

private val diskuse: Response
get() =
bytesToResponse(
Expand All @@ -1023,12 +1098,12 @@ class FeedParserTest : DIAware {
private fun bytesToResponse(
resourceName: String,
url: String,
contentType: String = "application/xml",
contentType: String? = "application/xml",
): Response {
val responseBody: ResponseBody =
javaClass.getResourceAsStream(resourceName)!!
.use { it.readBytes() }
.toResponseBody(contentType.toMediaTypeOrNull())
.toResponseBody(contentType?.toMediaTypeOrNull())

return Response.Builder()
.body(responseBody)
Expand Down
Loading

0 comments on commit ef92b20

Please sign in to comment.