Add recent comments RSS feed
authorLanius Trolling <lanius@laniustrolling.dev>
Thu, 11 Jan 2024 13:28:37 +0000 (08:28 -0500)
committerLanius Trolling <lanius@laniustrolling.dev>
Thu, 11 Jan 2024 13:29:45 +0000 (08:29 -0500)
src/jvmMain/kotlin/info/mechyrdia/Factbooks.kt
src/jvmMain/kotlin/info/mechyrdia/data/views_comment.kt
src/jvmMain/kotlin/info/mechyrdia/lore/view_nav.kt
src/jvmMain/kotlin/info/mechyrdia/lore/views_rss.kt

index 9892827e4be285bcb8ab452a90b96a3c6f5681eb..f2f6f8eefb40e4c35374c5718d1bb240926724ad 100644 (file)
@@ -170,6 +170,10 @@ fun Application.factbooks() {
                        call.respondText(buildString { generateRecentPageEdits() }, ContentType.Application.Rss)
                }
                
+               get("/comments.rss") {
+                       call.respondText(buildString(call.recentCommentsRssFeedGenerator()), ContentType.Application.Rss)
+               }
+               
                // Client settings
                
                get("/change-theme") {
index 96f64bdad94d30cc3e7c953f918778ccd1dec8e8..3f8ad93ae1d8c052ba3459ef6fae2840775dd301 100644 (file)
@@ -35,7 +35,7 @@ suspend fun ApplicationCall.recentCommentsPage(): HTML.() -> Unit {
                Comment.Table
                        .sorted(Sorts.descending(Comment::submittedAt.serialName))
                        .filterNot { comment ->
-                               NationData.get(comment.submittedBy).isBanned
+                               comment.submittedBy != currNation?.id && NationData.get(comment.submittedBy).isBanned
                        }
                        .take(limit)
                        .toList(),
index 05a40e6722d9a70cbc768a63ecbbe8a031b1db83..3a35966917e8cf61e2c9926c38507e443c8a595c 100644 (file)
@@ -53,6 +53,7 @@ suspend fun ApplicationCall.standardNavBar(path: List<String>? = null) = listOf(
        NavHead("Useful Links"),
        NavLink("/comment/help", "Commenting Help"),
        NavLink("/comment/recent", "Recent Comments"),
+       NavLink("/comments.rss", "RSS Feed: New Comments"),
        NavLink("/edits.rss", "RSS Feed: Page Updates"),
 ) + loadExternalLinks()
 
index 021f5c3c8b9253b6d75f1a71fe32ef212a8194d9..b4abc54e69222ff11f381c48bb1902d36d4ef164 100644 (file)
@@ -1,7 +1,13 @@
 package info.mechyrdia.lore
 
+import com.mongodb.client.model.Sorts
 import info.mechyrdia.Configuration
+import info.mechyrdia.data.*
+import io.ktor.server.application.*
 import io.ktor.util.*
+import kotlinx.coroutines.flow.filterNot
+import kotlinx.coroutines.flow.take
+import kotlinx.coroutines.flow.toList
 import java.io.File
 import java.time.Instant
 import java.time.ZoneOffset
@@ -34,7 +40,7 @@ fun Appendable.generateRecentPageEdits() {
        RssChannel(
                title = "Recently Edited Factbooks | The Hour of Decision",
                link = "https://mechyrdia.info",
-               description = "A RSS news feed containing all factbooks in The Hour of Decision, in order of most recently edited.",
+               description = "An RSS feed containing all factbooks in The Hour of Decision, in order of most recently edited.",
                pubDate = mostRecentChange,
                lastBuildDate = mostRecentChange,
                ttl = 30,
@@ -80,6 +86,62 @@ fun Appendable.generateRecentPageEdits() {
        ).toXml(this)
 }
 
+suspend fun ApplicationCall.recentCommentsRssFeedGenerator(): Appendable.() -> Unit {
+       val currNation = currentNation()
+       
+       val limit = request.queryParameters["limit"]?.toIntOrNull() ?: 10
+       
+       val validLimits = 1..100
+       
+       if (limit !in validLimits)
+               return RssChannel(
+                       title = "Recent Comments - Error | The Hour of Decision",
+                       link = "https://mechyrdia.info/comment/recent",
+                       description = "Comment limit must be between ${validLimits.first} and ${validLimits.last}, got $limit",
+                       pubDate = null,
+                       lastBuildDate = Instant.now(),
+                       ttl = 120,
+               )::toXml
+       
+       val comments = CommentRenderData(
+               Comment.Table
+                       .sorted(Sorts.descending(Comment::submittedAt.serialName))
+                       .filterNot { comment ->
+                               comment.submittedBy != currNation?.id && NationData.get(comment.submittedBy).isBanned
+                       }
+                       .take(limit)
+                       .toList(),
+               nationCache
+       )
+       
+       val mostRecentComment = comments.firstOrNull()?.submittedAt
+       
+       return RssChannel(
+               title = "Recent Comments | The Hour of Decision",
+               link = "https://mechyrdia.info/comment/recent",
+               description = "An RSS feed containing the $limit most recently-submitted comments",
+               pubDate = mostRecentComment,
+               lastBuildDate = mostRecentComment,
+               ttl = 60,
+               categories = listOf(
+                       RssCategory(domain = "https://nationstates.net", category = "Mechyrdia")
+               ),
+               items = comments.map { comment ->
+                       RssItem(
+                               title = "Comment by ${comment.submittedBy.name} on https://mechyrdia.info/lore/${comment.submittedIn}",
+                               description = comment.contentsRaw.replace(INSIDE_TAG_TEXT, "").escapeHTML(),
+                               link = "https://mechyrdia.info/comment/view/${comment.id}",
+                               author = null,
+                               comments = "https://mechyrdia.info/lore/${comment.submittedIn}#comments",
+                               pubDate = comment.lastEdit ?: comment.submittedAt,
+                               categories = listOf(
+                                       RssCategory(domain = "https://nationstates.net", category = comment.submittedBy.name)
+                               )
+                       )
+               }
+       )::toXml
+}
+
 data class RssCategory(
        val category: String,
        val domain: String? = null