tatutulli.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. <?php
  2. trait TautulliHomepageItem
  3. {
  4. public function tautulliSettingsArray()
  5. {
  6. return array(
  7. 'name' => 'Tautulli',
  8. 'enabled' => strpos('personal', $this->config['license']) !== false,
  9. 'image' => 'plugins/images/tabs/tautulli.png',
  10. 'category' => 'Monitor',
  11. 'settings' => array(
  12. 'Enable' => array(
  13. array(
  14. 'type' => 'switch',
  15. 'name' => 'homepageTautulliEnabled',
  16. 'label' => 'Enable',
  17. 'value' => $this->config['homepageTautulliEnabled']
  18. ),
  19. array(
  20. 'type' => 'select',
  21. 'name' => 'homepageTautulliAuth',
  22. 'label' => 'Minimum Authentication',
  23. 'value' => $this->config['homepageTautulliAuth'],
  24. 'options' => $this->groupOptions
  25. )
  26. ),
  27. 'Options' => array(
  28. array(
  29. 'type' => 'input',
  30. 'name' => 'tautulliHeader',
  31. 'label' => 'Title',
  32. 'value' => $this->config['tautulliHeader'],
  33. 'help' => 'Sets the title of this homepage module'
  34. ),
  35. array(
  36. 'type' => 'switch',
  37. 'name' => 'tautulliHeaderToggle',
  38. 'label' => 'Toggle Title',
  39. 'value' => $this->config['tautulliHeaderToggle'],
  40. 'help' => 'Shows/hides the title of this homepage module'
  41. )
  42. ),
  43. 'Connection' => array(
  44. array(
  45. 'type' => 'input',
  46. 'name' => 'tautulliURL',
  47. 'label' => 'URL',
  48. 'value' => $this->config['tautulliURL'],
  49. 'help' => 'URL for Tautulli API, include the IP, the port and the base URL (e.g. /tautulli/) in the URL',
  50. 'placeholder' => 'http://<ip>:<port>'
  51. ),
  52. array(
  53. 'type' => 'password-alt',
  54. 'name' => 'tautulliApikey',
  55. 'label' => 'API Key',
  56. 'value' => $this->config['tautulliApikey']
  57. ),
  58. array(
  59. 'type' => 'select',
  60. 'name' => 'homepageTautulliRefresh',
  61. 'label' => 'Refresh Seconds',
  62. 'value' => $this->config['homepageTautulliRefresh'],
  63. 'options' => $this->timeOptions()
  64. ),
  65. ),
  66. 'Library Stats' => array(
  67. array(
  68. 'type' => 'switch',
  69. 'name' => 'tautulliLibraries',
  70. 'label' => 'Libraries',
  71. 'value' => $this->config['tautulliLibraries'],
  72. 'help' => 'Shows/hides the card with library information.',
  73. ),
  74. array(
  75. 'type' => 'select',
  76. 'name' => 'homepageTautulliLibraryAuth',
  77. 'label' => 'Minimum Authentication',
  78. 'value' => $this->config['homepageTautulliLibraryAuth'],
  79. 'options' => $this->groupOptions
  80. ),
  81. ),
  82. 'Viewing Stats' => array(
  83. array(
  84. 'type' => 'switch',
  85. 'name' => 'tautulliPopularMovies',
  86. 'label' => 'Popular Movies',
  87. 'value' => $this->config['tautulliPopularMovies'],
  88. 'help' => 'Shows/hides the card with Popular Movies information.',
  89. ),
  90. array(
  91. 'type' => 'switch',
  92. 'name' => 'tautulliPopularTV',
  93. 'label' => 'Popular TV',
  94. 'value' => $this->config['tautulliPopularTV'],
  95. 'help' => 'Shows/hides the card with Popular TV information.',
  96. ),
  97. array(
  98. 'type' => 'switch',
  99. 'name' => 'tautulliTopMovies',
  100. 'label' => 'Top Movies',
  101. 'value' => $this->config['tautulliTopMovies'],
  102. 'help' => 'Shows/hides the card with Top Movies information.',
  103. ),
  104. array(
  105. 'type' => 'switch',
  106. 'name' => 'tautulliTopTV',
  107. 'label' => 'Top TV',
  108. 'value' => $this->config['tautulliTopTV'],
  109. 'help' => 'Shows/hides the card with Top TV information.',
  110. ),
  111. array(
  112. 'type' => 'select',
  113. 'name' => 'homepageTautulliViewsAuth',
  114. 'label' => 'Minimum Authentication',
  115. 'value' => $this->config['homepageTautulliViewsAuth'],
  116. 'options' => $this->groupOptions
  117. ),
  118. ),
  119. 'Misc Stats' => array(
  120. array(
  121. 'type' => 'switch',
  122. 'name' => 'tautulliTopUsers',
  123. 'label' => 'Top Users',
  124. 'value' => $this->config['tautulliTopUsers'],
  125. 'help' => 'Shows/hides the card with Top Users information.',
  126. ),
  127. array(
  128. 'type' => 'switch',
  129. 'name' => 'tautulliTopPlatforms',
  130. 'label' => 'Top Platforms',
  131. 'value' => $this->config['tautulliTopPlatforms'],
  132. 'help' => 'Shows/hides the card with Top Platforms information.',
  133. ),
  134. array(
  135. 'type' => 'select',
  136. 'name' => 'homepageTautulliMiscAuth',
  137. 'label' => 'Minimum Authentication',
  138. 'value' => $this->config['homepageTautulliMiscAuth'],
  139. 'options' => $this->groupOptions
  140. ),
  141. ),
  142. 'Test Connection' => array(
  143. array(
  144. 'type' => 'blank',
  145. 'label' => 'Please Save before Testing'
  146. ),
  147. array(
  148. 'type' => 'button',
  149. 'label' => '',
  150. 'icon' => 'fa fa-flask',
  151. 'class' => 'pull-right',
  152. 'text' => 'Test Connection',
  153. 'attr' => 'onclick="testAPIConnection(\'tautulli\')"'
  154. ),
  155. )
  156. )
  157. );
  158. }
  159. public function testConnectionTautulli()
  160. {
  161. if (empty($this->config['tautulliURL'])) {
  162. $this->setAPIResponse('error', 'Tautulli URL is not defined', 422);
  163. return false;
  164. }
  165. if (empty($this->config['tautulliApikey'])) {
  166. $this->setAPIResponse('error', 'Tautulli Token is not defined', 422);
  167. return false;
  168. }
  169. $url = $this->qualifyURL($this->config['tautulliURL']);
  170. $apiURL = $url . '/api/v2?apikey=' . $this->config['tautulliApikey'];
  171. try {
  172. $homestatsUrl = $apiURL . '&cmd=get_home_stats&grouping=1';
  173. $homestats = Requests::get($homestatsUrl, [], []);
  174. if ($homestats->success) {
  175. $this->setAPIResponse('success', 'API Connection succeeded', 200);
  176. return true;
  177. } else {
  178. $this->setAPIResponse('error', 'Tautulli Error Occurred - Check URL or Credentials', 409);
  179. return false;
  180. }
  181. } catch (Requests_Exception $e) {
  182. $this->writeLog('error', 'Tautulli Connect Function - Error: ' . $e->getMessage(), 'SYSTEM');
  183. $this->setAPIResponse('error', $e->getMessage(), 500);
  184. return false;
  185. }
  186. }
  187. public function getTautulliHomepageData()
  188. {
  189. if (!$this->config['homepageTautulliEnabled']) {
  190. $this->setAPIResponse('error', 'Tautulli homepage item is not enabled', 409);
  191. return false;
  192. }
  193. if (!$this->qualifyRequest($this->config['homepageTautulliAuth'])) {
  194. $this->setAPIResponse('error', 'User not approved to view this homepage item', 401);
  195. return false;
  196. }
  197. if (empty($this->config['tautulliURL'])) {
  198. $this->setAPIResponse('error', 'Tautulli URL is not defined', 422);
  199. return false;
  200. }
  201. if (empty($this->config['tautulliApikey'])) {
  202. $this->setAPIResponse('error', 'Tautulli Token is not defined', 422);
  203. return false;
  204. }
  205. $api = [];
  206. $url = $this->qualifyURL($this->config['tautulliURL']);
  207. $apiURL = $url . '/api/v2?apikey=' . $this->config['tautulliApikey'];
  208. $height = $this->getCacheImageSize('h');
  209. $width = $this->getCacheImageSize('w');
  210. $nowPlayingHeight = $this->getCacheImageSize('nph');
  211. $nowPlayingWidth = $this->getCacheImageSize('npw');
  212. try {
  213. $homestatsUrl = $apiURL . '&cmd=get_home_stats&grouping=1';
  214. $homestats = Requests::get($homestatsUrl, [], []);
  215. if ($homestats->success) {
  216. $homestats = json_decode($homestats->body, true);
  217. $api['homestats'] = $homestats['response'];
  218. // Cache art & thumb for first result in each tautulli API result
  219. $categories = ['top_movies', 'top_tv', 'popular_movies', 'popular_tv'];
  220. foreach ($categories as $cat) {
  221. $key = array_search($cat, array_column($api['homestats']['data'], 'stat_id'));
  222. $img = $api['homestats']['data'][$key]['rows'][0];
  223. $this->cacheImage($url . '/pms_image_proxy?img=' . $img['art'] . '&rating_key=' . $img['rating_key'] . '&width=' . $nowPlayingWidth . '&height=' . $nowPlayingHeight, $img['rating_key'] . '-np');
  224. $this->cacheImage($url . '/pms_image_proxy?img=' . $img['thumb'] . '&rating_key=' . $img['rating_key'] . '&width=' . $width . '&height=' . $height, $img['rating_key'] . '-list');
  225. $img['art'] = 'plugins/images/cache/' . $img['rating_key'] . '-np.jpg';
  226. $img['thumb'] = 'plugins/images/cache/' . $img['rating_key'] . '-list.jpg';
  227. $api['homestats']['data'][$key]['rows'][0] = $img;
  228. }
  229. // Cache the platform icon
  230. $key = array_search('top_platforms', array_column($api['homestats']['data'], 'stat_id'));
  231. $platform = $api['homestats']['data'][$key]['rows'][0]['platform_name'];
  232. $this->cacheImage($url . '/images/platforms/' . $platform . '.svg', 'tautulli-' . $platform, 'svg');
  233. }
  234. $libstatsUrl = $apiURL . '&cmd=get_libraries';
  235. $libstats = Requests::get($libstatsUrl, [], []);
  236. if ($libstats->success) {
  237. $libstats = json_decode($libstats->body, true);
  238. $api['libstats'] = $libstats['response'];
  239. $categories = ['movie.svg', 'show.svg', 'artist.svg'];
  240. foreach ($categories as $cat) {
  241. $parts = explode('.', $cat);
  242. $this->cacheImage($url . '/images/libraries/' . $cat, 'tautulli-' . $parts[0], $parts[1]);
  243. }
  244. }
  245. $api['options'] = [
  246. 'url' => $url,
  247. 'libraries' => $this->config['tautulliLibraries'],
  248. 'topMovies' => $this->config['tautulliTopMovies'],
  249. 'topTV' => $this->config['tautulliTopTV'],
  250. 'topUsers' => $this->config['tautulliTopUsers'],
  251. 'topPlatforms' => $this->config['tautulliTopPlatforms'],
  252. 'popularMovies' => $this->config['tautulliPopularMovies'],
  253. 'popularTV' => $this->config['tautulliPopularTV'],
  254. 'title' => $this->config['tautulliHeaderToggle'],
  255. ];
  256. $ids = []; // Array of stat_ids to remove from the returned array
  257. if (!$this->qualifyRequest($this->config['homepageTautulliLibraryAuth'])) {
  258. $api['options']['libraries'] = false;
  259. unset($api['libstats']);
  260. }
  261. if (!$this->qualifyRequest($this->config['homepageTautulliViewsAuth'])) {
  262. $api['options']['topMovies'] = false;
  263. $api['options']['topTV'] = false;
  264. $api['options']['popularMovies'] = false;
  265. $api['options']['popularTV'] = false;
  266. $ids = array_merge(['top_movies', 'popular_movies', 'popular_tv', 'top_tv'], $ids);
  267. $api['homestats']['data'] = array_values($api['homestats']['data']);
  268. }
  269. if (!$this->qualifyRequest($this->config['homepageTautulliMiscAuth'])) {
  270. $api['options']['topUsers'] = false;
  271. $api['options']['topPlatforms'] = false;
  272. $ids = array_merge(['top_platforms', 'top_users'], $ids);
  273. $api['homestats']['data'] = array_values($api['homestats']['data']);
  274. }
  275. $ids = array_merge(['top_music', 'popular_music', 'last_watched', 'most_concurrent'], $ids);
  276. foreach ($ids as $id) {
  277. if ($key = array_search($id, array_column($api['homestats']['data'], 'stat_id'))) {
  278. unset($api['homestats']['data'][$key]);
  279. $api['homestats']['data'] = array_values($api['homestats']['data']);
  280. }
  281. }
  282. } catch (Requests_Exception $e) {
  283. $this->writeLog('error', 'Tautulli Connect Function - Error: ' . $e->getMessage(), 'SYSTEM');
  284. $this->setAPIResponse('error', $e->getMessage(), 500);
  285. return false;
  286. };
  287. $api = isset($api) ? $api : false;
  288. $this->setAPIResponse('success', null, 200, $api);
  289. return $api;
  290. }
  291. }