obj.py 2.42 KB
Newer Older
1 2
# -*- coding: utf-8 -*-

3
# Copyright (C) 2011 Romain Bignon, Laurent Bachelier
4
#
Romain Bignon's avatar
Romain Bignon committed
5
# This file is part of assnet.
6
#
Romain Bignon's avatar
Romain Bignon committed
7
# assnet is free software: you can redistribute it and/or modify
8
# it under the terms of the GNU Affero General Public License as published by
9 10
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
11
#
Romain Bignon's avatar
Romain Bignon committed
12
# assnet is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU Affero General Public License for more details.
16
#
17
# You should have received a copy of the GNU Affero General Public License
Romain Bignon's avatar
Romain Bignon committed
18
# along with assnet. If not, see <http://www.gnu.org/licenses/>.
19

20 21

from collections import defaultdict
22
from copy import deepcopy
23

Laurent Bachelier's avatar
Laurent Bachelier committed
24

25 26
class IObject(object):
    def __init__(self, storage):
27
        self.storage = storage
28
        self._confname = self._get_confname()
29 30
        self._mtime = None
        self._old_data = None
31 32 33 34 35 36 37 38 39 40 41 42 43
        self.exists = None
        self.data = ConfigDict()

    def _get_confname(self):
        raise NotImplementedError()

    def _postread(self):
        pass

    def _prewrite(self):
        pass

    def read(self):
44
        mtime = self.storage._get_mtime(self._confname)
45
        if self._mtime is None or self._mtime != mtime or self.is_modified():
46
            data = self.storage._read(self._confname)
47 48 49 50 51
            self._mtime = mtime
            self.exists = data is not None
            self.data = data or ConfigDict()
            self._postread()
            self._old_data = deepcopy(self.data)
52 53 54 55

    def save(self):
        self._prewrite()
        self.data.cleanup()
56
        # only write as needed
57
        if self._old_data is None or self.is_modified() or self.exists is not True:
58
            self.storage._write(self._confname, self.data)
59
            self._old_data = deepcopy(self.data)
60
            self._mtime = self.storage._get_mtime(self._confname)
61
            self.exists = True
62 63

    def remove(self):
64
        self.storage._remove(self._confname)
65
        self._mtime = None
66 67 68 69
        self.exists = False
        self.data.clear()
        self._postread()

70 71 72
    def is_modified(self):
        return self._old_data != self.data

Laurent Bachelier's avatar
Laurent Bachelier committed
73

74
class ConfigDict(defaultdict):
Laurent Bachelier's avatar
Laurent Bachelier committed
75
    def __init__(self, _=None):
76 77 78 79 80 81
        defaultdict.__init__(self, dict)

    def cleanup(self):
        for key in self.keys():
            if not len(self[key]):
                del self[key]