Beispiel #1
0
def event_video(request, event):
    context = {}
    if event.duration:
        context['duration'] = event.duration
        context['duration_human'] = show_duration(event.duration)
    # basically a thin wrapper on the vidly info
    tag = event.template_environment and event.template_environment.get('tag')
    if tag:
        qs = VidlySubmission.objects.filter(event=event, tag=tag)
        for vidly_submission in qs.order_by('-submission_time')[:1]:
            context['tag'] = tag
            results = vidly.query(tag).get(tag, {})
            context['status'] = results.get('Status')
            context['finished'] = results.get('Status') == 'Finished'
            if context['finished']:
                if not vidly_submission.finished:
                    vidly_submission.finished = timezone.now()
                    vidly_submission.save()
                if not event.archive_time:
                    event.archive_time = timezone.now()
                    event.save()
            elif results.get('Status') == 'Error':
                if not vidly_submission.errored:
                    vidly_submission.errored = timezone.now()
                    vidly_submission.save()

    return context
Beispiel #2
0
            def has_successful_vidly_submission(event):
                submissions = VidlySubmission.objects.filter(event=event)
                for submission in submissions.order_by('-submission_time')[:1]:
                    tag = submission.tag
                    results = vidly.query(tag).get(tag, {})
                    return results.get('Status') == 'Finished'

                return False
Beispiel #3
0
    def test_query(self, p_urlopen):
        def mocked_urlopen(request):
            return StringIO(SAMPLE_XML.strip())

        p_urlopen.side_effect = mocked_urlopen

        results = vidly.query('abc123')
        ok_('abc123' in results)
        eq_(results['abc123']['Status'], 'Finished')
Beispiel #4
0
    def test_query(self, p_urlopen):
        def mocked_urlopen(request):
            return StringIO(SAMPLE_XML.strip())

        p_urlopen.side_effect = mocked_urlopen

        results = vidly.query("abc123")
        ok_("abc123" in results)
        eq_(results["abc123"]["Status"], "Finished")
Beispiel #5
0
    def test_query(self, p_urlopen):

        def mocked_urlopen(request):
            return StringIO(SAMPLE_XML.strip())

        p_urlopen.side_effect = mocked_urlopen

        results = vidly.query('abc123')
        ok_('abc123' in results)
        eq_(results['abc123']['Status'], 'Finished')
Beispiel #6
0
def is_privacy_vidly_mismatch(event):
    if (event.template and 'vid.ly' in event.template.name.lower()
            and event.template_environment
            and event.template_environment.get('tag')):
        tag = event.template_environment.get('tag')
        statuses = vidly.query(tag)
        if tag in statuses:
            status = statuses[tag]
            public_event = event.privacy == Event.PRIVACY_PUBLIC
            public_video = status['Private'] == 'false'
            return public_event != public_video

    return False
Beispiel #7
0
def is_privacy_vidly_mismatch(event):
    if (
        event.template and
        'vid.ly' in event.template.name.lower() and
        event.template_environment and
        event.template_environment.get('tag')
    ):
        tag = event.template_environment.get('tag')
        statuses = vidly.query(tag)
        if tag in statuses:
            status = statuses[tag]
            public_event = event.privacy == Event.PRIVACY_PUBLIC
            public_video = status['Private'] == 'false'
            return public_event != public_video

    return False
Beispiel #8
0
def _videos_by_tags(tags):
    """Return a list of dicts where each dict looks something like this:

        {'id': 123, 'tag': 'abc123', 'Status': 'Processing', 'finished': False}

    And if there's no VidlySubmission the dict will just look like this:

        {'id': 124}

    The advantage of this function is that you only need to do 1 query
    to Vid.ly for a long list of tags.
    """
    all_results = vidly.query(tags.keys())
    video_contexts = []
    for tag, event in tags.items():
        video_context = {
            'id': event.id,
        }
        if event.duration:
            video_context['duration'] = event.duration
            video_context['duration_human'] = show_duration(event.duration)
        qs = VidlySubmission.objects.filter(event=event, tag=tag)
        for vidly_submission in qs.order_by('-submission_time')[:1]:
            video_context['tag'] = tag
            results = all_results.get(tag, {})
            video_context['status'] = results.get('Status')
            video_context['finished'] = results.get('Status') == 'Finished'
            if video_context['finished']:
                if not vidly_submission.finished:
                    vidly_submission.finished = timezone.now()
                    vidly_submission.save()
                if not event.archive_time:
                    event.archive_time = timezone.now()
                    event.save()
            elif results.get('Status') == 'Error':
                if not vidly_submission.errored:
                    vidly_submission.errored = timezone.now()
                    vidly_submission.save()
            else:
                video_context['estimated_time_left'] = (
                    vidly_submission.get_estimated_time_left()
                )
            break
        video_contexts.append(video_context)
    return video_contexts
