Bug#535569: Further update-gconf-defaults improvements.

Trent W. Buck trentbuck at gmail.com
Fri Jul 3 10:42:33 UTC 2009


Package: gconf2
Version: 2.26.2-1
Severity: wishlist
File: /usr/bin/update-gconf-defaults
Tags: patch

Hi Josselin,

Please find attached two further patches I have written for
update-gconf-defaults.  The first simply allows you to write comment
lines like

    # Epiphany

in the input files.  This just strikes me as an obvious thing, because
it allows you to safely include explanatory comments in the pref files.

The second makes the script ignore files that do not match the
patterns described by run-parts(1), so for example anything with a dot
in it will be ignored.  This is important for me as I have things like
inc.mk in the my private source directory.  It would also be useful if
you wanted to store the source files in ~/.gconf itself!

I also wanted to set up parsing of .ini-style sections, so that you
could have shorter/more readable entries by writing things like

    [apps/epiphany/general]
    homepage = about:blank
    show_toolbars = false

    [apps/gnome-screensaver]
    idle_delay = 2
    lock_delay = 1
    mode = blank-only

Instead of

    /apps/epiphany/general/homepage = about:blank
    /apps/epiphany/general/show_toolbars = false
    /apps/gnome-screensaver/idle_delay = 2
    /apps/gnome-screensaver/lock_delay = 1
    /apps/gnome-screensaver/mode = blank-only

Unfortunately I ran out of time before implementing that.

PS: You might find os.path.join(x,y) more readable than x+'/'+y.
-------------- next part --------------
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
# ? 2005 Josselin Mouette <joss at debian.org>
# Licensed under the GNU LGPL, see /usr/share/common-licenses/LGPL-2.1

treefile = '%gconf-tree.xml'

import os,tempfile,shutil,sys,re
from optparse import OptionParser

parser = OptionParser()
parser.add_option("--source", dest="source_dir", default="/usr/share/gconf/defaults",
                  help="directory where to find the defaults", metavar="DIR")
parser.add_option("--destination", dest="dest_dir", default="/var/lib/gconf/debian.defaults",
                  help="directory where to build the GConf tree", metavar="DIR")
parser.add_option("--mandatory", action="store_true", default=False, dest="mandatory",
                  help="select mandatory settings directories")
parser.add_option("--no-signal", action="store_false", default=True, dest="signal",
                  help="do not send SIGHUP the running gconfd-2 processes")

(options, args) = parser.parse_args()

if options.mandatory:
    options.source_dir="/usr/share/gconf/mandatory"
    options.dest_dir="/var/lib/gconf/debian.mandatory"

if not os.path.isdir(options.source_dir):
    parser.error("Source directory does not exist.")
if not os.path.isdir(options.dest_dir):
    parser.error("Destination directory does not exist.")
if not os.access(options.source_dir,os.R_OK|os.X_OK):
    parser.error("Source directory is not readable.")
if not os.access(options.dest_dir,os.W_OK|os.X_OK):
    parser.error("Destination directory is not writable.")

tmp_dir=tempfile.mkdtemp(prefix="gconf-")
tmp_home=tmp_dir+'/home'
tmp_gconf=tmp_dir+'/gconf'
tmp_file=tmp_dir+'/temp.entries'

save_stdout=os.dup(1)
os.close(1)

def cleanup():
  os.dup2(save_stdout,1)
  os.close(save_stdout)
  shutil.rmtree(tmp_dir)

def htmlescape(str):
  return str.replace('&','&amp;').replace('>','&gt;').replace('<','&lt;').replace('"','&quot;')

def int_entry(value):
  return '  <int>' + value + '</int>\n'

def bool_entry(value):
  return '  <bool>' + value + '</bool>\n'

def float_entry(value):
  return '  <float>' + value + '</float>\n'

def string_entry(value):
  return '  <string>' + htmlescape(value) + '</string>\n'

def list_entry(value):
  ret = '  <list type="string">\n'
  for v in value[1:-1].split(','):
    ret += '    <value><string>' + htmlescape(v) + '</string></value>\n'
  ret += '  </list>\n'
  return ret


def listcmp(a,b):
  """Number of starting similar elements in a and b"""
  m = min(len(a),len(b))
  for i in range(m):
    if a[i] != b[i]:
      return i
  return m

def apply_entries(filename):
  res=os.spawnvpe(os.P_WAIT,'gconftool-2',
           ['gconftool-2','--direct','--config-source',
            'xml:merged:'+tmp_gconf,'--load',filename],
           {'HOME': tmp_home})
  if res:
    cleanup()
    sys.exit(res)

gconf_val = {}

def write_and_apply_entries(filename):
  out=file(filename,'w')
  out.write('<gconfentryfile>\n<entrylist base="/">\n')
  for key in gconf_val:
    out.write('<entry>\n<key>' + key + '</key>\n<value>\n')
    # write the current entry
    value = gconf_val[key]
    if value[0] == '"' and value[-1] == '"':
      out.write(string_entry(value[1:-1]))
    elif value in ['true','false']:
      out.write(bool_entry(value))
    elif value[0] == '[' and value[-1] == ']':
      out.write(list_entry(value))
    elif value.isdigit():
      out.write(int_entry(value))
    else:
      try:
        float(value)
        out.write(float_entry(value))
      except ValueError:
        out.write(string_entry(value))
    out.write('</value>\n</entry>\n')
  out.write('</entrylist>\n</gconfentryfile>\n')
  out.close()
  apply_entries(filename)

