8a2f62b1ecdc408cbf4d67665c521c3e57937073
[rhynodge.git] / src / main / kotlin / net / pterodactylus / rhynodge / webpages / weather / wettercom / WetterComTrigger.kt
1 package net.pterodactylus.rhynodge.webpages.weather.wettercom
2
3 import kotlinx.html.body
4 import kotlinx.html.div
5 import kotlinx.html.h1
6 import kotlinx.html.head
7 import kotlinx.html.html
8 import kotlinx.html.img
9 import kotlinx.html.stream.createHTML
10 import kotlinx.html.style
11 import kotlinx.html.unsafe
12 import net.pterodactylus.rhynodge.Reaction
13 import net.pterodactylus.rhynodge.State
14 import net.pterodactylus.rhynodge.Trigger
15 import net.pterodactylus.rhynodge.output.DefaultOutput
16 import net.pterodactylus.rhynodge.output.Output
17 import java.text.DateFormat
18 import java.time.temporal.ChronoUnit.HOURS
19 import java.util.Locale
20
21 /**
22  * TODO
23  *
24  * @author [David ‘Bombe’ Roden](mailto:bombe@pterodactylus.net)
25  */
26 class WetterComTrigger : Trigger {
27
28     private val dateFormatter = DateFormat.getDateInstance(DateFormat.LONG, Locale.ENGLISH)
29     private var newState = false
30     private lateinit var currentState: WetterComState
31
32     override fun mergeStates(previousState: State, currentState: State): State? {
33         newState = previousState != currentState
34         this.currentState = currentState as WetterComState
35         return currentState
36     }
37
38     override fun triggers(): Boolean {
39         return newState
40     }
41
42     override fun output(reaction: Reaction): Output {
43         val output = DefaultOutput("The weather (according to wetter.com) on %s".format(dateFormatter.format(currentState.dateTime.toInstant().toEpochMilli())))
44         output.addText("text/html", htmlOutput())
45         return output
46     }
47
48     private fun htmlOutput(): String {
49         return createHTML().html {
50             head {
51                 style("text/css") {
52                     unsafe {
53                         +".hour-state { display: table-row; }"
54                         +" "
55                         +".hour-state > div { display: table-cell; padding-right: 1em; }"
56                     }
57                 }
58             }
59             body {
60                 val startTime = currentState.dateTime.toInstant()
61                 h1 { +"The Weather (according to wetter.com) on %s".format(dateFormatter.format(startTime.toEpochMilli())) }
62                 currentState.forEach {
63                     div("hour-state") {
64                         div("time") { +"%tH:%<tM".format(startTime.plus(it.hourIndex.toLong(), HOURS).toEpochMilli()) }
65                         div("temperature") { +"%d °C".format(it.temperature.toInt()) }
66                         div("rain-probability") { +"%d%%".format((it.rainProbability * 100).toInt()) }
67                         div("rain-amount") { +"%d l/m²".format(it.rainAmount.toInt()) }
68                         div("wind-direction") {
69                             div {
70                                 attributes += "style" to "padding: none; transform: rotate(%ddeg)".format(180 - it.windDirection.degrees)
71                                 +"➠"
72                             }
73                         }
74                         div("wind-speed") { +"%d km/h".format(it.windSpeed.toInt()) }
75                         div("description") { +it.description }
76                         div("image") { img(src = it.image) }
77                     }
78                 }
79             }
80         }.toString()
81     }
82
83 }