feat: Overseerr to Jellyseerr migration (#2019)

* feat: add Overseerr migration

* refactor: rename to Seerr

* refactor: more rename to Seerr

* feat: update the value of the MediaStatus.DELETED enum

* fix: add more details in migration logs

* fix: replace .update by .save for TypeORM hooks

* fix: add fake migration to skip the duplicated UpdateWebPush migration

* fix: rewrite the AddUserAvatarCacheFields migration for Overseerr merge

* fix: replace jellyseerr migrations with a dedicated one for overseerr

* fix: update overseerr migration

* fix: update overseerr migration

* fix: remove irrelevant changes

* fix: typos

* docs: update jsdoc comment

* docs: update seerr description

* docs: fix the contributing.md link

* fix: remove unwanterd change on postgres dev datasource

* docs: add latest tag to docker image

* fix: migrate old deleted status for 4k media

* fix: update Seerr version check
This commit is contained in:
Gauthier
2025-10-30 19:57:50 +01:00
committed by GitHub
parent 2e6e9ad657
commit 4e9c94c80f
60 changed files with 942 additions and 395 deletions

View File

@@ -115,7 +115,7 @@ Steps:
1. Make the necessary changes.
2. Test your changes.
3. Update the `version` in `charts/jellyseerr-chart/Chart.yaml` following [Semantic Versioning (SemVer)](https://semver.org/).
3. Update the `version` in `charts/seerr-chart/Chart.yaml` following [Semantic Versioning (SemVer)](https://semver.org/).
4. Run the `helm-docs` command to regenerate the chart's README.
### Contributing Code
@@ -162,7 +162,7 @@ If you are adding a new feature that requires a database migration, you will nee
1. Create a PostgreSQL database or use an existing one:
```bash
sudo docker run --name postgres-jellyseerr -e POSTGRES_PASSWORD=postgres -d -p 127.0.0.1:5432:5432/tcp postgres:latest
sudo docker run --name postgres-seerr -e POSTGRES_PASSWORD=postgres -d -p 127.0.0.1:5432:5432/tcp postgres:latest
```
2. Reset the SQLite database and the PostgreSQL database:
@@ -170,8 +170,8 @@ sudo docker run --name postgres-jellyseerr -e POSTGRES_PASSWORD=postgres -d -p 1
```bash
rm config/db/db.*
rm config/settings.*
PGPASSWORD=postgres sudo docker exec -it postgres-jellyseerr /usr/bin/psql -h 127.0.0.1 -U postgres -c "DROP DATABASE IF EXISTS jellyseerr;"
PGPASSWORD=postgres sudo docker exec -it postgres-jellyseerr /usr/bin/psql -h 127.0.0.1 -U postgres -c "CREATE DATABASE jellyseerr;"
PGPASSWORD=postgres sudo docker exec -it postgres-seerr /usr/bin/psql -h 127.0.0.1 -U postgres -c "DROP DATABASE IF EXISTS seerr;"
PGPASSWORD=postgres sudo docker exec -it postgres-seerr /usr/bin/psql -h 127.0.0.1 -U postgres -c "CREATE DATABASE seerr;"
```
3. Checkout the `develop` branch and create the original database for SQLite and PostgreSQL so that TypeORM can automatically generate the migrations:

View File

@@ -55,7 +55,7 @@ If `replicaCount` value was used - remove it. Helm update should work fine after
| fullnameOverride | string | `""` | |
| image.pullPolicy | string | `"IfNotPresent"` | |
| image.registry | string | `"ghcr.io"` | |
| image.repository | string | `"fallenbagel/jellyseerr"` | |
| image.repository | string | `"seerr-team/seerr"` | |
| image.sha | string | `""` | |
| image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion. |
| imagePullSecrets | list | `[]` | |

View File

@@ -1,6 +1,6 @@
image:
registry: ghcr.io
repository: fallenbagel/jellyseerr
repository: seerr-team/seerr
pullPolicy: IfNotPresent
# -- Overrides the image tag whose default is the chart appVersion.
tag: ''

View File

@@ -1,5 +1,5 @@
services:
jellyseerr:
seerr:
build:
context: .
dockerfile: Dockerfile.local
@@ -9,9 +9,9 @@ services:
DB_TYPE: 'postgres' # Which DB engine to use. The default is "sqlite". To use postgres, this needs to be set to "postgres"
DB_HOST: 'postgres' # The host (url) of the database
DB_PORT: '5432' # The port to connect to
DB_USER: 'jellyseerr' # Username used to connect to the database
DB_PASS: 'jellyseerr' # Password of the user used to connect to the database
DB_NAME: 'jellyseerr' # The name of the database to connect to
DB_USER: 'seerr' # Username used to connect to the database
DB_PASS: 'seerr' # Password of the user used to connect to the database
DB_NAME: 'seerr' # The name of the database to connect to
DB_LOG_QUERIES: 'false' # Whether to log the DB queries for debugging
DB_USE_SSL: 'false' # Whether to enable ssl for database connection
volumes:
@@ -25,9 +25,9 @@ services:
postgres:
image: postgres:18
environment:
POSTGRES_USER: jellyseerr
POSTGRES_PASSWORD: jellyseerr
POSTGRES_DB: jellyseerr
POSTGRES_USER: seerr
POSTGRES_PASSWORD: seerr
POSTGRES_DB: seerr
ports:
- '5432:5432'
volumes:

View File

@@ -1,5 +1,5 @@
services:
jellyseerr:
seerr:
build:
context: .
dockerfile: Dockerfile.local

View File

@@ -5,9 +5,9 @@ sidebar_position: 1
# Introduction
Welcome to the Jellyseerr Documentation.
Welcome to the Seerr Documentation.
**Jellyseerr** is a free and open source software application for managing requests for your media library. It integrates with the media server of your choice: [Jellyfin](https://jellyfin.org), [Plex](https://plex.tv), and [Emby](https://emby.media/). In addition, it integrates with your existing services, such as **[Sonarr](https://sonarr.tv/)**, **[Radarr](https://radarr.video/)**.
**Seerr** is a free and open source software application for managing requests for your media library. It integrates with the media server of your choice: [Jellyfin](https://jellyfin.org), [Plex](https://plex.tv), and [Emby](https://emby.media/). In addition, it integrates with your existing services, such as **[Sonarr](https://sonarr.tv/)**, **[Radarr](https://radarr.video/)**.
## Features
@@ -26,16 +26,10 @@ Welcome to the Jellyseerr Documentation.
- Easily **Watchlist** or **Blacklist** media.
- More features to come!
## Motivation
The primary motivation for starting Jellyseerr was to bring Jellyfin and Emby support to Overseerr. However, over time, **Jellyseerr** has evolved into its own distinct application with unique features. Designed as a one-stop shop for media requests, it offers a simple, easy-to-use experience for managing requests on Jellyfin, Emby, and Plex servers.
## We need your help!
[Jellyseerr](https://github.com/fallenbagel/jellyseerr) is an ambitious project where developers/contributors poured a lot of work into, and that builds on top of [Overseerr](https://github.com/sct/overseerr). And we have a lot more to do as well.
[Seerr](https://github.com/seerr-team/seerr) is an ambitious project developers/contributors poured a lot of work into, and we still have a lot more to do. Seerr is the result of a collaborative effort between the original Overseerr project and the Jellyseerr fork, created to deliver an excellent request management solution for Plex, Jellyfin and Emby users.
We value your feedback and support in identifying and fixing bugs to make Jellyseerr even better. As an open-source project, we welcome contributions from everyone. While Jellyseerr has diverged from Overseerr and evolved into its own unique application, we still encourage contributions to Overseerr, as it played a crucial role in inspiring what Jellyseerr has become today.
We value your feedback and support in identifying and fixing bugs to make Seerr even better. As an open-source project, we welcome contributions from everyone. Contribution includes building new features, patching bugs, translating the application, or even just writing documentation.
Contribution includes building new features, patching bugs, translating the application, or even just writing documentation.
If you would like to contribute, please be sure to review our [contribution guidelines](https://github.com/fallenbagel/jellyseerr/blob/develop/CONTRIBUTING.md).
If you would like to contribute, please be sure to review our [contribution guidelines](https://github.com/seerr-team/seerr/blob/develop/CONTRIBUTING.md).

View File

@@ -1,9 +0,0 @@
{
"label": "Extending Jellyseerr",
"position": 3,
"link": {
"type": "generated-index",
"title": "Extending Jellyseerr",
"description": "Extend Jellyseerr to your liking"
}
}

View File

@@ -0,0 +1,9 @@
{
"label": "Extending Seerr",
"position": 3,
"link": {
"type": "generated-index",
"title": "Extending Seerr",
"description": "Extend Seerr to your liking"
}
}

View File

@@ -1,11 +1,11 @@
---
title: Configuring the Database (Advanced)
description: Configure the database for Jellyseerr
description: Configure the database for Seerr
sidebar_position: 2
---
# Configuring the Database
Jellyseerr supports SQLite and PostgreSQL. The database connection can be configured using the following environment variables:
Seerr supports SQLite and PostgreSQL. The database connection can be configured using the following environment variables:
## SQLite Options
@@ -34,7 +34,7 @@ DB_HOST="localhost" # (optional) The host (URL) of the database. The default is
DB_PORT="5432" # (optional) The port to connect to. The default is "5432".
DB_USER= # (required) Username used to connect to the database.
DB_PASS= # (required) Password of the user used to connect to the database.
DB_NAME="jellyseerr" # (optional) The name of the database to connect to. The default is "jellyseerr".
DB_NAME="seerr" # (optional) The name of the database to connect to. The default is "seerr".
DB_LOG_QUERIES="false" # (optional) Whether to log the DB queries for debugging. The default is "false".
```
@@ -47,7 +47,7 @@ DB_TYPE=postgres # Which DB engine to use, either sqlite or postgres. The defaul
DB_SOCKET_PATH="/var/run/postgresql" # (required) The path to the PostgreSQL Unix socket directory.
DB_USER= # (required) Username used to connect to the database.
DB_PASS= # (optional) Password of the user used to connect to the database, depending on the server's authentication configuration.
DB_NAME="jellyseerr" # (optional) The name of the database to connect to. The default is "jellyseerr".
DB_NAME="seerr" # (optional) The name of the database to connect to. The default is "seerr".
DB_LOG_QUERIES="false" # (optional) Whether to log the DB queries for debugging. The default is "false".
```
@@ -91,9 +91,9 @@ DB_SSL_CERT_FILE= # (optional) Path to certificate chain in pem format for the p
### Migrating from SQLite to PostgreSQL
1. Set up your PostgreSQL database and configure Jellyseerr to use it
2. Run Jellyseerr to create the tables in the PostgreSQL database
3. Stop Jellyseerr
1. Set up your PostgreSQL database and configure Seerr to use it
2. Run Seerr to create the tables in the PostgreSQL database
3. Stop Seerr
4. Run the following command to export the data from the SQLite database and import it into the PostgreSQL database:
:::info
@@ -112,7 +112,7 @@ import TabItem from '@theme/TabItem';
<Tabs>
<TabItem value="docker" label="Using pgloader Container (Recommended)" default>
**Recommended method**: Use the pgloader container even for standalone Jellyseerr installations. This avoids building from source and ensures compatibility.
**Recommended method**: Use the pgloader container even for standalone Seerr installations. This avoids building from source and ensures compatibility.
```bash
# For standalone installations (no Docker network needed)
@@ -126,7 +126,7 @@ docker run --rm \
**For Docker Compose setups**: Add the network parameter if your PostgreSQL is also in a container:
```bash
docker run --rm \
--network your-jellyseerr-network \
--network your-seerr-network \
-v /path/to/your/config/db.sqlite3:/db.sqlite3:ro \
ghcr.io/ralgar/pgloader:pr-1531 \
pgloader --with "quote identifiers" --with "data only" \
@@ -167,4 +167,4 @@ Once pgloader is built, run the migration:
</TabItem>
</Tabs>
5. Start Jellyseerr
5. Start Seerr

View File

@@ -1,13 +1,13 @@
---
title: Reverse Proxy
description: Configure a reverse proxy for Jellyseerr.
description: Configure a reverse proxy for Seerr.
sidebar_position: 1
---
# Reverse Proxy
:::warning
Base URLs cannot be configured in Jellyseerr. With this limitation, only subdomain configurations are supported.
Base URLs cannot be configured in Seerr. With this limitation, only subdomain configurations are supported.
A Nginx subfolder workaround configuration is provided below, but it is not officially supported.
:::
@@ -19,21 +19,21 @@ import TabItem from '@theme/TabItem';
<Tabs groupId="nginx-reverse-proxy" queryString>
<TabItem value="subdomain" label="Subdomain">
Add the following configuration to a new file `/etc/nginx/sites-available/jellyseerr.example.com.conf`:
Add the following configuration to a new file `/etc/nginx/sites-available/seerr.example.com.conf`:
```nginx
server {
listen 80;
server_name jellyseerr.example.com;
server_name seerr.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name jellyseerr.example.com;
server_name seerr.example.com;
ssl_certificate /etc/letsencrypt/live/jellyseerr.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/jellyseerr.example.com/privkey.pem;
ssl_certificate /etc/letsencrypt/live/seerr.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/seerr.example.com/privkey.pem;
proxy_set_header Referer $http_referer;
proxy_set_header Host $host;
@@ -55,7 +55,7 @@ server {
Then, create a symlink to `/etc/nginx/sites-enabled`:
```bash
sudo ln -s /etc/nginx/sites-available/jellyseerr.example.com.conf /etc/nginx/sites-enabled/jellyseerr.example.com.conf
sudo ln -s /etc/nginx/sites-available/seerr.example.com.conf /etc/nginx/sites-enabled/seerr.example.com.conf
```
</TabItem>
@@ -63,19 +63,19 @@ sudo ln -s /etc/nginx/sites-available/jellyseerr.example.com.conf /etc/nginx/sit
<TabItem value="subfolder" label="Subfolder">
:::warning
This Nginx subfolder reverse proxy is an unsupported workaround, and only provided as an example. The filters may stop working when Jellyseerr is updated.
This Nginx subfolder reverse proxy is an unsupported workaround, and only provided as an example. The filters may stop working when Seerr is updated.
If you encounter any issues with Jellyseerr while using this workaround, we may ask you to try to reproduce the problem without the Nginx proxy.
If you encounter any issues with Seerr while using this workaround, we may ask you to try to reproduce the problem without the Nginx proxy.
:::
Add the following location block to your existing `nginx.conf` file.
```nginx
location ^~ /jellyseerr {
set $app 'jellyseerr';
location ^~ /seerr {
set $app 'seerr';
# Remove /jellyseerr path to pass to the app
rewrite ^/jellyseerr/?(.*)$ /$1 break;
# Remove /seerr path to pass to the app
rewrite ^/seerr/?(.*)$ /$1 break;
proxy_pass http://127.0.0.1:5055; # NO TRAILING SLASH
# Redirect location headers
@@ -113,16 +113,16 @@ A sample proxy configuration is included in [SWAG (Secure Web Application Gatewa
However, this page is still the only source of truth, so the SWAG sample configuration is not guaranteed to be up-to-date. If you find an inconsistency, please [report it to the LinuxServer team](https://github.com/linuxserver/reverse-proxy-confs/issues/new) or [submit a pull request to update it](https://github.com/linuxserver/reverse-proxy-confs/pulls).
To use the bundled configuration file, simply rename `jellyseerr.subdomain.conf.sample` in the `proxy-confs` folder to `jellyseerr.subdomain.conf`.
To use the bundled configuration file, simply rename `seerr.subdomain.conf.sample` in the `proxy-confs` folder to `seerr.subdomain.conf`.
Alternatively, you can create a new file `jellyseerr.subdomain.conf` in `proxy-confs` with the following configuration:
Alternatively, you can create a new file `seerr.subdomain.conf` in `proxy-confs` with the following configuration:
```nginx
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name jellyseerr.*;
server_name seerr.*;
include /config/nginx/ssl.conf;
@@ -131,7 +131,7 @@ server {
location / {
include /config/nginx/proxy.conf;
resolver 127.0.0.11 valid=30s;
set $upstream_app jellyseerr;
set $upstream_app seerr;
set $upstream_port 5055;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
@@ -148,9 +148,9 @@ Add a new proxy host with the following settings:
### Details
- **Domain Names:** Your desired external Jellyseerr hostname; e.g., `jellyseerr.example.com`
- **Domain Names:** Your desired external Seerr hostname; e.g., `seerr.example.com`
- **Scheme:** `http`
- **Forward Hostname / IP:** Internal Jellyseerr hostname or IP
- **Forward Hostname / IP:** Internal Seerr hostname or IP
- **Forward Port:** `5055`
- **Cache Assets:** yes
- **Block Common Exploits:** yes
@@ -172,7 +172,7 @@ Then, click “Save” and “Apply Changes”.
Create a Caddyfile with the following content:
```caddyfile
jellyseerr.example.com {
seerr.example.com {
reverse_proxy http://127.0.0.1:5055
}
```
@@ -184,7 +184,7 @@ Deploy the Caddyfile by running:
sudo caddy run --config /path/to/Caddyfile
```
Verify by visiting https://jellyseerr.example.com in your browser.
Verify by visiting https://seerr.example.com in your browser.
:::note
Caddy will automatically obtain and renew SSL certificates for your domain.
@@ -192,18 +192,18 @@ Caddy will automatically obtain and renew SSL certificates for your domain.
## Traefik (v2)
Add the following labels to the Jellyseerr service in your `compose.yaml` file:
Add the following labels to the Seerr service in your `compose.yaml` file:
```yaml
labels:
- 'traefik.enable=true'
## HTTP Routers
- 'traefik.http.routers.jellyseerr-rtr.entrypoints=https'
- 'traefik.http.routers.jellyseerr-rtr.rule=Host(`jellyseerr.domain.com`)'
- 'traefik.http.routers.jellyseerr-rtr.tls=true'
- 'traefik.http.routers.seerr-rtr.entrypoints=https'
- 'traefik.http.routers.seerr-rtr.rule=Host(`seerr.domain.com`)'
- 'traefik.http.routers.seerr-rtr.tls=true'
## HTTP Services
- 'traefik.http.routers.jellyseerr-rtr.service=jellyseerr-svc'
- 'traefik.http.services.jellyseerr-svc.loadbalancer.server.port=5055'
- 'traefik.http.routers.seerr-rtr.service=seerr-svc'
- 'traefik.http.services.seerr-svc.loadbalancer.server.port=5055'
```
For more information, please refer to the [Traefik documentation](https://doc.traefik.io/traefik/user-guides/docker-compose/basic-example/).
@@ -216,7 +216,7 @@ For more information, please refer to the [Traefik documentation](https://doc.tr
Add the following Location block to your existing Server configuration.
```apache
# Jellyseerr
# Seerr
ProxyPreserveHost On
ProxyPass / http://localhost:5055 retry=0 connectiontimeout=5 timeout=30 keepalive=on
ProxyPassReverse http://localhost:5055 /
@@ -228,18 +228,18 @@ Add the following Location block to your existing Server configuration.
<TabItem value="subfolder" label="Subfolder">
:::warning
This Apache2 subfolder reverse proxy is an unsupported workaround, and only provided as an example. The filters may stop working when Jellyseerr is updated.
This Apache2 subfolder reverse proxy is an unsupported workaround, and only provided as an example. The filters may stop working when Seerr is updated.
If you encounter any issues with Jellyseerr while using this workaround, we may ask you to try to reproduce the problem without the Apache2 proxy.
If you encounter any issues with Seerr while using this workaround, we may ask you to try to reproduce the problem without the Apache2 proxy.
:::
Add the following Location block to your existing Server configuration.
```apache
# Jellyseerr
# We will use "/jellyseerr" as subfolder
# Seerr
# We will use "/seerr" as subfolder
# You can replace it with any that you like
<Location /jellyseerr>
<Location /seerr>
ProxyPreserveHost On
ProxyPass http://localhost:5055 retry=0 connectiontimeout=5 timeout=30 keepalive=on
ProxyPassReverse http://localhost:5055
@@ -247,19 +247,19 @@ Add the following Location block to your existing Server configuration.
# Header update, to support subfolder
# Please Replace "FQDN" with your domain
Header edit location ^/login https://FQDN/jellyseerr/login
Header edit location ^/setup https://FQDN/jellyseerr/setup
Header edit location ^/login https://FQDN/seerr/login
Header edit location ^/setup https://FQDN/seerr/setup
AddOutputFilterByType INFLATE;SUBSTITUTE text/html application/javascript application/json
SubstituteMaxLineLength 2000K
# This is HTML and JS update
# Please update "/jellyseerr" if needed
Substitute "s|href=\"|href=\"/jellyseerr|inq"
Substitute "s|src=\"|src=\"/jellyseerr|inq"
Substitute "s|/api/|/jellyseerr/api/|inq"
Substitute "s|\"/_next/|\"/jellyseerr/_next/|inq"
# Please update "/seerr" if needed
Substitute "s|href=\"|href=\"/seerr|inq"
Substitute "s|src=\"|src=\"/seerr|inq"
Substitute "s|/api/|/seerr/api/|inq"
Substitute "s|\"/_next/|\"/seerr/_next/|inq"
# This is JSON update
Substitute "s|\"/avatarproxy/|\"/jellyseerr/avatarproxy/|inq"
Substitute "s|\"/avatarproxy/|\"/seerr/avatarproxy/|inq"
</Location>
```

View File

@@ -1,13 +1,13 @@
---
title: Build From Source (Advanced)
description: Install Jellyseerr by building from source
description: Install Seerr by building from source
sidebar_position: 2
---
# Build from Source (Advanced)
:::warning
This method is not recommended for most users. It is intended for advanced users who are familiar with managing their own server infrastructure.
Refer to [Configuring Databases](/extending-jellyseerr/database-config#postgresql-options) for details on how to configure your database.
Refer to [Configuring Databases](/extending-seerr/database-config#postgresql-options) for details on how to configure your database.
:::
import Tabs from '@theme/Tabs';
@@ -20,11 +20,11 @@ import TabItem from '@theme/TabItem';
## Unix (Linux, macOS)
### Installation
1. Assuming you want the working directory to be `/opt/jellyseerr`, create the directory and navigate to it:
1. Assuming you want the working directory to be `/opt/seerr`, create the directory and navigate to it:
```bash
sudo mkdir -p /opt/jellyseerr && cd /opt/jellyseerr
sudo mkdir -p /opt/seerr && cd /opt/seerr
```
2. Clone the Jellyseerr repository and checkout the develop branch:
2. Clone the Seerr repository and checkout the develop branch:
```bash
git clone https://github.com/fallenbagel/jellyseerr.git
cd jellyseerr
@@ -38,26 +38,26 @@ CYPRESS_INSTALL_BINARY=0 pnpm install --frozen-lockfile
```bash
pnpm build
```
5. Start Jellyseerr:
5. Start Seerr:
```bash
pnpm start
```
:::info
You can now access Jellyseerr by visiting `http://localhost:5055` in your web browser.
You can now access Seerr by visiting `http://localhost:5055` in your web browser.
:::
#### Extending the installation
<Tabs groupId="unix-extensions" queryString>
<TabItem value="linux" label="Linux">
To run jellyseerr as a systemd service:
1. create the environment file at `/etc/jellyseerr/jellyseerr.conf`:
To run seerr as a systemd service:
1. create the environment file at `/etc/seerr/seerr.conf`:
```bash
## Jellyseerr's default port is 5055, if you want to use both, change this.
## Seerr's default port is 5055, if you want to use both, change this.
## specify on which port to listen
PORT=5055
## specify on which interface to listen, by default jellyseerr listens on all interfaces
## specify on which interface to listen, by default seerr listens on all interfaces
#HOST=127.0.0.1
## Uncomment if you want to force Node.js to resolve IPv4 before IPv6 (advanced users only)
@@ -69,19 +69,19 @@ which node
```
Copy the path to node, it should be something like `/usr/bin/node`.
3. Create the systemd service file at `/etc/systemd/system/jellyseerr.service`, using either `sudo systemctl edit jellyseerr` or `sudo nano /etc/systemd/system/jellyseerr.service`:
3. Create the systemd service file at `/etc/systemd/system/seerr.service`, using either `sudo systemctl edit seerr` or `sudo nano /etc/systemd/system/seerr.service`:
```bash
[Unit]
Description=Jellyseerr Service
Description=Seerr Service
Wants=network-online.target
After=network-online.target
[Service]
EnvironmentFile=/etc/jellyseerr/jellyseerr.conf
EnvironmentFile=/etc/seerr/seerr.conf
Environment=NODE_ENV=production
Type=exec
Restart=on-failure
WorkingDirectory=/opt/jellyseerr
WorkingDirectory=/opt/seerr
ExecStart=/usr/bin/node dist/index.js
[Install]
@@ -93,33 +93,33 @@ If you are using a different path to node, replace `/usr/bin/node` with the path
4. Enable and start the service:
```bash
sudo systemctl enable jellyseerr
sudo systemctl start jellyseerr
sudo systemctl enable seerr
sudo systemctl start seerr
```
</TabItem>
<TabItem value="macos" label="macOS">
To run jellyseerr as a launchd service:
To run seerr as a launchd service:
1. Find the path to node:
```bash
which node
```
Copy the path to node, it should be something like `/usr/local/bin/node`.
2. Create a launchd plist file at `~/Library/LaunchAgents/com.jellyseerr.plist`:
2. Create a launchd plist file at `~/Library/LaunchAgents/com.seerr.plist`:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.jellyseerr</string>
<string>com.seerr</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/node</string>
<string>/opt/jellyseerr/dist/index.js</string>
<string>/opt/seerr/dist/index.js</string>
</array>
<key>WorkingDirectory</key>
<string>/opt/jellyseerr</string>
<string>/opt/seerr</string>
<key>EnvironmentVariables</key>
<dict>
<key>NODE_ENV</key>
@@ -139,11 +139,11 @@ If you are using a different path to node, replace `/usr/local/bin/node` with th
:::
3. Load the service:
```bash
sudo launchctl load ~/Library/LaunchAgents/com.jellyseerr.plist
sudo launchctl load ~/Library/LaunchAgents/com.seerr.plist
```
3. Start the service:
```bash
sudo launchctl start com.jellyseerr
sudo launchctl start com.seerr
```
4. To ensure the service starts on boot, run the following command:
```bash
@@ -151,14 +151,14 @@ sudo lauchctl load
```
</TabItem>
<TabItem value="pm2" label="PM2">
To run jellyseerr as a PM2 service:
To run seerr as a PM2 service:
1. Install PM2:
```bash
npm install -g pm2
```
2. Start jellyseerr with PM2:
2. Start seerr with PM2:
```bash
pm2 start dist/index.js --name jellyseerr --node-args="--NODE_ENV=production"
pm2 start dist/index.js --name seerr --node-args="--NODE_ENV=production"
```
3. Save the process list:
```bash
@@ -171,35 +171,35 @@ pm2 startup
**Managing the service**
- To start the service:
```powershell
pm2 start jellyseerr
pm2 start seerr
```
- To stop the service:
```powershell
pm2 stop jellyseerr
pm2 stop seerr
```
- To restart the service:
```powershell
pm2 restart jellyseerr
pm2 restart seerr
```
- To view the logs:
```powershell
pm2 logs jellyseerr
pm2 logs seerr
```
- To view the status:
```powershell
pm2 status jellyseerr
pm2 status seerr
```
</TabItem>
</Tabs>
## Windows
### Installation
1. Assuming you want the working directory to be `C:\jellyseerr`, create the directory and navigate to it:
1. Assuming you want the working directory to be `C:\seerr`, create the directory and navigate to it:
```powershell
mkdir C:\jellyseerr
cd C:\jellyseerr
mkdir C:\seerr
cd C:\seerr
```
2. Clone the Jellyseerr repository and checkout the develop branch:
2. Clone the Seerr repository and checkout the develop branch:
```powershell
git clone https://github.com/fallenbagel/jellyseerr.git .
git checkout main
@@ -213,24 +213,24 @@ set CYPRESS_INSTALL_BINARY=0 && pnpm install --frozen-lockfile
```powershell
pnpm build
```
5. Start Jellyseerr:
5. Start Seerr:
```powershell
pnpm start
```
:::tip
You can add the environment variables to a `.env` file in the Jellyseerr directory.
You can add the environment variables to a `.env` file in the Seerr directory.
:::
:::info
You can now access Jellyseerr by visiting `http://localhost:5055` in your web browser.
You can now access Seerr by visiting `http://localhost:5055` in your web browser.
:::
#### Extending the installation
<Tabs groupId="windows-extensions" queryString>
<TabItem value="task-scheduler" label="Task Scheduler">
To run jellyseerr as a bat script:
1. Create a file named `start-jellyseerr.bat` in the jellyseerr directory:
To run seerr as a bat script:
1. Create a file named `start-seerr.bat` in the seerr directory:
```bat
@echo off
set PORT=5055
@@ -240,43 +240,43 @@ node dist/index.js
2. Create a task in Task Scheduler:
- Open Task Scheduler
- Click on "Create Basic Task"
- Name the task "Jellyseerr"
- Name the task "Seerr"
- Set the trigger to "When the computer starts"
- Set the action to "Start a program"
- Set the program/script to the path of the `start-jellyseerr.bat` file
- Set the "Start in" to the jellyseerr directory.
- Set the program/script to the path of the `start-seerr.bat` file
- Set the "Start in" to the seerr directory.
- Click "Finish"
Now, Jellyseerr will start when the computer boots up in the background.
Now, Seerr will start when the computer boots up in the background.
</TabItem>
<TabItem value="nssm" label="NSSM">
To run jellyseerr as a service:
To run seerr as a service:
1. Download the [Non-Sucking Service Manager](https://nssm.cc/download)
2. Install NSSM:
```powershell
nssm install Jellyseerr "C:\Program Files\nodejs\node.exe" "C:\jellyseerr\dist\index.js"
nssm set Jellyseerr AppDirectory "C:\jellyseerr"
nssm set Jellyseerr AppEnvironmentExtra NODE_ENV=production
nssm install Seerr "C:\Program Files\nodejs\node.exe" "C:\seerr\dist\index.js"
nssm set Seerr AppDirectory "C:\seerr"
nssm set Seerr AppEnvironmentExtra NODE_ENV=production
```
3. Start the service:
```powershell
nssm start Jellyseerr
nssm start Seerr
```
4. To ensure the service starts on boot, run the following command:
```powershell
nssm set Jellyseerr Start SERVICE_AUTO_START
nssm set Seerr Start SERVICE_AUTO_START
```
</TabItem>
<TabItem value="pm2" label="PM2">
To run jellyseerr as a PM2 service:
To run seerr as a PM2 service:
1. Install PM2:
```powershell
npm install -g pm2
```
2. Start jellyseerr with PM2:
2. Start seerr with PM2:
```powershell
pm2 start dist/index.js --name jellyseerr --node-args="--NODE_ENV=production"
pm2 start dist/index.js --name seerr --node-args="--NODE_ENV=production"
```
3. Save the process list:
```powershell
@@ -289,31 +289,31 @@ pm2 startup
##### Managing the service
- To start the service:
```powershell
pm2 start jellyseerr
pm2 start seerr
```
- To stop the service:
```powershell
pm2 stop jellyseerr
pm2 stop seerr
```
- To restart the service:
```powershell
pm2 restart jellyseerr
pm2 restart seerr
```
- To view the logs:
```powershell
pm2 logs jellyseerr
pm2 logs seerr
```
- To view the status:
```powershell
pm2 status jellyseerr
pm2 status seerr
```
</TabItem>
</Tabs>
### Updating
To update Jellyseerr, navigate to the Jellyseerr directory and run the following commands:
To update Seerr, navigate to the Seerr directory and run the following commands:
```bash
git pull
```
Then, follow the steps in the installation section to rebuild and restart Jellyseerr.
Then, follow the steps in the installation section to rebuild and restart Seerr.

View File

@@ -1,6 +1,6 @@
---
title: Docker (Recommended)
description: Install Jellyseerr using Docker
description: Install Seerr using Docker
sidebar_position: 1
---
# Docker
@@ -8,7 +8,7 @@ sidebar_position: 1
This is the recommended method for most users.
Details on how to install Docker can be found on the [official Docker website](https://docs.docker.com/get-docker/).
Refer to [Configuring Databases](/extending-jellyseerr/database-config#postgresql-options) for details on how to configure your database.
Refer to [Configuring Databases](/extending-seerr/database-config#postgresql-options) for details on how to configure your database.
:::
:::info
@@ -23,7 +23,7 @@ To confirm that the container image you are using is authentic and unmodified, p
## Unix (Linux, macOS)
:::warning
Be sure to replace `/path/to/appdata/config` in the below examples with a valid host directory path. If this volume mount is not configured correctly, your Jellyseerr settings/data will not be persisted when the container is recreated (e.g., when updating the image or rebooting your machine).
Be sure to replace `/path/to/appdata/config` in the below examples with a valid host directory path. If this volume mount is not configured correctly, your Seerr settings/data will not be persisted when the container is recreated (e.g., when updating the image or rebooting your machine).
The `TZ` environment variable value should also be set to the [TZ database name](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) of your time zone!
@@ -40,7 +40,7 @@ For details on the Docker CLI, please [review the official `docker run` document
```bash
docker run -d \
--name jellyseerr \
--name seerr \
--init \
-e LOG_LEVEL=debug \
-e TZ=Asia/Tashkent \
@@ -48,7 +48,7 @@ docker run -d \
-p 5055:5055 \
-v /path/to/appdata/config:/app/config \
--restart unless-stopped \
ghcr.io/fallenbagel/jellyseerr:latest
ghcr.io/seerr-team/seerr:latest
```
The argument `-e PORT=5055` is optional.
@@ -68,11 +68,11 @@ To run the container as a specific user/group, you may optionally add `--user=[
Stop and remove the existing container:
```bash
docker stop jellyseerr && docker rm jellyseerr
docker stop seerr && docker rm seerr
```
Pull the latest image:
```bash
docker pull ghcr.io/fallenbagel/jellyseerr:latest
docker pull ghcr.io/seerr-team/seerr:latest
```
Finally, run the container with the same parameters originally used to create the container:
```bash
@@ -80,7 +80,7 @@ docker run -d ...
```
:::tip
You may alternatively use a third-party updating mechanism, such as [Watchtower](https://github.com/containrrr/watchtower) or [Ouroboros](https://github.com/pyouroboros/ouroboros), to keep Jellyseerr up-to-date automatically.
You may alternatively use a third-party updating mechanism, such as [Watchtower](https://github.com/containrrr/watchtower) or [Ouroboros](https://github.com/pyouroboros/ouroboros), to keep Seerr up-to-date automatically.
You could also use [diun](https://github.com/crazy-max/diun) to receive notifications when a new image is available.
:::
@@ -90,14 +90,14 @@ You could also use [diun](https://github.com/crazy-max/diun) to receive notifica
For details on how to use Docker Compose, please [review the official Compose documentation](https://docs.docker.com/compose/reference/).
#### Installation:
Define the `jellyseerr` service in your `compose.yaml` as follows:
Define the `seerr` service in your `compose.yaml` as follows:
```yaml
---
services:
jellyseerr:
image: ghcr.io/fallenbagel/jellyseerr:latest
seerr:
image: ghcr.io/seerr-team/seerr:latest
init: true
container_name: jellyseerr
container_name: seerr
environment:
- LOG_LEVEL=debug
- TZ=Asia/Tashkent
@@ -123,7 +123,7 @@ docker compose up -d
#### Updating:
Pull the latest image:
```bash
docker compose pull jellyseerr
docker compose pull seerr
```
Then, restart all services defined in the Compose file:
```bash
@@ -142,31 +142,31 @@ Please refer to the [Docker Desktop for Windows user manual](https://docs.docker
**WSL2 will need to be installed to prevent DB corruption!** Please see the [Docker Desktop WSL 2 backend documentation](https://docs.docker.com/docker-for-windows/wsl/) for instructions on how to enable WSL2. The commands below will only work with WSL2 installed!
:::
First, create a volume to store the configuration data for Jellyseerr using using either the Docker CLI:
First, create a volume to store the configuration data for Seerr using using either the Docker CLI:
```bash
docker volume create jellyseerr-data
docker volume create seerr-data
```
or the Docker Desktop app:
1. Open the Docker Desktop app
2. Head to the Volumes tab
3. Click on the "New Volume" button near the top right
4. Enter a name for the volume (example: `jellyseerr-data`) and hit "Create"
4. Enter a name for the volume (example: `seerr-data`) and hit "Create"
Then, create and start the Jellyseerr container:
Then, create and start the Seerr container:
<Tabs groupId="docker-methods" queryString>
<TabItem value="docker-cli" label="Docker CLI">
```bash
docker run -d \
--name jellyseerr \
--name seerr \
--init \
-e LOG_LEVEL=debug \
-e TZ=Asia/Tashkent \
-e PORT=5055 \
-p 5055:5055 \
-v jellyseerr-data:/app/config \
-v seerr-data:/app/config \
--restart unless-stopped \
ghcr.io/fallenbagel/jellyseerr:latest
ghcr.io/seerr-team/seerr:latest
```
The argument `-e PORT=5055` is optional.
@@ -183,7 +183,7 @@ If you want to add a healthcheck to the above command, you can add the following
#### Updating:
Pull the latest image:
```bash
docker compose pull jellyseerr
docker compose pull seerr
```
Then, restart all services defined in the Compose file:
```bash
@@ -195,17 +195,17 @@ docker compose up -d
```yaml
---
services:
jellyseerr:
image: ghcr.io/fallenbagel/jellyseerr:latest
seerr:
image: ghcr.io/seerr-team/seerr:latest
init: true
container_name: jellyseerr
container_name: seerr
environment:
- LOG_LEVEL=debug
- TZ=Asia/Tashkent
ports:
- 5055:5055
volumes:
- jellyseerr-data:/app/config
- seerr-data:/app/config
healthcheck:
test: wget --no-verbose --tries=1 --spider http://localhost:5055/api/v1/status || exit 1
start_period: 20s
@@ -215,14 +215,14 @@ services:
restart: unless-stopped
volumes:
jellyseerr-data:
seerr-data:
external: true
```
#### Updating:
Pull the latest image:
```bash
docker compose pull jellyseerr
docker compose pull seerr
```
Then, restart all services defined in the Compose file:
```bash
@@ -231,7 +231,7 @@ docker compose up -d
</TabItem>
</Tabs>
To access the files inside the volume created above, navigate to `\\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes\jellyseerr-data\_data` using File Explorer.
To access the files inside the volume created above, navigate to `\\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes\seerr-data\_data` using File Explorer.
:::info
Docker on Windows works differently than it does on Linux; it runs Docker inside of a stripped-down Linux VM. Volume mounts are exposed to Docker inside this VM via SMB mounts. While this is fine for media, it is unacceptable for the `/app/config` directory because SMB does not support file locking. This will eventually corrupt your database, which can lead to slow behavior and crashes.

View File

@@ -4,7 +4,7 @@ title: Getting Started
import DocCardList from '@theme/DocCardList';
:::info
After running Jellyseerr for the first time, configure it by visiting the web UI at `http://[address]:5055` and completing the setup steps.
After running Seerr for the first time, configure it by visiting the web UI at `http://[address]:5055` and completing the setup steps.
:::
<DocCardList />

View File

@@ -16,12 +16,12 @@ To confirm that the chart you are using is authentic and unmodified, please refe
## Installation
```console
helm install jellyseerr oci://ghcr.io/fallenbagel/jellyseerr/jellyseerr-chart
helm install seerr oci://ghcr.io/seerr-team/seerr/seerr-chart
```
Helm values can be found in the Jellyseerr repository under [charts/jellyseerr-chart/README.md](https://github.com/fallenbagel/jellyseerr/tree/develop/charts/jellyseerr-chart).
Verify the signature with [cosign](https://docs.sigstore.dev/cosign/system_config/installation/) (replace [tag], with the TAG you want to verify) :
```console
cosign verify ghcr.io/fallenbagel/jellyseerr/jellyseerr-chart:[tag] --certificate-identity=https://github.com/fallenbagel/jellyseerr/.github/workflows/helm.yml@refs/heads/main --certificate-oidc-issuer=https://token.ac
cosign verify ghcr.io/seerr-team/seerr/seerr-chart:[tag] --certificate-identity=https://github.com/fallenbagel/jellyseerr/.github/workflows/helm.yml@refs/heads/main --certificate-oidc-issuer=https://token.ac
tions.githubusercontent.com
```

View File

@@ -1,6 +1,6 @@
---
title: AUR (Advanced)
description: Install Jellyseerr using the Arch User Repository
description: Install Seerr using the Arch User Repository
sidebar_position: 2
---
@@ -15,7 +15,7 @@ This method is not recommended for most users. It is intended for advanced users
## Installation
To install Jellyseerr from the AUR, you can use an AUR helper like `yay` or `paru`:
To install Seerr from the AUR, you can use an AUR helper like `yay` or `paru`:
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
@@ -23,20 +23,20 @@ import TabItem from '@theme/TabItem';
<Tabs groupId="aur-methods" queryString>
<TabItem value="yay" label="yay">
```bash
yay -S jellyseerr
yay -S seerr
```
</TabItem>
<TabItem value="paru" label="paru">
```bash
paru -S jellyseerr
paru -S seerr
```
</TabItem>
</Tabs>
:::info
After installing Jellyseerr, configure it by visiting the web UI at `http://[address]:5055` and completing the setup steps.
After installing Seerr, configure it by visiting the web UI at `http://[address]:5055` and completing the setup steps.
:::
:::tip
You can find the environment file at `/etc/conf.d/jellyseerr` and the service file at `/etc/systemd/system/jellyseerr.service`.
You can find the environment file at `/etc/conf.d/seerr` and the service file at `/etc/systemd/system/seerr.service`.
:::

View File

@@ -1,10 +1,10 @@
---
title: Nix Package Manager (Advanced)
description: Install Jellyseerr using Nixpkgs
description: Install Seerr using Nixpkgs
sidebar_position: 1
---
import { JellyseerrVersion, NixpkgVersion } from '@site/src/components/JellyseerrVersion';
import { SeerrVersion, NixpkgVersion } from '@site/src/components/SeerrVersion';
import Admonition from '@theme/Admonition';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

View File

@@ -1,6 +1,6 @@
---
title: Unraid (Advanced)
description: Install Jellyseerr using Unraid
description: Install Seerr using Unraid
sidebar_position: 3
---
@@ -14,7 +14,7 @@ This method is not recommended for most users. It is intended for advanced users
:::
1. Ensure you have the **Community Applications** plugin installed.
2. Inside the **Community Applications** app store, search for **Jellyseerr**.
2. Inside the **Community Applications** app store, search for **Seerr**.
3. Click the **Install Button**.
4. On the following **Add Container** screen, make changes to the **Host Port** and **Host Path 1** \(Appdata\) as needed.
5. Click apply and access "Jellyseerr" at your `<ServerIP:HostPort>` in a web browser.
5. Click apply and access "Seerr" at your `<ServerIP:HostPort>` in a web browser.

View File

@@ -39,7 +39,7 @@ Add the following to your `compose.yaml` to use Google's DNS:
```yaml
---
services:
jellyseerr:
seerr:
dns:
- 8.8.8.8
```
@@ -47,7 +47,7 @@ or for Cloudflare's DNS:
```yaml
---
services:
jellyseerr:
seerr:
dns:
- 1.1.1.1
```
@@ -55,7 +55,7 @@ or for Quad9's DNS:
```yaml
---
services:
jellyseerr:
seerr:
dns:
- 9.9.9.9
```
@@ -97,19 +97,19 @@ You can try them all and see which one works for your network.
</TabItem>
</Tabs>
### Option 2: Use Jellyseerr through a proxy
### Option 2: Use Seerr through a proxy
If you can't change your DNS servers or force IPV4 resolution, you can use Jellyseerr through a proxy.
If you can't change your DNS servers or force IPV4 resolution, you can use Seerr through a proxy.
In some places (like China), the ISP blocks not only the DNS resolution but also the connection to the TMDB API.
You can configure Jellyseerr to use a proxy with the [HTTP(S) Proxy](/using-jellyseerr/settings/general#enable-proxy-support) setting.
You can configure Seerr to use a proxy with the [HTTP(S) Proxy](/using-seerr/settings/general#enable-proxy-support) setting.
### Option 3: Force IPV4 resolution first
Sometimes there are configuration issues with IPV6 that prevent the hostname resolution from working correctly.
You can try to force the resolution to use IPV4 first by going to `Settings > Networking > Advanced Networking` and enabling `Force IPv4 Resolution First` setting and restarting Jellyseerr.
You can try to force the resolution to use IPV4 first by going to `Settings > Networking > Advanced Networking` and enabling `Force IPv4 Resolution First` setting and restarting Seerr.
### Option 4: Check that your server can reach TMDB API
@@ -119,7 +119,7 @@ Make sure that your server can reach the TMDB API by running the following comma
<TabItem value="docker-cli" label="Docker CLI">
```bash
docker exec -it jellyseerr sh -c "apk update && apk add curl && curl -L https://api.themoviedb.org"
docker exec -it seerr sh -c "apk update && apk add curl && curl -L https://api.themoviedb.org"
```
</TabItem>
@@ -127,7 +127,7 @@ docker exec -it jellyseerr sh -c "apk update && apk add curl && curl -L https://
<TabItem value="docker-compose" label="Docker Compose">
```bash
docker compose exec jellyseerr sh -c "apk update && apk add curl && curl -L https://api.themoviedb.org"
docker compose exec seerr sh -c "apk update && apk add curl && curl -L https://api.themoviedb.org"
```
</TabItem>
@@ -161,16 +161,16 @@ This can happen if you have a new installation of Jellyfin/Emby or if you have c
### Solution: Reset admin access
1. Back up your `settings.json` file (located in your Jellyseerr data directory)
2. Stop the Jellyseerr container/service
1. Back up your `settings.json` file (located in your Seerr data directory)
2. Stop the Seerr container/service
3. Delete the `settings.json` file
4. Start Jellyseerr again
4. Start Seerr again
5. This will force the setup page to appear
6. Go through the setup process with the same login details
7. You can skip the services setup
8. Once you reach the discover page, stop Jellyseerr
8. Once you reach the discover page, stop Seerr
9. Restore your backed-up `settings.json` file
10. Start Jellyseerr again
10. Start Seerr again
This process should restore your admin privileges while preserving your settings.

View File

@@ -1,9 +0,0 @@
{
"label": "Using Jellyseerr",
"position": 2,
"link": {
"type": "generated-index",
"title": "Using Jellyseerr",
"description": "Learn how to use Jellyseerr"
}
}

View File

@@ -1,13 +0,0 @@
---
title: Jobs & Cache
description: Configure jobs and cache settings.
sidebar_position: 6
---
# Jobs & Cache
Jellyseerr performs certain maintenance tasks as regularly-scheduled jobs, but they can also be manually triggered on this page.
Jellyseerr also caches requests to external API endpoints to optimize performance and avoid making unnecessary API calls. If necessary, the cache for any particular endpoint can be cleared by clicking the "Flush Cache" button.
You can also view the current image cache size as well as the total number of cached images.

View File

@@ -1,64 +0,0 @@
---
title: Adding Users
description: Add users to your Jellyseerr instance.
sidebar_position: 2
---
# Adding Users
There are currently two methods to add users to Jellyseerr: importing Mediaserver users and creating "local users." All new users are created with the [default permissions](/using-jellyseerr/settings/users#default-permissions) defined in **Settings &rarr; Users**.
### Importing Mediaserver Users
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs groupId="media-server-type" queryString>
<TabItem value="jellyfin" label="Jellyfin">
Clicking the **Import Jellyfin Users** button on the **User List** page will fetch the list of users with access to the Jellyfin server and add them to Jellyseerr automatically.
Importing Jellyfin users is not required, however. Any user with access to the Jellyfin server can log in to Jellyseerr even if they have not been imported, and will be assigned the configured [default permissions](/using-jellyseerr/settings/users#default-permissions) upon their first login.
:::tip
To disable new Jellyfin sign-ins, navigate to **Settings &rarr; Users** and uncheck the [**Enable New Jellyfin Sign-In**](/using-jellyseerr/settings/users#enable-new-jellyfinembyplex-sign-in) box.
:::
</TabItem>
<TabItem value="emby" label="Emby">
Clicking the **Import Emby Users** button on the **User List** page will fetch the list of users with access to the Emby server and add them to Jellyseerr automatically.
Importing Emby users is not required, however. Any user with access to the Emby server can log in to Jellyseerr even if they have not been imported, and will be assigned the configured [default permissions](/using-jellyseerr/settings/users#default-permissions) upon their first login.
:::tip
To disable new Emby sign-ins, navigate to **Settings &rarr; Users** and uncheck the [**Enable New Emby Sign-In**](/using-jellyseerr/settings/users#enable-new-jellyfinembyplex-sign-in) box.
:::
</TabItem>
<TabItem value="plex" label="Plex">
Clicking the **Import Plex Users** button on the **User List** page will fetch the list of users with access to the Plex server from [plex.tv](https://www.plex.tv/), and add them to Jellyseerr automatically.
Importing Plex users is not required, however. Any user with access to the Plex server can log in to Jellyseerr even if they have not been imported, and will be assigned the configured [default permissions](/using-jellyseerr/settings/users#default-permissions) upon their first login.
:::tip
To disable new Plex sign-ins, navigate to **Settings &rarr; Users** and uncheck the [**Enable New Plex Sign-In**](/using-jellyseerr/settings/users#enable-new-jellyfinembyplex-sign-in) box.
:::
</TabItem>
</Tabs>
### Creating Local Users
If you would like to grant Jellyseerr access to a user who doesn't have their own Plex account and/or access to the Plex server, you can manually add them by clicking the **Create Local User** button.
#### Email Address
Enter a valid email address at which the user can receive messages pertaining to their account and other notifications. The email address currently cannot be modified after the account is created.
#### Automatically Generate Password
If an [application URL](/using-jellyseerr/settings/general#application-url) is set and [email notifications](/using-jellyseerr/notifications/email) have been configured and enabled, Jellyseerr can automatically generate a password for the new user.
#### Password
If you would prefer to manually configure a password, enter a password here that is a minimum of 8 characters.

View File

@@ -0,0 +1,9 @@
{
"label": "Using Seerr",
"position": 2,
"link": {
"type": "generated-index",
"title": "Using Seerr",
"description": "Learn how to use Seerr"
}
}

View File

@@ -4,12 +4,12 @@ description: Understand which data you should back up.
sidebar_position: 4
---
# Which data does Jellyseerr save and where?
# Which data does Seerr save and where?
## Settings
All configurations from the **Settings** panel in the Jellyseerr web UI are saved, including integrations with Radarr, Sonarr, Jellyfin, Plex, and notification settings.
These settings are stored in the `settings.json` file located in the Jellyseerr data folder.
All configurations from the **Settings** panel in the Seerr web UI are saved, including integrations with Radarr, Sonarr, Jellyfin, Plex, and notification settings.
These settings are stored in the `settings.json` file located in the Seerr data folder.
## User Data
@@ -19,20 +19,20 @@ Apart from the settings, all other data—including user accounts, media request
### SQLite
If your backup system uses filesystem snapshots (such as Kubernetes with Volsync), you can directly back up the Jellyseerr data folder.
Otherwise, you need to stop the Jellyseerr application and back up the `config` folder.
If your backup system uses filesystem snapshots (such as Kubernetes with Volsync), you can directly back up the Seerr data folder.
Otherwise, you need to stop the Seerr application and back up the `config` folder.
For advanced users, it's possible to back up the database without stopping the application by using the [SQLite CLI](https://www.sqlite.org/download.html). Run the following command to create a backup:
```bash
sqlite3 db/db.sqlite3 ".backup '/tmp/jellyseerr_db.sqlite3.bak'"
sqlite3 db/db.sqlite3 ".backup '/tmp/seerr_db.sqlite3.bak'"
```
Then, copy the `/tmp/jellyseerr_dump.sqlite3.bak` file to your desired backup location.
Then, copy the `/tmp/seerr_dump.sqlite3.bak` file to your desired backup location.
### PostgreSQL
You can back up the `config` folder and dump the PostgreSQL database without stopping the Jellyseerr application.
You can back up the `config` folder and dump the PostgreSQL database without stopping the Seerr application.
Install [postgresql-client](https://www.postgresql.org/download/) and run the following command to create a backup (just replace the placeholders):
@@ -45,7 +45,7 @@ Depending on how your PostgreSQL instance is configured, you may need to add the
:::
```bash
pg_dump -U <database_user> -d <database_name> -f /tmp/jellyseerr_db.sql
pg_dump -U <database_user> -d <database_name> -f /tmp/seerr_db.sql
```
# Restore
@@ -60,10 +60,10 @@ After restoring your `db/db.sqlite3` file and, optionally, the `settings.json` f
├── db
│ └── db.sqlite3
├── logs <-- Optional
└── settings.json <-- Optional (required if you want to avoid reconfiguring Jellyseerr)
└── settings.json <-- Optional (required if you want to avoid reconfiguring Seerr)
```
Once the files are restored, start the Jellyseerr application.
Once the files are restored, start the Seerr application.
### PostgreSQL
@@ -78,7 +78,7 @@ Depending on how your PostgreSQL instance is configured, you may need to add the
:::
```bash
pg_restore -U <database_user> -d <database_name> /tmp/jellyseerr_db.sql
pg_restore -U <database_user> -d <database_name> /tmp/seerr_db.sql
```
Optionally, restore the `settings.json` file. The `config` folder structure should look like this:
@@ -87,7 +87,7 @@ Optionally, restore the `settings.json` file. The `config` folder structure shou
.
├── cache <-- Optional
├── logs <-- Optional
└── settings.json <-- Optional (required if you want to avoid reconfiguring Jellyseerr)
└── settings.json <-- Optional (required if you want to avoid reconfiguring Seerr)
```
Once the database and files are restored, start the Jellyseerr application.
Once the database and files are restored, start the Seerr application.

View File

@@ -9,12 +9,12 @@ sidebar_position: 1
## Configuration
:::info
If the [Application URL](/using-jellyseerr/settings/general#application-title) setting is configured in **Settings → General**, Jellyseerr will explicitly set the origin server hostname when connecting to the SMTP host.
If the [Application URL](/using-seerr/settings/general#application-title) setting is configured in **Settings → General**, Seerr will explicitly set the origin server hostname when connecting to the SMTP host.
:::
### Sender Name (optional)
Configure a friendly name for the email sender (e.g., "Jellyseerr").
Configure a friendly name for the email sender (e.g., "Seerr").
### Sender Address

View File

@@ -8,7 +8,7 @@ sidebar_position: 3
## Supported Notification Agents
Jellyseerr currently supports the following notification agents:
Seerr currently supports the following notification agents:
import DocCardList from '@theme/DocCardList';
@@ -16,7 +16,7 @@ import DocCardList from '@theme/DocCardList';
## Setting Up Notifications
Simply configure your desired notification agents in **Settings -> Notifications** in the Jellyseerr web UI.
Simply configure your desired notification agents in **Settings -> Notifications** in the Seerr web UI.
Users can customize their notification preferences in their own user notification settings.

View File

@@ -16,7 +16,7 @@ User notifications are separate from system notifications, and the available not
### Access Token
[Create an access token](https://www.pushbullet.com/#settings) and set it here to grant Jellyseerr access to the Pushbullet API.
[Create an access token](https://www.pushbullet.com/#settings) and set it here to grant Seerr access to the Pushbullet API.
### Channel Tag (optional)

View File

@@ -24,7 +24,7 @@ This value will be sent as an `Authorization` HTTP header.
### JSON Payload
Customize the JSON payload to suit your needs. Jellyseerr provides several [template variables](#template-variables) for use in the payload, which will be replaced with the relevant data when the notifications are triggered.
Customize the JSON payload to suit your needs. Seerr provides several [template variables](#template-variables) for use in the payload, which will be replaced with the relevant data when the notifications are triggered.
## Template Variables

View File

@@ -6,12 +6,12 @@ sidebar_position: 2
# Web Push
The web push notification agent enables you and your users to receive Jellyseerr notifications in a supported browser.
The web push notification agent enables you and your users to receive Seerr notifications in a supported browser.
This notification agent does not require any configuration, but is not enabled in Jellyseerr by default.
This notification agent does not require any configuration, but is not enabled in Seerr
:::warning
Web push notifications require a secure connection to your Jellyseerr instance. Refer to the [Reverse Proxy](/extending-jellyseerr/reverse-proxy) documentation for more information.
Web push notifications require a secure connection to your Seerr instance. Refer to the [Reverse Proxy](/extending-seerr/reverse-proxy) documentation for more information.
:::
To set up web push notifications, simply enable the agent in **Settings → Notifications → Web Push**. You and your users will then be prompted to allow notifications in your web browser.

View File

@@ -4,7 +4,6 @@
"link": {
"type": "generated-index",
"title": "Plex Integration",
"description": "Learn about Jellyseerr's Plex integration features"
"description": "Learn about Seerr's Plex integration features"
}
}

View File

@@ -1,12 +1,12 @@
---
title: Overview
description: Learn about Jellyseerr's Plex integration features
description: Learn about Seerr's Plex integration features
sidebar_position: 1
---
# Plex Features Overview
Jellyseerr provides integration features that connect with your Plex media server to automate media management tasks.
Seerr provides integration features that connect with your Plex media server to automate media management tasks.
## Available Features
@@ -16,12 +16,12 @@ Jellyseerr provides integration features that connect with your Plex media serve
## Prerequisites
:::info Authentication Required
To use any Plex integration features, you must have logged into Jellyseerr at least once with your Plex account.
To use any Plex integration features, you must have logged into Seerr at least once with your Plex account.
:::
**Requirements:**
- Plex account with access to the configured Plex server
- Jellyseerr configured with Plex as the media server
- Seerr configured with Plex as the media server
- User authentication via Plex login
- Appropriate user permissions for specific features

View File

@@ -6,7 +6,7 @@ sidebar_position: 1
# Watchlist Auto Request
The Plex Watchlist Auto Request feature allows Jellyseerr to automatically create requests for media items you add to your Plex Watchlist. Simply add content to your Plex Watchlist, and Jellyseerr will automatically request it for you.
The Plex Watchlist Auto Request feature allows Seerr to automatically create requests for media items you add to your Plex Watchlist. Simply add content to your Plex Watchlist, and Seerr will automatically request it for you.
:::info
This feature is only available for Plex users. Local users cannot use the Watchlist Auto Request feature.
@@ -14,9 +14,9 @@ This feature is only available for Plex users. Local users cannot use the Watchl
## Prerequisites
- You must have logged into Jellyseerr at least once with your Plex account
- You must have logged into Seerr at least once with your Plex account
- Your administrator must have granted you the necessary permissions
- Your Plex account must have access to the Plex server configured in Jellyseerr
- Your Plex account must have access to the Plex server configured in Seerr
## Permission System
@@ -54,12 +54,12 @@ Contact your administrator to verify you have been granted:
### Step 3: Start Using
- Add movies and TV shows to your Plex Watchlist
- Jellyseerr will automatically create requests for new items
- Seerr will automatically create requests for new items
- You'll receive notifications when items are auto-requested
## How It Works
Once properly configured, Jellyseerr will:
Once properly configured, Seerr will:
1. Periodically checks your Plex Watchlist for new items
2. Verify if the content already exists in your media libraries
@@ -90,6 +90,6 @@ Auto-request only works for standard quality content. 4K content must be request
- Local users cannot use this feature
- 4K content requires manual requests
- Users must have logged into Jellyseerr with their Plex account
- Users must have logged into Seerr with their Plex account
- Respects user request limits and quotas
- Won't request content already in your libraries

View File

@@ -4,6 +4,6 @@
"link": {
"type": "generated-index",
"title": "Settings",
"description": "Configure Jellyseerr to your liking"
"description": "Configure Seerr to your liking"
}
}

View File

@@ -6,11 +6,11 @@ sidebar_position: 7
# DNS Caching
Jellyseerr uses DNS caching to improve performance and reduce the number of DNS lookups required for external API calls. This can help speed up response times and reduce load on DNS servers, when something like a Pi-hole is used as a DNS resolver.
Seerr uses DNS caching to improve performance and reduce the number of DNS lookups required for external API calls. This can help speed up response times and reduce load on DNS servers, when something like a Pi-hole is used as a DNS resolver.
## Configuration
You can enable the DNS caching settings in the Network tab of the Jellyseerr settings. The default values follow the standard DNS caching behavior.
You can enable the DNS caching settings in the Network tab of the Seerr settings. The default values follow the standard DNS caching behavior.
- **Force Minimum TTL**: Set a minimum time-to-live (TTL) in seconds for DNS cache entries. This ensures that frequently accessed DNS records are cached for a longer period, reducing the need for repeated lookups. Default is 0.
- **Force Maximum TTL**: Set a maximum time-to-live (TTL) in seconds for DNS cache entries. This prevents infrequently accessed DNS records from being cached indefinitely, allowing for more up-to-date information to be retrieved. Default is -1 (unlimited).

View File

@@ -1,6 +1,6 @@
---
title: General
description: Configure global and default settings for Jellyseerr.
description: Configure global and default settings for Seerr.
sidebar_position: 1
---
@@ -8,7 +8,7 @@ sidebar_position: 1
## API Key
This is your Jellyseerr API key, which can be used to integrate Jellyseerr with third-party applications. Do **not** share this key publicly, as it can be used to gain administrator access!
This is your Seerr API key, which can be used to integrate Seerr with third-party applications. Do **not** share this key publicly, as it can be used to gain administrator access!
If you need to generate a new API key for any reason, simply click the button to the right of the text box.
@@ -16,17 +16,17 @@ If you want to set the API key, rather than letting it be randomly generated, yo
## Application Title
If you aren't a huge fan of the name "Jellyseerr" and would like to display something different to your users, you can customize the application title!
If you aren't a huge fan of the name "Seerr" and would like to display something different to your users, you can customize the application title!
## Application URL
Set this to the externally-accessible URL of your Jellyseerr instance.
Set this to the externally-accessible URL of your Seerr instance.
You must configure this setting in order to enable password reset and generation emails.
## Enable Proxy Support
If you have Jellyseerr behind a reverse proxy, enable this setting to allow Jellyseerr to correctly register client IP addresses. For details, please see the [Express Documentation](https://expressjs.com/en/guide/behind-proxies.html).
If you have Seerr behind a reverse proxy, enable this setting to allow Seerr to correctly register client IP addresses. For details, please see the [Express Documentation](https://expressjs.com/en/guide/behind-proxies.html).
This setting is **disabled** by default.
@@ -36,13 +36,13 @@ This setting is **disabled** by default.
**This is an advanced setting.** Please only enable this setting if you are familiar with CSRF protection and how it works.
:::
CSRF stands for [cross-site request forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery). When this setting is enabled, all external API access that alters Jellyseerr application data is blocked.
CSRF stands for [cross-site request forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery). When this setting is enabled, all external API access that alters Seerr application data is blocked.
If you do not use Jellyseerr integrations with third-party applications to add/modify/delete requests or users, you can consider enabling this setting to protect against malicious attacks.
If you do not use Seerr integrations with third-party applications to add/modify/delete requests or users, you can consider enabling this setting to protect against malicious attacks.
One caveat, however, is that HTTPS is required, meaning that once this setting is enabled, you will no longer be able to access your Jellyseerr instance over _HTTP_ (including using an IP address and port number).
One caveat, however, is that HTTPS is required, meaning that once this setting is enabled, you will no longer be able to access your Seerr instance over _HTTP_ (including using an IP address and port number).
If you enable this setting and find yourself unable to access Jellyseerr, you can disable the setting by modifying `settings.json` in `/app/config`.
If you enable this setting and find yourself unable to access Seerr, you can disable the setting by modifying `settings.json` in `/app/config`.
This setting is **disabled** by default.
@@ -56,7 +56,7 @@ You should enable this if you are having issues with loading images directly fro
## Display Language
Set the default display language for Jellyseerr. Users can override this setting in their user settings.
Set the default display language for Seerr. Users can override this setting in their user settings.
## Discover Region, Discover Language & Streaming Region

View File

@@ -0,0 +1,13 @@
---
title: Jobs & Cache
description: Configure jobs and cache settings.
sidebar_position: 6
---
# Jobs & Cache
Seerr performs certain maintenance tasks as regularly-scheduled jobs, but they can also be manually triggered on this page.
Seerr also caches requests to external API endpoints to optimize performance and avoid making unnecessary API calls. If necessary, the cache for any particular endpoint can be cleared by clicking the "Flush Cache" button.
You can also view the current image cache size as well as the total number of cached images.

View File

@@ -20,13 +20,13 @@ It is **not** tied to your Jellyfin account.
### Jellyfin Libraries
In this section, simply select the libraries you would like Jellyseerr to scan. Jellyseerr will periodically check the selected libraries for available content to update the media status that is displayed to users.
In this section, simply select the libraries you would like Seerr to scan. Seerr will periodically check the selected libraries for available content to update the media status that is displayed to users.
If you do not see your Jellyfin library listed, verify your Jellyfin settings are correct and click the Sync Libraries button.
### Manual Library Scan
Jellyseerr will perform a full scan of your Jellyfin libraries once every 24 hours (recently added items are fetched more frequently). If this is your first time configuring Jellyfin, a one-time full manual library scan is recommended!
Seerr will perform a full scan of your Jellyfin libraries once every 24 hours (recently added items are fetched more frequently). If this is your first time configuring Jellyfin, a one-time full manual library scan is recommended!
### Jellyfin Settings
@@ -37,15 +37,15 @@ This section is where you configure the connection to your Jellyfin server.
#### Internal URL
The internal URL is the URL that Jellyseerr will use to communicate with your Jellyfin server. This URL should be accessible from the machine running Jellyseerr.
The internal URL is the URL that Seerr will use to communicate with your Jellyfin server. This URL should be accessible from the machine running Seerr.
In most cases, this will be the hostname or IP address of the machine running Jellyfin, followed by the port number Jellyfin is running on (usually 8096).
:::note
When running Jellyseerr in a docker container with a bridged network (default), the container's network will be separate from the host network. Therefore, you cannot use `localhost` or `127.0.0.1` as the internal URL as it will resolve to the container itself.
When running Seerr in a docker container with a bridged network (default), the container's network will be separate from the host network. Therefore, you cannot use `localhost` or `127.0.0.1` as the internal URL as it will resolve to the container itself.
:::
:::tip
If you are running Jellyfin in a docker container, you can put both Jellyseerr and Jellyfin on the same docker network by using a custom [docker network](https://docs.docker.com/reference/cli/docker/network/). This will allow you to use the container name as the internal URL.
If you are running Jellyfin in a docker container, you can put both Seerr and Jellyfin on the same docker network by using a custom [docker network](https://docs.docker.com/reference/cli/docker/network/). This will allow you to use the container name as the internal URL.
:::
#### External URL
@@ -56,7 +56,7 @@ In most cases, the external URL will be different from the internal URL. This is
#### Forgot Password URL
The forgot password URL is the URL that users will be directed to when they click the "Forgot Password" button on the login page. This URL should be accessible from the machine running Jellyseerr.
The forgot password URL is the URL that users will be directed to when they click the "Forgot Password" button on the login page. This URL should be accessible from the machine running Seerr.
By default, this field is empty and the "Forgot Password" button on the login page will redirect to the Jellyfin internal URL with the path `/web/index.html#!/forgotpassword`.
@@ -67,15 +67,15 @@ You can customize this URL to point to a custom password reset page if you have
#### Hostname or IP Address
If you have Jellyseerr installed on the same network as Jellyfin, you can set this to the local IP address of your Jellyfin server. Otherwise, this should be set to a valid hostname (e.g., jellyfin.myawesomeserver.com).
If you have Seerr installed on the same network as Jellyfin, you can set this to the local IP address of your Jellyfin server. Otherwise, this should be set to a valid hostname (e.g., jellyfin.myawesomeserver.com).
In most cases, this will be the hostname or IP address of the machine running Jellyfin.
:::note
When running Jellyseerr in a docker container with a bridged network (default), the container's network will be separate from the host network. Therefore, you cannot use `localhost` or `127.0.0.1` as the internal URL as it will resolve to the container itself.
When running Seerr in a docker container with a bridged network (default), the container's network will be separate from the host network. Therefore, you cannot use `localhost` or `127.0.0.1` as the internal URL as it will resolve to the container itself.
:::
:::tip
If you are running Jellyfin in a docker container, you can put both Jellyseerr and Jellyfin on the same docker network by using a custom [docker network](https://docs.docker.com/reference/cli/docker/network/). This will allow you to use the container name as the internal URL.
If you are running Jellyfin in a docker container, you can put both Seerr and Jellyfin on the same docker network by using a custom [docker network](https://docs.docker.com/reference/cli/docker/network/). This will allow you to use the container name as the internal URL.
:::
#### Port
@@ -94,7 +94,7 @@ In most cases, the external URL will be different from the internal URL. This is
#### Forgot Password URL
The forgot password URL is the URL that users will be directed to when they click the "Forgot Password" button on the login page. This URL should be accessible from the machine running Jellyseerr.
The forgot password URL is the URL that users will be directed to when they click the "Forgot Password" button on the login page. This URL should be accessible from the machine running Seerr.
By default, this field is empty and the "Forgot Password" button on the login page will redirect to the Jellyfin internal URL with the path `/web/index.html#!/forgotpassword`.
@@ -114,13 +114,13 @@ It is **not** tied to your Emby account.
### Emby Libraries
In this section, simply select the libraries you would like Jellyseerr to scan. Jellyseerr will periodically check the selected libraries for available content to update the media status that is displayed to users.
In this section, simply select the libraries you would like Seerr to scan. Seerr will periodically check the selected libraries for available content to update the media status that is displayed to users.
If you do not see your Emby library listed, verify your Emby settings are correct and click the Sync Libraries button.
### Manual Library Scan
Jellyseerr will perform a full scan of your Emby libraries once every 24 hours (recently added items are fetched more frequently). If this is your first time configuring Emby, a one-time full manual library scan is recommended!
Seerr will perform a full scan of your Emby libraries once every 24 hours (recently added items are fetched more frequently). If this is your first time configuring Emby, a one-time full manual library scan is recommended!
### Emby Settings
@@ -131,15 +131,15 @@ This section is where you configure the connection to your Emby server.
#### Internal URL
The internal URL is the URL that Jellyseerr will use to communicate with your Emby server. This URL should be accessible from the machine running Jellyseerr.
The internal URL is the URL that Seerr will use to communicate with your Emby server. This URL should be accessible from the machine running Seerr.
In most cases, this will be the hostname or IP address of the machine running Emby, followed by the port number Emby is running on (usually 8096).
:::note
When running Jellyseerr in a docker container with a bridged network (default), the container's network will be separate from the host network. Therefore, you cannot use `localhost` or `127.0.0.1` as the internal URL as it will resolve to the container itself.
When running Seerr in a docker container with a bridged network (default), the container's network will be separate from the host network. Therefore, you cannot use `localhost` or `127.0.0.1` as the internal URL as it will resolve to the container itself.
:::
:::tip
If you are running Emby in a docker container, you can put both Jellyseerr and Emby on the same docker network by using a custom [docker network](https://docs.docker.com/reference/cli/docker/network/). This will allow you to use the container name as the internal URL.
If you are running Emby in a docker container, you can put both Seerr and Emby on the same docker network by using a custom [docker network](https://docs.docker.com/reference/cli/docker/network/). This will allow you to use the container name as the internal URL.
:::
#### External URL
@@ -150,7 +150,7 @@ In most cases, the external URL will be different from the internal URL. This is
#### Forgot Password URL
The forgot password URL is the URL that users will be directed to when they click the "Forgot Password" button on the login page. This URL should be accessible from the machine running Jellyseerr.
The forgot password URL is the URL that users will be directed to when they click the "Forgot Password" button on the login page. This URL should be accessible from the machine running Seerr.
By default, this field is empty and the "Forgot Password" button on the login page will redirect to the Emby internal URL with the path `/web/index.html#!/forgotpassword.html`.
@@ -161,15 +161,15 @@ You can customize this URL to point to a custom password reset page if you have
#### Hostname or IP Address
If you have Jellyseerr installed on the same network as Emby, you can set this to the local IP address of your Emby server. Otherwise, this should be set to a valid hostname (e.g., jellyfin.myawesomeserver.com).
If you have Seerr installed on the same network as Emby, you can set this to the local IP address of your Emby server. Otherwise, this should be set to a valid hostname (e.g., jellyfin.myawesomeserver.com).
In most cases, this will be the hostname or IP address of the machine running Emby.
:::note
When running Jellyseerr in a docker container with a bridged network (default), the container's network will be separate from the host network. Therefore, you cannot use `localhost` or `127.0.0.1` as the internal URL as it will resolve to the container itself.
When running Seerr in a docker container with a bridged network (default), the container's network will be separate from the host network. Therefore, you cannot use `localhost` or `127.0.0.1` as the internal URL as it will resolve to the container itself.
:::
:::tip
If you are running Emby in a docker container, you can put both Jellyseerr and Emby on the same docker network by using a custom [docker network](https://docs.docker.com/reference/cli/docker/network/). This will allow you to use the container name as the internal URL.
If you are running Emby in a docker container, you can put both Seerr and Emby on the same docker network by using a custom [docker network](https://docs.docker.com/reference/cli/docker/network/). This will allow you to use the container name as the internal URL.
:::
#### Port
@@ -188,7 +188,7 @@ In most cases, the external URL will be different from the internal URL. This is
#### Forgot Password URL
The forgot password URL is the URL that users will be directed to when they click the "Forgot Password" button on the login page. This URL should be accessible from the machine running Jellyseerr.
The forgot password URL is the URL that users will be directed to when they click the "Forgot Password" button on the login page. This URL should be accessible from the machine running Seerr.
By default, this field is empty and the "Forgot Password" button on the login page will redirect to the Emby internal URL with the path `/web/index.html#!/startup/forgotpassword.html`.
@@ -205,12 +205,12 @@ You can customize this URL to point to a custom password reset page if you have
:::info
To set up Plex, you can either enter your details manually or select a server retrieved from [plex.tv](https://plex.tv/). Press the button to the right of the "Server" dropdown to retrieve available servers.
Depending on your setup/configuration, you may need to enter your Plex server details manually in order to establish a connection from Jellyseerr.
Depending on your setup/configuration, you may need to enter your Plex server details manually in order to establish a connection from Seerr.
:::
#### Hostname or IP Address
If you have Jellyseerr installed on the same network as Plex, you can set this to the local IP address of your Plex server. Otherwise, this should be set to a valid hostname (e.g., `plex.myawesomeserver.com`).
If you have Seerr installed on the same network as Plex, you can set this to the local IP address of your Plex server. Otherwise, this should be set to a valid hostname (e.g., `plex.myawesomeserver.com`).
#### Port
@@ -228,13 +228,13 @@ Note that you will need to enter the full path to the web app (e.g., `https://pl
### Plex Libraries
In this section, simply select the libraries you would like Jellyseerr to scan. Jellyseerr will periodically check the selected libraries for available content to update the media status that is displayed to users.
In this section, simply select the libraries you would like Seerr to scan. Seerr will periodically check the selected libraries for available content to update the media status that is displayed to users.
If you do not see your Plex libraries listed, verify your Plex settings are correct and click the **Sync Libraries** button.
### Manual Library Scan
Jellyseerr will perform a full scan of your Plex libraries once every 24 hours (recently added items are fetched more frequently). If this is your first time configuring Plex, a one-time full manual library scan is recommended!
Seerr will perform a full scan of your Plex libraries once every 24 hours (recently added items are fetched more frequently). If this is your first time configuring Plex, a one-time full manual library scan is recommended!
</TabItem>

View File

@@ -6,4 +6,4 @@ sidebar_position: 5
# Notifications
Please see the [Notifications](/using-jellyseerr/notifications) page for more information.
Please see the [Notifications](/using-seerr/notifications) page for more information.

View File

@@ -7,9 +7,9 @@ sidebar_position: 4
# Services
:::info
**If you keep separate copies of non-4K and 4K content in your media libraries, you will need to set up multiple Radarr/Sonarr instances and link each of them to Jellyseerr.**
**If you keep separate copies of non-4K and 4K content in your media libraries, you will need to set up multiple Radarr/Sonarr instances and link each of them to Seerr.**
Jellyseerr checks these linked servers to determine whether or not media has already been requested or is available, so two servers of each type are required _if you keep separate non-4K and 4K copies of media._
Seerr checks these linked servers to determine whether or not media has already been requested or is available, so two servers of each type are required _if you keep separate non-4K and 4K copies of media._
**If you only maintain one copy of media, you can instead simply set up one server and set the "Quality Profile" setting on a per-request basis.**
:::
@@ -17,7 +17,7 @@ Jellyseerr checks these linked servers to determine whether or not media has alr
### Radarr/Sonarr Settings
:::warning
**Only v3 & V4 Radarr/Sonarr servers are supported!** If your Radarr/Sonarr server is still running v2, you will need to upgrade in order to add it to Jellyseerr.
**Only v3 & V4 Radarr/Sonarr servers are supported!** If your Radarr/Sonarr server is still running v2, you will need to upgrade in order to add it to Seerr.
::::
#### Default Server
@@ -36,7 +36,7 @@ Enter a friendly name for the Radarr/Sonarr server.
#### Hostname or IP Address
If you have Jellyseerr installed on the same network as Radarr/Sonarr, you can set this to the local IP address of your Radarr/Sonarr server. Otherwise, this should be set to a valid hostname (e.g., `radarr.myawesomeserver.com`).
If you have Seerr installed on the same network as Radarr/Sonarr, you can set this to the local IP address of your Radarr/Sonarr server. Otherwise, this should be set to a valid hostname (e.g., `radarr.myawesomeserver.com`).
#### Port

View File

@@ -10,21 +10,21 @@ sidebar_position: 2
When enabled, users who have configured passwords will be allowed to sign in using their email address.
When disabled, your mediaserver OAuth becomes the only sign-in option, and any "local users" you have created will not be able to sign in to Jellyseerr.
When disabled, your mediaserver OAuth becomes the only sign-in option, and any "local users" you have created will not be able to sign in to Seerr.
This setting is **enabled** by default.
## Enable Jellyfin/Emby/Plex Sign-In
When enabled, users will be able to sign in to Jellyseerr using their Jellyfin/Emby/Plex credentials, provided they have linked their media server accounts.
When enabled, users will be able to sign in to Seerr using their Jellyfin/Emby/Plex credentials, provided they have linked their media server accounts.
When disabled, users will only be able to sign in using their email address. Users without a password set will not be able to sign in to Jellyseerr.
When disabled, users will only be able to sign in using their email address. Users without a password set will not be able to sign in to Seerr.
This setting is **enabled** by default.
## Enable New Jellyfin/Emby/Plex Sign-In
When enabled, users with access to your media server will be able to sign in to Jellyseerr even if they have not yet been imported. Users will be automatically assigned the permissions configured in the [Default Permissions](#default-permissions) setting upon first sign-in.
When enabled, users with access to your media server will be able to sign in to Seerr even if they have not yet been imported. Users will be automatically assigned the permissions configured in the [Default Permissions](#default-permissions) setting upon first sign-in.
This setting is **enabled** by default.
@@ -40,6 +40,6 @@ Note that users with the **Manage Users** permission are exempt from request lim
Select the permissions you would like assigned to new users to have by default upon account creation.
If [Enable New Jellyfin/Emby/Plex Sign-In](#enable-new-jellyfinembyplex-sign-in) is enabled, any user with access to your media server will be able to sign in to Jellyseerr, and they will be granted the permissions you select here upon first sign-in.
If [Enable New Jellyfin/Emby/Plex Sign-In](#enable-new-jellyfinembyplex-sign-in) is enabled, any user with access to your media server will be able to sign in to Seerr, and they will be granted the permissions you select here upon first sign-in.
This setting only affects new users, and has no impact on existing users. In order to modify permissions for existing users, you will need to edit the users.

View File

@@ -4,6 +4,6 @@
"link": {
"type": "generated-index",
"title": "Users",
"description": "Configure your Jellyseerr users"
"description": "Configure your Seerr users"
}
}

View File

@@ -0,0 +1,64 @@
---
title: Adding Users
description: Add users to your Seerr instance.
sidebar_position: 2
---
# Adding Users
There are currently two methods to add users to Seerr: importing Mediaserver users and creating "local users." All new users are created with the [default permissions](/using-seerr/settings/users#default-permissions) defined in **Settings &rarr; Users**.
### Importing Mediaserver Users
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs groupId="media-server-type" queryString>
<TabItem value="jellyfin" label="Jellyfin">
Clicking the **Import Jellyfin Users** button on the **User List** page will fetch the list of users with access to the Jellyfin server and add them to Seerr automatically.
Importing Jellyfin users is not required, however. Any user with access to the Jellyfin server can log in to Seerr even if they have not been imported, and will be assigned the configured [default permissions](/using-seerr/settings/users#default-permissions) upon their first login.
:::tip
To disable new Jellyfin sign-ins, navigate to **Settings &rarr; Users** and uncheck the [**Enable New Jellyfin Sign-In**](/using-seerr/settings/users#enable-new-jellyfinembyplex-sign-in) box.
:::
</TabItem>
<TabItem value="emby" label="Emby">
Clicking the **Import Emby Users** button on the **User List** page will fetch the list of users with access to the Emby server and add them to Seerr automatically.
Importing Emby users is not required, however. Any user with access to the Emby server can log in to Seerr even if they have not been imported, and will be assigned the configured [default permissions](/using-seerr/settings/users#default-permissions) upon their first login.
:::tip
To disable new Emby sign-ins, navigate to **Settings &rarr; Users** and uncheck the [**Enable New Emby Sign-In**](/using-seerr/settings/users#enable-new-jellyfinembyplex-sign-in) box.
:::
</TabItem>
<TabItem value="plex" label="Plex">
Clicking the **Import Plex Users** button on the **User List** page will fetch the list of users with access to the Plex server from [plex.tv](https://www.plex.tv/), and add them to Seerr automatically.
Importing Plex users is not required, however. Any user with access to the Plex server can log in to Seerr even if they have not been imported, and will be assigned the configured [default permissions](/using-seerr/settings/users#default-permissions) upon their first login.
:::tip
To disable new Plex sign-ins, navigate to **Settings &rarr; Users** and uncheck the [**Enable New Plex Sign-In**](/using-seerr/settings/users#enable-new-jellyfinembyplex-sign-in) box.
:::
</TabItem>
</Tabs>
### Creating Local Users
If you would like to grant Seerr access to a user who doesn't have their own Plex account and/or access to the Plex server, you can manually add them by clicking the **Create Local User** button.
#### Email Address
Enter a valid email address at which the user can receive messages pertaining to their account and other notifications. The email address currently cannot be modified after the account is created.
#### Automatically Generate Password
If an [application URL](/using-seerr/settings/general#application-url) is set and [email notifications](/using-seerr/notifications/email) have been configured and enabled, Seerr can automatically generate a password for the new user.
#### Password
If you would prefer to manually configure a password, enter a password here that is a minimum of 8 characters.

View File

@@ -1,6 +1,6 @@
---
title: Deleting Users
description: Delete users from Jellyseerr.
description: Delete users from Seerr.
sidebar_position: 4
---

View File

@@ -31,11 +31,11 @@ You cannot leave this field blank.
### Display Language
Users can override the [global display language](/using-jellyseerr/settings/general#display-language) to use Jellyseerr in their preferred language.
Users can override the [global display language](/using-seerr/settings/general#display-language) to use Seerr in their preferred language.
### Discover Region & Discover Language
Users can override the [global filter settings](/using-jellyseerr/settings/general#discover-region-discover-language--streaming-region) to suit their own preferences.
Users can override the [global filter settings](/using-seerr/settings/general#discover-region-discover-language--streaming-region) to suit their own preferences.
### Movie Request Limit & Series Request Limit
@@ -55,7 +55,7 @@ Passwords must be a minimum of 8 characters long.
## Notifications
Users can configure their personal notification settings here. Please see [Notifications](/using-jellyseerr/notifications/) for details on configuring and enabling notifications.
Users can configure their personal notification settings here. Please see [Notifications](/using-seerr/notifications/) for details on configuring and enabling notifications.
## Permissions

View File

@@ -1,12 +1,12 @@
---
title: Owner Account
description: Your owner account is the primary account for managing Jellyseerr.
description: Your owner account is the primary account for managing Seerr.
sidebar_position: 1
---
# Owner Account
The user account created during Jellyseerr setup is the "Owner" account, which cannot be deleted or modified by other users. This account's credentials are used to authenticate with your media server and configure Jellyseerr settings.
The user account created during Seerr setup is the "Owner" account, which cannot be deleted or modified by other users. This account's credentials are used to authenticate with your media server and configure Seerr settings.
:::note
In case of Jellyfin/Emby, the owner account is also used for API access to your media server. This account should have a valid authentication token for your media server.

View File

@@ -1,8 +1,8 @@
# Jellyseerr Documentation
# Seerr Documentation
Jellyseerr docs is built using [Docusaurus](https://docusaurus.io/), a modern static website generator.
Seerr docs is built using [Docusaurus](https://docusaurus.io/), a modern static website generator.
Jellyseerr docs will be available at [docs.seerr.dev](https://docs.seerr.dev).
Seerr docs will be available at [docs.seerr.dev](https://docs.seerr.dev).
### Installation

View File

@@ -1,13 +1,13 @@
import { useEffect, useState } from 'react';
export const JellyseerrVersion = () => {
export const SeerrVersion = () => {
const [version, setVersion] = useState<string | null>('0.0.0');
useEffect(() => {
async function fetchVersion() {
try {
const response = await fetch(
'https://raw.githubusercontent.com/fallenbagel/jellyseerr/main/package.json'
'https://raw.githubusercontent.com/seerr-team/seerr/main/package.json'
);
const data = await response.json();

View File

@@ -74,7 +74,7 @@ const postgresDevConfig: DataSourceOptions = {
: parseInt(process.env.DB_PORT ?? '5432'),
username: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME ?? 'jellyseerr',
database: process.env.DB_NAME ?? 'seerr',
ssl: buildSslConfig(),
synchronize: false,
migrationsRun: true,
@@ -92,7 +92,7 @@ const postgresProdConfig: DataSourceOptions = {
: parseInt(process.env.DB_PORT ?? '5432'),
username: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME ?? 'jellyseerr',
database: process.env.DB_NAME ?? 'seerr',
ssl: buildSslConfig(),
synchronize: false,
migrationsRun: false,

View File

@@ -16,6 +16,7 @@ import SlackAgent from '@server/lib/notifications/agents/slack';
import TelegramAgent from '@server/lib/notifications/agents/telegram';
import WebhookAgent from '@server/lib/notifications/agents/webhook';
import WebPushAgent from '@server/lib/notifications/agents/webpush';
import checkOverseerrMerge from '@server/lib/overseerrMerge';
import { getSettings } from '@server/lib/settings';
import logger from '@server/logger';
import clearCookies from '@server/middleware/clearcookies';
@@ -59,7 +60,12 @@ if (!appDataPermissions()) {
app
.prepare()
.then(async () => {
const dbConnection = await dataSource.initialize();
// Run Overseerr to Seerr migration
await checkOverseerrMerge();
const dbConnection = dataSource.isInitialized
? dataSource
: await dataSource.initialize();
// Run migrations in production
if (process.env.NODE_ENV === 'production') {

View File

@@ -0,0 +1,542 @@
import { MediaServerType } from '@server/constants/server';
import dataSource, { getRepository } from '@server/datasource';
import Media from '@server/entity/Media';
import Settings from '@server/lib/settings';
import logger from '@server/logger';
import type { MigrationInterface, MixedList, QueryRunner } from 'typeorm';
const checkOverseerrMerge = async (): Promise<boolean> => {
// Load settings without running migrations
const settings = await new Settings().load(undefined, true);
if (settings.main.mediaServerType) {
return false; // The application has already been migrated
}
const jellyseerMigrations = [
[1613379909641, 'AddJellyfinUserParams1613379909641'],
[1613412948344, 'ServerTypeEnum1613412948344'],
[1613670041760, 'AddJellyfinDeviceId1613670041760'],
[1682608634546, 'AddWatchlists1682608634546'],
[1699901142442, 'AddBlacklist1699901142442'],
[1727907530757, 'AddUserSettingsStreamingRegion1727907530757'],
[1734287582736, 'AddTelegramMessageThreadId1734287582736'],
[1734805733535, 'AddOverrideRules1734805733535'],
[1737320080282, 'AddBlacklistTagsColumn1737320080282'],
[1743023610704, 'UpdateWebPush1743023610704'],
[1743107645301, 'AddUserAvatarCacheFields1743107645301'],
[1745492372230, 'UpdateWebPush1745492372230'],
];
// Open the database connection to get the migrations and close it afterwards
const dbConnection = await dataSource.initialize();
const migrations = dbConnection.migrations;
await dbConnection.destroy();
// We have to replace Jellyseerr migrations not working with Overseerr with a custom one
try {
// Filter out the Jellyseerr migrations and replace them with the Seerr migration
// eslint-disable-next-line @typescript-eslint/ban-types
const newMigrations: MixedList<string | Function> = migrations
?.filter(
(migration) =>
!jellyseerMigrations
.map(([, name]) => name)
.includes(migration.name as string) ||
migration.name === 'UpdateWebPush1745492372230'
)
.map((migration) =>
migration.name === 'UpdateWebPush1745492372230'
? SeerrMigration1759769291608
: migration.constructor
);
dataSource.setOptions({
...dataSource.options,
migrations: newMigrations,
});
} catch (error) {
logger.error('Failed to load migrations for Overseerr merge', {
label: 'Seerr Migration',
error: error.message,
});
process.exit(1);
}
// Reopen the database connection with the updated migrations
await dataSource.initialize();
// Add fake migration record to prevent running the already existing Overseerr migration again
try {
await dbConnection.query(
`INSERT INTO migrations (timestamp,name) VALUES
${jellyseerMigrations
.map(([timestamp, name]) => `(${timestamp}, '${name}')`)
.join(', ')}
`
);
} catch (error) {
logger.error('Failed to insert migration records', {
label: 'Seerr Migration',
error: error.message,
});
process.exit(1);
}
// Manually run the migration to update the database schema
if (process.env.NODE_ENV === 'production') {
await dbConnection.query('PRAGMA foreign_keys=OFF');
await dbConnection.runMigrations();
await dbConnection.query('PRAGMA foreign_keys=ON');
}
// MediaStatus.Blacklisted was added before MediaStatus.Deleted in Jellyseerr
try {
const mediaRepository = getRepository(Media);
const mediaToUpdate = await mediaRepository.find({ where: { status: 6 } });
for (const media of mediaToUpdate) {
media.status = 7;
await mediaRepository.save(media);
}
const media4kToUpdate = await mediaRepository.find({
where: { status4k: 6 },
});
for (const media of media4kToUpdate) {
media.status4k = 7;
await mediaRepository.save(media);
}
} catch (error) {
logger.error('Failed to update Media status from Blacklisted to Deleted', {
label: 'Seerr Migration',
error: error.message,
});
process.exit(1);
}
// Set media server type to Plex (default for Overseerr)
settings.main.mediaServerType = MediaServerType.PLEX;
// Replace default Overseerr values with Seerr values
if (settings.main.applicationTitle === 'Overseerr') {
settings.main.applicationTitle = 'Seerr';
}
if (settings.notifications.agents.email.options.senderName === 'Overseerr') {
settings.notifications.agents.email.options.senderName = 'Seerr';
}
// Save the updated settings
try {
await settings.save();
} catch (error) {
logger.error('Failed to save updated settings for Overseerr merge', {
label: 'Seerr Migration',
error: error.message,
});
process.exit(1);
}
logger.info('Yeah! Overseerr to Seerr migration completed successfully!', {
label: 'Seerr Migration',
});
return true;
};
/**
* Overseerr to Jellyseerr migration
* Generated by TypeORM
*/
class SeerrMigration1759769291608 implements MigrationInterface {
name = 'SeerrMigration1759769291608';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE "temporary_user_push_subscription" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "endpoint" varchar NOT NULL, "p256dh" varchar NOT NULL, "auth" varchar NOT NULL, "userId" integer, "userAgent" varchar DEFAULT (NULL), "createdAt" datetime DEFAULT (datetime('now')), CONSTRAINT "UQ_f90ab5a4ed54905a4bb51a7148b" UNIQUE ("auth"), CONSTRAINT "FK_03f7958328e311761b0de675fbe" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
);
await queryRunner.query(
`INSERT INTO "temporary_user_push_subscription"("id", "endpoint", "p256dh", "auth", "userId", "userAgent", "createdAt") SELECT "id", "endpoint", "p256dh", "auth", "userId", "userAgent", "createdAt" FROM "user_push_subscription"`
);
await queryRunner.query(`DROP TABLE "user_push_subscription"`);
await queryRunner.query(
`ALTER TABLE "temporary_user_push_subscription" RENAME TO "user_push_subscription"`
);
await queryRunner.query(
`CREATE TABLE "blacklist" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "mediaType" varchar NOT NULL, "title" varchar, "tmdbId" integer NOT NULL, "blacklistedTags" varchar, "createdAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "userId" integer, "mediaId" integer, CONSTRAINT "UQ_6bbafa28411e6046421991ea21c" UNIQUE ("tmdbId"), CONSTRAINT "REL_62b7ade94540f9f8d8bede54b9" UNIQUE ("mediaId"))`
);
await queryRunner.query(
`CREATE INDEX "IDX_6bbafa28411e6046421991ea21" ON "blacklist" ("tmdbId") `
);
await queryRunner.query(
`CREATE TABLE "override_rule" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "radarrServiceId" integer, "sonarrServiceId" integer, "users" varchar, "genre" varchar, "language" varchar, "keywords" varchar, "profileId" integer, "rootFolder" varchar, "tags" varchar, "createdAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "updatedAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP))`
);
await queryRunner.query(
`CREATE TABLE "watchlist" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "ratingKey" varchar NOT NULL, "mediaType" varchar NOT NULL, "title" varchar NOT NULL, "tmdbId" integer NOT NULL, "createdAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "updatedAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "requestedById" integer, "mediaId" integer, CONSTRAINT "UNIQUE_USER_DB" UNIQUE ("tmdbId", "requestedById"))`
);
await queryRunner.query(
`CREATE INDEX "IDX_939f205946256cc0d2a1ac51a8" ON "watchlist" ("tmdbId") `
);
await queryRunner.query(
`CREATE TABLE "temporary_user_settings" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "notificationTypes" text, "discordId" varchar, "userId" integer, "originalLanguage" varchar, "telegramChatId" varchar, "telegramSendSilently" boolean, "pgpKey" varchar, "locale" varchar NOT NULL DEFAULT (''), "pushbulletAccessToken" varchar, "pushoverApplicationToken" varchar, "pushoverUserKey" varchar, "watchlistSyncMovies" boolean, "watchlistSyncTv" boolean, "pushoverSound" varchar, CONSTRAINT "UQ_986a2b6d3c05eb4091bb8066f78" UNIQUE ("userId"), CONSTRAINT "FK_986a2b6d3c05eb4091bb8066f78" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
);
await queryRunner.query(
`INSERT INTO "temporary_user_settings"("id", "notificationTypes", "discordId", "userId", "originalLanguage", "telegramChatId", "telegramSendSilently", "pgpKey", "locale", "pushbulletAccessToken", "pushoverApplicationToken", "pushoverUserKey", "watchlistSyncMovies", "watchlistSyncTv", "pushoverSound") SELECT "id", "notificationTypes", "discordId", "userId", "originalLanguage", "telegramChatId", "telegramSendSilently", "pgpKey", "locale", "pushbulletAccessToken", "pushoverApplicationToken", "pushoverUserKey", "watchlistSyncMovies", "watchlistSyncTv", "pushoverSound" FROM "user_settings"`
);
await queryRunner.query(`DROP TABLE "user_settings"`);
await queryRunner.query(
`ALTER TABLE "temporary_user_settings" RENAME TO "user_settings"`
);
await queryRunner.query(`DROP INDEX "IDX_7157aad07c73f6a6ae3bbd5ef5"`);
await queryRunner.query(`DROP INDEX "IDX_41a289eb1fa489c1bc6f38d9c3"`);
await queryRunner.query(`DROP INDEX "IDX_7ff2d11f6a83cb52386eaebe74"`);
await queryRunner.query(
`CREATE TABLE "temporary_media" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "mediaType" varchar NOT NULL, "tmdbId" integer NOT NULL, "tvdbId" integer, "imdbId" varchar, "status" integer NOT NULL DEFAULT (1), "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "lastSeasonChange" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "status4k" integer NOT NULL DEFAULT (1), "mediaAddedAt" datetime, "serviceId" integer, "serviceId4k" integer, "externalServiceId" integer, "externalServiceId4k" integer, "externalServiceSlug" varchar, "externalServiceSlug4k" varchar, "ratingKey" varchar, "ratingKey4k" varchar, "jellyfinMediaId" varchar, "jellyfinMediaId4k" varchar, CONSTRAINT "UQ_41a289eb1fa489c1bc6f38d9c3c" UNIQUE ("tvdbId"))`
);
await queryRunner.query(
`INSERT INTO "temporary_media"("id", "mediaType", "tmdbId", "tvdbId", "imdbId", "status", "createdAt", "updatedAt", "lastSeasonChange", "status4k", "mediaAddedAt", "serviceId", "serviceId4k", "externalServiceId", "externalServiceId4k", "externalServiceSlug", "externalServiceSlug4k", "ratingKey", "ratingKey4k") SELECT "id", "mediaType", "tmdbId", "tvdbId", "imdbId", "status", "createdAt", "updatedAt", "lastSeasonChange", "status4k", "mediaAddedAt", "serviceId", "serviceId4k", "externalServiceId", "externalServiceId4k", "externalServiceSlug", "externalServiceSlug4k", "ratingKey", "ratingKey4k" FROM "media"`
);
await queryRunner.query(`DROP TABLE "media"`);
await queryRunner.query(`ALTER TABLE "temporary_media" RENAME TO "media"`);
await queryRunner.query(
`CREATE INDEX "IDX_7157aad07c73f6a6ae3bbd5ef5" ON "media" ("tmdbId") `
);
await queryRunner.query(
`CREATE INDEX "IDX_41a289eb1fa489c1bc6f38d9c3" ON "media" ("tvdbId") `
);
await queryRunner.query(
`CREATE INDEX "IDX_7ff2d11f6a83cb52386eaebe74" ON "media" ("imdbId") `
);
await queryRunner.query(
`CREATE TABLE "temporary_user_settings" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "notificationTypes" text, "discordId" varchar, "userId" integer, "originalLanguage" varchar, "telegramChatId" varchar, "telegramSendSilently" boolean, "pgpKey" varchar, "locale" varchar NOT NULL DEFAULT (''), "pushbulletAccessToken" varchar, "pushoverApplicationToken" varchar, "pushoverUserKey" varchar, "watchlistSyncMovies" boolean, "watchlistSyncTv" boolean, "pushoverSound" varchar, "discoverRegion" varchar, "streamingRegion" varchar, "telegramMessageThreadId" varchar, CONSTRAINT "UQ_986a2b6d3c05eb4091bb8066f78" UNIQUE ("userId"), CONSTRAINT "FK_986a2b6d3c05eb4091bb8066f78" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
);
await queryRunner.query(
`INSERT INTO "temporary_user_settings"("id", "notificationTypes", "discordId", "userId", "originalLanguage", "telegramChatId", "telegramSendSilently", "pgpKey", "locale", "pushbulletAccessToken", "pushoverApplicationToken", "pushoverUserKey", "watchlistSyncMovies", "watchlistSyncTv", "pushoverSound") SELECT "id", "notificationTypes", "discordId", "userId", "originalLanguage", "telegramChatId", "telegramSendSilently", "pgpKey", "locale", "pushbulletAccessToken", "pushoverApplicationToken", "pushoverUserKey", "watchlistSyncMovies", "watchlistSyncTv", "pushoverSound" FROM "user_settings"`
);
await queryRunner.query(`DROP TABLE "user_settings"`);
await queryRunner.query(
`ALTER TABLE "temporary_user_settings" RENAME TO "user_settings"`
);
await queryRunner.query(
`CREATE TABLE "temporary_user" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar NOT NULL, "username" varchar, "plexId" integer, "plexToken" varchar, "permissions" integer NOT NULL DEFAULT (0), "avatar" varchar NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "password" varchar, "userType" integer NOT NULL DEFAULT (1), "plexUsername" varchar, "resetPasswordGuid" varchar, "recoveryLinkExpirationDate" date, "movieQuotaLimit" integer, "movieQuotaDays" integer, "tvQuotaLimit" integer, "tvQuotaDays" integer, "jellyfinUsername" varchar, "jellyfinUserId" varchar, "jellyfinDeviceId" varchar, "jellyfinAuthToken" varchar, "avatarETag" varchar, "avatarVersion" varchar, CONSTRAINT "UQ_e12875dfb3b1d92d7d7c5377e22" UNIQUE ("email"))`
);
await queryRunner.query(
`INSERT INTO "temporary_user"("id", "email", "username", "plexId", "plexToken", "permissions", "avatar", "createdAt", "updatedAt", "password", "userType", "plexUsername", "resetPasswordGuid", "recoveryLinkExpirationDate", "movieQuotaLimit", "movieQuotaDays", "tvQuotaLimit", "tvQuotaDays") SELECT "id", "email", "username", "plexId", "plexToken", "permissions", "avatar", "createdAt", "updatedAt", "password", "userType", "plexUsername", "resetPasswordGuid", "recoveryLinkExpirationDate", "movieQuotaLimit", "movieQuotaDays", "tvQuotaLimit", "tvQuotaDays" FROM "user"`
);
await queryRunner.query(`DROP TABLE "user"`);
await queryRunner.query(`ALTER TABLE "temporary_user" RENAME TO "user"`);
await queryRunner.query(
`CREATE TABLE "temporary_season_request" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "seasonNumber" integer NOT NULL, "status" integer NOT NULL DEFAULT (1), "createdAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "updatedAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "requestId" integer, CONSTRAINT "FK_6f14737e346d6b27d8e50d2157a" FOREIGN KEY ("requestId") REFERENCES "media_request" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
);
await queryRunner.query(
`INSERT INTO "temporary_season_request"("id", "seasonNumber", "status", "createdAt", "updatedAt", "requestId") SELECT "id", "seasonNumber", "status", "createdAt", "updatedAt", "requestId" FROM "season_request"`
);
await queryRunner.query(`DROP TABLE "season_request"`);
await queryRunner.query(
`ALTER TABLE "temporary_season_request" RENAME TO "season_request"`
);
await queryRunner.query(
`CREATE TABLE "temporary_media_request" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "status" integer NOT NULL, "createdAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "updatedAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "type" varchar NOT NULL, "mediaId" integer, "requestedById" integer, "modifiedById" integer, "is4k" boolean NOT NULL DEFAULT (0), "serverId" integer, "profileId" integer, "rootFolder" varchar, "languageProfileId" integer, "tags" text, "isAutoRequest" boolean NOT NULL DEFAULT (0), CONSTRAINT "FK_f4fc4efa14c3ba2b29c4525fa15" FOREIGN KEY ("modifiedById") REFERENCES "user" ("id") ON DELETE SET NULL ON UPDATE NO ACTION, CONSTRAINT "FK_6997bee94720f1ecb7f31137095" FOREIGN KEY ("requestedById") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_a1aa713f41c99e9d10c48da75a0" FOREIGN KEY ("mediaId") REFERENCES "media" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
);
await queryRunner.query(
`INSERT INTO "temporary_media_request"("id", "status", "createdAt", "updatedAt", "type", "mediaId", "requestedById", "modifiedById", "is4k", "serverId", "profileId", "rootFolder", "languageProfileId", "tags", "isAutoRequest") SELECT "id", "status", "createdAt", "updatedAt", "type", "mediaId", "requestedById", "modifiedById", "is4k", "serverId", "profileId", "rootFolder", "languageProfileId", "tags", "isAutoRequest" FROM "media_request"`
);
await queryRunner.query(`DROP TABLE "media_request"`);
await queryRunner.query(
`ALTER TABLE "temporary_media_request" RENAME TO "media_request"`
);
await queryRunner.query(
`CREATE TABLE "temporary_season" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "seasonNumber" integer NOT NULL, "status" integer NOT NULL DEFAULT (1), "createdAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "updatedAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "mediaId" integer, "status4k" integer NOT NULL DEFAULT (1), CONSTRAINT "FK_087099b39600be695591da9a49c" FOREIGN KEY ("mediaId") REFERENCES "media" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
);
await queryRunner.query(
`INSERT INTO "temporary_season"("id", "seasonNumber", "status", "createdAt", "updatedAt", "mediaId", "status4k") SELECT "id", "seasonNumber", "status", "createdAt", "updatedAt", "mediaId", "status4k" FROM "season"`
);
await queryRunner.query(`DROP TABLE "season"`);
await queryRunner.query(
`ALTER TABLE "temporary_season" RENAME TO "season"`
);
await queryRunner.query(`DROP INDEX "IDX_7157aad07c73f6a6ae3bbd5ef5"`);
await queryRunner.query(`DROP INDEX "IDX_41a289eb1fa489c1bc6f38d9c3"`);
await queryRunner.query(`DROP INDEX "IDX_7ff2d11f6a83cb52386eaebe74"`);
await queryRunner.query(
`CREATE TABLE "temporary_media" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "mediaType" varchar NOT NULL, "tmdbId" integer NOT NULL, "tvdbId" integer, "imdbId" varchar, "status" integer NOT NULL DEFAULT (1), "createdAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "updatedAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "lastSeasonChange" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "status4k" integer NOT NULL DEFAULT (1), "mediaAddedAt" datetime DEFAULT (CURRENT_TIMESTAMP), "serviceId" integer, "serviceId4k" integer, "externalServiceId" integer, "externalServiceId4k" integer, "externalServiceSlug" varchar, "externalServiceSlug4k" varchar, "ratingKey" varchar, "ratingKey4k" varchar, "jellyfinMediaId" varchar, "jellyfinMediaId4k" varchar, CONSTRAINT "UQ_41a289eb1fa489c1bc6f38d9c3c" UNIQUE ("tvdbId"))`
);
await queryRunner.query(
`INSERT INTO "temporary_media"("id", "mediaType", "tmdbId", "tvdbId", "imdbId", "status", "createdAt", "updatedAt", "lastSeasonChange", "status4k", "mediaAddedAt", "serviceId", "serviceId4k", "externalServiceId", "externalServiceId4k", "externalServiceSlug", "externalServiceSlug4k", "ratingKey", "ratingKey4k", "jellyfinMediaId", "jellyfinMediaId4k") SELECT "id", "mediaType", "tmdbId", "tvdbId", "imdbId", "status", "createdAt", "updatedAt", "lastSeasonChange", "status4k", "mediaAddedAt", "serviceId", "serviceId4k", "externalServiceId", "externalServiceId4k", "externalServiceSlug", "externalServiceSlug4k", "ratingKey", "ratingKey4k", "jellyfinMediaId", "jellyfinMediaId4k" FROM "media"`
);
await queryRunner.query(`DROP TABLE "media"`);
await queryRunner.query(`ALTER TABLE "temporary_media" RENAME TO "media"`);
await queryRunner.query(
`CREATE INDEX "IDX_7157aad07c73f6a6ae3bbd5ef5" ON "media" ("tmdbId") `
);
await queryRunner.query(
`CREATE INDEX "IDX_41a289eb1fa489c1bc6f38d9c3" ON "media" ("tvdbId") `
);
await queryRunner.query(
`CREATE INDEX "IDX_7ff2d11f6a83cb52386eaebe74" ON "media" ("imdbId") `
);
await queryRunner.query(
`CREATE TABLE "temporary_user_push_subscription" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "endpoint" varchar NOT NULL, "p256dh" varchar NOT NULL, "auth" varchar NOT NULL, "userId" integer, "userAgent" varchar, "createdAt" datetime DEFAULT (CURRENT_TIMESTAMP), CONSTRAINT "UQ_f90ab5a4ed54905a4bb51a7148b" UNIQUE ("auth"), CONSTRAINT "FK_03f7958328e311761b0de675fbe" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
);
await queryRunner.query(
`INSERT INTO "temporary_user_push_subscription"("id", "endpoint", "p256dh", "auth", "userId", "userAgent", "createdAt") SELECT "id", "endpoint", "p256dh", "auth", "userId", "userAgent", "createdAt" FROM "user_push_subscription"`
);
await queryRunner.query(`DROP TABLE "user_push_subscription"`);
await queryRunner.query(
`ALTER TABLE "temporary_user_push_subscription" RENAME TO "user_push_subscription"`
);
await queryRunner.query(
`CREATE TABLE "temporary_user" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar NOT NULL, "username" varchar, "plexId" integer, "plexToken" varchar, "permissions" integer NOT NULL DEFAULT (0), "avatar" varchar NOT NULL, "createdAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "updatedAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "password" varchar, "userType" integer NOT NULL DEFAULT (1), "plexUsername" varchar, "resetPasswordGuid" varchar, "recoveryLinkExpirationDate" date, "movieQuotaLimit" integer, "movieQuotaDays" integer, "tvQuotaLimit" integer, "tvQuotaDays" integer, "jellyfinUsername" varchar, "jellyfinUserId" varchar, "jellyfinDeviceId" varchar, "jellyfinAuthToken" varchar, "avatarETag" varchar, "avatarVersion" varchar, CONSTRAINT "UQ_e12875dfb3b1d92d7d7c5377e22" UNIQUE ("email"))`
);
await queryRunner.query(
`INSERT INTO "temporary_user"("id", "email", "username", "plexId", "plexToken", "permissions", "avatar", "createdAt", "updatedAt", "password", "userType", "plexUsername", "resetPasswordGuid", "recoveryLinkExpirationDate", "movieQuotaLimit", "movieQuotaDays", "tvQuotaLimit", "tvQuotaDays", "jellyfinUsername", "jellyfinUserId", "jellyfinDeviceId", "jellyfinAuthToken", "avatarETag", "avatarVersion") SELECT "id", "email", "username", "plexId", "plexToken", "permissions", "avatar", "createdAt", "updatedAt", "password", "userType", "plexUsername", "resetPasswordGuid", "recoveryLinkExpirationDate", "movieQuotaLimit", "movieQuotaDays", "tvQuotaLimit", "tvQuotaDays", "jellyfinUsername", "jellyfinUserId", "jellyfinDeviceId", "jellyfinAuthToken", "avatarETag", "avatarVersion" FROM "user"`
);
await queryRunner.query(`DROP TABLE "user"`);
await queryRunner.query(`ALTER TABLE "temporary_user" RENAME TO "user"`);
await queryRunner.query(
`CREATE TABLE "temporary_issue_comment" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "message" text NOT NULL, "createdAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "updatedAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "userId" integer, "issueId" integer, CONSTRAINT "FK_180710fead1c94ca499c57a7d42" FOREIGN KEY ("issueId") REFERENCES "issue" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_707b033c2d0653f75213614789d" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
);
await queryRunner.query(
`INSERT INTO "temporary_issue_comment"("id", "message", "createdAt", "updatedAt", "userId", "issueId") SELECT "id", "message", "createdAt", "updatedAt", "userId", "issueId" FROM "issue_comment"`
);
await queryRunner.query(`DROP TABLE "issue_comment"`);
await queryRunner.query(
`ALTER TABLE "temporary_issue_comment" RENAME TO "issue_comment"`
);
await queryRunner.query(
`CREATE TABLE "temporary_issue" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "issueType" integer NOT NULL, "status" integer NOT NULL DEFAULT (1), "problemSeason" integer NOT NULL DEFAULT (0), "problemEpisode" integer NOT NULL DEFAULT (0), "createdAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "updatedAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "mediaId" integer, "createdById" integer, "modifiedById" integer, CONSTRAINT "FK_da88a1019c850d1a7b143ca02e5" FOREIGN KEY ("modifiedById") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_10b17b49d1ee77e7184216001e0" FOREIGN KEY ("createdById") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_276e20d053f3cff1645803c95d8" FOREIGN KEY ("mediaId") REFERENCES "media" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
);
await queryRunner.query(
`INSERT INTO "temporary_issue"("id", "issueType", "status", "problemSeason", "problemEpisode", "createdAt", "updatedAt", "mediaId", "createdById", "modifiedById") SELECT "id", "issueType", "status", "problemSeason", "problemEpisode", "createdAt", "updatedAt", "mediaId", "createdById", "modifiedById" FROM "issue"`
);
await queryRunner.query(`DROP TABLE "issue"`);
await queryRunner.query(`ALTER TABLE "temporary_issue" RENAME TO "issue"`);
await queryRunner.query(
`CREATE TABLE "temporary_discover_slider" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "type" integer NOT NULL, "order" integer NOT NULL, "isBuiltIn" boolean NOT NULL DEFAULT (0), "enabled" boolean NOT NULL DEFAULT (1), "title" varchar, "data" varchar, "createdAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "updatedAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP))`
);
await queryRunner.query(
`INSERT INTO "temporary_discover_slider"("id", "type", "order", "isBuiltIn", "enabled", "title", "data", "createdAt", "updatedAt") SELECT "id", "type", "order", "isBuiltIn", "enabled", "title", "data", "createdAt", "updatedAt" FROM "discover_slider"`
);
await queryRunner.query(`DROP TABLE "discover_slider"`);
await queryRunner.query(
`ALTER TABLE "temporary_discover_slider" RENAME TO "discover_slider"`
);
await queryRunner.query(`DROP INDEX "IDX_6bbafa28411e6046421991ea21"`);
await queryRunner.query(
`CREATE TABLE "temporary_blacklist" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "mediaType" varchar NOT NULL, "title" varchar, "tmdbId" integer NOT NULL, "blacklistedTags" varchar, "createdAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "userId" integer, "mediaId" integer, CONSTRAINT "UQ_6bbafa28411e6046421991ea21c" UNIQUE ("tmdbId"), CONSTRAINT "REL_62b7ade94540f9f8d8bede54b9" UNIQUE ("mediaId"), CONSTRAINT "FK_53c1ab62c3e5875bc3ac474823e" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_62b7ade94540f9f8d8bede54b99" FOREIGN KEY ("mediaId") REFERENCES "media" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
);
await queryRunner.query(
`INSERT INTO "temporary_blacklist"("id", "mediaType", "title", "tmdbId", "blacklistedTags", "createdAt", "userId", "mediaId") SELECT "id", "mediaType", "title", "tmdbId", "blacklistedTags", "createdAt", "userId", "mediaId" FROM "blacklist"`
);
await queryRunner.query(`DROP TABLE "blacklist"`);
await queryRunner.query(
`ALTER TABLE "temporary_blacklist" RENAME TO "blacklist"`
);
await queryRunner.query(
`CREATE INDEX "IDX_6bbafa28411e6046421991ea21" ON "blacklist" ("tmdbId") `
);
await queryRunner.query(`DROP INDEX "IDX_939f205946256cc0d2a1ac51a8"`);
await queryRunner.query(
`CREATE TABLE "temporary_watchlist" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "ratingKey" varchar NOT NULL, "mediaType" varchar NOT NULL, "title" varchar NOT NULL, "tmdbId" integer NOT NULL, "createdAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "updatedAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "requestedById" integer, "mediaId" integer, CONSTRAINT "UNIQUE_USER_DB" UNIQUE ("tmdbId", "requestedById"), CONSTRAINT "FK_ae34e6b153a90672eb9dc4857d7" FOREIGN KEY ("requestedById") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_6641da8d831b93dfcb429f8b8bc" FOREIGN KEY ("mediaId") REFERENCES "media" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
);
await queryRunner.query(
`INSERT INTO "temporary_watchlist"("id", "ratingKey", "mediaType", "title", "tmdbId", "createdAt", "updatedAt", "requestedById", "mediaId") SELECT "id", "ratingKey", "mediaType", "title", "tmdbId", "createdAt", "updatedAt", "requestedById", "mediaId" FROM "watchlist"`
);
await queryRunner.query(`DROP TABLE "watchlist"`);
await queryRunner.query(
`ALTER TABLE "temporary_watchlist" RENAME TO "watchlist"`
);
await queryRunner.query(
`CREATE INDEX "IDX_939f205946256cc0d2a1ac51a8" ON "watchlist" ("tmdbId") `
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP INDEX "IDX_939f205946256cc0d2a1ac51a8"`);
await queryRunner.query(
`ALTER TABLE "watchlist" RENAME TO "temporary_watchlist"`
);
await queryRunner.query(
`CREATE TABLE "watchlist" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "ratingKey" varchar NOT NULL, "mediaType" varchar NOT NULL, "title" varchar NOT NULL, "tmdbId" integer NOT NULL, "createdAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "updatedAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "requestedById" integer, "mediaId" integer, CONSTRAINT "UNIQUE_USER_DB" UNIQUE ("tmdbId", "requestedById"))`
);
await queryRunner.query(
`INSERT INTO "watchlist"("id", "ratingKey", "mediaType", "title", "tmdbId", "createdAt", "updatedAt", "requestedById", "mediaId") SELECT "id", "ratingKey", "mediaType", "title", "tmdbId", "createdAt", "updatedAt", "requestedById", "mediaId" FROM "temporary_watchlist"`
);
await queryRunner.query(`DROP TABLE "temporary_watchlist"`);
await queryRunner.query(
`CREATE INDEX "IDX_939f205946256cc0d2a1ac51a8" ON "watchlist" ("tmdbId") `
);
await queryRunner.query(`DROP INDEX "IDX_6bbafa28411e6046421991ea21"`);
await queryRunner.query(
`ALTER TABLE "blacklist" RENAME TO "temporary_blacklist"`
);
await queryRunner.query(
`CREATE TABLE "blacklist" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "mediaType" varchar NOT NULL, "title" varchar, "tmdbId" integer NOT NULL, "blacklistedTags" varchar, "createdAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "userId" integer, "mediaId" integer, CONSTRAINT "UQ_6bbafa28411e6046421991ea21c" UNIQUE ("tmdbId"), CONSTRAINT "REL_62b7ade94540f9f8d8bede54b9" UNIQUE ("mediaId"))`
);
await queryRunner.query(
`INSERT INTO "blacklist"("id", "mediaType", "title", "tmdbId", "blacklistedTags", "createdAt", "userId", "mediaId") SELECT "id", "mediaType", "title", "tmdbId", "blacklistedTags", "createdAt", "userId", "mediaId" FROM "temporary_blacklist"`
);
await queryRunner.query(`DROP TABLE "temporary_blacklist"`);
await queryRunner.query(
`CREATE INDEX "IDX_6bbafa28411e6046421991ea21" ON "blacklist" ("tmdbId") `
);
await queryRunner.query(
`ALTER TABLE "discover_slider" RENAME TO "temporary_discover_slider"`
);
await queryRunner.query(
`CREATE TABLE "discover_slider" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "type" integer NOT NULL, "order" integer NOT NULL, "isBuiltIn" boolean NOT NULL DEFAULT (0), "enabled" boolean NOT NULL DEFAULT (1), "title" varchar, "data" varchar, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')))`
);
await queryRunner.query(
`INSERT INTO "discover_slider"("id", "type", "order", "isBuiltIn", "enabled", "title", "data", "createdAt", "updatedAt") SELECT "id", "type", "order", "isBuiltIn", "enabled", "title", "data", "createdAt", "updatedAt" FROM "temporary_discover_slider"`
);
await queryRunner.query(`DROP TABLE "temporary_discover_slider"`);
await queryRunner.query(`ALTER TABLE "issue" RENAME TO "temporary_issue"`);
await queryRunner.query(
`CREATE TABLE "issue" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "issueType" integer NOT NULL, "status" integer NOT NULL DEFAULT (1), "problemSeason" integer NOT NULL DEFAULT (0), "problemEpisode" integer NOT NULL DEFAULT (0), "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "mediaId" integer, "createdById" integer, "modifiedById" integer, CONSTRAINT "FK_da88a1019c850d1a7b143ca02e5" FOREIGN KEY ("modifiedById") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_10b17b49d1ee77e7184216001e0" FOREIGN KEY ("createdById") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_276e20d053f3cff1645803c95d8" FOREIGN KEY ("mediaId") REFERENCES "media" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
);
await queryRunner.query(
`INSERT INTO "issue"("id", "issueType", "status", "problemSeason", "problemEpisode", "createdAt", "updatedAt", "mediaId", "createdById", "modifiedById") SELECT "id", "issueType", "status", "problemSeason", "problemEpisode", "createdAt", "updatedAt", "mediaId", "createdById", "modifiedById" FROM "temporary_issue"`
);
await queryRunner.query(`DROP TABLE "temporary_issue"`);
await queryRunner.query(
`ALTER TABLE "issue_comment" RENAME TO "temporary_issue_comment"`
);
await queryRunner.query(
`CREATE TABLE "issue_comment" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "message" text NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "userId" integer, "issueId" integer, CONSTRAINT "FK_180710fead1c94ca499c57a7d42" FOREIGN KEY ("issueId") REFERENCES "issue" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_707b033c2d0653f75213614789d" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
);
await queryRunner.query(
`INSERT INTO "issue_comment"("id", "message", "createdAt", "updatedAt", "userId", "issueId") SELECT "id", "message", "createdAt", "updatedAt", "userId", "issueId" FROM "temporary_issue_comment"`
);
await queryRunner.query(`DROP TABLE "temporary_issue_comment"`);
await queryRunner.query(`ALTER TABLE "user" RENAME TO "temporary_user"`);
await queryRunner.query(
`CREATE TABLE "user" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar NOT NULL, "username" varchar, "plexId" integer, "plexToken" varchar, "permissions" integer NOT NULL DEFAULT (0), "avatar" varchar NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "password" varchar, "userType" integer NOT NULL DEFAULT (1), "plexUsername" varchar, "resetPasswordGuid" varchar, "recoveryLinkExpirationDate" date, "movieQuotaLimit" integer, "movieQuotaDays" integer, "tvQuotaLimit" integer, "tvQuotaDays" integer, "jellyfinUsername" varchar, "jellyfinUserId" varchar, "jellyfinDeviceId" varchar, "jellyfinAuthToken" varchar, "avatarETag" varchar, "avatarVersion" varchar, CONSTRAINT "UQ_e12875dfb3b1d92d7d7c5377e22" UNIQUE ("email"))`
);
await queryRunner.query(
`INSERT INTO "user"("id", "email", "username", "plexId", "plexToken", "permissions", "avatar", "createdAt", "updatedAt", "password", "userType", "plexUsername", "resetPasswordGuid", "recoveryLinkExpirationDate", "movieQuotaLimit", "movieQuotaDays", "tvQuotaLimit", "tvQuotaDays", "jellyfinUsername", "jellyfinUserId", "jellyfinDeviceId", "jellyfinAuthToken", "avatarETag", "avatarVersion") SELECT "id", "email", "username", "plexId", "plexToken", "permissions", "avatar", "createdAt", "updatedAt", "password", "userType", "plexUsername", "resetPasswordGuid", "recoveryLinkExpirationDate", "movieQuotaLimit", "movieQuotaDays", "tvQuotaLimit", "tvQuotaDays", "jellyfinUsername", "jellyfinUserId", "jellyfinDeviceId", "jellyfinAuthToken", "avatarETag", "avatarVersion" FROM "temporary_user"`
);
await queryRunner.query(`DROP TABLE "temporary_user"`);
await queryRunner.query(
`ALTER TABLE "user_push_subscription" RENAME TO "temporary_user_push_subscription"`
);
await queryRunner.query(
`CREATE TABLE "user_push_subscription" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "endpoint" varchar NOT NULL, "p256dh" varchar NOT NULL, "auth" varchar NOT NULL, "userId" integer, "userAgent" varchar DEFAULT (NULL), "createdAt" datetime DEFAULT (datetime('now')), CONSTRAINT "UQ_f90ab5a4ed54905a4bb51a7148b" UNIQUE ("auth"), CONSTRAINT "FK_03f7958328e311761b0de675fbe" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
);
await queryRunner.query(
`INSERT INTO "user_push_subscription"("id", "endpoint", "p256dh", "auth", "userId", "userAgent", "createdAt") SELECT "id", "endpoint", "p256dh", "auth", "userId", "userAgent", "createdAt" FROM "temporary_user_push_subscription"`
);
await queryRunner.query(`DROP TABLE "temporary_user_push_subscription"`);
await queryRunner.query(`DROP INDEX "IDX_7ff2d11f6a83cb52386eaebe74"`);
await queryRunner.query(`DROP INDEX "IDX_41a289eb1fa489c1bc6f38d9c3"`);
await queryRunner.query(`DROP INDEX "IDX_7157aad07c73f6a6ae3bbd5ef5"`);
await queryRunner.query(`ALTER TABLE "media" RENAME TO "temporary_media"`);
await queryRunner.query(
`CREATE TABLE "media" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "mediaType" varchar NOT NULL, "tmdbId" integer NOT NULL, "tvdbId" integer, "imdbId" varchar, "status" integer NOT NULL DEFAULT (1), "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "lastSeasonChange" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "status4k" integer NOT NULL DEFAULT (1), "mediaAddedAt" datetime, "serviceId" integer, "serviceId4k" integer, "externalServiceId" integer, "externalServiceId4k" integer, "externalServiceSlug" varchar, "externalServiceSlug4k" varchar, "ratingKey" varchar, "ratingKey4k" varchar, "jellyfinMediaId" varchar, "jellyfinMediaId4k" varchar, CONSTRAINT "UQ_41a289eb1fa489c1bc6f38d9c3c" UNIQUE ("tvdbId"))`
);
await queryRunner.query(
`INSERT INTO "media"("id", "mediaType", "tmdbId", "tvdbId", "imdbId", "status", "createdAt", "updatedAt", "lastSeasonChange", "status4k", "mediaAddedAt", "serviceId", "serviceId4k", "externalServiceId", "externalServiceId4k", "externalServiceSlug", "externalServiceSlug4k", "ratingKey", "ratingKey4k", "jellyfinMediaId", "jellyfinMediaId4k") SELECT "id", "mediaType", "tmdbId", "tvdbId", "imdbId", "status", "createdAt", "updatedAt", "lastSeasonChange", "status4k", "mediaAddedAt", "serviceId", "serviceId4k", "externalServiceId", "externalServiceId4k", "externalServiceSlug", "externalServiceSlug4k", "ratingKey", "ratingKey4k", "jellyfinMediaId", "jellyfinMediaId4k" FROM "temporary_media"`
);
await queryRunner.query(`DROP TABLE "temporary_media"`);
await queryRunner.query(
`CREATE INDEX "IDX_7ff2d11f6a83cb52386eaebe74" ON "media" ("imdbId") `
);
await queryRunner.query(
`CREATE INDEX "IDX_41a289eb1fa489c1bc6f38d9c3" ON "media" ("tvdbId") `
);
await queryRunner.query(
`CREATE INDEX "IDX_7157aad07c73f6a6ae3bbd5ef5" ON "media" ("tmdbId") `
);
await queryRunner.query(
`ALTER TABLE "season" RENAME TO "temporary_season"`
);
await queryRunner.query(
`CREATE TABLE "season" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "seasonNumber" integer NOT NULL, "status" integer NOT NULL DEFAULT (1), "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "mediaId" integer, "status4k" integer NOT NULL DEFAULT (1), CONSTRAINT "FK_087099b39600be695591da9a49c" FOREIGN KEY ("mediaId") REFERENCES "media" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
);
await queryRunner.query(
`INSERT INTO "season"("id", "seasonNumber", "status", "createdAt", "updatedAt", "mediaId", "status4k") SELECT "id", "seasonNumber", "status", "createdAt", "updatedAt", "mediaId", "status4k" FROM "temporary_season"`
);
await queryRunner.query(`DROP TABLE "temporary_season"`);
await queryRunner.query(
`ALTER TABLE "media_request" RENAME TO "temporary_media_request"`
);
await queryRunner.query(
`CREATE TABLE "media_request" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "status" integer NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "type" varchar NOT NULL, "mediaId" integer, "requestedById" integer, "modifiedById" integer, "is4k" boolean NOT NULL DEFAULT (0), "serverId" integer, "profileId" integer, "rootFolder" varchar, "languageProfileId" integer, "tags" text, "isAutoRequest" boolean NOT NULL DEFAULT (0), CONSTRAINT "FK_f4fc4efa14c3ba2b29c4525fa15" FOREIGN KEY ("modifiedById") REFERENCES "user" ("id") ON DELETE SET NULL ON UPDATE NO ACTION, CONSTRAINT "FK_6997bee94720f1ecb7f31137095" FOREIGN KEY ("requestedById") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_a1aa713f41c99e9d10c48da75a0" FOREIGN KEY ("mediaId") REFERENCES "media" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
);
await queryRunner.query(
`INSERT INTO "media_request"("id", "status", "createdAt", "updatedAt", "type", "mediaId", "requestedById", "modifiedById", "is4k", "serverId", "profileId", "rootFolder", "languageProfileId", "tags", "isAutoRequest") SELECT "id", "status", "createdAt", "updatedAt", "type", "mediaId", "requestedById", "modifiedById", "is4k", "serverId", "profileId", "rootFolder", "languageProfileId", "tags", "isAutoRequest" FROM "temporary_media_request"`
);
await queryRunner.query(`DROP TABLE "temporary_media_request"`);
await queryRunner.query(
`ALTER TABLE "season_request" RENAME TO "temporary_season_request"`
);
await queryRunner.query(
`CREATE TABLE "season_request" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "seasonNumber" integer NOT NULL, "status" integer NOT NULL DEFAULT (1), "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "requestId" integer, CONSTRAINT "FK_6f14737e346d6b27d8e50d2157a" FOREIGN KEY ("requestId") REFERENCES "media_request" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
);
await queryRunner.query(
`INSERT INTO "season_request"("id", "seasonNumber", "status", "createdAt", "updatedAt", "requestId") SELECT "id", "seasonNumber", "status", "createdAt", "updatedAt", "requestId" FROM "temporary_season_request"`
);
await queryRunner.query(`DROP TABLE "temporary_season_request"`);
await queryRunner.query(`ALTER TABLE "user" RENAME TO "temporary_user"`);
await queryRunner.query(
`CREATE TABLE "user" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar NOT NULL, "username" varchar, "plexId" integer, "plexToken" varchar, "permissions" integer NOT NULL DEFAULT (0), "avatar" varchar NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "password" varchar, "userType" integer NOT NULL DEFAULT (1), "plexUsername" varchar, "resetPasswordGuid" varchar, "recoveryLinkExpirationDate" date, "movieQuotaLimit" integer, "movieQuotaDays" integer, "tvQuotaLimit" integer, "tvQuotaDays" integer, CONSTRAINT "UQ_e12875dfb3b1d92d7d7c5377e22" UNIQUE ("email"))`
);
await queryRunner.query(
`INSERT INTO "user"("id", "email", "username", "plexId", "plexToken", "permissions", "avatar", "createdAt", "updatedAt", "password", "userType", "plexUsername", "resetPasswordGuid", "recoveryLinkExpirationDate", "movieQuotaLimit", "movieQuotaDays", "tvQuotaLimit", "tvQuotaDays") SELECT "id", "email", "username", "plexId", "plexToken", "permissions", "avatar", "createdAt", "updatedAt", "password", "userType", "plexUsername", "resetPasswordGuid", "recoveryLinkExpirationDate", "movieQuotaLimit", "movieQuotaDays", "tvQuotaLimit", "tvQuotaDays" FROM "temporary_user"`
);
await queryRunner.query(`DROP TABLE "temporary_user"`);
await queryRunner.query(
`ALTER TABLE "user_settings" RENAME TO "temporary_user_settings"`
);
await queryRunner.query(
`CREATE TABLE "user_settings" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "notificationTypes" text, "discordId" varchar, "userId" integer, "originalLanguage" varchar, "telegramChatId" varchar, "telegramSendSilently" boolean, "pgpKey" varchar, "locale" varchar NOT NULL DEFAULT (''), "pushbulletAccessToken" varchar, "pushoverApplicationToken" varchar, "pushoverUserKey" varchar, "watchlistSyncMovies" boolean, "watchlistSyncTv" boolean, "pushoverSound" varchar, CONSTRAINT "UQ_986a2b6d3c05eb4091bb8066f78" UNIQUE ("userId"), CONSTRAINT "FK_986a2b6d3c05eb4091bb8066f78" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
);
await queryRunner.query(
`INSERT INTO "user_settings"("id", "notificationTypes", "discordId", "userId", "originalLanguage", "telegramChatId", "telegramSendSilently", "pgpKey", "locale", "pushbulletAccessToken", "pushoverApplicationToken", "pushoverUserKey", "watchlistSyncMovies", "watchlistSyncTv", "pushoverSound") SELECT "id", "notificationTypes", "discordId", "userId", "originalLanguage", "telegramChatId", "telegramSendSilently", "pgpKey", "locale", "pushbulletAccessToken", "pushoverApplicationToken", "pushoverUserKey", "watchlistSyncMovies", "watchlistSyncTv", "pushoverSound" FROM "temporary_user_settings"`
);
await queryRunner.query(`DROP TABLE "temporary_user_settings"`);
await queryRunner.query(`DROP INDEX "IDX_7ff2d11f6a83cb52386eaebe74"`);
await queryRunner.query(`DROP INDEX "IDX_41a289eb1fa489c1bc6f38d9c3"`);
await queryRunner.query(`DROP INDEX "IDX_7157aad07c73f6a6ae3bbd5ef5"`);
await queryRunner.query(`ALTER TABLE "media" RENAME TO "temporary_media"`);
await queryRunner.query(
`CREATE TABLE "media" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "mediaType" varchar NOT NULL, "tmdbId" integer NOT NULL, "tvdbId" integer, "imdbId" varchar, "status" integer NOT NULL DEFAULT (1), "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "lastSeasonChange" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "status4k" integer NOT NULL DEFAULT (1), "mediaAddedAt" datetime, "serviceId" integer, "serviceId4k" integer, "externalServiceId" integer, "externalServiceId4k" integer, "externalServiceSlug" varchar, "externalServiceSlug4k" varchar, "ratingKey" varchar, "ratingKey4k" varchar, CONSTRAINT "UQ_41a289eb1fa489c1bc6f38d9c3c" UNIQUE ("tvdbId"))`
);
await queryRunner.query(
`INSERT INTO "media"("id", "mediaType", "tmdbId", "tvdbId", "imdbId", "status", "createdAt", "updatedAt", "lastSeasonChange", "status4k", "mediaAddedAt", "serviceId", "serviceId4k", "externalServiceId", "externalServiceId4k", "externalServiceSlug", "externalServiceSlug4k", "ratingKey", "ratingKey4k") SELECT "id", "mediaType", "tmdbId", "tvdbId", "imdbId", "status", "createdAt", "updatedAt", "lastSeasonChange", "status4k", "mediaAddedAt", "serviceId", "serviceId4k", "externalServiceId", "externalServiceId4k", "externalServiceSlug", "externalServiceSlug4k", "ratingKey", "ratingKey4k" FROM "temporary_media"`
);
await queryRunner.query(`DROP TABLE "temporary_media"`);
await queryRunner.query(
`CREATE INDEX "IDX_7ff2d11f6a83cb52386eaebe74" ON "media" ("imdbId") `
);
await queryRunner.query(
`CREATE INDEX "IDX_41a289eb1fa489c1bc6f38d9c3" ON "media" ("tvdbId") `
);
await queryRunner.query(
`CREATE INDEX "IDX_7157aad07c73f6a6ae3bbd5ef5" ON "media" ("tmdbId") `
);
await queryRunner.query(
`ALTER TABLE "user_settings" RENAME TO "temporary_user_settings"`
);
await queryRunner.query(
`CREATE TABLE "user_settings" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "notificationTypes" text, "discordId" varchar, "userId" integer, "region" varchar, "originalLanguage" varchar, "telegramChatId" varchar, "telegramSendSilently" boolean, "pgpKey" varchar, "locale" varchar NOT NULL DEFAULT (''), "pushbulletAccessToken" varchar, "pushoverApplicationToken" varchar, "pushoverUserKey" varchar, "watchlistSyncMovies" boolean, "watchlistSyncTv" boolean, "pushoverSound" varchar, CONSTRAINT "UQ_986a2b6d3c05eb4091bb8066f78" UNIQUE ("userId"), CONSTRAINT "FK_986a2b6d3c05eb4091bb8066f78" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
);
await queryRunner.query(
`INSERT INTO "user_settings"("id", "notificationTypes", "discordId", "userId", "originalLanguage", "telegramChatId", "telegramSendSilently", "pgpKey", "locale", "pushbulletAccessToken", "pushoverApplicationToken", "pushoverUserKey", "watchlistSyncMovies", "watchlistSyncTv", "pushoverSound") SELECT "id", "notificationTypes", "discordId", "userId", "originalLanguage", "telegramChatId", "telegramSendSilently", "pgpKey", "locale", "pushbulletAccessToken", "pushoverApplicationToken", "pushoverUserKey", "watchlistSyncMovies", "watchlistSyncTv", "pushoverSound" FROM "temporary_user_settings"`
);
await queryRunner.query(`DROP TABLE "temporary_user_settings"`);
await queryRunner.query(`DROP INDEX "IDX_939f205946256cc0d2a1ac51a8"`);
await queryRunner.query(`DROP TABLE "watchlist"`);
await queryRunner.query(`DROP TABLE "override_rule"`);
await queryRunner.query(`DROP INDEX "IDX_6bbafa28411e6046421991ea21"`);
await queryRunner.query(`DROP TABLE "blacklist"`);
await queryRunner.query(
`ALTER TABLE "user_push_subscription" RENAME TO "temporary_user_push_subscription"`
);
await queryRunner.query(
`CREATE TABLE "user_push_subscription" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "endpoint" varchar NOT NULL, "p256dh" varchar NOT NULL, "auth" varchar NOT NULL, "userId" integer, "userAgent" varchar DEFAULT (NULL), "createdAt" datetime DEFAULT (datetime('now')), CONSTRAINT "UQ_f90ab5a4ed54905a4bb51a7148b" UNIQUE ("auth"), CONSTRAINT "FK_03f7958328e311761b0de675fbe" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
);
await queryRunner.query(
`INSERT INTO "user_push_subscription"("id", "endpoint", "p256dh", "auth", "userId", "userAgent", "createdAt") SELECT "id", "endpoint", "p256dh", "auth", "userId", "userAgent", "createdAt" FROM "temporary_user_push_subscription"`
);
await queryRunner.query(`DROP TABLE "temporary_user_push_subscription"`);
}
}
export default checkOverseerrMerge;

View File

@@ -764,9 +764,13 @@ class Settings {
* This will load settings from file unless an optional argument of the object structure
* is passed in.
* @param overrideSettings If passed in, will override all existing settings with these
* @param raw If true, will load the settings without running migrations or generating missing
* values
*/
public async load(overrideSettings?: AllSettings): Promise<Settings> {
public async load(
overrideSettings?: AllSettings,
raw = false
): Promise<Settings> {
if (overrideSettings) {
this.data = overrideSettings;
return this;
@@ -779,10 +783,12 @@ class Settings {
await this.save();
}
if (data) {
if (data && !raw) {
const parsedJson = JSON.parse(data);
const migratedData = await runMigrations(parsedJson, SETTINGS_PATH);
this.data = merge(this.data, migratedData);
} else if (data) {
this.data = JSON.parse(data);
}
// generate keys and ids if it's missing

View File

@@ -46,7 +46,7 @@ export const runMigrations = async (
} catch (e) {
// we stop Seerr if the migration failed
logger.error(
`Error while running migration '${migration}': ${e.message}`,
`Error while running migration '${migration}': ${e.message}\n${e.stack}`,
{
label: 'Settings Migrator',
}

View File

@@ -32,14 +32,14 @@ const logger = winston.createLogger({
}),
new winston.transports.DailyRotateFile({
filename: process.env.CONFIG_DIRECTORY
? `${process.env.CONFIG_DIRECTORY}/logs/jellyseerr-%DATE%.log`
: path.join(__dirname, '../config/logs/jellyseerr-%DATE%.log'),
? `${process.env.CONFIG_DIRECTORY}/logs/seerr-%DATE%.log`
: path.join(__dirname, '../config/logs/seerr-%DATE%.log'),
datePattern: 'YYYY-MM-DD',
zippedArchive: true,
maxSize: '20m',
maxFiles: '7d',
createSymlink: true,
symlinkName: 'jellyseerr.log',
symlinkName: 'seerr.log',
}),
new winston.transports.DailyRotateFile({
filename: process.env.CONFIG_DIRECTORY

View File

@@ -35,7 +35,7 @@ import useSWR from 'swr';
const messages = defineMessages('components.Settings.SettingsLogs', {
logs: 'Logs',
logsDescription:
'You can also view these logs directly via <code>stdout</code>, or in <code>{appDataPath}/logs/jellyseerr.log</code>.',
'You can also view these logs directly via <code>stdout</code>, or in <code>{appDataPath}/logs/seerr.log</code>.',
time: 'Timestamp',
level: 'Severity',
label: 'Label',

View File

@@ -950,7 +950,7 @@
"components.Settings.SettingsLogs.level": "Severity",
"components.Settings.SettingsLogs.logDetails": "Log Details",
"components.Settings.SettingsLogs.logs": "Logs",
"components.Settings.SettingsLogs.logsDescription": "You can also view these logs directly via <code>stdout</code>, or in <code>{appDataPath}/logs/jellyseerr.log</code>.",
"components.Settings.SettingsLogs.logsDescription": "You can also view these logs directly via <code>stdout</code>, or in <code>{appDataPath}/logs/seerr.log</code>.",
"components.Settings.SettingsLogs.message": "Message",
"components.Settings.SettingsLogs.pauseLogs": "Pause",
"components.Settings.SettingsLogs.resumeLogs": "Resume",