AutoPodcasterBridge.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. <?php
  2. class AutoPodcasterBridge extends FeedExpander {
  3. const MAINTAINER='boyska';
  4. const NAME='Auto Podcaster';
  5. const URI = '';
  6. const CACHE_TIMEOUT = 300; // 5 minuti
  7. const DESCRIPTION='Make a "multimedia" podcast out of a normal feed';
  8. const PARAMETERS = array('url' => array(
  9. 'url' => array(
  10. 'name' => 'URL',
  11. 'required' => true
  12. )));
  13. private function archiveIsAudioFormat($formatString) {
  14. return strpos($formatString, 'MP3') !== false ||
  15. strpos($formatString, 'Ogg') === 0;
  16. }
  17. private function extractAudio($dom) {
  18. $audios = [];
  19. foreach($dom->find('audio') as $audioEl) {
  20. $sources = [];
  21. if($audioEl->src !== false) {
  22. $sources[] = $audioEl->src;
  23. }
  24. foreach($audioEl->find('source') as $sourceEl) {
  25. $sources[] = $sourceEl->src;
  26. }
  27. if($sources) {
  28. $audios[$sources[0]] = ['sources' => $sources];
  29. }
  30. }
  31. return $audios;
  32. }
  33. private function extractIframeArchive($dom) {
  34. $audios = [];
  35. foreach($dom->find('iframe') as $iframeEl) {
  36. if(strpos($iframeEl->src, "https://archive.org/embed/") === 0) {
  37. $listURL = preg_replace("/\/embed\//", "/details/", $iframeEl->src, 1) . "?output=json";
  38. $baseURL = preg_replace("/\/embed\//", "/download/", $iframeEl->src, 1);
  39. $list = json_decode(file_get_contents($listURL));
  40. $audios = [];
  41. foreach($list->files as $name =>$data) {
  42. if($data->source === 'original' &&
  43. $this->archiveIsAudioFormat($data->format)) {
  44. $audios[$baseURL . $name] = ['sources' => [$baseURL . $name]];
  45. }
  46. }
  47. foreach($list->files as $name =>$data) {
  48. if($data->source === 'derivative' &&
  49. $this->archiveIsAudioFormat($data->format) &&
  50. isset($audios[$baseURL . "/" . $data->original])) {
  51. $audios[$baseURL . "/" . $data->original]['sources'][] = $baseURL . $name;
  52. }
  53. }
  54. }
  55. }
  56. return $audios;
  57. }
  58. protected function parseItem($newItem){
  59. $item = parent::parseItem($newItem);
  60. $dom = getSimpleHTMLDOMCached($item['uri']);
  61. $audios = [];
  62. if ($dom !== false) {
  63. /* 1st extraction method: by "audio" tag */
  64. $audios = array_merge($audios, $this->extractAudio($dom));
  65. /* 2nd extraction method: by "iframe" tag */
  66. $audios = array_merge($audios, $this->extractIframeArchive($dom));
  67. }
  68. elseif($item['content'] !== NULL) {
  69. /* 1st extraction method: by "audio" tag */
  70. $audios = array_merge($audios, $this->extractAudio(str_get_html($item['content'])));
  71. /* 2nd extraction method: by "iframe" tag */
  72. $audios = array_merge($audios,
  73. $this->extractIframeArchive(str_get_html($item['content'])));
  74. }
  75. if(count($audios) === 0) {
  76. return null;
  77. }
  78. $item['enclosures'] = array_values($audios);
  79. $item['enclosures'] = [];
  80. foreach(array_values($audios) as $audio) {
  81. $item['enclosures'][] = $audio['sources'][0];
  82. }
  83. return $item;
  84. }
  85. public function collectData(){
  86. if($this->getInput('url') && substr($this->getInput('url'), 0, strlen('http')) !== 'http') {
  87. // just in case someone find a way to access local files by playing with the url
  88. returnClientError('The url parameter must either refer to http or https protocol.');
  89. }
  90. $this->collectExpandableDatas($this->getURI());
  91. }
  92. public function getName(){
  93. if(!is_null($this->getInput('url'))) {
  94. return self::NAME . ' : ' . $this->getInput('url');
  95. }
  96. return parent::getName();
  97. }
  98. public function getURI(){
  99. return $this->getInput('url');
  100. }
  101. }