From 06820530048a9570390b5501350d4fbe6c621f07 Mon Sep 17 00:00:00 2001 From: Adam Sampson Date: Mon, 5 May 2003 02:52:54 +0000 Subject: [PATCH] Abstract persistability out into a couple of classes. --- rawdoglib/__init__.py | 2 +- rawdoglib/persister.py | 61 ++++++++++++++++++++++++++++++++++++++++++ rawdoglib/rawdog.py | 27 ++++++------------- 3 files changed, 70 insertions(+), 20 deletions(-) create mode 100644 rawdoglib/persister.py diff --git a/rawdoglib/__init__.py b/rawdoglib/__init__.py index 0b2a0f1..e191d68 100644 --- a/rawdoglib/__init__.py +++ b/rawdoglib/__init__.py @@ -1 +1 @@ -__all__ = ['rssparser', 'timeoutsocket', 'rawdog'] +__all__ = ['rssparser', 'timeoutsocket', 'rawdog', 'persister'] diff --git a/rawdoglib/persister.py b/rawdoglib/persister.py new file mode 100644 index 0000000..2ed830f --- /dev/null +++ b/rawdoglib/persister.py @@ -0,0 +1,61 @@ +# rawdog: RSS aggregator without delusions of grandeur. +# Copyright 2003 Adam Sampson +# +# rawdog is free software; you can redistribute and/or modify it +# under the terms of that license as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# rawdog 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 rawdog; see the file COPYING. If not, write to the +# Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA, or see http://www.gnu.org/. + +import pickle, fcntl + +class Persistable: + """Something which can be persisted. When a subclass of this wants to + indicate that it has been modified, it should call + self.modified().""" + def __init__(self): self._modified = 0 + def modified(self, state = 1): self._modified = state + def is_modified(self): return self._modified + +class Persister: + """Persist another class to a file, safely. The class being persisted + must derive from Persistable (although this isn't enforced).""" + + def __init__(self, filename, klass): + self.filename = filename + self.klass = klass + self.file = None + self.object = None + + def load(self): + """Load the persisted object from the file, or create a new one + if this isn't possible. Returns the loaded object.""" + try: + self.file = open(self.filename, "r+") + fcntl.lockf(self.file.fileno(), fcntl.LOCK_EX) + self.object = pickle.load(self.file) + self.object.modified(0) + except IOError: + self.file = open(self.filename, "w+") + fcntl.lockf(self.file.fileno(), fcntl.LOCK_EX) + self.object = self.klass() + self.object.modified() + return self.object + + def save(self): + """Save the persisted object back to the file if necessary.""" + if self.object.is_modified(): + self.file.seek(0) + self.file.truncate(0) + pickle.dump(self.object, self.file) + self.file.close() + diff --git a/rawdoglib/rawdog.py b/rawdoglib/rawdog.py index 02f7e7d..c22e53a 100644 --- a/rawdoglib/rawdog.py +++ b/rawdoglib/rawdog.py @@ -18,7 +18,8 @@ VERSION = "0.4" import rssparser -import pickle, os, fcntl, time, sha +from persister import Persistable, Persister +import os, time, sha def format_time(secs, config): """Format a time and date nicely.""" @@ -204,7 +205,7 @@ class Config: else: raise ConfigError("Unknown config command: " + l[0]) -class Rawdog: +class Rawdog(Persistable): """The aggregator itself.""" def __init__(self): @@ -240,7 +241,7 @@ class Rawdog: del self.articles[key] self.last_update = now - self.changed = 1 + self.modified() def write(self, config): outputfile = config["outputfile"] @@ -370,17 +371,9 @@ def main(argv): except ConfigError, err: print err return 1 - - try: - f = open("state", "r+") - fcntl.lockf(f.fileno(), fcntl.LOCK_EX) - rawdog = pickle.load(f) - rawdog.changed = 0 - except IOError: - f = open("state", "w+") - fcntl.lockf(f.fileno(), fcntl.LOCK_EX) - rawdog = Rawdog() - rawdog.changed = 1 + + persister = Persister("state", Rawdog) + rawdog = persister.load() for action in argv: if action == "list": @@ -393,11 +386,7 @@ def main(argv): print "Unknown action: " + action return 1 - if rawdog.changed: - f.seek(0) - f.truncate(0) - pickle.dump(rawdog, f) - f.close() + persister.save() return 0 -- 2.35.1