PageRenderTime 68ms CodeModel.GetById 36ms RepoModel.GetById 0ms app.codeStats 0ms

/www/lib/movie.php

https://github.com/vikjon0/newznab
PHP | 582 lines | 492 code | 78 blank | 12 comment | 136 complexity | b1ba3a17667daa45dfd64c6e6dc9f05e MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php
  2. require_once(WWW_DIR."/lib/framework/db.php");
  3. require_once(WWW_DIR."/lib/TMDb.php");
  4. require_once(WWW_DIR."/lib/category.php");
  5. require_once(WWW_DIR."/lib/nfo.php");
  6. require_once(WWW_DIR."/lib/site.php");
  7. require_once(WWW_DIR."/lib/util.php");
  8. require_once(WWW_DIR."/lib/releaseimage.php");
  9. class Movie
  10. {
  11. function Movie($echooutput=false)
  12. {
  13. $this->echooutput = $echooutput;
  14. $s = new Sites();
  15. $site = $s->get();
  16. $this->apikey = $site->tmdbkey;
  17. $this->imgSavePath = WWW_DIR.'covers/movies/';
  18. }
  19. public function getMovieInfo($imdbId)
  20. {
  21. $db = new DB();
  22. return $db->queryOneRow(sprintf("SELECT * FROM movieinfo where imdbID = %d", $imdbId));
  23. }
  24. public function getRange($start, $num)
  25. {
  26. $db = new DB();
  27. if ($start === false)
  28. $limit = "";
  29. else
  30. $limit = " LIMIT ".$start.",".$num;
  31. return $db->query(" SELECT * FROM movieinfo ORDER BY createddate DESC".$limit);
  32. }
  33. public function getCount()
  34. {
  35. $db = new DB();
  36. $res = $db->queryOneRow("select count(ID) as num from movieinfo");
  37. return $res["num"];
  38. }
  39. public function getMovieCount($cat, $maxage=-1, $excludedcats=array())
  40. {
  41. $db = new DB();
  42. $browseby = $this->getBrowseBy();
  43. $catsrch = "";
  44. if (count($cat) > 0 && $cat[0] != -1)
  45. {
  46. $catsrch = " (";
  47. foreach ($cat as $category)
  48. {
  49. if ($category != -1)
  50. {
  51. $categ = new Category();
  52. if ($categ->isParent($category))
  53. {
  54. $children = $categ->getChildren($category);
  55. $chlist = "-99";
  56. foreach ($children as $child)
  57. $chlist.=", ".$child["ID"];
  58. if ($chlist != "-99")
  59. $catsrch .= " r.categoryID in (".$chlist.") or ";
  60. }
  61. else
  62. {
  63. $catsrch .= sprintf(" r.categoryID = %d or ", $category);
  64. }
  65. }
  66. }
  67. $catsrch.= "1=2 )";
  68. }
  69. if ($maxage > 0)
  70. $maxage = sprintf(" and r.postdate > now() - interval %d day ", $maxage);
  71. else
  72. $maxage = "";
  73. $exccatlist = "";
  74. if (count($excludedcats) > 0)
  75. $exccatlist = " and r.categoryID not in (".implode(",", $excludedcats).")";
  76. $sql = sprintf("select count(distinct r.imdbID) as num from releases r inner join movieinfo m on m.imdbID = r.imdbID and m.title != '' where r.passwordstatus <= (select value from site where setting='showpasswordedrelease') and %s %s %s %s ", $browseby, $catsrch, $maxage, $exccatlist);
  77. $res = $db->queryOneRow($sql);
  78. return $res["num"];
  79. }
  80. public function getMovieRange($cat, $start, $num, $orderby, $maxage=-1, $excludedcats=array())
  81. {
  82. $db = new DB();
  83. $browseby = $this->getBrowseBy();
  84. if ($start === false)
  85. $limit = "";
  86. else
  87. $limit = " LIMIT ".$start.",".$num;
  88. $catsrch = "";
  89. if (count($cat) > 0 && $cat[0] != -1)
  90. {
  91. $catsrch = " (";
  92. foreach ($cat as $category)
  93. {
  94. if ($category != -1)
  95. {
  96. $categ = new Category();
  97. if ($categ->isParent($category))
  98. {
  99. $children = $categ->getChildren($category);
  100. $chlist = "-99";
  101. foreach ($children as $child)
  102. $chlist.=", ".$child["ID"];
  103. if ($chlist != "-99")
  104. $catsrch .= " r.categoryID in (".$chlist.") or ";
  105. }
  106. else
  107. {
  108. $catsrch .= sprintf(" r.categoryID = %d or ", $category);
  109. }
  110. }
  111. }
  112. $catsrch.= "1=2 )";
  113. }
  114. $maxage = "";
  115. if ($maxage > 0)
  116. $maxage = sprintf(" and r.postdate > now() - interval %d day ", $maxage);
  117. $exccatlist = "";
  118. if (count($excludedcats) > 0)
  119. $exccatlist = " and r.categoryID not in (".implode(",", $excludedcats).")";
  120. $order = $this->getMovieOrder($orderby);
  121. $sql = sprintf(" SELECT GROUP_CONCAT(r.ID ORDER BY r.postdate desc SEPARATOR ',') as grp_release_id, GROUP_CONCAT(r.guid ORDER BY r.postdate desc SEPARATOR ',') as grp_release_guid, GROUP_CONCAT(rn.ID ORDER BY r.postdate desc SEPARATOR ',') as grp_release_nfoID, GROUP_CONCAT(groups.name ORDER BY r.postdate desc SEPARATOR ',') as grp_release_grpname, GROUP_CONCAT(r.searchname ORDER BY r.postdate desc SEPARATOR '#') as grp_release_name, GROUP_CONCAT(r.postdate ORDER BY r.postdate desc SEPARATOR ',') as grp_release_postdate, GROUP_CONCAT(r.size ORDER BY r.postdate desc SEPARATOR ',') as grp_release_size, GROUP_CONCAT(r.totalpart ORDER BY r.postdate desc SEPARATOR ',') as grp_release_totalparts, GROUP_CONCAT(r.comments ORDER BY r.postdate desc SEPARATOR ',') as grp_release_comments, GROUP_CONCAT(r.grabs ORDER BY r.postdate desc SEPARATOR ',') as grp_release_grabs, m.*, groups.name as group_name, rn.ID as nfoID from releases r left outer join groups on groups.ID = r.groupID inner join movieinfo m on m.imdbID = r.imdbID and m.title != '' left outer join releasenfo rn on rn.releaseID = r.ID and rn.nfo is not null where r.passwordstatus <= (select value from site where setting='showpasswordedrelease') and %s %s %s %s group by m.imdbID order by %s %s".$limit, $browseby, $catsrch, $maxage, $exccatlist, $order[0], $order[1]);
  122. return $db->query($sql);
  123. }
  124. public function getMovieOrder($orderby)
  125. {
  126. $order = ($orderby == '') ? 'max(r.postdate)' : $orderby;
  127. $orderArr = explode("_", $order);
  128. switch($orderArr[0]) {
  129. case 'title':
  130. $orderfield = 'm.title';
  131. break;
  132. case 'year':
  133. $orderfield = 'm.year';
  134. break;
  135. case 'rating':
  136. $orderfield = 'm.rating';
  137. break;
  138. case 'posted':
  139. default:
  140. $orderfield = 'max(r.postdate)';
  141. break;
  142. }
  143. $ordersort = (isset($orderArr[1]) && preg_match('/^asc|desc$/i', $orderArr[1])) ? $orderArr[1] : 'desc';
  144. return array($orderfield, $ordersort);
  145. }
  146. public function getMovieOrdering()
  147. {
  148. return array('title_asc', 'title_desc', 'year_asc', 'year_desc', 'rating_asc', 'rating_desc');
  149. }
  150. public function getBrowseByOptions()
  151. {
  152. return array('title', 'director', 'actors', 'genre', 'rating', 'year', 'imdb');
  153. }
  154. public function getBrowseBy()
  155. {
  156. $db = new Db;
  157. $browseby = ' ';
  158. $browsebyArr = $this->getBrowseByOptions();
  159. foreach ($browsebyArr as $bb) {
  160. if (isset($_REQUEST[$bb]) && !empty($_REQUEST[$bb])) {
  161. $bbv = stripslashes($_REQUEST[$bb]);
  162. if ($bb == 'rating') { $bbv .= '.'; }
  163. if ($bb == 'imdb') {
  164. $browseby .= "m.{$bb}ID = $bbv AND ";
  165. } else {
  166. $browseby .= "m.$bb LIKE(".$db->escapeString('%'.$bbv.'%').") AND ";
  167. }
  168. }
  169. }
  170. return $browseby;
  171. }
  172. public function makeFieldLinks($data, $field)
  173. {
  174. if ($data[$field] == "")
  175. return "";
  176. $tmpArr = explode(', ',$data[$field]);
  177. $newArr = array();
  178. $i = 0;
  179. foreach($tmpArr as $ta) {
  180. if ($i > 5) { break; } //only use first 6
  181. $newArr[] = '<a href="'.WWW_TOP.'/movies?'.$field.'='.urlencode($ta).'" title="'.$ta.'">'.$ta.'</a>';
  182. $i++;
  183. }
  184. return implode(', ', $newArr);
  185. }
  186. public function update($id, $title, $tagline, $plot, $year, $rating, $genre, $director, $actors, $language, $cover, $backdrop)
  187. {
  188. $db = new DB();
  189. $db->query(sprintf("UPDATE movieinfo SET title=%s, tagline=%s, plot=%s, year=%s, rating=%s, genre=%s, director=%s, actors=%s, language=%s, cover=%d, backdrop=%d, updateddate=NOW() WHERE imdbID = %d",
  190. $db->escapeString($title), $db->escapeString($tagline), $db->escapeString($plot), $db->escapeString($year), $db->escapeString($rating), $db->escapeString($genre), $db->escapeString($director), $db->escapeString($actors), $db->escapeString($language), $cover, $backdrop, $id));
  191. }
  192. public function updateMovieInfo($imdbId)
  193. {
  194. $ri = new ReleaseImage();
  195. if ($this->echooutput)
  196. echo "fetching imdb info from tmdb - ".$imdbId."\n";
  197. //check themoviedb for imdb info
  198. $tmdb = $this->fetchTmdbProperties($imdbId);
  199. if (!$tmdb)
  200. {
  201. if ($this->echooutput)
  202. echo "not found in tmdb\n";
  203. }
  204. //check imdb for movie info
  205. $imdb = $this->fetchImdbProperties($imdbId);
  206. if (!$imdb)
  207. {
  208. if ($this->echooutput)
  209. echo "unable to get movie info from imdb - ".$imdbId."\n";
  210. }
  211. if (!$imdb && !$tmdb) {
  212. return false;
  213. }
  214. $mov = array();
  215. $mov['imdb_id'] = $imdbId;
  216. $mov['tmdb_id'] = (!isset($tmdb['tmdb_id']) || $tmdb['tmdb_id'] == '') ? "NULL" : $tmdb['tmdb_id'];
  217. //prefer tmdb cover over imdb cover
  218. $mov['cover'] = 0;
  219. if (isset($tmdb['cover']) && $tmdb['cover'] != '') {
  220. $mov['cover'] = $ri->saveImage($imdbId.'-cover', $tmdb['cover'], $this->imgSavePath);
  221. } elseif (isset($imdb['cover']) && $imdb['cover'] != '') {
  222. $mov['cover'] = $ri->saveImage($imdbId.'-cover', $imdb['cover'], $this->imgSavePath);
  223. }
  224. $mov['backdrop'] = 0;
  225. if (isset($tmdb['backdrop']) && $tmdb['backdrop'] != '') {
  226. $mov['backdrop'] = $ri->saveImage($imdbId.'-backdrop', $tmdb['backdrop'], $this->imgSavePath, 1024, 768);
  227. }
  228. $mov['title'] = '';
  229. if (isset($imdb['title']) && $imdb['title'] != '') {
  230. $mov['title'] = $imdb['title'];
  231. } elseif (isset($tmdb['title']) && $tmdb['title'] != '') {
  232. $mov['title'] = $tmdb['title'];
  233. }
  234. $mov['title'] = html_entity_decode($mov['title'], ENT_QUOTES, 'UTF-8');
  235. $mov['rating'] = '';
  236. if (isset($imdb['rating']) && $imdb['rating'] != '') {
  237. $mov['rating'] = $imdb['rating'];
  238. } elseif (isset($tmdb['rating']) && $tmdb['rating'] != '') {
  239. $mov['rating'] = $tmdb['rating'];
  240. }
  241. $mov['tagline'] = '';
  242. if (isset($imdb['tagline']) && $imdb['tagline'] != '') {
  243. $mov['tagline'] = html_entity_decode($imdb['tagline'], ENT_QUOTES, 'UTF-8');
  244. }
  245. $mov['plot'] = '';
  246. if (isset($imdb['plot']) && $imdb['plot'] != '') {
  247. $mov['plot'] = $imdb['plot'];
  248. } elseif (isset($tmdb['plot']) && $tmdb['plot'] != '') {
  249. $mov['plot'] = $tmdb['plot'];
  250. }
  251. $mov['plot'] = html_entity_decode($mov['plot'], ENT_QUOTES, 'UTF-8');
  252. $mov['year'] = '';
  253. if (isset($imdb['year']) && $imdb['year'] != '') {
  254. $mov['year'] = $imdb['year'];
  255. } elseif (isset($tmdb['year']) && $tmdb['year'] != '') {
  256. $mov['year'] = $tmdb['year'];
  257. }
  258. $mov['genre'] = '';
  259. if (isset($tmdb['genre']) && $tmdb['genre'] != '') {
  260. $mov['genre'] = $tmdb['genre'];
  261. } elseif (isset($imdb['genre']) && $imdb['genre'] != '') {
  262. $mov['genre'] = $imdb['genre'];
  263. }
  264. if (is_array($mov['genre'])) {
  265. $mov['genre'] = implode(', ', array_unique($mov['genre']));
  266. }
  267. $mov['genre'] = html_entity_decode($mov['genre'], ENT_QUOTES, 'UTF-8');
  268. $mov['director'] = '';
  269. if (isset($imdb['director']) && $imdb['director'] != '') {
  270. $mov['director'] = (is_array($imdb['director'])) ? implode(', ', array_unique($imdb['director'])) : $imdb['director'];
  271. }
  272. $mov['director'] = html_entity_decode($mov['director'], ENT_QUOTES, 'UTF-8');
  273. $mov['actors'] = '';
  274. if (isset($imdb['actors']) && $imdb['actors'] != '') {
  275. $mov['actors'] = (is_array($imdb['actors'])) ? implode(', ', array_unique($imdb['actors'])) : $imdb['actors'];
  276. }
  277. $mov['actors'] = html_entity_decode($mov['actors'], ENT_QUOTES, 'UTF-8');
  278. $mov['language'] = '';
  279. if (isset($imdb['language']) && $imdb['language'] != '') {
  280. $mov['language'] = (is_array($imdb['language'])) ? implode(', ', array_unique($imdb['language'])) : $imdb['language'];
  281. }
  282. $mov['language'] = html_entity_decode($mov['language'], ENT_QUOTES, 'UTF-8');
  283. $db = new DB();
  284. $query = sprintf("
  285. INSERT INTO movieinfo
  286. (imdbID, tmdbID, title, rating, tagline, plot, year, genre, director, actors, language, cover, backdrop, createddate, updateddate)
  287. VALUES
  288. (%d, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %d, %d, NOW(), NOW())
  289. ON DUPLICATE KEY UPDATE
  290. imdbID=%d, tmdbID=%s, title=%s, rating=%s, tagline=%s, plot=%s, year=%s, genre=%s, director=%s, actors=%s, language=%s, cover=%d, backdrop=%d, updateddate=NOW()",
  291. $mov['imdb_id'], $mov['tmdb_id'], $db->escapeString($mov['title']), $db->escapeString($mov['rating']), $db->escapeString($mov['tagline']), $db->escapeString($mov['plot']), $db->escapeString($mov['year']), $db->escapeString($mov['genre']), $db->escapeString($mov['director']), $db->escapeString($mov['actors']), $db->escapeString($mov['language']), $mov['cover'], $mov['backdrop'],
  292. $mov['imdb_id'], $mov['tmdb_id'], $db->escapeString($mov['title']), $db->escapeString($mov['rating']), $db->escapeString($mov['tagline']), $db->escapeString($mov['plot']), $db->escapeString($mov['year']), $db->escapeString($mov['genre']), $db->escapeString($mov['director']), $db->escapeString($mov['actors']), $db->escapeString($mov['language']), $mov['cover'], $mov['backdrop']);
  293. $movieId = $db->queryInsert($query);
  294. if ($movieId) {
  295. if ($this->echooutput)
  296. echo "added/updated movie: ".$mov['title']." (".$mov['year'].") - ".$mov['imdb_id']."\n";
  297. } else {
  298. if ($this->echooutput)
  299. echo "nothing to update for movie: ".$mov['title']." (".$mov['year'].") - ".$mov['imdb_id']."\n";
  300. }
  301. return $movieId;
  302. }
  303. public function fetchTmdbProperties($imdbId)
  304. {
  305. $tmdb = new TMDb($this->apikey);
  306. $lookupId = 'tt'.$imdbId;
  307. $tmdbLookup = json_decode($tmdb->getMovie($lookupId, TMDb::IMDB));
  308. if (!$tmdbLookup) { return false; }
  309. $movie = array_shift($tmdbLookup);
  310. if ($movie == 'Nothing found.') { return false; }
  311. $ret = array();
  312. $ret['title'] = $movie->name;
  313. $ret['tmdb_id'] = $movie->id;
  314. $ret['imdb_id'] = $imdbId;
  315. $ret['rating'] = ($movie->rating == 0) ? '' : $movie->rating;
  316. $ret['plot'] = $movie->overview;
  317. $ret['year'] = date("Y", strtotime($movie->released));
  318. if (isset($movie->genres) && sizeof($movie->genres) > 0)
  319. {
  320. $genres = array();
  321. foreach($movie->genres as $genre)
  322. {
  323. $genres[] = $genre->name;
  324. }
  325. $ret['genre'] = $genres;
  326. }
  327. if (isset($movie->posters) && sizeof($movie->posters) > 0)
  328. {
  329. foreach($movie->posters as $poster)
  330. {
  331. if ($poster->image->size == 'cover')
  332. {
  333. $ret['cover'] = $poster->image->url;
  334. break;
  335. }
  336. }
  337. }
  338. if (isset($movie->backdrops) && sizeof($movie->backdrops) > 0)
  339. {
  340. foreach($movie->backdrops as $backdrop)
  341. {
  342. if ($backdrop->image->size == 'original')
  343. {
  344. $ret['backdrop'] = $backdrop->image->url;
  345. break;
  346. }
  347. }
  348. }
  349. return $ret;
  350. }
  351. public function fetchImdbProperties($imdbId)
  352. {
  353. $imdb_regex = array(
  354. 'title' => '/<meta property="og:title" content="(.*?) \(/iS',
  355. 'tagline' => '/taglines:<\/h4>\s([^<]+)/iS',
  356. 'plot' => '/<p>\s<p.*?>\s?(.*?)\s?<\/p>\s<\/p>/iS',
  357. 'rating' => '/<span.*?ratingValue">([0-9]{1,2}\.[0-9]{1,2})<\/span>/iS',
  358. 'year' => '/<title>.*?\(.*?(\d{4}).*?<\/title>/iS',
  359. 'cover' => '/<a.*?href="\/media\/.*?><img src="(.*?)"/iS'
  360. );
  361. $imdb_regex_multi = array(
  362. 'genre' => '/href="\/genre\/(.*?)"/iS',
  363. 'language' => '/<a href="\/language\/[a-z]+".*?>(.*?)<\/a>/iS'
  364. );
  365. $buffer = getUrl("http://www.imdb.com/title/tt$imdbId/");
  366. // make sure we got some data
  367. if ($buffer !== false && strlen($buffer))
  368. {
  369. $ret = array();
  370. foreach ($imdb_regex as $field => $regex)
  371. {
  372. if (preg_match($regex, $buffer, $matches))
  373. {
  374. $match = $matches[1];
  375. $match = strip_tags(trim(rtrim(addslashes($match))));
  376. $ret[$field] = $match;
  377. }
  378. }
  379. foreach ($imdb_regex_multi as $field => $regex)
  380. {
  381. if (preg_match_all($regex, $buffer, $matches))
  382. {
  383. $match = $matches[1];
  384. $match = array_map("trim", $match);
  385. $ret[$field] = $match;
  386. }
  387. }
  388. //actors
  389. if (preg_match('/<table class="cast_list">(.+)<\/table>/is', $buffer, $hit))
  390. {
  391. if (preg_match_all('/<td class="name">.*?<a.*?href="\/name\/(nm\d{1,8})\/".*?>([^<]+)<\/a>/is', $hit[0], $results, PREG_PATTERN_ORDER))
  392. {
  393. $ret['actors'] = $results[2];
  394. }
  395. }
  396. //directors
  397. if (preg_match('/Directors?:[\s]+?<\/h4>(.+)<\/div>/sU', $buffer, $hit))
  398. {
  399. if (preg_match_all('/<a.*?>(.*?)<\/a>/is', $hit[0], $results, PREG_PATTERN_ORDER))
  400. {
  401. $ret['director'] = $results[1];
  402. }
  403. }
  404. return $ret;
  405. }
  406. return false;
  407. }
  408. public function processMovieReleases()
  409. {
  410. $ret = 0;
  411. $db = new DB();
  412. $nfo = new Nfo;
  413. $res = $db->queryDirect(sprintf("SELECT searchname, ID from releases where imdbID IS NULL and categoryID in ( select ID from category where parentID = %d )", Category::CAT_PARENT_MOVIE));
  414. if (mysql_num_rows($res) > 0)
  415. {
  416. if ($this->echooutput)
  417. echo "Processing ".mysql_num_rows($res)." movie releases\n";
  418. while ($arr = mysql_fetch_assoc($res))
  419. {
  420. $moviename = $this->parseMovieName($arr['searchname']);
  421. if ($moviename !== false)
  422. {
  423. if ($this->echooutput)
  424. echo 'Looking up: '.$moviename.' ['.$arr['searchname'].']'."\n";
  425. $buffer = getUrl("http://www.google.com/search?source=ig&hl=en&rlz=&btnG=Google+Search&aq=f&oq=&q=".urlencode($moviename.' imdb'));
  426. // make sure we got some data
  427. if ($buffer !== false && strlen($buffer))
  428. {
  429. $imdbId = $nfo->parseImdb($buffer);
  430. if ($imdbId !== false)
  431. {
  432. if ($this->echooutput)
  433. echo '- found '.$imdbId."\n";
  434. //update release with imdb id
  435. $db->query(sprintf("UPDATE releases SET imdbID = %s WHERE ID = %d", $db->escapeString($imdbId), $arr["ID"]));
  436. //check for existing movie entry
  437. $movCheck = $this->getMovieInfo($imdbId);
  438. if ($movCheck === false || (isset($movCheck['updateddate']) && (time() - strtotime($movCheck['updateddate'])) > 2592000))
  439. {
  440. $movieId = $this->updateMovieInfo($imdbId);
  441. }
  442. } else {
  443. //no imdb id found, set to all zeros so we dont process again
  444. $db->query(sprintf("UPDATE releases SET imdbID = %d WHERE ID = %d", 0, $arr["ID"]));
  445. }
  446. } else {
  447. //url fetch failed, will try next run
  448. }
  449. } else {
  450. //no valid movie name found, set to all zeros so we dont process again
  451. $db->query(sprintf("UPDATE releases SET imdbID = %d WHERE ID = %d", 0, $arr["ID"]));
  452. }
  453. }
  454. }
  455. }
  456. public function parseMovieName($releasename)
  457. {
  458. $cat = new Category;
  459. if (!$cat->isMovieForeign($releasename)) {
  460. preg_match('/^(?P<name>.*)[\.\-_\( ](?P<year>19\d{2}|20\d{2})/i', $releasename, $matches);
  461. if (!isset($matches['year'])) {
  462. preg_match('/^(?P<name>.*)[\.\-_ ](?:dvdrip|bdrip|brrip|bluray|hdtv|divx|xvid|proper|repack|real\.proper|sub\.?fix|sub\.?pack|ac3d|unrated|1080i|1080p|720p)/i', $releasename, $matches);
  463. }
  464. if (isset($matches['name'])) {
  465. $name = preg_replace('/\(.*?\)|\.|_/i', ' ', $matches['name']);
  466. $year = (isset($matches['year'])) ? ' ('.$matches['year'].')' : '';
  467. return trim($name).$year;
  468. }
  469. }
  470. return false;
  471. }
  472. public function getGenres()
  473. {
  474. return array(
  475. 'Action',
  476. 'Adventure',
  477. 'Animation',
  478. 'Biography',
  479. 'Comedy',
  480. 'Crime',
  481. 'Documentary',
  482. 'Drama',
  483. 'Family',
  484. 'Fantasy',
  485. 'Film-Noir',
  486. 'Game-Show',
  487. 'History',
  488. 'Horror',
  489. 'Music',
  490. 'Musical',
  491. 'Mystery',
  492. 'News',
  493. 'Reality-TV',
  494. 'Romance',
  495. 'Sci-Fi',
  496. 'Sport',
  497. 'Talk-Show',
  498. 'Thriller',
  499. 'War',
  500. 'Western'
  501. );
  502. }
  503. }
  504. ?>