Made PlexManage works with external user tokens. Added FAQ entry about migrating external user data from plex to other platforms.

This commit is contained in:
Abdulmhsen B. A. A
2023-12-22 19:05:16 +03:00
parent 844d6f5558
commit 73823288a3
4 changed files with 56 additions and 37 deletions

20
FAQ.md
View File

@@ -155,6 +155,26 @@ $ docker exec -ti console backend:users:list --with-tokens -- [BACKEND_NAME]
----
### How do i migrate invited friends i.e. (external user) data from from plex to emby/jellyfin?
As this tool is designed to work with single user, You have to treat each invited friend as a separate user. what is
needed, you need to contact that friend of yours and ask him to give you a copy of his [X-Plex-Token](https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/),
then create new container and add the backend with the token you got from your friend.
After that, add your other backends like emby/jellyfin using your regular API key. jellyfin/emby differentiate between users by using the userId which
you should select at the start of the add process.
After that. run the `state:import -f -s [plex_server_name]` command to import the user watch state. After that, you can run the `state:export -fi -s [emby/jellyfin_server_name]` to export the
watch state to the new backend.
You have to repeat these steps for each user you want to migrate their data off the plex server.
> [!IMPORTANT]
> YOU MUST always start with fresh data for **EACH USER**, otherwise unexpected things might happen.
> Make sure to delete docker-compose.yaml `./data` directory. to start fresh
----
### Does this tool require webhooks to work?
No, You can use the `task scheduler` or on `demand sync` if you want.

57
composer.lock generated
View File

