diff options
-rw-r--r-- | .gitmodules | 3 | ||||
-rw-r--r-- | CMakeLists.txt | 5 | ||||
-rw-r--r-- | close_direct_conversations/CMakeLists.txt | 6 | ||||
-rw-r--r-- | close_direct_conversations/main.c (renamed from close_im/main.c) | 17 | ||||
-rw-r--r-- | close_im/CMakeLists.txt | 9 | ||||
-rw-r--r-- | common/CMakeLists.txt | 1 | ||||
-rw-r--r-- | common/subscriptions.c | 39 | ||||
-rw-r--r-- | common/subscriptions.h | 28 | ||||
m--------- | external/uthash | 0 | ||||
-rw-r--r-- | restapi/CMakeLists.txt | 1 | ||||
-rw-r--r-- | restapi/subscriptions.c | 63 | ||||
-rw-r--r-- | restapi/subscriptions.h | 9 |
12 files changed, 169 insertions, 12 deletions
diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e9ff57b --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "external/uthash"] + path = external/uthash + url = https://github.com/troydhanson/uthash diff --git a/CMakeLists.txt b/CMakeLists.txt index c6b6b2a..f6d77ab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,7 +41,10 @@ ExternalProject_Add(cjson ) include_directories(${CMAKE_BINARY_DIR}/cjson/src) +### uthash library ##### +include_directories("${PROJECT_SOURCE_DIR}/external/uthash/src") + ### Project subdirectories ##### -add_subdirectory(close_im) +add_subdirectory(close_direct_conversations) add_subdirectory(common) add_subdirectory(restapi) diff --git a/close_direct_conversations/CMakeLists.txt b/close_direct_conversations/CMakeLists.txt new file mode 100644 index 0000000..7aba3e4 --- /dev/null +++ b/close_direct_conversations/CMakeLists.txt @@ -0,0 +1,6 @@ +file(GLOB_RECURSE SOURCES *.c) + +ADD_EXECUTABLE(rocket_close_direct_conversations ${SOURCES}) +target_link_libraries(rocket_close_direct_conversations common restapi) + +install(TARGETS rocket_close_direct_conversations DESTINATION bin) diff --git a/close_im/main.c b/close_direct_conversations/main.c index c54ab25..0938982 100644 --- a/close_im/main.c +++ b/close_direct_conversations/main.c @@ -1,12 +1,19 @@ -#include "common/util.h" #include <stdlib.h> #include <stdio.h> #include <termios.h> #include <unistd.h> #include "common/config.h" +#include "common/util.h" #include "restapi/auth.h" #include "restapi/im.h" +#include "restapi/subscriptions.h" + +void print_subscription(const struct subscription* sub) +{ + if (sub->type == SUBSCRIPTION_DIRECT) + printf("\t%s\n", sub->name); +} int main(void) { @@ -51,10 +58,16 @@ int main(void) } if (restapi_login(login, password) == 0) { + struct subscription* subscriptions = restapi_subscriptions_get(); + + printf("Active direct conversations :\n"); + common_subscriptions_const_walk(subscriptions, &print_subscription); + common_subscriptions_free(subscriptions); + while(1) { char* buff = NULL; size_t len2; - printf("IM to close: "); + printf("Direct conversation to close: "); ssize_t entry = getline(&buff, &len2, stdin); if (entry > 1) { buff[entry-1] = 0; diff --git a/close_im/CMakeLists.txt b/close_im/CMakeLists.txt deleted file mode 100644 index aec4090..0000000 --- a/close_im/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -file(GLOB_RECURSE SOURCES *.c) - -ADD_EXECUTABLE(rocket_close_im ${SOURCES}) -target_link_libraries(rocket_close_im common restapi) -target_link_libraries(rocket_close_im config curl) -add_dependencies(rocket_close_im cjson-build) -target_link_libraries(rocket_close_im ${CMAKE_CURRENT_BINARY_DIR}/../cjson/src/cjson-build/libcjson.a) - -install(TARGETS rocket_close_im DESTINATION bin) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index aa5402a..876571b 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -2,3 +2,4 @@ file(GLOB_RECURSE SOURCES *.c) include_directories("${CMAKE_CURRENT_BINARY_DIR}") ADD_LIBRARY(common STATIC ${SOURCES}) +target_link_libraries(common config curl) diff --git a/common/subscriptions.c b/common/subscriptions.c new file mode 100644 index 0000000..d6d15aa --- /dev/null +++ b/common/subscriptions.c @@ -0,0 +1,39 @@ +#include "subscriptions.h" + +void common_subscription_add(struct subscription** subscriptions, const char* id, const char* name, enum subscription_type type) +{ + struct subscription * subscription = common_subscription_new(id, name, type); + HASH_ADD_KEYPTR(hh, *subscriptions, subscription->id, strlen(id), subscription); +} + +struct subscription* common_subscription_new(const char* id, const char* name, enum subscription_type type) +{ + struct subscription* subscription = malloc(sizeof(struct subscription)); + subscription->id = malloc(strlen(id) + 1); + strcpy(subscription->id, id); + subscription->name = malloc(strlen(name) + 1); + strcpy(subscription->name, name); + subscription->type = type; + return subscription; +} + +void common_subscriptions_free(struct subscription* subscriptions) +{ + struct subscription *sub, *tmp; + + HASH_ITER(hh, subscriptions, sub, tmp) { + HASH_DEL(subscriptions, sub); + free(sub->id); + free(sub->name); + free(sub); + } +} + +void common_subscriptions_const_walk(const struct subscription* subscriptions, void (*func)(const struct subscription*)) +{ + const struct subscription *sub, *tmp; + + HASH_ITER(hh, subscriptions, sub, tmp) { + func(sub); + } +} diff --git a/common/subscriptions.h b/common/subscriptions.h new file mode 100644 index 0000000..6c10a24 --- /dev/null +++ b/common/subscriptions.h @@ -0,0 +1,28 @@ +#ifndef COMMON_SUBSCRIPTIONS_H_ +#define COMMON_SUBSCRIPTIONS_H_ + +#include <uthash.h> + +static const char *subscription_type_str[] = { + "channel", "direct", "private", +}; + +enum subscription_type { + SUBSCRIPTION_CHANNEL, + SUBSCRIPTION_DIRECT, + SUBSCRIPTION_PRIVATE, +}; + +struct subscription { + char* id; + char* name; + enum subscription_type type; + UT_hash_handle hh; +}; + +void common_subscription_add(struct subscription** subscriptions, const char* id, const char* name, enum subscription_type type); +struct subscription* common_subscription_new(const char* id, const char* name, enum subscription_type type); +void common_subscriptions_free(struct subscription* subscriptions); +void common_subscriptions_const_walk(const struct subscription* subscriptions, void (*func)(const struct subscription*)); + +#endif diff --git a/external/uthash b/external/uthash new file mode 160000 +Subproject f19dde22d80a563948a263afe00947e6e42ed8f diff --git a/restapi/CMakeLists.txt b/restapi/CMakeLists.txt index 45a22c2..e1cad6a 100644 --- a/restapi/CMakeLists.txt +++ b/restapi/CMakeLists.txt @@ -3,3 +3,4 @@ file(GLOB_RECURSE SOURCES *.c) ADD_LIBRARY(restapi STATIC ${SOURCES}) add_dependencies(restapi cjson-build) target_link_libraries(restapi common) +target_link_libraries(restapi ${CMAKE_CURRENT_BINARY_DIR}/../cjson/src/cjson-build/libcjson.a) diff --git a/restapi/subscriptions.c b/restapi/subscriptions.c new file mode 100644 index 0000000..b52ea9a --- /dev/null +++ b/restapi/subscriptions.c @@ -0,0 +1,63 @@ +#include <cjson/cJSON.h> +#include <curl/curl.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "common/http.h" +#include "subscriptions.h" + +struct subscription* // returns NULL if error or a uthash of subscriptions that needs to be freed by the caller +restapi_subscriptions_get(void) +{ + struct subscription* subscriptions = NULL; + + const char* buffer = http_get("/api/v1/subscriptions.get"); + + if (buffer == NULL) { + fprintf(stderr, "Error while subscriptions_get, http get didn't return any data.\n"); + return NULL; + } + + cJSON* json = cJSON_Parse(buffer); + if (json == NULL) { + const char *error_ptr = cJSON_GetErrorPtr(); + if (error_ptr != NULL) + fprintf(stderr, "Json parsing error before: %s\n", error_ptr); + fprintf(stderr, "Error while subscriptions_get, couldn't parse json output :\n%s\n", buffer); + goto get_json_cleanup; + } + + const cJSON* success = cJSON_GetObjectItemCaseSensitive(json, "success"); + if (cJSON_IsTrue(success)) { + cJSON* updates = cJSON_GetObjectItemCaseSensitive(json, "update"); + if (!cJSON_IsArray(updates)) { + fprintf(stderr, "Error while subscriptions_get, couldn't parse json output :\n%s\n", buffer); + goto get_json_cleanup; + } + const cJSON* update = NULL; + cJSON_ArrayForEach(update, updates) { + const cJSON* id = cJSON_GetObjectItemCaseSensitive(update, "_id"); + const cJSON* name = cJSON_GetObjectItemCaseSensitive(update, "name"); + const cJSON* type = cJSON_GetObjectItemCaseSensitive(update, "t"); + const cJSON* open = cJSON_GetObjectItemCaseSensitive(update, "open"); + enum subscription_type etype; + if (!cJSON_IsString(id) || id->valuestring == NULL || !cJSON_IsString(name) || name->valuestring == NULL || !cJSON_IsString(type) || type->valuestring == NULL || !cJSON_IsTrue(open)) + continue; + if (strcmp(type->valuestring, "c") == 0) + etype = SUBSCRIPTION_CHANNEL; + else if (strcmp(type->valuestring, "d") == 0) + etype = SUBSCRIPTION_DIRECT; + else if (strcmp(type->valuestring, "p") == 0) + etype = SUBSCRIPTION_PRIVATE; + else { + fprintf(stderr, "Bug found : Unknown subscription type %s\n%s\n", type->valuestring, buffer); + exit(999); + } + common_subscription_add(&subscriptions, id->valuestring, name->valuestring, etype); + } + } +get_json_cleanup: + cJSON_Delete(json); + return subscriptions; +} diff --git a/restapi/subscriptions.h b/restapi/subscriptions.h new file mode 100644 index 0000000..0347e15 --- /dev/null +++ b/restapi/subscriptions.h @@ -0,0 +1,9 @@ +#ifndef RESTAPI_SUBSCRIPTIONS_H_ +#define RESTAPI_SUBSCRIPTIONS_H_ + +#include "common/subscriptions.h" + +struct subscription* // returns NULL if error or a uthash of subscriptions that needs to be freed by the caller +restapi_subscriptions_get(void); + +#endif |