Example #1
0
def _remove(data, request):
    user = request.user if request.user.is_authenticated() else None
    if not fEs.is_admin(user):
        raise PermissionDenied

    foto = entity_from_request(data)
    if isinstance(foto, six.string_types):
        return {'error': foto}

    # No visibility equals removal.
    foto.update_visibility([])

    return {'Ok': True}
Example #2
0
def _remove(data, request):
    user = request.user if request.user.is_authenticated() else None
    if not fEs.is_admin(user):
        raise PermissionDenied

    foto = entity_from_request(data)
    if isinstance(foto, basestring):
        return {'error': foto}

    # No visibility equals removal.
    foto.update_visibility([])

    return {'Ok': True}
Example #3
0
def fotoadmin_move(request):
    if not fEs.is_admin(request.user):
        raise PermissionDenied
    MoveFotosForm = getMoveFotosForm()
    if request.method == 'POST':
        form = MoveFotosForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            (store, user, dir) = cd['move_src'].split('/')
            giedo.fotoadmin_move_fotos(cd['move_dst'], store, user, dir)
    else:
        form = MoveFotosForm()
    return render_to_response('fotos/admin/move.html',
            {'form': form},
             context_instance=RequestContext(request))
Example #4
0
def fotoadmin_move(request):
    if not fEs.is_admin(request.user):
        raise PermissionDenied
    MoveFotosForm = getMoveFotosForm()
    if request.method == 'POST':
        form = MoveFotosForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            (store, user, dir) = cd['move_src'].split('/')
            giedo.fotoadmin_move_fotos(cd['move_dst'], store, user, dir)
            return redirect('fotos', path=cd['move_dst'])
    else:
        form = MoveFotosForm()
    return render(request, 'fotos/admin/move.html',
                  {'form': form})
Example #5
0
def entities_json(children, user):
    '''
    Return the JSON dictionary for this entity.
    '''

    entries = []
    people = {}
    for child in children:
        entry = {
            'type': child._type,
            'path': child.full_path,
            'name': child.name,
            'title': child.title,
            'rotation': child.rotation
        }

        if fEs.is_admin(user):
            entry['visibility'] = child.visibility[0]

        if child.description:
            entry['description'] = child.description
        if child._type == 'foto':
            entry['largeSize'] = child.get_cache_size('large')
            entry['large2xSize'] = child.get_cache_size('large2x')
            entry['thumbnailSize'] = child.get_cache_size('thumb')
        elif child._type == 'album':
            album_foto = child.get_random_foto_for(user)
            if album_foto is not None:
                entry['thumbnailSize'] = album_foto.get_cache_size('thumb')
                entry['thumbnailPath'] = album_foto.full_path

        if child._type != 'album' and user is not None and user.is_authenticated(
        ):
            tags = []
            tagged = child.get_tags()
            if tagged:
                for tag in tagged:
                    tags.append(str(tag.name))
                    people[str(tag.name)] = six.text_type(tag.humanName)
                entry['tags'] = tags

        entries.append(entry)

    return entries, people
Example #6
0
def fotoadmin_create_event(request):
    if not fEs.is_admin(request.user):
        raise PermissionDenied
    if request.method == 'POST':
        form = CreateEventForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            ret = giedo.fotoadmin_create_event(str(cd['date']),
                                               cd['name'], cd['fullHumanName'])
            if ret.get('success', False):
                messages.info(request, _('Fotoalbum aangemaakt!'))
            else:
                messages.error(request, _('Er is een fout opgetreden: %s') %
                               ret.get('error', _('geen foutmelding')))
            return redirect('fotoadmin-move')
    else:
        form = CreateEventForm()
    return render(request, 'fotos/admin/create.html',
                  {'form': form, 'events': list_events()})
Example #7
0
File: api.py Project: mrngm/kninfra
def entities_json(children, user):
    '''
    Return the JSON dictionary for this entity.
    '''

    entries = []
    people = {}
    for child in children:
        entry = {'type': child._type,
                 'path': child.full_path,
                 'name': child.name,
                 'title': child.title,
                 'rotation': child.rotation}

        if fEs.is_admin(user):
            entry['visibility'] = child.visibility[0]

        if child.description:
            entry['description'] = child.description
        if child._type == 'foto':
            entry['largeSize'] = child.get_cache_size('large')
            entry['large2xSize'] = child.get_cache_size('large2x')
            entry['thumbnailSize'] = child.get_cache_size('thumb')
        elif child._type == 'album':
            album_foto = child.get_random_foto_for(user)
            if album_foto is not None:
                entry['thumbnailSize'] = album_foto.get_cache_size('thumb')
                entry['thumbnailPath'] = album_foto.full_path

        if child._type != 'album':
            tags = []
            tagged = child.get_tags()
            if tagged:
                for tag in tagged:
                    tags.append(str(tag.name))
                    people[str(tag.name)] = six.text_type(tag.humanName)
                entry['tags'] = tags

        entries.append(entry)

    return entries, people