Beispiel #9
0
def _videos_by_tags(tags):
    """Return a list of dicts where each dict looks something like this:

        {'id': 123, 'tag': 'abc123', 'Status': 'Processing', 'finished': False}

    And if there's no VidlySubmission the dict will just look like this:

        {'id': 124}

    The advantage of this function is that you only need to do 1 query
    to Vid.ly for a long list of tags.
    """
    all_results = vidly.query(tags.keys())
    video_contexts = []
    for tag, event in tags.items():
        video_context = {
            'id': event.id,
        }
        if event.duration:
            video_context['duration'] = event.duration
            video_context['duration_human'] = show_duration(event.duration)
        qs = VidlySubmission.objects.filter(event=event, tag=tag)
        for vidly_submission in qs.order_by('-submission_time')[:1]:
            video_context['tag'] = tag
            results = all_results.get(tag, {})
            video_context['status'] = results.get('Status')
            video_context['finished'] = results.get('Status') == 'Finished'
            if video_context['finished']:
                if not vidly_submission.finished:
                    vidly_submission.finished = timezone.now()
                    vidly_submission.save()
                if not event.archive_time:
                    event.archive_time = timezone.now()
                    event.save()
            elif results.get('Status') == 'Error':
                if not vidly_submission.errored:
                    vidly_submission.errored = timezone.now()
                    vidly_submission.save()
            else:
                video_context['estimated_time_left'] = (
                    vidly_submission.get_estimated_time_left()
                )
            break
        video_contexts.append(video_context)
    return video_contexts
Beispiel #10
0
def migrate_submission(vidly_submission):
    shortlink = vidly_submission.tag
    results = vidly.query(shortlink)

    if results[shortlink]["Status"] == "Finished":
        if not vidly_submission.finished:
            vidly_submission.finished = timezone.now()
            vidly_submission.save()

        event = vidly_submission.event
        event.template_environment["tag"] = shortlink
        event.save()

    elif results[shortlink]["Status"] == "Error":
        if not vidly_submission.errored:
            vidly_submission.errored = timezone.now()
            vidly_submission.save()

            email_about_archiver_error(event=vidly_submission.event, tag=shortlink)
Beispiel #11
0
def vidly_media_status(request):
    context = {}
    if request.GET.get('tag'):
        tag = request.GET.get('tag')
    else:
        if not request.GET.get('id'):
            return http.HttpResponseBadRequest("No 'id'")
        event = get_object_or_404(Event, pk=request.GET['id'])
        environment = event.template_environment or {}

        if not environment.get('tag') or environment.get('tag') == 'None':
            # perhaps it has a VidlySubmission anyway
            submissions = (
                VidlySubmission.objects
                .exclude(tag__isnull=True)
                .filter(event=event).order_by('-submission_time')
            )
            for submission in submissions[:1]:
                environment = {'tag': submission.tag}
                break
            else:
                return {}
        tag = environment['tag']

    cache_key = 'vidly-query-{md5}'.format(
        md5=hashlib.md5(tag.encode('utf8')).hexdigest().strip())
    force = request.GET.get('refresh', False)
    if force:
        results = None  # force a refresh
    else:
        results = cache.get(cache_key)
    if not results:
        results = vidly.query(tag).get(tag, {})
        expires = 60
        # if it's healthy we might as well cache a bit
        # longer because this is potentially used a lot
        if results.get('Status') == 'Finished':
            expires = 60 * 60
        if results:
            cache.set(cache_key, results, expires)

    context['status'] = results.get('Status')
    return context
Beispiel #12
0
def vidly_media_status(request):
    context = {}
    if request.GET.get('tag'):
        tag = request.GET.get('tag')
    else:
        if not request.GET.get('id'):
            return http.HttpResponseBadRequest("No 'id'")
        event = get_object_or_404(Event, pk=request.GET['id'])
        environment = event.template_environment or {}

        if not environment.get('tag') or environment.get('tag') == 'None':
            # perhaps it has a VidlySubmission anyway
            submissions = (
                VidlySubmission.objects
                .exclude(tag__isnull=True)
                .filter(event=event).order_by('-submission_time')
            )
            for submission in submissions[:1]:
                environment = {'tag': submission.tag}
                break
            else:
                return {}
        tag = environment['tag']

    cache_key = 'vidly-query-{md5}'.format(
        md5=hashlib.md5(tag.encode('utf8')).hexdigest().strip())
    force = request.GET.get('refresh', False)
    if force:
        results = None  # force a refresh
    else:
        results = cache.get(cache_key)
    if not results:
        results = vidly.query(tag).get(tag, {})
        expires = 60
        # if it's healthy we might as well cache a bit
        # longer because this is potentially used a lot
        if results.get('Status') == 'Finished':
            expires = 60 * 60
        if results:
            cache.set(cache_key, results, expires)

    context['status'] = results.get('Status')
    return context
