1.1 --- a/src/main/kotlin/de/uapcore/lightpit/servlet/FeedServlet.kt Sat Oct 09 17:46:12 2021 +0200 1.2 +++ b/src/main/kotlin/de/uapcore/lightpit/servlet/FeedServlet.kt Sat Oct 09 20:05:39 2021 +0200 1.3 @@ -28,10 +28,12 @@ 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.util.IssueFilter 1.8 -import de.uapcore.lightpit.util.IssueSorter 1.9 -import de.uapcore.lightpit.util.SpecificFilter 1.10 +import de.uapcore.lightpit.entities.IssueHistoryData 1.11 +import de.uapcore.lightpit.entities.IssueHistoryEntry 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 +import java.text.SimpleDateFormat 1.16 import javax.servlet.annotation.WebServlet 1.17 1.18 @WebServlet(urlPatterns = ["/feed/*"]) 1.19 @@ -41,6 +43,43 @@ 1.20 get("/%project/issues.rss", this::issues) 1.21 } 1.22 1.23 + private fun String.convertLF() = replace("\r", "").replace("\n", "<br>") 1.24 + 1.25 + private fun fullContent(issue: IssueHistoryData) = IssueDiff( 1.26 + issue.id, 1.27 + issue.subject, 1.28 + issue.component, 1.29 + issue.status.name, 1.30 + issue.category.name, 1.31 + issue.subject, 1.32 + issue.description.convertLF(), 1.33 + issue.assignee, 1.34 + issue.eta?.let { SimpleDateFormat("dd.MM.yyyy").format(it) } ?: "", 1.35 + issue.affected, 1.36 + issue.resolved 1.37 + ) 1.38 + 1.39 + private fun diffContent(cur: IssueHistoryData, next: IssueHistoryData): IssueDiff { 1.40 + val prev = fullContent(next) 1.41 + val diff = fullContent(cur) 1.42 + // TODO: compute and apply diff 1.43 + return diff 1.44 + } 1.45 + 1.46 + /** 1.47 + * Generates the feed entries. 1.48 + * Assumes that [historyEntry] is already sorted by timestamp (descending). 1.49 + */ 1.50 + private fun generateFeedEntries(historyEntry: List<IssueHistoryEntry>) = 1.51 + if (historyEntry.isEmpty()) emptyList() 1.52 + else historyEntry.zipWithNext().map { (cur, next) -> 1.53 + IssueFeedEntry( 1.54 + cur.time, cur.type, diffContent(cur.data, next.data) 1.55 + ) 1.56 + }.plus( 1.57 + historyEntry.last().let { IssueFeedEntry(it.time, it.type, fullContent(it.data)) } 1.58 + ) 1.59 + 1.60 private fun issues(http: HttpRequest, dao: DataAccessObject) { 1.61 val project = http.pathParams["project"]?.let { dao.findProjectByNode(it) } 1.62 if (project == null) { 1.63 @@ -48,10 +87,12 @@ 1.64 return 1.65 } 1.66 1.67 - // TODO: add a timestamp filter (e.g. last 30 days) 1.68 - val issues = dao.listIssues(IssueFilter(SpecificFilter(project))).sortedWith(IssueSorter.DEFAULT_ISSUE_SORTER) 1.69 + val days = http.param("days")?.toIntOrNull() ?: 30 1.70 1.71 - http.view = IssueFeed(project, issues) 1.72 + val issueHistory = dao.listIssueHistory(project.id, days) 1.73 + // TODO: add comment history depending on parameter 1.74 + 1.75 + http.view = IssueFeed(project, generateFeedEntries(issueHistory)) 1.76 http.renderFeed("issues-feed") 1.77 } 1.78 } 1.79 \ No newline at end of file