API:Obrázek denního prohlížeče

This page is a translated version of the page API:Picture of the day viewer and the translation is 100% complete.

Přehled

V tomto výukovém programu se naučíte, jak vytvořit prohlížeč Wikipedia:Picture of the day pomocí MediaWiki Action API.

Tento průvodce vás naučí, jak to udělat pomocí:

Postup pro vytvoření této aplikace krok za krokem

Krok 1: Nastavení vývojového prostředí Python a Flask

Nastavení Pythonu

Tento výukový program používá Python 3. Nejnovější verzi Pythonu si můžete stáhnout zde:

Další pokyny k instalaci Pythonu na různé operační systémy naleznete v Python příručce pro začátečníky.

Nastavení Flask

Pip je správce balíčků, který můžete použít k instalaci Flasku: pip install flask. Pokud ještě Pip nemáte, nainstalujte si jej z oficiální web Pip.


Krok 2: Vytvořte jednoduchou aplikaci Flask

Pokud jste vše úspěšně nainstalovali, umístěte následující skript do app.py ve složce projektu: $HOME/picture-of-the-day-viewer/app.py. Když jej spustíte (pomocí flask run nebo python app.py), mělo by zobrazit "Hello world" na http://localhost:5000/:

#!/usr/bin/python3

from flask import Flask
APP = Flask(__name__)

@APP.route("/")
def hello():
  return "Hello World!"

if __name__ == "__main__":
  APP.run()

Krok 3: Obrázek denního prohlížeče

Nyní, když máte vše nastaveno, můžete začít psát kód pro prohlížeč Day viewer (obrázek dne). Obrázek dne neboli POTD je vybraný obrázek denně zobrazovaný na domovské stránce Wikipedie. Obrázek získáte ze šablony wiki, která se mění každý den.

Získání dnešního data

Protože se POTD aktualizuje denně, potřebujete dnešní datum, abyste se dostali do archivů a získali stabilní verzi správného obrázku. Chcete-li to provést, importujte Pythonovu date třídu.

Dále definujte novou funkci index(). Index() vykreslí webovou stránku a předá veškerá data spojená s našimi voláními API. Další informace o souboru index.html, který budeme používat jako šablonu, najdete v Zobrazení stránky. Prozatím by index() měl obsahovat proměnnou obsahující aktuální datum. Brzy jej použijeme k vytvoření dotazu pro přístup k POTD.

#!/usr/bin/python3
from datetime import date
from flask import Flask, render_template

APP = Flask(__name__)

@APP.route("/")
def index():
  todays_date = date.today().isoformat()

if __name__ == "__main__":
  APP.run()


Volání Action API

Action API funguje tak, že odešle zpět data jako odpověď na HTTP požadavky. Chcete-li tak učinit, naimportujete knihovnu požadavků Pythonu.

Dále přidejte dvě nové proměnné: SESSION = requests.Session() a ENDPOINT = "https://en.wikipedia.org/w/api.php". Objekt SESSION použijete k odesílání požadavků na adresu URL ENDPOINT.

V nové funkci fetch_potd() zavolejte API:Obrázky a vyžádejte si obrázek vložený do chráněné stránky POTD (příklad). Z tohoto volání použijte název souboru obrázku k volání API:Informace o obrázku a načtěte zdrojovou adresu URL obrázku. V tomto příkladu je druhé volání API zpracováno v pomocné funkci fetch_image_src().

Archivy Wikipedie uvádí data ve formátu ISO standard, například: 2019-01-31, pro 31. ledna 2019. Správný formát můžete získat pomocí metody data, isoformat().

def fetch_potd(cur_date):
  date_iso = cur_date.isoformat()
  title = "Template:POTD_protected/" + date_iso

  params = {
    "action": "query",
    "format": "json",
    "formatversion": "2",
    "prop": "images",
    "titles": title
  }

  response = SESSION.get(url = ENDPOINT, params = params)
  data = response.json()
  filename = data["query"]["pages"][0]["images"][0]["title"]
  image_page_url = "https://en.wikipedia.org/wiki/" + title
    
  image_data = {
    "filename": filename,
    "image_page_url": image_page_url,
    "image_src": fetch_image_src(filename),
    "date": cur_date
  }

  return image_data

def fetch_image_src(filename):
  params = {
    "action": "query",
    "format": "json",
    "prop": "imageinfo",
    "iiprop": "url",
    "titles": filename
  }

  response = SESSION.get(url = ENDPOINT, params = params)
  data = response.json()
  page = next(iter(data["query"]["pages"].values()))
  image_info = page["imageinfo"][0]
  image_url = image_info["url"]

  return image_url

Nakonec změňte index() na volání fetch_potd(). Importujte render_template z flask a získejte index(), vraťte render_template("index.html", data=data).


