Compare commits

..

1 Commits

Author SHA1 Message Date
renovate[bot]
5a8ac31d87 chore(deps): update dependency eslint-plugin-react-hooks to v4.6.2 2026-02-17 15:15:59 +00:00
16 changed files with 68 additions and 303 deletions

View File

@@ -129,7 +129,7 @@ jobs:
build:
name: Build (per-arch, native runners)
if: github.ref == 'refs/heads/develop'
if: github.ref == 'refs/heads/develop' && !contains(github.event.head_commit.message, '[skip ci]')
strategy:
matrix:
include:
@@ -237,7 +237,7 @@ jobs:
discord:
name: Send Discord Notification
needs: publish
if: always() && github.event_name != 'pull_request'
if: always() && github.event_name != 'pull_request' && !contains(github.event.head_commit.message, '[skip ci]')
runs-on: ubuntu-24.04
steps:
- name: Determine Workflow Status

View File

@@ -1,87 +0,0 @@
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: Create tag
on:
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
determine-tag-version:
name: Determine tag version
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-24.04
permissions:
contents: read
outputs:
tag_version: ${{ steps.git-cliff.outputs.tag_version }}
steps:
- name: Checkout
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: Install git-cliff
uses: taiki-e/install-action@cede0bb282aae847dfa8aacca3a41c86d973d4d7 # v2.68.1
with:
tool: git-cliff
- name: Get tag version
id: git-cliff
run: |
tag_version=$(git-cliff -c .github/cliff.toml --bumped-version --unreleased)
echo "Next tag version is ${tag_version}"
echo "tag_version=${tag_version}" >> "$GITHUB_OUTPUT"
create-tag:
name: Create tag
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-24.04
permissions:
contents: write
needs: determine-tag-version
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG_VERSION: ${{ needs.determine-tag-version.outputs.tag_version }}
steps:
- name: Checkout
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
ssh-key: '${{ secrets.COMMIT_KEY }}'
- name: Pnpm Setup
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
- name: Set up Node.js
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
with:
node-version-file: 'package.json'
# For workflows with elevated privileges we recommend disabling automatic caching.
# https://github.com/actions/setup-node
package-manager-cache: false
- name: Configure git
run: |
git config --global user.name "${{ github.actor }}"
git config --global user.email "${{ github.actor }}@users.noreply.github.com"
- name: Bump package.json
run: npm version ${TAG_VERSION} --no-commit-hooks --no-git-tag-version
- name: Commit updated files
run: |
git add package.json
git commit -m 'chore(release): prepare ${TAG_VERSION}'
git push
- name: Create git tag
run: |
git tag ${TAG_VERSION}
git push origin ${TAG_VERSION}

View File

@@ -304,3 +304,42 @@ jobs:
run: gh release edit "${{ env.VERSION }}" --draft=false --repo "${{ github.repository }}"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
discord:
name: Send Discord Notification
needs: publish-release
if: always()
runs-on: ubuntu-24.04
steps:
- name: Determine status
id: status
run: |
case "${{ needs.publish-release.result }}" in
success) echo "status=Success" >> $GITHUB_OUTPUT; echo "colour=3066993" >> $GITHUB_OUTPUT ;;
failure) echo "status=Failure" >> $GITHUB_OUTPUT; echo "colour=15158332" >> $GITHUB_OUTPUT ;;
cancelled) echo "status=Cancelled" >> $GITHUB_OUTPUT; echo "colour=10181046" >> $GITHUB_OUTPUT ;;
*) echo "status=Skipped" >> $GITHUB_OUTPUT; echo "colour=9807270" >> $GITHUB_OUTPUT ;;
esac
- name: Send notification
run: |
WEBHOOK="${{ secrets.DISCORD_WEBHOOK }}"
PAYLOAD=$(cat <<EOF
{
"embeds": [{
"title": "${{ steps.status.outputs.status }}: ${{ github.workflow }}",
"color": ${{ steps.status.outputs.colour }},
"fields": [
{ "name": "Repository", "value": "[${{ github.repository }}](${{ github.server_url }}/${{ github.repository }})", "inline": true },
{ "name": "Ref", "value": "${{ github.ref }}", "inline": true },
{ "name": "Event", "value": "${{ github.event_name }}", "inline": true },
{ "name": "Triggered by", "value": "${{ github.actor }}", "inline": true },
{ "name": "Workflow", "value": "[${{ github.workflow }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})", "inline": true }
]
}]
}
EOF
)
curl -sS -H "Content-Type: application/json" -X POST -d "$PAYLOAD" "$WEBHOOK" || true