Beispiel #13
0
def migrate_submission(vidly_submission):
    shortlink = vidly_submission.tag
    results = vidly.query(shortlink)

    if results[shortlink]['Status'] == 'Finished':
        if not vidly_submission.finished:
            vidly_submission.finished = timezone.now()
            vidly_submission.save()

        event = vidly_submission.event
        event.template_environment['tag'] = shortlink
        event.save()

    elif results[shortlink]['Status'] == 'Error':
        if not vidly_submission.errored:
            vidly_submission.errored = timezone.now()
            vidly_submission.save()

            email_about_archiver_error(
                event=vidly_submission.event,
                tag=shortlink,
            )
Beispiel #14
0
def event_publish(request, event):
    if event.status != Event.STATUS_INITIATED:
        return http.HttpResponseBadRequest("Not in an initiated state")

    # there has to be a Vid.ly video
    tag = event.template_environment['tag']
    submission = None
    qs = VidlySubmission.objects.filter(event=event, tag=tag)
    for each in qs.order_by('-submission_time'):
        submission = each
        break
    assert submission, "Event has no vidly submission"

    groups = []

    with transaction.atomic():
        results = vidly.query(tag).get(tag, {})
        # Let's check the privacy/tokenization of the video.
        # What matters (source of truth) is the event's privacy state.
        if event.privacy != Event.PRIVACY_PUBLIC and results:
            # make sure the submission the the video IS token protected
            if not submission.token_protection:
                submission.token_protection = True
                submission.save()
            if results['Private'] == 'false':
                # We can only do this if the video has been successfully
                # transcoded.
                if results['Status'] == 'Finished':
                    vidly.update_media_protection(
                        tag,
                        True
                    )
        if results.get('Status') == 'Finished':
            event.status = Event.STATUS_SCHEDULED
            # If it's definitely finished, it means we managed to ask
            # Vid.ly this question before Vid.ly had a chance to ping
            # us on the webhook. Might as well set it now.
            if not event.archive_time:
                event.archive_time = timezone.now()
        else:
            # vidly hasn't finished processing it yet
            event.status = Event.STATUS_PENDING
        event.save()

        if not event.picture:
            # assign the default placeholder picture if there is one
            try:
                event.picture = Picture.objects.get(default_placeholder=True)
                event.save()
            except Picture.DoesNotExist:  # pragma: no cover
                pass

        if not event.channels.all():
            # forcibly put it in the default channel(s)
            for channel in Channel.objects.filter(default=True):
                event.channels.add(channel)

        if not Discussion.objects.filter(event=event):
            discussion = Discussion.objects.create(
                event=event,
                enabled=True,
                notify_all=True
            )
            discussion.moderators.add(event.creator)

        if event.privacy == Event.PRIVACY_PUBLIC:
            for topic in event.topics.all():
                for group in topic.groups.all():
                    if group not in groups:
                        groups.append(group)
            for group in groups:
                Approval.objects.create(event=event, group=group)

    for group in groups:
        sending.email_about_approval_requested(
            event,
            group,
            request
        )

    return True
