src/main/kotlin/de/uapcore/lightpit/servlet/FeedServlet.kt

changeset 242
b7f3e972b13c
parent 241
1ca4f27cefe8
child 254
55ca6cafc3dd
     1.1 --- a/src/main/kotlin/de/uapcore/lightpit/servlet/FeedServlet.kt	Sat Nov 27 12:12:20 2021 +0100
     1.2 +++ b/src/main/kotlin/de/uapcore/lightpit/servlet/FeedServlet.kt	Sat Nov 27 13:03:57 2021 +0100
     1.3 @@ -30,8 +30,10 @@
     1.4  import de.uapcore.lightpit.AbstractServlet
     1.5  import de.uapcore.lightpit.HttpRequest
     1.6  import de.uapcore.lightpit.dao.DataAccessObject
     1.7 -import de.uapcore.lightpit.entities.IssueHistoryData
     1.8 +import de.uapcore.lightpit.entities.IssueCommentHistoryEntry
     1.9  import de.uapcore.lightpit.entities.IssueHistoryEntry
    1.10 +import de.uapcore.lightpit.types.IssueHistoryType
    1.11 +import de.uapcore.lightpit.viewmodel.CommentDiff
    1.12  import de.uapcore.lightpit.viewmodel.IssueDiff
    1.13  import de.uapcore.lightpit.viewmodel.IssueFeed
    1.14  import de.uapcore.lightpit.viewmodel.IssueFeedEntry
    1.15 @@ -46,8 +48,36 @@
    1.16          get("/%project/issues.rss", this::issues)
    1.17      }
    1.18  
    1.19 -    private fun fullContent(issue: IssueHistoryData) = IssueDiff(
    1.20 -        issue.id,
    1.21 +    val diffGenerator by lazyOf(DiffRowGenerator.create()
    1.22 +        .showInlineDiffs(true)
    1.23 +        .mergeOriginalRevised(true)
    1.24 +        .inlineDiffByWord(true)
    1.25 +        .oldTag { start -> if (start) "<strike style=\"color:red\">" else "</strike>" }
    1.26 +        .newTag { start -> if (start) "<i style=\"color: green\">" else "</i>" }
    1.27 +        .build()
    1.28 +    )
    1.29 +
    1.30 +    private fun fullContent(data: IssueCommentHistoryEntry) =
    1.31 +        CommentDiff(
    1.32 +            data.issueid,
    1.33 +            data.commentid,
    1.34 +            data.subject,
    1.35 +            data.comment.replace("\r", "")
    1.36 +        )
    1.37 +
    1.38 +    private fun diffContent(cur: IssueCommentHistoryEntry, next: IssueCommentHistoryEntry) =
    1.39 +        CommentDiff(
    1.40 +            cur.issueid,
    1.41 +            cur.commentid,
    1.42 +            cur.subject,
    1.43 +            diffGenerator.generateDiffRows(
    1.44 +                next.comment.replace("\r", "").split('\n'),
    1.45 +                cur.comment.replace("\r", "").split('\n')
    1.46 +            ).joinToString("\n", transform = DiffRow::getOldLine)
    1.47 +        )
    1.48 +
    1.49 +    private fun fullContent(issue: IssueHistoryEntry) = IssueDiff(
    1.50 +        issue.issueid,
    1.51          issue.subject,
    1.52          issue.component,
    1.53          issue.status.name,
    1.54 @@ -60,19 +90,10 @@
    1.55          issue.resolved
    1.56      )
    1.57  
    1.58 -    private fun diffContent(cur: IssueHistoryData, next: IssueHistoryData): IssueDiff {
    1.59 -        val generator = DiffRowGenerator.create()
    1.60 -            .showInlineDiffs(true)
    1.61 -            .mergeOriginalRevised(true)
    1.62 -            .inlineDiffByWord(true)
    1.63 -            .oldTag { start -> if (start) "<strike style=\"color:red\">" else "</strike>" }
    1.64 -            .newTag { start -> if (start) "<i style=\"color: green\">" else "</i>" }
    1.65 -            .build()
    1.66 -
    1.67 +    private fun diffContent(cur: IssueHistoryEntry, next: IssueHistoryEntry): IssueDiff {
    1.68          val prev = fullContent(next)
    1.69          val diff = fullContent(cur)
    1.70 -
    1.71 -        val result = generator.generateDiffRows(
    1.72 +        val result = diffGenerator.generateDiffRows(
    1.73              listOf(
    1.74                  prev.subject, prev.component, prev.status,
    1.75                  prev.category, prev.assignee, prev.eta, prev.affected, prev.resolved
    1.76 @@ -92,7 +113,7 @@
    1.77          diff.affected = result[6].oldLine
    1.78          diff.resolved = result[7].oldLine
    1.79  
    1.80 -        diff.description = generator.generateDiffRows(
    1.81 +        diff.description = diffGenerator.generateDiffRows(
    1.82              prev.description.split('\n'),
    1.83              diff.description.split('\n')
    1.84          ).joinToString("\n", transform = DiffRow::getOldLine)
    1.85 @@ -102,21 +123,42 @@
    1.86  
    1.87      /**
    1.88       * Generates the feed entries.
    1.89 -     * Assumes that [historyEntry] is already sorted by timestamp (descending).
    1.90 +     * Assumes that [issueEntries] and [commentEntries] are already sorted by timestamp (descending).
    1.91       */
    1.92 -    private fun generateFeedEntries(historyEntry: List<IssueHistoryEntry>): List<IssueFeedEntry> =
    1.93 -        if (historyEntry.isEmpty()) {
    1.94 +    private fun generateFeedEntries(
    1.95 +        issueEntries: List<IssueHistoryEntry>,
    1.96 +        commentEntries: List<IssueCommentHistoryEntry>
    1.97 +    ): List<IssueFeedEntry> =
    1.98 +        (generateIssueFeedEntries(issueEntries) + generateCommentFeedEntries(commentEntries)).sortedByDescending { it.time }
    1.99 +
   1.100 +    private fun generateIssueFeedEntries(entries: List<IssueHistoryEntry>): List<IssueFeedEntry> =
   1.101 +        if (entries.isEmpty()) {
   1.102              emptyList()
   1.103          } else {
   1.104 -            historyEntry.groupBy { it.data.id }.mapValues { (_, history) ->
   1.105 +            entries.groupBy { it.issueid }.mapValues { (_, history) ->
   1.106                  history.zipWithNext().map { (cur, next) ->
   1.107                      IssueFeedEntry(
   1.108 -                        cur.time, cur.type, diffContent(cur.data, next.data)
   1.109 +                        cur.time, cur.type, issue = diffContent(cur, next)
   1.110                      )
   1.111                  }.plus(
   1.112 -                    history.last().let { IssueFeedEntry(it.time, it.type, fullContent(it.data)) }
   1.113 +                    history.last().let { IssueFeedEntry(it.time, it.type, issue = fullContent(it)) }
   1.114                  )
   1.115 -            }.flatMap { it.value }.sortedByDescending { it.time }
   1.116 +            }.flatMap { it.value }
   1.117 +        }
   1.118 +
   1.119 +    private fun generateCommentFeedEntries(entries: List<IssueCommentHistoryEntry>): List<IssueFeedEntry> =
   1.120 +        if (entries.isEmpty()) {
   1.121 +            emptyList()
   1.122 +        } else {
   1.123 +            entries.groupBy { it.commentid }.mapValues { (_, history) ->
   1.124 +                history.zipWithNext().map { (cur, next) ->
   1.125 +                    IssueFeedEntry(
   1.126 +                        cur.time, cur.type, comment = diffContent(cur, next)
   1.127 +                    )
   1.128 +                }.plus(
   1.129 +                    history.last().let { IssueFeedEntry(it.time, it.type, comment = fullContent(it)) }
   1.130 +                )
   1.131 +            }.flatMap { it.value }
   1.132          }
   1.133  
   1.134      private fun issues(http: HttpRequest, dao: DataAccessObject) {
   1.135 @@ -126,6 +168,7 @@
   1.136              return
   1.137          }
   1.138          val assignees = http.param("assignee")?.split(',')
   1.139 +        val comments = http.param("comments") ?: "all"
   1.140  
   1.141          val days = http.param("days")?.toIntOrNull() ?: 30
   1.142  
   1.143 @@ -133,9 +176,14 @@
   1.144          val issueHistory = if (assignees == null) issuesFromDb else
   1.145              issuesFromDb.filter { assignees.contains(it.currentAssignee) }
   1.146  
   1.147 -        // TODO: add comment history depending on parameter
   1.148 +        val commentsFromDb = dao.listIssueCommentHistory(project.id, days)
   1.149 +        val commentHistory = when (comments) {
   1.150 +            "all" -> commentsFromDb
   1.151 +            "new" -> commentsFromDb.filter { it.type == IssueHistoryType.NewComment }
   1.152 +            else -> emptyList()
   1.153 +        }
   1.154  
   1.155 -        http.view = IssueFeed(project, generateFeedEntries(issueHistory))
   1.156 +        http.view = IssueFeed(project, generateFeedEntries(issueHistory, commentHistory))
   1.157          http.renderFeed("issues-feed")
   1.158      }
   1.159  }
   1.160 \ No newline at end of file

mercurial