Implode Artikel Sekategori dari Mediawiki


Untuk mengumpulkan artikel sekategori dari suatu instalasi mediawiki (seperti Wikipedia), kita bisa membuka halaman kategori, membuka halaman satu demi satu, dan mem-paste-nya ke dalam pengolah kata kita. Kalau malas buka satu demi satu, kita bisa saja melakukannya dengan memanfaatkan mediawiki API. :)

Update: Telah ditambahkan dukungan bagi penanganan cmcontinue dan menghasilkan halaman web dimulai dari artikel tertentu.

 

Install xampp dan taruh file index.php dan main.php di dalam folder htdocs. Kemudian nyalakan apache server (di xampp, pastikan cURL sudah terpasang) dan buka localhost di browser. Langkah itu saja sudah cukup untuk bisa mengumpulkan artikel sekategori dari mediawiki.

Hehehe… Selanjutnya akan diuraikan bagaimana cara kerja index.php dan main.php. :)

 

index.php

index.php ini hanya berisi HTML form yang terhubung dengan main.php.

<input type="radio" name="category" value="Kecamatan_di_Kabupaten_Rembang">Kecamatan di Kabupaten Rembang<br>
<input type="radio" name="category" value="Kecamatan_di_Kabupaten_Blora">Kecamatan di Kabupaten Blora<br> Artikel Awal: <input name="start" type="text" />

Di sini, “value” dan konten dapat diganti agar sesuai dengan kebutuhan. Value dari atribut “value” harus sama dengan namespace kategori di wiki.

Update: “Artikel Awal” apabila diisi maka artikel-artikel yang dikumpulkan hanya artikel-artikel mulai dari artikel yang diinputkan (urutan sesuai abjad). 

 

main.php
set_time_limit(0);
$url = 'http://id.wikipedia.org/w/api.php';

set_time_limit(0) bermanfaat untuk mengatur agar script tidak berhenti apabila menjalankan script terlalu lama.

Di sini API dari Wikipedia Bahasa Indonesia digunakan sebagai contoh. Apabila ingin menerapkan pada wiki lain, tinggal ganti URL di atas sesuai dengan URL API wiki.

function apireq($q){
global $url;
$url = $url.'?'.$q;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_USERAGENT, 'Your Name/1.0 (http://yoursite.com/)');
$result = curl_exec($ch);
if (!$result) {
exit('cURL Error: '.curl_error($ch));
}
return $result;
}

Fungsi apireq untuk membuat request dengan menggunakan cURL. Di sini cukup mengganti ‘Your Name/1.0 (http://yoursite.com/)’ dengan nama dan situs kita.

function wquery($a){
$q = 'format=json&action=query&'.http_build_query($a);
return apireq($q);
}

Request yang bisa dikirim ke API bisa berupa query, login, dll. Fungsi wquery ini melingkupi fungsi apireq di atas, dengan menambahkan format=json&action=query untuk membuat request query dengan respon berformat json.

function getcm($c){
$r = array();
$c = 'Category:'.$c;
$cmcontinue = false;
do {
$a = json_decode(wquery(array('list'=>'categorymembers','cmtitle'=>$c,'cmcontinue'=>$cmcontinue)));
$m = $a->query->categorymembers;
foreach ($m as $v){
if ((intval($v->ns)==0) and ($v->title != 'Halaman Utama')){
array_push($r,$v->title);
}
}
if (property_exists($a,'query-continue')){
$theEscapeForHyphen = 'query-continue';
$cmcontinue = $a->$theEscapeForHyphen->categorymembers->cmcontinue;
} else {
$cmcontinue = false;
}
} while ($cmcontinue != false);
return $r;
}

Fungsi ini menerima judul kategori berupa string dan menghasilkan array berisi judul-judul halaman yang berada di dalam kategori tersebut. Fungsi ini menggunakan fungsi wquery di atas untuk membuat query. Kondisi dalam ‘if ((intval($v->ns)==0) and (true))’ bisa dimodifikasi untuk menyaring halaman yang tidak diinginkan.

Update: Ternyata respon dari API maksimal mengandung 10 judul artikel. Apabila kategori tersebut memiliki lebih dari 10 artikel, maka respon akan memiliki properti “query-continue”. Untuk menangani hal ini disiapkan variabel $cmcontinue dan dibuat do-while yang akan terus mengirim request hingga properti “query-continue” tak lagi dikembalikan.
$theEscapeForHyphen disiapkan untuk mensiasati pemanggilan properti yang menggunakan tanda “-” (hyphen).

function gfk($a){
foreach ($a as $k=>$v){
return $k;
}
}

Fungsi ini adalah fungsi untuk membantu fungsi berikutnya (getcon). gfk (get first key) digunakan untuk menghasilkan key pertama dari sebuah objek, mengingat objek yang dikembalikan oleh API memiliki unsur key yang tidak tetap, contohnya page id.

function clncon($con0){
$unwanted = array(); // array of regex here
$temp = $con0;
foreach($unwanted as $elem){
$temp = preg_replace($elem,"",$temp);
}
return $temp;
}

Fungsi ini untuk membersihkan konten yang dihasilkan dari respon. Untuk menyaring konten yang tidak diharapkan, tambahkan regex di dalam array $unwanted. Pada potongan kode di atas, $unwanted hanya berupa array kosong. Sebenarnya regex tidak dianjurkan untuk memanipulasi html, tapi baru tahu cara ini saja. :”)

