Utilisateur:Tpt/OPDS
Apparence
Voici un début de générateur de catalogue OPDS pour Wikisource. N’hésitez pas à le modifier, le transformer et l’utiliser sur votre propre serveur.
OPDS Creator 0.1
[modifier]opds.php
[modifier]<?php
$infos = array(
'fr' => array(
'namespaces' => array(
'category' => 'Category',
'catégorie' => 'Category'
),
'mainCategories' => array(
array(
'title' => 'Catégorie:Thèmes',
'content' => 'Livres par thèmes'
)
)
),
'en' => array(
'namespaces' => array(
'category' => 'Category'
),
'mainCategories' => array()
)
);
$i18n = array(
'fr' => array(
'opds.see-on-wikisource' => 'Voir sur Wikisource',
'opds.search-on-wikisource' => 'Rechercher sur Wikisource',
'opds.mainpage' => 'Page d\'Accueil',
'opds.wiki' => 'Wikisource'
),
'en' => array(
'opds.see-on-wikisource' => 'See on Wikisource',
'opds.search-on-wikisource' => 'Search on Wikisource',
'opds.mainpage' => 'Main page',
'opds.wiki' => 'Wikisource'
)
);
$myPath = 'http://genewiki.legtux.org/opds/opds.php'; //Placer ici l’url du fichier.
date_default_timezone_set('UTC');
class OPDS {
protected $lang = '';
protected $page = '';
protected $id = '';
protected $space = 'main';
protected $url = '';
protected $info = null;
protected $i18n = null;
protected $myPath = '';
public function __construct($infos, $i18n, $myPath) {
$this->info = $infos;
$this->i18n = $i18n;
$this->lang = isset($_GET['lang']) ? strtolower(substr($_GET['lang'], 0, 2)) : $this->getLang();
if(!array_key_exists($this->lang, $this->info))
$this::error(404);
$this->id = isset($_GET['page']) ? htmlspecialchars(urldecode($_GET['page'])) : '';
$page = explode(':', $this->id, 2);
if(isset($page[1])) {
$namespace = strtolower($page[0]);
if(!$this->info[$this->lang]['namespaces'][$namespace])
$this::error(404);
$this->space = $this->info[$this->lang]['namespaces'][$namespace];
$this->page = $page[1];
$this->url = 'http://' . $this->lang . '.wikisource.org/wiki/' . urlencode($this->space) . ':' . urlencode($this->page);
} else {
$this->page = $page[0];
$this->url = 'http://' . $this->lang . '.wikisource.org/wiki/' . urlencode($this->page);
}
$this->myPath = $myPath;
}
protected function getLang() {
if(!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
$langs = explode(',',$_SERVER['HTTP_ACCEPT_LANGUAGE']);
foreach($langs as $lang) {
$sLang = strtolower(substr($lang, 0, 2));
if(array_key_exists($lang, $this->info)) {
return $lang;
}
}
}
return '';
}
protected function getApiData($params) {
$data = 'action=query&format=php';
foreach($params as $param_name => $param_value) {
$data .= '&' . $param_name . '=' . urlencode($param_value);
}
$ch = curl_init($this->lang . '.wikisource.org/w/api.php?' . $data);
curl_setopt($ch, CURLOPT_USERAGENT, 'OPDS Creator 0.1');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
if (curl_errno($ch)) {
return curl_error($ch);
}
curl_close($ch);
return unserialize($response);
}
protected function feed($data) {
require('views/feed.php');
}
protected function page() {
$data = array(
'categories' => array()
);
$response = $this->getApiData(array('titles' => $this->page, 'prop' => 'categories', '!hidden' => 'true'));
foreach($response['query']['pages'] as $list) {
if(isset($list['missing'])) {
$this::error(404);
} else if(isset($list['categories'])) {
$data['categories'] = $list['categories'];
}
}
require('views/page.php');
}
protected function category() {
$data = array(
'categories' => array(),
'pages' => array(),
'subcategories' => array(),
'langlinks' => array()
);
$response = $this->getApiData(array('prop' => 'categories', 'titles' => $this->id, '!hidden' => 'true'));
foreach($response['query']['pages'] as $list) {
if(isset($list['missing'])) {
$this::error(404);
} else if(isset($list['categories'])) {
$data['categories'] = $list['categories'];
}
}
$response = $this->getApiData(array('list' => 'categorymembers', 'cmtitle' => $this->id, 'cmnamespace' => '0', 'cmlimit' => '200'));
if(isset($response['query']['categorymembers'])) {
$data['pages'] = $response['query']['categorymembers'];
}
$response = $this->getApiData(array('list' => 'categorymembers', 'cmtitle' => $this->id, 'cmnamespace' => '14', 'cmlimit' => '200'));
if(isset($response['query']['categorymembers'])) {
$data['subcategories'] = $response['query']['categorymembers'];
}
$response = $this->getApiData(array('prop' => 'langlinks', 'titles' => $this->id, 'lllimit' => '100'));
foreach($response['query']['pages'] as $list) {
if(isset($list['langlinks'])) {
$data['langlinks'] = $list['langlinks'];
}
}
$this->feed($data);
}
protected function mainPage() {
$data = array(
'categories' => array(),
'pages' => array(),
'subcategories' => $this->info[$this->lang]['mainCategories'],
'langlinks' => array()
);
foreach($this->info as $lang) {
$data['langlinks'][] = array('lang' => $lang, '*' => '');
}
$this->feed($data);
}
protected static function error($id) {
switch($id){
case 404:
header('HTTP/1.0 404 Not Found');
exit;
}
}
public function run() {
if($this->page == '') {
$this->mainPage();
} else {
switch($this->space) {
case 'main':
$this->page();
break;
case 'Category':
$this->category();
break;
}
}
}
protected function getLink($page, $lang = '') {
if($lang == '')
$lang = $this->lang;
return $this->myPath . '?lang=' . $lang . '&page=' . urlencode($page);
}
}
$opds = new OPDS($infos, $i18n, $myPath);
$opds->run();
views/feed.php
[modifier]<?php
if($data['pages'] == array()) {
header('Content-Type: application/atom+xml;profile=opds-catalog;kind=navigation');
} else {
header('Content-Type: application/atom+xml;profile=opds-catalog;kind=acquisition');
}
$totalResults = count($data['pages']);
$updated = date(DATE_ATOM);
$text = <<<EOT
<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="{$this->lang}" xmlns:app="http://www.w3.org/2007/app" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:opds="http://opds-spec.org/2010/catalog" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns="http://www.w3.org/2005/Atom">
<title>{$this->page}</title>
<id>{$this->url}</id>
<updated>{$updated}</updated>
<link type="text/html" title="{$this->i18n[$this->lang]['opds.see-on-wikisource']}" rel="alternate" href="{$this->url}" />
<link type="application/atom+xml" rel="self" href="{$this->getLink($this->id)}"/>
<icon>http://assets2.feedbooks.net/images/favicon.ico?t=1303221755</icon>
<author>
<name>Wikisource</name>
<uri>http://{$this->lang}.wikisource.org</uri>
</author>
<link type="application/atom+xml;profile=opds-catalog;kind=navigation" rel="start" title="{$this->i18n[$this->lang]['opds.mainpage']}" href="{$this->getLink('')}" />
<link type="application/opensearchdescription+xml" rel="search" title="{$this->i18n[$this->lang]['opds.search-on-wikisource']}" href="http://{$this->lang}.wikisource.org/w/opensearch_desc.php" />
<opensearch:totalResults>{$totalResults}</opensearch:totalResults>
<opensearch:itemsPerPage>200</opensearch:itemsPerPage>
<link type="application/atom+xml;profile=opds-catalog;kind=acquisition" rel="next" title="Page Suivante" href="http://www.feedbooks.com/books/top.atom?page=2&range=month" />
EOT;
foreach($data['categories'] as $categorie) {
$title = explode(':', $categorie['title'], 2);
$text .= '<category label="' . $title[1] . '" term="' . sha1($title[1]) . '" />' . "\n";
}
foreach($data['langlinks'] as $langlink) {
$text .= '<link type="application/atom+xml;profile=opds-catalog;kind=acquisition" rel="http://opds-spec.org/facet" title="' . $langlink['lang'] . '" opds:facetGroup="Langue" href="' . $this->getLink($langlink['*'], $langlink['lang']) . '" />' . "\n";
}
foreach($data['subcategories'] as $categorie) {
$url = 'http://' . $this->lang . '.wikisource.org/wiki/' . $categorie['title'];
$title = explode(':', $categorie['title'], 2);
$rel = isset($categorie['rel']) ? 'http://opds-spec.org/sort/' . $categorie['rel'] : 'subsection';
$content = isset($categorie['content']) ? $categorie['content'] : $title[1];
$text .= <<<EOT
<entry>
<title>{$title[1]}</title>
<id>{$url}</id>
<updated>2011-10-26T13:24:34Z</updated>
<dcterms:language>{$this->lang}</dcterms:language>
<summary>{$content}</summary>
<dcterms:source>Wikisource</dcterms:source>
<content type="text">{$title[1]}</content>
<link type="application/atom+xml;profile=opds-catalog" rel="{$rel}" href="{$this->getLink($categorie['title'])}"/>
</entry>
EOT;
}
foreach($data['pages'] as $page) {
$url = 'http://' . $this->lang . '.wikisource.org/wiki/' . $page['title'];
$text .= <<<EOT
<entry>
<title>{$page['title']}</title>
<id>{$url}</id>
<author>
<name>Vatsyayana</name>
<uri>http://www.feedbooks.com/author/91</uri>
</author>
<published>2011-07-08T14:45:05Z</published>
<updated>2011-10-26T13:24:34Z</updated>
<dcterms:language>{$this->lang}</dcterms:language>
<summary>Empty</summary>
<dcterms:source>Wikisource</dcterms:source>
<link type="application/atom+xml;profile=opds-catalog;type=entry" rel="alternate" title="Full entry" href="{$this->getLink($page['title'])}" />
<link type="text/html" title="{$this->i18n[$this->lang]['opds.see-on-wikisource']}" rel="alternate" href="{$url}" />
</entry>
EOT;
}
$text .= '</feed>';
echo $text;
views/page.php
[modifier]<?php
header('Content-type: application/atom+xml;type=entry;profile=opds-catalog');
$text = <<<EOT
<?xml version="1.0" encoding="UTF-8"?>
<entry xml:lang="{$this->lang}" xmlns="http://www.w3.org/2005/Atom" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:thr="http://purl.org/syndication/thread/1.0">
<title>{$this->page}</title>
<id>{$this->url}</id>
<author>
<name>Vatsyayana</name>
<uri>http://www.feedbooks.com/author/91</uri>
</author>
<published>2011-07-08T14:45:05Z</published>
<updated>2011-07-08T14:45:05Z</updated>
<dcterms:language>{$this->lang}</dcterms:language>
EOT;
foreach($data['categories'] as $categorie) {
$title = explode(':', $categorie['title'], 2);
$text .= '<category label="' . $title[1] . '" term="' . sha1($title[1]) . '" />' . "\n";
}
$text .= <<<EOT
<summary>Empty</summary>
<dcterms:source>Wikisource</dcterms:source>
<link type="text/html" title="{$this->i18n[$this->lang]['opds.see-on-wikisource']}" rel="alternate" href="{$this->url}"/>
<link type="application/atom+xml;profile=opds-catalog;kind=acquisition" title="Du même auteur" rel="related" href="http://www.feedbooks.com/author/91/books/top.atom?lang=fr"/>
</entry>
EOT;
echo $text;