tv.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. <?
  2. # Config
  3. $MEDIA_PATH = '/mnt/media';
  4. $TV_PATH = $MEDIA_PATH . '/TV';
  5. $MONITORED_CMD = '/home/profplump/bin/video/torrentMonitored.pl NULL ';
  6. $EXISTS_FILES = array('no_quality_checks', 'more_number_formats', 'skip');
  7. $CONTENT_FILES = array('must_match', 'search_name');
  8. $TVDB_URL = 'http://thetvdb.com/?tab=series';
  9. # True if the input path is junk -- self-links, OS X noise, etc.
  10. function isJunk($path) {
  11. $path = basename($path);
  12. # Ignore certain fixed paths
  13. foreach (array('.', '..', '.DS_Store') as $value) {
  14. if ($path == $value) {
  15. return true;
  16. }
  17. }
  18. # Ignore ._ paths
  19. if (preg_match('/^\.\_/', $path)) {
  20. return true;
  21. }
  22. # Otherwise the path is good
  23. return false;
  24. }
  25. # Find all the monitored series/seasons from the given command
  26. function monitoredShows($cmd) {
  27. $retval = array();
  28. $proc = popen($cmd . ' 2>&1', 'r');
  29. $paths = array();
  30. while (!feof($proc)) {
  31. $str = fread($proc, 4096);
  32. $arr = explode("\0", $str);
  33. $paths = array_merge($paths, $arr);
  34. }
  35. pclose($proc);
  36. # Translates paths to a series/seasons structure
  37. foreach ($paths as $path) {
  38. preg_match('@/([^\/]+)/Season\s+(\d+)@', $path, $matches);
  39. if (!array_key_exists($matches[1], $retval)) {
  40. $retval[ $matches[1] ] = array();
  41. }
  42. $retval[ $matches[1] ][ $matches[2] ] = true;
  43. }
  44. return $retval;
  45. }
  46. # Find all shows under the given path
  47. function allShows($base) {
  48. $retval = array();
  49. # Look for series folders
  50. $tv_dir = opendir($base);
  51. if ($tv_dir === FALSE) {
  52. die('Unable to opendir(): ' . $path . "\n");
  53. }
  54. while (false !== ($show = readdir($tv_dir))) {
  55. # Skip junk
  56. if (isJunk($show)) {
  57. continue;
  58. }
  59. # We only care about directories
  60. $show_path = $base . '/' . $show;
  61. if (!is_dir($show_path)) {
  62. continue;
  63. }
  64. # Record the show title
  65. $retval[ $show ] = array();
  66. # Look for season folders
  67. $show_dir = opendir($show_path);
  68. if ($show_dir === FALSE) {
  69. die('Unable to opendir(): ' . $show_path . "\n");
  70. }
  71. while (false !== ($season = readdir($show_dir))) {
  72. # Skip junk
  73. if (isJunk($show)) {
  74. continue;
  75. }
  76. # We only care about directories
  77. $season_path = $show_path . '/' . $season;
  78. if (!is_dir($season_path)) {
  79. continue;
  80. }
  81. # Record season numbers
  82. if (preg_match('/Season\s+(\d+)/i', $season, $matches)) {
  83. $retval[ $show ][ $matches[1] ] = true;
  84. }
  85. }
  86. closedir($show_dir);
  87. }
  88. closedir($tv_dir);
  89. return $retval;
  90. }
  91. # Print a DL of all shows and note the available and monitored seasons
  92. function printAllShows() {
  93. global $TV_PATH;
  94. global $MEDIA_PATH;
  95. global $MONITORED_CMD;
  96. $shows = allShows($TV_PATH);
  97. $monitored = monitoredShows($MONITORED_CMD . $MEDIA_PATH);
  98. echo "<dl>\n";
  99. foreach ($shows as $show => $seasons) {
  100. echo '<dt><a href="?show=' . urlencode($show) . '">' . htmlspecialchars($show) . "</a></dt>\n";
  101. foreach ($seasons as $season => $val) {
  102. if ($val) {
  103. echo '<dd>Season ' . htmlspecialchars($season);
  104. if ($monitored[ $show ][ $season ]) {
  105. echo ' (monitored)';
  106. }
  107. echo "</dd>\n";
  108. }
  109. }
  110. }
  111. echo "</dl>\n";
  112. }
  113. function printShow($show) {
  114. global $TV_PATH;
  115. global $EXISTS_FILES;
  116. global $CONTENT_FILES;
  117. global $TVDB_URL;
  118. # Construct our show path and make sure it's reasonable
  119. $path = $TV_PATH . '/' . $show;
  120. if (!is_dir($path)) {
  121. die('Unknown show: ' . $show);
  122. }
  123. # Look for all the exists and content files
  124. $flags = array();
  125. foreach ($EXISTS_FILES as $name) {
  126. $flags[ $name ] = false;
  127. if (file_exists($path . '/' . $name)) {
  128. $flags[ $name ] = true;
  129. }
  130. }
  131. foreach ($CONTENT_FILES as $name) {
  132. $flags[ $name ] = false;
  133. $file = $path . '/' . $name;
  134. if (is_readable($file)) {
  135. $flags[ $name ] = trim(file_get_contents($file));
  136. }
  137. }
  138. # Read the TVDB IDs from the *.webloc file
  139. $show_dir = opendir($path);
  140. if ($show_dir === FALSE) {
  141. die('Unable to opendir(): ' . $path . "\n");
  142. }
  143. while (false !== ($name = readdir($show_dir))) {
  144. # Skip junk
  145. if (isJunk($name)) {
  146. continue;
  147. }
  148. # We only care about readable *.webloc files
  149. if (!preg_match('/\.webloc$/', $name)) {
  150. continue;
  151. }
  152. # The file must be readable to be useful
  153. $file = $path . '/' . $name;
  154. if (!is_readable($file)) {
  155. continue;
  156. }
  157. # Read and parse the file
  158. $str = trim(file_get_contents($file));
  159. if (preg_match('/[\?\&]id=(\d+)/', $str, $matches)) {
  160. $flags['tvdb-id'] = $matches[1];
  161. }
  162. if (preg_match('/[\?\&]lid=(\d+)/', $str, $matches)) {
  163. $flags['tvdb-lid'] = $matches[1];
  164. }
  165. # Construct a URL
  166. if (array_key_exists('tvdb-id', $flags)) {
  167. $flags['url'] = $TVDB_URL . '&id=' . $flags['tvdb-id'];
  168. if (array_key_exists('tvdb-lid', $flags)) {
  169. $flags['url'] .= '&lid=' . $flags['tvdb-lid'];
  170. }
  171. }
  172. }
  173. closedir($show_dir);
  174. echo '<pre>';
  175. echo $show . "\n";
  176. print_r($flags);
  177. echo '</pre>';
  178. }
  179. #=========================================================================================
  180. # Send our headers early
  181. header('Content-type: text/html; charset=utf-8');
  182. # Did the user request a specific show?
  183. $show = false;
  184. if (isset($_REQUEST['show'])) {
  185. # This is not a great filter, but it should make the string safe for use as a quoted path
  186. $show = preg_replace('/[\0\n\r]/', '', $_REQUEST['show']);
  187. $show = basename($show);
  188. }
  189. #=========================================================================================
  190. # Generic XHTML 1.1 header
  191. print <<<ENDOLA
  192. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
  193. "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
  194. <html xmlns="http://www.w3.org/1999/xhtml">
  195. <head>
  196. <meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
  197. <title>UberZach TV</title>
  198. </head>
  199. <body>
  200. ENDOLA;
  201. if ($show === false) {
  202. printAllShows();
  203. } else {
  204. printShow($show);
  205. }
  206. # Generic XHTML 1.1 footer
  207. print <<<ENDOLA
  208. </body>
  209. </html>
  210. ENDOLA;
  211. ?>