Example #8
0
def _set_metadata(data, request):
    user = request.user if request.user.is_authenticated() else None
    if not fEs.is_admin(user):
        raise PermissionDenied

    if 'title' not in data:
        return {'error': 'missing title attribute'}
    if not isinstance(data['title'], six.string_types):
        return {'error': 'title should be string'}
    title = data['title'].strip()
    if not title:
        title = None

    if 'visibility' not in data:
        return {'error': 'missing visibility attribute'}
    if data['visibility'] not in ['world', 'leden', 'hidden']:
        return {'error': 'visibility not valid'}
    visibility = data['visibility']

    entity = entity_from_request(data)
    if isinstance(entity, six.string_types):
        return {'error': entity}

    result = {'Ok': True}

    if entity._type == 'foto':
        if 'rotation' not in data:
            return {'error': 'missing rotation attribute'}
        if not isinstance(data['rotation'], int):
            return {'error': 'rotation should be a number'}
        rotation = data['rotation']
        if rotation not in [0, 90, 180, 270]:
            return {'error': 'rotation is not valid'}
        entity.set_rotation(rotation, save=False)

        result['largeSize'] = entity.get_cache_size('large')
        result['large2xSize'] = entity.get_cache_size('large2x')

    if entity._type in ['foto', 'video']:
        if 'description' not in data:
            return {'error': 'missing description attribute'}
        if not isinstance(data['description'], six.string_types):
            return {'error': 'description should be a string'}
        description = data['description'].strip()
        if not description:
            description = None
        entity.set_description(description, save=False)

        if 'tags' not in data:
            return {'error': 'missing tags attribute'}
        if not isinstance(data['tags'], list):
            return {'error': 'tags should be a list'}
        if not all(isinstance(n, six.string_types) for n in data['tags']):
            return {'error': 'tags may only contain strings'}
        tags = data['tags']
        entity.set_tags(tags, save=True)

        result['thumbnailSize'] = entity.get_cache_size('thumb')
        result['thumbnail2xSize'] = entity.get_cache_size('thumb2x')

    entity.set_title(title, save=False)

    # save changes in one batch
    entity.save()
    # except for visibility which is much harder to save in the same batch
    if entity.is_root:
        return result

    was_visible = 'leden' in fEs.actual_visibility(entity.effective_visibility)
    entity.update_visibility([visibility])
    is_visible = 'leden' in fEs.actual_visibility(entity.effective_visibility)

    # Send a mail when a new album comes online.
    if not entity.notified_informacie:
        if not was_visible and is_visible and isinstance(
                entity, fEs.FotoAlbum):
            event = entity
            while event.depth > 1:
                event = event.get_parent()
            if entity.depth > 1:
                Es.notify_informacie('add_foto_album',
                                     request.user,
                                     fotoEvent=event,
                                     fotoAlbum=entity)
            else:
                Es.notify_informacie('add_foto_event',
                                     request.user,
                                     fotoEvent=event)
            entity.set_informacie_notified()
        elif was_visible and not is_visible:
            # Do not send a mail when an old album (pre-notifications)
            # is set to invisible and back to visible. Act like a
            # notification has already been sent.
            entity.set_informacie_notified()

    return result
