Revision 2db7d9df snf-cyclades-app/synnefo/plankton/backend.py

b/snf-cyclades-app/synnefo/plankton/backend.py
54 54
import warnings
55 55

  
56 56
from operator import itemgetter
57
from time import gmtime, strftime, time
57
from time import gmtime, strftime
58
from functools import wraps
58 59

  
59 60
from django.conf import settings
60 61

  
61
from pithos.backends.base import NotAllowedError
62
from pithos.backends.base import NotAllowedError as PithosNotAllowedError
62 63

  
63 64

  
64 65
PLANKTON_DOMAIN = 'plankton'
......
86 87
    pass
87 88

  
88 89

  
90
class NotAllowedError(BackendException):
91
    pass
92

  
93

  
89 94
from pithos.backends.util import PithosBackendPool
90 95
POOL_SIZE = 8
91 96
_pithos_backend_pool = \
......
98 103
    return _pithos_backend_pool.pool_get()
99 104

  
100 105

  
106
def handle_backend_exceptions(func):
107
    @wraps(func)
108
    def wrapper(*args, **kwargs):
109
        try:
110
            return func(*args, **kwargs)
111
        except PithosNotAllowedError:
112
            raise NotAllowedError()
113
    return wrapper
114

  
115

  
101 116
class ImageBackend(object):
102 117
    """A wrapper arround the pithos backend to simplify image handling."""
103 118

  
......
109 124
        self.backend = get_pithos_backend()
110 125
        warnings.filters = original_filters     # Restore warnings
111 126

  
127
    @handle_backend_exceptions
112 128
    def _get_image(self, location):
113 129
        def format_timestamp(t):
114 130
            return strftime('%Y-%m-%d %H:%M:%S', gmtime(t))
......
159 175

  
160 176
        return image
161 177

  
178
    @handle_backend_exceptions
162 179
    def _get_meta(self, location, version=None):
163 180
        account, container, object = split_location(location)
164 181
        try:
......
167 184
        except NameError:
168 185
            return None
169 186

  
187
    @handle_backend_exceptions
170 188
    def _get_permissions(self, location):
171 189
        account, container, object = split_location(location)
172 190
        action, path, permissions = self.backend.get_object_permissions(
173 191
                self.user, account, container, object)
174 192
        return permissions
175 193

  
194
    @handle_backend_exceptions
176 195
    def _store(self, f, size=None):
177 196
        """Breaks data into blocks and stores them in the backend"""
178 197

  
......
193 212

  
194 213
        return hashmap, bytes
195 214

  
215
    @handle_backend_exceptions
196 216
    def _update(self, location, size, hashmap, meta, permissions):
197 217
        account, container, object = split_location(location)
198 218
        self.backend.update_object_hashmap(self.user, account, container,
......
200 220
                permissions=permissions)
201 221
        self._update_meta(location, meta, replace=True)
202 222

  
223
    @handle_backend_exceptions
203 224
    def _update_meta(self, location, meta, replace=False):
204 225
        account, container, object = split_location(location)
205 226

  
......
213 234
        self.backend.update_object_meta(self.user, account, container, object,
214 235
                PLANKTON_DOMAIN, prefixed, replace)
215 236

  
237
    @handle_backend_exceptions
216 238
    def _update_permissions(self, location, permissions):
217 239
        account, container, object = split_location(location)
218 240
        self.backend.update_object_permissions(self.user, account, container,
219 241
                object, permissions)
220 242

  
243
    @handle_backend_exceptions
221 244
    def add_user(self, image_id, user):
222 245
        image = self.get_image(image_id)
223 246
        assert image, "Image not found"
......
232 255
    def close(self):
233 256
        self.backend.close()
234 257

  
258
    @handle_backend_exceptions
235 259
    def delete(self, image_id):
236 260
        image = self.get_image(image_id)
237 261
        account, container, object = split_location(image['location'])
238 262
        self.backend.delete_object(self.user, account, container, object)
239 263

  
264
    @handle_backend_exceptions
240 265
    def get_data(self, location):
241 266
        account, container, object = split_location(location)
242 267
        size, hashmap = self.backend.get_object_hashmap(self.user, account,
......
245 270
        assert len(data) == size
246 271
        return data
247 272

  
273
    @handle_backend_exceptions
248 274
    def get_image(self, image_id):
249 275
        try:
250 276
            account, container, object = self.backend.get_uuid(self.user,
......
255 281
        location = get_location(account, container, object)
256 282
        return self._get_image(location)
257 283

  
284
    @handle_backend_exceptions
258 285
    def iter(self):
259 286
        """Iter over all images available to the user"""
260 287

  
......
269 296
                    if image:
270 297
                        yield image
271 298

  
299
    @handle_backend_exceptions
272 300
    def iter_public(self, filters=None):
273 301
        filters = filters or {}
274 302
        backend = self.backend
......
295 323
                    if image:
296 324
                        yield image
297 325

  
326
    @handle_backend_exceptions
298 327
    def iter_shared(self, member):
299 328
        """Iterate over image ids shared to this member"""
300 329

  
......
313 342
                except (NameError, NotAllowedError):
314 343
                    continue
315 344

  
345
    @handle_backend_exceptions
316 346
    def list(self):
317 347
        """Iter over all images available to the user"""
318 348

  
319 349
        return list(self.iter())
320 350

  
351
    @handle_backend_exceptions
321 352
    def list_public(self, filters, params):
322 353
        images = list(self.iter_public(filters))
323 354
        key = itemgetter(params.get('sort_key', 'created_at'))
......
325 356
        images.sort(key=key, reverse=reverse)
326 357
        return images
327 358

  
359
    @handle_backend_exceptions
328 360
    def list_users(self, image_id):
329 361
        image = self.get_image(image_id)
330 362
        assert image, "Image not found"
......
332 364
        permissions = self._get_permissions(image['location'])
333 365
        return [user for user in permissions.get('read', []) if user != '*']
334 366

  
367
    @handle_backend_exceptions
335 368
    def put(self, name, f, params):
336 369
        assert 'checksum' not in params, "Passing a checksum is not supported"
337 370
        assert 'id' not in params, "Passing an ID is not supported"
......
359 392
        self._update(location, size, hashmap, meta, permissions)
360 393
        return self._get_image(location)
361 394

  
395
    @handle_backend_exceptions
362 396
    def register(self, name, location, params):
363 397
        assert 'id' not in params, "Passing an ID is not supported"
364 398
        assert location.startswith('pithos://'), "Invalid location"
......
395 429
        self._update_permissions(location, permissions)
396 430
        return self._get_image(location)
397 431

  
432
    @handle_backend_exceptions
398 433
    def remove_user(self, image_id, user):
399 434
        image = self.get_image(image_id)
400 435
        assert image, "Image not found"
......
407 442
            return      # User did not have access anyway
408 443
        self._update_permissions(location, permissions)
409 444

  
445
    @handle_backend_exceptions
410 446
    def replace_users(self, image_id, users):
411 447
        image = self.get_image(image_id)
412 448
        assert image, "Image not found"
......
418 454
            permissions['read'].append('*')
419 455
        self._update_permissions(location, permissions)
420 456

  
457
    @handle_backend_exceptions
421 458
    def update(self, image_id, params):
422 459
        image = self.get_image(image_id)
423 460
        assert image, "Image not found"
......
440 477

  
441 478
        self._update_meta(location, meta)
442 479
        return self.get_image(image_id)
443

  

Also available in: Unified diff