trakt.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. <?php
  2. trait TraktHomepageItem
  3. {
  4. public function traktSettingsArray($infoOnly = false)
  5. {
  6. $homepageInformation = [
  7. 'name' => 'Trakt',
  8. 'enabled' => strpos('personal', $this->config['license']) !== false,
  9. 'image' => 'plugins/images/tabs/trakt.png',
  10. 'category' => 'Calendar',
  11. 'settingsArray' => __FUNCTION__
  12. ];
  13. if ($infoOnly) {
  14. return $homepageInformation;
  15. }
  16. $homepageSettings = array(
  17. 'docs' => 'https://docs.organizr.app/books/setup-features/page/trakt',
  18. 'settings' => array(
  19. 'About' => array(
  20. array(
  21. 'type' => 'html',
  22. 'override' => 12,
  23. 'label' => '',
  24. 'html' => '
  25. <div class="panel panel-default">
  26. <div class="panel-wrapper collapse in">
  27. <div class="panel-body">
  28. <h3 lang="en">Trakt Homepage Item</h3>
  29. <p lang="en">This homepage item enables the calendar on the homepage and displays your movies and/or tv shows from Trakt\'s API.</p>
  30. <p lang="en">In order for this item to be setup, you need to goto the following URL to create a new API app.</p>
  31. <p><a href="https://trakt.tv/oauth/applications/new" target="_blank">New API App</a></p>
  32. <p lang="en">Enter anything for Name and Description. You can leave Javascript and Permissions blank. The only info you have to enter is for Redirect URI. Enter the following URL:</p>
  33. <code>' . $this->getServerPath() . 'api/v2/oauth/trakt</code>
  34. </div>
  35. </div>
  36. </div>'
  37. ),
  38. ),
  39. 'Enable' => array(
  40. array(
  41. 'type' => 'switch',
  42. 'name' => 'homepageTraktEnabled',
  43. 'label' => 'Enable',
  44. 'value' => $this->config['homepageTraktEnabled']
  45. ),
  46. array(
  47. 'type' => 'select',
  48. 'name' => 'homepageTraktAuth',
  49. 'label' => 'Minimum Authentication',
  50. 'value' => $this->config['homepageTraktAuth'],
  51. 'options' => $this->groupOptions
  52. )
  53. ),
  54. 'Connection' => array(
  55. array(
  56. 'type' => 'input',
  57. 'name' => 'traktClientId',
  58. 'label' => 'Client Id',
  59. 'value' => $this->config['traktClientId'],
  60. 'help' => 'Please make sure to use local IP address and port - You also may use local dns name too.'
  61. ),
  62. array(
  63. 'type' => 'password-alt',
  64. 'name' => 'traktClientSecret',
  65. 'label' => 'Client Secret',
  66. 'value' => $this->config['traktClientSecret']
  67. ),
  68. array(
  69. 'type' => 'blank',
  70. 'label' => 'Please Save before clicking button'
  71. ),
  72. array(
  73. 'type' => 'button',
  74. 'label' => '',
  75. 'icon' => 'fa fa-user',
  76. 'class' => 'pull-right',
  77. 'text' => 'Connect Account',
  78. 'attr' => 'onclick="openOAuth(\'trakt\')"'
  79. ),
  80. ),
  81. 'Calendar' => array(
  82. array(
  83. 'type' => 'number',
  84. 'name' => 'calendarStartTrakt',
  85. 'label' => '# of Days Before',
  86. 'value' => $this->config['calendarStartTrakt'],
  87. 'placeholder' => '',
  88. 'help' => 'Total Days (Adding start and end days) has a maximum of 33 Days from Trakt API'
  89. ),
  90. array(
  91. 'type' => 'number',
  92. 'name' => 'calendarEndTrakt',
  93. 'label' => '# of Days After',
  94. 'value' => $this->config['calendarEndTrakt'],
  95. 'placeholder' => '',
  96. 'help' => 'Total Days (Adding start and end days) has a maximum of 33 Days from Trakt API'
  97. ),
  98. array(
  99. 'type' => 'select',
  100. 'name' => 'calendarFirstDay',
  101. 'label' => 'Start Day',
  102. 'value' => $this->config['calendarFirstDay'],
  103. 'options' => $this->daysOptions()
  104. ),
  105. array(
  106. 'type' => 'select',
  107. 'name' => 'calendarDefault',
  108. 'label' => 'Default View',
  109. 'value' => $this->config['calendarDefault'],
  110. 'options' => $this->calendarDefaultOptions()
  111. ),
  112. array(
  113. 'type' => 'select',
  114. 'name' => 'calendarTimeFormat',
  115. 'label' => 'Time Format',
  116. 'value' => $this->config['calendarTimeFormat'],
  117. 'options' => $this->timeFormatOptions()
  118. ),
  119. array(
  120. 'type' => 'select',
  121. 'name' => 'calendarLocale',
  122. 'label' => 'Locale',
  123. 'value' => $this->config['calendarLocale'],
  124. 'options' => $this->calendarLocaleOptions()
  125. ),
  126. array(
  127. 'type' => 'select',
  128. 'name' => 'calendarLimit',
  129. 'label' => 'Items Per Day',
  130. 'value' => $this->config['calendarLimit'],
  131. 'options' => $this->limitOptions()
  132. ),
  133. array(
  134. 'type' => 'select',
  135. 'name' => 'calendarRefresh',
  136. 'label' => 'Refresh Seconds',
  137. 'value' => $this->config['calendarRefresh'],
  138. 'options' => $this->timeOptions()
  139. )
  140. )
  141. )
  142. );
  143. return array_merge($homepageInformation, $homepageSettings);
  144. }
  145. public function traktHomepagePermissions($key = null)
  146. {
  147. $permissions = [
  148. 'calendar' => [
  149. 'enabled' => [
  150. 'homepageTraktEnabled'
  151. ],
  152. 'auth' => [
  153. 'homepageTraktAuth'
  154. ],
  155. 'not_empty' => [
  156. 'traktClientId',
  157. 'traktAccessToken'
  158. ]
  159. ]
  160. ];
  161. if (array_key_exists($key, $permissions)) {
  162. return $permissions[$key];
  163. } elseif ($key == 'all') {
  164. return $permissions;
  165. } else {
  166. return [];
  167. }
  168. }
  169. public function getTraktCalendar($startDate = null)
  170. {
  171. $startDate = date('Y-m-d', strtotime('-' . $this->config['calendarStartTrakt'] . ' days'));
  172. $calendarItems = array();
  173. $errors = null;
  174. $totalDays = (int)$this->config['calendarStartTrakt'] + (int)$this->config['calendarEndTrakt'];
  175. if (!$this->homepageItemPermissions($this->traktHomepagePermissions('calendar'), true)) {
  176. return false;
  177. }
  178. $headers = [
  179. 'Content-Type' => 'application/json',
  180. 'Authorization' => 'Bearer ' . $this->config['traktAccessToken'],
  181. 'trakt-api-version' => 2,
  182. 'trakt-api-key' => $this->config['traktClientId']
  183. ];
  184. $url = $this->qualifyURL('https://api.trakt.tv/calendars/my/shows/' . $startDate . '/' . $totalDays . '?extended=full');
  185. $options = $this->requestOptions($url, false, $this->config['calendarRefresh']);
  186. try {
  187. $response = Requests::get($url, $headers, $options);
  188. if ($response->success) {
  189. $data = json_decode($response->body, true);
  190. $traktTv = $this->formatTraktCalendarTv($data);
  191. if (!empty($traktTv)) {
  192. $calendarItems = array_merge($calendarItems, $traktTv);
  193. }
  194. }
  195. } catch (Requests_Exception $e) {
  196. $this->writeLog('error', 'Trakt Connect Function - Error: ' . $e->getMessage(), 'SYSTEM');
  197. $this->setAPIResponse('error', $e->getMessage(), 500);
  198. $errors = true;
  199. }
  200. $url = $this->qualifyURL('https://api.trakt.tv/calendars/my/movies/' . $startDate . '/' . $totalDays . '?extended=full');
  201. try {
  202. $response = Requests::get($url, $headers, $options);
  203. if ($response->success) {
  204. $data = json_decode($response->body, true);
  205. $traktMovies = $this->formatTraktCalendarMovies($data);
  206. if (!empty($traktTv)) {
  207. $calendarItems = array_merge($calendarItems, $traktMovies);
  208. }
  209. }
  210. } catch (Requests_Exception $e) {
  211. $this->writeLog('error', 'Trakt Connect Function - Error: ' . $e->getMessage(), 'SYSTEM');
  212. $this->setAPIResponse('error', $e->getMessage(), 500);
  213. $errors = true;
  214. }
  215. if ($errors) {
  216. $this->setAPIResponse('error', 'An error Occurred', 500, null);
  217. return false;
  218. }
  219. $this->setAPIResponse('success', null, 200, $calendarItems);
  220. $this->traktOAuthRefresh();
  221. return $calendarItems;
  222. }
  223. public function formatTraktCalendarTv($array)
  224. {
  225. $gotCalendar = array();
  226. $i = 0;
  227. foreach ($array as $child) {
  228. $i++;
  229. $seriesName = $child['show']['title'];
  230. $seriesID = $child['show']['ids']['tmdb'];
  231. $episodeID = $child['show']['ids']['tmdb'];
  232. if (!isset($episodeID)) {
  233. $episodeID = "";
  234. }
  235. //$episodeName = htmlentities($child['title'], ENT_QUOTES);
  236. $episodeAirDate = $child['first_aired'];
  237. $episodeAirDate = strtotime($episodeAirDate);
  238. $episodeAirDate = date("Y-m-d H:i:s", $episodeAirDate);
  239. if (new DateTime() < new DateTime($episodeAirDate)) {
  240. $unaired = true;
  241. }
  242. if ($child['episode']['number'] == 1) {
  243. $episodePremier = "true";
  244. } else {
  245. $episodePremier = "false";
  246. $date = new DateTime($episodeAirDate);
  247. $date->add(new DateInterval("PT1S"));
  248. $date->format(DateTime::ATOM);
  249. $child['first_aired'] = gmdate('Y-m-d\TH:i:s\Z', strtotime($date->format(DateTime::ATOM)));
  250. }
  251. $downloaded = 0;
  252. $monitored = 0;
  253. if ($downloaded == "0" && isset($unaired) && $episodePremier == "true") {
  254. $downloaded = "text-primary animated flash";
  255. } elseif ($downloaded == "0" && isset($unaired) && $monitored == "0") {
  256. $downloaded = "text-dark";
  257. } elseif ($downloaded == "0" && isset($unaired)) {
  258. $downloaded = "text-info";
  259. } elseif ($downloaded == "1") {
  260. $downloaded = "text-success";
  261. } else {
  262. $downloaded = "text-danger";
  263. }
  264. $fanart = "/plugins/images/cache/no-np.png";
  265. $bottomTitle = 'S' . sprintf("%02d", $child['episode']['season']) . 'E' . sprintf("%02d", $child['episode']['number']) . ' - ' . $child['episode']['title'];
  266. $details = array(
  267. "seasonCount" => $child['episode']['season'],
  268. "status" => 'dunno',
  269. "topTitle" => $seriesName,
  270. "bottomTitle" => $bottomTitle,
  271. "overview" => isset($child['episode']['overview']) ? $child['episode']['overview'] : '',
  272. "runtime" => isset($child['episode']['runtime']) ? $child['episode']['runtime'] : '',
  273. "image" => $fanart,
  274. "ratings" => isset($child['show']['rating']) ? $child['show']['rating'] : '',
  275. "videoQuality" => "unknown",
  276. "audioChannels" => "unknown",
  277. "audioCodec" => "unknown",
  278. "videoCodec" => "unknown",
  279. "size" => "unknown",
  280. "genres" => isset($child['show']['genres']) ? $child['show']['genres'] : '',
  281. );
  282. array_push($gotCalendar, array(
  283. "id" => "Trakt-Tv-" . $i,
  284. "title" => $seriesName,
  285. "start" => $child['first_aired'],
  286. "className" => "inline-popups bg-calendar calendar-item get-tmdb-image tmdb-tv tmdbID--" . $seriesID,
  287. "imagetype" => "tv " . $downloaded,
  288. "imagetypeFilter" => "tv",
  289. "downloadFilter" => $downloaded,
  290. "bgColor" => str_replace('text', 'bg', $downloaded),
  291. "details" => $details
  292. ));
  293. }
  294. if ($i != 0) {
  295. return $gotCalendar;
  296. }
  297. return false;
  298. }
  299. public function formatTraktCalendarMovies($array)
  300. {
  301. $gotCalendar = array();
  302. $i = 0;
  303. foreach ($array as $child) {
  304. $i++;
  305. $movieName = $child['movie']['title'];
  306. $movieID = $child['movie']['ids']['tmdb'];
  307. if (!isset($movieID)) {
  308. $movieID = '';
  309. }
  310. $physicalRelease = (isset($child['movie']['released']) ? $child['movie']['released'] : null);
  311. //$backupRelease = (isset($child['info']['release_date']['theater']) ? $child['info']['release_date']['theater'] : null);
  312. //$physicalRelease = (isset($physicalRelease) ? $physicalRelease : $backupRelease);
  313. $physicalRelease = strtotime($physicalRelease);
  314. $physicalRelease = date('Y-m-d', $physicalRelease);
  315. $oldestDay = new DateTime ($this->currentTime);
  316. $oldestDay->modify('-' . $this->config['calendarStart'] . ' days');
  317. $newestDay = new DateTime ($this->currentTime);
  318. $newestDay->modify('+' . $this->config['calendarEnd'] . ' days');
  319. $startDt = new DateTime ($physicalRelease);
  320. if (new DateTime() < $startDt) {
  321. $notReleased = 'true';
  322. } else {
  323. $notReleased = 'false';
  324. }
  325. $downloaded = 'text-dark';
  326. $banner = '/plugins/images/cache/no-np.png';
  327. $details = array(
  328. 'topTitle' => $movieName,
  329. 'bottomTitle' => $child['movie']['tagline'],
  330. 'status' => $child['movie']['status'],
  331. 'overview' => $child['movie']['overview'],
  332. 'runtime' => $child['movie']['runtime'],
  333. 'image' => $banner,
  334. 'ratings' => isset($child['movie']['rating']) ? $child['movie']['rating'] : '',
  335. 'videoQuality' => 'unknown',
  336. 'audioChannels' => '',
  337. 'audioCodec' => '',
  338. 'videoCodec' => '',
  339. 'genres' => $child['movie']['genres'],
  340. 'year' => isset($child['movie']['year']) ? $child['movie']['year'] : '',
  341. 'studio' => isset($child['movie']['year']) ? $child['movie']['year'] : '',
  342. );
  343. array_push($gotCalendar, array(
  344. 'id' => 'Trakt-Movie-' . $i,
  345. 'title' => $movieName,
  346. 'start' => $physicalRelease,
  347. 'className' => 'inline-popups bg-calendar calendar-item get-tmdb-image tmdb-movie tmdbID--' . $movieID,
  348. 'imagetype' => 'film ' . $downloaded,
  349. 'imagetypeFilter' => 'film',
  350. 'downloadFilter' => $downloaded,
  351. 'bgColor' => str_replace('text', 'bg', $downloaded),
  352. 'details' => $details
  353. ));
  354. }
  355. if ($i != 0) {
  356. return $gotCalendar;
  357. }
  358. return [];
  359. }
  360. }