-
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
244 additions
and
108 deletions.
There are no files selected for viewing
25 changes: 23 additions & 2 deletions
25
feedfinder/src/main/java/com/jocmp/feedfinder/DefaultRequest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,30 @@ | ||
package com.jocmp.feedfinder | ||
|
||
import java.net.URL | ||
import java.net.http.HttpClient | ||
import java.net.http.HttpRequest | ||
import java.net.http.HttpResponse | ||
|
||
internal class DefaultRequest: Request { | ||
|
||
internal class DefaultRequest( | ||
private val client: HttpClient = buildClient() | ||
) : Request { | ||
override suspend fun fetch(url: URL): Response { | ||
TODO("Not yet implemented") | ||
val request = HttpRequest.newBuilder(url.toURI()) | ||
.GET() | ||
.build() | ||
|
||
val body = client.send(request, HttpResponse.BodyHandlers.ofString()).body() | ||
|
||
return Response(body = body) | ||
} | ||
|
||
companion object { | ||
fun buildClient(): HttpClient { | ||
return HttpClient | ||
.newBuilder() | ||
.followRedirects(HttpClient.Redirect.ALWAYS) | ||
.build() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 13 additions & 4 deletions
17
feedfinder/src/main/java/com/jocmp/feedfinder/parser/XMLFeed.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,31 @@ | ||
package com.jocmp.feedfinder.parser | ||
|
||
import com.prof18.rssparser.RssParser | ||
import com.prof18.rssparser.exception.RssParsingException | ||
import com.prof18.rssparser.model.RssChannel | ||
|
||
internal class XMLFeed(private val channel: RssChannel) : Feed { | ||
internal class XMLFeed(private val channel: RssChannel?) : Feed { | ||
override fun isValid(): Boolean { | ||
return !channel.link.isNullOrBlank() && | ||
return channel != null && | ||
!channel.link.isNullOrBlank() && | ||
!channel.title.isNullOrBlank() && | ||
hasEntries() | ||
} | ||
|
||
private fun hasEntries(): Boolean { | ||
return channel.items.isNotEmpty() | ||
return channel != null && | ||
channel.items.isNotEmpty() | ||
} | ||
|
||
companion object { | ||
suspend fun from(body: String): XMLFeed { | ||
return XMLFeed(RssParser().parse(body)) | ||
val channel = try { | ||
RssParser().parse(body) | ||
} catch (e: RssParsingException) { | ||
null | ||
} | ||
|
||
return XMLFeed(channel) | ||
} | ||
} | ||
} |
33 changes: 0 additions & 33 deletions
33
feedfinder/src/main/java/com/jocmp/feedfinder/sources/MetaLink.kt
This file was deleted.
Oops, something went wrong.
50 changes: 50 additions & 0 deletions
50
feedfinder/src/main/java/com/jocmp/feedfinder/sources/MetaLinkSource.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package com.jocmp.feedfinder.sources | ||
|
||
import com.jocmp.feedfinder.DefaultRequest | ||
import com.jocmp.feedfinder.Request | ||
import com.jocmp.feedfinder.Response | ||
import com.jocmp.feedfinder.parser.Feed | ||
import com.jocmp.feedfinder.parser.Parser | ||
import org.jsoup.nodes.Element | ||
import java.net.URL | ||
import kotlinx.coroutines.async | ||
import kotlinx.coroutines.awaitAll | ||
import kotlinx.coroutines.coroutineScope | ||
|
||
internal class MetaLinkSource( | ||
private val response: Response, | ||
private val request: Request = DefaultRequest() | ||
) : Source { | ||
override suspend fun find(): List<Feed> { | ||
val document = response.findDocument() ?: return emptyList() | ||
|
||
return coroutineScope { | ||
document.select("link[rel~=alternate]") | ||
.filter { element -> isValidLink(element) } | ||
.map { async { request.fetch(url = URL(it.attr("href"))) } } | ||
.awaitAll() | ||
.mapNotNull { response -> | ||
when (val result = response.parse()) { | ||
is Parser.Result.ParsedFeed -> result.feed | ||
is Parser.Result.HTMLDocument -> null | ||
} | ||
} | ||
} | ||
} | ||
|
||
private fun isValidLink(element: Element): Boolean { | ||
val type = element.attr("type").lowercase() | ||
val href = element.attr("href") | ||
|
||
return href.isNotBlank() && linkTypes.contains(type) | ||
} | ||
|
||
companion object { | ||
private val linkTypes = setOf( | ||
"application/rss+xml", | ||
"application/atom+xml", | ||
"application/feed+json", | ||
"application/json" | ||
) | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
feedfinder/src/main/java/com/jocmp/feedfinder/sources/ResponseDocumentExt.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.jocmp.feedfinder.sources | ||
|
||
import com.jocmp.feedfinder.Response | ||
import com.jocmp.feedfinder.parser.Parser | ||
import org.jsoup.nodes.Document | ||
|
||
internal suspend fun Response.findDocument(): Document? { | ||
val result = parse(validate = false) | ||
|
||
if (result is Parser.Result.HTMLDocument) { | ||
return result.document | ||
} | ||
|
||
return null | ||
} |
7 changes: 0 additions & 7 deletions
7
feedfinder/src/main/java/com/jocmp/feedfinder/sources/ResponseSource.kt
This file was deleted.
Oops, something went wrong.
6 changes: 5 additions & 1 deletion
6
feedfinder/src/main/java/com/jocmp/feedfinder/sources/Source.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,11 @@ | ||
package com.jocmp.feedfinder.sources | ||
|
||
import com.jocmp.feedfinder.Response | ||
import com.jocmp.feedfinder.parser.Feed | ||
import com.jocmp.feedfinder.parser.Parser | ||
import org.jsoup.nodes.Document | ||
import java.net.URL | ||
|
||
sealed interface Source { | ||
internal sealed interface Source { | ||
suspend fun find(): List<Feed> | ||
} |
This file was deleted.
Oops, something went wrong.
17 changes: 17 additions & 0 deletions
17
feedfinder/src/main/java/com/jocmp/feedfinder/sources/XMLSource.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.jocmp.feedfinder.sources | ||
|
||
import com.jocmp.feedfinder.Response | ||
import com.jocmp.feedfinder.parser.Feed | ||
import com.jocmp.feedfinder.parser.Parser.Result.ParsedFeed | ||
|
||
internal class XMLSource(private val response: Response): Source { | ||
override suspend fun find(): List<Feed> { | ||
val result = response.parse() | ||
|
||
if (result is ParsedFeed && result.feed.isValid()) { | ||
return listOf(result.feed) | ||
} | ||
|
||
return emptyList() | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.jocmp.feedfinder | ||
|
||
import java.io.File | ||
|
||
fun testResource(resource: String): String { | ||
return "src/test/resources/${resource}" | ||
} | ||
|
||
fun testFile(resource: String): File { | ||
return File(testResource(resource)) | ||
} |
Oops, something went wrong.