Realtime snapshot

This commit is contained in:
Jake Barnby
2021-08-31 21:59:35 +12:00
parent 8434e384f1
commit ab4d24f3b5
21 changed files with 2428 additions and 144 deletions
+6 -6
View File
@@ -2,16 +2,16 @@
![Maven Central](https://img.shields.io/maven-central/v/io.appwrite/sdk-for-android.svg?color=green&style=flat-square)
![License](https://img.shields.io/github/license/appwrite/sdk-for-android.svg?style=flat-square)
![Version](https://img.shields.io/badge/api%20version-0.9.0-blue.svg?style=flat-square)
![Version](https://img.shields.io/badge/api%20version-0.8.0-blue.svg?style=flat-square)
[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator)
[![Twitter Account](https://img.shields.io/twitter/follow/appwrite_io?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite_io)
[![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord)
**This SDK is compatible with Appwrite server version 0.9.x. For older versions, please check [previous releases](https://github.com/appwrite/sdk-for-android/releases).**
**This SDK is compatible with Appwrite server version 0.10.x. For older versions, please check previous releases.**
Appwrite is an open-source backend as a service server that abstract and simplify complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the Android SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs)
Appwrite is an open-source backend as a service server that abstract and simplify complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the Flutter SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to https://appwrite.io/docs
![Appwrite](https://appwrite.io/images/github.png)
![Appwrite](https://appwrite.io/v1/images/console.png)
## Installation
@@ -38,7 +38,7 @@ repositories {
Next, add the dependency to your project's `build.gradle(.kts)` file:
```groovy
implementation("io.appwrite:sdk-for-android:0.0.1")
implementation("io.appwrite:sdk-for-android:0.2.0-SNAPSHOT")
```
### Maven
@@ -49,7 +49,7 @@ Add this to your project's `pom.xml` file:
<dependency>
<groupId>io.appwrite</groupId>
<artifactId>sdk-for-android</artifactId>
<version>0.0.1</version>
<version>0.2.0-SNAPSHOT</version>
</dependency>
</dependencies>
```
+1 -1
View File
@@ -3,7 +3,7 @@ apply plugin: 'io.github.gradle-nexus.publish-plugin'
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = "1.4.31"
version '0.0.1'
version '0.2.0-SNAPSHOT'
repositories {
maven { url "https://plugins.gradle.org/m2/" }
google()
-48
View File
@@ -1,48 +0,0 @@
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import io.appwrite.Client
import io.appwrite.services.Account
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Client client = new Client(getApplicationContext())
.setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint
.setProject("5df5acd0d48c2"); // Your project ID
Account account = new Account(client);
account.getSession(
"[SESSION_ID]"
new Continuation<Object>() {
@NotNull
@Override
public CoroutineContext getContext() {
return EmptyCoroutineContext.INSTANCE;
}
@Override
public void resumeWith(@NotNull Object o) {
String json = "";
try {
if (o instanceof Result.Failure) {
Result.Failure failure = (Result.Failure) o;
throw failure.exception;
} else {
Response response = (Response) o;
json = response.body().string();
}
} catch (Throwable th) {
Log.e("ERROR", th.toString());
}
}
}
);
}
}
@@ -1,26 +0,0 @@
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import io.appwrite.Client
import io.appwrite.services.Account
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val client = Client(applicationContext)
.setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint
.setProject("5df5acd0d48c2") // Your project ID
val account = Account(client)
GlobalScope.launch {
val response = account.getSession(
sessionId = "[SESSION_ID]"
)
val json = response.body?.string()
}
}
}
+10 -9
View File
@@ -7,11 +7,11 @@ plugins {
ext {
PUBLISH_GROUP_ID = 'io.appwrite'
PUBLISH_ARTIFACT_ID = 'sdk-for-android'
PUBLISH_VERSION = '0.0.1'
PUBLISH_VERSION = '0.2.0-SNAPSHOT'
POM_URL = 'https://github.com/appwrite/sdk-for-android'
POM_SCM_URL = 'https://github.com/appwrite/sdk-for-android'
POM_ISSUE_URL = 'https://github.com/appwrite/sdk-for-android/issues'
POM_DESCRIPTION = 'Appwrite is an open-source backend as a service server that abstract and simplify complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the Android SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs)'
POM_DESCRIPTION = 'Appwrite is an open-source backend as a service server that abstract and simplify complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the Flutter SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to https://appwrite.io/docs'
POM_LICENSE_URL = 'https://opensource.org/licenses/GPL-3.0'
POM_LICENSE_NAME = "GPL-3.0"
POM_DEVELOPER_ID = 'appwrite'
@@ -53,8 +53,8 @@ android {
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${KotlinCompilerVersion.VERSION}")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.3")
api("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.3")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1")
api("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0")
api(platform("com.squareup.okhttp3:okhttp-bom:4.9.0"))
api("com.squareup.okhttp3:okhttp")
@@ -65,15 +65,16 @@ dependencies {
implementation("net.gotev:cookie-store:1.3.5")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.3.1")
implementation("androidx.lifecycle:lifecycle-common-java8:2.3.1")
implementation("androidx.appcompat:appcompat:1.2.0")
implementation("androidx.fragment:fragment-ktx:1.3.2")
implementation("androidx.activity:activity-ktx:1.2.2")
implementation("androidx.appcompat:appcompat:1.3.1")
implementation("androidx.fragment:fragment-ktx:1.3.6")
implementation("androidx.activity:activity-ktx:1.3.1")
implementation("androidx.browser:browser:1.3.0")
testImplementation 'junit:junit:4.+'
testImplementation "androidx.test.ext:junit-ktx:1.1.2"
testImplementation "androidx.test:core-ktx:1.3.0"
testImplementation "androidx.test.ext:junit-ktx:1.1.3"
testImplementation "androidx.test:core-ktx:1.4.0"
testImplementation "org.robolectric:robolectric:4.5.1"
testApi("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.5.1")
}
apply from: "${rootProject.projectDir}/scripts/publish-module.gradle"
+51 -6
View File
@@ -5,8 +5,7 @@ import android.content.pm.PackageManager
import com.google.gson.Gson
import io.appwrite.appwrite.BuildConfig
import io.appwrite.exceptions.AppwriteException
import io.appwrite.extensions.JsonExtensions.fromJson
import io.appwrite.models.Error
import io.appwrite.extensions.fromJson
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@@ -36,6 +35,7 @@ import kotlin.coroutines.resume
class Client @JvmOverloads constructor(
context: Context,
var endPoint: String = "https://appwrite.io/v1",
var endPointRealtime: String? = null,
private var selfSigned: Boolean = false
) : CoroutineScope {
@@ -71,7 +71,7 @@ class Client @JvmOverloads constructor(
"origin" to "appwrite-android://${context.packageName}",
"user-agent" to "${context.packageName}/${appVersion}, ${System.getProperty("http.agent")}",
"x-sdk-version" to "appwrite:android:${BuildConfig.SDK_VERSION}",
"x-appwrite-response-format" to "0.9.0"
"x-appwrite-response-format" to "0.10.0"
)
config = mutableMapOf()
@@ -93,6 +93,21 @@ class Client @JvmOverloads constructor(
return this
}
/**
* Set Key
*
* Your secret API key
*
* @param {string} key
*
* @return this
*/
fun setKey(value: String): Client {
config["key"] = value
addHeader("x-appwrite-key", value)
return this
}
/**
* Set JWT
*
@@ -121,6 +136,19 @@ class Client @JvmOverloads constructor(
return this
}
/**
* Set Mode
*
* @param {string} mode
*
* @return this
*/
fun setMode(value: String): Client {
config["mode"] = value
addHeader("x-appwrite-mode", value)
return this
}
/**
* Set self Signed
*
@@ -171,7 +199,7 @@ class Client @JvmOverloads constructor(
}
/**
* Set endpoint
* Set endpoint and realtime endpoint.
*
* @param endpoint
*
@@ -179,6 +207,23 @@ class Client @JvmOverloads constructor(
*/
fun setEndpoint(endPoint: String): Client {
this.endPoint = endPoint
if (this.endPointRealtime == null && endPoint.startsWith("http")) {
this.endPointRealtime = endPoint.replaceFirst("http", "ws")
}
return this
}
/**
* Set realtime endpoint
*
* @param endpoint
*
* @return this
*/
fun setEndpointRealtime(endPoint: String): Client {
this.endPointRealtime = endPoint
return this
}
@@ -317,9 +362,9 @@ class Client @JvmOverloads constructor(
val contentType: String = response.headers["content-type"] ?: ""
val error = if (contentType.contains("application/json", ignoreCase = true)) {
bodyString.fromJson(Error::class.java)
bodyString.fromJson<AppwriteException>()
} else {
Error(bodyString, response.code)
AppwriteException(bodyString, response.code)
}
it.cancel(AppwriteException(
@@ -0,0 +1,12 @@
package io.appwrite.extensions
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.withContext
suspend fun <T> Collection<T>.forEachAsync(
callback: suspend (T) -> Unit
) = withContext(IO) {
map { async { callback.invoke(it) } }.awaitAll()
}
@@ -2,11 +2,33 @@ package io.appwrite.extensions
import com.google.gson.Gson
object JsonExtensions {
val gson = Gson()
fun Any.toJson(): String =
Gson().toJson(this)
fun Any.toJson(): String =
gson.toJson(this)
fun <T> String.fromJson(clazz: Class<T>): T =
Gson().fromJson(this, clazz)
}
fun <T> String.fromJson(clazz: Class<T>): T =
gson.fromJson(this, clazz)
inline fun <reified T> String.fromJson(): T =
gson.fromJson(this, T::class.java)
fun <T> Any.jsonCast(to: Class<T>): T =
toJson().fromJson(to)
inline fun <reified T> Any.jsonCast(): T =
toJson().fromJson(T::class.java)
fun <T> Any.tryJsonCast(to: Class<T>): T? = try {
toJson().fromJson(to)
} catch (ex: Exception) {
ex.printStackTrace()
null
}
inline fun <reified T> Any.tryJsonCast(): T? = try {
toJson().fromJson(T::class.java)
} catch (ex: Exception) {
ex.printStackTrace()
null
}
@@ -0,0 +1,31 @@
package io.appwrite.models
import java.io.Closeable
data class RealtimeSubscription(
private val close: () -> Unit
) : Closeable {
override fun close() = close.invoke()
}
data class RealtimeCallback(
val payloadClass: Class<*>,
val callback: (RealtimeResponseEvent<*>) -> Unit
)
open class RealtimeResponse(
val type: String,
val data: Any
)
data class RealtimeResponseEvent<T>(
val event: String,
val channels: Collection<String>,
val timestamp: Long,
var payload: T
)
enum class RealtimeCode(val value: Int) {
POLICY_VIOLATION(1008),
UNKNOWN_ERROR(-1)
}
@@ -11,7 +11,7 @@ import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl
import java.io.File
class Account(private val client: Client) : BaseService(client) {
class Account(client: Client) : Service(client) {
/**
* Get Account
@@ -134,8 +134,7 @@ class Account(private val client: Client) : BaseService(client) {
* Use this endpoint to create a JSON Web Token. You can use the resulting JWT
* to authenticate on behalf of the current user when working with the
* Appwrite server-side API and SDKs. The JWT secret is valid for 15 minutes
* from its creation and will be invalid if the user will logout in that time
* frame.
* from its creation and will be invalid if the user will logout.
*
* @return [Response]
*/
@@ -432,10 +431,9 @@ class Account(private val client: Client) : BaseService(client) {
*
* Use this endpoint to allow a new user to register an anonymous account in
* your project. This route will also create a new session for the user. To
* allow the new user to convert an anonymous account to a normal account, you
* need to update its [email and
* password](/docs/client/account#accountUpdateEmail) or create an [OAuth2
* session](/docs/client/account#accountCreateOAuth2Session).
* allow the new user to convert an anonymous account to a normal account
* account, you need to update its [email and
* password](/docs/client/account#accountUpdateEmail).
*
* @return [Response]
*/
@@ -529,31 +527,6 @@ class Account(private val client: Client) : BaseService(client) {
}
/**
* Get Session By ID
*
* Use this endpoint to get a logged in user's session using a Session ID.
* Inputting 'current' will return the current session being used.
*
* @param sessionId
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun getSession(
sessionId: String
): Response {
val path = "/account/sessions/{sessionId}".replace("{sessionId}", sessionId)
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Delete Account Session
*
@@ -9,7 +9,7 @@ import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl
import java.io.File
class Avatars(private val client: Client) : BaseService(client) {
class Avatars(client: Client) : Service(client) {
/**
* Get Browser Icon
@@ -7,8 +7,165 @@ import okhttp3.Cookie
import okhttp3.Response
import java.io.File
class Database(private val client: Client) : BaseService(client) {
class Database(client: Client) : Service(client) {
/**
* List Collections
*
* Get a list of all the user collections. You can use the query params to
* filter your results. On admin mode, this endpoint will return a list of all
* of the project's collections. [Learn more about different API
* modes](/docs/admin).
*
* @param search
* @param limit
* @param offset
* @param orderType
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun listCollections(
search: String? = null,
limit: Int? = null,
offset: Int? = null,
orderType: String? = null
): Response {
val path = "/database/collections"
val params = mapOf<String, Any?>(
"search" to search,
"limit" to limit,
"offset" to offset,
"orderType" to orderType
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Create Collection
*
* Create a new Collection.
*
* @param name
* @param read
* @param write
* @param rules
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun createCollection(
name: String,
read: List<Any>,
write: List<Any>,
rules: List<Any>
): Response {
val path = "/database/collections"
val params = mapOf<String, Any?>(
"name" to name,
"read" to read,
"write" to write,
"rules" to rules
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("POST", path, headers, params)
}
/**
* Get Collection
*
* Get a collection by its unique ID. This endpoint response returns a JSON
* object with the collection metadata.
*
* @param collectionId
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun getCollection(
collectionId: String
): Response {
val path = "/database/collections/{collectionId}".replace("{collectionId}", collectionId)
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Update Collection
*
* Update a collection by its unique ID.
*
* @param collectionId
* @param name
* @param read
* @param write
* @param rules
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun updateCollection(
collectionId: String,
name: String,
read: List<Any>? = null,
write: List<Any>? = null,
rules: List<Any>? = null
): Response {
val path = "/database/collections/{collectionId}".replace("{collectionId}", collectionId)
val params = mapOf<String, Any?>(
"name" to name,
"read" to read,
"write" to write,
"rules" to rules
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("PUT", path, headers, params)
}
/**
* Delete Collection
*
* Delete a collection by its unique ID. Only users with write permissions
* have access to delete this resource.
*
* @param collectionId
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun deleteCollection(
collectionId: String
): Response {
val path = "/database/collections/{collectionId}".replace("{collectionId}", collectionId)
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("DELETE", path, headers, params)
}
/**
* List Documents
*
@@ -7,8 +7,178 @@ import okhttp3.Cookie
import okhttp3.Response
import java.io.File
class Functions(private val client: Client) : BaseService(client) {
class Functions(client: Client) : Service(client) {
/**
* List Functions
*
* Get a list of all the project's functions. You can use the query params to
* filter your results.
*
* @param search
* @param limit
* @param offset
* @param orderType
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun list(
search: String? = null,
limit: Int? = null,
offset: Int? = null,
orderType: String? = null
): Response {
val path = "/functions"
val params = mapOf<String, Any?>(
"search" to search,
"limit" to limit,
"offset" to offset,
"orderType" to orderType
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Create Function
*
* Create a new function. You can pass a list of
* [permissions](/docs/permissions) to allow different project users or team
* with access to execute the function using the client API.
*
* @param name
* @param execute
* @param env
* @param vars
* @param events
* @param schedule
* @param timeout
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun create(
name: String,
execute: List<Any>,
env: String,
vars: Any? = null,
events: List<Any>? = null,
schedule: String? = null,
timeout: Int? = null
): Response {
val path = "/functions"
val params = mapOf<String, Any?>(
"name" to name,
"execute" to execute,
"env" to env,
"vars" to vars,
"events" to events,
"schedule" to schedule,
"timeout" to timeout
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("POST", path, headers, params)
}
/**
* Get Function
*
* Get a function by its unique ID.
*
* @param functionId
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun get(
functionId: String
): Response {
val path = "/functions/{functionId}".replace("{functionId}", functionId)
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Update Function
*
* Update function by its unique ID.
*
* @param functionId
* @param name
* @param execute
* @param vars
* @param events
* @param schedule
* @param timeout
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun update(
functionId: String,
name: String,
execute: List<Any>,
vars: Any? = null,
events: List<Any>? = null,
schedule: String? = null,
timeout: Int? = null
): Response {
val path = "/functions/{functionId}".replace("{functionId}", functionId)
val params = mapOf<String, Any?>(
"name" to name,
"execute" to execute,
"vars" to vars,
"events" to events,
"schedule" to schedule,
"timeout" to timeout
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("PUT", path, headers, params)
}
/**
* Delete Function
*
* Delete a function by its unique ID.
*
* @param functionId
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun delete(
functionId: String
): Response {
val path = "/functions/{functionId}".replace("{functionId}", functionId)
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("DELETE", path, headers, params)
}
/**
* List Executions
*
@@ -104,4 +274,186 @@ class Functions(private val client: Client) : BaseService(client) {
return client.call("GET", path, headers, params)
}
/**
* Update Function Tag
*
* Update the function code tag ID using the unique function ID. Use this
* endpoint to switch the code tag that should be executed by the execution
* endpoint.
*
* @param functionId
* @param tag
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun updateTag(
functionId: String,
tag: String
): Response {
val path = "/functions/{functionId}/tag".replace("{functionId}", functionId)
val params = mapOf<String, Any?>(
"tag" to tag
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("PATCH", path, headers, params)
}
/**
* List Tags
*
* Get a list of all the project's code tags. You can use the query params to
* filter your results.
*
* @param functionId
* @param search
* @param limit
* @param offset
* @param orderType
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun listTags(
functionId: String,
search: String? = null,
limit: Int? = null,
offset: Int? = null,
orderType: String? = null
): Response {
val path = "/functions/{functionId}/tags".replace("{functionId}", functionId)
val params = mapOf<String, Any?>(
"search" to search,
"limit" to limit,
"offset" to offset,
"orderType" to orderType
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Create Tag
*
* Create a new function code tag. Use this endpoint to upload a new version
* of your code function. To execute your newly uploaded code, you'll need to
* update the function's tag to use your new tag UID.
*
* This endpoint accepts a tar.gz file compressed with your code. Make sure to
* include any dependencies your code has within the compressed file. You can
* learn more about code packaging in the [Appwrite Cloud Functions
* tutorial](/docs/functions).
*
* Use the "command" param to set the entry point used to execute your code.
*
* @param functionId
* @param command
* @param code
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun createTag(
functionId: String,
command: String,
code: File
): Response {
val path = "/functions/{functionId}/tags".replace("{functionId}", functionId)
val params = mapOf<String, Any?>(
"command" to command,
"code" to code
)
val headers = mapOf(
"content-type" to "multipart/form-data"
)
return client.call("POST", path, headers, params)
}
/**
* Get Tag
*
* Get a code tag by its unique ID.
*
* @param functionId
* @param tagId
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun getTag(
functionId: String,
tagId: String
): Response {
val path = "/functions/{functionId}/tags/{tagId}".replace("{functionId}", functionId).replace("{tagId}", tagId)
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Delete Tag
*
* Delete a code tag by its unique ID.
*
* @param functionId
* @param tagId
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun deleteTag(
functionId: String,
tagId: String
): Response {
val path = "/functions/{functionId}/tags/{tagId}".replace("{functionId}", functionId).replace("{tagId}", tagId)
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("DELETE", path, headers, params)
}
/**
* Get Function Usage
*
* @param functionId
* @param range
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun getUsage(
functionId: String,
range: String? = null
): Response {
val path = "/functions/{functionId}/usage".replace("{functionId}", functionId)
val params = mapOf<String, Any?>(
"range" to range
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
}
@@ -0,0 +1,275 @@
package io.appwrite.services
import android.net.Uri
import io.appwrite.Client
import io.appwrite.exceptions.AppwriteException
import okhttp3.Cookie
import okhttp3.Response
import java.io.File
class Health(client: Client) : Service(client) {
/**
* Get HTTP
*
* Check the Appwrite HTTP server is up and responsive.
*
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun get(): Response {
val path = "/health"
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Get Anti virus
*
* Check the Appwrite Anti Virus server is up and connection is successful.
*
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun getAntiVirus(): Response {
val path = "/health/anti-virus"
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Get Cache
*
* Check the Appwrite in-memory cache server is up and connection is
* successful.
*
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun getCache(): Response {
val path = "/health/cache"
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Get DB
*
* Check the Appwrite database server is up and connection is successful.
*
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun getDB(): Response {
val path = "/health/db"
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Get Certificate Queue
*
* Get the number of certificates that are waiting to be issued against
* [Letsencrypt](https://letsencrypt.org/) in the Appwrite internal queue
* server.
*
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun getQueueCertificates(): Response {
val path = "/health/queue/certificates"
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Get Functions Queue
*
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun getQueueFunctions(): Response {
val path = "/health/queue/functions"
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Get Logs Queue
*
* Get the number of logs that are waiting to be processed in the Appwrite
* internal queue server.
*
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun getQueueLogs(): Response {
val path = "/health/queue/logs"
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Get Tasks Queue
*
* Get the number of tasks that are waiting to be processed in the Appwrite
* internal queue server.
*
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun getQueueTasks(): Response {
val path = "/health/queue/tasks"
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Get Usage Queue
*
* Get the number of usage stats that are waiting to be processed in the
* Appwrite internal queue server.
*
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun getQueueUsage(): Response {
val path = "/health/queue/usage"
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Get Webhooks Queue
*
* Get the number of webhooks that are waiting to be processed in the Appwrite
* internal queue server.
*
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun getQueueWebhooks(): Response {
val path = "/health/queue/webhooks"
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Get Local Storage
*
* Check the Appwrite local storage device is up and connection is successful.
*
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun getStorageLocal(): Response {
val path = "/health/storage/local"
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Get Time
*
* Check the Appwrite server time is synced with Google remote NTP server. We
* use this technology to smoothly handle leap seconds with no disruptive
* events. The [Network Time
* Protocol](https://en.wikipedia.org/wiki/Network_Time_Protocol) (NTP) is
* used by hundreds of millions of computers and devices to synchronize their
* clocks over the Internet. If your computer sets its own clock, it likely
* uses NTP.
*
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun getTime(): Response {
val path = "/health/time"
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
}
@@ -7,7 +7,7 @@ import okhttp3.Cookie
import okhttp3.Response
import java.io.File
class Locale(private val client: Client) : BaseService(client) {
class Locale(client: Client) : Service(client) {
/**
* Get User Locale
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,174 @@
package io.appwrite.services
import io.appwrite.Client
import io.appwrite.exceptions.AppwriteException
import io.appwrite.extensions.forEachAsync
import io.appwrite.extensions.fromJson
import io.appwrite.extensions.jsonCast
import io.appwrite.models.*
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers.IO
import okhttp3.Request
import okhttp3.Response
import okhttp3.WebSocket
import okhttp3.WebSocketListener
import okhttp3.internal.concurrent.TaskRunner
import okhttp3.internal.ws.RealWebSocket
import java.util.*
import kotlin.coroutines.CoroutineContext
class Realtime(client: Client) : Service(client), CoroutineScope {
private val job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + job
private companion object {
private const val TYPE_ERROR = "error"
private const val TYPE_EVENT = "event"
private const val DEBOUNCE_MILLIS = 1L
private var socket: RealWebSocket? = null
private var channelCallbacks = mutableMapOf<String, MutableCollection<RealtimeCallback>>()
private var errorCallbacks = mutableSetOf<(AppwriteException) -> Unit>()
private var subCallDepth = 0
}
private fun createSocket() {
val queryParamBuilder = StringBuilder()
.append("project=${client.config["project"]}")
channelCallbacks.keys.forEach {
queryParamBuilder
.append("&channels[]=$it")
}
val request = Request.Builder()
.url("${client.endPointRealtime}/realtime?$queryParamBuilder")
.build()
if (socket != null) {
closeSocket()
}
socket = RealWebSocket(
taskRunner = TaskRunner.INSTANCE,
originalRequest = request,
listener = AppwriteWebSocketListener(),
random = Random(),
pingIntervalMillis = client.http.pingIntervalMillis.toLong(),
extensions = null,
minimumDeflateSize = client.http.minWebSocketMessageToCompress
)
socket!!.connect(client.http)
}
private fun closeSocket() {
socket?.close(RealtimeCode.POLICY_VIOLATION.value, null)
}
fun subscribe(
vararg channels: String,
callback: (RealtimeResponseEvent<Any>) -> Unit,
) = subscribe(
channels = channels,
Any::class.java,
callback
)
fun <T> subscribe(
vararg channels: String,
payloadType: Class<T>,
callback: (RealtimeResponseEvent<T>) -> Unit,
): RealtimeSubscription {
channels.forEach {
if (!channelCallbacks.containsKey(it)) {
channelCallbacks[it] = mutableListOf(
RealtimeCallback(
payloadType,
callback as (RealtimeResponseEvent<*>) -> Unit
)
)
return@forEach
}
channelCallbacks[it]?.add(
RealtimeCallback(payloadType, callback as (RealtimeResponseEvent<*>) -> Unit)
)
}
launch {
subCallDepth++
delay(DEBOUNCE_MILLIS)
if (subCallDepth == 1) {
createSocket()
}
subCallDepth--
}
return RealtimeSubscription { unsubscribe(*channels) }
}
fun unsubscribe(vararg channels: String) {
channels.forEach {
channelCallbacks[it] = mutableListOf()
}
if (channelCallbacks.all { it.value.isEmpty() }) {
errorCallbacks = mutableSetOf()
closeSocket()
}
}
fun doOnError(callback: (AppwriteException) -> Unit) {
errorCallbacks.add(callback)
}
private inner class AppwriteWebSocketListener : WebSocketListener() {
override fun onMessage(webSocket: WebSocket, text: String) {
super.onMessage(webSocket, text)
launch(IO) {
val message = text.fromJson<RealtimeResponse>()
when (message.type) {
TYPE_ERROR -> handleResponseError(message)
TYPE_EVENT -> handleResponseEvent(message)
}
}
}
private fun handleResponseError(message: RealtimeResponse) {
val error = message.data.jsonCast<AppwriteException>()
errorCallbacks.forEach { it.invoke(error) }
}
private suspend fun handleResponseEvent(message: RealtimeResponse) {
val event = message.data.jsonCast<RealtimeResponseEvent<Any>>()
event.channels.forEachAsync { channel ->
channelCallbacks[channel]?.forEachAsync { callbackWrapper ->
event.payload = event.payload.jsonCast(callbackWrapper.payloadClass)
callbackWrapper.callback.invoke(event)
}
}
}
override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
super.onClosing(webSocket, code, reason)
if (code == RealtimeCode.POLICY_VIOLATION.value) {
return
}
launch {
delay(1000)
createSocket()
}
}
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
super.onFailure(webSocket, t, response)
t.printStackTrace()
}
}
}
@@ -2,4 +2,4 @@ package io.appwrite.services
import io.appwrite.Client
abstract class BaseService(private val client: Client)
abstract class Service(val client: Client)
@@ -9,7 +9,7 @@ import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl
import java.io.File
class Storage(private val client: Client) : BaseService(client) {
class Storage(client: Client) : Service(client) {
/**
* List Files
@@ -195,7 +195,6 @@ class Storage(private val client: Client) : BaseService(client) {
* @param fileId
* @param width
* @param height
* @param gravity
* @param quality
* @param borderWidth
* @param borderColor
@@ -212,7 +211,6 @@ class Storage(private val client: Client) : BaseService(client) {
fileId: String,
width: Int? = null,
height: Int? = null,
gravity: String? = null,
quality: Int? = null,
borderWidth: Int? = null,
borderColor: String? = null,
@@ -226,7 +224,6 @@ class Storage(private val client: Client) : BaseService(client) {
val params = mapOf<String, Any?>(
"width" to width,
"height" to height,
"gravity" to gravity,
"quality" to quality,
"borderWidth" to borderWidth,
"borderColor" to borderColor,
@@ -7,7 +7,7 @@ import okhttp3.Cookie
import okhttp3.Response
import java.io.File
class Teams(private val client: Client) : BaseService(client) {
class Teams(client: Client) : Service(client) {
/**
* List Teams
@@ -0,0 +1,303 @@
package io.appwrite.services
import android.net.Uri
import io.appwrite.Client
import io.appwrite.exceptions.AppwriteException
import okhttp3.Cookie
import okhttp3.Response
import java.io.File
class Users(client: Client) : Service(client) {
/**
* List Users
*
* Get a list of all the project's users. You can use the query params to
* filter your results.
*
* @param search
* @param limit
* @param offset
* @param orderType
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun list(
search: String? = null,
limit: Int? = null,
offset: Int? = null,
orderType: String? = null
): Response {
val path = "/users"
val params = mapOf<String, Any?>(
"search" to search,
"limit" to limit,
"offset" to offset,
"orderType" to orderType
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Create User
*
* Create a new user.
*
* @param email
* @param password
* @param name
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun create(
email: String,
password: String,
name: String? = null
): Response {
val path = "/users"
val params = mapOf<String, Any?>(
"email" to email,
"password" to password,
"name" to name
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("POST", path, headers, params)
}
/**
* Get User
*
* Get a user by its unique ID.
*
* @param userId
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun get(
userId: String
): Response {
val path = "/users/{userId}".replace("{userId}", userId)
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Delete User
*
* Delete a user by its unique ID.
*
* @param userId
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun delete(
userId: String
): Response {
val path = "/users/{userId}".replace("{userId}", userId)
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("DELETE", path, headers, params)
}
/**
* Get User Logs
*
* Get a user activity logs list by its unique ID.
*
* @param userId
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun getLogs(
userId: String
): Response {
val path = "/users/{userId}/logs".replace("{userId}", userId)
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Get User Preferences
*
* Get the user preferences by its unique ID.
*
* @param userId
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun getPrefs(
userId: String
): Response {
val path = "/users/{userId}/prefs".replace("{userId}", userId)
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Update User Preferences
*
* Update the user preferences by its unique ID. You can pass only the
* specific settings you wish to update.
*
* @param userId
* @param prefs
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun updatePrefs(
userId: String,
prefs: Any
): Response {
val path = "/users/{userId}/prefs".replace("{userId}", userId)
val params = mapOf<String, Any?>(
"prefs" to prefs
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("PATCH", path, headers, params)
}
/**
* Get User Sessions
*
* Get the user sessions list by its unique ID.
*
* @param userId
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun getSessions(
userId: String
): Response {
val path = "/users/{userId}/sessions".replace("{userId}", userId)
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("GET", path, headers, params)
}
/**
* Delete User Sessions
*
* Delete all user's sessions by using the user's unique ID.
*
* @param userId
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun deleteSessions(
userId: String
): Response {
val path = "/users/{userId}/sessions".replace("{userId}", userId)
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("DELETE", path, headers, params)
}
/**
* Delete User Session
*
* Delete a user sessions by its unique ID.
*
* @param userId
* @param sessionId
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun deleteSession(
userId: String,
sessionId: String
): Response {
val path = "/users/{userId}/sessions/{sessionId}".replace("{userId}", userId).replace("{sessionId}", sessionId)
val params = mapOf<String, Any?>(
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("DELETE", path, headers, params)
}
/**
* Update User Status
*
* Update the user status by its unique ID.
*
* @param userId
* @param status
* @return [Response]
*/
@JvmOverloads
@Throws(AppwriteException::class)
suspend fun updateStatus(
userId: String,
status: Int
): Response {
val path = "/users/{userId}/status".replace("{userId}", userId)
val params = mapOf<String, Any?>(
"status" to status
)
val headers = mapOf(
"content-type" to "application/json"
)
return client.call("PATCH", path, headers, params)
}
}