wip
This commit is contained in:
parent
9aafd0f238
commit
f69b73187e
@ -14,24 +14,63 @@ struct memory {
|
|||||||
size_t size;
|
size_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Callback function for writing response data
|
struct data {
|
||||||
static size_t write_callback(void *contents, size_t size, size_t nmemb, struct memory *mem) {
|
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;
|
size_t realsize = size * nmemb;
|
||||||
|
struct memory *mem = (struct memory *)clientp;
|
||||||
|
|
||||||
char *ptr = realloc(mem->response, mem->size + realsize + 1);
|
char *ptr = realloc(mem->response, mem->size + realsize + 1);
|
||||||
if(!ptr) {
|
if(ptr == NULL)
|
||||||
// out of memory
|
return 0; /* out of memory! */
|
||||||
printf("not enough memory (realloc returned NULL)\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
mem->response = ptr;
|
mem->response = ptr;
|
||||||
memcpy(&(mem->response[mem->size]), contents, realsize);
|
memcpy(&(mem->response[mem->size]), data, realsize);
|
||||||
mem->size += realsize;
|
mem->size += realsize;
|
||||||
mem->response[mem->size] = 0;
|
mem->response[mem->size] = 0;
|
||||||
|
|
||||||
return realsize;
|
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
|
// Function to make an HTTP request using libcurl
|
||||||
int api_http_request(
|
int api_http_request(
|
||||||
yadisk_api_client *client,
|
yadisk_api_client *client,
|
||||||
@ -45,14 +84,19 @@ int api_http_request(
|
|||||||
CURLcode res;
|
CURLcode res;
|
||||||
struct memory chunk = {0};
|
struct memory chunk = {0};
|
||||||
|
|
||||||
curl_global_init(CURL_GLOBAL_ALL);
|
|
||||||
curl = curl_easy_init();
|
curl = curl_easy_init();
|
||||||
|
|
||||||
if(curl) {
|
if(curl) {
|
||||||
char url[256];
|
char url[512];
|
||||||
snprintf(url, sizeof(url), "%s%s", YANDEX_DISK_API_HOST, path);
|
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_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);
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
|
||||||
|
|
||||||
// Set the HTTP method
|
// Set the HTTP method
|
||||||
@ -79,7 +123,6 @@ int api_http_request(
|
|||||||
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
|
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
|
||||||
free(chunk.response);
|
free(chunk.response);
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
curl_global_cleanup();
|
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
*output = strdup(chunk.response);
|
*output = strdup(chunk.response);
|
||||||
@ -91,6 +134,5 @@ int api_http_request(
|
|||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
}
|
}
|
||||||
|
|
||||||
curl_global_cleanup();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -8,15 +8,41 @@
|
|||||||
#define YANDEX_DISK_API_HOST "https://cloud-api.yandex.net"
|
#define YANDEX_DISK_API_HOST "https://cloud-api.yandex.net"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *key;
|
const char* key;
|
||||||
const char *value;
|
const char* value;
|
||||||
} query_param;
|
} query_param;
|
||||||
|
|
||||||
int api_http_request(yadisk_api_client *client,
|
int api_http_request(yadisk_api_client* client,
|
||||||
const char *method,
|
const char* method,
|
||||||
const char *path,
|
const char* path,
|
||||||
query_param *params,
|
query_param* params,
|
||||||
size_t num_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
|
#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;
|
char* output = NULL;
|
||||||
int error = api_http_request(client, "GET", "/v1/disk", NULL, 0, &output);
|
int error = api_http_request(client, "GET", "/v1/disk", NULL, 0, &output);
|
||||||
json_object* root = json_tokener_parse(output);
|
|
||||||
if (error) {
|
if (error) {
|
||||||
json_object_put(root);
|
return YADISK_FAILED_HTTP_REQUEST;
|
||||||
return YADISK_FAILED_PARSE_JSON;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
json_object* total_space = NULL;
|
json_object* root = json_tokener_parse(output);
|
||||||
if (!json_object_object_get_ex(root, "total_space", &total_space)) {
|
free(output);
|
||||||
// printf("Key total_space doesn't exists!");
|
|
||||||
return YADISK_FAILED_PARSE_JSON;
|
GET_JSON_UINT64(root, "total_space", &(info->total_space));
|
||||||
}
|
GET_JSON_UINT64(root, "trash_size", &(info->trash_size));
|
||||||
info->total_space = json_object_get_uint64(total_space);
|
GET_JSON_UINT64(root, "used_space", &(info->used_space));
|
||||||
json_object_put(total_space);
|
GET_JSON_STRING(root, "reg_time", &(info->reg_time));
|
||||||
|
GET_JSON_BOOL(root, "is_paid", &(info->is_paid));
|
||||||
|
|
||||||
json_object_put(root);
|
json_object_put(root);
|
||||||
free(output);
|
|
||||||
|
|
||||||
return YADISK_OK;
|
return YADISK_OK;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
|
|
||||||
typedef struct yadisk_disk_info {
|
typedef struct yadisk_disk_info {
|
||||||
unsigned long total_space;
|
unsigned long total_space;
|
||||||
|
unsigned long trash_size;
|
||||||
|
unsigned long used_space;
|
||||||
|
int is_paid;
|
||||||
|
const char* reg_time;
|
||||||
} yadisk_disk_info;
|
} yadisk_disk_info;
|
||||||
|
|
||||||
yadisk_code yadisk_get_disk(yadisk_api_client* client, yadisk_disk_info* info);
|
yadisk_code yadisk_get_disk(yadisk_api_client* client, yadisk_disk_info* info);
|
||||||
|
@ -5,8 +5,27 @@
|
|||||||
#include "yadisk_api_internal.h"
|
#include "yadisk_api_internal.h"
|
||||||
|
|
||||||
yadisk_code
|
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;
|
char* output = NULL;
|
||||||
int error = api_http_request(client, "GET", "/v1/disk", NULL, 0, &output);
|
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.
|
// 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"
|
#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 {
|
typedef struct {
|
||||||
|
unsigned long limit;
|
||||||
|
unsigned long offset;
|
||||||
|
unsigned long total;
|
||||||
} yadisk_resource_embedded;
|
} yadisk_resource_embedded;
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
YADISK_RESOURCE_ITEM_PROPERTIES
|
||||||
const char* path;
|
|
||||||
const char* name;
|
|
||||||
const char* resource_id;
|
|
||||||
const char* type;
|
|
||||||
const yadisk_resource_embedded* _embedded;
|
const yadisk_resource_embedded* _embedded;
|
||||||
} yadisk_resource_info;
|
} 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"
|
#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 {
|
typedef enum {
|
||||||
YADISK_OK = 0,
|
YADISK_OK = 0,
|
||||||
YADISK_FAILED_PARSE_JSON = 1
|
YADISK_FAILED_PARSE_JSON = 1,
|
||||||
|
YADISK_FAILED_HTTP_REQUEST = 2
|
||||||
} yadisk_code;
|
} yadisk_code;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char* token;
|
char* token;
|
||||||
} yadisk_api_client;
|
} yadisk_api_client;
|
||||||
|
|
||||||
|
int yadisk_init();
|
||||||
|
void yadisk_cleanup();
|
||||||
|
|
||||||
#endif //YADISK_YADISK_SHARED_H
|
#endif //YADISK_YADISK_SHARED_H
|
||||||
|
24
tests/app.c
24
tests/app.c
@ -11,15 +11,33 @@ int main() {
|
|||||||
printf("Enter OAuth token: ");
|
printf("Enter OAuth token: ");
|
||||||
fgets(token, sizeof(token), stdin);
|
fgets(token, sizeof(token), stdin);
|
||||||
|
|
||||||
|
yadisk_init();
|
||||||
|
|
||||||
yadisk_api_client* client = &(yadisk_api_client){
|
yadisk_api_client* client = &(yadisk_api_client){
|
||||||
.token = token
|
.token = token
|
||||||
};
|
};
|
||||||
|
|
||||||
yadisk_disk_info yadisk_disk_info;
|
yadisk_disk_info yadisk_disk_info;
|
||||||
|
|
||||||
yadisk_get_disk(client, &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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user