trakt.php 12 KB

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