<commit_before>"""
Views for the news application
"""

from django.conf import settings
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.db.models import Q, Prefetch
from django.http import HttpResponseForbidden
from django.shortcuts import redirect, get_object_or_404
from django.views.generic import TemplateView
from django.views.generic.dates import (
    YearArchiveView,
    MonthArchiveView,
    DayArchiveView,
    DateDetailView
)

from rest_framework import viewsets
from rest_framework.permissions import DjangoModelPermissions
import django_filters

from muckrock.news.filters import (
    ArticleDateRangeFilterSet,
    ArticleAuthorFilterSet
)
from muckrock.news.models import Article
from muckrock.news.serializers import ArticleSerializer
from muckrock.project.forms import ProjectManagerForm
from muckrock.project.models import Project
from muckrock.tags.models import Tag, parse_tags
from muckrock.utils import cache_get_or_set
from muckrock.views import PaginationMixin, MRSearchFilterListView

# pylint: disable=too-many-ancestors

class NewsDetail(DateDetailView):
    """View for news detail"""
    template_name = 'news/detail.html'
    date_field = 'pub_date'

    def get_queryset(self):
        """Get articles for this view"""
        queryset = Article.objects.prefetch_authors().prefetch_editors()
        if self.request.user.is_staff:
            return queryset.all()
        else:
            return queryset.get_published()

    def get_allow_future(self):
        """Can future posts be seen?"""
        return self.request.user.is_staff

    def get_related_articles(self, article):
        """Get articles related to the current one."""
        # pylint: disable=no-self-use
        # articles in the same project as this one
        project_filter = Q(projects__in=article.projects.all())
        # articles with the same tag as this one
        tag_filter = Q(tags__in=article.tags.all())
        # articles in projects with the same tag as this one
        project_tag_filter = Q(projects__tags__in=article.tags.all())
        related_articles = (Article.objects
                .get_published()
                .filter(project_filter | tag_filter | project_tag_filter)
                .exclude(pk=article.pk)
                .distinct()
                .prefetch_authors()
                .prefetch_editors())
        return related_articles[:4]

    def get_context_data(self, **kwargs):
        context = super(NewsDetail, self).get_context_data(**kwargs)
        context['projects'] = context['object'].projects.all()
        context['foias'] = (context['object'].foias
                .select_related_view().get_public_file_count())
        context['related_articles'] = self.get_related_articles(context['object'])
        context['sidebar_admin_url'] = reverse('admin:news_article_change',
            args=(context['object'].pk,))
        context['stripe_pk'] = settings.STRIPE_PUB_KEY
        return context

    def post(self, request, **kwargs):
        """Handles POST requests on article pages"""
        # pylint:disable=unused-argument
        article = self.get_object()
        authorized = self.request.user.is_staff
        action = request.POST.get('action')
        if not authorized:
            return HttpResponseForbidden()
        if action == 'projects':
            form = ProjectManagerForm(request.POST, request.user)
            if form.is_valid():
                projects = form.cleaned_data['projects']
                article.projects = projects
        tags = request.POST.get('tags')
        if tags:
            tag_set = set()
            for tag in parse_tags(tags):
                new_tag, _ = Tag.objects.get_or_create(name=tag)
                tag_set.add(new_tag)
            article.tags.set(*tag_set)
        return redirect(article)


