trakt.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  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>' . $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. if (array_key_exists($key, $permissions)) {
  79. return $permissions[$key];
  80. } elseif ($key == 'all') {
  81. return $permissions;
  82. } else {
  83. return [];
  84. }
  85. }
  86. public function getTraktCalendar($startDate = null)
  87. {
  88. $startDate = date('Y-m-d', strtotime('-' . $this->config['calendarStartTrakt'] . ' days'));
  89. $calendarItems = array();
  90. $errors = null;
  91. $totalDays = (int)$this->config['calendarStartTrakt'] + (int)$this->config['calendarEndTrakt'];
  92. if (!$this->homepageItemPermissions($this->traktHomepagePermissions('calendar'), true)) {
  93. return false;
  94. }
  95. $headers = [
  96. 'Content-Type' => 'application/json',
  97. 'Authorization' => 'Bearer ' . $this->config['traktAccessToken'],
  98. 'trakt-api-version' => 2,
  99. 'trakt-api-key' => $this->config['traktClientId']
  100. ];
  101. $url = $this->qualifyURL('https://api.trakt.tv/calendars/my/shows/' . $startDate . '/' . $totalDays . '?extended=full');
  102. $options = $this->requestOptions($url, $this->config['calendarRefresh']);
  103. try {
  104. $response = Requests::get($url, $headers, $options);
  105. if ($response->success) {
  106. $data = json_decode($response->body, true);
  107. $traktTv = $this->formatTraktCalendarTv($data);
  108. if (!empty($traktTv)) {
  109. $calendarItems = array_merge($calendarItems, $traktTv);
  110. }
  111. }
  112. } catch (Requests_Exception $e) {
  113. $this->writeLog('error', 'Trakt Connect Function - Error: ' . $e->getMessage(), 'SYSTEM');
  114. $this->setAPIResponse('error', $e->getMessage(), 500);
  115. $errors = true;
  116. }
  117. $url = $this->qualifyURL('https://api.trakt.tv/calendars/my/movies/' . $startDate . '/' . $totalDays . '?extended=full');
  118. try {
  119. $response = Requests::get($url, $headers, $options);
  120. if ($response->success) {
  121. $data = json_decode($response->body, true);
  122. $traktMovies = $this->formatTraktCalendarMovies($data);
  123. if (!empty($traktTv)) {
  124. $calendarItems = array_merge($calendarItems, $traktMovies);
  125. }
  126. }
  127. } catch (Requests_Exception $e) {
  128. $this->writeLog('error', 'Trakt Connect Function - Error: ' . $e->getMessage(), 'SYSTEM');
  129. $this->setAPIResponse('error', $e->getMessage(), 500);
  130. $errors = true;
  131. }
  132. if ($errors) {
  133. $this->setAPIResponse('error', 'An error Occurred', 500, null);
  134. return false;
  135. }
  136. $this->setAPIResponse('success', null, 200, $calendarItems);
  137. $this->traktOAuthRefresh();
  138. return $calendarItems;
  139. }
  140. public function formatTraktCalendarTv($array)
  141. {
  142. $gotCalendar = array();
  143. $i = 0;
  144. foreach ($array as $child) {
  145. $i++;
  146. $seriesName = $child['show']['title'];
  147. $seriesID = $child['show']['ids']['tmdb'];
  148. $episodeID = $child['show']['ids']['tmdb'];
  149. if (!isset($episodeID)) {
  150. $episodeID = "";
  151. }
  152. //$episodeName = htmlentities($child['title'], ENT_QUOTES);
  153. $episodeAirDate = $child['first_aired'];
  154. $episodeAirDate = strtotime($episodeAirDate);
  155. $episodeAirDate = date("Y-m-d H:i:s", $episodeAirDate);
  156. if (new DateTime() < new DateTime($episodeAirDate)) {
  157. $unaired = true;
  158. }
  159. if ($child['episode']['number'] == 1) {
  160. $episodePremier = "true";
  161. } else {
  162. $episodePremier = "false";
  163. $date = new DateTime($episodeAirDate);
  164. $date->add(new DateInterval("PT1S"));
  165. $date->format(DateTime::ATOM);
  166. $child['first_aired'] = gmdate('Y-m-d\TH:i:s\Z', strtotime($date->format(DateTime::ATOM)));
  167. }
  168. $downloaded = 0;
  169. $monitored = 0;
  170. if ($downloaded == "0" && isset($unaired) && $episodePremier == "true") {
  171. $downloaded = "text-primary animated flash";
  172. } elseif ($downloaded == "0" && isset($unaired) && $monitored == "0") {
  173. $downloaded = "text-dark";
  174. } elseif ($downloaded == "0" && isset($unaired)) {
  175. $downloaded = "text-info";
  176. } elseif ($downloaded == "1") {
  177. $downloaded = "text-success";
  178. } else {
  179. $downloaded = "text-danger";
  180. }
  181. $fanart = "/plugins/images/cache/no-np.png";
  182. $bottomTitle = 'S' . sprintf("%02d", $child['episode']['season']) . 'E' . sprintf("%02d", $child['episode']['number']) . ' - ' . $child['episode']['title'];
  183. $details = array(
  184. "seasonCount" => $child['episode']['season'],
  185. "status" => 'dunno',
  186. "topTitle" => $seriesName,
  187. "bottomTitle" => $bottomTitle,
  188. "overview" => isset($child['episode']['overview']) ? $child['episode']['overview'] : '',
  189. "runtime" => isset($child['episode']['runtime']) ? $child['episode']['runtime'] : '',
  190. "image" => $fanart,
  191. "ratings" => isset($child['show']['rating']) ? $child['show']['rating'] : '',
  192. "videoQuality" => "unknown",
  193. "audioChannels" => "unknown",
  194. "audioCodec" => "unknown",
  195. "videoCodec" => "unknown",
  196. "size" => "unknown",
  197. "genres" => isset($child['show']['genres']) ? $child['show']['genres'] : '',
  198. );
  199. array_push($gotCalendar, array(
  200. "id" => "Trakt-Tv-" . $i,
  201. "title" => $seriesName,
  202. "start" => $child['first_aired'],
  203. "className" => "inline-popups bg-calendar calendar-item get-tmdb-image tmdb-tv tmdbID--" . $seriesID,
  204. "imagetype" => "tv " . $downloaded,
  205. "imagetypeFilter" => "tv",
  206. "downloadFilter" => $downloaded,
  207. "bgColor" => str_replace('text', 'bg', $downloaded),
  208. "details" => $details
  209. ));
  210. }
  211. if ($i != 0) {
  212. return $gotCalendar;
  213. }
  214. return false;
  215. }
  216. public function formatTraktCalendarMovies($array)
  217. {
  218. $gotCalendar = array();
  219. $i = 0;
  220. foreach ($array as $child) {
  221. $i++;
  222. $movieName = $child['movie']['title'];
  223. $movieID = $child['movie']['ids']['tmdb'];
  224. if (!isset($movieID)) {
  225. $movieID = '';
  226. }
  227. $physicalRelease = (isset($child['movie']['released']) ? $child['movie']['released'] : null);
  228. //$backupRelease = (isset($child['info']['release_date']['theater']) ? $child['info']['release_date']['theater'] : null);
  229. //$physicalRelease = (isset($physicalRelease) ? $physicalRelease : $backupRelease);
  230. $physicalRelease = strtotime($physicalRelease);
  231. $physicalRelease = date('Y-m-d', $physicalRelease);
  232. $oldestDay = new DateTime ($this->currentTime);
  233. $oldestDay->modify('-' . $this->config['calendarStart'] . ' days');
  234. $newestDay = new DateTime ($this->currentTime);
  235. $newestDay->modify('+' . $this->config['calendarEnd'] . ' days');
  236. $startDt = new DateTime ($physicalRelease);
  237. if (new DateTime() < $startDt) {
  238. $notReleased = 'true';
  239. } else {
  240. $notReleased = 'false';
  241. }
  242. $downloaded = 'text-dark';
  243. $banner = '/plugins/images/cache/no-np.png';
  244. $details = array(
  245. 'topTitle' => $movieName,
  246. 'bottomTitle' => $child['movie']['tagline'],
  247. 'status' => $child['movie']['status'],
  248. 'overview' => $child['movie']['overview'],
  249. 'runtime' => $child['movie']['runtime'],
  250. 'image' => $banner,
  251. 'ratings' => isset($child['movie']['rating']) ? $child['movie']['rating'] : '',
  252. 'videoQuality' => 'unknown',
  253. 'audioChannels' => '',
  254. 'audioCodec' => '',
  255. 'videoCodec' => '',
  256. 'genres' => $child['movie']['genres'],
  257. 'year' => isset($child['movie']['year']) ? $child['movie']['year'] : '',
  258. 'studio' => isset($child['movie']['year']) ? $child['movie']['year'] : '',
  259. );
  260. array_push($gotCalendar, array(
  261. 'id' => 'Trakt-Movie-' . $i,
  262. 'title' => $movieName,
  263. 'start' => $physicalRelease,
  264. 'className' => 'inline-popups bg-calendar calendar-item get-tmdb-image tmdb-movie tmdbID--' . $movieID,
  265. 'imagetype' => 'film ' . $downloaded,
  266. 'imagetypeFilter' => 'film',
  267. 'downloadFilter' => $downloaded,
  268. 'bgColor' => str_replace('text', 'bg', $downloaded),
  269. 'details' => $details
  270. ));
  271. }
  272. if ($i != 0) {
  273. return $gotCalendar;
  274. }
  275. return [];
  276. }
  277. }