Zobrazení stránky

 
Obrázek snímku obrazovky aplikace Day Viewer

Šablony Flask většinou obsahují značky HTML, ale také používají Jinja k vykreslení dynamického obsahu. Značení Jinja vypadá takto: {{ variable }} a používá se k vložení proměnných nebo výrazů Pythonu do naší základní struktury stránky. Přidejte k index.html základní HTML 5 základní popis a několik prvků. Nezapomeňte jej uložit do adresáře v aplikaci s názvem /templates.

<!DOCTYPE html>
<html lang="en">
  <meta charset="utf-8">
  <title>Picture of the Day</title>
  <link rel="stylesheet" href="/static/style.css">

  <main>
    <h1>Picture of the day:</h1>
    <div class="card">
      <div class="potd">
        <h2>{{ data.filename }}</h2>
        <a href="{{ data.image_page_url }}" target="blank">
        <figure>
          <img src="{{ data.image_src }}">
          <figcaption>View on Wikipedia</figcaption>
        </figure>
        </a>
      </div>
      <div class = "date-container">
      <div class = "current-date">{{ data.date.strftime("%d %B %Y") }}</div>
    </div>
    </div>
</main>

Interaktivní

Přidejte prvek ‎<form> k index.html a dejte mu následující vstupní tlačítka pro odeslání: Back (zpět) a Next (další). Pokud je vybráno kterékoli tlačítko, formulář odešle požadavek POST a vybraná hodnota bude předána zpět na app.py. To uživatelům umožní procházet archivy Picture of the Day.

Dále aktualizujte app.py funkcí change_date() pro nastavení data prezentovaného uživateli. Rozšiřte také cestu / pro zpracování požadavků POST z formuláře. Chcete-li povolit app.py číst zprávu požadavku POST, importujte třídu Request Flask.

Kompletní Python a HTML kód:

$HOME/picture-of-the-day-viewer/app.py
"""
    app.py
    MediaWiki Action API Code Samples

    Fetches Wikipedia Picture of the Day (POTD) and displays it on a webpage.
    Also allows users to go backward or forward a date to view other POTD.

    MIT License
"""

#!/usr/bin/python3

from datetime import date, timedelta
from flask import Flask, render_template, request
import requests

APP = Flask(__name__)
SESSION = requests.Session()
ENDPOINT = "https://en.wikipedia.org/w/api.php"
CURRENT_DATE = date.today()

@APP.route("/", methods=["GET", "POST"])
def index():
    """
    Requests data from Action API via 'fetch_potd' function & renders it on the
    index page accessible at '/'
    """

    if request.method == "POST":
        change_date()

    data = fetch_potd(CURRENT_DATE)

    return render_template("index.html", data=data)

def change_date():
    """
    Changes current date in response to input from the web form
    """

    global CURRENT_DATE

    user_input = request.form["change_date"]
    new_date = CURRENT_DATE
    last_date = date.today()
    first_date = date(year=2004, month=5, day=14)

    if user_input == "← Back":
        new_date = new_date - timedelta(days=1)
    elif user_input == "Next →":
        new_date = new_date + timedelta(days=1)

    if new_date > last_date or new_date < first_date:
        return

    CURRENT_DATE = new_date

def fetch_potd(cur_date):
    """
    Returns image data related to the current POTD
    """

    date_iso = cur_date.isoformat()
    title = "Template:POTD protected/" + date_iso

    params = {
        "action": "query",
        "format": "json",
        "formatversion": "2",
        "prop": "images",
        "titles": title
    }

    response = SESSION.get(url=ENDPOINT, params=params)
    data = response.json()

    filename = data["query"]["pages"][0]["images"][0]["title"]
    image_src = fetch_image_src(filename)
    image_page_url = "https://en.wikipedia.org/wiki/Template:POTD_protected/" + date_iso

    image_data = {
        "filename": filename,
        "image_src": image_src,
        "image_page_url": image_page_url,
        "date": cur_date
    }

    return image_data

def fetch_image_src(filename):
    """
    Returns the POTD's image url
    """

    params = {
        "action": "query",
        "format": "json",
        "prop": "imageinfo",
        "iiprop": "url",
        "titles": filename
    }

    response = SESSION.get(url=ENDPOINT, params=params)
    data = response.json()
    page = next(iter(data["query"]["pages"].values()))
    image_info = page["imageinfo"][0]
    image_url = image_info["url"]

    return image_url

if __name__ == "__main__":
    APP.run()
