Format notification log exports
This commit is contained in:
@@ -0,0 +1,43 @@
|
|||||||
|
package se.ajpanton.notificationlog.export
|
||||||
|
|
||||||
|
import se.ajpanton.notificationlog.model.NotificationLogEntry
|
||||||
|
import se.ajpanton.notificationlog.settings.LogField
|
||||||
|
import se.ajpanton.notificationlog.settings.LogViewSettings
|
||||||
|
import se.ajpanton.notificationlog.settings.TimestampZone
|
||||||
|
import java.text.DateFormat
|
||||||
|
import java.util.Date
|
||||||
|
import java.util.TimeZone
|
||||||
|
|
||||||
|
object LogExporter {
|
||||||
|
fun csv(entries: List<NotificationLogEntry>, settings: LogViewSettings): String =
|
||||||
|
rows(entries, settings).joinToString("\n") { row -> row.joinToString(",") { csvValue(it) } }
|
||||||
|
|
||||||
|
fun formatted(entries: List<NotificationLogEntry>, settings: LogViewSettings): String {
|
||||||
|
val rows = rows(entries, settings)
|
||||||
|
val widths = rows.fold(emptyList<Int>()) { current, row -> row.mapIndexed { i, value -> maxOf(current.getOrElse(i) { 0 }, value.length) } }
|
||||||
|
return rows.joinToString("\n") { row -> row.mapIndexed { i, value -> value.padEnd(widths[i]) }.joinToString(" ") }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun html(entries: List<NotificationLogEntry>, settings: LogViewSettings): String = buildString {
|
||||||
|
append("<!doctype html><meta charset=\"utf-8\"><table><thead><tr>")
|
||||||
|
settings.order.filter { it in settings.visibleFields }.forEach { append("<th>${escape(header(it))}</th>") }
|
||||||
|
append("</tr></thead><tbody>")
|
||||||
|
rows(entries, settings).forEach { row -> append("<tr>"); row.forEach { append("<td>${escape(it)}</td>") }; append("</tr>") }
|
||||||
|
append("</tbody></table>")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun rows(entries: List<NotificationLogEntry>, settings: LogViewSettings) = listOf(
|
||||||
|
settings.order.filter { it in settings.visibleFields }.map(::header),
|
||||||
|
) + entries.sortedByDescending { it.recordedAtEpochMillis }.map { entry ->
|
||||||
|
settings.order.filter { it in settings.visibleFields }.map { field -> when (field) {
|
||||||
|
LogField.TIMESTAMP -> timestamp(entry.recordedAtEpochMillis, settings.timestampZone)
|
||||||
|
LogField.APP_NAME -> entry.appName; LogField.PACKAGE_NAME -> entry.packageName
|
||||||
|
LogField.ACTION -> entry.action.name.lowercase().replace('_', ' ')
|
||||||
|
LogField.CONTENTS -> entry.contents ?: ""
|
||||||
|
} }
|
||||||
|
}
|
||||||
|
private fun header(field: LogField) = field.name.lowercase().replace('_', ' ')
|
||||||
|
private fun timestamp(value: Long, zone: TimestampZone): String = DateFormat.getDateTimeInstance().apply { if (zone == TimestampZone.UTC) timeZone = TimeZone.getTimeZone("UTC") }.format(Date(value))
|
||||||
|
private fun csvValue(value: String) = "\"${value.replace("\"", "\"\"")}\""
|
||||||
|
private fun escape(value: String) = value.replace("&", "&").replace("<", "<").replace(">", ">").replace("\"", """)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user