def synchronize_all(verbose=False):
    submissions = (
        VidlySubmission.objects
        .filter(event__template__name__icontains='Vid.ly')
        .filter(event__privacy=Event.PRIVACY_PUBLIC)
        .filter(token_protection=True)
    )

    tag_map = defaultdict(list)
    for submission in submissions:
        tag_map[submission.tag].append(submission)

    results = vidly.query(tag_map.keys())

    count_corrections = 0
    for tag, info in results.items():
        private = info['Private'] == 'true'
        for s in tag_map[tag]:
            if not private:
                if verbose:  # pragma: no cover
                    print (
                        "The VidlySubmission for (%r, %r) "
                        "was token protected by not according to Vid.ly" % (
                            s.event.title,
                            s.event.slug
                        )
                    )
                s.token_protection = False
                s.save()
                count_corrections += 1

    if verbose:  # pragma: no cover
        print (
            "Corrected %d vidly submissions' token protection\n" % (
                count_corrections,
            )
        )

    # Next we might have events that use tags that we have no
    # VidlySubmissions for.
    events = (
        Event.objects
        .filter(template__name__icontains='Vid.ly')
        .filter(template_environment__contains='"tag":')
    )
    event_map = defaultdict(list)
    for event in events:
        tag = event.template_environment['tag']
        event_map[tag].append(event)
    submission_tags = list(
        VidlySubmission.objects
        .filter(tag__in=event_map.keys())
        .values_list('tag', flat=True)
    )
    no_submission_tags = set(event_map.keys()) - set(submission_tags)
    no_submission_tags = list(no_submission_tags)
    if verbose:  # pragma: no cover
        print (
            "There are %d event tags we don't have vidly submissions for" % (
                len(no_submission_tags),
            )
        )
    shuffle(no_submission_tags)
    # let's not overload the Vid.ly query with doing too many lookups
    if len(no_submission_tags) > 100:
        no_submission_tags = no_submission_tags[:100]
        if verbose:  # pragma: no cover
            print "Capping to correct only 100 tags"
    results = vidly.query(no_submission_tags)
    count_creations = 0
    for tag in no_submission_tags:
        try:
            info = results[tag]
        except KeyError:
            if verbose:  # pragma: no cover
                for event in event_map[tag]:
                    print (
                        "(%s, %s) has tag %s but this does not exist on "
                        "Vid.ly" % (
                            event.title,
                            event.slug,
                            tag
                        )
                    )
            continue
        private = info['Private'] == 'true'
        hd = info['IsHD'] == 'true'
        created = info['Created']
        created = datetime.datetime.strptime(
            created,
            '%Y-%m-%d %H:%M:%S'
        )
        created = created.replace(tzinfo=utc)
        for event in event_map[tag]:
            assert not VidlySubmission.objects.filter(event=event, tag=tag)
            VidlySubmission.objects.create(
                event=event,
                tag=tag,
                token_protection=private,
                hd=hd,
                url=info['SourceFile'],
                email=info['UserEmail'],
                submission_time=created,
            )
            count_creations += 1

    if verbose:  # pragma: no cover
        print (
            "Created %d vidly submissions\n" % (
                count_creations,
            )
        )
Beispiel #16
0
def vidly_media_info(request):

    def as_fields(result):
        return [
            {'key': a, 'value': b}
            for (a, b)
            in sorted(result.items())
        ]

    if not request.GET.get('id'):
        return http.HttpResponseBadRequest("No 'id'")
    event = get_object_or_404(Event, pk=request.GET['id'])
    environment = event.template_environment or {}

    if not environment.get('tag') or environment.get('tag') == 'None':
        # perhaps it has a VidlySubmission anyway
        submissions = (
            VidlySubmission.objects
            .exclude(tag__isnull=True)
            .filter(event=event).order_by('-submission_time')
        )
        for submission in submissions[:1]:
            environment = {'tag': submission.tag}
            break

    if not environment.get('tag') or environment.get('tag') == 'None':
        return {'fields': as_fields({
            '*Note*': 'Not a valid tag in template',
            '*Template contents*': unicode(environment),
        })}
    else:
        tag = environment['tag']
        cache_key = 'vidly-query-%s' % tag
        force = request.GET.get('refresh', False)
        if force:
            results = None  # force a refresh
        else:
            results = cache.get(cache_key)
        if not results:
            all_results = vidly.query(tag)
            if tag not in all_results:
                return {
                    'ERRORS': ['Tag (%s) not found in Vid.ly' % tag]
                }
            results = all_results[tag]
            cache.set(cache_key, results, 60)

    data = {'fields': as_fields(results)}
    is_hd = results.get('IsHD', False)
    if is_hd == 'false':
        is_hd = False

    data['past_submission'] = {
        'url': results['SourceFile'],
        'email': results['UserEmail'],
        'hd': bool(is_hd),
        'token_protection': event.privacy != Event.PRIVACY_PUBLIC,
    }
    if request.GET.get('past_submission_info'):
        qs = (
            VidlySubmission.objects
            .filter(event=event)
            .order_by('-submission_time')
        )
        for submission in qs[:1]:
            if event.privacy != Event.PRIVACY_PUBLIC:
                # forced
                token_protection = True
            else:
                # whatever it was before
                token_protection = submission.token_protection
            data['past_submission'] = {
                'url': submission.url,
                'email': submission.email,
                'hd': submission.hd,
                'token_protection': token_protection,
            }

    return data
