diff --git a/include/endpoints/api_v1_macros.h b/include/endpoints/api_v1_macros.h index 6a15961..2809c69 100644 --- a/include/endpoints/api_v1_macros.h +++ b/include/endpoints/api_v1_macros.h @@ -9,10 +9,13 @@ api_v1_macros_GET(struct mg_connection *nc, struct http_message *hm, endpoint_ar void api_v1_macros_POST(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response); -//void -//api_v1_tags_STR_GET(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response); +void +api_v1_macros_STR_GET(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response); -//void -//api_v1_tags_STR_DELETE(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response); +void +api_v1_macros_STR_PUT(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response); + +void +api_v1_macros_STR_DELETE(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response); #endif /* CORE_ENDPOINTS_API_V1_MACROS_H */ diff --git a/include/logger.h b/include/logger.h index fc207f5..20c30e0 100644 --- a/include/logger.h +++ b/include/logger.h @@ -8,9 +8,12 @@ #include #include +#define LOG_NONE INT_MAX + void logger_log(int level, const char *filename, int line, const char *func, const char *msg, ...); +#define LOGGER_NONE(...) logger_log(LOG_NONE , __FILE__, __LINE__, __func__, ##__VA_ARGS__) #define LOGGER_DEBUG(...) logger_log(LOG_DEBUG , __FILE__, __LINE__, __func__, ##__VA_ARGS__) #define LOGGER_INFO(...) logger_log(LOG_INFO , __FILE__, __LINE__, __func__, ##__VA_ARGS__) #define LOGGER_NOTICE(...) logger_log(LOG_NOTICE , __FILE__, __LINE__, __func__, ##__VA_ARGS__) diff --git a/include/macros.h b/include/macros.h index 4242abe..062081a 100644 --- a/include/macros.h +++ b/include/macros.h @@ -1,6 +1,24 @@ #ifndef CORE_MACROS_H #define CORE_MACROS_H -#define STRLEN(s) ((sizeof(s)/sizeof(s[0])) - sizeof(s[0])) +#include + +#define M_STRLEN(s) ((sizeof(s)/sizeof(s[0])) - sizeof(s[0])) + +#define M_RESPONSE_TEXT_STATIC(logger_func, response, code, content) do { logger_func("%s\n", content); endpoint_response_text(response, code, content, M_STRLEN(content)); } while(0) +#define M_RESPONSE_400_NO_VALID_JSON(response) M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request is not valid json") +#define M_RESPONSE_400_NO_VALID_ID(response) M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request does not contain valid id (uuid)") +#define M_RESPONSE_400_NO_NAME(response) M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request does not contain a name") + +#define M_RESPONSE_403_PROTECTED_SCHEDULE(response) M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 403, "the target schedule is protected") + +#define M_RESPONSE_404_NO_CONTROLLER_FOUND_FOR_ID(response) M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "no controller was found for the requested id") +#define M_RESPONSE_404_NO_SCHEDULE_FOUND_FOR_ID(response) M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "no schedule was found for the requested id") +#define M_RESPONSE_404_NO_MACRO_FOUND_FOR_ID(response) M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "no schedule was found for the requested id") +#define M_RESPONSE_404_NO_TAG_FOUND(response) M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "the requested tag was not found") + +#define M_RESPONSE_500_FAILED_TO_SAVE_TO_DATABASE(response) M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "the server failed to save to the database") +#define M_RESPONSE_500_FAILED_TO_READ_FROM_DATABASE(response) M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "the server failed to read from the database") +#define M_RESPONSE_500_FAILED_TO_DELETE_FROM_DATABASE(response) M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "the server failed to delete from the database") #endif /* CORE_MACROS_H */ diff --git a/include/models/macro_action.h b/include/models/macro_action.h index 7505e0c..22ddd63 100644 --- a/include/models/macro_action.h +++ b/include/models/macro_action.h @@ -12,6 +12,9 @@ typedef struct int macro_action_insert(macro_action_t *macro_action); +int +macro_action_delete_for_macro(int macro_id); + macro_action_t** macro_action_get_for_macro(int macro_id); diff --git a/src/endpoint.c b/src/endpoint.c index 0a6ed54..5173538 100644 --- a/src/endpoint.c +++ b/src/endpoint.c @@ -84,8 +84,5 @@ endpoint_response_json(endpoint_response_t *response, int status_code, const cJS } } - LOGGER_ERR("failed to print schedule json\n"); - - static const char content[] = "failed to print json"; - endpoint_response_text(response, status_code, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "failed to print json"); } diff --git a/src/endpoints/api_v1_controllers_STR.c b/src/endpoints/api_v1_controllers_STR.c index f4f47f7..0a6c0ba 100644 --- a/src/endpoints/api_v1_controllers_STR.c +++ b/src/endpoints/api_v1_controllers_STR.c @@ -18,10 +18,7 @@ api_v1_controllers_STR_GET(struct mg_connection *nc, struct http_message *hm, en uuid_t target_uid; if(uuid_parse(args[0].value.v_str, target_uid)) { - LOGGER_DEBUG("failed to unparse uid\n"); - - static const char content[] = "given id was invalid"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_400_NO_VALID_ID(response); return; } @@ -29,10 +26,7 @@ api_v1_controllers_STR_GET(struct mg_connection *nc, struct http_message *hm, en if(!controller) { - LOGGER_DEBUG("could not find a controller for uid '%s'\n", args[0].value.v_str); - - static const char content[] = "no controller for id found"; - endpoint_response_text(response, 404, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "no controller found for id"); return; } LOGGER_DEBUG("returning controller for uid '%s'\n", args[0].value.v_str); @@ -53,10 +47,7 @@ api_v1_controllers_STR_PUT(struct mg_connection *nc, struct http_message *hm, en uuid_t target_uid; if(uuid_parse(args[0].value.v_str, target_uid)) { - LOGGER_DEBUG("failed to unparse uid\n"); - - static const char content[] = "given id was invalid"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_400_NO_VALID_ID(response); return; } @@ -64,10 +55,7 @@ api_v1_controllers_STR_PUT(struct mg_connection *nc, struct http_message *hm, en if(!controller) { - LOGGER_DEBUG("could not find a controller for uid '%s'\n", args[0].value.v_str); - - static const char content[] = "no controller for id found"; - endpoint_response_text(response, 404, content, STRLEN(content)); + M_RESPONSE_404_NO_CONTROLLER_FOUND_FOR_ID(response); return; } LOGGER_DEBUG("starting overwrite for controller %s\n", args[0].value.v_str); @@ -76,70 +64,64 @@ api_v1_controllers_STR_PUT(struct mg_connection *nc, struct http_message *hm, en if(json == NULL) { - static const char content[] = "no valid json was supplied"; - endpoint_response_text(response, 400, content, STRLEN(content)); controller_free(controller); + + M_RESPONSE_400_NO_VALID_JSON(response); return; } cJSON *json_name = cJSON_GetObjectItemCaseSensitive(json, "name"); if(json_name) { - if(cJSON_IsString(json_name) && json_name->valuestring) + if(!cJSON_IsString(json_name) || json_name->valuestring == NULL) { - strncpy(controller->name, json_name->valuestring, MAX_NAME_LENGTH); - controller->name[MAX_NAME_LENGTH] = '\0'; - LOGGER_DEBUG("new controller name: %s\n", controller->name); - } - else - { - static const char content[] = "the given name is no valid string"; - endpoint_response_text(response, 400, content, STRLEN(content)); cJSON_Delete(json); controller_free(controller); + + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the given name is invalid"); return; } + + strncpy(controller->name, json_name->valuestring, MAX_NAME_LENGTH); + controller->name[MAX_NAME_LENGTH] = '\0'; + LOGGER_DEBUG("new controller name: %s\n", controller->name); } cJSON *json_ip = cJSON_GetObjectItemCaseSensitive(json, "ip"); if(json_ip) { - if(cJSON_IsString(json_ip) && json_ip->valuestring) + if(!cJSON_IsString(json_ip) || json_ip->valuestring == NULL) { - unsigned char buf[sizeof(struct in_addr)]; - if(inet_pton(AF_INET, json_ip->valuestring, buf)) - { - strncpy(controller->ip, json_ip->valuestring, IP_LENGTH); - controller->ip[IP_LENGTH] = '\0'; - LOGGER_DEBUG("new controller ip: %s\n", controller->ip); - } - else - { - static const char content[] = "the given ip address is no valid IPv4 address"; - endpoint_response_text(response, 400, content, STRLEN(content)); - cJSON_Delete(json); - controller_free(controller); - return; - } + cJSON_Delete(json); + controller_free(controller); + + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "no ip address given"); + return; + } + + unsigned char buf[sizeof(struct in_addr)]; + if(inet_pton(AF_INET, json_ip->valuestring, buf)) + { + strncpy(controller->ip, json_ip->valuestring, IP_LENGTH); + controller->ip[IP_LENGTH] = '\0'; + LOGGER_DEBUG("new controller ip: %s\n", controller->ip); } else { - static const char content[] = "the given ip address is no valid string"; - endpoint_response_text(response, 400, content, STRLEN(content)); cJSON_Delete(json); controller_free(controller); + + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the given ip address is not valid"); return; } } if(controller_save(controller)) { - LOGGER_ERR("failed to save controller\n"); controller_free(controller); cJSON_Delete(json); - static const char content[] = "failed to save controller to database"; - endpoint_response_text(response, 500, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "failed to save controller to database"); return; } LOGGER_DEBUG("saved controller %s\n", args[0].value.v_str); @@ -165,10 +147,7 @@ api_v1_controllers_STR_DELETE(struct mg_connection *nc, struct http_message *hm, uuid_t target_uid; if(uuid_parse(target_uid_str, target_uid)) { - LOGGER_DEBUG("failed to unparse uid\n"); - - static const char content[] = "given id was invalid"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_400_NO_VALID_ID(response); return; } @@ -176,25 +155,17 @@ api_v1_controllers_STR_DELETE(struct mg_connection *nc, struct http_message *hm, if(!controller) { - LOGGER_DEBUG("could not find a controller for uid '%s'\n", args[0].value.v_str); - - static const char content[] = "no controller for id found"; - endpoint_response_text(response, 404, content, STRLEN(content)); + M_RESPONSE_404_NO_CONTROLLER_FOUND_FOR_ID(response); return; } if(controller_remove(controller)) { - LOGGER_ERR("failed to remove controller from database\n"); - - static const char content[] = "failed to remove controller from database"; - endpoint_response_text(response, 500, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "failed to remove controller from database"); } else { - LOGGER_DEBUG("deleted controller %s\n", args[0].value.v_str); - static const char content[] = "delete controller"; - endpoint_response_text(response, 200, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 200, "deleted controller"); } controller_free(controller); return; diff --git a/src/endpoints/api_v1_controllers_STR_relays.c b/src/endpoints/api_v1_controllers_STR_relays.c index 6accc90..ad8a83e 100644 --- a/src/endpoints/api_v1_controllers_STR_relays.c +++ b/src/endpoints/api_v1_controllers_STR_relays.c @@ -15,10 +15,7 @@ api_v1_controllers_STR_relays_GET(struct mg_connection *nc, struct http_message uuid_t target_uid; if(uuid_parse(args[0].value.v_str, target_uid)) { - LOGGER_DEBUG("failed to unparse uid\n"); - - static const char content[] = "given id was invalid"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_400_NO_VALID_ID(response); return; } @@ -26,10 +23,7 @@ api_v1_controllers_STR_relays_GET(struct mg_connection *nc, struct http_message if(!controller) { - LOGGER_DEBUG("could not find a controller for uid '%s'\n", args[0].value.v_str); - - static const char content[] = "no controller for id found"; - endpoint_response_text(response, 404, content, STRLEN(content)); + M_RESPONSE_404_NO_CONTROLLER_FOUND_FOR_ID(response); return; } diff --git a/src/endpoints/api_v1_controllers_STR_relays_INT.c b/src/endpoints/api_v1_controllers_STR_relays_INT.c index de5cf7b..d6ec00d 100644 --- a/src/endpoints/api_v1_controllers_STR_relays_INT.c +++ b/src/endpoints/api_v1_controllers_STR_relays_INT.c @@ -18,10 +18,7 @@ api_v1_controllers_STR_relays_INT_GET(struct mg_connection *nc, struct http_mess uuid_t target_uid; if(uuid_parse(args[0].value.v_str, target_uid)) { - LOGGER_DEBUG("failed to unparse uid\n"); - - static const char content[] = "given id was invalid"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_400_NO_VALID_ID(response); return; } @@ -29,10 +26,7 @@ api_v1_controllers_STR_relays_INT_GET(struct mg_connection *nc, struct http_mess if(!controller) { - LOGGER_DEBUG("could not find a controller for uid '%s'\n", args[0].value.v_str); - - static const char content[] = "no controller for id found"; - endpoint_response_text(response, 404, content, STRLEN(content)); + M_RESPONSE_404_NO_CONTROLLER_FOUND_FOR_ID(response); return; } @@ -43,10 +37,7 @@ api_v1_controllers_STR_relays_INT_GET(struct mg_connection *nc, struct http_mess if(!relay) { - LOGGER_DEBUG("could not find a relay with num %d for controller '%s'\n", args[1].value.v_int, args[0].value.v_str); - - static const char content[] = "no relay for this controller found"; - endpoint_response_text(response, 404, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "no relay for this controller found"); return; } @@ -67,10 +58,7 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *nc, struct http_mess uuid_t target_uid; if(uuid_parse(args[0].value.v_str, target_uid)) { - LOGGER_DEBUG("failed to unparse uid\n"); - - static const char content[] = "given id was invalid"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_400_NO_VALID_ID(response); return; } @@ -78,10 +66,7 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *nc, struct http_mess if(!controller) { - LOGGER_DEBUG("could not find a controller for uid '%s'\n", args[0].value.v_str); - - static const char content[] = "no controller for id found"; - endpoint_response_text(response, 404, content, STRLEN(content)); + M_RESPONSE_404_NO_CONTROLLER_FOUND_FOR_ID(response); return; } @@ -91,10 +76,7 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *nc, struct http_mess if(args[1].value.v_int > controller_relay_count) { - LOGGER_DEBUG("relay num %d is too high for %s\n", args[1].value.v_int, args[0].value.v_str); - - static const char content[] = "relay number is too high for this controller"; - endpoint_response_text(response, 404, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "relay number is too high for this controller"); return; } @@ -129,8 +111,7 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *nc, struct http_mess if(json == NULL) { - static const char content[] = "no valid json was supplied"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_400_NO_VALID_JSON(response); return; } @@ -154,21 +135,17 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *nc, struct http_mess cJSON *json_schedule_uid = cJSON_GetObjectItemCaseSensitive(json_schedule, "id"); if(!cJSON_IsString(json_schedule_uid) || (json_schedule_uid->valuestring == NULL)) { - LOGGER_DEBUG("schedules[%d] is missing uid\n", schedule_position); cJSON_Delete(json); - static const char content[] = "at least one schedule is missing an id"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one schedule is missing an id"); return; } uuid_t target_uid; if(schedule_uid_parse(json_schedule_uid->valuestring, target_uid)) { - LOGGER_DEBUG("schedules[%d] has bad uid\n", schedule_position); cJSON_Delete(json); - static const char content[] = "at least one schedule has a bad id"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "at least one schedule has a bad id"); return; } @@ -195,11 +172,9 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *nc, struct http_mess uuid_t target_uid; if(schedule_uid_parse(json_active_schedule_uid->valuestring, target_uid)) { - LOGGER_DEBUG("active_schedule has bad uid\n"); cJSON_Delete(json); - static const char content[] = "active_schedule has a bad id"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "active schedule has a bad uid"); return; } relay->schedules[day_of_week] = schedule_get_by_uid_or_off(target_uid); @@ -212,14 +187,10 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *nc, struct http_mess if(relay_save(relay)) { - LOGGER_ERR("failed to save relay\n"); - database_transaction_rollback(&lock); - cJSON_Delete(json); - static const char content[] = "failed to save relay to database"; - endpoint_response_text(response, 500, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "failed to save relay to database"); return; } @@ -238,16 +209,12 @@ api_v1_controllers_STR_relays_INT_PUT(struct mg_connection *nc, struct http_mess { if(!cJSON_IsString(json_tag) || (json_tag->valuestring == NULL)) { - LOGGER_DEBUG("invalid tag in tags\n"); - database_transaction_rollback(&lock); - relay_free(relay); cJSON_Delete(json); free(tag_ids); - static const char content[] = "invalid tag in tags"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "invalid tag in tags"); return; } const char *tag = json_tag->valuestring; diff --git a/src/endpoints/api_v1_controllers_STR_relays_INT_pulse.c b/src/endpoints/api_v1_controllers_STR_relays_INT_pulse.c index 97eb9de..f72812a 100644 --- a/src/endpoints/api_v1_controllers_STR_relays_INT_pulse.c +++ b/src/endpoints/api_v1_controllers_STR_relays_INT_pulse.c @@ -18,10 +18,7 @@ api_v1_controllers_STR_relays_INT_pulse_POST(struct mg_connection *nc, struct ht uuid_t target_uid; if(uuid_parse(args[0].value.v_str, target_uid)) { - LOGGER_DEBUG("failed to unparse uid\n"); - - static const char content[] = "given id was invalid"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_400_NO_VALID_ID(response); return; } @@ -29,10 +26,7 @@ api_v1_controllers_STR_relays_INT_pulse_POST(struct mg_connection *nc, struct ht if(!controller) { - LOGGER_DEBUG("could not find a controller for uid '%s'\n", args[0].value.v_str); - - static const char content[] = "no controller for id found"; - endpoint_response_text(response, 404, content, STRLEN(content)); + M_RESPONSE_404_NO_CONTROLLER_FOUND_FOR_ID(response); return; } @@ -43,10 +37,7 @@ api_v1_controllers_STR_relays_INT_pulse_POST(struct mg_connection *nc, struct ht if(!relay) { - LOGGER_DEBUG("could not find a relay with num %d for controller '%s'\n", args[1].value.v_int, args[0].value.v_str); - - static const char content[] = "no relay for this controller found"; - endpoint_response_text(response, 404, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "no relay found"); return; } @@ -67,7 +58,6 @@ api_v1_controllers_STR_relays_INT_pulse_POST(struct mg_connection *nc, struct ht LOGGER_DEBUG("commanding pulse to relay %d for controller %s\n", args[1].value.v_int, args[0].value.v_str); command_relay_pulse(relay, duration); - static const char content[] = "sent pulse"; - endpoint_response_text(response, 200, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 200, "sent pulse"); relay_free(relay); } diff --git a/src/endpoints/api_v1_controllers_discover.c b/src/endpoints/api_v1_controllers_discover.c index d2e00d7..c6d7648 100644 --- a/src/endpoints/api_v1_controllers_discover.c +++ b/src/endpoints/api_v1_controllers_discover.c @@ -114,13 +114,7 @@ api_v1_controllers_discover_POST(struct mg_connection *nc, struct http_message * if(discover_server_port == -1) { - LOGGER_ERR("failed to get server port for discovery\n"); - static const char content[] = ""; - response->status_code = 500; - response->content_type = "text/plain"; - response->content_length = STRLEN(content);; - response->content = content; - response->alloced_content = false; + M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "the server failed to prepare discovery"); return; } @@ -130,13 +124,7 @@ api_v1_controllers_discover_POST(struct mg_connection *nc, struct http_message * LOGGER_DEBUG("sending udp broadcast\n"); if(send_udp_broadcast("255.255.255.255", global_config.discovery_port, payload, sizeof(payload)) < 0) { - LOGGER_ERR("failed to send UDP broadcast\n"); - static const char content[] = ""; - response->status_code = 500; - response->content_type = "text/plain"; - response->content_length = STRLEN(content);; - response->content = content; - response->alloced_content = false; + M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "the server failed to send discovery broadcast"); return; } diff --git a/src/endpoints/api_v1_macros.c b/src/endpoints/api_v1_macros.c index 309eec8..e78b14f 100644 --- a/src/endpoints/api_v1_macros.c +++ b/src/endpoints/api_v1_macros.c @@ -42,30 +42,23 @@ api_v1_macros_POST(struct mg_connection *nc, struct http_message *hm, endpoint_a if(json == NULL) { - static const char content[] = "no valid json was supplied"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_400_NO_VALID_JSON(response); return; } cJSON *json_name = cJSON_GetObjectItemCaseSensitive(json, "name"); if(!cJSON_IsString(json_name) || (json_name->valuestring == NULL)) { - LOGGER_DEBUG("no name for macro provided\n"); - cJSON_Delete(json); - - static const char content[] = "no name for macro provided"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_400_NO_NAME(response); return; } cJSON *json_actions = cJSON_GetObjectItemCaseSensitive(json, "actions"); if(!cJSON_IsArray(json_actions)) { - LOGGER_DEBUG("no actions for macro provided\n"); cJSON_Delete(json); - static const char content[] = "no actions for macro provided"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request does not contains actions for the macro"); return; } @@ -82,15 +75,11 @@ api_v1_macros_POST(struct mg_connection *nc, struct http_message *hm, endpoint_a if(macro_save(new_macro)) { - LOGGER_DEBUG("macro could not be saved\n"); - database_transaction_rollback(&lock); - cJSON_Delete(json); macro_free(new_macro); - static const char content[] = "macro could not be saved"; - endpoint_response_text(response, 500, content, STRLEN(content)); + M_RESPONSE_500_FAILED_TO_SAVE_TO_DATABASE(response); return; } @@ -100,56 +89,53 @@ api_v1_macros_POST(struct mg_connection *nc, struct http_message *hm, endpoint_a cJSON *json_action_weekday = cJSON_GetObjectItemCaseSensitive(json_action, "weekday"); if(!cJSON_IsNumber(json_action_weekday) || (json_action_weekday->valueint < 0) || (json_action_weekday->valueint > 6)) { - LOGGER_DEBUG("one action is missing a weekday\n"); + database_transaction_rollback(&lock); cJSON_Delete(json); macro_free(new_macro); - static const char content[] = "one action is missing a weekday"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains an action without weekday"); return; } cJSON *json_action_schedule = cJSON_GetObjectItemCaseSensitive(json_action, "schedule"); if(!cJSON_IsObject(json_action_schedule)) { - LOGGER_DEBUG("action is missing schedule\n"); + database_transaction_rollback(&lock); cJSON_Delete(json); macro_free(new_macro); - static const char content[] = "one action is missing schedule"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains an action without schedule"); return; } cJSON *json_action_schedule_uid = cJSON_GetObjectItemCaseSensitive(json_action_schedule, "id"); if(!cJSON_IsString(json_action_schedule_uid) || (json_action_schedule_uid->valuestring == NULL)) { - LOGGER_DEBUG("action is missing schedule id\n"); + database_transaction_rollback(&lock); cJSON_Delete(json); macro_free(new_macro); - static const char content[] = "one action is missing schedule id"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains an action without schedule id"); return; } uuid_t action_schedule_uid; if(schedule_uid_parse(json_action_schedule_uid->valuestring, action_schedule_uid)) { - LOGGER_DEBUG("action schedule has bad uid\n"); + database_transaction_rollback(&lock); cJSON_Delete(json); + macro_free(new_macro); - static const char content[] = "action schedule has bad id"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains an action with an invalid schedule id"); return; } schedule_t *action_schedule = schedule_get_by_uid(action_schedule_uid); if(action_schedule == NULL) { - LOGGER_DEBUG("action schedule was not found\n"); + database_transaction_rollback(&lock); cJSON_Delete(json); + macro_free(new_macro); - static const char content[] = "action schedule was not found"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "the schedule for at least one action was not found"); return; } @@ -160,55 +146,52 @@ api_v1_macros_POST(struct mg_connection *nc, struct http_message *hm, endpoint_a cJSON *json_action_relay = cJSON_GetObjectItemCaseSensitive(json_action, "relay"); if(!cJSON_IsObject(json_action_relay)) { - LOGGER_DEBUG("action is missing relay\n"); + database_transaction_rollback(&lock); cJSON_Delete(json); macro_free(new_macro); - static const char content[] = "one action is missing relay"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains an action without relay"); return; } cJSON *json_action_relay_number = cJSON_GetObjectItemCaseSensitive(json_action_relay, "number"); if(!cJSON_IsNumber(json_action_relay_number)) { - LOGGER_DEBUG("action is missing relay number\n"); + database_transaction_rollback(&lock); cJSON_Delete(json); macro_free(new_macro); - static const char content[] = "one action is missing relay number"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains an action without relay number"); return; } cJSON *json_action_relay_controller_uid = cJSON_GetObjectItemCaseSensitive(json_action_relay, "controller_id"); if(!cJSON_IsString(json_action_relay_controller_uid) || (json_action_relay_controller_uid->valuestring == NULL)) { - LOGGER_DEBUG("action is missing relay controller id\n"); + database_transaction_rollback(&lock); cJSON_Delete(json); macro_free(new_macro); - static const char content[] = "one action is missing relay controller id"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains an action without relay controller id"); return; } uuid_t action_controller_uid; if(uuid_parse(json_action_relay_controller_uid->valuestring, action_controller_uid)) { - LOGGER_DEBUG("action controller has bad uid\n"); + database_transaction_rollback(&lock); cJSON_Delete(json); + macro_free(new_macro); - static const char content[] = "action controller has bad id"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains an action with an invalid relay controller id"); return; } controller_t *action_controller = controller_get_by_uid(action_controller_uid); if(action_controller == NULL) { - LOGGER_DEBUG("action controller was not found\n"); + database_transaction_rollback(&lock); cJSON_Delete(json); + macro_free(new_macro); - static const char content[] = "action controller was not found"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "the controller for at least one action relay was not found"); return; } @@ -220,11 +203,11 @@ api_v1_macros_POST(struct mg_connection *nc, struct http_message *hm, endpoint_a relay_t *action_relay = relay_get_for_controller(controller_id, relay_num); if(action_relay == NULL) { - LOGGER_DEBUG("action relay was not found\n"); + database_transaction_rollback(&lock); cJSON_Delete(json); + macro_free(new_macro); - static const char content[] = "action relay was not found"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "the relay for at least one action was not found"); return; } diff --git a/src/endpoints/api_v1_macros_STR.c b/src/endpoints/api_v1_macros_STR.c new file mode 100644 index 0000000..e2d228f --- /dev/null +++ b/src/endpoints/api_v1_macros_STR.c @@ -0,0 +1,281 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void +api_v1_macros_STR_GET(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response) +{ + (void)hm; + (void)nc; + + uuid_t target_uid; + if(uuid_parse(args[0].value.v_str, target_uid)) + { + M_RESPONSE_400_NO_VALID_ID(response); + return; + } + + macro_t* macro = macro_get_by_uid(target_uid); + + if(!macro) + { + M_RESPONSE_404_NO_MACRO_FOUND_FOR_ID(response); + return; + } + + cJSON *json = macro_to_json(macro); + + endpoint_response_json(response, 200, json); + cJSON_Delete(json); + macro_free(macro); +} + +void +api_v1_macros_STR_PUT(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response) +{ + (void)hm; + (void)nc; + + uuid_t target_uid; + if(uuid_parse(args[0].value.v_str, target_uid)) + { + M_RESPONSE_400_NO_VALID_ID(response); + return; + } + + macro_t* macro = macro_get_by_uid(target_uid); + + if(!macro) + { + M_RESPONSE_404_NO_MACRO_FOUND_FOR_ID(response); + return; + } + + cJSON *json = cJSON_ParseWithLength(hm->body.p, hm->body.len); + + if(json == NULL) + { + M_RESPONSE_400_NO_VALID_JSON(response); + return; + } + + database_transaction_lock lock; + database_transaction_begin(&lock); + + cJSON *json_name = cJSON_GetObjectItemCaseSensitive(json, "name"); + if(cJSON_IsString(json_name) && (json_name->valuestring != NULL)) + { + strncpy(macro->name, json_name->valuestring, MAX_NAME_LENGTH); + macro->name[MAX_NAME_LENGTH] = '\0'; + + if(macro_save(macro)) + { + database_transaction_rollback(&lock); + cJSON_Delete(json); + macro_free(macro); + + M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "macro could not be saved"); + return; + } + } + + cJSON *json_actions = cJSON_GetObjectItemCaseSensitive(json, "actions"); + if(cJSON_IsArray(json_actions)) + { + macro_action_delete_for_macro(macro->id); + + cJSON *json_action; + cJSON_ArrayForEach(json_action, json_actions) + { + cJSON *json_action_weekday = cJSON_GetObjectItemCaseSensitive(json_action, "weekday"); + if(!cJSON_IsNumber(json_action_weekday) || (json_action_weekday->valueint < 0) || (json_action_weekday->valueint > 6)) + { + database_transaction_rollback(&lock); + cJSON_Delete(json); + macro_free(macro); + + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one action is missing a weekday"); + return; + } + + cJSON *json_action_schedule = cJSON_GetObjectItemCaseSensitive(json_action, "schedule"); + if(!cJSON_IsObject(json_action_schedule)) + { + database_transaction_rollback(&lock); + cJSON_Delete(json); + macro_free(macro); + + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one action is missing a schedule"); + return; + } + cJSON *json_action_schedule_uid = cJSON_GetObjectItemCaseSensitive(json_action_schedule, "id"); + if(!cJSON_IsString(json_action_schedule_uid) || (json_action_schedule_uid->valuestring == NULL)) + { + database_transaction_rollback(&lock); + cJSON_Delete(json); + macro_free(macro); + + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one action is missing a schedule id"); + return; + } + uuid_t action_schedule_uid; + if(schedule_uid_parse(json_action_schedule_uid->valuestring, action_schedule_uid)) + { + database_transaction_rollback(&lock); + cJSON_Delete(json); + macro_free(macro); + + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one action has a bad schedule id"); + return; + } + + schedule_t *action_schedule = schedule_get_by_uid(action_schedule_uid); + if(action_schedule == NULL) + { + database_transaction_rollback(&lock); + cJSON_Delete(json); + macro_free(macro); + + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one action schedule was not found"); + return; + } + + int action_schedule_id = action_schedule->id; + schedule_free(action_schedule); + + + cJSON *json_action_relay = cJSON_GetObjectItemCaseSensitive(json_action, "relay"); + if(!cJSON_IsObject(json_action_relay)) + { + database_transaction_rollback(&lock); + cJSON_Delete(json); + macro_free(macro); + + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one action is missing a relay"); + return; + } + cJSON *json_action_relay_number = cJSON_GetObjectItemCaseSensitive(json_action_relay, "number"); + if(!cJSON_IsNumber(json_action_relay_number)) + { + database_transaction_rollback(&lock); + cJSON_Delete(json); + macro_free(macro); + + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one action is missing a relay number"); + return; + } + cJSON *json_action_relay_controller_uid = cJSON_GetObjectItemCaseSensitive(json_action_relay, "controller_id"); + if(!cJSON_IsString(json_action_relay_controller_uid) || (json_action_relay_controller_uid->valuestring == NULL)) + { + database_transaction_rollback(&lock); + cJSON_Delete(json); + macro_free(macro); + + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one action is missing a relay controller id"); + return; + } + uuid_t action_controller_uid; + if(uuid_parse(json_action_relay_controller_uid->valuestring, action_controller_uid)) + { + database_transaction_rollback(&lock); + cJSON_Delete(json); + macro_free(macro); + + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one action has a bad relay controller id"); + return; + } + + controller_t *action_controller = controller_get_by_uid(action_controller_uid); + if(action_controller == NULL) + { + database_transaction_rollback(&lock); + cJSON_Delete(json); + macro_free(macro); + + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "at least one action relay controller was not found"); + return; + } + + int controller_id = action_controller->id; + int relay_num = json_action_relay_number->valueint; + + controller_free(action_controller); + + relay_t *action_relay = relay_get_for_controller(controller_id, relay_num); + if(action_relay == NULL) + { + database_transaction_rollback(&lock); + cJSON_Delete(json); + macro_free(macro); + + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "action relay was not found"); + return; + } + + int action_relay_id = action_relay->id; + relay_free(action_relay); + + + macro_action_t *action = malloc(sizeof(macro_action_t)); + action->macro_id = macro->id; + action->relay_id = action_relay_id; + action->schedule_id = action_schedule_id; + action->weekday = json_action_weekday->valueint; + + macro_action_insert(action); + free(action); + } + } + + database_transaction_commit(&lock); + + cJSON_Delete(json); + json = macro_to_json(macro); + + endpoint_response_json(response, 201, json); + + cJSON_Delete(json); + macro_free(macro); +} + +void +api_v1_macros_STR_DELETE(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response) +{ + (void)hm; + (void)nc; + + const char *target_uid_str = args[0].value.v_str; + + uuid_t target_uid; + if(uuid_parse(target_uid_str, target_uid)) + { + M_RESPONSE_400_NO_VALID_ID(response); + return; + } + + macro_t* macro = macro_get_by_uid(target_uid); + + if(!macro) + { + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 404, "no macro with id found"); + return; + } + + if(macro_remove(macro)) + { + M_RESPONSE_TEXT_STATIC(LOGGER_ERR, response, 500, "failed to remove macro from database"); + } + else + { + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 200, "deleted macro"); + } + macro_free(macro); + return; +} diff --git a/src/endpoints/api_v1_relays_tag_STR.c b/src/endpoints/api_v1_relays_tag_STR.c index 06a6adc..ffce429 100644 --- a/src/endpoints/api_v1_relays_tag_STR.c +++ b/src/endpoints/api_v1_relays_tag_STR.c @@ -16,17 +16,13 @@ api_v1_relays_tag_STR_GET(struct mg_connection *nc, struct http_message *hm, end int tag_id = tag_get_id(args[0].value.v_str); if(tag_id == 0) { - static const char content[] = "tag was not found"; - endpoint_response_text(response, 404, content, STRLEN(content)); + M_RESPONSE_404_NO_TAG_FOUND(response); return; } int *relays_ids = junction_tag_get_relays_for_tag_id(tag_id); if(relays_ids == NULL) { - LOGGER_ERR("failed to load relays for tag from database\n"); - - static const char content[] = "failed to load relays for tag from database"; - endpoint_response_text(response, 500, content, STRLEN(content)); + M_RESPONSE_500_FAILED_TO_READ_FROM_DATABASE(response); return; } diff --git a/src/endpoints/api_v1_schedules.c b/src/endpoints/api_v1_schedules.c index eda0f2e..7a9ad6e 100644 --- a/src/endpoints/api_v1_schedules.c +++ b/src/endpoints/api_v1_schedules.c @@ -16,30 +16,23 @@ api_v1_schedules_POST(struct mg_connection *nc, struct http_message *hm, endpoin if(json == NULL) { - static const char content[] = "no valid json was supplied"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_400_NO_VALID_JSON(response); return; } cJSON *json_name = cJSON_GetObjectItemCaseSensitive(json, "name"); if(!cJSON_IsString(json_name) || (json_name->valuestring == NULL)) { - LOGGER_DEBUG("no name for schedule provided\n"); - cJSON_Delete(json); - - static const char content[] = "no name for schedule provided"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_400_NO_NAME(response); return; } cJSON *json_periods = cJSON_GetObjectItemCaseSensitive(json, "periods"); if(!cJSON_IsArray(json_periods)) { - LOGGER_DEBUG("no periods for schedule provided\n"); cJSON_Delete(json); - static const char content[] = "no periods for schedule provided"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request does not contain periods"); return; } @@ -49,11 +42,9 @@ api_v1_schedules_POST(struct mg_connection *nc, struct http_message *hm, endpoin { if(!cJSON_IsString(json_tag) || (json_tag->valuestring == NULL)) { - LOGGER_DEBUG("invalid tag in tags\n"); cJSON_Delete(json); - static const char content[] = "invalid tag in tags"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains at least one invalid tag"); return; } } @@ -79,22 +70,18 @@ api_v1_schedules_POST(struct mg_connection *nc, struct http_message *hm, endpoin if(!cJSON_IsString(json_period_start) || (json_period_start->valuestring == NULL)) { - LOGGER_DEBUG("period is missing start\n"); cJSON_Delete(json); schedule_free(new_schedule); - static const char content[] = "one period is missing a start"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains at least one period without a start"); return; } if(!cJSON_IsString(json_period_end) || (json_period_end->valuestring == NULL)) { - LOGGER_DEBUG("period is missing end\n"); cJSON_Delete(json); schedule_free(new_schedule); - static const char content[] = "one period is missing an end"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains at least one period without an end"); return; } @@ -102,22 +89,18 @@ api_v1_schedules_POST(struct mg_connection *nc, struct http_message *hm, endpoin uint16_t end; if(period_helper_parse_hhmm(json_period_start->valuestring, &start)) { - LOGGER_DEBUG("couldn't parse start '%s'\n", json_period_start->valuestring); cJSON_Delete(json); schedule_free(new_schedule); - static const char content[] = "the start for one period is invalid"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains at least one period with an invalid start"); return; } if(period_helper_parse_hhmm(json_period_end->valuestring, &end)) { - LOGGER_DEBUG("couldn't parse end '%s'\n", json_period_end->valuestring); cJSON_Delete(json); schedule_free(new_schedule); - static const char content[] = "the end for one period is invalid"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains at least one period with an invalid end"); return; } diff --git a/src/endpoints/api_v1_schedules_STR.c b/src/endpoints/api_v1_schedules_STR.c index 26e8689..3abc0c8 100644 --- a/src/endpoints/api_v1_schedules_STR.c +++ b/src/endpoints/api_v1_schedules_STR.c @@ -19,10 +19,7 @@ api_v1_schedules_STR_GET(struct mg_connection *nc, struct http_message *hm, endp uuid_t target_uid; if(schedule_uid_parse(args[0].value.v_str, target_uid)) { - LOGGER_DEBUG("failed to unparse uid\n"); - - static const char content[] = "given id was invalid"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_400_NO_VALID_ID(response); return; } @@ -30,10 +27,7 @@ api_v1_schedules_STR_GET(struct mg_connection *nc, struct http_message *hm, endp if(!schedule) { - LOGGER_DEBUG("could not find a schedule for uid '%s'\n", args[0].value.v_str); - - static const char content[] = "no schedule for id found"; - endpoint_response_text(response, 404, content, STRLEN(content)); + M_RESPONSE_404_NO_SCHEDULE_FOUND_FOR_ID(response); return; } @@ -53,10 +47,7 @@ api_v1_schedules_STR_PUT(struct mg_connection *nc, struct http_message *hm, endp uuid_t target_uid; if(schedule_uid_parse(args[0].value.v_str, target_uid)) { - LOGGER_DEBUG("failed to unparse uid\n"); - - static const char content[] = "given id was invalid"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_400_NO_VALID_ID(response); return; } @@ -64,10 +55,7 @@ api_v1_schedules_STR_PUT(struct mg_connection *nc, struct http_message *hm, endp if(!schedule) { - LOGGER_DEBUG("could not find a schedule for uid '%s'\n", args[0].value.v_str); - - static const char content[] = "no schedule for id found"; - endpoint_response_text(response, 404, content, STRLEN(content)); + M_RESPONSE_404_NO_SCHEDULE_FOUND_FOR_ID(response); return; } @@ -75,8 +63,7 @@ api_v1_schedules_STR_PUT(struct mg_connection *nc, struct http_message *hm, endp if(json == NULL) { - static const char content[] = "no valid json was supplied"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_400_NO_VALID_JSON(response); return; } @@ -137,12 +124,10 @@ api_v1_schedules_STR_PUT(struct mg_connection *nc, struct http_message *hm, endp if(schedule_save(schedule)) { - LOGGER_ERR("failed to save schedule\n"); free(schedule); cJSON_Delete(json); - static const char content[] = "failed to save schedule to database"; - endpoint_response_text(response, 500, content, STRLEN(content)); + M_RESPONSE_500_FAILED_TO_SAVE_TO_DATABASE(response); return; } @@ -190,10 +175,7 @@ api_v1_schedules_STR_DELETE(struct mg_connection *nc, struct http_message *hm, e uuid_t target_uid; if(schedule_uid_parse(target_uid_str, target_uid)) { - LOGGER_DEBUG("failed to unparse uid\n"); - - static const char content[] = "given id was invalid"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_400_NO_VALID_ID(response); return; } @@ -201,33 +183,25 @@ api_v1_schedules_STR_DELETE(struct mg_connection *nc, struct http_message *hm, e if(!schedule) { - LOGGER_DEBUG("could not find a schedule for uid '%s'\n", args[0].value.v_str); - - static const char content[] = "no schedule for id found"; - endpoint_response_text(response, 404, content, STRLEN(content)); + M_RESPONSE_404_NO_SCHEDULE_FOUND_FOR_ID(response); return; } if(schedule_is_protected(schedule)) { - static const char content[] = "target schedule is protected"; - endpoint_response_text(response, 403, content, STRLEN(content)); - schedule_free(schedule); + + M_RESPONSE_403_PROTECTED_SCHEDULE(response); return; } if(schedule_remove(schedule)) { - LOGGER_ERR("failed to remove schedule from database\n"); - - static const char content[] = "failed to remove schedule from database"; - endpoint_response_text(response, 500, content, STRLEN(content)); + M_RESPONSE_500_FAILED_TO_DELETE_FROM_DATABASE(response); } else { - static const char content[] = "deleted schedule"; - endpoint_response_text(response, 200, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 200, "the target schedule got deleted"); } schedule_free(schedule); return; diff --git a/src/endpoints/api_v1_schedules_list.c b/src/endpoints/api_v1_schedules_list.c index ede980b..46d2b8a 100644 --- a/src/endpoints/api_v1_schedules_list.c +++ b/src/endpoints/api_v1_schedules_list.c @@ -20,29 +20,23 @@ api_v1_schedules_list_POST(struct mg_connection *nc, struct http_message *hm, en { if(json == NULL) { - static const char content[] = "no valid json was supplied"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_400_NO_VALID_JSON(response); return; } cJSON *json_name = cJSON_GetObjectItemCaseSensitive(json, "name"); if(!cJSON_IsString(json_name) || (json_name->valuestring == NULL)) { - LOGGER_DEBUG("no name for schedule provided\n"); - cJSON_Delete(json_list); - - static const char content[] = "no name for schedule provided"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request does not contain a name for at least one schedule"); return; } + cJSON *json_periods = cJSON_GetObjectItemCaseSensitive(json, "periods"); if(!cJSON_IsArray(json_periods)) { - LOGGER_DEBUG("no periods for schedule provided\n"); cJSON_Delete(json_list); - static const char content[] = "no periods for schedule provided"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request does not contain periods for at least one schedule"); return; } @@ -52,11 +46,9 @@ api_v1_schedules_list_POST(struct mg_connection *nc, struct http_message *hm, en { if(!cJSON_IsString(json_tag) || (json_tag->valuestring == NULL)) { - LOGGER_DEBUG("invalid tag in tags\n"); cJSON_Delete(json_list); - static const char content[] = "invalid tag in tags"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains at least one invalid tag"); return; } } @@ -82,22 +74,18 @@ api_v1_schedules_list_POST(struct mg_connection *nc, struct http_message *hm, en if(!cJSON_IsString(json_period_start) || (json_period_start->valuestring == NULL)) { - LOGGER_DEBUG("period is missing start\n"); cJSON_Delete(json_list); schedule_free(new_schedule); - static const char content[] = "one period is missing a start"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains at least one period without a start"); return; } if(!cJSON_IsString(json_period_end) || (json_period_end->valuestring == NULL)) { - LOGGER_DEBUG("period is missing end\n"); cJSON_Delete(json_list); schedule_free(new_schedule); - static const char content[] = "one period is missing an end"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains at least one period without an end"); return; } @@ -105,22 +93,18 @@ api_v1_schedules_list_POST(struct mg_connection *nc, struct http_message *hm, en uint16_t end; if(period_helper_parse_hhmm(json_period_start->valuestring, &start)) { - LOGGER_DEBUG("couldn't parse start '%s'\n", json_period_start->valuestring); cJSON_Delete(json_list); schedule_free(new_schedule); - static const char content[] = "the start for one period is invalid"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains at least one period with an invalid start"); return; } if(period_helper_parse_hhmm(json_period_end->valuestring, &end)) { - LOGGER_DEBUG("couldn't parse end '%s'\n", json_period_end->valuestring); cJSON_Delete(json_list); schedule_free(new_schedule); - static const char content[] = "the end for one period is invalid"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains at least one period with an invalid end"); return; } diff --git a/src/endpoints/api_v1_schedules_tag_STR.c b/src/endpoints/api_v1_schedules_tag_STR.c index b0d22ec..08723dc 100644 --- a/src/endpoints/api_v1_schedules_tag_STR.c +++ b/src/endpoints/api_v1_schedules_tag_STR.c @@ -16,17 +16,13 @@ api_v1_schedules_tag_STR_GET(struct mg_connection *nc, struct http_message *hm, int tag_id = tag_get_id(args[0].value.v_str); if(tag_id == 0) { - static const char content[] = "tag was not found"; - endpoint_response_text(response, 404, content, STRLEN(content)); + M_RESPONSE_404_NO_TAG_FOUND(response); return; } int *schedules_ids = junction_tag_get_schedules_for_tag_id(tag_id); if(schedules_ids == NULL) { - LOGGER_ERR("failed to load schedules for tag from database\n"); - - static const char content[] = "failed to load schedules for tag from database"; - endpoint_response_text(response, 500, content, STRLEN(content)); + M_RESPONSE_500_FAILED_TO_READ_FROM_DATABASE(response); return; } diff --git a/src/endpoints/api_v1_tags.c b/src/endpoints/api_v1_tags.c index 26b08b6..928ec17 100644 --- a/src/endpoints/api_v1_tags.c +++ b/src/endpoints/api_v1_tags.c @@ -44,48 +44,38 @@ api_v1_tags_POST(struct mg_connection *nc, struct http_message *hm, endpoint_arg if(json == NULL) { - static const char content[] = "no valid json was supplied"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_400_NO_VALID_JSON(response); return; } cJSON *json_tag = cJSON_GetObjectItemCaseSensitive(json, "tag"); if(!cJSON_IsString(json_tag) || (json_tag->valuestring == NULL)) { - LOGGER_DEBUG("no tag provided\n"); cJSON_Delete(json); - static const char content[] = "no tag provided"; - endpoint_response_text(response, 400, content, STRLEN(content)); - return; - } - - if(tag_get_id(json_tag->valuestring)) - { - LOGGER_DEBUG("tag existed already\n"); - cJSON_Delete(json); - - static const char content[] = "tag existed already"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request does not contain a tag"); return; } if(strlen(json_tag->valuestring) == 0) { - LOGGER_DEBUG("tag is empty\n"); cJSON_Delete(json); - static const char content[] = "tag is empty"; - endpoint_response_text(response, 400, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the request contains an empty tag"); + return; + } + + if(tag_get_id(json_tag->valuestring)) + { + cJSON_Delete(json); + + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 400, "the tag does already exist"); return; } if(tag_save(0, json_tag->valuestring)) { - LOGGER_DEBUG("tag could not be saved\n"); - - static const char content[] = "tag could not be saved"; - endpoint_response_text(response, 500, content, STRLEN(content)); + M_RESPONSE_500_FAILED_TO_SAVE_TO_DATABASE(response); } else { diff --git a/src/endpoints/api_v1_tags_STR.c b/src/endpoints/api_v1_tags_STR.c index 6aca7f0..e0e7c55 100644 --- a/src/endpoints/api_v1_tags_STR.c +++ b/src/endpoints/api_v1_tags_STR.c @@ -16,26 +16,19 @@ api_v1_tags_STR_GET(struct mg_connection *nc, struct http_message *hm, endpoint_ int tag_id = tag_get_id(args[0].value.v_str); if(tag_id == 0) { - static const char content[] = "tag was not found"; - endpoint_response_text(response, 404, content, STRLEN(content)); + M_RESPONSE_404_NO_TAG_FOUND(response); return; } int *relays_ids = junction_tag_get_relays_for_tag_id(tag_id); if(relays_ids == NULL) { - LOGGER_ERR("failed to load relays for tag from database\n"); - - static const char content[] = "failed to load relays for tag from database"; - endpoint_response_text(response, 500, content, STRLEN(content)); + M_RESPONSE_500_FAILED_TO_READ_FROM_DATABASE(response); return; } int *schedules_ids = junction_tag_get_schedules_for_tag_id(tag_id); if(schedules_ids == NULL) { - LOGGER_ERR("failed to load schedules for tag from database\n"); - - static const char content[] = "failed to load schedules for tag from database"; - endpoint_response_text(response, 500, content, STRLEN(content)); + M_RESPONSE_500_FAILED_TO_READ_FROM_DATABASE(response); return; } @@ -91,21 +84,16 @@ api_v1_tags_STR_DELETE(struct mg_connection *nc, struct http_message *hm, endpoi int tag_id = tag_get_id(args[0].value.v_str); if(tag_id == 0) { - static const char content[] = "tag was not found"; - endpoint_response_text(response, 404, content, STRLEN(content)); + M_RESPONSE_404_NO_TAG_FOUND(response); return; } if(tag_remove(tag_id)) { - LOGGER_ERR("failed to remove tag from database\n"); - - static const char content[] = "failed to remove tag from database"; - endpoint_response_text(response, 500, content, STRLEN(content)); + M_RESPONSE_500_FAILED_TO_DELETE_FROM_DATABASE(response); } else { - static const char content[] = "deleted tag"; - endpoint_response_text(response, 200, content, STRLEN(content)); + M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 200, "the tag got deleted"); } } diff --git a/src/handlers/http.c b/src/handlers/http.c index 87d2908..84c4a36 100644 --- a/src/handlers/http.c +++ b/src/handlers/http.c @@ -82,8 +82,8 @@ handle_http_request(struct mg_connection *nc, struct http_message *hm) endpoint_t *endpoint = router_find_endpoint(hm->uri.p, hm->uri.len, &hm->method); endpoint_response_t response; - static const char content[] = "the server did not create a response"; - endpoint_response_text(&response, 500, content, STRLEN(content)); + + M_RESPONSE_TEXT_STATIC(LOGGER_NONE, &response, 500, "server did not create a response"); if(!endpoint) { diff --git a/src/logger.c b/src/logger.c index 2869668..1839d38 100644 --- a/src/logger.c +++ b/src/logger.c @@ -17,7 +17,7 @@ const char *COLOR_EMERG = COLOR_MAGENTA; void logger_log(int level, const char *filename, int line, const char *func, const char *msg, ...) { - if(global_config.log_level < level) + if(global_config.log_level < level || level == LOG_NONE ) { return; } diff --git a/src/models/junction_relay_schedule.c b/src/models/junction_relay_schedule.c index 63f844c..f0854bf 100644 --- a/src/models/junction_relay_schedule.c +++ b/src/models/junction_relay_schedule.c @@ -40,14 +40,14 @@ junction_relay_schedule_insert_weekdays(int relay_id, int *schedule_ids) static const char query_base[] = "INSERT INTO junction_relay_schedule (weekday, schedule_id, relay_id) VALUES"; static const char query_extender[] = " (?, ?, ?)"; - size_t query_len = STRLEN(query_base) + (7 * (STRLEN(query_extender) + 1)) + 1; + size_t query_len = M_STRLEN(query_base) + (7 * (M_STRLEN(query_extender) + 1)) + 1; char *query = malloc(sizeof(char) * query_len + 1); strncpy(query, query_base, query_len); - query_len -= STRLEN(query_base); + query_len -= M_STRLEN(query_base); for(int i = 0; i < 7; ++i) { strncat(query, query_extender, query_len); - query_len -= STRLEN(query_extender); + query_len -= M_STRLEN(query_extender); char *query_divider = (i < 7 - 1) ? "," : ";"; strncat(query, query_divider, query_len); query_len -= 1; diff --git a/src/models/junction_tag.c b/src/models/junction_tag.c index e03a195..7d84af5 100644 --- a/src/models/junction_tag.c +++ b/src/models/junction_tag.c @@ -67,14 +67,14 @@ junction_tag_insert_list(int *tag_ids, int relay_id, int schedule_id, int count) static const char query_base[] = "INSERT INTO junction_tag(tag_id, schedule_id, relay_id) VALUES"; static const char query_extender[] = " (?, ?, ?)"; - size_t query_len = STRLEN(query_base) + (count * (STRLEN(query_extender) + 1)) + 1; + size_t query_len = M_STRLEN(query_base) + (count * (M_STRLEN(query_extender) + 1)) + 1; char *query = malloc(sizeof(char) * query_len + 1); strncpy(query, query_base, query_len); - query_len -= STRLEN(query_base); + query_len -= M_STRLEN(query_base); for(int i = 0; i < count; ++i) { strncat(query, query_extender, query_len); - query_len -= STRLEN(query_extender); + query_len -= M_STRLEN(query_extender); char *query_divider = (i < count - 1) ? "," : ";"; strncat(query, query_divider, query_len); query_len -= 1; diff --git a/src/models/macro.c b/src/models/macro.c index a40ed61..5bffdb3 100644 --- a/src/models/macro.c +++ b/src/models/macro.c @@ -143,7 +143,7 @@ int macro_remove(macro_t *macro) { sqlite3_stmt *stmt; - if(!macro->id) + if(macro->id == 0) { return 0; } @@ -155,6 +155,8 @@ macro_remove(macro_t *macro) sqlite3_finalize(stmt); + cache_invalidate_macro(macro->id); + return rc != SQLITE_DONE; } diff --git a/src/models/macro_action.c b/src/models/macro_action.c index c0333c5..eb07116 100644 --- a/src/models/macro_action.c +++ b/src/models/macro_action.c @@ -94,6 +94,23 @@ macro_action_insert(macro_action_t *macro_action) return rc != SQLITE_DONE; } +int +macro_action_delete_for_macro(int macro_id) +{ + sqlite3_stmt *stmt; + + sqlite3_prepare_v2(global_database, "DELETE FROM macro_actions WHERE macro_id=?1;", -1, &stmt, NULL); + sqlite3_bind_int(stmt, 1, macro_id); + + int rc = sqlite3_step(stmt); + + sqlite3_finalize(stmt); + + cache_invalidate_macro(macro_id); + + return rc != SQLITE_DONE; +} + macro_action_t** macro_action_get_for_macro(int macro_id) { diff --git a/src/router.c b/src/router.c index b4b0387..23ef95d 100644 --- a/src/router.c +++ b/src/router.c @@ -93,8 +93,9 @@ router_init() router_register_endpoint("/api/v1/macros/", HTTP_METHOD_GET, api_v1_macros_GET); router_register_endpoint("/api/v1/macros/", HTTP_METHOD_POST, api_v1_macros_POST); - //router_register_endpoint("/api/v1/macros/{str}", HTTP_METHOD_GET, api_v1_macros_STR_GET); - //router_register_endpoint("/api/v1/macros/{str}", HTTP_METHOD_DELETE, api_v1_macros_STR_DELETE); + router_register_endpoint("/api/v1/macros/{str}", HTTP_METHOD_GET, api_v1_macros_STR_GET); + router_register_endpoint("/api/v1/macros/{str}", HTTP_METHOD_PUT, api_v1_macros_STR_PUT); + router_register_endpoint("/api/v1/macros/{str}", HTTP_METHOD_DELETE, api_v1_macros_STR_DELETE); router_register_endpoint("/api/v1/ws/relays", HTTP_METHOD_WEBSOCKET, api_v1_ws_relays); }