← Back to team overview

deja-dup-team team mailing list archive

Re: [Merge] lp:~ubuntu-mate-dev/deja-dup/caja into lp:deja-dup

 

Review: Needs Information

So Deja Dup has a mission statement, which includes being focused on as few target desktop environments as possible (https://wiki.gnome.org/Apps/DejaDup/Mission).

Which doesn't mean I'm rejecting this, just a heads up that if this lands in trunk, I likely won't put much effort myself into making sure it works beyond having it compile on Ubuntu, but patches welcome of course.  :)

Additionally, this adds a build-dependency on caja.  That's fine for the trunk version of the packaging, which builds in the official PPAs.  But for Ubuntu itself, caja is in universe while deja-dup is in main.  So to actually build this extension by default in Ubuntu, caja would need to be promoted to main.  Which is a hard sell just for this extension (I speak as one of the members of the Ubuntu MIR team that decides what gets promoted).  Ubuntu is just one distro, but still.

Have you considered instead, that this extension could easily live outside of the deja-dup source tree?  Maybe in caja itself or as a separate deja-dup-compatibility package.  All you need is deja_dup_parse_dir from DirHandling.c, right?  Which could be copied; it doesn't change often.  I'm happy to offer it to caja as GPL-2+ (I'm sole author of that bit of code).

What do you think?  Again, I'm happy to have it live in deja-dup, but I'm not sure I can enable its support in Ubuntu that way.

Diff comments:

> === modified file 'AUTHORS'
> --- AUTHORS	2014-10-25 13:52:17 +0000
> +++ AUTHORS	2015-01-31 16:36:09 +0000
> @@ -27,6 +27,13 @@
>             2011-2013 Canonical Ltd
>  License: GPL-3+
>  
> +Files: deja-dup/caja/CajaExtension.[ch]
> +Copyright: 2004–2005 Free Software Foundation, Inc.
> +           2009–2011 Michael Terry <mike@xxxxxxxxxxx>
> +           2011-2013 Canonical Ltd
> +           2015 Martin Wimpress <martin@xxxxxxxxxxxxxxxx>
> +License: GPL-3+
> +
>  Files: deja-dup/preferences/PreferencesPanel.c
>  Copyright: 2010 Intel, Inc
>             2011 Michael Terry <mike@xxxxxxxxxxx>
> 
> === modified file 'CMakeLists.txt'
> --- CMakeLists.txt	2014-09-20 15:04:46 +0000
> +++ CMakeLists.txt	2015-01-31 16:36:09 +0000
> @@ -25,6 +25,7 @@
>  
>  deja_option(ENABLE_CCPANEL "Build gnome-control-center panel" CHECK)
>  deja_option(ENABLE_NAUTILUS "Build nautilus plugin" CHECK)
> +deja_option(ENABLE_CAJA "Build caja plugin" CHECK)
>  deja_option(ENABLE_UNITY "Integrate with Unity" CHECK)
>  deja_option(ENABLE_UNITY_CCPANEL "Build unity-control-center panel" CHECK)
>  
> @@ -54,6 +55,14 @@
>                    ERROR_QUIET)
>  endif()
>  
> +deja_enable_option(CAJA libcaja-extension)
> +if(ENABLE_CAJA)
> +  execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=extensiondir libcaja-extension
> +                  OUTPUT_VARIABLE CAJA_EXTENSIONDIR
> +                  OUTPUT_STRIP_TRAILING_WHITESPACE
> +                  ERROR_QUIET)
> +endif()
> +
>  deja_enable_option(UNITY_CCPANEL libunity-control-center)
>  if(ENABLE_UNITY_CCPANEL)
>    execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=extensiondir libunity-control-center
> 
> === modified file 'NEWS'
> --- NEWS	2014-10-25 13:52:17 +0000
> +++ NEWS	2015-01-31 16:36:09 +0000
> @@ -1,5 +1,7 @@
>  Déjà Dup 33.x
>  -------------
> +Features:
> + • Added Caja extension.
>  Bug Fixes:
>   • Support duplicity 0.6.25 and up
>  
> 
> === modified file 'debian/control'
> --- debian/control	2014-09-20 14:51:29 +0000
> +++ debian/control	2015-01-31 16:36:09 +0000
> @@ -13,6 +13,7 @@
>                 libgnome-control-center-dev (>= 3.4),
>                 libgtk-3-dev (>= 3.6),
>                 libnautilus-extension-dev (>= 3.0),
> +               libcaja-extension-dev (>= 1.8.2),
>                 libnotify-dev (>= 0.7),
>                 libpeas-dev,
>                 libsecret-1-dev,
> 
> === modified file 'debian/rules'
> --- debian/rules	2014-01-09 04:42:28 +0000
> +++ debian/rules	2015-01-31 16:36:09 +0000
> @@ -11,6 +11,7 @@
>  override_dh_auto_configure:
>  	dh_auto_configure -- -DENABLE_CCPANEL=ON \
>  	                     -DENABLE_NAUTILUS=ON \
> +	                     -DENABLE_CAJA=ON \
>  	                     -DENABLE_UNITY=ON \
>  	                     -DENABLE_UNITY_CCPANEL=ON \
>  	                     -DCMAKE_INSTALL_LIBEXECDIR="/usr/lib/${DEB_HOST_MULTIARCH}" \
> 
> === modified file 'deja-dup/CMakeLists.txt'
> --- deja-dup/CMakeLists.txt	2014-10-30 15:06:01 +0000
> +++ deja-dup/CMakeLists.txt	2015-01-31 16:36:09 +0000
> @@ -50,6 +50,7 @@
>  add_subdirectory(help)
>  add_subdirectory(monitor)
>  add_subdirectory(nautilus)
> +add_subdirectory(caja)

