6c8fdabf26d5febc7f7e49fde7221bdbb621355e
[chloro.git] / chloro / phyll / views.py
1 # chloro - personal space
2 # Copyright (C) 2019  Frederic Peters
3 #
4 # This program is free software: you can redistribute it and/or modify it
5 # under the terms of the GNU Affero General Public License as published
6 # by the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU Affero General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 import urllib.parse
18
19 from django.conf import settings
20 from django.contrib.syndication.views import Feed
21 from django.core.exceptions import PermissionDenied
22 from django.http import Http404
23 from django.utils.feedgenerator import Atom1Feed
24 from django.views.generic import CreateView, DeleteView, DetailView, ListView, UpdateView, TemplateView
25
26 from .models import Note
27
28
29 class NoteView(DetailView):
30     model = Note
31
32     def get(self, request, *args, **kwargs):
33         note = self.get_object()
34         if kwargs.get('year'):
35             # check date does match
36             creation = self.get_object().creation_timestamp
37             if (creation.year, creation.month, creation.day) != (
38                 int(kwargs['year']),
39                 int(kwargs['month']),
40                 int(kwargs['day']),
41             ):
42                 raise Http404()
43         if not note.published and not request.user.is_staff:
44             raise PermissionDenied()
45         return super(NoteView, self).get(request, *args, **kwargs)
46
47
48 class NoteEditView(UpdateView):
49     model = Note
50     fields = ['title', 'slug', 'text', 'tags', 'published']
51
52
53 class NoteAddView(CreateView):
54     model = Note
55     fields = ['title', 'slug', 'text', 'tags', 'published']
56
57
58 class NoteDeleteView(DeleteView):
59     model = Note
60
61     def get_success_url(self):
62         return '/'
63
64
65 class HomeView(TemplateView):
66     template_name = 'phyll/home.html'
67
68     def get_context_data(self, **kwargs):
69         context = super(HomeView, self).get_context_data(**kwargs)
70         context['latest'] = Note.objects.filter(published=True).latest('creation_timestamp')
71         return context
72
73
74 class ArchivesView(ListView):
75     model = Note
76
77     def get_queryset(self):
78         qs = super(ArchivesView, self).get_queryset()
79         if not self.request.user.is_staff:
80             qs = qs.filter(published=True)
81         return qs
82
83
84 class ListOnTagView(ListView):
85     model = Note
86
87     def get_queryset(self):
88         qs = Note.objects.filter(tags__name__in=[self.kwargs['tag']])
89         if not self.request.user.is_staff:
90             qs = qs.filter(published=True)
91         return qs
92
93
94 class Atom1FeedWithBaseXml(Atom1Feed):
95     def root_attributes(self):
96         root_attributes = super(Atom1FeedWithBaseXml, self).root_attributes()
97         scheme, netloc, path, params, query, fragment = urllib.parse.urlparse(self.feed['feed_url'])
98         root_attributes['xml:base'] = urllib.parse.urlunparse((scheme, netloc, '/', params, query, fragment))
99         return root_attributes
100
101
102 class AtomFeed(Feed):
103     title = settings.SITE_TITLE
104     link = '/'
105     feed_type = Atom1FeedWithBaseXml
106     author_name = settings.SITE_AUTHOR
107
108     def get_object(self, request, *args, **kwargs):
109         self.sub = kwargs.get('sub', 'default')
110         return super(AtomFeed, self).get_object(request, *args, **kwargs)
111
112     def items(self):
113         qs = Note.objects.filter(published=True)
114         if self.sub == 'default':
115             pass
116         elif self.sub == 'gnome-en':
117             qs = qs.filter(tags__name__in=['gnome']).filter(tags__name__in=['lang-en'])
118         else:
119             qs = qs.filter(tags__name__in=[self.sub])
120         return qs.select_related()[:20]
121
122     def item_description(self, item):
123         return item.text
124
125     def item_guid(self, item):
126         for tag in item.tags.all():
127             if tag.name.startswith('old-post-id-'):
128                 return 'http://www.0d.be/posts/%s' % tag.name.split('-')[-1]
129         return 'https://www.0d.be' + item.get_absolute_url()
130
131     def item_title(self, item):
132         return item.title
133
134     def item_pubdate(self, item):
135         return item.creation_timestamp