Image mime uploads

FossilOrigin-Name: e754d3788e56b835300a96cab662483f74fd4abe088caac919adeedc20340ef8
This commit is contained in:
me@ow.nekobit.net 2022-04-07 02:08:36 +00:00
parent b2c0435aed
commit 69c12e124e
4 changed files with 128 additions and 5 deletions

View file

@ -16,7 +16,7 @@
#ifndef MASTODONT_ATTACHMENT
#define MASTODONT_ATTACHMENT
#include "mastodont_types.h"
/* Status: Complete, not implemented */
#include "mastodont_fetch.h"
enum mstdnt_attachment_type
{
@ -39,6 +39,26 @@ struct mstdnt_attachment
char* blurhash;
};
struct mstdnt_upload_media_args
{
char* file;
char* thumbnail;
char* description;
/* TODO focus */
};
int mstdnt_attachment_result(struct mstdnt_fetch_results* results,
struct mstdnt_storage* storage,
struct mstdnt_attachment* att);
void _mstdnt_val_attachments_call(cJSON* v, void* _type);
void load_attachment_from_json(struct mstdnt_attachment* att, cJSON* att_json);
int mastodont_upload_media(mastodont_t* api,
struct mstdnt_upload_media_args* args,
struct mstdnt_storage* storage,
struct mstdnt_attachment* attachment);
void cleanup_attachments(struct mstdnt_attachment* attachment);
void _mstdnt_val_attachments_call(cJSON* v, void* _type);

View file

@ -17,8 +17,10 @@
#include <stdlib.h>
#include <mastodont_attachment.h>
#include <mastodont_json_helper.h>
#include <mastodont_request.h>
#include <mastodont_query.h>
static void load_attachment_from_json(struct mstdnt_attachment* att, cJSON* att_json)
void load_attachment_from_json(struct mstdnt_attachment* att, cJSON* att_json)
{
cJSON* it;
@ -42,6 +44,22 @@ static void load_attachment_from_json(struct mstdnt_attachment* att, cJSON* att_
}
}
int mstdnt_attachment_result(struct mstdnt_fetch_results* results,
struct mstdnt_storage* storage,
struct mstdnt_attachment* att)
{
/* Can be null sometimes */
if (!att) return 0;
cJSON* root;
if (_mstdnt_json_init(&root, results, storage) ||
!cJSON_IsObject(root))
return 1;
load_attachment_from_json(att, root->child);
return 0;
}
void _mstdnt_val_attachments_call(cJSON* v, void* _type)
{
struct _mstdnt_generic_args* args = _type;
@ -70,6 +88,42 @@ void _mstdnt_val_attachments_call(cJSON* v, void* _type)
}
}
static int mstdnt_attachment_callback(struct mstdnt_fetch_results* results,
struct mstdnt_storage* storage,
void* _args)
{
return mstdnt_attachment_result(results, storage, _args);
}
int mastodont_upload_media(mastodont_t* api,
struct mstdnt_upload_media_args* args,
struct mstdnt_storage* storage,
struct mstdnt_attachment* attachment)
{
union param_value u_file, u_thumbnail, u_description;
u_file.s = args->file;
u_thumbnail.s = args->thumbnail;
u_description.s = args->description;
struct _mstdnt_query_param params[] = {
{ _MSTDNT_QUERY_STRING, "file", u_file },
{ _MSTDNT_QUERY_STRING, "thumbnail", u_thumbnail },
{ _MSTDNT_QUERY_STRING, "description", u_description },
};
struct mastodont_request_args req_args = {
storage,
"api/v1/media",
NULL, 0,
params, _mstdnt_arr_len(params),
CURLOPT_MIMEPOST,
attachment,
mstdnt_attachment_callback,
};
return mastodont_request(api, &req_args);
}
void cleanup_attachments(struct mstdnt_attachment* attachment)
{
if (attachment) free(attachment);

View file

@ -77,7 +77,9 @@ int mastodont_fetch_curl(mastodont_t* mstdnt,
curl_easy_setopt(mstdnt->curl, CURLOPT_SSL_VERIFYHOST,
!MSTDNT_T_FLAG_ISSET(mstdnt, MSTDNT_FLAG_SSL_UNVERIFIED));
/* PUT, POST, GET */
curl_easy_setopt(mstdnt->curl, request_t, 1);
/* Mimes are expected to be set beforehand manually */
if (request_t != CURLOPT_MIMEPOST)
curl_easy_setopt(mstdnt->curl, request_t, 1);
res = curl_easy_perform(mstdnt->curl);

View file

@ -20,11 +20,47 @@
#include <mastodont_request.h>
#include <mastodont_query.h>
#define CONV_SIZE 64
static void mime_params_post(curl_mime* mime,
struct _mstdnt_query_param* params,
size_t size)
{
size_t i;
curl_mimepart* part;
char conv_val[CONV_SIZE];
char* val_ptr;
char* escape_str;
for (i = 0; i < size; ++i)
{
part = curl_mime_addpart(mime);
switch (params[i].type)
{
case _MSTDNT_QUERY_INT:
snprintf(conv_val, CONV_SIZE, "%d", params[i].value.i);
val_ptr = conv_val;
break;
case _MSTDNT_QUERY_STRING:
val_ptr = params[i].value.s;
break;
default:
/* Any other types are not supported! */
break;
}
curl_mime_data(part, val_ptr, CURL_ZERO_TERMINATED);
curl_mime_name(part, params[i].key);
}
}
int mastodont_request(mastodont_t* data, struct mastodont_request_args* args)
{
int res = 0, curlerror = 0;
struct mstdnt_storage* storage = args->storage;
struct mstdnt_fetch_results results = { 0 };
curl_mime* mime = NULL;
char* post;
char* url_query = args->params_query ?
_mstdnt_query_string(data, args->url, args->params_query, args->params_query_len) :
@ -34,11 +70,20 @@ int mastodont_request(mastodont_t* data, struct mastodont_request_args* args)
memset(storage, 0, sizeof(struct mstdnt_storage));
storage->needs_cleanup = 0;
if (args->params_post)
if (args->params_post && args->request_type == CURLOPT_POST)
{
post = _mstdnt_query_string(data, NULL, args->params_post, args->params_post_len);
curl_easy_setopt(data->curl, CURLOPT_POSTFIELDS, post);
}
else if (args->params_post && args->request_type == CURLOPT_MIMEPOST)
{
/* Initialize MIME post */
mime = curl_mime_init(data->curl);
curl_easy_setopt(data->curl, args->request_type, mime);
/* Let's handle query params array */
mime_params_post(mime, args->params_post, args->params_post_len);
}
/* Make it empty, no post data provided */
/* I'm not sure why the pleroma api does this */
else if (args->request_type == CURLOPT_POST)
@ -46,6 +91,8 @@ int mastodont_request(mastodont_t* data, struct mastodont_request_args* args)
curlerror = mastodont_fetch_curl(data, url_query, &results, args->request_type);
if (mime) curl_mime_free(mime);
if (curlerror != CURLE_OK)
{
res = 1;
@ -68,7 +115,7 @@ int mastodont_request(mastodont_t* data, struct mastodont_request_args* args)
cleanup_res:
mastodont_fetch_results_cleanup(&results);
cleanup:
if (args->params_post) free(post);
if (args->params_post && args->request_type == CURLOPT_POST) free(post);
/* Only free if params_query set */
if (args->params_query) free(url_query);
return res;