Skip to content

Commit

Permalink
Merge pull request #588 from arabcoders/dev
Browse files Browse the repository at this point in the history
Fully implemented our vision for Multi-user sync via state:sync command
  • Loading branch information
arabcoders authored Jan 23, 2025
2 parents 9fee1ca + 96ccd88 commit 8c212c5
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 92 deletions.
54 changes: 29 additions & 25 deletions FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,53 +211,57 @@ database state back to the selected backend.

### Is there support for Multi-user setup?

There is a minimal support for multi-user setup via `state:sync` command. However, it still requires that you add your
backends as usual for single user setup and to use `state:sync` command, it's required that all backends have admin
access to be able to retrieve access-tokens for users. That means for Plex you need an admin token, and for
jellyfin/emby you need API key, not `user:password` limited access.
There are minimal support for multi-user setup via `state:sync` command. There are some requirements to get it working
correctly. The tools will try to match the users based on the name, and fallback on the `mapper.yaml` file if it's
provided. The tool will try to sync the users data between the backends.

To get started using `state:sync` command, as mentioned before setup your backends as normal, then create a
`/config/config/mapper.yaml` file if your backends doesn't have the same user. for example
#### Things that will get synced

* Play status, i.e. watched/unwatched.
* Watch progress.

#### Requirements to get the command working

* All backends need to have admin level access, this is needed to inquiry about the users and generate the required
access tokens.
* That means for plex, it needs the admin token, to find it
check [plex article about it](https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/).
* For jellyfin/emby you need to use the API key, not the user password. You can generate api keys via Dashboard >
Advanced > API Keys.

#### Whats the schema for the `mapper.yaml` file?

The schema is simple, it's a list of users in the following format:

```yaml
- backend_name1:
- my_plex_server:
name: "mike_jones"
options: { }
backend_name2:
my_jellyfin_server:
name: "jones_mike"
options: { }
backend_name3:
my_emby_server:
name: "mikeJones"
options: { }

- backend_name1:
- my_emby_server:
name: "jiji_jones"
options: { }
backend_name2:
my_plex_server:
name: "jones_jiji"
options: { }
backend_name3:
my_jellyfin_server:
name: "jijiJones"
options: { }
```
This yaml file helps map your users accounts in the different backends, so the tool can sync the correct user data.
Then simply run `state:sync -v` it will generate the required tokens and match users data between the backends.
then sync the difference, Keep in mind that it will be slow and that's expected as it needs to do the same thing without
caching for all users servers and backends. it's recommended to not run this command frequently. as it's puts a lot of
load on the backends. By default, it will sync once every 3 hours. you can ofc change it to suit your needs.
then sync the difference. By default, the task is scheduled to run every 3 hour, you can change the schedule by
altering the `WS_CRON_SYNC_AT` environment variable via `ENV` page or `system:env` command.

> [!NOTE]
> Known issues:

* Currently, `state:sync` doesn't have a way of syncing plex users that has PIN enabled.
* Majority of the command flags aren't working or not implemented yet.

> [!IMPORTANT]
> Please keep in mind the new command is still in alpha stage, so things will probably break. Please report any bugs
> you encounter. Also, please make sure to have a backup of your data before running the command. just in-case,
> while we did test it on our live data, it's always better to be safe than sorry.
To have the task run automatically, you need to enable the task via the `WebUI > Tasks` page or `system:env` command.

----

Expand Down
94 changes: 68 additions & 26 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Old Updates

### 2024-12-30

