diff options
author | MarcoPolo-PasTonMolo <marcopolopastonmolo@protonmail.com> | 2022-07-03 21:23:07 +0300 |
---|---|---|
committer | MarcoPolo-PasTonMolo <marcopolopastonmolo@protonmail.com> | 2022-07-03 21:23:07 +0300 |
commit | f0202a2fe0da0a1aa05009b875dffe47bfa3df8d (patch) | |
tree | a62f0792df34fae5796fe55743485ac79bd3f825 /src | |
parent | 476c73251c2787930f866c76484eb1417a834cea (diff) | |
download | profani-tty-f0202a2fe0da0a1aa05009b875dffe47bfa3df8d.tar.gz |
On new chatwin fetch mam according to guidelines.
Taken from here: https://github.com/modernxmpp/modernxmpp/commit/cd3e871e55c2cff45dffd05d6e50380b99845849
Diffstat (limited to 'src')
-rw-r--r-- | src/database.c | 45 | ||||
-rw-r--r-- | src/database.h | 1 | ||||
-rw-r--r-- | src/xmpp/iq.c | 61 | ||||
-rw-r--r-- | src/xmpp/stanza.c | 89 | ||||
-rw-r--r-- | src/xmpp/stanza.h | 4 |
5 files changed, 161 insertions, 39 deletions
diff --git a/src/database.c b/src/database.c index 6e10b222..6f719aa2 100644 --- a/src/database.c +++ b/src/database.c @@ -187,6 +187,51 @@ log_database_add_outgoing_muc_pm(const char* const id, const char* const barejid _log_database_add_outgoing("mucpm", id, barejid, message, replace_id, enc); } +// Get info (timestamp and stanza_id) of the first or last message in db +ProfMessage* +log_database_get_limits_info(const gchar* const contact_barejid, gboolean is_last) +{ + sqlite3_stmt* stmt = NULL; + gchar* query; + const char* jid = connection_get_fulljid(); + Jid* myjid = jid_create(jid); + if (!myjid) + return NULL; + + if (is_last) { + query = sqlite3_mprintf("SELECT * FROM (SELECT `archive_id`, `timestamp` from `ChatLogs` WHERE (`from_jid` = '%q' AND `to_jid` = '%q') OR (`from_jid` = '%q' AND `to_jid` = '%q') ORDER BY `timestamp` DESC LIMIT 1) ORDER BY `timestamp` ASC;", contact_barejid, myjid->barejid, myjid->barejid, contact_barejid); + } else { + query = sqlite3_mprintf("SELECT * FROM (SELECT `archive_id`, `timestamp` from `ChatLogs` WHERE (`from_jid` = '%q' AND `to_jid` = '%q') OR (`from_jid` = '%q' AND `to_jid` = '%q') ORDER BY `timestamp` ASC LIMIT 1) ORDER BY `timestamp` ASC;", contact_barejid, myjid->barejid, myjid->barejid, contact_barejid); + } + + if (!query) { + log_error("log_database_get_last_info(): SQL query. could not allocate memory"); + return NULL; + } + + jid_destroy(myjid); + + int rc = sqlite3_prepare_v2(g_chatlog_database, query, -1, &stmt, NULL); + if (rc != SQLITE_OK) { + log_error("log_database_get_last_info(): unknown SQLite error"); + return NULL; + } + + ProfMessage* msg = message_init(); + + if (sqlite3_step(stmt) == SQLITE_ROW) { + char* archive_id = (char*)sqlite3_column_text(stmt, 0); + char* date = (char*)sqlite3_column_text(stmt, 1); + + msg->stanzaid = strdup(archive_id); + msg->timestamp = g_date_time_new_from_iso8601(date, NULL); + } + sqlite3_finalize(stmt); + sqlite3_free(query); + + return msg; +} + GSList* log_database_get_previous_chat(const gchar* const contact_barejid) { diff --git a/src/database.h b/src/database.h index a29b0808..21f04595 100644 --- a/src/database.h +++ b/src/database.h @@ -46,6 +46,7 @@ void log_database_add_outgoing_chat(const char* const id, const char* const bare void log_database_add_outgoing_muc(const char* const id, const char* const barejid, const char* const message, const char* const replace_id, prof_enc_t enc); void log_database_add_outgoing_muc_pm(const char* const id, const char* const barejid, const char* const message, const char* const replace_id, prof_enc_t enc); GSList* log_database_get_previous_chat(const gchar* const contact_barejid); +ProfMessage* log_database_get_limits_info(const gchar* const contact_barejid, gboolean is_last); void log_database_close(void); #endif // DATABASE_H diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 8d40a86f..9918354e 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -2582,24 +2582,43 @@ iq_mam_request(ProfChatWin* win) return; } + ProfMessage* last_msg = log_database_get_limits_info(win->barejid, TRUE); + char* lastid = NULL; + char* firstid = NULL; + char* startdate = NULL; + char* enddate = NULL; + gboolean should_add_rsm_handler = TRUE; + + // If last message found + if (last_msg->timestamp) { + lastid = last_msg->stanzaid; + startdate = g_date_time_format(last_msg->timestamp, "%FT%T.%f%:z"); + + } else { + GDateTime* now = g_date_time_new_now_utc(); + enddate = g_date_time_format(now, "%FT%T.%f%:z"); + g_date_time_unref(now); + // To get last page we need to set before to empty string + firstid = ""; + should_add_rsm_handler = FALSE; + } + xmpp_ctx_t* const ctx = connection_get_ctx(); - GDateTime* now = g_date_time_new_now_utc(); - GDateTime* timestamp = g_date_time_add_days(now, -7); - g_date_time_unref(now); - gchar* datestr = g_date_time_format(timestamp, "%FT%TZ"); - xmpp_stanza_t* iq = stanza_create_mam_iq(ctx, win->barejid, datestr, NULL); + xmpp_stanza_t* iq = stanza_create_mam_iq(ctx, win->barejid, startdate, enddate, firstid, lastid); - MamRsmUserdata* data = malloc(sizeof(MamRsmUserdata)); - if (data) { - data->datestr = strdup(datestr); - data->barejid = strdup(win->barejid); + if (should_add_rsm_handler) { + MamRsmUserdata* data = malloc(sizeof(MamRsmUserdata)); + if (data) { + data->start_datestr = startdate; + data->end_datestr = enddate; + data->barejid = strdup(win->barejid); - iq_id_handler_add(xmpp_stanza_get_id(iq), _mam_rsm_id_handler, NULL, data); + iq_id_handler_add(xmpp_stanza_get_id(iq), _mam_rsm_id_handler, NULL, data); + } } - g_free(datestr); - g_date_time_unref(timestamp); + message_free(last_msg); iq_send_stanza(iq); xmpp_stanza_release(iq); @@ -2619,24 +2638,28 @@ _mam_rsm_id_handler(xmpp_stanza_t* const stanza, void* const userdata) } else if (g_strcmp0(type, "result") == 0) { xmpp_stanza_t* fin = xmpp_stanza_get_child_by_name_and_ns(stanza, STANZA_NAME_FIN, STANZA_NS_MAM2); if (fin) { + gboolean is_complete = g_strcmp0(xmpp_stanza_get_attribute(fin, "complete"), "true") == 0; + + if (is_complete) { + return 0; + } + xmpp_stanza_t* set = xmpp_stanza_get_child_by_name_and_ns(fin, STANZA_TYPE_SET, STANZA_NS_RSM); if (set) { char* lastid = NULL; xmpp_stanza_t* last = xmpp_stanza_get_child_by_name(set, STANZA_NAME_LAST); - if (last) { - lastid = xmpp_stanza_get_text(last); - } + lastid = xmpp_stanza_get_text(last); // 4.3.2. send same stanza with set,max stanza xmpp_ctx_t* const ctx = connection_get_ctx(); MamRsmUserdata* data = (MamRsmUserdata*)userdata; - xmpp_stanza_t* iq = stanza_create_mam_iq(ctx, data->barejid, data->datestr, lastid); - free(data->barejid); - free(data->datestr); - free(data); + + xmpp_stanza_t* iq = stanza_create_mam_iq(ctx, data->barejid, data->start_datestr, data->end_datestr, NULL, lastid); free(lastid); + iq_id_handler_add(xmpp_stanza_get_id(iq), _mam_rsm_id_handler, NULL, data); + iq_send_stanza(iq); xmpp_stanza_release(iq); } diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index 8dcad982..86791d94 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -2701,7 +2701,7 @@ stanza_attach_correction(xmpp_ctx_t* ctx, xmpp_stanza_t* stanza, const char* con } xmpp_stanza_t* -stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, const char* const startdate, const char* const lastid) +stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, const char* const startdate, const char* const enddate, const char* const firstid, const char* const lastid) { char* id = connection_create_stanza_id(); xmpp_stanza_t* iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id); @@ -2747,26 +2747,48 @@ stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, const char* const s xmpp_stanza_add_child(field_with, value_with); // field 'start' - xmpp_stanza_t* field_start = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(field_start, STANZA_NAME_FIELD); - xmpp_stanza_set_attribute(field_start, STANZA_ATTR_VAR, "start"); + xmpp_stanza_t* field_start, *value_start, *start_date_text; + if (startdate) { + field_start = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(field_start, STANZA_NAME_FIELD); + xmpp_stanza_set_attribute(field_start, STANZA_ATTR_VAR, "start"); - xmpp_stanza_t* value_start = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(value_start, STANZA_NAME_VALUE); + value_start = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(value_start, STANZA_NAME_VALUE); - xmpp_stanza_t* date_text = xmpp_stanza_new(ctx); - xmpp_stanza_set_text(date_text, startdate); - xmpp_stanza_add_child(value_start, date_text); + start_date_text = xmpp_stanza_new(ctx); + xmpp_stanza_set_text(start_date_text, startdate); + xmpp_stanza_add_child(value_start, start_date_text); - xmpp_stanza_add_child(field_start, value_start); + xmpp_stanza_add_child(field_start, value_start); + } + + xmpp_stanza_t* field_end, *value_end, *end_date_text; + if (enddate) { + field_end = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(field_end, STANZA_NAME_FIELD); + xmpp_stanza_set_attribute(field_end, STANZA_ATTR_VAR, "end"); + + value_end = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(value_end, STANZA_NAME_VALUE); + + end_date_text = xmpp_stanza_new(ctx); + xmpp_stanza_set_text(end_date_text, enddate); + xmpp_stanza_add_child(value_end, end_date_text); + + xmpp_stanza_add_child(field_end, value_end); + } // 4.3.2 set/rsm - xmpp_stanza_t *after, *after_text, *set; - if (lastid) { + xmpp_stanza_t *set; + if (lastid || firstid) { set = xmpp_stanza_new(ctx); xmpp_stanza_set_name(set, STANZA_TYPE_SET); xmpp_stanza_set_ns(set, STANZA_NS_RSM); + } + xmpp_stanza_t *after, *after_text; + if (lastid) { after = xmpp_stanza_new(ctx); xmpp_stanza_set_name(after, STANZA_NAME_AFTER); @@ -2777,30 +2799,59 @@ stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, const char* const s xmpp_stanza_add_child(set, after); } + xmpp_stanza_t *before, *before_text; + if (firstid) { + before = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(before, STANZA_NAME_BEFORE); + + before_text = xmpp_stanza_new(ctx); + xmpp_stanza_set_text(before_text, firstid); + + xmpp_stanza_add_child(before, before_text); + xmpp_stanza_add_child(set, before); + } + // add and release xmpp_stanza_add_child(iq, query); xmpp_stanza_add_child(query, x); xmpp_stanza_add_child(x, field_form_type); xmpp_stanza_add_child(x, field_with); - xmpp_stanza_add_child(x, field_start); - if (lastid) { - xmpp_stanza_add_child(query, after); + if (startdate) { + xmpp_stanza_add_child(x, field_start); + xmpp_stanza_release(field_start); + xmpp_stanza_release(value_start); + xmpp_stanza_release(start_date_text); + } + + if (enddate) { + xmpp_stanza_add_child(x, field_end); + xmpp_stanza_release(field_end); + xmpp_stanza_release(value_end); + xmpp_stanza_release(end_date_text); + } + + if (firstid || lastid) { + xmpp_stanza_add_child(query, set); + xmpp_stanza_release(set); + } + if (lastid) { xmpp_stanza_release(after_text); xmpp_stanza_release(after); - xmpp_stanza_release(set); + } + + if (firstid) { + xmpp_stanza_release(before_text); + xmpp_stanza_release(before); } xmpp_stanza_release(mam_text); xmpp_stanza_release(with_text); - xmpp_stanza_release(date_text); xmpp_stanza_release(value_mam); xmpp_stanza_release(value_with); - xmpp_stanza_release(value_start); xmpp_stanza_release(field_form_type); xmpp_stanza_release(field_with); - xmpp_stanza_release(field_start); xmpp_stanza_release(x); xmpp_stanza_release(query); diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index 12c9a5ee..71454e9d 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -115,7 +115,9 @@ #define STANZA_NAME_MINIMIZE "minimize" #define STANZA_NAME_FIN "fin" #define STANZA_NAME_LAST "last" +#define STANZA_NAME_FIRST "first" #define STANZA_NAME_AFTER "after" +#define STANZA_NAME_BEFORE "before" #define STANZA_NAME_USERNAME "username" #define STANZA_NAME_PROPOSE "propose" #define STANZA_NAME_REPORT "report" @@ -413,7 +415,7 @@ void stanza_free_caps(XMPPCaps* caps); xmpp_stanza_t* stanza_create_avatar_retrieve_data_request(xmpp_ctx_t* ctx, const char* stanza_id, const char* const item_id, const char* const jid); xmpp_stanza_t* stanza_create_avatar_data_publish_iq(xmpp_ctx_t* ctx, const char* img_data, gsize len); xmpp_stanza_t* stanza_create_avatar_metadata_publish_iq(xmpp_ctx_t* ctx, const char* img_data, gsize len, int height, int width); -xmpp_stanza_t* stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, const char* const startdate, const char* const lastid); +xmpp_stanza_t* stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, const char* const startdate, const char* const enddate, const char* const firstid, const char* const lastid); xmpp_stanza_t* stanza_change_password(xmpp_ctx_t* ctx, const char* const user, const char* const password); xmpp_stanza_t* stanza_register_new_account(xmpp_ctx_t* ctx, const char* const user, const char* const password); xmpp_stanza_t* stanza_request_voice(xmpp_ctx_t* ctx, const char* const room); |