En af Wallnots få (men trofaste) brugere, bad om arkiv- og søgefunktionalitet på Wallnot.
Det krævede en større omlægning af Wallnot fra:
- En side, der viser links til et øjebliksbillede af gratisartikler fra forsiden af danske netaviser.
Til:
- En side der løbende arkiverer links til gratisartikler fra danske netaviser
Det kræver:
- En bagvedliggende database
- Løbende vedligeholdelse så links, der ændrer status fra gratis- til betalingsartikler, fjernes fra siden
Den nye Wallnot har:
- Søgefunktion på artikeloverskrifter
- Arkiv, der hele tiden bliver større
- Zetland- og delte Politiken-artikler fra de sidste par år. Zetlandarkivet er nærmest komplet.
- En robot, der løbende tjekker links fra de sidste par dage for ændret betalingsmursstatus
- Mulighed for at filtrere Ritzau-telegrammer og dubletartikler fra
- Bevaret hurtig- og enkeltheden fra version 1.
Arkitekturen bag Wallnot version 2
Version 2 af Wallnot er udviklet i Django, mens robotterne der indsamler og vedligeholder links er skrevet i Python.
Selve omlægningen til Django er faktisk enkel.
I models.py beskrives datamodellen, altså felterne i den bagvedliggende database:
from django.db import models from django.utils import timezone from django.contrib import admin # Create your models here. class Article(models.Model): title = models.CharField('Overskrift', max_length=500) unique_id = models.CharField('Avisens artikel-id', max_length=20, unique=True, null=True, blank=True) date = models.DateTimeField('Publiceringstidspunkt') MEDIUM_CHOICES = ( ('politiken', 'Politiken'), ('berlingske', 'Berlingske'), ('jyllandsposten', 'Jyllandsposten'), ('information', 'Information'), ('kristeligtdagblad', 'Kristeligt Dagblad'), ('weekendavisen', 'Weekendavisen'), ('zetland', 'Zetland'), ('finansdk', 'Finans.dk'), ('borsen', 'Børsen'), ('arbejderen', 'Arbejderen'), ) medium = models.CharField('Medie', max_length=30, choices=MEDIUM_CHOICES) url = models.URLField('Adresse', max_length=400, unique=True) ritzau = models.BooleanField('Ritzautelegram', default=False, null=True, blank=True) excerpt = models.CharField('Første sætning', max_length=1000, null=True, blank=True) duplicate = models.BooleanField('Dublet', default=False, null=True, blank=True) user_reports_paywall = models.BooleanField('Brugerrapporteret paywall', default=False, null=True) created_at = models.DateTimeField('Tilføjet den', default=timezone.now, editable=False) class ArticleAdmin(admin.ModelAdmin): list_display = ('title','unique_id','ritzau','duplicate','excerpt','date') list_filter = ('medium', 'user_reports_paywall', 'ritzau','duplicate') search_fields = ['title', 'unique_id', 'excerpt']
Derudover skal der bygges et view, der beskriver forespørgslen til databasen. Her i en forkortet udgave uden logikken bag brugerrapportering af links bag paywall:
from django.shortcuts import render from django.core.paginator import Paginator import requests import json from .models import Article def index(request): articles = Article.objects.order_by('-date') searchterm = request.GET.get('q') medium = request.GET.get('m') ritzau = request.GET.get('r') duplicates = request.GET.get('d') newwindow = request.GET.get('w') if searchterm: firstsearchcharacter = searchterm[:1] # Exclude queries by adding ! to searchterm if firstsearchcharacter == "!": searchterm = searchterm[1:] articles = articles.exclude(title__iregex=searchterm) searchterm = "!" + searchterm # Perform normal regex-enabled search else: articles = articles.filter(title__iregex=searchterm) if medium: articles = articles.filter(medium=medium) if ritzau: articles = articles.exclude(ritzau=True) if not duplicates and not medium: articles = articles.exclude(duplicate=True) paginator = Paginator(articles, 80) page_number = request.GET.get('page') page_obj = paginator.get_page(page_number) context = {'request': request, 'page_obj': page_obj, 'medium': medium, 'searchterm': searchterm, 'ritzau': ritzau, 'newwindow': newwindow, 'duplicates': duplicates} return render(request, 'wall/index.html', context)
Til sidst skrives en skabelon (template) der omsætter data til HTML. Her er fx den ganske korte bid kode, der spytter artikellinks ud på siden:
{% for article in page_obj %} {% ifchanged article.date|date %}<h3>{{ article.date|date }}</h3>{% endifchanged %} <p>{{ article.date|date:"H:i" }}: <a href="{{ article.url }}"{% if newwindow %} target="_blank"{% endif %}>{{ article.title }}</a> {% if article.ritzau %}<small><sup> ritzau </sup></small> {% endif %}{% if article.duplicate and not medium %}<small><sup> dublet </sup></small> {% endif %}<img title="Giv besked hvis artiklen er bag en paywall" id="{{ article.id }}" class="myBtnt" src="{% static "wall/alert.svg" %}"/></p> {% endfor %}
God fornøjelse med den nye Wallnot!