function getcon($t){
$con0 = json_decode(wquery(array('titles'=>$t,'prop'=>'revisions','rvprop'=>'content','rvparse'=>true)));
$con1 = $con0->query->pages; $temp = gfk($con1);
$con2 = $con1->$temp->revisions[0]; unset($temp); $temp = gfk($con2);
$con3 = $con2->$temp; unset($temp);
$con4 = '<hr> <h1> '.$t.' </h1> <br /> '.$con3;
$con5 = clncon($con4);
return $con5;
}

Fungsi ini menerima suatu judul dan menghasilkan: judul, diikuti garis horisontal, dan konten (revisi terbaru) dari judul tersebut. Untuk bisa meraih konten dari objek didayagunakan fungsi gfk (get first key) yang sudah didefinisikan sebelumnya. Objek respon yang dihasilkan API merupakan objek yang mengandung objek.

function jcon($c,$s = null){
$ar = array();
$cm = getcm($c);
$ks = array_search($s, $cm);
if (!$ks){
$ks = 0;
}
for ($i = $ks; $i < count($cm); ++$i){
$con = getcon($cm[$i]);
array_push($ar,$con);
}
$jc = implode(" ", $ar);
return $jc;
}

Fungsi jcon (join content) ini adalah inti dari seluruh kode. Fungsi ini memanggil getcm() untuk menghasilkan array judul-judul halaman dalam kategori $c. Selanjutnya memanggil getcon() bagi tiap judul untuk menghasilkan konten dari seluruh judul tersebut, yang disimpan dalam array. Hasil akhir yang dikembalikan fungsi ini adalah gabungan (implode) dari seluruh teks konten dari judul sekategori.

Update: Apabila “Artikel Awal” dalam index.php diisi, maka $ks akan menghasilkan posisi “Artikel Awal” dalam array artikel sekategori. Sehingga pengambilan konten akan dimulai dari posisi “Artikel Awal”.

$c = $_POST['category'];
$s = $_POST['start'];
echo jcon($c,$s);

Potongan kode di atas menerima input bagi jcon() dari formulir HTML dalam index.php dan mencetak hasil dari jcon().

Ringkasan

Pada dasarnya request yang dibuat kode ini hanya ada 2, yakni:

http://id.wikipedia.org/w/api.php?format=json&action=query&list=categorymembers&cmtitle=JUDULKATEGORI&cmcontinue=FALSEATAUJUDULHALAMAN

digunakan untuk menghasilkan judul dari halaman-halaman yang menjadi anggota dari suatu kategori.

Update: ditambahkan request cmcontinue

http://id.wikipedia.org/w/api.php?format=json&action=query&titles=JUDULHALAMAN&prop=revisions&rvprop=content&&rvparse=true

digunakan untuk menghasilkan konten revisi terbaru dari halaman tertentu

Penutup

Kode ini masih memiliki keterbatasan, hasil masih agak berantakan dan hasil sering tak lengkap akibat terkendala limit dari API mediawiki. :( Tapi ini cukup bermanfaat bagi yang punya wiki pribadi maupun bersama untuk mencatat hal tertentu. Semoga bermanfaat.

Komentar Pemirsa