summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rw-r--r--pikul.c130
-rw-r--r--pikul.h11
-rw-r--r--private.h3
-rw-r--r--sicepat.c85
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
diff --git a/pikul.c b/pikul.c
index 00d1284..f3710f8 100644
--- a/pikul.c
+++ b/pikul.c
@@ -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)
diff --git a/pikul.h b/pikul.h
index 8e41762..4802547 100644
--- a/pikul.h
+++ b/pikul.h
@@ -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);
diff --git a/private.h b/private.h
index 954d29e..8266484 100644
--- a/private.h
+++ b/private.h
@@ -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;
+}