def recent_entries(request): """ Show recent entries, sorted by their assigned date, modification or creation date. """ date_mode = request.GET.get('mode', 'created') if date_mode == 'modified': entries_ids = Entry.all_visible.order_by('-modified').values_list('id', flat=True) elif date_mode == 'recorded': entries_ids = EntryVersion.newest.order_by('-entry_date', '-entry_id')\ .values_list('entry_id', flat=True).distinct() else: # Sort by creation date by default entries_ids = Entry.all_visible.order_by('-created').values_list('id', flat=True) page_length = UserSettings.get_page_length(request) page_num = request.GET.get('page', '1') paginator = Paginator(entries_ids, page_length, orphans=page_length // 10) try: page = paginator.page(page_num) except PageNotAnInteger: page = paginator.page(1) except EmptyPage: page = paginator.page(paginator.num_pages) to_show = page_numbers_to_show(paginator, page.number) entries_map = Entry.prefetch_entries(page, show_unapproved=is_contributor(request)) entries = [entries_map[entry_id] for entry_id in page] return render(request, 'palanaeum/recent_entries.html', {'page_numbers_to_show': to_show, 'page': page, 'entries': entries, 'mode': date_mode, 'page_params': 'mode={}'.format(date_mode)})
def show_entry_history(request, entry_id): """ Display a page with two version of the entries, compared with each other, with highlighted changes. """ if not is_contributor(request): messages.warning(request, _('This page is for contributors only.')) return redirect('index') entry = get_object_or_404(Entry, pk=entry_id) version_1 = request.GET.get('version_1', False) version_2 = request.GET.get('version_2', False) if version_2: newer = get_object_or_404(EntryVersion, pk=version_2, entry_id=entry_id) else: newer = entry.versions.last() if version_1: older = get_object_or_404(EntryVersion, pk=version_1, entry_id=entry_id) else: if entry.versions.count() > 1: older = entry.versions.filter(is_approved=True).exclude(pk=newer.pk).last() if older is None: older = entry.versions.exclude(pk=newer.pk).last() else: older = entry.versions.last() if older is None or newer is None: raise Http404 if newer.date < older.date: newer, older = older, newer def make_html(version): html = ['<article class="entry-article w3-display-container w3-border w3-card">'] for line in version.lines.all(): html.append("<h3>{}</h3>".format(line.speaker)) html.append(line.text) if version.note: html.append('<small class="footnote">Footnote: {}</small>'.format(version.note)) html.append("</article>") return "".join(html) newer_html = make_html(newer) older_html = make_html(older) html_diff = htmldiff(older_html, newer_html) return render(request, "palanaeum/staff/entry_history.html", { 'newer_version': newer, 'newer_html': newer_html, 'html_diff': html_diff, 'older_version': older, 'older_html': older_html, 'entry': entry, 'all_versions': EntryVersion.objects.filter(entry=entry), 'snippets': Snippet.all_visible.filter(entry=entry), 'images': ImageSource.all_visible.filter(entry=entry) })
def view_event(request, event_id): """ Display single Event page. """ event = get_object_or_404(Event, pk=event_id) if not event.visible(): raise PermissionDenied entry_ids = Entry.all_visible.filter(event=event).values_list('id', flat=True) entries_map = Entry.prefetch_entries(entry_ids, show_unapproved=is_contributor(request)) entries = sorted(entries_map.values(), key=lambda e: e.order) sources = list(event.sources_iterator()) approval_msg = get_config('approval_message') if event.review_state == Event.REVIEW_APPROVED: approval_explanation = get_config('review_reviewed_explanation') elif event.review_state == Event.REVIEW_PENDING: approval_explanation = get_config('review_pending_explanation') else: approval_explanation = '' return render(request, 'palanaeum/event.html', {'event': event, 'entries': entries, 'sources': sources, 'approval_msg': approval_msg, 'review_message': approval_explanation})
def edit_entry(request, entry_id=None, event_id=None): """ Display an edit page for Entry object. """ if not is_contributor(request): messages.warning(request, _('This page is for contributors only.')) return redirect('index') if entry_id is None: entry = Entry() entry.event = get_object_or_404(Event, pk=event_id) entry.date = entry.event.date entry.created_by = request.user entry.set_order_last() else: entry = get_object_or_404(Entry, pk=entry_id) if entry_id is not None: snippets = list(Snippet.all_visible.filter(entry=entry)) images = list(ImageSource.all_visible.filter(entry=entry)) else: snippets = [] images = [] return render(request, 'palanaeum/staff/entry_edit_form.html', {'entry': entry, 'event': entry.event, 'snippets': snippets, 'images': images})
def view_event(request, event_id): """ Display single Event page. """ event = get_object_or_404(Event, pk=event_id) if not event.visible(): raise PermissionDenied # Caching only responses for anonymous users, as that's the majority of # visits and those don't change that much. anonymous_user_cache = "anon_event_view_{}".format(event_id) if request.user and request.user.is_anonymous: cached_response = cache.get(anonymous_user_cache) if cached_response is not None: cached_response, cache_timestamp = cached_response if cache_timestamp <= event.modified_date: return cached_response entry_ids = Entry.all_visible.filter(event=event).values_list('id', flat=True) entries_map = Entry.prefetch_entries( entry_ids, show_unapproved=is_contributor(request)) entries = sorted(entries_map.values(), key=lambda e: e.order) sources = list(event.sources_iterator()) approval_msg = get_config('approval_message') if event.review_state == Event.REVIEW_APPROVED: approval_explanation = get_config('review_reviewed_explanation') elif event.review_state == Event.REVIEW_PENDING: approval_explanation = get_config('review_pending_explanation') else: approval_explanation = '' response = render( request, 'palanaeum/event.html', { 'event': event, 'entries': entries, 'sources': sources, 'approval_msg': approval_msg, 'review_message': approval_explanation }) if request.user and request.user.is_anonymous: cache.set(anonymous_user_cache, (response, event.modified_date)) return response
def editable(self): return is_contributor(get_request())
def save_entry(request): """ Save received entry data. """ if not is_contributor(request): raise AjaxException(_('Only contributors can perform this action.')) if 'entry_id' not in request.POST or not request.POST['entry_id']: entry = Entry() event = get_object_or_404(Event, pk=request.POST['event_id']) entry.event = event entry.date = event.date entry.created_by = request.user entry.is_approved = False entry.set_order_last() entry.save() entry_version = EntryVersion() entry_version.entry = entry entry_version.user = request.user else: entry_id = request.POST['entry_id'] entry = get_object_or_404(Entry, pk=entry_id) event = entry.event entry_version = entry.versions.last() if entry_version is None: entry_version = EntryVersion() entry_version.entry = entry entry_version.user = request.user date_str = request.POST.get('date', event.date.strftime("%Y-%m-%d")) if date_str: try: entry.date = datetime.strptime(date_str, "%Y-%m-%d") except ValueError: raise AjaxException(_("Unsupported date format. Expected date format is: YYYY-MM-DD.")) else: entry.date = event.date entry.paraphrased = bool(request.POST.get('paraphrased', False)) entry.save() entry_version.archive_version() entry_version.note = request.POST.get('note', '') entry_version.user = request.user entry_version.is_approved = False entry_version.approved_by = None entry_version.approved_date = None entry_version.save() lines_id_mapping, deleted_lines_ids = _save_entry_lines(request, entry_version) # There is a bunch of stuff that only staff can do... if request.user.is_staff: _save_entry_url_sources(request, entry) tags_str = ", ".join(request.POST.getlist('tags[]')) entry.update_tags(tags_str) entry_version.approve(request.user) logging.getLogger('palanaeum.staff').info("Entry %s updated by %s", entry.id, request.user) return {'lines_id_mapping': lines_id_mapping, 'deleted_lines': deleted_lines_ids, 'entry_id': entry.id, 'add_entry_url': reverse('event_add_entry', kwargs={'event_id': event.id})}
def show_entry_history(request, entry_id): """ Display a page with two version of the entries, compared with each other, with highlighted changes. """ if not is_contributor(request): messages.warning(request, _('This page is for contributors only.')) return redirect('index') entry = get_object_or_404(Entry, pk=entry_id) version_1 = request.GET.get('version_1', False) version_2 = request.GET.get('version_2', False) # Default newer is the newest version newer = entry.versions.last() older = None if version_2 and version_1: newer = get_object_or_404(EntryVersion, pk=version_2, entry_id=entry_id) older = get_object_or_404(EntryVersion, pk=version_1, entry_id=entry_id) elif newer is not None: # Default older is the last approved version # If there's no approved version, then it's the second to last version older = (entry.versions.filter(is_approved=True).exclude(pk=newer.pk).last() \ or entry.versions.exclude(pk=newer.pk).last() or newer) if older is None or newer is None: raise Http404 if newer.date < older.date: newer, older = older, newer def make_html(version): html = [ '<article class="entry-article w3-display-container w3-border w3-card">' ] html += ['<header>Date: {}</header>'.format(version.entry_date)] for line in version.lines.all(): html.append("<h3>{}{}</h3>".format( line.speaker, " ({})".format(_('paraphrased')) if version.paraphrased else '')) html.append(line.text) if version.note: html.append('<small class="footnote">Footnote: {}</small>'.format( version.note)) if version.url_sources.exists(): sources = "Sources: " + ", ".join( source.html() for source in version.url_sources.all()) html.append("<div style='float:right'>{}</div>".format(sources)) if version.tags.exists(): tags = ", ".join(str(tag) for tag in version.tags.all()) html.append('<footer>{}: {}</footer>'.format(_('Tags'), tags)) else: html.append('<footer></footer>') html.append("</article>") return "".join(html) newer_html = make_html(newer) older_html = make_html(older) html_diff = htmldiff(older_html, newer_html) return render( request, "palanaeum/staff/entry_history.html", { 'newer_version': newer, 'newer_html': newer_html, 'html_diff': html_diff, 'older_version': older, 'older_html': older_html, 'entry': entry, 'all_versions': EntryVersion.objects.filter(entry=entry), 'snippets': Snippet.all_visible.filter(entry=entry), 'images': ImageSource.all_visible.filter(entry=entry) })