#define _POSIX_C_SOURCE 200809L #include #include #include #include #include "timeline.h" #include "auth.h" #include "config.h" #include "http.h" #include "string-util.h" #include "log.h" #define TIMELINE_URL "https://%s/api/v1/timelines/home" static char *get_timeline_url(const char *domain) { char *url; size_t size; size = strlen(TIMELINE_URL) + strlen(domain) - 1; url = malloc(size); if (!url) { err(1, NULL); return NULL; } sprintf(url, TIMELINE_URL, domain); return url; } struct timeline *timeline_from_json(const char *json_data) { struct timeline *t; json_t *root; json_error_t error; root = json_loads(json_data, 0, &error); if (!root) { log_msg(LOG_WARNING, "timeline_from_json", "json root it null"); return NULL; } if (!json_is_array(root)) { log_msg(LOG_WARNING, "timeline_from_json", "json root is not array"); json_decref(root); return NULL; } t = calloc(1, sizeof(struct timeline)); if (!t) { err(1, NULL); json_decref(root); return NULL; } t->size = json_array_size(root); t->statuses = calloc(t->size, sizeof(struct status *)); if (!(t->statuses)) { err(1, NULL); timeline_free(t); json_decref(root); return NULL; } json_t *data; for (size_t i = 0; i < t->size; i++) { data = json_array_get(root, i); if (!data) goto error; t->statuses[i] = status_from_json_t(data); if (!(t->statuses[i])) goto error; } json_decref(root); return t; error: timeline_free(t); json_decref(root); return NULL; } void timeline_free(struct timeline *t) { for (size_t i = 0; i < t->size; i++) { if (t->statuses[i]) status_free(t->statuses[i]); } free(t->statuses); free(t); } struct timeline *get_timeline(const char *max_id, const char *since_id, const char *min_id, int limit) { char *url, *resp; struct timeline *t; url = get_timeline_url(config->instance_url); if (!url) { err(1, "get_timeline"); return NULL; } resp = get_request(url); free(url); if (!resp) { return NULL; } t = timeline_from_json(resp); free(resp); if (!t) { return NULL; } return t; }