tautulli.php 13 KB

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