From c2535042d1037fa408b83492353530b0b9fa83ab Mon Sep 17 00:00:00 2001 From: "me@ow.nekobit.net" Date: Wed, 13 Apr 2022 02:59:35 +0000 Subject: [PATCH] Scrobbles Untested FossilOrigin-Name: 21270d0e934ba72bfff1da3abbf9487f143eebd2be1729148d05ecc2020f8606 --- include/mastodont_scrobbles.h | 65 ++++++++++++++++++ src/scrobbles.c | 125 ++++++++++++++++++++++++++++++++++ src/status.c | 9 ++- 3 files changed, 194 insertions(+), 5 deletions(-) create mode 100644 include/mastodont_scrobbles.h create mode 100644 src/scrobbles.c diff --git a/include/mastodont_scrobbles.h b/include/mastodont_scrobbles.h new file mode 100644 index 0000000..e37d06f --- /dev/null +++ b/include/mastodont_scrobbles.h @@ -0,0 +1,65 @@ +/* + * This program 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. + * + * 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 Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MASTODONT_SCROBBLES_H +#define MASTODONT_SCROBBLES_H +#include +#include +#include +#include + +struct mstdnt_scrobble +{ + struct mstdnt_account account; + char* album; + char* artist; + char* created_at; + char* id; + int length; + char* title; +}; + +struct mstdnt_get_scrobbles_args +{ + char* max_id; + char* min_id; + char* since_id; + int offset; + int limit; +}; + +struct _mstdnt_scrobbles_cb_args +{ + struct mstdnt_scrobble** scrobbles; + size_t* size; +}; + +int mastodont_get_scrobbles(mastodont_t* data, + char* id, + struct mstdnt_get_scrobbles_args* args, + struct mstdnt_storage* storage, + struct mstdnt_scrobble* scrobbles[], + size_t* size); + +int mstdnt_scrobbles_result(struct mstdnt_fetch_results* results, + struct mstdnt_storage* storage, + struct mstdnt_scrobble* scrobbles[], + size_t* size); + +int _mstdnt_scrobbles_from_result_callback(struct mstdnt_fetch_results* results, + struct mstdnt_storage* storage, + void* arg); + +#endif /* MASTODONT_SCROBBLES_H */ diff --git a/src/scrobbles.c b/src/scrobbles.c new file mode 100644 index 0000000..654a2a0 --- /dev/null +++ b/src/scrobbles.c @@ -0,0 +1,125 @@ +/* + * This program 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. + * + * 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 Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +int mstdnt_scrobble_from_json(struct mstdnt_scrobble* scrobble, cJSON* js) +{ + cJSON* v; + + /* Zero out */ + memset(scrobble, 0, sizeof(struct mstdnt_scrobble)); + + struct _mstdnt_val_ref vals[] = { + { "account", &(scrobble->account), _mstdnt_val_account_call }, + { "album", &(scrobble->id), _mstdnt_val_string_call }, + { "artist", &(scrobble->id), _mstdnt_val_string_call }, + { "created_at", &(scrobble->id), _mstdnt_val_string_call }, + { "id", &(scrobble->id), _mstdnt_val_string_call }, + { "length", &(scrobble->id), _mstdnt_val_uint_call }, + { "title", &(scrobble->id), _mstdnt_val_string_call } + }; + + for (v = js; v; v = v->next) + _mstdnt_key_val_ref(v, vals, _mstdnt_arr_len(vals)); + + return 0; +} + +int mstdnt_scrobbles_result(struct mstdnt_fetch_results* results, + struct mstdnt_storage* storage, + struct mstdnt_scrobble* scrobbles[], + size_t* size) +{ + size_t i = 0; + cJSON* root, *scrobble_j_list; + if (_mstdnt_json_init(&root, results, storage) && + !cJSON_IsArray(root)) + return 1; + + if (size) *size = cJSON_GetArraySize(root); + + /* Scrobbles can be an empty array! */ + if (!(size ? *size : cJSON_GetArraySize(root))) + return 0; /* Not an error, but we are done parsing */ + + /* malloc array - cJSON does a loop to count, let's do it once preferably */ + *scrobbles = calloc(1, (size ? *size : cJSON_GetArraySize(root)) + * sizeof(struct mstdnt_scrobble)); + if (*scrobbles == NULL) + return 1; + + cJSON_ArrayForEach(scrobble_j_list, root) + { + mstdnt_scrobble_json((*scrobbles) + i++, scrobble_j_list->child); + } + + return 0; +} + + +int _mstdnt_scrobbles_from_result_callback(struct mstdnt_fetch_results* results, + struct mstdnt_storage* storage, + void* _args) +{ + struct _mstdnt_scrobbles_cb_args* args = _args; + return mstdnt_scrobbles_from_result(results, storage, args->scrobbles, args->size); +} + +int mastodont_get_scrobbles(mastodont_t* data, + char* id, + struct mstdnt_get_scrobbles_args* args, + struct mstdnt_storage* storage, + struct mstdnt_scrobble* scrobbles[], + size_t* size) +{ + struct _mstdnt_scrobbles_cb_args cb_args = { scrobbles, size }; + char url[MSTDNT_URLSIZE]; + snprintf(url, MSTDNT_URLSIZE, "api/v1/pleroma/accounts/%s/scrobbles", id); + + union param_value u_max_id, u_min_id, + u_since_id, u_offset, u_limit; + u_max_id.s = args->max_id; + u_min_id.s = args->min_id; + u_since_id.s = args->since_id; + u_offset.i = args->offset; + u_limit.i = args->limit; + + struct _mstdnt_query_param params[] = { + { _MSTDNT_QUERY_STRING, "max_id", u_max_id }, + { _MSTDNT_QUERY_STRING, "min_id", u_min_id }, + { _MSTDNT_QUERY_STRING, "since_id", u_since_id }, + { _MSTDNT_QUERY_INT, "offset", u_offset }, + { _MSTDNT_QUERY_INT, "limit", u_limit }, + }; + + struct mastodont_request_args req_args = { + storage, + url, + params, _mstdnt_arr_len(params), + NULL, 0, + CURLOPT_HTTPGET, + &cb_args, + _mstdnt_scrobbles_from_result_callback + }; + + return mastodont_request(data, &req_args); +} + diff --git a/src/status.c b/src/status.c index fa2be38..b7ab573 100644 --- a/src/status.c +++ b/src/status.c @@ -78,14 +78,13 @@ int mstdnt_status_from_json(struct mstdnt_status* status, cJSON* js) { "replies_count", &(status->replies_count), _mstdnt_val_uint_call }, { "media_attachments", &att_args, _mstdnt_val_attachments_call }, { "pleroma", &(status->pleroma), _mstdnt_val_status_pleroma_call }, - { "reblog", &(status->reblog), _mstdnt_val_malloc_status_call } + { "reblog", &(status->reblog), _mstdnt_val_malloc_status_call }, + { "account", &(status->account), _mstdnt_val_account_call } }; for (v = js; v; v = v->next) - if (_mstdnt_key_val_ref(v, vals, _mstdnt_arr_len(vals)) == 1) - if (cJSON_IsObject(v)) - if (strcmp("account", v->string) == 0) - mstdnt_account_from_json(&(status->account), v->child); + _mstdnt_key_val_ref(v, vals, _mstdnt_arr_len(vals)); + return 0; }