import datetime import json from collections import OrderedDict from itertools import groupby from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator from django.db.models import Sum, Min from django.http import HttpResponse from django.shortcuts import get_object_or_404, render from django.utils import timezone from django.views.decorators.cache import cache_page from woid.apps.services.models import Service, Story from woid.apps.services.utils import remove_duplicates def stories(request, service, queryset, subtitle): paginator = Paginator(queryset, 100) page = request.GET.get('page') try: stories = paginator.page(page) except PageNotAnInteger: stories = paginator.page(1) except EmptyPage: stories = paginator.page(paginator.num_pages) if stories.number > 1: start = (stories.number - 1) * 100 + 1 else: start = 1 if 'application/json' in request.META.get('HTTP_ACCEPT'): stories_dict = map(lambda story: story.to_dict(), stories) dump = json.dumps({ 'service': service.to_dict(), 'stories': stories_dict, 'subtitle': subtitle }) return HttpResponse(dump, content_type='application/json') else: return render(request, 'services/stories.html', { 'service': service, 'stories': stories, 'subtitle': subtitle, 'start': start }) @cache_page(60) def front_page(request): today = timezone.now() stories = list() services = Service.objects.all() for service in services: top_story = service.stories.filter(status=Story.OK, date=today).order_by('-score').first() if top_story: stories.append(top_story) subtitle = today.strftime('%d %b %Y') if 'application/json' in request.META.get('HTTP_ACCEPT'): stories_dict = map(lambda story: story.to_dict(), stories) dump = json.dumps({ 'stories': stories_dict, 'subtitle': subtitle }) return HttpResponse(dump, content_type='application/json') else: return render(request, 'services/front_page.html', {'stories': stories, 'subtitle': subtitle}) @cache_page(60) def index(request, slug): today = timezone.now() return day(request, slug, today.year, today.month, today.day) @cache_page(5 * 60) def year(request, slug, year): service = get_object_or_404(Service, slug=slug) queryset = service.stories \ .filter(status=Story.OK, date__year=year) \ .values('url', 'title') \ .annotate(score=Sum('score'), date=Min('date')) \ .order_by('-score') return stories(request, service, queryset, year) @cache_page(5 * 60) def month(request, slug, year, month): service = get_object_or_404(Service, slug=slug) queryset = service.stories \ .filter(status=Story.OK, date__year=year, date__month=month) \ .values('url', 'title') \ .annotate(score=Sum('score'), date=Min('date')) \ .order_by('-score') subtitle = timezone.datetime(int(year), int(month), 1).strftime('%b %Y') return stories(request, service, queryset, subtitle) @cache_page(5 * 60) def day(request, slug, year, month, day): date = datetime.datetime(int(year), int(month), int(day)) service = get_object_or_404(Service, slug=slug) queryset = service.stories.filter(status=Story.OK, date=date)[:10] subtitle = timezone.datetime(int(year), int(month), int(day)).strftime('%d %b %Y') return stories(request, service, queryset, subtitle) @cache_page(60 * 60) def archive(request, slug): service = get_object_or_404(Service, slug=slug) dates = service.stories.all().order_by('-date').values_list('date', flat=True) str_dates = map(lambda date: date.strftime('%Y-%m-%d'), dates) str_dates = remove_duplicates(str_dates) archive = OrderedDict() for year, months in groupby(str_dates, lambda date: date[:4]): archive[year] = OrderedDict() for month, days in groupby(months, lambda date: date[5:7]): archive[year][month] = list() for day in days: archive[year][month].append(day[8:10]) if 'application/json' in request.META.get('HTTP_ACCEPT'): dump = json.dumps(archive) return HttpResponse(dump, content_type='application/json') else: return render(request, 'services/archive.html', { 'service': service, 'archive': archive })