$HOME/picture-of-the-day-viewer/templates/index.html
<!DOCTYPE html>
<html lang="en">
  <meta charset="utf-8">
  <title>Picture of the Day</title>
  <link rel="stylesheet" href="/static/style.css">

  <main>
    <h1>Picture of the day:</h1>
    <div class="card">
      <div class="potd">
        <h2>{{ data.filename }}</h2>
        <a href="{{ data.image_page_url }}" target="blank">
        <figure>
          <img src="{{ data.image_src }}">
          <figcaption>View on Wikipedia</figcaption>
        </figure>
        </a>
      </div>
      <div class="date-container">
        <time class="current-date">{{ data.date.strftime("%d %B %Y") }}</time>
        <div class="date-navigator">
          <form action="/" method="POST">
            {% if data.date.strftime("%d %B %Y") == "14 May 2004" %}
            <input type="submit" name="change_date" value="← Back" disabled>
            {% else %}
            <input type="submit" name="change_date" value="← Back">
            {% endif %}
            {% if data.date == data.date.today() %}
            <input type="submit" name="change_date" value="Next →" disabled>
            {% else %}
            <input type="submit" name="change_date" value="Next →">
            {% endif %}
          </form>
        </div>
      </div>
    </div>
</main>

Styl vaší aplikace

Flask používá adresář s názvem static, který obsahuje všechny pomocné soubory, které zůstávají stejné po celou dobu životního cyklu aplikace. Toto je užitečné místo pro umístění jakýchkoli šablon stylů nebo dalších skriptů. Naše šablona stylů bude používat některé barvy a vizuální motivy založené na Wikimedia Style Guide. Umístěte soubor CSS do $HOME/picture-of-the-day-viewer/static/style.css.

$HOME/picture-of-the-day-viewer/static/style.css
html {
    margin: 0;
    padding: 0;
    height: 100vh;
    width: 100vw;
}

body {
    margin: 0;
    background: #f8f9fa; /* light grey */
    font-family: Arial, Helvetica, sans-serif;
    font-size: 16px;
}

h1 {
    margin: 0;
    padding: 12px;
    background: #2a4b8d; /* dark blue */
    color: #ffffff;
}

h2 {
    margin-top: 8px;
    padding: 12px;
    font-size: 1em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    background: #f3f9ff; /* very light blue */
    border: 1px solid #2a4b8d; /* dark blue */
}

a {
    color: #3366cc; /* blue */
}

p {
    margin: 8px;
}

.card {
    position: relative;
    margin: auto;
    min-width: 200px;
    max-width: 67vw;
    height: 90vh;
    background: #ffffff;
    border-radius: 8px;
    box-shadow: 3px 6px 10px rgba(0, 0, 0, 0.16);
}

.potd {
    width: inherit;
    height: 60vh;
}

figure {
    width: 100%;
    margin: auto;
    text-align: center;
}

figure img {
    display: block;
    margin: 12px auto; 
    max-width: 64vw;
    max-height: 50vh;
    border: 1px solid#3366cc; /* blue */
}

figure a {
    margin: 8px;
}

.date-container {
    display: block;
    position: absolute;
    bottom: 0;
    left: 0;
    right:0;
    text-align: center;
    font-weight: bold;
}

.current-date {
    margin: 16px auto;
    font-size: 2em;
    background: #ffffff;
    color: #72777d; /* grey */
}

.date-navigator {
    margin: 16px auto;
    font-size: 2em;
    text-transform: uppercase;
    text-align: center;
    background: #3366cc; /* blue */
    color: #ffffff;
}

.date-navigator input {
    margin: 8px;
    min-height: 44px;
    width: 45%;
    font-size: 0.67em;
    font-weight: inherit;
    text-transform: none;
    background: #3366cc; /* blue */
    color: inherit;
    border: 1px solid #ffffff;
    box-shadow: 3px 6px 10px rgba(0, 0, 0, 0.16);
    cursor: pointer;
}

.date-navigator input:hover {
    background: #447FF5; /* light blue */
}

.date-navigator input:active {
    background: #2a4b8d; /* dark blue */
    border: none;
    box-shadow: none;
}

.footer {
    text-align: center;
}

.date-navigator input:disabled {
    color: #c8cdff; /* grey */
    border: 1px solid #c8cdff; /* grey */
    box-shadow: none;
    cursor: default;
}

.date-navigator input:disabled:hover {
    background: #3366cc; /* blue */
}

Další kroky

  • Přispějte ukázkovou aplikací, kterou jste vyvinuli pomocí MediaWiki API, do tohoto [$url úložiště ukázek kódu].
  • Naučte se některé způsoby, jak přidat popisný text ze stránky Obrázek dne:
    • API:Hledání poskytuje snippets, které lze použít jako náhled odkazu
    • action=cirrusdump lze použít k získání celého analyzovaného textu z článků na Wikis, které mají nainstalované rozšíření Cirrussearch (viz příklad).

Související odkazy