API:Yakındaki yerler görüntüleyici

From mediawiki.org
This page is a translated version of the page API:Nearby places viewer and the translation is 100% complete.

Genel bakış

Bu eğitimde, MediaWiki Eylem API'si kullanarak bulunduğunuz yere yakın viki sayfalarını nasıl arayacağınızı öğreneceksiniz.

Bu eğitim size bunu kullanarak nasıl yapacağınızı öğretecektir:

Bu uygulamayı oluşturmak için adım adım bir süreç

1. adım: Python ve Flask geliştirme ortamını ayarlayın

Bir Flask uygulaması için Python geliştirme ortamını kurmak için Python'u kurmanız, sanal bir ortam oluşturmanız ve Flask'ı kurmanız gerekir.

Bu uygulama, yeni Python projeleri için önerilen sürüm olan Python3'ü kullanır. Python2 ve Python3 arasındaki farklar hakkında buradan daha fazla bilgi edinin Python3'ü yerel makinenize kurmak için, bu kurulum kılavuzlarında adım adım talimatları izleyin.

Uygulamayı oluşturmak için geliştirme ortamının nasıl kurulacağı aşağıda açıklanmıştır:

$ mkdir nearby-places-viewer
$ cd nearby-places-viewer/
This will create a new directory and change into it
$ python3 --version #Python 3.6.5
This command checks your Python version 
$ python3 -m venv venv
This command will create a virtual environment named 'venv'
$ source venv/bin/activate
This will activate the virtual environment
$ pip install Flask
This command will install the Flask package with all its dependencies

2. adım: Basit bir Flask uygulaması oluşturun

Basit bir statik sayfa oluşturun

Aşağıdaki kodu $HOME/nearby-places-viewer/nearby.py içinde yerleştirin

#!/usr/bin/python3

"""
    nearby.py

    MediaWiki Action API Code Samples
    
    Nearby places viewer app: Demo of geo search for wiki pages 
    near a location using the Geolocation API and MediaWiki Action 
    API's Geosearch module. 

    MIT license
"""

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    """ Displays the index page accessible at '/'
    """
    return render_template('places.html')

if __name__ == '__main__':
    app.run()

Bu <h1>Nearby places viewer</h1> kod satırını bir HTML dosyasına templates klasörünün içine bırakın: $HOME/nearby-places-viewer/templates/places.html

Not: Bu basit uygulamada, templates dizininden places.html adlı şablonu oluşturan render_template yöntemini kullanıyoruz.

Ardından python nearby.py komutuyla Flask uygulamanızı çalıştırın ve uygulamanızı tarayıcıda görüntülemek için http://127.0.0.1:5000/ açın. Tarayıcı pencerenizde "Nearby places viewer" görmeniz gerekir.

Uygulamanızı şekillendirin

Biraz uygulama stili yapalım. HTML dosyasında arama girişini kabul etmek için bir düğme öğesi ekleyin ve harici ve dahili bir stil sayfası yüklemek için etiketleri bağlayın. Bu durumda harici stil sayfası, Amatic yazı tipi için bir CSS dosyasının URL'sidir.

$HOME/nearby-places-viewer/templates/places.html içindeki mevcut kodu aşağıdaki ile değiştirin:

<link rel="stylesheet" href="//tools-static.wmflabs.org/fontcdn/css?family=Amatic+SC:700">
<link rel="stylesheet" href="/static/style.css">

<h1>Nearby places viewer</h1>
<button>Click here to search</button>

Aşağıdaki kodu $HOME/nearby-places-viewer/static/style.css içinde yerleştirin

h1 {
    font-family: 'Amatic SC', cursive;
    font-size: 2.5em;
    font-weight: normal;
    color: black;
}

button {
    font-size: 16px;
    padding: 10px 25px;
    cursor: pointer;
    text-decoration: none;
    color: white;
    border-radius: 4px;
    background-color: #7c7ce0;
    margin-bottom: 20px;
}
Yakındaki yerler görüntüleyici demo uygulaması ekran görüntüsü (1)

Uygulama düzeni

$HOME/nearby-places-viewer
├── templates/
│   └── places.html
├── static/
│   └── static.css
├── nearby.py
└── venv/

3. adım: Mevcut konumunuzun koordinatlarını alın

