fix: Improve status reporting and filename handling for /url save

Use the original aesgcm:// URL when downloading OMEMO downloads.  Then
in the final message use the decrypted file destination instead of the
internal temporary path.

Use the unique download ID instead of the URL for message updates to
have proper progress reporting.

Unify the final transfer status to "done" across both downloads and
uploads.

Fixes: https://github.com/profanity-im/profanity/issues/1939
Signed-off-by: Michael Vetter <jubalh@iodoru.org>
This commit is contained in:
Michael Vetter
2026-03-24 21:20:24 +00:00
parent 050096c21e
commit a9ef000328
5 changed files with 55 additions and 24 deletions

View File

@@ -9209,18 +9209,30 @@ _prepare_filename(ProfWin* window, gchar* url, gchar* path)
break;
}
// Ensure that the downloads directory exists for saving cleartexts.
auto_gchar gchar* downloads_dir = path ? get_expanded_path(path) : files_get_download_path(jid);
if (g_mkdir_with_parents(downloads_dir, S_IRWXU) != 0) {
cons_show_error("Failed to create download directory "
"at '%s' with error '%s'",
downloads_dir, strerror(errno));
return NULL;
auto_gchar gchar* expanded_path = path ? get_expanded_path(path) : files_get_download_path(jid);
// If path is provided and doesn't look like a directory, create its parent.
// Otherwise, create the directory itself.
if (path && !g_str_has_suffix(expanded_path, G_DIR_SEPARATOR_S) && !g_file_test(expanded_path, G_FILE_TEST_IS_DIR)) {
auto_gchar gchar* dirname = g_path_get_dirname(expanded_path);
if (g_mkdir_with_parents(dirname, S_IRWXU) != 0) {
cons_show_error("Failed to create download directory "
"at '%s' with error '%s'",
dirname, strerror(errno));
return NULL;
}
} else {
if (g_mkdir_with_parents(expanded_path, S_IRWXU) != 0) {
cons_show_error("Failed to create download directory "
"at '%s' with error '%s'",
expanded_path, strerror(errno));
return NULL;
}
}
// Generate an unique filename from the URL that should be stored in the
// downloads directory.
return unique_filename_from_url(url, downloads_dir);
return unique_filename_from_url(url, expanded_path);
}
#ifdef HAVE_OMEMO

View File

@@ -80,9 +80,11 @@ aesgcm_file_get(void* userdata)
http_dl->worker = aesgcm_dl->worker;
http_dl->id = strdup(aesgcm_dl->id);
http_dl->url = strdup(https_url);
http_dl->display_url = strdup(aesgcm_dl->url);
http_dl->filename = strdup(tmpname);
http_dl->cmd_template = NULL;
http_dl->silent = FALSE;
http_dl->silent_done = TRUE;
http_dl->return_bytes_received = TRUE;
aesgcm_dl->http_dl = http_dl;
@@ -113,10 +115,12 @@ aesgcm_file_get(void* userdata)
http_print_transfer_update(aesgcm_dl->window, aesgcm_dl->id,
"Downloading '%s' failed: Failed to decrypt "
"file (%s).",
https_url, gcry_strerror(crypt_res));
aesgcm_dl->url, gcry_strerror(crypt_res));
} else {
http_print_transfer_update(aesgcm_dl->window, aesgcm_dl->id,
"Decrypted file saved to '%s'", aesgcm_dl->filename);
"Downloading '%s': done\nSaved to '%s'",
aesgcm_dl->url, aesgcm_dl->filename);
win_mark_received(aesgcm_dl->window, aesgcm_dl->id);
}
if (aesgcm_dl->cmd_template != NULL) {

View File

@@ -32,7 +32,6 @@
#include "common.h"
GSList* download_processes = NULL;
gboolean silent = FALSE;
static int
_xferinfo(void* userdata, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
@@ -58,9 +57,16 @@ _xferinfo(void* userdata, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultot
dlperc = (100 * dlnow) / dltotal;
}
if (!silent)
http_print_transfer_update(download->window, download->url,
"Downloading '%s': %d%%", download->url, dlperc);
if (!download->silent) {
const char* url = download->display_url ? download->display_url : download->url;
if (dlnow == dltotal && dltotal > 0) {
http_print_transfer_update(download->window, download->id,
"Downloading '%s': done", url);
} else {
http_print_transfer_update(download->window, download->id,
"Downloading '%s': %d%%", url, dlperc);
}
}
pthread_mutex_unlock(&lock);
@@ -85,15 +91,15 @@ http_file_get(void* userdata)
CURL* curl;
CURLcode res;
silent = download->silent;
download->cancel = 0;
download->bytes_received = 0;
pthread_mutex_lock(&lock);
if (!silent) {
const char* display_url = download->display_url ? download->display_url : download->url;
if (!download->silent) {
http_print_transfer(download->window, download->id,
"Downloading '%s': 0%%", download->url);
"Downloading '%s': 0%%", display_url);
}
FILE* outfh = fopen(download->filename, "wb");
@@ -172,18 +178,18 @@ http_file_get(void* userdata)
http_print_transfer_update(download->window, download->id,
"Downloading '%s' failed: "
"Download was canceled",
download->url);
display_url);
} else {
http_print_transfer_update(download->window, download->id,
"Downloading '%s' failed: %s",
download->url, err);
display_url, err);
}
free(err);
} else {
if (!download->cancel && !silent) {
if (!download->cancel && !download->silent && !download->silent_done) {
http_print_transfer_update(download->window, download->id,
"Downloading '%s': done\nSaved to '%s'",
download->url, download->filename);
display_url, download->filename);
win_mark_received(download->window, download->id);
if (download->return_bytes_received) {
ret = malloc(sizeof(*ret));
@@ -204,7 +210,7 @@ http_file_get(void* userdata)
http_print_transfer_update(download->window, download->id,
"Downloading '%s' failed: Unable to call "
"command '%s' with file at '%s' (%s).",
download->url,
display_url,
download->cmd_template,
download->filename,
"TODO: Log the error");
@@ -221,6 +227,7 @@ out:
free(download->filename);
free(download->url);
free(download->display_url);
free(download->id);
free(download);

View File

@@ -25,6 +25,7 @@ typedef struct http_download_t
{
char* id;
char* url;
char* display_url;
char* filename;
char* cmd_template;
curl_off_t bytes_received;
@@ -32,6 +33,7 @@ typedef struct http_download_t
pthread_t worker;
int cancel;
gboolean silent;
gboolean silent_done;
gboolean return_bytes_received;
} HTTPDownload;

View File

@@ -65,7 +65,13 @@ _xferinfo(void* userdata, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultot
ulperc = (100 * ulnow) / ultotal;
}
gchar* msg = g_strdup_printf("Uploading '%s': %d%%", upload->filename, ulperc);
gchar* msg = NULL;
if (ulnow == ultotal && ultotal > 0) {
msg = g_strdup_printf("Uploading '%s': done", upload->filename);
} else {
msg = g_strdup_printf("Uploading '%s': %d%%", upload->filename, ulperc);
}
if (!msg) {
msg = g_strdup(FALLBACK_MSG);
}
@@ -288,7 +294,7 @@ http_file_put(void* userdata)
cons_show_error(err_msg);
} else {
if (!upload->cancel) {
auto_gchar gchar* status_msg = g_strdup_printf("Uploading '%s': 100%%", upload->filename);
auto_gchar gchar* status_msg = g_strdup_printf("Uploading '%s': done", upload->filename);
if (!status_msg) {
status_msg = g_strdup(FALLBACK_MSG);
}