mirror of
https://github.com/seerr-team/seerr.git
synced 2026-06-15 11:59:11 -04:00
feat(user-settings): add a per-user media language setting
This commit is contained in:
255
seerr-api.yml
255
seerr-api.yml
@@ -15,7 +15,8 @@ tags:
|
||||
- name: settings
|
||||
description: Endpoints related to Seerr's settings and configuration.
|
||||
- name: auth
|
||||
description: Endpoints related to logging in or out, and the currently authenticated user.
|
||||
description: Endpoints related to logging in or out, and the currently
|
||||
authenticated user.
|
||||
- name: users
|
||||
description: Endpoints related to user management.
|
||||
- name: search
|
||||
@@ -152,6 +153,10 @@ components:
|
||||
type: string
|
||||
nullable: true
|
||||
example: 'en'
|
||||
mediaLocale:
|
||||
type: string
|
||||
nullable: true
|
||||
example: 'en'
|
||||
discoverRegion:
|
||||
type: string
|
||||
nullable: true
|
||||
@@ -1239,7 +1244,9 @@ components:
|
||||
status:
|
||||
type: number
|
||||
example: 0
|
||||
description: Status of the request. 1 = PENDING APPROVAL, 2 = APPROVED, 3 = DECLINED
|
||||
description:
|
||||
Status of the request. 1 = PENDING APPROVAL, 2 = APPROVED, 3 =
|
||||
DECLINED
|
||||
readOnly: true
|
||||
media:
|
||||
$ref: '#/components/schemas/MediaInfo'
|
||||
@@ -1286,7 +1293,10 @@ components:
|
||||
status:
|
||||
type: number
|
||||
example: 0
|
||||
description: Availability of the media. 1 = `UNKNOWN`, 2 = `PENDING`, 3 = `PROCESSING`, 4 = `PARTIALLY_AVAILABLE`, 5 = `AVAILABLE`, 6 = `DELETED`
|
||||
description:
|
||||
Availability of the media. 1 = `UNKNOWN`, 2 = `PENDING`, 3 =
|
||||
`PROCESSING`, 4 = `PARTIALLY_AVAILABLE`, 5 = `AVAILABLE`, 6 =
|
||||
`DELETED`
|
||||
requests:
|
||||
type: array
|
||||
readOnly: true
|
||||
@@ -2173,7 +2183,9 @@ paths:
|
||||
/status/appdata:
|
||||
get:
|
||||
summary: Get application data volume status
|
||||
description: For Docker installs, returns whether or not the volume mount was configured properly. Always returns true for non-Docker installs.
|
||||
description:
|
||||
For Docker installs, returns whether or not the volume mount was
|
||||
configured properly. Always returns true for non-Docker installs.
|
||||
security: []
|
||||
tags:
|
||||
- public
|
||||
@@ -2317,7 +2329,9 @@ paths:
|
||||
name: enable
|
||||
explode: false
|
||||
allowReserved: true
|
||||
description: Comma separated list of libraries to enable. Any libraries not passed will be disabled!
|
||||
description:
|
||||
Comma separated list of libraries to enable. Any libraries not
|
||||
passed will be disabled!
|
||||
schema:
|
||||
type: string
|
||||
nullable: true
|
||||
@@ -2386,7 +2400,9 @@ paths:
|
||||
$ref: '#/components/schemas/JellyfinLibrary'
|
||||
post:
|
||||
summary: Start full Jellyfin library sync
|
||||
description: Runs a full Jellyfin library sync and returns the progress in a JSON array.
|
||||
description:
|
||||
Runs a full Jellyfin library sync and returns the progress in a
|
||||
JSON array.
|
||||
tags:
|
||||
- settings
|
||||
requestBody:
|
||||
@@ -2472,7 +2488,9 @@ paths:
|
||||
name: enable
|
||||
explode: false
|
||||
allowReserved: true
|
||||
description: Comma separated list of libraries to enable. Any libraries not passed will be disabled!
|
||||
description:
|
||||
Comma separated list of libraries to enable. Any libraries not
|
||||
passed will be disabled!
|
||||
schema:
|
||||
type: string
|
||||
nullable: true
|
||||
@@ -2633,7 +2651,8 @@ paths:
|
||||
/settings/metadatas/test:
|
||||
post:
|
||||
summary: Test Provider configuration
|
||||
description: Tests if the TVDB configuration is valid. Returns a list of available languages on success.
|
||||
description: Tests if the TVDB configuration is valid. Returns a list of
|
||||
available languages on success.
|
||||
tags:
|
||||
- settings
|
||||
requestBody:
|
||||
@@ -2727,7 +2746,9 @@ paths:
|
||||
/settings/radarr/test:
|
||||
post:
|
||||
summary: Test Radarr configuration
|
||||
description: Tests if the Radarr configuration is valid. Returns profiles and root folders on success.
|
||||
description:
|
||||
Tests if the Radarr configuration is valid. Returns profiles and
|
||||
root folders on success.
|
||||
tags:
|
||||
- settings
|
||||
requestBody:
|
||||
@@ -2816,7 +2837,9 @@ paths:
|
||||
/settings/radarr/{radarrId}/profiles:
|
||||
get:
|
||||
summary: Get available Radarr profiles
|
||||
description: Returns a list of profiles available on the Radarr server instance in a JSON array.
|
||||
description:
|
||||
Returns a list of profiles available on the Radarr server instance
|
||||
in a JSON array.
|
||||
tags:
|
||||
- settings
|
||||
parameters:
|
||||
@@ -2871,7 +2894,9 @@ paths:
|
||||
/settings/sonarr/test:
|
||||
post:
|
||||
summary: Test Sonarr configuration
|
||||
description: Tests if the Sonarr configuration is valid. Returns profiles and root folders on success.
|
||||
description:
|
||||
Tests if the Sonarr configuration is valid. Returns profiles and
|
||||
root folders on success.
|
||||
tags:
|
||||
- settings
|
||||
requestBody:
|
||||
@@ -2961,7 +2986,9 @@ paths:
|
||||
get:
|
||||
summary: Get public settings
|
||||
security: []
|
||||
description: Returns settings that are not protected or sensitive. Mainly used to determine if the application has been configured for the first time.
|
||||
description:
|
||||
Returns settings that are not protected or sensitive. Mainly used
|
||||
to determine if the application has been configured for the first time.
|
||||
tags:
|
||||
- settings
|
||||
responses:
|
||||
@@ -2974,7 +3001,9 @@ paths:
|
||||
/settings/initialize:
|
||||
post:
|
||||
summary: Initialize application
|
||||
description: Sets the app as initialized, allowing the user to navigate to pages other than the setup page.
|
||||
description:
|
||||
Sets the app as initialized, allowing the user to navigate to pages
|
||||
other than the setup page.
|
||||
tags:
|
||||
- settings
|
||||
responses:
|
||||
@@ -2987,7 +3016,9 @@ paths:
|
||||
/settings/jobs:
|
||||
get:
|
||||
summary: Get scheduled jobs
|
||||
description: Returns list of all scheduled jobs and details about their next execution time in a JSON array.
|
||||
description:
|
||||
Returns list of all scheduled jobs and details about their next
|
||||
execution time in a JSON array.
|
||||
tags:
|
||||
- settings
|
||||
responses:
|
||||
@@ -3002,7 +3033,9 @@ paths:
|
||||
/settings/jobs/{jobId}/run:
|
||||
post:
|
||||
summary: Invoke a specific job
|
||||
description: Invokes a specific job to run. Will return the new job status in JSON format.
|
||||
description:
|
||||
Invokes a specific job to run. Will return the new job status in
|
||||
JSON format.
|
||||
tags:
|
||||
- settings
|
||||
parameters:
|
||||
@@ -3040,7 +3073,9 @@ paths:
|
||||
/settings/jobs/{jobId}/schedule:
|
||||
post:
|
||||
summary: Modify job schedule
|
||||
description: Re-registers the job with the schedule specified. Will return the job in JSON format.
|
||||
description:
|
||||
Re-registers the job with the schedule specified. Will return the
|
||||
job in JSON format.
|
||||
tags:
|
||||
- settings
|
||||
parameters:
|
||||
@@ -3836,7 +3871,9 @@ paths:
|
||||
$ref: '#/components/schemas/DiscoverSlider'
|
||||
delete:
|
||||
summary: Delete slider by ID
|
||||
description: Deletes the slider with the provided sliderId. Requires the `ADMIN` permission.
|
||||
description:
|
||||
Deletes the slider with the provided sliderId. Requires the `ADMIN`
|
||||
permission.
|
||||
tags:
|
||||
- settings
|
||||
parameters:
|
||||
@@ -3885,7 +3922,9 @@ paths:
|
||||
/settings/discover/reset:
|
||||
get:
|
||||
summary: Reset all discover sliders
|
||||
description: Resets all discovery sliders to the default values. Requires the `ADMIN` permission.
|
||||
description:
|
||||
Resets all discovery sliders to the default values. Requires the
|
||||
`ADMIN` permission.
|
||||
tags:
|
||||
- settings
|
||||
responses:
|
||||
@@ -3938,7 +3977,12 @@ paths:
|
||||
/auth/plex:
|
||||
post:
|
||||
summary: Sign in using a Plex token
|
||||
description: Takes an `authToken` (Plex token) to log the user in. Generates a session cookie for use in further requests. If the user does not exist, and there are no other users, then a user will be created with full admin privileges. If a user logs in with access to the main Plex server, they will also have an account created, but without any permissions.
|
||||
description:
|
||||
Takes an `authToken` (Plex token) to log the user in. Generates a
|
||||
session cookie for use in further requests. If the user does not exist,
|
||||
and there are no other users, then a user will be created with full
|
||||
admin privileges. If a user logs in with access to the main Plex server,
|
||||
they will also have an account created, but without any permissions.
|
||||
security: []
|
||||
tags:
|
||||
- auth
|
||||
@@ -3963,7 +4007,12 @@ paths:
|
||||
/auth/jellyfin:
|
||||
post:
|
||||
summary: Sign in using a Jellyfin username and password
|
||||
description: Takes the user's username and password to log the user in. Generates a session cookie for use in further requests. If the user does not exist, and there are no other users, then a user will be created with full admin privileges. If a user logs in with access to the Jellyfin server, they will also have an account created, but without any permissions.
|
||||
description: Takes the user's username and password to log the user in.
|
||||
Generates a session cookie for use in further requests. If the user does
|
||||
not exist, and there are no other users, then a user will be created
|
||||
with full admin privileges. If a user logs in with access to the
|
||||
Jellyfin server, they will also have an account created, but without any
|
||||
permissions.
|
||||
security: []
|
||||
tags:
|
||||
- auth
|
||||
@@ -3997,7 +4046,9 @@ paths:
|
||||
/auth/local:
|
||||
post:
|
||||
summary: Sign in using a local account
|
||||
description: Takes an `email` and a `password` to log the user in. Generates a session cookie for use in further requests.
|
||||
description:
|
||||
Takes an `email` and a `password` to log the user in. Generates a
|
||||
session cookie for use in further requests.
|
||||
security: []
|
||||
tags:
|
||||
- auth
|
||||
@@ -4025,7 +4076,8 @@ paths:
|
||||
/auth/logout:
|
||||
post:
|
||||
summary: Sign out and clear session cookie
|
||||
description: Completely clear the session cookie and associated values, effectively signing the user out.
|
||||
description: Completely clear the session cookie and associated values,
|
||||
effectively signing the user out.
|
||||
tags:
|
||||
- auth
|
||||
responses:
|
||||
@@ -4435,7 +4487,8 @@ paths:
|
||||
$ref: '#/components/schemas/User'
|
||||
delete:
|
||||
summary: Delete user by ID
|
||||
description: Deletes the user with the provided userId. Requires the `MANAGE_USERS` permission.
|
||||
description: Deletes the user with the provided userId. Requires the
|
||||
`MANAGE_USERS` permission.
|
||||
tags:
|
||||
- users
|
||||
parameters:
|
||||
@@ -4968,7 +5021,8 @@ paths:
|
||||
/user/{userId}/settings/main:
|
||||
get:
|
||||
summary: Get general settings for a user
|
||||
description: Returns general settings for a specific user. Requires `MANAGE_USERS` permission if viewing other users.
|
||||
description: Returns general settings for a specific user. Requires
|
||||
`MANAGE_USERS` permission if viewing other users.
|
||||
tags:
|
||||
- users
|
||||
parameters:
|
||||
@@ -4986,7 +5040,9 @@ paths:
|
||||
$ref: '#/components/schemas/UserSettings'
|
||||
post:
|
||||
summary: Update general settings for a user
|
||||
description: Updates and returns general settings for a specific user. Requires `MANAGE_USERS` permission if editing other users.
|
||||
description:
|
||||
Updates and returns general settings for a specific user. Requires
|
||||
`MANAGE_USERS` permission if editing other users.
|
||||
tags:
|
||||
- users
|
||||
parameters:
|
||||
@@ -5011,7 +5067,9 @@ paths:
|
||||
/user/{userId}/settings/password:
|
||||
get:
|
||||
summary: Get password page informatiom
|
||||
description: Returns important data for the password page to function correctly. Requires `MANAGE_USERS` permission if viewing other users.
|
||||
description:
|
||||
Returns important data for the password page to function correctly.
|
||||
Requires `MANAGE_USERS` permission if viewing other users.
|
||||
tags:
|
||||
- users
|
||||
parameters:
|
||||
@@ -5033,7 +5091,9 @@ paths:
|
||||
example: true
|
||||
post:
|
||||
summary: Update password for a user
|
||||
description: Updates a user's password. Requires `MANAGE_USERS` permission if editing other users.
|
||||
description:
|
||||
Updates a user's password. Requires `MANAGE_USERS` permission if
|
||||
editing other users.
|
||||
tags:
|
||||
- users
|
||||
parameters:
|
||||
@@ -5062,7 +5122,9 @@ paths:
|
||||
/user/{userId}/settings/linked-accounts/plex:
|
||||
post:
|
||||
summary: Link the provided Plex account to the current user
|
||||
description: Logs in to Plex with the provided auth token, then links the associated Plex account with the user's account. Users can only link external accounts to their own account.
|
||||
description: Logs in to Plex with the provided auth token, then links the
|
||||
associated Plex account with the user's account. Users can only link
|
||||
external accounts to their own account.
|
||||
tags:
|
||||
- users
|
||||
parameters:
|
||||
@@ -5091,7 +5153,8 @@ paths:
|
||||
description: Account already linked to a user
|
||||
delete:
|
||||
summary: Remove the linked Plex account for a user
|
||||
description: Removes the linked Plex account for a specific user. Requires `MANAGE_USERS` permission if editing other users.
|
||||
description: Removes the linked Plex account for a specific user. Requires
|
||||
`MANAGE_USERS` permission if editing other users.
|
||||
tags:
|
||||
- users
|
||||
parameters:
|
||||
@@ -5110,7 +5173,10 @@ paths:
|
||||
/user/{userId}/settings/linked-accounts/jellyfin:
|
||||
post:
|
||||
summary: Link the provided Jellyfin account to the current user
|
||||
description: Logs in to Jellyfin with the provided credentials, then links the associated Jellyfin account with the user's account. Users can only link external accounts to their own account.
|
||||
description:
|
||||
Logs in to Jellyfin with the provided credentials, then links the
|
||||
associated Jellyfin account with the user's account. Users can only link
|
||||
external accounts to their own account.
|
||||
tags:
|
||||
- users
|
||||
parameters:
|
||||
@@ -5141,7 +5207,9 @@ paths:
|
||||
description: Account already linked to a user
|
||||
delete:
|
||||
summary: Remove the linked Jellyfin account for a user
|
||||
description: Removes the linked Jellyfin account for a specific user. Requires `MANAGE_USERS` permission if editing other users.
|
||||
description:
|
||||
Removes the linked Jellyfin account for a specific user. Requires
|
||||
`MANAGE_USERS` permission if editing other users.
|
||||
tags:
|
||||
- users
|
||||
parameters:
|
||||
@@ -5160,7 +5228,8 @@ paths:
|
||||
/user/{userId}/settings/notifications:
|
||||
get:
|
||||
summary: Get notification settings for a user
|
||||
description: Returns notification settings for a specific user. Requires `MANAGE_USERS` permission if viewing other users.
|
||||
description: Returns notification settings for a specific user. Requires
|
||||
`MANAGE_USERS` permission if viewing other users.
|
||||
tags:
|
||||
- users
|
||||
parameters:
|
||||
@@ -5178,7 +5247,9 @@ paths:
|
||||
$ref: '#/components/schemas/UserSettingsNotifications'
|
||||
post:
|
||||
summary: Update notification settings for a user
|
||||
description: Updates and returns notification settings for a specific user. Requires `MANAGE_USERS` permission if editing other users.
|
||||
description:
|
||||
Updates and returns notification settings for a specific user.
|
||||
Requires `MANAGE_USERS` permission if editing other users.
|
||||
tags:
|
||||
- users
|
||||
parameters:
|
||||
@@ -5203,7 +5274,8 @@ paths:
|
||||
/user/{userId}/settings/permissions:
|
||||
get:
|
||||
summary: Get permission settings for a user
|
||||
description: Returns permission settings for a specific user. Requires `MANAGE_USERS` permission if viewing other users.
|
||||
description: Returns permission settings for a specific user. Requires
|
||||
`MANAGE_USERS` permission if viewing other users.
|
||||
tags:
|
||||
- users
|
||||
parameters:
|
||||
@@ -5225,7 +5297,8 @@ paths:
|
||||
example: 2
|
||||
post:
|
||||
summary: Update permission settings for a user
|
||||
description: Updates and returns permission settings for a specific user. Requires `MANAGE_USERS` permission if editing other users.
|
||||
description: Updates and returns permission settings for a specific user.
|
||||
Requires `MANAGE_USERS` permission if editing other users.
|
||||
tags:
|
||||
- users
|
||||
parameters:
|
||||
@@ -5376,7 +5449,9 @@ paths:
|
||||
/search/company:
|
||||
get:
|
||||
summary: Search for companies
|
||||
description: Returns a list of TMDB companies matching the search query. (Will not return origin country)
|
||||
description:
|
||||
Returns a list of TMDB companies matching the search query. (Will
|
||||
not return origin country)
|
||||
tags:
|
||||
- search
|
||||
parameters:
|
||||
@@ -5512,19 +5587,25 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
example: PG-13
|
||||
description: Exact certification to filter by (used when certificationMode is 'exact')
|
||||
description:
|
||||
Exact certification to filter by (used when certificationMode is
|
||||
'exact')
|
||||
- in: query
|
||||
name: certificationGte
|
||||
schema:
|
||||
type: string
|
||||
example: G
|
||||
description: Minimum certification to filter by (used when certificationMode is 'range')
|
||||
description:
|
||||
Minimum certification to filter by (used when certificationMode is
|
||||
'range')
|
||||
- in: query
|
||||
name: certificationLte
|
||||
schema:
|
||||
type: string
|
||||
example: PG-13
|
||||
description: Maximum certification to filter by (used when certificationMode is 'range')
|
||||
description:
|
||||
Maximum certification to filter by (used when certificationMode is
|
||||
'range')
|
||||
- in: query
|
||||
name: certificationCountry
|
||||
schema:
|
||||
@@ -5537,7 +5618,9 @@ paths:
|
||||
type: string
|
||||
enum: [exact, range]
|
||||
example: exact
|
||||
description: Determines whether to use exact certification matching or a certification range (internal use only, not sent to TMDB API)
|
||||
description:
|
||||
Determines whether to use exact certification matching or a
|
||||
certification range (internal use only, not sent to TMDB API)
|
||||
responses:
|
||||
'200':
|
||||
description: Results
|
||||
@@ -5609,7 +5692,9 @@ paths:
|
||||
/discover/movies/language/{language}:
|
||||
get:
|
||||
summary: Discover movies by original language
|
||||
description: Returns a list of movies based on the provided ISO 639-1 language code in a JSON object.
|
||||
description:
|
||||
Returns a list of movies based on the provided ISO 639-1 language
|
||||
code in a JSON object.
|
||||
tags:
|
||||
- search
|
||||
parameters:
|
||||
@@ -5656,7 +5741,9 @@ paths:
|
||||
/discover/movies/studio/{studioId}:
|
||||
get:
|
||||
summary: Discover movies by studio
|
||||
description: Returns a list of movies based on the provided studio ID in a JSON object.
|
||||
description:
|
||||
Returns a list of movies based on the provided studio ID in a JSON
|
||||
object.
|
||||
tags:
|
||||
- search
|
||||
parameters:
|
||||
@@ -5843,19 +5930,25 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
example: TV-14
|
||||
description: Exact certification to filter by (used when certificationMode is 'exact')
|
||||
description:
|
||||
Exact certification to filter by (used when certificationMode is
|
||||
'exact')
|
||||
- in: query
|
||||
name: certificationGte
|
||||
schema:
|
||||
type: string
|
||||
example: TV-PG
|
||||
description: Minimum certification to filter by (used when certificationMode is 'range')
|
||||
description:
|
||||
Minimum certification to filter by (used when certificationMode is
|
||||
'range')
|
||||
- in: query
|
||||
name: certificationLte
|
||||
schema:
|
||||
type: string
|
||||
example: TV-MA
|
||||
description: Maximum certification to filter by (used when certificationMode is 'range')
|
||||
description:
|
||||
Maximum certification to filter by (used when certificationMode is
|
||||
'range')
|
||||
- in: query
|
||||
name: certificationCountry
|
||||
schema:
|
||||
@@ -5868,7 +5961,9 @@ paths:
|
||||
type: string
|
||||
enum: [exact, range]
|
||||
example: exact
|
||||
description: Determines whether to use exact certification matching or a certification range (internal use only, not sent to TMDB API)
|
||||
description:
|
||||
Determines whether to use exact certification matching or a
|
||||
certification range (internal use only, not sent to TMDB API)
|
||||
responses:
|
||||
'200':
|
||||
description: Results
|
||||
@@ -5893,7 +5988,9 @@ paths:
|
||||
/discover/tv/language/{language}:
|
||||
get:
|
||||
summary: Discover TV shows by original language
|
||||
description: Returns a list of TV shows based on the provided ISO 639-1 language code in a JSON object.
|
||||
description:
|
||||
Returns a list of TV shows based on the provided ISO 639-1 language
|
||||
code in a JSON object.
|
||||
tags:
|
||||
- search
|
||||
parameters:
|
||||
@@ -5940,7 +6037,9 @@ paths:
|
||||
/discover/tv/genre/{genreId}:
|
||||
get:
|
||||
summary: Discover TV shows by genre
|
||||
description: Returns a list of TV shows based on the provided genre ID in a JSON object.
|
||||
description:
|
||||
Returns a list of TV shows based on the provided genre ID in a JSON
|
||||
object.
|
||||
tags:
|
||||
- search
|
||||
parameters:
|
||||
@@ -5987,7 +6086,9 @@ paths:
|
||||
/discover/tv/network/{networkId}:
|
||||
get:
|
||||
summary: Discover TV shows by network
|
||||
description: Returns a list of TV shows based on the provided network ID in a JSON object.
|
||||
description:
|
||||
Returns a list of TV shows based on the provided network ID in a
|
||||
JSON object.
|
||||
tags:
|
||||
- search
|
||||
parameters:
|
||||
@@ -6470,7 +6571,9 @@ paths:
|
||||
$ref: '#/components/schemas/MediaRequest'
|
||||
put:
|
||||
summary: Update MediaRequest
|
||||
description: Updates a specific media request and returns the request in a JSON object. Requires the `MANAGE_REQUESTS` permission.
|
||||
description:
|
||||
Updates a specific media request and returns the request in a JSON
|
||||
object. Requires the `MANAGE_REQUESTS` permission.
|
||||
tags:
|
||||
- request
|
||||
parameters:
|
||||
@@ -6521,7 +6624,9 @@ paths:
|
||||
$ref: '#/components/schemas/MediaRequest'
|
||||
delete:
|
||||
summary: Delete request
|
||||
description: Removes a request. If the user has the `MANAGE_REQUESTS` permission, any request can be removed. Otherwise, only pending requests can be removed.
|
||||
description: Removes a request. If the user has the `MANAGE_REQUESTS`
|
||||
permission, any request can be removed. Otherwise, only pending requests
|
||||
can be removed.
|
||||
tags:
|
||||
- request
|
||||
parameters:
|
||||
@@ -6618,7 +6723,9 @@ paths:
|
||||
/movie/{movieId}/recommendations:
|
||||
get:
|
||||
summary: Get recommended movies
|
||||
description: Returns list of recommended movies based on provided movie ID in a JSON object.
|
||||
description:
|
||||
Returns list of recommended movies based on provided movie ID in a
|
||||
JSON object.
|
||||
tags:
|
||||
- movies
|
||||
parameters:
|
||||
@@ -6663,7 +6770,9 @@ paths:
|
||||
/movie/{movieId}/similar:
|
||||
get:
|
||||
summary: Get similar movies
|
||||
description: Returns list of similar movies based on the provided movieId in a JSON object.
|
||||
description:
|
||||
Returns list of similar movies based on the provided movieId in a
|
||||
JSON object.
|
||||
tags:
|
||||
- movies
|
||||
parameters:
|
||||
@@ -6750,7 +6859,9 @@ paths:
|
||||
/movie/{movieId}/ratingscombined:
|
||||
get:
|
||||
summary: Get RT and IMDB movie ratings combined
|
||||
description: Returns ratings from RottenTomatoes and IMDB based on the provided movieId in a JSON object.
|
||||
description:
|
||||
Returns ratings from RottenTomatoes and IMDB based on the provided
|
||||
movieId in a JSON object.
|
||||
tags:
|
||||
- movies
|
||||
parameters:
|
||||
@@ -6863,7 +6974,9 @@ paths:
|
||||
/tv/{tvId}/recommendations:
|
||||
get:
|
||||
summary: Get recommended TV series
|
||||
description: Returns list of recommended TV series based on the provided tvId in a JSON object.
|
||||
description:
|
||||
Returns list of recommended TV series based on the provided tvId in
|
||||
a JSON object.
|
||||
tags:
|
||||
- tv
|
||||
parameters:
|
||||
@@ -6908,7 +7021,9 @@ paths:
|
||||
/tv/{tvId}/similar:
|
||||
get:
|
||||
summary: Get similar TV series
|
||||
description: Returns list of similar TV series based on the provided tvId in a JSON object.
|
||||
description:
|
||||
Returns list of similar TV series based on the provided tvId in a
|
||||
JSON object.
|
||||
tags:
|
||||
- tv
|
||||
parameters:
|
||||
@@ -7014,7 +7129,8 @@ paths:
|
||||
/person/{personId}/combined_credits:
|
||||
get:
|
||||
summary: Get combined credits
|
||||
description: Returns the person's combined credits based on the provided personId in a JSON object.
|
||||
description: Returns the person's combined credits based on the provided
|
||||
personId in a JSON object.
|
||||
tags:
|
||||
- person
|
||||
parameters:
|
||||
@@ -7104,7 +7220,9 @@ paths:
|
||||
/media/{mediaId}:
|
||||
delete:
|
||||
summary: Delete media item
|
||||
description: Removes a media item. The `MANAGE_REQUESTS` permission is required to perform this action.
|
||||
description:
|
||||
Removes a media item. The `MANAGE_REQUESTS` permission is required
|
||||
to perform this action.
|
||||
tags:
|
||||
- media
|
||||
parameters:
|
||||
@@ -7121,7 +7239,9 @@ paths:
|
||||
/media/{mediaId}/file:
|
||||
delete:
|
||||
summary: Delete media file
|
||||
description: Removes a media file from radarr/sonarr. The `ADMIN` permission is required to perform this action.
|
||||
description:
|
||||
Removes a media file from radarr/sonarr. The `ADMIN` permission is
|
||||
required to perform this action.
|
||||
tags:
|
||||
- media
|
||||
parameters:
|
||||
@@ -7134,7 +7254,9 @@ paths:
|
||||
type: string
|
||||
- in: query
|
||||
name: is4k
|
||||
description: Whether to remove from 4K service instance (true) or regular service instance (false)
|
||||
description:
|
||||
Whether to remove from 4K service instance (true) or regular
|
||||
service instance (false)
|
||||
required: false
|
||||
example: false
|
||||
schema:
|
||||
@@ -7278,7 +7400,9 @@ paths:
|
||||
/service/radarr/{radarrId}:
|
||||
get:
|
||||
summary: Get Radarr server quality profiles and root folders
|
||||
description: Returns a Radarr server's quality profile and root folder details in a JSON object.
|
||||
description:
|
||||
Returns a Radarr server's quality profile and root folder details
|
||||
in a JSON object.
|
||||
tags:
|
||||
- service
|
||||
parameters:
|
||||
@@ -7318,7 +7442,9 @@ paths:
|
||||
/service/sonarr/{sonarrId}:
|
||||
get:
|
||||
summary: Get Sonarr server quality profiles and root folders
|
||||
description: Returns a Sonarr server's quality profile and root folder details in a JSON object.
|
||||
description:
|
||||
Returns a Sonarr server's quality profile and root folder details
|
||||
in a JSON object.
|
||||
tags:
|
||||
- service
|
||||
parameters:
|
||||
@@ -7655,7 +7781,10 @@ paths:
|
||||
$ref: '#/components/schemas/Issue'
|
||||
delete:
|
||||
summary: Delete issue
|
||||
description: Removes an issue. If the user has the `MANAGE_ISSUES` permission, any issue can be removed. Otherwise, only a users own issues can be removed.
|
||||
description:
|
||||
Removes an issue. If the user has the `MANAGE_ISSUES` permission,
|
||||
any issue can be removed. Otherwise, only a users own issues can be
|
||||
removed.
|
||||
tags:
|
||||
- issue
|
||||
parameters:
|
||||
|
||||
@@ -43,6 +43,9 @@ export class UserSettings {
|
||||
@Column({ default: '' })
|
||||
public locale?: string;
|
||||
|
||||
@Column({ nullable: true })
|
||||
public mediaLocale?: string;
|
||||
|
||||
@Column({ nullable: true })
|
||||
public discoverRegion?: string;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ export interface UserSettingsGeneralResponse {
|
||||
username?: string;
|
||||
email?: string;
|
||||
locale?: string;
|
||||
mediaLocale?: string;
|
||||
discoverRegion?: string;
|
||||
streamingRegion?: string;
|
||||
originalLanguage?: string;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import type { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class AddMediaLanguageSetting1777644799789 implements MigrationInterface {
|
||||
name = 'AddMediaLanguageSetting1777644799789';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "user_settings" ADD "mediaLocale" character varying`
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "user_settings" DROP COLUMN "mediaLocale"`
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import type { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class AddMediaLanguageSetting1777644713621 implements MigrationInterface {
|
||||
name = 'AddMediaLanguageSetting1777644713621';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DROP INDEX "IDX_03f7958328e311761b0de675fb"`);
|
||||
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 "UQ_6427d07d9a171a3a1ab87480005" UNIQUE ("endpoint", "userId"), 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 INDEX "IDX_03f7958328e311761b0de675fb" ON "user_push_subscription" ("userId") `
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE "temporary_user_settings" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "locale" varchar NOT NULL DEFAULT (''), "discoverRegion" varchar, "streamingRegion" varchar, "originalLanguage" varchar, "pgpKey" varchar, "discordId" varchar, "pushbulletAccessToken" varchar, "pushoverApplicationToken" varchar, "pushoverUserKey" varchar, "pushoverSound" varchar, "telegramChatId" varchar, "telegramSendSilently" boolean, "watchlistSyncMovies" boolean, "watchlistSyncTv" boolean, "notificationTypes" text, "userId" integer, "telegramMessageThreadId" varchar, "mediaLocale" varchar, CONSTRAINT "REL_986a2b6d3c05eb4091bb8066f7" 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", "locale", "discoverRegion", "streamingRegion", "originalLanguage", "pgpKey", "discordId", "pushbulletAccessToken", "pushoverApplicationToken", "pushoverUserKey", "pushoverSound", "telegramChatId", "telegramSendSilently", "watchlistSyncMovies", "watchlistSyncTv", "notificationTypes", "userId", "telegramMessageThreadId") SELECT "id", "locale", "discoverRegion", "streamingRegion", "originalLanguage", "pgpKey", "discordId", "pushbulletAccessToken", "pushoverApplicationToken", "pushoverUserKey", "pushoverSound", "telegramChatId", "telegramSendSilently", "watchlistSyncMovies", "watchlistSyncTv", "notificationTypes", "userId", "telegramMessageThreadId" 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_03f7958328e311761b0de675fb"`);
|
||||
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 "UQ_6427d07d9a171a3a1ab87480005" UNIQUE ("endpoint", "userId"), 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 INDEX "IDX_03f7958328e311761b0de675fb" ON "user_push_subscription" ("userId") `
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DROP INDEX "IDX_03f7958328e311761b0de675fb"`);
|
||||
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_f90ab5a4ed54905a4bb51a7148b" UNIQUE ("auth"), CONSTRAINT "UQ_6427d07d9a171a3a1ab87480005" UNIQUE ("endpoint", "userId"), 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_03f7958328e311761b0de675fb" ON "user_push_subscription" ("userId") `
|
||||
);
|
||||
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, "locale" varchar NOT NULL DEFAULT (''), "discoverRegion" varchar, "streamingRegion" varchar, "originalLanguage" varchar, "pgpKey" varchar, "discordId" varchar, "pushbulletAccessToken" varchar, "pushoverApplicationToken" varchar, "pushoverUserKey" varchar, "pushoverSound" varchar, "telegramChatId" varchar, "telegramSendSilently" boolean, "watchlistSyncMovies" boolean, "watchlistSyncTv" boolean, "notificationTypes" text, "userId" integer, "telegramMessageThreadId" varchar, CONSTRAINT "REL_986a2b6d3c05eb4091bb8066f7" 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", "locale", "discoverRegion", "streamingRegion", "originalLanguage", "pgpKey", "discordId", "pushbulletAccessToken", "pushoverApplicationToken", "pushoverUserKey", "pushoverSound", "telegramChatId", "telegramSendSilently", "watchlistSyncMovies", "watchlistSyncTv", "notificationTypes", "userId", "telegramMessageThreadId") SELECT "id", "locale", "discoverRegion", "streamingRegion", "originalLanguage", "pgpKey", "discordId", "pushbulletAccessToken", "pushoverApplicationToken", "pushoverUserKey", "pushoverSound", "telegramChatId", "telegramSendSilently", "watchlistSyncMovies", "watchlistSyncTv", "notificationTypes", "userId", "telegramMessageThreadId" FROM "temporary_user_settings"`
|
||||
);
|
||||
await queryRunner.query(`DROP TABLE "temporary_user_settings"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_03f7958328e311761b0de675fb"`);
|
||||
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_f90ab5a4ed54905a4bb51a7148b" UNIQUE ("auth"), CONSTRAINT "UQ_6427d07d9a171a3a1ab87480005" UNIQUE ("endpoint", "userId"), 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_03f7958328e311761b0de675fb" ON "user_push_subscription" ("userId") `
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -258,10 +258,11 @@ router.get<{ id: string }>('/network/:id', async (req, res, next) => {
|
||||
|
||||
router.get('/genres/movie', isAuthenticated(), async (req, res, next) => {
|
||||
const tmdb = new TheMovieDb();
|
||||
const mediaLocale = req.user?.settings?.mediaLocale ?? req.locale;
|
||||
|
||||
try {
|
||||
const genres = await tmdb.getMovieGenres({
|
||||
language: (req.query.language as string) ?? req.locale,
|
||||
language: (req.query.language as string) ?? mediaLocale,
|
||||
});
|
||||
|
||||
return res.status(200).json(genres);
|
||||
@@ -279,10 +280,11 @@ router.get('/genres/movie', isAuthenticated(), async (req, res, next) => {
|
||||
|
||||
router.get('/genres/tv', isAuthenticated(), async (req, res, next) => {
|
||||
const tmdb = new TheMovieDb();
|
||||
const mediaLocale = req.user?.settings?.mediaLocale ?? req.locale;
|
||||
|
||||
try {
|
||||
const genres = await tmdb.getTvGenres({
|
||||
language: (req.query.language as string) ?? req.locale,
|
||||
language: (req.query.language as string) ?? mediaLocale,
|
||||
});
|
||||
|
||||
return res.status(200).json(genres);
|
||||
|
||||
@@ -15,11 +15,12 @@ const movieRoutes = Router();
|
||||
|
||||
movieRoutes.get('/:id', async (req, res, next) => {
|
||||
const tmdb = new TheMovieDb();
|
||||
const mediaLocale = req.user?.settings?.mediaLocale ?? req.locale;
|
||||
|
||||
try {
|
||||
const tmdbMovie = await tmdb.getMovie({
|
||||
movieId: Number(req.params.id),
|
||||
language: (req.query.language as string) ?? req.locale,
|
||||
language: (req.query.language as string) ?? mediaLocale,
|
||||
});
|
||||
|
||||
const media = await Media.getMedia(tmdbMovie.id, MediaType.MOVIE);
|
||||
@@ -58,12 +59,13 @@ movieRoutes.get('/:id', async (req, res, next) => {
|
||||
|
||||
movieRoutes.get('/:id/recommendations', async (req, res, next) => {
|
||||
const tmdb = new TheMovieDb();
|
||||
const mediaLocale = req.user?.settings?.mediaLocale ?? req.locale;
|
||||
|
||||
try {
|
||||
const results = await tmdb.getMovieRecommendations({
|
||||
movieId: Number(req.params.id),
|
||||
page: Number(req.query.page),
|
||||
language: (req.query.language as string) ?? req.locale,
|
||||
language: (req.query.language as string) ?? mediaLocale,
|
||||
});
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
@@ -103,12 +105,13 @@ movieRoutes.get('/:id/recommendations', async (req, res, next) => {
|
||||
|
||||
movieRoutes.get('/:id/similar', async (req, res, next) => {
|
||||
const tmdb = new TheMovieDb();
|
||||
const mediaLocale = req.user?.settings?.mediaLocale ?? req.locale;
|
||||
|
||||
try {
|
||||
const results = await tmdb.getMovieSimilar({
|
||||
movieId: Number(req.params.id),
|
||||
page: Number(req.query.page),
|
||||
language: (req.query.language as string) ?? req.locale,
|
||||
language: (req.query.language as string) ?? mediaLocale,
|
||||
});
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
|
||||
@@ -12,11 +12,12 @@ const personRoutes = Router();
|
||||
|
||||
personRoutes.get('/:id', async (req, res, next) => {
|
||||
const tmdb = new TheMovieDb();
|
||||
const mediaLocale = req.user?.settings?.mediaLocale ?? req.locale;
|
||||
|
||||
try {
|
||||
const person = await tmdb.getPerson({
|
||||
personId: Number(req.params.id),
|
||||
language: (req.query.language as string) ?? req.locale,
|
||||
language: (req.query.language as string) ?? mediaLocale,
|
||||
});
|
||||
return res.status(200).json(mapPersonDetails(person));
|
||||
} catch (e) {
|
||||
@@ -34,11 +35,12 @@ personRoutes.get('/:id', async (req, res, next) => {
|
||||
|
||||
personRoutes.get('/:id/combined_credits', async (req, res, next) => {
|
||||
const tmdb = new TheMovieDb();
|
||||
const mediaLocale = req.user?.settings?.mediaLocale ?? req.locale;
|
||||
|
||||
try {
|
||||
const combinedCredits = await tmdb.getPersonCombinedCredits({
|
||||
personId: Number(req.params.id),
|
||||
language: (req.query.language as string) ?? req.locale,
|
||||
language: (req.query.language as string) ?? mediaLocale,
|
||||
});
|
||||
|
||||
const castMedia = await Media.getRelatedMedia(
|
||||
|
||||
@@ -10,6 +10,7 @@ const searchRoutes = Router();
|
||||
|
||||
searchRoutes.get('/', async (req, res, next) => {
|
||||
const queryString = req.query.query as string;
|
||||
const mediaLocale = req.user?.settings?.mediaLocale ?? req.locale;
|
||||
const searchProvider = findSearchProvider(queryString.toLowerCase());
|
||||
let results: TmdbSearchMultiResponse;
|
||||
|
||||
@@ -20,7 +21,7 @@ searchRoutes.get('/', async (req, res, next) => {
|
||||
.match(searchProvider.pattern) as RegExpMatchArray;
|
||||
results = await searchProvider.search({
|
||||
id,
|
||||
language: (req.query.language as string) ?? req.locale,
|
||||
language: (req.query.language as string) ?? mediaLocale,
|
||||
query: queryString,
|
||||
});
|
||||
} else {
|
||||
@@ -29,7 +30,7 @@ searchRoutes.get('/', async (req, res, next) => {
|
||||
results = await tmdb.searchMulti({
|
||||
query: queryString,
|
||||
page: Number(req.query.page),
|
||||
language: (req.query.language as string) ?? req.locale,
|
||||
language: (req.query.language as string) ?? mediaLocale,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ const tvRoutes = Router();
|
||||
|
||||
tvRoutes.get('/:id', async (req, res, next) => {
|
||||
const tmdb = new TheMovieDb();
|
||||
const mediaLocale = req.user?.settings?.mediaLocale ?? req.locale;
|
||||
|
||||
try {
|
||||
const tmdbTv = await tmdb.getTvShow({
|
||||
@@ -28,7 +29,7 @@ tvRoutes.get('/:id', async (req, res, next) => {
|
||||
: await getMetadataProvider('tv');
|
||||
const tv = await metadataProvider.getTvShow({
|
||||
tvId: Number(req.params.id),
|
||||
language: (req.query.language as string) ?? req.locale,
|
||||
language: (req.query.language as string) ?? mediaLocale,
|
||||
});
|
||||
const media = await Media.getMedia(tv.id, MediaType.TV);
|
||||
|
||||
@@ -67,6 +68,8 @@ tvRoutes.get('/:id', async (req, res, next) => {
|
||||
});
|
||||
|
||||
tvRoutes.get('/:id/season/:seasonNumber', async (req, res, next) => {
|
||||
const mediaLocale = req.user?.settings?.mediaLocale ?? req.locale;
|
||||
|
||||
try {
|
||||
const tmdb = new TheMovieDb();
|
||||
const tmdbTv = await tmdb.getTvShow({
|
||||
@@ -81,7 +84,7 @@ tvRoutes.get('/:id/season/:seasonNumber', async (req, res, next) => {
|
||||
const season = await metadataProvider.getTvSeason({
|
||||
tvId: Number(req.params.id),
|
||||
seasonNumber: Number(req.params.seasonNumber),
|
||||
language: (req.query.language as string) ?? req.locale,
|
||||
language: (req.query.language as string) ?? mediaLocale,
|
||||
});
|
||||
|
||||
return res.status(200).json(mapSeasonWithEpisodes(season));
|
||||
@@ -101,12 +104,13 @@ tvRoutes.get('/:id/season/:seasonNumber', async (req, res, next) => {
|
||||
|
||||
tvRoutes.get('/:id/recommendations', async (req, res, next) => {
|
||||
const tmdb = new TheMovieDb();
|
||||
const mediaLocale = req.user?.settings?.mediaLocale ?? req.locale;
|
||||
|
||||
try {
|
||||
const results = await tmdb.getTvRecommendations({
|
||||
tvId: Number(req.params.id),
|
||||
page: Number(req.query.page),
|
||||
language: (req.query.language as string) ?? req.locale,
|
||||
language: (req.query.language as string) ?? mediaLocale,
|
||||
});
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
@@ -145,12 +149,13 @@ tvRoutes.get('/:id/recommendations', async (req, res, next) => {
|
||||
|
||||
tvRoutes.get('/:id/similar', async (req, res, next) => {
|
||||
const tmdb = new TheMovieDb();
|
||||
const mediaLocale = req.user?.settings?.mediaLocale ?? req.locale;
|
||||
|
||||
try {
|
||||
const results = await tmdb.getTvSimilar({
|
||||
tvId: Number(req.params.id),
|
||||
page: Number(req.query.page),
|
||||
language: (req.query.language as string) ?? req.locale,
|
||||
language: (req.query.language as string) ?? mediaLocale,
|
||||
});
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
|
||||
@@ -49,6 +49,7 @@ userSettingsRoutes.get<{ id: string }, UserSettingsGeneralResponse>(
|
||||
username: user.username,
|
||||
email: user.email,
|
||||
locale: user.settings?.locale,
|
||||
mediaLocale: user.settings?.mediaLocale,
|
||||
discoverRegion: user.settings?.discoverRegion,
|
||||
streamingRegion: user.settings?.streamingRegion,
|
||||
originalLanguage: user.settings?.originalLanguage,
|
||||
@@ -122,6 +123,7 @@ userSettingsRoutes.post<
|
||||
user.settings = new UserSettings({
|
||||
user: req.user,
|
||||
locale: req.body.locale,
|
||||
mediaLocale: req.body.mediaLocale,
|
||||
discoverRegion: req.body.discoverRegion,
|
||||
streamingRegion: req.body.streamingRegion,
|
||||
originalLanguage: req.body.originalLanguage,
|
||||
@@ -130,6 +132,7 @@ userSettingsRoutes.post<
|
||||
});
|
||||
} else {
|
||||
user.settings.locale = req.body.locale;
|
||||
user.settings.mediaLocale = req.body.mediaLocale;
|
||||
user.settings.discoverRegion = req.body.discoverRegion;
|
||||
user.settings.streamingRegion = req.body.streamingRegion;
|
||||
user.settings.originalLanguage = req.body.originalLanguage;
|
||||
@@ -142,6 +145,7 @@ userSettingsRoutes.post<
|
||||
return res.status(200).json({
|
||||
username: savedUser.username,
|
||||
locale: savedUser.settings?.locale,
|
||||
mediaLocale: savedUser.settings?.mediaLocale,
|
||||
discoverRegion: savedUser.settings?.discoverRegion,
|
||||
streamingRegion: savedUser.settings?.streamingRegion,
|
||||
originalLanguage: savedUser.settings?.originalLanguage,
|
||||
|
||||
@@ -60,6 +60,7 @@ const messages = defineMessages(
|
||||
seriesrequestlimit: 'Series Request Limit',
|
||||
enableOverride: 'Override Global Limit',
|
||||
applanguage: 'Display Language',
|
||||
mediaLanguage: 'Media Language',
|
||||
languageDefault: 'Default ({language})',
|
||||
validationemailrequired: 'Email required',
|
||||
validationemailformat: 'Valid email required',
|
||||
@@ -152,6 +153,7 @@ const UserGeneralSettings = () => {
|
||||
displayName: data?.username !== user?.email ? data?.username : '',
|
||||
email: data?.email?.includes('@') ? data.email : '',
|
||||
locale: data?.locale,
|
||||
mediaLocale: data?.mediaLocale,
|
||||
discoverRegion: data?.discoverRegion,
|
||||
streamingRegion: data?.streamingRegion,
|
||||
originalLanguage: data?.originalLanguage,
|
||||
@@ -171,6 +173,7 @@ const UserGeneralSettings = () => {
|
||||
email:
|
||||
values.email || user?.jellyfinUsername || user?.plexUsername,
|
||||
locale: values.locale,
|
||||
mediaLocale: values.mediaLocale,
|
||||
discoverRegion: values.discoverRegion,
|
||||
streamingRegion: values.streamingRegion,
|
||||
originalLanguage: values.originalLanguage,
|
||||
@@ -362,6 +365,36 @@ const UserGeneralSettings = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<label htmlFor="mediaLocale" className="text-label">
|
||||
{intl.formatMessage(messages.mediaLanguage)}
|
||||
</label>
|
||||
<div className="form-input-area">
|
||||
<div className="form-input-field">
|
||||
<Field as="select" id="mediaLocale" name="mediaLocale">
|
||||
<option value="" lang={locale}>
|
||||
{intl.formatMessage(messages.languageDefault, {
|
||||
language:
|
||||
availableLanguages[currentSettings.locale].display,
|
||||
})}
|
||||
</option>
|
||||
{(
|
||||
Object.keys(
|
||||
availableLanguages
|
||||
) as (keyof typeof availableLanguages)[]
|
||||
).map((key) => (
|
||||
<option
|
||||
key={key}
|
||||
value={availableLanguages[key].code}
|
||||
lang={availableLanguages[key].code}
|
||||
>
|
||||
{availableLanguages[key].display}
|
||||
</option>
|
||||
))}
|
||||
</Field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<label htmlFor="discoverRegion" className="text-label">
|
||||
<span>{intl.formatMessage(messages.discoverRegion)}</span>
|
||||
|
||||
@@ -33,6 +33,7 @@ export interface UserSettings {
|
||||
streamingRegion?: string;
|
||||
originalLanguage?: string;
|
||||
locale?: string;
|
||||
mediaLocale?: string;
|
||||
notificationTypes: Partial<NotificationAgentTypes>;
|
||||
watchlistSyncMovies?: boolean;
|
||||
watchlistSyncTv?: boolean;
|
||||
|
||||
@@ -1464,6 +1464,7 @@
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.generalsettings": "General Settings",
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.languageDefault": "Default ({language})",
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.localuser": "Local User",
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.mediaLanguage": "Media Language",
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.mediaServerUser": "{mediaServerName} User",
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.movierequestlimit": "Movie Request Limit",
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.originallanguage": "Discover Language",
|
||||
|
||||
Reference in New Issue
Block a user