mirror of
https://github.com/Eyre-S/Coeur-Morny-Cono.git
synced 2024-11-22 11:14:55 +08:00
make http:sticker/id basic usable
This commit is contained in:
parent
f2bd0a38c2
commit
9ddfa6539d
@ -2,23 +2,45 @@ package cc.sukazyo.cono.morny.core.http.api
|
||||
|
||||
import cats.effect.IO
|
||||
import cc.sukazyo.cono.morny.data.TelegramImages
|
||||
import cc.sukazyo.cono.morny.util.StringEnsure.firstLine
|
||||
import cc.sukazyo.cono.morny.util.UseThrowable.toLogString
|
||||
import org.http4s.{Header, MediaType, Response}
|
||||
import org.http4s.dsl.io.*
|
||||
import org.http4s.headers.`Content-Type`
|
||||
|
||||
import java.net.URLEncoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
object HttpStatus extends HttpStatus
|
||||
|
||||
trait HttpStatus {
|
||||
|
||||
private type ResponseT = Response[IO]
|
||||
private type ResponseIO = IO[ResponseT]
|
||||
|
||||
extension (response: ResponseT) {
|
||||
|
||||
|
||||
def setMornyInternalErrorHeader (e: Throwable): ResponseT =
|
||||
response.setMornyInternalErrorHeader(
|
||||
e.getClass.getSimpleName,
|
||||
e.getMessage,
|
||||
e.toLogString
|
||||
e.getClass.getSimpleName.firstLine,
|
||||
e.getMessage.firstLine,
|
||||
URLEncoder.encode(e.toLogString, StandardCharsets.UTF_8) // todo: maybe extract this const
|
||||
)
|
||||
|
||||
/** Set HTTP Header that shows Morny's Internal Server Error related information.
|
||||
*
|
||||
* It will set the following headers, corresponding to this method's parameters, you
|
||||
* can customize those values.
|
||||
* - Morny-Internal-Error-Type
|
||||
* - Morny-Internal-Error-Message
|
||||
* - Morny-Internal-Error-Detail
|
||||
*
|
||||
* **Notice that ANY header value MUST NOT contains line breaking!** Or it will only
|
||||
* returns an empty 500 response.
|
||||
*
|
||||
* @return the [[ResponseT]], with above headers added.
|
||||
*/
|
||||
def setMornyInternalErrorHeader (
|
||||
`Morny-Internal-Error-Type`: String,
|
||||
`Morny-Internal-Error-Message`: String,
|
||||
@ -43,7 +65,7 @@ trait HttpStatus {
|
||||
.map(_.withContentType(`Content-Type`(MediaType.image.png)))
|
||||
|
||||
/** 500 Internal Server Error */
|
||||
def MornyInternalServerError (): ResponseIO =
|
||||
def MornyInternalServerError (): ResponseIO =
|
||||
InternalServerError(TelegramImages.IMG_500.get)
|
||||
.map(_.withContentType(`Content-Type`(MediaType.image.png)))
|
||||
|
||||
|
@ -0,0 +1,24 @@
|
||||
package cc.sukazyo.cono.morny.stickers_get
|
||||
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
enum StickerType {
|
||||
case WEBP
|
||||
case WEBM
|
||||
case PNG
|
||||
}
|
||||
|
||||
object StickerType {
|
||||
|
||||
class UnknownStickerTypeException (message: String)
|
||||
extends Exception (s"Unknown sticker type: $message")
|
||||
|
||||
// @throws[UnknownStickerTypeException]
|
||||
def check (stickerFile: Array[Byte]): StickerType =
|
||||
val header = new String(stickerFile.take(50), StandardCharsets.UTF_8)
|
||||
if header.contains("WEBP") then WEBP
|
||||
else if header.contains("webm") then WEBM
|
||||
else if header.contains("PNG") then PNG
|
||||
else throw UnknownStickerTypeException("Unable to infer file type.")
|
||||
|
||||
}
|
@ -3,12 +3,15 @@ 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.stickers_get.StickerType
|
||||
import cc.sukazyo.cono.morny.stickers_get.StickerType.UnknownStickerTypeException
|
||||
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.File.getContent
|
||||
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Requests.execute
|
||||
import com.pengrad.telegrambot.request.GetFile
|
||||
import com.pengrad.telegrambot.TelegramBot
|
||||
import org.http4s.HttpRoutes
|
||||
import org.http4s.{HttpRoutes, MediaType}
|
||||
import org.http4s.dsl.io.*
|
||||
import org.http4s.headers.`Content-Type`
|
||||
|
||||
import java.io.IOException
|
||||
|
||||
@ -23,8 +26,16 @@ class StickerService (using coeur: MornyCoeur) extends HttpService4Api {
|
||||
try {
|
||||
given TelegramBot = coeur.account
|
||||
val file = response.file.getContent
|
||||
val file_type: MediaType = StickerType.check(file) match
|
||||
case StickerType.WEBP => MediaType.image.webp
|
||||
case StickerType.WEBM => MediaType.video.webm
|
||||
case StickerType.PNG => MediaType.image.png
|
||||
Ok(file)
|
||||
.map(_.withContentType(`Content-Type`(file_type)))
|
||||
} catch {
|
||||
case e: UnknownStickerTypeException =>
|
||||
MornyInternalServerError()
|
||||
.map(_.setMornyInternalErrorHeader(e))
|
||||
case e: IOException =>
|
||||
MornyServiceUnavailable()
|
||||
.map(_.setMornyInternalErrorHeader(e))
|
||||
|
@ -4,6 +4,14 @@ object StringEnsure {
|
||||
|
||||
extension (str: String) {
|
||||
|
||||
/** Take the first line of this String.
|
||||
*
|
||||
* It will find the first `\n` (unicode 0x0a, aka. LF) or `\n` (unicode 0x0e, aka. CR)
|
||||
* and take all the chars before it, and ignores all the contents after it.
|
||||
*/
|
||||
def firstLine : String =
|
||||
str.takeWhile(c => (c != '\n') && (c != '\r'))
|
||||
|
||||
/** Ensure the string have a length not smaller that the given length.
|
||||
*
|
||||
* If the length of the string is smaller than the given length, then the string will be padded
|
||||
|
Loading…
Reference in New Issue
Block a user