diff --git a/core/src/main/kotlin/dev/usbharu/multim/api/EmojiApi.kt b/core/src/main/kotlin/dev/usbharu/multim/api/EmojiApi.kt new file mode 100644 index 0000000..748839e --- /dev/null +++ b/core/src/main/kotlin/dev/usbharu/multim/api/EmojiApi.kt @@ -0,0 +1,10 @@ +package dev.usbharu.multim.api + +import dev.usbharu.multim.error.MultiMResult +import dev.usbharu.multim.model.Emoji + +interface EmojiApi { + suspend fun get(name:String):MultiMResult + + suspend fun findByName(name:String):MultiMResult> +} diff --git a/core/src/main/kotlin/dev/usbharu/multim/factory/MultiMApis.kt b/core/src/main/kotlin/dev/usbharu/multim/factory/MultiMApis.kt index f9259c8..169a6f9 100644 --- a/core/src/main/kotlin/dev/usbharu/multim/factory/MultiMApis.kt +++ b/core/src/main/kotlin/dev/usbharu/multim/factory/MultiMApis.kt @@ -1,11 +1,13 @@ package dev.usbharu.multim.factory import dev.usbharu.multim.api.AccountApi +import dev.usbharu.multim.api.EmojiApi import dev.usbharu.multim.api.StatusApi import dev.usbharu.multim.api.TimelineApi abstract class MultiMApis( var statusApi: StatusApi, var accountApi: AccountApi, - var timelineApi: TimelineApi + var timelineApi: TimelineApi, + var emojiApi: EmojiApi ) diff --git a/core/src/main/kotlin/dev/usbharu/multim/multi/MultiAccountApi.kt b/core/src/main/kotlin/dev/usbharu/multim/multi/MultiAccountApi.kt index 3edb676..702eca9 100644 --- a/core/src/main/kotlin/dev/usbharu/multim/multi/MultiAccountApi.kt +++ b/core/src/main/kotlin/dev/usbharu/multim/multi/MultiAccountApi.kt @@ -1,15 +1,17 @@ package dev.usbharu.multim.multi import dev.usbharu.multim.api.AccountApi +import dev.usbharu.multim.api.EmojiApi import dev.usbharu.multim.api.StatusApi import dev.usbharu.multim.api.TimelineApi import dev.usbharu.multim.factory.MultiMApis -class MultiAccountApi(statusApi: StatusApi, accountApi: AccountApi, timelineApi: TimelineApi) : - MultiMApis(statusApi, accountApi, timelineApi) { +class MultiAccountApi(statusApi: StatusApi, accountApi: AccountApi, timelineApi: TimelineApi,emojiApi: EmojiApi) : + MultiMApis(statusApi, accountApi, timelineApi,emojiApi) { constructor(apiBase: MultiAccountApiBase) : this( MultiAccountStatusApi(apiBase), MultiAccountAccountApi(apiBase), - MultiAccountTimelineApi(apiBase) + MultiAccountTimelineApi(apiBase), + MultiAccountEmojiApi(apiBase) ) } diff --git a/core/src/main/kotlin/dev/usbharu/multim/multi/MultiAccountEmojiApi.kt b/core/src/main/kotlin/dev/usbharu/multim/multi/MultiAccountEmojiApi.kt new file mode 100644 index 0000000..17b454b --- /dev/null +++ b/core/src/main/kotlin/dev/usbharu/multim/multi/MultiAccountEmojiApi.kt @@ -0,0 +1,53 @@ +package dev.usbharu.multim.multi + +import com.github.michaelbull.result.Result +import com.github.michaelbull.result.flatMap +import com.github.michaelbull.result.map +import dev.usbharu.multim.api.EmojiApi +import dev.usbharu.multim.error.MultiMError +import dev.usbharu.multim.error.MultiMResult +import dev.usbharu.multim.model.Emoji + +class MultiAccountEmojiApi(val multiAccountApiBase: MultiAccountApiBase) : EmojiApi { + override suspend fun get(name: String): MultiMResult { + return getImpl2(name) { get(it) }.flatMap { it.first } + } + + override suspend fun findByName(name: String): MultiMResult> { + return getImpl2(name) { findByName(it) }.flatMap { it.first } + } + + suspend fun get(name: MultiAccountData): MultiMResult> { + return getImpl(name) { get(it) } + } + + suspend fun findByName(name: MultiAccountData): MultiMResult>> { + return getImpl(name) { findByName(it) } + } + + private suspend fun getImpl( + apiData: MultiAccountData, + callback: suspend EmojiApi.(T) -> Result + ): Result, MultiMError> { + return emojiApi(apiData) + .flatMap { callback(it, apiData.innerData) } + .map { MultiAccountDataImpl(it, apiData.hashCode) } + } + + private suspend fun getImpl2( + apiData: T, + callback: suspend EmojiApi.(T) -> R + ): Result, MultiMError> { + return emojiApi(apiData) + .map { callback(it, apiData) } + .map { + it to ((apiData as? MultiAccountData<*>)?.hashCode + ?: multiAccountApiBase.mainClientHashCode!!) + } + } + + private fun emojiApi(id: T): Result { + return multiAccountApiBase.getImpl((id as? MultiAccountData<*>)?.hashCode) + .map { it.emojiApi } + } +} diff --git a/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/MisskeyV12Info.kt b/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/MisskeyV12Info.kt index c368b77..48d41f3 100644 --- a/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/MisskeyV12Info.kt +++ b/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/MisskeyV12Info.kt @@ -3,10 +3,7 @@ package dev.usbharu.multim.misskey.v12 import dev.usbharu.multim.ServiceInfo import dev.usbharu.multim.misskey.v12.api.MisskeyApis import dev.usbharu.multim.misskey.v12.api.MisskeyMultiMApis -import dev.usbharu.multim.misskey.v12.common.api.MisskeyAccountApi -import dev.usbharu.multim.misskey.v12.common.api.MisskeyApiClient -import dev.usbharu.multim.misskey.v12.common.api.MisskeyStatusApi -import dev.usbharu.multim.misskey.v12.common.api.MisskeyTimelineApi +import dev.usbharu.multim.misskey.v12.common.api.* object MisskeyV12Info : ServiceInfo( Regex("misskey"), @@ -16,7 +13,7 @@ object MisskeyV12Info : ServiceInfo( { apiClient -> MisskeyApis(apiClient as MisskeyApiClient) }, { if (it is MisskeyApis) { - MisskeyMultiMApis(MisskeyStatusApi(it),MisskeyAccountApi(it),MisskeyTimelineApi(it)) + MisskeyMultiMApis(MisskeyStatusApi(it),MisskeyAccountApi(it),MisskeyTimelineApi(it),MisskeyEmojiApi(it)) }else { TODO() } diff --git a/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/api/Meta.kt b/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/api/Meta.kt new file mode 100644 index 0000000..3f14538 --- /dev/null +++ b/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/api/Meta.kt @@ -0,0 +1,14 @@ +package dev.usbharu.multim.misskey.v12.api + +import dev.usbharu.multim.error.MultiMResult +import dev.usbharu.multim.error.mapMultiMError +import dev.usbharu.multim.misskey.v12.common.api.MisskeyApiClient +import dev.usbharu.multim.misskey.v12.model.MetaRequest +import dev.usbharu.multim.misskey.v12.model.MetaResponse + +class Meta(val client: MisskeyApiClient) { + suspend fun meta(metaRequest: MetaRequest): MultiMResult { + return client.post(metaRequest, "api/meta") + .mapMultiMError() + } +} diff --git a/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/api/MisskeyApis.kt b/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/api/MisskeyApis.kt index 0bb8f56..79b5b5e 100644 --- a/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/api/MisskeyApis.kt +++ b/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/api/MisskeyApis.kt @@ -10,4 +10,5 @@ class MisskeyApis(misskeyApiClient: MisskeyApiClient) : PlatformApis(misskeyApiC val timeline = Timeline(misskeyApiClient) val following = Following(misskeyApiClient) val users = Users(misskeyApiClient) + val meta = Meta(misskeyApiClient) } diff --git a/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/api/MisskeyMultiMApis.kt b/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/api/MisskeyMultiMApis.kt index 3691783..44895e7 100644 --- a/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/api/MisskeyMultiMApis.kt +++ b/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/api/MisskeyMultiMApis.kt @@ -1,10 +1,11 @@ package dev.usbharu.multim.misskey.v12.api import dev.usbharu.multim.api.AccountApi +import dev.usbharu.multim.api.EmojiApi import dev.usbharu.multim.api.StatusApi import dev.usbharu.multim.api.TimelineApi import dev.usbharu.multim.factory.MultiMApis -class MisskeyMultiMApis(statusApi: StatusApi, accountApi: AccountApi,timelineApi: TimelineApi) : - MultiMApis(statusApi, accountApi,timelineApi) { +class MisskeyMultiMApis(statusApi: StatusApi, accountApi: AccountApi,timelineApi: TimelineApi,emojiApi: EmojiApi) : + MultiMApis(statusApi, accountApi,timelineApi,emojiApi) { } diff --git a/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/common/MisskeyEmoji.kt b/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/common/MisskeyEmoji.kt new file mode 100644 index 0000000..ca1f3ac --- /dev/null +++ b/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/common/MisskeyEmoji.kt @@ -0,0 +1,6 @@ +package dev.usbharu.multim.misskey.v12.common + +import dev.usbharu.multim.model.Emoji + +class MisskeyEmoji(name: String, url: String) : Emoji(name, url) { +} diff --git a/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/common/api/MisskeyEmojiApi.kt b/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/common/api/MisskeyEmojiApi.kt new file mode 100644 index 0000000..1b216ec --- /dev/null +++ b/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/common/api/MisskeyEmojiApi.kt @@ -0,0 +1,42 @@ +package dev.usbharu.multim.misskey.v12.common.api + +import com.github.michaelbull.result.flatMap +import com.github.michaelbull.result.map +import com.github.michaelbull.result.toResultOr +import dev.usbharu.multim.api.EmojiApi +import dev.usbharu.multim.error.ErrorType +import dev.usbharu.multim.error.MultiMError +import dev.usbharu.multim.error.MultiMResult +import dev.usbharu.multim.misskey.v12.api.MisskeyApis +import dev.usbharu.multim.misskey.v12.common.MisskeyEmoji +import dev.usbharu.multim.misskey.v12.model.MetaRequest +import dev.usbharu.multim.model.Emoji +import dev.usbharu.multim.misskey.v12.model.components.Emoji as MisskeyModelEmoji + +class MisskeyEmojiApi(val misskeyApis: MisskeyApis) : EmojiApi { + override suspend fun get(name: String): MultiMResult { + return misskeyApis.meta.meta(MetaRequest()) + .flatMap { + it.emojis.find { emoji: MisskeyModelEmoji -> emoji.name.equals(name, true) } + .toResultOr { + MultiMError( + "Emoji $name not Found", + null, + ErrorType.ILLEGAL_ARGUMENT + ) + } + }.map { MisskeyEmoji(it.name, it.url) } + + } + + override suspend fun findByName(name: String): MultiMResult> { + return misskeyApis.meta.meta(MetaRequest()) + .map { + it.emojis.filter { emoji: MisskeyModelEmoji -> + emoji.name.startsWith(name, true).or(emoji.name.endsWith(name, true)) + } + }.map { + it.map { MisskeyEmoji(it.name, it.url) } + } + } +} diff --git a/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/model/Meta.kt b/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/model/Meta.kt new file mode 100644 index 0000000..14b6ca9 --- /dev/null +++ b/impl/misskey/src/main/kotlin/dev/usbharu/multim/misskey/v12/model/Meta.kt @@ -0,0 +1,69 @@ +package dev.usbharu.multim.misskey.v12.model + +import dev.usbharu.multim.misskey.v12.model.components.Emoji +import kotlinx.serialization.Serializable + +@Serializable +data class MetaRequest(val detail: Boolean = true) + +@Serializable +data class MetaResponse( + val maintainerName: String? = null, + val maintainerEmail: String? = null, + val version: String, + val name: String? = null, + val uri: String, + val description: String? = null, + val langs: List = listOf(), + val tosUrl: String? = null, + val repositoryUrl: String = "https://github.com/misskey-dev/misskey", + val feedbackUrl: String = "https://github.com/misskey-dev/misskey/issues/new", + val defaultDarkTheme: String? = null, + val defaultLightTheme: String? = null, + val disableRegistration: Boolean, + val disableLocalTimeline: Boolean, + val disableGlobalTimeline: Boolean, + val driveCapacityPerLocalUserMb: Long, //めちゃくちゃでかい値をセットしている人を観測しているのでLong + val cacheRemoteFiles: Boolean, + val emailRequiredForSignup: Boolean, + val enableHcaptcha: Boolean, + val hcaptchaSiteKey: String? = null, + val enableRecaptcha: Boolean, + val recaptchaSiteKey: String? = null, + val swPublickey: String? = null, + val mascotImageUrl: String = "/assets/ai.png", + val bannerUrl: String? = null, + val errorImageUrl: String = "https://xn--p31a.moe/aiart/yubitun.png", + val iconUrl: String? = null, + val maxNoteTextLength: Long, + val emojis: List, + val ads: List = listOf(), + val requireSetup: Boolean, + val enableEmail: Boolean, + val enableTwitterIntegration: Boolean, + val enableGithubIntegration: Boolean, + val enableDiscordIntegration: Boolean, + val enableServiceWorker: Boolean, + val translatorAvailable: Boolean, + val proxyAccountName: String? = null, + val features: Features? = null +) { + @Serializable + data class Ad(val place: String, val url: String, val imageUrl: String) + + @Serializable + data class Features( + val registration: Boolean, + val localTimeLine: Boolean, + val globalTimeLine: Boolean, + val elasticsearch: Boolean, + val hcaptcha: Boolean, + val recaptcha: Boolean, + val objectStorage: Boolean, + val twitter: Boolean, + val github: Boolean, + val discord: Boolean, + val serviceWorker: Boolean, + val miauth: Boolean = true + ) +} diff --git a/impl/misskey/src/test/kotlin/MisskeyTestUtil.kt b/impl/misskey/src/test/kotlin/MisskeyTestUtil.kt index f88171c..9e6b514 100644 --- a/impl/misskey/src/test/kotlin/MisskeyTestUtil.kt +++ b/impl/misskey/src/test/kotlin/MisskeyTestUtil.kt @@ -1,3 +1,7 @@ +import com.github.michaelbull.result.Err +import com.github.michaelbull.result.Ok +import com.github.michaelbull.result.Result +import com.github.michaelbull.result.getError import dev.usbharu.multim.misskey.v12.model.components.Note import dev.usbharu.multim.misskey.v12.model.components.UserLite import io.ktor.client.* @@ -11,6 +15,7 @@ import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import kotlinx.serialization.json.jsonObject import org.assertj.core.api.Fail +import org.junit.jupiter.api.Assertions object MisskeyTestUtil { @@ -74,4 +79,13 @@ object MisskeyTestUtil { fun createFakeNoteToString(id: String, userId: String, username: String, text: String?): String { return json.encodeToString(createFakeNote(id, userId, username, text)) } + + fun assertIsOk(result: Result<*, *>){ + Assertions.assertInstanceOf(Ok::class.java, result, "resultの型がOkではない") + } + + inline fun assertIsErr(result: Result<*, T>){ + Assertions.assertInstanceOf(Err::class.java, result, "resultの型がErrではない") + Assertions.assertInstanceOf(R::class.java, result.getError(), "Errorの型が違う") + } } diff --git a/impl/misskey/src/test/kotlin/dev/usbharu/multim/misskey/v12/api/MetaTest.kt b/impl/misskey/src/test/kotlin/dev/usbharu/multim/misskey/v12/api/MetaTest.kt new file mode 100644 index 0000000..519324b --- /dev/null +++ b/impl/misskey/src/test/kotlin/dev/usbharu/multim/misskey/v12/api/MetaTest.kt @@ -0,0 +1,28 @@ +package dev.usbharu.multim.misskey.v12.api + +import MisskeyTestUtil.assertIsOk +import dev.usbharu.multim.api.createHttpClient +import dev.usbharu.multim.misskey.v12.common.api.MisskeyApiClient +import dev.usbharu.multim.misskey.v12.model.MetaRequest +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runTest +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test + +class MetaTest + +@OptIn(ExperimentalCoroutinesApi::class) +class MetaTestE2E{ + + val misskeyApiClient = MisskeyApiClient( + System.getProperty("multim_misskey_token"),System.getProperty("multim_misskey_instance"), + createHttpClient() + ) + + @Test + fun meta() = runTest { + val meta = Meta(misskeyApiClient).meta(MetaRequest()) + println(meta) + assertIsOk(meta) + } +}