4
0

trakt.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  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 = [
  17. 'docs' => 'https://docs.organizr.app/books/setup-features/page/trakt',
  18. 'debug' => true,
  19. 'settings' => [
  20. 'About' => [
  21. $this->settingsOption('html', null, [
  22. 'override' => 12,
  23. 'html' => '
  24. <div class="panel panel-default">
  25. <div class="panel-wrapper collapse in">
  26. <div class="panel-body">
  27. <h3 lang="en">Trakt Homepage Item</h3>
  28. <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>
  29. <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>
  30. <p><a href="https://trakt.tv/oauth/applications/new" target="_blank">New API App</a></p>
  31. <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>
  32. <code class="elip hidden-xs">' . $this->getServerPath() . 'api/v2/oauth/trakt</code>
  33. </div>
  34. </div>
  35. </div>'
  36. ]),
  37. ],
  38. 'Enable' => [
  39. $this->settingsOption('enable', 'homepageTraktEnabled'),
  40. $this->settingsOption('auth', 'homepageTraktAuth'),
  41. ],
  42. 'Connection' => [
  43. $this->settingsOption('input', 'traktClientId', ['label' => 'Client Id']),
  44. $this->settingsOption('password-alt', 'traktClientSecret', ['label' => 'Client Secret']),
  45. $this->settingsOption('blank'),
  46. $this->settingsOption('button', '', ['label' => 'Please Save before clicking button', 'icon' => 'fa fa-user', 'class' => 'pull-right', 'text' => 'Connect Account', 'attr' => 'onclick="openOAuth(\'trakt\')"']),
  47. ],
  48. 'Calendar' => [
  49. $this->settingsOption('calendar-start', 'calendarStartTrakt', ['help' => 'Total Days (Adding start and end days) has a maximum of 33 Days from Trakt API']),
  50. $this->settingsOption('calendar-end', 'calendarEndTrakt', ['help' => 'Total Days (Adding start and end days) has a maximum of 33 Days from Trakt API']),
  51. $this->settingsOption('calendar-starting-day', 'calendarFirstDay'),
  52. $this->settingsOption('calendar-default-view', 'calendarDefault'),
  53. $this->settingsOption('calendar-time-format', 'calendarTimeFormat'),
  54. $this->settingsOption('calendar-locale', 'calendarLocale'),
  55. $this->settingsOption('calendar-limit', 'calendarLimit'),
  56. $this->settingsOption('refresh', 'calendarRefresh'),
  57. ]
  58. ]
  59. ];
  60. return array_merge($homepageInformation, $homepageSettings);
  61. }
  62. public function traktHomepagePermissions($key = null)
  63. {
  64. $permissions = [
  65. 'calendar' => [
  66. 'enabled' => [
  67. 'homepageTraktEnabled'
  68. ],
  69. 'auth' => [
  70. 'homepageTraktAuth'
  71. ],
  72. 'not_empty' => [
  73. 'traktClientId',
  74. 'traktAccessToken'
  75. ]
  76. ]
  77. ];
  78. return $this->homepageCheckKeyPermissions($key, $permissions);
  79. }
  80. public function getTraktCalendar($startDate = null)
  81. {
  82. $startDate = date('Y-m-d', strtotime('-' . $this->config['calendarStartTrakt'] . ' days'));
  83. $calendarItems = array();
  84. $errors = null;
  85. $totalDays = (int)$this->config['calendarStartTrakt'] + (int)$this->config['calendarEndTrakt'];
  86. if (!$this->homepageItemPermissions($this->traktHomepagePermissions('calendar'), true)) {
  87. return false;
  88. }
  89. $headers = [
  90. 'Content-Type' => 'application/json',
  91. 'Authorization' => 'Bearer ' . $this->config['traktAccessToken'],
  92. 'trakt-api-version' => 2,
  93. 'trakt-api-key' => $this->config['traktClientId']
  94. ];
  95. $url = $this->qualifyURL('https://api.trakt.tv/calendars/my/shows/' . $startDate . '/' . $totalDays . '?extended=full');
  96. $options = $this->requestOptions($url, $this->config['calendarRefresh']);
  97. try {
  98. $response = Requests::get($url, $headers, $options);
  99. if ($response->success) {
  100. $data = json_decode($response->body, true);
  101. $traktTv = $this->formatTraktCalendarTv($data);
  102. if (!empty($traktTv)) {
  103. $calendarItems = array_merge($calendarItems, $traktTv);
  104. }
  105. }
  106. } catch (Requests_Exception $e) {
  107. $this->setLoggerChannel('Trakt')->error($e);
  108. $this->setResponse(500, $e->getMessage());
  109. $errors = true;
  110. }
  111. $url = $this->qualifyURL('https://api.trakt.tv/calendars/my/movies/' . $startDate . '/' . $totalDays . '?extended=full');
  112. try {
  113. $response = Requests::get($url, $headers, $options);
  114. if ($response->success) {
  115. $data = json_decode($response->body, true);
  116. $traktMovies = $this->formatTraktCalendarMovies($data);
  117. if (!empty($traktTv)) {
  118. $calendarItems = array_merge($calendarItems, $traktMovies);
  119. }
  120. }
  121. } catch (Requests_Exception $e) {
  122. $this->setLoggerChannel('Trakt')->error($e);
  123. $this->setResponse(500, $e->getMessage());
  124. $errors = true;
  125. }
  126. if ($errors) {
  127. $this->setAPIResponse('error', 'An error Occurred', 500, null);
  128. return false;
  129. }
  130. $this->setAPIResponse('success', null, 200, $calendarItems);
  131. $this->traktOAuthRefresh();
  132. return $calendarItems;
  133. }
  134. public function formatTraktCalendarTv($array)
  135. {
  136. $gotCalendar = array();
  137. $i = 0;
  138. foreach ($array as $child) {
  139. $i++;
  140. $seriesName = $child['show']['title'];
  141. $seriesID = $child['show']['ids']['tmdb'];
  142. $episodeID = $child['show']['ids']['tmdb'];
  143. if (!isset($episodeID)) {
  144. $episodeID = "";
  145. }
  146. //$episodeName = htmlentities($child['title'], ENT_QUOTES);
  147. $episodeAirDate = $child['first_aired'];
  148. $episodeAirDate = strtotime($episodeAirDate);
  149. $episodeAirDate = date("Y-m-d H:i:s", $episodeAirDate);
  150. if (new DateTime() < new DateTime($episodeAirDate)) {
  151. $unaired = true;
  152. }
  153. if ($child['episode']['number'] == 1) {
  154. $episodePremier = "true";
  155. } else {
  156. $episodePremier = "false";
  157. $date = new DateTime($episodeAirDate);
  158. $date->add(new DateInterval("PT1S"));
  159. $date->format(DateTime::ATOM);
  160. $child['first_aired'] = gmdate('Y-m-d\TH:i:s\Z', strtotime($date->format(DateTime::ATOM)));
  161. }
  162. $downloaded = 0;
  163. $monitored = 0;
  164. if ($downloaded == "0" && isset($unaired) && $episodePremier == "true") {
  165. $downloaded = "text-primary animated flash";
  166. } elseif ($downloaded == "0" && isset($unaired) && $monitored == "0") {
  167. $downloaded = "text-dark";
  168. } elseif ($downloaded == "0" && isset($unaired)) {
  169. $downloaded = "text-info";
  170. } elseif ($downloaded == "1") {
  171. $downloaded = "text-success";
  172. } else {
  173. $downloaded = "text-danger";
  174. }
  175. $fanart = "/plugins/images/homepage/no-np.png";
  176. $bottomTitle = 'S' . sprintf("%02d", $child['episode']['season']) . 'E' . sprintf("%02d", $child['episode']['number']) . ' - ' . $child['episode']['title'];
  177. $details = array(
  178. "seasonCount" => $child['episode']['season'],
  179. "status" => 'dunno',
  180. "topTitle" => $seriesName,
  181. "bottomTitle" => $bottomTitle,
  182. "overview" => isset($child['episode']['overview']) ? $child['episode']['overview'] : '',
  183. "runtime" => isset($child['episode']['runtime']) ? $child['episode']['runtime'] : '',
  184. "image" => $fanart,
  185. "ratings" => isset($child['show']['rating']) ? $child['show']['rating'] : '',
  186. "videoQuality" => "unknown",
  187. "audioChannels" => "unknown",
  188. "audioCodec" => "unknown",
  189. "videoCodec" => "unknown",
  190. "size" => "unknown",
  191. "genres" => isset($child['show']['genres']) ? $child['show']['genres'] : '',
  192. );
  193. array_push($gotCalendar, array(
  194. "id" => "Trakt-Tv-" . $i,
  195. "title" => $seriesName,
  196. "start" => $child['first_aired'],
  197. "className" => "inline-popups bg-calendar calendar-item get-tmdb-image tmdb-tv tmdbID--" . $seriesID,
  198. "imagetype" => "tv " . $downloaded,
  199. "imagetypeFilter" => "tv",
  200. "downloadFilter" => $downloaded,
  201. "bgColor" => str_replace('text', 'bg', $downloaded),
  202. "details" => $details
  203. ));
  204. }
  205. if ($i != 0) {
  206. return $gotCalendar;
  207. }
  208. return false;
  209. }
  210. public function formatTraktCalendarMovies($array)
  211. {
  212. $gotCalendar = array();
  213. $i = 0;
  214. foreach ($array as $child) {
  215. $i++;
  216. $movieName = $child['movie']['title'];
  217. $movieID = $child['movie']['ids']['tmdb'];
  218. if (!isset($movieID)) {
  219. $movieID = '';
  220. }
  221. $physicalRelease = (isset($child['movie']['released']) ? $child['movie']['released'] : null);
  222. //$backupRelease = (isset($child['info']['release_date']['theater']) ? $child['info']['release_date']['theater'] : null);
  223. //$physicalRelease = (isset($physicalRelease) ? $physicalRelease : $backupRelease);
  224. $physicalRelease = strtotime($physicalRelease);
  225. $physicalRelease = date('Y-m-d', $physicalRelease);
  226. $oldestDay = new DateTime ($this->currentTime);
  227. $oldestDay->modify('-' . $this->config['calendarStart'] . ' days');
  228. $newestDay = new DateTime ($this->currentTime);
  229. $newestDay->modify('+' . $this->config['calendarEnd'] . ' days');
  230. $startDt = new DateTime ($physicalRelease);
  231. if (new DateTime() < $startDt) {
  232. $notReleased = 'true';
  233. } else {
  234. $notReleased = 'false';
  235. }
  236. $downloaded = 'text-dark';
  237. $banner = '/plugins/images/homepage/no-np.png';
  238. $details = array(
  239. 'topTitle' => $movieName,
  240. 'bottomTitle' => $child['movie']['tagline'],
  241. 'status' => $child['movie']['status'],
  242. 'overview' => $child['movie']['overview'],
  243. 'runtime' => $child['movie']['runtime'],
  244. 'image' => $banner,
  245. 'ratings' => isset($child['movie']['rating']) ? $child['movie']['rating'] : '',
  246. 'videoQuality' => 'unknown',
  247. 'audioChannels' => '',
  248. 'audioCodec' => '',
  249. 'videoCodec' => '',
  250. 'genres' => $child['movie']['genres'],
  251. 'year' => isset($child['movie']['year']) ? $child['movie']['year'] : '',
  252. 'studio' => isset($child['movie']['year']) ? $child['movie']['year'] : '',
  253. );
  254. array_push($gotCalendar, array(
  255. 'id' => 'Trakt-Movie-' . $i,
  256. 'title' => $movieName,
  257. 'start' => $physicalRelease,
  258. 'className' => 'inline-popups bg-calendar calendar-item get-tmdb-image tmdb-movie tmdbID--' . $movieID,
  259. 'imagetype' => 'film ' . $downloaded,
  260. 'imagetypeFilter' => 'film',
  261. 'downloadFilter' => $downloaded,
  262. 'bgColor' => str_replace('text', 'bg', $downloaded),
  263. 'details' => $details
  264. ));
  265. }
  266. if ($i != 0) {
  267. return $gotCalendar;
  268. }
  269. return [];
  270. }
  271. }