API: Hoton mai kallon rana

This page is a translated version of the page API:Picture of the day viewer and the translation is 99% complete.
Outdated translations are marked like this.

Dubawa

A cikin wannan koyawa, za ku koyi yadda ake gina Wikipedia: Hoton ranar ta amfani da MediaWiki Action API.

Wannan koyawa za ta koya muku yadda ake yin hakan ta amfani da:

Tsarin mataki-mataki don gina wannan aikace-aikacen

Mataki na 1: Sanya Python da yanayin ci gaban Flask =

Saita Python

Wannan koyawa tana amfani da Python 3. Kuna iya sauke sabon sigar Python daga nan:

Duba Python jagorar mafari don ƙarin umarni kan shigar Python akan tsarin aiki daban-daban.

Saita Flask

Pip mai sarrafa fakiti ne wanda zaku iya amfani dashi don shigar da Flask: pip install flask. Idan ba ku da Pip riga, shigar da shi daga gidan yanar gizon Pip na hukuma.


Mataki na 2: Ƙirƙiri aikace-aikacen Flask mai sauƙi =

Idan an shigar da komai cikin nasara, sanya wannan rubutun a cikin app.py, cikin babban fayil ɗin aikin ku: $HOME/picture-of-the-day-viewer/app.py. Lokacin da kuke gudanar da shi (ta amfani da flask run ko python app.py), yakamata ya nuna "Hello duniya" akan 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()

Mataki na 3: Hoton mai kallon rana =

Yanzu da kun saita komai, zaku iya fara rubuta lambar don Hoton Mai kallon Ranar. Hoton ranar, ko POTD, hoton da aka fito da shi ana nunawa kowace rana a shafin gida na Wikipedia. Za ku sami hoton daga samfurin wiki wanda ke canzawa kowace rana.

= Samun ranar yau

Saboda POTD yana ɗaukaka kullun, kuna buƙatar kwanan wata don samun damar wuraren adana kayan tarihi kuma ku sami ingantaccen sigar hoto daidai. Don yin wannan, shigo da Python's date class.

Na gaba, ayyana sabon aiki, index(). Index() zai sanya shafin yanar gizon kuma ya wuce tare da kowane bayanan da ke da alaƙa da kiran API ɗin mu. Duba #Nuna shafi don ƙarin bayani kan fayil ɗin index.html da za mu yi amfani da shi azaman samfuri. A yanzu, index() ya kamata ya ƙunshi mai canzawa mai riƙe kwanan wata. Za mu yi amfani da shi nan ba da jimawa ba don shirya tambaya don samun damar 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()


Kiran API Action

API ɗin Action yana aiki ta hanyar mayar da bayanai don amsa buƙatun HTTP. Don yin haka, zaku shigo da da ɗakin karatu na Buƙatun Python.

Na gaba ƙara sabbin masu canji biyu: SESSION = requests.Session() da ENDPOINT = "https://en.wikipedia.org/w/api.php". Za ku yi amfani da abin SESSION don yin buƙatun zuwa URL na ENDPOINT.

A cikin sabon aiki, fetch_potd(), kira API:Images don neman hoton da aka saka a cikin wani shafi mai kariya na POTD ([: ha: Template: POTD/2019-03-04|misali]]). Daga wannan kiran, yi amfani da sunan fayil ɗin hoton don kiran API:Imageinfo , da kuma dawo da tushen url na hoton. A cikin wannan misali, ana kula da kiran API na biyu a cikin aikin taimako, fetch_image_src().

Rumbun tarihin Wikipedia yana lissafin kwanan wata ta tsarin ISO misali, misali: 2019-01-31, na 31 ga watan Janairu, shekara ta 2019. Kuna iya samun madaidaicin tsari ta amfani da hanyar kwanan wata, 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

A ƙarshe, canza index() don kiran fetch_potd(). Shigo da render_template daga flask, kuma ku mayar da index() render_template("index.html", data=data).


Nuna shafin

 
Hoton Ranar Mai kallo app screenshot

Samfuran flask galibi suna ɗauke da alamar HTML, amma kuma suna amfani da Jinja don yin abun ciki mai ƙarfi. Jinja markup yayi kama da haka: {{ variable }}, kuma ana amfani dashi don allurar mabambantan Python ko maganganu cikin tsarin shafin mu na asali. Ƙara wasu asali HTML 5 tukunyar jirgi da ƴan abubuwa zuwa index.html. Tabbatar cewa kun adana shi zuwa kundin adireshi a cikin app ɗin ku, mai suna /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>

= Yin shi mu'amala

Ƙara wani kashi ‎<form> zuwa index.html, kuma a ba shi abubuwan shigar da maɓallin maɓallin mai zuwa: Baya da Na gaba. Lokacin da aka zaɓi kowane maɓalli, fam ɗin zai ƙaddamar da buƙatar POST, kuma ƙimar da aka zaɓa za a mayar da ita zuwa app.py. Wannan zai ba masu amfani damar yin bincike ta cikin Hotunan Rana.

Na gaba, sabunta app.py tare da aikin change_date(), don saita kwanan watan da aka gabatar ga mai amfani. Hakanan ƙara hanyar / don ɗaukar buƙatun POST daga fom. Don ba da damar app.py karanta saƙon buƙatun POST, shigo da aji Request na Flask.

Cikakken Python da lambar HTML:

$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>

= Salon app din ku

Flask yana amfani da kundin adireshi, mai suna tsaye, don ƙunsar kowane fayilolin mataimaka waɗanda suka kasance iri ɗaya a tsawon rayuwar ƙa'idar. Wannan wuri ne mai fa'ida don sanya kowane salon rubutu ko ƙarin rubutun. Salon salon mu zai kasance yana amfani da wasu launuka da abubuwan gani bisa Guide Salon Wikimedia. Sanya fayil ɗin CSS a cikin $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 */
}

Matakai na gaba

  • Ba da gudummawar ƙa'idar demo da kuka haɓaka ta amfani da MediaWiki API zuwa wannan [majiya ta samfuran lambar https://github.com/wikimedia/MediaWiki-Action-API-Code-Samples].
  • Koyi wasu hanyoyi don ƙara rubutu mai siffa daga shafin Hoton ranar:
    • API:Search yana ba da snippets wanda za'a iya amfani dashi azaman samfoti na hanyar haɗin gwiwa
    • Ana iya amfani da action=cirrusdump don samun gabaɗayan rubutun da aka rarraba daga labarai akan Wikis waɗanda aka sanya ƙarin Cirrussearch (duba misali).

Duba nan