Skip to content

Commit

Permalink
Konvert :web:status-history (#58)
Browse files Browse the repository at this point in the history
 * Auto-konvert web/status-history
 * Fix auto-konversion issues
 * Idiomatic Kotlin
  • Loading branch information
TWiStErRob committed Dec 29, 2023
1 parent 8752369 commit d96df51
Show file tree
Hide file tree
Showing 28 changed files with 1,339 additions and 1,436 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import java.util.Collections;
import java.util.List;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import net.twisterrob.blt.model.Line;

public class LineStatus {
Expand All @@ -27,11 +30,11 @@ public void setType(DelayType type) {
m_type = type;
}

public String getDescription() {
public @Nullable String getDescription() {
return m_description;
}
public void setDescription(String description) {
if (description != null && description.trim().length() == 0) {
if (description != null && description.trim().isEmpty()) {
m_description = null;
} else {
m_description = description;
Expand All @@ -53,7 +56,7 @@ public List<BranchStatus> getBranchStatuses() {
return Collections.unmodifiableList(m_branches);
}

public String getBranchDescription() {
public @Nonnull String getBranchDescription() {
StringBuilder sb = new StringBuilder();
if (!getBranchStatuses().isEmpty()) {
sb.append("Affected branches:\n");
Expand Down
3 changes: 2 additions & 1 deletion web/status-history/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform

plugins {
id("net.twisterrob.blt.convention")
id("org.gradle.java")
id("org.jetbrains.kotlin.jvm")
id("com.google.devtools.ksp")
id("io.micronaut.minimal.application")
id("com.google.cloud.tools.appengine-appyaml")
id("org.gradle.idea")
Expand Down
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.
}
}
}
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,
)
}
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)
}
}
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
}
Loading

0 comments on commit d96df51

Please sign in to comment.