Example #1
0
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)})
Example #2
0
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)
    })
Example #3
0
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})
Example #4
0
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})
Example #5
0
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
Example #6
0
 def editable(self):
     return is_contributor(get_request())
Example #7
0
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})}
Example #8
0
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)
        })