series.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. <?
  2. require 'config.php';
  3. function seriesExists($series) {
  4. return is_dir(seriesPath($series));
  5. }
  6. function seriesPath($series) {
  7. return TV_PATH . '/' . $series;
  8. }
  9. # Find all series and seasons under a given path
  10. function allSeriesSeasons($base, $use_cache = true) {
  11. global $CACHE_AGE;
  12. global $CACHE_FILE;
  13. $retval = array();
  14. # Look for a cache file (stale or otherwise)
  15. if ($use_cache) {
  16. $stale = false;
  17. $file = $CACHE_FILE;
  18. if (!file_exists($file)) {
  19. $file = staleCacheName($CACHE_FILE);
  20. $stale = true;
  21. }
  22. if (file_exists($file)) {
  23. if (filemtime($file) + $CACHE_AGE < time()) {
  24. $stale = true;
  25. }
  26. $retval = @unserialize(@file_get_contents($file));
  27. }
  28. if (is_array($retval) && count($retval) > 0) {
  29. if ($stale) {
  30. $retval['***Stale data - Click to force a refresh'] = array();
  31. }
  32. return $retval;
  33. }
  34. }
  35. # Read live data from the disk
  36. $all_series = allSeries($base);
  37. foreach ($all_series as $series) {
  38. $retval[ $series ] = findSeasons($series);
  39. }
  40. # Always update the cache if we read from disk
  41. $temp = @tempnam(dirname($CACHE_FILE), 'tv_web.cache');
  42. if ($temp) {
  43. if (dirname($temp) != dirname($CACHE_FILE)) {
  44. unlink($temp);
  45. $temp = false;
  46. }
  47. }
  48. if ($temp) {
  49. file_put_contents($temp, serialize($retval));
  50. rename($temp, $CACHE_FILE);
  51. }
  52. return $retval;
  53. }
  54. # Find all series under the given path
  55. function allSeries($base) {
  56. $retval = array();
  57. # Look for series folders
  58. $tv_dir = opendir($base);
  59. if ($tv_dir === FALSE) {
  60. die('Unable to opendir(): ' . htmlspecialchars($path) . "\n");
  61. }
  62. while (false !== ($series = readdir($tv_dir))) {
  63. # Skip junk
  64. if (isJunk($series)) {
  65. continue;
  66. }
  67. # Ensure the series is reasonable
  68. if (!seriesExists($series)) {
  69. continue;
  70. }
  71. $retval[] = $series;
  72. }
  73. closedir($tv_dir);
  74. return $retval;
  75. }
  76. # Read and parse all of the series-level exists, content, and *.webloc files
  77. function readFlags($series) {
  78. global $EXISTS_FILES;
  79. global $CONTENT_FILES;
  80. $flags = array();
  81. # Ensure the series exists
  82. if (!seriesExists($series)) {
  83. die('Invalid series: ' . htmlspecialchars($series) . "\n");
  84. }
  85. $path = seriesPath($series);
  86. # Find the most recent mtime in the series directory
  87. $flags['mtime'] = filemtime($path);
  88. $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
  89. try {
  90. foreach($objects as $name => $object) {
  91. # Skip junk
  92. if (isJunk($name)) {
  93. continue;
  94. }
  95. # Track the most recent mtime
  96. $mtime = filemtime($name);
  97. if ($mtime > $flags['mtime']) {
  98. $flags['mtime'] = $mtime;
  99. }
  100. }
  101. } catch (UnexpectedValueException $e) {
  102. }
  103. # Look for all the exists files
  104. foreach ($EXISTS_FILES as $name) {
  105. $flags[ $name ] = false;
  106. if (file_exists($path . '/' . $name)) {
  107. $flags[ $name ] = true;
  108. }
  109. }
  110. # Read all the content files
  111. foreach ($CONTENT_FILES as $name) {
  112. $flags[ $name ] = false;
  113. $file = $path . '/' . $name;
  114. if (is_readable($file)) {
  115. $flags[ $name ] = trim(file_get_contents($file));
  116. }
  117. }
  118. # Read the TVDB IDs from the *.webloc file
  119. $webloc = findWebloc($path);
  120. if ($webloc !== false) {
  121. $flags = array_merge($flags, readWebloc($webloc));
  122. }
  123. return $flags;
  124. }
  125. # Parse and save all of the serires-level exists and content files
  126. function saveFlags($series, $data, $series_last, $seasons_last) {
  127. die_if_not_authenticated();
  128. global $EXISTS_FILES;
  129. global $CONTENT_FILES;
  130. # Ensure the series exists
  131. if (!seriesExists($series)) {
  132. die('Invalid series: ' . htmlspecialchars($series) . "\n");
  133. }
  134. $series_path = seriesPath($series);
  135. # Special handling for "skip"
  136. {
  137. $path = $series_path . '/skip';
  138. if ($data['skip']) {
  139. if (!file_exists($path)) {
  140. touch($path);
  141. }
  142. } else {
  143. if (file_exists($path)) {
  144. unlink($path);
  145. }
  146. }
  147. }
  148. # Ignore everything else if we are now or were just in "skip" mode
  149. if ($series_last['skip'] || $data['skip']) {
  150. return;
  151. }
  152. # Exists files
  153. foreach ($EXISTS_FILES as $file) {
  154. $path = $series_path . '/' . $file;
  155. if ($data[ $file ]) {
  156. if (!file_exists($path)) {
  157. touch($path);
  158. }
  159. } else {
  160. if (file_exists($path)) {
  161. unlink($path);
  162. }
  163. }
  164. }
  165. # Content files
  166. foreach ($CONTENT_FILES as $file) {
  167. $path = $series_path . '/' . $file;
  168. $data[ $file ] = trim($data[ $file ]);
  169. if ($data[ $file ]) {
  170. file_put_contents($path, $data[ $file ] . "\n");
  171. } else {
  172. if (file_exists($path)) {
  173. unlink($path);
  174. }
  175. }
  176. }
  177. # Force a cache update
  178. clearCache();
  179. }
  180. # Add a series as identified by TVDB URL or ID
  181. function addSeries($str) {
  182. die_if_not_authenticated();
  183. global $TVDB_LANG_ID;
  184. $id = false;
  185. $lid = false;
  186. $series = false;
  187. # Accept URLs or raw IDs
  188. if (preg_match('/^\d+$/', $str)) {
  189. $id = intval($str);
  190. } else {
  191. $result = parseTVDBURL($str);
  192. $id = $result['tvdb-id'];
  193. $lid = $result['tvdb-lid'];
  194. }
  195. # Ensure we got something useful
  196. if (!$id) {
  197. die('Invalid ID or URL: ' . htmlspecialchars($str) . "\n");
  198. }
  199. if (!$lid) {
  200. $lid = $TVDB_LANG_ID;
  201. }
  202. # Find the show name
  203. $series = getTVDBTitle($id, $lid);
  204. # Ensure the title is reasonable
  205. if (!$series) {
  206. die('No such TVDB series: ' . htmlspecialchars($id) . "\n");
  207. }
  208. # Clean the title for filesystem use
  209. $series = cleanSeries($series);
  210. if (seriesExists($series)) {
  211. die('Series already exists: ' . htmlspecialchars($series) . "\n");
  212. }
  213. # Return the series name or FALSE on failure
  214. $retval = false;
  215. # If all is well, create the folder and webloc file
  216. $series_path = seriesPath($series);
  217. if (@mkdir($series_path)) {
  218. writeWebloc(TVDBURL($id, $lid), $series_path . '/' . $series . '.webloc');
  219. addSeason($series, 1);
  220. $retval = $series;
  221. }
  222. return $retval;
  223. }
  224. ?>