İlk adım olarak, yakındaki viki sayfalarını aramak için mevcut konumunuzun koordinatlarını almanız gerekir. Bunu yapmak için, bazı JavaScript kodlarıyla birlikte Geolocation API'yi kullanabilirsiniz.

Click here to search düğmesini tıkladığınızda, uygulama Geolocation API'sini arar ve API'nin Navigator.geolocation nesnesi aracılığıyla cihazınızın mevcut konumunu alır. API'nin yanıtı, enlem ve boylamı elde edebileceğiniz Position değerindeki bir nesnedir.

Not: Uygulamanız API'yi aradığında size bilgi verilir ve tarayıcınızın konumunuza erişmesine izin vermeniz istenir.

Aşağıdaki kodu $HOME/nearby-places-viewer/static/places.js içinde yerleştirin

$( document ).ready(function() {
	var x = document.getElementById( "places-list" );
	
	$( 'button' ).click(function() { 
		getLocation(); 
	});

	function getLocation() {
		x.innerHTML = "Searching your location..";

		if (navigator.geolocation) {
			navigator.geolocation.getCurrentPosition(fetchPlaces);
		} else { 
			x.innerHTML = "Geolocation is not supported by this browser.";
		}
	}

	function fetchPlaces(position) {
		x.innerHTML = position.coords.latitude + "|" + position.coords.longitude;
	}
});

HTML dosyasındaki özel JavaScript /static/places.js ve jQuery bağlayın: $HOME/nearby-places-viewer/templates/places.html

<!-- Add these two lines at the top -->
<script src="//tools-static.wmflabs.org/cdnjs/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="/static/places.js"></script> 

<!-- Add this line after the button element -->
<div id="places-list"></div>

4. adım: Konum verilerini AJAX ile sunucuya gönderin

Bu uygulama, 3. adımda elde edilen konum verilerini sunucuya göndermek için jQuery'nin AJAX yöntemini kullanır ve sayfa yenilemeden POST'u $HOME/nearby-places-viewer/nearby.py içinde / Python Flask rotasına gönderir.

Bir sonraki adım olarak, fetchPlaces işlevine $HOME/nearby-places-viewer/static/places.js içindeki AJAX çağrısını ekleyelim.

Not: Bu noktada, uygulamanızı çalıştırmayı denerseniz, gönderi isteklerini işlemek için / yoluna destek eklemediğimiz için tarayıcı penceresinde bir hata görmeniz olasıdır.

function fetchPlaces(position) {
	var data = { 
		"latitude": position.coords.latitude, 
		"longitude": position.coords.longitude
	};

	$.ajax({
		url: "/",
		type: "POST",
		data: JSON.stringify(data),
		contentType: "application/json",
		dataType: "json",

		success: function (response) { 
			x.innerHTML = "Success!";
		}, 
		error: function () { 
			x.innerHTML = "An error occurred while fetching places!"; 
		}
	});
}

5. adım: MediaWiki Eylem API'si aracılığıyla yakındaki yerleri getirin

İlk olarak, POST isteklerini işlemek için Python Flask rotasını / olarak $HOME/nearby-places-viewer/nearby.py içinde genişletin. Bunu, rota dekoratöründeki methods bağımsız değişken listesine hem GET hem de POST ekleyerek yapabilirsiniz. Ardından, request nesnesinden JSON formatında mevcut olan konum verilerini alabilir ve daha sonraki işlemler için fetch_places_nearby() işlevine iletebilirsiniz.

@app.route('/', methods=['GET', 'POST'])
def index():
    """ Displays the index page accessible at '/'
    """

    if request.method == "POST":
        data = request.get_json()
        latitude = data['latitude']
        longitude = data['longitude']

        results = fetch_places_nearby(latitude, longitude)
        return jsonify(results=results)

    return render_template('places.html')

fetch_places_nearby() işlevindeki kod, bir konumun yakınındaki viki sayfalarını aramak için Eylem API'den GET talebinde bulunur. API çağrısı, https://en.wikipedia.org/w/api.php bitiş noktası ve sorgu dizesi parametrelerinden oluşur. Anahtar parametrelerden bazıları şunlardır:

  • action=query bilgileri sorgulamak için ana modül
  • generator=geosearch sorgu modülünün alt modülü list, bir sayfa kümesi için arama sonuçlarını almak üzere jeneratör modülü olarak kullanılır
  • prop=coordinates|pageimages|description|info sayfalar için hangi özelliklerin döndürüleceğini söyler

