API: Mai duba hutu
This page is part of the MediaWiki Action API documentation. |
Bayani
Wannan koyawa ta ƙunshi yadda ake ƙirƙira ƙa'idar demo wacce ke ɗaukar ranaku da bukukuwan ranar da aka bayar daga Wikipedia, tare da zaɓi don shiga don ƙara sabbin ranaku.
Kayan aiki da fasahar da ake amfani da su don ƙirƙirar ƙa'idar demo sune:
- Python 3 da Flask, tsarin Python.
- jQuery and Bootstrap. They are loaded from Wikimedia Toolforge for privacy reasons.
- MediaWiki Action API kayayyaki: API:Parse , API:Login da API:Edit .
Tsarin mataki-mataki don gina wannan aikace-aikacen
Mataki na 1: Sanya Python da yanayin ci gaban Flask =
Python ya zo an riga an shigar dashi akan yawancin rabawa na Linux. For other operating systems, see the Python beginner's guide for installation instructions.
Shigar da Flask ta hanyar gudu pip install flask
.
Idan ba ku da Pip, samo shi daga gidan yanar gizon Pip na hukuma
Mataki na 2: Ƙirƙiri aikace-aikacen Flask mai sauƙi =
A cikin kundin adireshin gidan ku, ƙirƙiri babban fayil mai suna holidays-viewer
wanda zai ƙunshi duk fayilolin app ɗin.
A cikin babban fayil ɗin, ƙirƙiri fayil mai suna app.py
kuma sanya lambar mai zuwa a ciki:
#!/usr/bin/python3
from flask import Flask
APP = Flask(__name__)
@APP.route("/")
def list_holidays():
return "Holidays and observances"
if __name__ == "__main__":
APP.run()
Gudanar da app ta amfani da umarnin python app.py
kuma buɗe http://127.0.0.1:5000/
akan burauzar ku.
Ya kamata ku ga an nuna "Holidays and observances".
Mataki na 3: Ƙirƙiri shimfidar tushe =
App ɗin zai sami shafuka huɗu: shafin gida, shafin bincike, shafin shiga da kuma ƙara shafi.
Kowane shafi zai sami wasu abubuwan gama gari, don haka muna buƙatar ƙirƙirar fayil ɗin shimfidar wuri mai suna layout.html
don ya ƙunshi waɗannan abubuwan.
Note that we are using Bootstrap classes to apply a specific CSS style to an element, Materialize icons for the add, search and arrow-back icons, and Jinja to extend the base layout to other pages and to pass variables from Python to HTML.
$HOME/holidays-viewer/templates/layout.html |
---|
<title>Holidays</title>
<link rel="stylesheet" href="//tools-static.wmflabs.org/cdnjs/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css">
<link rel="stylesheet" href="//tools-static.wmflabs.org/fontcdn/css?family=Material+Icons">
<div class="content bg-secondary rounded m-auto">
<div class="title-bar bg-primary-dark text-white pl-2">
<small>Holidays and observances</small>
</div>
<div class="header-bar bg-primary text-white shadow p-2">
{% if request.path != url_for('list_holidays') %}
<a class=" btn text-white" href="{{ url_for('list_holidays') }}">
<i class="material-icons">arrow_back</i>
</a>
{% endif %}
<h5>{{header}}</h5>
<div class="filler"></div>
<a class="btn text-white" href="{{ url_for('add') }}">
<i class="material-icons">add</i>
</a>
<a class="btn text-white" href="{{ url_for('search') }}">
<i class="material-icons">search</i>
</a>
</div>
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="alert alert-primary mb-0" role="alert">
{% for message in messages %}
{{ message }}
{% endfor %}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</div>
<script src="//tools-static.wmflabs.org/cdnjs/ajax/libs/twitter-bootstrap/4.0.0/js/bootstrap.min.js"></script>
|
Sauran shafuka za su tsawaita layout.html
ta amfani da lambar da ke ƙasa:
{% extends "layout.html" %}
{% block content %}
<!--content for other pages-->
{% endblock %}
Mataki na 4: Lissafin hutu =
Tushen url na ƙa'idar zai haifar da aikin list_holidays(...)
, wanda ke jera ranakun hutu na takamaiman kwanan wata.
A cikin aikin da kuma cikin aikace-aikacen, holidays_date
yana nufin ranar hutu da za a jera, header
yana nufin taken shafin, kuma holidays_html
yana nufin html wanda ya ƙunshi hutun da za a jera.
Hakanan za mu yi amfani da aikin render_template(...)
wanda ke samar da takamaiman fayil na html daga kundin tsarin samfuri.
Sauran gardama da aka ƙara zuwa aikin sune masu canji waɗanda ake wucewa zuwa fayil ɗin html.
A cikin app.py
, sabunta list_holidays()
tare da lambar da ke ƙasa:
@APP.route('/', methods=['GET', 'POST'])
@APP.route('/<holidays_date>', methods=['GET', 'POST'])
def list_holidays(holidays_date=None):
holidays_html = ""
return render_template("index.html", header=holidays_date.replace('_', ' '),
holidays_html=holidays_html)
$HOME/holidays-viewer/templates/index.html |
---|
{% extends "layout.html" %}
{% block content %}
<div class="holidays-html">
{{holidays_html|safe}}
</div>
{% endblock %}
|
= Samu ranar yau
Idan ba a bayyana kwanan wata ba, za mu jera ranakun hutu na ranar yau.
Don amfani da tsarin datetime na Python don samun kwanan wata, shigo da tsarin tare da from datetime import datetime
sannan ƙirƙirar aikin mai zuwa:
def get_todays_date():
current_month = datetime.now().strftime('%B')
current_day = datetime.now().strftime('%d')
if current_day.startswith('0'):
current_day = current_day.replace('0', '')
return current_month + "_" + current_day
Kira aikin a cikin list_holidays(...)
:
if holidays_date is None:
holidays_date = get_todays_date()
= Samu hutun da za a jera
= Samu hutun da za a jera
Wikipedia yana da shafi na kowace rana kuma bukukuwan suna ƙarƙashin sashe mai suna "Holidays and observances". Don samun hutu, muna buƙatar samun lambar sashin sa da abun cikin wannan lambar sashe.
Ƙirƙiri aiki don samun lambar sashe ta amfani da API:Parse :
def get_holidays_section(url, page, date_to_get):
params = {
"format":"json",
"action":"parse",
"prop":"sections",
"page":page
}
response = S.get(url=url, params=params)
data = response.json()
sections = data['parse']['sections']
section_number = "0"
for index, value in enumerate(sections):
if value['anchor'] == "Holidays_and_observances":
section_number = index + 1
if url == TEST_URL:
if value['anchor'] == date_to_get:
section_number = index + 1
return section_number
Ƙirƙiri wani aiki da ake kira get_holidays(...)
don samun hutu a wannan sashe ta amfani da API:Parse shima, sannan a kira ayyukan a cikin list_holidays(...)
:
section_number = get_holidays_section(URL, holidays_date, None)
holidays = get_holidays(URL, holidays_date, section_number)
holidays_html = holidays
Sabunta hanyoyin hutu
HTML na hutun da aka dawo ya ƙunshi hanyoyin ciki waɗanda ke nuna waɗancan bukukuwan, misali "/wiki/New_Years_Day
".
Muna buƙatar tsara "//en.wikipedia.org
" zuwa waɗannan hanyoyin haɗin yanar gizon ta amfani da jQuery don sanya su hanyoyin haɗin waje a cikin app ɗin mu, da sanya su buɗe a cikin sabon shafin.
Don yin haka, ƙara lambar zuwa $HOME/holidays-viewer/static/update-links.js
:
$( document ).ready( function() {
$( ".holidays-html a" ).attr( "target", "_blank" );
$( ".holidays-html a" ).attr( "href", function( i, href ) {
return "//en.wikipedia.org" + href;
});
});
Sannan ƙara jQuery zuwa layout.html
ta amfani da:
<script src="//tools-static.wmflabs.org/cdnjs/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="static/update-links.js"></script>
Mataki na 5: Nemo hutun wasu kwanakin =
Don samun hutu don wasu kwanakin, ƙirƙiri hanyar bincike don nuna fom da ke tattara wata da rana don bincika:
@APP.route("/search")
def search():
return render_template("search.html", header="Search date")
$HOME/holidays-viewer/templates/search.html |
---|
{% extends "layout.html" %}
{% block content %}
<div class="instructions m-3">
Search for holidays by date
</div>
<div class="base rounded shadow bg-white m-3">
<form class="m-auto" action="/" method="POST">
<fieldset>
<div class="label-field">Select Month</div>
<select class="bg-secondary mb-5 border-0" name="monthList">
<option value="January">January
<option value="February">February
<option value="March">March
<option value="April">April
<option value="May">May
<option value="June">June
<option value="July">July
<option value="August">August
<option value="September">September
<option value="October">October
<option value="November">November
<option value="December">December
</select>
</fieldset>
<fieldset>
<div class="label-field">Select Day</div>
<select class="bg-secondary mb-5 border-0" name="dayList">
<option value="1">1
<option value="2">2
<option value="3">3
<option value="4">4
<option value="5">5
<option value="6">6
<option value="7">7
<option value="8">8
<option value="9">9
<option value="10">10
<option value="11">11
<option value="12">12
<option value="13">13
<option value="14">14
<option value="15">15
<option value="16">16
<option value="17">17
<option value="18">18
<option value="19">19
<option value="20">20
<option value="21">21
<option value="22">22
<option value="23">23
<option value="24">24
<option value="25">25
<option value="26">26
<option value="27">27
<option value="28">28
<option value="29">29
<option value="30">30
<option value="31">31
</select>
</fieldset>
<button type="submit" name="search" class="bg-primary btn btn-submit text-white">Submit</button>
</form>
</div>
{% endblock %}
|
Da zarar an ƙaddamar da fom ɗin nema, sabunta holidays_date
don zama ranar da aka shigar.
Don yin haka, ƙara lambar zuwa list_holidays(...)
:
if request.method == 'POST' and 'search' in request.form:
search_month = str(request.form.get('monthList'))
search_day = str(request.form.get('dayList'))
holidays_date = search_month +"_"+search_day
Mataki na 6: Ƙara hutu =
Shafin da za mu ƙara sabon hutu zuwa gare shi yana da kariya daga gyarawa daga masu amfani da ba a san su ba, don haka muna buƙatar shiga ta amfani da API:Login#clientlogin da farko.
Don ƙara hutu, aika buƙatu zuwa API:Edit tare da kwanan wata da bayanin biki. Gyaran yana ƙara sabbin ranaku zuwa wannan shafin akan Gwajin Wikipedia: Sandbox/Holidays_and_observances. Wannan don hana ƙara hutun gwaji zuwa Wikipedia na Ingilishi.
Bayan an ƙara biki, a tura zuwa shafin farko inda za a nuna bukukuwan da aka ƙara, kuma a tsara su da ƙarfi don bambanta su da ainihin bukukuwan.
Don samo hutun gwaji tare da ainihin hutu, sabunta list_holidays(...)
:
test_section_number = get_holidays_section(TEST_URL, TEST_PAGE, holidays_date)
test_holidays = get_holidays(TEST_URL, TEST_PAGE, test_section_number)
holidays_html = test_holidays + holidays
flash("Holidays added through this app are in bold")
$HOME/holidays-viewer/templates/login.html |
---|
{% extends "layout.html" %}
{% block content %}
<div class="instructions m-3">
<p>You need to login to Wikipedia in order to add a new holiday
</div>
<div class="base rounded shadow bg-white m-3">
<form class="m-auto" action="/login" method="POST">
<div class="form-group">
<div class="form-field">
<div class="label-field">Username</div>
<input class="bg-secondary mb-5 border-0" name="username">
</div>
<div class="form-field">
<div class="label-field">Password</div>
<input class="bg-secondary mb-5 border-0" type="password" name="password">
</div>
</div>
<button type="submit" name="login" class="bg-primary btn btn-submit text-white">Login</button>
</form>
</div>
{% endblock %}
|
$HOME/holidays-viewer/templates/add.html |
---|
{% extends "layout.html" %}
{% block content %}
<div class="instructions m-3">
<p>Add a new test holiday
</div>
<div class="base rounded shadow bg-white m-3">
<form class="m-auto" action="" method="POST">
<div class="form-group">
<div class="form-field">
<div class="label-field">Date [MMMM dd]</div>
<input class="bg-secondary border-0 mb-5" name="date" placeholder="e.g April 1">
</div>
<div class="form-field">
<div class="label-field">Description</div>
<input class="bg-secondary border-0 mb-5" name="description" placeholder="e.g April fools' day">
</div>
</div>
<button type="submit" name="add" class="bg-primary btn btn-submit text-white">Add</button>
</form>
</div>
{% endblock %}
|
Mataki na 7: Salon app =
Don ƙara ƙarin salo a app ɗin mu, ƙirƙiri salon salo mai suna style.css
kuma ku haɗa shi daga layout.html
ta ƙara <link rel="stylesheet" href="static/style.css">
.
$HOME/holidays-viewer/static/style.css |
---|
.content {
width: 420px;
min-height: 100vh;
}
.holidays-html{
overflow-y: auto;
overflow-x: hidden;
max-height: 88vh;
scrollbar-width: thin;
}
.base {
height: 400px;
display: flex;
}
input, select {
width: 300px;
height: 40px;
}
.btn-submit {
width: 300px;
}
.btn {
cursor: pointer;
align-content: center;
background-color: transparent;
}
.bg-primary {
background-color: #36c !important;
}
.bg-primary-dark {
background-color: #2a4b8d !important;
}
.bg-secondary {
background-color: #eaecf0 !important;
}
.header-bar {
height: 48px;
display: flex;
flex: 1;
align-items: center;
}
.filler {
flex-grow: 1;
text-align: center
}
h2 {
display: none;
}
ul {
margin: 5px;
padding: 0;
}
li {
list-style-type: none;
margin-bottom: 4px;
background-color: white;
padding: 8px;
border-radius: 5px;
}
ul li li {
box-shadow: 0 .5rem 1rem rgba(0,0,0,.15);
}
|
Tsarin aikace-aikacen
A wannan gaba, tsarin aikace-aikacenku yakamata ya kasance:
$HOME/holidays-viewer ├── templates/ │ └── add.html └── index.html └── layout.html └── login.html └── search.html ├── static/ │ └── style.css └── update-links.js ├── app.py
Tare da app.py
da layout.html
kasancewa:
$HOME/holidays-viewer/app.py |
---|
#!/usr/bin/python3
"""
app.py
MediaWiki API Demos
Mai duba hutu: ƙa'idar demo mai ɗaukar ranaku hutu daga Wikipedia tare da zaɓuɓɓuka don bincika hutun wasu ranaku, da shiga don ƙara sabbin ranaku.
lasisin MIT
"""
from datetime import datetime
from flask import Flask, render_template, flash, request, url_for, redirect
import requests
APP = Flask(__name__)
APP.secret_key = 'your_secret_key'
URL = "https://en.wikipedia.org/w/api.php"
TEST_URL = "https://test.wikipedia.org/w/api.php"
TEST_PAGE = "Sandbox/Holidays_and_observances"
S = requests.Session()
IS_LOGGED_IN = False
@APP.route('/', methods=['GET', 'POST'])
@APP.route('/<holidays_date>', methods=['GET', 'POST'])
def list_holidays(holidays_date=None):
""" Ya lissafa ranakun hutu don kwanan wata ko kwanan wata na al'ada
"""
if holidays_date is None:
holidays_date = get_todays_date()
# Update date to a custom date
if request.method == 'POST' and 'search' in request.form:
search_month = str(request.form.get('monthList'))
search_day = str(request.form.get('dayList'))
holidays_date = search_month +"_"+search_day
# Get the section numbers for the holidays on Wikipedia and for those on the test page
section_number = get_holidays_section(URL, holidays_date, None)
test_section_number = get_holidays_section(TEST_URL, TEST_PAGE, holidays_date)
holidays = get_holidays(URL, holidays_date, section_number)
test_holidays = get_holidays(TEST_URL, TEST_PAGE, test_section_number)
holidays_html = test_holidays + holidays
flash('Holidays added through this app are in bold')
return render_template("index.html", header=holidays_date.replace('_', ' '),
holidays_html=holidays_html)
def get_todays_date():
""" Samu watan a matsayin rubutu da rana ta yanzu a matsayin lamba
"""
current_month = datetime.now().strftime('%B')
current_day = datetime.now().strftime('%d')
if current_day.startswith('0'):
current_day = current_day.replace('0', '')
return current_month + "_" + current_day
def get_holidays_section(url, page, date_to_get):
""" Samu lambar sashe don hutu akan Wikipedia da hutu akan shafin gwaji
"""
params = {
"format":"json",
"action":"parse",
"prop":"sections",
"page":page
}
response = S.get(url=url, params=params)
data = response.json()
sections = data['parse']['sections']
section_number = "0"
for index, value in enumerate(sections):
if value['anchor'] == "Holidays_and_observances":
section_number = index + 1
if url == TEST_URL:
if value['anchor'] == date_to_get:
section_number = index + 1
return section_number
def get_holidays(url, page, section_number):
""" Samu html wanda ya ƙunshi biki
"""
params = {
"format":"json",
"action":"parse",
"prop":"text",
"page": page,
"section": section_number,
"disableeditsection":1
}
response = S.get(url=url, params=params)
data = response.json()
text = data['parse']['text']['*']
return text
@APP.route("/search")
def search():
""" Bincika hutu na kwanakin al'ada
"""
return render_template("search.html", header="Search date")
@APP.route("/login", methods=['GET', 'POST'])
def login():
""" Shiga Wikipedia
"""
if request.method == 'POST' and 'login' in request.form:
params_0 = {
"action": "query",
"meta": "tokens",
"type": "login",
"format": "json"
}
response = S.get(url=URL, params=params_0)
data = response.json()
login_token = data['query']['tokens']['logintoken']
params_1 = {
"action": "clientlogin",
"username": str(request.form.get('username')),
"password": str(request.form.get('password')),
"loginreturnurl": "http://127.0.0.1:5000/login",
"logintoken": login_token,
"format": "json"
}
response = S.post(url=URL, data=params_1)
data = response.json()
if data['clientlogin']['status'] != 'PASS':
flash('Oops! Something went wrong -- ' + data['clientlogin']['messagecode'])
else:
global IS_LOGGED_IN
IS_LOGGED_IN = True
flash('Login success! Welcome, ' + data['clientlogin']['username'] + '!')
return redirect(url_for('add'))
return render_template("login.html", header="Login")
@APP.route("/add", methods=['GET', 'POST'])
def add():
""" Ƙara sabon biki zuwa shafin gwaji kuma a tura zuwa ranakun hutun don nuna ƙarin hutu
"""
if not IS_LOGGED_IN:
return redirect(url_for('login'))
if request.method == 'POST' and 'add' in request.form:
# Wiki markup to format the added holiday's text as a list item and in bold
holiday_text = "* '''" + str(request.form.get('description')) + "'''"
date = str(request.form.get('date'))
params_2 = {
"action": "query",
"meta": "tokens",
"format": "json"
}
response = S.get(url=TEST_URL, params=params_2)
data = response.json()
csrf_token = data['query']['tokens']['csrftoken']
params_4 = {
"action": "edit",
"title": TEST_PAGE,
"token": csrf_token,
"format": "json",
"section": "new",
"sectiontitle": date,
"text": holiday_text,
}
response = S.post(url=TEST_URL, data=params_4)
data = response.json()
if data['edit']['result'] != 'Success':
flash('Oops! Something went wrong -- ' + data['clientlogin']['messagecode'])
else:
flash('New holiday added successfully!')
return redirect(url_for('list_holidays', holidays_date=date.replace(' ', '_')))
return render_template("add.html", header="Add holiday")
if __name__ == "__main__":
APP.run()
|
$HOME/holidays-viewer/templates/layout.html |
---|
<title>Holidays</title>
<link rel="stylesheet" href="//tools-static.wmflabs.org/cdnjs/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css">
<link rel="stylesheet" href="//tools-static.wmflabs.org/fontcdn/css?family=Material+Icons">
<link rel="stylesheet" href="static/style.css">
<script src="//tools-static.wmflabs.org/cdnjs/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="static/update-links.js"></script>
<div class="content bg-secondary rounded m-auto">
<div class="title-bar bg-primary-dark text-white pl-2">
<small>Holidays and observances</small>
</div>
<div class="header-bar bg-primary text-white shadow p-2">
{% if request.path != url_for('list_holidays') %}
<a class=" btn text-white" href="{{ url_for('list_holidays') }}">
<i class="material-icons">arrow_back</i>
</a>
{% endif %}
<h5>{{header}}</h5>
<div class="filler"></div>
<a class="btn text-white" href="{{ url_for('add') }}">
<i class="material-icons">add</i>
</a>
<a class="btn text-white" href="{{ url_for('search') }}">
<i class="material-icons">search</i>
</a>
</div>
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="alert alert-primary mb-0" role="alert">
{% for message in messages %}
{{ message }}
{% endfor %}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</div>
<script src="//tools-static.wmflabs.org/cdnjs/ajax/libs/twitter-bootstrap/4.0.0/js/bootstrap.min.js"></script>
|
Matakai na gaba
- Ba da gudummawar ƙa'idar demo da kuka haɓaka ta amfani da MediaWiki API zuwa wannan code ma'ajiyar kayan ajiya.
Duba nan
- API:Main page — Jagorar farawa mai sauri don MediaWiki Action API.
- API:Parsing wikitext — Yana nazarin abubuwan da ke cikin shafi kuma sami fitarwa.
- API:Edit — Yana gyara shafi.
- API:Login — Yana ba da damar shiga wiki.