@@ -2556,23 +2556,23 @@
},
{
"name": "phpunit/php-code-coverage",
"version": "9.2.29",
"version": "9.2.30",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76"
"reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76",
"reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca2bd87d2f9215904682a9cb9bb37dda98e76089",
"reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-libxml": "*",
"ext-xmlwriter": "*",
"nikic/php-parser": "^4.15",
"nikic/php-parser": "^4.18 || ^5.0",
"php": ">=7.3",
"phpunit/php-file-iterator": "^3.0.3",
"phpunit/php-text-template": "^2.0.2",
@@ -2622,7 +2622,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.29"
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.30"
},
"funding": [
{
@@ -2630,7 +2630,7 @@
"type": "github"
}
],
"time": "2023-09-19T04:57:46+00:00"
"time": "2023-12-22T06:47:57+00:00"
},
{
"name": "phpunit/php-file-iterator",
@@ -2982,12 +2982,12 @@
"source": {
"type": "git",
"url": "https://github.com/Roave/SecurityAdvisories.git",
"reference": "3c2385497f806decca1e5abeba3cb8fd7caba4e0"
"reference": "be9456d1430df8be755ff7da33b22b80f0ed2f5f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/3c2385497f806decca1e5abeba3cb8fd7caba4e0",
"reference": "3c2385497f806decca1e5abeba3cb8fd7caba4e0",
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/be9456d1430df8be755ff7da33b22b80f0ed2f5f",
"reference": "be9456d1430df8be755ff7da33b22b80f0ed2f5f",
"shasum": ""
},
"conflict": {
@@ -3021,7 +3021,7 @@
"austintoddj/canvas": "<=3.4.2",
"automad/automad": "<1.8",
"awesome-support/awesome-support": "<=6.0.7",
"aws/aws-sdk-php": ">=3,<3.2.1",
"aws/aws-sdk-php": "<3.288.1",
"azuracast/azuracast": "<0.18.3",
"backdrop/backdrop": "<1.24.2",
"backpack/crud": "<3.4.9",
@@ -3103,7 +3103,7 @@
"dolibarr/dolibarr": "<18.0.2",
"dompdf/dompdf": "<2.0.4",
"doublethreedigital/guest-entries": "<3.1.2",
"drupal/core": "<9.4.14|>=9.5,<9.5.8|>=10,<10.0.8",
"drupal/core": "<9.5.11|>=10,<10.0.11|>=10.1,<10.1.4",
"drupal/drupal": ">=6,<6.38|>=7,<7.80|>=8,<8.9.16|>=9,<9.1.12|>=9.2,<9.2.4",
"duncanmcclean/guest-entries": "<3.1.2",
"dweeves/magmi": "<=0.7.24",
@@ -3371,7 +3371,7 @@
"phpoffice/phpspreadsheet": "<1.16",
"phpseclib/phpseclib": "<2.0.31|>=3,<3.0.34",
"phpservermon/phpservermon": "<3.6",
"phpsysinfo/phpsysinfo": "<3.2.5",
"phpsysinfo/phpsysinfo": "<3.4.3",
"phpunit/phpunit": ">=4.8.19,<4.8.28|>=5,<5.6.3",
"phpwhois/phpwhois": "<=4.2.5",
"phpxmlrpc/extras": "<0.6.1",
@@ -3608,6 +3608,7 @@
"yii2mod/yii2-cms": "<1.9.2",
"yiisoft/yii": "<1.1.29",
"yiisoft/yii2": "<2.0.38",
"yiisoft/yii2-authclient": "<2.2.15",
"yiisoft/yii2-bootstrap": "<2.0.4",
"yiisoft/yii2-dev": "<2.0.43",
"yiisoft/yii2-elasticsearch": "<2.0.5",
@@ -3691,7 +3692,7 @@
"type": "tidelift"
}
],
"time": "2023-12-15T16:04:17+00:00"
"time": "2023-12-22T00:14:36+00:00"
},
{
"name": "sebastian/cli-parser",
@@ -3936,20 +3937,20 @@
},
{
"name": "sebastian/complexity",
"version": "2.0.2",
"version": "2.0.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/complexity.git",
"reference": "739b35e53379900cc9ac327b2147867b8b6efd88"
"reference": "25f207c40d62b8b7aa32f5ab026c53561964053a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88",
"reference": "739b35e53379900cc9ac327b2147867b8b6efd88",
"url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a",
"reference": "25f207c40d62b8b7aa32f5ab026c53561964053a",
"shasum": ""
},
"require": {
"nikic/php-parser": "^4.7",
"nikic/php-parser": "^4.18 || ^5.0",
"php": ">=7.3"
},
"require-dev": {
@@ -3981,7 +3982,7 @@
"homepage": "https://github.com/sebastianbergmann/complexity",
"support": {
"issues": "https://github.com/sebastianbergmann/complexity/issues",
"source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2"
"source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3"
},
"funding": [
{
@@ -3989,7 +3990,7 @@
"type": "github"
}
],
"time": "2020-10-26T15:52:27+00:00"
"time": "2023-12-22T06:19:30+00:00"
},
{
"name": "sebastian/diff",
@@ -4263,20 +4264,20 @@
},
{
"name": "sebastian/lines-of-code",
"version": "1.0.3",
"version": "1.0.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/lines-of-code.git",
"reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc"
"reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc",
"reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc",
"url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5",
"reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5",
"shasum": ""
},
"require": {
"nikic/php-parser": "^4.6",
"nikic/php-parser": "^4.18 || ^5.0",
"php": ">=7.3"
},
"require-dev": {
@@ -4308,7 +4309,7 @@
"homepage": "https://github.com/sebastianbergmann/lines-of-code",
"support": {
"issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
"source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3"
"source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4"
},
"funding": [
{
@@ -4316,7 +4317,7 @@
"type": "github"
}
],
"time": "2020-11-28T06:42:11+00:00"
"time": "2023-12-22T06:20:34+00:00"
},
{
"name": "sebastian/object-enumerator",

View File

@@ -59,9 +59,9 @@ class PlexManage implements ManageInterface
$question = new Question(
r(
<<<HELP
<question>Enter [<value>{name}</value>] Plex admin token</question>. {default}
<question>Enter [<value>{name}</value>] X-Plex-Token</question>. {default}
------------------
<info>Please log in your main plex account to extract the admin token.</info>
to find your plex token. follow the steps described in the following link.
<href={url}>{url}</>
------------------
@@ -119,7 +119,7 @@ class PlexManage implements ManageInterface
throw new RuntimeException('Plex API returned empty list of servers.');
}
$list = $map = [];
$list = $map = $uuid = [];
foreach ($backends as $server) {
$val = r('{name} - {uri}', [
@@ -129,6 +129,7 @@ class PlexManage implements ManageInterface
$list[] = $val;
$map[$val] = ag($server, 'uri');
$uuid[$val] = ag($server, 'identifier');
}
$list[] = 'Other. Enter manually.';
@@ -147,6 +148,7 @@ class PlexManage implements ManageInterface
if (true === ag_exists($map, $server)) {
$backend = ag_set($backend, 'url', ag($map, $server));
$backend = ag_set($backend, 'uuid', ag($uuid, $server));
return;
}
}
@@ -232,11 +234,7 @@ class PlexManage implements ManageInterface
<<<ERROR
<error>Failed to automatically get server unique identifier.</error>
------------------
<notice>This most likely means the token that was given doesn't have access to the selected server.
Or the token is for invited friend i.e. (external user), which the token doesn't have access to the
internal settings, Thus the tool cannot get the server unique identifier.</notice>
<comment>If that's the case, you san safely ignore this error and put random string in the next step.</comment>
<comment>However, keep in mind webhooks will not work without correct backend unique identifier.</comment>
<notice>This most likely means the token that was given doesn't have access to the selected server.</notice>
------------------
{class}: {error}
ERROR,

View File

@@ -194,7 +194,7 @@ final class UnifyCommand extends Command
$client = makeBackend(Config::get($ref), $backendName);
$uuid = $client->getIdentifier(true);
$uuid = $client->getContext()->backendId ?? $client->getIdentifier(true);
if (empty($uuid)) {
$output->writeln(