Not: geosearch modülü hakkında daha fazla bilgi için API:Geosearch sayfasına ziyaret edin.

def fetch_places_nearby(lat, lon):
    params = {
        "action": "query",
        "prop": "coordinates|pageimages|description|info",
        "inprop": "url",
        "pithumbsize": 144,
        "generator": "geosearch",
        "ggsradius": 10000,
        "ggslimit": 10,
        "ggscoord": str(lat) + "|" + str(lon),
        "format": "json",
    }

    res = SESSION.get(url=API_ENDPOINT, params=params)
    data = res.json()
    places = data['query'] and data['query']['pages'] 
    # TODO: further process 'places' list
    
    return places

İçe aktarma ifadeleri ve işlenmiş places listesi ile eksiksiz Python ve Flask kodunu görüntüleyin. Bu uygulama, iki coğrafi koordinat arasındaki mesafeyi hesaplamak için Python'da bulunan Haversine paketini kullanır.

$HOME/nearby-places-viewer/nearby.py
#!/usr/bin/python3

"""
    nearby.py

    MediaWiki Action API Code Samples

    Nearby places viewer app: Demo of geo search for wiki pages near a location using
    the Geolocation API and MediaWiki Action API's Geosearch module.

    MIT license
"""

from flask import Flask, request, render_template, jsonify
import requests
from haversine import haversine


APP = Flask(__name__)
SESSION = requests.Session()
API_ENDPOINT = 'https://en.wikipedia.org/w/api.php'


@APP.route('/', methods=['GET', 'POST'])
def index():
    """ Displays the index page accessible at '/'
    """

    if request.method == "POST":
        data = request.get_json()
        latitude = data['latitude']
        longitude = data['longitude']

        results = fetch_places_nearby(latitude, longitude)
        return jsonify(results=results)

    return render_template('places.html')

def fetch_places_nearby(lat, lon):
    """ Fetches nearby places via MediaWiki Action API's Geosearch module
    """
    params = {
        "action": "query",
        "prop": "coordinates|pageimages|description|info",
        "inprop": "url",
        "pithumbsize": 144,
        "generator": "geosearch",
        "ggsradius": 10000,
        "ggslimit": 10,
        "ggscoord": str(lat) + "|" + str(lon),
        "format": "json",
    }

    res = SESSION.get(url=API_ENDPOINT, params=params)
    data = res.json()
    places = data['query'] and data['query']['pages']
    results = []

    for k in places:
        title = places[k]['title']
        description = places[k]['description'] if "description" in places[k] else ''
        thumbnail = places[k]['thumbnail']['source'] if "thumbnail" in places[k] else ''
        article_url = places[k]['fullurl']

        cur_loc = (lat, lon)
        place_loc = (places[k]['coordinates'][0]['lat'], places[k]['coordinates'][0]['lon'])

        distance = round(haversine(cur_loc, place_loc, unit='mi'), 2)

        results.append({
            'title': title,
            'description': description,
            'thumbnail': thumbnail,
            'articleUrl': article_url,
            'distance': distance
        })

    return results

if __name__ == '__main__':
    APP.run(debug=True)

6. adım: JSON yanıtından yerlerin listesi için bir kullanıcı arayüzü oluşturun

AJAX'ın success geri aramasında sunucudan döndürülen JSON verilerini işleyin ve div içeriğini değiştirmek için HTML DOM innerHTML özelliğini kullanın.

success: function (response) { 
	var places = response["results"],
		no_thumb = "..";

	x.innerHTML = "";
	
	for (var p in places) {
		var thumbnail = places[p].thumbnail || no_thumb;

		x.innerHTML += "<div class=\"item\"><div class=\"col-xs-8 no-padding\"><h5><a href=\"" +
			places[p]["articleUrl"] + "\" target=\"_blank\">" +
			places[p]["title"] + "</a></h5><p>" +
			places[p]["description"] + "</p><span>📍" + places[p]["distance"] +
			" miles</p></div><div class=\"col-xs-4 no-padding\"><img src=\"" +
			thumbnail + " \"></div></div>";
	}
}

