From b3137d835c734856315bcd659010c1c9425a10d9 Mon Sep 17 00:00:00 2001 From: Andreas Florath Date: Thu, 27 Dec 2012 22:17:37 +0100 Subject: [PATCH] Finished UserPreferences writing and reading --- rmtoo/lib/GenNonEmptyDict.py | 5 +- rmtoo/lib/RequirementSet.py | 4 +- rmtoo/lib/UserPreferences.py | 83 ++++++++++++++++++- .../UnitTest/CoreTests/TestUserPreferences.py | 31 ++++++- 4 files changed, 114 insertions(+), 9 deletions(-) diff --git a/rmtoo/lib/GenNonEmptyDict.py b/rmtoo/lib/GenNonEmptyDict.py index 9e55eb8f..73a8126b 100644 --- a/rmtoo/lib/GenNonEmptyDict.py +++ b/rmtoo/lib/GenNonEmptyDict.py @@ -27,4 +27,7 @@ def __getitem__(self, key): if key not in self.__dict: self.__dict[key] = self.__factory(key) return self.__dict[key] - \ No newline at end of file + + def iteritems(self): + '''Passes the things directly from the dict.''' + return self.__dict.iteritems() \ No newline at end of file diff --git a/rmtoo/lib/RequirementSet.py b/rmtoo/lib/RequirementSet.py index a6b0c6c4..939b4b59 100644 --- a/rmtoo/lib/RequirementSet.py +++ b/rmtoo/lib/RequirementSet.py @@ -2,7 +2,7 @@ rmtoo Free and Open Source Requirements Management Tool - ??? + Container object which holds the set of requirements. (c) 2010-2012 by flonatel GmbH & Co. KG @@ -674,7 +674,7 @@ def normalize_dependencies(self): tracer.debug("[%s] Try to add 'Solved by' [%s]." % (r.get_name(), on)) record.set_content("Solved by", on) - except ValueError, ve: + except ValueError: tracer.debug("[%s] Try to append 'Solved by' [%s]." % (r.get_name(), on)) record.append_entry(RecordEntry( diff --git a/rmtoo/lib/UserPreferences.py b/rmtoo/lib/UserPreferences.py index c2c28ad7..58b97a41 100644 --- a/rmtoo/lib/UserPreferences.py +++ b/rmtoo/lib/UserPreferences.py @@ -10,16 +10,28 @@ ''' import os +import tempfile +import json +import shutil +from rmtoo.lib.logging import tracer from rmtoo.lib.GenNonEmptyDict import GenNonEmptyDict class FileStorage(object): '''Holds all the values which go in one file.''' - def __init__(self, rel_filename): + def __init__(self, rel_filename, base_dir): '''Initializaes the FileStorage with the relative filename.''' self.__rel_filename = rel_filename + self.__base_dir = base_dir + self.__filename = os.path.join(self.__base_dir, self.__rel_filename) self.__dict = {} + + def read(self): + '''Reads in the file content from the filesystem.''' + with open(self.__filename, 'r') as f: + s = f.read() + self.__dict = json.loads(s) def set_value(self, key, value): '''Directly access the underlaying dict.''' @@ -28,7 +40,55 @@ def set_value(self, key, value): def get_value(self, key): '''Directly access the underlaying dict.''' return self.__dict[key] + + def __write_tmp(self): + '''Write the data to a temporaty file and return the filename.''' + tracer.debug("called") + try: + tracer.debug("Create temp file") + tfile = tempfile.NamedTemporaryFile(dir=self.__base_dir, + delete=False) + tracer.debug("Write to temp file [%s]." % tfile.name) + tfile.write(json.dumps(self.__dict, sort_keys=True, indent=2)) + tracer.debug("Wrote to temp file") + except Exception as ex: + tracer.warn("Exception during writing temp data [%s]" % ex) + finally: + tracer.debug("Close temp file") + tfile.close() + tracer.debug("finished") + return tfile.name + + def __move_tmp(self, tmpfilename): + '''Moves the tmpfilename to the original file - as atomar + as possible.''' + tracer.debug("Moving [%s] -> [%s]" % (tmpfilename, self.__filename)) + shutil.move(tmpfilename, self.__filename) + def __remove_tmp(self, tmpfilename): + '''Remove the tmpfilename - if exists.''' + try: + os.remove(tmpfilename) + except OSError as ose: + if ose.errno == 2: + # In this case the file did not exists - so it is removed + return + raise + + def write(self): + '''Writes the current content to the file.''' + tracer.debug("Write preferences data to file") + try: + tmpfilename = self.__write_tmp() + tracer.debug("Wrote data to [%s]" % tmpfilename) + self.__move_tmp(tmpfilename) + except Exception as ex: + tracer.warn("Exception during writing data [%s]: [%s]" + % (self.__rel_filename, ex)) + finally: + self.__remove_tmp(tmpfilename) + tracer.debug("Finished writing properties to file.") + class UserPreferences(object): '''Global User Preferences handling. There are some global user preferences which must be stored @@ -50,8 +110,20 @@ def __eval_rmtoo_home_dir(rmtoo_home_dir): def __init__(self, rmtoo_home_dir=None): '''Constructs a User Preferences object which can hold and store configuration values.''' + + def __create_new_FileStorage(rel_filename): + return FileStorage(rel_filename, self.__rmtoo_home_dir) + self.__rmtoo_home_dir = self.__eval_rmtoo_home_dir(rmtoo_home_dir) - self.__file_storage = GenNonEmptyDict(FileStorage) + self.__file_storage = GenNonEmptyDict(__create_new_FileStorage) + + def read(self): + '''Reads in all the files in the home directory and puts them + into internal memory.''' + for f in os.listdir(self.__rmtoo_home_dir): + fs = FileStorage(f, self.__rmtoo_home_dir) + fs.read() + self.__file_storage.insert(f, fs) def get_rmtoo_home_dir(self): '''Returns the used home directory.''' @@ -64,4 +136,9 @@ def set_value(self, filename, propname, value): def get_value(self, filename, propname): '''Gets the property from the file.''' - return self.__file_storage[filename].get_value(propname) \ No newline at end of file + return self.__file_storage[filename].get_value(propname) + + def write(self): + '''Write the whole set of files to the directory.''' + for _, f in self.__file_storage.iteritems(): + f.write() \ No newline at end of file diff --git a/rmtoo/tests/UnitTest/CoreTests/TestUserPreferences.py b/rmtoo/tests/UnitTest/CoreTests/TestUserPreferences.py index 4867ee89..de76abeb 100644 --- a/rmtoo/tests/UnitTest/CoreTests/TestUserPreferences.py +++ b/rmtoo/tests/UnitTest/CoreTests/TestUserPreferences.py @@ -11,6 +11,8 @@ import os import unittest +import tempfile +import shutil from rmtoo.lib.UserPreferences import UserPreferences @@ -19,17 +21,40 @@ class TestUserPreferences(unittest.TestCase): def test_set_rmtoo_home_dir(self): '''UserPreferences: check if the rmtoo home dir is set correctly.''' up = UserPreferences("/tmp/my/path") - assert(up.get_rmtoo_home_dir() == "/tmp/my/path") + self.assertEqual("/tmp/my/path", up.get_rmtoo_home_dir()) def test_default_rmtoo_home_dir(self): '''UserPreferences: check if the default rmtoo home dir works.''' up = UserPreferences() - assert(up.get_rmtoo_home_dir() == os.path.expanduser("~/.rmtoo")) + self.assertEqual(os.path.expanduser("~/.rmtoo"), + up.get_rmtoo_home_dir()) def test_add_new_value(self): '''UserPreferences: add new value to preferences.''' mid = "ThisIsMyNotSoAutomatedGeneratedId" up = UserPreferences() up.set_value("stats", "id", mid) - assert(up.get_value("stats", "id") == mid) + self.assertEqual(mid, up.get_value("stats", "id")) + + def test_get_nonex_value(self): + '''UserPreferences: Get a non existing value''' + up = UserPreferences() + self.assertRaises(KeyError, up.get_value, "dasIst", "nicht,da") + + def test_basic_io(self): + '''UserPreferences: create prefs, write them, read them''' + mid = "ThisIsMyNotSoAutomatedGeneratedId" + tdir = tempfile.mkdtemp() + + up = UserPreferences(tdir) + up.set_value("stats", "id", mid) + up.write() + + upr = UserPreferences(tdir) + upr.read() + val = upr.get_value("stats", "id") + + shutil.rmtree(tdir) + + self.assertEqual(mid, val) \ No newline at end of file