grim/purple-spasm

3c2a35b27899
Add some basic send message support and replies for pings
/*
* PurpleSpasm - A Twitch Protocol Plugin
* Copyright (C) 2017 Gary Kramlich <grim@reaperworld.com>
*
* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <libsoup/soup.h>
#include "debug.h"
#include "spasm.h"
#include "spasm-const.h"
#include "spasm-rest.h"
/******************************************************************************
* Types
*****************************************************************************/
typedef struct {
PurpleSpasmAccount *sa;
PurpleSpasmRestCallback cb;
gpointer data;
} PurpleSpasmRestCallbackData;
/******************************************************************************
* Callbacks
*****************************************************************************/
static void
_purple_spasm_request_cb(GObject *obj, GAsyncResult *res,
gpointer data)
{
GInputStream *istream = NULL;
GError *error = NULL;
JsonParser *parser = NULL;
JsonNode *root = NULL;
JsonObject *json_obj = NULL;
PurpleSpasmRestCallbackData *cb_data = (PurpleSpasmRestCallbackData *)data;
istream = soup_session_send_finish(SOUP_SESSION(obj), res, &error);
if(error) {
cb_data->cb(cb_data->sa, NULL, error, cb_data->data);
g_free(cb_data);
return;
}
parser = json_parser_new();
json_parser_load_from_stream(parser, istream, NULL, &error);
if(error) {
cb_data->cb(cb_data->sa, NULL, error, cb_data->data);
g_free(cb_data);
g_object_unref(G_OBJECT(parser));
return;
}
root = json_parser_get_root(parser);
if(root == NULL || !JSON_NODE_HOLDS_OBJECT(root)) {
error = g_error_new(
PURPLE_SPASM_DOMAIN,
0,
"invalid json response"
);
cb_data->cb(cb_data->sa, NULL, error, cb_data->data);
g_error_free(error);
g_free(cb_data);
g_object_unref(G_OBJECT(parser));
return;
}
json_obj = json_node_get_object(root);
if(json_obj == NULL) {
error = g_error_new(
PURPLE_SPASM_DOMAIN,
0,
"json is not an object"
);
cb_data->cb(cb_data->sa, NULL, error, cb_data->data);
g_error_free(error);
g_free(cb_data);
g_object_unref(G_OBJECT(parser));
return;
}
if(json_object_has_member(json_obj, "error")) {
purple_debug_info("spasm", "error: %s\n", json_object_get_string_member(json_obj, "error"));
error = g_error_new(
PURPLE_SPASM_DOMAIN,
0,
"error : %s : %" G_GINT64_FORMAT,
json_object_get_string_member(json_obj, "message"),
json_object_get_int_member(json_obj, "status")
);
cb_data->cb(cb_data->sa, NULL, error, cb_data->data);
g_error_free(error);
g_free(cb_data);
g_object_unref(G_OBJECT(parser));
return;
}
cb_data->cb(cb_data->sa, parser, NULL, cb_data->data);
g_object_unref(G_OBJECT(parser));
}
/******************************************************************************
* API
*****************************************************************************/
void
purple_spasm_rest_request(PurpleSpasmAccount *sa, const gchar *method,
const gchar *path, const gchar *body,
PurpleSpasmRestCallback callback, gpointer data)
{
PurpleSpasmRestCallbackData *cb;
SoupMessage *msg = NULL;
SoupSession *session = NULL;
gchar *url = NULL, *auth = NULL;
g_return_if_fail(sa);
url = g_build_filename(PURPLE_SPASM_BASE_URL, path, NULL);
msg = soup_message_new(method, url);
g_free(url);
// Set the Client-ID header
soup_message_headers_replace(
msg->request_headers,
"Client-ID",
PURPLE_SPASM_OAUTH2_CLIENT_ID
);
// Set the Accept header
soup_message_headers_replace(
msg->request_headers,
"Accept",
PURPLE_SPASM_CONTENT_TYPE
);
// Set the authorization header to the access token
auth = g_strdup_printf("OAuth %s", purple_spasm_account_get_access_token(sa));
soup_message_headers_replace(
msg->request_headers,
"Authorization", auth
);
g_free(auth);
cb = g_new0(PurpleSpasmRestCallbackData, 1);
cb->sa = sa;
cb->cb = callback;
cb->data = data;
session = purple_spasm_account_get_session(sa);
soup_session_send_async(
session,
msg,
purple_spasm_account_get_cancellable(sa),
_purple_spasm_request_cb,
cb
);
g_object_unref(G_OBJECT(session));
}