articles.py 6.24 KB
Newer Older
1
2
from django.http import HttpResponseRedirect
from django.views.generic.detail import DetailView
3
from django.views.generic.list import ListView
4
from django.views.generic.edit import UpdateView
5
from django.utils.translation import ugettext_lazy as _
cynddl's avatar
cynddl committed
6
from django.urls import reverse, reverse_lazy
cynddl's avatar
cynddl committed
7
from django.db.models import Count
Thibaut Broggi's avatar
Thibaut Broggi committed
8
from django.db.models import Q
9
10
from django import forms

11
12
from django.contrib.auth.mixins import (LoginRequiredMixin,
                                        PermissionRequiredMixin)
13

14
from crispy_forms.helper import FormHelper
cynddl's avatar
cynddl committed
15
from crispy_forms.layout import Layout, Field, Div, HTML
16
17
from crispy_forms.bootstrap import AppendedText

cynddl's avatar
cynddl committed
18
19
from taggit.models import Tag
from rp.forms import TagMultipleChoiceField
20

luxcem's avatar
luxcem committed
21
22
23
from rp.models import Article


24
25
26
27
class ArticleList(ListView):
    model = Article
    paginate_by = 10
    template_name = "rp/article_list_public.html"
28
    filter_lang = None
cynddl's avatar
cynddl committed
29
    filter_tag = None
30
31
32
    archive = 'false'
    quote = 'both'
    speak = 'both'
cynddl's avatar
cynddl committed
33

34
35
36
37
38
39
    def get_queryset(self):
        if self.filter_lang in ["EN", "FR"]:
            qs = Article.objects.filter(lang=self.filter_lang)
        else:
            qs = Article.objects.filter()

40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
        # Tags filtering
        self.quote = self.request.GET.get('quote', self.quote)
        self.speak = self.request.GET.get('speak', self.speak)
        self.archive = self.request.GET.get('archive', self.archive)

        if self.speak != 'both':
            if self.speak == 'true':
                qs = qs.filter(speak=True)
            else:
                qs = qs.filter(speak=False)

        if self.quote != 'both':
            if self.quote == 'true':
                qs = qs.filter(quote=True)
            else:
                qs = qs.filter(quote=False)

        if self.archive != 'both':
            if self.archive == 'true':
                qs = qs.filter(archive=True)
            else:
                qs = qs.filter(archive=False)

Thibaut Broggi's avatar
Thibaut Broggi committed
63
64
65
66
        search_keywords = self.request.GET.get('q', '')
        if search_keywords != '':
            qs = qs.filter(Q(title__icontains=search_keywords)
                           | Q(extracts__icontains=search_keywords))
Thibaut Broggi's avatar
Thibaut Broggi committed
67

cynddl's avatar
cynddl committed
68
69
70
71
        filter_tag = self.kwargs.get("filter_tag", self.filter_tag)
        if filter_tag is not None:
            qs = qs.filter(tags__name__in=[filter_tag])

72
        return qs.order_by('-created_at')
cynddl's avatar
cynddl committed
73
74
75
76

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

77
78
        qs = Tag.objects.annotate(
                num_times=Count('taggit_taggeditem_items')).all()
cynddl's avatar
cynddl committed
79
80
        qs = qs.order_by('-num_times')
        context["tags"] = qs
81
        context["search"] = self.request.GET.get('q', '')
82
83
84
        context["archive"] = self.request.GET.get('archive', self.archive)
        context["speak"] = self.request.GET.get('speak', self.speak)
        context["quote"] = self.request.GET.get('quote', self.quote)
cynddl's avatar
cynddl committed
85
86

        return context
87
88


89
class ArticleListFlux(LoginRequiredMixin, ListView):
luxcem's avatar
luxcem committed
90
    model = Article
cynddl's avatar
cynddl committed
91
92
93
94
95
    paginate_by = 10

    def get_queryset(self):
        filter_view = self.kwargs.get("filter_view", "draft")

96
97
        if filter_view in ["published", "draft", "rejected"]:
            qs = Article.objects.filter(status=filter_view.upper())
cynddl's avatar
cynddl committed
98
        else:
99
            qs = Article.objects.filter(status="NEW")
cynddl's avatar
cynddl committed
100
101
102
103
104
105

        return qs.order_by('-created_at')

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["filter_view"] = self.kwargs.get("filter_view", "draft")
106
        context["nb_draft"] = Article.objects.filter(status="DRAFT").count()
cynddl's avatar
cynddl committed
107
        return context
108
109


110
class ArticleDetailView(LoginRequiredMixin, DetailView):
111
112
113
114
115
116
117
118
119
    model = Article
    preview = False

    def get_context_data(self, **kwargs):
        context = super(ArticleDetailView, self).get_context_data(**kwargs)
        context['is_preview'] = self.preview
        return context


120
class ArticleEdit(PermissionRequiredMixin, UpdateView):
121
    model = Article
122
    permission_required = 'rp.can_edit'
123

124
125
    fields = ['screenshot', 'url', 'lang', 'title', 'tags', 'extracts',
              'quote', 'speak', 'archive']
cynddl's avatar
cynddl committed
126
    success_url = reverse_lazy("rp:article-list")
127

128
129
130
131
132
133
134
    def get(self, request, **kwargs):
        self.object = self.get_object()

        if 'fetch_content' in self.request.GET:
            self.object.fetch_content()
        elif 'fetch_image' in self.request.GET:
            self.object.fetch_image()
135
136
        elif 'fetch_metadata' in self.request.GET:
            self.object.fetch_metadata()
137
138
139
140

        context = self.get_context_data(object=self.object)
        return self.render_to_response(context)

141
142
143
144
145
    def form_valid(self, form):
        self.object = form.save()

        if "preview" in self.request.POST:
            self.success_url = reverse("rp:article-preview", args=[self.object.id])
cynddl's avatar
cynddl committed
146
147
        elif "view" in self.request.POST:
            self.success_url = reverse("rp:article-view", args=[self.object.id])
148
        elif "publish" in self.request.POST:
149
            self.object.publish()
150
            self.object.save()
151
152
153
154
155
156
157
158
159
160

        return HttpResponseRedirect(self.get_success_url())

    def get_form(self, form_class=None):
        form = super().get_form(form_class)
        form.fields["screenshot"].widget = forms.widgets.FileInput()

        form.helper = FormHelper()
        form.helper.form_tag = False

cynddl's avatar
cynddl committed
161
162
        # Change the layout of the tags field
        form.fields["tags"] = TagMultipleChoiceField(
163
            queryset=Tag.objects.all(), required=False)
cynddl's avatar
cynddl committed
164

165
166
167
168
169
        left_layout = Div(
            Div(
                Field('title', wrapper_class='col-sm-10'),
                Field('lang', wrapper_class='col-sm-2'),
                css_class="row"),
170
171
172
            AppendedText(
                'url',
                _('<a href="%s">Go to link</a>') % form.initial['url']),
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
            'tags',
            'extracts',
            css_class="col-sm-8")

        right_layout = Div(
            'screenshot',
            HTML(
                """
                {% if form.screenshot.value %}
                <img class="img-responsive mb-4"
                     src="/media/{{ form.screenshot.value }}">
                {% endif %}
                """
            ),
            css_class="col-sm-4")

        form.helper.layout = Layout(
            Div(left_layout, right_layout, css_class="row"))

        return form