Re: How to get trashed file path after "g_file_trash" ?



On Wed, Mar 19, 2008 at 5:01 PM, Amos Brocco <amos brocco unifr ch> wrote:
> Hello,
>  I'm porting the undo patch code [1] from gnome-vfs to gio/gvfs.
>  I'm facing the following problem: to undo a "move to trash" action I
>  need to know where the file has been trashed (and under which name);
>
>  so, is there a way to get the path or am I forced to process every file
>  in the trash path and check the "orig_path" attribute?

The "g_file_restore_from_trash()" API seems like a bit odd to me; the
trash location is a real location now, we can move to and from it at
will, but it's certainly doable. The problem I see with this API is
that if you've got a GFile to the item in the trash, coding up the
restore operation isn't difficult at all, but probably should be
application-specific (as there are several different cases I can think
of in this situation).

The even bigger problem would be that this operation is very nasty in
the dozens of ways it can go wrong, of which we'd want much better
error handling and reporting than GLib could probably give us without
a dozen flags and/or operation versions. And it's is odd that it would
belong to the GFile namespace, but would only work for trash:/// URIs.
And if you already have one of them, why don't you implement it the
way you see fit anyways?

For the ridiculous email-ware implementation of this:
/**
 * g_file_restore_from_trash:
 * @file: a #GFile with a trash:/// URI pointing to a trashed file.
 * @flags: a set of #GFileCopyFlags to use during the move.
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 * @progress_callback: #GFileProgressCallback function for updates.
 * @progress_callback_data: gpointer to user data for the callback function.
 * @error: #GError for returning error conditions, or %NULL
 *
 * Restores a file from the Trash bin to its original location. This method is
 * more than a little bit ridiculous IMO, as it gives no recovery
 * strategy; it just fails if there's any kind of error at all. It also lives
 * in the g_file_* namespace, even though it only works for
 * "trash:///" URIs. It also does sync I/O twice; once to get info on the
 * trashed file, and one very long I/O operation during the move. Did I
 * mention that I think this is a bit silly for GIO? ;)
 *
 * If you're writing an application that restores files from trash, you should
 * probably implement this yourself, and not use this method. It definitely
 * won't work for Nautilus ;).
 */
gboolean
g_file_restore_from_trash (GFile *file,
                           GFileCopyFlags flags,
                           GCancellable *cancellable,
                           GFileProgressCallback progress_callback,
                           gpointer progress_callback_data,
                           GError **error)
{
  GFileInfo *info;
  GError *my_error;
  g_return_val_if_fail (G_IS_FILE (file), FALSE);

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return FALSE;

  if (!g_file_has_uri_scheme (file, "trash"))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
         _("Restoring from non-trash URIs is not possible"));
      return FALSE;
    }

  info = g_file_query_info (source,
			    "trash::orig-path",
			    cancellable,
			    &my_error);
  if (info != NULL)
    {
      GFile *dest = NULL;
      gboolean success = FALSE;
      dest = g_file_new_for_path(g_file_info_get_attribute_byte_string
(info, "trash::orig-path"));
      success = g_file_move (file, dest, cancellable,
                progress_callback, progress_callback_data, &my_error);

      g_error_propagate (error, my_error);
      g_object_unref (info);
      g_object_unref (dest);
      return success;
    }
  else
    g_error_propagate (error, my_error);

  return FALSE;
}

Keep in mind I didn't test that, but it's more or less what would have
to happen.

If you only have the file name, enumerate the trash directory, sort
the results, and do a binary search for it. Not sure what would happen
if you trashed two files of the same name from the same directory
though, having to deal with the edge cases of the "_filename.2",
"_filename.3" with the same original path if you're thinking about
going that way though. Nautilus will have to do a lot more than the
above to keep track of these things, such as being able to recreate
directory structures if someone decided to delete them instead of just
trashing them, making sure that the item's original path is mounted
(which should probably always be the case, but who knows what
weirdness could happen), etc.

For your patch, something like an asynchronous version of the above
process could probably work, as long as you store the original file
name and the time you trashed the file so that you can recover the
right item each time (the important part here being to store both so
we are getting the sequencing right for multiple items of the same
name and original path being trashed). You might want to wait until
after the machinery for restore-from-trash has already been added to
Nautilus so that your patch can simply work with it, rather than
having to implement a special-cased version of it. I'm currently
working on D-Bus support as a subset of removing years of cruft that's
accumulated, but I can do restore-from-trash next if someone doesn't
beat me to the punch. It's a tough problem to crack though.

Hey Alex, when are we branching for 2.23 again? ;)

Just a few scattered thoughts on this.
-A. Walton

>
>  --
>  Amos Brocco | Ph.D Student | Computer Science Department - DIUF |
>  University of Fribourg | A406 Pérolles 21 | Bd. Pérolles 90 |
>  CH-1700 Fribourg | http://diuf.unifr.ch/pai/people/broccoa
>
>
>
> --
>  nautilus-list mailing list
>  nautilus-list gnome org
>  http://mail.gnome.org/mailman/listinfo/nautilus-list
>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]