Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4b707e619 | ||
|
|
8233d97f21 | ||
|
|
f8a8ebdf76 | ||
|
|
d362b030f9 | ||
|
|
cc876c8276 | ||
|
|
8da4870997 | ||
|
|
c98becf936 | ||
|
|
9739e18949 |
14
CHANGELOG.md
14
CHANGELOG.md
@@ -1,3 +1,17 @@
|
|||||||
|
## [2.2.2](https://github.com/fallenbagel/jellyseerr/compare/v2.2.1...v2.2.2) (2024-12-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **overriderules:** apply override rules to tv shows during request ([#1198](https://github.com/fallenbagel/jellyseerr/issues/1198)) ([f8a8ebd](https://github.com/fallenbagel/jellyseerr/commit/f8a8ebdf76f939ccc28ce7b39343e3a606c90b33)), closes [#1197](https://github.com/fallenbagel/jellyseerr/issues/1197) [#1195](https://github.com/fallenbagel/jellyseerr/issues/1195)
|
||||||
|
|
||||||
|
## [2.2.1](https://github.com/fallenbagel/jellyseerr/compare/v2.2.0...v2.2.1) (2024-12-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **overriderules:** apply override rules during request only for non-admin/non-auto-approve users ([#1197](https://github.com/fallenbagel/jellyseerr/issues/1197)) ([8da4870](https://github.com/fallenbagel/jellyseerr/commit/8da48709977fa0111225c3519f9128bea41867fc)), closes [#1195](https://github.com/fallenbagel/jellyseerr/issues/1195)
|
||||||
|
|
||||||
# [2.2.0](https://github.com/fallenbagel/jellyseerr/compare/v2.1.0...v2.2.0) (2024-12-29)
|
# [2.2.0](https://github.com/fallenbagel/jellyseerr/compare/v2.1.0...v2.2.0) (2024-12-29)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,6 @@ sidebar_position: 2
|
|||||||
---
|
---
|
||||||
# Configuring the Database
|
# Configuring the Database
|
||||||
|
|
||||||
:::important
|
|
||||||
Postgres is not supported on **latest** yet. (It is currently only available in **develop**)
|
|
||||||
:::
|
|
||||||
|
|
||||||
Jellyseerr supports SQLite and PostgreSQL. The database connection can be configured using the following environment variables:
|
Jellyseerr supports SQLite and PostgreSQL. The database connection can be configured using the following environment variables:
|
||||||
|
|
||||||
## SQLite Options
|
## SQLite Options
|
||||||
@@ -51,9 +47,14 @@ DB_SSL_CERT_FILE= # (optional) Path to certificate chain in pem format for the p
|
|||||||
2. Run Jellyseerr to create the tables in the PostgreSQL database
|
2. Run Jellyseerr to create the tables in the PostgreSQL database
|
||||||
3. Stop Jellyseerr
|
3. Stop Jellyseerr
|
||||||
4. Run the following command to export the data from the SQLite database and import it into the PostgreSQL database:
|
4. Run the following command to export the data from the SQLite database and import it into the PostgreSQL database:
|
||||||
- Edit the postgres connection string to match your setup
|
:::info
|
||||||
- WARNING: The most recent release of pgloader has an issue quoting the table columns. Use the version in the docker container to avoid this issue.
|
Edit the postgres connection string to match your setup
|
||||||
- "I don't have or don't want to use docker" - You can build the working pgloader version [in this PR](https://github.com/dimitri/pgloader/pull/1531) from source and use the same options as below.
|
|
||||||
|
If you don't have or don't want to use docker, you can build the working pgloader version [in this PR](https://github.com/dimitri/pgloader/pull/1531) from source and use the same options as below.
|
||||||
|
:::
|
||||||
|
:::caution
|
||||||
|
The most recent release of pgloader has an issue quoting the table columns. Use the version in the docker container to avoid this issue.
|
||||||
|
:::
|
||||||
```bash
|
```bash
|
||||||
docker run --rm -v config/db.sqlite3:/db.sqlite3:ro -v pgloader/pgloader.load:/pgloader.load ghcr.io/ralgar/pgloader:pr-1531 pgloader --with "quote identifiers" --with "data only" /db.sqlite3 postgresql://{{DB_USER}}:{{DB_PASS}}@{{DB_HOST}}:{{DB_PORT}}/{{DB_NAME}}
|
docker run --rm -v config/db.sqlite3:/db.sqlite3:ro -v pgloader/pgloader.load:/pgloader.load ghcr.io/ralgar/pgloader:pr-1531 pgloader --with "quote identifiers" --with "data only" /db.sqlite3 postgresql://{{DB_USER}}:{{DB_PASS}}@{{DB_HOST}}:{{DB_PORT}}/{{DB_NAME}}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "jellyseerr",
|
"name": "jellyseerr",
|
||||||
"version": "2.2.0",
|
"version": "2.2.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"preinstall": "npx only-allow pnpm",
|
"preinstall": "npx only-allow pnpm",
|
||||||
|
|||||||
@@ -207,6 +207,84 @@ export class MediaRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply overrides if the user is not an admin or has the "auto approve" permission
|
||||||
|
const useOverrides = !user.hasPermission(
|
||||||
|
[
|
||||||
|
requestBody.is4k ? Permission.AUTO_APPROVE_4K : Permission.AUTO_APPROVE,
|
||||||
|
Permission.MANAGE_REQUESTS,
|
||||||
|
],
|
||||||
|
{ type: 'or' }
|
||||||
|
);
|
||||||
|
|
||||||
|
let rootFolder = requestBody.rootFolder;
|
||||||
|
let profileId = requestBody.profileId;
|
||||||
|
let tags = requestBody.tags;
|
||||||
|
|
||||||
|
if (useOverrides) {
|
||||||
|
const overrideRuleRepository = getRepository(OverrideRule);
|
||||||
|
const overrideRules = await overrideRuleRepository.find({
|
||||||
|
where:
|
||||||
|
requestBody.mediaType === MediaType.MOVIE
|
||||||
|
? { radarrServiceId: requestBody.serverId }
|
||||||
|
: { sonarrServiceId: requestBody.serverId },
|
||||||
|
});
|
||||||
|
const appliedOverrideRules = overrideRules.filter((rule) => {
|
||||||
|
if (
|
||||||
|
rule.users &&
|
||||||
|
!rule.users
|
||||||
|
.split(',')
|
||||||
|
.some((userId) => Number(userId) === requestUser.id)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
rule.genre &&
|
||||||
|
!rule.genre
|
||||||
|
.split(',')
|
||||||
|
.some((genreId) =>
|
||||||
|
tmdbMedia.genres
|
||||||
|
.map((genre) => genre.id)
|
||||||
|
.includes(Number(genreId))
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
rule.language &&
|
||||||
|
!rule.language
|
||||||
|
.split('|')
|
||||||
|
.some((languageId) => languageId === tmdbMedia.original_language)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
const overrideRootFolder = appliedOverrideRules.find(
|
||||||
|
(rule) => rule.rootFolder
|
||||||
|
)?.rootFolder;
|
||||||
|
if (overrideRootFolder) {
|
||||||
|
rootFolder = overrideRootFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
const overrideProfileId = appliedOverrideRules.find(
|
||||||
|
(rule) => rule.profileId
|
||||||
|
)?.profileId;
|
||||||
|
if (overrideProfileId) {
|
||||||
|
profileId = overrideProfileId;
|
||||||
|
}
|
||||||
|
|
||||||
|
const overrideTags = appliedOverrideRules.find((rule) => rule.tags)?.tags;
|
||||||
|
if (overrideTags) {
|
||||||
|
tags = [
|
||||||
|
...new Set([
|
||||||
|
...(tags || []),
|
||||||
|
...overrideTags.split(',').map((tag) => Number(tag)),
|
||||||
|
]),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (requestBody.mediaType === MediaType.MOVIE) {
|
if (requestBody.mediaType === MediaType.MOVIE) {
|
||||||
await mediaRepository.save(media);
|
await mediaRepository.save(media);
|
||||||
|
|
||||||
@@ -245,9 +323,9 @@ export class MediaRequest {
|
|||||||
: undefined,
|
: undefined,
|
||||||
is4k: requestBody.is4k,
|
is4k: requestBody.is4k,
|
||||||
serverId: requestBody.serverId,
|
serverId: requestBody.serverId,
|
||||||
profileId: requestBody.profileId,
|
profileId: profileId,
|
||||||
rootFolder: requestBody.rootFolder,
|
rootFolder: rootFolder,
|
||||||
tags: requestBody.tags,
|
tags: tags,
|
||||||
isAutoRequest: options.isAutoRequest ?? false,
|
isAutoRequest: options.isAutoRequest ?? false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -350,10 +428,10 @@ export class MediaRequest {
|
|||||||
: undefined,
|
: undefined,
|
||||||
is4k: requestBody.is4k,
|
is4k: requestBody.is4k,
|
||||||
serverId: requestBody.serverId,
|
serverId: requestBody.serverId,
|
||||||
profileId: requestBody.profileId,
|
profileId: profileId,
|
||||||
rootFolder: requestBody.rootFolder,
|
rootFolder: rootFolder,
|
||||||
languageProfileId: requestBody.languageProfileId,
|
languageProfileId: requestBody.languageProfileId,
|
||||||
tags: requestBody.tags,
|
tags: tags,
|
||||||
seasons: finalSeasons.map(
|
seasons: finalSeasons.map(
|
||||||
(sn) =>
|
(sn) =>
|
||||||
new SeasonRequest({
|
new SeasonRequest({
|
||||||
@@ -717,6 +795,48 @@ export class MediaRequest {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let rootFolder = radarrSettings.activeDirectory;
|
||||||
|
let qualityProfile = radarrSettings.activeProfileId;
|
||||||
|
let tags = radarrSettings.tags ? [...radarrSettings.tags] : [];
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.rootFolder &&
|
||||||
|
this.rootFolder !== '' &&
|
||||||
|
this.rootFolder !== radarrSettings.activeDirectory
|
||||||
|
) {
|
||||||
|
rootFolder = this.rootFolder;
|
||||||
|
logger.info(`Request has an override root folder: ${rootFolder}`, {
|
||||||
|
label: 'Media Request',
|
||||||
|
requestId: this.id,
|
||||||
|
mediaId: this.media.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.profileId &&
|
||||||
|
this.profileId !== radarrSettings.activeProfileId
|
||||||
|
) {
|
||||||
|
qualityProfile = this.profileId;
|
||||||
|
logger.info(
|
||||||
|
`Request has an override quality profile ID: ${qualityProfile}`,
|
||||||
|
{
|
||||||
|
label: 'Media Request',
|
||||||
|
requestId: this.id,
|
||||||
|
mediaId: this.media.id,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.tags && !isEqual(this.tags, radarrSettings.tags)) {
|
||||||
|
tags = this.tags;
|
||||||
|
logger.info(`Request has override tags`, {
|
||||||
|
label: 'Media Request',
|
||||||
|
requestId: this.id,
|
||||||
|
mediaId: this.media.id,
|
||||||
|
tagIds: tags,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const tmdb = new TheMovieDb();
|
const tmdb = new TheMovieDb();
|
||||||
const radarr = new RadarrAPI({
|
const radarr = new RadarrAPI({
|
||||||
apiKey: radarrSettings.apiKey,
|
apiKey: radarrSettings.apiKey,
|
||||||
@@ -737,151 +857,6 @@ export class MediaRequest {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let rootFolder = radarrSettings.activeDirectory;
|
|
||||||
let qualityProfile = radarrSettings.activeProfileId;
|
|
||||||
let tags = radarrSettings.tags ? [...radarrSettings.tags] : [];
|
|
||||||
|
|
||||||
const overrideRuleRepository = getRepository(OverrideRule);
|
|
||||||
const overrideRules = await overrideRuleRepository.find({
|
|
||||||
where: { radarrServiceId: radarrSettings.id },
|
|
||||||
});
|
|
||||||
const appliedOverrideRules = overrideRules.filter((rule) => {
|
|
||||||
if (
|
|
||||||
rule.users &&
|
|
||||||
!rule.users
|
|
||||||
.split(',')
|
|
||||||
.some((userId) => Number(userId) === this.requestedBy.id)
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
rule.genre &&
|
|
||||||
!rule.genre
|
|
||||||
.split(',')
|
|
||||||
.some((genreId) =>
|
|
||||||
movie.genres.map((genre) => genre.id).includes(Number(genreId))
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
rule.language &&
|
|
||||||
!rule.language
|
|
||||||
.split('|')
|
|
||||||
.some((languageId) => languageId === movie.original_language)
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
rule.keywords &&
|
|
||||||
!rule.keywords
|
|
||||||
.split(',')
|
|
||||||
.some((keywordId) =>
|
|
||||||
movie.keywords.keywords
|
|
||||||
.map((keyword) => keyword.id)
|
|
||||||
.includes(Number(keywordId))
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (
|
|
||||||
this.rootFolder &&
|
|
||||||
this.rootFolder !== '' &&
|
|
||||||
this.rootFolder !== radarrSettings.activeDirectory
|
|
||||||
) {
|
|
||||||
rootFolder = this.rootFolder;
|
|
||||||
logger.info(
|
|
||||||
`Request has a manually overriden root folder: ${rootFolder}`,
|
|
||||||
{
|
|
||||||
label: 'Media Request',
|
|
||||||
requestId: this.id,
|
|
||||||
mediaId: this.media.id,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
const overrideRootFolder = appliedOverrideRules.find(
|
|
||||||
(rule) => rule.rootFolder
|
|
||||||
)?.rootFolder;
|
|
||||||
if (overrideRootFolder) {
|
|
||||||
rootFolder = overrideRootFolder;
|
|
||||||
this.rootFolder = rootFolder;
|
|
||||||
logger.info(
|
|
||||||
`Request has an override root folder from override rules: ${rootFolder}`,
|
|
||||||
{
|
|
||||||
label: 'Media Request',
|
|
||||||
requestId: this.id,
|
|
||||||
mediaId: this.media.id,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
this.profileId &&
|
|
||||||
this.profileId !== radarrSettings.activeProfileId
|
|
||||||
) {
|
|
||||||
qualityProfile = this.profileId;
|
|
||||||
logger.info(
|
|
||||||
`Request has a manually overriden quality profile ID: ${qualityProfile}`,
|
|
||||||
{
|
|
||||||
label: 'Media Request',
|
|
||||||
requestId: this.id,
|
|
||||||
mediaId: this.media.id,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
const overrideProfileId = appliedOverrideRules.find(
|
|
||||||
(rule) => rule.profileId
|
|
||||||
)?.profileId;
|
|
||||||
if (overrideProfileId) {
|
|
||||||
qualityProfile = overrideProfileId;
|
|
||||||
this.profileId = qualityProfile;
|
|
||||||
logger.info(
|
|
||||||
`Request has an override quality profile ID from override rules: ${qualityProfile}`,
|
|
||||||
{
|
|
||||||
label: 'Media Request',
|
|
||||||
requestId: this.id,
|
|
||||||
mediaId: this.media.id,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.tags && !isEqual(this.tags, radarrSettings.tags)) {
|
|
||||||
tags = this.tags;
|
|
||||||
logger.info(`Request has manually overriden tags`, {
|
|
||||||
label: 'Media Request',
|
|
||||||
requestId: this.id,
|
|
||||||
mediaId: this.media.id,
|
|
||||||
tagIds: tags,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const overrideTags = appliedOverrideRules.find(
|
|
||||||
(rule) => rule.tags
|
|
||||||
)?.tags;
|
|
||||||
if (overrideTags) {
|
|
||||||
tags = [
|
|
||||||
...new Set([
|
|
||||||
...tags,
|
|
||||||
...overrideTags.split(',').map((tag) => Number(tag)),
|
|
||||||
]),
|
|
||||||
];
|
|
||||||
this.tags = tags;
|
|
||||||
logger.info(`Request has override tags from override rules`, {
|
|
||||||
label: 'Media Request',
|
|
||||||
requestId: this.id,
|
|
||||||
mediaId: this.media.id,
|
|
||||||
tagIds: tags,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const requestRepository = getRepository(MediaRequest);
|
|
||||||
requestRepository.save(this);
|
|
||||||
|
|
||||||
if (radarrSettings.tagRequests) {
|
if (radarrSettings.tagRequests) {
|
||||||
let userTag = (await radarr.getTags()).find((v) =>
|
let userTag = (await radarr.getTags()).find((v) =>
|
||||||
v.label.startsWith(this.requestedBy.id + ' - ')
|
v.label.startsWith(this.requestedBy.id + ' - ')
|
||||||
@@ -923,6 +898,7 @@ export class MediaRequest {
|
|||||||
mediaId: this.media.id,
|
mediaId: this.media.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const requestRepository = getRepository(MediaRequest);
|
||||||
this.status = MediaRequestStatus.APPROVED;
|
this.status = MediaRequestStatus.APPROVED;
|
||||||
await requestRepository.save(this);
|
await requestRepository.save(this);
|
||||||
return;
|
return;
|
||||||
@@ -962,6 +938,8 @@ export class MediaRequest {
|
|||||||
await mediaRepository.save(media);
|
await mediaRepository.save(media);
|
||||||
})
|
})
|
||||||
.catch(async () => {
|
.catch(async () => {
|
||||||
|
const requestRepository = getRepository(MediaRequest);
|
||||||
|
|
||||||
this.status = MediaRequestStatus.FAILED;
|
this.status = MediaRequestStatus.FAILED;
|
||||||
await requestRepository.save(this);
|
await requestRepository.save(this);
|
||||||
|
|
||||||
@@ -1061,7 +1039,6 @@ export class MediaRequest {
|
|||||||
throw new Error('Media data not found');
|
throw new Error('Media data not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
const requestRepository = getRepository(MediaRequest);
|
|
||||||
if (
|
if (
|
||||||
media[this.is4k ? 'status4k' : 'status'] === MediaStatus.AVAILABLE
|
media[this.is4k ? 'status4k' : 'status'] === MediaStatus.AVAILABLE
|
||||||
) {
|
) {
|
||||||
@@ -1071,6 +1048,7 @@ export class MediaRequest {
|
|||||||
mediaId: this.media.id,
|
mediaId: this.media.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const requestRepository = getRepository(MediaRequest);
|
||||||
this.status = MediaRequestStatus.APPROVED;
|
this.status = MediaRequestStatus.APPROVED;
|
||||||
await requestRepository.save(this);
|
await requestRepository.save(this);
|
||||||
return;
|
return;
|
||||||
@@ -1085,6 +1063,7 @@ export class MediaRequest {
|
|||||||
const tvdbId = series.external_ids.tvdb_id ?? media.tvdbId;
|
const tvdbId = series.external_ids.tvdb_id ?? media.tvdbId;
|
||||||
|
|
||||||
if (!tvdbId) {
|
if (!tvdbId) {
|
||||||
|
const requestRepository = getRepository(MediaRequest);
|
||||||
await mediaRepository.remove(media);
|
await mediaRepository.remove(media);
|
||||||
await requestRepository.remove(this);
|
await requestRepository.remove(this);
|
||||||
throw new Error('TVDB ID not found');
|
throw new Error('TVDB ID not found');
|
||||||
@@ -1122,110 +1101,29 @@ export class MediaRequest {
|
|||||||
? [...sonarrSettings.tags]
|
? [...sonarrSettings.tags]
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
const overrideRuleRepository = getRepository(OverrideRule);
|
|
||||||
const overrideRules = await overrideRuleRepository.find({
|
|
||||||
where: { sonarrServiceId: sonarrSettings.id },
|
|
||||||
});
|
|
||||||
const appliedOverrideRules = overrideRules.filter((rule) => {
|
|
||||||
if (
|
|
||||||
rule.users &&
|
|
||||||
!rule.users
|
|
||||||
.split(',')
|
|
||||||
.some((userId) => Number(userId) === this.requestedBy.id)
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
rule.genre &&
|
|
||||||
!rule.genre
|
|
||||||
.split(',')
|
|
||||||
.some((genreId) =>
|
|
||||||
series.genres.map((genre) => genre.id).includes(Number(genreId))
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
rule.language &&
|
|
||||||
!rule.language
|
|
||||||
.split('|')
|
|
||||||
.some((languageId) => languageId === series.original_language)
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
rule.keywords &&
|
|
||||||
!rule.keywords
|
|
||||||
.split(',')
|
|
||||||
.some((keywordId) =>
|
|
||||||
series.keywords.results
|
|
||||||
.map((keyword) => keyword.id)
|
|
||||||
.includes(Number(keywordId))
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this.rootFolder &&
|
this.rootFolder &&
|
||||||
this.rootFolder !== '' &&
|
this.rootFolder !== '' &&
|
||||||
this.rootFolder !== rootFolder
|
this.rootFolder !== rootFolder
|
||||||
) {
|
) {
|
||||||
rootFolder = this.rootFolder;
|
rootFolder = this.rootFolder;
|
||||||
logger.info(
|
logger.info(`Request has an override root folder: ${rootFolder}`, {
|
||||||
`Request has a manually overriden root folder: ${rootFolder}`,
|
|
||||||
{
|
|
||||||
label: 'Media Request',
|
label: 'Media Request',
|
||||||
requestId: this.id,
|
requestId: this.id,
|
||||||
mediaId: this.media.id,
|
mediaId: this.media.id,
|
||||||
}
|
});
|
||||||
);
|
|
||||||
} else {
|
|
||||||
const overrideRootFolder = appliedOverrideRules.find(
|
|
||||||
(rule) => rule.rootFolder
|
|
||||||
)?.rootFolder;
|
|
||||||
if (overrideRootFolder) {
|
|
||||||
rootFolder = overrideRootFolder;
|
|
||||||
this.rootFolder = rootFolder;
|
|
||||||
logger.info(
|
|
||||||
`Request has an override root folder from override rules: ${rootFolder}`,
|
|
||||||
{
|
|
||||||
label: 'Media Request',
|
|
||||||
requestId: this.id,
|
|
||||||
mediaId: this.media.id,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.profileId && this.profileId !== qualityProfile) {
|
if (this.profileId && this.profileId !== qualityProfile) {
|
||||||
qualityProfile = this.profileId;
|
qualityProfile = this.profileId;
|
||||||
logger.info(
|
logger.info(
|
||||||
`Request has a manually overriden quality profile ID: ${qualityProfile}`,
|
`Request has an override quality profile ID: ${qualityProfile}`,
|
||||||
{
|
{
|
||||||
label: 'Media Request',
|
label: 'Media Request',
|
||||||
requestId: this.id,
|
requestId: this.id,
|
||||||
mediaId: this.media.id,
|
mediaId: this.media.id,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
const overrideProfileId = appliedOverrideRules.find(
|
|
||||||
(rule) => rule.profileId
|
|
||||||
)?.profileId;
|
|
||||||
if (overrideProfileId) {
|
|
||||||
qualityProfile = overrideProfileId;
|
|
||||||
this.profileId = qualityProfile;
|
|
||||||
logger.info(
|
|
||||||
`Request has an override quality profile ID from override rules: ${qualityProfile}`,
|
|
||||||
{
|
|
||||||
label: 'Media Request',
|
|
||||||
requestId: this.id,
|
|
||||||
mediaId: this.media.id,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -1245,31 +1143,12 @@ export class MediaRequest {
|
|||||||
|
|
||||||
if (this.tags && !isEqual(this.tags, tags)) {
|
if (this.tags && !isEqual(this.tags, tags)) {
|
||||||
tags = this.tags;
|
tags = this.tags;
|
||||||
logger.info(`Request has manually overriden tags`, {
|
logger.info(`Request has override tags`, {
|
||||||
label: 'Media Request',
|
label: 'Media Request',
|
||||||
requestId: this.id,
|
requestId: this.id,
|
||||||
mediaId: this.media.id,
|
mediaId: this.media.id,
|
||||||
tagIds: tags,
|
tagIds: tags,
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
const overrideTags = appliedOverrideRules.find(
|
|
||||||
(rule) => rule.tags
|
|
||||||
)?.tags;
|
|
||||||
if (overrideTags) {
|
|
||||||
tags = [
|
|
||||||
...new Set([
|
|
||||||
...tags,
|
|
||||||
...overrideTags.split(',').map((tag) => Number(tag)),
|
|
||||||
]),
|
|
||||||
];
|
|
||||||
this.tags = tags;
|
|
||||||
logger.info(`Request has override tags from override rules`, {
|
|
||||||
label: 'Media Request',
|
|
||||||
requestId: this.id,
|
|
||||||
mediaId: this.media.id,
|
|
||||||
tagIds: tags,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sonarrSettings.tagRequests) {
|
if (sonarrSettings.tagRequests) {
|
||||||
@@ -1304,8 +1183,6 @@ export class MediaRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
requestRepository.save(this);
|
|
||||||
|
|
||||||
const sonarrSeriesOptions: AddSeriesOptions = {
|
const sonarrSeriesOptions: AddSeriesOptions = {
|
||||||
profileId: qualityProfile,
|
profileId: qualityProfile,
|
||||||
languageProfileId: languageProfile,
|
languageProfileId: languageProfile,
|
||||||
@@ -1343,6 +1220,8 @@ export class MediaRequest {
|
|||||||
await mediaRepository.save(media);
|
await mediaRepository.save(media);
|
||||||
})
|
})
|
||||||
.catch(async () => {
|
.catch(async () => {
|
||||||
|
const requestRepository = getRepository(MediaRequest);
|
||||||
|
|
||||||
this.status = MediaRequestStatus.FAILED;
|
this.status = MediaRequestStatus.FAILED;
|
||||||
await requestRepository.save(this);
|
await requestRepository.save(this);
|
||||||
|
|
||||||
|
|||||||
@@ -524,24 +524,6 @@ const SettingsMain = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="actions">
|
|
||||||
<div className="flex justify-end">
|
|
||||||
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
|
||||||
<Button
|
|
||||||
buttonType="primary"
|
|
||||||
type="submit"
|
|
||||||
disabled={isSubmitting || !isValid}
|
|
||||||
>
|
|
||||||
<ArrowDownOnSquareIcon />
|
|
||||||
<span>
|
|
||||||
{isSubmitting
|
|
||||||
? intl.formatMessage(globalMessages.saving)
|
|
||||||
: intl.formatMessage(globalMessages.save)}
|
|
||||||
</span>
|
|
||||||
</Button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="form-row">
|
<div className="form-row">
|
||||||
<label htmlFor="proxyEnabled" className="checkbox-label">
|
<label htmlFor="proxyEnabled" className="checkbox-label">
|
||||||
<span className="mr-2">
|
<span className="mr-2">
|
||||||
@@ -718,6 +700,24 @@ const SettingsMain = () => {
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
<div className="actions">
|
||||||
|
<div className="flex justify-end">
|
||||||
|
<span className="ml-3 inline-flex rounded-md shadow-sm">
|
||||||
|
<Button
|
||||||
|
buttonType="primary"
|
||||||
|
type="submit"
|
||||||
|
disabled={isSubmitting || !isValid}
|
||||||
|
>
|
||||||
|
<ArrowDownOnSquareIcon />
|
||||||
|
<span>
|
||||||
|
{isSubmitting
|
||||||
|
? intl.formatMessage(globalMessages.saving)
|
||||||
|
: intl.formatMessage(globalMessages.save)}
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
|||||||
Reference in New Issue
Block a user