diff --git a/configure.ac b/configure.ac
index a65e3ab..367f277 100644
--- a/configure.ac
+++ b/configure.ac
@@ -55,6 +55,7 @@ AC_PATH_PROG([GLIB_MKENUMS], [glib-mkenums])
PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.38])
PKG_CHECK_MODULES([GOBJECT], [gobject-2.0 >= 2.38])
PKG_CHECK_MODULES([SOUP], [libsoup-2.4])
+PKG_CHECK_MODULES([JSON], [json-glib-1.0])
LIBMATRIX_GLIB_LIBS='$(top_builddir)/src/libmatrix-glib-$(MATRIX_GLIB_API_VERSION).la'
AC_SUBST(LIBMATRIX_GLIB_LIBS)
diff --git a/docs/reference/matrix-glib/matrix-glib-docs.xml b/docs/reference/matrix-glib/matrix-glib-docs.xml
index 792f07e..86add7e 100644
--- a/docs/reference/matrix-glib/matrix-glib-docs.xml
+++ b/docs/reference/matrix-glib/matrix-glib-docs.xml
@@ -19,9 +19,9 @@
Matrix Client
-
+
-
+
Object Hierarchy
diff --git a/docs/reference/matrix-glib/matrix-glib-sections.txt b/docs/reference/matrix-glib/matrix-glib-sections.txt
index def1caa..243b1dc 100644
--- a/docs/reference/matrix-glib/matrix-glib-sections.txt
+++ b/docs/reference/matrix-glib/matrix-glib-sections.txt
@@ -18,19 +18,55 @@ matrix_client_get_type
matrix-api
MatrixAPI
+MatrixAPICallback
+matrix_api_ban_user
+matrix_api_create_room
+matrix_api_event_stream
+matrix_api_get_emote_body
+matrix_api_get_html_body
+matrix_api_get_text_body
+matrix_api_get_room_name
+matrix_api_get_room_state
+matrix_api_get_room_topic
+matrix_api_initial_sync
+matrix_api_invite_user
+matrix_api_join_room
+matrix_api_kick_user
+matrix_api_leave_room
+matrix_api_login
+matrix_api_register_account
+matrix_api_send_emote
+matrix_api_send_message
+matrix_api_send_message_event
+matrix_api_send_state_event
+matrix_api_set_membership
MatrixAPI
-MatrixAPIClass
-MATRIX_IS_API
-MATRIX_IS_API_CLASS
-MATRIX_API
-MATRIX_API_CLASS
-MATRIX_API_GET_CLASS
+MatrixAPIInterface
MATRIX_TYPE_API
+MATRIX_API
+MATRIX_IS_API
+MATRIX_API_GET_IFACE
MatrixApiPrivate
matrix_api_get_type
+
+matrix-http-api
+matrix_http_api_get_validate_certificate
+matrix_http_api_set_validate_certificate
+
+MatrixHTTPAPI
+MatrixHTTPAPIClass
+MATRIX_TYPE_HTTP_API
+MATRIX_HTTP_API
+MATRIX_HTTP_API_CLASS
+MATRIX_IS_HTTP_API
+MATRIX_IS_HTTP_API_CLASS
+MATRIX_HTTP_API_GET_CLASS
+matrix_http_api_get_type
+
+
matrix-version
MATRIX_GLIB_MAJOR_VERSION
diff --git a/src/Makefile.am b/src/Makefile.am
index 0d645e2..2cd5539 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -5,6 +5,7 @@ lib_LTLIBRARIES = libmatrix-glib-0.0.la
INST_H_SRC_FILES = \
matrix-client.h \
matrix-api.h \
+ matrix-http-api.h \
$(NULL)
INST_H_BUILT_FILES = matrix-version.h
@@ -13,12 +14,13 @@ libmatrix_glib_0_0_la_SOURCES = \
matrix-client.c \
matrix-version.c \
matrix-api.c \
+ matrix-http-api.c \
$(INST_H_SRC_FILES) \
$(INST_H_BUILT_FILES) \
$(NULL)
-libmatrix_glib_0_0_la_CFLAGS = $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) $(SOUP_CFLAGS)
-libmatrix_glib_0_0_la_LIBADD = $(GLIB_LIBS) $(GOBJECT_LIBS) $(SOUP_LIBS)
+libmatrix_glib_0_0_la_CFLAGS = $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) $(SOUP_CFLAGS) $(JSON_CFLAGS)
+libmatrix_glib_0_0_la_LIBADD = $(GLIB_LIBS) $(GOBJECT_LIBS) $(SOUP_LIBS) $(JSON_LIBS)
libmatrix_glib_0_0_la_DEPENDENCIES =
CLEANFILES =
@@ -29,7 +31,7 @@ MatrixGlib-$(MATRIX_GLIB_API_VERSION).gir: libmatrix-glib-0.0.la
Matrix_@MATRIX_GLIB_API_VERSION_U@_gir_FILES = $(INST_H_SRC_FILES) $(INST_H_BUILT_FILES) $(filter %.c,$(libmatrix_glib_0_0_la_SOURCES))
Matrix_@MATRIX_GLIB_API_VERSION_U@_gir_LIBS = libmatrix-glib-0.0.la
Matrix_@MATRIX_GLIB_API_VERSION_U@_gir_SCANNERFLAGS = --identifier-prefix=Matrix --symbol-prefix=matrix --warn-all
-Matrix_@MATRIX_GLIB_API_VERSION_U@_gir_INCLUDES = GLib-2.0 GObject-2.0 Soup-2.4
+Matrix_@MATRIX_GLIB_API_VERSION_U@_gir_INCLUDES = GLib-2.0 GObject-2.0 Soup-2.4 Json-1.0
Matrix_@MATRIX_GLIB_API_VERSION_U@_gir_CFLAGS = -D__MATRIX_GLIB_BUILDING__ -I$(top_srcdir) -I$(srcdir) -I$(builddir)
Matrix_@MATRIX_GLIB_API_VERSION_U@_gir_EXPORT_PACKAGES = matrix-glib
INTROSPECTION_GIRS = Matrix-$(MATRIX_GLIB_API_VERSION).gir
diff --git a/src/matrix-api.c b/src/matrix-api.c
index d01085c..63e9f05 100644
--- a/src/matrix-api.c
+++ b/src/matrix-api.c
@@ -18,168 +18,529 @@
#include "matrix-api.h"
-#include
-#include
-
/**
* SECTION:matrix-api
- * @short_description: Low level API calls to communicate with a
- * Matrix.org server
* @title: MatrixAPI
- * @stability: Unstable
- * @include: matrix-glib/matrix.h
+ * @short_description: An interface for actual API implementations,
+ * like #MatrixHTTPAPI
*
- * This is a class for low level communication with a Matrix.org
- * server.
- */
+ * This interface provides a skeleton for all API functionality for
+ * client communication with a Matrix.org homeserver.
+ **/
/**
* MatrixAPI:
*
- * The MatrixAPI object’s instance definition.
+ * An opaque pointer type.
+ **/
+
+/**
+ * MatrixAPIInterface:
+ * @login: virtual function for matrix_api_login()
+ * @register_account: virtual_function for
+ * matrix_api_register_account()
+ * @initial_sync: virtual function for matrix_api_initial_sync()
+ * @event_stream: virtual function for matrix_api_event_stream()
+ * @create_room: virtual function for matrix_api_create_room()
+ * @join_room: virtual function for matrix_api_join_room()
+ * @send_state_event: virtual function for
+ * matrix_api_send_state_event()
+ * @send_message_event: virtual function for
+ * matrix_api_send_message_event()
+ * @send_message: virtual function for matrix_api_send_message()
+ * @send_emote: virtual function for matrix_api_send_emote()
+ * @get_room_name: virtual function for matrix_api_get_room_name()
+ * @get_room_topic: virtual function for matrix_api_get_room_topic()
+ * @leave_room: virtual function for matrix_api_leave_room()
+ * @invite_user: virtual function for matrix_api_invite_user()
+ * @kick_user: virtual function for matrix_api_kick_user()
+ * @set_membership: virtual function for matrix_api_set_membership()
+ * @ban_user: virtual function for matrix_api_ban_user()
+ * @get_room_state: virtual function for matrix_api_get_room_state()
+ * @get_text_body: virtual function for matrix_api_get_text_body()
+ * @get_html_body: virtual function for matrix_api_get_html_body()
+ * @get_emote_body: virtual function for matrix_api_get_emote_body()
+ * @_send: virtual function for matrix_api_send()
+ *
+ * The interface vtable for #MatrixAPI
*/
/**
- * MatrixAPIClass:
- * @parent_class: the parent class structure (#GObjectClass)
+ * MatrixAPICallback:
+ * @api: A #MatrixAPI implementation
+ * @content: the JSON content of the response, as a #JsonNode
+ * @data: User data specified when calling original request function
*
- * The MatrixAPI object’s class definition.
+ * A callback function to use with API calls.
*/
-#define API_ENDPOINT "/_matrix/client/api/v1"
-
-typedef struct _MatrixAPIPrivate {
- SoupSession *soup_session;
- guint txn_id;
- gchar *url;
- gchar *token;
- gboolean validate_cert;
-} MatrixAPIPrivate;
-
-enum {
- PROP_URL = 1,
- N_PROPERTIES
-};
-
-GParamSpec *obj_properties[N_PROPERTIES] = {NULL,};
-
-G_DEFINE_TYPE_WITH_PRIVATE(MatrixAPI, matrix_api, G_TYPE_OBJECT);
+G_DEFINE_INTERFACE(MatrixAPI, matrix_api, G_TYPE_OBJECT);
static void
-matrix_api_finalize(GObject *gobject)
+matrix_api_default_init(MatrixAPIInterface *iface)
{
- g_signal_handlers_destroy(gobject);
- G_OBJECT_CLASS(matrix_api_parent_class)->finalize(gobject);
}
-static void
-matrix_api_set_property(GObject *gobject,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
+/**
+ * matrix_api_ban_user:
+ * @api: a #MatrixAPI implementation
+ * @callback: (scope async): the function to call when the request is
+ * finished
+ * @user_data: user data to pass to the callback function
+ * @room_id: the room ID where the user should be banned
+ * @user_id: the user ID to ban
+ * @reason: (allow-none): the reason of the ban
+ *
+ * Ban the specified user from the specified room. An optional reason
+ * can be specified.
+ */
+void
+matrix_api_ban_user(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id,
+ gchar *user_id,
+ gchar *reason)
{
- MatrixAPI *api = MATRIX_API(gobject);
- MatrixAPIPrivate *priv = matrix_api_get_instance_private(api);
+ g_return_if_fail(MATRIX_IS_API(api));
- switch (prop_id) {
- case PROP_URL:
- {
- const gchar *base_url;
- gchar *last_occurence;
-
- base_url = g_value_get_string(value);
-
- if (!g_str_is_ascii(base_url)) {
- g_warning("URL specified (%s) is not ASCII", base_url);
-
- return;
- }
-
- last_occurence = g_strrstr(base_url, API_ENDPOINT);
-
- if ((g_strcmp0(last_occurence, API_ENDPOINT) == 0) ||
- (g_strcmp0(last_occurence, API_ENDPOINT"/") == 0)) {
- priv->url = g_strdup(base_url);
- } else {
- priv->url = g_strdup_printf(
- "%s%s%s",
- base_url,
- (base_url[strlen(base_url) - 1] == '/') ? "" : "/",
- API_ENDPOINT);
- }
-
- break;
- }
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
- }
+ MATRIX_API_GET_IFACE(api)
+ ->ban_user(api, callback, user_data, room_id, user_id, reason);
}
-static void
-matrix_api_get_property(GObject *gobject,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+/**
+ * matrix_api_create_room:
+ * @api: a #MatrixAPI implementation
+ * @callback: (scope async): the function to call when the request is
+ * finished
+ * @user_data: user data to pass to the callback function
+ * @alias: the alias (name) of the room
+ * @is_public: if %TRUE, the room will be accessible for anyone
+ * @invitees: (allow-none): list of user IDs to invite to the new room
+ *
+ * Create a new room with the given name and invite the users in
+ * @invitees.
+ */
+void
+matrix_api_create_room(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *alias,
+ gboolean is_public,
+ GStrv invitees)
{
- MatrixAPI *api = MATRIX_API(gobject);
- MatrixAPIPrivate *priv = matrix_api_get_instance_private(api);
+ g_return_if_fail(MATRIX_IS_API(api));
- switch (prop_id) {
- case PROP_URL:
- g_value_set_string(value, priv->url);
-
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
- }
+ MATRIX_API_GET_IFACE(api)
+ ->create_room(api, callback, user_data, alias, is_public, invitees);
}
-static void
-matrix_api_class_init(MatrixAPIClass *klass)
+/**
+ * matrix_api_event_stream:
+ * @api: a #MatrixAPI implementation
+ * @callback: (scope async): the function to call when the request is
+ * finished
+ * @user_data: user data to pass to the callback function
+ * @from_token: (allow-none): events will be listed from this token
+ * @timeout: timeout of the request
+ *
+ * Get the event stream, optionally beginning from @from_token.
+ */
+void
+matrix_api_event_stream(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *from_token,
+ gulong timeout)
{
- GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ g_return_if_fail(MATRIX_IS_API(api));
- gobject_class->set_property = matrix_api_set_property;
- gobject_class->get_property = matrix_api_get_property;
- gobject_class->finalize = matrix_api_finalize;
-
- /**
- * MatrixAPI:url:
- *
- * The base URL to use for communication with the Matrix.org
- * server.
- */
- obj_properties[PROP_URL] = g_param_spec_string(
- "url", "Server URL",
- "Matrix.org home server to connect to.",
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
-
- g_object_class_install_properties(gobject_class,
- N_PROPERTIES,
- obj_properties);
+ MATRIX_API_GET_IFACE(api)
+ ->event_stream(api, callback, user_data, from_token, timeout);
}
-static void
-matrix_api_init(MatrixAPI *api)
+/**
+ * matrix_api_get_room_name:
+ * @api: a #MatrixAPI implementation
+ * @callback: (scope async): the function to call when the request is
+ * finished
+ * @user_data: user data to pass to the callback function
+ * @room_id: the room ID to get a name for
+ *
+ * Get the name (alias) of a room.
+ */
+void
+matrix_api_get_room_name(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id)
{
- MatrixAPIPrivate *priv = matrix_api_get_instance_private(api);
+ g_return_if_fail(MATRIX_IS_API(api));
- priv->txn_id = 0;
- priv->url = NULL;
- priv->token = NULL;
- priv->validate_cert = TRUE;
- priv->soup_session = soup_session_new_with_options(
- SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_CONTENT_SNIFFER,
- NULL);
+ MATRIX_API_GET_IFACE(api)
+ ->get_room_name(api, callback, user_data, room_id);
}
-MatrixAPI *
-matrix_api_new(const gchar *base_url, const gchar *token)
+/**
+ * matrix_api_get_room_state:
+ * @api: a #MatrixAPI implementation
+ * @callback: (scope async): the function to call when the request is
+ * finished
+ * @user_data: user data to pass to the callback function
+ * @room_id: the room ID to get a state for
+ *
+ * Get the state of a room.
+ */
+void
+matrix_api_get_room_state(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id)
{
- return g_object_new(MATRIX_TYPE_API,
- "base-url", base_url,
- "token", token,
- NULL);
+ g_return_if_fail(MATRIX_IS_API(api));
+
+ MATRIX_API_GET_IFACE(api)
+ ->get_room_state(api, callback, user_data, room_id);
+}
+
+/**
+ * matrix_api_get_room_topic:
+ * @api: a #MatrixAPI implementation
+ * @callback: (scope async): the function to call when the request is
+ * finished
+ * @user_data: user data to pass to the callback function
+ * @room_id: the room ID to get a topic for
+ *
+ * Get the topic of a room.
+ */
+void
+matrix_api_get_room_topic(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id)
+{
+ g_return_if_fail(MATRIX_IS_API(api));
+
+ MATRIX_API_GET_IFACE(api)
+ ->get_room_topic(api, callback, user_data, room_id);
+}
+
+/**
+ * matrix_api_initial_sync:
+ * @api: a #MatrixAPI implementation
+ * @callback: (scope async): the function to call when the request is
+ * finished
+ * @user_data: user data to pass to the callback function
+ * @limit: the maximum number of events to get
+ *
+ * perform an initial sync of events
+ */
+void
+matrix_api_initial_sync(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ guint limit)
+{
+ g_return_if_fail(MATRIX_IS_API(api));
+
+ MATRIX_API_GET_IFACE(api)
+ ->initial_sync(api, callback, user_data, limit);
+}
+
+/**
+ * matrix_api_invite_user:
+ * @api: a #MatrixAPI implementation
+ * @callback: (scope async): the function to call when the request is
+ * finished
+ * @user_data: user data to pass to the callback function
+ * @room_id: the room ID to invite the user to
+ * @user_id: the user ID to invite
+ *
+ * Invite a user to a room.
+ */
+void
+matrix_api_invite_user(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id,
+ gchar *user_id)
+{
+ g_return_if_fail(MATRIX_IS_API(api));
+
+ MATRIX_API_GET_IFACE(api)
+ ->invite_user(api, callback, user_data, room_id, user_id);
+}
+
+/**
+ * matrix_api_join_room:
+ * @api: a #MatrixAPI implementation
+ * @callback: (scope async): the function to call when the request is
+ * finished
+ * @user_data: user data to pass to the callback function
+ * @room_id_or_alias: the room ID or room alias to join to
+ *
+ * Join a room.
+ */
+void
+matrix_api_join_room(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id_or_alias)
+{
+ g_return_if_fail(MATRIX_IS_API(api));
+
+ MATRIX_API_GET_IFACE(api)
+ ->join_room(api, callback, user_data, room_id_or_alias);
+}
+
+/**
+ * matrix_api_kick_user:
+ * @api: a #MatrixAPI implementation
+ * @callback: (scope async): the function to call when the request is
+ * finished
+ * @user_data: user data to pass to the callback function
+ * @room_id: the room ID to kick the user from
+ * @user_id: the user to kick
+ * @reason: (allow-none): the reason of kicking
+ *
+ * Kick a user from a room, with an optional reason.
+ */
+void
+matrix_api_kick_user(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id,
+ gchar *user_id,
+ gchar *reason)
+{
+ g_return_if_fail(MATRIX_IS_API(api));
+
+ MATRIX_API_GET_IFACE(api)
+ ->kick_user(api, callback, user_data, room_id, user_id, reason);
+}
+
+/**
+ * matrix_api_leave_room:
+ * @api: a #MatrixAPI implementation
+ * @callback: (scope async): the function to call when the request is
+ * finished
+ * @user_data: user data to pass to the callback function
+ * @room_id: the room ID to kick the user from
+ *
+ * Leave a room
+ */
+void
+matrix_api_leave_room(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id)
+{
+ g_return_if_fail(MATRIX_IS_API(api));
+
+ MATRIX_API_GET_IFACE(api)
+ ->leave_room(api, callback, user_data, room_id);
+}
+
+/**
+ * matrix_api_login:
+ * @api: a #MatrixAPI implementation
+ * @callback: (scope async): the function to call when the request is
+ * finished
+ * @user_data: user data to pass to the callback function
+ * @login_type: the login type to use
+ * @parameters: (allow-none): parameters to pass for the login request
+ *
+ * Attempt to login with type @login_type. Implementations of this
+ * method must set the token property on a successful login.
+ */
+void
+matrix_api_login(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *login_type,
+ GHashTable *parameters)
+{
+ g_return_if_fail(MATRIX_IS_API(api));
+
+ MATRIX_API_GET_IFACE(api)
+ ->login(api, callback, user_data, login_type, parameters);
+}
+
+/**
+ * matrix_api_register_account:
+ * @api: a #MatrixAPI implementation
+ * @callback: (scope async): the function to call when the request is
+ * finished
+ * @user_data: user data to pass to the callback function
+ * @login_type: the login type to use
+ * @parameters: (allow-none): parameters to pass for the registration
+ * request
+ *
+ * Attempt to register with type @login_type. Implementations of this
+ * method must set the token property on a successful login.
+ */
+void
+matrix_api_register_account(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *login_type,
+ GHashTable *parameters)
+{
+ g_return_if_fail(MATRIX_IS_API(api));
+
+ MATRIX_API_GET_IFACE(api)
+ ->register_account(api, callback, user_data, login_type, parameters);
+}
+
+/**
+ * matrix_api_send_emote:
+ * @api: a #MatrixAPI implementation
+ * @callback: (scope async): the function to call when the request is
+ * finished
+ * @user_data: user data to pass to the callback function
+ * @room_id: the room to send the emote to
+ * @text_content: the emote text to send
+ *
+ * Send an emote to the room.
+ */
+void
+matrix_api_send_emote(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id,
+ gchar *text_content)
+{
+ g_return_if_fail(MATRIX_IS_API(api));
+
+ MATRIX_API_GET_IFACE(api)
+ ->send_emote(api, callback, user_data, room_id, text_content);
+}
+
+/**
+ * matrix_api_send_message:
+ * @api: a #MatrixAPI implementation
+ * @callback: (scope async): the function to call when the request is
+ * finished
+ * @user_data: user data to pass to the callback function
+ * @room_id: the room to send the emote to
+ * @text_content: the emote text to send
+ * @msg_type: the type of the message to be sent
+ *
+ * Send a custom message to the room.
+ */
+void
+matrix_api_send_message(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id,
+ gchar *text_content,
+ gchar *msg_type)
+{
+ g_return_if_fail(MATRIX_IS_API(api));
+
+ MATRIX_API_GET_IFACE(api)
+ ->send_message(api,
+ callback, user_data,
+ room_id,
+ text_content,
+ msg_type);
+}
+
+/**
+ * matrix_api_send_message_event:
+ * @api: a #MatrixAPI implementation
+ * @callback: (scope async): the function to call when the request is
+ * finished
+ * @user_data: user data to pass to the callback function
+ * @room_id: the room to send the emote to
+ * @event_type: the type of the event to send
+ * @content: the content of the event as a #JsonNode
+ * @txn_id: the transaction ID to use
+ *
+ * Send a message event to the room.
+ */
+void
+matrix_api_send_message_event(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id,
+ gchar *event_type,
+ JsonNode *content,
+ guint txn_id)
+{
+ g_return_if_fail(MATRIX_IS_API(api));
+
+ MATRIX_API_GET_IFACE(api)
+ ->send_message_event(api,
+ callback, user_data,
+ room_id,
+ event_type,
+ content,
+ txn_id);
+}
+
+/**
+ * matrix_api_send_state_event:
+ * @api: a #MatrixAPI implementation
+ * @callback: (scope async): the function to call when the request is
+ * finished
+ * @user_data: user data to pass to the callback function
+ * @room_id: the room to send the emote to
+ * @event_type: the type of the event to send
+ * @content: the content of the event as a #JsonNode
+ * @state_key: the state key to send
+ *
+ * Send a state event to the room
+ */
+void
+matrix_api_send_state_event(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id,
+ gchar *event_type,
+ JsonNode *content,
+ gchar *state_key)
+{
+ g_return_if_fail(MATRIX_IS_API(api));
+
+ MATRIX_API_GET_IFACE(api)
+ ->send_state_event(api,
+ callback, user_data,
+ room_id,
+ event_type,
+ content,
+ state_key);
+}
+
+/**
+ * matrix_api_set_membership:
+ * @api: a #MatrixAPI implementation
+ * @callback: (scope async): the function to call when the request is
+ * finished
+ * @user_data: user data to pass to the callback function
+ * @room_id: the room to send the emote to
+ * @user_id: the user of whom membership will be set
+ * @membership: the new membership of the user
+ * @reason: (allow-none): the reason of the change
+ *
+ * Set the membership of the user for the given room.
+ */
+void
+matrix_api_set_membership(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id,
+ gchar *user_id,
+ gchar *membership,
+ gchar *reason)
+{
+ g_return_if_fail(MATRIX_IS_API(api));
+
+ MATRIX_API_GET_IFACE(api)
+ ->set_membership(api,
+ callback, user_data,
+ room_id,
+ user_id,
+ membership,
+ reason);
}
diff --git a/src/matrix-api.h b/src/matrix-api.h
index 00ab55e..190f9b1 100644
--- a/src/matrix-api.h
+++ b/src/matrix-api.h
@@ -16,80 +16,245 @@
* .
*/
-#ifndef __MATRIX_API_H__
-#define __MATRIX_API_H__
+#ifndef __MATRIX_API_IFACE_H__
+#define __MATRIX_API_IFACE_H__
#include
+#include
G_BEGIN_DECLS
#define MATRIX_TYPE_API (matrix_api_get_type())
#define MATRIX_API(o) (G_TYPE_CHECK_INSTANCE_CAST((o), MATRIX_TYPE_API, MatrixAPI))
-#define MATRIX_API_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), MATRIX_TYPE_API, MatrixAPIClass))
#define MATRIX_IS_API(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), MATRIX_TYPE_API))
-#define MATRIX_IS_API_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), MATRIX_TYPE_API))
-#define MATRIX_API_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), MATRIX_TYPE_API, MatrixAPIClass))
+#define MATRIX_API_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE((o), MATRIX_TYPE_API, MatrixAPIInterface))
-typedef struct _MatrixAPI MatrixAPI;
-typedef struct _MatrixAPIClass MatrixAPIClass;
+typedef struct _MatrixAPIInterface MatrixAPIInterface;
+typedef struct _MatrixAPI MatrixAPI;
-struct _MatrixAPI {
- /* Parent instance structure */
- GObject parent_instance;
+typedef void (*MatrixAPICallback)(MatrixAPI *api, JsonNode *content, gpointer data);
- /* Instance members */
+struct _MatrixAPIInterface {
+ /*< private >*/
+ GTypeInterface g_iface;
+
+ /*< public >*/
+
+ void (*register_account)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *login_type,
+ GHashTable *parameters);
+ void (*login)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *login_type,
+ GHashTable *parameters);
+ void (*initial_sync)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ guint limit);
+ void (*event_stream)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *from_token,
+ gulong timeout);
+ void (*create_room)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_alias,
+ gboolean is_public,
+ GStrv invitees);
+ void (*join_room)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id_or_alias);
+ void (*send_state_event)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id,
+ gchar *event_type,
+ JsonNode *content,
+ gchar *state_key);
+ void (*send_message_event)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id,
+ gchar *event_type,
+ JsonNode *content,
+ guint txn_id);
+ void (*send_message)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id,
+ gchar *text_content,
+ gchar *msg_type);
+ void (*send_emote)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id,
+ gchar *text_content);
+ void (*get_room_name)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id);
+ void (*get_room_topic)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id);
+ void (*leave_room)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id);
+ void (*invite_user)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id,
+ gchar *user_id);
+ void (*kick_user)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id,
+ gchar *user_id,
+ gchar *reason);
+ void (*set_membership)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id,
+ gchar *user_id,
+ gchar *membership,
+ gchar *reason);
+ void (*ban_user)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id,
+ gchar *user_id,
+ gchar *reason);
+ void (*get_room_state)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id);
+ void (*get_text_body)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *text,
+ gchar *msgtype);
+ void (*get_html_body)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *html,
+ gchar *msgtype);
+ void (*get_emote_body)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *text);
+ void (*_send)(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *method,
+ gchar *path,
+ gchar *content,
+ gchar *query_params,
+ gchar *headers);
+
+ /*< private >*/
+ void *padding[20];
};
-struct _MatrixAPIClass {
- GObjectClass parent_class;
-};
-
-GType matrix_api_get_type(void) G_GNUC_CONST;
-
-void matrix_api_initial_sync(MatrixAPI *api, guint limit);
-void matrix_api_set_validate_certificate(MatrixAPI *api, gboolean valid);
-gboolean matrix_api_get_validate_certificate(MatrixAPI *api);
-void matrix_api_register(MatrixAPI *api, gchar *login_type, ...);
-void matrix_api_login(MatrixAPI *api, gchar *login_type, ...);
+void matrix_api_initial_sync(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ guint limit);
+void matrix_api_register_account(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *login_type,
+ GHashTable *parameters);
+void matrix_api_login(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *login_type,
+ GHashTable *parameters);
void matrix_api_create_room(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
gchar *alias,
gboolean is_public,
- GList *invitees);
-void matrix_api_join_room(MatrixAPI *api, gchar *room_id_or_alias);
-void matrix_api_event_stream(MatrixAPI *api, gchar *from_token, gulong timeout);
+ GStrv invitees);
+void matrix_api_join_room(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id_or_alias);
+void matrix_api_event_stream(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *from_token,
+ gulong timeout);
void matrix_api_send_state_event(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
gchar *room_id,
gchar *event_type,
JsonNode *content,
gchar *state_key);
void matrix_api_send_message_event(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
gchar *room_id,
gchar *event_type,
JsonNode *content,
guint txn_id);
void matrix_api_send_message(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
gchar *room_id,
gchar *text_content,
gchar *msg_type);
-void matrix_api_send_emote(MatrixAPI *api, gchar *room_id, gchar *text_content);
-void matrix_api_get_room_name(MatrixAPI *api, gchar *room_id);
-void matrix_api_get_room_topic(MatrixAPI *api, gchar *room_id);
-void matrix_api_leave_room(MatrixAPI *api, gchar *room_id);
-void matrix_api_invite_user(MatrixAPI *api, gchar *room_id, gchar *user_id);
+void matrix_api_send_emote(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id,
+ gchar *text_content);
+void matrix_api_get_room_name(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id);
+void matrix_api_get_room_topic(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id);
+void matrix_api_leave_room(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id);
+void matrix_api_invite_user(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id,
+ gchar *user_id);
void matrix_api_kick_user(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
gchar *room_id,
gchar *user_id,
gchar *reason);
void matrix_api_set_membership(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
gchar *room_id,
gchar *user_id,
gchar *membership,
gchar *reason);
void matrix_api_ban_user(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
gchar *room_id,
gchar *user_id,
gchar *reason);
-void matrix_api_get_room_state(MatrixAPI *api, gchar *room_id);
+void matrix_api_get_room_state(MatrixAPI *api,
+ MatrixAPICallback callback,
+ gpointer user_data,
+ gchar *room_id);
void matrix_api_get_text_body(MatrixAPI *api, gchar *text, gchar *msgtype);
void matrix_api_get_html_body(MatrixAPI *api, gchar *html, gchar *msgtype);
void matrix_api_get_emote_body(MatrixAPI *api, gchar *text);
@@ -102,4 +267,4 @@ void _send(MatrixAPI *api,
G_END_DECLS
-#endif /* __MATRIX_API_H__ */
+#endif /* __MATRIX_API_IFACE_H__ */
diff --git a/src/matrix-http-api.c b/src/matrix-http-api.c
new file mode 100644
index 0000000..6b58885
--- /dev/null
+++ b/src/matrix-http-api.c
@@ -0,0 +1,251 @@
+/*
+ * This file is part of matrix-glib-sdk
+ *
+ * matrix-glib-sdk is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * matrix-glib-sdk 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with matrix-glib-sdk. If not, see
+ * .
+ */
+
+#include "matrix-http-api.h"
+#include "matrix-api.h"
+
+#include
+#include
+
+/**
+ * SECTION:matrix-http-api
+ * @short_description: Low level API calls to communicate with a
+ * Matrix.org server via HTTP
+ * @title: MatrixHTTPAPI
+ * @stability: Unstable
+ * @include: matrix-glib/matrix.h
+ *
+ * This is a class for low level communication with a Matrix.org
+ * server via HTTP.
+ */
+
+/**
+ * MatrixHTTPAPI:
+ *
+ * The MatrixHTTPAPI object’s instance definition.
+ */
+
+/**
+ * MatrixHTTPAPIClass:
+ * @parent_class: the parent class structure (#GObjectClass)
+ *
+ * The MatrixHTTPAPI object’s class definition.
+ */
+
+#define API_ENDPOINT "/_matrix/client/api/v1"
+
+typedef struct _MatrixHTTPAPIPrivate {
+ SoupSession *soup_session;
+ guint txn_id;
+ gchar *url;
+ gchar *token;
+ gboolean validate_certificate;
+} MatrixHTTPAPIPrivate;
+
+enum {
+ PROP_VALIDATE_CERTIFICATE = 1,
+ PROP_URL,
+ N_PROPERTIES
+};
+
+GParamSpec *obj_properties[N_PROPERTIES] = {NULL,};
+
+static void matrix_http_api_matrix_api_init(MatrixAPIInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE(MatrixHTTPAPI, matrix_http_api, G_TYPE_OBJECT,
+ G_ADD_PRIVATE(MatrixHTTPAPI)
+ G_IMPLEMENT_INTERFACE(MATRIX_TYPE_API, matrix_http_api_matrix_api_init));
+
+static void
+matrix_http_api_matrix_api_init(MatrixAPIInterface *iface)
+{}
+
+static void
+matrix_http_api_finalize(GObject *gobject)
+{
+ g_signal_handlers_destroy(gobject);
+ G_OBJECT_CLASS(matrix_http_api_parent_class)->finalize(gobject);
+}
+
+static void
+matrix_http_api_set_property(GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MatrixHTTPAPI *api = MATRIX_HTTP_API(gobject);
+ MatrixHTTPAPIPrivate *priv = matrix_http_api_get_instance_private(api);
+
+ switch (prop_id) {
+ case PROP_VALIDATE_CERTIFICATE:
+ priv->validate_certificate = g_value_get_boolean(value);
+
+ break;
+
+ case PROP_URL:
+ {
+ const gchar *base_url;
+ gchar *last_occurence;
+
+ base_url = g_value_get_string(value);
+
+ if (!g_str_is_ascii(base_url)) {
+ g_warning("URL specified (%s) is not ASCII", base_url);
+
+ return;
+ }
+
+ last_occurence = g_strrstr(base_url, API_ENDPOINT);
+
+ if ((g_strcmp0(last_occurence, API_ENDPOINT) == 0) ||
+ (g_strcmp0(last_occurence, API_ENDPOINT"/") == 0)) {
+ priv->url = g_strdup(base_url);
+ } else {
+ priv->url = g_strdup_printf(
+ "%s%s%s",
+ base_url,
+ (base_url[strlen(base_url) - 1] == '/') ? "" : "/",
+ API_ENDPOINT);
+ }
+
+ break;
+ }
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+ }
+}
+
+static void
+matrix_http_api_get_property(GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MatrixHTTPAPI *api = MATRIX_HTTP_API(gobject);
+ MatrixHTTPAPIPrivate *priv = matrix_http_api_get_instance_private(api);
+
+ switch (prop_id) {
+ case PROP_VALIDATE_CERTIFICATE:
+ g_value_set_boolean(value, priv->validate_certificate);
+
+ break;
+
+ case PROP_URL:
+ g_value_set_string(value, priv->url);
+
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+ }
+}
+
+static void
+matrix_http_api_class_init(MatrixHTTPAPIClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+ gobject_class->set_property = matrix_http_api_set_property;
+ gobject_class->get_property = matrix_http_api_get_property;
+ gobject_class->finalize = matrix_http_api_finalize;
+
+ /**
+ * MatrixHTTPAPI:validate-certificate:
+ *
+ * Set to %FALSE if you don’t want the SSL/TLS certificates to be
+ * validated.
+ */
+ obj_properties[PROP_VALIDATE_CERTIFICATE] = g_param_spec_boolean(
+ "validate-certificate",
+ "Validate certificate",
+ "TRUE if server certificates should be validated",
+ TRUE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * MatrixHTTPAPI:url:
+ *
+ * The base URL to use for communication with the Matrix.org
+ * server.
+ */
+ obj_properties[PROP_URL] = g_param_spec_string(
+ "url", "Server URL",
+ "Matrix.org home server to connect to.",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties(gobject_class,
+ N_PROPERTIES,
+ obj_properties);
+}
+
+static void
+matrix_http_api_init(MatrixHTTPAPI *api)
+{
+ MatrixHTTPAPIPrivate *priv = matrix_http_api_get_instance_private(api);
+
+ priv->txn_id = 0;
+ priv->url = NULL;
+ priv->token = NULL;
+ priv->validate_certificate = TRUE;
+ priv->soup_session = soup_session_new_with_options(
+ SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_CONTENT_SNIFFER,
+ NULL);
+}
+
+MatrixHTTPAPI *
+matrix_http_api_new(const gchar *base_url, const gchar *token)
+{
+ return g_object_new(MATRIX_TYPE_HTTP_API,
+ "base-url", base_url,
+ "token", token,
+ NULL);
+}
+
+/**
+ * matrix_http_api_set_validate_certificate:
+ * @api: a #MatrixHTTPAPI implementation
+ * @validate_certificate: %TRUE if server certificates should be
+ * validated
+ *
+ * Sets if server certificates should be validated.
+ */
+void
+matrix_http_api_set_validate_certificate(MatrixHTTPAPI *api,
+ gboolean validate_certificate)
+{
+ MatrixHTTPAPIPrivate *priv = matrix_http_api_get_instance_private(api);
+
+ priv->validate_certificate = validate_certificate;
+}
+
+/**
+ * matrix_http_api_get_validate_certificate:
+ * @api: a #MatrixHTTPAPI implementation
+ *
+ * Gets the value set by matrix_http_api_set_validate_certificate()
+ *
+ * Returns: %TRUE if the server certificates should be validated
+ */
+gboolean
+matrix_http_api_get_validate_certificate(MatrixHTTPAPI *api)
+{
+ MatrixHTTPAPIPrivate *priv = matrix_http_api_get_instance_private(api);
+
+ return priv->validate_certificate;
+}
diff --git a/src/matrix-http-api.h b/src/matrix-http-api.h
new file mode 100644
index 0000000..3b45672
--- /dev/null
+++ b/src/matrix-http-api.h
@@ -0,0 +1,54 @@
+/*
+ * This file is part of matrix-glib-sdk
+ *
+ * matrix-glib-sdk is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * matrix-glib-sdk 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with matrix-glib-sdk. If not, see
+ * .
+ */
+
+#ifndef __MATRIX_HTTP_API_H__
+#define __MATRIX_HTTP_API_H__
+
+#include
+
+G_BEGIN_DECLS
+
+#define MATRIX_TYPE_HTTP_API (matrix_http_api_get_type())
+#define MATRIX_HTTP_API(o) (G_TYPE_CHECK_INSTANCE_CAST((o), MATRIX_TYPE_HTTP_API, MatrixHTTPAPI))
+#define MATRIX_HTTP_API_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), MATRIX_TYPE_HTTP_API, MatrixHTTPAPIClass))
+#define MATRIX_IS_HTTP_API(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), MATRIX_TYPE_HTTP_API))
+#define MATRIX_IS_HTTP_API_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), MATRIX_TYPE_HTTP_API))
+#define MATRIX_HTTP_API_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), MATRIX_TYPE_HTTP_API, MatrixHTTPAPIClass))
+
+typedef struct _MatrixHTTPAPI MatrixHTTPAPI;
+typedef struct _MatrixHTTPAPIClass MatrixHTTPAPIClass;
+
+struct _MatrixHTTPAPI {
+ /* Parent instance structure */
+ GObject parent_instance;
+
+ /* Instance members */
+};
+
+struct _MatrixHTTPAPIClass {
+ GObjectClass parent_class;
+};
+
+GType matrix_http_api_get_type(void) G_GNUC_CONST;
+void matrix_http_api_set_validate_certificate(MatrixHTTPAPI *api,
+ gboolean validate_certificate);
+gboolean matrix_http_api_get_validate_certificate(MatrixHTTPAPI *api);
+
+G_END_DECLS
+
+#endif /* __MATRIX_HTTP_API_H__ */