Skip to content

Commit

Permalink
On new chatwin fetch mam according to guidelines.
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcoPolo-PasTonMolo committed Jul 3, 2022
1 parent 476c732 commit f0202a2
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 39 deletions.
45 changes: 45 additions & 0 deletions src/database.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
1 change: 1 addition & 0 deletions src/database.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
61 changes: 42 additions & 19 deletions src/xmpp/iq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
}
Expand Down
89 changes: 70 additions & 19 deletions src/xmpp/stanza.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);

Expand All @@ -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);

Expand Down
4 changes: 3 additions & 1 deletion src/xmpp/stanza.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit f0202a2

Please sign in to comment.