Skip to content

Commit 518927e

Browse files
committed
Add resumable upload support
1 parent 3719973 commit 518927e

File tree

2 files changed

+38
-16
lines changed

2 files changed

+38
-16
lines changed

templates/kotlin/src/main/kotlin/io/appwrite/Client.kt.twig

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ class Client @JvmOverloads constructor(
184184
headers: Map<String, String> = mapOf(),
185185
params: Map<String, Any?> = mapOf(),
186186
responseType: Class<T>,
187-
convert: ((Map<String, Any,>) -> T)? = null
187+
converter: ((Map<String, Any,>) -> T)? = null
188188
): T {
189189
val filteredParams = params.filterValues { it != null }
190190

@@ -220,7 +220,7 @@ class Client @JvmOverloads constructor(
220220
.get()
221221
.build()
222222

223-
return awaitResponse(request, responseType, convert)
223+
return awaitResponse(request, responseType, converter)
224224
}
225225

226226
val body = if (MultipartBody.FORM.toString() == headers["content-type"]) {
@@ -257,7 +257,7 @@ class Client @JvmOverloads constructor(
257257
.method(method, body)
258258
.build()
259259

260-
return awaitResponse(request, responseType, convert)
260+
return awaitResponse(request, responseType, converter)
261261
}
262262

263263
/**
@@ -275,8 +275,9 @@ class Client @JvmOverloads constructor(
275275
headers: MutableMap<String, String>,
276276
params: MutableMap<String, Any?>,
277277
responseType: Class<T>,
278-
convert: ((Map<String, Any,>) -> T),
278+
converter: ((Map<String, Any,>) -> T),
279279
paramName: String,
280+
idParamName: String? = null,
280281
onProgress: ((UploadProgress) -> Unit)? = null,
281282
): T {
282283
val file = params[paramName] as File
@@ -289,12 +290,12 @@ class Client @JvmOverloads constructor(
289290
file.asRequestBody()
290291
)
291292
return call(
292-
"POST",
293+
method = "POST",
293294
path,
294295
headers,
295296
params,
296297
responseType,
297-
convert
298+
converter
298299
)
299300
}
300301

@@ -303,6 +304,22 @@ class Client @JvmOverloads constructor(
303304
var offset = 0L
304305
var result: Map<*, *>? = null
305306

307+
if (idParamName?.isNotEmpty() == true && params[idParamName] != "unique()") {
308+
// Make a request to check if a file already exists
309+
try {
310+
val current = call(
311+
method = "GET",
312+
path = "$path/$params[idParamName]",
313+
headers = headers,
314+
params = emptyMap(),
315+
responseType = Map::class.java,
316+
)
317+
val chunksUploaded = current["chunksUploaded"] as Long
318+
offset = size.coerceAtMost(chunksUploaded * CHUNK_SIZE)
319+
} catch (ex: {{spec.title | caseUcfirst}}Exception) {
320+
}
321+
}
322+
306323
generateSequence {
307324
val readBytes = input.read(buffer)
308325
if (readBytes >= 0) {
@@ -322,11 +339,11 @@ class Client @JvmOverloads constructor(
322339
"bytes $offset-${((offset + CHUNK_SIZE) - 1).coerceAtMost(size)}/$size"
323340

324341
result = call(
325-
"POST",
342+
method = "POST",
326343
path,
327344
headers,
328345
params,
329-
Map::class.java
346+
responseType = Map::class.java
330347
)
331348

332349
offset += CHUNK_SIZE
@@ -336,27 +353,27 @@ class Client @JvmOverloads constructor(
336353
progress = offset.coerceAtMost(size).toDouble()/size * 100,
337354
sizeUploaded = offset.coerceAtMost(size),
338355
chunksTotal = result!!["chunkTotal"].toString().toInt(),
339-
chunksUploaded = result!!["chunkUploaded"].toString().toInt(),
356+
chunksUploaded = result!!["chunksUploaded"].toString().toInt(),
340357
))
341358
}
342359

343-
return convert(result as Map<String, Any>)
360+
return converter(result as Map<String, Any>)
344361
}
345362

346363
/**
347364
* Await Response
348365
*
349366
* @param request
350367
* @param responseType
351-
* @param convert
368+
* @param converter
352369
*
353370
* @return [T]
354371
*/
355372
@Throws({{ spec.title | caseUcfirst }}Exception::class)
356373
private suspend fun <T> awaitResponse(
357374
request: Request,
358375
responseType: Class<T>,
359-
convert: ((Map<String, Any,>) -> T)? = null
376+
converter: ((Map<String, Any,>) -> T)? = null
360377
) = suspendCancellableCoroutine<T> {
361378
http.newCall(request).enqueue(object : Callback {
362379
override fun onFailure(call: Call, e: IOException) {
@@ -422,7 +439,7 @@ class Client @JvmOverloads constructor(
422439
object : TypeToken<Map<String, Any>>(){}.type
423440
)
424441
it.resume(
425-
convert?.invoke(map) ?: map as T
442+
converter?.invoke(map) ?: map as T
426443
)
427444
}
428445
})

templates/kotlin/src/main/kotlin/io/appwrite/services/ServiceTemplate.kt.twig

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class {{ service.name | caseUcfirst }}(client: Client) : Service(client) {
112112
{{ method.headers|map((header, key) => " \"#{key}\" to \"#{header}\"")|join(',\n')|raw }}
113113
)
114114
{% if method.responseModel %}
115-
val convert: (Map<String, Any>) -> {{ _self.resultType(sdk.namespace, method) }} = {
115+
val converter: (Map<String, Any>) -> {{ _self.resultType(sdk.namespace, method) }} = {
116116
{% if method.responseModel == 'any' %}
117117
it
118118
{% else %}
@@ -121,20 +121,25 @@ class {{ service.name | caseUcfirst }}(client: Client) : Service(client) {
121121
}
122122
{% endif %}
123123
{% if 'multipart/form-data' in method.consumes %}
124+
var idParamName: String? = null
124125
{% for parameter in method.parameters.all %}
125126
{% if parameter.type == 'file' %}
126127
val paramName = "{{ parameter.name }}"
127128
{% endif %}
129+
{% if parameter.isUploadID %}
130+
idParamName = "{{ parameter.name }}"
131+
{% endif %}
128132
{% endfor %}
129133
return client.chunkedUpload(
130134
path,
131135
headers,
132136
params,
133137
responseType = {{ _self.resultType(sdk.namespace, method) }}::class.java,
134138
{% if method.responseModel %}
135-
convert = convert,
139+
converter,
136140
{% endif %}
137141
paramName,
142+
idParamName,
138143
onProgress,
139144
)
140145
{% else %}
@@ -145,7 +150,7 @@ class {{ service.name | caseUcfirst }}(client: Client) : Service(client) {
145150
params,
146151
responseType = {{ _self.resultType(sdk.namespace, method) }}::class.java,
147152
{% if method.responseModel %}
148-
convert = convert,
153+
converter,
149154
{% endif %}
150155
)
151156
{% endif %}

0 commit comments

Comments
 (0)