All Downloads are FREE. Search and download functionalities are using the official Maven repository.

xyz.cssxsh.mirai.hibernate.http.HibernateAdapter.kt Maven / Gradle / Ivy

package xyz.cssxsh.mirai.hibernate.http

import io.ktor.http.*
import io.ktor.http.content.*
import io.ktor.server.application.*
import io.ktor.server.http.content.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import kotlinx.serialization.*
import kotlinx.serialization.json.*
import net.mamoe.mirai.api.http.adapter.*
import net.mamoe.mirai.api.http.context.session.*
import net.mamoe.mirai.event.events.*
import net.mamoe.mirai.message.data.*
import xyz.cssxsh.hibernate.*
import xyz.cssxsh.mirai.hibernate.*
import xyz.cssxsh.mirai.hibernate.entry.*
import java.io.File

public class HibernateAdapter : MahKtorAdapter("hibernate") {

    @PublishedApi
    internal val setting: HibernateAdapterSetting by lazy {
        getSetting() ?: HibernateAdapterSetting(port = 8081)
    }

    @Suppress("INVISIBLE_MEMBER")
    private val factory: org.hibernate.SessionFactory get() = xyz.cssxsh.mirai.hibernate.factory

    override fun onEnable() {
        log.info(">>> [hibernate message recorder] is listening at http://${host}:${port}")
    }

    override suspend fun onReceiveBotEvent(event: BotEvent, session: Session) {
        // ignore
    }

