1 # chloro - personal space
2 # Copyright (C) 2019 Frederic Peters
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.
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.
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/>.
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 HttpResponse, Http404
23 from django.utils.feedgenerator import Atom1Feed
24 from django.views import View
25 from django.views.generic import CreateView, DeleteView, DetailView, ListView, UpdateView, TemplateView
27 from .models import Note
30 class NoteView(DetailView):
33 def get(self, request, *args, **kwargs):
34 note = self.get_object()
35 if kwargs.get('year'):
36 # check date does match
37 creation = self.get_object().creation_timestamp
38 if (creation.year, creation.month, creation.day) != (
44 if not note.published and not request.user.is_staff:
45 raise PermissionDenied()
46 return super(NoteView, self).get(request, *args, **kwargs)
49 class NoteEditView(UpdateView):
51 fields = ['title', 'slug', 'text', 'tags', 'published']
54 class NoteApiSaveView(View):
55 http_method_names = ['post']
57 def post(self, request, *args, **kwargs):
58 note = Note.objects.get(slug=kwargs['slug'])
59 note.text = request.POST['text']
61 return HttpResponse('ok')
64 class NoteAddView(CreateView):
66 fields = ['title', 'slug', 'text', 'tags', 'published']
69 class NoteDeleteView(DeleteView):
72 def get_success_url(self):
76 class HomeView(TemplateView):
77 template_name = 'phyll/home.html'
79 def get_context_data(self, **kwargs):
80 context = super(HomeView, self).get_context_data(**kwargs)
81 context['posts'] = Note.objects.filter(published=True).order_by('-creation_timestamp')[:5]
85 class ArchivesView(ListView):
88 def get_queryset(self):
89 qs = super(ArchivesView, self).get_queryset()
90 if not self.request.user.is_staff:
91 qs = qs.filter(published=True)
95 class ListOnTagView(ListView):
98 def get_queryset(self):
99 qs = Note.objects.filter(tags__name__in=[self.kwargs['tag']])
100 if not self.request.user.is_staff:
101 qs = qs.filter(published=True)
105 class Atom1FeedWithBaseXml(Atom1Feed):
106 def root_attributes(self):
107 root_attributes = super(Atom1FeedWithBaseXml, self).root_attributes()
108 scheme, netloc, path, params, query, fragment = urllib.parse.urlparse(self.feed['feed_url'])
109 root_attributes['xml:base'] = urllib.parse.urlunparse((scheme, netloc, '/', params, query, fragment))
110 return root_attributes
113 class AtomFeed(Feed):
114 title = settings.SITE_TITLE
116 feed_type = Atom1FeedWithBaseXml
117 author_name = settings.SITE_AUTHOR
119 def get_object(self, request, *args, **kwargs):
120 self.sub = kwargs.get('sub', 'default')
121 return super(AtomFeed, self).get_object(request, *args, **kwargs)
124 qs = Note.objects.filter(published=True)
125 if self.sub == 'default':
127 elif self.sub == 'gnome-en':
128 qs = qs.filter(tags__name__in=['gnome']).filter(tags__name__in=['lang-en'])
130 qs = qs.filter(tags__name__in=[self.sub])
131 return qs.select_related()[:20]
133 def item_description(self, item):
136 def item_guid(self, item):
137 for tag in item.tags.all():
138 if tag.name.startswith('old-post-id-'):
139 return 'http://www.0d.be/posts/%s' % tag.name.split('-')[-1]
140 return 'https://www.0d.be' + item.get_absolute_url()
142 def item_title(self, item):
145 def item_pubdate(self, item):
146 return item.creation_timestamp