def test_get_base_url(self): request = RequestFactory().get('/') root_url = utils.get_base_url(request) eq_(root_url, 'http://testserver') request = RequestFactory().get('/', SERVER_PORT=443) request.is_secure = lambda: True assert request.is_secure() root_url = utils.get_base_url(request) eq_(root_url, 'https://testserver')
def vidly_url_to_shortcode(request, id): event = get_object_or_404(Event, id=id) form = forms.VidlyURLForm(data=request.POST) if form.is_valid(): url = form.cleaned_data['url'] if event.privacy != Event.PRIVACY_PUBLIC: # forced token_protection = True else: token_protection = form.cleaned_data['token_protection'] hd = form.cleaned_data['hd'] base_url = get_base_url(request) webhook_url = base_url + reverse('manage:vidly_media_webhook') shortcode, error = vidly.add_media( url, token_protection=token_protection, hd=hd, notify_url=webhook_url, ) VidlySubmission.objects.create( event=event, url=url, token_protection=token_protection, hd=hd, tag=shortcode, submission_error=error ) url_scrubbed = scrub_transform_passwords(url) if shortcode: return {'shortcode': shortcode, 'url': url_scrubbed} else: return http.HttpResponseBadRequest(error) return http.HttpResponseBadRequest(str(form.errors))
def vidly_media_resubmit(request): if request.POST.get('cancel'): return redirect(reverse('manage:vidly_media') + '?status=Error') form = forms.VidlyResubmitForm(data=request.POST) if not form.is_valid(): return http.HttpResponse(str(form.errors)) event = get_object_or_404(Event, pk=form.cleaned_data['id']) environment = event.template_environment or {} if not environment.get('tag') or environment.get('tag') == 'None': raise ValueError("Not a valid tag in template") if event.privacy != Event.PRIVACY_PUBLIC: token_protection = True # no choice else: token_protection = form.cleaned_data['token_protection'] base_url = get_base_url(request) webhook_url = base_url + reverse('manage:vidly_media_webhook') old_tag = environment['tag'] url = prepare_vidly_video_url(form.cleaned_data['url']) shortcode, error = vidly.add_media( url=url, hd=form.cleaned_data['hd'], token_protection=token_protection, notify_url=webhook_url, ) VidlySubmission.objects.create( event=event, url=url, token_protection=token_protection, hd=form.cleaned_data['hd'], tag=shortcode, submission_error=error ) if error: messages.warning( request, "Media could not be re-submitted:\n<br>\n%s" % error ) else: messages.success( request, "Event re-submitted to use tag '%s'" % shortcode ) vidly.delete_media(old_tag) event.template_environment['tag'] = shortcode event.status = Event.STATUS_PROCESSING event.save() cache_key = 'vidly-query-%s' % old_tag cache.delete(cache_key) return redirect(reverse('manage:vidly_media') + '?status=Error')
def event_archive(request, event): if event.status != Event.STATUS_INITIATED: return http.HttpResponseBadRequest( "You can't archive events that are NOT in the state of initiated." ) submissions = VidlySubmission.objects.filter( event=event, url__startswith=event.upload.url ) for vidly_submission in submissions.order_by('-submission_time'): break else: # we haven't sent it in for archive yet upload = event.upload base_url = get_base_url(request) webhook_url = base_url + reverse('new:vidly_media_webhook') video_url = prepare_vidly_video_url(upload.url) tag, error = vidly.add_media( video_url, hd=True, notify_url=webhook_url, # Note that we deliberately don't bother yet to set # token_protection here because we don't yet know if the # event is going to be private or not. # Also, it's much quicker to make screencaptures of videos # that are not token protected on vid.ly. ) # then we need to record that we did this vidly_submission = VidlySubmission.objects.create( event=event, url=video_url, tag=tag, hd=True, submission_error=error or None ) default_template = Template.objects.get(default_archive_template=True) # Do an in place edit in case this started before the fetch_duration # has started. Event.objects.filter(id=event.id).update( template=default_template, template_environment={'tag': tag}, ) create_all_timestamp_pictures.delay(event.id) return { 'tag': vidly_submission.tag, 'error': vidly_submission.submission_error }
def get_object(self, request, private_or_public='', channel_slug=settings.DEFAULT_CHANNEL_SLUG, format_type=None, not_channel_slug=None): if private_or_public == 'private': # old URL private_or_public = 'company' self.private_or_public = private_or_public self.format_type = format_type self._root_url = get_base_url(request) self._channel = get_object_or_404(Channel, slug=channel_slug) self._not_channel = None if not_channel_slug: self._not_channel = get_object_or_404( Channel, slug=not_channel_slug, )
def new_event_tweet(request, id): data = {} event = get_object_or_404(Event, id=id) if request.method == 'POST': form = forms.EventTweetForm(event, data=request.POST) if form.is_valid(): event_tweet = form.save(commit=False) if event_tweet.send_date: assert event.location, "event must have a location" tz = pytz.timezone(event.location.timezone) event_tweet.send_date = tz_apply(event_tweet.send_date, tz) else: now = timezone.now() event_tweet.send_date = now event_tweet.event = event event_tweet.creator = request.user event_tweet.save() messages.info(request, 'Tweet saved') url = reverse('manage:event_edit', args=(event.pk,)) return redirect(url) else: initial = {} event_url = reverse('main:event', args=(event.slug,)) base_url = get_base_url(request) abs_url = urlparse.urljoin(base_url, event_url) try: abs_url = shorten_url(abs_url) data['shortener_error'] = None except (ImproperlyConfigured, ValueError) as err: data['shortener_error'] = str(err) # except OtherHttpRelatedErrors? # data['shortener_error'] = "Network error trying to shorten URL" initial['text'] = unhtml('%s\n%s' % (short_desc(event), abs_url)) initial['include_placeholder'] = bool(event.placeholder_img) initial['send_date'] = '' form = forms.EventTweetForm(initial=initial, event=event) data['event'] = event data['form'] = form data['tweets'] = EventTweet.objects.filter(event=event) return render(request, 'manage/new_event_tweet.html', data)
def get_object(self, request, private_or_public='', channel_slug=settings.DEFAULT_CHANNEL_SLUG, format_type=None, not_channel_slug=None): if private_or_public == 'private': # old URL private_or_public = 'company' self.private_or_public = private_or_public self.format_type = format_type self._root_url = get_base_url(request) self._channel = get_object_or_404(Channel, slug=channel_slug) self._not_channel = None if request.GET.get('ss'): self._savedsearch = get_object_or_404( SavedSearch, id=request.GET['ss'] ) else: self._savedsearch = None if not_channel_slug: self._not_channel = get_object_or_404( Channel, slug=not_channel_slug, )
def get_object(self, request, channel_slug=None): self._root_url = get_base_url(request) if channel_slug: self.channel = get_object_or_404( Channel, slug__iexact=channel_slug ) else: self.channel = Channel.objects.get( slug=settings.DEFAULT_CHANNEL_SLUG ) if self.channel.cover_art: self.itunes_lg_url = thumbnail( self.channel.cover_art, '1400x1400' ).url self.itunes_sm_url = thumbnail( self.channel.cover_art, '144x144' ).url if self.itunes_lg_url.startswith('//'): # e.g. //cdn.example.com/media/cache/file.png protocol = self._root_url.split('//')[0] self.itunes_lg_url = protocol + self.itunes_lg_url self.itunes_sm_url = protocol + self.itunes_sm_url elif '://' not in self.itunes_lg_url: self.itunes_lg_url = self._root_url + self.itunes_lg_url self.itunes_sm_url = self._root_url + self.itunes_sm_url else: # Use the default ones self.itunes_sm_url = get_abs_static( 'main/img/podcast-cover-144x144.png', request ) self.itunes_lg_url = get_abs_static( 'main/img/podcast-cover-1400x1400.png', request ) super(ITunesFeed, self).get_object(request)
def events_calendar_ical(request, privacy=None, channel_slug=None): cache_key = 'calendar' savedsearch = None if privacy: cache_key += '_%s' % privacy if channel_slug: cache_key += '_%s' % channel_slug if request.GET.get('ss'): savedsearch = get_object_or_404(SavedSearch, id=request.GET['ss']) cache_key += '_%s' % savedsearch.pk if request.GET.get('location'): if request.GET.get('location').isdigit(): location = get_object_or_404( Location, pk=request.GET.get('location') ) else: location = get_object_or_404( Location, name=request.GET.get('location') ) cache_key += str(location.pk) cached = None else: location = None cached = cache.get(cache_key) if cached: # additional response headers aren't remembered so add them again cached['Access-Control-Allow-Origin'] = '*' return cached cal = vobject.iCalendar() now = timezone.now() if savedsearch: base_qs = savedsearch.get_events() else: base_qs = Event.objects.scheduled_or_processing() if channel_slug: channel = get_object_or_404( Channel, slug__iexact=channel_slug ) channels = Channel.objects.filter( Q(id=channel.id) | Q(parent=channel.id) ) base_qs = base_qs.filter(channels__in=channels) if privacy == 'public': base_qs = base_qs.approved().filter( privacy=Event.PRIVACY_PUBLIC ) title = 'Air Mozilla Public Events' elif privacy == 'private': base_qs = base_qs.exclude( privacy=Event.PRIVACY_PUBLIC ) title = 'Air Mozilla Private Events' else: title = 'Air Mozilla Events' if savedsearch: if savedsearch.name: title += ' (from saved search "{}")'.format(savedsearch.name) else: title += ' (from saved search)' if location: base_qs = base_qs.filter(location=location) cal.add('X-WR-CALNAME').value = title events = list(base_qs .filter(start_time__lt=now) .order_by('-start_time')[:settings.CALENDAR_SIZE]) events += list(base_qs .filter(start_time__gte=now) .order_by('start_time')) base_url = get_base_url(request) for event in events: vevent = cal.add('vevent') vevent.add('summary').value = event.title vevent.add('dtstart').value = event.start_time vevent.add('dtend').value = ( event.start_time + datetime.timedelta( seconds=event.duration or event.estimated_duration ) ) vevent.add('description').value = short_desc(event, strip_html=True) if event.location: vevent.add('location').value = event.location.name vevent.add('url').value = ( base_url + reverse('main:event', args=(event.slug,)) ) icalstream = cal.serialize() # response = http.HttpResponse( # icalstream, # content_type='text/plain; charset=utf-8' # ) response = http.HttpResponse( icalstream, content_type='text/calendar; charset=utf-8' ) filename = 'AirMozillaEvents%s' % (privacy and privacy or '') if location: filename += '_%s' % slugify(location.name) if savedsearch: filename += '_ss%s' % savedsearch.id filename += '.ics' response['Content-Disposition'] = ( 'inline; filename=%s' % filename) if not location: cache.set(cache_key, response, 60 * 10) # 10 minutes # https://bugzilla.mozilla.org/show_bug.cgi?id=909516 response['Access-Control-Allow-Origin'] = '*' return response
def legacy_video_migration(request): # pragma: no cover """for one off mass vid.ly submission""" class VideoURLError(Exception): pass def redirect_recurse(url): """return the URL only when it's not redirecting. Raise an error on all other statuses >= 400 """ response = requests.head(url) if response.status_code in (301, 302): return redirect_recurse(response.headers['Location']) elif response.status_code >= 400: raise VideoURLError('{} => {}'.format( url, response.status_code )) return url if request.method == 'POST': events = Event.objects.filter(id__in=request.POST.getlist('ids')) template, = Template.objects.filter(default_archive_template=True) for event in events: try: url = event.template_environment['url'] url = redirect_recurse(url) base_url = get_base_url(request) webhook_url = base_url + reverse('manage:vidly_media_webhook') url = prepare_vidly_video_url(url) token_protection = event.privacy != Event.PRIVACY_PUBLIC shortcode, error = vidly.add_media( url, hd=True, token_protection=token_protection, notify_url=webhook_url, ) VidlySubmission.objects.create( event=event, url=url, token_protection=token_protection, hd=True, tag=shortcode, submission_error=error ) event.template_environment = { 'tag': shortcode, } if shortcode: event.template = template event.archive_time = None event.status = Event.STATUS_PROCESSING event.save() videoinfo.fetch_duration( event, video_url=url, save=True, verbose=settings.DEBUG ) if Event.objects.get(id=event.id).duration: create_all_event_pictures.delay( event.id, video_url=url, ) create_all_timestamp_pictures.delay( event.id, video_url=url, ) except Exception as exception: error = str(exception) messages.error( request, 'Failed to submit "{}". Error: {}'.format( event.title, error, ) ) messages.success( request, 'Submitted {} events for Vid.ly processing'.format( events.count() ) ) return redirect('manage:legacy_video_migration') search = request.GET.get('search', 'http://videos.mozilla.org/') if search: events = Event.objects.filter( template_environment__icontains=search ) else: events = Event.objects.none() context = { 'events': events, 'search': search, } return render(request, 'manage/legacy_video_migration.html', context)
def legacy_video_migration(request): # pragma: no cover """for one off mass vid.ly submission""" class VideoURLError(Exception): pass def redirect_recurse(url): """return the URL only when it's not redirecting. Raise an error on all other statuses >= 400 """ response = requests.head(url) if response.status_code in (301, 302): return redirect_recurse(response.headers['Location']) elif response.status_code >= 400: raise VideoURLError('{} => {}'.format(url, response.status_code)) return url if request.method == 'POST': events = Event.objects.filter(id__in=request.POST.getlist('ids')) template, = Template.objects.filter(default_archive_template=True) for event in events: try: url = event.template_environment['url'] url = redirect_recurse(url) base_url = get_base_url(request) webhook_url = base_url + reverse('manage:vidly_media_webhook') url = prepare_vidly_video_url(url) token_protection = event.privacy != Event.PRIVACY_PUBLIC shortcode, error = vidly.add_media( url, hd=True, token_protection=token_protection, notify_url=webhook_url, ) VidlySubmission.objects.create( event=event, url=url, token_protection=token_protection, hd=True, tag=shortcode, submission_error=error) event.template_environment = { 'tag': shortcode, } if shortcode: event.template = template event.archive_time = None event.status = Event.STATUS_PROCESSING event.save() videoinfo.fetch_duration(event, video_url=url, save=True, verbose=settings.DEBUG) if Event.objects.get(id=event.id).duration: create_all_event_pictures.delay( event.id, video_url=url, ) create_all_timestamp_pictures.delay( event.id, video_url=url, ) except Exception as exception: error = str(exception) messages.error( request, 'Failed to submit "{}". Error: {}'.format( event.title, error, )) messages.success( request, 'Submitted {} events for Vid.ly processing'.format(events.count())) return redirect('manage:legacy_video_migration') search = request.GET.get('search', 'http://videos.mozilla.org/') if search: events = Event.objects.filter(template_environment__icontains=search) else: events = Event.objects.none() context = { 'events': events, 'search': search, } return render(request, 'manage/legacy_video_migration.html', context)
def event_closed_captions_submit(request, event_id, id): event = get_object_or_404(Event, id=event_id) closedcaptions = get_object_or_404(ClosedCaptions, event=event, id=id) # XXX This might change. Instead of using the same tag as the one # being used, we might use a custom one just for the transcription # service. submission, = VidlySubmission.objects.filter( event=event, tag=event.template_environment['tag'] ) if request.method == 'POST': form = forms.SubmitClosedCaptionsForm(request.POST) if form.is_valid(): file_format = form.cleaned_data['file_format'] base_url = get_base_url(request) public_url = base_url + reverse( 'closedcaptions:download', args=( closedcaptions.filename_hash, closedcaptions.id, event.slug, file_format, ) ) # Send it in vidly.update_media_closed_captions( submission.tag, submission.url, public_url, hd=submission.hd, notify_url=None # XXX improve this some day ) if not closedcaptions.submission_info: closedcaptions.submission_info = {} if not closedcaptions.submission_info.get('submissions'): closedcaptions.submission_info['submissions'] = [] closedcaptions.submission_info['submissions'].append({ 'tag': submission.tag, 'url': submission.url, 'public_url': public_url, 'hd': submission.hd, 'date': timezone.now().isoformat(), }) closedcaptions.save() messages.success( request, '{} submitted for Vid.ly transcoding'.format( public_url ) ) return redirect('manage:event_closed_captions', event.id) else: form = forms.SubmitClosedCaptionsForm() content = closedcaptions.file.read() reader = pycaption.detect_format(content) converter = pycaption.CaptionConverter() converter.read(content, reader()) last_caption = converter.write(LastTimestampWriter()) / 1000000 context = { 'form': form, 'event': closedcaptions.event, 'closedcaptions': closedcaptions, 'last_caption': last_caption, 'submission': submission, } return render(request, 'manage/event_closed_captions_submit.html', context)
def event_assignments_ical(request): cache_key = 'event_assignements_ical' assignee = request.GET.get('assignee') if assignee: assignee = get_object_or_404(User, email=assignee) cache_key += str(assignee.pk) cached = cache.get(cache_key) if cached: # additional response headers aren't remembered so add them again cached['Access-Control-Allow-Origin'] = '*' return cached cal = vobject.iCalendar() now = timezone.now() base_qs = EventAssignment.objects.all().order_by('-event__start_time') if assignee: base_qs = base_qs.filter(users=assignee) title = 'Airmo' if assignee: title += ' for %s' % assignee.email else: title += ' crew assignments' cal.add('X-WR-CALNAME').value = title assignments = list( base_qs .filter(event__start_time__lt=now) [:settings.CALENDAR_SIZE] ) assignments += list( base_qs .filter(event__start_time__gte=now) ) base_url = get_base_url(request) for assignment in assignments: event = assignment.event vevent = cal.add('vevent') vevent.add('summary').value = "[AirMo crew] %s" % event.title # Adjusted start times for Event Assignment iCal feeds # to allow staff sufficient time for event set-up. vevent.add('dtstart').value = ( event.start_time - datetime.timedelta(minutes=30) ) vevent.add('dtend').value = ( event.start_time + datetime.timedelta(hours=1) ) emails = [u.email for u in assignment.users.all().order_by('email')] vevent.add('description').value = 'Assigned to: ' + ', '.join(emails) locations = [] if event.location: locations.append(event.location.name) locations.extend([ x.name for x in assignment.locations.all().order_by('name') ]) locations.sort() vevent.add('location').value = ', '.join(locations) vevent.add('url').value = ( base_url + reverse('main:event', args=(event.slug,)) ) icalstream = cal.serialize() # return http.HttpResponse(icalstream, # content_type='text/plain; charset=utf-8') response = http.HttpResponse(icalstream, content_type='text/calendar; charset=utf-8') filename = 'AirMozillaEventAssignments' filename += '.ics' response['Content-Disposition'] = ( 'inline; filename=%s' % filename) cache.set(cache_key, response, 60 * 10) # 10 minutes # https://bugzilla.mozilla.org/show_bug.cgi?id=909516 response['Access-Control-Allow-Origin'] = '*' return response
def new_event_rev_order(request, event_id): event = get_object_or_404(Event, id=event_id) if request.method == 'POST': form = forms.RevInputForm(request.POST) if form.is_valid(): rev_input = RevInput.objects.create( url=form.cleaned_data['url'], content_type=form.cleaned_data['content_type'], filename=form.cleaned_data['filename'], ) uri = rev.input_order( rev_input.url, filename=rev_input.filename, content_type=rev_input.content_type, ) rev_input.uri = uri rev_input.save() rev_order = RevOrder.objects.create( event=event, input=rev_input, created_user=request.user, output_file_formats=form.cleaned_data['output_file_formats'], ) base_url = get_base_url(request) webhook_url = base_url + reverse('manage:rev_order_update_hook') webhook_url = 'http://requestb.in/sxwiousx' order_uri = rev.place_order( uri, output_file_formats=form.cleaned_data['output_file_formats'], webhook_url=webhook_url, ) rev_order.uri = order_uri rev_order.order_number = order_uri.split('/')[-1] rev_order.update_status(save=False) rev_order.save() return redirect('manage:event_rev_orders', event.pk) else: url = '' content_type = '' filename = '' # If the event is public, and has a vidly submission, use its # SD version in MPEG4 format. if event.template.name.lower().count('vid.ly'): submissions = VidlySubmission.objects.filter( event=event, tag=event.template_environment['tag'], finished__isnull=False, submission_error__isnull=True, ) for submission in submissions.order_by('-finished')[:1]: url = 'https://vid.ly/{}?content=video&format=mp4'.format( submission.tag, ) filename = '{}.mp4'.format(submission.tag) content_type = 'video/mpeg' # get the real URL response = requests.head(url) if response.status_code in (301, 302): url = response.headers['Location'] filename = os.path.basename(url.split('?')[0]) initial = { 'url': url, 'content_type': content_type, 'filename': filename, 'output_file_formats': ['Dfxp'], } form = forms.RevInputForm(initial=initial) context = { 'event': event, 'form': form, } return render(request, 'manage/new_event_rev_order.html', context)
def events_calendar_ical(request, privacy=None): cache_key = 'calendar' if privacy: cache_key += '_%s' % privacy if request.GET.get('location'): if request.GET.get('location').isdigit(): location = get_object_or_404( Location, pk=request.GET.get('location') ) else: location = get_object_or_404( Location, name=request.GET.get('location') ) cache_key += str(location.pk) cached = None else: location = None cached = cache.get(cache_key) if cached: # additional response headers aren't remembered so add them again cached['Access-Control-Allow-Origin'] = '*' return cached cal = vobject.iCalendar() now = timezone.now() base_qs = Event.objects.approved() if privacy == 'public': base_qs = base_qs.filter(privacy=Event.PRIVACY_PUBLIC) title = 'Air Mozilla Public Events' elif privacy == 'private': base_qs = base_qs.exclude(privacy=Event.PRIVACY_PUBLIC) title = 'Air Mozilla Private Events' else: title = 'Air Mozilla Events' if location: base_qs = base_qs.filter(location=location) cal.add('X-WR-CALNAME').value = title events = list(base_qs .filter(start_time__lt=now) .order_by('-start_time')[:settings.CALENDAR_SIZE]) events += list(base_qs .filter(start_time__gte=now) .order_by('start_time')) base_url = get_base_url(request) for event in events: vevent = cal.add('vevent') vevent.add('summary').value = event.title vevent.add('dtstart').value = event.start_time vevent.add('dtend').value = ( event.start_time + datetime.timedelta(seconds=(event.duration or 3600)) ) vevent.add('description').value = short_desc(event, strip_html=True) if event.location: vevent.add('location').value = event.location.name vevent.add('url').value = base_url + event.slug + '/' icalstream = cal.serialize() # response = http.HttpResponse( # icalstream, # content_type='text/plain; charset=utf-8' # ) response = http.HttpResponse( icalstream, content_type='text/calendar; charset=utf-8' ) filename = 'AirMozillaEvents%s' % (privacy and privacy or '') if location: filename += '_%s' % slugify(location.name) filename += '.ics' response['Content-Disposition'] = ( 'inline; filename=%s' % filename) if not location: cache.set(cache_key, response, 60 * 10) # 10 minutes # https://bugzilla.mozilla.org/show_bug.cgi?id=909516 response['Access-Control-Allow-Origin'] = '*' return response
def event_assignments_ical(request): cache_key = 'event_assignements_ical' assignee = request.GET.get('assignee') if assignee: assignee = get_object_or_404(User, email=assignee) cache_key += str(assignee.pk) cached = cache.get(cache_key) if cached: # additional response headers aren't remembered so add them again cached['Access-Control-Allow-Origin'] = '*' return cached cal = vobject.iCalendar() now = timezone.now() base_qs = EventAssignment.objects.all().order_by('-event__start_time') if assignee: base_qs = base_qs.filter(users=assignee) title = 'Airmo' if assignee: title += ' for %s' % assignee.email else: title += ' crew assignments' cal.add('X-WR-CALNAME').value = title assignments = list( base_qs.filter(event__start_time__lt=now)[:settings.CALENDAR_SIZE]) assignments += list(base_qs.filter(event__start_time__gte=now)) base_url = get_base_url(request) for assignment in assignments: event = assignment.event vevent = cal.add('vevent') vevent.add('summary').value = "[AirMo crew] %s" % event.title # Adjusted start times for Event Assignment iCal feeds # to allow staff sufficient time for event set-up. vevent.add('dtstart').value = (event.start_time - datetime.timedelta(minutes=30)) vevent.add('dtend').value = (event.start_time + datetime.timedelta(hours=1)) emails = [u.email for u in assignment.users.all().order_by('email')] vevent.add('description').value = 'Assigned to: ' + ', '.join(emails) locations = [] if event.location: locations.append(event.location.name) locations.extend( [x.name for x in assignment.locations.all().order_by('name')]) locations.sort() vevent.add('location').value = ', '.join(locations) vevent.add('url').value = (base_url + reverse('main:event', args=(event.slug, ))) icalstream = cal.serialize() # return http.HttpResponse(icalstream, # content_type='text/plain; charset=utf-8') response = http.HttpResponse(icalstream, content_type='text/calendar; charset=utf-8') filename = 'AirMozillaEventAssignments' filename += '.ics' response['Content-Disposition'] = ('inline; filename=%s' % filename) cache.set(cache_key, response, 60 * 10) # 10 minutes # https://bugzilla.mozilla.org/show_bug.cgi?id=909516 response['Access-Control-Allow-Origin'] = '*' return response
def events_calendar_ical(request, privacy=None, channel_slug=None): cache_key = 'calendar' if privacy: cache_key += '_%s' % privacy if channel_slug: cache_key += '_%s' % channel_slug if request.GET.get('location'): if request.GET.get('location').isdigit(): location = get_object_or_404(Location, pk=request.GET.get('location')) else: location = get_object_or_404(Location, name=request.GET.get('location')) cache_key += str(location.pk) cached = None else: location = None cached = cache.get(cache_key) if cached: # additional response headers aren't remembered so add them again cached['Access-Control-Allow-Origin'] = '*' return cached cal = vobject.iCalendar() now = timezone.now() base_qs = Event.objects.scheduled_or_processing() if channel_slug: channel = get_object_or_404(Channel, slug__iexact=channel_slug) channels = Channel.objects.filter( Q(id=channel.id) | Q(parent=channel.id)) base_qs = base_qs.filter(channels__in=channels) if privacy == 'public': base_qs = base_qs.approved().filter(privacy=Event.PRIVACY_PUBLIC) title = 'Air Mozilla Public Events' elif privacy == 'private': base_qs = base_qs.exclude(privacy=Event.PRIVACY_PUBLIC) title = 'Air Mozilla Private Events' else: title = 'Air Mozilla Events' if location: base_qs = base_qs.filter(location=location) cal.add('X-WR-CALNAME').value = title events = list( base_qs.filter(start_time__lt=now).order_by('-start_time') [:settings.CALENDAR_SIZE]) events += list(base_qs.filter(start_time__gte=now).order_by('start_time')) base_url = get_base_url(request) for event in events: vevent = cal.add('vevent') vevent.add('summary').value = event.title vevent.add('dtstart').value = event.start_time vevent.add('dtend').value = (event.start_time + datetime.timedelta( seconds=event.duration or event.estimated_duration)) vevent.add('description').value = short_desc(event, strip_html=True) if event.location: vevent.add('location').value = event.location.name vevent.add('url').value = (base_url + reverse('main:event', args=(event.slug, ))) icalstream = cal.serialize() # response = http.HttpResponse( # icalstream, # content_type='text/plain; charset=utf-8' # ) response = http.HttpResponse(icalstream, content_type='text/calendar; charset=utf-8') filename = 'AirMozillaEvents%s' % (privacy and privacy or '') if location: filename += '_%s' % slugify(location.name) filename += '.ics' response['Content-Disposition'] = ('inline; filename=%s' % filename) if not location: cache.set(cache_key, response, 60 * 10) # 10 minutes # https://bugzilla.mozilla.org/show_bug.cgi?id=909516 response['Access-Control-Allow-Origin'] = '*' return response