mirror of
https://git.jabber.space/devs/cproof.git
synced 2026-07-20 06:26:21 +00:00
Merge branch 'master' into feat/ai
This commit is contained in:
@@ -278,6 +278,8 @@ static Autocomplete logging_ac;
|
||||
static Autocomplete logging_group_ac;
|
||||
static Autocomplete privacy_ac;
|
||||
static Autocomplete privacy_log_ac;
|
||||
static Autocomplete history_ac;
|
||||
static Autocomplete history_switch_ac;
|
||||
static Autocomplete color_ac;
|
||||
static Autocomplete correction_ac;
|
||||
static Autocomplete avatar_ac;
|
||||
@@ -435,6 +437,8 @@ static Autocomplete* all_acs[] = {
|
||||
&logging_group_ac,
|
||||
&privacy_ac,
|
||||
&privacy_log_ac,
|
||||
&history_ac,
|
||||
&history_switch_ac,
|
||||
&color_ac,
|
||||
&correction_ac,
|
||||
&avatar_ac,
|
||||
@@ -1147,6 +1151,18 @@ cmd_ac_init(void)
|
||||
autocomplete_add(privacy_log_ac, "on");
|
||||
autocomplete_add(privacy_log_ac, "off");
|
||||
autocomplete_add(privacy_log_ac, "redact");
|
||||
autocomplete_add(privacy_log_ac, "flatfile");
|
||||
|
||||
autocomplete_add(history_ac, "on");
|
||||
autocomplete_add(history_ac, "off");
|
||||
autocomplete_add(history_ac, "backend");
|
||||
autocomplete_add(history_ac, "switch");
|
||||
autocomplete_add(history_ac, "verify");
|
||||
autocomplete_add(history_ac, "export");
|
||||
autocomplete_add(history_ac, "import");
|
||||
|
||||
autocomplete_add(history_switch_ac, "sqlite");
|
||||
autocomplete_add(history_switch_ac, "flatfile");
|
||||
|
||||
autocomplete_add(logging_group_ac, "on");
|
||||
autocomplete_add(logging_group_ac, "off");
|
||||
@@ -1799,7 +1815,7 @@ _cmd_ac_complete_params(ProfWin* window, const char* const input, gboolean previ
|
||||
|
||||
// autocomplete boolean settings
|
||||
gchar* boolean_choices[] = { "/beep", "/states", "/outtype", "/flash", "/splash",
|
||||
"/history", "/vercheck", "/privileges", "/wrap",
|
||||
"/vercheck", "/privileges", "/wrap",
|
||||
"/carbons", "/slashguard", "/mam", "/silence" };
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(boolean_choices); i++) {
|
||||
@@ -1809,6 +1825,24 @@ _cmd_ac_complete_params(ProfWin* window, const char* const input, gboolean previ
|
||||
}
|
||||
}
|
||||
|
||||
result = autocomplete_param_with_ac(input, "/history switch", history_switch_ac, TRUE, previous);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
gchar* history_jid_subcmds[] = { "/history verify", "/history export", "/history import" };
|
||||
for (int i = 0; i < ARRAY_SIZE(history_jid_subcmds); i++) {
|
||||
result = autocomplete_param_with_func(input, history_jid_subcmds[i], roster_barejid_autocomplete, previous, NULL);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
result = autocomplete_param_with_ac(input, "/history", history_ac, TRUE, previous);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// autocomplete nickname in chat rooms
|
||||
if (window->type == WIN_MUC) {
|
||||
ProfMucWin* mucwin = (ProfMucWin*)window;
|
||||
|
||||
@@ -1875,18 +1875,33 @@ static const struct cmd_t command_defs[] = {
|
||||
},
|
||||
|
||||
{ CMD_PREAMBLE("/history",
|
||||
parse_args, 1, 1, &cons_history_setting)
|
||||
parse_args, 1, 2, &cons_history_setting)
|
||||
CMD_MAINFUNC(cmd_history)
|
||||
CMD_TAGS(
|
||||
CMD_TAG_UI,
|
||||
CMD_TAG_CHAT)
|
||||
CMD_SYN(
|
||||
"/history on|off")
|
||||
"/history on|off",
|
||||
"/history backend",
|
||||
"/history switch sqlite|flatfile",
|
||||
"/history verify [<jid>]",
|
||||
"/history export [<jid>]",
|
||||
"/history import [<jid>]")
|
||||
CMD_DESC(
|
||||
"Switch chat history on or off, /logging chat will automatically be enabled when this setting is on. "
|
||||
"When history is enabled, previous messages are shown in chat windows.")
|
||||
"When history is enabled, previous messages are shown in chat windows. "
|
||||
"Use 'backend' to show the active database backend. "
|
||||
"Use 'switch' to change the active database backend at runtime without reconnecting. "
|
||||
"Use 'verify' to check integrity of stored message history. "
|
||||
"Use 'export' to copy messages from SQLite to flat-file format, or 'import' to copy from flat-file to SQLite. "
|
||||
"Both export and import merge with existing data (duplicates are skipped).")
|
||||
CMD_ARGS(
|
||||
{ "on|off", "Enable or disable showing chat history." })
|
||||
{ "on|off", "Enable or disable showing chat history." },
|
||||
{ "backend", "Show the name of the active database backend." },
|
||||
{ "switch sqlite|flatfile", "Switch the active database backend at runtime." },
|
||||
{ "verify [<jid>]", "Verify integrity of message history. Optionally specify a JID to check only one contact." },
|
||||
{ "export [<jid>]", "Export SQLite history to flat-file format. Optionally specify a JID to export only one contact." },
|
||||
{ "import [<jid>]", "Import flat-file history into SQLite. Optionally specify a JID to import only one contact." })
|
||||
},
|
||||
|
||||
{ CMD_PREAMBLE("/log",
|
||||
@@ -2718,7 +2733,7 @@ static const struct cmd_t command_defs[] = {
|
||||
CMD_TAG_CHAT,
|
||||
CMD_TAG_DISCOVERY)
|
||||
CMD_SYN(
|
||||
"/privacy logging on|redact|off",
|
||||
"/privacy logging on|redact|off|flatfile",
|
||||
"/privacy os on|off")
|
||||
CMD_DESC(
|
||||
"Configure privacy settings. "
|
||||
@@ -2726,12 +2741,13 @@ static const struct cmd_t command_defs[] = {
|
||||
"clientid to set the client identification name "
|
||||
"session_alarm to configure an alarm when more clients log in.")
|
||||
CMD_ARGS(
|
||||
{ "logging on|redact|off", "Switch chat logging. This will also disable logging in the internally used SQL database. Your messages will not be saved anywhere locally. This might have unintended consequences, such as not being able to decrypt OMEMO encrypted messages received later via MAM, and should be used with caution." },
|
||||
{ "logging on|redact|off|flatfile", "Switch chat logging. 'on' uses SQLite database (default). 'flatfile' stores messages as plain text files in ~/.local/share/profanity/flatlog/ that can be manually edited with any text editor. 'off' disables logging entirely. 'redact' stores messages with content replaced by '[redacted]'. Note: 'off' might have unintended consequences, such as not being able to decrypt OMEMO encrypted messages received later via MAM. The 'flatfile' setting takes effect on next connection." },
|
||||
{ "os on|off", "Choose whether to include the OS name if a user asks for software information (XEP-0092)." }
|
||||
)
|
||||
CMD_EXAMPLES(
|
||||
"/privacy",
|
||||
"/privacy logging off",
|
||||
"/privacy logging flatfile",
|
||||
"/privacy os off")
|
||||
},
|
||||
|
||||
|
||||
@@ -6687,6 +6687,13 @@ cmd_privacy(ProfWin* window, const char* const command, gchar** args)
|
||||
} else if (g_strcmp0(arg, "redact") == 0) {
|
||||
cons_show("Messages are going to be redacted.");
|
||||
prefs_set_string(PREF_DBLOG, arg);
|
||||
} else if (g_strcmp0(arg, "flatfile") == 0) {
|
||||
auto_gchar gchar* ff_path = files_get_data_path(DIR_FLATLOG);
|
||||
cons_show("Using flat-file backend for message logging. Takes effect on next connection.");
|
||||
cons_show("Flatfile directory: %s", ff_path);
|
||||
prefs_set_string(PREF_DBLOG, arg);
|
||||
prefs_set_boolean(PREF_CHLOG, TRUE);
|
||||
prefs_set_boolean(PREF_HISTORY, TRUE);
|
||||
} else {
|
||||
cons_bad_cmd_usage(command);
|
||||
return TRUE;
|
||||
@@ -6723,6 +6730,54 @@ cmd_logging(ProfWin* window, const char* const command, gchar** args)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_show_integrity_issues(GSList* issues)
|
||||
{
|
||||
int errors = 0, warnings = 0, infos = 0;
|
||||
for (GSList* l = issues; l; l = l->next) {
|
||||
integrity_issue_t* issue = l->data;
|
||||
const char* level_str;
|
||||
switch (issue->level) {
|
||||
case INTEGRITY_ERROR:
|
||||
level_str = "ERROR";
|
||||
errors++;
|
||||
break;
|
||||
case INTEGRITY_WARNING:
|
||||
level_str = "WARN";
|
||||
warnings++;
|
||||
break;
|
||||
case INTEGRITY_INFO:
|
||||
level_str = "INFO";
|
||||
infos++;
|
||||
break;
|
||||
default:
|
||||
level_str = "???";
|
||||
break;
|
||||
}
|
||||
if (issue->line > 0) {
|
||||
if (issue->level == INTEGRITY_ERROR) {
|
||||
cons_show_error("[%s] %s:%d — %s", level_str, issue->file, issue->line, issue->message);
|
||||
} else {
|
||||
cons_show("[%s] %s:%d — %s", level_str, issue->file, issue->line, issue->message);
|
||||
}
|
||||
} else {
|
||||
if (issue->level == INTEGRITY_ERROR) {
|
||||
cons_show_error("[%s] %s — %s", level_str, issue->file, issue->message);
|
||||
} else {
|
||||
cons_show("[%s] %s — %s", level_str, issue->file, issue->message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!issues) {
|
||||
cons_show("Verification complete: no issues found.");
|
||||
} else {
|
||||
cons_show("Verification complete: %d error(s), %d warning(s), %d info(s).",
|
||||
errors, warnings, infos);
|
||||
g_slist_free_full(issues, (GDestroyNotify)integrity_issue_free);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
cmd_history(ProfWin* window, const char* const command, gchar** args)
|
||||
{
|
||||
@@ -6731,6 +6786,91 @@ cmd_history(ProfWin* window, const char* const command, gchar** args)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (g_strcmp0(args[0], "backend") == 0) {
|
||||
if (active_db_backend && active_db_backend->name) {
|
||||
cons_show("Active database backend: %s", active_db_backend->name);
|
||||
} else {
|
||||
cons_show("No database backend is currently active.");
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (g_strcmp0(args[0], "switch") == 0) {
|
||||
jabber_conn_status_t conn_status = connection_get_status();
|
||||
if (conn_status != JABBER_CONNECTED) {
|
||||
cons_show_error("You must be connected to switch database backend.");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (args[1] == NULL) {
|
||||
cons_bad_cmd_usage(command);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (g_strcmp0(args[1], "sqlite") != 0 && g_strcmp0(args[1], "flatfile") != 0) {
|
||||
cons_show_error("Backend must be 'sqlite' or 'flatfile'.");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (active_db_backend && g_strcmp0(active_db_backend->name, args[1]) == 0) {
|
||||
cons_show("Already using '%s' backend.", args[1]);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cons_show("Switching database backend to '%s'...", args[1]);
|
||||
if (log_database_switch_backend(args[1])) {
|
||||
cons_show("Database backend switched to '%s'.", args[1]);
|
||||
} else {
|
||||
cons_show_error("Failed to switch database backend.");
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (g_strcmp0(args[0], "verify") == 0) {
|
||||
const gchar* contact_jid = args[1]; // may be NULL (verify all)
|
||||
cons_show("Verifying history integrity...");
|
||||
|
||||
GSList* issues = log_database_verify_integrity(contact_jid);
|
||||
_show_integrity_issues(issues);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (g_strcmp0(args[0], "export") == 0) {
|
||||
#ifdef HAVE_SQLITE
|
||||
const gchar* contact_jid = args[1]; // may be NULL (export all)
|
||||
if (contact_jid) {
|
||||
cons_show("Exporting SQLite history for %s to flat-file...", contact_jid);
|
||||
} else {
|
||||
cons_show("Exporting all SQLite history to flat-file...");
|
||||
}
|
||||
int n = log_database_export_to_flatfile(contact_jid);
|
||||
if (n >= 0) {
|
||||
cons_show("Export complete: %d message(s) exported.", n);
|
||||
}
|
||||
#else
|
||||
cons_show_error("Export requires SQLite support. Rebuild with --with-sqlite.");
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (g_strcmp0(args[0], "import") == 0) {
|
||||
#ifdef HAVE_SQLITE
|
||||
const gchar* contact_jid = args[1]; // may be NULL (import all)
|
||||
if (contact_jid) {
|
||||
cons_show("Importing flat-file history for %s into SQLite...", contact_jid);
|
||||
} else {
|
||||
cons_show("Importing all flat-file history into SQLite...");
|
||||
}
|
||||
int n = log_database_import_from_flatfile(contact_jid);
|
||||
if (n >= 0) {
|
||||
cons_show("Import complete: %d message(s) imported.", n);
|
||||
}
|
||||
#else
|
||||
cons_show_error("Import requires SQLite support. Rebuild with --with-sqlite.");
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_cmd_set_boolean_preference(args[0], "Chat history", PREF_HISTORY);
|
||||
|
||||
// if set to on, set chlog (/logging chat on)
|
||||
|
||||
Reference in New Issue
Block a user