def resubmit_failures(max_attempts=1, verbose=False):
    failed = vidly.medialist('Error')
    resubmitted = []
    for shortcode in failed:
        try:
            submission = VidlySubmission.objects.exclude(
                event__status=Event.STATUS_REMOVED,
            ).get(tag=shortcode)
        except VidlySubmission.DoesNotExist:
            # If we have no record of submissions with that shortcode,
            # it's probably a piece of video on Vid.ly that came from
            # some other instance.
            continue

        if verbose:  # pragma: no cover
            print repr(shortcode), "has failed"
            # print submissions.count(), "known vidly submissions in our DB"

        if not submission.errored:
            # That's weird and nearly impossible.
            # It can happen that the transcoding *did* fail but we
            # were never informed (or failed to acknowledge being
            # informed).
            results = vidly.query(shortcode)[shortcode]
            if results['Status'] == 'Error':
                submission.errored = parse_non_iso_date(results['Updated'])
                submission.save()
        assert submission.errored

        # If we can find any submissions that are submitted after
        # this failed one that has not errored, then bail out.
        non_failures = VidlySubmission.objects.filter(
            event=submission.event,
            errored__isnull=True,
            submission_time__gt=submission.submission_time,
        )
        if non_failures.exists():
            if verbose:  # pragma: no cover
                print (
                    "Found at least one non-failure submission more recent."
                )
            continue

        # How many failed attempts have there been?
        # If there's too many resubmissions, the bail out of fear of
        # re-submitting something that'll never work.
        failures = VidlySubmission.objects.filter(
            event=submission.event,
            errored__isnull=False,
        ).exclude(
            id=submission.id
        )
        if failures.count() >= max_attempts:
            if verbose:  # pragma: no cover
                print (
                    "Already been {} failed attempts.".format(failures.count())
                )
            continue

        if verbose:  # pragma: no cover
            print "Resubmitting! {!r}".format(submission.event)
        error = resubmit(submission)
        if verbose:  # pragma: no cover
            print "Resubmission error", error
            print "\n"

        resubmitted.append(submission)
    return resubmitted
Beispiel #18
0
def resubmit_failures(max_attempts=1, verbose=False):
    failed = vidly.medialist('Error')
    resubmitted = []
    for shortcode in failed:
        try:
            submission = VidlySubmission.objects.exclude(
                event__status=Event.STATUS_REMOVED, ).get(tag=shortcode)
        except VidlySubmission.DoesNotExist:
            # If we have no record of submissions with that shortcode,
            # it's probably a piece of video on Vid.ly that came from
            # some other instance.
            continue

        if verbose:  # pragma: no cover
            print repr(shortcode), "has failed"
            # print submissions.count(), "known vidly submissions in our DB"

        if not submission.errored:
            # That's weird and nearly impossible.
            # It can happen that the transcoding *did* fail but we
            # were never informed (or failed to acknowledge being
            # informed).
            results = vidly.query(shortcode)[shortcode]
            if results['Status'] == 'Error':
                submission.errored = parse_non_iso_date(results['Updated'])
                submission.save()
        assert submission.errored

        # If we can find any submissions that are submitted after
        # this failed one that has not errored, then bail out.
        non_failures = VidlySubmission.objects.filter(
            event=submission.event,
            errored__isnull=True,
            submission_time__gt=submission.submission_time,
        )
        if non_failures.exists():
            if verbose:  # pragma: no cover
                print("Found at least one non-failure submission more recent.")
            continue

        # How many failed attempts have there been?
        # If there's too many resubmissions, the bail out of fear of
        # re-submitting something that'll never work.
        failures = VidlySubmission.objects.filter(
            event=submission.event,
            errored__isnull=False,
        ).exclude(id=submission.id)
        if failures.count() >= max_attempts:
            if verbose:  # pragma: no cover
                print("Already been {} failed attempts.".format(
                    failures.count()))
            continue

        if verbose:  # pragma: no cover
            print "Resubmitting! {!r}".format(submission.event)
        error = resubmit(submission)
        if verbose:  # pragma: no cover
            print "Resubmission error", error
            print "\n"

        resubmitted.append(submission)
    return resubmitted