View File

@@ -1,4 +1,4 @@
FROM node:24.13.1-alpine3.22@sha256:d28696cabe6a72c5addbb608b344818e5a158d849174abd4b1ae85ab48536280 AS base
FROM node:22.22.0-alpine3.22@sha256:0c49915657c1c77c64c8af4d91d2f13fe96853bbd957993ed00dd592cbecc284 AS base
ARG SOURCE_DATE_EPOCH
ARG TARGETPLATFORM
ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64}
@@ -33,7 +33,7 @@ RUN pnpm build
RUN rm -rf .next/cache
FROM node:24.13.1-alpine3.22@sha256:d28696cabe6a72c5addbb608b344818e5a158d849174abd4b1ae85ab48536280
FROM node:22.22.0-alpine3.22@sha256:0c49915657c1c77c64c8af4d91d2f13fe96853bbd957993ed00dd592cbecc284
ARG SOURCE_DATE_EPOCH
ARG COMMIT_TAG
ENV NODE_ENV=production

View File

@@ -1,4 +1,4 @@
FROM node:24.13.1-alpine3.22@sha256:d28696cabe6a72c5addbb608b344818e5a158d849174abd4b1ae85ab48536280
FROM node:22.22.0-alpine3.22@sha256:0c49915657c1c77c64c8af4d91d2f13fe96853bbd957993ed00dd592cbecc284
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"

View File

@@ -30,7 +30,7 @@ If your PostgreSQL server is configured to accept TCP connections, you can speci
```dotenv
DB_TYPE=postgres # Which DB engine to use, either sqlite or postgres. The default is sqlite.
DB_HOST=localhost # (optional) The host (URL) of the database. The default is "localhost".
DB_HOST="localhost" # (optional) The host (URL) of the database. The default is "localhost".
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.

View File

@@ -1,111 +0,0 @@
---
title: Synology (Advanced)
description: Install Seerr on Synology NAS using SynoCommunity
sidebar_position: 5
---
# Synology
:::warning
Third-party installation methods are maintained by the community. The Seerr team is not responsible for these packages.
:::
:::warning
This method is not recommended for most users. It is intended for advanced users who are using Synology NAS.
:::
## Prerequisites
- Synology NAS running **DSM 7.2** or later
- 64-bit architecture (x86_64 or ARMv8)
- [SynoCommunity package source](https://synocommunity.com/) added to Package Center
## Adding the SynoCommunity Package Source
If you haven't already added SynoCommunity to your Package Center:
1. Open **Package Center** in DSM
2. Click **Settings** in the top-right corner
3. Go to the **Package Sources** tab
4. Click **Add**
5. Enter the following:
- **Name**: `SynoCommunity`
- **Location**: `https://packages.synocommunity.com`
6. Click **OK**
## Installation
1. In **Package Center**, search for **Seerr**
2. Click **Install**
3. Follow the installation wizard prompts
4. Package Center will automatically install any required dependencies (Node.js v22)
### Access Seerr
Once installed, access Seerr at:
```
http://<your-synology-ip>:5055
```
You can also click the **Open** button in Package Center or find Seerr in the DSM main menu.
## Configuration
Seerr's configuration files are stored at:
```
/var/packages/seerr/var/config
```
:::info
The Seerr package runs as a dedicated service user managed by DSM. No manual permission configuration is required.
:::
## Managing the Service
You can start, stop, and restart Seerr from **Package Center** → Find Seerr → Use the action buttons.
## Updating
When a new version is available:
1. Open **Package Center**
2. Go to **Installed** packages
3. Find **Seerr** and click **Update** if available
:::tip
Enable automatic updates in Package Center settings to keep Seerr up to date.
:::
## Troubleshooting
### Viewing Logs
Seerr logs are located at `/var/packages/seerr/var/config/logs` and can be accessed using:
- **File Browser** package (recommended for most users)
- SSH (advanced users)
### Port Conflicts
Seerr uses port 5055. If this port is already in use:
- **Docker containers**: Remap the conflicting container to a different port
- **Other packages**: The conflicting package will need to be uninstalled as Seerr's port cannot be changed
SynoCommunity ensures there are no port conflicts with other SynoCommunity packages or official Synology packages.
### Package Won't Start
Ensure Node.js v22 is installed and running by checking its status in **Package Center**.
## Uninstallation
1. Open **Package Center**
2. Find **Seerr** in your installed packages
3. Click **Uninstall**
:::caution
Uninstalling will remove the application but preserve your configuration data by default. Select "Remove data" during uninstallation if you want a complete removal.
:::