Please keep this list alphabetical.

>  add_subdirectory(preferences)
>  add_subdirectory(tests)
>  add_subdirectory(widgets)
> 
> === added directory 'deja-dup/caja'
> === added file 'deja-dup/caja/CMakeLists.txt'
> --- deja-dup/caja/CMakeLists.txt	1970-01-01 00:00:00 +0000
> +++ deja-dup/caja/CMakeLists.txt	2015-01-31 16:36:09 +0000
> @@ -0,0 +1,28 @@
> +# -*- Mode: CMake; indent-tabs-mode: nil; tab-width: 2 -*-
> +#
> +# This file is part of Déjà Dup.
> +# For copyright information, see AUTHORS.
> +#
> +# Déjà Dup is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# Déjà Dup is distributed in the hope that it will be useful, but
> +# WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +# General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with Déjà Dup.  If not, see <http://www.gnu.org/licenses/>.
> +
> +if(ENABLE_CAJA)
> +add_library(deja-dup-caja MODULE CajaExtension.c)
> +target_link_libraries(deja-dup-caja ${GLIB_LDFLAGS} ${CAJA_LDFLAGS})
> +set_target_properties(deja-dup-caja PROPERTIES
> +                      OUTPUT_NAME deja-dup
> +                      INCLUDE_DIRECTORIES "${CMAKE_BINARY_DIR}/libdeja"
> +                      COMPILE_FLAGS "${GLIB_CFLAGS} ${CAJA_CFLAGS} ${COMMON_CFLAGS}")
> +add_dependencies(deja-dup-caja deja) # needs DirHandling.c
> +install(TARGETS deja-dup-caja DESTINATION "${CAJA_EXTENSIONDIR}")
> +endif()
> 
> === added file 'deja-dup/caja/CajaExtension.c'
> --- deja-dup/caja/CajaExtension.c	1970-01-01 00:00:00 +0000
> +++ deja-dup/caja/CajaExtension.c	2015-01-31 16:36:09 +0000
> @@ -0,0 +1,338 @@
> +/* -*- Mode: C; indent-tabs-mode: nil; tab-width: 2 -*- */
> +/*
> +    This file is part of Déjà Dup.
> +    © 2004–2005 Free Software Foundation, Inc.
> +    © 2009–2011 Michael Terry <mike@xxxxxxxxxxx>
> +
> +    Déjà Dup is free software: you can redistribute it and/or modify
> +    it under the terms of the GNU General Public License as published by
> +    the Free Software Foundation, either version 3 of the License, or
> +    (at your option) any later version.
> +
> +    Déjà Dup is distributed in the hope that it will be useful,
> +    but WITHOUT ANY WARRANTY; without even the implied warranty of
> +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +    GNU General Public License for more details.
> +
> +    You should have received a copy of the GNU General Public License
> +    along with Déjà Dup.  If not, see <http://www.gnu.org/licenses/>.
> +*/
> +
> +#include "DirHandling.c"
> +
> +#include "CajaExtension.h"
> +#include <libcaja-extension/caja-menu-provider.h>
> +#include <glib/gi18n-lib.h>
> +
> +GList *dirs = NULL;
> +GSettings *settings = NULL;
> +
> +// This will treat a < b iff a is 'lower' in the file tree than b
> +static int
> +cmp_prefix(GFile *a, GFile *b)
> +{
> +  if (a == NULL && b == NULL)
> +    return 0;
> +  else if (b == NULL || g_file_has_prefix(a, b))
> +    return -1;
> +  else if (a == NULL || g_file_has_prefix(b, a))
> +    return 1;
> +  else
> +    return 0;
> +}
> +
> +/* Do the include/exclude processing up front so that when
> +   we query to see if a file is included, it will be fast. */
> +static void
> +update_include_excludes ()
> +{
> +  /* Clear any existing dirs */
> +  if (dirs != NULL) {
> +    g_list_foreach(dirs, (GFunc)g_object_unref, NULL);
> +    g_list_free(dirs);
> +    dirs = NULL;
> +  }
> +
> +  if (settings == NULL)
> +    return;
> +
> +  gchar **includes_strv = g_settings_get_strv(settings, "include-list");
> +  gchar **excludes_strv = g_settings_get_strv(settings, "exclude-list");
> +
> +  gchar **p;
> +  for (p = includes_strv; p && *p; p++) {
> +    GFile *file = deja_dup_parse_dir(*p);
> +    if (file != NULL) {
> +      g_object_set_data(G_OBJECT(file), "included", GINT_TO_POINTER(TRUE));
> +      dirs = g_list_insert_sorted(dirs, file, (GCompareFunc)cmp_prefix);
> +    }
> +  }
> +  for (p = excludes_strv; p && *p; p++) {
> +    GFile *file = deja_dup_parse_dir(*p);
> +    if (file != NULL) {
> +      g_object_set_data(G_OBJECT(file), "included", GINT_TO_POINTER(FALSE));
> +      dirs = g_list_insert_sorted(dirs, file, (GCompareFunc)cmp_prefix);
> +    }
> +  }
> +
> +
> +  g_strfreev(includes_strv);
> +  g_strfreev(excludes_strv);
> +}
> +
> +static gboolean
> +update_include_excludes_idle_cb ()
> +{
> +  update_include_excludes ();
> +  return FALSE;
> +}
> +
> +static gboolean
> +is_dir_included(GFile *file)
> +{
> +  GList *p;
> +  for (p = dirs; p; p = p->next) {
> +    if (g_file_equal(file, (GFile *)p->data) ||
> +        g_file_has_prefix(file, (GFile *)p->data)) {
> +      gboolean included;
> +      included = GPOINTER_TO_INT(g_object_get_data(p->data, "included"));
> +      return included;
> +    }
> +  }
> +  return FALSE;
> +}
> +
> +static void
> +make_file_list(CajaFileInfo *info, GString *str)
> +{
> +  gchar *uri = caja_file_info_get_uri(info);
> +  if (!str->len)
> +    g_string_assign(str, uri);
> +  else
> +    g_string_append_printf(str, " %s", uri);
> +  g_free(uri);
> +}
> +
> +static void
> +restore_missing_files_callback(CajaMenuItem *item)
> +{
> +  gchar *cmd;
> +  CajaFileInfo *info;
> +
> +  info = g_object_get_data(G_OBJECT(item), "deja_dup_extension_file");
> +
> +  cmd = g_strdup_printf("deja-dup --restore-missing %s",
> +                        caja_file_info_get_uri(info));
> +
> +  g_spawn_command_line_async(cmd, NULL);
> +
> +  g_free(cmd);
> +}
> +
> +static void
> +restore_files_callback(CajaMenuItem *item)
> +{
> +  GString *str = g_string_new("");
> +  gchar *cmd;
> +  GList *files;
> +
> +  files = g_object_get_data(G_OBJECT(item), "deja_dup_extension_files");
> +
> +  g_list_foreach(files, (GFunc)make_file_list, str);
> +  cmd = g_strdup_printf("deja-dup --restore %s", 
> +                        str->str);
> +
> +  g_spawn_command_line_async(cmd, NULL);
> +
> +  g_free(cmd);
> +  g_string_free(str, TRUE);
> +}
> +
> +static GList *
> +deja_dup_caja_extension_get_background_items(CajaMenuProvider *provider,
> +                                                 GtkWidget *window,
> +                                                 CajaFileInfo *file)
> +{
> +  CajaMenuItem *item;
> +  guint length;
> +  GList *file_copies;
> +  gchar *path;
> +
> +  if (file == NULL)
> +    return NULL;
> +
> +  path = g_find_program_in_path("deja-dup");
> +  if (!path)
> +    return NULL;
> +  g_free(path);
> +
> +  if (!is_dir_included(caja_file_info_get_location(file)))
> +    return NULL;
> +
> +  item = caja_menu_item_new("DejaDupCajaExtension::restore_missing_item",
> +                                dgettext(GETTEXT_PACKAGE, "Restore Missing Files…"),
> +                                dgettext(GETTEXT_PACKAGE, "Restore deleted files from backup"),
> +                                "deja-dup");
> +
> +  g_signal_connect(item, "activate", G_CALLBACK(restore_missing_files_callback), NULL);
> +  g_object_set_data_full (G_OBJECT(item), "deja_dup_extension_file",
> +                          g_object_ref(file),
> +                          (GDestroyNotify)g_object_unref);
> +
> +  return g_list_append(NULL, item);
> +}
> +
> +static GList *
> +deja_dup_caja_extension_get_file_items(CajaMenuProvider *provider,
> +                                           GtkWidget *window,
> +                                           GList *files)
> +{
> +  CajaMenuItem *item;
> +  guint length;
> +  GList *file_copies;
> +  gchar *path;
> +
> +  if (files == NULL)
> +    return NULL;
> +
> +  path = g_find_program_in_path("deja-dup");
> +  if (!path)
> +    return NULL;
> +  g_free(path);
> +
> +  gboolean is_one_included = FALSE;
> +  GList *p;
> +  for (p = files; p; p = p->next) {
> +    GFile *gfile = caja_file_info_get_location((CajaFileInfo *)p->data);
> +    if (is_dir_included(gfile))
> +      is_one_included = TRUE;
> +  }
> +  if (!is_one_included)
> +    return NULL;
> +
> +  length = g_list_length(files);
> +  item = caja_menu_item_new("DejaDupCajaExtension::restore_item",
> +                                dngettext(GETTEXT_PACKAGE,
> +                                          "Revert to Previous Version…",
> +                                          "Revert to Previous Versions…",
> +                                          length),
> +                                dngettext(GETTEXT_PACKAGE,
> +                                          "Restore file from backup",
> +                                          "Restore files from backup",
> +                                          length),
> +                                "deja-dup");
> +
> +  g_signal_connect(item, "activate", G_CALLBACK(restore_files_callback), NULL);
> +  g_object_set_data_full (G_OBJECT(item), "deja_dup_extension_files", 
> +                          caja_file_info_list_copy(files),
> +                          (GDestroyNotify)caja_file_info_list_free);
> +
> +  return g_list_append(NULL, item);
> +}
> +
> +
> +enum  {
> +  DEJA_DUP_CAJA_EXTENSION_DUMMY_PROPERTY
> +};
> +static gpointer deja_dup_caja_extension_parent_class = NULL;
> +
> +
> +static GType deja_dup_caja_extension_type = 0;
> +
> +
> +DejaDupCajaExtension* deja_dup_caja_extension_construct (GType object_type) {
> +  DejaDupCajaExtension * self;
> +  self = g_object_newv (object_type, 0, NULL);
> +  return self;
> +}
> +
> +
> +DejaDupCajaExtension* deja_dup_caja_extension_new (void) {
> +  return deja_dup_caja_extension_construct (TYPE_DEJA_DUP_CAJA_EXTENSION);
> +}
> +
> +
> +static void deja_dup_caja_extension_class_init (DejaDupCajaExtensionClass * klass) {
> +  deja_dup_caja_extension_parent_class = g_type_class_peek_parent (klass);
> +}
> +
> +
> +static void deja_dup_caja_extension_instance_init (DejaDupCajaExtension * self) {
> +}
> +
> +
> +GType deja_dup_caja_extension_get_type (void) {
> +  return deja_dup_caja_extension_type;
> +}
> +
> +
> +static void
> +deja_dup_caja_extension_menu_provider_iface_init (CajaMenuProviderIface *iface)
> +{
> +  iface->get_background_items = deja_dup_caja_extension_get_background_items;
> +  iface->get_file_items = deja_dup_caja_extension_get_file_items;
> +}
> +
> +void deja_dup_caja_extension_register_type (GTypeModule *module)
> +{
> +  static const GTypeInfo info = {
> +    sizeof (DejaDupCajaExtensionClass),
> +    (GBaseInitFunc) NULL,
> +    (GBaseFinalizeFunc) NULL,
> +    (GClassInitFunc) deja_dup_caja_extension_class_init,
> +    NULL,
> +    NULL,
> +    sizeof (DejaDupCajaExtension),
> +    0,
> +    (GInstanceInitFunc) deja_dup_caja_extension_instance_init,
> +  };
> +
> +  deja_dup_caja_extension_type = g_type_module_register_type (module,
> +    G_TYPE_OBJECT,
> +    "DejaDupCajaExtension",
> +    &info, 0);
> +
> +  static const GInterfaceInfo menu_provider_iface_info =
> +  {
> +    (GInterfaceInitFunc)deja_dup_caja_extension_menu_provider_iface_init,
> +     NULL,
> +     NULL
> +  };
> +
> +  g_type_module_add_interface (module, deja_dup_caja_extension_type,
> +    CAJA_TYPE_MENU_PROVIDER, &menu_provider_iface_info);
> +}
> +
> +static GType type_list[1];
> +
> +void caja_module_initialize(GTypeModule *module)
> +{
> +  /*g_print("Initializing Déjà Dup extension\n");*/
> +  deja_dup_caja_extension_register_type(module);
> +  type_list[0] = TYPE_DEJA_DUP_CAJA_EXTENSION;
> +
> +  bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR);
> +  bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
> +
> +  settings = g_settings_new("org.gnome.DejaDup");
> +  g_signal_connect(settings, "changed::include-list",
> +                   update_include_excludes, NULL);
> +  g_signal_connect(settings, "changed::exclude-list",
> +                   update_include_excludes, NULL);
> +  g_idle_add(update_include_excludes_idle_cb, NULL);
> +}
> +
> +void caja_module_list_types (const GType **types, int *num_types)
> +{
> +  *types = type_list;
> +  *num_types = G_N_ELEMENTS (type_list);
> +}
> +
> +void caja_module_shutdown(void)
> +{
> +  g_object_unref(settings);
> +  settings = NULL;
> +
> +  update_include_excludes(); /* will clear it now that settings is NULL */
> +}
> +
> 
> === added file 'deja-dup/caja/CajaExtension.h'
> --- deja-dup/caja/CajaExtension.h	1970-01-01 00:00:00 +0000
> +++ deja-dup/caja/CajaExtension.h	2015-01-31 16:36:09 +0000
> @@ -0,0 +1,57 @@
> +/* -*- Mode: C; indent-tabs-mode: nil; tab-width: 2 -*- */
> +/*
> +    This file is part of Déjà Dup.
> +    © 2009 Michael Terry <mike@xxxxxxxxxxx>
> +
> +    Déjà Dup is free software: you can redistribute it and/or modify
> +    it under the terms of the GNU General Public License as published by
> +    the Free Software Foundation, either version 3 of the License, or
> +    (at your option) any later version.
> +
> +    Déjà Dup is distributed in the hope that it will be useful,
> +    but WITHOUT ANY WARRANTY; without even the implied warranty of
> +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +    GNU General Public License for more details.
> +
> +    You should have received a copy of the GNU General Public License
> +    along with Déjà Dup.  If not, see <http://www.gnu.org/licenses/>.
> +*/
> +
> +#ifndef __CAJAEXTENSION_H__
> +#define __CAJAEXTENSION_H__
> +
> +#include <glib.h>
> +#include <glib-object.h>
> +
> +G_BEGIN_DECLS
> +
> +
> +#define TYPE_DEJA_DUP_CAJA_EXTENSION (deja_dup_caja_extension_get_type ())
> +#define DEJA_DUP_CAJA_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_DEJA_DUP_CAJA_EXTENSION, DejaDupCajaExtension))
> +#define DEJA_DUP_CAJA_EXTENSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_DEJA_DUP_CAJA_EXTENSION, DejaDupCajaExtensionClass))
> +#define IS_DEJA_DUP_CAJA_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_DEJA_DUP_CAJA_EXTENSION))
> +#define IS_DEJA_DUP_CAJA_EXTENSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_DEJA_DUP_CAJA_EXTENSION))
> +#define DEJA_DUP_CAJA_EXTENSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_DEJA_DUP_CAJA_EXTENSION, DejaDupCajaExtensionClass))
> +
> +typedef struct _DejaDupCajaExtension DejaDupCajaExtension;
> +typedef struct _DejaDupCajaExtensionClass DejaDupCajaExtensionClass;
> +typedef struct _DejaDupCajaExtensionPrivate DejaDupCajaExtensionPrivate;
> +
> +struct _DejaDupCajaExtension {
> +	GObject parent_instance;
> +	DejaDupCajaExtensionPrivate * priv;
> +};
> +
> +struct _DejaDupCajaExtensionClass {
> +	GObjectClass parent_class;
> +};
> +
> +
> +DejaDupCajaExtension* deja_dup_caja_extension_construct (GType object_type);
> +DejaDupCajaExtension* deja_dup_caja_extension_new (void);
> +GType deja_dup_caja_extension_get_type (void);
> +
> +
> +G_END_DECLS
> +
> +#endif
> 


-- 
https://code.launchpad.net/~ubuntu-mate-dev/deja-dup/caja/+merge/248194
Your team Déjà Dup Developers is subscribed to branch lp:deja-dup.


References