From dd8534f0f49f99674f0afa3746e059891f639cb7 Mon Sep 17 00:00:00 2001 From: tateisu Date: Mon, 8 Oct 2018 02:57:19 +0900 Subject: [PATCH] =?UTF-8?q?=E5=88=A5=E3=82=A2=E3=82=AB=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=83=9C=E3=80=81=E3=83=96=E3=83=BC=E3=82=B9=E3=83=88=E3=81=A7?= =?UTF-8?q?Misskey=20=E3=82=A2=E3=82=AB=E3=82=A6=E3=83=B3=E3=83=88?= =?UTF-8?q?=E3=82=92=E9=81=B8=E3=81=B9=E3=82=8B(=20https://misskey.m544.ne?= =?UTF-8?q?t/=20=E3=81=A7=E5=8B=95=E4=BD=9C=E7=A2=BA=E8=AA=8D=E6=B8=88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/jp/juggler/subwaytooter/Column.kt | 2 +- .../jp/juggler/subwaytooter/DlgContextMenu.kt | 2 +- .../juggler/subwaytooter/api/TootApiClient.kt | 133 +++++++++++------- .../jp/juggler/subwaytooter/util/Utils.kt | 5 +- 4 files changed, 84 insertions(+), 58 deletions(-) diff --git a/app/src/main/java/jp/juggler/subwaytooter/Column.kt b/app/src/main/java/jp/juggler/subwaytooter/Column.kt index 5f42e704..9ecac79b 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/Column.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/Column.kt @@ -2890,7 +2890,7 @@ class Column( task.executeOnExecutor(App1.task_executor) } - var bMinIdMatched : Boolean = false + private var bMinIdMatched : Boolean = false private fun parseRange( result : TootApiResult?, diff --git a/app/src/main/java/jp/juggler/subwaytooter/DlgContextMenu.kt b/app/src/main/java/jp/juggler/subwaytooter/DlgContextMenu.kt index 6130456e..3240782e 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/DlgContextMenu.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/DlgContextMenu.kt @@ -205,8 +205,8 @@ internal class DlgContextMenu( val canPin = status.canPin(access_info) btnProfileUnpin.visibility = if(canPin && status.pinned) View.VISIBLE else View.GONE btnProfilePin.visibility = if(canPin && ! status.pinned) View.VISIBLE else View.GONE - } + var bShowConversationMute = false if(status != null) { if(access_info.isMe(status.account)) { diff --git a/app/src/main/java/jp/juggler/subwaytooter/api/TootApiClient.kt b/app/src/main/java/jp/juggler/subwaytooter/api/TootApiClient.kt index c6d27cc2..936d39d4 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/api/TootApiClient.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/api/TootApiClient.kt @@ -2,20 +2,17 @@ package jp.juggler.subwaytooter.api import android.content.Context import android.content.SharedPreferences -import android.net.Uri import jp.juggler.subwaytooter.* import jp.juggler.subwaytooter.api.entity.TootAccount - -import org.json.JSONException -import org.json.JSONObject - -import jp.juggler.subwaytooter.table.ClientInfo -import jp.juggler.subwaytooter.table.SavedAccount import jp.juggler.subwaytooter.api.entity.TootInstance import jp.juggler.subwaytooter.api.entity.TootStatus +import jp.juggler.subwaytooter.table.ClientInfo +import jp.juggler.subwaytooter.table.SavedAccount import jp.juggler.subwaytooter.util.* import okhttp3.* import org.json.JSONArray +import org.json.JSONException +import org.json.JSONObject import java.util.* import java.util.regex.Pattern @@ -1346,16 +1343,32 @@ class TootApiClient( } -fun TootApiClient.syncAccountByUrl(accessInfo : SavedAccount, who_url : String) : TootApiResult? { +private fun parseMisskeyApShow(parser : TootParser, jsonObject : JSONObject?) : Any? { + return when(jsonObject?.parseString("type")) { + "Note" -> { + parser.status(jsonObject.optJSONObject("object")) + } + + "User" -> { + parser.status(jsonObject.optJSONObject("object")) + } + + else -> { + null + } + } +} +fun TootApiClient.syncAccountByUrl(accessInfo : SavedAccount, who_url : String) : TootApiResult? { + // misskey由来のアカウントURLは https://host/@user@instance などがある val m = TootAccount.reAccountUrl.matcher(who_url) - if( m.find() ){ + if(m.find()) { // val host = m.group(1) val user = m.group(2).unescapeUri() val instance = m.groupOrNull(3)?.unescapeUri() - if( instance?.isNotEmpty()==true){ - return this.syncAccountByUrl( accessInfo,"https://$instance/@$user") + if(instance?.isNotEmpty() == true) { + return this.syncAccountByUrl(accessInfo, "https://$instance/@$user") } } @@ -1447,61 +1460,75 @@ fun TootApiClient.syncAccountByAcct(accessInfo : SavedAccount, acct : String) : } } -fun TootApiClient.syncStatus(accessInfo : SavedAccount, url : String) : TootApiResult? { - - // FIXME Misskeyアカウントでも別アカのトゥートをローカルに同期したい! +fun TootApiClient.syncStatus(accessInfo : SavedAccount, url : String) = if(accessInfo.isMisskey) { - return TootApiResult("Misskey has no API to sync note from remote to local.") - } - - val path = String.format( - Locale.JAPAN, - Column.PATH_SEARCH, - url.encodePercent() - ) + "&resolve=1" - - val result = request(path) - if(result != null) { - val tmp = TootParser(context, accessInfo).results(result.jsonObject) - if(tmp != null && tmp.statuses.isNotEmpty()) { - result.data = tmp.statuses[0] + val params = accessInfo.putMisskeyApiToken().put("uri", url) + val result = request("/api/ap/show", params.toPostRequestBuilder()) + if(result != null) { + val obj = parseMisskeyApShow(TootParser(context, accessInfo), result.jsonObject) + if(obj != null) result.data = obj } + result + } else { + val path = String.format( + Locale.JAPAN, + Column.PATH_SEARCH, + url.encodePercent() + ) + "&resolve=1" + + val result = request(path) + if(result != null) { + val tmp = TootParser(context, accessInfo).results(result.jsonObject) + if(tmp != null && tmp.statuses.isNotEmpty()) { + result.data = tmp.statuses[0] + } + } + result + } + +private inline fun String?.useNotEmpty( block:(String)->Z? ) :Z? = + if(this?.isNotEmpty() == true) { + block(this) + }else{ + null } - return result -} fun TootApiClient.syncStatus( accessInfo : SavedAccount, statusRemote : TootStatus ) : TootApiResult? { - // FIXME Misskeyアカウントでも別アカのトゥートをローカルに同期したい! - if(accessInfo.isMisskey) { - return TootApiResult("Misskey has no API to sync note from remote to local.") - } + // URL->URIの順に試す - var result : TootApiResult? = TootApiResult("missing url or uri") - var sv = statusRemote.url - when { - sv?.isEmpty() != false -> { - } - - sv.contains("/notes/") -> { + val uriList = ArrayList(2) + + statusRemote.url.useNotEmpty { + if( it.contains("/notes/") ){ // Misskeyタンスから読んだマストドンの投稿はurlがmisskeyタンス上のものになる - // uri で試す + // ActivityPub object id としては不適切なので使わない + }else { + uriList.add(it) } - - else -> { - result = syncStatus(accessInfo, sv) - if(result == null || result.data is TootStatus) { - return result - } + } + + statusRemote.uri.useNotEmpty { + // uri の方は↑の問題はない + uriList.add(it) + } + + if( accessInfo.isMisskey && uriList.size >1 && uriList[0].contains("@") ){ + // https://github.com/syuilo/misskey/pull/2832 + // @user を含むuri はMisskeyだと少し効率が悪いそうなので順序を入れ替える + uriList.reverse() + } + + for( uri in uriList){ + val result = syncStatus(accessInfo, uri) + if(result == null || result.data is TootStatus) { + return result } } - sv = statusRemote.uri - if(sv?.isNotEmpty() == true) { - result = syncStatus(accessInfo, sv) - } - return result + return TootApiResult("can't resolve status URL/URI.") + } \ No newline at end of file diff --git a/app/src/main/java/jp/juggler/subwaytooter/util/Utils.kt b/app/src/main/java/jp/juggler/subwaytooter/util/Utils.kt index c1c5faaf..b204347a 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/util/Utils.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/util/Utils.kt @@ -342,9 +342,8 @@ private fun ByteArray.encodeHex() : String { return sb.toString() } -fun ByteArray.encodeBase64Url() : String { - return Base64.encodeToString(this, Base64.URL_SAFE or Base64.NO_PADDING or Base64.NO_WRAP) -} +fun ByteArray.encodeBase64Url() : String = + Base64.encodeToString(this, Base64.URL_SAFE or Base64.NO_PADDING or Base64.NO_WRAP) fun ByteArray.digestSHA256() : ByteArray { val digest = MessageDigest.getInstance("SHA-256")