Compare commits
13 Commits
preview-pl
...
fix-retry-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de1bf4caff | ||
|
|
c6bcfe0ae4 | ||
|
|
6076878f76 | ||
|
|
8f0c904928 | ||
|
|
04b9d87174 | ||
|
|
b499976902 | ||
|
|
87fb0dfd6c | ||
|
|
b6a913211a | ||
|
|
39ae32f509 | ||
|
|
c2977f6430 | ||
|
|
92504b7864 | ||
|
|
018e04a657 | ||
|
|
e503de323a |
4
.github/cliff.toml
vendored
4
.github/cliff.toml
vendored
@@ -33,9 +33,9 @@ body = """
|
||||
{{ self::print_commit(commit=commit) }}
|
||||
{%- endfor %}
|
||||
{%- for commit in commits %}
|
||||
{%- if not commit.scope -%}
|
||||
{%- if not commit.scope %}
|
||||
{{ self::print_commit(commit=commit) }}
|
||||
{%- endif -%}
|
||||
{%- endif %}
|
||||
{%- endfor -%}
|
||||
{%- endfor -%}
|
||||
|
||||
|
||||
2
.github/renovate/helm.json5
vendored
2
.github/renovate/helm.json5
vendored
@@ -16,7 +16,7 @@
|
||||
description: 'Update appVersion in Chart.yaml to match Docker image',
|
||||
fileMatch: ['(^|/)Chart\\.yaml$'],
|
||||
matchStrings: [
|
||||
'#\\s+renovate:\\s+image=(?<depName>\\S*)\nappVersion:\\s+"(?<currentValue>\\S*)"',
|
||||
"#\\s+renovate:\\s+image=(?<depName>\\S*)\nappVersion:\\s+'(?<currentValue>\\S*)'",
|
||||
],
|
||||
datasourceTemplate: 'docker',
|
||||
},
|
||||
|
||||
2
.github/workflows/docs-deploy.yml
vendored
2
.github/workflows/docs-deploy.yml
vendored
@@ -6,7 +6,7 @@ on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- legacy-jellyseerr
|
||||
- develop
|
||||
paths:
|
||||
- 'docs/**'
|
||||
- 'gen-docs/**'
|
||||
|
||||
20
.github/workflows/release.yml
vendored
20
.github/workflows/release.yml
vendored
@@ -279,17 +279,17 @@ jobs:
|
||||
--certificate-identity "https://github.com/${{ github.workflow_ref }}" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
|
||||
|
||||
- name: Verify attestations
|
||||
run: |
|
||||
cosign verify-attestation "ghcr.io/${{ github.repository }}@${{ needs.publish.outputs.image_digest }}" \
|
||||
--type cyclonedx \
|
||||
--certificate-identity "https://github.com/${{ github.workflow_ref }}" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" > /dev/null
|
||||
# - name: Verify attestations
|
||||
# run: |
|
||||
# cosign verify-attestation "ghcr.io/${{ github.repository }}@${{ needs.publish.outputs.image_digest }}" \
|
||||
# --type cyclonedx \
|
||||
# --certificate-identity "https://github.com/${{ github.workflow_ref }}" \
|
||||
# --certificate-oidc-issuer "https://token.actions.githubusercontent.com" > /dev/null
|
||||
|
||||
cosign verify-attestation "${{ env.DOCKER_HUB }}@${{ needs.publish.outputs.image_digest }}" \
|
||||
--type cyclonedx \
|
||||
--certificate-identity "https://github.com/${{ github.workflow_ref }}" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" > /dev/null
|
||||
# cosign verify-attestation "${{ env.DOCKER_HUB }}@${{ needs.publish.outputs.image_digest }}" \
|
||||
# --type cyclonedx \
|
||||
# --certificate-identity "https://github.com/${{ github.workflow_ref }}" \
|
||||
# --certificate-oidc-issuer "https://token.actions.githubusercontent.com" > /dev/null
|
||||
|
||||
publish-release:
|
||||
name: Publish release
|
||||
|
||||
34
README.md
34
README.md
@@ -1,6 +1,6 @@
|
||||
<div align="center">⚠️ <strong>NOTE:</strong> We are currently in the process of merging Overseerr and Jellyseerr into this unified repository.</div>
|
||||
|
||||
<h1 align="center" style="font-size: 4em;">🚧 Seerr</h1>
|
||||
<p align="center">
|
||||
<img src="./public/logo_full.svg" alt="Seerr" style="margin: 20px 0;">
|
||||
</p>
|
||||
<p align="center">
|
||||
<img src="https://github.com/seerr-team/seerr/actions/workflows/release.yml/badge.svg" alt="Seerr Release" />
|
||||
<img src="https://github.com/seerr-team/seerr/actions/workflows/ci.yml/badge.svg" alt="Seerr CI">
|
||||
@@ -32,31 +32,19 @@ With more features on the way! Check out our [issue tracker](/../../issues) to s
|
||||
|
||||
## Getting Started
|
||||
|
||||
For instructions on how to install and run **Jellyseerr**, please refer to the official documentation:
|
||||
Check out our documentation for instructions on how to install and run Seerr:
|
||||
|
||||
https://docs.seerr.dev/getting-started/
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Seerr is not officially released yet.**
|
||||
> The project is currently available **only on the `develop` branch** and is intended for **beta testing only**.
|
||||
|
||||
The documentation linked above is for running the **latest Jellyseerr** release.
|
||||
|
||||
> [!WARNING]
|
||||
> If you are migrating from **Overseerr** to **Seerr** for beta testing, **do not follow the Jellyseerr latest setup guide**.
|
||||
|
||||
Instead, follow the dedicated migration guide (with `:develop` tag):
|
||||
https://github.com/seerr-team/seerr/blob/develop/docs/migration-guide.mdx
|
||||
|
||||
> [!CAUTION]
|
||||
> **DO NOT run Jellyseerr (latest) using an existing Overseerr database. This includes third-party images with `seerr:latest` (as it points to jellyseerr 2.7.3 and not seerr.**
|
||||
> Doing so **may cause database corruption and/or irreversible data loss and/or weird unintended behaviour**.
|
||||
|
||||
For migration assistance, beta testing questions, or troubleshooting, please join our **Discord** and ask for support there.
|
||||
|
||||
## Preview
|
||||
|
||||
<img src="./public/preview.jpg">
|
||||
<img src="./public/preview.jpg" alt="Seerr application preview" />
|
||||
|
||||
## Migrating from Overseerr/Jellyseerr to Seerr
|
||||
|
||||
Read our [release announcement](https://docs.seerr.dev/blog/seerr-release) to learn what Seerr means for Jellyseerr and Overseerr users.
|
||||
|
||||
Please follow our [migration guide](https://docs.seerr.dev/migration-guide) for detailed instructions on migrating from Overseerr or Jellyseerr.
|
||||
|
||||
## Support
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@ kubeVersion: '>=1.23.0-0'
|
||||
name: seerr-chart
|
||||
description: Seerr helm chart for Kubernetes
|
||||
type: application
|
||||
version: 3.0.0
|
||||
version: 3.1.0
|
||||
# renovate: image=ghcr.io/seerr-team/seerr
|
||||
appVersion: '3.0.0'
|
||||
appVersion: 'v3.0.1'
|
||||
maintainers:
|
||||
- name: Seerr Team
|
||||
url: https://github.com/orgs/seerr-team/people
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# seerr-chart
|
||||
|
||||
  
|
||||
  
|
||||
|
||||
Seerr helm chart for Kubernetes
|
||||
|
||||
@@ -44,9 +44,10 @@ If `replicaCount` value was used - remove it. Helm update should work fine after
|
||||
| Key | Type | Default | Description |
|
||||
|-----|------|---------|-------------|
|
||||
| affinity | object | `{}` | |
|
||||
| config | object | `{"persistence":{"accessModes":["ReadWriteOnce"],"annotations":{},"name":"","size":"5Gi","volumeName":""}}` | Creating PVC to store configuration |
|
||||
| config | object | `{"persistence":{"accessModes":["ReadWriteOnce"],"annotations":{},"existingClaim":"","name":"","size":"5Gi","volumeName":""}}` | Creating PVC to store configuration |
|
||||
| config.persistence.accessModes | list | `["ReadWriteOnce"]` | Access modes of persistent disk |
|
||||
| config.persistence.annotations | object | `{}` | Annotations for PVCs |
|
||||
| config.persistence.existingClaim | string | `""` | Specify an existing `PersistentVolumeClaim` to use. If this value is provided, the default PVC will not be created |
|
||||
| config.persistence.name | string | `""` | Config name |
|
||||
| config.persistence.size | string | `"5Gi"` | Size of persistent disk |
|
||||
| config.persistence.volumeName | string | `""` | Name of the permanent volume to reference in the claim. Can be used to bind to existing volumes. |
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{{- if not .Values.config.persistence.existingClaim -}}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
@@ -22,3 +23,4 @@ spec:
|
||||
resources:
|
||||
requests:
|
||||
storage: "{{ .Values.config.persistence.size }}"
|
||||
{{- end -}}
|
||||
@@ -103,7 +103,7 @@ spec:
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "seerr.configPersistenceName" . }}
|
||||
claimName: {{ if .Values.config.persistence.existingClaim }}{{ .Values.config.persistence.existingClaim }}{{- else }}{{ include "seerr.configPersistenceName" . }}{{- end }}
|
||||
{{- with .Values.volumes }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -86,6 +86,8 @@ config:
|
||||
# -- Name of the permanent volume to reference in the claim.
|
||||
# Can be used to bind to existing volumes.
|
||||
volumeName: ''
|
||||
# -- Specify an existing `PersistentVolumeClaim` to use. If this value is provided, the default PVC will not be created
|
||||
existingClaim: ''
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
|
||||
@@ -5,12 +5,7 @@ sidebar_position: 3
|
||||
---
|
||||
|
||||
# Unraid
|
||||
:::danger
|
||||
This method has not yet been updated for Seerr and is awaiting a community contribution.
|
||||
Feel free to open a pull request on GitHub to update this installation method.
|
||||
:::
|
||||
|
||||
<!--
|
||||
:::warning
|
||||
Third-party installation methods are maintained by the community. The Seerr team is not responsible for these packages.
|
||||
:::
|
||||
@@ -19,9 +14,68 @@ Third-party installation methods are maintained by the community. The Seerr team
|
||||
This method is not recommended for most users. It is intended for advanced users who are using Unraid.
|
||||
:::
|
||||
|
||||
1. Ensure you have the **Community Applications** plugin installed.
|
||||
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 "Seerr" at your `<ServerIP:HostPort>` in a web browser.
|
||||
-->
|
||||
|
||||
If an official Unraid Community Applications template for Seerr isn't available in your catalog, you can install Seerr manually using Unraid's Docker UI.
|
||||
|
||||
## Fresh Installation
|
||||
|
||||
### 1. Create the config directory
|
||||
|
||||
Open the Unraid terminal and run:
|
||||
|
||||
```bash
|
||||
mkdir -p /mnt/user/appdata/seerr
|
||||
chown -R 1000:1000 /mnt/user/appdata/seerr
|
||||
```
|
||||
|
||||
### 2. Add the Docker container
|
||||
|
||||
Navigate to the **Docker** tab in Unraid and click **Add Container**. Fill in the following:
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| **Name** | `seerr` |
|
||||
| **Repository** | `ghcr.io/seerr-team/seerr:latest` |
|
||||
| **Registry URL** (optional) | `https://ghcr.io` |
|
||||
| **Icon URL** | `https://raw.githubusercontent.com/seerr-team/seerr/develop/public/android-chrome-512x512.png` |
|
||||
| **WebUI** | `http://[IP]:[PORT:5055]` |
|
||||
| **Extra Parameters** | `--init` |
|
||||
| **Network Type** | `bridge` |
|
||||
| **Privileged** | `Off` |
|
||||
|
||||
Then click **Add another Path, Port, Variable** to add:
|
||||
|
||||
**Port:**
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Container Port | `5055` |
|
||||
| Host Port | `5055` |
|
||||
| Connection Type | `TCP` |
|
||||
|
||||
**Path:**
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Container Path | `/app/config` |
|
||||
| Host Path | `/mnt/user/appdata/seerr` |
|
||||
|
||||
**Variable:**
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Key | `TZ` |
|
||||
| Value | Your [TZ database name](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) (e.g., `America/New_York`) |
|
||||
|
||||
**Variable (optional):**
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Key | `LOG_LEVEL` |
|
||||
| Value | `info` |
|
||||
|
||||
Click **Apply** to create and start the container.
|
||||
|
||||
### 3. Access Seerr
|
||||
|
||||
Open the WebUI at `http://<your-unraid-ip>:5055` and follow the setup wizard.
|
||||
|
||||
:::info
|
||||
The `--init` flag in **Extra Parameters** is required. Seerr does not include its own init process, so `--init` ensures proper signal handling and clean container shutdowns.
|
||||
:::
|
||||
@@ -23,7 +23,6 @@ Installation methods are now divided into two categories: official and third-par
|
||||
The Seerr team is only responsible for official installation methods, while third-party methods are maintained by the community.
|
||||
Some methods are currently not maintained, but this does not mean they are permanently discontinued. The community may restore and support them if they choose to do so.
|
||||
|
||||
- **Unraid app:** Not maintained
|
||||
- **Snap package:** Not maintained
|
||||
:::
|
||||
|
||||
@@ -200,14 +199,82 @@ Summary of changes :
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Nix (Third-party installation methods)
|
||||
## Third-party installation methods
|
||||
### Nix
|
||||
|
||||
Waiting for https://github.com/NixOS/nixpkgs/pull/450096 and https://github.com/NixOS/nixpkgs/pull/450093
|
||||
|
||||
### AUR (Third-party installation methods)
|
||||
### AUR
|
||||
|
||||
See https://aur.archlinux.org/packages/seerr
|
||||
|
||||
### TrueNAS (Third-party installation methods)
|
||||
### TrueNAS
|
||||
|
||||
Waiting for https://github.com/truenas/apps/issues/3374
|
||||
|
||||
### Unraid
|
||||
|
||||
Refer to [Seerr Unraid Documentation](/getting-started/third-parties/unraid), all of our examples have been updated to reflect the below change.
|
||||
|
||||
Seerr will automatically migrate your existing Overseerr or Jellyseerr data on first startup. No manual database migration is needed.
|
||||
|
||||
1. Stop and remove the old Overseerr (or Jellyseerr) container from the Unraid **Docker** tab. Click the container icon, then **Stop**, then **Remove**. **⚠️ Do not delete the appdata folder ⚠️**
|
||||
|
||||
2. Back up your existing appdata folder:
|
||||
```bash
|
||||
cp -a /mnt/user/appdata/overseerr /mnt/user/appdata/overseerr-backup
|
||||
```
|
||||
|
||||
3. Fix config folder permissions — Seerr runs as the `node` user (UID 1000) instead of root:
|
||||
```bash
|
||||
chown -R 1000:1000 /mnt/user/appdata/overseerr
|
||||
```
|
||||
For Jellyseerr users, replace `overseerr` with `jellyseerr` in the path above.
|
||||
|
||||
4. Add a new container in the Unraid **Docker** tab. Click **Add Container** and fill in the following:
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| **Name** | `seerr` |
|
||||
| **Repository** | `ghcr.io/seerr-team/seerr:latest` |
|
||||
| **Registry URL** (optional) | `https://ghcr.io` |
|
||||
| **Icon URL** | `https://raw.githubusercontent.com/seerr-team/seerr/develop/public/android-chrome-512x512.png` |
|
||||
| **WebUI** | `http://[IP]:[PORT:5055]` |
|
||||
| **Extra Parameters** | `--init` |
|
||||
| **Network Type** | `bridge` |
|
||||
| **Privileged** | `Off` |
|
||||
|
||||
Then click **Add another Path, Port, Variable** to add:
|
||||
|
||||
**Port:**
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Container Port | `5055` |
|
||||
| Host Port | `5055` |
|
||||
| Connection Type | `TCP` |
|
||||
|
||||
**Path** — point this to your existing config folder:
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Container Path | `/app/config` |
|
||||
| Host Path | `/mnt/user/appdata/overseerr` |
|
||||
|
||||
For Jellyseerr users, use `/mnt/user/appdata/jellyseerr`.
|
||||
|
||||
**Variable:**
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Key | `TZ` |
|
||||
| Value | Your [TZ database name](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) (e.g., `America/New_York`) |
|
||||
|
||||
**Variable (optional):**
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Key | `LOG_LEVEL` |
|
||||
| Value | `info` |
|
||||
|
||||
5. Click **Apply** to start the container. Check the container logs to confirm the automatic migration completed successfully.
|
||||
|
||||
:::tip
|
||||
If you are using a reverse proxy (such as SWAG or Nginx Proxy Manager), update your proxy configuration to point to the new container name `seerr`. The default port remains `5055`.
|
||||
:::
|
||||
@@ -6,18 +6,22 @@ sidebar_position: 2
|
||||
|
||||
# Web Push
|
||||
|
||||
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 Seerr
|
||||
|
||||
:::warning
|
||||
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.
|
||||
The web push notification agent enables you and your users to receive Seerr notifications in a supported browser. This offers a native notification experience without the need to install an app.
|
||||
|
||||
Users can opt out of these notifications, or customize the notification types they would like to subscribe to, in their user settings.
|
||||
This notification agent does not require any configuration, but is not enabled by default in Seerr.
|
||||
|
||||
:::info
|
||||
Web push notifications offer a native notification experience without the need to install an app.
|
||||
To set up web push notifications, simply enable the agent in **Settings → Notifications → Web Push**.
|
||||
|
||||
You and your users have the option to enable web push notifications by going to your **User Profile → Edit Settings → Notifications → Web Push → Enable web push**. Here you can also customize the notifications you'd like to receive.
|
||||
|
||||
:::info[Mobile Users]
|
||||
For Web Push notifications to work on mobile you need to add Seerr to your home screen as progressive web app (PWA).
|
||||
:::
|
||||
|
||||
:::info[iOS Users]
|
||||
On iOS you may need to enable the Safari notifications feature flag by going to **Settings → Safari → Advanced → Feature Flags** and enabling "Notifications".
|
||||
:::
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// previously cached resources to be updated from the network.
|
||||
// This variable is intentionally declared and unused.
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const OFFLINE_VERSION = 4;
|
||||
const OFFLINE_VERSION = 5;
|
||||
const CACHE_NAME = 'offline';
|
||||
// Customize this with a different URL if needed.
|
||||
const OFFLINE_URL = '/offline.html';
|
||||
|
||||
@@ -92,7 +92,7 @@ class ServarrBase<QueueItemAppendT> extends ExternalAPI {
|
||||
apiKey,
|
||||
cacheName,
|
||||
apiName,
|
||||
timeout = 5000,
|
||||
timeout = 10000,
|
||||
}: {
|
||||
url: string;
|
||||
apiKey: string;
|
||||
|
||||
@@ -36,6 +36,7 @@ export class Blocklist implements BlocklistItem {
|
||||
@ManyToOne(() => User, (user) => user.id, {
|
||||
eager: true,
|
||||
})
|
||||
@Index()
|
||||
user?: User;
|
||||
|
||||
@OneToOne(() => Media, (media) => media.blocklist, {
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
AfterLoad,
|
||||
Column,
|
||||
Entity,
|
||||
Index,
|
||||
ManyToOne,
|
||||
OneToMany,
|
||||
PrimaryGeneratedColumn,
|
||||
@@ -19,6 +20,7 @@ class Issue {
|
||||
public id: number;
|
||||
|
||||
@Column({ type: 'int' })
|
||||
@Index()
|
||||
public issueType: IssueType;
|
||||
|
||||
@Column({ type: 'int', default: IssueStatus.OPEN })
|
||||
@@ -34,12 +36,14 @@ class Issue {
|
||||
eager: true,
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
@Index()
|
||||
public media: Media;
|
||||
|
||||
@ManyToOne(() => User, (user) => user.createdIssues, {
|
||||
eager: true,
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
@Index()
|
||||
public createdBy: User;
|
||||
|
||||
@ManyToOne(() => User, {
|
||||
@@ -47,6 +51,7 @@ class Issue {
|
||||
onDelete: 'CASCADE',
|
||||
nullable: true,
|
||||
})
|
||||
@Index()
|
||||
public modifiedBy?: User;
|
||||
|
||||
@OneToMany(() => IssueComment, (comment) => comment.issue, {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import { DbAwareColumn } from '@server/utils/DbColumnHelper';
|
||||
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import {
|
||||
Column,
|
||||
Entity,
|
||||
Index,
|
||||
ManyToOne,
|
||||
PrimaryGeneratedColumn,
|
||||
} from 'typeorm';
|
||||
import Issue from './Issue';
|
||||
import { User } from './User';
|
||||
|
||||
@@ -12,11 +18,13 @@ class IssueComment {
|
||||
eager: true,
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
@Index()
|
||||
public user: User;
|
||||
|
||||
@ManyToOne(() => Issue, (issue) => issue.comments, {
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
@Index()
|
||||
public issue: Issue;
|
||||
|
||||
@Column({ type: 'text' })
|
||||
|
||||
@@ -521,12 +521,14 @@ export class MediaRequest {
|
||||
eager: true,
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
@Index()
|
||||
public media: Media;
|
||||
|
||||
@ManyToOne(() => User, (user) => user.requests, {
|
||||
eager: true,
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
@Index()
|
||||
public requestedBy: User;
|
||||
|
||||
@ManyToOne(() => User, {
|
||||
@@ -535,6 +537,7 @@ export class MediaRequest {
|
||||
eager: true,
|
||||
onDelete: 'SET NULL',
|
||||
})
|
||||
@Index()
|
||||
public modifiedBy?: User;
|
||||
|
||||
@DbAwareColumn({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' })
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import { MediaStatus } from '@server/constants/media';
|
||||
import { DbAwareColumn } from '@server/utils/DbColumnHelper';
|
||||
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import {
|
||||
Column,
|
||||
Entity,
|
||||
Index,
|
||||
ManyToOne,
|
||||
PrimaryGeneratedColumn,
|
||||
} from 'typeorm';
|
||||
import Media from './Media';
|
||||
|
||||
@Entity()
|
||||
@@ -20,6 +26,7 @@ class Season {
|
||||
@ManyToOne(() => Media, (media) => media.seasons, {
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
@Index()
|
||||
public media: Promise<Media>;
|
||||
|
||||
@DbAwareColumn({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' })
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import { MediaRequestStatus } from '@server/constants/media';
|
||||
import { DbAwareColumn } from '@server/utils/DbColumnHelper';
|
||||
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import {
|
||||
Column,
|
||||
Entity,
|
||||
Index,
|
||||
ManyToOne,
|
||||
PrimaryGeneratedColumn,
|
||||
} from 'typeorm';
|
||||
import { MediaRequest } from './MediaRequest';
|
||||
|
||||
@Entity()
|
||||
@@ -17,6 +23,7 @@ class SeasonRequest {
|
||||
@ManyToOne(() => MediaRequest, (request) => request.seasons, {
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
@Index()
|
||||
public request: MediaRequest;
|
||||
|
||||
@DbAwareColumn({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' })
|
||||
|
||||
@@ -2,6 +2,7 @@ import { DbAwareColumn } from '@server/utils/DbColumnHelper';
|
||||
import {
|
||||
Column,
|
||||
Entity,
|
||||
Index,
|
||||
ManyToOne,
|
||||
PrimaryGeneratedColumn,
|
||||
Unique,
|
||||
@@ -18,6 +19,7 @@ export class UserPushSubscription {
|
||||
eager: true,
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
@Index()
|
||||
public user: User;
|
||||
|
||||
@Column()
|
||||
|
||||
@@ -47,12 +47,14 @@ export class Watchlist implements WatchlistItem {
|
||||
eager: true,
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
@Index()
|
||||
public requestedBy: User;
|
||||
|
||||
@ManyToOne(() => Media, (media) => media.watchlists, {
|
||||
eager: true,
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
@Index()
|
||||
public media: Media;
|
||||
|
||||
@DbAwareColumn({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' })
|
||||
|
||||
153
server/migration/postgres/1771259406751-AddForeignKeyIndexes.ts
Normal file
153
server/migration/postgres/1771259406751-AddForeignKeyIndexes.ts
Normal file
@@ -0,0 +1,153 @@
|
||||
import type { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class AddForeignKeyIndexes1771259406751 implements MigrationInterface {
|
||||
name = 'AddForeignKeyIndexes1771259406751';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "blocklist" DROP CONSTRAINT "FK_53c1ab62c3e5875bc3ac474823e"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "blocklist" DROP CONSTRAINT "FK_62b7ade94540f9f8d8bede54b99"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`DROP INDEX "public"."IDX_6bbafa28411e6046421991ea21"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE SEQUENCE IF NOT EXISTS "blocklist_id_seq" OWNED BY "blocklist"."id"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "blocklist" ALTER COLUMN "id" SET DEFAULT nextval('"blocklist_id_seq"')`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "blocklist" ALTER COLUMN "id" DROP DEFAULT`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_ae34e6b153a90672eb9dc4857d" ON "watchlist" ("requestedById") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_6641da8d831b93dfcb429f8b8b" ON "watchlist" ("mediaId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_707b033c2d0653f75213614789" ON "issue_comment" ("userId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_180710fead1c94ca499c57a7d4" ON "issue_comment" ("issueId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_53d04c07c3f4f54eae372ed665" ON "issue" ("issueType") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_276e20d053f3cff1645803c95d" ON "issue" ("mediaId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_10b17b49d1ee77e7184216001e" ON "issue" ("createdById") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_da88a1019c850d1a7b143ca02e" ON "issue" ("modifiedById") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_6f14737e346d6b27d8e50d2157" ON "season_request" ("requestId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_a1aa713f41c99e9d10c48da75a" ON "media_request" ("mediaId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_6997bee94720f1ecb7f3113709" ON "media_request" ("requestedById") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_f4fc4efa14c3ba2b29c4525fa1" ON "media_request" ("modifiedById") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_03f7958328e311761b0de675fb" ON "user_push_subscription" ("userId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_09b94c932e84635c5461f3c0a9" ON "blocklist" ("tmdbId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_356721a49f145aa439c16e6b99" ON "blocklist" ("userId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_087099b39600be695591da9a49" ON "season" ("mediaId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "blocklist" ADD CONSTRAINT "FK_356721a49f145aa439c16e6b999" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "blocklist" ADD CONSTRAINT "FK_5c8af2d0e83b3be6d250eccc19d" FOREIGN KEY ("mediaId") REFERENCES "media"("id") ON DELETE CASCADE ON UPDATE NO ACTION`
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "blocklist" DROP CONSTRAINT "FK_5c8af2d0e83b3be6d250eccc19d"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "blocklist" DROP CONSTRAINT "FK_356721a49f145aa439c16e6b999"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`DROP INDEX "public"."IDX_087099b39600be695591da9a49"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`DROP INDEX "public"."IDX_356721a49f145aa439c16e6b99"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`DROP INDEX "public"."IDX_09b94c932e84635c5461f3c0a9"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`DROP INDEX "public"."IDX_03f7958328e311761b0de675fb"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`DROP INDEX "public"."IDX_f4fc4efa14c3ba2b29c4525fa1"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`DROP INDEX "public"."IDX_6997bee94720f1ecb7f3113709"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`DROP INDEX "public"."IDX_a1aa713f41c99e9d10c48da75a"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`DROP INDEX "public"."IDX_6f14737e346d6b27d8e50d2157"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`DROP INDEX "public"."IDX_da88a1019c850d1a7b143ca02e"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`DROP INDEX "public"."IDX_10b17b49d1ee77e7184216001e"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`DROP INDEX "public"."IDX_276e20d053f3cff1645803c95d"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`DROP INDEX "public"."IDX_53d04c07c3f4f54eae372ed665"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`DROP INDEX "public"."IDX_180710fead1c94ca499c57a7d4"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`DROP INDEX "public"."IDX_707b033c2d0653f75213614789"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`DROP INDEX "public"."IDX_6641da8d831b93dfcb429f8b8b"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`DROP INDEX "public"."IDX_ae34e6b153a90672eb9dc4857d"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "blocklist" ALTER COLUMN "id" SET DEFAULT nextval('blacklist_id_seq')`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "blocklist" ALTER COLUMN "id" DROP DEFAULT`
|
||||
);
|
||||
await queryRunner.query(`DROP SEQUENCE "blocklist_id_seq"`);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_6bbafa28411e6046421991ea21" ON "blocklist" ("tmdbId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "blocklist" ADD CONSTRAINT "FK_62b7ade94540f9f8d8bede54b99" FOREIGN KEY ("mediaId") REFERENCES "media"("id") ON DELETE CASCADE ON UPDATE NO ACTION`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "blocklist" ADD CONSTRAINT "FK_53c1ab62c3e5875bc3ac474823e" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`
|
||||
);
|
||||
}
|
||||
}
|
||||
203
server/migration/sqlite/1771259394105-AddForeignKeyIndexes.ts
Normal file
203
server/migration/sqlite/1771259394105-AddForeignKeyIndexes.ts
Normal file
@@ -0,0 +1,203 @@
|
||||
import type { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class AddForeignKeyIndexes1771259394105 implements MigrationInterface {
|
||||
name = 'AddForeignKeyIndexes1771259394105';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DROP INDEX "IDX_6bbafa28411e6046421991ea21"`);
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE "temporary_blocklist" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "mediaType" varchar NOT NULL, "title" varchar, "tmdbId" integer NOT NULL, "blocklistedTags" varchar, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "userId" integer, "mediaId" integer, CONSTRAINT "REL_62b7ade94540f9f8d8bede54b9" UNIQUE ("mediaId"), CONSTRAINT "UQ_6bbafa28411e6046421991ea21c" UNIQUE ("tmdbId"))`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`INSERT INTO "temporary_blocklist"("id", "mediaType", "title", "tmdbId", "blocklistedTags", "createdAt", "userId", "mediaId") SELECT "id", "mediaType", "title", "tmdbId", "blocklistedTags", "createdAt", "userId", "mediaId" FROM "blocklist"`
|
||||
);
|
||||
await queryRunner.query(`DROP TABLE "blocklist"`);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "temporary_blocklist" RENAME TO "blocklist"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_6bbafa28411e6046421991ea21" ON "blocklist" ("tmdbId") `
|
||||
);
|
||||
await queryRunner.query(`DROP INDEX "IDX_6bbafa28411e6046421991ea21"`);
|
||||
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_6427d07d9a171a3a1ab87480005" UNIQUE ("endpoint", "userId"), 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_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_6427d07d9a171a3a1ab87480005" UNIQUE ("endpoint", "userId"), 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_blocklist" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "mediaType" varchar NOT NULL, "title" varchar, "tmdbId" integer NOT NULL, "blocklistedTags" varchar, "createdAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "userId" integer, "mediaId" integer, CONSTRAINT "REL_62b7ade94540f9f8d8bede54b9" UNIQUE ("mediaId"), CONSTRAINT "UQ_6bbafa28411e6046421991ea21c" UNIQUE ("tmdbId"))`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`INSERT INTO "temporary_blocklist"("id", "mediaType", "title", "tmdbId", "blocklistedTags", "createdAt", "userId", "mediaId") SELECT "id", "mediaType", "title", "tmdbId", "blocklistedTags", "createdAt", "userId", "mediaId" FROM "blocklist"`
|
||||
);
|
||||
await queryRunner.query(`DROP TABLE "blocklist"`);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "temporary_blocklist" RENAME TO "blocklist"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_ae34e6b153a90672eb9dc4857d" ON "watchlist" ("requestedById") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_6641da8d831b93dfcb429f8b8b" ON "watchlist" ("mediaId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_707b033c2d0653f75213614789" ON "issue_comment" ("userId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_180710fead1c94ca499c57a7d4" ON "issue_comment" ("issueId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_53d04c07c3f4f54eae372ed665" ON "issue" ("issueType") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_276e20d053f3cff1645803c95d" ON "issue" ("mediaId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_10b17b49d1ee77e7184216001e" ON "issue" ("createdById") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_da88a1019c850d1a7b143ca02e" ON "issue" ("modifiedById") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_6f14737e346d6b27d8e50d2157" ON "season_request" ("requestId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_a1aa713f41c99e9d10c48da75a" ON "media_request" ("mediaId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_6997bee94720f1ecb7f3113709" ON "media_request" ("requestedById") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_f4fc4efa14c3ba2b29c4525fa1" ON "media_request" ("modifiedById") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_03f7958328e311761b0de675fb" ON "user_push_subscription" ("userId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_09b94c932e84635c5461f3c0a9" ON "blocklist" ("tmdbId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_356721a49f145aa439c16e6b99" ON "blocklist" ("userId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_087099b39600be695591da9a49" ON "season" ("mediaId") `
|
||||
);
|
||||
await queryRunner.query(`DROP INDEX "IDX_09b94c932e84635c5461f3c0a9"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_356721a49f145aa439c16e6b99"`);
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE "temporary_blocklist" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "mediaType" varchar NOT NULL, "title" varchar, "tmdbId" integer NOT NULL, "blocklistedTags" varchar, "createdAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "userId" integer, "mediaId" integer, CONSTRAINT "REL_62b7ade94540f9f8d8bede54b9" UNIQUE ("mediaId"), CONSTRAINT "UQ_6bbafa28411e6046421991ea21c" UNIQUE ("tmdbId"), CONSTRAINT "FK_356721a49f145aa439c16e6b999" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_5c8af2d0e83b3be6d250eccc19d" FOREIGN KEY ("mediaId") REFERENCES "media" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`INSERT INTO "temporary_blocklist"("id", "mediaType", "title", "tmdbId", "blocklistedTags", "createdAt", "userId", "mediaId") SELECT "id", "mediaType", "title", "tmdbId", "blocklistedTags", "createdAt", "userId", "mediaId" FROM "blocklist"`
|
||||
);
|
||||
await queryRunner.query(`DROP TABLE "blocklist"`);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "temporary_blocklist" RENAME TO "blocklist"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_09b94c932e84635c5461f3c0a9" ON "blocklist" ("tmdbId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_356721a49f145aa439c16e6b99" ON "blocklist" ("userId") `
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DROP INDEX "IDX_356721a49f145aa439c16e6b99"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_09b94c932e84635c5461f3c0a9"`);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "blocklist" RENAME TO "temporary_blocklist"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE "blocklist" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "mediaType" varchar NOT NULL, "title" varchar, "tmdbId" integer NOT NULL, "blocklistedTags" varchar, "createdAt" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "userId" integer, "mediaId" integer, CONSTRAINT "REL_62b7ade94540f9f8d8bede54b9" UNIQUE ("mediaId"), CONSTRAINT "UQ_6bbafa28411e6046421991ea21c" UNIQUE ("tmdbId"))`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`INSERT INTO "blocklist"("id", "mediaType", "title", "tmdbId", "blocklistedTags", "createdAt", "userId", "mediaId") SELECT "id", "mediaType", "title", "tmdbId", "blocklistedTags", "createdAt", "userId", "mediaId" FROM "temporary_blocklist"`
|
||||
);
|
||||
await queryRunner.query(`DROP TABLE "temporary_blocklist"`);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_356721a49f145aa439c16e6b99" ON "blocklist" ("userId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_09b94c932e84635c5461f3c0a9" ON "blocklist" ("tmdbId") `
|
||||
);
|
||||
await queryRunner.query(`DROP INDEX "IDX_087099b39600be695591da9a49"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_356721a49f145aa439c16e6b99"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_09b94c932e84635c5461f3c0a9"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_03f7958328e311761b0de675fb"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_f4fc4efa14c3ba2b29c4525fa1"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_6997bee94720f1ecb7f3113709"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_a1aa713f41c99e9d10c48da75a"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_6f14737e346d6b27d8e50d2157"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_da88a1019c850d1a7b143ca02e"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_10b17b49d1ee77e7184216001e"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_276e20d053f3cff1645803c95d"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_53d04c07c3f4f54eae372ed665"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_180710fead1c94ca499c57a7d4"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_707b033c2d0653f75213614789"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_6641da8d831b93dfcb429f8b8b"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_ae34e6b153a90672eb9dc4857d"`);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "blocklist" RENAME TO "temporary_blocklist"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE "blocklist" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "mediaType" varchar NOT NULL, "title" varchar, "tmdbId" integer NOT NULL, "blocklistedTags" varchar, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "userId" integer, "mediaId" integer, CONSTRAINT "REL_62b7ade94540f9f8d8bede54b9" UNIQUE ("mediaId"), CONSTRAINT "UQ_6bbafa28411e6046421991ea21c" UNIQUE ("tmdbId"))`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`INSERT INTO "blocklist"("id", "mediaType", "title", "tmdbId", "blocklistedTags", "createdAt", "userId", "mediaId") SELECT "id", "mediaType", "title", "tmdbId", "blocklistedTags", "createdAt", "userId", "mediaId" FROM "temporary_blocklist"`
|
||||
);
|
||||
await queryRunner.query(`DROP TABLE "temporary_blocklist"`);
|
||||
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, "createdAt" datetime DEFAULT (CURRENT_TIMESTAMP), CONSTRAINT "UQ_6427d07d9a171a3a1ab87480005" UNIQUE ("endpoint", "userId"), 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(
|
||||
`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, "createdAt" datetime DEFAULT (CURRENT_TIMESTAMP), CONSTRAINT "UQ_6427d07d9a171a3a1ab87480005" UNIQUE ("endpoint", "userId"), 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(
|
||||
`CREATE INDEX "IDX_6bbafa28411e6046421991ea21" ON "blocklist" ("tmdbId") `
|
||||
);
|
||||
await queryRunner.query(`DROP INDEX "IDX_6bbafa28411e6046421991ea21"`);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "blocklist" RENAME TO "temporary_blocklist"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE "blocklist" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "mediaType" varchar NOT NULL, "title" varchar, "tmdbId" integer NOT NULL, "blocklistedTags" varchar, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "userId" integer, "mediaId" integer, CONSTRAINT "REL_62b7ade94540f9f8d8bede54b9" UNIQUE ("mediaId"), CONSTRAINT "UQ_6bbafa28411e6046421991ea21c" UNIQUE ("tmdbId"), CONSTRAINT "FK_62b7ade94540f9f8d8bede54b99" FOREIGN KEY ("mediaId") REFERENCES "media" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_53c1ab62c3e5875bc3ac474823e" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`INSERT INTO "blocklist"("id", "mediaType", "title", "tmdbId", "blocklistedTags", "createdAt", "userId", "mediaId") SELECT "id", "mediaType", "title", "tmdbId", "blocklistedTags", "createdAt", "userId", "mediaId" FROM "temporary_blocklist"`
|
||||
);
|
||||
await queryRunner.query(`DROP TABLE "temporary_blocklist"`);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX "IDX_6bbafa28411e6046421991ea21" ON "blocklist" ("tmdbId") `
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -947,6 +947,15 @@ export class MediaRequestSubscriber implements EntitySubscriberInterface<MediaRe
|
||||
try {
|
||||
await this.sendToRadarr(event.entity as MediaRequest);
|
||||
await this.sendToSonarr(event.entity as MediaRequest);
|
||||
} catch (e) {
|
||||
logger.error('Error while sending to *arr in afterUpdate subscriber', {
|
||||
label: 'Media Request',
|
||||
requestId: (event.entity as MediaRequest).id,
|
||||
errorMessage: e instanceof Error ? e.message : String(e),
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
await this.updateParentStatus(event.entity as MediaRequest);
|
||||
|
||||
if (event.entity.status === MediaRequestStatus.COMPLETED) {
|
||||
@@ -958,11 +967,14 @@ export class MediaRequestSubscriber implements EntitySubscriberInterface<MediaRe
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
logger.error('Error in afterUpdate subscriber', {
|
||||
label: 'Media Request',
|
||||
requestId: (event.entity as MediaRequest).id,
|
||||
errorMessage: e instanceof Error ? e.message : String(e),
|
||||
});
|
||||
logger.error(
|
||||
'Error while updating parent status in afterUpdate subscriber',
|
||||
{
|
||||
label: 'Media Request',
|
||||
requestId: (event.entity as MediaRequest).id,
|
||||
errorMessage: e instanceof Error ? e.message : String(e),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -974,14 +986,26 @@ export class MediaRequestSubscriber implements EntitySubscriberInterface<MediaRe
|
||||
try {
|
||||
await this.sendToRadarr(event.entity as MediaRequest);
|
||||
await this.sendToSonarr(event.entity as MediaRequest);
|
||||
await this.updateParentStatus(event.entity as MediaRequest);
|
||||
} catch (e) {
|
||||
logger.error('Error in afterInsert subscriber', {
|
||||
logger.error('Error while sending to *arr in afterInsert subscriber', {
|
||||
label: 'Media Request',
|
||||
requestId: (event.entity as MediaRequest).id,
|
||||
errorMessage: e instanceof Error ? e.message : String(e),
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
await this.updateParentStatus(event.entity as MediaRequest);
|
||||
} catch (e) {
|
||||
logger.error(
|
||||
'Error while updating parent status in afterInsert subscriber',
|
||||
{
|
||||
label: 'Media Request',
|
||||
requestId: (event.entity as MediaRequest).id,
|
||||
errorMessage: e instanceof Error ? e.message : String(e),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public async afterRemove(event: RemoveEvent<MediaRequest>): Promise<void> {
|
||||
|
||||
Reference in New Issue
Block a user