def view_diary(request, year=None, month=None, day=None, req_days_ahead=None, event_type=None): # Returns public diary view, starting at specified year/month/day, filtered # by event type. # # Returns different things depending on the supplied parameters; # - if only year is passed, and no daysahead parameter,listings for the # whole of that year # - if only year & month passed, and no daysahead parameter, listings for # the whole of that month # - if year, month & day, and no daysahead parameter, listings for that day # only # - if dayssahead parameter is passed, that many days from the specified # year/month/date query_days_ahead = req_days_ahead or request.GET.get('daysahead', None) # Shared utility method to parse HTTP parameters and return a date range startdate, days_ahead = get_date_range(year, month, day, query_days_ahead) if startdate is None: raise Http404("Start date not found") enddate = startdate + datetime.timedelta(days=days_ahead) return _view_diary(request, startdate, enddate, tag=event_type)
def get(self, request, year=None, day=None, month=None): # Fiddly way to set startdate to the start of the local day: # Get current UTC time and convert to local time: now_local = django.utils.timezone.localtime( django.utils.timezone.now()) # Create a new local time with hour/min/sec set to zero: current_tz = django.utils.timezone.get_current_timezone() today_local_date = current_tz.localize(datetime.datetime( now_local.year, now_local.month, now_local.day)) yesterday_local_date = today_local_date - datetime.timedelta(days=1) query_days_ahead = request.GET.get('daysahead', None) start_date, days_ahead = get_date_range( year, month, day, query_days_ahead, default_days_ahead=30) if not request.user.is_superuser: # Don't allow data from before yesterday to be displayed: # TODO datepicker is still nobbled to yesterday if start_date < yesterday_local_date: start_date = yesterday_local_date end_date = start_date + datetime.timedelta(days=days_ahead) showings = (Showing.objects.not_cancelled() .confirmed() .start_in_range(start_date, end_date) .order_by('start') # force sane number of queries: .prefetch_related('rotaentry_set__role') .select_related()) # Used by per-showing rota notes click to edit control: url_with_id = reverse('edit-showing-rota-notes', kwargs={'showing_id': 999}) showing_notes_url_prefix = url_with_id[:url_with_id.find("999")] context = { 'start_date': start_date, 'end_date': end_date, 'days_ahead': days_ahead, 'showings': showings, 'edit_showing_notes_url_prefix': showing_notes_url_prefix } return render(request, u'edit_rota.html', context)
def view_event_field(request, field, year, month, day): # Method shared across various (slightly primitive) views into event data; # the copy, terms and rota reports. # # This method gets the list of events for the given date range (using the # same shared logic for parsing the parameters as the public list / edit # list) and then uses the appropriate template to render the results. logger.debug(u"view_event_field: field {0}".format(field)) assert field in ('copy', 'terms', 'rota', 'copy_summary') query_days_ahead = request.GET.get('daysahead', None) start_date, days_ahead = get_date_range(year, month, day, query_days_ahead) if start_date is None: raise Http404(days_ahead) end_date = start_date + datetime.timedelta(days=days_ahead) showings = (Showing.objects.not_cancelled() .confirmed() .start_in_range(start_date, end_date) .order_by('start') # following prefetch is for the rota view .prefetch_related('rotaentry_set__role') .select_related()) search = request.GET.get('search') if search: logging.info(u"Search term: {0}".format(search)) # Note slightly sneaky use of **; this effectively results in a method # call like: showings.filter(event__copy__icontains=search) showings = showings.filter( Q(**{'event__' + field + '__icontains': search}) | Q(event__name__icontains=search) ) context = { 'start_date': start_date, 'end_date': end_date, 'days_ahead': days_ahead, 'showings': showings, 'event_field': field, 'search': search, } return render(request, u'view_{0}.html'.format(field), context)
def get(self, request, year=None, day=None, month=None): # Fiddly way to set startdate to the start of the local day: # Get current UTC time and convert to local time: now_local = django.utils.timezone.localtime( django.utils.timezone.now()) # Create a new local time with hour/min/sec set to zero: current_tz = django.utils.timezone.get_current_timezone() today_local_date = current_tz.localize( datetime.datetime(now_local.year, now_local.month, now_local.day)) yesterday_local_date = today_local_date - datetime.timedelta(days=1) query_days_ahead = request.GET.get('daysahead', None) start_date, days_ahead = get_date_range(year, month, day, query_days_ahead, default_days_ahead=30) # Don't allow data from before yesterday to be displayed: if start_date < yesterday_local_date: start_date = yesterday_local_date end_date = start_date + datetime.timedelta(days=days_ahead) showings = ( Showing.objects.not_cancelled().confirmed().start_in_range( start_date, end_date).order_by('start') # force sane number of queries: .prefetch_related('rotaentry_set__role').select_related()) # Used by per-showing rota notes click to edit control: url_with_id = reverse('edit-showing-rota-notes', kwargs={'showing_id': 999}) showing_notes_url_prefix = url_with_id[:url_with_id.find("999")] context = { 'start_date': start_date, 'end_date': end_date, 'days_ahead': days_ahead, 'showings': showings, 'edit_showing_notes_url_prefix': showing_notes_url_prefix } return render(request, u'edit_rota.html', context)
def view_event_field(request, field, year, month, day): # Method shared across various (slightly primitive) views into event data; # the copy, terms and rota reports. # # This method gets the list of events for the given date range (using the # same shared logic for parsing the parameters as the public list / edit # list) and then uses the appropriate template to render the results. assert field in ("copy", "terms", "rota", "copy_summary") query_days_ahead = request.GET.get("daysahead", None) start_date, days_ahead = get_date_range(year, month, day, query_days_ahead) if start_date is None: raise Http404(days_ahead) end_date = start_date + datetime.timedelta(days=days_ahead) showings = ( Showing.objects.not_cancelled() .confirmed() .start_in_range(start_date, end_date) .order_by("start") # following prefetch is for the rota view .prefetch_related("rotaentry_set__role") .select_related() ) search = request.GET.get("search") if search: logging.info(u"Search term: {0}".format(search)) # Note slightly sneaky use of **; this effectively results in a method # call like: showings.filter(event__copy__icontains=search) showings = showings.filter(Q(**{"event__" + field + "__icontains": search}) | Q(event__name__icontains=search)) context = { "start_date": start_date, "end_date": end_date, "days_ahead": days_ahead, "showings": showings, "event_field": field, "search": search, } return render(request, u"view_{0}.html".format(field), context)
def get(self, request, year=None, day=None, month=None): # Fiddly way to set startdate to the start of the local day: # Get current UTC time and convert to local time: now_local = django.utils.timezone.localtime(django.utils.timezone.now()) # Create a new local time with hour/min/sec set to zero: current_tz = django.utils.timezone.get_current_timezone() today_local_date = current_tz.localize(datetime.datetime(now_local.year, now_local.month, now_local.day)) yesterday_local_date = today_local_date - datetime.timedelta(days=1) query_days_ahead = request.GET.get("daysahead", None) start_date, days_ahead = get_date_range(year, month, day, query_days_ahead, default_days_ahead=30) # Don't allow data from before yesterday to be displayed: if start_date < yesterday_local_date: start_date = yesterday_local_date end_date = start_date + datetime.timedelta(days=days_ahead) showings = ( Showing.objects.not_cancelled() .confirmed() .start_in_range(start_date, end_date) .order_by("start") # force sane number of queries: .prefetch_related("rotaentry_set__role") .select_related() ) # Used by per-showing rota notes click to edit control: url_with_id = reverse("edit-showing-rota-notes", kwargs={"showing_id": 999}) showing_notes_url_prefix = url_with_id[: url_with_id.find("999")] context = { "start_date": start_date, "end_date": end_date, "days_ahead": days_ahead, "showings": showings, "edit_showing_notes_url_prefix": showing_notes_url_prefix, } return render(request, u"edit_rota.html", context)
def view_event_field(request, field, year, month, day): # Method shared across various (slightly primitive) views into event data; # the copy, terms and rota reports. # # This method gets the list of events for the given date range (using the # same shared logic for parsing the parameters as the public list / edit # list) and then uses the appropriate template to render the results. assert field in ('copy', 'terms', 'rota', 'copy_summary') query_days_ahead = request.GET.get('daysahead', None) start_date, days_ahead = get_date_range(year, month, day, query_days_ahead) if start_date is None: raise Http404(days_ahead) end_date = start_date + datetime.timedelta(days=days_ahead) showings = ( Showing.objects.not_cancelled().confirmed().start_in_range( start_date, end_date).order_by('start') # following prefetch is for the rota view .prefetch_related('rotaentry_set__role').select_related()) search = request.GET.get('search') if search: logging.info(u"Search term: {0}".format(search)) # Note slightly sneaky use of **; this effectively results in a method # call like: showings.filter(event__copy__icontains=search) showings = showings.filter( Q(**{'event__' + field + '__icontains': search}) | Q(event__name__icontains=search)) context = { 'start_date': start_date, 'end_date': end_date, 'days_ahead': days_ahead, 'showings': showings, 'event_field': field, 'search': search, } return render(request, u'view_{0}.html'.format(field), context)
def edit_diary_list(request, year=None, day=None, month=None): # Basic "edit" list view. Logic about processing of year/month/day # parameters is basically the same as for the public diary view. # # The logic is a bit twisty, from the requirement to show list all dates # and 'ideas' fields in the range, even if they don't have any events in # them, yet. context = {} # Sort out date range to display # If the query contained the number of days ahead to show then retrieve it # and store it as the default for this session (so coming back to the page # will look the same) query_days_ahead = request.GET.get('daysahead', None) if query_days_ahead: edit_prefs.set_preference(request.session, 'daysahead', query_days_ahead) default_days_ahead = query_days_ahead else: default_days_ahead = int( edit_prefs.get_preference(request.session, 'daysahead')) # utility function, shared with public diary view startdatetime, days_ahead = get_date_range( year, month, day, query_days_ahead, default_days_ahead) startdate = startdatetime.date() if startdatetime is None: raise Http404(days_ahead) # Don't allow viewing of dates before today, to avoid editing of the past: local_now = timezone.localtime(timezone.now()) if startdate < local_now.date(): # Redirect to page with today as the start date: new_url = u"{0}?daysahead={1}".format( reverse( 'day-edit', kwargs={ 'year': local_now.year, 'month': local_now.month, 'day': local_now.day }), days_ahead) return HttpResponseRedirect(new_url) enddatetime = startdatetime + datetime.timedelta(days=days_ahead) # Get all showings in the date range showings = (Showing.objects.start_in_range( startdatetime, enddatetime).order_by('start').select_related()) # Build two dicts, to hold the showings and the ideas. These dicts are # initially empty, and get filled in if there are actually showings or # ideas for those dates. # This is done so that if dates don't have ideas/showings they still get # shown in the list dates = OrderedDict() ideas = {startdate: ''} # Actually, I lied: start of visible list is not # neccesarily the 1st of the month, so make sure # that it gets an 'IDEAS' link shown for days in xrange(days_ahead): # Iterate through every date in the visible range, creating a dict # entry for each day_in_range = startdatetime + datetime.timedelta(days=days) dates[day_in_range.date()] = [] # If it's the 1st of the month, make sure there's an ideas entry if day_in_range.day == 1: ideas[day_in_range.date()] = '' # Now insert all the showings into the 'dates' dict for showing in showings: dates[showing.start.date()].append(showing) # Dates without a showing will still be in the dates dict, so will still # be shown # Now get all 'ideas' in date range. Fiddle the date range to be from the # start of the month in startdate, so the idea for that month gets # included: idea_startdate = datetime.date( day=1, month=startdate.month, year=startdate.year) idea_list = (DiaryIdea.objects.filter( month__range=[idea_startdate, enddatetime]).order_by('month'). select_related()) # Assemble into the idea dict, with keys that will match the keys in the # showings dict for idea in idea_list: ideas[idea.month] = idea.ideas # Fiddle so that the idea for the first month is displayed, even if # startdate is after the first day of the month: if (idea_startdate not in showings and len(idea_list) > 0 and idea_list[0].month.month == startdate.month): ideas[startdate] = idea_list[0].ideas context['ideas'] = ideas context['dates'] = dates # Page title: context['event_list_name'] = u"Diary for {0} to {1}".format( startdatetime.strftime("%d-%m-%Y"), enddatetime.strftime("%d-%m-%Y")) context['start'] = startdatetime context['end'] = enddatetime context['edit_prefs'] = edit_prefs.get_preferences(request.session) return render(request, 'edit_event_index.html', context)
def edit_diary_list(request, year=None, day=None, month=None): # Basic "edit" list view. Logic about processing of year/month/day # parameters is basically the same as for the public diary view. # # The logic is a bit twisty, from the requirement to show list all dates # and 'ideas' fields in the range, even if they don't have any events in # them, yet. context = {} # Sort out date range to display # If the query contained the number of days ahead to show then retrieve it # and store it as the default for this session (so coming back to the page # will look the same) query_days_ahead = request.GET.get('daysahead', None) if query_days_ahead: edit_prefs.set_preference(request.session, 'daysahead', query_days_ahead) default_days_ahead = query_days_ahead else: default_days_ahead = int( edit_prefs.get_preference(request.session, 'daysahead')) # utility function, shared with public diary view startdatetime, days_ahead = get_date_range(year, month, day, query_days_ahead, default_days_ahead) startdate = startdatetime.date() if startdatetime is None: raise Http404(days_ahead) # Don't allow viewing of dates before today, to avoid editing of the past: local_now = timezone.localtime(timezone.now()) if startdate < local_now.date(): # Redirect to page with today as the start date: new_url = u"{0}?daysahead={1}".format( reverse('day-edit', kwargs={ 'year': local_now.year, 'month': local_now.month, 'day': local_now.day }), days_ahead) return HttpResponseRedirect(new_url) enddatetime = startdatetime + datetime.timedelta(days=days_ahead) # Get all showings in the date range showings = (Showing.objects.start_in_range( startdatetime, enddatetime).order_by('start').select_related()) # Build two dicts, to hold the showings and the ideas. These dicts are # initially empty, and get filled in if there are actually showings or # ideas for those dates. # This is done so that if dates don't have ideas/showings they still get # shown in the list dates = OrderedDict() # Actually, I lied: start of visible list is not necessarily the 1st of the # month, so make sure that it gets an 'IDEAS' link shown: ideas = {startdate: ''} for days in six.moves.range(days_ahead): # Iterate through every date in the visible range, creating a dict # entry for each day_in_range = startdatetime + datetime.timedelta(days=days) dates[day_in_range.date()] = [] # If it's the 1st of the month, make sure there's an ideas entry if day_in_range.day == 1: ideas[day_in_range.date()] = '' # Now insert all the showings into the 'dates' dict for showing in showings: dates[timezone.localtime(showing.start).date()].append(showing) # Dates without a showing will still be in the dates dict, so will still # be shown # Now get all 'ideas' in date range. Fiddle the date range to be from the # start of the month in startdate, so the idea for that month gets # included: idea_startdate = datetime.date(day=1, month=startdate.month, year=startdate.year) idea_list = (DiaryIdea.objects.filter( month__range=[idea_startdate, enddatetime]).order_by( 'month').select_related()) # Assemble into the idea dict, with keys that will match the keys in the # showings dict for idea in idea_list: ideas[idea.month] = idea.ideas # Fiddle so that the idea for the first month is displayed, even if # startdate is after the first day of the month: if (idea_startdate not in showings and len(idea_list) > 0 and idea_list[0].month.month == startdate.month): ideas[startdate] = idea_list[0].ideas context['ideas'] = ideas context['dates'] = dates # Page title: context['event_list_name'] = u"Diary for {0} to {1}".format( startdatetime.strftime("%d-%m-%Y"), enddatetime.strftime("%d-%m-%Y")) context['start'] = startdatetime context['end'] = enddatetime context['edit_prefs'] = edit_prefs.get_preferences(request.session) context['rooms'] = ([None] + list(Room.objects.all()) if settings.MULTIROOM_ENABLED else [None]) context['multiroom_enabled'] = settings.MULTIROOM_ENABLED return render(request, 'edit_event_index.html', context)
def view_diary(request, year=None, month=None, day=None, event_type=None): # Returns public diary view, starting at specified year/month/day, filtered # by event type. # # Returns different things depending on the supplied parameters; # - if only year is passed, and no daysahead parameter,listings for the # whole of that year # - if only year & month passed, and no daysahead parameter, listings for # the whole of that month # - if year, month & day, and no daysahead parameter, listings for that day # only # - if dayssahead parameter is passed, that many days from the specified # year/month/date context = {} query_days_ahead = request.GET.get('daysahead', None) # Shared utility method to parse HTTP parameters and return a date range startdate, days_ahead = get_date_range(year, month, day, query_days_ahead) if startdate is None: raise Http404(days_ahead) enddate = startdate + datetime.timedelta(days=days_ahead) # Start getting together data to send to the template... context['today'] = datetime.date.today() context['start'] = startdate context['end'] = enddate # Following is user input passed back, so make doubly sure that it gets # escaped in the template: context['event_type'] = mark_for_escaping(event_type) if event_type else None # Set page title if year: # If some specific dates were provided, use those context['event_list_name'] = u"Cube Programme for {0}".format( u"/".join([str(s) for s in (day, month, year) if s]) ) else: # Default title context['event_list_name'] = "Cube Programme" # Build query. The select_related() and prefetch_related on the end # encourages it to get the associated showing/event data, to reduce the # number of SQL queries showings = (Showing.objects.public() .start_in_range(startdate, enddate) .order_by('start') .select_related() .prefetch_related('event__media')) if event_type: showings = showings.filter(event__tags__slug=event_type) # Build a list of events for that list of showings: events = OrderedDict() for showing in showings: events.setdefault(showing.event, list()).append(showing) context['showings'] = showings # Set of Showing objects for date range context['events'] = events # Ordered dict mapping event -> list of showings # This is prepended to filepaths from the MediaPaths table to use # as a location for images: context['media_url'] = settings.MEDIA_URL context['printed_programmes'] = PrintedProgramme.objects.month_in_range( startdate, enddate) return render(request, 'view_showing_index.html', context)