class AuthorList(ListView):
    model = Author
    context_object_name = 'author_list'
    queryset = Author.objects.annotate(Count('articles')).\
        order_by("last_name", "first_name")
    template_name = 'periodicals/author_list.html'
    paginate_by = settings.PERIODICALS_PAGINATION class AuthorDetail(ListView):
    model = Article
    context_object_name = 'article_list'
    slug_url_kwarg = 'author_slug'
    template_name = 'periodicals/author_detail.html'
    paginate_by = settings.PERIODICALS_PAGINATION

    def get_queryset(self):
        self.author = get_object_or_404(Author,
                                        slug=self.kwargs['author_slug'])

        return Article.objects.filter(authors__in=(self.author.id,)).\
            select_related().order_by('-issue__pub_date')

    def get_context_data(self, **kwargs):
        context = super(AuthorDetail, self).get_context_data(**kwargs)
        context['author'] = self.author
        return context class ArticleDetail(DetailView):
    model = Article
    context_object_name = 'article'
    slug_url_kwarg = 'article_slug'
    template_name = 'periodicals/article_detail.html'

    def get_queryset(self):
        periodical_slug = self.kwargs['periodical_slug']
        self.periodical = get_object_or_404(Periodical,
                                            slug=periodical_slug)
        issue_slug = self.kwargs['issue_slug']
        self.issue = get_object_or_404(Issue,
                                       periodical=self.periodical,
                                       slug=issue_slug)
        return super(ArticleDetail, self).get_queryset()

    def get_context_data(self, **kwargs):
        context = super(ArticleDetail, self).get_context_data(**kwargs)
        article = context['article']
        next_article = previous_article = None
        if article.page:
            try:
                next_article = Article.objects.filter(issue=self.issue).\
                    filter(page__gt=article.page).order_by('page')[0:1].get()
            except ObjectDoesNotExist:
                next_article = None
            try:
                previous_article = Article.objects.filter(issue=self.issue).\
                    filter(page__lt=article.page).order_by('-page')[0:1].get()
            except ObjectDoesNotExist:
                previous_article = None
        context['periodical'] = self.periodical
        context['issue'] = self.issue
        context['previous_article'] = previous_article
        context['next_article'] = next_article
        context['links_enabled'] = settings.PERIODICALS_LINKS_ENABLED
        context['form'] = LinkItemForm()
        return context class ArticleTags(TaggedObjectListView):
    queryset = Article.objects.order_by('-issue__pub_date').select_related().all()
    paginate_by = settings.PERIODICALS_PAGINATION

    def get_queryset(self):
        tag = self.kwargs.get('tag', None)
        if tag:
            # unslugify tag
            self.kwargs['tag'] = tag.replace('-', ' ')

        return super(ArticleTags, self).get_queryset() class IssueYear(YearArchiveView):
    queryset = Issue.objects.all()
    date_field = 'pub_date'
    make_object_list = True
    allow_future = False
    template_name = 'periodicals/issue_year.html'

    def get_queryset(self):
        periodical_slug = self.kwargs['periodical_slug']
        periodical = get_object_or_404(Periodical, slug=periodical_slug)
        self.periodical = periodical
        qs = super(IssueYear, self).get_queryset().\
            filter(periodical=periodical).reverse()
        return qs

    def get_context_data(self, **kwargs):
        context = super(IssueYear, self).get_context_data(**kwargs)
        context['periodical'] = self.periodical
        return context class IssueDetail(TemplateView):
    # issue_slug is only unique per month so can't use
    # regular DetailView
    template_name = 'periodicals/issue_detail.html'

    def get_context_data(self, **kwargs):
        context = super(IssueDetail, self).get_context_data(**kwargs)
        periodical_slug = kwargs['periodical_slug']
        periodical = get_object_or_404(Periodical,
                                       slug=periodical_slug)
        issue = get_object_or_404(Issue,
                                  periodical=periodical,
                                  slug=kwargs['issue_slug'])
        try:
            next_month = Issue.objects.filter(periodical=periodical).\
                filter(pub_date__gt=issue.pub_date).order_by('pub_date')[0:1].get()
        except ObjectDoesNotExist:
            next_month = None

        try:
            previous_month = Issue.objects.filter(periodical=periodical).\
                filter(pub_date__lt=issue.pub_date).order_by('-pub_date')[0:1].get()
        except ObjectDoesNotExist:
            previous_month = None

        context['issue'] = issue
        context['periodical'] = periodical
        context['previous_month'] = previous_month
        context['next_month'] = next_month
        context['links_enabled'] = settings.PERIODICALS_LINKS_ENABLED
        context['form'] = LinkItemForm()
        return context class PeriodicalList(ListView):
    model = Periodical
    template_name = 'periodicals/periodical_list.html' class PeriodicalDetail(ArchiveIndexView):
    model = Issue
    date_field = 'pub_date'
    allow_empty = True
    allow_future = True
    template_name = 'periodicals/periodical_detail.html'
    slug_url_kwarg = 'periodical_slug'

    def get_queryset(self):
        self.periodical_slug = self.kwargs['periodical_slug']
        qs = super(PeriodicalDetail, self).get_queryset()
        return qs

    def get_context_data(self, **kwargs):
        context = super(PeriodicalDetail, self).get_context_data(**kwargs)
        periodical = get_object_or_404(Periodical, slug=self.periodical_slug)
        context['periodical'] = periodical
        context['links_enabled'] = settings.PERIODICALS_LINKS_ENABLED
        return context class SeriesList(ListView):
    model = Article
    context_object_name = 'series_list'
    template_name = 'periodicals/series_list.html'
    paginate_by = settings.PERIODICALS_PAGINATION

    def get_queryset(self):
        self.periodical = get_object_or_404(Periodical,
                                            slug=self.kwargs['periodical_slug'])
        return Article.objects.filter(issue__periodical=self.periodical).\
            order_by('series').values('series').annotate(series_count=Count('series'))

    def get_context_data(self, **kwargs):
        context = super(SeriesList, self).get_context_data(**kwargs)
        context['periodical'] = self.periodical
        return context class SeriesDetail(ListView):
    model = Article
    context_object_name = 'article_list'
    template_name = 'periodicals/series_detail.html'
    paginate_by = settings.PERIODICALS_PAGINATION

    def get_queryset(self):
        self.periodical = get_object_or_404(Periodical,
                                            slug=self.kwargs['periodical_slug'])
        self.series = self.kwargs['series']
        return Article.objects.filter(issue__periodical=self.periodical).\
            filter(series=self.series).\
            select_related().order_by('-issue__pub_date')

    def get_context_data(self, **kwargs):
        context = super(SeriesDetail, self).get_context_data(**kwargs)
        context['periodical'] = self.periodical
        context['series'] = self.series
        return context