We have removed the old environment variables `WS_CRON_PROGRESS` and `WS_CRON_PUSH` in favor of the new ones
`WS_SYNC_PROGRESS` and `WS_PUSH_ENABLED`. please update your environment variables accordingly. We have also added
new FAQ entry about watch progress syncing via [this link](FAQ.md#sync-watch-progress).

### 2024-10-07

We have added a WebUI page for Custom GUIDs and stabilized on `v1.0` for the `guid.yaml` file spec. We strongly
recommend
to use the `WebUI` to manage the GUIDs, as it's much easier to use than editing the `guid.yaml` file directly. and both
the
`WebUI` and `API` have safeguards to prevent you from breaking the parser. For more information please check out the
associated
FAQ entry about it at [this link](FAQ.md#advanced-how-to-extend-the-guid-parser-to-support-more-guids-or-custom-ones).

### 2024-09-14

We have recently added support for extending WatchState with more GUIDs, as of now, the support for it is done via
Expand All @@ -14,46 +30,61 @@ or request the maintainer to add support for it.
### 2024-08-19

We have migrated the `state:push` task into the new events system, as such the old task `state:push` is now gone.
To enable the new event handler for push events, use the new environment variable `WS_PUSH_ENABLED` and set it to `true`.
To enable the new event handler for push events, use the new environment variable `WS_PUSH_ENABLED` and set it to
`true`.
Right now, it's disabled by default. However, for people who had the old task enabled, it will reuse that setting.

Keep in mind, the new event handler is more efficient and will only push data when there is a change in the play state. And it's much faster
Keep in mind, the new event handler is more efficient and will only push data when there is a change in the play state.
And it's much faster
than the old task. This event handler will push data within a minute of the change.

PS: Please enable the task by setting its new environment variable `WS_PUSH_ENABLED` to `true`. The old `WS_CRON_PUSH` is now gone.
PS: Please enable the task by setting its new environment variable `WS_PUSH_ENABLED` to `true`. The old `WS_CRON_PUSH`
is now gone.
and will be removed in the future releases.

### 2024-08-18

We have started migrating the old events system to a new one, so far we have migrated the `progress` and `requests` to it. As such,
The old tasks `state:progress` and `state:requests` are now gone. To control if you want to enable the watch progress, there is new
environment variable `WS_SYNC_PROGRESS` which you can set to `true` to enable the watch progress. It's disabled by default.
We have started migrating the old events system to a new one, so far we have migrated the `progress` and `requests` to
it. As such,
The old tasks `state:progress` and `state:requests` are now gone. To control if you want to enable the watch progress,
there is new
environment variable `WS_SYNC_PROGRESS` which you can set to `true` to enable the watch progress. It's disabled by
default.

We will continue to migrate the rest of the events to the new system, and we will keep you updated.

### 2024-08-10

I have recently added new experimental feature, to play your content directly from the WebUI. This feature is still in
alpha, and missing a lot of features. But it's a start. Right now it does auto transcode on the fly to play any content in the browser.
alpha, and missing a lot of features. But it's a start. Right now it does auto transcode on the fly to play any content
in the browser.

The feature requires that you mount your media directories to the `WatchState` container similar to the `File integrity` feature. I have plans to expand
the feature to support more controls, however, right now it's only support basic subtitles streams and default audio stream or first audio stream.
The feature requires that you mount your media directories to the `WatchState` container similar to the `File integrity`
feature. I have plans to expand
the feature to support more controls, however, right now it's only support basic subtitles streams and default audio
stream or first audio stream.

The transcoder works by converting the media on the fly to `HLS` segments, and the subtitles are selectable via the player ui which are also converted to `vtt` format.
The transcoder works by converting the media on the fly to `HLS` segments, and the subtitles are selectable via the
player ui which are also converted to `vtt` format.

Expects bugs and issues, as the feature is still in alpha. But I would love to hear your feedback. You can play the media by visiting
the history page of the item you will see red play button on top right corner of the page. If the items has a play button, then you correctly mounted
Expects bugs and issues, as the feature is still in alpha. But I would love to hear your feedback. You can play the
media by visiting
the history page of the item you will see red play button on top right corner of the page. If the items has a play
button, then you correctly mounted
the media directories. otherwise, the button be disabled with tooltip of `Media is inaccessible`.

The feature is not meant to replace your backend media player, the purpose of this feature is to quickly check the media without leaving the WebUI.
The feature is not meant to replace your backend media player, the purpose of this feature is to quickly check the media
without leaving the WebUI.

### 2024-08-01

We recently enabled listening on tls connections via `8443` which can be controlled by `HTTPS_PORT` environment variable.
We recently enabled listening on tls connections via `8443` which can be controlled by `HTTPS_PORT` environment
variable.
Before today, we simply only exposed the port via the `Dockerfile`, but we weren't listening for connections on it.

However, please keep in mind that the certificate is self-signed, and you might get a warning from your browser. You can
either accept the warning or add the certificate to your trusted certificates. We strongly recommend using a reverse proxy.
either accept the warning or add the certificate to your trusted certificates. We strongly recommend using a reverse
proxy.
instead of relying on self-signed certificates.

### 2024-07-22
Expand All @@ -62,14 +93,18 @@ We have recently added a new WebUI feature, `File integrity`, this feature will
are reporting files that are not available on the disk. This feature is still in alpha, and we are working on improving
it.

This feature `REQUIRES` that you mount your media directories to the `WatchState` container preferably as readonly. There is plans to add
This feature `REQUIRES` that you mount your media directories to the `WatchState` container preferably as readonly.
There is plans to add
a path replacement feature to allow you change the pathing, but it's not implemented yet.

This feature will work on both local and remote cloud storages provided they are mounted into the container. We also may recommend not to
use this feature depending on how your cloud storage provider treats file stat calls. As it might lead to unnecessary money spending. and of course
This feature will work on both local and remote cloud storages provided they are mounted into the container. We also may
recommend not to
use this feature depending on how your cloud storage provider treats file stat calls. As it might lead to unnecessary
money spending. and of course
it will be slower.

For more information about how we cache the stat calls, please refer to the [FAQ](FAQ.md#How-does-the-file-integrity-feature-works).
For more information about how we cache the stat calls, please refer to
the [FAQ](FAQ.md#How-does-the-file-integrity-feature-works).

### 2024-07-06

Expand Down Expand Up @@ -111,8 +146,10 @@ can be used. This environment variable can be enabled by setting `WS_API_AUTO=tr
### 2024-05-14

We are happy to announce the beta testing of the `WebUI`. To get started on using it you just need to visit the url `http://localhost:8080` We are supposed to
enabled it by default tomorrow, but we decided to give you a head start. We are looking forward to your feedback. If you don't use the `WebUI` then you need to
We are happy to announce the beta testing of the `WebUI`. To get started on using it you just need to visit the url
`http://localhost:8080` We are supposed to
enabled it by default tomorrow, but we decided to give you a head start. We are looking forward to your feedback. If you
don't use the `WebUI` then you need to
add the environment variable `WEBUI_ENABLED=0` in your `compose.yaml` file. and restart the container.

### 2024-05-13
Expand All @@ -128,8 +165,10 @@ Note: `WS_WEBUI_ENABLED` will be gone in few weeks, However it will still work f
### 2024-05-05

**Edit** - We received requests that people are exposing watchstate externally, and there was concern that having open
webhook endpoints might lead to abuse. As such, we have added a new environment variable `WS_SECURE_API_ENDPOINTS`. Simply set
the environment variable to `1` to secure the webhook endpoint. This means you have to add `?apikey=yourapikey` to the end
webhook endpoints might lead to abuse. As such, we have added a new environment variable `WS_SECURE_API_ENDPOINTS`.
Simply set
the environment variable to `1` to secure the webhook endpoint. This means you have to add `?apikey=yourapikey` to the
end
of the webhook endpoint.

-----
Expand Down Expand Up @@ -166,9 +205,12 @@ All commands that was accepting backend name as argument now accepts `-s, --sele
the command interface more consistent and easier to use.

Another breaking change is the removal of the `-c, --config` flag from all commands that was accepting it. This flag was
used to override the default `servers.yaml` file. This was not working as expected as there are more than just the `servers.yaml`
to consider like, the state of cache, and the state of the database. As such, we have removed this flag. However, we have
added a new environment variable called `WS_BACKENDS_FILE` which can be used to override the default `servers.yaml` file.
used to override the default `servers.yaml` file. This was not working as expected as there are more than just the
`servers.yaml`
to consider like, the state of cache, and the state of the database. As such, we have removed this flag. However, we
have
added a new environment variable called `WS_BACKENDS_FILE` which can be used to override the default `servers.yaml`
file.
We strongly recommend not to use it as it might lead to unexpected behavior.

We started working on a `Web API` which hopefully will lead to a `web frontend` to manage the tool. This is a long
Expand Down
23 changes: 7 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ out of the box, this tool support `Jellyfin`, `Plex` and `Emby` media servers.

## Updates

### 2025-01-24

We are excited to share that multi-user sync is now fully supported! Our first goal was to make sure the feature worked,
and since releasing it, we’ve worked hard to improve it based on feedback and testing. We’re now confident that it works
as expected and are happy to invite you to start using it. To learn more and get started, please check out the FAQ entry
here: [this link](FAQ.md#is-there-support-for-multi-user-setup).

### 2025-01-18

Due to popular demand, we finally have added the ability to sync all users data, however, it's limited to only
Expand All @@ -22,22 +29,6 @@ API key for jellyfin and emby. Enable the task and let it run, it will sync all

Please read the FAQ entry about it at [this link](FAQ.md#is-there-support-for-multi-user-setup).

### 2024-12-30

We have removed the old environment variables `WS_CRON_PROGRESS` and `WS_CRON_PUSH` in favor of the new ones
`WS_SYNC_PROGRESS` and `WS_PUSH_ENABLED`. please update your environment variables accordingly. We have also added
new FAQ entry about watch progress syncing via [this link](FAQ.md#sync-watch-progress).

### 2024-10-07

We have added a WebUI page for Custom GUIDs and stabilized on `v1.0` for the `guid.yaml` file spec. We strongly
recommend
to use the `WebUI` to manage the GUIDs, as it's much easier to use than editing the `guid.yaml` file directly. and both
the
`WebUI` and `API` have safeguards to prevent you from breaking the parser. For more information please check out the
associated
FAQ entry about it at [this link](FAQ.md#advanced-how-to-extend-the-guid-parser-to-support-more-guids-or-custom-ones).

---
Refer to [NEWS](NEWS.md) for old updates.

Expand Down
2 changes: 1 addition & 1 deletion config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@
SyncCommand::TASK_NAME => [
'command' => SyncCommand::ROUTE,
'name' => SyncCommand::TASK_NAME,
'info' => '[Alpha stage] Sync All users play state. Read the FAQ.',
'info' => 'Sync ALL users play state. Read the FAQ.',
'enabled' => (bool)env('WS_CRON_SYNC', false),
'timer' => $checkTaskTimer((string)env('WS_CRON_SYNC_AT', '9 */3 * * *'), '9 */3 * * *'),
'args' => env('WS_CRON_SYNC_ARGS', '-v'),
Expand Down
2 changes: 1 addition & 1 deletion src/Backends/Plex/Action/GetUserToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ private function getUserToken(Context $context, int|string $userId, string $user

$pin = ag($context->options, Options::PLEX_USER_PIN);

$this->logger->debug('Requesting temporary access token for [{backend}] user [{username}]{pin}', [
$this->logger->debug("Requesting temporary access token for '{backend}' user '{username}'{pin}", [
'backend' => $context->backendName,
'username' => $username,
'user_id' => $userId,
Expand Down
Loading

0 comments on commit 8c212c5

Please sign in to comment.