mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-26 12:49:24 +01:00
Revert "Deduplicate (de)serialization code shared by UsersDictionary and ChannelsDictionary."
This reverts commit a4f8e3f647
.
This commit is contained in:
parent
5bfee2e72b
commit
bcbaa979d5
107
src/ircdb.py
107
src/ircdb.py
@ -620,27 +620,64 @@ class DuplicateHostmask(ValueError):
|
||||
|
||||
class UsersDictionary(utils.IterableMap):
|
||||
"""A simple serialized-to-file User Database."""
|
||||
__slots__ = ('filename', 'users', '_nameCache', '_hostmaskCache')
|
||||
__slots__ = ('noFlush', 'filename', 'users', '_nameCache',
|
||||
'_hostmaskCache')
|
||||
def __init__(self):
|
||||
self.noFlush = False
|
||||
self.filename = None
|
||||
self._preserver = unpreserve.Preserver(self.__class__.__name__)
|
||||
self.users = {}
|
||||
self.nextId = 0
|
||||
self._nameCache = utils.structures.CacheDict(1000)
|
||||
self._hostmaskCache = utils.structures.CacheDict(1000)
|
||||
|
||||
# This is separate because the Creator has to access our instance.
|
||||
def open(self, filename):
|
||||
self.filename = filename
|
||||
self._preserver.open(filename, IrcUserCreator, self)
|
||||
reader = unpreserve.Reader(IrcUserCreator, self)
|
||||
try:
|
||||
self.noFlush = True
|
||||
try:
|
||||
reader.readFile(filename)
|
||||
self.noFlush = False
|
||||
self.flush()
|
||||
except EnvironmentError as e:
|
||||
log.error('Invalid user dictionary file, resetting to empty.')
|
||||
log.error('Exact error: %s', utils.exnToString(e))
|
||||
except Exception as e:
|
||||
log.exception('Exact error:')
|
||||
finally:
|
||||
self.noFlush = False
|
||||
|
||||
def reload(self):
|
||||
"""Reloads the database from its file."""
|
||||
self.nextId = 0
|
||||
self.users.clear()
|
||||
self._nameCache.clear()
|
||||
self._hostmaskCache.clear()
|
||||
if self.filename is not None:
|
||||
try:
|
||||
self.open(self.filename)
|
||||
except EnvironmentError as e:
|
||||
log.warning('UsersDictionary.reload failed: %s', e)
|
||||
else:
|
||||
log.error('UsersDictionary.reload called with no filename.')
|
||||
|
||||
def flush(self):
|
||||
"""Flushes the database to its file."""
|
||||
if self.filename is not None:
|
||||
L = sorted(self.users.items())
|
||||
blocks = [('user %s' % id, user) for (id, user) in L]
|
||||
self._preserver.flush(self.filename, blocks)
|
||||
if not self.noFlush:
|
||||
if self.filename is not None:
|
||||
L = list(self.users.items())
|
||||
L.sort()
|
||||
fd = utils.file.AtomicFile(self.filename)
|
||||
for (id, u) in L:
|
||||
fd.write('user %s' % id)
|
||||
fd.write(os.linesep)
|
||||
u.preserve(fd, indent=' ')
|
||||
fd.close()
|
||||
else:
|
||||
log.error('UsersDictionary.flush called with no filename.')
|
||||
else:
|
||||
log.error('UsersDictionary.flush called with no filename.')
|
||||
log.debug('Not flushing UsersDictionary because of noFlush.')
|
||||
|
||||
def close(self):
|
||||
self.flush()
|
||||
@ -648,17 +685,6 @@ class UsersDictionary(utils.IterableMap):
|
||||
world.flushers.remove(self.flush)
|
||||
self.users.clear()
|
||||
|
||||
def reload(self):
|
||||
"""Reloads the database from its file."""
|
||||
if self.filename is not None:
|
||||
self.nextId = 0
|
||||
self.users.clear()
|
||||
self._nameCache.clear()
|
||||
self._hostmaskCache.clear()
|
||||
self.open(self.filename)
|
||||
else:
|
||||
log.error('UsersDictionary.reload called with no filename.')
|
||||
|
||||
def items(self):
|
||||
return self.users.items()
|
||||
|
||||
@ -806,24 +832,44 @@ class UsersDictionary(utils.IterableMap):
|
||||
|
||||
|
||||
class ChannelsDictionary(utils.IterableMap):
|
||||
__slots__ = ('channels', 'filename')
|
||||
__slots__ = ('noFlush', 'filename', 'channels')
|
||||
def __init__(self):
|
||||
self.noFlush = False
|
||||
self.filename = None
|
||||
self._preserver = unpreserve.Preserver(self.__class__.__name__)
|
||||
self.channels = ircutils.IrcDict()
|
||||
|
||||
def open(self, filename):
|
||||
self.filename = filename
|
||||
self._preserver.open(filename, IrcChannelCreator, self)
|
||||
self.noFlush = True
|
||||
try:
|
||||
self.filename = filename
|
||||
reader = unpreserve.Reader(IrcChannelCreator, self)
|
||||
try:
|
||||
reader.readFile(filename)
|
||||
self.noFlush = False
|
||||
self.flush()
|
||||
except EnvironmentError as e:
|
||||
log.error('Invalid channel database, resetting to empty.')
|
||||
log.error('Exact error: %s', utils.exnToString(e))
|
||||
except Exception as e:
|
||||
log.error('Invalid channel database, resetting to empty.')
|
||||
log.exception('Exact error:')
|
||||
finally:
|
||||
self.noFlush = False
|
||||
|
||||
def flush(self):
|
||||
"""Flushes the channel database to its file."""
|
||||
if self.filename is not None:
|
||||
L = sorted(self.channels.items())
|
||||
blocks = [('channel %s' % name, channel) for (name, channel) in L]
|
||||
self._preserver.flush(self.filename, blocks)
|
||||
if not self.noFlush:
|
||||
if self.filename is not None:
|
||||
fd = utils.file.AtomicFile(self.filename)
|
||||
for (channel, c) in self.channels.items():
|
||||
fd.write('channel %s' % channel)
|
||||
fd.write(os.linesep)
|
||||
c.preserve(fd, indent=' ')
|
||||
fd.close()
|
||||
else:
|
||||
log.warning('ChannelsDictionary.flush without self.filename.')
|
||||
else:
|
||||
log.error('UsersDictionary.flush called with no filename.')
|
||||
log.debug('Not flushing ChannelsDictionary because of noFlush.')
|
||||
|
||||
def close(self):
|
||||
self.flush()
|
||||
@ -835,7 +881,10 @@ class ChannelsDictionary(utils.IterableMap):
|
||||
"""Reloads the channel database from its file."""
|
||||
if self.filename is not None:
|
||||
self.channels.clear()
|
||||
self.open(self.filename)
|
||||
try:
|
||||
self.open(self.filename)
|
||||
except EnvironmentError as e:
|
||||
log.warning('ChannelsDictionary.reload failed: %s', e)
|
||||
else:
|
||||
log.warning('ChannelsDictionary.reload without self.filename.')
|
||||
|
||||
|
@ -27,10 +27,6 @@
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
###
|
||||
|
||||
import os
|
||||
|
||||
from . import log, utils
|
||||
|
||||
class Reader(object):
|
||||
"""Opens a file and reads it in blocks, using the `Creator` class to
|
||||
instantiate an object for each of the blocks.
|
||||
@ -104,40 +100,5 @@ class Reader(object):
|
||||
self.creator.finish()
|
||||
|
||||
|
||||
class Preserver(object):
|
||||
__slots__ = ('_class_name','noFlush')
|
||||
|
||||
def __init__(self, class_name):
|
||||
self._class_name = class_name
|
||||
self.noFlush = False
|
||||
|
||||
def open(self, filename, Creator, *args, **kwargs):
|
||||
"""Opens the `filename` and instantiates objects using the provided
|
||||
`Creator` and args (see the `Reader` class)."""
|
||||
try:
|
||||
reader = Reader(Creator, *args, **kwargs)
|
||||
try:
|
||||
self.noFlush = True
|
||||
reader.readFile(filename)
|
||||
finally:
|
||||
self.noFlush = False
|
||||
self.flush()
|
||||
except (EnvironmentError, Exception) as e:
|
||||
log.exception('Invalid %s file, resetting to empty.',
|
||||
self._class_name)
|
||||
|
||||
def flush(self, filename, blocks):
|
||||
if not self.noFlush:
|
||||
fd = utils.file.AtomicFile(filename)
|
||||
for (first_line, object_) in blocks:
|
||||
fd.write(first_line)
|
||||
fd.write(os.linesep)
|
||||
object_.preserve(fd, indent=' ')
|
||||
fd.close()
|
||||
else:
|
||||
log.debug('Not flushing %s because of noFlush.',
|
||||
self._class_name)
|
||||
|
||||
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user