    override fun MahKtorAdapterInitBuilder.initKtorAdapter() {
        host = setting.host
        port = setting.port
        module {
            routing {
                static("/") {
                    staticRootFolder = File(System.getProperty(STATIC_KEY, "./web"))
                    default("index.html")
                    files(".")
                }
                // region face
                get("/face/random") {
                    call.respondText(status = HttpStatusCode.OK, contentType = ContentType.Application.Json) {
                        try {
                            val record = FaceRecord.random()
                            success(data = record)
                        } catch (cause: NoSuchElementException) {
                            failure(code = 400, message = "random failure, face record may be empty.")
                        } catch (cause: Throwable) {
                            failure(code = 500, message = cause.message ?: cause.stackTraceToString())
                        }
                    }
                }
                put("/face/disable") {
                    call.respondText(status = HttpStatusCode.OK, contentType = ContentType.Application.Json) {
                        try {
                            val md5 = call.parameters["md5"] ?: throw NoSuchElementException("need parameter md5")
                            val records = FaceRecord.disable(md5 = md5)
                            success(data = records)
                        } catch (cause: NoSuchElementException) {
                            failure(code = 400, message = cause.message ?: cause.stackTraceToString())
                        } catch (cause: IllegalStateException) {
                            failure(code = 400, message = cause.message ?: cause.stackTraceToString())
                        } catch (cause: Throwable) {
                            failure(code = 500, message = cause.message ?: cause.stackTraceToString())
                        }
                    }
                }
                get("/face/tag") {
                    call.respondText(status = HttpStatusCode.OK, contentType = ContentType.Application.Json) {
                        try {
                            val md5 = call.parameters["md5"] ?: throw NoSuchElementException("need parameter md5")
                            val records = FaceTagRecord.get(md5 = md5)
                            success(data = records)
                        } catch (cause: NoSuchElementException) {
                            failure(code = 400, message = cause.message ?: cause.stackTraceToString())
                        } catch (cause: Throwable) {
                            failure(code = 500, message = cause.message ?: cause.stackTraceToString())
                        }
                    }
                }
                put("/face/tag") {
                    call.respondText(status = HttpStatusCode.OK, contentType = ContentType.Application.Json) {
                        try {
                            val md5 = call.parameters["md5"] ?: throw NoSuchElementException("need parameter md5")
                            val tag = call.parameters["tag"] ?: throw NoSuchElementException("need parameter tag")
                            val records = FaceTagRecord.set(md5 = md5, tag = tag)
                            success(data = records)
                        } catch (cause: NoSuchElementException) {
                            failure(code = 400, message = cause.message ?: cause.stackTraceToString())
                        } catch (cause: Throwable) {
                            failure(code = 500, message = cause.message ?: cause.stackTraceToString())
                        }
                    }
                }
                delete("/face/tag") {
                    call.respondText(status = HttpStatusCode.OK, contentType = ContentType.Application.Json) {
                        try {
                            val md5 = call.parameters["md5"] ?: throw NoSuchElementException("need parameter md5")
                            val tag = call.parameters["tag"] ?: throw NoSuchElementException("need parameter tag")
                            val records = FaceTagRecord.remove(md5 = md5, tag = tag)
                            success(data = records)
                        } catch (cause: NoSuchElementException) {
                            failure(code = 400, message = cause.message ?: cause.stackTraceToString())
                        } catch (cause: Throwable) {
                            failure(code = 500, message = cause.message ?: cause.stackTraceToString())
                        }
                    }
                }
                // endregion

                // region message
                get("/message/bot") {
                    call.respondText(status = HttpStatusCode.OK, contentType = ContentType.Application.Json) {
                        try {
                            val bot = call.parameters["bot"]?.toLongOrNull()
                                ?: throw NoSuchElementException("need parameter bot")
                            val start = call.parameters["start"]?.toIntOrNull()
                                ?: throw NoSuchElementException("need parameter start")
                            val end = call.parameters["end"]?.toIntOrNull()
                                ?: throw NoSuchElementException("need parameter end")
                            val records = factory.fromSession { session ->
                                session.withCriteria { query ->
                                    val record = query.from()
                                    query.select(record)
                                        .where(
                                            between(record.get("time"), start, end),
                                            equal(record.get("bot"), bot)
                                        )
                                        .orderBy(desc(record.get("time")))
                                }.list()
                            }
                            success(data = records)
                        } catch (cause: NoSuchElementException) {
                            failure(code = 400, message = cause.message ?: cause.stackTraceToString())
                        } catch (cause: Throwable) {
                            failure(code = 500, message = cause.message ?: cause.stackTraceToString())
                        }
                    }
                }
                get("/message/group") {
                    call.respondText(status = HttpStatusCode.OK, contentType = ContentType.Application.Json) {
                        try {
                            val bot = call.parameters["bot"]?.toLongOrNull()
                                ?: throw NoSuchElementException("need parameter bot")
                            val group = call.parameters["group"]?.toLongOrNull()
                                ?: throw NoSuchElementException("need parameter group")
                            val start = call.parameters["start"]?.toIntOrNull()
                                ?: throw NoSuchElementException("need parameter start")
                            val end = call.parameters["end"]?.toIntOrNull()
                                ?: throw NoSuchElementException("need parameter end")
                            val records = factory.fromSession { session ->
                                session.withCriteria { query ->
                                    val record = query.from()
                                    query.select(record)
                                        .where(
                                            equal(record.get("bot"), bot),
                                            between(record.get("time"), start, end),
                                            equal(record.get("kind"), MessageSourceKind.GROUP),
                                            equal(record.get("targetId"), group)
                                        )
                                        .orderBy(desc(record.get("time")))
                                }.list()
                            }
                            success(data = records)
                        } catch (cause: NoSuchElementException) {
                            failure(code = 400, message = cause.message ?: cause.stackTraceToString())
                        } catch (cause: Throwable) {
                            failure(code = 500, message = cause.message ?: cause.stackTraceToString())
                        }
                    }
                }
                get("/message/friend") {
                    call.respondText(status = HttpStatusCode.OK, contentType = ContentType.Application.Json) {
                        try {
                            val bot = call.parameters["bot"]?.toLongOrNull()
                                ?: throw NoSuchElementException("need parameter bot")
                            val friend = call.parameters["friend"]?.toLongOrNull()
                                ?: throw NoSuchElementException("need parameter friend")
                            val start = call.parameters["start"]?.toIntOrNull()
                                ?: throw NoSuchElementException("need parameter start")
                            val end = call.parameters["end"]?.toIntOrNull()
                                ?: throw NoSuchElementException("need parameter end")
                            val records = factory.fromSession { session ->
                                session.withCriteria { query ->
                                    val record = query.from()
                                    query.select(record)
                                        .where(
                                            equal(record.get("bot"), bot),
                                            between(record.get("time"), start, end),
                                            equal(record.get("kind"), MessageSourceKind.FRIEND),
                                            or(
                                                equal(record.get("fromId"), friend),
                                                equal(record.get("targetId"), friend)
                                            )
                                        )
                                        .orderBy(desc(record.get("time")))
                                }.list()
                            }
                            success(data = records)
                        } catch (cause: NoSuchElementException) {
                            failure(code = 400, message = cause.message ?: cause.stackTraceToString())
                        } catch (cause: Throwable) {
                            failure(code = 500, message = cause.message ?: cause.stackTraceToString())
                        }
                    }
                }
                get("/message/member") {
                    call.respondText(status = HttpStatusCode.OK, contentType = ContentType.Application.Json) {
                        try {
                            val bot = call.parameters["bot"]?.toLongOrNull()
                                ?: throw NoSuchElementException("need parameter bot")
                            val group = call.parameters["group"]?.toLongOrNull()
                                ?: throw NoSuchElementException("need parameter group")
                            val member = call.parameters["member"]?.toLongOrNull()
                                ?: throw NoSuchElementException("need parameter member")
                            val start = call.parameters["start"]?.toIntOrNull()
                                ?: throw NoSuchElementException("need parameter start")
                            val end = call.parameters["end"]?.toIntOrNull()
                                ?: throw NoSuchElementException("need parameter end")
                            val records = factory.fromSession { session ->
                                session.withCriteria { query ->
                                    val record = query.from()
                                    query.select(record)
                                        .where(
                                            equal(record.get("bot"), bot),
                                            between(record.get("time"), start, end),
                                            equal(record.get("kind"), MessageSourceKind.GROUP),
                                            equal(record.get("fromId"), member),
                                            equal(record.get("targetId"), group)
                                        )
                                        .orderBy(desc(record.get("time")))
                                }.list()
                            }
                            success(data = records)
                        } catch (cause: NoSuchElementException) {
                            failure(code = 400, message = cause.message ?: cause.stackTraceToString())
                        } catch (cause: Throwable) {
                            failure(code = 500, message = cause.message ?: cause.stackTraceToString())
                        }
                    }
                }
                get("/message/stranger") {
                    call.respondText(status = HttpStatusCode.OK, contentType = ContentType.Application.Json) {
                        try {
                            val bot = call.parameters["bot"]?.toLongOrNull()
                                ?: throw NoSuchElementException("need parameter bot")
                            val stranger = call.parameters["stranger"]?.toLongOrNull()
                                ?: throw NoSuchElementException("need parameter stranger")
                            val start = call.parameters["start"]?.toIntOrNull()
                                ?: throw NoSuchElementException("need parameter start")
                            val end = call.parameters["end"]?.toIntOrNull()
                                ?: throw NoSuchElementException("need parameter end")
                            val records = factory.fromSession { session ->
                                session.withCriteria { query ->
                                    val record = query.from()
                                    query.select(record)
                                        .where(
                                            equal(record.get("bot"), bot),
                                            between(record.get("time"), start, end),
                                            equal(record.get("kind"), MessageSourceKind.STRANGER),
                                            or(
                                                equal(record.get("fromId"), stranger),
                                                equal(record.get("targetId"), stranger)
                                            )
                                        )
                                        .orderBy(desc(record.get("time")))
                                }.list()
                            }
                            success(data = records)
                        } catch (cause: NoSuchElementException) {
                            failure(code = 400, message = cause.message ?: cause.stackTraceToString())
                        } catch (cause: Throwable) {
                            failure(code = 500, message = cause.message ?: cause.stackTraceToString())
                        }
                    }
                }
                get("/message/kind") {
                    call.respondText(status = HttpStatusCode.OK, contentType = ContentType.Application.Json) {
                        try {
                            val kind = call.parameters["kind"]
                                ?: throw NoSuchElementException("need parameter kind")
                            val start = call.parameters["start"]?.toIntOrNull()
                                ?: throw NoSuchElementException("need parameter start")
                            val end = call.parameters["end"]?.toIntOrNull()
                                ?: throw NoSuchElementException("need parameter end")
                            val records = factory.fromSession { session ->
                                session.withCriteria { query ->
                                    val record = query.from()
                                    query.select(record)
                                        .where(
                                            between(record.get("time"), start, end),
                                            equal(
                                                record.get("kind"),
                                                MessageSourceKind.valueOf(kind)
                                            )
                                        )
                                        .orderBy(desc(record.get("time")))
                                }.list()
                            }
                            success(data = records)
                        } catch (cause: NoSuchElementException) {
                            failure(code = 400, message = cause.message ?: cause.stackTraceToString())
                        } catch (cause: Throwable) {
                            failure(code = 500, message = cause.message ?: cause.stackTraceToString())
                        }
                    }
                }
                get("/message/source") {
                    call.respondText(status = HttpStatusCode.OK, contentType = ContentType.Application.Json) {
                        try {
                            val target = call.parameters["target"]?.toIntOrNull()
                                ?: throw NoSuchElementException("need parameter target")
                            val time = call.parameters["time"]?.toIntOrNull()
                                ?: throw NoSuchElementException("need parameter time")
                            val ids = call.parameters["ids"]
                                ?: throw NoSuchElementException("need parameter ids")
                            val records = factory.fromSession { session ->
                                session.withCriteria { query ->
                                    val record = query.from()
                                    query.select(record)
                                        .where(
                                            equal(record.get("targetId"), target),
                                            equal(record.get("time"), time),
                                            equal(record.get("ids"), ids)
                                        )
                                }.list()
                            }
                            success(data = records)
                        } catch (cause: NoSuchElementException) {
                            failure(code = 400, message = cause.message ?: cause.stackTraceToString())
                        } catch (cause: Throwable) {
                            failure(code = 500, message = cause.message ?: cause.stackTraceToString())
                        }
                    }
                }
                // endregion

                // region archive
                get("/archive/bot") {
                    call.respondText(status = HttpStatusCode.OK, contentType = ContentType.Application.Json) {
                        try {
                            val records = factory.fromSession { session ->
                                session.withCriteria { query ->
                                    val record = query.from()
                                    query.select(record)
                                }.list()
                            }
                            success(data = records)
                        } catch (cause: NoSuchElementException) {
                            failure(code = 400, message = cause.message ?: cause.stackTraceToString())
                        } catch (cause: Throwable) {
                            failure(code = 500, message = cause.message ?: cause.stackTraceToString())
                        }
                    }
                }
                get("/archive/group") {
                    call.respondText(status = HttpStatusCode.OK, contentType = ContentType.Application.Json) {
                        try {
                            val bot = call.parameters["bot"]?.toLongOrNull()
                            val records = factory.fromSession { session ->
                                session.withCriteria { query ->
                                    val record = query.from()
                                    val group = record.get("group")
                                    query.select(record)

                                    if (bot != null) {
                                        val subquery = query.subquery()
                                        val member = subquery.from()
                                        val uuid = member.get("uuid")
                                        subquery.select(member)
                                            .where(
                                                equal(uuid.get("group"), group),
                                                equal(uuid.get("uid"), bot)
                                            )
                                        query.where(exists(subquery))
                                    }
                                }.list()
                            }
                            success(data = records)
                        } catch (cause: NoSuchElementException) {
                            failure(code = 400, message = cause.message ?: cause.stackTraceToString())
                        } catch (cause: Throwable) {
                            failure(code = 500, message = cause.message ?: cause.stackTraceToString())
                        }
                    }
                }
                get("/archive/friend") {
                    call.respondText(status = HttpStatusCode.OK, contentType = ContentType.Application.Json) {
                        try {
                            val bot = call.parameters["bot"]?.toLongOrNull()
                            val records = factory.fromSession { session ->
                                session.withCriteria { query ->
                                    val record = query.from()
                                    val uuid = record.get("uuid")
                                    query.select(record)
                                    if (bot != null) {
                                        query.where(
                                            equal(uuid.get("bot"), bot)
                                        )
                                    }
                                }.list()
                            }
                            success(data = records)
                        } catch (cause: NoSuchElementException) {
                            failure(code = 400, message = cause.message ?: cause.stackTraceToString())
                        } catch (cause: Throwable) {
                            failure(code = 500, message = cause.message ?: cause.stackTraceToString())
                        }
                    }
                }
                get("/archive/member") {
                    call.respondText(status = HttpStatusCode.OK, contentType = ContentType.Application.Json) {
                        try {
                            val group = call.parameters["group"]
                                ?: throw NoSuchElementException("need parameter group")
                            val records = factory.fromSession { session ->
                                session.withCriteria { query ->
                                    val record = query.from()
                                    val uuid = record.get("uuid")
                                    query.select(record)
                                        .where(
                                            equal(uuid.get("group"), group)
                                        )
                                }.list()
                            }
                            success(data = records)
                        } catch (cause: NoSuchElementException) {
                            failure(code = 400, message = cause.message ?: cause.stackTraceToString())
                        } catch (cause: Throwable) {
                            failure(code = 500, message = cause.message ?: cause.stackTraceToString())
                        }
                    }
                }
                // endregion
            }
        }
    }

    public companion object {
        @JvmStatic
        internal val STATIC_KEY: String = "xyz.cssxsh.mirai.hibernate.http.static"

        @JvmStatic
        internal inline fun  success(data: T): String {
            val result = HibernateAdapterResult(
                code = 0,
                message = "success",
                data = data
            )
            return Json.encodeToString(result)
        }

        @JvmStatic
        @Suppress("NOTHING_TO_INLINE")
        internal inline fun failure(code: Int, message: String): String {
            val result = HibernateAdapterResult(
                code = code,
                message = message
            )

            return Json.encodeToString(result)
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy