예제 #1
0
    def post(self, request, pk):
        serializer = AlbumUpdateSerializer(data=request.DATA)
        if not serializer.is_valid():
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        now = timezone.now()

        if serializer.object.add_photos:
            photo_ids = serializer.object.add_photos

            try:
                photo_operations.add_pending_photos_to_album(photo_ids, self.album.id, now)
            except photo_operations.PhotoNotUploadedAddPhotoException:
                return Response(u"Trying to add a Photo that has not yet been uploaded", status=status.HTTP_400_BAD_REQUEST)
            except photo_operations.InvalidPhotoIdAddPhotoException:
                return Response(u"Trying to add a Photo with an invalid photo_id", status=status.HTTP_400_BAD_REQUEST)

            photos_added_to_album.send(sender=self,
                                       photos=photo_ids,
                                       by_user=request.user,
                                       to_album=self.album)

        if serializer.object.copy_photos:
            photo_ids = serializer.object.copy_photos
            photo_operations.copy_photos_to_album(request.user, photo_ids, self.album.id, now)

            photos_added_to_album.send(sender=self,
                                       photos=photo_ids,
                                       by_user=request.user,
                                       to_album=self.album)

        album_add_members(self.album, request.user, serializer.object.add_members, now)

        payload = optimized_views.get_album_detail_payload(request.user, self.album)
        return Response(payload, content_type='application/json')
예제 #2
0
def add_youtube_photo(client_upload_id, storage_id, author, album, now, youtube_id):
    def get_next_album_index(album):
        album_index_q = Photo.objects.filter(album=album).aggregate(Max("album_index"))

        max_album_index = album_index_q["album_index__max"]
        if max_album_index is None:
            return 0
        else:
            return max_album_index + 1

    success = False
    while not success:
        try:
            with transaction.atomic():
                next_album_index = get_next_album_index(album)
                p, created = Photo.objects.get_or_create(
                    storage_id=storage_id,
                    defaults={
                        "photo_id": Photo.generate_photo_id(),
                        "media_type": Photo.MEDIA_TYPE_YOUTUBE,
                        "client_upload_id": client_upload_id,
                        "subdomain": Photo.choose_random_subdomain(),
                        "date_created": now,
                        "author": author,
                        "album": album,
                        "album_index": next_album_index,
                        "youtube_id": youtube_id,
                    },
                )
        except IntegrityError:
            # This will happen if there is a collision with a duplicate
            # 'album_index' from a concurrent request
            success = False
        else:
            success = True
    if created:
        if not in_testing_mode():
            # Update the photo servers:
            for photo_server in PhotoServer.objects.filter(subdomain=p.subdomain, unreachable=False):
                # TODO We should use concurrent requests for this

                num_retries = 5
                initial_retry_time = 4

                try:
                    request_with_n_retries(
                        num_retries,
                        initial_retry_time,
                        lambda: photo_server_set_photos(photo_server.photos_update_url, photo_server.auth_key, [p]),
                    )
                except requests.exceptions.RequestException:
                    # TODO Log this
                    photo_server.set_unreachable()

        album.save_revision(now, True)

        photos_added_to_album.send(sender=None, photos=[p.photo_id], by_user=author, to_album=album)
예제 #3
0
def album(request, pk):
    album = get_object_or_404(Album, pk=pk)
    if not album.is_user_member(request.user.id):
        # TODO ...
        pass

    num_photos_added = 0
    num_photos_failed = 0

    if request.POST:
        if "add_photos" in request.POST:
            pending_photo_ids = []
            for f in request.FILES.getlist("photo_files"):

                pending_photo = Photo.objects.upload_request(author=request.user)

                if settings.USING_LOCAL_PHOTOS:
                    image_uploads.process_file_upload(pending_photo, f.chunks())
                else:
                    # Forward request to photo upload server
                    userAuthToken = AuthToken.objects.create_auth_token(
                        request.user, "Internal Photo Upload Auth Token", timezone.now()
                    )

                    r = requests.put(
                        settings.PHOTO_UPLOAD_SERVER_URL + "/photos/upload/" + pending_photo.photo_id + "/original/",
                        headers={"Authorization": "Token " + userAuthToken.key},
                        data=f.chunks(),
                    )
                    r.raise_for_status()

                pending_photo_ids.append(pending_photo.photo_id)
                num_photos_added += 1

            # Upload pending photos
            done = False
            total_retry_time = 0
            while not done:
                now = timezone.now()
                try:
                    photo_operations.add_pending_photos_to_album(pending_photo_ids, album.id, now)
                    done = True
                except RuntimeError:
                    # TODO This is a really bad workaround to deal with the
                    # situation where the photos aren't "done" yet (in which
                    # case "add_pending_photos_to_album" currently raises a
                    # "RuntimeError")
                    RETRY_TIME = 5
                    MAX_RETRY_TIME = 600  # 10 minutes

                    if total_retry_time >= MAX_RETRY_TIME:
                        raise

                    time.sleep(RETRY_TIME)
                    total_retry_time += RETRY_TIME

            # TODO: If this function will be refactored to use Class Based Views
            # change sender from `request` to `self` (View instance)
            photos_added_to_album.send(sender=request, photos=pending_photo_ids, by_user=request.user, to_album=album)

    aws_token = aws_sts.get_s3_upload_token(request.user)

    data = {
        "album": album,
        "photos": album.get_photos(),
        "members": album.get_member_users(),
        "num_photos_added": num_photos_added,
        "num_photos_failed": num_photos_failed,
        "aws_token": aws_token,
    }
    return render_to_response("frontend/album.html", data, context_instance=RequestContext(request))
예제 #4
0
def event_photos(request, event):
    album = event.album

    num_photos_added = 0
    num_photos_failed = 0

    if request.POST:
        if 'add_photos' in request.POST:
            pending_photo_ids = []
            for f in request.FILES.getlist('photo_files'):

                pending_photo = Photo.objects.upload_request(author=request.user)

                if settings.USING_LOCAL_PHOTOS:
                    image_uploads.process_file_upload(pending_photo, f.chunks())
                else:
                    # Forward request to photo upload server
                    userAuthToken = AuthToken.objects.create_auth_token(request.user, 'Internal Photo Upload Auth Token', timezone.now())

                    r = requests.put(settings.PHOTO_UPLOAD_SERVER_URL + '/photos/upload/' + pending_photo.photo_id + '/original/',
                            headers = { 'Authorization': 'Token ' + userAuthToken.key },
                            data = f.chunks())
                    r.raise_for_status()

                pending_photo_ids.append(pending_photo.photo_id)

                num_photos_added += 1

            # Upload pending photos
            done = False
            total_retry_time = 0
            while not done:
                now = timezone.now()
                try:
                    photo_operations.add_pending_photos_to_album(pending_photo_ids, album.id, now)
                    done = True
                except RuntimeError:
                    # TODO This is a really bad workaround to deal with the
                    # situation where the photos aren't "done" yet (in which
                    # case "add_pending_photos_to_album" currently raises a
                    # "RuntimeError")
                    RETRY_TIME = 5
                    MAX_RETRY_TIME = 600 # 10 minutes

                    if total_retry_time >= MAX_RETRY_TIME:
                        raise

                    time.sleep(RETRY_TIME)
                    total_retry_time += RETRY_TIME

            # TODO: If this function will be refactored to use Class Based Views
            # change sender from `request` to `self` (View instance)
            photos_added_to_album.send(sender=request,
                                       photos=pending_photo_ids,
                                       by_user=request.user,
                                       to_album=album)

    data = {
            'event': event,
            'organization': event.organization,
            'album': album,
            'photos': album.get_photos(),
            'members': album.get_member_users(),
            'num_photos_added': num_photos_added,
            'num_photos_failed': num_photos_failed
            }
    return render(request, 'affiliates/event/photos.html', data)