Beispiel #19
0
def event_publish(request, event):
    if event.status != Event.STATUS_INITIATED:
        return http.HttpResponseBadRequest("Not in an initiated state")

    groups = []

    with transaction.atomic():
        # there has to be a Vid.ly video
        if 'youtube' in event.template.name.lower():
            event.status = Event.STATUS_SCHEDULED
        else:
            tag = event.template_environment['tag']
            submission = None
            qs = VidlySubmission.objects.filter(event=event, tag=tag)
            for each in qs.order_by('-submission_time'):
                submission = each
                break
            assert submission, "Event has no vidly submission"

            results = vidly.query(tag).get(tag, {})
            # Let's check the privacy/tokenization of the video.
            # What matters (source of truth) is the event's privacy state.
            if event.privacy != Event.PRIVACY_PUBLIC and results:
                # make sure the submission the the video IS token protected
                if not submission.token_protection:
                    submission.token_protection = True
                    submission.save()
                if results['Private'] == 'false':
                    # We can only do this if the video has been successfully
                    # transcoded.
                    if results['Status'] == 'Finished':
                        vidly.update_media_protection(tag, True)
            if results.get('Status') == 'Finished':
                event.status = Event.STATUS_SCHEDULED
                # If it's definitely finished, it means we managed to ask
                # Vid.ly this question before Vid.ly had a chance to ping
                # us on the webhook. Might as well set it now.
                if not event.archive_time:
                    event.archive_time = timezone.now()
            else:
                # vidly hasn't finished processing it yet
                event.status = Event.STATUS_PROCESSING
        event.save()

        if not event.picture and not event.placeholder_img:
            # assign the default placeholder picture if there is one
            try:
                event.picture = Picture.objects.get(default_placeholder=True)
                event.save()
            except Picture.DoesNotExist:  # pragma: no cover
                pass

        if not event.channels.all():
            # forcibly put it in the default channel(s)
            for channel in Channel.objects.filter(default=True):
                event.channels.add(channel)

        if not Discussion.objects.filter(event=event):
            discussion = Discussion.objects.create(event=event,
                                                   enabled=True,
                                                   notify_all=True)
            discussion.moderators.add(event.creator)

        if event.privacy == Event.PRIVACY_PUBLIC:
            for topic in event.topics.all():
                for group in topic.groups.all():
                    if group not in groups:
                        groups.append(group)
            for group in groups:
                Approval.objects.create(event=event, group=group)

    for group in groups:
        sending.email_about_approval_requested(event, group, request)

    return True
Beispiel #20
0
def vidly_media_info(request):
    def as_fields(result):
        return [{'key': a, 'value': b} for (a, b) in sorted(result.items())]

    if not request.GET.get('id'):
        return http.HttpResponseBadRequest("No 'id'")
    event = get_object_or_404(Event, pk=request.GET['id'])
    environment = event.template_environment or {}

    if not environment.get('tag') or environment.get('tag') == 'None':
        # perhaps it has a VidlySubmission anyway
        submissions = (VidlySubmission.objects.exclude(
            tag__isnull=True).filter(event=event).order_by('-submission_time'))
        for submission in submissions[:1]:
            environment = {'tag': submission.tag}
            break

    if not environment.get('tag') or environment.get('tag') == 'None':
        return {
            'fields':
            as_fields({
                '*Note*': 'Not a valid tag in template',
                '*Template contents*': unicode(environment),
            })
        }
    else:
        tag = environment['tag']
        cache_key = 'vidly-query-%s' % tag
        force = request.GET.get('refresh', False)
        if force:
            results = None  # force a refresh
        else:
            results = cache.get(cache_key)
        if not results:
            all_results = vidly.query(tag)
            if tag not in all_results:
                return {'ERRORS': ['Tag (%s) not found in Vid.ly' % tag]}
            results = all_results[tag]
            cache.set(cache_key, results, 60)

    data = {'fields': as_fields(results)}
    is_hd = results.get('IsHD', False)
    if is_hd == 'false':
        is_hd = False

    data['past_submission'] = {
        'url': results['SourceFile'],
        'email': results['UserEmail'],
        'hd': bool(is_hd),
        'token_protection': event.privacy != Event.PRIVACY_PUBLIC,
    }
    if request.GET.get('past_submission_info'):
        qs = (VidlySubmission.objects.filter(
            event=event).order_by('-submission_time'))
        for submission in qs[:1]:
            if event.privacy != Event.PRIVACY_PUBLIC:
                # forced
                token_protection = True
            else:
                # whatever it was before
                token_protection = submission.token_protection
            data['past_submission'] = {
                'url': submission.url,
                'email': submission.email,
                'hd': submission.hd,
                'token_protection': token_protection,
            }

    return data
