[dia: 1/2] Add support for the XDG Base Directory Support with an automated migration path.



commit f5015d2a59fd5693a81a87c9d819eaae81c32f49
Author: EdĂȘnis Freindorfer Azevedo <edenisfa gmail com>
Date:   Thu Dec 6 18:45:46 2018 -0200

    Add support for the XDG Base Directory Support with an automated migration path.

 app/app_procs.c                     | 35 +++++++++++-------
 app/menus.c                         |  4 +--
 app/sheets_dialog_callbacks.c       |  4 +--
 lib/dia_dirs.c                      | 72 +++++++++++++++++++++++++++++++------
 lib/dia_dirs.h                      |  4 ++-
 lib/dialib.c                        |  2 +-
 lib/libdia.def                      |  3 +-
 lib/object_defaults.c               |  4 +--
 lib/persistence.c                   |  4 +--
 lib/plug-ins.c                      |  6 ++--
 lib/sheet.c                         |  2 +-
 objects/custom/custom.c             |  4 +--
 objects/custom_lines/custom_lines.c |  4 +--
 plug-ins/python/python-startup.py   | 20 ++++++++++-
 plug-ins/xslt/xslt.c                |  3 +-
 tests/test-objects.c                |  2 ++
 16 files changed, 128 insertions(+), 45 deletions(-)
