-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Auto-konvert web/status-history * Fix auto-konversion issues * Idiomatic Kotlin
- Loading branch information
1 parent
8752369
commit d96df51
Showing
28 changed files
with
1,339 additions
and
1,436 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 14 additions & 14 deletions
28
web/status-history/src/main/java/net/twisterrob/travel/statushistory/Application.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,18 @@ | ||
package net.twisterrob.travel.statushistory; | ||
package net.twisterrob.travel.statushistory | ||
|
||
import io.micronaut.context.ApplicationContext; | ||
import io.micronaut.runtime.Micronaut; | ||
import io.micronaut.runtime.Micronaut | ||
|
||
public class Application { | ||
@SuppressWarnings("try") | ||
public static void main(String... args) { | ||
Micronaut micronaut = Micronaut | ||
.build(args) | ||
.classes(Application.class) | ||
.banner(false) | ||
; | ||
try (ApplicationContext context = micronaut.start()) { | ||
// Nothing yet, wrap in try-with-resources to ensure teardown. | ||
} | ||
object Application { | ||
|
||
@JvmStatic | ||
fun main(vararg args: String) { | ||
Micronaut | ||
.build(*args) | ||
.classes(Application::class.java) | ||
.banner(false) | ||
.start() | ||
.use { _ -> | ||
// Nothing yet, wrap in try-with-resources to ensure teardown. | ||
} | ||
} | ||
} |
48 changes: 23 additions & 25 deletions
48
...s-history/src/main/java/net/twisterrob/travel/statushistory/controller/IndexController.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,33 @@ | ||
package net.twisterrob.travel.statushistory.controller; | ||
package net.twisterrob.travel.statushistory.controller | ||
|
||
import io.micronaut.http.HttpResponse; | ||
import io.micronaut.http.MediaType; | ||
import io.micronaut.http.MutableHttpResponse; | ||
import io.micronaut.http.annotation.Controller; | ||
import io.micronaut.http.annotation.Get; | ||
import io.micronaut.http.server.types.files.StreamedFile; | ||
import io.micronaut.views.View; | ||
|
||
import net.twisterrob.travel.statushistory.viewmodel.Versions; | ||
import io.micronaut.http.HttpResponse | ||
import io.micronaut.http.MediaType | ||
import io.micronaut.http.MutableHttpResponse | ||
import io.micronaut.http.annotation.Controller | ||
import io.micronaut.http.annotation.Get | ||
import io.micronaut.http.server.types.files.StreamedFile | ||
import io.micronaut.views.View | ||
import net.twisterrob.travel.statushistory.viewmodel.Versions | ||
|
||
@Controller | ||
public class IndexController { | ||
class IndexController { | ||
|
||
@Get("/") | ||
@View("index") | ||
public MutableHttpResponse<?> index() { | ||
return HttpResponse.ok(new IndexModel(new Versions())); | ||
} | ||
fun index(): MutableHttpResponse<*> = | ||
HttpResponse.ok( | ||
IndexModel(Versions()) | ||
) | ||
|
||
@Get("/favicon.ico") | ||
public StreamedFile favicon() { | ||
return new StreamedFile( | ||
IndexController.class.getClassLoader().getResourceAsStream("public/favicon.ico"), | ||
MediaType.IMAGE_PNG_TYPE | ||
); | ||
} | ||
|
||
private record IndexModel( | ||
Versions versions | ||
) { | ||
fun favicon(): StreamedFile = | ||
StreamedFile( | ||
IndexController::class.java.classLoader.getResourceAsStream("public/favicon.ico"), | ||
MediaType.IMAGE_PNG_TYPE | ||
) | ||
|
||
} | ||
@Suppress("unused") // Used by index.hbs. | ||
private class IndexModel( | ||
val versions: Versions, | ||
) | ||
} |
59 changes: 33 additions & 26 deletions
59
...rc/main/java/net/twisterrob/travel/statushistory/controller/InternalFeedbackController.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,43 @@ | ||
package net.twisterrob.travel.statushistory.controller; | ||
package net.twisterrob.travel.statushistory.controller | ||
|
||
import java.io.IOException; | ||
import java.util.Properties; | ||
|
||
import javax.mail.*; | ||
import javax.mail.internet.*; | ||
import io.micronaut.http.MediaType; | ||
import io.micronaut.http.annotation.Body; | ||
import io.micronaut.http.annotation.Consumes; | ||
import io.micronaut.http.annotation.Controller; | ||
import io.micronaut.http.annotation.Post; | ||
|
||
import org.slf4j.*; | ||
import io.micronaut.http.MediaType | ||
import io.micronaut.http.annotation.Body | ||
import io.micronaut.http.annotation.Consumes | ||
import io.micronaut.http.annotation.Controller | ||
import io.micronaut.http.annotation.Post | ||
import org.slf4j.Logger | ||
import org.slf4j.LoggerFactory | ||
import java.io.IOException | ||
import java.util.Properties | ||
import javax.mail.Message | ||
import javax.mail.MessagingException | ||
import javax.mail.Session | ||
import javax.mail.Transport | ||
import javax.mail.internet.InternetAddress | ||
import javax.mail.internet.MimeMessage | ||
|
||
@Controller | ||
public class InternalFeedbackController { | ||
private static final Logger LOG = LoggerFactory.getLogger(InternalFeedbackController.class); | ||
class InternalFeedbackController { | ||
|
||
@Post("/InternalFeedback") | ||
@Consumes(MediaType.ALL) | ||
public void doPost(@Body String body) throws IOException { | ||
Properties props = new Properties(); | ||
Session session = Session.getDefaultInstance(props, null); | ||
Message msg = new MimeMessage(session); | ||
fun doPost(@Body body: String?) { | ||
val props = Properties() | ||
val session = Session.getDefaultInstance(props, null) | ||
val msg: Message = MimeMessage(session) | ||
try { | ||
msg.setFrom(new InternetAddress("[email protected]", "BLT Internal Feedback")); | ||
msg.addRecipient(Message.RecipientType.TO, new InternetAddress("[email protected]", "Me")); | ||
msg.setSubject("Better London Travel automated internal feedback"); | ||
msg.setText(body); | ||
Transport.send(msg); | ||
} catch (MessagingException e) { | ||
throw new IOException("Cannot send mail", e); | ||
msg.setFrom(InternetAddress("[email protected]", "BLT Internal Feedback")) | ||
msg.addRecipient(Message.RecipientType.TO, InternetAddress("[email protected]", "Me")) | ||
msg.subject = "Better London Travel automated internal feedback" | ||
msg.setText(body) | ||
Transport.send(msg) | ||
} catch (e: MessagingException) { | ||
throw IOException("Cannot send mail", e) | ||
} | ||
} | ||
|
||
companion object { | ||
|
||
private val LOG: Logger = LoggerFactory.getLogger(InternalFeedbackController::class.java) | ||
} | ||
} |
137 changes: 63 additions & 74 deletions
137
...c/main/java/net/twisterrob/travel/statushistory/controller/LineStatusHistoryController.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,91 +1,80 @@ | ||
package net.twisterrob.travel.statushistory.controller; | ||
package net.twisterrob.travel.statushistory.controller | ||
|
||
import java.util.*; | ||
|
||
import io.micronaut.http.HttpResponse; | ||
import io.micronaut.http.MediaType; | ||
import io.micronaut.http.annotation.Controller; | ||
import io.micronaut.http.annotation.Get; | ||
import io.micronaut.http.annotation.Produces; | ||
import io.micronaut.http.annotation.QueryValue; | ||
import io.micronaut.views.View; | ||
|
||
import net.twisterrob.blt.data.StaticData; | ||
import net.twisterrob.blt.io.feeds.trackernet.LineStatusFeed; | ||
import net.twisterrob.travel.domain.london.status.Feed; | ||
import net.twisterrob.travel.domain.london.status.api.HistoryUseCase; | ||
import net.twisterrob.travel.domain.london.status.api.ParsedStatusItem; | ||
import net.twisterrob.travel.statushistory.viewmodel.LineColor; | ||
import net.twisterrob.travel.statushistory.viewmodel.Result; | ||
import net.twisterrob.travel.statushistory.viewmodel.ResultChange; | ||
import io.micronaut.http.HttpResponse | ||
import io.micronaut.http.MediaType | ||
import io.micronaut.http.annotation.Controller | ||
import io.micronaut.http.annotation.Get | ||
import io.micronaut.http.annotation.Produces | ||
import io.micronaut.http.annotation.QueryValue | ||
import io.micronaut.views.View | ||
import net.twisterrob.blt.data.StaticData | ||
import net.twisterrob.blt.io.feeds.trackernet.LineStatusFeed | ||
import net.twisterrob.travel.domain.london.status.Feed | ||
import net.twisterrob.travel.domain.london.status.api.HistoryUseCase | ||
import net.twisterrob.travel.domain.london.status.api.ParsedStatusItem | ||
import net.twisterrob.travel.statushistory.viewmodel.LineColor | ||
import net.twisterrob.travel.statushistory.viewmodel.Result | ||
import net.twisterrob.travel.statushistory.viewmodel.ResultChange | ||
import java.util.Date | ||
|
||
@Controller | ||
public class LineStatusHistoryController { | ||
|
||
private final HistoryUseCase useCase; | ||
private final StaticData staticData; | ||
|
||
public LineStatusHistoryController(HistoryUseCase useCase, StaticData staticData) { | ||
this.useCase = useCase; | ||
this.staticData = staticData; | ||
} | ||
class LineStatusHistoryController( | ||
private val useCase: HistoryUseCase, | ||
private val staticData: StaticData, | ||
) { | ||
|
||
@Get("/LineStatusHistory") | ||
@View("LineStatus") | ||
@Produces(MediaType.TEXT_HTML) | ||
public HttpResponse<?> lineStatusHistory( | ||
@QueryValue(value = "current", defaultValue = "false") boolean displayCurrent, | ||
@QueryValue(value = "errors", defaultValue = "false") boolean displayErrors, | ||
@QueryValue(value = "max", defaultValue = "100") int max | ||
) { | ||
Feed feed = Feed.TubeDepartureBoardsLineStatus; | ||
|
||
List<ParsedStatusItem> history = useCase.history(feed, max, displayCurrent); | ||
List<Result> results = history | ||
.stream() | ||
.filter((it) -> displayErrors || !(it instanceof ParsedStatusItem.ParseFailed)) | ||
.map(LineStatusHistoryController::toResult).toList(); | ||
List<ResultChange> differences = getDifferences(results); | ||
fun lineStatusHistory( | ||
@QueryValue(value = "current", defaultValue = "false") displayCurrent: Boolean, | ||
@QueryValue(value = "errors", defaultValue = "false") displayErrors: Boolean, | ||
@QueryValue(value = "max", defaultValue = "100") max: Int, | ||
): HttpResponse<*> { | ||
val feed = Feed.TubeDepartureBoardsLineStatus | ||
val history = useCase.history(feed, max, displayCurrent) | ||
val results = history | ||
.filter { displayErrors || it !is ParsedStatusItem.ParseFailed } | ||
.map(ParsedStatusItem::toResult) | ||
val differences = getDifferences(results) | ||
|
||
return HttpResponse.ok( | ||
new LineStatusHistoryModel( | ||
differences, | ||
new LineColor.AllColors(staticData.getLineColors()) | ||
) | ||
); | ||
LineStatusHistoryModel( | ||
differences, | ||
LineColor.AllColors(staticData.lineColors) | ||
) | ||
) | ||
} | ||
|
||
private record LineStatusHistoryModel( | ||
List<ResultChange> feedChanges, | ||
Iterable<LineColor> colors | ||
) { | ||
@Suppress("unused") // Used by LineStatus.hbs. | ||
private class LineStatusHistoryModel( | ||
val feedChanges: List<ResultChange>, | ||
val colors: Iterable<LineColor>, | ||
) | ||
} | ||
|
||
} | ||
private fun ParsedStatusItem.toResult(): Result { | ||
val date = Date(this.item.retrievedDate.toEpochMilliseconds()) | ||
return when (this) { | ||
is ParsedStatusItem.ParsedFeed -> | ||
Result(date, this.content as LineStatusFeed) | ||
|
||
private static Result toResult(ParsedStatusItem parsed) { | ||
Result result; | ||
Date date = new Date(parsed.getItem().getRetrievedDate().toEpochMilliseconds()); | ||
if (parsed instanceof ParsedStatusItem.ParsedFeed feed) { | ||
result = new Result(date, (LineStatusFeed)feed.getContent()); | ||
} else if (parsed instanceof ParsedStatusItem.AlreadyFailed failure) { | ||
result = new Result(date, failure.getItem().getError().getStacktrace()); | ||
} else if (parsed instanceof ParsedStatusItem.ParseFailed parseFailure) { | ||
result = new Result(date, "Error while displaying loaded XML: " + parseFailure.getError().getStacktrace()); | ||
} else { | ||
throw new IllegalArgumentException("Unsupported parse result: " + parsed); | ||
} | ||
return result; | ||
is ParsedStatusItem.AlreadyFailed -> | ||
Result(date, this.item.error.stacktrace) | ||
|
||
is ParsedStatusItem.ParseFailed -> | ||
Result(date, "Error while displaying loaded XML: ${this.error.stacktrace}") | ||
} | ||
} | ||
|
||
private static List<ResultChange> getDifferences(List<Result> results) { | ||
List<ResultChange> resultChanges = new ArrayList<>(results.size()); | ||
Result newResult = null; | ||
for (Result oldResult : results) { // we're going forward, but the list is backwards | ||
resultChanges.add(new ResultChange(oldResult, newResult)); | ||
newResult = oldResult; | ||
} | ||
resultChanges.add(new ResultChange(null, newResult)); | ||
resultChanges.remove(0); | ||
return resultChanges; | ||
private fun getDifferences(results: List<Result>): List<ResultChange> { | ||
val resultChanges: MutableList<ResultChange> = ArrayList(results.size) | ||
var newResult: Result? = null | ||
for (oldResult in results) { // We're going forward, but the list is backwards. | ||
resultChanges.add(ResultChange(oldResult, newResult)) | ||
newResult = oldResult | ||
} | ||
resultChanges.add(ResultChange(null, newResult)) | ||
resultChanges.removeAt(0) | ||
return resultChanges | ||
} |
Oops, something went wrong.