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 cats.effect.IO
|
||||||
import cc.sukazyo.cono.morny.data.TelegramImages
|
import cc.sukazyo.cono.morny.data.TelegramImages
|
||||||
|
import cc.sukazyo.cono.morny.util.StringEnsure.firstLine
|
||||||
import cc.sukazyo.cono.morny.util.UseThrowable.toLogString
|
import cc.sukazyo.cono.morny.util.UseThrowable.toLogString
|
||||||
import org.http4s.{Header, MediaType, Response}
|
import org.http4s.{Header, MediaType, Response}
|
||||||
import org.http4s.dsl.io.*
|
import org.http4s.dsl.io.*
|
||||||
import org.http4s.headers.`Content-Type`
|
import org.http4s.headers.`Content-Type`
|
||||||
|
|
||||||
|
import java.net.URLEncoder
|
||||||
|
import java.nio.charset.StandardCharsets
|
||||||
|
|
||||||
|
object HttpStatus extends HttpStatus
|
||||||
|
|
||||||
trait HttpStatus {
|
trait HttpStatus {
|
||||||
|
|
||||||
private type ResponseT = Response[IO]
|
private type ResponseT = Response[IO]
|
||||||
private type ResponseIO = IO[ResponseT]
|
private type ResponseIO = IO[ResponseT]
|
||||||
|
|
||||||
extension (response: ResponseT) {
|
extension (response: ResponseT) {
|
||||||
|
|
||||||
|
|
||||||
def setMornyInternalErrorHeader (e: Throwable): ResponseT =
|
def setMornyInternalErrorHeader (e: Throwable): ResponseT =
|
||||||
response.setMornyInternalErrorHeader(
|
response.setMornyInternalErrorHeader(
|
||||||
e.getClass.getSimpleName,
|
e.getClass.getSimpleName.firstLine,
|
||||||
e.getMessage,
|
e.getMessage.firstLine,
|
||||||
e.toLogString
|
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 (
|
def setMornyInternalErrorHeader (
|
||||||
`Morny-Internal-Error-Type`: String,
|
`Morny-Internal-Error-Type`: String,
|
||||||
`Morny-Internal-Error-Message`: String,
|
`Morny-Internal-Error-Message`: String,
|
||||||
@ -43,7 +65,7 @@ trait HttpStatus {
|
|||||||
.map(_.withContentType(`Content-Type`(MediaType.image.png)))
|
.map(_.withContentType(`Content-Type`(MediaType.image.png)))
|
||||||
|
|
||||||
/** 500 Internal Server Error */
|
/** 500 Internal Server Error */
|
||||||
def MornyInternalServerError (): ResponseIO =
|
def MornyInternalServerError (): ResponseIO =
|
||||||
InternalServerError(TelegramImages.IMG_500.get)
|
InternalServerError(TelegramImages.IMG_500.get)
|
||||||
.map(_.withContentType(`Content-Type`(MediaType.image.png)))
|
.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 cats.effect.IO
|
||||||
import cc.sukazyo.cono.morny.core.http.api.HttpService4Api
|
import cc.sukazyo.cono.morny.core.http.api.HttpService4Api
|
||||||
import cc.sukazyo.cono.morny.core.MornyCoeur
|
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.File.getContent
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Requests.execute
|
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Requests.execute
|
||||||
import com.pengrad.telegrambot.request.GetFile
|
import com.pengrad.telegrambot.request.GetFile
|
||||||
import com.pengrad.telegrambot.TelegramBot
|
import com.pengrad.telegrambot.TelegramBot
|
||||||
import org.http4s.HttpRoutes
|
import org.http4s.{HttpRoutes, MediaType}
|
||||||
import org.http4s.dsl.io.*
|
import org.http4s.dsl.io.*
|
||||||
|
import org.http4s.headers.`Content-Type`
|
||||||
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
@ -23,8 +26,16 @@ class StickerService (using coeur: MornyCoeur) extends HttpService4Api {
|
|||||||
try {
|
try {
|
||||||
given TelegramBot = coeur.account
|
given TelegramBot = coeur.account
|
||||||
val file = response.file.getContent
|
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)
|
Ok(file)
|
||||||
|
.map(_.withContentType(`Content-Type`(file_type)))
|
||||||
} catch {
|
} catch {
|
||||||
|
case e: UnknownStickerTypeException =>
|
||||||
|
MornyInternalServerError()
|
||||||
|
.map(_.setMornyInternalErrorHeader(e))
|
||||||
case e: IOException =>
|
case e: IOException =>
|
||||||
MornyServiceUnavailable()
|
MornyServiceUnavailable()
|
||||||
.map(_.setMornyInternalErrorHeader(e))
|
.map(_.setMornyInternalErrorHeader(e))
|
||||||
|
@ -4,6 +4,14 @@ object StringEnsure {
|
|||||||
|
|
||||||
extension (str: String) {
|
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.
|
/** 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
|
* 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