Example #9
0
def _set_metadata(data, request):
    user = request.user if request.user.is_authenticated() else None
    if not fEs.is_admin(user):
        raise PermissionDenied

    if 'title' not in data:
        return {'error': 'missing title attribute'}
    if not isinstance(data['title'], basestring):
        return {'error': 'title should be string'}
    title = data['title'].strip()
    if not title:
        title = None

    if 'visibility' not in data:
        return {'error': 'missing visibility attribute'}
    if data['visibility'] not in ['world', 'leden', 'hidden']:
        return {'error': 'visibility not valid'}
    visibility = data['visibility']

    entity = entity_from_request(data)
    if isinstance(entity, basestring):
        return {'error': entity}

    result = {'Ok': True}

    if entity._type == 'foto':
        if 'rotation' not in data:
            return {'error': 'missing rotation attribute'}
        if not isinstance(data['rotation'], int):
            return {'error': 'rotation should be a number'}
        rotation = data['rotation']
        if rotation not in [0, 90, 180, 270]:
            return {'error': 'rotation is not valid'}
        entity.set_rotation(rotation, save=False)

        result['largeSize'] = entity.get_cache_size('large')

    if entity._type in ['foto', 'video']:
        if 'description' not in data:
            return {'error': 'missing description attribute'}
        if not isinstance(data['description'], basestring):
            return {'error': 'description should be a string'}
        description = data['description'].strip()
        if not description:
            description = None
        entity.set_description(description, save=False)

        if 'tags' not in data:
            return {'error': 'missing tags attribute'}
        if not isinstance(data['tags'], list):
            return {'error': 'tags should be a list'}
        if not all(isinstance(n, basestring) for n in data['tags']):
            return {'error': 'tags may only contain strings'}
        tags = data['tags']
        entity.set_tags(tags, save=True)

        result['thumbnailSize'] = entity.get_cache_size('thumb')

    entity.set_title(title, save=False)

    # save changes in one batch
    entity.save()
    # except for visibility which is much harder to save in the same batch
    if entity.is_root:
        return result
    entity.update_visibility([visibility])
    return result
Example #10
0
def fotos(request, path=''):
    path = unquote(path)

    if any(k in request.GET for k in ['album', 'search_album', 'search_tag']):
        # redirect old URL
        path = request.GET.get('album', '')
        q = None
        if request.GET.get('search_album'):
            q = 'album:' + request.GET.get('search_album')
        if request.GET.get('search_tag'):
            q = 'tag:' + request.GET.get('search_tag')
        url = reverse('fotos', kwargs={'path': path})
        if q is not None:
            qs = QueryDict('', mutable=True)
            qs['q'] = q
            url += '?' + qs.urlencode()
        return redirect(url, permanent=True)

    album = fEs.by_path(path)
    if album is None:
        bits = path.rsplit('/', 1)
        if len(bits) == 2:
            path = bits[0]
            name = bits[1].replace('+', ' ')
            entity = fEs.by_path_and_name(path, name)
            if entity is not None:
                # Zen Photo used + signs in the filename part of the URL.
                url = reverse('fotos', kwargs={'path': path}) \
                    + '#' + filepath_to_uri(name)
                return redirect(url, permanent=True)
        raise Http404

    if album._type != 'album':
        # This is a photo, not an album.
        # Backwards compatibility, probably to Zen Photo.
        url = reverse('fotos', kwargs={'path': album.path}) \
            + '#' + filepath_to_uri(album.name)
        return redirect(url, permanent=True)

    user = request.user if request.user.is_authenticated() else None

    if not album.may_view(user) and user is None:
        # user is not logged in
        return redirect_to_login(request.get_full_path())

    if not album.may_view(user):
        # user is logged in, but may not view the album
        title = album.title
        if not title:
            title = album.name
        # respond with a nice error message
        response = render_to_response(
            'fotos/fotos.html',
            {'fotos': {'parents': album_parents_json(album)},
             'error': 'permission-denied'},
            context_instance=RequestContext(request)
        )
        response.status_code = 403
        return response

    if 'download' in request.GET:
        if album.is_root:
            # Downloading ALL photos would be way too much
            raise PermissionDenied
        download = ZipSeeker()
        add_download_files(download, album, album.full_path, user)
        response = StreamingHttpResponse(download.blocks(),
                                         content_type='application/zip')
        response['Content-Length'] = download.size()
        response['Last-Modified'] = http_date(download.lastModified())
        # TODO: human-readable download name?
        response['Content-Disposition'] = 'attachment; filename=' + \
            album.name + '.zip'
        return response

    people = None
    if fEs.is_admin(user):
        # Get all members (now or in the past), and sort them first
        # by whether they are active (active members first) and
        # then by their name.
        humanNames = {}
        active = []
        inactive = []
        for u in Es.users():
            humanNames[str(u.name)] = six.text_type(u.humanName)
            if u.is_active:
                active.append(str(u.name))
            else:
                inactive.append(str(u.name))
        active.sort()
        inactive.sort()
        people = []
        for name in active + inactive:
            people.append((name, humanNames[name]))

    fotos = album_json(album, user)
    return render_to_response('fotos/fotos.html',
                              {'fotos': fotos,
                               'fotos_admin': fEs.is_admin(user),
                               'people': people},
                              context_instance=RequestContext(request))
