~ubuntu-branches/debian/sid/obnam/sid

« back to all changes in this revision

Viewing changes to obnamlib/fmt_ga/indexes.py

  • Committer: Package Import Robot
  • Author(s): Lars Wirzenius
  • Date: 2015-07-01 18:14:49 UTC
  • Revision ID: package-import@ubuntu.com-20150701181449-taxcvqg9cviw2cxo
Tags: 1.10-1
* New upstream version.
  * Fix "restore to /tmp messes up directory perms" by preventing
    restores to a non-empty directory. (Closes: #760492)
* Add build-dependency on git.
* Drop build-dependency on texlive and building of PDF form of manual.
  Texlive is an insanely large build dependency.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2015  Lars Wirzenius
 
2
#
 
3
# This program is free software: you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation, either version 3 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
#
 
16
# =*= License: GPL-3+ =*=
 
17
 
 
18
 
 
19
import hashlib
 
20
import os
 
21
 
 
22
import obnamlib
 
23
 
 
24
 
 
25
class GAChunkIndexes(object):
 
26
 
 
27
    def __init__(self):
 
28
        self._fs = None
 
29
        self.set_dirname('chunk-indexes')
 
30
        self.clear()
 
31
 
 
32
    def set_fs(self, fs):
 
33
        self._fs = fs
 
34
 
 
35
    def set_dirname(self, dirname):
 
36
        self._dirname = dirname
 
37
 
 
38
    def get_dirname(self):
 
39
        return self._dirname
 
40
 
 
41
    def clear(self):
 
42
        self._data = {}
 
43
        self._data_is_loaded = False
 
44
 
 
45
    def commit(self):
 
46
        self._load_data()
 
47
        self._save_data()
 
48
 
 
49
    def _save_data(self):
 
50
        blob = obnamlib.serialise_object(self._data)
 
51
        filename = self._get_filename()
 
52
        self._fs.overwrite_file(filename, blob)
 
53
 
 
54
    def _get_filename(self):
 
55
        return os.path.join(self.get_dirname(), 'data.dat')
 
56
 
 
57
    def prepare_chunk_for_indexes(self, chunk_content):
 
58
        return hashlib.sha512(chunk_content).hexdigest()
 
59
 
 
60
    def put_chunk_into_indexes(self, chunk_id, token, client_id):
 
61
        self._load_data()
 
62
        self._prepare_data()
 
63
        self._data['index'].append({
 
64
            'chunk-id': chunk_id,
 
65
            'sha512': token,
 
66
            'client-id': client_id,
 
67
        })
 
68
 
 
69
    def _load_data(self):
 
70
        if not self._data_is_loaded:
 
71
            filename = self._get_filename()
 
72
            if self._fs.exists(filename):
 
73
                blob = self._fs.cat(filename)
 
74
                self._data = obnamlib.deserialise_object(blob)
 
75
                assert self._data is not None
 
76
            else:
 
77
                self._data = {}
 
78
            self._data_is_loaded = True
 
79
 
 
80
    def _prepare_data(self):
 
81
        if 'index' not in self._data:
 
82
            self._data['index'] = []
 
83
 
 
84
    def find_chunk_ids_by_content(self, chunk_content):
 
85
        self._load_data()
 
86
        if 'index' in self._data:
 
87
            token = self.prepare_chunk_for_indexes(chunk_content)
 
88
            result = [
 
89
                record['chunk-id']
 
90
                for record in self._data['index']
 
91
                if record['sha512'] == token]
 
92
        else:
 
93
            result = []
 
94
 
 
95
        if not result:
 
96
            raise obnamlib.RepositoryChunkContentNotInIndexes()
 
97
        return result
 
98
 
 
99
    def remove_chunk_from_indexes(self, chunk_id, client_id):
 
100
        self._load_data()
 
101
        self._prepare_data()
 
102
 
 
103
        self._data['index'] = self._filter_out(
 
104
            self._data['index'],
 
105
            lambda x:
 
106
            x['chunk-id'] == chunk_id and x['client-id'] == client_id)
 
107
 
 
108
    def _filter_out(self, records, pred):
 
109
        return [record for record in records if not pred(record)]
 
110
 
 
111
    def remove_chunk_from_indexes_for_all_clients(self, chunk_id):
 
112
        self._load_data()
 
113
        self._prepare_data()
 
114
 
 
115
        self._data['index'] = self._filter_out(
 
116
            self._data['index'],
 
117
            lambda x: x['chunk-id'] == chunk_id)
 
118
 
 
119
    def validate_chunk_content(self, chunk_id):
 
120
        return None