واجهة برمجة التطبيقات:عارض صورة اليوم المختارة
هذه الصفحة جزء من توثيق واجهة برمجة تطبيقات ميدياويكي التي تحمل اسم Action. |
نظرة عامة
سوف تتعلم في هذا التدريب التعليمي كيفية تصميم عارض ويكيبيديا:صورة اليوم المختارة مستخدما واجهة برمجة تطبيقات ميدياويكي من النوع Action.
سوف يعلمك هذا التدريب التعليمي كيفية تنفيذ هذا مستخدما:
- بايثون 3 وكذا إطار عمل فلاسك
- واجهة برمجة تطبيقات ميدياويكي التي تحمل اسم Action وكذا وحدات Images وImageinfo البرمجية
عملية خطوة بخطوة لتصميم هذا التطبيق
الخطوة 1: تأسيس بيئة تطوير البرمجيات مستخدما بايثون وفلاسك
تأسيس بايثون
يستخدم هذا التدريب التوضيحي بايثون الإصدار 3. يمكنك تنزيل أحدث إصدار من بايثون من هنا:
طالع الدليل الإرشادي للمبتدئين في نظام بايثون لمزيد من التعليمات التي تتناول تنصيب بايثون على أنظمة تشغيل أخرى.
تأسيس فلاسك
إن هو يمكنك استخدامه في تثبيت Flask: pip install flask
.
إن لم يكن لديك «بيب» بالفعل، ثبته من الموقع الشبكي الرسمي لبيب.
الخطوة 2: إنشاء تطبيق فلاسك بسيط
لو كان كل شيء مثبتًا لديك ويعمل على ما يرام، ضع النص البرمجي التالي في app.py
، داخل مجلد مشروعك: $HOME/picture-of-the-day-viewer/app.py
.
حينما تشغله (مستخدمًا flask run
أو python app.py
)، سوف يعرض «Hello world» في 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()
الخطوة 3: عارض صورة اليوم المختارة
منذ أن كل شيء جاهز، يمكنك البدء في كتابة الكود البرمجي لعارض صورة اليوم المختارة. صورة اليوم المختارة، اختصارًا «POTD»، هي Wikipedia:Wikipedia:Featured_pictures صورة مختارة تعرض يوميًا على الصفحة الرئيسية لويكيبيديا. سوف تحصل على الصورة من قالب ويكي يتغير كل يوم.
جلب تاريخ اليوم
منذ أن صورة اليوم المختارة تحدّث يوميًا، سوف تحتاج لتاريخ اليوم كي تصل إلى الأرشيف والحصول على نسخة مستقرة من الصورة الملائمة.
كي تفعل ذلك، استورد الفئة date
الخاصة ببايثون.
الخطوة التالية هي تحديد دالة جديدة هي index()
.
سوف تعرض Index()
صفحة الويب وتمرر أية بيانات متعلقة باستدعاءات واجهة برمجة التطبيقات لديك.
طالع عرض الصفحة لمزيد من المعلومات عن ملف index.html
الذي سوف نستخدمه في صفة القالب المعني.
أما الآن، يجب أن يحتوي index()
على متغير يحتوي على التاريخ الجاري.
سوف نستخدمه لاحقًا في صياغة استعلام للوصول إلى صورة اليوم المختارة.
#!/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()
استدعاء واجهة برمجة التطبيقات التي تحمل اسم Action
تعمل واجهة برمجة التطبيقات التي تحمل الاسم Action عن طريق إرسال البيانات ردًا على . كي تنفّذ ذلك، سوف تستورد مكتبة طلبات بايثون.
تاليًا أضف متغيرين اثنين جديدين: SESSION = requests.Session()
وENDPOINT = "https://en.wikipedia.org/w/api.php"
.
سوف تستخدم عنصر SESSION
كي ترفع طلبات إلى معرف الموارد الموحد ENDPOINT
.
استدعي في دالة جديدة، fetch_potd()
، العنصر واجهة برمجة التطبيقات:صور كي تطلب دمج الصورة داخل صفحة صورة اليوم المختارة المحمية (مثال).
لأغراض هذا الاستدعاء، استخدم اسم ملف الصورة كي تستدعي واجهة برمجة التطبيقات:معلومات_صورة ، والحصول على معرف الموارد الموحد المصدر للصورة.
في هذا المثال، يتولى التعامل مع استدعاء واجهة برمجة التطبيقات الثاني الدالة المساعدة، fetch_image_src()
.
تدرج أرشيفات ويكيبيديا التاريخ مستخدمة صيغة ، على سبيل المثال: 2019-01-31، تعبيرًا عن 31 يناير 2019.
يمكنك الحصول على الصيغة الصحيحة مستخدمًا طريقة التاريخ هذه 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
في الختام، غيّر index()
كي تستدعي fetch_potd()
.
استورد render_template
من flask
، واجعل index()
يرد render_template("index.html", data=data)
.
عرض الصفحة
تحتوي قوالب Flask في الغالب على ترميز إتش تي إم إل، إلا أنها تحتوي أيضًا على Jinja لعرض محتوى متحرك.
يبدو ترميز Jinja مثل ما يلي: {{ variable }}
، ويستخدم في وضع متغيرات بايثون أو صيغها في بنية صفحاتنا الأساسية.
أضف نص معياري أساسي من فئة وبضع عناصر إلى index.html
.
احرص على حفظ ذلك في مجلد داخل تطبيقك، اسمه /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>
تحويلها إلى صفحة تفاعلية
أضف عنصر <form>
إلى index.html
، ثم امنحه مدخلات زر الإرسال التالية: «عودة - Back» و «التالي - Next». حينما لا يختار أي من الزرين، سوف يرسل النموذج طلب نشر «POST»، وسوف تمرر القيمة المختارة مرة أخرى إلى app.py
.
سوف يسمح هذا الأمر للمستخدمين تصفح أرشيف صورة اليوم المختارة.
بعد ذلك حدّث app.py
داخل الدالة change_date()
، كي تضبط التاريخ المعروض للمستخدم.
وسّع أيضًا طريق /
كي تتعامل مع طلبات النشر «POST» من النموذج.
كي تسمح لملف app.py
بقراءة رسائل طلبات النشر «POST»، استورد فئة Request
من Flask.
هذا هو الكود البرمجي الكامل لبايثون وإتش تي إم إل:
$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>
|
تحديد نمط تطبيقك
يستعين Flask بمجلد، اسمه static، يحتوي على أية ملفات مساعدة تظل كما هي طوال مدة عمر التطبيق.
هذا الموضع موضع مفيد يمكنك فيه وضع أية صفحات طرز أو نصوص برمجية إضافية.
سوف تستخدم صفحة الطرز الخاصة بنا بعض الألوان والأشكال المرئية التي تستند إلى الدليل الإرشادي لأسلوب ويكيميديا.
ضع ملف سي إس إس في $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 */
}
|
الخطوات التالية
- ساهم بتطبيق تجريبي صممته بنفسك مستخدمًا واجهة برمجة تطبيقات ميدياويكي في مستودع عينات الكود البرمجي هذا.
- تعرف على بعض السبل لإضافة نص وصفي من صفحة صورة اليوم المختارة:
- يقدم API:Search عنصر
snippets
يمكن استخدامه في صفة عارض لمحة سريعة عن وصلة شبكية - يمكن استخدام #1 للحصول على النص المعرب كاملًا من المقالات على مواقع الويكي التي نصّب فيها الامتداد #2 (طالع المثال).
- يقدم API:Search عنصر
انظر أيضا
- واجهة برمجة التطبيقات:الصفحة الرئيسية : نظرة عامة على واجهة برمجة تطبيقات Action
- API:FAQ : أسئلة متكررة تقدم بيانًا متعمقًا لواجهة برمجة التطبيقات Action
- واجهة برمجة التطبيقات:صور
- واجهة برمجة التطبيقات:معلومات_صورة
- مستودع عينات كود واجهة برمجة التطبيقات Action الخاص بميدياويكي: يحتوي على المزيد من العينات التوضيحية وعينات من الكود البرمجي
- المزيد على ويكيبيديا وIFTTT