MangareaderBridge.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <?php
  2. define('MANGAREADER_LIMIT', 10); // The default limit
  3. class MangareaderBridge extends BridgeAbstract{
  4. public function loadMetadatas() {
  5. $this->maintainer = "logmanoriginal";
  6. $this->name = "Mangareader Bridge";
  7. $this->uri = "http://www.mangareader.net";
  8. $this->description = "Returns the latest updates, popular mangas or manga updates (new chapters)";
  9. $this->parameters["Get latest updates"] = array();
  10. $this->parameters["Get popular mangas"] = array(
  11. 'category'=>array(
  12. 'name'=>'Category',
  13. 'type'=>'list',
  14. 'required'=>true,
  15. 'values'=>array(
  16. 'All'=>'all',
  17. 'Action'=>'action',
  18. 'Adventure'=>'adventure',
  19. 'Comedy'=>'comedy',
  20. 'Demons'=>'demons',
  21. 'Drama'=>'drama',
  22. 'Ecchi'=>'ecchi',
  23. 'Fantasy'=>'fantasy',
  24. 'Gender Bender'=>'gender-bender',
  25. 'Harem'=>'harem',
  26. 'Historical'=>'historical',
  27. 'Horror'=>'horror',
  28. 'Josei'=>'josei',
  29. 'Magic'=>'magic',
  30. 'Martial Arts'=>'martial-arts',
  31. 'Mature'=>'mature',
  32. 'Mecha'=>'mecha',
  33. 'Military'=>'military',
  34. 'Mystery'=>'mystery',
  35. 'One Shot'=>'one-shot',
  36. 'Psychological'=>'psychological',
  37. 'Romance'=>'romance',
  38. 'School Life'=>'school-life',
  39. 'Sci-Fi'=>'sci-fi',
  40. 'Seinen'=>'seinen',
  41. 'Shoujo'=>'shoujo',
  42. 'Shoujoai'=>'shoujoai',
  43. 'Shounen'=>'shounen',
  44. 'Shounenai'=>'shounenai',
  45. 'Slice of Life'=>'slice-of-life',
  46. 'Smut'=>'smut',
  47. 'Sports'=>'sports',
  48. 'Super Power'=>'super-power',
  49. 'Supernatural'=>'supernatural',
  50. 'Tragedy'=>'tragedy',
  51. 'Vampire'=>'vampire',
  52. 'Yaoi'=>'yaoi',
  53. 'Yuri'=>'yuri'
  54. ),
  55. 'exampleValue'=>'All',
  56. 'title'=>'Select your category'
  57. )
  58. );
  59. $this->parameters["Get manga updates"] = array(
  60. 'path'=>array(
  61. 'name'=>'Path',
  62. 'required'=>true,
  63. 'pattern'=>'[a-zA-Z0-9-_]*',
  64. 'exampleValue'=>'bleach, umi-no-kishidan',
  65. 'title'=>'URL part of desired manga'
  66. ),
  67. 'limit'=>array(
  68. 'name'=>'Limit',
  69. 'type'=>'number',
  70. 'exampleValue'=>10,
  71. 'title'=>'Number of items to return [-1 returns all]'
  72. )
  73. );
  74. }
  75. public function collectData(array $param){
  76. $this->request = '';
  77. $type = "latest"; // can be "latest", "popular" or "path". Default is "latest"!
  78. $path = "latest";
  79. $limit = MANGAREADER_LIMIT;
  80. if(isset($param['category'])){ // Get popular updates
  81. $type = "popular";
  82. $path = "popular";
  83. if($param['category'] !== "all"){
  84. $path .= "/" . $param['category'];
  85. }
  86. }
  87. if(isset($param['path'])){ // Get manga updates
  88. $type = "path";
  89. $path = $param['path'];
  90. }
  91. if(isset($param['limit']) && $param['limit'] !== ""){ // Get manga updates (optional parameter)
  92. $limit = $param['limit'];
  93. }
  94. // We'll use the DOM parser for this as it makes navigation easier
  95. $html = $this->getContents("http://www.mangareader.net/" . $path);
  96. if(!$html){
  97. $this->returnClientError('Could not receive data for ' . $path . '!');
  98. }
  99. $doc = new DomDocument;
  100. @$doc->loadHTML($html);
  101. // Navigate via XPath
  102. $xpath = new DomXPath($doc);
  103. // Build feed based on the context (site updates or manga updates)
  104. if($type === "latest"){
  105. $this->request = 'Latest updates';
  106. // Query each item (consists of Manga + chapters)
  107. $nodes = $xpath->query("//*[@id='latestchapters']/table//td");
  108. foreach ($nodes as $node){
  109. // Query the manga
  110. $manga = $xpath->query("a[@class='chapter']", $node)->item(0);
  111. // Collect the chapters for each Manga
  112. $chapters = $xpath->query("a[@class='chaptersrec']", $node);
  113. if (isset($manga) && $chapters->length >= 1){
  114. $item = array();
  115. $item['uri'] = 'http://www.mangareader.net' . htmlspecialchars($manga->getAttribute('href'));
  116. $item['title'] = htmlspecialchars($manga->nodeValue);
  117. // Add each chapter to the feed
  118. $item['content'] = "";
  119. foreach ($chapters as $chapter){
  120. if($item['content'] <> ""){
  121. $item['content'] .= "<br>";
  122. }
  123. $item['content'] .= "<a href='http://www.mangareader.net" . htmlspecialchars($chapter->getAttribute('href')) . "'>" . htmlspecialchars($chapter->nodeValue) . "</a>";
  124. }
  125. $this->items[] = $item;
  126. }
  127. }
  128. }
  129. if($type === "popular"){
  130. $pagetitle = $xpath->query(".//*[@id='bodyalt']/h1")->item(0)->nodeValue;
  131. $this->request = substr($pagetitle, 0, strrpos($pagetitle, " -")); // "Popular mangas for ..."
  132. // Query all mangas
  133. $mangas = $xpath->query("//*[@id='mangaresults']/*[@class='mangaresultitem']");
  134. foreach ($mangas as $manga){
  135. // The thumbnail is encrypted in a css-style...
  136. // format: "background-image:url('<the part which is actually interesting>')"
  137. $mangaimgelement = $xpath->query(".//*[@class='imgsearchresults']", $manga)->item(0)->getAttribute('style');
  138. $thumbnail = substr($mangaimgelement, 22, strlen($mangaimgelement) - 24);
  139. $item = array();
  140. $item['title'] = htmlspecialchars($xpath->query(".//*[@class='manga_name']//a", $manga)->item(0)->nodeValue);
  141. $item['uri'] = 'http://www.mangareader.net' . $xpath->query(".//*[@class='manga_name']//a", $manga)->item(0)->getAttribute('href');
  142. $item['author'] = htmlspecialchars($xpath->query("//*[@class='author_name']", $manga)->item(0)->nodeValue);
  143. $item['chaptercount'] = $xpath->query(".//*[@class='chapter_count']", $manga)->item(0)->nodeValue;
  144. $item['genre'] = htmlspecialchars($xpath->query(".//*[@class='manga_genre']", $manga)->item(0)->nodeValue);
  145. $item['content'] = '<a href="' . $item['uri'] . '"><img src="' . $thumbnail . '" alt="' . $item['title'] . '" /></a><p>' . $item['genre'] . '</p><p>' . $item['chaptercount'] . '</p>';
  146. $this->items[] = $item;
  147. }
  148. }
  149. if($type === "path") {
  150. $this->request = $xpath->query(".//*[@id='mangaproperties']//*[@class='aname']")->item(0)->nodeValue;
  151. $query = "(.//*[@id='listing']//tr)[position() > 1]";
  152. if($limit !== -1){
  153. $query = "(.//*[@id='listing']//tr)[position() > 1][position() > last() - " . $limit . "]";
  154. }
  155. $chapters = $xpath->query($query);
  156. foreach ($chapters as $chapter){
  157. $item = array();
  158. $item['title'] = htmlspecialchars($xpath->query("td[1]", $chapter)->item(0)->nodeValue);
  159. $item['uri'] = 'http://www.mangareader.net' . $xpath->query("td[1]/a", $chapter)->item(0)->getAttribute('href');
  160. $item['timestamp'] = strtotime($xpath->query("td[2]", $chapter)->item(0)->nodeValue);
  161. array_unshift($this->items, $item);
  162. }
  163. }
  164. // Return some dummy-data if no content available
  165. if(count($this->items) == 0){
  166. $item = array();
  167. $item['content'] = "<p>No updates available</p>";
  168. $this->items[] = $item;
  169. }
  170. }
  171. public function getName(){
  172. return (!empty($this->request) ? $this->request . ' - ' : '') . 'Mangareader Bridge';
  173. }
  174. public function getCacheDuration(){
  175. return 10800; // 3 hours
  176. }
  177. }
  178. ?>