diff --git a/README.md b/README.md index e59c3a6..bb52282 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ [![Maven metadata of snapshots][badge_snapshot_img]][badge_snapshot_target] [//]: # (**[说明书][book] | [FindInTelegram][tg-account]**) -[badge_handbook_img]: https://img.shields.io/website?url=https%3A%2F%2Fbook.sukazyo.cc%2Fmorny&up_message=0.8.0.11*PUTIAN&up_color=7b68ee&down_message=%E4%B8%8D%E5%8F%AF%E7%94%A8&down_color=dc143c&label=%E8%AF%B4%E6%98%8E%E4%B9%A6 +[badge_handbook_img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fbook.sukazyo.cc%2Fmorny%2Fmain.json&query=%24.target_version&label=%E8%AF%B4%E6%98%8E%E4%B9%A6&color=7b68ee [badge_handbook_target]: https://book.sukazyo.cc/morny [badge_telegram_img]: https://img.shields.io/website?url=https%3A%2F%2Ft.me%2Fmorny_cono_annie_bot&up_message=%40morny_cono_annie_bot&up_color=28a8ea&down_message=unavailable&down_color=red&logo=telegram&label=Telegram [badge_telegram_target]: https://t.me/morny_cono_annie_bot diff --git a/build.sbt b/build.sbt index c33f138..561166e 100644 --- a/build.sbt +++ b/build.sbt @@ -66,7 +66,11 @@ lazy val root = (project in file(".")) }, assembly / artifact := (assembly / artifact).value .withClassifier(Some("fat")), - addArtifact(assembly / artifact, assembly), + if (MornyProject.publishWithFatJar) { + addArtifact(assembly / artifact, assembly) + } else { + Nil + }, if (System.getenv("DOCKER_BUILD") != null) { assembly / assemblyJarName := { sLog.value info "environment DOCKER_BUILD checked" diff --git a/project/MornyConfiguration.scala b/project/MornyConfiguration.scala index 87c170a..4958e9e 100644 --- a/project/MornyConfiguration.scala +++ b/project/MornyConfiguration.scala @@ -8,13 +8,13 @@ object MornyConfiguration { val MORNY_CODE_STORE = "https://github.com/Eyre-S/Coeur-Morny-Cono" val MORNY_COMMIT_PATH = "https://github.com/Eyre-S/Coeur-Morny-Cono/commit/%s" - val VERSION = "2.0.0-alpha10" + val VERSION = "2.0.0-alpha11" val VERSION_DELTA: Option[String] = None val CODENAME = "guanggu" val SNAPSHOT = true - val dependencies = Seq( + val dependencies: Seq[ModuleID] = Seq( "com.github.spotbugs" % "spotbugs-annotations" % "4.7.3" % Compile, @@ -22,15 +22,19 @@ object MornyConfiguration { "cc.sukazyo" % "resource-tools" % "0.2.2", "com.github.pengrad" % "java-telegram-bot-api" % "6.2.0", + "org.http4s" %% "http4s-dsl" % "0.23.24", + "org.http4s" %% "http4s-circe" % "0.23.24", + "org.http4s" %% "http4s-netty-server" % "0.5.11", - "com.softwaremill.sttp.client3" %% "core" % "3.9.0", + "com.softwaremill.sttp.client3" %% "core" % "3.9.0", "com.softwaremill.sttp.client3" %% "okhttp-backend" % "3.9.0", "com.squareup.okhttp3" % "okhttp" % "4.11.0" % Runtime, + "org.typelevel" %% "case-insensitive" % "1.4.0", "com.google.code.gson" % "gson" % "2.10.1", - "io.circe" %% "circe-core" % "0.14.6", + "io.circe" %% "circe-core" % "0.14.6", "io.circe" %% "circe-generic" % "0.14.6", - "io.circe" %% "circe-parser" % "0.14.6", + "io.circe" %% "circe-parser" % "0.14.6", "org.jsoup" % "jsoup" % "1.16.2", "com.cronutils" % "cron-utils" % "9.2.0", @@ -40,10 +44,10 @@ object MornyConfiguration { // - cron-utils "org.slf4j" % "slf4j-nop" % "2.0.9" % Runtime, - "org.scalatest" %% "scalatest" % "3.2.17" % Test, + "org.scalatest" %% "scalatest" % "3.2.17" % Test, "org.scalatest" %% "scalatest-freespec" % "3.2.17" % Test, // for test report - "com.vladsch.flexmark" % "flexmark" % "0.64.0" % Test, + "com.vladsch.flexmark" % "flexmark" % "0.64.0" % Test, "com.vladsch.flexmark" % "flexmark-profile-pegdown" % "0.64.0" % Test ) diff --git a/project/MornyProject.scala b/project/MornyProject.scala index 7f7b96b..1d301bc 100644 --- a/project/MornyProject.scala +++ b/project/MornyProject.scala @@ -1,15 +1,14 @@ import org.eclipse.jgit.api.Git import org.eclipse.jgit.revwalk.RevWalk import org.eclipse.jgit.storage.file.FileRepositoryBuilder - -import java.io.File +import sbt.* //noinspection TypeAnnotation object MornyProject { val _git_repo = new FileRepositoryBuilder() - .setGitDir(new File(".git")) - .setWorkTree(new File("")) + .setGitDir(file(".git")) + .setWorkTree(file(".")) .readEnvironment() .build() val _git = new Git(_git_repo) @@ -45,6 +44,7 @@ object MornyProject { val dependencies = MornyConfiguration.dependencies + val publishWithFatJar = !version_is_snapshot def publishTo = MornyConfiguration.publishTo val publishCredentials = MornyConfiguration.publishCredentials diff --git a/src/main/resources/assets_morny/images/http-sekai-404.png b/src/main/resources/assets_morny/images/http-sekai-404.png new file mode 100644 index 0000000..0098184 Binary files /dev/null and b/src/main/resources/assets_morny/images/http-sekai-404.png differ diff --git a/src/main/resources/assets_morny/images/http-sekai-500.png b/src/main/resources/assets_morny/images/http-sekai-500.png new file mode 100644 index 0000000..710f2da Binary files /dev/null and b/src/main/resources/assets_morny/images/http-sekai-500.png differ diff --git a/src/main/resources/assets_morny/images/http-sekai-501.png b/src/main/resources/assets_morny/images/http-sekai-501.png new file mode 100644 index 0000000..ed6964c Binary files /dev/null and b/src/main/resources/assets_morny/images/http-sekai-501.png differ diff --git a/src/main/resources/assets_morny/images/http-sekai-523.png b/src/main/resources/assets_morny/images/http-sekai-523.png new file mode 100644 index 0000000..a95eec7 Binary files /dev/null and b/src/main/resources/assets_morny/images/http-sekai-523.png differ diff --git a/src/main/scala/cc/sukazyo/cono/morny/core/MornyCoeur.scala b/src/main/scala/cc/sukazyo/cono/morny/core/MornyCoeur.scala index a08820c..2a48181 100644 --- a/src/main/scala/cc/sukazyo/cono/morny/core/MornyCoeur.scala +++ b/src/main/scala/cc/sukazyo/cono/morny/core/MornyCoeur.scala @@ -4,6 +4,8 @@ import cc.sukazyo.cono.morny.core.Log.{exceptionLog, logger} import cc.sukazyo.cono.morny.core.MornyCoeur.* import cc.sukazyo.cono.morny.core.bot.api.{EventListenerManager, MornyCommandManager, MornyQueryManager} import cc.sukazyo.cono.morny.core.bot.event.{MornyOnInlineQuery, MornyOnTelegramCommand, MornyOnUpdateTimestampOffsetLock} +import cc.sukazyo.cono.morny.core.http.api.{HttpServer, MornyHttpServerContext} +import cc.sukazyo.cono.morny.core.http.internal.MornyHttpServerContextImpl import cc.sukazyo.cono.morny.reporter.MornyReport import cc.sukazyo.cono.morny.util.schedule.Scheduler import cc.sukazyo.cono.morny.util.EpochDateTime.EpochMillis @@ -38,6 +40,7 @@ object MornyCoeur { eventManager: EventListenerManager, commandManager: MornyCommandManager, queryManager: MornyQueryManager, + httpServer: MornyHttpServerContext, givenCxt: GivenContext ) @@ -52,6 +55,7 @@ object MornyCoeur { eventManager: EventListenerManager, commandManager: MornyCommandManager, queryManager: MornyQueryManager, + httpServer: MornyHttpServerContext, givenCxt: GivenContext ) @@ -66,6 +70,7 @@ object MornyCoeur { eventManager: EventListenerManager, commandManager: MornyCommandManager, queryManager: MornyQueryManager, + httpServer: MornyHttpServerContext, givenCxt: GivenContext ) @@ -166,11 +171,14 @@ class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(tes val commands: MornyCommandManager = MornyCommandManager() val queries: MornyQueryManager = MornyQueryManager() + private var _httpServerContext: MornyHttpServerContext = MornyHttpServerContextImpl() + // Coeur Initializing Pre Event modules.foreach(it => it.onInitializingPre(OnInitializingPreContext( externalContext, coeurStartTimestamp, account, username, userid, tasks, trusted, eventManager, commands, queries, + _httpServerContext, initializeContext))) // register core/api events @@ -199,12 +207,16 @@ class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(tes ) } + // register core http api service + import cc.sukazyo.cono.morny.core.http.services as http_srv + _httpServerContext register4API http_srv.Ping() // Coeur Initializing Event modules.foreach(it => it.onInitializing(OnInitializingContext( externalContext, coeurStartTimestamp, account, username, userid, tasks, trusted, eventManager, commands, queries, + _httpServerContext, initializeContext))) val watchDog: WatchDog = WatchDog("watch-dog", 1000, 1500, { (consumed, _) => @@ -221,6 +233,7 @@ class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(tes externalContext, coeurStartTimestamp, account, username, userid, tasks, trusted, eventManager, commands, queries, + _httpServerContext, initializeContext))) ///>>> BLOCK START instance configure & startup stage 2 @@ -237,6 +250,9 @@ class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(tes modules.foreach(it => it.onStarting(OnStartingContext( initializeContext))) + logger info "start http server" + val http: HttpServer = _httpServerContext.start + _httpServerContext = null logger info "start telegram event listening" import com.pengrad.telegrambot.TelegramException account.setUpdatesListener(eventManager, (e: TelegramException) => { diff --git a/src/main/scala/cc/sukazyo/cono/morny/core/MornyConfig.java b/src/main/scala/cc/sukazyo/cono/morny/core/MornyConfig.java index 71b8205..8ec087d 100644 --- a/src/main/scala/cc/sukazyo/cono/morny/core/MornyConfig.java +++ b/src/main/scala/cc/sukazyo/cono/morny/core/MornyConfig.java @@ -103,7 +103,13 @@ public class MornyConfig { public final boolean commandLogoutClear; /* ======================================= * - * system: morny report * + * system: http server * + * ======================================= */ + + public final int httpPort; + + /* ======================================= * + * function: reporter * * ======================================= */ /** @@ -164,11 +170,14 @@ public class MornyConfig { this.medicationTimerUseTimezone = prototype.medicationTimerUseTimezone; prototype.medicationNotifyAt.forEach(i -> { if (i < 0 || i > 23) throw new CheckFailure.UnavailableTimeInMedicationNotifyAt(); }); this.medicationNotifyAt = prototype.medicationNotifyAt; + if (prototype.httpPort < 0 || prototype.httpPort > 65535) throw new CheckFailure.UnavailableHttpPort(); + this.httpPort = prototype.httpPort; } public static class CheckFailure extends RuntimeException { public static class NullTelegramBotKey extends CheckFailure {} public static class UnavailableTimeInMedicationNotifyAt extends CheckFailure {} + public static class UnavailableHttpPort extends CheckFailure {} } public static class Prototype { @@ -193,6 +202,7 @@ public class MornyConfig { public long medicationNotifyToChat = -1L; @Nonnull public ZoneOffset medicationTimerUseTimezone = ZoneOffset.UTC; @Nonnull public final Set medicationNotifyAt = new HashSet<>(); + public int httpPort = 30179; } diff --git a/src/main/scala/cc/sukazyo/cono/morny/core/ServerMain.scala b/src/main/scala/cc/sukazyo/cono/morny/core/ServerMain.scala index c1a0918..ce238b7 100644 --- a/src/main/scala/cc/sukazyo/cono/morny/core/ServerMain.scala +++ b/src/main/scala/cc/sukazyo/cono/morny/core/ServerMain.scala @@ -57,6 +57,10 @@ object ServerMain { case "--trusted-reader-dinner" | "-trsd" => i += 1; config.dinnerTrustedReaders add(args(i) toLong) case "--dinner-chat" | "-chd" => i += 1; config.dinnerChatId = args(i) toLong + case "--http-listen-port" | "-hp" => + i += 1 + config.httpPort = args(i) toInt + case "--medication-notify-chat" | "-medc" => i += 1; config.medicationNotifyToChat = args(i) toLong case "--medication-notify-timezone" | "-medtz" => i += 1 diff --git a/src/main/scala/cc/sukazyo/cono/morny/core/ServerModulesLoader.scala b/src/main/scala/cc/sukazyo/cono/morny/core/ServerModulesLoader.scala index a4b5d7e..50dad7d 100644 --- a/src/main/scala/cc/sukazyo/cono/morny/core/ServerModulesLoader.scala +++ b/src/main/scala/cc/sukazyo/cono/morny/core/ServerModulesLoader.scala @@ -19,7 +19,8 @@ object ServerModulesLoader { morny.medication_timer.ModuleMedicationTimer(), morny.morny_misc.ModuleMornyMisc(), morny.uni_meow.ModuleUniMeow(), - morny.reporter.Module() + morny.reporter.Module(), + morny.stickers_get.Module(), ) diff --git a/src/main/scala/cc/sukazyo/cono/morny/core/http/ServiceUI.scala b/src/main/scala/cc/sukazyo/cono/morny/core/http/ServiceUI.scala new file mode 100644 index 0000000..c05dc79 --- /dev/null +++ b/src/main/scala/cc/sukazyo/cono/morny/core/http/ServiceUI.scala @@ -0,0 +1,19 @@ +package cc.sukazyo.cono.morny.core.http + +import cats.effect.IO +import cc.sukazyo.cono.morny.core.http.api.HttpService4Api +import cc.sukazyo.cono.morny.data.TelegramImages +import org.http4s.{HttpRoutes, MediaType} +import org.http4s.dsl.impl./ +import org.http4s.dsl.io.* +import org.http4s.headers.`Content-Type` + +class ServiceUI extends HttpService4Api { + + override lazy val service: HttpRoutes[IO] = HttpRoutes.of[IO] { + case GET -> Root => + NotImplemented(TelegramImages.IMG_501.get) + .map(_.withContentType(`Content-Type`(MediaType.image.jpeg))) + } + +} diff --git a/src/main/scala/cc/sukazyo/cono/morny/core/http/api/HttpServer.scala b/src/main/scala/cc/sukazyo/cono/morny/core/http/api/HttpServer.scala new file mode 100644 index 0000000..3c77578 --- /dev/null +++ b/src/main/scala/cc/sukazyo/cono/morny/core/http/api/HttpServer.scala @@ -0,0 +1,9 @@ +package cc.sukazyo.cono.morny.core.http.api + +import cats.effect.unsafe.IORuntime + +trait HttpServer (using IORuntime) { + + def stop(): Unit + +} diff --git a/src/main/scala/cc/sukazyo/cono/morny/core/http/api/HttpService4Api.scala b/src/main/scala/cc/sukazyo/cono/morny/core/http/api/HttpService4Api.scala new file mode 100644 index 0000000..7cd2069 --- /dev/null +++ b/src/main/scala/cc/sukazyo/cono/morny/core/http/api/HttpService4Api.scala @@ -0,0 +1,35 @@ +package cc.sukazyo.cono.morny.core.http.api + +import cats.effect.IO +import cc.sukazyo.cono.morny.core.Log.exceptionLog +import org.http4s.{HttpRoutes, Response} + +trait HttpService4Api { + + lazy val service: HttpRoutes[IO] + + extension (response: Response[IO]) { + def setMornyInternalErrorHeader (e: Throwable): Response[IO] = + response.setMornyInternalErrorHeader( + e.getClass.getSimpleName, + e.getMessage, + exceptionLog(e) + ) + def setMornyInternalErrorHeader ( + `Morny-Internal-Error-Type`: String, + `Morny-Internal-Error-Message`: String, + `Morny-Internal-Error-Detail`: String + ): Response[IO] = + response.withHeaders( + "Morny-Internal-Error-Type" -> `Morny-Internal-Error-Type`, + "Morny-Internal-Error-Message" -> `Morny-Internal-Error-Message`, + "Morny-Internal-Error-Detail" -> `Morny-Internal-Error-Detail`, + ) + } + +} + +object HttpService4Api { + def apply (_service: HttpRoutes[IO]): HttpService4Api = new HttpService4Api: + override lazy val service: HttpRoutes[IO] = _service +} diff --git a/src/main/scala/cc/sukazyo/cono/morny/core/http/api/MornyHttpServerContext.scala b/src/main/scala/cc/sukazyo/cono/morny/core/http/api/MornyHttpServerContext.scala new file mode 100644 index 0000000..50ad0d5 --- /dev/null +++ b/src/main/scala/cc/sukazyo/cono/morny/core/http/api/MornyHttpServerContext.scala @@ -0,0 +1,9 @@ +package cc.sukazyo.cono.morny.core.http.api + +trait MornyHttpServerContext { + + def register4API (service: HttpService4Api*): Unit + + def start: HttpServer + +} diff --git a/src/main/scala/cc/sukazyo/cono/morny/core/http/internal/MornyHttpServerContextImpl.scala b/src/main/scala/cc/sukazyo/cono/morny/core/http/internal/MornyHttpServerContextImpl.scala new file mode 100644 index 0000000..e637963 --- /dev/null +++ b/src/main/scala/cc/sukazyo/cono/morny/core/http/internal/MornyHttpServerContextImpl.scala @@ -0,0 +1,61 @@ +package cc.sukazyo.cono.morny.core.http.internal + +import cc.sukazyo.cono.morny.core.MornyCoeur +import cc.sukazyo.cono.morny.core.http.api.{HttpServer, HttpService4Api, MornyHttpServerContext} +import cc.sukazyo.cono.morny.core.http.ServiceUI +import cc.sukazyo.cono.morny.core.Log.{exceptionLog, logger} + +import scala.collection.mutable + +class MornyHttpServerContextImpl (using coeur: MornyCoeur) extends MornyHttpServerContext { + + private val services_api = mutable.Queue.empty[HttpService4Api] + + private lazy val service_ui = ServiceUI() + + override def register4API (services: HttpService4Api*): Unit = + services_api ++= services + + override def start: HttpServer = { + import cats.data.OptionT + import cats.effect.unsafe.implicits.global + import cats.effect.IO + import cats.implicits.toSemigroupKOps + import org.http4s.server.{Router, Server} + import org.http4s.server.middleware.{ErrorAction, ErrorHandling} + + val router = Router( + "/" -> service_ui.service, + "/api" -> services_api.map(_.service).reduce(_ <+> _) + ) + + def errorHandler (t: Throwable, message: =>String): OptionT[IO, Unit] = + OptionT.liftF(IO { + logger error + s"""Unexpected exception occurred on Morny Http Server : + |${exceptionLog(t)}""".stripMargin + }) + val withErrorHandler = ErrorHandling.Recover.total( + ErrorAction.log( + router, + messageFailureLogAction = errorHandler, + serviceErrorLogAction = errorHandler + ) + ) + + val server = org.http4s.netty.server.NettyServerBuilder[IO] + .bindHttp(coeur.config.httpPort, "0.0.0.0") + .withHttpApp(withErrorHandler.orNotFound) + .resource + val (_server, _shutdown_io) = server.allocated.unsafeRunSync() match + case (_1, _2) => (_1, _2) + logger notice s"Morny HTTP Server started at ${_server.baseUri}" + + new HttpServer(using global): + val server: Server = _server + private val shutdown_io = _shutdown_io + override def stop (): Unit = shutdown_io.unsafeRunSync() + + } + +} diff --git a/src/main/scala/cc/sukazyo/cono/morny/core/http/services/Ping.scala b/src/main/scala/cc/sukazyo/cono/morny/core/http/services/Ping.scala new file mode 100644 index 0000000..c2b7fe6 --- /dev/null +++ b/src/main/scala/cc/sukazyo/cono/morny/core/http/services/Ping.scala @@ -0,0 +1,22 @@ +package cc.sukazyo.cono.morny.core.http.services + +import cats.effect.IO +import cc.sukazyo.cono.morny.core.http.api.HttpService4Api +import org.http4s.{HttpRoutes, Response} +import org.http4s.circe.jsonEncoder +import org.http4s.dsl.io.* + +class Ping extends HttpService4Api { + + case class PingResult ( + pong: Boolean = true + ) + + override lazy val service: HttpRoutes[IO] = HttpRoutes.of[IO] { + case GET -> Root / "ping" => + import io.circe.generic.auto.* + import io.circe.syntax.* + Ok(PingResult().asJson) + } + +} diff --git a/src/main/scala/cc/sukazyo/cono/morny/data/TelegramImages.scala b/src/main/scala/cc/sukazyo/cono/morny/data/TelegramImages.scala index d26a45b..d642e1c 100644 --- a/src/main/scala/cc/sukazyo/cono/morny/data/TelegramImages.scala +++ b/src/main/scala/cc/sukazyo/cono/morny/data/TelegramImages.scala @@ -31,5 +31,9 @@ object TelegramImages { } val IMG_ABOUT: AssetsFileImage = AssetsFileImage("images/featured-image@0.5x.jpg") + val IMG_404: AssetsFileImage = AssetsFileImage("images/http-sekai-404.png") + val IMG_500: AssetsFileImage = AssetsFileImage("images/http-sekai-500.png") + val IMG_501: AssetsFileImage = AssetsFileImage("images/http-sekai-501.png") + val IMG_523: AssetsFileImage = AssetsFileImage("images/http-sekai-523.png") } diff --git a/src/main/scala/cc/sukazyo/cono/morny/stickers_get/Module.scala b/src/main/scala/cc/sukazyo/cono/morny/stickers_get/Module.scala new file mode 100644 index 0000000..6538b0b --- /dev/null +++ b/src/main/scala/cc/sukazyo/cono/morny/stickers_get/Module.scala @@ -0,0 +1,28 @@ +package cc.sukazyo.cono.morny.stickers_get + +import cc.sukazyo.cono.morny.core.internal.MornyInternalModule +import cc.sukazyo.cono.morny.core.MornyCoeur +import cc.sukazyo.cono.morny.stickers_get.http.StickerService + +class Module extends MornyInternalModule { + + override val id: String = "morny.stickers-get" + override val name: String = "Morny Can Get and Provide Stickers" + override val description: String | Null = + // language=markdown + """Make Morny as a Telegram Stickers API. + | + |This module handles `/api/sticker` route that you can get a sticker + |by a sticker ID via HTTP request. + | + |original idea is: https://github.com/tjhorner/tstickers-api + |""".stripMargin + + override def onInitializing (using MornyCoeur)(cxt: MornyCoeur.OnInitializingContext): Unit = { + import cxt.* + + httpServer register4API StickerService() + + } + +} diff --git a/src/main/scala/cc/sukazyo/cono/morny/stickers_get/http/StickerService.scala b/src/main/scala/cc/sukazyo/cono/morny/stickers_get/http/StickerService.scala new file mode 100644 index 0000000..4372d59 --- /dev/null +++ b/src/main/scala/cc/sukazyo/cono/morny/stickers_get/http/StickerService.scala @@ -0,0 +1,57 @@ +package cc.sukazyo.cono.morny.stickers_get.http + +import cats.effect.IO +import cc.sukazyo.cono.morny.core.http.api.HttpService4Api +import cc.sukazyo.cono.morny.core.MornyCoeur +import cc.sukazyo.cono.morny.data.TelegramImages +import com.pengrad.telegrambot.request.GetFile +import org.http4s.{HttpRoutes, MediaType} +import org.http4s.dsl.io.* +import org.http4s.headers.`Content-Type` + +import java.io.IOException + +class StickerService (using coeur: MornyCoeur) extends HttpService4Api { + + override lazy val service: HttpRoutes[IO] = HttpRoutes.of { + + case GET -> Root / "sticker" / "id" / id => + try { + val response = coeur.account execute GetFile(id) + if response.isOk then + try { + val file = coeur.account getFileContent response.file + Ok(file) + } catch { + case e: IOException => + ServiceUnavailable( + TelegramImages.IMG_523.get, + `Content-Type`(MediaType.image.png), + ).map(_.setMornyInternalErrorHeader(e)) + } + else + NotFound( + TelegramImages.IMG_404.get, + `Content-Type`(MediaType.image.png), + ).map(_.setMornyInternalErrorHeader( + "_telegram_api", + response.errorCode.toString, + response.description, + )) + } catch + case io: IOException => + ServiceUnavailable( + TelegramImages.IMG_523.get, + `Content-Type`(MediaType.image.png), + ).map(_.setMornyInternalErrorHeader(io)) + case e: Throwable => + InternalServerError( + TelegramImages.IMG_500.get, + `Content-Type`(MediaType.image.png), + ).map(_.setMornyInternalErrorHeader(e)) + + case GET -> Root / "sticker" => + NotFound("not found") + + } +} diff --git a/src/test/scala/cc/sukazyo/cono/morny/MornyCLI.scala b/src/test/scala/cc/sukazyo/cono/morny/MornyCLI.scala index a5c01f8..0f003d1 100644 --- a/src/test/scala/cc/sukazyo/cono/morny/MornyCLI.scala +++ b/src/test/scala/cc/sukazyo/cono/morny/MornyCLI.scala @@ -1,5 +1,6 @@ package cc.sukazyo.cono.morny +import cc.sukazyo.cono.morny.core.ServerMain import cc.sukazyo.cono.morny.util.UniversalCommand import scala.io.StdIn