---
diff --git a/app/app_procs.c b/app/app_procs.c
index dfd84e9c..c62cdb86 100644
--- a/app/app_procs.c
+++ b/app/app_procs.c
@@ -1086,41 +1086,50 @@ app_exit(void)
 
 static void create_user_dirs(void)
 {
-  gchar *dir, *subdir;
+  gchar *confdir, *datadir, *subdir;
 
 #ifdef G_OS_WIN32
-  /* not necessary to quit the program with g_error, everywhere else
-   * dia_config_filename appears to be used. Spit out a warning ...
+  /*
+   * not necessary to quit the program with g_error. Spit out a warning ...
    */
-  if (!g_get_home_dir())
+  if (!g_get_user_config_dir() || !g_get_user_data_dir())
   {
-    g_warning(_("Could not create per-user Dia configuration directory"));
+    g_warning(_("Could not create per-user Dia directories!"));
     return; /* ... and return. Probably removes my one and only FAQ. --HB */
   }
 #endif
-  dir = g_strconcat(g_get_home_dir(), G_DIR_SEPARATOR_S ".dia", NULL);
-  if (g_mkdir(dir, 0755) && errno != EEXIST) {
+  datadir = g_strconcat(g_get_user_data_dir(), G_DIR_SEPARATOR_S "dia", NULL);
+  if (g_mkdir(datadir, 0755) && errno != EEXIST) {
+#ifndef G_OS_WIN32
+    g_critical(_("Could not create per-user Dia data directory"));
+    exit(1);
+#else /* HB: it this really a reason to exit the program on *nix ? */
+    g_warning(_("Could not create per-user Dia data directory."));
+#endif
+  }
+  confdir = g_strconcat(g_get_user_config_dir(), G_DIR_SEPARATOR_S "dia", NULL);
+  if (g_mkdir(confdir, 0755) && errno != EEXIST) {
 #ifndef G_OS_WIN32
     g_critical(_("Could not create per-user Dia configuration directory"));
     exit(1);
 #else /* HB: it this really a reason to exit the program on *nix ? */
-    g_warning(_("Could not create per-user Dia configuration directory. Please make "
-        "sure that the environment variable HOME points to an existing directory."));
+    g_warning(_("Could not create per-user Dia configuration directory."));
 #endif
   }
 
   /* it is no big deal if these directories can't be created */
-  subdir = g_strconcat(dir, G_DIR_SEPARATOR_S "objects", NULL);
+  subdir = g_strconcat(datadir, G_DIR_SEPARATOR_S "objects", NULL);
   g_mkdir(subdir, 0755);
   g_free(subdir);
-  subdir = g_strconcat(dir, G_DIR_SEPARATOR_S "shapes", NULL);
+  subdir = g_strconcat(datadir, G_DIR_SEPARATOR_S "shapes", NULL);
   g_mkdir(subdir, 0755);
   g_free(subdir);
-  subdir = g_strconcat(dir, G_DIR_SEPARATOR_S "sheets", NULL);
+  subdir = g_strconcat(datadir, G_DIR_SEPARATOR_S "sheets", NULL);
   g_mkdir(subdir, 0755);
   g_free(subdir);
 
-  g_free(dir);
+  g_free(datadir);
+  g_free(confdir);
 }
 
 static PluginInitResult
diff --git a/app/menus.c b/app/menus.c
index b39bb73d..daa9d57d 100644
--- a/app/menus.c
+++ b/app/menus.c
@@ -347,7 +347,7 @@ load_accels(void)
 {
   gchar *accelfilename;
   /* load accelerators and prepare to later save them */
-  accelfilename = dia_config_filename("menurc");
+  accelfilename = dia_user_config_filename("menurc");
 
   if (accelfilename) {
     gtk_accel_map_load(accelfilename);
@@ -359,7 +359,7 @@ save_accels(gpointer data)
 {
   gchar *accelfilename;
 
-  accelfilename = dia_config_filename("menurc");
+  accelfilename = dia_user_config_filename("menurc");
   if (accelfilename) {
     gtk_accel_map_save (accelfilename);
     g_free (accelfilename);
diff --git a/app/sheets_dialog_callbacks.c b/app/sheets_dialog_callbacks.c
index b21042ae..aba8cf90 100644
--- a/app/sheets_dialog_callbacks.c
+++ b/app/sheets_dialog_callbacks.c
@@ -1616,7 +1616,7 @@ write_user_sheet(Sheet *sheet)
   SheetObject *sheetobject;
   GSList *sheet_objects;
     
-  dir_user_sheets = dia_config_filename("sheets");
+  dir_user_sheets = dia_user_data_filename("sheets");
   if (!*(sheet->filename)) {
     gchar *basename;
 
@@ -1707,7 +1707,7 @@ write_user_sheet(Sheet *sheet)
       gchar *dest;
       gchar *basename;
 
-      dia_user_shapes = dia_config_filename("shapes");
+      dia_user_shapes = dia_user_data_filename("shapes");
 
       basename = g_path_get_basename(som->svg_filename);
       dest = g_strdup_printf("%s%s%s", dia_user_shapes, G_DIR_SEPARATOR_S, basename);
diff --git a/lib/dia_dirs.c b/lib/dia_dirs.c
index 99e8590c..2572c769 100644
--- a/lib/dia_dirs.c
+++ b/lib/dia_dirs.c
@@ -156,24 +156,76 @@ dia_get_locale_directory(void)
 #endif
 }
 
-/** Get the name of a file under the Dia config directory.  If no home
- *  directory can be found, uses a temporary directory.
+/** Migrate a file or dir from $HOME/.dia to a new location.
+ * @param newloc New location of the subfile.
+ * @param subfile Name of the subfile.
+ */
+void
+dia_migrate_file (const gchar *newloc, const gchar *subfile)
+{
+  gchar *oldloc;
+  gchar *oldroot;
+
+  oldloc = g_strconcat(g_get_home_dir(), G_DIR_SEPARATOR_S ".dia"
+                       G_DIR_SEPARATOR_S, subfile, NULL);
+  if(g_file_test(oldloc, G_FILE_TEST_EXISTS))
+  {
+    if (!g_rename(oldloc, newloc))
+    {
+      g_warning("Could not migrate '%s' from '%s' to '%s'.",
+                subfile, oldloc, newloc);
+    }
+  }
+  g_free(oldloc);
+  /* we are trying to remove an empty folder '$HOME/.dia'
+   * if it is not empty, it is not removed */
+  oldroot = g_strconcat(g_get_home_dir(), G_DIR_SEPARATOR_S ".dia", NULL);
+  g_rmdir(oldroot);
+  g_free(oldroot);
+}
+
+/** Get the name of a file under the XDG user Dia config directory.
+ * @param subfile Name of the subfile.
+ * @returns A string with the full path of the desired file.  This string
+ *          should be freed after use.
+ */
+gchar *
+dia_user_config_filename(const gchar *subfile)
+{
+  const gchar *confdir;
+  gchar *diaconfdir;
+
+  confdir = g_get_user_config_dir();
+  if (!confdir) {
+    confdir = g_get_tmp_dir(); /* put config stuff in /tmp -- not ideal, but
+                                * we should not reach this state */
+  }
+  diaconfdir = g_strconcat(confdir, G_DIR_SEPARATOR_S "dia" G_DIR_SEPARATOR_S,
+                           subfile, NULL);
+  dia_migrate_file(diaconfdir, subfile);
+  return diaconfdir;
+}
+
+/** Get the name of a file under the XDG user Dia config directory.
  * @param subfile Name of the subfile.
  * @returns A string with the full path of the desired file.  This string
  *          should be freed after use.
  */
 gchar *
-dia_config_filename(const gchar *subfile)
+dia_user_data_filename(const gchar *subfile)
 {
-  const gchar *homedir;
+  const gchar *datadir;
+  gchar *diadatadir;
 
-  homedir = g_get_home_dir();
-  if (!homedir) {
-    homedir = g_get_tmp_dir(); /* put config stuff in /tmp -- not ideal, but
-                               * we should not reach this state */
+  datadir = g_get_user_data_dir();
+  if (!datadir) {
+    datadir = g_get_tmp_dir(); /* put config stuff in /tmp -- not ideal, but
+                                * we should not reach this state */
   }
-  return g_strconcat(homedir, G_DIR_SEPARATOR_S ".dia" G_DIR_SEPARATOR_S,
-                    subfile, NULL);
+  diadatadir = g_strconcat(datadir, G_DIR_SEPARATOR_S "dia" G_DIR_SEPARATOR_S,
+                           subfile, NULL);
+  dia_migrate_file(diadatadir, subfile);
+  return diadatadir;
 }
 
 /** Ensure that the directory part of `filename' exists.
diff --git a/lib/dia_dirs.h b/lib/dia_dirs.h
index c0cbff05..ded774e4 100644
--- a/lib/dia_dirs.h
+++ b/lib/dia_dirs.h
@@ -30,7 +30,9 @@
 gchar *dia_get_data_directory (const gchar* subdir);
 gchar *dia_get_lib_directory  (const gchar* subdir);
 gchar *dia_get_locale_directory (void);
-gchar *dia_config_filename    (const gchar* file);
+void dia_migrate_file (const gchar *newloc, const gchar *file);
+gchar *dia_user_config_filename (const gchar* file);
+gchar *dia_user_data_filename (const gchar* file);
 gboolean dia_config_ensure_dir  (const gchar* filename);
 gchar *dia_get_absolute_filename (const gchar *filename);
 gchar *dia_relativize_filename (const gchar *master, const gchar *slave);
diff --git a/lib/dialib.c b/lib/dialib.c
index 2d99e66c..5d5c2f9a 100644
--- a/lib/dialib.c
+++ b/lib/dialib.c
@@ -114,7 +114,7 @@ libdia_init (guint flags)
 
     gtk_widget_set_default_colormap(gdk_rgb_get_cmap());
 
-    diagtkrc = dia_config_filename("diagtkrc");
+    diagtkrc = dia_user_config_filename("diagtkrc");
     dia_log_message ("Config from %s", diagtkrc);
     gtk_rc_parse(diagtkrc);
     g_free(diagtkrc);
diff --git a/lib/libdia.def b/lib/libdia.def
index 8d9b5b9a..d6a03e70 100644
--- a/lib/libdia.def
+++ b/lib/libdia.def
@@ -204,7 +204,8 @@ EXPORTS
  dia_color_selector_new
  dia_color_selector_set_color
  dia_color_selector_set_use_alpha
- dia_config_filename
+ dia_user_config_filename
+ dia_user_data_filename
 
  dia_context_add_message
  dia_context_add_message_with_errno
diff --git a/lib/object_defaults.c b/lib/object_defaults.c
index fd151a83..f29c31ac 100644
--- a/lib/object_defaults.c
+++ b/lib/object_defaults.c
@@ -109,7 +109,7 @@ dia_object_defaults_load (const gchar *filename, gboolean create_lazy, DiaContex
   /* overload properties from file */
   if (!filename) 
     {
-      gchar *default_filename = dia_config_filename("defaults.dia");
+      gchar *default_filename = dia_user_data_filename("defaults.dia");
 
       dia_context_set_filename(ctx, default_filename);
       if (g_file_test(default_filename, G_FILE_TEST_EXISTS))
@@ -396,7 +396,7 @@ dia_object_defaults_save (const gchar *filename, DiaContext *ctx)
   gchar *real_filename;
 
   if (!filename)
-    real_filename = dia_config_filename("defaults.dia");
+    real_filename = dia_user_data_filename("defaults.dia");
   else
     real_filename = g_strdup (filename);
 
diff --git a/lib/persistence.c b/lib/persistence.c
index 2cba2cb4..2ffa5969 100644
--- a/lib/persistence.c
+++ b/lib/persistence.c
@@ -309,7 +309,7 @@ void
 persistence_load()
 {
   xmlDocPtr doc;
-  gchar *filename = dia_config_filename("persistence");
+  gchar *filename = dia_user_data_filename("persistence");
   DiaContext *ctx;
 
   persistence_init();
@@ -482,7 +482,7 @@ persistence_save()
   xmlDocPtr doc;
   xmlNs *name_space;
   DiaContext *ctx;
-  gchar *filename = dia_config_filename("persistence");
+  gchar *filename = dia_user_data_filename("persistence");
 
   ctx = dia_context_new ("Persistence");
   doc = xmlNewDoc((const xmlChar *)"1.0");
diff --git a/lib/plug-ins.c b/lib/plug-ins.c
index 250ef472..8f81a985 100644
--- a/lib/plug-ins.c
+++ b/lib/plug-ins.c
@@ -374,7 +374,7 @@ dia_register_plugins(void)
 
   library_path = g_getenv("DIA_LIB_PATH");
 
-  lib_dir = dia_config_filename("objects");
+  lib_dir = dia_user_data_filename("objects");
 
   if (lib_dir != NULL) {
     dia_register_plugins_in_dir(lib_dir);
@@ -444,7 +444,7 @@ ensure_pluginrc(void)
 
   if (pluginrc)
     return;
-  filename = dia_config_filename("pluginrc");
+  filename = dia_user_config_filename("pluginrc");
   dia_context_set_filename (ctx, filename);
   if (g_file_test (filename,  G_FILE_TEST_IS_REGULAR))
     pluginrc = diaXmlParseFile(filename, ctx, FALSE);
@@ -613,7 +613,7 @@ dia_pluginrc_write(void)
     xmlSetProp(pluginnode, (const xmlChar *)"filename", (xmlChar *)info->filename);
   }
 
-  filename = dia_config_filename("pluginrc");
+  filename = dia_user_config_filename("pluginrc");
   
   xmlDiaSaveFile(filename, pluginrc);
   
diff --git a/lib/sheet.c b/lib/sheet.c
index 698b750f..560d52f5 100644
--- a/lib/sheet.c
+++ b/lib/sheet.c
@@ -130,7 +130,7 @@ load_all_sheets(void)
   char *sheet_path;
   char *home_dir;
 
-  home_dir = dia_config_filename("sheets");
+  home_dir = dia_user_data_filename("sheets");
   if (home_dir) {
     dia_log_message ("sheets from '%s'", home_dir);
     load_sheets_from_dir(home_dir, SHEET_SCOPE_USER);
diff --git a/objects/custom/custom.c b/objects/custom/custom.c
index 5de009dd..8df3c558 100644
--- a/objects/custom/custom.c
+++ b/objects/custom/custom.c
@@ -141,9 +141,9 @@ dia_plugin_init(PluginInfo *info)
                            NULL, NULL))
     return DIA_PLUGIN_INIT_ERROR;
 
-  home_dir = g_get_home_dir();
+  home_dir = g_get_user_data_dir();
   if (home_dir) {
-    home_dir = dia_config_filename("shapes");
+    home_dir = dia_user_data_filename("shapes");
     load_shapes_from_tree(home_dir);
     g_free((char *)home_dir);
   }
diff --git a/objects/custom_lines/custom_lines.c b/objects/custom_lines/custom_lines.c
index 05916300..b3dda366 100644
--- a/objects/custom_lines/custom_lines.c
+++ b/objects/custom_lines/custom_lines.c
@@ -161,9 +161,9 @@ dia_plugin_init(PluginInfo *info)
                            NULL, NULL))
     return DIA_PLUGIN_INIT_ERROR;
   
-  home_dir = g_get_home_dir();
+  home_dir = g_get_user_data_dir();
   if (home_dir) {
-    home_dir = dia_config_filename("lines");
+    home_dir = dia_user_data_filename("lines");
     load_linefiles_from_tree(home_dir);
     g_free((char *)home_dir);
   }
diff --git a/plug-ins/python/python-startup.py b/plug-ins/python/python-startup.py
index 9883724b..8c8a542a 100644
--- a/plug-ins/python/python-startup.py
+++ b/plug-ins/python/python-startup.py
@@ -22,8 +22,26 @@ def load(plugindir):
 # import any python plugins from the user ...
 if not os.environ.has_key('HOME'):
        os.environ['HOME'] = os.pathsep + 'tmp'
+       os.environ['XDG_DATA_HOME'] = os.pathsep + 'tmp'
+else:
+       default = os.path.join(os.environ['HOME'], '.local', 'share')
+       oldlocation = os.path.join(os.environ['HOME'], '.dia', 'python')
+       newlocation = os.path.join (
+               os.getenv ('XDG_DATA_HOME', default),
+               'dia',
+               'python'
+       )
+       if os.path.isdir(oldlocation):
+               try:
+                       os.rename(oldlocation, newlocation)
+               except OSError:
+                       sys.stderr.write('WARNING:' +
+                                        'Could not migrate python scripts from ' +
+                                        '"%s" to "%s". Do it manually!%s' %
+                                        (oldlocation, newlocation, os.linesep))
+
 # import all plugins found in user plugin dir
-load(os.path.join(os.environ['HOME'], '.dia', 'python'))
+load(os.path.join(os.environ['XDG_DATA_HOME'], 'dia', 'python'))
 
 # find system python plugin dir
 curdir = os.path.dirname(__file__)
diff --git a/plug-ins/xslt/xslt.c b/plug-ins/xslt/xslt.c
index 88f9695d..3564918c 100644
--- a/plug-ins/xslt/xslt.c
+++ b/plug-ins/xslt/xslt.c
@@ -354,8 +354,7 @@ dia_plugin_init(PluginInfo *info)
        global_res = read_configuration(path);
        g_free (path);
 
-       path = dia_config_filename("xslt" G_DIR_SEPARATOR_S 
-                                                    "stylesheets.xml");
+       path = dia_user_data_filename("xslt" G_DIR_SEPARATOR_S "stylesheets.xml");
        user_res = read_configuration(path);
        g_free (path);
        
diff --git a/tests/test-objects.c b/tests/test-objects.c
index 6388786a..9102d30a 100644
--- a/tests/test-objects.c
+++ b/tests/test-objects.c
@@ -1090,6 +1090,8 @@ main (int argc, char** argv)
   else
     {
       /* avoid loading objects/plug-ins form the users home directory */
+      g_setenv ("XDG_DATA_HOME", "/tmp", TRUE);
+      g_setenv ("XDG_CONFIG_HOME", "/tmp", TRUE);
       g_setenv ("HOME", "/tmp", TRUE);
       dia_register_plugins ();
     }


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