class NewsExploreView(TemplateView):
    """Shows the most interesting and worthwhile articles."""
    template_name = 'news/explore.html'

    def get_context_data(self, **kwargs):
        """Adds interesting articles to the explore page."""
        context = super(NewsExploreView, self).get_context_data(**kwargs)
        recent_articles = cache_get_or_set('hp:articles',
            lambda: (Article.objects.get_published().prefetch_related(
                'authors',
                'authors__profile',
                'projects',
            )[:5]),<commit_msg>fix user argument to project form<commit_after>"""
Views for the news application
"""

from django.conf import settings
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.db.models import Q, Prefetch
from django.http import HttpResponseForbidden
from django.shortcuts import redirect, get_object_or_404
from django.views.generic import TemplateView
from django.views.generic.dates import (
    YearArchiveView,
    MonthArchiveView,
    DayArchiveView,
    DateDetailView
)

from rest_framework import viewsets
from rest_framework.permissions import DjangoModelPermissions
import django_filters

from muckrock.news.filters import (
    ArticleDateRangeFilterSet,
    ArticleAuthorFilterSet
)
from muckrock.news.models import Article
from muckrock.news.serializers import ArticleSerializer
from muckrock.project.forms import ProjectManagerForm
from muckrock.project.models import Project
from muckrock.tags.models import Tag, parse_tags
from muckrock.utils import cache_get_or_set
from muckrock.views import PaginationMixin, MRSearchFilterListView

# pylint: disable=too-many-ancestors

class NewsDetail(DateDetailView):
    """View for news detail"""
    template_name = 'news/detail.html'
    date_field = 'pub_date'

    def get_queryset(self):
        """Get articles for this view"""
        queryset = Article.objects.prefetch_authors().prefetch_editors()
        if self.request.user.is_staff:
            return queryset.all()
        else:
            return queryset.get_published()

    def get_allow_future(self):
        """Can future posts be seen?"""
        return self.request.user.is_staff

    def get_related_articles(self, article):
        """Get articles related to the current one."""
        # pylint: disable=no-self-use
        # articles in the same project as this one
        project_filter = Q(projects__in=article.projects.all())
        # articles with the same tag as this one
        tag_filter = Q(tags__in=article.tags.all())
        # articles in projects with the same tag as this one
        project_tag_filter = Q(projects__tags__in=article.tags.all())
        related_articles = (Article.objects
                .get_published()
                .filter(project_filter | tag_filter | project_tag_filter)
                .exclude(pk=article.pk)
                .distinct()
                .prefetch_authors()
                .prefetch_editors())
        return related_articles[:4]

    def get_context_data(self, **kwargs):
        context = super(NewsDetail, self).get_context_data(**kwargs)
        context['projects'] = context['object'].projects.all()
        context['foias'] = (context['object'].foias
                .select_related_view().get_public_file_count())
        context['related_articles'] = self.get_related_articles(context['object'])
        context['sidebar_admin_url'] = reverse('admin:news_article_change',
            args=(context['object'].pk,))
        context['stripe_pk'] = settings.STRIPE_PUB_KEY
        return context

    def post(self, request, **kwargs):
        """Handles POST requests on article pages"""
        # pylint:disable=unused-argument
        article = self.get_object()
        authorized = self.request.user.is_staff
        action = request.POST.get('action')
        if not authorized:
            return HttpResponseForbidden()
        if action == 'projects':
            form = ProjectManagerForm(request.POST, user=request.user)
            if form.is_valid():
                projects = form.cleaned_data['projects']
                article.projects = projects
        tags = request.POST.get('tags')
        if tags:
            tag_set = set()
            for tag in parse_tags(tags):
                new_tag, _ = Tag.objects.get_or_create(name=tag)
                tag_set.add(new_tag)
            article.tags.set(*tag_set)
        return redirect(article)


class NewsExploreView(TemplateView):
    """Shows the most interesting and worthwhile articles."""
    template_name = 'news/explore.html'

    def get_context_data(self, **kwargs):
        """Adds interesting articles to the explore page."""
        context = super(NewsExploreView, self).get_context_data(**kwargs)
        recent_articles = cache_get_or_set('hp:articles',
            lambda: (Article.objects.get_published().prefetch_related(
                'authors',
                'authors__profile',
                'projects',
            )[:5]),
{'fraction_non_alphanumeric': 0.09549994388957468, 'fraction_numerical': 0.001122208506340478, 'mean_word_length': 2.8815331010452963, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '317879', 'n_tokens_mistral': 2474, 'n_tokens_neox': 2373, 'n_words': 570}