Преглед изворни кода

introduce base class for storage

The base class will contain logical data access functions,
the subclass will handle the persisting layer.
Helge Jung пре 9 година
родитељ
комит
f6149fb812
3 измењених фајлова са 54 додато и 5 уклоњено
  1. 35 0
      ffstatus/basestorage.py
  2. 1 1
      ffstatus/server.py
  3. 18 4
      ffstatus/storage.py

+ 35 - 0
ffstatus/basestorage.py

@@ -0,0 +1,35 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+from __future__ import print_function, unicode_literals
+
+class BaseStorage(object):
+    """
+    Provides operations on the storage data.
+    This class gets subclassed to actually write the data
+    to a file, database, whatever.
+    """
+
+    data = None
+
+    def open(self):
+        """
+        When overridden in a subclass,
+        closes the persistent storage.
+        """
+        pass
+
+    def save(self):
+        """
+        When overriden in a subclass,
+        stores the data to a persistent storage.
+        """
+        pass
+
+    def close(self):
+        """
+        When overridden in a subclass,
+        closes the persistent storage.
+        """
+        pass
+

+ 1 - 1
ffstatus/server.py

@@ -625,7 +625,7 @@ class ApiServer(ThreadingMixIn, HTTPServer):
         return 'ApiServer on {0}'.format(self.server_address)
         return 'ApiServer on {0}'.format(self.server_address)
 
 
 if __name__ == '__main__':
 if __name__ == '__main__':
-    dummystorage = Storage()
+    dummystorage = ffstatus.basestorage.BaseStorage()
     server = ApiServer(('0.0.0.0', 8888), dummystorage)
     server = ApiServer(('0.0.0.0', 8888), dummystorage)
 
 
     print("Server:", str(server))
     print("Server:", str(server))

+ 18 - 4
ffstatus/storage.py

@@ -5,31 +5,44 @@ import cPickle as pickle
 import logging
 import logging
 import os
 import os
 
 
-class Storage:
-    data = None
+from .basestorage import BaseStorage
+
+class Storage(BaseStorage):
+    """Provides file-based persistency for BaseStorage"""
 
 
     def __init__(self, storage_dir):
     def __init__(self, storage_dir):
         self.logger = logging.getLogger('Storage')
         self.logger = logging.getLogger('Storage')
         self.storage_dir = storage_dir
         self.storage_dir = storage_dir
 
 
         self.logger.debug('Using storage at \'{0}\''.format(storage_dir))
         self.logger.debug('Using storage at \'{0}\''.format(storage_dir))
-        self.storage_file = open(os.path.join(storage_dir, 'storage.dat'), 'a+b')
+        self.storage_filename = os.path.join(storage_dir, 'storage.dat')
+
+        self.storage_file = None
+
+    def open(self):
+        self.storage_file = open(self.storage_filename, 'a+b')
         try:
         try:
             self.storage_file.seek(0, os.SEEK_SET)
             self.storage_file.seek(0, os.SEEK_SET)
             self.data = pickle.load(self.storage_file)
             self.data = pickle.load(self.storage_file)
+
         except EOFError:
         except EOFError:
             self.logger.warn('The storage file was empty. I\'ll assume this is the first start with this storage directory.')
             self.logger.warn('The storage file was empty. I\'ll assume this is the first start with this storage directory.')
+
         except Exception as err:
         except Exception as err:
             self.logger.error('Loading the storage failed. Please resolve the error and/or remove the storage file \'{0}\': {1}'.format(
             self.logger.error('Loading the storage failed. Please resolve the error and/or remove the storage file \'{0}\': {1}'.format(
-                os.path.join(storage_dir, self.storage_file.name),
+                self.storage_filename,
                 str(err),
                 str(err),
             ))
             ))
             raise err
             raise err
+
         if self.data is None:
         if self.data is None:
             self.data = {}
             self.data = {}
         self.logger.info('Opened storage with ' + str(len(self.data)) + ' entries.')
         self.logger.info('Opened storage with ' + str(len(self.data)) + ' entries.')
 
 
     def save(self):
     def save(self):
+        if self.storage_file is None:
+            return
+
         self.storage_file.seek(0, os.SEEK_SET)
         self.storage_file.seek(0, os.SEEK_SET)
         self.storage_file.truncate()
         self.storage_file.truncate()
         pickle.dump(self.data, self.storage_file, protocol=2)
         pickle.dump(self.data, self.storage_file, protocol=2)
@@ -38,4 +51,5 @@ class Storage:
     def close(self):
     def close(self):
         self.save()
         self.save()
         self.storage_file.close()
         self.storage_file.close()
+        self.storage_file = None
         self.data = None
         self.data = None