wip
This commit is contained in:
parent
9aafd0f238
commit
f69b73187e
@ -14,24 +14,63 @@ struct memory {
|
||||
size_t size;
|
||||
};
|
||||
|
||||
// Callback function for writing response data
|
||||
static size_t write_callback(void *contents, size_t size, size_t nmemb, struct memory *mem) {
|
||||
struct data {
|
||||
char trace_ascii; /* 1 or 0 */
|
||||
};
|
||||
|
||||
|
||||
static size_t cb(void *data, size_t size, size_t nmemb, void *clientp)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
struct memory *mem = (struct memory *)clientp;
|
||||
|
||||
char *ptr = realloc(mem->response, mem->size + realsize + 1);
|
||||
if(!ptr) {
|
||||
// out of memory
|
||||
printf("not enough memory (realloc returned NULL)\n");
|
||||
return 0;
|
||||
}
|
||||
if(ptr == NULL)
|
||||
return 0; /* out of memory! */
|
||||
|
||||
mem->response = ptr;
|
||||
memcpy(&(mem->response[mem->size]), contents, realsize);
|
||||
memcpy(&(mem->response[mem->size]), data, realsize);
|
||||
mem->size += realsize;
|
||||
mem->response[mem->size] = 0;
|
||||
|
||||
return realsize;
|
||||
}
|
||||
|
||||
char* build_query_string(query_param *params, size_t num_params) {
|
||||
CURL *curl = curl_easy_init();
|
||||
if (!curl) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *query = NULL;
|
||||
size_t query_len = 0;
|
||||
|
||||
for (size_t i = 0; i < num_params; ++i) {
|
||||
char *encoded_key = curl_easy_escape(curl, params[i].key, 0);
|
||||
char *encoded_value = curl_easy_escape(curl, params[i].value, 0);
|
||||
|
||||
// Calculate additional space needed: key=value& (including null terminator)
|
||||
size_t additional_len = strlen(encoded_key) + strlen(encoded_value) + 2;
|
||||
if (i < num_params - 1) {
|
||||
additional_len++; // For '&'
|
||||
}
|
||||
|
||||
query = realloc(query, query_len + additional_len);
|
||||
sprintf(query + query_len, "%s=%s", encoded_key, encoded_value);
|
||||
query_len += additional_len - 1; // Minus null terminator
|
||||
|
||||
if (i < num_params - 1) {
|
||||
strcat(query, "&");
|
||||
}
|
||||
|
||||
curl_free(encoded_key);
|
||||
curl_free(encoded_value);
|
||||
}
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
return query;
|
||||
}
|
||||
|
||||
// Function to make an HTTP request using libcurl
|
||||
int api_http_request(
|
||||
yadisk_api_client *client,
|
||||
@ -45,14 +84,19 @@ int api_http_request(
|
||||
CURLcode res;
|
||||
struct memory chunk = {0};
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
curl = curl_easy_init();
|
||||
|
||||
if(curl) {
|
||||
char url[256];
|
||||
char url[512];
|
||||
if (num_params) {
|
||||
char *query_string = build_query_string(params, num_params);
|
||||
snprintf(url, sizeof(url), "%s%s?%s", YANDEX_DISK_API_HOST, path, query_string);
|
||||
free(query_string);
|
||||
} else {
|
||||
snprintf(url, sizeof(url), "%s%s", YANDEX_DISK_API_HOST, path);
|
||||
}
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cb);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
|
||||
|
||||
// Set the HTTP method
|
||||
@ -79,7 +123,6 @@ int api_http_request(
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
|
||||
free(chunk.response);
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
return -1;
|
||||
} else {
|
||||
*output = strdup(chunk.response);
|
||||
@ -91,6 +134,5 @@ int api_http_request(
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
||||
|
@ -8,15 +8,41 @@
|
||||
#define YANDEX_DISK_API_HOST "https://cloud-api.yandex.net"
|
||||
|
||||
typedef struct {
|
||||
const char *key;
|
||||
const char *value;
|
||||
const char* key;
|
||||
const char* value;
|
||||
} query_param;
|
||||
|
||||
int api_http_request(yadisk_api_client *client,
|
||||
const char *method,
|
||||
const char *path,
|
||||
query_param *params,
|
||||
int api_http_request(yadisk_api_client* client,
|
||||
const char* method,
|
||||
const char* path,
|
||||
query_param* params,
|
||||
size_t num_params,
|
||||
char **output);
|
||||
char** output);
|
||||
|
||||
|
||||
#define THROW_PARSE_JSON_ERROR { \
|
||||
return YADISK_FAILED_PARSE_JSON; \
|
||||
}
|
||||
|
||||
#define __DANGER_GET_JSON_OBJECT(root, key) \
|
||||
json_object* obj = NULL; \
|
||||
if (!json_object_object_get_ex(root, key, &obj)){\
|
||||
json_object_put(root); \
|
||||
THROW_PARSE_JSON_ERROR \
|
||||
} \
|
||||
|
||||
#define GET_JSON_STRING(root, key, v) { \
|
||||
__DANGER_GET_JSON_OBJECT(root, key) \
|
||||
*v = json_object_get_string(obj); \
|
||||
}
|
||||
|
||||
#define GET_JSON_UINT64(root, key, v) { \
|
||||
__DANGER_GET_JSON_OBJECT(root, key) \
|
||||
*v = json_object_get_uint64(obj); \
|
||||
}
|
||||
#define GET_JSON_BOOL(root, key, v) { \
|
||||
__DANGER_GET_JSON_OBJECT(root, key) \
|
||||
*v = json_object_get_boolean(obj); \
|
||||
}
|
||||
|
||||
#endif //YADISK_YADISK_API_INTERNAL_H
|
||||
|
@ -9,21 +9,21 @@ yadisk_code yadisk_get_disk(yadisk_api_client* client, yadisk_disk_info* info)
|
||||
{
|
||||
char* output = NULL;
|
||||
int error = api_http_request(client, "GET", "/v1/disk", NULL, 0, &output);
|
||||
json_object* root = json_tokener_parse(output);
|
||||
if (error) {
|
||||
json_object_put(root);
|
||||
return YADISK_FAILED_PARSE_JSON;
|
||||
return YADISK_FAILED_HTTP_REQUEST;
|
||||
}
|
||||
|
||||
json_object* total_space = NULL;
|
||||
if (!json_object_object_get_ex(root, "total_space", &total_space)) {
|
||||
// printf("Key total_space doesn't exists!");
|
||||
return YADISK_FAILED_PARSE_JSON;
|
||||
}
|
||||
info->total_space = json_object_get_uint64(total_space);
|
||||
json_object_put(total_space);
|
||||
|
||||
json_object_put(root);
|
||||
json_object* root = json_tokener_parse(output);
|
||||
free(output);
|
||||
|
||||
GET_JSON_UINT64(root, "total_space", &(info->total_space));
|
||||
GET_JSON_UINT64(root, "trash_size", &(info->trash_size));
|
||||
GET_JSON_UINT64(root, "used_space", &(info->used_space));
|
||||
GET_JSON_STRING(root, "reg_time", &(info->reg_time));
|
||||
GET_JSON_BOOL(root, "is_paid", &(info->is_paid));
|
||||
|
||||
json_object_put(root);
|
||||
|
||||
|
||||
return YADISK_OK;
|
||||
}
|
||||
|
@ -9,6 +9,10 @@
|
||||
|
||||
typedef struct yadisk_disk_info {
|
||||
unsigned long total_space;
|
||||
unsigned long trash_size;
|
||||
unsigned long used_space;
|
||||
int is_paid;
|
||||
const char* reg_time;
|
||||
} yadisk_disk_info;
|
||||
|
||||
yadisk_code yadisk_get_disk(yadisk_api_client* client, yadisk_disk_info* info);
|
||||
|
@ -5,8 +5,27 @@
|
||||
#include "yadisk_api_internal.h"
|
||||
|
||||
yadisk_code
|
||||
yadisk_get_disk_resources(yadisk_api_client* client, const char* path)
|
||||
yadisk_get_disk_resources(
|
||||
yadisk_api_client* client, const char* path, yadisk_resource_info* info
|
||||
)
|
||||
{
|
||||
char* output;
|
||||
int error = api_http_request(client, "GET", "/v1/disk", NULL, 0, &output);
|
||||
char* output = NULL;
|
||||
query_param params[] = {
|
||||
{"path", path},
|
||||
};
|
||||
int error = api_http_request(client, "GET", "/v1/disk/resources", params, 1, &output);
|
||||
if (error) {
|
||||
return YADISK_FAILED_HTTP_REQUEST;
|
||||
}
|
||||
json_object* root = json_tokener_parse(output);
|
||||
free(output);
|
||||
GET_JSON_STRING(root, "path", &(info->path));
|
||||
GET_JSON_STRING(root, "name", &(info->name));
|
||||
GET_JSON_STRING(root, "resource_id", &(info->resource_id));
|
||||
GET_JSON_STRING(root, "type", &(info->type));
|
||||
GET_JSON_STRING(root, "created", &(info->created));
|
||||
GET_JSON_STRING(root, "modified", &(info->modified));
|
||||
|
||||
json_object_put(root);
|
||||
return YADISK_OK;
|
||||
};
|
||||
|
@ -1,18 +1,35 @@
|
||||
//
|
||||
// Created by maxim on 27.11.23.
|
||||
//
|
||||
#ifndef YADISK_GET_DISK_RESOURCES_H_INCLUDED
|
||||
#define YADISK_GET_DISK_RESOURCES_H_INCLUDED
|
||||
|
||||
#include "yadisk_shared.h"
|
||||
|
||||
#define YADISK_RESOURCE_ITEM_PROPERTIES \
|
||||
const char* path; \
|
||||
const char* name; \
|
||||
const char* resource_id; \
|
||||
const char* type; \
|
||||
const char* created; \
|
||||
const char* modified;
|
||||
|
||||
struct yadisk_resource_item
|
||||
{
|
||||
YADISK_RESOURCE_ITEM_PROPERTIES
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
unsigned long limit;
|
||||
unsigned long offset;
|
||||
unsigned long total;
|
||||
} yadisk_resource_embedded;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char* path;
|
||||
const char* name;
|
||||
const char* resource_id;
|
||||
const char* type;
|
||||
typedef struct {
|
||||
YADISK_RESOURCE_ITEM_PROPERTIES
|
||||
const yadisk_resource_embedded* _embedded;
|
||||
} yadisk_resource_info;
|
||||
|
||||
yadisk_code yadisk_get_disk_resources(yadisk_api_client *client, const char *path);
|
||||
yadisk_code yadisk_get_disk_resources(yadisk_api_client* client, const char* path, yadisk_resource_info* resource);
|
||||
|
||||
#endif // YADISK_GET_DISK_RESOURCES_H_INCLUDED
|
||||
|
@ -3,3 +3,13 @@
|
||||
//
|
||||
|
||||
#include "yadisk_shared.h"
|
||||
|
||||
int yadisk_init()
|
||||
{
|
||||
return curl_global_init(CURL_GLOBAL_ALL);
|
||||
}
|
||||
|
||||
void yadisk_cleanup()
|
||||
{
|
||||
curl_global_cleanup();
|
||||
}
|
@ -11,11 +11,15 @@
|
||||
|
||||
typedef enum {
|
||||
YADISK_OK = 0,
|
||||
YADISK_FAILED_PARSE_JSON = 1
|
||||
YADISK_FAILED_PARSE_JSON = 1,
|
||||
YADISK_FAILED_HTTP_REQUEST = 2
|
||||
} yadisk_code;
|
||||
|
||||
typedef struct {
|
||||
char* token;
|
||||
} yadisk_api_client;
|
||||
|
||||
int yadisk_init();
|
||||
void yadisk_cleanup();
|
||||
|
||||
#endif //YADISK_YADISK_SHARED_H
|
||||
|
22
tests/app.c
22
tests/app.c
@ -11,15 +11,33 @@ int main() {
|
||||
printf("Enter OAuth token: ");
|
||||
fgets(token, sizeof(token), stdin);
|
||||
|
||||
yadisk_init();
|
||||
|
||||
yadisk_api_client* client = &(yadisk_api_client){
|
||||
.token = token
|
||||
};
|
||||
|
||||
yadisk_disk_info yadisk_disk_info;
|
||||
|
||||
yadisk_get_disk(client, &yadisk_disk_info);
|
||||
|
||||
printf("Total disk size: %lu", yadisk_disk_info.total_space);
|
||||
printf("Total disk size: %lu\n", yadisk_disk_info.total_space);
|
||||
printf("Trash size: %lu\n", yadisk_disk_info.trash_size);
|
||||
printf("Used space: %lu\n", yadisk_disk_info.used_space);
|
||||
printf("Registration time: %s\n", yadisk_disk_info.reg_time);
|
||||
printf("Is paid: %s\n", yadisk_disk_info.is_paid ? "Yes" : "No");
|
||||
|
||||
printf("=================\n");
|
||||
|
||||
yadisk_resource_info resource;
|
||||
yadisk_get_disk_resources(client, "/", &resource);
|
||||
printf("Path: %s\n", resource.path);
|
||||
printf("Name: %s\n", resource.name);
|
||||
printf("Type: %s\n", resource.type);
|
||||
printf("Created: %s\n", resource.created);
|
||||
printf("Modified: %s\n", resource.modified);
|
||||
printf("ResourceID: %s\n", resource.resource_id);
|
||||
|
||||
yadisk_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user