Beispiel #21
0
def synchronize_all(verbose=False):
    submissions = (VidlySubmission.objects.filter(
        event__template__name__icontains='Vid.ly').filter(
            event__privacy=Event.PRIVACY_PUBLIC).filter(token_protection=True))

    tag_map = defaultdict(list)
    for submission in submissions:
        tag_map[submission.tag].append(submission)

    results = vidly.query(tag_map.keys())

    count_corrections = 0
    for tag, info in results.items():
        private = info['Private'] == 'true'
        for s in tag_map[tag]:
            if not private:
                if verbose:  # pragma: no cover
                    print(
                        "The VidlySubmission for (%r, %r) "
                        "was token protected by not according to Vid.ly" %
                        (s.event.title, s.event.slug))
                s.token_protection = False
                s.save()
                count_corrections += 1

    if verbose:  # pragma: no cover
        print("Corrected %d vidly submissions' token protection\n" %
              (count_corrections, ))

    # Next we might have events that use tags that we have no
    # VidlySubmissions for.
    events = (Event.objects.filter(template__name__icontains='Vid.ly').filter(
        template_environment__contains='"tag":'))
    event_map = defaultdict(list)
    for event in events:
        tag = event.template_environment['tag']
        event_map[tag].append(event)
    submission_tags = list(
        VidlySubmission.objects.filter(tag__in=event_map.keys()).values_list(
            'tag', flat=True))
    no_submission_tags = set(event_map.keys()) - set(submission_tags)
    no_submission_tags = list(no_submission_tags)
    if verbose:  # pragma: no cover
        print("There are %d event tags we don't have vidly submissions for" %
              (len(no_submission_tags), ))
    shuffle(no_submission_tags)
    # let's not overload the Vid.ly query with doing too many lookups
    if len(no_submission_tags) > 100:
        no_submission_tags = no_submission_tags[:100]
        if verbose:  # pragma: no cover
            print "Capping to correct only 100 tags"
    results = vidly.query(no_submission_tags)
    count_creations = 0
    for tag in no_submission_tags:
        try:
            info = results[tag]
        except KeyError:
            if verbose:  # pragma: no cover
                for event in event_map[tag]:
                    print(
                        "(%s, %s) has tag %s but this does not exist on "
                        "Vid.ly" % (event.title, event.slug, tag))
            continue
        private = info['Private'] == 'true'
        hd = info['IsHD'] == 'true'
        created = info['Created']
        created = datetime.datetime.strptime(created, '%Y-%m-%d %H:%M:%S')
        created = created.replace(tzinfo=utc)
        for event in event_map[tag]:
            assert not VidlySubmission.objects.filter(event=event, tag=tag)
            VidlySubmission.objects.create(
                event=event,
                tag=tag,
                token_protection=private,
                hd=hd,
                url=info['SourceFile'],
                email=info['UserEmail'],
                submission_time=created,
            )
            count_creations += 1

    if verbose:  # pragma: no cover
        print("Created %d vidly submissions\n" % (count_creations, ))
Beispiel #22
0
def event_publish(request, event):
    # context = {}
    if event.status != Event.STATUS_INITIATED:
        return http.HttpResponseBadRequest("Not in an initiated state")

    # there has to be a Vid.ly video
    tag = event.template_environment['tag']
    submission = None
    qs = VidlySubmission.objects.filter(event=event, tag=tag)
    for each in qs.order_by('-submission_time'):
        submission = each
        break
    assert submission, "Event has no vidly submission"

    permissions = Permission.objects.filter(codename='change_approval')
    groups = Group.objects.filter(permissions__in=permissions)

    with transaction.atomic():
        results = vidly.query(tag).get(tag, {})
        if results.get('Status') == 'Finished':
            event.status = Event.STATUS_SCHEDULED
            # If it's definitely finished, it means we managed to ask
            # Vid.ly this question before Vid.ly had a chance to ping
            # us on the webhook. Might as well set it now.
            if not event.archive_time:
                event.archive_time = timezone.now()
        else:
            # vidly hasn't finished processing it yet
            event.status = Event.STATUS_PENDING
        event.save()

        if not event.picture:
            # assign the default placeholder picture if there is one
            try:
                event.picture = Picture.objects.get(default_placeholder=True)
                event.save()
            except Picture.DoesNotExist:  # pragma: no cover
                pass

        if not event.channels.all():
            # forcibly put it in the default channel(s)
            for channel in Channel.objects.filter(default=True):
                event.channels.add(channel)

        if not Discussion.objects.filter(event=event):
            discussion = Discussion.objects.create(
                event=event,
                enabled=True,
                notify_all=True
            )
            discussion.moderators.add(event.creator)

        if event.privacy == Event.PRIVACY_PUBLIC:
            for group in groups:
                Approval.objects.create(event=event, group=group)

    for group in groups:
        sending.email_about_approval_requested(
            event,
            group,
            request
        )

    return True
