misskeyのカラムに出たリモートの投稿のuriを解釈する
This commit is contained in:
parent
8be857c8f1
commit
4f29ec0676
|
@ -1138,20 +1138,10 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
|||
|
||||
var target_status : TootStatus? = null
|
||||
override fun background(client : TootApiClient) : TootApiResult? {
|
||||
// 検索APIに他タンスのステータスのURLを投げると、自タンスのステータスを得られる
|
||||
val path = String.format(
|
||||
Locale.JAPAN,
|
||||
Column.PATH_SEARCH,
|
||||
in_reply_to_url.encodePercent()
|
||||
) + "&resolve=1"
|
||||
|
||||
val result = client.request(path)
|
||||
val jsonObject = result?.jsonObject
|
||||
if(jsonObject != null) {
|
||||
val tmp = TootParser(this@ActPost, access_info).results(jsonObject)
|
||||
if(tmp?.statuses?.isNotEmpty() == true) {
|
||||
target_status = tmp.statuses[0]
|
||||
}
|
||||
val result = client.syncStatus(access_info,in_reply_to_url)
|
||||
if( result?.data != null ) {
|
||||
target_status = result.data as? TootStatus
|
||||
if(target_status == null) {
|
||||
return TootApiResult(getString(R.string.status_id_conversion_failed))
|
||||
}
|
||||
|
|
|
@ -1,31 +1,26 @@
|
|||
package jp.juggler.subwaytooter.action
|
||||
|
||||
import android.net.Uri
|
||||
|
||||
import java.util.ArrayList
|
||||
import java.util.Locale
|
||||
import java.util.regex.Pattern
|
||||
|
||||
import jp.juggler.subwaytooter.ActMain
|
||||
import jp.juggler.subwaytooter.ActPost
|
||||
import jp.juggler.subwaytooter.App1
|
||||
import jp.juggler.subwaytooter.Column
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.api.TootApiClient
|
||||
import jp.juggler.subwaytooter.api.TootApiResult
|
||||
import jp.juggler.subwaytooter.api.TootTask
|
||||
import jp.juggler.subwaytooter.api.TootTaskRunner
|
||||
import jp.juggler.subwaytooter.api.TootParser
|
||||
import jp.juggler.subwaytooter.api.entity.*
|
||||
import jp.juggler.subwaytooter.*
|
||||
import jp.juggler.subwaytooter.api.*
|
||||
import jp.juggler.subwaytooter.api.entity.EntityId
|
||||
import jp.juggler.subwaytooter.api.entity.EntityIdLong
|
||||
import jp.juggler.subwaytooter.api.entity.TootStatus
|
||||
import jp.juggler.subwaytooter.api.entity.TootVisibility
|
||||
import jp.juggler.subwaytooter.dialog.AccountPicker
|
||||
import jp.juggler.subwaytooter.dialog.ActionsDialog
|
||||
import jp.juggler.subwaytooter.dialog.DlgConfirm
|
||||
import jp.juggler.subwaytooter.table.AcctColor
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import jp.juggler.subwaytooter.util.*
|
||||
import jp.juggler.subwaytooter.util.EmptyCallback
|
||||
import jp.juggler.subwaytooter.util.LogCategory
|
||||
import jp.juggler.subwaytooter.util.showToast
|
||||
import jp.juggler.subwaytooter.util.toPostRequestBuilder
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
import java.util.regex.Pattern
|
||||
|
||||
object Action_Toot {
|
||||
|
||||
|
@ -130,38 +125,17 @@ object Action_Toot {
|
|||
|
||||
var result : TootApiResult?
|
||||
|
||||
var target_status : TootStatus?
|
||||
val target_status : TootStatus
|
||||
if(nCrossAccountMode == CROSS_ACCOUNT_REMOTE_INSTANCE) {
|
||||
|
||||
if(access_info.isMisskey) {
|
||||
return TootApiResult("Misskey has no API to sync note from remote to local.")
|
||||
}
|
||||
|
||||
// 検索APIに他タンスのステータスのURLを投げると、自タンスのステータスを得られる
|
||||
val status_url = arg_status.url
|
||||
if(status_url?.isEmpty() != false) return TootApiResult("missing status URL")
|
||||
val path = String.format(
|
||||
Locale.JAPAN,
|
||||
Column.PATH_SEARCH,
|
||||
status_url.encodePercent()
|
||||
) + "&resolve=1"
|
||||
|
||||
result = client.request(path)
|
||||
val jsonObject = result?.jsonObject ?: return result
|
||||
|
||||
target_status = null
|
||||
val tmp = TootParser(activity, access_info).results(jsonObject)
|
||||
if(tmp != null) {
|
||||
if(tmp.statuses.isNotEmpty()) {
|
||||
target_status = tmp.statuses[0]
|
||||
log.d("status id conversion %s => %s", arg_status.id, target_status.id)
|
||||
}
|
||||
}
|
||||
if(target_status == null) {
|
||||
return TootApiResult(activity.getString(R.string.status_id_conversion_failed))
|
||||
} else if(target_status.favourited) {
|
||||
result = client.syncStatus( access_info,arg_status)
|
||||
if( result?.data == null) return result
|
||||
target_status = result.data as? TootStatus
|
||||
?: return TootApiResult(activity.getString(R.string.status_id_conversion_failed))
|
||||
if(target_status.favourited) {
|
||||
return TootApiResult(activity.getString(R.string.already_favourited))
|
||||
}
|
||||
|
||||
} else {
|
||||
target_status = arg_status
|
||||
}
|
||||
|
@ -400,34 +374,14 @@ object Action_Toot {
|
|||
|
||||
var result : TootApiResult?
|
||||
|
||||
var target_status : TootStatus?
|
||||
val target_status : TootStatus
|
||||
if(nCrossAccountMode == CROSS_ACCOUNT_REMOTE_INSTANCE) {
|
||||
|
||||
if(access_info.isMisskey) {
|
||||
// XXX Misskey対応はトゥートの同期方法が分からないので保留
|
||||
return TootApiResult("Misskey has no API to sync the note from remote to local.")
|
||||
}
|
||||
|
||||
val status_url = arg_status.url
|
||||
if(status_url?.isEmpty() != false) return TootApiResult("missing status URL")
|
||||
// 検索APIに他タンスのステータスのURLを投げると、自タンスのステータスを得られる
|
||||
val path = String.format(
|
||||
Locale.JAPAN,
|
||||
Column.PATH_SEARCH,
|
||||
status_url.encodePercent()
|
||||
) + "&resolve=1"
|
||||
|
||||
result = client.request(path)
|
||||
val jsonObject = result?.jsonObject ?: return result
|
||||
|
||||
target_status = null
|
||||
val tmp = parser.results(jsonObject)
|
||||
if(tmp?.statuses?.isNotEmpty() == true) {
|
||||
target_status = tmp.statuses[0]
|
||||
}
|
||||
if(target_status == null) {
|
||||
return TootApiResult(activity.getString(R.string.status_id_conversion_failed))
|
||||
} else if(target_status.reblogged) {
|
||||
result = client.syncStatus(access_info,arg_status)
|
||||
if( result?.data == null) return result
|
||||
target_status = result.data as? TootStatus
|
||||
?: return TootApiResult(activity.getString(R.string.status_id_conversion_failed))
|
||||
if(target_status.reblogged) {
|
||||
return TootApiResult(activity.getString(R.string.already_boosted))
|
||||
}
|
||||
} else {
|
||||
|
@ -799,27 +753,13 @@ object Action_Toot {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
// 検索APIに他タンスのステータスのURLを投げると、自タンスのステータスを得られる
|
||||
val path = String.format(
|
||||
Locale.JAPAN,
|
||||
Column.PATH_SEARCH,
|
||||
remote_status_url.encodePercent()
|
||||
) + "&resolve=1"
|
||||
result = client.request(path)
|
||||
val jsonObject = result?.jsonObject
|
||||
if(jsonObject != null) {
|
||||
val tmp = TootParser(activity, access_info).results(jsonObject)
|
||||
if(tmp?.statuses?.isNotEmpty() == true) {
|
||||
val status = tmp.statuses[0]
|
||||
result = client.syncStatus(access_info,remote_status_url)
|
||||
if( result?.data == null ) return result
|
||||
val status = result.data as? TootStatus
|
||||
?: return TootApiResult(activity.getString(R.string.status_id_conversion_failed))
|
||||
local_status_id = status.id
|
||||
log.d("status id conversion %s => %s", remote_status_url, status.id)
|
||||
}
|
||||
if(local_status_id == null) {
|
||||
result =
|
||||
TootApiResult(activity.getString(R.string.status_id_conversion_failed))
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
@ -949,25 +889,10 @@ object Action_Toot {
|
|||
|
||||
var local_status : TootStatus? = null
|
||||
override fun background(client : TootApiClient) : TootApiResult? {
|
||||
// 検索APIに他タンスのステータスのURLを投げると、自タンスのステータスを得られる
|
||||
val path = String.format(
|
||||
Locale.JAPAN,
|
||||
Column.PATH_SEARCH,
|
||||
remote_status_url.encodePercent()
|
||||
) + "&resolve=1"
|
||||
|
||||
val result = client.request(path)
|
||||
val jsonObject = result?.jsonObject
|
||||
if(jsonObject != null) {
|
||||
val tmp = TootParser(activity, access_info).results(jsonObject)
|
||||
if(tmp?.statuses?.isNotEmpty() == true) {
|
||||
val ls = tmp.statuses[0]
|
||||
local_status = ls
|
||||
log.d("status id conversion %s => %s", remote_status_url, ls.id)
|
||||
}
|
||||
local_status
|
||||
val result = client.syncStatus(access_info,remote_status_url)
|
||||
if( result?.data == null) return result
|
||||
local_status = result.data as? TootStatus
|
||||
?: return TootApiResult(activity.getString(R.string.status_id_conversion_failed))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ 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.util.*
|
||||
import okhttp3.*
|
||||
import org.json.JSONArray
|
||||
|
@ -68,15 +69,15 @@ class TootApiClient(
|
|||
const val KEY_MISSKEY_APP_SECRET = "secret"
|
||||
const val KEY_API_KEY_MISSKEY = "apiKeyMisskey"
|
||||
|
||||
// // APIからsecretを得られないバグがあるので定数を渡す
|
||||
// const val appSecretError =
|
||||
// "This Misskey instance Currently Misskey does not allow client registration from API, please tell me notify instance name that you want login via Subway Tooter."
|
||||
// val testAppSecretMap = mapOf(
|
||||
// Pair("misskey.xyz", "NGiWNZFP37WiAee3SGcVe8eSiDyLbbWf")
|
||||
// , Pair("misskey.jp", "GO45N7JgeEWtlNUS4xRcOFY56JMjUTZk")
|
||||
// , Pair("msky.cafe", "lvU12i7CXAB5xiqkABwzyJRzdAqhf0k3")
|
||||
// , Pair("misskey.m544.net", "SLcaqff0Puymh4Fl30JCc09i6uumwJ4t")
|
||||
// )
|
||||
// // APIからsecretを得られないバグがあるので定数を渡す
|
||||
// const val appSecretError =
|
||||
// "This Misskey instance Currently Misskey does not allow client registration from API, please tell me notify instance name that you want login via Subway Tooter."
|
||||
// val testAppSecretMap = mapOf(
|
||||
// Pair("misskey.xyz", "NGiWNZFP37WiAee3SGcVe8eSiDyLbbWf")
|
||||
// , Pair("misskey.jp", "GO45N7JgeEWtlNUS4xRcOFY56JMjUTZk")
|
||||
// , Pair("msky.cafe", "lvU12i7CXAB5xiqkABwzyJRzdAqhf0k3")
|
||||
// , Pair("misskey.m544.net", "SLcaqff0Puymh4Fl30JCc09i6uumwJ4t")
|
||||
// )
|
||||
|
||||
private const val NO_INFORMATION = "(no information)"
|
||||
|
||||
|
@ -222,6 +223,7 @@ class TootApiClient(
|
|||
put("notification-write")
|
||||
|
||||
put("favorite-read")
|
||||
put("favorites-read")
|
||||
put("favorite-write")
|
||||
|
||||
put("account/read")
|
||||
|
@ -317,7 +319,7 @@ class TootApiClient(
|
|||
if(isApiCancelled) return null
|
||||
|
||||
// Misskey の /api/notes/favorites/create は 204(no content)を返す。ボディはカラになる。
|
||||
if( bodyString?.isEmpty() != false && response.code() in 200 until 300 ){
|
||||
if(bodyString?.isEmpty() != false && response.code() in 200 until 300) {
|
||||
result.bodyString = ""
|
||||
return ""
|
||||
}
|
||||
|
@ -441,7 +443,7 @@ class TootApiClient(
|
|||
var bodyString = readBodyString(result, progressPath, jsonErrorParser)
|
||||
?: return if(isApiCancelled) null else result
|
||||
|
||||
if( bodyString.isEmpty() ){
|
||||
if(bodyString.isEmpty()) {
|
||||
|
||||
// 204 no content は 空オブジェクトと解釈する
|
||||
result.data = JSONObject()
|
||||
|
@ -457,15 +459,14 @@ class TootApiClient(
|
|||
} else {
|
||||
result.data = json
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
// HTMLならタグを除去する
|
||||
val ct = response.body()?.contentType()
|
||||
if(ct?.subtype() == "html") {
|
||||
val decoded = DecodeOptions().decodeHTML(bodyString).toString()
|
||||
bodyString =decoded
|
||||
bodyString = decoded
|
||||
}
|
||||
|
||||
|
||||
val sb = StringBuilder()
|
||||
.append(context.getString(R.string.response_not_json))
|
||||
.append(' ')
|
||||
|
@ -481,7 +482,7 @@ class TootApiClient(
|
|||
sb.append(")")
|
||||
|
||||
val url = response.request()?.url()?.toString()
|
||||
if(url?.isNotEmpty()==true) {
|
||||
if(url?.isNotEmpty() == true) {
|
||||
sb.append(' ').append(url)
|
||||
}
|
||||
|
||||
|
@ -590,7 +591,7 @@ class TootApiClient(
|
|||
return result
|
||||
}
|
||||
|
||||
private fun prepareBrowserUrlMisskey( appSecret:String) : String? {
|
||||
private fun prepareBrowserUrlMisskey(appSecret : String) : String? {
|
||||
|
||||
val result = TootApiResult.makeWithCaption(instance)
|
||||
|
||||
|
@ -709,8 +710,8 @@ class TootApiClient(
|
|||
val jsonObject = r2?.jsonObject ?: return r2
|
||||
|
||||
val appSecret = jsonObject.parseString(KEY_MISSKEY_APP_SECRET)
|
||||
if( appSecret?.isEmpty() != false) {
|
||||
showToast(context,true,context.getString(R.string.cant_get_misskey_app_secret))
|
||||
if(appSecret?.isEmpty() != false) {
|
||||
showToast(context, true, context.getString(R.string.cant_get_misskey_app_secret))
|
||||
return null
|
||||
}
|
||||
// {
|
||||
|
@ -758,7 +759,7 @@ class TootApiClient(
|
|||
?: return result.setError("missing client id")
|
||||
|
||||
val appSecret = client_info.parseString(KEY_MISSKEY_APP_SECRET)
|
||||
if( appSecret?.isEmpty() != false) {
|
||||
if(appSecret?.isEmpty() != false) {
|
||||
return result.setError(context.getString(R.string.cant_get_misskey_app_secret))
|
||||
}
|
||||
|
||||
|
@ -821,7 +822,6 @@ class TootApiClient(
|
|||
return result
|
||||
}
|
||||
|
||||
|
||||
// クライアントをタンスに登録
|
||||
fun registerClient(scope_string : String, clientName : String) : TootApiResult? {
|
||||
val result = TootApiResult.makeWithCaption(this.instance)
|
||||
|
@ -1330,35 +1330,36 @@ class TootApiClient(
|
|||
return result
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun TootApiClient.syncAccountByUrl(accessInfo:SavedAccount,who_url:String):TootApiResult?{
|
||||
if( accessInfo.isMisskey){
|
||||
fun TootApiClient.syncAccountByUrl(accessInfo : SavedAccount, who_url : String) : TootApiResult? {
|
||||
if(accessInfo.isMisskey) {
|
||||
val acct = TootAccount.getAcctFromUrl(who_url)
|
||||
?: return TootApiResult(context.getString(R.string.user_id_conversion_failed))
|
||||
|
||||
val delm = acct.indexOf('@')
|
||||
val params = accessInfo.putMisskeyApiToken(JSONObject())
|
||||
if(delm!=-1){
|
||||
params.put("username",acct.substring(0,delm))
|
||||
params.put("host",acct.substring(delm+1))
|
||||
}else{
|
||||
params.put("username",acct)
|
||||
if(delm != - 1) {
|
||||
params.put("username", acct.substring(0, delm))
|
||||
params.put("host", acct.substring(delm + 1))
|
||||
} else {
|
||||
params.put("username", acct)
|
||||
}
|
||||
|
||||
val result = this.request("/api/users/show",params.toPostRequestBuilder())
|
||||
val result = this.request("/api/users/show", params.toPostRequestBuilder())
|
||||
val jsonObject = result?.jsonObject
|
||||
|
||||
if(jsonObject != null) {
|
||||
val tmp = TootParser(this.context,accessInfo).account(jsonObject)
|
||||
if(tmp != null){
|
||||
val tmp = TootParser(this.context, accessInfo).account(jsonObject)
|
||||
if(tmp != null) {
|
||||
result.data = tmp
|
||||
} else {
|
||||
result.setError(context.getString(R.string.user_id_conversion_failed))
|
||||
}
|
||||
}
|
||||
return result
|
||||
}else{
|
||||
} else {
|
||||
val path = String.format(
|
||||
Locale.JAPAN,
|
||||
Column.PATH_SEARCH,
|
||||
|
@ -1367,7 +1368,7 @@ fun TootApiClient.syncAccountByUrl(accessInfo:SavedAccount,who_url:String):TootA
|
|||
val result = this.request(path)
|
||||
val jsonObject = result?.jsonObject
|
||||
if(jsonObject != null) {
|
||||
val tmp = TootParser(this.context,accessInfo).results(jsonObject)
|
||||
val tmp = TootParser(this.context, accessInfo).results(jsonObject)
|
||||
if(tmp != null && tmp.accounts.isNotEmpty()) {
|
||||
result.data = tmp.accounts[0].get()
|
||||
} else {
|
||||
|
@ -1378,30 +1379,30 @@ fun TootApiClient.syncAccountByUrl(accessInfo:SavedAccount,who_url:String):TootA
|
|||
}
|
||||
}
|
||||
|
||||
fun TootApiClient.syncAccountByAcct(accessInfo:SavedAccount,acct:String):TootApiResult?{
|
||||
if( accessInfo.isMisskey){
|
||||
fun TootApiClient.syncAccountByAcct(accessInfo : SavedAccount, acct : String) : TootApiResult? {
|
||||
if(accessInfo.isMisskey) {
|
||||
val delm = acct.indexOf('@')
|
||||
val params = accessInfo.putMisskeyApiToken(JSONObject())
|
||||
if(delm!=-1){
|
||||
params.put("username",acct.substring(0,delm))
|
||||
params.put("host",acct.substring(delm+1))
|
||||
}else{
|
||||
params.put("username",acct)
|
||||
if(delm != - 1) {
|
||||
params.put("username", acct.substring(0, delm))
|
||||
params.put("host", acct.substring(delm + 1))
|
||||
} else {
|
||||
params.put("username", acct)
|
||||
}
|
||||
|
||||
val result = this.request("/api/users/show",params.toPostRequestBuilder())
|
||||
val result = this.request("/api/users/show", params.toPostRequestBuilder())
|
||||
val jsonObject = result?.jsonObject
|
||||
|
||||
if(jsonObject != null) {
|
||||
val tmp = TootParser(this.context,accessInfo).account(jsonObject)
|
||||
if(tmp != null){
|
||||
val tmp = TootParser(this.context, accessInfo).account(jsonObject)
|
||||
if(tmp != null) {
|
||||
result.data = tmp
|
||||
} else {
|
||||
result.setError(context.getString(R.string.user_id_conversion_failed))
|
||||
}
|
||||
}
|
||||
return result
|
||||
}else{
|
||||
} else {
|
||||
val path = String.format(
|
||||
Locale.JAPAN,
|
||||
Column.PATH_SEARCH,
|
||||
|
@ -1410,7 +1411,7 @@ fun TootApiClient.syncAccountByAcct(accessInfo:SavedAccount,acct:String):TootApi
|
|||
val result = this.request(path)
|
||||
val jsonObject = result?.jsonObject
|
||||
if(jsonObject != null) {
|
||||
val tmp = TootParser(this.context,accessInfo).results(jsonObject)
|
||||
val tmp = TootParser(this.context, accessInfo).results(jsonObject)
|
||||
if(tmp != null && tmp.accounts.isNotEmpty()) {
|
||||
result.data = tmp.accounts[0].get()
|
||||
} else {
|
||||
|
@ -1420,3 +1421,57 @@ fun TootApiClient.syncAccountByAcct(accessInfo:SavedAccount,acct:String):TootApi
|
|||
return result
|
||||
}
|
||||
}
|
||||
|
||||
fun TootApiClient.syncStatus(accessInfo : SavedAccount, url : String) : TootApiResult? {
|
||||
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]
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun TootApiClient.syncStatus(
|
||||
accessInfo : SavedAccount,
|
||||
statusRemote : TootStatus
|
||||
) : TootApiResult? {
|
||||
if(accessInfo.isMisskey) {
|
||||
return TootApiResult("Misskey has no API to sync note from remote to local.")
|
||||
}
|
||||
var result : TootApiResult? = TootApiResult("missing url or uri")
|
||||
var sv = statusRemote.url
|
||||
when {
|
||||
sv?.isEmpty() != false -> {
|
||||
}
|
||||
|
||||
sv.contains("/notes/") -> {
|
||||
// Misskeyタンスから読んだマストドンの投稿はurlがmisskeyタンス上のものになる
|
||||
// uri で試す
|
||||
}
|
||||
|
||||
else -> {
|
||||
result = syncStatus(accessInfo, sv)
|
||||
if(result == null || result.data is TootStatus) {
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sv = statusRemote.uri
|
||||
if(sv?.isNotEmpty() == true) {
|
||||
result = syncStatus(accessInfo, sv)
|
||||
}
|
||||
return result
|
||||
}
|
|
@ -180,8 +180,15 @@ class TootStatus(parser : TootParser, src : JSONObject) : TimelineItem() {
|
|||
val misskeyId = src.parseString("id")
|
||||
this.host_access = parser.linkHelper.host
|
||||
|
||||
val uri = src.parseString("uri")
|
||||
if( uri != null ){
|
||||
this.uri = uri
|
||||
this.url = uri
|
||||
}else {
|
||||
this.uri = "https://$instance/notes/$misskeyId"
|
||||
this.url = "https://$instance/notes/$misskeyId"
|
||||
}
|
||||
|
||||
this.created_at = src.parseString("createdAt")
|
||||
this.time_created_at = parseTime(this.created_at)
|
||||
this.id = EntityIdString(src.parseString("id") ?: error("missing id"))
|
||||
|
|
Loading…
Reference in New Issue