Revision aed77afe

b/snf-cyclades-app/synnefo/plankton/backend.py
255 255
        location = get_location(account, container, object)
256 256
        return self._get_image(location)
257 257

  
258
    def iter(self):
259
        """Iter over all images available to the user"""
260

  
261
        backend = self.backend
262
        for account in backend.list_accounts(self.user):
263
            for container in backend.list_containers(self.user, account,
264
                                                     shared=True):
265
                for path, version_id in backend.list_objects(self.user,
266
                        account, container, domain=PLANKTON_DOMAIN):
267
                    location = get_location(account, container, path)
268
                    image = self._get_image(location)
269
                    if image:
270
                        yield image
271

  
272
    def iter_public(self, filters=None):
258
    def _iter(self, public=False, filters=None, shared_from=None):
273 259
        filters = filters or {}
274
        backend = self.backend
275 260

  
261
        # Fix keys
276 262
        keys = [PLANKTON_PREFIX + 'name']
277 263
        size_range = (None, None)
278

  
279 264
        for key, val in filters.items():
280 265
            if key == 'size_min':
281 266
                size_range = (int(val), size_range[1])
......
284 269
            else:
285 270
                keys.append('%s = %s' % (PLANKTON_PREFIX + key, val))
286 271

  
287
        for account in backend.list_accounts(None):
288
            for container in backend.list_containers(None, account,
272
        backend = self.backend
273
        if shared_from:
274
            # To get shared images, we connect as shared_from member and
275
            # get the list shared by us
276
            user = shared_from
277
            accounts = [self.user]
278
        else:
279
            user = None if public else self.user
280
            accounts = backend.list_accounts(user)
281

  
282
        for account in accounts:
283
            for container in backend.list_containers(user, account,
289 284
                                                     shared=True):
290
                for path, version_id in backend.list_objects(None, account,
291
                        container, domain=PLANKTON_DOMAIN, keys=keys,
292
                        shared=True, size_range=size_range):
285
                for path, _ in backend.list_objects(user, account, container,
286
                                                    domain=PLANKTON_DOMAIN,
287
                                                    keys=keys, shared=True,
288
                                                    size_range=size_range):
293 289
                    location = get_location(account, container, path)
294 290
                    image = self._get_image(location)
295 291
                    if image:
296 292
                        yield image
297 293

  
298
    def iter_shared(self, member):
299
        """Iterate over image ids shared to this member"""
294
    def iter(self, filters=None):
295
        """Iter over all images available to the user"""
296
        return self._iter(filters=filters)
300 297

  
301
        backend = self.backend
298
    def iter_public(self, filters=None):
299
        """Iter over public images"""
300
        return self._iter(public=True, filters=filters)
302 301

  
303
        # To get the list we connect as member and get the list shared by us
304
        for container in  backend.list_containers(member, self.user):
305
            for object, version_id in backend.list_objects(member, self.user,
306
                    container, domain=PLANKTON_DOMAIN):
307
                try:
308
                    location = get_location(self.user, container, object)
309
                    meta = backend.get_object_meta(member, self.user,
310
                            container, object, PLANKTON_DOMAIN)
311
                    if PLANKTON_PREFIX + 'name' in meta:
312
                        yield meta['uuid']
313
                except (NameError, NotAllowedError):
314
                    continue
315

  
316
    def list(self):
317
        """Iter over all images available to the user"""
302
    def iter_shared(self, filters=None, member=None):
303
        """Iter over images shared to member"""
304
        return self._iter(filters=filters)
318 305

  
319
        return list(self.iter())
306
    def list(self, filters=None, params={}):
307
        """Return all images available to the user"""
308
        images = list(self.iter(filters))
309
        key = itemgetter(params.get('sort_key', 'created_at'))
310
        reverse = params.get('sort_dir', 'desc') == 'desc'
311
        images.sort(key=key, reverse=reverse)
312
        return images
320 313

  
321
    def list_public(self, filters, params):
314
    def list_public(self, filters, params={}):
315
        """Return public images"""
322 316
        images = list(self.iter_public(filters))
323 317
        key = itemgetter(params.get('sort_key', 'created_at'))
324 318
        reverse = params.get('sort_dir', 'desc') == 'desc'
......
385 379
            raise BackendException("Invalid checksum")
386 380

  
387 381
        is_public = params.pop('is_public', False)
388
        permissions = {'read': ['*']} if is_public else {}
382
        if is_public:
383
            permissions = {'read': ['*']}
384
        else:
385
            permissions = {'read': [self.user]}
389 386

  
390 387
        meta = {}
391 388
        meta['properties'] = params.pop('properties', {})
b/snf-cyclades-app/synnefo/plankton/urls.py
45 45
    else:
46 46
        return HttpResponseNotAllowed(['GET', 'POST'])
47 47

  
48

  
48 49
def demux_image(request, image_id):
49 50
    if request.method == 'GET':
50 51
        return views.get_image(request, image_id)
......
55 56
    else:
56 57
        return HttpResponseNotAllowed(['GET', 'HEAD', 'PUT'])
57 58

  
59

  
58 60
def demux_image_members(request, image_id):
59 61
    if request.method == 'GET':
60 62
        return views.list_image_members(request, image_id)
......
63 65
    else:
64 66
        return HttpResponseNotAllowed(['GET', 'PUT'])
65 67

  
68

  
66 69
def demux_members(request, image_id, member):
67 70
    if request.method == 'DELETE':
68 71
        return views.remove_image_member(request, image_id, member)
......
77 80
    (r'^images/detail$', views.list_public_images, {'detail': True}),
78 81
    (r'^images/([\w-]+)$', demux_image),
79 82
    (r'^images/([\w-]+)/members$', demux_image_members),
80
    (r'^images/([\w-]+)/members/(\w+)$', demux_members),
81
    (r'^shared-images/(\w+)$', views.list_shared_images)
83
    (r'^images/([\w-]+)/members/([\w@._-]+)$', demux_members),
84
    (r'^shared-images/$', views.list_shared_images),
85
    (r'^shared-images/detail', views.list_shared_images, {'detail': True}),
86
    (r'^shared-images/([\w@._-]+)$', views.list_shared_images_with)
82 87
)
b/snf-cyclades-app/synnefo/plankton/views.py
35 35

  
36 36
from logging import getLogger
37 37
from string import punctuation
38
from StringIO import StringIO
39 38
from urllib import unquote
40 39

  
41 40
from django.conf import settings
......
272 271

  
273 272

  
274 273
@plankton_method('GET')
275
def list_shared_images(request, member):
274
def list_shared_images_with(request, member):
276 275
    """Request shared images
277 276

  
278 277
    Described in:
......
283 282
        the users's images that are accessible by `member`.
284 283
    """
