diff options
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | pikul.c | 130 | ||||
-rw-r--r-- | pikul.h | 11 | ||||
-rw-r--r-- | private.h | 3 | ||||
-rw-r--r-- | sicepat.c | 85 |
5 files changed, 228 insertions, 4 deletions
diff --git a/Makefile.am b/Makefile.am index ff1a123..c00b280 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,7 @@ lib_LTLIBRARIES = libpikul.la libpikul_la_SOURCES = pikul.c \ - anteraja.c + anteraja.c \ + sicepat.c libpikul_la_CPPFLAGS = $(DEPS_CFLAGS) libpikul_la_LDFLAGS = $(DEPS_LIBS) include_HEADERS = pikul.h @@ -24,6 +24,11 @@ void anteraja_order(const char *, const char *, const char *, const char *, cons char **[], double); void anteraja_cleanup(); +const char **sicepat_init(char *[]); +const char **sicepat_origins(); +const char **sicepat_destinations(); +const char **sicepat_services(const char *, const char *, double); + static void recurse(struct json_object *outer, const char *trail[], struct json_object **last) { struct json_object *inner = NULL; @@ -49,7 +54,16 @@ static size_t handle(char *contents, size_t size, size_t nmemb, struct shipping #endif #endif json_tokener *tokener = shipping->tokener; - json_object *response = json_tokener_parse_ex(tokener, contents, realsize); + json_object *response; + if (shipping->mode == PLACES) { + shipping->response_data = realloc(shipping->response_data, + shipping->response_size + realsize + 1); + memcpy(&(shipping->response_data[shipping->response_size]), contents, realsize); + shipping->response_size += realsize; + shipping->response_data[shipping->response_size] = '\0'; + response = json_tokener_parse_ex(tokener, shipping->response_data, shipping->response_size); + } else + response = json_tokener_parse_ex(tokener, contents, realsize); enum json_tokener_error error = json_tokener_get_error(tokener); if (!response) { if (error == json_tokener_continue) @@ -67,6 +81,46 @@ static size_t handle(char *contents, size_t size, size_t nmemb, struct shipping return realsize; } switch (shipping->mode) { + case PLACES: + ; + struct json_object *place_array = NULL; + recurse(response, shipping->trail, &place_array); + size_t places_length = json_object_array_length(place_array); + struct pikul_place **places = malloc(sizeof(struct pikul_place *) + * (places_length + 1)); + const char **place_attrs = (const char **)shipping->data; + enum { PLACE_CODE, DISTRICT, CITY, PROVINCE }; + for (size_t i = 0; i < places_length; i++) { + places[i] = calloc(1, sizeof(struct pikul_place)); + struct pikul_place *place = places[i]; + json_object *object = json_object_array_get_idx(place_array, i); + struct json_object_iterator iterator = json_object_iter_begin(object); + struct json_object_iterator iterator_end = json_object_iter_end(object); + while (!json_object_iter_equal(&iterator, &iterator_end)) { + const char *name = json_object_iter_peek_name(&iterator); + json_object *value = json_object_iter_peek_value(&iterator); + int len = json_object_get_string_len(value); + if (len) { + char *string = malloc(len + 1); + strcpy(string, json_object_get_string(value)); + if (!strcmp(name, place_attrs[PLACE_CODE])) + place->code = string; + else if (place_attrs[DISTRICT] + && !strcmp(name, place_attrs[DISTRICT])) + place->district = string; + else if (place_attrs[CITY] + && !strcmp(name, place_attrs[CITY])) + place->city = string; + else if (place_attrs[PROVINCE] + && !strcmp(name, place_attrs[PROVINCE])) + place->province = string; + } + json_object_iter_next(&iterator); + } + } + places[places_length] = NULL; + shipping->data = places; + break; case SERVICES: ; struct json_object *array = NULL; @@ -136,6 +190,9 @@ void pikul_init(enum pikul_company company, char *provisions[]) case PIKUL_ANTERAJA: fields = anteraja_init(provisions); break; + case PIKUL_SICEPAT: + fields = sicepat_init(provisions); + break; default: break; } @@ -149,6 +206,68 @@ void pikul_init(enum pikul_company company, char *provisions[]) shipping->tokener = json_tokener_new(); } +struct pikul_place **pikul_origins(enum pikul_company company) +{ + struct shipping *shipping = shipping_list[company]; + switch (company) { + case PIKUL_SICEPAT: + shipping->data = sicepat_origins(); + break; + default: + break; + } + curl_easy_setopt(shipping->handle, CURLOPT_URL, shipping->url); + curl_easy_setopt(shipping->handle, CURLOPT_HTTPGET, 1L); + shipping->mode = PLACES; + shipping->response_size = 0; + shipping->response_data = malloc(1); + curl_easy_perform(shipping->handle); + free(shipping->response_data); + free(shipping->url); + return (struct pikul_place **)shipping->data; +} + +struct pikul_place **pikul_destinations(enum pikul_company company) +{ + struct shipping *shipping = shipping_list[company]; + switch (company) { + case PIKUL_SICEPAT: + shipping->data = sicepat_destinations(); + break; + default: + break; + } + curl_easy_setopt(shipping->handle, CURLOPT_URL, shipping->url); + curl_easy_setopt(shipping->handle, CURLOPT_HTTPGET, 1L); + shipping->mode = PLACES; + shipping->response_size = 0; + shipping->response_data = malloc(1); + curl_easy_perform(shipping->handle); + free(shipping->response_data); + free(shipping->url); + return (struct pikul_place **)shipping->data; +} + +static inline void free_place(struct pikul_place *place) +{ + if (place->province) + free(place->province); + if (place->city) + free(place->city); + if (place->district) + free(place->district); + free(place->code); + free(place); +} + +void pikul_free_places(struct pikul_place **places) +{ + size_t i = 0; + while (places[i]) + free_place(places[i++]); + free(places); +} + struct pikul_service **pikul_services(enum pikul_company company, const char *origin, const char *destination, double weight) { @@ -158,6 +277,9 @@ struct pikul_service **pikul_services(enum pikul_company company, case PIKUL_ANTERAJA: shipping->data = anteraja_services(origin, destination, weight); break; + case PIKUL_SICEPAT: + shipping->data = sicepat_services(origin, destination, weight); + break; default: break; } @@ -168,7 +290,8 @@ struct pikul_service **pikul_services(enum pikul_company company, #ifdef DEBUG fprintf(stderr, "POST: %s\n", shipping->post); #endif - } + } else + curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); shipping->mode = SERVICES; curl_easy_perform(curl); if (shipping->post) @@ -316,7 +439,8 @@ char *pikul_order(enum pikul_company company, const char *order_number, const ch #ifdef DEBUG fprintf(stderr, "POST: %s\n", shipping->post); #endif - } + } else + curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); shipping->mode = ORDER; curl_easy_perform(curl); if (shipping->post) @@ -4,9 +4,17 @@ enum pikul_company { PIKUL, PIKUL_ANTERAJA, + PIKUL_SICEPAT, PIKUL_END }; +struct pikul_place { + char *code; + char *district; + char *city; + char *province; +}; + struct pikul_service { char *code; char *name; @@ -19,6 +27,9 @@ extern "C" { #endif void pikul_init(enum pikul_company company, char *provisions[]); +struct pikul_place **pikul_origins(enum pikul_company company); +struct pikul_place **pikul_destinations(enum pikul_company company); +void pikul_free_places(struct pikul_place **places); struct pikul_service **pikul_services(enum pikul_company company, const char *origin, const char *destination, double weight); void pikul_free_services(struct pikul_service **services); @@ -9,8 +9,11 @@ extern struct shipping { const char **status_trail; char *url; char *post; + size_t response_size; + char *response_data; json_tokener *tokener; enum { + PLACES, SERVICES, ORDER } mode; diff --git a/sicepat.c b/sicepat.c new file mode 100644 index 0000000..8e19412 --- /dev/null +++ b/sicepat.c @@ -0,0 +1,85 @@ +#include <stdlib.h> +#include <string.h> +#include "private.h" + +#define BASE "https://api.sicepat.com/customer/" +#define ORIGINS "origin" +#define DESTINATIONS "destination" + +const char **sicepat_init(char *provisions[]) +{ + struct shipping *shipping = shipping_list[PIKUL_SICEPAT]; + shipping->base = malloc(strlen(BASE) + 1); + strcpy(shipping->base, BASE); + static const char *status_trail[] = { + "sicepat", + "status", + "code", + NULL + }; + shipping->status_trail = status_trail; + static const char *fields[] = { "api-key", NULL }; + return fields; +} + +const char **sicepat_origins() +{ + struct shipping *shipping = shipping_list[PIKUL_SICEPAT]; + shipping->url = malloc(strlen(BASE) + strlen(ORIGINS) + 1); + sprintf(shipping->url, "%s%s", BASE, ORIGINS); + static const char *trail[] = { + "sicepat", + "results", + NULL + }; + shipping->trail = trail; + static const char *attributes[] = { + "origin_code", + NULL, + "origin_name", + NULL + }; + return attributes; +} + +const char **sicepat_destinations() +{ + struct shipping *shipping = shipping_list[PIKUL_SICEPAT]; + shipping->url = malloc(strlen(BASE) + strlen(DESTINATIONS) + 1); + sprintf(shipping->url, "%s%s", BASE, DESTINATIONS); + static const char *trail[] = { + "sicepat", + "results", + NULL + }; + shipping->trail = trail; + static const char *attributes[] = { + "destination_code", + "subdistrict", + "city", + "province" + }; + return attributes; +} + +const char **sicepat_services(const char *origin, const char *destination, double weight) +{ + struct shipping *shipping = shipping_list[PIKUL_SICEPAT]; + shipping->url = malloc(strlen(shipping->base) + strlen("tariff?origin=") + strlen(origin) + + strlen("&destination=") + strlen(destination) + strlen("&weight=") + 9); + sprintf(shipping->url, "%stariff?origin=%s&destination=%s&weight=%f", shipping->base, origin, + destination, weight); + static const char *trail[] = { + "sicepat", + "results", + NULL + }; + shipping->trail = trail; + static const char *attributes[] = { + "service", + "description", + "etd", + "tariff" + }; + return attributes; +} |