Example #11
0
def fotos(request, path=''):
    path = unquote(path)

    if any(k in request.GET for k in ['album', 'search_album', 'search_tag']):
        # redirect old URL
        path = request.GET.get('album', '')
        q = None
        if request.GET.get('search_album'):
            q = 'album:' + request.GET.get('search_album')
        if request.GET.get('search_tag'):
            q = 'tag:' + request.GET.get('search_tag')
        url = reverse('fotos', kwargs={'path':path})
        if q is not None:
            qs = QueryDict('', mutable=True)
            qs['q'] = q
            url += '?' + qs.urlencode()
        return redirect(url, permanent=True)

    album = fEs.by_path(path)
    if album is None:
        bits = path.rsplit('/', 1)
        if len(bits) == 2:
            path = bits[0]
            name = bits[1].replace('+', ' ')
            entity = fEs.by_path_and_name(path, name)
            if entity is not None:
                # Zen Photo used + signs in the filename part of the URL.
                url = reverse('fotos', kwargs={'path':path}) \
                        + '#'+filepath_to_uri(name)
                return redirect(url, permanent=True)
        raise Http404

    if album._type != 'album':
        # This is a photo, not an album.
        # Backwards compatibility, probably to Zen Photo.
        url = reverse('fotos', kwargs={'path':album.path}) \
                + '#'+filepath_to_uri(album.name)
        return redirect(url, permanent=True)

    user = request.user if request.user.is_authenticated() else None

    if not album.may_view(user) and user is None:
        # user is not logged in
        return redirect_to_login(request.get_full_path())

    if not album.may_view(user):
        # user is logged in, but may not view the album
        title = album.title
        if not title:
            title = album.name
        # respond with a nice error message
        response = render_to_response('fotos/fotos.html',
                  {'fotos': {'parents': album_parents_json(album)},
                   'error': 'permission-denied'},
                  context_instance=RequestContext(request))
        response.status_code = 403
        return response

    people = None
    if fEs.is_admin(user):
        # Get all members (now or in the past), and sort them first by whether they
        # are active (active members first) and then by their name.
        humanNames = {}
        active = []
        inactive = []
        for u in Es.users():
            humanNames[str(u.name)] = unicode(u.humanName)
            if u.is_active:
                active.append(str(u.name))
            else:
                inactive.append(str(u.name))
        active.sort()
        inactive.sort()
        people = []
        for name in active+inactive:
            people.append((name, humanNames[name]))

    fotos = album_json(album, user)
    return render_to_response('fotos/fotos.html',
             {'fotos': fotos,
              'fotos_admin': fEs.is_admin(user),
              'people': people},
             context_instance=RequestContext(request))
Example #12
0
def _set_metadata(data, request):
    user = request.user if request.user.is_authenticated() else None
    if not fEs.is_admin(user):
        raise PermissionDenied

    if 'title' not in data:
        return {'error': 'missing title attribute'}
    if not isinstance(data['title'], basestring):
        return {'error': 'title should be string'}
    title = data['title'].strip()
    if not title:
        title = None

    if 'visibility' not in data:
        return {'error': 'missing visibility attribute'}
    if data['visibility'] not in ['world', 'leden', 'hidden']:
        return {'error': 'visibility not valid'}
    visibility = data['visibility']

    entity = entity_from_request(data)
    if isinstance(entity, basestring):
        return {'error': entity}

    result = {'Ok': True}

    if entity._type == 'foto':
        if 'rotation' not in data:
            return {'error': 'missing rotation attribute'}
        if not isinstance(data['rotation'], int):
            return {'error': 'rotation should be a number'}
        rotation = data['rotation']
        if rotation not in [0, 90, 180, 270]:
            return {'error': 'rotation is not valid'}
        entity.set_rotation(rotation, save=False)

        result['largeSize'] = entity.get_cache_size('large')

    if entity._type in ['foto', 'video']:
        if 'description' not in data:
            return {'error': 'missing description attribute'}
        if not isinstance(data['description'], basestring):
            return {'error': 'description should be a string'}
        description = data['description'].strip()
        if not description:
            description = None
        entity.set_description(description, save=False)

        if 'tags' not in data:
            return {'error': 'missing tags attribute'}
        if not isinstance(data['tags'], list):
            return {'error': 'tags should be a list'}
        if not all(isinstance(n, basestring) for n in data['tags']):
            return {'error': 'tags may only contain strings'}
        tags = data['tags']
        entity.set_tags(tags, save=True)

        result['thumbnailSize'] = entity.get_cache_size('thumb')

    entity.set_title(title, save=False)

    # save changes in one batch
    entity.save()
    # except for visibility which is much harder to save in the same batch
    if entity.is_root:
        return result

    was_visible = 'leden' in fEs.actual_visibility(entity.effective_visibility)
    entity.update_visibility([visibility])
    is_visible = 'leden' in fEs.actual_visibility(entity.effective_visibility)

    # Send a mail when a new album comes online.
    if not entity.notified_informacie:
        if not was_visible and is_visible and isinstance(entity, fEs.FotoAlbum):
            event = entity
            while event.depth > 1:
                event = event.get_parent()
            if entity.depth > 1:
                Es.notify_informacie('add_foto_album', request.user, fotoEvent=event, fotoAlbum=entity)
            else:
                Es.notify_informacie('add_foto_event', request.user, fotoEvent=event)
            entity.set_informacie_notified()
        elif was_visible and not is_visible:
            # Do not send a mail when an old album (pre-notifications) is set to
            # invisible and back to visible. Act like a notification has already
            # been sent.
            entity.set_informacie_notified()

    return result
