summaryrefslogtreecommitdiff
path: root/src/python/persist.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/python/persist.py')
-rw-r--r--src/python/persist.py157
1 files changed, 157 insertions, 0 deletions
diff --git a/src/python/persist.py b/src/python/persist.py
new file mode 100644
index 0000000..1357609
--- /dev/null
+++ b/src/python/persist.py
@@ -0,0 +1,157 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file is OXullo Interecans <x at brainrapers dot org>
+
+
+import os
+import time
+import cPickle as pickle
+
+import libavg
+
+
+class Persist(object):
+ def __init__(self, storeFile, initialData, validator=lambda v: True,
+ autoCommit=False):
+ self.__storeFile = storeFile
+
+ if hasattr(initialData, '__call__'):
+ initialData = initialData()
+ elif initialData is None:
+ initialData = dict()
+
+ if os.path.exists(self.__storeFile):
+ if not os.path.isfile:
+ raise RuntimeError('%s dump file is not a plain file' % self)
+ elif not os.access(self.__storeFile, os.R_OK | os.W_OK):
+ raise RuntimeError('%s dump file'
+ 'cannot be accessed with r/w permissions' % self)
+
+ try:
+ f = open(self.__storeFile)
+ except IOError:
+ libavg.logger.debug('Initializing %s' % self)
+ self.data = initialData
+ self.commit()
+ else:
+ try:
+ self.data = pickle.load(f)
+ except:
+ f.close()
+ libavg.logger.warning('Persist %s is corrupted or unreadable, '
+ 'reinitializing' % self)
+ self.data = initialData
+ self.commit()
+ else:
+ f.close()
+ if not validator(self.data):
+ libavg.logger.warning('Sanity check failed for %s, '
+ 'reinitializing' % self)
+ self.data = initialData
+ self.commit()
+ else:
+ libavg.logger.debug('%s successfully loaded' % self)
+
+ if autoCommit:
+ import atexit
+ atexit.register(self.commit)
+
+ def __repr__(self):
+ return '<%s %s>' % (self.__class__.__name__, self.__storeFile)
+
+ @property
+ def storeFile(self):
+ return self.__storeFile
+
+ def commit(self):
+ tempFile = self.__storeFile + '.tmp.' + str(int(time.time() * 1000))
+
+ try:
+ with open(tempFile, 'wb') as f:
+ pickle.dump(self.data, f)
+ except Exception, e:
+ libavg.logger.warning('Cannot save %s (%s)' % (self.__storeFile, str(e)))
+ return False
+ else:
+ if os.path.exists(self.__storeFile):
+ try:
+ os.remove(self.__storeFile)
+ except Exception, e:
+ libavg.logger.warning('Cannot overwrite dump file '
+ '%s (%s)' % (self, str(e)))
+ return False
+ try:
+ os.rename(tempFile, self.__storeFile)
+ except Exception, e:
+ libavg.logger.warning('Cannot save %s (%s)' % (self, str(e)))
+ os.remove(tempFile)
+ return False
+ else:
+ libavg.logger.debug('%s saved' % self)
+ return True
+
+
+class UserPersistentData(Persist):
+ def __init__(self, appName, fileName, *args, **kargs):
+ basePath = os.path.join(self._getUserDataPath(), appName)
+ fullPath = os.path.join(basePath, '%s.pkl' % fileName)
+
+ try:
+ os.makedirs(basePath)
+ except OSError, e:
+ import errno
+ if e.errno != errno.EEXIST:
+ raise
+
+ super(UserPersistentData, self).__init__(fullPath, *args, **kargs)
+
+ def _getUserDataPath(self):
+ if os.name == 'posix':
+ path = os.path.join(os.environ['HOME'], '.avg')
+ elif os.name == 'nt':
+ path = os.path.join(os.environ['APPDATA'], 'Avg')
+ else:
+ raise RuntimeError('Unsupported system %s' % os.name)
+
+ return path
+
+
+if __name__ == '__main__':
+ testFile = './testfile.pkl'
+ initialData = {'initial': True}
+ p = Persist(testFile, initialData)
+ p.commit()
+ p.data['initial'] = False
+ p.commit()
+
+ p = Persist(testFile, initialData)
+ print not p.data['initial']
+
+ os.unlink(testFile)
+
+ p = UserPersistentData('myapp', 'hiscore', initialData)
+ p.data['initial'] = False
+ p.commit()
+
+ print p
+