package jp.juggler.subwaytooter.util import jp.juggler.subwaytooter.api.entity.Acct import jp.juggler.subwaytooter.api.entity.Host import jp.juggler.subwaytooter.api.entity.HostAndDomain import jp.juggler.subwaytooter.api.entity.TootAccount import jp.juggler.util.findOrNull import jp.juggler.util.groupEx interface LinkHelper : HostAndDomain { // SavedAccountのロード時にhostを供給する必要があった override val apiHost: Host // fun findAcct(url : String?) : String? = null // fun colorFromAcct(acct : String?) : AcctColor? = null override val apDomain: Host val misskeyVersion: Int get() = 0 val isMisskey: Boolean get() = misskeyVersion > 0 // FIXME もし将来別のサービスにも対応するなら、ここは書き直す必要がある val isMastodon: Boolean get() = misskeyVersion <= 0 // user とか user@host とかを user@host に変換する // nullや空文字列なら ?@? を返す fun getFullAcct(src: Acct?): Acct = when { src?.username?.isEmpty() != false -> Acct.UNKNOWN src.host?.isValid == true -> src else -> src.followHost(apDomain.valid() ?: apiHost.valid() ?: Host.UNKNOWN) } companion object { val unknown = object : LinkHelper { override val apiHost: Host = Host.UNKNOWN override val apDomain: Host = Host.UNKNOWN } fun create(apiHostArg: Host, apDomainArg: Host? = null, misskeyVersion: Int = 0) = object : LinkHelper { override val apiHost: Host = apiHostArg // fun findAcct(url : String?) : String? = null // fun colorFromAcct(acct : String?) : AcctColor? = null override val apDomain: Host = apDomainArg ?: apiHostArg override val misskeyVersion: Int get() = misskeyVersion } } } fun LinkHelper.matchHost(src: String?) = apiHost.match(src) || apDomain.match(src) fun LinkHelper.matchHost(src: Host?) = apiHost == src || apDomain == src fun LinkHelper.matchHost(src: LinkHelper) = apiHost == src.apiHost || apDomain == src.apDomain || apDomain == src.apiHost || apiHost == src.apDomain fun LinkHelper.matchHost(src: TootAccount) = apiHost == src.apiHost || apDomain == src.apDomain || apDomain == src.apiHost || apiHost == src.apDomain // user や user@host から user@host を返す fun getFullAcctOrNull( rawAcct: Acct, url: String, hostDomain1: HostAndDomain? = null, hostDomain2: HostAndDomain? = null ) = if (rawAcct.isValidFull) { // 最初から有効なfull acctがあればそれを使う rawAcct } else { // URL中のホスト名を使うが、引数でホストとドメインの対応が提供されていればドメインへの変換を試みる val host = TootAccount.reHostInUrl.matcher(url) .findOrNull()?.groupEx(1)?.let { Host.parse(it) } if (host == null) { null } else { Acct.parse( rawAcct.username, when (host) { hostDomain1?.apiHost -> hostDomain1.apDomain hostDomain2?.apiHost -> hostDomain2.apDomain else -> host } ).validFull() // apDomainが ? だった場合など } }