285 284

  
286
    log.debug('list_shared_images %s', member)
285
    log.debug('list_shared_images_with %s', member)
287 286

  
288 287
    images = []
289
    for image_id in request.backend.iter_shared(member):
288
    for image in request.backend.iter_shared(member):
289
        image_id = image['id']
290 290
        images.append({'image_id': image_id, 'can_share': False})
291 291

  
292 292
    data = json.dumps({'shared_images': images}, indent=settings.DEBUG)
......
350 350

  
351 351
    request.backend.replace_users(image_id, members)
352 352
    return HttpResponse(status=204)
353

  
354

  
355
@plankton_method('GET')
356
def list_shared_images(request, detail=False):
357
    def get_request_params(keys):
358
        params = {}
359
        for key in keys:
360
            val = request.GET.get(key, None)
361
            if val is not None:
362
                params[key] = val
363
        return params
364

  
365
    log.debug('list_shared_images detail=%s, request %s', detail, request)
366

  
367
    filters = get_request_params(FILTERS)
368
    params = get_request_params(PARAMS)
369

  
370
    params.setdefault('sort_key', 'created_at')
371
    params.setdefault('sort_dir', 'desc')
372

  
373
    assert params['sort_key'] in SORT_KEY_OPTIONS
374
    assert params['sort_dir'] in SORT_DIR_OPTIONS
375

  
376
    images = request.backend.list(filters, params)
377
    images = filter(lambda x: not x['is_public'], images)
378

  
379
    # Remove keys that should not be returned
380
    fields = DETAIL_FIELDS if detail else LIST_FIELDS
381
    for image in images:
382
        for key in image.keys():
383
            if key not in fields:
384
                del image[key]
385

  
386
    data = json.dumps(images, indent=settings.DEBUG)
387
    return HttpResponse(data)

Also available in: Unified diff