From a5e4726b9050402edb4eba7175be66641e05f32c Mon Sep 17 00:00:00 2001 From: vvd170501 <36827317+vvd170501@users.noreply.github.com> Date: Wed, 28 Dec 2022 20:25:41 +0300 Subject: [PATCH] Move telegram mongo code; fix telegram plugin build without mongo --- plugins/telegram/Makefile.in | 4 - plugins/telegram/mongo_conn.c | 1826 ++++++++++++++++++++-- plugins/telegram/telegram.c | 9 +- plugins/telegram/telegram_chat.c | 288 ---- plugins/telegram/telegram_chat.h | 2 - plugins/telegram/telegram_chat_state.c | 288 ---- plugins/telegram/telegram_chat_state.h | 2 - plugins/telegram/telegram_pbs.c | 252 --- plugins/telegram/telegram_pbs.h | 2 - plugins/telegram/telegram_subscription.c | 301 ---- plugins/telegram/telegram_subscription.h | 2 - plugins/telegram/telegram_token.c | 463 ------ plugins/telegram/telegram_token.h | 2 - plugins/telegram/telegram_user.c | 269 ---- plugins/telegram/telegram_user.h | 2 - 15 files changed, 1737 insertions(+), 1975 deletions(-) diff --git a/plugins/telegram/Makefile.in b/plugins/telegram/Makefile.in index 7568851460..c7bb35df21 100644 --- a/plugins/telegram/Makefile.in +++ b/plugins/telegram/Makefile.in @@ -56,12 +56,8 @@ EXTRALIBS= CCOMPFLAGS=-D_GNU_SOURCE -std=gnu11 LDCOMPFLAGS= -ifneq ($(MONGO_EXISTS)$(MONGOC_EXISTS),) ifneq ($(MYSQL_LIBS),) include main.make else include empty.make endif -else -include empty.make -endif diff --git a/plugins/telegram/mongo_conn.c b/plugins/telegram/mongo_conn.c index 68cbd42b0d..074f45f873 100644 --- a/plugins/telegram/mongo_conn.c +++ b/plugins/telegram/mongo_conn.c @@ -16,6 +16,16 @@ #include "mongo_conn.h" +#if HAVE_LIBMONGOC - 0 > 0 || HAVE_LIBMONGO_CLIENT - 0 == 1 + +#include "telegram_pbs.h" +#include "telegram_token.h" +#include "telegram_chat.h" +#include "telegram_user.h" +#include "telegram_chat_state.h" +#include "telegram_subscription.h" + +#include "ejudge/bson_utils.h" #include "ejudge/xalloc.h" #include "ejudge/errlog.h" #include "ejudge/osdeps.h" @@ -28,9 +38,18 @@ #include #endif +#include #include #include +#if HAVE_LIBMONGOC - 0 > 0 +struct _bson_t; +typedef struct _bson_t ej_bson_t; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 +struct _bson; +typedef struct _bson ej_bson_t; +#endif + #define MONGO_RETRY_TIMEOUT 60 static struct generic_conn * @@ -171,7 +190,7 @@ mongo_conn_free(struct mongo_conn *conn) } return NULL; #else - return NULL; +#error mongo packages are missing #endif } @@ -261,7 +280,7 @@ mongo_conn_open(struct mongo_conn *state) } return 1; #else - return 0; +#error mongo packages are missing #endif } @@ -287,18 +306,231 @@ ns_func( return mongo_conn_ns((struct mongo_conn *) gc, collection_name); } -struct telegram_pbs; -struct telegram_pbs * -telegram_pbs_fetch(struct mongo_conn *conn, const unsigned char *bot_id); -int -telegram_pbs_save(struct mongo_conn *conn, const struct telegram_pbs *pbs); +#define TELEGRAM_BOTS_TABLE_NAME "telegram_bots" + +static struct telegram_pbs * +telegram_pbs_parse_bson(const ej_bson_t *bson) +{ +#if HAVE_LIBMONGOC - 0 > 0 + bson_iter_t iter, * const bc = &iter; + struct telegram_pbs *pbs = NULL; + + if (!bson_iter_init(&iter, bson)) goto cleanup; + + XCALLOC(pbs, 1); + while (bson_iter_next(&iter)) { + const unsigned char *key = bson_iter_key(bc); + if (!strcmp(key, "_id")) { + if (ej_bson_parse_string_new(bc, "_id", &pbs->_id) < 0) goto cleanup; + } else if (!strcmp(key, "update_id")) { + if (ej_bson_parse_int64_new(bc, "update_id", &pbs->update_id) < 0) goto cleanup; + } + } + + return pbs; + +cleanup: + telegram_pbs_free(pbs); + return NULL; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + bson_cursor *bc = NULL; + struct telegram_pbs *pbs = NULL; + + XCALLOC(pbs, 1); + bc = bson_cursor_new(bson); + while (bson_cursor_next(bc)) { + const unsigned char *key = bson_cursor_key(bc); + if (!strcmp(key, "_id")) { + if (ej_bson_parse_string(bc, "_id", &pbs->_id) < 0) goto cleanup; + } else if (!strcmp(key, "update_id")) { + if (ej_bson_parse_int64(bc, "update_id", &pbs->update_id) < 0) goto cleanup; + } + } + bson_cursor_free(bc); + return pbs; + +cleanup: + telegram_pbs_free(pbs); + return NULL; +#else +#error mongo packages are missing +#endif +} + +static ej_bson_t * +telegram_pbs_unparse_bson(const struct telegram_pbs *pbs) +{ +#if HAVE_LIBMONGOC - 0 > 0 + if (!pbs) return NULL; + + bson_t *bson = bson_new(); + if (pbs->_id && *pbs->_id) { + bson_append_utf8(bson, "_id", -1, pbs->_id, strlen(pbs->_id)); + } + if (pbs->update_id != 0) { + bson_append_int64(bson, "update_id", -1, pbs->update_id); + } + return bson; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + if (!pbs) return NULL; + + bson *bson = bson_new(); + if (pbs->_id && *pbs->_id) { + bson_append_string(bson, "_id", pbs->_id, strlen(pbs->_id)); + } + if (pbs->update_id != 0) { + bson_append_int64(bson, "update_id", pbs->update_id); + } + bson_finish(bson); + return bson; +#else +#error mongo packages are missing +#endif +} + +static int +telegram_pbs_save(struct mongo_conn *conn, const struct telegram_pbs *pbs) +{ +#if HAVE_LIBMONGOC - 0 > 0 + if (!conn->b.vt->open(&conn->b)) return -1; + + int retval = -1; + mongoc_collection_t *coll = NULL; + bson_t *query = NULL; + bson_t *bson = NULL; + bson_error_t error; + + if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_BOTS_TABLE_NAME))) { + err("get_collection failed\n"); + goto cleanup; + } + query = bson_new(); + bson_append_utf8(query, "_id", -1, pbs->_id, -1); + bson = telegram_pbs_unparse_bson(pbs); + + if (!mongoc_collection_update(coll, MONGOC_UPDATE_UPSERT, query, bson, NULL, &error)) { + err("telegram_chat_save: failed: %s", error.message); + goto cleanup; + } + + retval = 0; + +cleanup: + if (coll) mongoc_collection_destroy(coll); + if (query) bson_destroy(query); + if (bson) bson_destroy(bson); + return retval; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + if (!mongo_conn_open(conn)) return -1; + int retval = -1; + + bson *s = bson_new(); + bson_append_string(s, "_id", pbs->_id, strlen(pbs->_id)); + bson_finish(s); + + bson *b = telegram_pbs_unparse_bson(pbs); + if (!mongo_sync_cmd_update(conn->conn, mongo_conn_ns(conn, TELEGRAM_BOTS_TABLE_NAME), MONGO_WIRE_FLAG_UPDATE_UPSERT, s, b)) { + err("save_persistent_bot_state: failed: %s", os_ErrorMsg()); + goto done; + } + retval = 0; + +done: + bson_free(s); + bson_free(b); + return retval; +#else +#error mongo packages are missing +#endif +} static struct telegram_pbs * pbs_fetch_func( struct generic_conn *gc, const unsigned char *bot_id) { - return telegram_pbs_fetch((struct mongo_conn *) gc, bot_id); + struct mongo_conn *conn = (struct mongo_conn *) gc; +#if HAVE_LIBMONGOC - 0 > 0 + if (!conn->b.vt->open(&conn->b)) return NULL; + + bson_t *query = NULL; + mongoc_cursor_t *cursor = NULL; + const bson_t *doc = NULL; + struct telegram_pbs *retval = NULL; + mongoc_collection_t *coll = NULL; + + if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_BOTS_TABLE_NAME))) { + err("get_collection failed\n"); + goto cleanup; + } + query = bson_new(); + bson_append_utf8(query, "_id", -1, bot_id, -1); + cursor = mongoc_collection_find_with_opts(coll, query, NULL, NULL); + if (cursor && mongoc_cursor_next(cursor, &doc)) { + retval = telegram_pbs_parse_bson(doc); + goto cleanup; + } + + if (cursor) mongoc_cursor_destroy(cursor); + cursor = NULL; + bson_destroy(query); query = NULL; + mongoc_collection_destroy(coll); coll = NULL; + retval = telegram_pbs_create(bot_id); + telegram_pbs_save(conn, retval); + +cleanup: + if (cursor) mongoc_cursor_destroy(cursor); + if (coll) mongoc_collection_destroy(coll); + if (query) bson_destroy(query); + return retval; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + if (!mongo_conn_open(conn)) return NULL; + + mongo_packet *pkt = NULL; + bson *query = NULL; + mongo_sync_cursor *cursor = NULL; + bson *result = NULL; + struct telegram_pbs *pbs = NULL; + + query = bson_new(); + bson_append_string(query, "_id", bot_id, strlen(bot_id)); + bson_finish(query); + pkt = mongo_sync_cmd_query(conn->conn, mongo_conn_ns(conn, TELEGRAM_BOTS_TABLE_NAME), 0, 0, 1, query, NULL); + if (!pkt && errno == ENOENT) { + bson_free(query); query = NULL; + pbs = telegram_pbs_create(bot_id); + telegram_pbs_save(conn, pbs); + goto cleanup; + } + if (!pkt) { + err("mongo query failed: %s", os_ErrorMsg()); + goto cleanup; + } + bson_free(query); query = NULL; + cursor = mongo_sync_cursor_new(conn->conn, conn->ns, pkt); + if (!cursor) { + err("mongo query failed: cannot create cursor: %s", os_ErrorMsg()); + goto cleanup; + } + pkt = NULL; + if (mongo_sync_cursor_next(cursor)) { + result = mongo_sync_cursor_get_data(cursor); + pbs = telegram_pbs_parse_bson(result); + } else { + mongo_sync_cursor_free(cursor); cursor = NULL; + pbs = telegram_pbs_create(bot_id); + telegram_pbs_save(conn, pbs); + } + +cleanup: + if (result) bson_free(result); + if (cursor) mongo_sync_cursor_free(cursor); + if (pkt) mongo_wire_packet_free(pkt); + if (query) bson_free(query); + return pbs; +#else +#error mongo packages are missing +#endif } static int @@ -309,8 +541,182 @@ pbs_save_func( return telegram_pbs_save((struct mongo_conn *) gc, pbs); } -int -telegram_token_fetch(struct mongo_conn *conn, const unsigned char *token_str, struct telegram_token **p_token); +#undef TELEGRAM_BOTS_TABLE_NAME + +#define TELEGRAM_TOKENS_TABLE_NAME "telegram_tokens" + +static struct telegram_token * +telegram_token_parse_bson(const ej_bson_t *bson) +{ +#if HAVE_LIBMONGOC - 0 > 0 + bson_iter_t iter, * const bc = &iter; + struct telegram_token *token = NULL; + + if (!bson_iter_init(&iter, bson)) goto cleanup; + + XCALLOC(token, 1); + while (bson_iter_next(&iter)) { + const unsigned char *key = bson_iter_key(bc); + if (!strcmp(key, "_id")) { + if (ej_bson_parse_oid_new(bc, "_id", token->_id) < 0) goto cleanup; + } else if (!strcmp(key, "bot_id")) { + if (ej_bson_parse_string_new(bc, "bot_id", &token->bot_id) < 0) goto cleanup; + } else if (!strcmp(key, "user_id")) { + if (ej_bson_parse_int_new(bc, "user_id", &token->user_id, 1, 1, 0, 0) < 0) goto cleanup; + } else if (!strcmp(key, "user_login")) { + if (ej_bson_parse_string_new(bc, "user_login", &token->user_login) < 0) goto cleanup; + } else if (!strcmp(key, "user_name")) { + if (ej_bson_parse_string_new(bc, "user_name", &token->user_name) < 0) goto cleanup; + } else if (!strcmp(key, "token")) { + if (ej_bson_parse_string_new(bc, "token", &token->token) < 0) goto cleanup; + } else if (!strcmp(key, "contest_id")) { + if (ej_bson_parse_int_new(bc, "contest_id", &token->contest_id, 1, 0, 0, 0) < 0) goto cleanup; + } else if (!strcmp(key, "contest_name")) { + if (ej_bson_parse_string_new(bc, "contest_name", &token->contest_name) < 0) goto cleanup; + } else if (!strcmp(key, "locale_id")) { + if (ej_bson_parse_int_new(bc, "locale_id", &token->locale_id, 1, 0, 0, 0) < 0) goto cleanup; + } else if (!strcmp(key, "expiry_time")) { + if (ej_bson_parse_utc_datetime_new(bc, "expiry_time", &token->expiry_time) < 0) goto cleanup; + } + } + return token; +cleanup: + telegram_token_free(token); + return NULL; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + struct telegram_token *token = NULL; + bson_cursor *bc = NULL; + + XCALLOC(token, 1); + bc = bson_cursor_new(bson); + while (bson_cursor_next(bc)) { + const unsigned char *key = bson_cursor_key(bc); + if (!strcmp(key, "_id")) { + if (ej_bson_parse_oid(bc, "_id", token->_id) < 0) goto cleanup; + } else if (!strcmp(key, "bot_id")) { + if (ej_bson_parse_string(bc, "bot_id", &token->bot_id) < 0) goto cleanup; + } else if (!strcmp(key, "user_id")) { + if (ej_bson_parse_int(bc, "user_id", &token->user_id, 1, 1, 0, 0) < 0) goto cleanup; + } else if (!strcmp(key, "user_login")) { + if (ej_bson_parse_string(bc, "user_login", &token->user_login) < 0) goto cleanup; + } else if (!strcmp(key, "user_name")) { + if (ej_bson_parse_string(bc, "user_name", &token->user_name) < 0) goto cleanup; + } else if (!strcmp(key, "token")) { + if (ej_bson_parse_string(bc, "token", &token->token) < 0) goto cleanup; + } else if (!strcmp(key, "contest_id")) { + if (ej_bson_parse_int(bc, "contest_id", &token->contest_id, 1, 0, 0, 0) < 0) goto cleanup; + } else if (!strcmp(key, "contest_name")) { + if (ej_bson_parse_string(bc, "contest_name", &token->contest_name) < 0) goto cleanup; + } else if (!strcmp(key, "locale_id")) { + if (ej_bson_parse_int(bc, "locale_id", &token->locale_id, 1, 0, 0, 0) < 0) goto cleanup; + } else if (!strcmp(key, "expiry_time")) { + if (ej_bson_parse_utc_datetime(bc, "expiry_time", &token->expiry_time) < 0) goto cleanup; + } + } + bson_cursor_free(bc); + return token; + +cleanup: + telegram_token_free(token); + return NULL; +#else +#error mongo packages are missing +#endif +} + +static ej_bson_t * +telegram_token_unparse_bson(const struct telegram_token *token) +{ +#if HAVE_LIBMONGOC - 0 > 0 + if (!token) return NULL; + + bson_t *bson = bson_new(); + int empty_id = 1; + for (int i = 0; i < 12; ++i) { + if (token->_id[i]) { + empty_id = 0; + break; + } + } + + if (!empty_id) { + bson_append_oid(bson, "_id", -1, (bson_oid_t *) &token->_id); + } + if (token->bot_id && *token->bot_id) { + bson_append_utf8(bson, "bot_id", -1, token->bot_id, strlen(token->bot_id)); + } + if (token->user_id > 0) { + bson_append_int32(bson, "user_id", -1, token->user_id); + } + if (token->user_login && *token->user_login) { + bson_append_utf8(bson, "user_login", -1, token->user_login, strlen(token->user_login)); + } + if (token->user_name && *token->user_name) { + bson_append_utf8(bson, "user_name", -1, token->user_name, strlen(token->user_name)); + } + if (token->token && *token->token) { + bson_append_utf8(bson, "token", -1, token->token, strlen(token->token)); + } + if (token->contest_id > 0) { + bson_append_int32(bson, "contest_id", -1, token->contest_id); + } + if (token->contest_name && *token->contest_name) { + bson_append_utf8(bson, "contest_name", -1, token->contest_name, strlen(token->contest_name)); + } + if (token->locale_id > 0) { + bson_append_int32(bson, "locale_id", -1, token->locale_id); + } + if (token->expiry_time > 0) { + bson_append_date_time(bson, "expiry_time", -1, 1000LL * token->expiry_time); + } + return bson; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + if (!token) return NULL; + + bson *b = bson_new(); + int empty_id = 1; + for (int i = 0; i < 12; ++i) { + if (token->_id[i]) { + empty_id = 0; + break; + } + } + if (!empty_id) { + bson_append_oid(b, "_id", token->_id); + } + if (token->bot_id && *token->bot_id) { + bson_append_string(b, "bot_id", token->bot_id, strlen(token->bot_id)); + } + if (token->user_id > 0) { + bson_append_int32(b, "user_id", token->user_id); + } + if (token->user_login && *token->user_login) { + bson_append_string(b, "user_login", token->user_login, strlen(token->user_login)); + } + if (token->user_name && *token->user_name) { + bson_append_string(b, "user_name", token->user_name, strlen(token->user_name)); + } + if (token->token && *token->token) { + bson_append_string(b, "token", token->token, strlen(token->token)); + } + if (token->contest_id > 0) { + bson_append_int32(b, "contest_id", token->contest_id); + } + if (token->contest_name && *token->contest_name) { + bson_append_string(b, "contest_name", token->contest_name, strlen(token->contest_name)); + } + if (token->locale_id > 0) { + bson_append_int32(b, "locale_id", token->locale_id); + } + if (token->expiry_time > 0) { + bson_append_utc_datetime(b, "expiry_time", 1000LL * token->expiry_time); + } + bson_finish(b); + return b; +#else +#error mongo packages are missing +#endif +} static int token_fetch_func( @@ -318,128 +724,1356 @@ token_fetch_func( const unsigned char *token_str, struct telegram_token **p_token) { - return telegram_token_fetch((struct mongo_conn*) gc, token_str, p_token); -} + struct mongo_conn *conn = (struct mongo_conn *) gc; +#if HAVE_LIBMONGOC - 0 > 0 + if (!conn->b.vt->open(&conn->b)) return -1; + + int retval = -1; + mongoc_collection_t *coll = NULL; + bson_t *query = NULL; + mongoc_cursor_t *cursor = NULL; + const bson_t *doc = NULL; + + if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_TOKENS_TABLE_NAME))) { + err("get_collection failed\n"); + goto cleanup; + } + + query = bson_new(); + bson_append_utf8(query, "token", -1, token_str, strlen(token_str)); + + cursor = mongoc_collection_find_with_opts(coll, query, NULL, NULL); + if (!cursor) goto cleanup; + + if (mongoc_cursor_next(cursor, &doc)) { + *p_token = telegram_token_parse_bson(doc); + retval = 1; + } else { + retval = 0; + } + +cleanup: + if (cursor) mongoc_cursor_destroy(cursor); + if (query) bson_destroy(query); + if (coll) mongoc_collection_destroy(coll); + return retval; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + int retval = -1; + + if (!mongo_conn_open(conn)) return -1; + + bson *query = NULL; + mongo_packet *pkt = NULL; + mongo_sync_cursor *cursor = NULL; + bson *result = NULL; + + query = bson_new(); + bson_append_string(query, "token", token_str, strlen(token_str)); + bson_finish(query); -int -telegram_token_save(struct mongo_conn *conn, const struct telegram_token *token); + pkt = mongo_sync_cmd_query(conn->conn, mongo_conn_ns(conn, TELEGRAM_TOKENS_TABLE_NAME), 0, 0, 1, query, NULL); + if (!pkt && errno == ENOENT) { + retval = 0; + goto cleanup; + } + if (!pkt) { + err("mongo query failed: %s", os_ErrorMsg()); + goto cleanup; + } + bson_free(query); query = NULL; + + cursor = mongo_sync_cursor_new(conn->conn, conn->ns, pkt); + if (!cursor) { + err("mongo query failed: cannot create cursor: %s", os_ErrorMsg()); + goto cleanup; + } + pkt = NULL; + if (mongo_sync_cursor_next(cursor)) { + result = mongo_sync_cursor_get_data(cursor); + if (result) { + struct telegram_token *t = telegram_token_parse_bson(result); + if (t) { + *p_token = t; + retval = 1; + } + } else { + retval = 0; + } + } else { + retval = 0; + } + +cleanup: + if (result) bson_free(result); + if (cursor) mongo_sync_cursor_free(cursor); + if (pkt) mongo_wire_packet_free(pkt); + if (query) bson_free(query); + return retval; +#else +#error mongo packages are missing +#endif +} static int token_save_func( struct generic_conn *gc, const struct telegram_token *token) { - return telegram_token_save((struct mongo_conn *) gc, token); -} + struct mongo_conn *conn = (struct mongo_conn *) gc; +#if HAVE_LIBMONGOC - 0 > 0 + if (!conn->b.vt->open(&conn->b)) return -1; + + int retval = -1; + mongoc_database_t *db = NULL; + mongoc_collection_t *coll = NULL; + bson_t *bson = NULL; + bson_error_t error; + bson_t *ind = NULL; + char *ind_name = NULL; + bson_t *create_bson = NULL; + + if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_TOKENS_TABLE_NAME))) { + err("get_collection failed\n"); + goto cleanup; + } -void -telegram_token_remove(struct mongo_conn *conn, const unsigned char *token); + bson = telegram_token_unparse_bson(token); + + if (!mongoc_collection_insert_one(coll, bson, NULL, NULL, &error)) { + err("telegram_token_save: failed: %s", error.message); + goto cleanup; + } + retval = 0; + + if (!conn->token_index_created) { + conn->token_index_created = 1; + + ind = bson_new(); + bson_append_int32(ind, "token", -1, 1); + ind_name = mongoc_collection_keys_to_index_string(ind); + create_bson = BCON_NEW("createIndexes", BCON_UTF8(TELEGRAM_TOKENS_TABLE_NAME), + "indexes", "[", "{", "key", BCON_DOCUMENT(ind), + "name", BCON_UTF8(ind_name), "}", "]"); + + if ((db = mongoc_client_get_database(conn->client, conn->b.database))) { + mongoc_database_write_command_with_opts(db, create_bson, NULL, NULL, NULL); + } + } + +cleanup: + if (create_bson) bson_destroy(create_bson); + if (ind_name) bson_free(ind_name); + if (ind) bson_destroy(ind); + if (bson) bson_destroy(bson); + if (coll) mongoc_collection_destroy(coll); + if (db) mongoc_database_destroy(db); + return retval; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + if (!mongo_conn_open(conn)) return -1; + int retval = -1; + + bson *b = telegram_token_unparse_bson(token); + bson *ind = NULL; + + if (!mongo_sync_cmd_insert(conn->conn, mongo_conn_ns(conn, TELEGRAM_TOKENS_TABLE_NAME), b, NULL)) { + err("save_token: failed: %s", os_ErrorMsg()); + goto cleanup; + } + + ind = bson_new(); + bson_append_int32(ind, "token", 1); + bson_finish(ind); + mongo_sync_cmd_index_create(conn->conn, conn->ns, ind, 0); + + retval = 0; +cleanup: + if (ind) bson_free(ind); + bson_free(b); + return retval; +#else +#error mongo packages are missing +#endif +} static void token_remove_func( struct generic_conn *gc, const unsigned char *token) { - telegram_token_remove((struct mongo_conn *) gc, token); -} + struct mongo_conn *conn = (struct mongo_conn *) gc; +#if HAVE_LIBMONGOC - 0 > 0 + if (!conn->b.vt->open(&conn->b)) return; + + mongoc_collection_t *coll = NULL; + bson_t *query = NULL; + bson_error_t error; + + if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_TOKENS_TABLE_NAME))) { + err("get_collection failed\n"); + goto cleanup; + } + + query = bson_new(); + bson_append_utf8(query, "token", -1, token, strlen(token)); + + if (!mongoc_collection_delete_one(coll, query, NULL, NULL, &error)) { + err("telegram_token_remove_expired: failed: %s", error.message); + goto cleanup; + } + +cleanup: + if (query) bson_destroy(query); + if (coll) mongoc_collection_destroy(coll); +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + if (!mongo_conn_open(conn)) return; + + bson *q = bson_new(); + bson_append_string(q, "token", token, strlen(token)); + bson_finish(q); -void -telegram_token_remove_expired(struct mongo_conn *conn, time_t current_time); + mongo_sync_cmd_delete(conn->conn, mongo_conn_ns(conn, TELEGRAM_TOKENS_TABLE_NAME), 0, q); + + bson_free(q); +#else +#error mongo packages are missing +#endif +} static void token_remove_expired_func( struct generic_conn *gc, time_t current_time) { - telegram_token_remove_expired((struct mongo_conn *) gc, current_time); -} + struct mongo_conn *conn = (struct mongo_conn *) gc; +#if HAVE_LIBMONGOC - 0 > 0 + if (current_time <= 0) current_time = time(NULL); -struct telegram_chat * -telegram_chat_fetch(struct mongo_conn *conn, long long _id); + if (!conn->b.vt->open(&conn->b)) return; -static struct telegram_chat * -chat_fetch_func( - struct generic_conn *gc, - long long _id) -{ - return telegram_chat_fetch((struct mongo_conn *) gc, _id); -} + mongoc_collection_t *coll = NULL; + bson_t *qq = NULL; + bson_t *q = NULL; + bson_error_t error; -int -telegram_chat_save(struct mongo_conn *conn, const struct telegram_chat *tc); + if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_TOKENS_TABLE_NAME))) { + err("get_collection failed\n"); + goto cleanup; + } -static int -chat_save_func( - struct generic_conn *gc, - const struct telegram_chat *tc) -{ - return telegram_chat_save((struct mongo_conn *) gc, tc); -} + qq = bson_new(); + bson_append_date_time(qq, "$lt", -1, 1000LL * current_time); + q = bson_new(); + bson_append_document(q, "expiry_time", -1, qq); + bson_destroy(qq); qq = NULL; -struct telegram_user * -telegram_user_fetch(struct mongo_conn *conn, long long _id); + if (!mongoc_collection_delete_many(coll, q, NULL, NULL, &error)) { + err("telegram_token_remove_expired: failed: %s", error.message); + goto cleanup; + } -static struct telegram_user * -user_fetch_func( - struct generic_conn *gc, - long long _id) -{ - return telegram_user_fetch((struct mongo_conn *) gc, _id); -} +cleanup: + if (q) bson_destroy(q); + if (qq) bson_destroy(qq); + if (coll) mongoc_collection_destroy(coll); + return; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + if (current_time <= 0) current_time = time(NULL); -int -telegram_user_save(struct mongo_conn *conn, const struct telegram_user *tu); + if (!mongo_conn_open(conn)) return; -static int -user_save_func( - struct generic_conn *gc, - const struct telegram_user *tu) -{ - return telegram_user_save((struct mongo_conn *) gc, tu); -} + bson *qq = bson_new(); + bson_append_utc_datetime(qq, "$lt", 1000LL * current_time); + bson_finish(qq); + bson *q = bson_new(); + bson_append_document(q, "expiry_time", qq); qq = NULL; + bson_finish(q); -struct telegram_chat_state * -telegram_chat_state_fetch(struct mongo_conn *conn, long long _id); + mongo_sync_cmd_delete(conn->conn, mongo_conn_ns(conn, TELEGRAM_TOKENS_TABLE_NAME), 0, q); -static struct telegram_chat_state * -chat_state_fetch_func( - struct generic_conn *gc, - long long _id) -{ - return telegram_chat_state_fetch((struct mongo_conn *) gc, _id); + bson_free(q); +#else +#error mongo packages are missing +#endif } -int -telegram_chat_state_save(struct mongo_conn *conn, const struct telegram_chat_state *tcs); +#undef TELEGRAM_TOKENS_TABLE_NAME -static int -chat_state_save_func( - struct generic_conn *gc, - const struct telegram_chat_state *tcs) +#define TELEGRAM_CHATS_TABLE_NAME "telegram_chats" + +static struct telegram_chat * +telegram_chat_parse_bson(const ej_bson_t *bson) { - return telegram_chat_state_save((struct mongo_conn *) gc, tcs); -} +#if HAVE_LIBMONGOC - 0 > 0 + bson_iter_t iter, * const bc = &iter; + struct telegram_chat *tc = NULL; -struct telegram_subscription * -telegram_subscription_fetch(struct mongo_conn *conn, const unsigned char *bot_id, int user_id, int contest_id); + if (!bson_iter_init(&iter, bson)) goto cleanup; -static struct telegram_subscription * -subscription_fetch_func( - struct generic_conn *gc, - const unsigned char *bot_id, - int user_id, - int contest_id) -{ - return telegram_subscription_fetch((struct mongo_conn *) gc, bot_id, user_id, contest_id); -} + XCALLOC(tc, 1); + while (bson_iter_next(&iter)) { + const unsigned char *key = bson_iter_key(bc); + if (!strcmp(key, "_id")) { + if (ej_bson_parse_int64_new(bc, "_id", &tc->_id) < 0) goto cleanup; + } else if (!strcmp(key, "type")) { + if (ej_bson_parse_string_new(bc, "type", &tc->type) < 0) goto cleanup; + } else if (!strcmp(key, "title")) { + if (ej_bson_parse_string_new(bc, "title", &tc->title) < 0) goto cleanup; + } else if (!strcmp(key, "username")) { + if (ej_bson_parse_string_new(bc, "username", &tc->username) < 0) goto cleanup; + } else if (!strcmp(key, "first_name")) { + if (ej_bson_parse_string_new(bc, "first_name", &tc->first_name) < 0) goto cleanup; + } else if (!strcmp(key, "last_name")) { + if (ej_bson_parse_string_new(bc, "last_name", &tc->last_name) < 0) goto cleanup; + } + } -int -telegram_subscription_save(struct mongo_conn *conn, const struct telegram_subscription *subscription); + return tc; -static int -subscription_save_func( - struct generic_conn *gc, - const struct telegram_subscription *subscription) -{ - return telegram_subscription_save((struct mongo_conn*) gc, subscription); -} +cleanup: + telegram_chat_free(tc); + return NULL; + +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + bson_cursor *bc = NULL; + struct telegram_chat *tc = NULL; + + XCALLOC(tc, 1); + bc = bson_cursor_new(bson); + while (bson_cursor_next(bc)) { + const unsigned char *key = bson_cursor_key(bc); + if (!strcmp(key, "_id")) { + if (ej_bson_parse_int64(bc, "_id", &tc->_id) < 0) goto cleanup; + } else if (!strcmp(key, "type")) { + if (ej_bson_parse_string(bc, "type", &tc->type) < 0) goto cleanup; + } else if (!strcmp(key, "title")) { + if (ej_bson_parse_string(bc, "title", &tc->title) < 0) goto cleanup; + } else if (!strcmp(key, "username")) { + if (ej_bson_parse_string(bc, "username", &tc->username) < 0) goto cleanup; + } else if (!strcmp(key, "first_name")) { + if (ej_bson_parse_string(bc, "first_name", &tc->first_name) < 0) goto cleanup; + } else if (!strcmp(key, "last_name")) { + if (ej_bson_parse_string(bc, "last_name", &tc->last_name) < 0) goto cleanup; + } + } + bson_cursor_free(bc); + return tc; + +cleanup: + telegram_chat_free(tc); + return NULL; +#else +#error mongo packages are missing +#endif +} + +static ej_bson_t * +telegram_chat_unparse_bson(const struct telegram_chat *tc) +{ +#if HAVE_LIBMONGOC - 0 > 0 + if (!tc) return NULL; + + bson_t *bson = bson_new(); + + if (tc->_id) { + bson_append_int64(bson, "_id", -1, tc->_id); + } + if (tc->type && *tc->type) { + bson_append_utf8(bson, "type", -1, tc->type, strlen(tc->type)); + } + if (tc->title && *tc->title) { + bson_append_utf8(bson, "title", -1, tc->title, strlen(tc->title)); + } + if (tc->username && *tc->username) { + bson_append_utf8(bson, "username", -1, tc->username, strlen(tc->username)); + } + if (tc->first_name && *tc->first_name) { + bson_append_utf8(bson, "first_name", -1, tc->first_name, strlen(tc->first_name)); + } + if (tc->last_name && *tc->last_name) { + bson_append_utf8(bson, "last_name", -1, tc->last_name, strlen(tc->last_name)); + } + + return bson; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + if (!tc) return NULL; + + bson *bson = bson_new(); + if (tc->_id) { + bson_append_int64(bson, "_id", tc->_id); + } + if (tc->type && *tc->type) { + bson_append_string(bson, "type", tc->type, strlen(tc->type)); + } + if (tc->title && *tc->title) { + bson_append_string(bson, "title", tc->title, strlen(tc->title)); + } + if (tc->username && *tc->username) { + bson_append_string(bson, "username", tc->username, strlen(tc->username)); + } + if (tc->first_name && *tc->first_name) { + bson_append_string(bson, "first_name", tc->first_name, strlen(tc->first_name)); + } + if (tc->last_name && *tc->last_name) { + bson_append_string(bson, "last_name", tc->last_name, strlen(tc->last_name)); + } + bson_finish(bson); + return bson; +#else +#error mongo packages are missing +#endif +} + +static struct telegram_chat * +chat_fetch_func( + struct generic_conn *gc, + long long _id) +{ + struct mongo_conn *conn = (struct mongo_conn *) gc; +#if HAVE_LIBMONGOC - 0 > 0 + if (!conn->b.vt->open(&conn->b)) return NULL; + + mongoc_collection_t *coll = NULL; + bson_t *query = NULL; + mongoc_cursor_t *cursor = NULL; + const bson_t *doc = NULL; + struct telegram_chat *retval = NULL; + + if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_CHATS_TABLE_NAME))) { + err("get_collection failed\n"); + goto cleanup; + } + query = bson_new(); + bson_append_int64(query, "_id", -1, _id); + cursor = mongoc_collection_find_with_opts(coll, query, NULL, NULL); + if (!cursor) goto cleanup; + + if (mongoc_cursor_next(cursor, &doc)) { + retval = telegram_chat_parse_bson(doc); + } + +cleanup: + if (cursor) mongoc_cursor_destroy(cursor); + if (coll) mongoc_collection_destroy(coll); + if (query) bson_destroy(query); + return retval; + +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + if (!mongo_conn_open(conn)) return NULL; + + bson *query = NULL; + mongo_packet *pkt = NULL; + mongo_sync_cursor *cursor = NULL; + bson *result = NULL; + struct telegram_chat *retval = NULL; + + query = bson_new(); + bson_append_int64(query, "_id", _id); + bson_finish(query); + + pkt = mongo_sync_cmd_query(conn->conn, mongo_conn_ns(conn, TELEGRAM_CHATS_TABLE_NAME), 0, 0, 1, query, NULL); + if (!pkt && errno == ENOENT) { + goto cleanup; + } + if (!pkt) { + err("mongo query failed: %s", os_ErrorMsg()); + goto cleanup; + } + bson_free(query); query = NULL; + + cursor = mongo_sync_cursor_new(conn->conn, conn->ns, pkt); + if (!cursor) { + err("mongo query failed: cannot create cursor: %s", os_ErrorMsg()); + goto cleanup; + } + pkt = NULL; + if (mongo_sync_cursor_next(cursor)) { + result = mongo_sync_cursor_get_data(cursor); + if (result) { + retval = telegram_chat_parse_bson(result); + } + } + +cleanup: + if (result) bson_free(result); + if (cursor) mongo_sync_cursor_free(cursor); + if (pkt) mongo_wire_packet_free(pkt); + if (query) bson_free(query); + return retval; +#else +#error mongo packages are missing +#endif +} + +static int +chat_save_func( + struct generic_conn *gc, + const struct telegram_chat *tc) +{ + struct mongo_conn *conn = (struct mongo_conn *) gc; +#if HAVE_LIBMONGOC - 0 > 0 + if (!conn->b.vt->open(&conn->b)) return -1; + + int retval = -1; + mongoc_collection_t *coll = NULL; + bson_t *query = NULL; + bson_t *bson = NULL; + bson_error_t error; + + if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_CHATS_TABLE_NAME))) { + err("get_collection failed\n"); + goto cleanup; + } + query = bson_new(); + bson_append_int64(query, "_id", -1, tc->_id); + bson = telegram_chat_unparse_bson(tc); + + if (!mongoc_collection_update(coll, MONGOC_UPDATE_UPSERT, query, bson, NULL, &error)) { + err("telegram_chat_save: failed: %s", error.message); + goto cleanup; + } + + retval = 0; + +cleanup: + if (coll) mongoc_collection_destroy(coll); + if (query) bson_destroy(query); + if (bson) bson_destroy(bson); + return retval; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + if (!mongo_conn_open(conn)) return -1; + int retval = -1; + + bson *b = telegram_chat_unparse_bson(tc); + bson *q = bson_new(); + bson_append_int64(q, "_id", tc->_id); + bson_finish(q); + + if (!mongo_sync_cmd_update(conn->conn, mongo_conn_ns(conn, TELEGRAM_CHATS_TABLE_NAME), MONGO_WIRE_FLAG_UPDATE_UPSERT, q, b)) { + err("save_token: failed: %s", os_ErrorMsg()); + goto cleanup; + } + + retval = 0; + +cleanup: + bson_free(q); + bson_free(b); + return retval; +#else +#error mongo packages are missing +#endif +} + +#undef TELEGRAM_CHATS_TABLE_NAME + +#define TELEGRAM_USERS_TABLE_NAME "telegram_users" + +static struct telegram_user * +telegram_user_parse_bson(const ej_bson_t *bson) +{ +#if HAVE_LIBMONGOC - 0 > 0 + bson_iter_t iter, * const bc = &iter; + struct telegram_user *tu = NULL; + + if (!bson_iter_init(&iter, bson)) goto cleanup; + + XCALLOC(tu, 1); + while (bson_iter_next(&iter)) { + const unsigned char *key = bson_iter_key(bc); + if (!strcmp(key, "_id")) { + if (ej_bson_parse_int64_new(bc, "_id", &tu->_id) < 0) goto cleanup; + } else if (!strcmp(key, "username")) { + if (ej_bson_parse_string_new(bc, "username", &tu->username) < 0) goto cleanup; + } else if (!strcmp(key, "first_name")) { + if (ej_bson_parse_string_new(bc, "first_name", &tu->first_name) < 0) goto cleanup; + } else if (!strcmp(key, "last_name")) { + if (ej_bson_parse_string_new(bc, "last_name", &tu->last_name) < 0) goto cleanup; + } + } + + return tu; + +cleanup: + telegram_user_free(tu); + return NULL; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + bson_cursor *bc = NULL; + struct telegram_user *tu = NULL; + + XCALLOC(tu, 1); + bc = bson_cursor_new(bson); + while (bson_cursor_next(bc)) { + const unsigned char *key = bson_cursor_key(bc); + if (!strcmp(key, "_id")) { + if (ej_bson_parse_int64(bc, "_id", &tu->_id) < 0) goto cleanup; + } else if (!strcmp(key, "username")) { + if (ej_bson_parse_string(bc, "username", &tu->username) < 0) goto cleanup; + } else if (!strcmp(key, "first_name")) { + if (ej_bson_parse_string(bc, "first_name", &tu->first_name) < 0) goto cleanup; + } else if (!strcmp(key, "last_name")) { + if (ej_bson_parse_string(bc, "last_name", &tu->last_name) < 0) goto cleanup; + } + } + bson_cursor_free(bc); + return tu; + +cleanup: + telegram_user_free(tu); + return NULL; +#else + return NULL; +#endif +} + +static ej_bson_t * +telegram_user_unparse_bson(const struct telegram_user *tu) +{ +#if HAVE_LIBMONGOC - 0 > 0 + if (!tu) return NULL; + + bson_t *bson = bson_new(); + + if (tu->_id) { + bson_append_int64(bson, "_id", -1, tu->_id); + } + if (tu->username && *tu->username) { + bson_append_utf8(bson, "username", -1, tu->username, strlen(tu->username)); + } + if (tu->first_name && *tu->first_name) { + bson_append_utf8(bson, "first_name", -1, tu->first_name, strlen(tu->first_name)); + } + if (tu->last_name && *tu->last_name) { + bson_append_utf8(bson, "last_name", -1, tu->last_name, strlen(tu->last_name)); + } + + return bson; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + if (!tu) return NULL; + + bson *bson = bson_new(); + if (tu->_id) { + bson_append_int64(bson, "_id", tu->_id); + } + if (tu->username && *tu->username) { + bson_append_string(bson, "username", tu->username, strlen(tu->username)); + } + if (tu->first_name && *tu->first_name) { + bson_append_string(bson, "first_name", tu->first_name, strlen(tu->first_name)); + } + if (tu->last_name && *tu->last_name) { + bson_append_string(bson, "last_name", tu->last_name, strlen(tu->last_name)); + } + bson_finish(bson); + return bson; +#else + return NULL; +#endif +} + +static struct telegram_user * +user_fetch_func( + struct generic_conn *gc, + long long _id) +{ + struct mongo_conn *conn = (struct mongo_conn *) gc; +#if HAVE_LIBMONGOC - 0 > 0 + if (!conn->b.vt->open(&conn->b)) return NULL; + + struct telegram_user *retval = NULL; + mongoc_collection_t *coll = NULL; + bson_t *query = NULL; + mongoc_cursor_t *cursor = NULL; + const bson_t *doc = NULL; + + if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_USERS_TABLE_NAME))) { + err("get_collection failed\n"); + goto cleanup; + } + + query = bson_new(); + bson_append_int64(query, "_id", -1, _id); + + cursor = mongoc_collection_find_with_opts(coll, query, NULL, NULL); + if (!cursor) goto cleanup; + + if (mongoc_cursor_next(cursor, &doc)) { + retval = telegram_user_parse_bson(doc); + } + +cleanup: + if (cursor) mongoc_cursor_destroy(cursor); + if (query) bson_destroy(query); + if (coll) mongoc_collection_destroy(coll); + return retval; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + if (!mongo_conn_open(conn)) return NULL; + + bson *query = NULL; + mongo_packet *pkt = NULL; + mongo_sync_cursor *cursor = NULL; + bson *result = NULL; + struct telegram_user *retval = NULL; + + query = bson_new(); + bson_append_int64(query, "_id", _id); + bson_finish(query); + + pkt = mongo_sync_cmd_query(conn->conn, mongo_conn_ns(conn, TELEGRAM_USERS_TABLE_NAME), 0, 0, 1, query, NULL); + if (!pkt && errno == ENOENT) { + goto cleanup; + } + if (!pkt) { + err("mongo query failed: %s", os_ErrorMsg()); + goto cleanup; + } + bson_free(query); query = NULL; + + cursor = mongo_sync_cursor_new(conn->conn, conn->ns, pkt); + if (!cursor) { + err("mongo query failed: cannot create cursor: %s", os_ErrorMsg()); + goto cleanup; + } + pkt = NULL; + if (mongo_sync_cursor_next(cursor)) { + result = mongo_sync_cursor_get_data(cursor); + if (result) { + retval = telegram_user_parse_bson(result); + } + } + +cleanup: + if (result) bson_free(result); + if (cursor) mongo_sync_cursor_free(cursor); + if (pkt) mongo_wire_packet_free(pkt); + if (query) bson_free(query); + return retval; +#else +#error mongo packages are missing +#endif +} + +static int +user_save_func( + struct generic_conn *gc, + const struct telegram_user *tu) +{ + struct mongo_conn *conn = (struct mongo_conn *) gc; +#if HAVE_LIBMONGOC - 0 > 0 + if (!conn->b.vt->open(&conn->b)) return -1; + + int retval = -1; + mongoc_collection_t *coll = NULL; + bson_t *query = NULL; + bson_t *bson = NULL; + bson_error_t error; + + if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_USERS_TABLE_NAME))) { + err("get_collection failed\n"); + goto cleanup; + } + + bson = telegram_user_unparse_bson(tu); + query = bson_new(); + bson_append_int64(query, "_id", -1, tu->_id); + + if (!mongoc_collection_update(coll, MONGOC_UPDATE_UPSERT, query, bson, NULL, &error)) { + err("telegram_chat_save: failed: %s", error.message); + goto cleanup; + } + + retval = 0; + +cleanup: + if (query) bson_destroy(query); + if (bson) bson_destroy(bson); + if (coll) mongoc_collection_destroy(coll); + return retval; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + if (!mongo_conn_open(conn)) return -1; + int retval = -1; + + bson *b = telegram_user_unparse_bson(tu); + bson *q = bson_new(); + bson_append_int64(q, "_id", tu->_id); + bson_finish(q); + + if (!mongo_sync_cmd_update(conn->conn, mongo_conn_ns(conn, TELEGRAM_USERS_TABLE_NAME), MONGO_WIRE_FLAG_UPDATE_UPSERT, q, b)) { + err("save_token: failed: %s", os_ErrorMsg()); + goto cleanup; + } + + retval = 0; + +cleanup: + bson_free(b); + bson_free(q); + return retval; +#else +#error mongo packages are missing +#endif +} + +#undef TELEGRAM_USERS_TABLE_NAME + +#define TELEGRAM_CHAT_STATES_TABLE_NAME "telegram_chat_states" + +static struct telegram_chat_state * +telegram_chat_state_parse_bson(const ej_bson_t *bson) +{ +#if HAVE_LIBMONGOC - 0 > 0 + bson_iter_t iter, * const bc = &iter; + struct telegram_chat_state *tcs = NULL; + + if (!bson_iter_init(&iter, bson)) goto cleanup; + XCALLOC(tcs, 1); + + while (bson_iter_next(bc)) { + const unsigned char *key = bson_iter_key(bc); + if (!strcmp(key, "_id")) { + if (ej_bson_parse_int64_new(bc, "_id", &tcs->_id) < 0) goto cleanup; + } else if (!strcmp(key, "command")) { + if (ej_bson_parse_string_new(bc, "command", &tcs->command) < 0) goto cleanup; + } else if (!strcmp(key, "token")) { + if (ej_bson_parse_string_new(bc, "token", &tcs->token) < 0) goto cleanup; + } else if (!strcmp(key, "state")) { + if (ej_bson_parse_int_new(bc, "state", &tcs->state, 0, 0, 0, 0) < 0) goto cleanup; + } else if (!strcmp(key, "review_flag")) { + if (ej_bson_parse_int_new(bc, "review_flag", &tcs->review_flag, 0, 0, 0, 0) < 0) goto cleanup; + } else if (!strcmp(key, "reply_flag")) { + if (ej_bson_parse_int_new(bc, "reply_flag", &tcs->reply_flag, 0, 0, 0, 0) < 0) goto cleanup; + } + } + + return tcs; + +cleanup: + telegram_chat_state_free(tcs); + return NULL; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + bson_cursor *bc = NULL; + struct telegram_chat_state *tcs = NULL; + + XCALLOC(tcs, 1); + bc = bson_cursor_new(bson); + while (bson_cursor_next(bc)) { + const unsigned char *key = bson_cursor_key(bc); + if (!strcmp(key, "_id")) { + if (ej_bson_parse_int64(bc, "_id", &tcs->_id) < 0) goto cleanup; + } else if (!strcmp(key, "command")) { + if (ej_bson_parse_string(bc, "command", &tcs->command) < 0) goto cleanup; + } else if (!strcmp(key, "token")) { + if (ej_bson_parse_string(bc, "token", &tcs->token) < 0) goto cleanup; + } else if (!strcmp(key, "state")) { + if (ej_bson_parse_int(bc, "state", &tcs->state, 0, 0, 0, 0) < 0) goto cleanup; + } else if (!strcmp(key, "review_flag")) { + if (ej_bson_parse_int(bc, "review_flag", &tcs->review_flag, 0, 0, 0, 0) < 0) goto cleanup; + } else if (!strcmp(key, "reply_flag")) { + if (ej_bson_parse_int(bc, "reply_flag", &tcs->reply_flag, 0, 0, 0, 0) < 0) goto cleanup; + } + } + bson_cursor_free(bc); + return tcs; + +cleanup: + telegram_chat_state_free(tcs); + return NULL; +#else +#error mongo packages are missing +#endif +} + +static ej_bson_t * +telegram_chat_state_unparse_bson(const struct telegram_chat_state *tcs) +{ +#if HAVE_LIBMONGOC - 0 > 0 + if (!tcs) return NULL; + + bson_t *bson = bson_new(); + + if (tcs->_id) { + bson_append_int64(bson, "_id", -1, tcs->_id); + } + if (tcs->command && *tcs->command) { + bson_append_utf8(bson, "command", -1, tcs->command, strlen(tcs->command)); + } + if (tcs->token && *tcs->token) { + bson_append_utf8(bson, "token", -1, tcs->token, strlen(tcs->token)); + } + if (tcs->state > 0) { + bson_append_int32(bson, "state", -1, tcs->state); + } + if (tcs->review_flag > 0) { + bson_append_int32(bson, "review_flag", -1, tcs->review_flag); + } + if (tcs->reply_flag > 0) { + bson_append_int32(bson, "reply_flag", -1, tcs->reply_flag); + } + + return bson; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + if (!tcs) return NULL; + + bson *bson = bson_new(); + if (tcs->_id) { + bson_append_int64(bson, "_id", tcs->_id); + } + if (tcs->command && *tcs->command) { + bson_append_string(bson, "command", tcs->command, strlen(tcs->command)); + } + if (tcs->token && *tcs->token) { + bson_append_string(bson, "token", tcs->token, strlen(tcs->token)); + } + if (tcs->state > 0) { + bson_append_int32(bson, "state", tcs->state); + } + if (tcs->review_flag > 0) { + bson_append_int32(bson, "review_flag", tcs->review_flag); + } + if (tcs->reply_flag > 0) { + bson_append_int32(bson, "reply_flag", tcs->reply_flag); + } + bson_finish(bson); + return bson; +#else +#error mongo packages are missing +#endif +} + +static struct telegram_chat_state * +chat_state_fetch_func( + struct generic_conn *gc, + long long _id) +{ + struct mongo_conn *conn = (struct mongo_conn *) gc; +#if HAVE_LIBMONGOC - 0 > 0 + if (!conn->b.vt->open(&conn->b)) return NULL; + + mongoc_collection_t *coll = NULL; + struct telegram_chat_state *retval = NULL; + bson_t *query = NULL; + mongoc_cursor_t *cursor = NULL; + const bson_t *doc = NULL; + + if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_CHAT_STATES_TABLE_NAME))) { + err("get_collection failed\n"); + goto cleanup; + } + + query = bson_new(); + bson_append_int64(query, "_id", -1, _id); + cursor = mongoc_collection_find_with_opts(coll, query, NULL, NULL); + if (!cursor) goto cleanup; + + if (mongoc_cursor_next(cursor, &doc)) { + retval = telegram_chat_state_parse_bson(doc); + } + +cleanup: + if (cursor) mongoc_cursor_destroy(cursor); + if (query) bson_destroy(query); + if (coll) mongoc_collection_destroy(coll); + + return retval; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + if (!mongo_conn_open(conn)) return NULL; + + bson *query = NULL; + mongo_packet *pkt = NULL; + mongo_sync_cursor *cursor = NULL; + bson *result = NULL; + struct telegram_chat_state *retval = NULL; + + query = bson_new(); + bson_append_int64(query, "_id", _id); + bson_finish(query); + + pkt = mongo_sync_cmd_query(conn->conn, mongo_conn_ns(conn, TELEGRAM_CHAT_STATES_TABLE_NAME), 0, 0, 1, query, NULL); + if (!pkt && errno == ENOENT) { + goto cleanup; + } + if (!pkt) { + err("mongo query failed: %s", os_ErrorMsg()); + goto cleanup; + } + bson_free(query); query = NULL; + + cursor = mongo_sync_cursor_new(conn->conn, conn->ns, pkt); + if (!cursor) { + err("mongo query failed: cannot create cursor: %s", os_ErrorMsg()); + goto cleanup; + } + pkt = NULL; + if (mongo_sync_cursor_next(cursor)) { + result = mongo_sync_cursor_get_data(cursor); + if (result) { + retval = telegram_chat_state_parse_bson(result); + } + } + +cleanup: + if (result) bson_free(result); + if (cursor) mongo_sync_cursor_free(cursor); + if (pkt) mongo_wire_packet_free(pkt); + if (query) bson_free(query); + return retval; +#else +#error mongo packages are missing +#endif +} + +static int +chat_state_save_func( + struct generic_conn *gc, + const struct telegram_chat_state *tcs) +{ + struct mongo_conn *conn = (struct mongo_conn *) gc; +#if HAVE_LIBMONGOC - 0 > 0 + if (!conn->b.vt->open(&conn->b)) return -1; + + int retval = -1; + mongoc_collection_t *coll = NULL; + bson_t *query = NULL; + bson_t *bson = NULL; + bson_error_t error; + + if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_CHAT_STATES_TABLE_NAME))) { + err("get_collection failed\n"); + goto cleanup; + } + query = bson_new(); + bson_append_int64(query, "_id", -1, tcs->_id); + bson = telegram_chat_state_unparse_bson(tcs); + + if (!mongoc_collection_update(coll, MONGOC_UPDATE_UPSERT, query, bson, NULL, &error)) { + err("telegram_chat_save: failed: %s", error.message); + goto cleanup; + } + + retval = 0; + +cleanup: + if (coll) mongoc_collection_destroy(coll); + if (query) bson_destroy(query); + if (bson) bson_destroy(bson); + return retval; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + if (!mongo_conn_open(conn)) return -1; + int retval = -1; + + bson *b = telegram_chat_state_unparse_bson(tcs); + bson *q = bson_new(); + bson_append_int64(q, "_id", tcs->_id); + bson_finish(q); + + if (!mongo_sync_cmd_update(conn->conn, mongo_conn_ns(conn, TELEGRAM_CHAT_STATES_TABLE_NAME), MONGO_WIRE_FLAG_UPDATE_UPSERT, q, b)) { + err("save_token: failed: %s", os_ErrorMsg()); + goto cleanup; + } + + retval = 0; + +cleanup: + bson_free(q); + bson_free(b); + return retval; +#else +#error mongo packages are missing +#endif +} + +#undef TELEGRAM_CHAT_STATES_TABLE_NAME + +#define TELEGRAM_SUBSCRIPTIONS_TABLE_NAME "telegram_subscriptions" + +static struct telegram_subscription * +telegram_subscription_parse_bson(const ej_bson_t *bson) +{ +#if HAVE_LIBMONGOC - 0 > 0 + bson_iter_t iter, * const bc = &iter; + struct telegram_subscription *sub = NULL; + + if (!bson_iter_init(&iter, bson)) goto cleanup; + + XCALLOC(sub, 1); + while (bson_iter_next(&iter)) { + const unsigned char *key = bson_iter_key(bc); + if (!strcmp(key, "_id")) { + if (ej_bson_parse_string_new(bc, "_id", &sub->_id) < 0) goto cleanup; + } else if (!strcmp(key, "bot_id")) { + if (ej_bson_parse_string_new(bc, "bot_id", &sub->bot_id) < 0) goto cleanup; + } else if (!strcmp(key, "user_id")) { + if (ej_bson_parse_int_new(bc, "user_id", &sub->user_id, 1, 1, 0, 0) < 0) goto cleanup; + } else if (!strcmp(key, "contest_id")) { + if (ej_bson_parse_int_new(bc, "contest_id", &sub->contest_id, 1, 0, 0, 0) < 0) goto cleanup; + } else if (!strcmp(key, "review_flag")) { + if (ej_bson_parse_int_new(bc, "review_flag", &sub->review_flag, 1, 0, 0, 0) < 0) goto cleanup; + } else if (!strcmp(key, "reply_flag")) { + if (ej_bson_parse_int_new(bc, "reply_flag", &sub->reply_flag, 1, 0, 0, 0) < 0) goto cleanup; + } else if (!strcmp(key, "chat_id")) { + if (ej_bson_parse_int64_new(bc, "chat_id", &sub->chat_id) < 0) goto cleanup; + } + } + return sub; + +cleanup: + telegram_subscription_free(sub); + return NULL; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + struct telegram_subscription *sub = NULL; + bson_cursor *bc = NULL; + + XCALLOC(sub, 1); + bc = bson_cursor_new(bson); + while (bson_cursor_next(bc)) { + const unsigned char *key = bson_cursor_key(bc); + if (!strcmp(key, "_id")) { + if (ej_bson_parse_string(bc, "_id", &sub->_id) < 0) goto cleanup; + } else if (!strcmp(key, "bot_id")) { + if (ej_bson_parse_string(bc, "bot_id", &sub->bot_id) < 0) goto cleanup; + } else if (!strcmp(key, "user_id")) { + if (ej_bson_parse_int(bc, "user_id", &sub->user_id, 1, 1, 0, 0) < 0) goto cleanup; + } else if (!strcmp(key, "contest_id")) { + if (ej_bson_parse_int(bc, "contest_id", &sub->contest_id, 1, 0, 0, 0) < 0) goto cleanup; + } else if (!strcmp(key, "review_flag")) { + if (ej_bson_parse_int(bc, "review_flag", &sub->review_flag, 1, 0, 0, 0) < 0) goto cleanup; + } else if (!strcmp(key, "reply_flag")) { + if (ej_bson_parse_int(bc, "reply_flag", &sub->reply_flag, 1, 0, 0, 0) < 0) goto cleanup; + } else if (!strcmp(key, "chat_id")) { + if (ej_bson_parse_int64(bc, "chat_id", &sub->chat_id) < 0) goto cleanup; + } + } + bson_cursor_free(bc); + return sub; + +cleanup: + telegram_subscription_free(sub); + return NULL; +#else +#error mongo packages are missing +#endif +} + +static ej_bson_t * +telegram_subscription_unparse_bson(const struct telegram_subscription *sub) +{ +#if HAVE_LIBMONGOC - 0 > 0 + if (!sub) return NULL; + + bson_t *bson = bson_new(); + if (sub->_id && *sub->_id) { + bson_append_utf8(bson, "_id", -1, sub->_id, strlen(sub->_id)); + } + if (sub->bot_id && *sub->bot_id) { + bson_append_utf8(bson, "bot_id", -1, sub->bot_id, strlen(sub->bot_id)); + } + if (sub->user_id > 0) { + bson_append_int32(bson, "user_id", -1, sub->user_id); + } + if (sub->contest_id > 0) { + bson_append_int32(bson, "contest_id", -1, sub->contest_id); + } + if (sub->review_flag > 0) { + bson_append_int32(bson, "review_flag", -1, sub->review_flag); + } + if (sub->reply_flag > 0) { + bson_append_int32(bson, "reply_flag", -1, sub->reply_flag); + } + if (sub->chat_id) { + bson_append_int64(bson, "chat_id", -1, sub->chat_id); + } + return bson; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + if (!sub) return NULL; + + bson *b = bson_new(); + if (sub->_id && *sub->_id) { + bson_append_string(b, "_id", sub->_id, strlen(sub->_id)); + } + if (sub->bot_id && *sub->bot_id) { + bson_append_string(b, "bot_id", sub->bot_id, strlen(sub->bot_id)); + } + if (sub->user_id > 0) { + bson_append_int32(b, "user_id", sub->user_id); + } + if (sub->contest_id > 0) { + bson_append_int32(b, "contest_id", sub->contest_id); + } + if (sub->review_flag > 0) { + bson_append_int32(b, "review_flag", sub->review_flag); + } + if (sub->reply_flag > 0) { + bson_append_int32(b, "reply_flag", sub->reply_flag); + } + if (sub->chat_id) { + bson_append_int64(b, "chat_id", sub->chat_id); + } + bson_finish(b); + return b; +#else +#error mongo packages are missing +#endif +} + +static struct telegram_subscription * +subscription_fetch_func( + struct generic_conn *gc, + const unsigned char *bot_id, + int user_id, + int contest_id) +{ + struct mongo_conn *conn = (struct mongo_conn *) gc; +#if HAVE_LIBMONGOC - 0 > 0 + if (!conn->b.vt->open(&conn->b)) return NULL; + + unsigned char buf[1024]; + if (!bot_id || !*bot_id || contest_id <= 0 || user_id <= 0) return NULL; + snprintf(buf, sizeof(buf), "%s-%d-%d", bot_id, contest_id, user_id); + + mongoc_collection_t *coll = NULL; + bson_t *query = NULL; + mongoc_cursor_t *cursor = NULL; + const bson_t *doc = NULL; + struct telegram_subscription *retval = NULL; + + if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_SUBSCRIPTIONS_TABLE_NAME))) { + err("get_collection failed\n"); + goto cleanup; + } + + query = bson_new(); + bson_append_utf8(query, "_id", -1, buf, strlen(buf)); + cursor = mongoc_collection_find_with_opts(coll, query, NULL, NULL); + if (!cursor) goto cleanup; + + if (mongoc_cursor_next(cursor, &doc)) { + retval = telegram_subscription_parse_bson(doc); + } + +cleanup: + if (cursor) mongoc_cursor_destroy(cursor); + if (coll) mongoc_collection_destroy(coll); + if (query) bson_destroy(query); + return retval; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + if (!mongo_conn_open(conn)) return NULL; + + unsigned char buf[1024]; + if (!bot_id || !*bot_id || contest_id <= 0 || user_id <= 0) return NULL; + snprintf(buf, sizeof(buf), "%s-%d-%d", bot_id, contest_id, user_id); + + bson *query = NULL; + mongo_packet *pkt = NULL; + mongo_sync_cursor *cursor = NULL; + bson *result = NULL; + struct telegram_subscription *retval = NULL; + + query = bson_new(); + bson_append_string(query, "_id", buf, strlen(buf)); + bson_finish(query); + + pkt = mongo_sync_cmd_query(conn->conn, mongo_conn_ns(conn, TELEGRAM_SUBSCRIPTIONS_TABLE_NAME), 0, 0, 1, query, NULL); + if (!pkt && errno == ENOENT) { + goto cleanup; + } + if (!pkt) { + err("mongo query failed: %s", os_ErrorMsg()); + goto cleanup; + } + bson_free(query); query = NULL; + + cursor = mongo_sync_cursor_new(conn->conn, conn->ns, pkt); + if (!cursor) { + err("mongo query failed: cannot create cursor: %s", os_ErrorMsg()); + goto cleanup; + } + pkt = NULL; + if (mongo_sync_cursor_next(cursor)) { + result = mongo_sync_cursor_get_data(cursor); + if (result) { + retval = telegram_subscription_parse_bson(result); + } + } + +cleanup: + if (result) bson_free(result); + if (cursor) mongo_sync_cursor_free(cursor); + if (pkt) mongo_wire_packet_free(pkt); + if (query) bson_free(query); + return retval; +#else +#error mongo packages are missing +#endif +} + +static int +subscription_save_func( + struct generic_conn *gc, + const struct telegram_subscription *sub) +{ + struct mongo_conn *conn = (struct mongo_conn *) gc; +#if HAVE_LIBMONGOC - 0 > 0 + if (!conn->b.vt->open(&conn->b)) return -1; + + int retval = -1; + mongoc_collection_t *coll = NULL; + bson_t *query = NULL; + bson_t *bson = NULL; + bson_error_t error; + + if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_SUBSCRIPTIONS_TABLE_NAME))) { + err("get_collection failed\n"); + goto cleanup; + } + + query = bson_new(); + bson_append_utf8(query, "_id", -1, sub->_id, strlen(sub->_id)); + bson = telegram_subscription_unparse_bson(sub); + + if (!mongoc_collection_update(coll, MONGOC_UPDATE_UPSERT, query, bson, NULL, &error)) { + err("telegram_chat_save: failed: %s", error.message); + goto cleanup; + } + + retval = 0; + +cleanup: + if (coll) mongoc_collection_destroy(coll); + if (query) bson_destroy(query); + if (bson) bson_destroy(bson); + return retval; +#elif HAVE_LIBMONGO_CLIENT - 0 == 1 + if (!mongo_conn_open(conn)) return -1; + int retval = -1; + + bson *b = telegram_subscription_unparse_bson(sub); + bson *q = bson_new(); + bson_append_string(q, "_id", sub->_id, strlen(sub->_id)); + bson_finish(q); + + if (!mongo_sync_cmd_update(conn->conn, mongo_conn_ns(conn, TELEGRAM_SUBSCRIPTIONS_TABLE_NAME), MONGO_WIRE_FLAG_UPDATE_UPSERT, q, b)) { + err("save_token: failed: %s", os_ErrorMsg()); + goto cleanup; + } + + retval = 0; + +cleanup: + bson_free(q); + bson_free(b); + return retval; +#else +#error mongo packages are missing +#endif +} + +#undef TELEGRAM_SUBSCRIPTIONS_TABLE_NAME + +#else // HAVE_LIBMONGOC - 0 > 0 || HAVE_LIBMONGO_CLIENT - 0 == 1 + +struct generic_conn * +mongo_conn_create(void) +{ + return NULL; +} + +#endif diff --git a/plugins/telegram/telegram.c b/plugins/telegram/telegram.c index ce58e7da08..35aed5d5d8 100644 --- a/plugins/telegram/telegram.c +++ b/plugins/telegram/telegram.c @@ -14,6 +14,7 @@ * GNU General Public License for more details. */ +#include "ejudge/config.h" #include "ejudge/telegram.h" #include "ejudge/xml_utils.h" #include "ejudge/random.h" @@ -343,6 +344,10 @@ prepare_func( err("telegram: invalid storage '%s'", storage); return -1; } + if (!conn) { + err("telegram: storage '%s' is not supported", storage); + return -1; + } state->conn = conn; conn->host = host; host = NULL; conn->port = port; @@ -1241,8 +1246,8 @@ handle_incoming_message( struct telegram_pbs *pbs, TeMessage *tem) { - struct telegram_user *mu = NULL; // mongo user - struct telegram_chat *mc = NULL; // mongo chat + struct telegram_user *mu = NULL; // mongo/mysql user. TODO use plugin-independent names + struct telegram_chat *mc = NULL; // mongo/mysql chat struct TeSendMessageResult *send_result = NULL; struct telegram_chat_state *tcs = NULL; struct telegram_token *token = NULL; diff --git a/plugins/telegram/telegram_chat.c b/plugins/telegram/telegram_chat.c index dfabdccf23..70ea5c9dcc 100644 --- a/plugins/telegram/telegram_chat.c +++ b/plugins/telegram/telegram_chat.c @@ -16,40 +16,10 @@ #include "telegram_chat.h" -#include "ejudge/bson_utils.h" - #include "ejudge/xalloc.h" -#include "ejudge/errlog.h" -#include "ejudge/osdeps.h" - -#include "mongo_conn.h" - -#if HAVE_LIBMONGOC - 0 > 1 -#include -#elif HAVE_LIBMONGOC - 0 > 0 -#include -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 -#include -#endif -#include #include -#if HAVE_LIBMONGOC - 0 > 0 -struct _bson_t; -typedef struct _bson_t ej_bson_t; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 -struct _bson; -typedef struct _bson ej_bson_t; -#endif - -#define TELEGRAM_CHATS_TABLE_NAME "telegram_chats" - -static struct telegram_chat * -telegram_chat_parse_bson(const ej_bson_t *bson); -static ej_bson_t * -telegram_chat_unparse_bson(const struct telegram_chat *tc); - struct telegram_chat * telegram_chat_free(struct telegram_chat *tc) { @@ -72,261 +42,3 @@ telegram_chat_create(void) XCALLOC(tc, 1); return tc; } - -static struct telegram_chat * -telegram_chat_parse_bson(const ej_bson_t *bson) -{ -#if HAVE_LIBMONGOC - 0 > 0 - bson_iter_t iter, * const bc = &iter; - struct telegram_chat *tc = NULL; - - if (!bson_iter_init(&iter, bson)) goto cleanup; - - XCALLOC(tc, 1); - while (bson_iter_next(&iter)) { - const unsigned char *key = bson_iter_key(bc); - if (!strcmp(key, "_id")) { - if (ej_bson_parse_int64_new(bc, "_id", &tc->_id) < 0) goto cleanup; - } else if (!strcmp(key, "type")) { - if (ej_bson_parse_string_new(bc, "type", &tc->type) < 0) goto cleanup; - } else if (!strcmp(key, "title")) { - if (ej_bson_parse_string_new(bc, "title", &tc->title) < 0) goto cleanup; - } else if (!strcmp(key, "username")) { - if (ej_bson_parse_string_new(bc, "username", &tc->username) < 0) goto cleanup; - } else if (!strcmp(key, "first_name")) { - if (ej_bson_parse_string_new(bc, "first_name", &tc->first_name) < 0) goto cleanup; - } else if (!strcmp(key, "last_name")) { - if (ej_bson_parse_string_new(bc, "last_name", &tc->last_name) < 0) goto cleanup; - } - } - - return tc; - -cleanup: - telegram_chat_free(tc); - return NULL; - -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - bson_cursor *bc = NULL; - struct telegram_chat *tc = NULL; - - XCALLOC(tc, 1); - bc = bson_cursor_new(bson); - while (bson_cursor_next(bc)) { - const unsigned char *key = bson_cursor_key(bc); - if (!strcmp(key, "_id")) { - if (ej_bson_parse_int64(bc, "_id", &tc->_id) < 0) goto cleanup; - } else if (!strcmp(key, "type")) { - if (ej_bson_parse_string(bc, "type", &tc->type) < 0) goto cleanup; - } else if (!strcmp(key, "title")) { - if (ej_bson_parse_string(bc, "title", &tc->title) < 0) goto cleanup; - } else if (!strcmp(key, "username")) { - if (ej_bson_parse_string(bc, "username", &tc->username) < 0) goto cleanup; - } else if (!strcmp(key, "first_name")) { - if (ej_bson_parse_string(bc, "first_name", &tc->first_name) < 0) goto cleanup; - } else if (!strcmp(key, "last_name")) { - if (ej_bson_parse_string(bc, "last_name", &tc->last_name) < 0) goto cleanup; - } - } - bson_cursor_free(bc); - return tc; - -cleanup: - telegram_chat_free(tc); - return NULL; -#else - return NULL; -#endif -} - -static ej_bson_t * -telegram_chat_unparse_bson(const struct telegram_chat *tc) -{ -#if HAVE_LIBMONGOC - 0 > 0 - if (!tc) return NULL; - - bson_t *bson = bson_new(); - - if (tc->_id) { - bson_append_int64(bson, "_id", -1, tc->_id); - } - if (tc->type && *tc->type) { - bson_append_utf8(bson, "type", -1, tc->type, strlen(tc->type)); - } - if (tc->title && *tc->title) { - bson_append_utf8(bson, "title", -1, tc->title, strlen(tc->title)); - } - if (tc->username && *tc->username) { - bson_append_utf8(bson, "username", -1, tc->username, strlen(tc->username)); - } - if (tc->first_name && *tc->first_name) { - bson_append_utf8(bson, "first_name", -1, tc->first_name, strlen(tc->first_name)); - } - if (tc->last_name && *tc->last_name) { - bson_append_utf8(bson, "last_name", -1, tc->last_name, strlen(tc->last_name)); - } - - return bson; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - if (!tc) return NULL; - - bson *bson = bson_new(); - if (tc->_id) { - bson_append_int64(bson, "_id", tc->_id); - } - if (tc->type && *tc->type) { - bson_append_string(bson, "type", tc->type, strlen(tc->type)); - } - if (tc->title && *tc->title) { - bson_append_string(bson, "title", tc->title, strlen(tc->title)); - } - if (tc->username && *tc->username) { - bson_append_string(bson, "username", tc->username, strlen(tc->username)); - } - if (tc->first_name && *tc->first_name) { - bson_append_string(bson, "first_name", tc->first_name, strlen(tc->first_name)); - } - if (tc->last_name && *tc->last_name) { - bson_append_string(bson, "last_name", tc->last_name, strlen(tc->last_name)); - } - bson_finish(bson); - return bson; -#else - return NULL; -#endif -} - -struct telegram_chat * -telegram_chat_fetch(struct mongo_conn *conn, long long _id) -{ -#if HAVE_LIBMONGOC - 0 > 0 - if (!conn->b.vt->open(&conn->b)) return NULL; - - mongoc_collection_t *coll = NULL; - bson_t *query = NULL; - mongoc_cursor_t *cursor = NULL; - const bson_t *doc = NULL; - struct telegram_chat *retval = NULL; - - if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_CHATS_TABLE_NAME))) { - err("get_collection failed\n"); - goto cleanup; - } - query = bson_new(); - bson_append_int64(query, "_id", -1, _id); - cursor = mongoc_collection_find_with_opts(coll, query, NULL, NULL); - if (!cursor) goto cleanup; - - if (mongoc_cursor_next(cursor, &doc)) { - retval = telegram_chat_parse_bson(doc); - } - -cleanup: - if (cursor) mongoc_cursor_destroy(cursor); - if (coll) mongoc_collection_destroy(coll); - if (query) bson_destroy(query); - return retval; - -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - if (!mongo_conn_open(conn)) return NULL; - - bson *query = NULL; - mongo_packet *pkt = NULL; - mongo_sync_cursor *cursor = NULL; - bson *result = NULL; - struct telegram_chat *retval = NULL; - - query = bson_new(); - bson_append_int64(query, "_id", _id); - bson_finish(query); - - pkt = mongo_sync_cmd_query(conn->conn, mongo_conn_ns(conn, TELEGRAM_CHATS_TABLE_NAME), 0, 0, 1, query, NULL); - if (!pkt && errno == ENOENT) { - goto cleanup; - } - if (!pkt) { - err("mongo query failed: %s", os_ErrorMsg()); - goto cleanup; - } - bson_free(query); query = NULL; - - cursor = mongo_sync_cursor_new(conn->conn, conn->ns, pkt); - if (!cursor) { - err("mongo query failed: cannot create cursor: %s", os_ErrorMsg()); - goto cleanup; - } - pkt = NULL; - if (mongo_sync_cursor_next(cursor)) { - result = mongo_sync_cursor_get_data(cursor); - if (result) { - retval = telegram_chat_parse_bson(result); - } - } - -cleanup: - if (result) bson_free(result); - if (cursor) mongo_sync_cursor_free(cursor); - if (pkt) mongo_wire_packet_free(pkt); - if (query) bson_free(query); - return retval; -#else - return NULL; -#endif -} - -int -telegram_chat_save(struct mongo_conn *conn, const struct telegram_chat *tc) -{ -#if HAVE_LIBMONGOC - 0 > 0 - if (!conn->b.vt->open(&conn->b)) return -1; - - int retval = -1; - mongoc_collection_t *coll = NULL; - bson_t *query = NULL; - bson_t *bson = NULL; - bson_error_t error; - - if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_CHATS_TABLE_NAME))) { - err("get_collection failed\n"); - goto cleanup; - } - query = bson_new(); - bson_append_int64(query, "_id", -1, tc->_id); - bson = telegram_chat_unparse_bson(tc); - - if (!mongoc_collection_update(coll, MONGOC_UPDATE_UPSERT, query, bson, NULL, &error)) { - err("telegram_chat_save: failed: %s", error.message); - goto cleanup; - } - - retval = 0; - -cleanup: - if (coll) mongoc_collection_destroy(coll); - if (query) bson_destroy(query); - if (bson) bson_destroy(bson); - return retval; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - if (!mongo_conn_open(conn)) return -1; - int retval = -1; - - bson *b = telegram_chat_unparse_bson(tc); - bson *q = bson_new(); - bson_append_int64(q, "_id", tc->_id); - bson_finish(q); - - if (!mongo_sync_cmd_update(conn->conn, mongo_conn_ns(conn, TELEGRAM_CHATS_TABLE_NAME), MONGO_WIRE_FLAG_UPDATE_UPSERT, q, b)) { - err("save_token: failed: %s", os_ErrorMsg()); - goto cleanup; - } - - retval = 0; - -cleanup: - bson_free(q); - bson_free(b); - return retval; -#else - return 0; -#endif -} diff --git a/plugins/telegram/telegram_chat.h b/plugins/telegram/telegram_chat.h index 526c630779..03a602c592 100644 --- a/plugins/telegram/telegram_chat.h +++ b/plugins/telegram/telegram_chat.h @@ -16,8 +16,6 @@ * GNU General Public License for more details. */ -#include "ejudge/config.h" - /* id Integer Unique identifier for this chat. This number may be greater than 32 bits and some programming languages may have difficulty/silent defects in interpreting it. But it smaller than 52 bits, so a signed 64 bit integer or double-precision float type are safe for storing this identifier. type String Type of chat, can be either “private”, “group”, “supergroup” or “channel” diff --git a/plugins/telegram/telegram_chat_state.c b/plugins/telegram/telegram_chat_state.c index 2baeebb015..1740b13dd8 100644 --- a/plugins/telegram/telegram_chat_state.c +++ b/plugins/telegram/telegram_chat_state.c @@ -16,40 +16,10 @@ #include "telegram_chat_state.h" -#include "ejudge/bson_utils.h" - #include "ejudge/xalloc.h" -#include "ejudge/errlog.h" -#include "ejudge/osdeps.h" - -#include "mongo_conn.h" - -#if HAVE_LIBMONGOC - 0 > 1 -#include -#elif HAVE_LIBMONGOC - 0 > 0 -#include -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 -#include -#endif -#include #include -#if HAVE_LIBMONGOC - 0 > 0 -struct _bson_t; -typedef struct _bson_t ej_bson_t; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 -struct _bson; -typedef struct _bson ej_bson_t; -#endif - -#define TELEGRAM_CHAT_STATES_TABLE_NAME "telegram_chat_states" - -static struct telegram_chat_state * -telegram_chat_state_parse_bson(const ej_bson_t *bson); -static ej_bson_t * -telegram_chat_state_unparse_bson(const struct telegram_chat_state *tcs); - struct telegram_chat_state * telegram_chat_state_free(struct telegram_chat_state *tcs) { @@ -77,261 +47,3 @@ telegram_chat_state_reset(struct telegram_chat_state *tcs) tcs->review_flag = 0; tcs->reply_flag = 0; } - -static struct telegram_chat_state * -telegram_chat_state_parse_bson(const ej_bson_t *bson) -{ -#if HAVE_LIBMONGOC - 0 > 0 - bson_iter_t iter, * const bc = &iter; - struct telegram_chat_state *tcs = NULL; - - if (!bson_iter_init(&iter, bson)) goto cleanup; - XCALLOC(tcs, 1); - - while (bson_iter_next(bc)) { - const unsigned char *key = bson_iter_key(bc); - if (!strcmp(key, "_id")) { - if (ej_bson_parse_int64_new(bc, "_id", &tcs->_id) < 0) goto cleanup; - } else if (!strcmp(key, "command")) { - if (ej_bson_parse_string_new(bc, "command", &tcs->command) < 0) goto cleanup; - } else if (!strcmp(key, "token")) { - if (ej_bson_parse_string_new(bc, "token", &tcs->token) < 0) goto cleanup; - } else if (!strcmp(key, "state")) { - if (ej_bson_parse_int_new(bc, "state", &tcs->state, 0, 0, 0, 0) < 0) goto cleanup; - } else if (!strcmp(key, "review_flag")) { - if (ej_bson_parse_int_new(bc, "review_flag", &tcs->review_flag, 0, 0, 0, 0) < 0) goto cleanup; - } else if (!strcmp(key, "reply_flag")) { - if (ej_bson_parse_int_new(bc, "reply_flag", &tcs->reply_flag, 0, 0, 0, 0) < 0) goto cleanup; - } - } - - return tcs; - -cleanup: - telegram_chat_state_free(tcs); - return NULL; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - bson_cursor *bc = NULL; - struct telegram_chat_state *tcs = NULL; - - XCALLOC(tcs, 1); - bc = bson_cursor_new(bson); - while (bson_cursor_next(bc)) { - const unsigned char *key = bson_cursor_key(bc); - if (!strcmp(key, "_id")) { - if (ej_bson_parse_int64(bc, "_id", &tcs->_id) < 0) goto cleanup; - } else if (!strcmp(key, "command")) { - if (ej_bson_parse_string(bc, "command", &tcs->command) < 0) goto cleanup; - } else if (!strcmp(key, "token")) { - if (ej_bson_parse_string(bc, "token", &tcs->token) < 0) goto cleanup; - } else if (!strcmp(key, "state")) { - if (ej_bson_parse_int(bc, "state", &tcs->state, 0, 0, 0, 0) < 0) goto cleanup; - } else if (!strcmp(key, "review_flag")) { - if (ej_bson_parse_int(bc, "review_flag", &tcs->review_flag, 0, 0, 0, 0) < 0) goto cleanup; - } else if (!strcmp(key, "reply_flag")) { - if (ej_bson_parse_int(bc, "reply_flag", &tcs->reply_flag, 0, 0, 0, 0) < 0) goto cleanup; - } - } - bson_cursor_free(bc); - return tcs; - -cleanup: - telegram_chat_state_free(tcs); - return NULL; -#else - return NULL; -#endif -} - -static ej_bson_t * -telegram_chat_state_unparse_bson(const struct telegram_chat_state *tcs) -{ -#if HAVE_LIBMONGOC - 0 > 0 - if (!tcs) return NULL; - - bson_t *bson = bson_new(); - - if (tcs->_id) { - bson_append_int64(bson, "_id", -1, tcs->_id); - } - if (tcs->command && *tcs->command) { - bson_append_utf8(bson, "command", -1, tcs->command, strlen(tcs->command)); - } - if (tcs->token && *tcs->token) { - bson_append_utf8(bson, "token", -1, tcs->token, strlen(tcs->token)); - } - if (tcs->state > 0) { - bson_append_int32(bson, "state", -1, tcs->state); - } - if (tcs->review_flag > 0) { - bson_append_int32(bson, "review_flag", -1, tcs->review_flag); - } - if (tcs->reply_flag > 0) { - bson_append_int32(bson, "reply_flag", -1, tcs->reply_flag); - } - - return bson; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - if (!tcs) return NULL; - - bson *bson = bson_new(); - if (tcs->_id) { - bson_append_int64(bson, "_id", tcs->_id); - } - if (tcs->command && *tcs->command) { - bson_append_string(bson, "command", tcs->command, strlen(tcs->command)); - } - if (tcs->token && *tcs->token) { - bson_append_string(bson, "token", tcs->token, strlen(tcs->token)); - } - if (tcs->state > 0) { - bson_append_int32(bson, "state", tcs->state); - } - if (tcs->review_flag > 0) { - bson_append_int32(bson, "review_flag", tcs->review_flag); - } - if (tcs->reply_flag > 0) { - bson_append_int32(bson, "reply_flag", tcs->reply_flag); - } - bson_finish(bson); - return bson; -#else - return NULL; -#endif -} - -struct telegram_chat_state * -telegram_chat_state_fetch(struct mongo_conn *conn, long long _id) -{ -#if HAVE_LIBMONGOC - 0 > 0 - if (!conn->b.vt->open(&conn->b)) return NULL; - - mongoc_collection_t *coll = NULL; - struct telegram_chat_state *retval = NULL; - bson_t *query = NULL; - mongoc_cursor_t *cursor = NULL; - const bson_t *doc = NULL; - - if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_CHAT_STATES_TABLE_NAME))) { - err("get_collection failed\n"); - goto cleanup; - } - - query = bson_new(); - bson_append_int64(query, "_id", -1, _id); - cursor = mongoc_collection_find_with_opts(coll, query, NULL, NULL); - if (!cursor) goto cleanup; - - if (mongoc_cursor_next(cursor, &doc)) { - retval = telegram_chat_state_parse_bson(doc); - } - -cleanup: - if (cursor) mongoc_cursor_destroy(cursor); - if (query) bson_destroy(query); - if (coll) mongoc_collection_destroy(coll); - - return retval; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - if (!mongo_conn_open(conn)) return NULL; - - bson *query = NULL; - mongo_packet *pkt = NULL; - mongo_sync_cursor *cursor = NULL; - bson *result = NULL; - struct telegram_chat_state *retval = NULL; - - query = bson_new(); - bson_append_int64(query, "_id", _id); - bson_finish(query); - - pkt = mongo_sync_cmd_query(conn->conn, mongo_conn_ns(conn, TELEGRAM_CHAT_STATES_TABLE_NAME), 0, 0, 1, query, NULL); - if (!pkt && errno == ENOENT) { - goto cleanup; - } - if (!pkt) { - err("mongo query failed: %s", os_ErrorMsg()); - goto cleanup; - } - bson_free(query); query = NULL; - - cursor = mongo_sync_cursor_new(conn->conn, conn->ns, pkt); - if (!cursor) { - err("mongo query failed: cannot create cursor: %s", os_ErrorMsg()); - goto cleanup; - } - pkt = NULL; - if (mongo_sync_cursor_next(cursor)) { - result = mongo_sync_cursor_get_data(cursor); - if (result) { - retval = telegram_chat_state_parse_bson(result); - } - } - -cleanup: - if (result) bson_free(result); - if (cursor) mongo_sync_cursor_free(cursor); - if (pkt) mongo_wire_packet_free(pkt); - if (query) bson_free(query); - return retval; -#else - return NULL; -#endif -} - -int -telegram_chat_state_save(struct mongo_conn *conn, const struct telegram_chat_state *tcs) -{ -#if HAVE_LIBMONGOC - 0 > 0 - if (!conn->b.vt->open(&conn->b)) return -1; - - int retval = -1; - mongoc_collection_t *coll = NULL; - bson_t *query = NULL; - bson_t *bson = NULL; - bson_error_t error; - - if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_CHAT_STATES_TABLE_NAME))) { - err("get_collection failed\n"); - goto cleanup; - } - query = bson_new(); - bson_append_int64(query, "_id", -1, tcs->_id); - bson = telegram_chat_state_unparse_bson(tcs); - - if (!mongoc_collection_update(coll, MONGOC_UPDATE_UPSERT, query, bson, NULL, &error)) { - err("telegram_chat_save: failed: %s", error.message); - goto cleanup; - } - - retval = 0; - -cleanup: - if (coll) mongoc_collection_destroy(coll); - if (query) bson_destroy(query); - if (bson) bson_destroy(bson); - return retval; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - if (!mongo_conn_open(conn)) return -1; - int retval = -1; - - bson *b = telegram_chat_state_unparse_bson(tcs); - bson *q = bson_new(); - bson_append_int64(q, "_id", tcs->_id); - bson_finish(q); - - if (!mongo_sync_cmd_update(conn->conn, mongo_conn_ns(conn, TELEGRAM_CHAT_STATES_TABLE_NAME), MONGO_WIRE_FLAG_UPDATE_UPSERT, q, b)) { - err("save_token: failed: %s", os_ErrorMsg()); - goto cleanup; - } - - retval = 0; - -cleanup: - bson_free(q); - bson_free(b); - return retval; -#else - return 0; -#endif -} diff --git a/plugins/telegram/telegram_chat_state.h b/plugins/telegram/telegram_chat_state.h index 80959eb75e..1d52a052a5 100644 --- a/plugins/telegram/telegram_chat_state.h +++ b/plugins/telegram/telegram_chat_state.h @@ -16,8 +16,6 @@ * GNU General Public License for more details. */ -#include "ejudge/config.h" - struct telegram_chat_state { long long _id; diff --git a/plugins/telegram/telegram_pbs.c b/plugins/telegram/telegram_pbs.c index a693ebc681..b47f5cbd83 100644 --- a/plugins/telegram/telegram_pbs.c +++ b/plugins/telegram/telegram_pbs.c @@ -14,39 +14,9 @@ * GNU General Public License for more details. */ -#include "ejudge/bson_utils.h" #include "ejudge/xalloc.h" -#include "ejudge/errlog.h" -#include "ejudge/osdeps.h" -#include "ejudge/config.h" #include "telegram_pbs.h" -#include "mongo_conn.h" - -#if HAVE_LIBMONGOC - 0 > 0 -struct _bson_t; -typedef struct _bson_t ej_bson_t; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 -struct _bson; -typedef struct _bson ej_bson_t; -#endif - -#if HAVE_LIBMONGOC - 0 > 1 -#include -#elif HAVE_LIBMONGOC - 0 > 0 -#include -#elif HAVE_LIBMONGO_CLIENT -#include -#endif - -#include - -#define TELEGRAM_BOTS_TABLE_NAME "telegram_bots" - -static ej_bson_t * -telegram_pbs_unparse_bson(const struct telegram_pbs *pbs); -static struct telegram_pbs * -telegram_pbs_parse_bson(const ej_bson_t *bson); struct telegram_pbs * telegram_pbs_free(struct telegram_pbs *pbs) @@ -66,225 +36,3 @@ telegram_pbs_create(const unsigned char *_id) pbs->_id = xstrdup(_id); return pbs; } - -static struct telegram_pbs * -telegram_pbs_parse_bson(const ej_bson_t *bson) -{ -#if HAVE_LIBMONGOC - 0 > 0 - bson_iter_t iter, * const bc = &iter; - struct telegram_pbs *pbs = NULL; - - if (!bson_iter_init(&iter, bson)) goto cleanup; - - XCALLOC(pbs, 1); - while (bson_iter_next(&iter)) { - const unsigned char *key = bson_iter_key(bc); - if (!strcmp(key, "_id")) { - if (ej_bson_parse_string_new(bc, "_id", &pbs->_id) < 0) goto cleanup; - } else if (!strcmp(key, "update_id")) { - if (ej_bson_parse_int64_new(bc, "update_id", &pbs->update_id) < 0) goto cleanup; - } - } - - return pbs; - -cleanup: - telegram_pbs_free(pbs); - return NULL; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - bson_cursor *bc = NULL; - struct telegram_pbs *pbs = NULL; - - XCALLOC(pbs, 1); - bc = bson_cursor_new(bson); - while (bson_cursor_next(bc)) { - const unsigned char *key = bson_cursor_key(bc); - if (!strcmp(key, "_id")) { - if (ej_bson_parse_string(bc, "_id", &pbs->_id) < 0) goto cleanup; - } else if (!strcmp(key, "update_id")) { - if (ej_bson_parse_int64(bc, "update_id", &pbs->update_id) < 0) goto cleanup; - } - } - bson_cursor_free(bc); - return pbs; - -cleanup: - telegram_pbs_free(pbs); - return NULL; -#else - return NULL -#endif -} - -static ej_bson_t * -telegram_pbs_unparse_bson(const struct telegram_pbs *pbs) -{ -#if HAVE_LIBMONGOC - 0 > 0 - if (!pbs) return NULL; - - bson_t *bson = bson_new(); - if (pbs->_id && *pbs->_id) { - bson_append_utf8(bson, "_id", -1, pbs->_id, strlen(pbs->_id)); - } - if (pbs->update_id != 0) { - bson_append_int64(bson, "update_id", -1, pbs->update_id); - } - return bson; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - if (!pbs) return NULL; - - bson *bson = bson_new(); - if (pbs->_id && *pbs->_id) { - bson_append_string(bson, "_id", pbs->_id, strlen(pbs->_id)); - } - if (pbs->update_id != 0) { - bson_append_int64(bson, "update_id", pbs->update_id); - } - bson_finish(bson); - return bson; -#else - return NULL; -#endif -} - -int -telegram_pbs_save(struct mongo_conn *conn, const struct telegram_pbs *pbs) -{ -#if HAVE_LIBMONGOC - 0 > 0 - if (!conn->b.vt->open(&conn->b)) return -1; - - int retval = -1; - mongoc_collection_t *coll = NULL; - bson_t *query = NULL; - bson_t *bson = NULL; - bson_error_t error; - - if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_BOTS_TABLE_NAME))) { - err("get_collection failed\n"); - goto cleanup; - } - query = bson_new(); - bson_append_utf8(query, "_id", -1, pbs->_id, -1); - bson = telegram_pbs_unparse_bson(pbs); - - if (!mongoc_collection_update(coll, MONGOC_UPDATE_UPSERT, query, bson, NULL, &error)) { - err("telegram_chat_save: failed: %s", error.message); - goto cleanup; - } - - retval = 0; - -cleanup: - if (coll) mongoc_collection_destroy(coll); - if (query) bson_destroy(query); - if (bson) bson_destroy(bson); - return retval; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - if (!mongo_conn_open(conn)) return -1; - int retval = -1; - - bson *s = bson_new(); - bson_append_string(s, "_id", pbs->_id, strlen(pbs->_id)); - bson_finish(s); - - bson *b = telegram_pbs_unparse_bson(pbs); - if (!mongo_sync_cmd_update(conn->conn, mongo_conn_ns(conn, TELEGRAM_BOTS_TABLE_NAME), MONGO_WIRE_FLAG_UPDATE_UPSERT, s, b)) { - err("save_persistent_bot_state: failed: %s", os_ErrorMsg()); - goto done; - } - retval = 0; - -done: - bson_free(s); - bson_free(b); - return retval; -#else - return 0; -#endif -} - -struct telegram_pbs * -telegram_pbs_fetch(struct mongo_conn *conn, const unsigned char *bot_id) -{ -#if HAVE_LIBMONGOC - 0 > 0 - if (!conn->b.vt->open(&conn->b)) return NULL; - - bson_t *query = NULL; - mongoc_cursor_t *cursor = NULL; - const bson_t *doc = NULL; - struct telegram_pbs *retval = NULL; - mongoc_collection_t *coll = NULL; - - if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_BOTS_TABLE_NAME))) { - err("get_collection failed\n"); - goto cleanup; - } - query = bson_new(); - bson_append_utf8(query, "_id", -1, bot_id, -1); - cursor = mongoc_collection_find_with_opts(coll, query, NULL, NULL); - if (cursor && mongoc_cursor_next(cursor, &doc)) { - retval = telegram_pbs_parse_bson(doc); - goto cleanup; - } - - if (cursor) mongoc_cursor_destroy(cursor); - cursor = NULL; - bson_destroy(query); query = NULL; - mongoc_collection_destroy(coll); coll = NULL; - retval = telegram_pbs_create(bot_id); - telegram_pbs_save(conn, retval); - -cleanup: - if (cursor) mongoc_cursor_destroy(cursor); - if (coll) mongoc_collection_destroy(coll); - if (query) bson_destroy(query); - return retval; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - if (!mongo_conn_open(conn)) return NULL; - - mongo_packet *pkt = NULL; - bson *query = NULL; - mongo_sync_cursor *cursor = NULL; - bson *result = NULL; - struct telegram_pbs *pbs = NULL; - - query = bson_new(); - bson_append_string(query, "_id", bot_id, strlen(bot_id)); - bson_finish(query); - pkt = mongo_sync_cmd_query(conn->conn, mongo_conn_ns(conn, TELEGRAM_BOTS_TABLE_NAME), 0, 0, 1, query, NULL); - if (!pkt && errno == ENOENT) { - bson_free(query); query = NULL; - pbs = telegram_pbs_create(bot_id); - telegram_pbs_save(conn, pbs); - goto cleanup; - } - if (!pkt) { - err("mongo query failed: %s", os_ErrorMsg()); - goto cleanup; - } - bson_free(query); query = NULL; - cursor = mongo_sync_cursor_new(conn->conn, conn->ns, pkt); - if (!cursor) { - err("mongo query failed: cannot create cursor: %s", os_ErrorMsg()); - goto cleanup; - } - pkt = NULL; - if (mongo_sync_cursor_next(cursor)) { - result = mongo_sync_cursor_get_data(cursor); - pbs = telegram_pbs_parse_bson(result); - } else { - mongo_sync_cursor_free(cursor); cursor = NULL; - pbs = telegram_pbs_create(bot_id); - telegram_pbs_save(conn, pbs); - } - -cleanup: - if (result) bson_free(result); - if (cursor) mongo_sync_cursor_free(cursor); - if (pkt) mongo_wire_packet_free(pkt); - if (query) bson_free(query); - return pbs; -#else - return NULL; -#endif -} diff --git a/plugins/telegram/telegram_pbs.h b/plugins/telegram/telegram_pbs.h index a361ef8b9c..866f4ce84b 100644 --- a/plugins/telegram/telegram_pbs.h +++ b/plugins/telegram/telegram_pbs.h @@ -16,8 +16,6 @@ * GNU General Public License for more details. */ -#include "ejudge/config.h" - /* persistent bot state for telegram bot */ struct telegram_pbs { diff --git a/plugins/telegram/telegram_subscription.c b/plugins/telegram/telegram_subscription.c index 1f56f13248..23f6e87c06 100644 --- a/plugins/telegram/telegram_subscription.c +++ b/plugins/telegram/telegram_subscription.c @@ -15,40 +15,12 @@ */ #include "telegram_subscription.h" -#include "mongo_conn.h" -#include "ejudge/bson_utils.h" #include "ejudge/xalloc.h" -#include "ejudge/osdeps.h" -#include "ejudge/errlog.h" -#if HAVE_LIBMONGOC - 0 > 1 -#include -#elif HAVE_LIBMONGOC - 0 > 0 -#include -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 -#include -#endif - -#include #include #include -#if HAVE_LIBMONGOC - 0 > 0 -struct _bson_t; -typedef struct _bson_t ej_bson_t; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 -struct _bson; -typedef struct _bson ej_bson_t; -#endif - -#define TELEGRAM_SUBSCRIPTIONS_TABLE_NAME "telegram_subscriptions" - -static struct telegram_subscription * -telegram_subscription_parse_bson(const ej_bson_t *bson); -static ej_bson_t * -telegram_subscription_unparse_bson(const struct telegram_subscription *subscription); - struct telegram_subscription * telegram_subscription_free(struct telegram_subscription *sub) { @@ -77,276 +49,3 @@ telegram_subscription_create(const unsigned char *bot_id, int user_id, int conte sub->contest_id = contest_id; return sub; } - -static struct telegram_subscription * -telegram_subscription_parse_bson(const ej_bson_t *bson) -{ -#if HAVE_LIBMONGOC - 0 > 0 - bson_iter_t iter, * const bc = &iter; - struct telegram_subscription *sub = NULL; - - if (!bson_iter_init(&iter, bson)) goto cleanup; - - XCALLOC(sub, 1); - while (bson_iter_next(&iter)) { - const unsigned char *key = bson_iter_key(bc); - if (!strcmp(key, "_id")) { - if (ej_bson_parse_string_new(bc, "_id", &sub->_id) < 0) goto cleanup; - } else if (!strcmp(key, "bot_id")) { - if (ej_bson_parse_string_new(bc, "bot_id", &sub->bot_id) < 0) goto cleanup; - } else if (!strcmp(key, "user_id")) { - if (ej_bson_parse_int_new(bc, "user_id", &sub->user_id, 1, 1, 0, 0) < 0) goto cleanup; - } else if (!strcmp(key, "contest_id")) { - if (ej_bson_parse_int_new(bc, "contest_id", &sub->contest_id, 1, 0, 0, 0) < 0) goto cleanup; - } else if (!strcmp(key, "review_flag")) { - if (ej_bson_parse_int_new(bc, "review_flag", &sub->review_flag, 1, 0, 0, 0) < 0) goto cleanup; - } else if (!strcmp(key, "reply_flag")) { - if (ej_bson_parse_int_new(bc, "reply_flag", &sub->reply_flag, 1, 0, 0, 0) < 0) goto cleanup; - } else if (!strcmp(key, "chat_id")) { - if (ej_bson_parse_int64_new(bc, "chat_id", &sub->chat_id) < 0) goto cleanup; - } - } - return sub; - -cleanup: - telegram_subscription_free(sub); - return NULL; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - struct telegram_subscription *sub = NULL; - bson_cursor *bc = NULL; - - XCALLOC(sub, 1); - bc = bson_cursor_new(bson); - while (bson_cursor_next(bc)) { - const unsigned char *key = bson_cursor_key(bc); - if (!strcmp(key, "_id")) { - if (ej_bson_parse_string(bc, "_id", &sub->_id) < 0) goto cleanup; - } else if (!strcmp(key, "bot_id")) { - if (ej_bson_parse_string(bc, "bot_id", &sub->bot_id) < 0) goto cleanup; - } else if (!strcmp(key, "user_id")) { - if (ej_bson_parse_int(bc, "user_id", &sub->user_id, 1, 1, 0, 0) < 0) goto cleanup; - } else if (!strcmp(key, "contest_id")) { - if (ej_bson_parse_int(bc, "contest_id", &sub->contest_id, 1, 0, 0, 0) < 0) goto cleanup; - } else if (!strcmp(key, "review_flag")) { - if (ej_bson_parse_int(bc, "review_flag", &sub->review_flag, 1, 0, 0, 0) < 0) goto cleanup; - } else if (!strcmp(key, "reply_flag")) { - if (ej_bson_parse_int(bc, "reply_flag", &sub->reply_flag, 1, 0, 0, 0) < 0) goto cleanup; - } else if (!strcmp(key, "chat_id")) { - if (ej_bson_parse_int64(bc, "chat_id", &sub->chat_id) < 0) goto cleanup; - } - } - bson_cursor_free(bc); - return sub; - -cleanup: - telegram_subscription_free(sub); - return NULL; -#else - return NULL; -#endif -} - -static ej_bson_t * -telegram_subscription_unparse_bson(const struct telegram_subscription *sub) -{ -#if HAVE_LIBMONGOC - 0 > 0 - if (!sub) return NULL; - - bson_t *bson = bson_new(); - if (sub->_id && *sub->_id) { - bson_append_utf8(bson, "_id", -1, sub->_id, strlen(sub->_id)); - } - if (sub->bot_id && *sub->bot_id) { - bson_append_utf8(bson, "bot_id", -1, sub->bot_id, strlen(sub->bot_id)); - } - if (sub->user_id > 0) { - bson_append_int32(bson, "user_id", -1, sub->user_id); - } - if (sub->contest_id > 0) { - bson_append_int32(bson, "contest_id", -1, sub->contest_id); - } - if (sub->review_flag > 0) { - bson_append_int32(bson, "review_flag", -1, sub->review_flag); - } - if (sub->reply_flag > 0) { - bson_append_int32(bson, "reply_flag", -1, sub->reply_flag); - } - if (sub->chat_id) { - bson_append_int64(bson, "chat_id", -1, sub->chat_id); - } - return bson; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - if (!sub) return NULL; - - bson *b = bson_new(); - if (sub->_id && *sub->_id) { - bson_append_string(b, "_id", sub->_id, strlen(sub->_id)); - } - if (sub->bot_id && *sub->bot_id) { - bson_append_string(b, "bot_id", sub->bot_id, strlen(sub->bot_id)); - } - if (sub->user_id > 0) { - bson_append_int32(b, "user_id", sub->user_id); - } - if (sub->contest_id > 0) { - bson_append_int32(b, "contest_id", sub->contest_id); - } - if (sub->review_flag > 0) { - bson_append_int32(b, "review_flag", sub->review_flag); - } - if (sub->reply_flag > 0) { - bson_append_int32(b, "reply_flag", sub->reply_flag); - } - if (sub->chat_id) { - bson_append_int64(b, "chat_id", sub->chat_id); - } - bson_finish(b); - return b; -#else - return NULL; -#endif -} - -struct telegram_subscription * -telegram_subscription_fetch(struct mongo_conn *conn, const unsigned char *bot_id, int user_id, int contest_id) -{ -#if HAVE_LIBMONGOC - 0 > 0 - if (!conn->b.vt->open(&conn->b)) return NULL; - - unsigned char buf[1024]; - if (!bot_id || !*bot_id || contest_id <= 0 || user_id <= 0) return NULL; - snprintf(buf, sizeof(buf), "%s-%d-%d", bot_id, contest_id, user_id); - - mongoc_collection_t *coll = NULL; - bson_t *query = NULL; - mongoc_cursor_t *cursor = NULL; - const bson_t *doc = NULL; - struct telegram_subscription *retval = NULL; - - if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_SUBSCRIPTIONS_TABLE_NAME))) { - err("get_collection failed\n"); - goto cleanup; - } - - query = bson_new(); - bson_append_utf8(query, "_id", -1, buf, strlen(buf)); - cursor = mongoc_collection_find_with_opts(coll, query, NULL, NULL); - if (!cursor) goto cleanup; - - if (mongoc_cursor_next(cursor, &doc)) { - retval = telegram_subscription_parse_bson(doc); - } - -cleanup: - if (cursor) mongoc_cursor_destroy(cursor); - if (coll) mongoc_collection_destroy(coll); - if (query) bson_destroy(query); - return retval; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - if (!mongo_conn_open(conn)) return NULL; - - unsigned char buf[1024]; - if (!bot_id || !*bot_id || contest_id <= 0 || user_id <= 0) return NULL; - snprintf(buf, sizeof(buf), "%s-%d-%d", bot_id, contest_id, user_id); - - bson *query = NULL; - mongo_packet *pkt = NULL; - mongo_sync_cursor *cursor = NULL; - bson *result = NULL; - struct telegram_subscription *retval = NULL; - - query = bson_new(); - bson_append_string(query, "_id", buf, strlen(buf)); - bson_finish(query); - - pkt = mongo_sync_cmd_query(conn->conn, mongo_conn_ns(conn, TELEGRAM_SUBSCRIPTIONS_TABLE_NAME), 0, 0, 1, query, NULL); - if (!pkt && errno == ENOENT) { - goto cleanup; - } - if (!pkt) { - err("mongo query failed: %s", os_ErrorMsg()); - goto cleanup; - } - bson_free(query); query = NULL; - - cursor = mongo_sync_cursor_new(conn->conn, conn->ns, pkt); - if (!cursor) { - err("mongo query failed: cannot create cursor: %s", os_ErrorMsg()); - goto cleanup; - } - pkt = NULL; - if (mongo_sync_cursor_next(cursor)) { - result = mongo_sync_cursor_get_data(cursor); - if (result) { - retval = telegram_subscription_parse_bson(result); - } - } - -cleanup: - if (result) bson_free(result); - if (cursor) mongo_sync_cursor_free(cursor); - if (pkt) mongo_wire_packet_free(pkt); - if (query) bson_free(query); - return retval; -#else - return NULL; -#endif -} - -int -telegram_subscription_save(struct mongo_conn *conn, const struct telegram_subscription *sub) -{ -#if HAVE_LIBMONGOC - 0 > 0 - if (!conn->b.vt->open(&conn->b)) return -1; - - int retval = -1; - mongoc_collection_t *coll = NULL; - bson_t *query = NULL; - bson_t *bson = NULL; - bson_error_t error; - - if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_SUBSCRIPTIONS_TABLE_NAME))) { - err("get_collection failed\n"); - goto cleanup; - } - - query = bson_new(); - bson_append_utf8(query, "_id", -1, sub->_id, strlen(sub->_id)); - bson = telegram_subscription_unparse_bson(sub); - - if (!mongoc_collection_update(coll, MONGOC_UPDATE_UPSERT, query, bson, NULL, &error)) { - err("telegram_chat_save: failed: %s", error.message); - goto cleanup; - } - - retval = 0; - -cleanup: - if (coll) mongoc_collection_destroy(coll); - if (query) bson_destroy(query); - if (bson) bson_destroy(bson); - return retval; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - if (!mongo_conn_open(conn)) return -1; - int retval = -1; - - bson *b = telegram_subscription_unparse_bson(sub); - bson *q = bson_new(); - bson_append_string(q, "_id", sub->_id, strlen(sub->_id)); - bson_finish(q); - - if (!mongo_sync_cmd_update(conn->conn, mongo_conn_ns(conn, TELEGRAM_SUBSCRIPTIONS_TABLE_NAME), MONGO_WIRE_FLAG_UPDATE_UPSERT, q, b)) { - err("save_token: failed: %s", os_ErrorMsg()); - goto cleanup; - } - - retval = 0; - -cleanup: - bson_free(q); - bson_free(b); - return retval; -#else - return 0; -#endif -} diff --git a/plugins/telegram/telegram_subscription.h b/plugins/telegram/telegram_subscription.h index 9318cb59fa..fd33b618a5 100644 --- a/plugins/telegram/telegram_subscription.h +++ b/plugins/telegram/telegram_subscription.h @@ -16,8 +16,6 @@ * GNU General Public License for more details. */ -#include "ejudge/config.h" - #include /* subscriptions */ diff --git a/plugins/telegram/telegram_token.c b/plugins/telegram/telegram_token.c index 8181441374..17ca475a8e 100644 --- a/plugins/telegram/telegram_token.c +++ b/plugins/telegram/telegram_token.c @@ -14,38 +14,9 @@ * GNU General Public License for more details. */ -#include "ejudge/bson_utils.h" #include "ejudge/xalloc.h" -#include "ejudge/osdeps.h" -#include "ejudge/errlog.h" #include "telegram_token.h" -#include "mongo_conn.h" - -#if HAVE_LIBMONGOC - 0 > 0 -struct _bson_t; -typedef struct _bson_t ej_bson_t; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 -struct _bson; -typedef struct _bson ej_bson_t; -#endif - -#if HAVE_LIBMONGOC - 0 > 1 -#include -#elif HAVE_LIBMONGOC - 0 > 0 -#include -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 -#include -#endif - -#include - -#define TELEGRAM_TOKENS_TABLE_NAME "telegram_tokens" - -static ej_bson_t * -telegram_token_unparse_bson(const struct telegram_token *token); -static struct telegram_token * -telegram_token_parse_bson(const ej_bson_t *bson); struct telegram_token * telegram_token_free(struct telegram_token *token) @@ -61,85 +32,6 @@ telegram_token_free(struct telegram_token *token) return NULL; } -static struct telegram_token * -telegram_token_parse_bson(const ej_bson_t *bson) -{ -#if HAVE_LIBMONGOC - 0 > 0 - bson_iter_t iter, * const bc = &iter; - struct telegram_token *token = NULL; - - if (!bson_iter_init(&iter, bson)) goto cleanup; - - XCALLOC(token, 1); - while (bson_iter_next(&iter)) { - const unsigned char *key = bson_iter_key(bc); - if (!strcmp(key, "_id")) { - if (ej_bson_parse_oid_new(bc, "_id", token->_id) < 0) goto cleanup; - } else if (!strcmp(key, "bot_id")) { - if (ej_bson_parse_string_new(bc, "bot_id", &token->bot_id) < 0) goto cleanup; - } else if (!strcmp(key, "user_id")) { - if (ej_bson_parse_int_new(bc, "user_id", &token->user_id, 1, 1, 0, 0) < 0) goto cleanup; - } else if (!strcmp(key, "user_login")) { - if (ej_bson_parse_string_new(bc, "user_login", &token->user_login) < 0) goto cleanup; - } else if (!strcmp(key, "user_name")) { - if (ej_bson_parse_string_new(bc, "user_name", &token->user_name) < 0) goto cleanup; - } else if (!strcmp(key, "token")) { - if (ej_bson_parse_string_new(bc, "token", &token->token) < 0) goto cleanup; - } else if (!strcmp(key, "contest_id")) { - if (ej_bson_parse_int_new(bc, "contest_id", &token->contest_id, 1, 0, 0, 0) < 0) goto cleanup; - } else if (!strcmp(key, "contest_name")) { - if (ej_bson_parse_string_new(bc, "contest_name", &token->contest_name) < 0) goto cleanup; - } else if (!strcmp(key, "locale_id")) { - if (ej_bson_parse_int_new(bc, "locale_id", &token->locale_id, 1, 0, 0, 0) < 0) goto cleanup; - } else if (!strcmp(key, "expiry_time")) { - if (ej_bson_parse_utc_datetime_new(bc, "expiry_time", &token->expiry_time) < 0) goto cleanup; - } - } - return token; -cleanup: - telegram_token_free(token); - return NULL; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - struct telegram_token *token = NULL; - bson_cursor *bc = NULL; - - XCALLOC(token, 1); - bc = bson_cursor_new(bson); - while (bson_cursor_next(bc)) { - const unsigned char *key = bson_cursor_key(bc); - if (!strcmp(key, "_id")) { - if (ej_bson_parse_oid(bc, "_id", token->_id) < 0) goto cleanup; - } else if (!strcmp(key, "bot_id")) { - if (ej_bson_parse_string(bc, "bot_id", &token->bot_id) < 0) goto cleanup; - } else if (!strcmp(key, "user_id")) { - if (ej_bson_parse_int(bc, "user_id", &token->user_id, 1, 1, 0, 0) < 0) goto cleanup; - } else if (!strcmp(key, "user_login")) { - if (ej_bson_parse_string(bc, "user_login", &token->user_login) < 0) goto cleanup; - } else if (!strcmp(key, "user_name")) { - if (ej_bson_parse_string(bc, "user_name", &token->user_name) < 0) goto cleanup; - } else if (!strcmp(key, "token")) { - if (ej_bson_parse_string(bc, "token", &token->token) < 0) goto cleanup; - } else if (!strcmp(key, "contest_id")) { - if (ej_bson_parse_int(bc, "contest_id", &token->contest_id, 1, 0, 0, 0) < 0) goto cleanup; - } else if (!strcmp(key, "contest_name")) { - if (ej_bson_parse_string(bc, "contest_name", &token->contest_name) < 0) goto cleanup; - } else if (!strcmp(key, "locale_id")) { - if (ej_bson_parse_int(bc, "locale_id", &token->locale_id, 1, 0, 0, 0) < 0) goto cleanup; - } else if (!strcmp(key, "expiry_time")) { - if (ej_bson_parse_utc_datetime(bc, "expiry_time", &token->expiry_time) < 0) goto cleanup; - } - } - bson_cursor_free(bc); - return token; - -cleanup: - telegram_token_free(token); - return NULL; -#else - return 0; -#endif -} - struct telegram_token * telegram_token_create(void) { @@ -147,358 +39,3 @@ telegram_token_create(void) XCALLOC(token, 1); return token; } - -static ej_bson_t * -telegram_token_unparse_bson(const struct telegram_token *token) -{ -#if HAVE_LIBMONGOC - 0 > 0 - if (!token) return NULL; - - bson_t *bson = bson_new(); - int empty_id = 1; - for (int i = 0; i < 12; ++i) { - if (token->_id[i]) { - empty_id = 0; - break; - } - } - - if (!empty_id) { - bson_append_oid(bson, "_id", -1, (bson_oid_t *) &token->_id); - } - if (token->bot_id && *token->bot_id) { - bson_append_utf8(bson, "bot_id", -1, token->bot_id, strlen(token->bot_id)); - } - if (token->user_id > 0) { - bson_append_int32(bson, "user_id", -1, token->user_id); - } - if (token->user_login && *token->user_login) { - bson_append_utf8(bson, "user_login", -1, token->user_login, strlen(token->user_login)); - } - if (token->user_name && *token->user_name) { - bson_append_utf8(bson, "user_name", -1, token->user_name, strlen(token->user_name)); - } - if (token->token && *token->token) { - bson_append_utf8(bson, "token", -1, token->token, strlen(token->token)); - } - if (token->contest_id > 0) { - bson_append_int32(bson, "contest_id", -1, token->contest_id); - } - if (token->contest_name && *token->contest_name) { - bson_append_utf8(bson, "contest_name", -1, token->contest_name, strlen(token->contest_name)); - } - if (token->locale_id > 0) { - bson_append_int32(bson, "locale_id", -1, token->locale_id); - } - if (token->expiry_time > 0) { - bson_append_date_time(bson, "expiry_time", -1, 1000LL * token->expiry_time); - } - return bson; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - if (!token) return NULL; - - bson *b = bson_new(); - int empty_id = 1; - for (int i = 0; i < 12; ++i) { - if (token->_id[i]) { - empty_id = 0; - break; - } - } - if (!empty_id) { - bson_append_oid(b, "_id", token->_id); - } - if (token->bot_id && *token->bot_id) { - bson_append_string(b, "bot_id", token->bot_id, strlen(token->bot_id)); - } - if (token->user_id > 0) { - bson_append_int32(b, "user_id", token->user_id); - } - if (token->user_login && *token->user_login) { - bson_append_string(b, "user_login", token->user_login, strlen(token->user_login)); - } - if (token->user_name && *token->user_name) { - bson_append_string(b, "user_name", token->user_name, strlen(token->user_name)); - } - if (token->token && *token->token) { - bson_append_string(b, "token", token->token, strlen(token->token)); - } - if (token->contest_id > 0) { - bson_append_int32(b, "contest_id", token->contest_id); - } - if (token->contest_name && *token->contest_name) { - bson_append_string(b, "contest_name", token->contest_name, strlen(token->contest_name)); - } - if (token->locale_id > 0) { - bson_append_int32(b, "locale_id", token->locale_id); - } - if (token->expiry_time > 0) { - bson_append_utc_datetime(b, "expiry_time", 1000LL * token->expiry_time); - } - bson_finish(b); - return b; -#else - return NULL; -#endif -} - -void -telegram_token_remove_expired(struct mongo_conn *conn, time_t current_time) -{ -#if HAVE_LIBMONGOC - 0 > 0 - if (current_time <= 0) current_time = time(NULL); - - if (!conn->b.vt->open(&conn->b)) return; - - mongoc_collection_t *coll = NULL; - bson_t *qq = NULL; - bson_t *q = NULL; - bson_error_t error; - - if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_TOKENS_TABLE_NAME))) { - err("get_collection failed\n"); - goto cleanup; - } - - qq = bson_new(); - bson_append_date_time(qq, "$lt", -1, 1000LL * current_time); - q = bson_new(); - bson_append_document(q, "expiry_time", -1, qq); - bson_destroy(qq); qq = NULL; - - if (!mongoc_collection_delete_many(coll, q, NULL, NULL, &error)) { - err("telegram_token_remove_expired: failed: %s", error.message); - goto cleanup; - } - -cleanup: - if (q) bson_destroy(q); - if (qq) bson_destroy(qq); - if (coll) mongoc_collection_destroy(coll); - return; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - if (current_time <= 0) current_time = time(NULL); - - if (!mongo_conn_open(conn)) return; - - bson *qq = bson_new(); - bson_append_utc_datetime(qq, "$lt", 1000LL * current_time); - bson_finish(qq); - bson *q = bson_new(); - bson_append_document(q, "expiry_time", qq); qq = NULL; - bson_finish(q); - - mongo_sync_cmd_delete(conn->conn, mongo_conn_ns(conn, TELEGRAM_TOKENS_TABLE_NAME), 0, q); - - bson_free(q); -#endif -} - -void -telegram_token_remove(struct mongo_conn *conn, const unsigned char *token) -{ -#if HAVE_LIBMONGOC - 0 > 0 - if (!conn->b.vt->open(&conn->b)) return; - - mongoc_collection_t *coll = NULL; - bson_t *query = NULL; - bson_error_t error; - - if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_TOKENS_TABLE_NAME))) { - err("get_collection failed\n"); - goto cleanup; - } - - query = bson_new(); - bson_append_utf8(query, "token", -1, token, strlen(token)); - - if (!mongoc_collection_delete_one(coll, query, NULL, NULL, &error)) { - err("telegram_token_remove_expired: failed: %s", error.message); - goto cleanup; - } - -cleanup: - if (query) bson_destroy(query); - if (coll) mongoc_collection_destroy(coll); -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - if (!mongo_conn_open(conn)) return; - - bson *q = bson_new(); - bson_append_string(q, "token", token, strlen(token)); - bson_finish(q); - - mongo_sync_cmd_delete(conn->conn, mongo_conn_ns(conn, TELEGRAM_TOKENS_TABLE_NAME), 0, q); - - bson_free(q); -#endif -} - -int -telegram_token_fetch(struct mongo_conn *conn, const unsigned char *token_str, struct telegram_token **p_token) -{ -#if HAVE_LIBMONGOC - 0 > 0 - if (!conn->b.vt->open(&conn->b)) return -1; - - int retval = -1; - mongoc_collection_t *coll = NULL; - bson_t *query = NULL; - mongoc_cursor_t *cursor = NULL; - const bson_t *doc = NULL; - - if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_TOKENS_TABLE_NAME))) { - err("get_collection failed\n"); - goto cleanup; - } - - query = bson_new(); - bson_append_utf8(query, "token", -1, token_str, strlen(token_str)); - - cursor = mongoc_collection_find_with_opts(coll, query, NULL, NULL); - if (!cursor) goto cleanup; - - if (mongoc_cursor_next(cursor, &doc)) { - *p_token = telegram_token_parse_bson(doc); - retval = 1; - } else { - retval = 0; - } - -cleanup: - if (cursor) mongoc_cursor_destroy(cursor); - if (query) bson_destroy(query); - if (coll) mongoc_collection_destroy(coll); - return retval; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - int retval = -1; - - if (!mongo_conn_open(conn)) return -1; - - bson *query = NULL; - mongo_packet *pkt = NULL; - mongo_sync_cursor *cursor = NULL; - bson *result = NULL; - - query = bson_new(); - bson_append_string(query, "token", token_str, strlen(token_str)); - bson_finish(query); - - pkt = mongo_sync_cmd_query(conn->conn, mongo_conn_ns(conn, TELEGRAM_TOKENS_TABLE_NAME), 0, 0, 1, query, NULL); - if (!pkt && errno == ENOENT) { - retval = 0; - goto cleanup; - } - if (!pkt) { - err("mongo query failed: %s", os_ErrorMsg()); - goto cleanup; - } - bson_free(query); query = NULL; - - cursor = mongo_sync_cursor_new(conn->conn, conn->ns, pkt); - if (!cursor) { - err("mongo query failed: cannot create cursor: %s", os_ErrorMsg()); - goto cleanup; - } - pkt = NULL; - if (mongo_sync_cursor_next(cursor)) { - result = mongo_sync_cursor_get_data(cursor); - if (result) { - struct telegram_token *t = telegram_token_parse_bson(result); - if (t) { - *p_token = t; - retval = 1; - } - } else { - retval = 0; - } - } else { - retval = 0; - } - -cleanup: - if (result) bson_free(result); - if (cursor) mongo_sync_cursor_free(cursor); - if (pkt) mongo_wire_packet_free(pkt); - if (query) bson_free(query); - return retval; -#else - return 0; -#endif -} - -int -telegram_token_save(struct mongo_conn *conn, const struct telegram_token *token) -{ -#if HAVE_LIBMONGOC - 0 > 0 - if (!conn->b.vt->open(&conn->b)) return -1; - - int retval = -1; - mongoc_database_t *db = NULL; - mongoc_collection_t *coll = NULL; - bson_t *bson = NULL; - bson_error_t error; - bson_t *ind = NULL; - char *ind_name = NULL; - bson_t *create_bson = NULL; - - if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_TOKENS_TABLE_NAME))) { - err("get_collection failed\n"); - goto cleanup; - } - - bson = telegram_token_unparse_bson(token); - - if (!mongoc_collection_insert_one(coll, bson, NULL, NULL, &error)) { - err("telegram_token_save: failed: %s", error.message); - goto cleanup; - } - retval = 0; - - if (!conn->token_index_created) { - conn->token_index_created = 1; - - ind = bson_new(); - bson_append_int32(ind, "token", -1, 1); - ind_name = mongoc_collection_keys_to_index_string(ind); - create_bson = BCON_NEW("createIndexes", BCON_UTF8(TELEGRAM_TOKENS_TABLE_NAME), - "indexes", "[", "{", "key", BCON_DOCUMENT(ind), - "name", BCON_UTF8(ind_name), "}", "]"); - - if ((db = mongoc_client_get_database(conn->client, conn->b.database))) { - mongoc_database_write_command_with_opts(db, create_bson, NULL, NULL, NULL); - } - } - -cleanup: - if (create_bson) bson_destroy(create_bson); - if (ind_name) bson_free(ind_name); - if (ind) bson_destroy(ind); - if (bson) bson_destroy(bson); - if (coll) mongoc_collection_destroy(coll); - if (db) mongoc_database_destroy(db); - return retval; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - if (!mongo_conn_open(conn)) return -1; - int retval = -1; - - bson *b = telegram_token_unparse_bson(token); - bson *ind = NULL; - - if (!mongo_sync_cmd_insert(conn->conn, mongo_conn_ns(conn, TELEGRAM_TOKENS_TABLE_NAME), b, NULL)) { - err("save_token: failed: %s", os_ErrorMsg()); - goto cleanup; - } - - ind = bson_new(); - bson_append_int32(ind, "token", 1); - bson_finish(ind); - mongo_sync_cmd_index_create(conn->conn, conn->ns, ind, 0); - - retval = 0; -cleanup: - if (ind) bson_free(ind); - bson_free(b); - return retval; -#else - return 0; -#endif -} diff --git a/plugins/telegram/telegram_token.h b/plugins/telegram/telegram_token.h index 47b09c7a0a..8968141837 100644 --- a/plugins/telegram/telegram_token.h +++ b/plugins/telegram/telegram_token.h @@ -16,8 +16,6 @@ * GNU General Public License for more details. */ -#include "ejudge/config.h" - #include /* tokens for bot interaction */ diff --git a/plugins/telegram/telegram_user.c b/plugins/telegram/telegram_user.c index 7dde5328e6..f5959b7095 100644 --- a/plugins/telegram/telegram_user.c +++ b/plugins/telegram/telegram_user.c @@ -16,40 +16,10 @@ #include "telegram_user.h" -#include "ejudge/bson_utils.h" - #include "ejudge/xalloc.h" -#include "ejudge/errlog.h" -#include "ejudge/osdeps.h" - -#include "mongo_conn.h" - -#if HAVE_LIBMONGOC - 0 > 1 -#include -#elif HAVE_LIBMONGOC - 0 > 0 -#include -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 -#include -#endif -#include #include -#if HAVE_LIBMONGOC - 0 > 0 -struct _bson_t; -typedef struct _bson_t ej_bson_t; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 -struct _bson; -typedef struct _bson ej_bson_t; -#endif - -#define TELEGRAM_USERS_TABLE_NAME "telegram_users" - -static struct telegram_user * -telegram_user_parse_bson(const ej_bson_t *bson); -static ej_bson_t * -telegram_user_unparse_bson(const struct telegram_user *tu); - struct telegram_user * telegram_user_free(struct telegram_user *tu) { @@ -70,242 +40,3 @@ telegram_user_create(void) XCALLOC(tu, 1); return tu; } - -static struct telegram_user * -telegram_user_parse_bson(const ej_bson_t *bson) -{ -#if HAVE_LIBMONGOC - 0 > 0 - bson_iter_t iter, * const bc = &iter; - struct telegram_user *tu = NULL; - - if (!bson_iter_init(&iter, bson)) goto cleanup; - - XCALLOC(tu, 1); - while (bson_iter_next(&iter)) { - const unsigned char *key = bson_iter_key(bc); - if (!strcmp(key, "_id")) { - if (ej_bson_parse_int64_new(bc, "_id", &tu->_id) < 0) goto cleanup; - } else if (!strcmp(key, "username")) { - if (ej_bson_parse_string_new(bc, "username", &tu->username) < 0) goto cleanup; - } else if (!strcmp(key, "first_name")) { - if (ej_bson_parse_string_new(bc, "first_name", &tu->first_name) < 0) goto cleanup; - } else if (!strcmp(key, "last_name")) { - if (ej_bson_parse_string_new(bc, "last_name", &tu->last_name) < 0) goto cleanup; - } - } - - return tu; - -cleanup: - telegram_user_free(tu); - return NULL; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - bson_cursor *bc = NULL; - struct telegram_user *tu = NULL; - - XCALLOC(tu, 1); - bc = bson_cursor_new(bson); - while (bson_cursor_next(bc)) { - const unsigned char *key = bson_cursor_key(bc); - if (!strcmp(key, "_id")) { - if (ej_bson_parse_int64(bc, "_id", &tu->_id) < 0) goto cleanup; - } else if (!strcmp(key, "username")) { - if (ej_bson_parse_string(bc, "username", &tu->username) < 0) goto cleanup; - } else if (!strcmp(key, "first_name")) { - if (ej_bson_parse_string(bc, "first_name", &tu->first_name) < 0) goto cleanup; - } else if (!strcmp(key, "last_name")) { - if (ej_bson_parse_string(bc, "last_name", &tu->last_name) < 0) goto cleanup; - } - } - bson_cursor_free(bc); - return tu; - -cleanup: - telegram_user_free(tu); - return NULL; -#else - return NULL; -#endif -} - -static ej_bson_t * -telegram_user_unparse_bson(const struct telegram_user *tu) -{ -#if HAVE_LIBMONGOC - 0 > 0 - if (!tu) return NULL; - - bson_t *bson = bson_new(); - - if (tu->_id) { - bson_append_int64(bson, "_id", -1, tu->_id); - } - if (tu->username && *tu->username) { - bson_append_utf8(bson, "username", -1, tu->username, strlen(tu->username)); - } - if (tu->first_name && *tu->first_name) { - bson_append_utf8(bson, "first_name", -1, tu->first_name, strlen(tu->first_name)); - } - if (tu->last_name && *tu->last_name) { - bson_append_utf8(bson, "last_name", -1, tu->last_name, strlen(tu->last_name)); - } - - return bson; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - if (!tu) return NULL; - - bson *bson = bson_new(); - if (tu->_id) { - bson_append_int64(bson, "_id", tu->_id); - } - if (tu->username && *tu->username) { - bson_append_string(bson, "username", tu->username, strlen(tu->username)); - } - if (tu->first_name && *tu->first_name) { - bson_append_string(bson, "first_name", tu->first_name, strlen(tu->first_name)); - } - if (tu->last_name && *tu->last_name) { - bson_append_string(bson, "last_name", tu->last_name, strlen(tu->last_name)); - } - bson_finish(bson); - return bson; -#else - return NULL; -#endif -} - -struct telegram_user * -telegram_user_fetch(struct mongo_conn *conn, long long _id) -{ -#if HAVE_LIBMONGOC - 0 > 0 - if (!conn->b.vt->open(&conn->b)) return NULL; - - struct telegram_user *retval = NULL; - mongoc_collection_t *coll = NULL; - bson_t *query = NULL; - mongoc_cursor_t *cursor = NULL; - const bson_t *doc = NULL; - - if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_USERS_TABLE_NAME))) { - err("get_collection failed\n"); - goto cleanup; - } - - query = bson_new(); - bson_append_int64(query, "_id", -1, _id); - - cursor = mongoc_collection_find_with_opts(coll, query, NULL, NULL); - if (!cursor) goto cleanup; - - if (mongoc_cursor_next(cursor, &doc)) { - retval = telegram_user_parse_bson(doc); - } - -cleanup: - if (cursor) mongoc_cursor_destroy(cursor); - if (query) bson_destroy(query); - if (coll) mongoc_collection_destroy(coll); - return retval; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - if (!mongo_conn_open(conn)) return NULL; - - bson *query = NULL; - mongo_packet *pkt = NULL; - mongo_sync_cursor *cursor = NULL; - bson *result = NULL; - struct telegram_user *retval = NULL; - - query = bson_new(); - bson_append_int64(query, "_id", _id); - bson_finish(query); - - pkt = mongo_sync_cmd_query(conn->conn, mongo_conn_ns(conn, TELEGRAM_USERS_TABLE_NAME), 0, 0, 1, query, NULL); - if (!pkt && errno == ENOENT) { - goto cleanup; - } - if (!pkt) { - err("mongo query failed: %s", os_ErrorMsg()); - goto cleanup; - } - bson_free(query); query = NULL; - - cursor = mongo_sync_cursor_new(conn->conn, conn->ns, pkt); - if (!cursor) { - err("mongo query failed: cannot create cursor: %s", os_ErrorMsg()); - goto cleanup; - } - pkt = NULL; - if (mongo_sync_cursor_next(cursor)) { - result = mongo_sync_cursor_get_data(cursor); - if (result) { - retval = telegram_user_parse_bson(result); - } - } - -cleanup: - if (result) bson_free(result); - if (cursor) mongo_sync_cursor_free(cursor); - if (pkt) mongo_wire_packet_free(pkt); - if (query) bson_free(query); - return retval; -#else - return NULL; -#endif -} - -int -telegram_user_save(struct mongo_conn *conn, const struct telegram_user *tu) -{ -#if HAVE_LIBMONGOC - 0 > 0 - if (!conn->b.vt->open(&conn->b)) return -1; - - int retval = -1; - mongoc_collection_t *coll = NULL; - bson_t *query = NULL; - bson_t *bson = NULL; - bson_error_t error; - - if (!(coll = mongoc_client_get_collection(conn->client, conn->b.database, TELEGRAM_USERS_TABLE_NAME))) { - err("get_collection failed\n"); - goto cleanup; - } - - bson = telegram_user_unparse_bson(tu); - query = bson_new(); - bson_append_int64(query, "_id", -1, tu->_id); - - if (!mongoc_collection_update(coll, MONGOC_UPDATE_UPSERT, query, bson, NULL, &error)) { - err("telegram_chat_save: failed: %s", error.message); - goto cleanup; - } - - retval = 0; - -cleanup: - if (query) bson_destroy(query); - if (bson) bson_destroy(bson); - if (coll) mongoc_collection_destroy(coll); - return retval; -#elif HAVE_LIBMONGO_CLIENT - 0 == 1 - if (!mongo_conn_open(conn)) return -1; - int retval = -1; - - bson *b = telegram_user_unparse_bson(tu); - bson *q = bson_new(); - bson_append_int64(q, "_id", tu->_id); - bson_finish(q); - - if (!mongo_sync_cmd_update(conn->conn, mongo_conn_ns(conn, TELEGRAM_USERS_TABLE_NAME), MONGO_WIRE_FLAG_UPDATE_UPSERT, q, b)) { - err("save_token: failed: %s", os_ErrorMsg()); - goto cleanup; - } - - retval = 0; - -cleanup: - bson_free(b); - bson_free(q); - return retval; -#else - return 0; -#endif -} diff --git a/plugins/telegram/telegram_user.h b/plugins/telegram/telegram_user.h index 899b66f2c5..dc72327701 100644 --- a/plugins/telegram/telegram_user.h +++ b/plugins/telegram/telegram_user.h @@ -16,8 +16,6 @@ * GNU General Public License for more details. */ -#include "ejudge/config.h" - struct telegram_user { long long _id;