AJAX başarılı geri arama ile eksiksiz JavaScript kodunu görüntüleyin.

$HOME/nearby-places-viewer/static/places.js
$( document ).ready(function() {
	var x = document.getElementById( "places-list" );
	
	$( ".btn-search" ).click(function() { 
		getLocation(); 
	});

	function getLocation() {
		x.innerHTML = "Searching your location..";

		if (navigator.geolocation) {
			navigator.geolocation.getCurrentPosition(fetchPlaces);
		} else { 
			x.innerHTML = "Geolocation is not supported by this browser.";
		}
	}

	function fetchPlaces(position) {
		var data = { 
			"latitude": position.coords.latitude, 
			"longitude": position.coords.longitude
		};

		$.ajax({
			url: "/",
			type: "POST",
			data: JSON.stringify(data),
			contentType: "application/json",
			dataType: "json",

			success: function (response) { 
				var places = response["results"],
					no_thumb = "https://upload.wikimedia.org/wikipedia/commons/thumb/7/75/Gnome-image-missing.svg/200px-Gnome-image-missing.svg.png";

				x.innerHTML = "";
				
				for (var p in places) {
					var thumbnail = places[p].thumbnail || no_thumb;

					x.innerHTML += "<div class=\"item\"><div class=\"col-xs-8 no-padding\"><h5><a href=\"" +
						places[p]["articleUrl"] + "\" target=\"_blank\">" +
						places[p]["title"] + "</a></h5><p>" +
						places[p]["description"] + "</p><span>📍" + places[p]["distance"] +
						" miles</p></div><div class=\"col-xs-4 no-padding\"><img src=\"" +
						thumbnail + " \"></div></div>";
				}
			}, 
			error: function () { x.innerHTML = "An error occurred while fetching places!"; }
		});
	}
});

7. adım: Bootstrap ile stil değişiklikleri

6. adımdaki kod parçacığının Bootstrap sınıf adlarını kullandığını fark etmiş olabilirsiniz. Evet, Places kullanıcı arayüzüne duyarlı bir düzen tasarımı eklemek için bu adımda Bootstrap çerçevesini entegre ediyoruz. Bunu yapmak için, CSS ve HTML dosyalarında biraz daha ince ayar yapalım.

Tam CSS ve HTML kodunu görüntüleyin.

$HOME/nearby-places-viewer/static/style.css
.places-container .no-padding {
    padding: 0;
}

.places-container .info {
    text-align: center;
}

.places-container .viewer-heading {
    font-family: 'Amatic SC', cursive;
    font-size: 2.5em;
    font-weight: normal;
    color: black;
}

.places-container .btn-search {
    font-size: 16px;
    padding: 10px 25px;
    cursor: pointer;
    text-decoration: none;
    color: white;
    border-radius: 4px;
    background-color: #7c7ce0;
}

.places-container .list {
    margin-top: 20px;
}

.places-container .item {
    min-height: 100px;
}

.places-container .item p,
span {
    font-size: 12px;
    margin: 2px;
}

.places-container .item span {
    color: gray;
}

.places-container .item img {
    float: right;
    width: 80px;
    height: 80px;
    border-radius: 5px;
    object-fit: cover;
}

.places-container .item a {
    color: #7c7ce0;
}
$HOME/nearby-places-viewer/templates/places.html
<title>Nearby places viewer</title>

<script src="//tools-static.wmflabs.org/cdnjs/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="//tools-static.wmflabs.org/cdnjs/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="/static/places.js"></script>

<link rel="stylesheet" href="//tools-static.wmflabs.org/cdnjs/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="//tools-static.wmflabs.org/fontcdn/css?family=Amatic+SC:700">
<link rel="stylesheet" href="/static/style.css">

<div class="container places-container col-lg-4 col-xs-12">
  <div class="col-xs-12 no-padding info">
    <h1 class="viewer-heading">Nearby places viewer</h1>
    <button class="btn-search">Click here to search</button>
  </div>
  <div class="col-xs-12 no-padding list" id="places-list">
  </div>
</div>
Yakındaki yerler görüntüleyici demo uygulaması ekran görüntüsü (2)

Sonraki Adımlar

  • MediaWiki API'sini kullanarak geliştirdiğiniz bir demo uygulamasını bu kod örnekleri deposuna katkıda bulunun.

Ayrıca bakınız