mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Gnc-Prefs: add code to migrate settings from gconf to gsettings at runtime
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@23273 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
ce33da254f
commit
a807648901
@ -484,6 +484,14 @@ AC_CHECK_LIB(xml2, xmlElemDump, [:], [
|
||||
])
|
||||
LIBS="$oLIBS"
|
||||
|
||||
### --------------------------------------------------------------------------
|
||||
### LIBXSLT
|
||||
|
||||
PKG_CHECK_MODULES(LIBXSLT, libxslt)
|
||||
AS_SCRUB_INCLUDE(LIBXLT_CFLAGS)
|
||||
AC_SUBST(LIBXSLT_CFLAGS)
|
||||
AC_SUBST(LIBXSLT_LIBS)
|
||||
|
||||
### --------------------------------------------------------------------------
|
||||
### Zlib
|
||||
|
||||
|
@ -33,7 +33,9 @@ AM_CPPFLAGS = \
|
||||
${GUILE_INCS} \
|
||||
${PYTHON_CPPFLAGS} \
|
||||
${GLIB_CFLAGS} \
|
||||
${GTK_CFLAGS}
|
||||
${GTK_CFLAGS} \
|
||||
${LIBXML2_CFLAGS} \
|
||||
${LIBXSLT_CFLAGS}
|
||||
|
||||
libgncmod_app_utils_la_SOURCES = \
|
||||
calculation/expression_parser.c \
|
||||
@ -97,7 +99,9 @@ libgncmod_app_utils_la_LIBADD = \
|
||||
${top_builddir}/src/libqof/qof/libgnc-qof.la \
|
||||
${GTK_LIBS} \
|
||||
${GUILE_LIBS} \
|
||||
${GLIB_LIBS}
|
||||
${GLIB_LIBS} \
|
||||
${LIBXML2_LIBS} \
|
||||
${LIBXSLT_LIBS}
|
||||
|
||||
if BUILDING_FROM_SCM
|
||||
swig-app-utils-guile.c: app-utils.i ${top_srcdir}/src/base-typemaps.i
|
||||
@ -134,9 +138,15 @@ gncscm_DATA = \
|
||||
config-var.scm \
|
||||
date-utilities.scm \
|
||||
hooks.scm \
|
||||
migrate-prefs.scm \
|
||||
options.scm \
|
||||
prefs.scm \
|
||||
simple-obj.scm
|
||||
|
||||
prefsmigrationdir = $(GNC_SHAREDIR)
|
||||
prefsmigration_DATA = \
|
||||
make-prefs-migration-script.xsl \
|
||||
migratable-prefs.xml
|
||||
|
||||
noinst_DATA = .scm-links
|
||||
|
||||
@ -150,7 +160,8 @@ EXTRA_DIST = \
|
||||
swig-app-utils-python.c \
|
||||
app-utils.i \
|
||||
${gncmod_DATA} \
|
||||
${gncscm_DATA}
|
||||
${gncscm_DATA} \
|
||||
${prefsmigration_DATA}
|
||||
|
||||
if OS_WIN32
|
||||
libgncmod_app_utils_la_SOURCES += gnc-help-utils.c
|
||||
|
@ -21,6 +21,7 @@
|
||||
(use-modules (gnucash main)) ;; FIXME: delete after we finish modularizing.
|
||||
(use-modules (gnucash gnc-module))
|
||||
(use-modules (ice-9 syncase))
|
||||
(use-modules (migrate-prefs))
|
||||
|
||||
;; Guile 2 needs to find the symbols from the c module at compile time already
|
||||
(cond-expand
|
||||
@ -276,6 +277,10 @@
|
||||
(export simple-obj-from-list)
|
||||
(export make-simple-obj)
|
||||
|
||||
;; migrate-prefs.scm
|
||||
(re-export migration-prepare)
|
||||
(re-export migration-cleanup)
|
||||
|
||||
(define gnc:*kvp-option-path* (list KVP-OPTION-PATH))
|
||||
(export gnc:*kvp-option-path*)
|
||||
|
||||
|
@ -27,14 +27,29 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "gnc-gsettings.h"
|
||||
#include "gnc-path.h"
|
||||
#include "guile-mappings.h"
|
||||
#include <libguile.h>
|
||||
#include "libqof/qof/qof.h"
|
||||
#include "gnc-prefs-p.h"
|
||||
|
||||
#include <libxml/xmlmemory.h>
|
||||
#include <libxml/debugXML.h>
|
||||
#include <libxml/HTMLtree.h>
|
||||
#include <libxml/xmlIO.h>
|
||||
#include <libxml/xinclude.h>
|
||||
#include <libxml/catalog.h>
|
||||
#include <libxslt/xslt.h>
|
||||
#include <libxslt/xsltInternals.h>
|
||||
#include <libxslt/transform.h>
|
||||
#include <libxslt/xsltutils.h>
|
||||
|
||||
#define CLIENT_TAG "%s-%s-client"
|
||||
#define NOTIFY_TAG "%s-%s-notify_id"
|
||||
|
||||
static GHashTable *schema_hash = NULL;
|
||||
static const gchar *gsettings_prefix;
|
||||
static xmlExternalEntityLoader defaultEntityLoader = NULL;
|
||||
|
||||
/* This static indicates the debugging module that this .o belongs to. */
|
||||
static QofLogModule log_module = G_LOG_DOMAIN;
|
||||
@ -276,6 +291,7 @@ gnc_gsettings_set_bool (const gchar *schema,
|
||||
GSettings *schema_ptr = gnc_gsettings_get_schema_ptr (schema);
|
||||
g_return_val_if_fail (G_IS_SETTINGS (schema_ptr), FALSE);
|
||||
|
||||
ENTER("schema: %s, key: %s", schema, key);
|
||||
if (gnc_gsettings_is_valid_key (schema_ptr, key))
|
||||
{
|
||||
result = g_settings_set_boolean (schema_ptr, key, value);
|
||||
@ -285,6 +301,7 @@ gnc_gsettings_set_bool (const gchar *schema,
|
||||
else
|
||||
PERR ("Invalid key %s for schema %s", key, schema);
|
||||
|
||||
LEAVE("result %i", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -387,6 +404,7 @@ gnc_gsettings_set_string (const gchar *schema,
|
||||
GSettings *schema_ptr = gnc_gsettings_get_schema_ptr (schema);
|
||||
g_return_val_if_fail (G_IS_SETTINGS (schema_ptr), FALSE);
|
||||
|
||||
ENTER("schema: %s, key: %s", schema, key);
|
||||
if (gnc_gsettings_is_valid_key (schema_ptr, key))
|
||||
{
|
||||
result = g_settings_set_string (schema_ptr, key, value);
|
||||
@ -396,6 +414,7 @@ gnc_gsettings_set_string (const gchar *schema,
|
||||
else
|
||||
PERR ("Invalid key %s for schema %s", key, schema);
|
||||
|
||||
LEAVE("result %i", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -529,5 +548,118 @@ void gnc_gsettings_load_backend (void)
|
||||
prefsbackend.set_value = gnc_gsettings_set_value;
|
||||
prefsbackend.reset = gnc_gsettings_reset;
|
||||
prefsbackend.reset_group = gnc_gsettings_reset_schema;
|
||||
|
||||
LEAVE("Prefsbackend bind = %p", prefsbackend.bind);
|
||||
}
|
||||
|
||||
/* Attempt to migrate preferences from gconf files
|
||||
to gsettings if not already done so */
|
||||
|
||||
/* This snippet is borrowed from the xsltproc source
|
||||
* and adapted to help the xsl transform find our temporary
|
||||
* files in $HOME/.gnc-migration-tmp/
|
||||
*/
|
||||
static xmlParserInputPtr
|
||||
xsltprocExternalEntityLoader(const char *URL, const char *ID,
|
||||
xmlParserCtxtPtr ctxt) {
|
||||
xmlParserInputPtr ret;
|
||||
warningSAXFunc warning = NULL;
|
||||
xmlChar *newURL;
|
||||
gchar *tmpdir = g_build_filename (g_getenv ("HOME"), ".gnc-migration-tmp", NULL);
|
||||
|
||||
int i;
|
||||
const char *lastsegment = URL;
|
||||
const char *iter = URL;
|
||||
|
||||
while (*iter != 0) {
|
||||
if (*iter == '/')
|
||||
lastsegment = iter + 1;
|
||||
iter++;
|
||||
}
|
||||
|
||||
if ((ctxt != NULL) && (ctxt->sax != NULL)) {
|
||||
warning = ctxt->sax->warning;
|
||||
ctxt->sax->warning = NULL;
|
||||
}
|
||||
|
||||
if (defaultEntityLoader != NULL) {
|
||||
ret = defaultEntityLoader(URL, ID, ctxt);
|
||||
if (ret != NULL) {
|
||||
if (warning != NULL)
|
||||
ctxt->sax->warning = warning;
|
||||
return(ret);
|
||||
}
|
||||
}
|
||||
|
||||
newURL = xmlStrdup((const xmlChar *) tmpdir);
|
||||
newURL = xmlStrcat(newURL, (const xmlChar *) "/");
|
||||
newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment);
|
||||
g_free (tmpdir);
|
||||
if (newURL != NULL) {
|
||||
ret = defaultEntityLoader((const char *)newURL, ID, ctxt);
|
||||
if (ret != NULL) {
|
||||
if (warning != NULL)
|
||||
ctxt->sax->warning = warning;
|
||||
xmlFree(newURL);
|
||||
return(ret);
|
||||
}
|
||||
xmlFree(newURL);
|
||||
}
|
||||
if (warning != NULL) {
|
||||
ctxt->sax->warning = warning;
|
||||
if (URL != NULL)
|
||||
warning(ctxt, "failed to load external entity \"%s\"\n", URL);
|
||||
else if (ID != NULL)
|
||||
warning(ctxt, "failed to load external entity \"%s\"\n", ID);
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
void gnc_gsettings_migrate_from_gconf (void)
|
||||
{
|
||||
gchar *pkgdatadir, *stylesheet, *input, *output;
|
||||
gchar *migr_dir;
|
||||
SCM migr_script;
|
||||
SCM result = scm_c_eval_string ("(use-modules (gnucash app-utils))(migration-prepare)");
|
||||
xsltStylesheetPtr stylesheetptr = NULL;
|
||||
xmlDocPtr inputxml, transformedxml;
|
||||
FILE *outfile;
|
||||
|
||||
pkgdatadir = gnc_path_get_pkgdatadir();
|
||||
stylesheet = g_build_filename(pkgdatadir, "make-prefs-migration-script.xsl", NULL);
|
||||
input = g_build_filename(pkgdatadir, "migratable-prefs.xml", NULL);
|
||||
migr_dir = g_build_filename(g_getenv ("HOME"), ".gnc-migration-tmp", NULL);
|
||||
output = g_build_filename(migr_dir, "migrate-prefs-user.scm", NULL);
|
||||
xmlSubstituteEntitiesDefault(1);
|
||||
xmlLoadExtDtdDefaultValue = 1;
|
||||
defaultEntityLoader = xmlGetExternalEntityLoader();
|
||||
xmlSetExternalEntityLoader(xsltprocExternalEntityLoader);
|
||||
stylesheetptr = xsltParseStylesheetFile((const xmlChar *)stylesheet);
|
||||
inputxml = xmlParseFile(input);
|
||||
transformedxml = xsltApplyStylesheet(stylesheetptr, inputxml, NULL);
|
||||
|
||||
outfile = fopen(output, "w");
|
||||
xsltSaveResultToFile(outfile, transformedxml, stylesheetptr);
|
||||
fclose(outfile);
|
||||
|
||||
migr_script = scm_from_locale_string (output);
|
||||
scm_primitive_load (migr_script);
|
||||
result = scm_c_eval_string ("(use-modules (migrate-prefs-user))(run-migration)");
|
||||
|
||||
xsltFreeStylesheet(stylesheetptr);
|
||||
xmlFreeDoc(inputxml);
|
||||
xmlFreeDoc(transformedxml);
|
||||
|
||||
xsltCleanupGlobals();
|
||||
xmlCleanupParser();
|
||||
|
||||
result = scm_c_eval_string ("(use-modules (gnucash app-utils))(migration-cleanup)");
|
||||
|
||||
g_free (pkgdatadir);
|
||||
g_free (stylesheet);
|
||||
g_free (input);
|
||||
g_free (output);
|
||||
g_free (migr_dir);
|
||||
|
||||
}
|
||||
|
@ -595,6 +595,11 @@ void gnc_gsettings_reset_schema (const gchar *schema);
|
||||
*/
|
||||
void gnc_gsettings_load_backend (void);
|
||||
|
||||
|
||||
/* Attempt to migrate preferences from gconf files
|
||||
to gsettings if not already done so */
|
||||
void gnc_gsettings_migrate_from_gconf (void);
|
||||
|
||||
#endif /* GNC_GSETTINGS_H */
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "gnc-component-manager.h"
|
||||
#include "gnc-hooks.h"
|
||||
#include "gnc-exp-parser.h"
|
||||
#include "gnc-gsettings.h"
|
||||
|
||||
GNC_MODULE_API_DECL(libgncmod_app_utils)
|
||||
|
||||
@ -77,6 +78,7 @@ libgncmod_app_utils_gnc_module_init(int refcount)
|
||||
gnc_component_manager_init ();
|
||||
gnc_hook_add_dangler(HOOK_STARTUP, (GFunc)gnc_exp_parser_init, NULL);
|
||||
gnc_hook_add_dangler(HOOK_SHUTDOWN, (GFunc)app_utils_shutdown, NULL);
|
||||
gnc_gsettings_migrate_from_gconf();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
193
src/app-utils/make-prefs-migration-script.xsl
Normal file
193
src/app-utils/make-prefs-migration-script.xsl
Normal file
@ -0,0 +1,193 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<xsl:stylesheet version="1.0"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:df="http://dateformats.data">
|
||||
<xsl:output method="text" encoding="UTF8"/>
|
||||
|
||||
<!-- Configure lookup table for date format -->
|
||||
<xsl:key name="datefmt-lookup" match="df:dateformat" use="df:name"/>
|
||||
<xsl:variable name="dateformats-top" select="document('')/*/df:dateformats"/>
|
||||
|
||||
<!-- Primary template - process each prefence group -->
|
||||
<xsl:template match="/">
|
||||
<!-- Write file header -->
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; migrate-prefs.scm
|
||||
;;; Custom generated script to migrate user preferences from
|
||||
;;; gconf to gsettings. This should only be run once -
|
||||
;;; when running GnuCash 2.6.x for the first time.
|
||||
;;;
|
||||
;;; Copyright 2013 Geert Janssens <geert@kobaltwit.be>
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-module (migrate-prefs-user))
|
||||
|
||||
(use-modules (gnucash core-utils))
|
||||
;(use-modules (gnucash gnc-module))
|
||||
;; Guile 2 needs to find the symbols from the c module at compile time already
|
||||
;(cond-expand
|
||||
; (guile-2
|
||||
; (eval-when
|
||||
; (compile load eval)
|
||||
; (load-extension "libgnc-core-utils" "scm_init_sw_core_utils_module")))
|
||||
; (else
|
||||
; (load-extension "libgnc-core-utils" "scm_init_sw_core_utils_module")))
|
||||
;(use-modules (sw_core_utils))
|
||||
|
||||
(define (run-migration)
|
||||
<xsl:for-each select="//prefsgroup">
|
||||
<xsl:if test="document(gconfpath)//entry">
|
||||
;; Processing preferences in group <xsl:value-of select="gschemaid"/>
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
<xsl:variable name="gconf-top" select="document(gconfpath)/gconf"/>
|
||||
<xsl:apply-templates select="./pref"/>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
|
||||
(display "Preference migration has finished")(newline)
|
||||
)
|
||||
|
||||
(export run-migration)
|
||||
</xsl:template>
|
||||
|
||||
<!-- Process one prefence -->
|
||||
<xsl:template match="pref">
|
||||
<xsl:variable name="gconf-top" select="document(../gconfpath)/gconf"/>
|
||||
<xsl:apply-templates select="$gconf-top">
|
||||
<xsl:with-param name="curr-pref" select="."/>
|
||||
</xsl:apply-templates>
|
||||
</xsl:template>
|
||||
|
||||
<!-- Find the equivalent entry in gconf -->
|
||||
<xsl:template match="gconf">
|
||||
<xsl:param name="curr-pref"/>
|
||||
<xsl:for-each select="entry">
|
||||
<xsl:if test="@name = $curr-pref/gconfkey">
|
||||
;; Processing preference <xsl:value-of select="$curr-pref/gschemaname"/>
|
||||
<xsl:apply-templates select=".">
|
||||
<xsl:with-param name="curr-pref" select="$curr-pref"/>
|
||||
</xsl:apply-templates>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
|
||||
<!-- Determine next action based on preference type -->
|
||||
<xsl:template match="entry">
|
||||
<xsl:param name="curr-pref"/>
|
||||
<xsl:choose>
|
||||
<xsl:when test="$curr-pref/gschematype = 'b'">
|
||||
;; Gconf value (boolean): <xsl:value-of select="./@value"/>
|
||||
(gnc-prefs-set-bool
|
||||
; preference group
|
||||
"<xsl:value-of select="$curr-pref/../gschemaid"/>"
|
||||
; preference name
|
||||
"<xsl:value-of select="$curr-pref/gschemaname"/>"
|
||||
; preference value
|
||||
<xsl:if test="./@value = 'true'">#t</xsl:if>
|
||||
<xsl:if test="./@value = 'false'">#f</xsl:if>
|
||||
)
|
||||
</xsl:when>
|
||||
|
||||
|
||||
<xsl:when test="$curr-pref/gschematype = 'datefmt'">
|
||||
;; Gconf value (string): "<xsl:value-of select="./stringvalue"/>" -> gsettings (integer)
|
||||
(gnc-prefs-set-int
|
||||
; preference group
|
||||
"<xsl:value-of select="$curr-pref/../gschemaid"/>"
|
||||
; preference name
|
||||
"<xsl:value-of select="$curr-pref/gschemaname"/>"
|
||||
; preference value
|
||||
<xsl:apply-templates select="$dateformats-top">
|
||||
<xsl:with-param name="curr-entry" select="."/>
|
||||
</xsl:apply-templates>
|
||||
)
|
||||
</xsl:when>
|
||||
|
||||
|
||||
<xsl:when test="$curr-pref/gschematype = '(dd)'">
|
||||
;; Type: pair of decimals (stored in Gconf as [d,d])
|
||||
; guile command to write pair of decimals value
|
||||
</xsl:when>
|
||||
|
||||
|
||||
<xsl:when test="$curr-pref/gschematype = 'd'">
|
||||
;; Gconf value (decimal): <xsl:value-of select="./@value"/>
|
||||
(gnc-prefs-set-float
|
||||
; preference group
|
||||
"<xsl:value-of select="$curr-pref/../gschemaid"/>"
|
||||
; preference name
|
||||
"<xsl:value-of select="$curr-pref/gschemaname"/>"
|
||||
; preference value
|
||||
<xsl:value-of select="./@value"/>
|
||||
)
|
||||
</xsl:when>
|
||||
|
||||
|
||||
<xsl:when test="$curr-pref/gschematype = 'i'">
|
||||
;; Gconf value (integer): <xsl:value-of select="./@value"/>
|
||||
(gnc-prefs-set-int
|
||||
; preference group
|
||||
"<xsl:value-of select="$curr-pref/../gschemaid"/>"
|
||||
; preference name
|
||||
"<xsl:value-of select="$curr-pref/gschemaname"/>"
|
||||
; preference value
|
||||
<xsl:value-of select="./@value"/>
|
||||
)
|
||||
</xsl:when>
|
||||
|
||||
|
||||
<xsl:when test="$curr-pref/gschematype = 's2b'">
|
||||
;; Gconf value (string): "<xsl:value-of select="./stringvalue"/>" -> gsettings (boolean)
|
||||
(let ((suffix (string-delete "<xsl:value-of select="./stringvalue"/>" #\_)))
|
||||
(gnc-prefs-set-bool
|
||||
; preference group
|
||||
"<xsl:value-of select="$curr-pref/../gschemaid"/>"
|
||||
; preference name
|
||||
"<xsl:value-of select="$curr-pref/gschemaname"/>"
|
||||
; preference value
|
||||
(string-suffix? suffix "<xsl:value-of select="$curr-pref/gschemaname"/>")))
|
||||
</xsl:when>
|
||||
|
||||
|
||||
<xsl:when test="$curr-pref/gschematype = 's'">
|
||||
;; Gconf value (string): "<xsl:value-of select="./stringvalue"/>"
|
||||
(gnc-prefs-set-string
|
||||
; preference group
|
||||
"<xsl:value-of select="$curr-pref/../gschemaid"/>"
|
||||
; preference name
|
||||
"<xsl:value-of select="$curr-pref/gschemaname"/>"
|
||||
; preference value
|
||||
"<xsl:value-of select="./stringvalue"/>"
|
||||
)
|
||||
</xsl:when>
|
||||
|
||||
|
||||
<xsl:when test="$curr-pref/gschematype = 'x'">
|
||||
;; Gconf value (64bit integer): <xsl:value-of select="./@value"/>
|
||||
(gnc-prefs-set-int64
|
||||
; preference group
|
||||
"<xsl:value-of select="$curr-pref/../gschemaid"/>"
|
||||
; preference name
|
||||
"<xsl:value-of select="$curr-pref/gschemaname"/>"
|
||||
; preference value
|
||||
<xsl:value-of select="./@value"/>
|
||||
)
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="df:dateformats">
|
||||
<xsl:param name="curr-entry"/>
|
||||
<xsl:value-of select="key('datefmt-lookup', $curr-entry/stringvalue)/df:index"/>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<df:dateformats>
|
||||
<df:dateformat><df:name>us</df:name><df:index>0</df:index></df:dateformat>
|
||||
<df:dateformat><df:name>uk</df:name><df:index>1</df:index></df:dateformat>
|
||||
<df:dateformat><df:name>ce</df:name><df:index>2</df:index></df:dateformat>
|
||||
<df:dateformat><df:name>iso</df:name><df:index>3</df:index></df:dateformat>
|
||||
<df:dateformat><df:name>locale</df:name><df:index>4</df:index></df:dateformat>
|
||||
</df:dateformats>
|
||||
|
||||
</xsl:stylesheet>
|
1061
src/app-utils/migratable-prefs.xml
Normal file
1061
src/app-utils/migratable-prefs.xml
Normal file
File diff suppressed because it is too large
Load Diff
108
src/app-utils/migrate-prefs.scm
Normal file
108
src/app-utils/migrate-prefs.scm
Normal file
@ -0,0 +1,108 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; migrate-prefs.scm
|
||||
;;; Functions used to migrated user preferences from gconf
|
||||
;;; to gsettings. Note that this module doesn't perform the
|
||||
;;; migration itself: it merely prepares the environment to
|
||||
;;; create the actual migration script.
|
||||
;;;
|
||||
;;; Copyright 2013 Geert Janssens <geert@kobaltwit.be>
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-module (migrate-prefs))
|
||||
|
||||
(use-modules (gnucash core-utils))
|
||||
|
||||
(define gconf-dir (string-append (getenv "HOME") "/.gconf/apps/gnucash"))
|
||||
(define prefix-length (+ (string-length gconf-dir) 1))
|
||||
(define migration-dir (string-append (getenv "HOME") "/.gnc-migration-tmp"))
|
||||
|
||||
(define (copy-one-file filename)
|
||||
(let ((stats (stat filename))
|
||||
(base-name "")
|
||||
(slash-index 0)
|
||||
(dest-name ""))
|
||||
;(display "processing file... ")(display filename)(newline)
|
||||
(if (eq? (stat:type stats) 'regular)
|
||||
(begin
|
||||
(set! base-name (string-drop filename prefix-length))
|
||||
;(display base-name)(newline)
|
||||
(set! slash-index (- (string-rindex base-name #\%) 1))
|
||||
(if (> slash-index 0)
|
||||
(begin
|
||||
(set! dest-name (string-take base-name (- (string-rindex base-name #\%) 1)))
|
||||
(set! dest-name (string-join (string-split dest-name #\/) "-"))
|
||||
(set! dest-name (string-append migration-dir "/" dest-name ".xml"))
|
||||
;(format #t "~A -> ~A\n" base-name dest-name)
|
||||
(copy-file filename dest-name)
|
||||
))))
|
||||
(if (eq? (stat:type stats) 'directory)
|
||||
(apply find copy-one-file (list filename))
|
||||
)))
|
||||
|
||||
|
||||
(define (directory-files dir)
|
||||
(if (not (access? dir R_OK))
|
||||
'()
|
||||
(let* ((p (opendir dir))
|
||||
(filelist (do ((file (readdir p) (readdir p))
|
||||
(ls '()))
|
||||
((eof-object? file) (closedir p) (reverse! ls))
|
||||
(if (not (string-suffix? "." file))
|
||||
(set! ls (cons file ls)))
|
||||
)))
|
||||
(sort filelist string<))))
|
||||
|
||||
(define (find proc . dirs)
|
||||
(cond ((pair? dirs)
|
||||
(for-each proc (map (lambda (x) (string-append (car dirs) "/" x))
|
||||
(directory-files (car dirs)))))))
|
||||
|
||||
(define (finddepth proc . dirs)
|
||||
(cond ((pair? dirs)
|
||||
(apply finddepth proc (cdr dirs))
|
||||
(for-each proc (map (lambda (x) (string-append (car dirs) "/" x))
|
||||
(directory-files (car dirs)))))))
|
||||
|
||||
|
||||
(define (migration-prepare-internal)
|
||||
; cleanup first if a previous migration attempt failed to do so
|
||||
(if (access? migration-dir (logior R_OK W_OK X_OK))
|
||||
(begin
|
||||
(format #t "Clear previous tmp dir ~A\n" migration-dir)
|
||||
(migration-cleanup-internal)))
|
||||
(mkdir migration-dir)
|
||||
(format #t "Copy all gconf files to tmp dir ~A\n" migration-dir)
|
||||
(apply find copy-one-file (list gconf-dir))
|
||||
)
|
||||
|
||||
(define (migration-prepare)
|
||||
(if (access? gconf-dir R_OK)
|
||||
(begin
|
||||
(display "*** GnuCash switched to a new preferences system ***\n")
|
||||
(display "Attempt to migrate your preferences from the old to the new system\n")
|
||||
(catch #t
|
||||
migration-prepare-internal
|
||||
(lambda args
|
||||
(display "An error occurred when trying to migrate preferences")))
|
||||
)))
|
||||
|
||||
(define (rmtree args)
|
||||
(define (zap f)
|
||||
(let ((rm (if (eq? (stat:type (stat f)) 'directory) rmdir delete-file)))
|
||||
;(format #t "deleting ~A\n" f)
|
||||
(catch #t
|
||||
(lambda () (rm f))
|
||||
(lambda args (format #t "couldn't delete ~A\n" f)))))
|
||||
(apply finddepth zap args))
|
||||
|
||||
(define (migration-cleanup-internal)
|
||||
(rmtree (list migration-dir))
|
||||
(rmdir migration-dir))
|
||||
|
||||
(define (migration-cleanup)
|
||||
(if (access? migration-dir (logior R_OK W_OK X_OK))
|
||||
(begin
|
||||
(format #t "Delete tmp dir ~A\n" migration-dir)
|
||||
(migration-cleanup-internal))))
|
||||
|
||||
(export migration-prepare migration-cleanup)
|
@ -34,3 +34,10 @@
|
||||
(re-export gnc-scm-log-msg)
|
||||
(re-export gnc-scm-log-debug)
|
||||
(re-export gnc-locale-default-iso-currency-code)
|
||||
|
||||
(re-export gnc-prefs-set-bool)
|
||||
(re-export gnc-prefs-set-int)
|
||||
(re-export gnc-prefs-set-int64)
|
||||
(re-export gnc-prefs-set-float)
|
||||
(re-export gnc-prefs-set-string)
|
||||
(re-export gnc-prefs-set-coords)
|
||||
|
Loading…
Reference in New Issue
Block a user