Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'release/scripts/bpymodules/BPyRegistry.py')
-rw-r--r--release/scripts/bpymodules/BPyRegistry.py248
1 files changed, 248 insertions, 0 deletions
diff --git a/release/scripts/bpymodules/BPyRegistry.py b/release/scripts/bpymodules/BPyRegistry.py
new file mode 100644
index 00000000000..33e438be79e
--- /dev/null
+++ b/release/scripts/bpymodules/BPyRegistry.py
@@ -0,0 +1,248 @@
+# --------------------------------------------------------------------------
+# Module BPyRegistry version 0.1
+# Helper functions to store / restore configuration data.
+# --------------------------------------------------------------------------
+# $Id$
+#
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# Copyright (C) 2004: Willian P. Germano, wgermano _at_ ig.com.br
+#
+# This program 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 2
+# of the License, or (at your option) any later version.
+#
+# This program 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 this program; if not, write to the Free Software Foundation,
+# --------------------------------------------------------------------------
+
+# The Registry is a Python dictionary that is kept in Blender for as long as
+# the program is running, where scripts can store / restore persistent data
+# (data that is not lost when the script exits). This module provides
+# functions to save and restore Registry entries as config data in the
+# bpydata/config folder. Scripts just need to give an extra parameter to
+# the Blender.Registry.Get/Set() functions to have their data automatically
+# saved and restored when needed.
+#
+# Note: entries starting with an underscore are not saved, so script authors
+# can use that fact to define data that is not meant to be stored in a
+# config file. Example: data to be passed to another script and references to
+# invalid data, like Blender objects and any function or method.
+#
+# Check the Blender.Registry documentation for more information.
+
+import Blender
+from Blender import Registry, sys as bsys
+
+_EXT = '.cfg' # file extension for saved config data
+
+# limits:
+MAX_ITEMS_NUM = 50 # max number of keys per dict and itens per list and tuple
+MAX_STR_LEN = 300 # max string length (remember this is just for config data)
+
+_CFG_DIR = ''
+if Blender.Get('udatadir'):
+ _CFG_DIR = Blender.sys.join(Blender.Get('udatadir'), 'config')
+if not _CFG_DIR or not bsys.exists(_CFG_DIR):
+ _CFG_DIR = Blender.sys.join(Blender.Get('datadir'), 'config')
+if not bsys.exists(_CFG_DIR):
+ _CFG_DIR = ''
+
+# to compare against, so we don't write to a cvs tree:
+_CVS_SUBPATH = 'release/scripts/bpydata/config/'
+if bsys.dirsep == '\\':
+ _CVS_SUBPATH = _CVS_SUBPATH.replace('/', '\\')
+
+_KEYS = [k for k in Registry.Keys() if k[0] != '_']
+
+def _sanitize(o):
+ "Check recursively that all objects are valid, set invalid ones to None"
+
+ global MAX_ITEMS_NUM, MAX_STR_LEN
+
+ valid_types = [int, float, bool, long, type]
+ valid_checked_types = [str, unicode]
+ # Only very simple types are considered valid for configuration data,
+ # functions, methods and Blender objects (use their names instead) aren't.
+
+ t = type(o)
+
+ if t == dict:
+ keys = o.keys()
+ if len(keys) > MAX_ITEMS_NUM:
+ return None
+ for k in keys:
+ o[k] = _sanitize(o[k])
+ elif t in [list, tuple]:
+ if len(o) > MAX_ITEMS_NUM:
+ return None
+ result = []
+ for i in o: result.append(_sanitize(i))
+ return result
+ elif t in valid_types:
+ return o
+ elif t in valid_checked_types:
+ if len(o) > MAX_STR_LEN:
+ o = o[:MAX_STR_LEN]
+ return o
+ else: return None
+
+ return o
+
+
+def _dict_to_str(name, d):
+ "Return a pretty-print version of the passed dictionary"
+
+ if name: l = ['%s = {' % name]
+ else: l = ['{']
+ keys = d.keys()
+ for k in keys:
+ if type(d[k]) == dict:
+ l.append("'%s': %s" % (k, _dict_to_str(None, d[k])))
+ else:
+ l.append("'%s': %s," % (k, repr(d[k])))
+ if name: l.append('}')
+ else: l.append('},')
+ return "\n".join(l)
+
+_HELP_MSG = """
+Please create a valid scripts config dir tree either by
+copying release/scripts/ tree to your <blenderhome> dir
+or by copying release/scripts/bpydata/ tree to a user
+defined scripts dir that you can set in the
+User Preferences -> Paths tab -> Python path input box.
+"""
+
+def _check_dir():
+ global _CFG_DIR, _CVS_SUBPATH, _HELP_MSG
+
+ if not _CFG_DIR:
+ errmsg = "scripts config dir not found!\n%s" % _HELP_MSG
+ raise IOError, errmsg
+ elif _CFG_DIR.find(_CVS_SUBPATH) > 0:
+ errmsg = """
+Your scripts config dir:\n%s
+seems to reside in your local Blender's cvs tree.\n%s""" % (_CFG_DIR, _HELP_MSG)
+ raise SystemError, errmsg
+ else: return
+
+
+# API:
+
+BPY_KEY_MISSING = 0
+BPY_KEY_IN_REGISTRY = 1
+BPY_KEY_IN_FILE = 2
+
+def HasConfigData (key):
+ """
+ Check if the given key exists, either already loaded in the Registry dict or
+ as a file in the script data config dir.
+ @type key: string
+ @param key: a given key name.
+ @returns:
+ - 0: key does not exist;
+ - 1: key exists in the Registry dict only;
+ - 2: key exists as a file only;
+ - 3: key exists in the Registry dict and also as a file.
+ @note: for readability it's better to check against the constant bitmasks
+ BPY_KEY_MISSING = 0, BPY_KEY_IN_REGISTRY = 1 and BPY_KEY_IN_FILE = 2.
+ """
+
+ fname = bsys.join(_CFG_DIR, "%s%s" % (key, _EXT))
+
+ result = BPY_KEY_MISSING
+ if key in Registry.Keys(): result |= BPY_KEY_IN_REGISTRY
+ if bsys.exists(fname): result |= BPY_KEY_IN_FILE
+
+ return result
+
+
+def LoadConfigData (key = None):
+ """
+ Load config data from file(s) to the Registry dictionary.
+ @type key: string
+ @param key: a given key name. If None (default), all available keys are
+ loaded.
+ @returns: None
+ """
+
+ _check_dir()
+
+ import os
+
+ if not key:
+ files = \
+ [bsys.join(_CFG_DIR, f) for f in os.listdir(_CFG_DIR) if f[-4:] == _EXT]
+ else:
+ files = []
+ fname = bsys.join(_CFG_DIR, "%s%s" % (key, _EXT))
+ if bsys.exists(fname): files.append(fname)
+
+ for p in files:
+ f = file(p, 'r')
+ lines = f.readlines()
+ f.close()
+ mainkey = lines[0].split('=')[0].strip()
+ pysrc = "\n".join(lines)
+ exec(pysrc)
+ exec("Registry.SetKey('%s', %s)" % (str(mainkey), mainkey))
+
+
+def RemoveConfigData (key = None):
+ """
+ Remove this key's config file from the <(u)datadir>/config/ folder.
+ @type key: string
+ @param key: the name of the key to be removed. If None (default) all
+ available config files are deleted.
+ """
+
+ _check_dir()
+
+ if not key:
+ files = \
+ [bsys.join(_CFG_DIR, f) for f in os.listdir(_CFG_DIR) if f[-4:] == _EXT]
+ else:
+ files = []
+ fname = bsys.join(_CFG_DIR, "%s%s" % (key, _EXT))
+ if bsys.exists(fname): files.append(fname)
+
+ import os
+
+ for p in files:
+ os.remove(p) # remove the file(s)
+
+
+def SaveConfigData (key = None):
+ """
+ Save Registry key(s) as file(s) in the <(u)datadir>/config/ folder.
+ @type key: string
+ @param key: the name of the key to be saved. If None (default) all
+ available keys are saved.
+ """
+
+ global _KEYS, _CFG_DIR
+
+ _check_dir()
+
+ if key: keys = [key]
+ else: keys = _KEYS
+
+ for mainkey in keys:
+ cfgdict = Registry.GetKey(mainkey).copy()
+ for k in cfgdict.keys():
+ if k[0] == '_': cfgdict.pop(k)
+
+ if not cfgdict: continue
+
+ filename = bsys.join(_CFG_DIR, "%s%s" % (mainkey, _EXT))
+ f = file(filename, 'w')
+ output = _dict_to_str(mainkey, _sanitize(cfgdict))
+ f.write(output)
+ f.close()
+