def test_update_media_protection_unprotect(self, p_urlopen): def mocked_urlopen(request): xml_string = urllib.unquote_plus(request.data) ok_('<Protect />' in xml_string) return StringIO(SAMPLE_MEDIA_UPDATED_XML.strip()) p_urlopen.side_effect = mocked_urlopen # This doesn't return anything but we're only interested in if it # can execute at all without errors. vidly.update_media_protection('abc123', False)
def test_update_media_protection_unprotect(self, p_urlopen): def mocked_urlopen(request): xml_string = urllib.unquote_plus(request.data) ok_("<Protect />" in xml_string) return StringIO(SAMPLE_MEDIA_UPDATED_XML.strip()) p_urlopen.side_effect = mocked_urlopen # This doesn't return anything but we're only interested in if it # can execute at all without errors. vidly.update_media_protection("abc123", False)
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 vidly_media_webhook(request): if not request.POST.get('xml'): return http.HttpResponseBadRequest("no 'xml'") xml_string = request.POST['xml'].strip() try: struct = xmltodict.parse(xml_string) except ExpatError: return http.HttpResponseBadRequest("Bad 'xml'") try: task = struct['Response']['Result']['Task'] try: vidly_submission = VidlySubmission.objects.get( url=task['SourceFile'], tag=task['MediaShortLink'] ) if task['Status'] == 'Finished': if not vidly_submission.finished: vidly_submission.finished = timezone.now() vidly_submission.save() event = vidly_submission.event if ( task['Private'] == 'false' and event.privacy != Event.PRIVACY_PUBLIC ): # the event is private but the video is not vidly.update_media_protection( vidly_submission.tag, True # make it private ) if not vidly_submission.token_protection: vidly_submission.token_protection = True vidly_submission.save() # Awesome! # This event now has a fully working transcoded piece of # media. if event.status == Event.STATUS_PENDING: event.status = Event.STATUS_SCHEDULED event.archive_time = timezone.now() event.save() # More awesome! We can start processing the transcoded media. if not event.duration: videoinfo.fetch_duration( event, save=True, verbose=settings.DEBUG ) event = Event.objects.get(id=event.id) if event.duration: if not Picture.objects.filter(event=event): videoinfo.fetch_screencapture( event, save=True, verbose=settings.DEBUG, set_first_available=True, ) elif task['Status'] == 'Error': if not vidly_submission.errored: vidly_submission.errored = timezone.now() vidly_submission.save() except VidlySubmission.DoesNotExist: # remember, we can't trust the XML since it's publicly # available and exposed as a webhook pass except KeyError: # If it doesn't have a "Result" or "Task", it was just a notification # that the media was added. pass return http.HttpResponse('OK\n')
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
def vidly_media_webhook(request): if not request.POST.get('xml'): return http.HttpResponseBadRequest("no 'xml'") xml_string = request.POST['xml'].strip() try: struct = xmltodict.parse(xml_string) except ExpatError: return http.HttpResponseBadRequest("Bad 'xml'") try: task = struct['Response']['Result']['Task'] try: vidly_submission = VidlySubmission.objects.get( url=task['SourceFile'], tag=task['MediaShortLink']) if task['Status'] == 'Finished': if not vidly_submission.finished: vidly_submission.finished = timezone.now() vidly_submission.save() event = vidly_submission.event if (task['Private'] == 'false' and event.privacy != Event.PRIVACY_PUBLIC): # the event is private but the video is not vidly.update_media_protection( vidly_submission.tag, True # make it private ) if not vidly_submission.token_protection: vidly_submission.token_protection = True vidly_submission.save() # Awesome! # This event now has a fully working transcoded piece of # media. if (event.status == Event.STATUS_PENDING or event.status == Event.STATUS_PROCESSING): event.status = Event.STATUS_SCHEDULED event.archive_time = timezone.now() event.save() # More awesome! We can start processing the transcoded media. # XXX move this to a background task. if not event.duration: videoinfo.fetch_duration(event, save=True, verbose=settings.DEBUG) event = Event.objects.get(id=event.id) if event.duration: if not Picture.objects.filter(event=event): videoinfo.fetch_screencapture( event, save=True, verbose=settings.DEBUG, set_first_available=True, ) elif task['Status'] == 'Error': if not vidly_submission.errored: vidly_submission.errored = timezone.now() vidly_submission.save() except VidlySubmission.DoesNotExist: # remember, we can't trust the XML since it's publicly # available and exposed as a webhook pass except KeyError: # If it doesn't have a "Result" or "Task", it was just a notification # that the media was added. pass return http.HttpResponse('OK\n')
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)