appwrite.el/appwrite.el

208 lines
6.9 KiB
EmacsLisp
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;;; appwrite.el --- Appwrite server SDK for Emacs -*- lexical-binding: t; -*-
;; Copyright (C) 2022 Lucien Cartier-Tilet
;; Author: Lucien Cartier-Tilet <lucien@phundrak.com>
;; Maintainer: Lucien Cartier-Tilet <lucien@phundrak.com>
;; URL: https://github.com/Phundrak/appwrite.el
;; Version: 0.1.0
;; Package-Requires: ((emacs "26.1"))
;; Keywords: database emacs-lisp
;; This file is not part of GNU Emacs.
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;;
;; Appwrite server SDK for Emacs
;;
;;; Code:
(require 'cl-lib)
(require 'json)
(require 'url)
(defgroup appwrite nil
"Customizationi group for `appwrite'."
:group 'emacs-lisp
:link '(url-link :tag "Gitea" "https://labs.phundrak.com/phundrak/appwrite.el")
:link '(url-link :tag "Github" "https://github.com/Phundrak/appwrite.el"))
(defcustom appwrite-endpoint ""
"Appwrite endpoint.
Must not include the API version, e.g.
\"https://appwrite.example.org\". The variable must not end with
a trailing forward slash. Setting this variable with
`customize-set-variable' takes care of it automatically."
:group 'appwrite
:type 'string
:set (lambda (symbol val)
(set-default symbol
(if (string-suffix-p "/" val)
(message "%s" (substring val 0 (1- (length val))))
val))))
(defvar appwrite-api-key ""
"API Key for accessing your Appwrite API.
Be sure to keep it safe and never upload its value somewhere on
the internet, even if its a private repository.")
(defvar appwrite-project ""
"ID of the project to act on.")
;;; Internal functions
(defun appwrite--get-full-url (api)
"Get the full url for API.
If API does not begin with an initial forward slash, add it
automatically.
If it does not contain an API version, prefix \"/v1\" by default."
(let ((versionp (string-match-p "^/?v[[:digit:]]+.*" api))
(initial-forward-slash-p (string-prefix-p "/" api)))
(concat appwrite-endpoint
(if versionp
""
"/v1")
(if initial-forward-slash-p
""
"/")
api)))
(cl-defun appwrite--query-api (&key (method "GET")
api
data
(content-type "application/json")
data-alist-p
asyncp
callback)
"Perform a method METHOD to API with DATA as its payload.
CONTENT-TYPE is whichever miime-type is being used.
If CONTENT-TYPE is \"application/json\", DATA is subject ot
automatic conversion depending on its type.
- If DATA passes `plistp', it will be converted to JSON as a
plist.
- If DATA passes `hash-table-p', it will be converted to JSON as
a hash table.
- If DATA-ALIST-P is t, DATA will be converted to JSON as an
associative table.
- Else, DATA will be passed a string containing JSON.
If ASYNCP is t, `appwrite--post-api' will be asynchronous.
CALLBACK must then be set as it will be called once the request
finishes. See `url-retrieve'."
(let* ((url (appwrite--get-full-url api))
(url-request-method method)
(url-request-extra-headers `(("X-Appwrite-key" . ,appwrite-api-key)
("X-Appwrite-Project" . ,appwrite-project)
("Content-type" . ,content-type)))
(url-request-data (cond ((not (string= content-type "application/json"))
data)
((plistp data) (json-encode-plist data))
((hash-table-p data) (json-encode data))
(data-alist-p (json-encode-alist data))
(t data))))
(if asyncp
(url-retrieve url callback)
(with-current-buffer (url-retrieve-synchronously url)
(buffer-string)))))
;;; Account
;;; Users
;;; Teams
;;; Databases
;;; Storage
(cl-defun appwrite-storage-create-bucket (id
name
&key
(permission "bucket")
read write (enabled t)
maximum-file-size allowed-file-extensions
(encryption t) (antivirus t))
"Create bucket.
Create bucket named NAME with id ID.
PERMISSION is the permissioin type model to use for reading files
in this bucket. By default, PERMISSION is \"bucket\". For more
info, see https://appwrite.io/docs/permissions
READ is an array of roles for read permissions.
WRITE is an array of roles for write permissions.
If ENABLED is nil, disable bucket, t by default.
MAXIMUM-FILE-SIZE is an integer indicating in bytes the maximum
size of an uploaded. The default is 30MB (not MiB), though this
might be different on self-hosted instances.
ALLOWED-FILE-EXTENSIONS is an array of allowed file extensions. A
maximum of 100 extensions no longer than 64 characters are
allowed.
If ENCRYPTION is t, enable encryption for the bucket. Files
larger than 20MB are skipped. t by default.
If ANTIVIRUS is t, enable antivirus for the bucket. Files larger
than 20MB are skipped. t by default."
(let ((data `(bucketId ,id name ,name permission ,permission)))
(when read
(setq data (append data `(read ,read))))
(when write
(setq data (append data `(write ,write))))
(when maximum-file-size
(setq data (append data `(maximumFileSize ,maximum-file-size))))
(when allowed-file-extensions
(setq data (append data `(allowedFileExtensions ,allowed-file-extensions))))
(setq data (append data `(enabled ,(if enabled t :json-false))))
(setq data (append data `(encryption ,(if encryption t :json-false))))
(setq data (append data `(antivirus ,(if antivirus t :json-false))))
;; (json-encode-plist data)
(appwrite--query-api :method "POST" :api "storage/buckets" :data (json-encode-plist data))))
(defun appwrite-storage-delete-bucket (id)
"Delete bucket with id ID."
(appwrite--query-api :method "DELETE"
:api (concat "storage/buckets/" id)))
;;; Functions
;;; Localization
;;; Avatars
;;; Health
(provide 'appwrite)
;;; appwrite.el ends here