Add more filters and heatmaps
This commit is contained in:
parent
cd6bd4b488
commit
f2a1a74bb8
|
@ -0,0 +1,26 @@
|
|||
package moe.kageru.spektacles
|
||||
|
||||
open class Counter<T>(source: Iterable<T>) : Iterable<Map.Entry<T, Int>> {
|
||||
val counts: Map<T, Int> = mutableMapOf<T, Int>().apply {
|
||||
for (element in source) {
|
||||
this[element] = this.getOrDefault(element, 0) + 1
|
||||
}
|
||||
}
|
||||
|
||||
override fun iterator(): Iterator<Map.Entry<T, Int>> {
|
||||
return counts.entries.iterator()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return counts.entries.joinToString("\n") { "${it.key}: ${it.value}" }
|
||||
}
|
||||
}
|
||||
|
||||
class SortedCounter<T: Comparable<T>>(source: Iterable<T>): Counter<T>(source) {
|
||||
override fun toString(): String {
|
||||
return counts.entries.sortedBy { it.key }.joinToString("\n") { "${it.key}: ${it.value}" }
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> Iterable<T>.toCounter(): Counter<T> = Counter(this)
|
||||
fun <T: Comparable<T>> Iterable<T>.toSortedCounter(): SortedCounter<T> = SortedCounter(this)
|
|
@ -0,0 +1,23 @@
|
|||
package moe.kageru.spektacles
|
||||
|
||||
import java.time.Month
|
||||
|
||||
fun ParsedLines.filterUsers(vararg users: String): ParsedLines {
|
||||
return this.filter { line -> line.user.exists { it in users } }
|
||||
}
|
||||
|
||||
fun ParsedLines.filterModes(vararg modes: UserMode): ParsedLines {
|
||||
return this.filter { line -> line.userMode in modes }
|
||||
}
|
||||
|
||||
fun ParsedLines.filterYears(vararg years: Int): ParsedLines {
|
||||
return this.filter { line -> line.time.year in years }
|
||||
}
|
||||
|
||||
fun ParsedLines.filterMonths(vararg months: Month): ParsedLines {
|
||||
return this.filter { line -> line.time.month in months }
|
||||
}
|
||||
|
||||
fun ParsedLines.filterDays(vararg days: Int): ParsedLines {
|
||||
return this.filter { line -> line.time.dayOfMonth in days }
|
||||
}
|
|
@ -8,4 +8,4 @@ object IoHandler {
|
|||
.filter { !it.startsWith("****") }
|
||||
}
|
||||
|
||||
typealias Lines = Sequence<String>
|
||||
typealias Lines = Sequence<String>
|
||||
|
|
|
@ -6,7 +6,7 @@ import java.time.LocalDateTime
|
|||
|
||||
class ParsedLine(val time: LocalDateTime,
|
||||
val user: Option<String>,
|
||||
val userMode: Option<UserMode>,
|
||||
val userMode: UserMode,
|
||||
val message: String,
|
||||
val isSystemMessage: Boolean,
|
||||
private val originalMessage: String
|
||||
|
@ -30,7 +30,7 @@ class ParsedLine(val time: LocalDateTime,
|
|||
it.groups["second"]!!.value.toInt()
|
||||
),
|
||||
it.groups["author"]?.value.toOption(),
|
||||
it.groups["mode"]?.value?.let { UserMode.values().first { mode -> mode.icon == it } }.toOption(),
|
||||
it.groups["mode"]?.value?.let { UserMode.values().first { mode -> mode.icon == it } } ?: UserMode.NONE,
|
||||
it.groups["message"]!!.value,
|
||||
it.groups["author"] == null,
|
||||
it.value
|
||||
|
@ -44,5 +44,13 @@ enum class UserMode(val icon: String) {
|
|||
BOT("&"),
|
||||
OP("@"),
|
||||
HOP("%"),
|
||||
VOICE("+");
|
||||
}
|
||||
VOICE("+"),
|
||||
NONE("")
|
||||
}
|
||||
|
||||
typealias ParsedLines = Sequence<ParsedLine>
|
||||
|
||||
fun Lines.parse(): ParsedLines {
|
||||
return map { ParsedLine.parse(it) }
|
||||
.filterNotNull()
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package moe.kageru.spektacles
|
||||
|
||||
import java.time.Month
|
||||
|
||||
fun ParsedLines.heatMapByHour(): SortedCounter<Int> = heatMapBy { it.time.hour }
|
||||
|
||||
fun ParsedLines.heatMapByMinute(): SortedCounter<Int> = heatMapBy { it.time.hour * 100 + it.time.minute }
|
||||
|
||||
fun ParsedLines.heatMapByMonth(): SortedCounter<Month> = heatMapBy { it.time.month }
|
||||
|
||||
private fun <T: Comparable<T>>ParsedLines.heatMapBy(op: (ParsedLine) -> T): SortedCounter<T> {
|
||||
return this.map(op)
|
||||
.asIterable()
|
||||
.toSortedCounter()
|
||||
}
|
|
@ -1,32 +1,21 @@
|
|||
package moe.kageru.spektacles
|
||||
|
||||
import java.time.Month
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
|
||||
fun main() {
|
||||
val res = measureTimeMillis {
|
||||
IoHandler.readFile("test.log")
|
||||
.map { ParsedLine.parse(it) }
|
||||
.filterNotNull()
|
||||
.filter { line -> line.user.exists { it == "kageru_" } }
|
||||
.flatMap { it.message.split(' ').asSequence() }
|
||||
//.flatMap { it.message.split(' ').k() }
|
||||
//.toCounter()
|
||||
//.counts["selphyDango"]
|
||||
val time = measureTimeMillis {
|
||||
spektacle()
|
||||
}
|
||||
println(res)
|
||||
println("Time spent: $time ms")
|
||||
}
|
||||
|
||||
class Counter<T>(source: Iterable<T>) : Iterable<T> {
|
||||
val counts = mutableMapOf<T, Int>().apply {
|
||||
for (element in source) {
|
||||
this[element] = this.getOrDefault(element, 0) + 1
|
||||
}
|
||||
}
|
||||
|
||||
override fun iterator(): Iterator<T> {
|
||||
return counts.keys.iterator()
|
||||
}
|
||||
fun spektacle() {
|
||||
IoHandler.readFile("test.log")
|
||||
.parse()
|
||||
.filterUsers("kageru_")
|
||||
.filterModes(UserMode.OP)
|
||||
.filterMonths(Month.APRIL)
|
||||
.heatMapByHour()
|
||||
.let(::println)
|
||||
}
|
||||
|
||||
fun <T> Iterable<T>.toCounter(): Counter<T> = Counter(this)
|
||||
|
|
Loading…
Reference in New Issue
Block a user