Kategorien
FreewarWiki:Bot/Skripts/npclist.php
< FreewarWiki:Bot | Skripts
<?php /* * WIKI Vorlagen Parser * */ define('TEMPLATE_GET_KEY', 1); define('TEMPLATE_GET_VALUE', 2); function get_templates($template, $wiki_text) { $pattern = '/\{\{(Vorlage:)?' . preg_quote($template, '/') . '/'; $templates = preg_split($pattern, $wiki_text); return array_slice($templates, 1); } function parse_template($text) { $template = array(); /* nicht kompatibel mit verschachtelten Vorlagen // Key-Value Paare spliten $lines = array_filter(explode('|', $template_text)); foreach ($lines as $line) { // Key/Value trennen $keyval = explode('=', $line, 2); // und entsprechend ins Array eintragen $template[$keyval[0]] = trim($keyval[1]); // 'Parameter=' wirft undefined offset 1 }//*/ $key = ; $mode = TEMPLATE_GET_KEY; $depth = 0; for ($i = 1, $length = strlen($text); $i < $length; ++$i) { if ($text[$i] === '{' && $text[$i+1] === '{') { // weitere Vorlage ++$depth; ++$i; $template[$key] .= '{'; } else if ($text[$i] === '}' && $text[$i+1] === '}') { // geschlossene Vorlage if ($depth === 0) { break; } else { --$depth; ++$i; $template[$key] .= '}'; } } else if ($text[$i] === '[' && $text[$i+1] === '[') { // geöffneter Link ++$depth; ++$i; $template[$key] .= '['; } else if ($text[$i] === ']' && $text[$i+1] === ']') { // geschlossener Link if ($depth === 0) { break; } else { --$depth; ++$i; $template[$key] .= ']'; } } if ($text[$i] === '=' && $depth === 0) { // Wertzuweisung beginnt $mode = TEMPLATE_GET_VALUE; $depth = 0; $key = trim($key); $template[$key] = ; } else if ($text[$i] === '|' && $depth === 0) { // Parameter Sparierung $mode = TEMPLATE_GET_KEY; $key = ; } else if ($mode === TEMPLATE_GET_KEY) { $key .= $text[$i]; } else if ($mode === TEMPLATE_GET_VALUE) { // Wert wird geschrieben $template[$key] .= $text[$i]; } } return array_map('trim', $template); } /* * Artikeln in Kategorie */ // verwendung in array_filter, prüfung ob seite und nicht etwa unterkat function is_page($data) { return $data['type'] == 'page'; } // seiten in kategorie $name function get_cm($name) { $cm = array(); // api url $url = 'http://' . WIKI_HOST . '/api.php?action=query&list=categorymembers'. '&cmtitle=Kategorie:' . urlencode($name) . '&cmlimit=max'. '&cmstartsortkey=0&cmprop=ids|title|type&format=json&cmsort=sortkey'; $continue_token = ; do { if ($continue_token) { // fortsetzungsseite $url .= "&cmcontinue=$continue_token"; } // holen, parsen $response = json_decode(file_get_contents($url), true); $continue_token = @$response['query-continue']['categorymembers']['cmcontinue']; $cm = array_merge($cm, array_map('extract_data', array_filter($response['query']['categorymembers'], 'is_page'))); } while ($continue_token); return $cm; } // npclist.php error_reporting(E_ALL ^ E_NOTICE); header('Content-Type: text/plain; charset=utf-8;'); # verwendung in array_filter, nur pageids holen, ähnlich array_column function extract_data($a) { return $a['pageid']; } # Entfernen von formatnum function formatnum_r($number) { return +str_replace('.', , $number); } # Holt Seitentitel aus mehreren Wikilinks in einer Liste function filter_wiki_links($s) { $links = array(); foreach (explode("*", $s) as $entry) { if (preg_match("/\[\[([^|\]]+)(\|([^|\]]+))?\]\]/", $entry, $matches)) { $links[] = isset($matches[2]) ? $matches[3] : $matches[1]; } } return $links; } define('WIKI_HOST', 'fwwiki.de'); define('CSV_DELIMITER', ';'); define('CSV_DELIMITER_INTER', ','); # Seiten pro API Abfrage define('CHUNK_LENGTH', 20); $npcs = array(); $page_chunks = array_chunk(get_cm('NPCs'), CHUNK_LENGTH); foreach ($page_chunks as $pages) { $api_url = "http://" . WIKI_HOST . "/api.php?action=query&format=json" . "&pageids=" . implode('|', $pages) . "&prop=revisions" . "&rvprop=content"; $api = json_decode(file_get_contents($api_url), true); /* Wir wollen die ursprüngliche Sortierung von get_cm * auch in den Seiten aus api.php. * array_merge vergibt aber neue Schlüssel wenn diese numerisch sind. * Der Union Operator $a1 + $a2 bevorzugt allerdings die Werte von $a1. * array_replace ist daher die einzige Variante. */ $pages_sorted = array_replace(array_flip($pages), $api['query']['pages']); foreach ($pages_sorted as $pageid => $info) { $raw = $info['revisions'][0]['*']; # NPC Vorlage $base = array_map('parse_template', get_templates('NPC/Layout', $raw)); $base = $base[0]; if (!isset($base['unangreifbar']) || $base['unangreifbar'] == 'none') { # Name setzen $name = isset($base['name']) ? $base['name'] : $info['title']; $images = preg_split("/\s+/", trim($base['Bild'])); # Basiseintrag $base_entry = array( 'name' => $name, 'A' => formatnum_r($base['Stärke']), 'LP' => formatnum_r($base['Lebenspunkte']), 'XP' => formatnum_r($base['XP']), 'GM' => formatnum_r($base['Gold']), 'bild' => $images[0], 'autor' => implode(CSV_DELIMITER_INTER, filter_wiki_links(trim($base['BildAutor']))), 'vklist' => implode(CSV_DELIMITER_INTER, filter_wiki_links($base['Vorkommen'])), 'itemlist' => implode(CSV_DELIMITER_INTER, filter_wiki_links($base['Items'])) ); echo implode(CSV_DELIMITER, $base_entry) . "\n"; if ($name == "Pironer") { implode(CSV_DELIMITER_INTER, filter_wiki_links($base['Items'])); } # Varianten $variants = array_map('parse_template', get_templates('NPC/Ausnahme', $raw)); # eintragen foreach ($variants as $variant) { echo implode(CSV_DELIMITER, array_merge($base_entry, $variant)) . "\n"; } } } }