View File

@@ -4,6 +4,12 @@ description: Install Seerr using TrueNAS
sidebar_position: 4
---
# TrueNAS
:::danger
This method has not yet been updated for Seerr and is currently a work in progress.
You can follow the ongoing work on this issue https://github.com/truenas/apps/issues/3374.
:::
<!--
:::warning
Third-party installation methods are maintained by the community. The Seerr team is not responsible for these packages.
:::
@@ -11,7 +17,4 @@ Third-party installation methods are maintained by the community. The Seerr team
:::warning
This method is not recommended for most users. It is intended for advanced users who are using TrueNAS distribution.
:::
## Installation
Go to the 'Apps' menu, click the 'Discover Apps' button in the top right, search for 'Seerr' in the search bar, and install the app.
-->

View File

@@ -210,42 +210,7 @@ See https://aur.archlinux.org/packages/seerr
### TrueNAS
Refer to [Seerr TrueNAS Documentation](/getting-started/third-parties/truenas), all of our examples have been updated to reflect the below change.
<Tabs groupId="truenas-migration" queryString>
<TabItem value="hostpath" label="Host Path">
**This guide describes how to migrate from Host Path storage (not ixVolume).**
1. Stop Jellyseerr/Overseerr
2. Install Seerr and use the same Host Path storage that was used by Jellyseerr/Overseerr
3. Start Seerr app
4. Delete Jellyseerr/Overseerr app
</TabItem>
<TabItem value="ixvolume" label="ixVolume">
**This guide describes how to migrate from ixVolume storage (not Host Path).**
1. Stop Jellyseerr/Overseerr
2. Create a dataset for Seerr
If your apps normally store data under something like:
```
/mnt/storage/<app-name>
```
then create a dataset named:
```
storage/seerr
```
resulting in:
```
/mnt/storage/seerr
```
3. Copy ixVolume Data
Open System Settings → Shell, or SSH into your TrueNAS server as root and run :
```bash
rsync -av /mnt/.ix-apps/app_mounts/jellyseerr/ /mnt/storage/seerr/
```
4. Install Seerr and use the same Host Path storage that was created before (`/mnt/storage/seerr/config` in our example)
5. Start Seerr app
6. Delete Jellyseerr/Overseerr app
</TabItem>
</Tabs>
Waiting for https://github.com/truenas/apps/issues/3374
### Unraid
@@ -312,4 +277,4 @@ For Jellyseerr users, use `/mnt/user/appdata/jellyseerr`.
:::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`.
:::
:::

View File

@@ -19,7 +19,7 @@ Please check how to migrate to Seerr in our [migration guide](https://docs.seerr
Seerr brings several features that were previously available in Jellyseerr but missing from Overseerr. These additions improve flexibility, performance, and overall control for admins and power users:
* **Alternative media solution:** Added support for Jellyfin and Emby as alternatives to Plex. Only one integration can be used at a time.
* **Alternative media solution:** Added support for Jellyfin and Emby in addition to the existing Plex integration.
* **PostgreSQL support**: In addition to SQLite, you can now opt in to using a PostgreSQL database.
* **Blocklist for movies, series, and tags**: Allows permitted users to hide movies, series, or tags from regular users.
* **Override rules**: Adjust default request settings based on conditions such as user, tag, or other criteria.

View File

@@ -16,12 +16,7 @@ const config: Config = {
deploymentBranch: 'gh-pages',
onBrokenLinks: 'throw',
markdown: {
hooks: {
onBrokenMarkdownLinks: 'warn',
},
},
onBrokenMarkdownLinks: 'warn',
i18n: {
defaultLocale: 'en',

View File

@@ -158,7 +158,7 @@
"eslint-plugin-no-relative-import-paths": "1.6.1",
"eslint-plugin-prettier": "4.2.1",
"eslint-plugin-react": "7.37.5",
"eslint-plugin-react-hooks": "4.6.0",
"eslint-plugin-react-hooks": "4.6.2",
"husky": "8.0.3",
"lint-staged": "13.1.2",
"nodemon": "3.1.11",
@@ -173,7 +173,7 @@
"typescript": "5.4.5"
},
"engines": {
"node": "^24.0.0",
"node": "^22.0.0",
"pnpm": "^10.0.0"
},
"config": {

13
pnpm-lock.yaml generated
View File

@@ -386,8 +386,8 @@ importers:
specifier: 7.37.5
version: 7.37.5(eslint@8.57.1)
eslint-plugin-react-hooks:
specifier: 4.6.0
version: 4.6.0(eslint@8.57.1)
specifier: 4.6.2
version: 4.6.2(eslint@8.57.1)
husky:
specifier: 8.0.3
version: 8.0.3
@@ -4604,8 +4604,8 @@ packages:
eslint-config-prettier:
optional: true
eslint-plugin-react-hooks@4.6.0:
resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==}
eslint-plugin-react-hooks@4.6.2:
resolution: {integrity: sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==}
engines: {node: '>=10'}
peerDependencies:
eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0
@@ -6901,7 +6901,6 @@ packages:
prebuild-install@7.1.3:
resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==}
engines: {node: '>=10'}
deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available.
hasBin: true
prelude-ls@1.2.1:
@@ -13988,7 +13987,7 @@ snapshots:
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1)
eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1)
eslint-plugin-react: 7.37.5(eslint@8.57.1)
eslint-plugin-react-hooks: 4.6.0(eslint@8.57.1)
eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1)
optionalDependencies:
typescript: 5.4.5
transitivePeerDependencies:
@@ -14109,7 +14108,7 @@ snapshots:
optionalDependencies:
eslint-config-prettier: 8.6.0(eslint@8.57.1)
eslint-plugin-react-hooks@4.6.0(eslint@8.57.1):
eslint-plugin-react-hooks@4.6.2(eslint@8.57.1):
dependencies:
eslint: 8.57.1

View File

@@ -206,19 +206,6 @@ class Media {
Object.assign(this, init);
}
public resetServiceData(): void {
this.serviceId = null;
this.serviceId4k = null;
this.externalServiceId = null;
this.externalServiceId4k = null;
this.externalServiceSlug = null;
this.externalServiceSlug4k = null;
this.ratingKey = null;
this.ratingKey4k = null;
this.jellyfinMediaId = null;
this.jellyfinMediaId4k = null;
}
@AfterLoad()
public setPlexUrls(): void {
const { machineId, webAppUrl } = getSettings().plex;

View File

@@ -45,7 +45,7 @@ class WatchlistSync {
[
Permission.AUTO_REQUEST,
Permission.AUTO_REQUEST_MOVIE,
Permission.AUTO_REQUEST_TV,
Permission.AUTO_APPROVE_TV,
],
{ type: 'or' }
)
@@ -70,33 +70,13 @@ class WatchlistSync {
response.items.map((i) => i.tmdbId)
);
const watchlistTmdbIds = response.items.map((i) => i.tmdbId);
const requestRepository = getRepository(MediaRequest);
const existingAutoRequests = await requestRepository
.createQueryBuilder('request')
.leftJoinAndSelect('request.media', 'media')
.where('request.requestedBy = :userId', { userId: user.id })
.andWhere('request.isAutoRequest = true')
.andWhere('media.tmdbId IN (:...tmdbIds)', { tmdbIds: watchlistTmdbIds })
.getMany();
const autoRequestedTmdbIds = new Set(
existingAutoRequests
.filter((r) => r.media != null)
.map((r) => `${r.media.mediaType}:${r.media.tmdbId}`)
);
const unavailableItems = response.items.filter(
// If we can find watchlist items in our database that are also available, we should exclude them
(i) =>
!autoRequestedTmdbIds.has(
`${i.type === 'show' ? MediaType.TV : MediaType.MOVIE}:${i.tmdbId}`
) &&
!mediaItems.find(
(m) =>
m.tmdbId === i.tmdbId &&
(m.status === MediaStatus.BLOCKLISTED ||
(m.status !== MediaStatus.UNKNOWN && m.mediaType === 'movie') ||
((m.status !== MediaStatus.UNKNOWN && m.mediaType === 'movie') ||
(m.mediaType === 'tv' && m.status === MediaStatus.AVAILABLE))
)
);

View File

@@ -174,12 +174,7 @@ mediaRoutes.delete(
where: { id: Number(req.params.id) },
});
if (media.status === MediaStatus.BLOCKLISTED) {
media.resetServiceData();
await mediaRepository.save(media);
} else {
await mediaRepository.remove(media);
}
await mediaRepository.remove(media);
return res.status(204).send();
} catch (e) {