Example #13
0
def fotos(request, path=''):
    path = unquote(path)

    if any(k in request.GET for k in ['album', 'search_album', 'search_tag']):
        # redirect old URL
        path = request.GET.get('album', '')
        q = None
        if request.GET.get('search_album'):
            q = 'album:' + request.GET.get('search_album')
        if request.GET.get('search_tag'):
            q = 'tag:' + request.GET.get('search_tag')
        url = reverse('fotos', kwargs={'path': path})
        if q is not None:
            qs = QueryDict('', mutable=True)
            qs['q'] = q
            url += '?' + qs.urlencode()
        return redirect(url, permanent=True)

    album = fEs.by_path(path)
    if album is None:
        bits = path.rsplit('/', 1)
        if len(bits) == 2:
            path = bits[0]
            name = bits[1].replace('+', ' ')
            entity = fEs.by_path_and_name(path, name)
            if entity is not None:
                # Zen Photo used + signs in the filename part of the URL.
                url = reverse('fotos', kwargs={'path': path}) \
                    + '#' + filepath_to_uri(name)
                return redirect(url, permanent=True)
        raise Http404

    if album._type != 'album':
        # This is a photo, not an album.
        # Backwards compatibility, probably to Zen Photo.
        url = reverse('fotos', kwargs={'path': album.path}) \
            + '#' + filepath_to_uri(album.name)
        return redirect(url, permanent=True)

    user = request.user if request.user.is_authenticated() else None

    if not album.may_view(user) and user is None:
        # user is not logged in
        return redirect_to_login(request.get_full_path())

    if not album.may_view(user):
        # user is logged in, but may not view the album
        title = album.title
        if not title:
            title = album.name
        # respond with a nice error message
        response = render(
            request,
            'fotos/fotos.html',
            {'fotos': {'parents': album_parents_json(album)},
             'error': 'permission-denied'},
        )
        response.status_code = 403
        return response

    if 'download' in request.GET:
        if album.is_root:
            # Downloading ALL photos would be way too much
            raise PermissionDenied
        download = ZipSeeker()
        add_download_files(download, album, album.full_path, user)
        response = StreamingHttpResponse(download.blocks(),
                                         content_type='application/zip')
        response['Content-Length'] = download.size()
        response['Last-Modified'] = http_date(download.lastModified())
        # TODO: human-readable download name?
        response['Content-Disposition'] = 'attachment; filename=' + \
            album.name + '.zip'
        return response

    people = None
    if fEs.is_admin(user):
        # Get all members (now or in the past), and sort them first
        # by whether they are active (active members first) and
        # then by their name.
        humanNames = {}
        active = []
        inactive = []
        for u in Es.users():
            humanNames[str(u.name)] = six.text_type(u.humanName)
            if u.is_active:
                active.append(str(u.name))
            else:
                inactive.append(str(u.name))
        active.sort()
        inactive.sort()
        people = []
        for name in active + inactive:
            people.append((name, humanNames[name]))

    fotos = album_json(album, user)
    return render(request, 'fotos/fotos.html',
                  {'fotos': fotos,
                   'fotos_admin': fEs.is_admin(user),
                   'people': people})