[gnome-user-share] obex: Download files through the cache dir
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-user-share] obex: Download files through the cache dir
- Date: Tue, 12 Nov 2013 13:21:14 +0000 (UTC)
commit 87cb41ba119ccc5667025a6f81308501f34d5975
Author: Bastien Nocera <hadess hadess net>
Date: Sat Nov 9 23:14:37 2013 +0100
obex: Download files through the cache dir
Save files in the cache dir before moving them to a unique name
in the Downloads folder.
We need to do this as obexd will only save to a set root folder,
which defaults to the XDG cache dir, and move this to a unique
name (without overwriting existing files).
src/obexpush.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 146 insertions(+), 14 deletions(-)
---
diff --git a/src/obexpush.c b/src/obexpush.c
index 94a1f67..b7c283f 100644
--- a/src/obexpush.c
+++ b/src/obexpush.c
@@ -209,7 +209,7 @@ ask_user_transfer_accepted (NotifyNotification *notification,
char *action,
GDBusMethodInvocation *invocation)
{
- gchar *file = g_object_get_data (G_OBJECT (invocation), "filename");
+ gchar *file = g_object_get_data (G_OBJECT (invocation), "temp-filename");
g_debug ("Notification: transfer accepted! accepting transfer");
@@ -376,7 +376,7 @@ on_session_acquired (GObject *object,
if (paired) {
g_debug ("Remote device is paired, auto-accepting the transfer");
g_dbus_method_invocation_return_value (invocation,
- g_variant_new ("(s)", g_object_get_data (G_OBJECT (invocation), "filename")));
+ g_variant_new ("(s)", g_object_get_data (G_OBJECT (invocation), "temp-filename")));
return;
} else {
g_debug ("Remote device is not paired, auto-rejecting the transfer");
@@ -390,8 +390,7 @@ out:
static void
check_if_bonded (GDBusProxy *transfer,
- GDBusMethodInvocation *invocation,
- const gchar *filename)
+ GDBusMethodInvocation *invocation)
{
GVariant *v;
const gchar *session = NULL;
@@ -428,6 +427,133 @@ obex_agent_cancel (GError **error)
{
}
+/* From the old embed/mozilla/MozDownload.cpp */
+static const char*
+file_is_compressed (const char *filename)
+{
+ int i;
+ static const char * const compression[] = {".gz", ".bz2", ".Z", ".lz", ".xz", NULL};
+
+ for (i = 0; compression[i] != NULL; i++) {
+ if (g_str_has_suffix (filename, compression[i]))
+ return compression[i];
+ }
+
+ return NULL;
+}
+
+static const char*
+parse_extension (const char *filename)
+{
+ const char *compression;
+ const char *last_separator;
+
+ compression = file_is_compressed (filename);
+
+ /* if the file is compressed we might have a double extension */
+ if (compression != NULL) {
+ int i;
+ static const char * const extensions[] = {"tar", "ps", "xcf", "dvi", "txt", "text", NULL};
+
+ for (i = 0; extensions[i] != NULL; i++) {
+ char *suffix;
+ suffix = g_strdup_printf (".%s%s", extensions[i], compression);
+
+ if (g_str_has_suffix (filename, suffix)) {
+ char *p;
+
+ p = g_strrstr (filename, suffix);
+ g_free (suffix);
+
+ return p;
+ }
+
+ g_free (suffix);
+ }
+ }
+
+ /* no compression, just look for the last dot in the filename */
+ last_separator = strrchr (filename, G_DIR_SEPARATOR);
+ return strrchr ((last_separator) ? last_separator : filename, '.');
+}
+
+static char *
+get_destination_path (const char *filename)
+{
+ char *dest_dir;
+ char *destination_filename;
+
+ dest_dir = lookup_download_dir ();
+ destination_filename = g_build_filename (dest_dir, filename, NULL);
+ g_free (dest_dir);
+
+ /* Append (n) as needed. */
+ if (g_file_test (destination_filename, G_FILE_TEST_EXISTS)) {
+ int i = 1;
+ const char *dot_pos;
+ gssize position;
+ char *serial = NULL;
+ GString *tmp_filename;
+
+ dot_pos = parse_extension (destination_filename);
+ if (dot_pos)
+ position = dot_pos - destination_filename;
+ else
+ position = strlen (destination_filename);
+
+ tmp_filename = g_string_new (NULL);
+
+ do {
+ serial = g_strdup_printf ("(%d)", i++);
+
+ g_string_assign (tmp_filename, destination_filename);
+ g_string_insert (tmp_filename, position, serial);
+
+ g_free (serial);
+ } while (g_file_test (tmp_filename->str, G_FILE_TEST_EXISTS));
+
+ destination_filename = g_strdup (tmp_filename->str);
+ g_string_free (tmp_filename, TRUE);
+ }
+
+ return destination_filename;
+}
+
+static void
+move_temp_filename (GObject *object)
+{
+ const char *orig_filename;
+ char *dest_filename;
+ GFile *src, *dest;
+ GError *error = NULL;
+ gboolean res;
+
+ orig_filename = g_object_get_data (object, "temp-filename");
+ /* FIXME move to the destination directly, rather than
+ * getting the name separately */
+ dest_filename = get_destination_path (g_object_get_data (object, "filename"));
+
+ src = g_file_new_for_path (orig_filename);
+ dest = g_file_new_for_path (dest_filename);
+
+ /* This is sync, but the files will be on the same partition already
+ * (~/.cache/obexd to ~/Downloads) */
+ res = g_file_move (src, dest,
+ G_FILE_COPY_NONE, NULL,
+ NULL, NULL, &error);
+ g_debug ("Moving %s (orig name %s) to %s",
+ orig_filename, (char *) g_object_get_data (object, "filename"), dest_filename);
+
+ if (res == FALSE) {
+ g_warning ("Failed to move %s to %s: '%s'",
+ orig_filename, dest_filename, error->message);
+ g_error_free (error);
+ }
+ g_object_unref (src);
+ g_object_unref (dest);
+ g_free (dest_filename);
+}
+
static void
transfer_property_changed (GDBusProxy *transfer,
GVariant *changed_properties,
@@ -455,6 +581,7 @@ transfer_property_changed (GDBusProxy *transfer,
g_debug ("Got status %s = %s for filename %s", status, str, filename);
if (g_str_equal (status, "complete")) {
+ move_temp_filename (G_OBJECT (transfer));
if (show_notifications) {
g_debug ("transfer completed, showing a notification");
show_notification (filename);
@@ -485,17 +612,20 @@ obex_agent_authorize_push (GObject *source_object,
GDBusMethodInvocation *invocation = user_data;
GVariant *variant = g_dbus_proxy_get_cached_property (transfer, "Name");
const gchar *filename = g_variant_get_string (variant, NULL);
- gchar *download_dir, *file;
+ char *template;
+ int fd;
gboolean authorize = FALSE;
g_debug ("AuthorizePush received");
- download_dir = lookup_download_dir ();
- file = g_build_filename (download_dir, filename, NULL);
- g_free (download_dir);
+ template = g_build_filename (g_get_user_cache_dir (), "obexd", "XXXXXX", NULL);
+ fd = g_mkstemp (template);
+ close (fd);
+
+ g_object_set_data_full (G_OBJECT (transfer), "filename", g_strdup (filename), g_free);
+ g_object_set_data_full (G_OBJECT (transfer), "temp-filename", g_strdup (template), g_free);
- g_object_set_data_full (G_OBJECT (transfer), "filename", g_strdup (file), g_free);
- g_object_set_data_full (G_OBJECT (invocation), "filename", g_strdup (file), g_free);
+ g_object_set_data_full (G_OBJECT (invocation), "temp-filename", g_strdup (template), g_free);
g_signal_connect (transfer, "g-properties-changed",
G_CALLBACK (transfer_property_changed), NULL);
@@ -505,13 +635,15 @@ obex_agent_authorize_push (GObject *source_object,
authorize = TRUE;
break;
case ACCEPT_BONDED:
- check_if_bonded (transfer, invocation, filename);
+ check_if_bonded (transfer, invocation);
g_variant_unref (variant);
+ g_free (template);
/* check_if_bonded() will accept or reject the transfer */
return;
case ACCEPT_ASK:
ask_user (invocation, filename);
g_variant_unref (variant);
+ g_free (template);
/* ask_user() will accept or reject the transfer */
return;
default:
@@ -520,12 +652,12 @@ obex_agent_authorize_push (GObject *source_object,
if (authorize) {
g_dbus_method_invocation_return_value (invocation,
- g_variant_new ("(s)", file));
+ g_variant_new ("(s)", template));
show_icon ();
- g_debug ("Incoming transfer authorized: %s", file);
- g_free (file);
+ g_debug ("Incoming transfer authorized: %s (temp file: %s)", filename, template);
+ g_free (template);
} else {
g_dbus_method_invocation_return_dbus_error (invocation,
"org.bluez.obex.Error.Rejected", "Not Authorized");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]