5 import newsletter.views
6 from combo.data.models import Page
7 from django.conf import settings
8 from django.contrib import messages
9 from django.contrib.auth.decorators import login_required
10 from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector
11 from django.core.exceptions import PermissionDenied
12 from django.shortcuts import redirect
13 from django.template import loader
14 from django.urls import reverse
15 from django.views.generic.base import RedirectView, TemplateView
16 from django.views.generic.list import ListView
17 from emissions.models import Diffusion, Emission, Episode, Focus, NewsCategory, NewsItem, SoundFile
18 from emissions.utils import period_program
20 from .poll.models import Vote
21 from .service_messages.models import Message
23 logger = logging.getLogger('panikdb')
26 class Home(TemplateView):
27 template_name = 'home.html'
29 def get_context_data(self, **kwargs):
30 context = super().get_context_data(**kwargs)
32 from .regie.views import RegieHome
34 context.update(RegieHome().get_context_data(**kwargs))
37 vote = Vote.objects.get(user=self.request.user)
38 except Vote.DoesNotExist:
39 context['display_poll_button'] = True
40 context['emissions'] = self.request.user.emissions.all().order_by('title')
41 context['news_categories'] = self.request.user.news_categories.all().order_by('title')
42 if not context['service_message']:
43 context['service_message'] = Message.objects.create(style='info')
44 if not context['service_message'].text and not self.request.user.has_perm(
45 'service_messages.change_message'
47 context['service_message'] = None
48 if self.request.user.has_perm('emissions.add_focus'):
49 context['focused_items'] = Focus.objects.select_related().filter(current=True)
50 context['recent_episodes'] = Episode.objects.select_related().order_by('-last_update_timestamp')
51 context['recent_newsitems'] = NewsItem.objects.select_related().order_by('-last_update_timestamp')
52 context['recent_soundfiles'] = SoundFile.objects.select_related().order_by(
53 '-last_update_timestamp'
59 home = login_required(Home.as_view())
62 class Search(TemplateView):
63 template_name = 'search/search.html'
65 def get_context_data(self, **kwargs):
66 context = super().get_context_data(**kwargs)
67 context['query'] = self.request.GET.get('q', '')
69 SearchVector('title', config=settings.FTS_DICTIONARY_CONFIG, weight='A')
70 + SearchVector('subtitle', config=settings.FTS_DICTIONARY_CONFIG, weight='A')
71 + SearchVector('text', config=settings.FTS_DICTIONARY_CONFIG, weight='B')
73 query = SearchQuery(self.request.GET.get('q', ''), config=settings.FTS_DICTIONARY_CONFIG)
75 'episodes': Episode.objects.annotate(rank=SearchRank(vector, query))
76 .filter(rank__gte=0.1)
77 .select_related('emission')
78 .order_by('-rank')[:10],
79 'emissions': Emission.objects.annotate(rank=SearchRank(vector, query))
80 .filter(rank__gte=0.1)
81 .order_by('-rank')[:10],
82 'newsitems': NewsItem.objects.annotate(rank=SearchRank(vector, query))
83 .filter(rank__gte=0.1)
84 .order_by('-rank')[:10],
89 search = Search.as_view()
92 class EmissionListView(emissions.views.EmissionListView):
96 emissions_list = login_required(EmissionListView.as_view())
99 class NewsListView(ListView):
102 def get_queryset(self):
103 return NewsCategory.objects.order_by('title')
105 def get_context_data(self, **kwargs):
106 context = super().get_context_data(**kwargs)
107 context['unsorted_newsitems'] = NewsItem.objects.filter(category__isnull=True).order_by('title')
111 news = login_required(NewsListView.as_view())
114 class NewsletterCreateView(newsletter.views.NewsletterCreateView):
115 def get_initial(self):
116 initial = super().get_initial()
118 newsletter_body = loader.get_template('newsletter/body.html')
119 newsletter_subject = loader.get_template('newsletter/subject.txt')
122 date = datetime.datetime.today()
123 if date.weekday() < 3:
124 # before and on Wednesday, use current week
125 date = date - datetime.timedelta(days=date.weekday())
127 # after Wednesday, use next week
128 date = date + datetime.timedelta(days=7 - date.weekday())
130 date = datetime.datetime(*date.timetuple()[:3])
131 date_end = date + datetime.timedelta(days=7)
133 context['date'] = date
134 context['date_end'] = date_end
136 context['soundfiles'] = (
137 SoundFile.objects.filter(podcastable=True, fragment=False)
139 .filter(creation_timestamp__gte=date - datetime.timedelta(days=7))
142 context['diffusions'] = list(
143 Diffusion.objects.select_related()
144 .filter(datetime__gte=date, datetime__lte=date + datetime.timedelta(days=7))
145 .order_by('datetime')
148 # remove rebroadcasts made during the same week
150 for diff in context['diffusions'][:]:
151 if diff.episode.id in seen_episodes:
152 context['diffusions'].remove(diff)
153 seen_episodes[diff.episode.id] = True
155 initial['subject'] = newsletter_subject.render(context)
156 initial['text'] = newsletter_body.render(context)
160 newsletter_create = NewsletterCreateView.as_view()
163 class FocusSetView(RedirectView):
166 def get_redirect_url(self, object_type, object_id):
167 if not self.request.user.has_perm('emissions.add_focus'):
168 raise PermissionDenied()
169 messages.success(self.request, emissions.views.SUCCESS_MESSAGE)
170 if object_type == 'emission':
171 emission = Emission.objects.get(id=object_id)
172 f, _created = Focus.objects.get_or_create(emission=emission)
175 logger.info('set focus on emission %s', emission)
176 return reverse('emission-view', kwargs={'slug': emission.slug})
177 if object_type == 'episode':
178 episode = Episode.objects.get(id=object_id)
179 f, _created = Focus.objects.get_or_create(episode=episode)
183 logger.info('set focus on episode %s', episode)
185 'episode-view', kwargs={'emission_slug': episode.emission.slug, 'slug': episode.slug}
187 if object_type == 'newsitem':
188 newsitem = NewsItem.objects.get(id=object_id)
189 f, _created = Focus.objects.get_or_create(newsitem=newsitem)
191 f.newsitem = newsitem
193 logger.info('set focus on newsitem %s', newsitem)
194 return reverse('newsitem-view', kwargs={'slug': newsitem.slug})
195 if object_type == 'soundfile':
196 soundfile = SoundFile.objects.get(id=object_id)
197 f, _created = Focus.objects.get_or_create(soundfile=soundfile)
199 f.soundfile = soundfile
201 logger.info('set focus on sound %s', soundfile)
205 'slug': soundfile.episode.slug,
206 'emission_slug': soundfile.episode.emission.slug,
209 if object_type == 'page':
210 page = Page.objects.get(id=object_id)
212 f = Focus.objects.get(page=page)
213 except Focus.DoesNotExist:
218 logger.info('set focus on page %s', page)
219 return reverse('combo-manager-page-view', kwargs={'pk': object_id})
222 focus_set = FocusSetView.as_view()
225 class FocusUnsetView(RedirectView):
228 def get_redirect_url(self, object_type, object_id):
229 if not self.request.user.has_perm('emissions.delete_focus'):
230 raise PermissionDenied()
231 messages.success(self.request, emissions.views.SUCCESS_MESSAGE)
232 if object_type == 'emission':
233 emission = Emission.objects.get(id=object_id)
234 focus = Focus.objects.get(emission=emission)
235 focus.current = False
237 logger.info('unset focus of emission %s', emission)
238 return reverse('emission-view', kwargs={'slug': emission.slug})
239 if object_type == 'episode':
240 episode = Episode.objects.get(id=object_id)
241 focus = Focus.objects.get(episode=episode)
242 focus.current = False
244 logger.info('unset focus of episode %s', episode)
246 'episode-view', kwargs={'emission_slug': episode.emission.slug, 'slug': episode.slug}
248 if object_type == 'newsitem':
249 newsitem = NewsItem.objects.get(id=object_id)
250 focus = Focus.objects.get(newsitem=newsitem)
251 focus.current = False
253 logger.info('unset focus of newsitem %s', newsitem)
254 return reverse('newsitem-view', kwargs={'slug': newsitem.slug})
255 if object_type == 'soundfile':
256 soundfile = SoundFile.objects.get(id=object_id)
257 focus = Focus.objects.get(soundfile=soundfile)
258 focus.current = False
260 logger.info('unset focus of soundfile %s', soundfile)
264 'slug': soundfile.episode.slug,
265 'emission_slug': soundfile.episode.emission.slug,
268 if object_type == 'page':
269 focus = Focus.objects.get(page=object_id)
270 focus.current = False
272 logger.info('unset focus of page %s', object_id)
273 return reverse('combo-manager-page-view', kwargs={'pk': object_id})
276 focus_unset = FocusUnsetView.as_view()