Beispiel #23
0
def event_edit(request, id):
    """Edit form for a particular event."""
    event = get_object_or_404(Event, id=id)
    result = can_edit_event(event, request.user)
    if isinstance(result, http.HttpResponse):
        return result
    if request.user.has_perm('main.change_event_others'):
        form_class = forms.EventEditForm
    elif request.user.has_perm('main.add_event_scheduled'):
        form_class = forms.EventExperiencedRequestForm
    else:
        form_class = forms.EventRequestForm

    curated_groups = (
        CuratedGroup.objects.filter(event=event).order_by('created')
    )

    if request.method == 'POST':
        form = form_class(request.POST, request.FILES, instance=event)
        if form.is_valid():
            event = form.save(commit=False)
            _event_process(request, form, event)
            event.save()
            form.save_m2m()
            edit_url = reverse('manage:event_edit', args=(event.pk,))
            if is_privacy_vidly_mismatch(event):
                # We'll need to update the status of token protection
                # on Vid.ly for this event.
                try:
                    vidly.update_media_protection(
                        event.template_environment['tag'],
                        event.privacy != Event.PRIVACY_PUBLIC,
                    )
                    submissions = VidlySubmission.objects.filter(
                        event=event,
                        tag=event.template_environment['tag'],
                    ).order_by('-submission_time')
                    for submission in submissions[:1]:
                        submission.token_protection = (
                            event.privacy != Event.PRIVACY_PUBLIC
                        )
                        submission.save()
                        break
                except vidly.VidlyUpdateError as x:
                    messages.error(
                        request,
                        'Video protect status could not be updated on '
                        'Vid.ly\n<code>%s</code>' % x
                    )
            messages.info(
                request,
                'Event "<a href=\"%s\">%s</a>" saved. [Edit again](%s)' % (
                    reverse('main:event', args=(event.slug,)),
                    event.title,
                    edit_url
                )
            )
            return redirect('manage:events')
    else:
        timezone.activate(pytz.timezone('UTC'))
        initial = {}
        initial['timezone'] = timezone.get_current_timezone()  # UTC
        initial['curated_groups'] = ','.join(
            x[0] for x in curated_groups.values_list('name')
        )
        form = form_class(instance=event, initial=initial)

    context = {
        'form': form,
        'event': event,
        'suggested_event': None,
        'suggested_event_comments': None,
        'tweets': EventTweet.objects.filter(event=event).order_by('id'),
    }
    try:
        suggested_event = SuggestedEvent.objects.get(accepted=event)
        context['suggested_event'] = suggested_event
        context['suggested_event_comments'] = (
            SuggestedEventComment.objects
            .filter(suggested_event=suggested_event)
            .select_related('user')
            .order_by('created')
        )
    except SuggestedEvent.DoesNotExist:
        pass

    context['is_vidly_event'] = False
    if event.template and 'Vid.ly' in event.template.name:
        context['is_vidly_event'] = True
        context['vidly_submissions'] = (
            VidlySubmission.objects
            .filter(event=event)
            .order_by('-submission_time')
        )

    # Is it stuck and won't auto-archive?
    context['stuck_pending'] = False
    now = timezone.now()
    time_ago = now - datetime.timedelta(minutes=15)
    if (
        event.status == Event.STATUS_PENDING
        and event.template
        and 'Vid.ly' in event.template.name
        and event.template_environment  # can be None
        and event.template_environment.get('tag')
        and not VidlySubmission.objects.filter(
            event=event,
            submission_time__gte=time_ago
        )
    ):
        tag = event.template_environment['tag']
        results = vidly.query(tag)
        status = results.get(tag, {}).get('Status')
        if status == 'Finished':
            context['stuck_pending'] = True

    try:
        discussion = Discussion.objects.get(event=event)
        context['discussion'] = discussion
        context['comments_count'] = Comment.objects.filter(event=event).count()
    except Discussion.DoesNotExist:
        context['discussion'] = None

    context['approvals'] = (
        Approval.objects
        .filter(event=event)
        .select_related('group')
    )

    try:
        context['assignment'] = EventAssignment.objects.get(event=event)
    except EventAssignment.DoesNotExist:
        context['assignment'] = None

    amara_videos = AmaraVideo.objects.filter(event=event)
    context['amara_videos_count'] = amara_videos.count()

    try:
        context['survey'] = Survey.objects.get(events=event)
    except Survey.DoesNotExist:
        context['survey'] = None

    context['total_hits'] = 0

    for each in EventHitStats.objects.filter(event=event).values('total_hits'):
        context['total_hits'] += each['total_hits']

    return render(request, 'manage/event_edit.html', context)