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;
}