from django.contrib import admin
from django.conf import settings
from django.conf.urls import patterns, url
from django.views.generic import TemplateView
from haystack.views import SearchView
from haystack.query import SearchQuerySet
from .views import (AuthorList, AuthorDetail,
                    ArticleDetail, ArticleTags,
                    IssueYear, IssueDetail,
                    PeriodicalList, PeriodicalDetail,
                    SeriesList, SeriesDetail)


# query results with most recent publication date first
sqs = SearchQuerySet().order_by('-pub_date')

urlpatterns = \
    patterns('',
             url(r'^search/',
                 SearchView(load_all=False,
                            template="periodicals/search.html",
                            searchqueryset=sqs,
                            ),
                 name='haystack_search',
                 ),
             # not in sitemap
             url(r'^authors/$',
                 AuthorList.as_view(),
                 name='periodicals_authors_list',
                 ),

             url(r'^authors/(?P<author_slug>[-\w]+)/$',
                 AuthorDetail.as_view(),
                 name='periodicals_author_detail'
                 ),

             url(r'^tags/$',
                 TemplateView.as_view(template_name='periodicals/tags.html'),
                 name='periodicals_tags',
                 ),

             url(r'^tag/(?P<tag>[^/]+)/$',
                 ArticleTags.as_view(template_name='periodicals/article_tag_detail.html'),
                 name='periodicals_article_tag_detail'
                 ),
             )

if settings.PERIODICALS_LINKS_ENABLED:
    urlpatterns += \
        patterns('',
                 # success for adding a link - don't include in sitemap
                 url(r'^links/added/$',
                     TemplateView.as_view(template_name='periodicals/link_success.html'),
                     name='periodicals_add_link_success'
                     ),

                 # add a link to an article - don't include in sitemap
                 url(r'^links/(?P<periodical_slug>[-\w]+)/(?P<issue_slug>[-\w]+)/(?P<article_slug>[-\w]+)/$',
                     'periodicals.views.add_article_link',
                     name='periodicals_add_article_link'
                     ),

                 # add a link to an issue - don't include in sitemap
                 url(r'^links/(?P<periodical_slug>[-\w]+)/(?P<issue_slug>[-\w]+)/$',
                     'periodicals.views.add_issue_link',
                     name='periodicals_add_issue_link'
                     ),

                 # Page showing all periodical Issues and Articles with external links
                 url(r'^links/(?P<periodical_slug>[-\w]+)/$',
                     'periodicals.views.links',
                     name='periodicals_links'
                     ),
                 )

urlpatterns += \
    patterns('',
             # periodical detail including list of periodical's years
             url(r'^(?P<periodical_slug>[-\w]+)/$',

                 PeriodicalDetail.as_view(),