plugin.php 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <?php
  2. // PLUGIN INFORMATION
  3. $GLOBALS['plugins']['plexlibraries'] = array( // Plugin Name
  4. 'name' => 'Plex Libraries', // Plugin Name
  5. 'author' => 'TehMuffinMoo', // Who wrote the plugin
  6. 'category' => 'Library Management', // One to Two Word Description
  7. 'link' => '', // Link to plugin info
  8. 'license' => 'personal', // License Type use , for multiple
  9. 'idPrefix' => 'PLEXLIBRARIES', // html element id prefix (All Uppercase)
  10. 'configPrefix' => 'PLEXLIBRARIES', // config file prefix for array items without the hypen (All Uppercase)
  11. 'version' => '1.0.1', // SemVer of plugin
  12. 'image' => 'api/plugins/plexLibraries/logo.png', // 1:1 non transparent image for plugin
  13. 'settings' => true, // does plugin need a settings modal?
  14. 'bind' => true, // use default bind to make settings page - true or false
  15. 'api' => 'api/v2/plugins/plexlibraries/settings', // api route for settings page (All Lowercase)
  16. 'homepage' => false // Is plugin for use on homepage? true or false
  17. );
  18. class plexLibrariesPlugin extends Organizr
  19. {
  20. public function _pluginGetSettings()
  21. {
  22. $libraryList = [['name' => 'Refresh page to update List', 'value' => '', 'disabled' => true]];
  23. if ($this->config['plexID'] !== '' && $this->config['plexToken'] !== '') {
  24. $libraryList = [];
  25. $loop = $this->plexLibraryList('key')['libraries'];
  26. foreach ($loop as $key => $value) {
  27. $libraryList[] = ['name' => $key, 'value' => $value];
  28. }
  29. }
  30. $this->setGroupOptionsVariable();
  31. return array(
  32. 'Settings' => array(
  33. $this->settingsOption('token', 'plexToken'),
  34. $this->settingsOption('button', '', ['label' => 'Get Plex Token', 'icon' => 'fa fa-ticket', 'text' => 'Retrieve', 'attr' => 'onclick="PlexOAuth(oAuthSuccess,oAuthError, null, \'#PLEXLIBRARIES-settings-page [name=plexToken]\')"']),
  35. $this->settingsOption('password-alt', 'plexID', ['label' => 'Plex Machine']),
  36. $this->settingsOption('button', '', ['label' => 'Get Plex Machine', 'icon' => 'fa fa-id-badge', 'text' => 'Retrieve', 'attr' => 'onclick="showPlexMachineForm(\'#PLEXLIBRARIES-settings-page [name=plexID]\')"']),
  37. $this->settingsOption('auth', 'PLEXLIBRARIES-pluginAuth'),
  38. $this->settingsOption('input', 'plexAdmin', ['label' => 'Plex Admin Username or Email']),
  39. $this->settingsOption('plex-library-include', 'PLEXLIBRARIES-librariesToInclude', ['options' => $libraryList])
  40. )
  41. );
  42. }
  43. public function _pluginLaunch()
  44. {
  45. $user = $this->getUserById($this->user['userID']);
  46. if ($user) {
  47. if ($user['plex_token'] !== null) {
  48. $this->setResponse(200, 'User approved for plugin');
  49. return true;
  50. }
  51. }
  52. $this->setResponse(401, 'User not approved for plugin');
  53. return false;
  54. }
  55. public function plexLibrariesPluginGetPlexShares($includeAll = false, $userId = "")
  56. {
  57. if (empty($this->config['plexToken'])) {
  58. $this->setResponse(409, 'plexToken is not setup');
  59. return false;
  60. }
  61. $headers = array(
  62. 'Content-type: application/xml',
  63. 'X-Plex-Token' => $this->config['plexToken'],
  64. );
  65. // Check if user is Plex Admin
  66. if ((strtolower($this->user['username']) == strtolower($this->config['plexAdmin']) || strtolower($this->user['email']) == strtolower($this->config['plexAdmin'])) && !$userId) {
  67. $url = 'https://plex.tv/api/servers/' . $this->config['plexID'] . '/shared_servers/';
  68. try {
  69. $response = Requests::get($url, $headers, []);
  70. if ($response->success) {
  71. libxml_use_internal_errors(true);
  72. $plex = simplexml_load_string($response->body);
  73. $libraryList = array();
  74. foreach ($plex->SharedServer as $child) {
  75. if (!empty($child['username'])) {
  76. $libraryList[(string)$child['username']]['username'] = (string)$child['username'];
  77. $libraryList[(string)$child['username']]['email'] = (string)$child['email'];
  78. $libraryList[(string)$child['username']]['id'] = (string)$child['id'];
  79. $libraryList[(string)$child['username']]['userID'] = (string)$child['userID'];
  80. foreach ($child->Section as $library) {
  81. $library = current($library->attributes());
  82. $libraryList[(string)$child['username']]['libraries'][] = $library;
  83. }
  84. }
  85. }
  86. $libraryList = array_change_key_case($libraryList, CASE_LOWER);
  87. ksort($libraryList);
  88. $apiData = [
  89. 'plexAdmin' => true,
  90. 'libraryData' => $libraryList
  91. ];
  92. $this->setResponse(200, null, $apiData);
  93. return $apiData;
  94. } else {
  95. $this->setResponse(500, 'Plex error');
  96. return false;
  97. }
  98. } catch (Requests_Exception $e) {
  99. $this->writeLog('error', 'PlexLibraries Plugin - Error: ' . $e->getMessage(), 'SYSTEM');
  100. $this->setAPIResponse('error', 'PlexLibraries Plugin - Error: ' . $e->getMessage(), 400);
  101. return false;
  102. }
  103. } else {
  104. $searchTerm = ($userId) ?: $this->user['email'];
  105. $searchKey = ($userId) ? 'shareId' : 'email';
  106. $plexUsers = $this->allPlexUsers(false, true);
  107. $key = array_search($searchTerm, array_column($plexUsers, $searchKey));
  108. if ($key !== false) {
  109. $url = 'https://plex.tv/api/servers/' . $this->config['plexID'] . '/shared_servers/' . $plexUsers[$key]['shareId'];
  110. } else {
  111. $this->setResponse(404, 'User Id was not found in Plex Users');
  112. return false;
  113. }
  114. try {
  115. $response = Requests::get($url, $headers, array());
  116. if ($response->success) {
  117. libxml_use_internal_errors(true);
  118. $plex = simplexml_load_string($response->body);
  119. $libraryList = array();
  120. foreach ($plex->SharedServer as $child) {
  121. if (!empty($child['username'])) {
  122. $libraryList[(string)$child['username']]['username'] = (string)$child['username'];
  123. $libraryList[(string)$child['username']]['email'] = (string)$child['email'];
  124. $libraryList[(string)$child['username']]['id'] = (string)$child['id'];
  125. $libraryList[(string)$child['username']]['shareId'] = (string)$plexUsers[$key]['shareId'];
  126. foreach ($child->Section as $library) {
  127. $library = current($library->attributes());
  128. if (!$includeAll) {
  129. $librariesToInclude = explode(',', $this->config['PLEXLIBRARIES-librariesToInclude']);
  130. if (in_array($library['key'], $librariesToInclude)) {
  131. $libraryList[(string)$child['username']]['libraries'][] = $library;
  132. }
  133. } else {
  134. $libraryList[(string)$child['username']]['libraries'][] = $library;
  135. }
  136. }
  137. }
  138. }
  139. $libraryList = array_change_key_case($libraryList, CASE_LOWER);
  140. $apiData = [
  141. 'plexAdmin' => false,
  142. 'libraryData' => $libraryList
  143. ];
  144. $this->setResponse(200, null, $apiData);
  145. return $apiData;
  146. } else {
  147. $this->setResponse(500, 'Plex Error', $response->body);
  148. return false;
  149. }
  150. } catch (Requests_Exception $e) {
  151. $this->writeLog('error', 'PlexLibraries Plugin - Error: ' . $e->getMessage(), 'SYSTEM');
  152. $this->setAPIResponse('error', 'PlexLibraries Plugin - Error: ' . $e->getMessage(), 400);
  153. return false;
  154. }
  155. }
  156. }
  157. public function plexLibrariesPluginUpdatePlexShares($userId, $action, $shareId)
  158. {
  159. if (!$userId) {
  160. $this->setResponse(409, 'User Id not supplied');
  161. return false;
  162. }
  163. if (!$action) {
  164. $this->setResponse(409, 'Action not supplied');
  165. return false;
  166. }
  167. if (!$shareId) {
  168. $this->setResponse(409, 'Share Id not supplied');
  169. return false;
  170. }
  171. if (!$this->qualifyRequest(1)) {
  172. $plexUsers = $this->allPlexUsers(false, true);
  173. $key = array_search($this->user['email'], array_column($plexUsers, 'email'));
  174. if (!$key) {
  175. $this->setResponse(404, 'User Id was not found in Plex Users');
  176. return false;
  177. } else {
  178. if ($plexUsers[$key]['shareId'] !== $userId) {
  179. $this->setResponse(401, 'You are not allowed to edit someone else\'s plex share');
  180. return false;
  181. }
  182. }
  183. }
  184. $Shares = $this->plexLibrariesPluginGetPlexShares(true, $userId);
  185. $NewShares = array();
  186. if ($Shares) {
  187. if (isset($Shares['libraryData'])) {
  188. foreach ($Shares['libraryData'] as $key => $Share) {
  189. foreach ($Share['libraries'] as $library) {
  190. if ($library['shared'] == 1) {
  191. $ShareString = (string)$library['id'];
  192. if ($action == 'share') {
  193. $NewShares[] = $ShareString;
  194. $Msg = 'Enabled share';
  195. } else {
  196. $Msg = 'Disabled share';
  197. if ($ShareString !== $shareId) {
  198. $NewShares[] = $ShareString;
  199. }
  200. }
  201. }
  202. }
  203. }
  204. if ($action == 'share') {
  205. if (!in_array($shareId, $NewShares)) {
  206. $NewShares[] = $shareId;
  207. }
  208. }
  209. }
  210. }
  211. if (empty($NewShares)) {
  212. $this->setResponse(409, 'You must have at least one share.');
  213. return false;
  214. } else {
  215. $http_body = [
  216. "server_id" => $this->config['plexID'],
  217. "shared_server" => [
  218. "library_section_ids" => $NewShares
  219. ]
  220. ];
  221. if ($userId) {
  222. $url = 'https://plex.tv/api/servers/' . $this->config['plexID'] . '/shared_servers/' . $userId . '?X-Plex-Token=' . $this->config['plexToken'];
  223. }
  224. $headers = [
  225. 'Accept' => 'application/json',
  226. 'Content-Type' => 'application/json',
  227. ];
  228. try {
  229. $response = Requests::put($url, $headers, json_encode($http_body), []);
  230. if ($response->success) {
  231. $this->setAPIResponse('success', $Msg, 200, $http_body);
  232. return $http_body;
  233. } else {
  234. $this->setAPIResponse('error', 'PlexLibraries Plugin - Error: Plex Error', 400);
  235. return false;
  236. }
  237. } catch (Requests_Exception $e) {
  238. $this->writeLog('error', 'PlexLibraries Plugin - Error: ' . $e->getMessage(), 'SYSTEM');
  239. $this->setAPIResponse('error', 'PlexLibraries Plugin - Error: ' . $e->getMessage(), 400);
  240. return false;
  241. }
  242. }
  243. }
  244. }