def read_entries(filename):
  for line in file(filename):
    l = line.rstrip('\n').split(None,1)
    if len(l) == 2 and l[0] != '#':
      gconf_val[l[0]] = l[1]


# Mimic run-parts(1) regarding valid file names.
valid_re = '(^|/)(' + '|'.join([
        '[a-z0-9]+',                  # LANANA-assigned namespace
        '_?([a-z0-9_.]+-)+[a-z0-9]+', # LSB hierarchical and reserved namespaces
        '[a-z0-9][a-z0-9-]*',         # Debian cron script namespace
        '[^/]\\.entries'              # .entries (backwards compatibility)
        ]) + ')$'

# Generate a list of absolute paths of files in source_dir that
# match the valid regexp.
defaults_files = [os.path.join(options.source_dir,f)
                  for f in os.listdir(options.source_dir)
                  if re.match(valid_re, f)]
for f in defaults_files:
  if f.endswith('.entries'):
    if gconf_val:
      write_and_apply_entries(tmp_file)
      gconf_val={}
    apply_entries(f)
  else:
    read_entries(f)
if gconf_val:
  write_and_apply_entries(tmp_file)

try:
  shutil.copyfile(tmp_gconf+'/'+treefile,options.dest_dir+'/'+treefile+'.tmp')
  os.rename(options.dest_dir+'/'+treefile+'.tmp',options.dest_dir+'/'+treefile)
except IOError:
  # No %gconf-tree.xml file was created.
  try:
    os.remove(options.dest_dir+'/'+treefile)
  except OSError:
    # No existing file
    pass

cleanup()

if options.signal:
    os.system('kill -s HUP `pidof gconfd-2` >/dev/null 2>&1')
-------------- next part --------------
Wed Jan 21 15:16:59 EST 2009  Trent W. Buck <trentbuck at gmail.com>
  * Fix coding so Emacs can write the file.
diff -rN -purd -u /usr/bin/update-gconf-defaults /usr/bin/update-gconf-defaults
--- /usr/bin/update-gconf-defaults	2009-07-03 20:40:10.457174602 +1000
+++ /usr/bin/update-gconf-defaults	2009-07-03 20:40:11.813169293 +1000
@@ -1,5 +1,5 @@
 #! /usr/bin/python
-# -*- coding: UTF-8 -*-
+# -*- coding: utf-8 -*-
 #
 # ? 2005 Josselin Mouette <joss at debian.org>
 # Licensed under the GNU LGPL, see /usr/share/common-licenses/LGPL-2.1
Wed Jan 21 15:50:41 EST 2009  Trent W. Buck <trentbuck at gmail.com>
  * Ignore "# comment" lines.
diff -rN -purd -u /usr/bin/update-gconf-defaults /usr/bin/update-gconf-defaults
--- /usr/bin/update-gconf-defaults	2009-07-03 20:40:34.953175349 +1000
+++ /usr/bin/update-gconf-defaults	2009-07-03 20:40:35.305177893 +1000
@@ -99,7 +99,7 @@ def write_and_apply_entries(filename):
 def read_entries(filename):
   for line in file(filename):
     l = line.rstrip('\n').split(None,1)
-    if len(l) == 2:
+    if len(l) == 2 and l[0] != '#':
       gconf_val[l[0]] = l[1]
 
 
Fri Jul  3 20:37:02 EST 2009  Trent W. Buck <trentbuck at gmail.com>
  * Mimic run-parts(1) regarding valid file names.
diff -rN -purd -u /usr/bin/update-gconf-defaults /usr/bin/update-gconf-defaults
--- /usr/bin/update-gconf-defaults	2009-07-03 20:40:58.589176403 +1000
+++ /usr/bin/update-gconf-defaults	2009-07-03 20:40:58.661175063 +1000
@@ -6,7 +6,7 @@
 
 treefile = '%gconf-tree.xml'
 
-import os,tempfile,shutil,sys
+import os,tempfile,shutil,sys,re
 from optparse import OptionParser
 
 parser = OptionParser()
@@ -122,20 +122,26 @@ def read_entries(filename):
       gconf_val[l[0]] = l[1]
 
 
-defaults_files = os.listdir(options.source_dir)
-defaults_files.sort()
+# Mimic run-parts(1) regarding valid file names.
+valid_re = '(^|/)(' + '|'.join([
+        '[a-z0-9]+',                  # LANANA-assigned namespace
+        '_?([a-z0-9_.]+-)+[a-z0-9]+', # LSB hierarchical and reserved namespaces
+        '[a-z0-9][a-z0-9-]*',         # Debian cron script namespace
+        '[^/]\\.entries'              # .entries (backwards compatibility)
+        ]) + ')$'
+# Generate a list of absolute paths of files in source_dir that
+# match the valid regexp.
+defaults_files = [os.path.join(options.source_dir,f)
+                  for f in os.listdir(options.source_dir)
+                  if re.match(valid_re, f)]
 for f in defaults_files:
-  realname=options.source_dir+'/'+f
-  for ext in ['.dpkg-tmp', '.bak', '.tmp', '~', '.sav', '.save']:
-    if f.endswith(ext):
-      continue
   if f.endswith('.entries'):
     if gconf_val:
       write_and_apply_entries(tmp_file)
       gconf_val={}
-    apply_entries(realname)
+    apply_entries(f)
   else:
-    read_entries(realname)
+    read_entries(f)
 if gconf_val:
   write_and_apply_entries(tmp_file)
 


More information about the pkg-gnome-maintainers mailing list