Compare commits

..

263 Commits

Author SHA1 Message Date
renovate[bot]
daa1d342ab Update dependency dotnet-ef to v9.0.12 2026-01-14 20:47:42 +00:00
Bond-009
6a7600a8c6 Merge pull request #16002 from jellyfin/renovate/ci-deps
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Update CI dependencies
2026-01-14 21:46:53 +01:00
renovate[bot]
0892847c2f Update CI dependencies 2026-01-14 03:34:32 +00:00
Samuvel Paul
62e51fd00a Translated using Weblate (Malayalam)
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/ml/
2026-01-10 14:36:47 +00:00
theguymadmax
cf9051c277 Backport pull request #15961 from jellyfin/release-10.11.z
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Fix crash when plugin repository has an invalid URL

Original-merge: 317a3a47c3

Merged-by: Bond-009 <bond.009@outlook.com>

Backported-by: Bond_009 <bond.009@outlook.com>
2026-01-10 06:11:27 -05:00
theguymadmax
d270957c82 Backport pull request #15950 from jellyfin/release-10.11.z
Revert "always sort season by index number"

Original-merge: 32d2414de0

Merged-by: Bond-009 <bond.009@outlook.com>

Backported-by: Bond_009 <bond.009@outlook.com>
2026-01-10 06:11:26 -05:00
theguymadmax
0ee872999d Backport pull request #15931 from jellyfin/release-10.11.z
Fix tag inheritance for Continue Watching queries

Original-merge: 559e0088e5

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2026-01-10 06:11:25 -05:00
SilentSkies
c4f4dcc181 Translated using Weblate (Welsh)
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/cy/
2026-01-09 23:05:26 +00:00
SilentSkies
22ee5113d0 Translated using Weblate (Welsh)
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/cy/
2026-01-09 22:22:37 +00:00
SilentSkies
e233eee07b Translated using Weblate (Welsh)
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/cy/
2026-01-09 22:16:00 +00:00
Bond-009
185849b68a Merge pull request #15956 from ZeusCraft10/fix/issue-15945-unknown-type-deserialization
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
fix: Handle unknown item types gracefully in DeserializeBaseItem
2026-01-09 18:40:59 +01:00
Bond-009
e62b6f8339 Merge pull request #15959 from nyanmisaka/truehd-dts-hls-codec-string
Add TrueHD and DTS codes string for HLS
2026-01-09 18:34:48 +01:00
Bond-009
9931537d87 Merge pull request #15958 from ZeusCraft10/fix/cryptography-provider-missing-iterations
Fix KeyNotFoundException in CryptographyProvider when iterations parameter is missing
2026-01-09 18:30:27 +01:00
Bond-009
82c4df5cde Merge pull request #15963 from jellyfin/renovate/z440.atl.core-7.x
Update dependency z440.atl.core to 7.10.0
2026-01-09 18:26:26 +01:00
renovate[bot]
103f556c8d Update dependency z440.atl.core to 7.10.0 2026-01-06 18:48:42 +00:00
nyanmisaka
582a1d9866 Add TrueHD and DTS codes string for HLS
Signed-off-by: nyanmisaka <nst799610810@gmail.com>
2026-01-06 23:15:06 +08:00
ZeusCraft10
244757c92c Fix KeyNotFoundException in CryptographyProvider.Verify
When a password hash is missing the 'iterations' parameter, Verify now
throws a descriptive FormatException instead of KeyNotFoundException.

- Extract GetIterationsParameter() helper method to avoid code duplication
- Provide distinct error messages for missing vs invalid parameters
- Add comprehensive unit tests for CryptographyProvider
2026-01-05 23:03:22 -05:00
ZeusCraft10
0ff869dfcd fix: Handle unknown item types gracefully in DeserializeBaseItem
When querying items with recursive=true, items with types from removed
plugins would cause a 500 error. Now these items are skipped with a
warning log instead of throwing an exception.

Fixes #15945
2026-01-05 21:08:26 -05:00
Niels van Velzen
a1e0e4fd9d Merge pull request #15888 from Shadowghost/fix-api-diff
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Fix API diff workflow
2026-01-05 17:22:50 +01:00
Dzmitry Zubialevich
4138214ac3 Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/be/
2026-01-05 13:51:28 +00:00
Shadowghost
8a1129bbde Use new repoository and lock to commit 2026-01-05 12:19:26 +01:00
Bond-009
706a8d2850 Merge pull request #14990 from jellyfin/renovate/metabrainz.musicbrainz-7.x
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
Update dependency MetaBrainz.MusicBrainz to v7
2026-01-03 12:11:44 +01:00
Bond-009
ba4dbcf5a1 Merge pull request #15916 from stevenaw/optimize-tofirstupper
Optimize `StringHelper.FirstToUpper()`
2026-01-03 12:04:19 +01:00
Dzmitry Zubialevich
bfae788a44 Translated using Weblate (Belarusian)
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/be/
2026-01-02 11:39:26 +00:00
Shadowghost
18dc32d735 Fix OpenAPI diff workflow 2026-01-02 10:07:45 +01:00
Shadowghost
85ff708597 Format workflows 2026-01-02 10:07:45 +01:00
Tim Eisele
23b48a0d0f Upgrade Swashbuckle and fix OpenAPI spec (#15886)
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
2026-01-01 18:46:51 -07:00
Peaches_MLG
d1055b0b36 Fixed issue with ABI Compatability - Difference not completing (#15924) 2026-01-01 18:46:17 -07:00
stevenaw
e5fb071708 Optimize StringHelper.ToFirstUpper() 2025-12-31 09:26:31 -05:00
SamuWhale
d28ee6d714 Translated using Weblate (Thai)
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/th/
2025-12-29 17:50:10 +00:00
MrPlow
2f62a8bb39 Translated using Weblate (German)
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/de/
2025-12-29 17:50:10 +00:00
Joker
75f1276119 Translated using Weblate (German)
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/de/
2025-12-29 11:04:35 +00:00
Bond_009
6c8395ff87 Fix build 2025-12-29 10:06:22 +01:00
Bond_009
82b2e7773f Pass cancellation token to GetReleaseGroupResultAsync 2025-12-29 10:05:46 +01:00
renovate[bot]
336958318d Update dependency MetaBrainz.MusicBrainz to v7 2025-12-29 09:00:33 +00:00
Bond-009
8a8f7956ef Merge pull request #15878 from jellyfin/renovate/xunit.skippablefact-1.x
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Update dependency Xunit.SkippableFact to 1.5.61
2025-12-28 13:23:48 +01:00
Collin-Swish
c728e97bda Backport pull request #15858 from jellyfin/release-10.11.z
Fix playlist item de-duplication

Original-merge: 78e3702cb0

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:38 -05:00
gnattu
5c76dd26bc Backport pull request #15835 from jellyfin/release-10.11.z
Use hvc1 codectag for Dolby Vision 8.4

Original-merge: 18096e48e0

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:37 -05:00
nyanmisaka
7af5ee1812 Backport pull request #15834 from jellyfin/release-10.11.z
Fix video lacking SAR and DAR are marked as anamorphic

Original-merge: 9470439cfa

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:36 -05:00
nyanmisaka
7f0e71578d Backport pull request #15833 from jellyfin/release-10.11.z
Fix missing H.264 and AV1 SDR fallbacks in HLS playlist

Original-merge: 01b20d3b75

Merged-by: Bond-009 <bond.009@outlook.com>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:34 -05:00
cvium
45e881c93e Backport pull request #15826 from jellyfin/release-10.11.z
add CultureDto cache

Original-merge: 1805f2259f

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:33 -05:00
nyanmisaka
b429306f05 Backport pull request #15819 from jellyfin/release-10.11.z
Fix the use of HWA in unsupported H.264 Hi422P/Hi444PP

Original-merge: 4c587776d6

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:32 -05:00
gnattu
88acd51ee2 Backport pull request #15807 from jellyfin/release-10.11.z
Enforce more strict webm check

Original-merge: 8379b4634a

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:31 -05:00
Shadowghost
3c802a7505 Backport pull request #15793 from jellyfin/release-10.11.z
Prefer US rating on fallback

Original-merge: 156761405e

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:30 -05:00
theguymadmax
928a8458dd Backport pull request #15786 from jellyfin/release-10.11.z
Fix parental rating filtering with sub-scores

Original-merge: 5804d6840c

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:28 -05:00
nyanmisaka
43797fee42 Backport pull request #15776 from jellyfin/release-10.11.z
Fix AV1 decoding hang regression on RK3588

Original-merge: 035b5895b0

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:27 -05:00
theguymadmax
b9158c467a Backport pull request #15768 from jellyfin/release-10.11.z
Fix NullReferenceException in ApplyOrder method

Original-merge: b617c62f8e

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:26 -05:00
theguymadmax
252ab45473 Backport pull request #15767 from jellyfin/release-10.11.z
Fix collections display order

Original-merge: 22da5187c8

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:25 -05:00
theguymadmax
afc083e9fa Backport pull request #15766 from jellyfin/release-10.11.z
Fix backdrop images being deleted when stored with media

Original-merge: 12c5d6b636

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:24 -05:00
theguymadmax
f867ce3842 Backport pull request #15757 from jellyfin/release-10.11.z
Fix trickplay images using wrong item on alternate versions

Original-merge: 481ee03f35

Merged-by: Bond-009 <bond.009@outlook.com>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:23 -05:00
Collin-Swish
2a464c316d Backport pull request #15752 from jellyfin/release-10.11.z
Fix case sensitivity edge case

Original-merge: b50ce1ad6b

Merged-by: Bond-009 <bond.009@outlook.com>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:21 -05:00
Shadowghost
b9cf26db2f Backport pull request #15746 from jellyfin/release-10.11.z
Skip invalid ignore rules

Original-merge: 6e60634c9f

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:20 -05:00
myzhysz
580585846b Backport pull request #15698 from jellyfin/release-10.11.z
Fix stack overflow during scan (#15000)

Original-merge: dde70fd8a2

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:19 -05:00
martenumberto
1af1c72e81 Backport pull request #15690 from jellyfin/release-10.11.z
Fix: Add .ts fallback for video streams to prevent crash

Original-merge: 2a0b90e385

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:18 -05:00
gnattu
5557004375 Backport pull request #15689 from jellyfin/release-10.11.z
Use original name for MusicAritist matching

Original-merge: 4c5a3fbff3

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:17 -05:00
ivanjx
5d50ff5f81 Backport pull request #15681 from jellyfin/release-10.11.z
Fix symlinked file size

Original-merge: d32f487e8e

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:15 -05:00
theguymadmax
8e2ed40a8b Backport pull request #15680 from jellyfin/release-10.11.z
Fix ItemAdded event triggering when updating metadata

Original-merge: fb65f8f853

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:14 -05:00
andrewrabert
8461268837 Backport pull request #15666 from jellyfin/release-10.11.z
Fix unnecessary database JOINs in ApplyNavigations

Original-merge: 4cdd8c8233

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:13 -05:00
SapientGuardian
8a0b963d2c Backport pull request #15662 from jellyfin/release-10.11.z
Fix blocking in async context in LimitedConcurrencyLibraryScheduler

Original-merge: d91adb5d54

Merged-by: Bond-009 <bond.009@outlook.com>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:12 -05:00
liszto
24acd94015 Backport pull request #15659 from jellyfin/release-10.11.z
Fix thumbnails never deletes from temp folder ( issue #15629 )

Original-merge: 636908fc4d

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-28 07:22:11 -05:00
MrPlow
c30654c33c Translated using Weblate (German)
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/de/
2025-12-28 01:44:02 +00:00
renovate[bot]
7bafd13564 Update dependency Xunit.SkippableFact to 1.5.61 2025-12-27 18:48:03 +00:00
Translation expert
0e73a56a45 Translated using Weblate (Arabic)
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/ar/
2025-12-26 01:04:36 +00:00
Bond-009
f9fec33048 Merge pull request #15797 from Smeagolworms4/fix-get-metadata-editor-info
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Fix GET MetadataEditor ContentTypeOptions for mixed content
2025-12-24 10:28:58 +01:00
Bond-009
934a9c9e32 Merge pull request #15831 from allmazz/upd-contributors
Add myself to CONTRIBUTORS.md
2025-12-24 10:26:02 +01:00
Bond-009
25115e95aa Merge branch 'master' into upd-contributors 2025-12-24 10:25:54 +01:00
Björn Tenje Persson
84f66dd54e Fixed Multi Sort in New ActivityManager (#15820)
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
2025-12-19 20:36:38 -07:00
Kityn
d446fde009 Translated using Weblate (Polish)
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/pl/
2025-12-19 06:55:08 +00:00
Fabrizio Mansilla
ee676fd568 Translated using Weblate (Spanish (Argentina))
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/es_AR/
2025-12-19 06:55:08 +00:00
Kirill Nikiforov
2cca942ce6 Add myself to CONTRIBUTORS.md 2025-12-18 22:56:33 +01:00
Michael
59d574edb7 Translated using Weblate (German)
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/de/
2025-12-17 22:15:03 +00:00
Bond-009
c170b18155 Merge pull request #15810 from jellyfin/renovate/ci-deps
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Update github/codeql-action action to v4.31.9
2025-12-17 18:08:51 +01:00
renovate[bot]
45a49a4fb4 Update github/codeql-action action to v4.31.9 2025-12-16 19:10:15 +00:00
João Moura
12a2f7c1a5 Translated using Weblate (Portuguese (Portugal))
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/pt_PT/
2025-12-16 18:22:40 +00:00
SmeagolWorms4
d0950c8f09 Fix GET MetadataEditor ContentTypeOptions for inheritedContentType 2025-12-15 23:11:01 +01:00
Joshua M. Boniface
ebf8220f1d Merge pull request #15798 from theguymadmax/10.11.5-template-version
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Update issue template version to 10.11.5
2025-12-15 09:59:51 -05:00
theguymadmax
c4e8180b3c Update issue template version to 10.11.5 2025-12-15 09:20:41 -05:00
Luigi311
771b0a7eab Library: Async the SaveImages function (#15718)
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
2025-12-13 08:43:49 -07:00
renovate[bot]
4db0ab0f40 Update GitHub Artifact Actions (#15783)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-13 08:42:57 -07:00
dkanada
dd480f96cd parse more information from book filenames (#15655)
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
2025-12-13 08:29:28 -07:00
Niels van Velzen
6b6d54a07c Remove legacy API route middleware (#15669) 2025-12-13 08:26:22 -07:00
Bond-009
428beda1c7 Merge pull request #15780 from jellyfin/renovate/ci-deps
Update github/codeql-action action to v4.31.8
2025-12-13 10:43:57 +01:00
Bond-009
baa8d40940 Merge pull request #15774 from stevenaw/optimize-GetUniqueFlags
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Optimize GetUniqueFlags<T>()
2025-12-12 18:00:25 +01:00
renovate[bot]
c8bdee26b7 Update github/codeql-action action to v4.31.8 2025-12-12 12:13:35 +00:00
stevenaw
ef73ed6ef7 optimize GetUniqueFlags() 2025-12-11 22:15:19 -05:00
Veldermon-rbg
d70e0fe9cf Translated using Weblate (Maori)
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/mi/
2025-12-10 05:20:53 +00:00
Veldermon-rbg
053cc9406d Added translation using Weblate (Maori) 2025-12-10 00:29:33 +00:00
Bas
0f85120c5e Translated using Weblate (Dutch)
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/nl/
2025-12-10 00:29:32 +00:00
Tom O'Neill
25aef7fabf Translated using Weblate (Dutch)
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/nl/
2025-12-10 00:29:32 +00:00
Mark Cilia Vincenti
492ea66841 Proper pinning of SkiaSharp to prevent accidental updates (#15736)
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
2025-12-08 21:16:14 -07:00
evan314159
8b2a8b94b6 avoid Take(0) when limit == 0 (#14608)
Co-authored-by: Evan <evan@MacBook-Pro.local>
2025-12-08 21:15:46 -07:00
xin
f24e80701c Fix typo in CheckOrCreateMarker exception (#15341) 2025-12-08 21:06:17 -07:00
Cody Robibero
0b3d6676d1 Add ability to sort and filter activity log entries (#15583) 2025-12-08 21:01:32 -07:00
Mark Cilia Vincenti
c3a8734adf Locking cleaning (#15713) 2025-12-08 21:01:12 -07:00
audrey-inglish
8fd59d6f33 Merge pull request #14879 from audrey-inglish/master
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Fix: normalize punctuation when computing CleanName so searches without punctuation match (closes #1674)
2025-12-08 18:43:37 +01:00
Bond-009
da3bff3edf Merge pull request #15433 from theguymadmax/fix-recently-added-shows
Fix episodes showing up on recently added shows
2025-12-08 18:38:50 +01:00
Bond-009
45cb5a0008 Merge pull request #15704 from theguymadmax/add-cpu-to-template
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Add CPU to issue template
2025-12-05 20:50:59 +01:00
Bond-009
ea097fb1a3 Merge pull request #15706 from jellyfin/renovate/ci-deps
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Update CI dependencies
2025-12-05 20:47:46 +01:00
renovate[bot]
a25b48b151 Update CI dependencies 2025-12-05 18:58:06 +00:00
Furqaan Dawood
873f1d9e83 Added translation using Weblate (Swahili)
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
2025-12-04 14:41:47 +00:00
Bond-009
294439bf74 Merge pull request #15682 from jellyfin/renovate/ci-deps
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Update CI dependencies
2025-12-03 20:05:29 +01:00
crobibero
6e74be0d46 Backport pull request #15672 from jellyfin/release-10.11.z
Cache OpenApi document generation

Original-merge: 8cd5652157

Merged-by: anthonylavado <anthony@lavado.ca>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-03 14:04:28 -05:00
nyanmisaka
deb81eae10 Backport pull request #15670 from jellyfin/release-10.11.z
Fix the empty output of trickplay on RK3576

Original-merge: 98d1d0cb35

Merged-by: nielsvanvelzen <nielsvanvelzen@users.noreply.github.com>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-03 14:04:27 -05:00
theguymadmax
70dcf3f7b3 Backport pull request #15594 from jellyfin/release-10.11.z
Fix isMovie filter logic

Original-merge: 94f3725208

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-03 14:04:25 -05:00
QuintonQu
ebcfed83c4 Backport pull request #15582 from jellyfin/release-10.11.z
Add hidden file check in BdInfoDirectoryInfo.cs.

Original-merge: 29b3aa8543

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-03 14:04:24 -05:00
theguymadmax
5d46278584 Backport pull request #15568 from jellyfin/release-10.11.z
Fix ResolveLinkTarget crashing on exFAT drives

Original-merge: fbb9a0b2c7

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-03 14:04:23 -05:00
theguymadmax
4f020a947a Backport pull request #15564 from jellyfin/release-10.11.z
Fix locked fields not saving

Original-merge: 0ee81e87be

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-03 14:04:22 -05:00
theguymadmax
3460d1de3c Backport pull request #15563 from jellyfin/release-10.11.z
Save item to database before providers run to prevent FK errors

Original-merge: c491a918c2

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-03 14:04:20 -05:00
gnattu
7d2e4cd817 Backport pull request #15557 from jellyfin/release-10.11.z
Restrict first video frame probing to file protocol

Original-merge: ee7ad83427

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-03 14:04:19 -05:00
gnattu
8cd6ef37c4 Backport pull request #15556 from jellyfin/release-10.11.z
Prevent copying HDR streams when only SDR is supported

Original-merge: 1e7e46cb82

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-03 14:04:18 -05:00
theguymadmax
e4daaf0d83 Backport pull request #15548 from jellyfin/release-10.11.z
Fix NullReferenceException in filesystem path comparison

Original-merge: 5ae444d96d

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-12-03 14:04:17 -05:00
theguymadmax
69c98af9f9 Add CPU to issue template 2025-12-03 09:45:50 -05:00
renovate[bot]
7425a493ee Update CI dependencies 2025-12-03 05:30:25 +00:00
Hasan Abdulaal
691c194152 Translated using Weblate (Arabic)
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/ar/
2025-12-02 13:27:39 +00:00
Niels van Velzen
2f8896c375 Merge pull request #15538 from KarkaLT/master
Add subtitle extraction timeout configuration option
2025-12-02 13:50:42 +01:00
Niels van Velzen
6c507b77ae Remove DtoExtensions.AddClientFields (#15638)
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
2025-11-30 07:22:54 -07:00
renovate[bot]
6ed0ccd37c Update appleboy/ssh-action action to v1.2.4 (#15660)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-30 07:15:08 -07:00
Martín
80e1e42947 Added translation using Weblate (Occitan)
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
2025-11-28 20:01:20 +00:00
Niels van Velzen
6ace00eb6a Merge pull request #15227 from kevgrig/issue15226
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Add milliseconds to default console output format
2025-11-27 16:33:38 +01:00
Niels van Velzen
a35ffbf17e Merge pull request #13977 from sususu98/fix/strm-local-subtitle-url
refactor(StreamInfo): reorganize subtitle URL logic and conditions
2025-11-27 16:33:19 +01:00
Niels van Velzen
8c02c3be93 Merge pull request #14824 from CodyEngel/fix-numeric-titles
Fix TV Series parsing containing only numbers.
2025-11-27 16:32:11 +01:00
Niels van Velzen
45669c9b30 Merge pull request #15437 from allmazz/feat/more_file_metadata_tags
Add support for more embedded metadata tags
2025-11-27 16:31:42 +01:00
Niels van Velzen
19c232809e Merge pull request #14950 from nielsvanvelzen/security-remove-has-password
Deprecate HasPassword property on UserDto
2025-11-27 16:31:05 +01:00
Niels van Velzen
301f65af48 Merge pull request #15559 from nielsvanvelzen/disable-legacy-auth
Disable legacy authorization methods by default
2025-11-27 16:30:45 +01:00
Bond-009
082ba58e51 Merge pull request #15630 from jellyfin/renovate/ci-deps
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Update CI dependencies
2025-11-25 18:30:46 +01:00
Bond-009
3b5bdc6bc2 Merge pull request #15246 from JPVenson/feature/AddVersionDisplayStartupUi
Add version to StartupUI
2025-11-25 18:30:27 +01:00
Bond-009
b05e91dba1 Merge pull request #15614 from jellyfin/renovate/polly-monorepo
Update dependency Polly to 8.6.5
2025-11-25 18:26:41 +01:00
renovate[bot]
c7703242e5 Update CI dependencies 2025-11-25 06:39:50 +00:00
Bond-009
21042ad0c2 Merge pull request #15626 from jellyfin/renovate/ci-deps
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Update github/codeql-action action to v4.31.5
2025-11-24 19:16:42 +01:00
renovate[bot]
8904551a59 Update github/codeql-action action to v4.31.5 2025-11-24 11:12:00 +00:00
renovate[bot]
cf1ef22367 Update dependency Polly to 8.6.5 2025-11-23 14:03:55 +00:00
rimasx
c08e81c52b Translated using Weblate (Estonian)
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/et/
2025-11-23 10:43:48 +00:00
Bond-009
23e66ae1ea Merge pull request #15607 from jellyfin/renovate/z440.atl.core-7.x
Update dependency z440.atl.core to 7.9.0
2025-11-23 10:22:43 +01:00
renovate[bot]
37bbdf3fe7 Update dependency z440.atl.core to 7.9.0 2025-11-22 15:15:12 +00:00
Bond-009
f124223015 Merge pull request #15591 from jellyfin/renovate/actions-checkout-6.x
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Update actions/checkout action to v6
2025-11-22 10:22:11 +01:00
Bond-009
9587a9b13c Merge pull request #15566 from jellyfin/renovate/ci-deps
Update github/codeql-action action to v4.31.4
2025-11-22 10:20:48 +01:00
Niels van Velzen
67c67df507 Use async migration 2025-11-20 22:11:55 +01:00
renovate[bot]
569f8cfcfc Update actions/checkout action to v6 2025-11-20 18:58:53 +00:00
Anthony Lavado
aa4ddd139a Add all 10.11 versions to issue template (#15565)
Some checks failed
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
2025-11-18 21:05:43 -05:00
renovate[bot]
8ac97f5471 Update github/codeql-action action to v4.31.4 2025-11-19 01:37:24 +00:00
Bond-009
efabfbc931 Merge pull request #15542 from jellyfin/renovate/ci-deps
Update actions/checkout action to v5.0.1
2025-11-18 22:04:58 +01:00
Bond-009
6b5dc115e8 Merge pull request #15478 from jellyfin/renovate/microsoft
Update Microsoft
2025-11-18 22:01:56 +01:00
Bond-009
2dc0af667e Merge pull request #15477 from jellyfin/renovate/dotnet-monorepo
Update dependency dotnet-ef to v9.0.11
2025-11-18 22:01:49 +01:00
Niels van Velzen
196c243a7d Disable legacy authorization methods by default 2025-11-18 16:17:04 +01:00
Rufis72
55dbff8f30 Translated using Weblate (English (Pirate))
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/en@pirate/
2025-11-18 08:19:02 +00:00
theguymadmax
2af43e0131 Backport pull request #15529 from jellyfin/release-10.11.z
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Fix movie titles using folder name when NFO saver is enabled

Original-merge: f8e012582a

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:09:14 -05:00
theguymadmax
faf1cea63e Backport pull request #15514 from jellyfin/release-10.11.z
Add 1 minute tolerance for NFO change detection

Original-merge: 6566188e45

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:09:13 -05:00
theguymadmax
7e25089c08 Backport pull request #15508 from jellyfin/release-10.11.z
Fix playlist DateCreated and DateLastMediaAdded not being set

Original-merge: 078f9584ed

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:09:12 -05:00
Iksas
8fa36a38e2 Backport pull request #15502 from jellyfin/release-10.11.z
Fix font extraction for certain transcoding settings

Original-merge: ee34c75386

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:09:10 -05:00
theguymadmax
5b3f29946b Backport pull request #15501 from jellyfin/release-10.11.z
Fix .ignore handling for directories

Original-merge: e8150428b6

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:09:09 -05:00
theguymadmax
c869b5b884 Backport pull request #15493 from jellyfin/release-10.11.z
Remove InheritedTags and update tag filtering logic

Original-merge: 4b38e35bbb

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:09:08 -05:00
CBPJ
a08b6ac266 Backport pull request #15487 from jellyfin/release-10.11.z
Fix gitignore-style not working properly on windows.

Original-merge: 435bb14bb2

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:09:07 -05:00
theguymadmax
4e68a5a078 Backport pull request #15472 from jellyfin/release-10.11.z
Fix series DateLastMediaAdded not updating when new episodes are added

Original-merge: abfbaca336

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:09:06 -05:00
Bond-009
99c68ddd50 Backport pull request #15468 from jellyfin/release-10.11.z
Check if target exists before trying to follow it

Original-merge: 5878b1ffc5

Merged-by: joshuaboniface <joshua@boniface.me>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:09:05 -05:00
Bond-009
d7f628677e Backport pull request #15466 from jellyfin/release-10.11.z
Don't error out when searching for marker files fails

Original-merge: f4a846aa4d

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:09:03 -05:00
theguymadmax
e51680cf56 Backport pull request #15462 from jellyfin/release-10.11.z
Fix NullReferenceException in GetPathProtocol when path is null

Original-merge: 7c1063177f

Merged-by: joshuaboniface <joshua@boniface.me>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:09:02 -05:00
theguymadmax
2e7d7752e9 Backport pull request #15446 from jellyfin/release-10.11.z
Fix AncestorIds not migrating

Original-merge: 177b6464ca

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:09:01 -05:00
IceStormNG
26ac2ccd74 Backport pull request #15441 from jellyfin/release-10.11.z
Fix System.NullReferenceException when people's role is null (10.11.z)

Original-merge: 5a9a8363f4

Merged-by: Bond-009 <bond.009@outlook.com>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:08:59 -05:00
theguymadmax
de9e653b73 Backport pull request #15435 from jellyfin/release-10.11.z
Fix search terms using diacritics

Original-merge: 63a3e55297

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:08:58 -05:00
theguymadmax
e34e7a1d0b Backport pull request #15423 from jellyfin/release-10.11.z
Invalidate parent folder's cache on deletion/creation

Original-merge: 49efd68fc7

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:08:57 -05:00
nielsvanvelzen
5a30f108fe Backport pull request #15422 from jellyfin/release-10.11.z
Update branding in Swagger page

Original-merge: d140630208

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:08:56 -05:00
JPVenson
74c9629372 Backport pull request #15413 from jellyfin/release-10.11.z
Fixed missing sort argument

Original-merge: 91c3b1617e

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:08:55 -05:00
theguymadmax
6c5f448787 Backport pull request #15404 from jellyfin/release-10.11.z
Improve season folder parsing

Original-merge: 2e5ced5098

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:08:54 -05:00
Bond-009
f848b8f12c Backport pull request #15390 from jellyfin/release-10.11.z
Don't enforce a minimum amount of free space for the tmp and log dirs

Original-merge: 097cb87f6f

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:08:53 -05:00
theguymadmax
bcec5f2e44 Backport pull request #15381 from jellyfin/release-10.11.z
Fix name filters to use only SortName

Original-merge: 7222910b05

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:08:51 -05:00
theguymadmax
7d05c875f3 Backport pull request #15380 from jellyfin/release-10.11.z
Fix item count display for collapsed items

Original-merge: 8f71922734

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:08:50 -05:00
theguymadmax
c805c5e2b1 Backport pull request #15373 from jellyfin/release-10.11.z
Fix collection grouping in mixed libraries

Original-merge: 13c4517a66

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:08:49 -05:00
evanreichard
c2c4c0adbf Backport pull request #15369 from jellyfin/release-10.11.z
feat(sqlite): add timeout config

Original-merge: c2e5081d64

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:08:48 -05:00
revam
5ea3910af9 Backport pull request #15263 from jellyfin/release-10.11.z
Resolve symlinks for static media source infos

Original-merge: 3b2d64995a

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:08:47 -05:00
theguymadmax
06fb300cff Backport pull request #14955 from jellyfin/release-10.11.z
Fix tmdbid not detected in single movie folder

Original-merge: def5956cd1

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-11-17 14:08:45 -05:00
renovate[bot]
626ab7e00a Update actions/checkout action to v5.0.1 2025-11-17 18:40:00 +00:00
Bond-009
1d140645b0 Merge pull request #15528 from jellyfin/renovate/z440.atl.core-7.x
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Update dependency z440.atl.core to 7.8.0
2025-11-17 19:38:20 +01:00
Karolis
5182aec13f Add subtitle extraction timeout configuration option 2025-11-17 15:18:29 +02:00
renovate[bot]
52f0c3dd24 Update dependency z440.atl.core to 7.8.0 2025-11-16 17:53:55 +00:00
Bond-009
b8327dbc9f Merge pull request #15480 from jellyfin/renovate/ci-deps
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Update CI dependencies
2025-11-16 18:52:54 +01:00
hoanghuy309
d1722936c0 Translated using Weblate (Vietnamese)
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/vi/
2025-11-15 06:48:18 +00:00
renovate[bot]
931240a3f5 Update CI dependencies 2025-11-14 01:24:06 +00:00
Grant Alexander
b216a27bfc Translated using Weblate (English (Pirate))
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/en@pirate/
2025-11-12 23:22:20 +00:00
renovate[bot]
8471a67bcd Update Microsoft 2025-11-11 18:42:18 +00:00
renovate[bot]
b8a409195f Update dependency dotnet-ef to v9.0.11 2025-11-11 18:42:10 +00:00
Bond-009
1da67e5e10 Merge pull request #15450 from jellyfin/renovate/fscheck.xunit-3.x
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Update dependency FsCheck.Xunit to 3.3.2
2025-11-09 19:39:59 +01:00
Bond-009
ed1ec7ca6b Merge pull request #15448 from jellyfin/renovate/z440.atl.core-7.x
Update dependency z440.atl.core to 7.7.0
2025-11-09 17:57:55 +01:00
renovate[bot]
3d7a68beb1 Update dependency FsCheck.Xunit to 3.3.2 2025-11-09 15:40:14 +00:00
renovate[bot]
32fc57cf17 Update dependency z440.atl.core to 7.7.0 2025-11-09 10:59:00 +00:00
Bond-009
0598c6eaf6 Merge pull request #15438 from jellyfin/renovate/ci-deps
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Update appleboy/ssh-action action to v1.2.3
2025-11-08 17:17:52 +01:00
Andrew
0d7b687da0 Update Jellyfin Server version in issue template (#15398) 2025-11-08 08:30:30 -07:00
renovate[bot]
e69754fd3a Update appleboy/ssh-action action to v1.2.3 2025-11-08 04:18:07 +00:00
Kirill Nikiforov
ac81ddd39a add support for more embedded metadata tags 2025-11-08 02:54:53 +04:00
theguymadmax
217ea488df Fix episode showing up on recently added shows 2025-11-07 09:39:23 -05:00
Diogo Coelho
f693c9d39f Translated using Weblate (Portuguese (Portugal))
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/pt_PT/
2025-11-06 11:37:15 +00:00
Bond-009
96d72788a1 Merge pull request #15312 from jellyfin/renovate/ci-deps
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Update github/codeql-action action to v4.31.2
2025-11-04 21:07:02 +01:00
Bond-009
0d74a95bb8 Merge pull request #15348 from jellyfin/renovate/serilog.sinks.console-6.x
Update dependency Serilog.Sinks.Console to 6.1.1
2025-11-04 21:05:17 +01:00
evanreichard
a7d039b7c6 Backport pull request #15328 from jellyfin/release-10.11.z
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
fix: in optimistic locking, key off table is locked

Original-merge: b5f0199a25

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2025-11-02 21:58:46 -05:00
Shadowghost
87b02b1316 Backport pull request #15326 from jellyfin/release-10.11.z
Skip too large extracted season numbers

Original-merge: e7dbb3afec

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2025-11-02 21:58:45 -05:00
vinnyspb
871de372ff Backport pull request #15325 from jellyfin/release-10.11.z
Update file size when refreshing metadata

Original-merge: f994dd6211

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2025-11-02 21:58:44 -05:00
crobibero
c9d93b0745 Backport pull request #15322 from jellyfin/release-10.11.z
Fix legacy migration file checks

Original-merge: da254ee968

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2025-11-02 21:58:43 -05:00
thornbill
1ccd10863e Backport pull request #15254 from jellyfin/release-10.11.z
Update password reset to always return the same response structure

Original-merge: 4ad3141875

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2025-11-02 21:58:42 -05:00
nyanmisaka
4258df4485 Backport pull request #15247 from jellyfin/release-10.11.z
Ignore initial delay in audio-only containers

Original-merge: 6bf88c049e

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2025-11-02 21:58:41 -05:00
renovate[bot]
63f06aad94 Update dependency Serilog.Sinks.Console to 6.1.1 2025-11-02 23:14:23 +00:00
Jacky He
ffe82be7a7 Translated using Weblate (Chinese (Traditional Han script, Hong Kong))
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/zh_Hant_HK/
2025-10-31 23:39:28 +00:00
Jacky He
23929a3e70 Translated using Weblate (Chinese (Traditional Han script, Hong Kong))
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/zh_Hant_HK/
2025-10-30 19:34:52 +00:00
renovate[bot]
83d0dbdbcb Update github/codeql-action action to v4.31.2 2025-10-30 18:35:55 +00:00
Battseren Badral
573ce9ceaa Translated using Weblate (Mongolian)
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/mn/
2025-10-29 22:47:08 +00:00
Jacky He
f21fe9f95e Translated using Weblate (Chinese (Traditional Han script, Hong Kong))
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/zh_Hant_HK/
2025-10-29 22:47:08 +00:00
Battseren Badral
f92eca3efb Translated using Weblate (Mongolian)
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/mn/
2025-10-29 00:03:00 +00:00
Pascal Wiesmann
7d778d7bef Translated using Weblate (Alemannic)
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/gsw/
2025-10-28 09:23:31 +00:00
JJBlue
21f65e2e27 Backport pull request #15220 from jellyfin/release-10.11.z
Some checks failed
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Skip extracted files in migration if bad timestamp or no access

Original-merge: a305204cfa

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:31 -04:00
theguymadmax
28b0657608 Backport pull request #15217 from jellyfin/release-10.11.z
Normalize paths in database queries

Original-merge: 75f472e6a7

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:30 -04:00
crobibero
a489942454 Backport pull request #15212 from jellyfin/release-10.11.z
Skip invalid database migration

Original-merge: 2966d27c97

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:29 -04:00
Shadowghost
423c2654c0 Backport pull request #15209 from jellyfin/release-10.11.z
Improve symlink handling

Original-merge: e5656af1f2

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:27 -04:00
crobibero
4dc826644d Backport pull request #15197 from jellyfin/release-10.11.z
Filter plugins by id instead of name

Original-merge: 5691eee4f1

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:26 -04:00
crobibero
0f21222a0c Backport pull request #15196 from jellyfin/release-10.11.z
Skip directory entry when restoring from backup

Original-merge: 0e4031ae52

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:25 -04:00
crobibero
570b8b2eb9 Backport pull request #15194 from jellyfin/release-10.11.z
Initialize transcode marker during startup

Original-merge: 81b8b0ca4a

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:24 -04:00
Shadowghost
08fd175f5a Backport pull request #15187 from jellyfin/release-10.11.z
Fix pagination and sorting for folders

Original-merge: 7d1824ea27

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:23 -04:00
gnattu
511b5d9c53 Backport pull request #15177 from jellyfin/release-10.11.z
Make priority class setting more robust

Original-merge: 70c32a26fa

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:22 -04:00
CeruleanRed
6514196e8d Backport pull request #15176 from jellyfin/release-10.11.z
Only save chapters that are within the runtime of the video file

Original-merge: 442af96ed9

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:21 -04:00
crobibero
ed6cb30762 Backport pull request #15170 from jellyfin/release-10.11.z
Clean up BackupService

Original-merge: ac3fa3c376

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:20 -04:00
crobibero
232c0399e2 Backport pull request #15164 from jellyfin/release-10.11.z
Fix XmlOutputFormatter

Original-merge: 2b94bb54aa

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:19 -04:00
nyanmisaka
dbb015441f Backport pull request #15144 from jellyfin/release-10.11.z
Fix videos with cropping metadata are probed as anamorphic

Original-merge: 175ee12bbc

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:18 -04:00
theguymadmax
4c1c160990 Backport pull request #15133 from jellyfin/release-10.11.z
Play selected song first with instant mix

Original-merge: 1520a697ad

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:17 -04:00
MBR-0001
0931d6e4de Backport pull request #15126 from jellyfin/release-10.11.z
Fix Has(Imdb/Tmdb/Tvdb)Id checks

Original-merge: 14b3085ff1

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:15 -04:00
ivanjx
3f2ebc4179 Backport pull request #15113 from jellyfin/release-10.11.z
Add season number fallback for OMDB and TMDB plugins

Original-merge: 618ec4543e

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:14 -04:00
Shadowghost
14e8194581 Backport pull request #15112 from jellyfin/release-10.11.z
Skip extracted files in migration if bad timestamp or no access

Original-merge: 7a1c1cd342

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:13 -04:00
theguymadmax
3c4dc16003 Backport pull request #15102 from jellyfin/release-10.11.z
Make season paths case-insensitive

Original-merge: 305b0fdca3

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:12 -04:00
Bond-009
54d28d9842 Backport pull request #15098 from jellyfin/release-10.11.z
Lower required tmp dir size to 512MiB

Original-merge: 0a6e8146be

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:11 -04:00
theguymadmax
adfa520057 Backport pull request #15087 from jellyfin/release-10.11.z
Optimize WhereReferencedItemMultipleTypes filtering

Original-merge: a5bc4524d8

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:10 -04:00
theguymadmax
5deb69b23f Backport pull request #15083 from jellyfin/release-10.11.z
Fix LiveTV images not saving to database

Original-merge: d738386fe2

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:09 -04:00
nyanmisaka
348b2992d7 Backport pull request #15072 from jellyfin/release-10.11.z
Reject stream copy of HDR10+ video if the client does not support HDR10

Original-merge: a725220c21

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:08 -04:00
gnattu
9f8fb6d588 Backport pull request #15055 from jellyfin/release-10.11.z
Log the message more clear when network manager is not ready

Original-merge: a245605152

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:07 -04:00
Shadowghost
cee16d47cb Backport pull request #15054 from jellyfin/release-10.11.z
Speed-up trickplay migration

Original-merge: ca830d5be7

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:06 -04:00
Shadowghost
9e53f46ad2 Backport pull request #15032 from jellyfin/release-10.11.z
Skip invalid keyframe cache data

Original-merge: f4a53209f4

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Bond_009 <bond.009@outlook.com>
2025-10-27 15:43:04 -04:00
Joshua M. Boniface
53dfcae1a6 Merge pull request #15236 from joshuaboniface/codeowners
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Update CODEOWNERS to capture bump_version
2025-10-27 09:10:47 -04:00
JPVenson
81f1cc78b2 Add version to StartupUI 2025-10-27 13:01:52 +00:00
kreaxv
efd659412f Translated using Weblate (Mongolian)
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/mn/
2025-10-27 09:41:00 +00:00
Joshua M. Boniface
c31ea251c4 Improve handling of .github dir 2025-10-26 22:17:33 -04:00
Joshua M. Boniface
285e7c6c4f Update CODEOWNERS to capture bump_version 2025-10-26 22:07:46 -04:00
Joshua M. Boniface
c274336563 Bump version to 10.12.0 (for real this time)
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
2025-10-26 21:52:03 -04:00
Joshua M. Boniface
d5fd5dfe6a Fix bump_version to handle spaced filename 2025-10-26 21:51:41 -04:00
Kevin G
42ddcfa565 Add milliseconds to default console output format
Signed-off-by: Kevin G <kevin@myplaceonline.com>
2025-10-26 10:29:29 -05:00
Bond-009
6fa69f9fe5 Merge pull request #15206 from jellyfin/renovate/ci-deps
Some checks failed
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Update danielpalme/ReportGenerator-GitHub-Action action to v5.4.18
2025-10-26 14:50:42 +01:00
Bond-009
0b876365a1 Merge pull request #15205 from jellyfin/renovate/z440.atl.core-7.x
Update dependency z440.atl.core to 7.6.0
2025-10-26 14:39:09 +01:00
Battseren Badral
cdc8325c7b Translated using Weblate (Mongolian)
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/mn/
2025-10-25 21:55:13 +00:00
renovate[bot]
a6a8e29916 Update danielpalme/ReportGenerator-GitHub-Action action to v5.4.18 2025-10-25 15:32:59 +00:00
renovate[bot]
6fd3847298 Update dependency z440.atl.core to 7.6.0 2025-10-25 15:12:02 +00:00
Bond-009
3ff516a430 Merge pull request #15191 from jellyfin/renovate/ci-deps
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Update github/codeql-action action to v4.31.0
2025-10-25 11:23:34 +02:00
Bond-009
d8591840f3 Merge pull request #15192 from jellyfin/renovate/major-github-artifact-actions
Update GitHub Artifact Actions (major)
2025-10-25 11:22:40 +02:00
HanHwanHo
c5affbbf71 Translated using Weblate (Korean)
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/ko/
2025-10-25 07:46:36 +00:00
renovate[bot]
788f090f27 Update GitHub Artifact Actions 2025-10-24 23:59:16 +00:00
renovate[bot]
0e3b6652b3 Update github/codeql-action action to v4.31.0 2025-10-24 23:59:06 +00:00
desibooklover
d167d59c23 Translated using Weblate (Punjabi)
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/pa/
2025-10-23 03:50:04 +00:00
desibooklover
f58b4860f7 Translated using Weblate (Hindi)
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/hi/
2025-10-23 03:50:04 +00:00
Grant Alexander
96b7fc0ac0 Translated using Weblate (Spanish (Mexico))
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/es_MX/
2025-10-21 15:20:51 +00:00
oddife
c8ad861590 Translated using Weblate (Marathi)
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/mr/
2025-10-20 21:27:58 +00:00
Jellyfin Release Bot
1a1a24cfff Bump version to 10.12.0
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
2025-10-19 20:45:13 -04:00
Niels van Velzen
d43db230fa Add back UpdateUserPassword_Empty_RemoveSetPassword test 2025-10-19 09:45:55 +02:00
Niels van Velzen
0fb6d930e1 Deprecate HasPassword property on UserDto 2025-10-05 11:10:36 +02:00
Cody Engel
2508e8349b update summary docs
Signed-off-by: Cody Engel <cengel815@gmail.com>
2025-09-23 08:22:00 -06:00
Cody Engel
bd9a44ce7d remove explicit ‘-‘ support in series name 2025-09-20 18:00:44 -06:00
Cody Engel
da31d0c6a6 support series that are numeric only
updates SeriesResolver to handle series names that only contain numbers such as 1923.
2025-09-20 14:04:00 -06:00
sususu98
aebabb1580 style: fix return statement indentation in StreamInfo.cs 2025-04-24 14:25:12 +08:00
sususu98
d5402718b7 Merge branch 'jellyfin:master' into fix/strm-local-subtitle-url 2025-04-24 14:18:17 +08:00
sususu98
fd108ff528 Style: Fix indentation in StreamInfo.cs 2025-04-24 14:17:33 +08:00
sususu98
22ce1f25d0 refactor(StreamInfo): reorganize subtitle URL logic and conditions
# Conflicts:
#	MediaBrowser.Model/Dlna/StreamInfo.cs
2025-04-23 18:18:38 +08:00
126 changed files with 1910 additions and 871 deletions

View File

@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "9.0.11",
"version": "9.0.12",
"commands": [
"dotnet-ef"
]

15
.github/CODEOWNERS vendored
View File

@@ -1,4 +1,11 @@
# Joshua must review all changes to deployment and build.sh
.ci/* @joshuaboniface
deployment/* @joshuaboniface
build.sh @joshuaboniface
# Joshua must review all changes to bump_version and any files it touches
bump_version @joshuaboniface
.github/ISSUE_TEMPLATE @joshuaboniface
MediaBrowser.Common/MediaBrowser.Common.csproj @joshuaboniface
Jellyfin.Data/Jellyfin.Data.csproj @joshuaboniface
MediaBrowser.Controller/MediaBrowser.Controller.csproj @joshuaboniface
MediaBrowser.Model/MediaBrowser.Model.csproj @joshuaboniface
Emby.Naming/Emby.Naming.csproj @joshuaboniface
src/Jellyfin.Extensions/Jellyfin.Extensions.csproj @joshuaboniface
# Core must approve all changes within the repo config
.github/ @jellyfin/core

View File

@@ -87,7 +87,12 @@ body:
label: Jellyfin Server version
description: What version of Jellyfin are you using?
options:
- 10.10.0+
- 10.11.5
- 10.11.4
- 10.11.3
- 10.11.2
- 10.11.1
- 10.11.0
- Master
- Unstable
- Older*
@@ -136,13 +141,14 @@ body:
- **FFmpeg Version**: [e.g. 5.1.2-Jellyfin]
- **Playback**: [Direct Play, Remux, Direct Stream, Transcode]
- **Hardware Acceleration**: [e.g. none, VAAPI, NVENC, etc.]
- **CPU Model**: [e.g. AMD Ryzen 5 9600X, Intel Core i7-8565U, etc.]
- **GPU Model**: [e.g. none, UHD630, GTX1050, etc.]
- **Installed Plugins**: [e.g. none, Fanart, Anime, etc.]
- **Reverse Proxy**: [e.g. none, nginx, apache, etc.]
- **Base URL**: [e.g. none, yes: /example]
- **Networking**: [e.g. Host, Bridge/NAT]
- **Jellyfin Data Storage**: [e.g. local SATA SSD, local HDD]
- **Media Storage**: [e.g. Local HDD, SMB Share]
- **Jellyfin Data Storage & Filesystem**: [e.g. local SATA SSD - ext4, local HDD - NTFS]
- **Media Storage & Filesystem**: [e.g. Local HDD - ext4, SMB Share]
- **External Integrations**: [e.g. Jellystat, Jellyseerr]
value: |
- OS:
@@ -153,13 +159,14 @@ body:
- FFmpeg Version:
- Playback Method:
- Hardware Acceleration:
- CPU Model:
- GPU Model:
- Plugins:
- Reverse Proxy:
- Base URL:
- Networking:
- Jellyfin Data Storage:
- Media Storage:
- Jellyfin Data Storage & Filesystem:
- Media Storage & Filesystem:
- External Integrations:
render: markdown
validations:

View File

@@ -21,17 +21,20 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Setup .NET
uses: actions/setup-dotnet@2016bd2012dba4e32de620c46fe006a3ac9f0602 # v5.0.1
uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5.1.0
with:
dotnet-version: '9.0.x'
- name: Initialize CodeQL
uses: github/codeql-action/init@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6
uses: github/codeql-action/init@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
with:
languages: ${{ matrix.language }}
queries: +security-extended
- name: Autobuild
uses: github/codeql-action/autobuild@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6
uses: github/codeql-action/autobuild@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6
uses: github/codeql-action/analyze@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10

View File

@@ -17,7 +17,7 @@ jobs:
repository: ${{ github.event.pull_request.head.repo.full_name }}
- name: Setup .NET
uses: actions/setup-dotnet@2016bd2012dba4e32de620c46fe006a3ac9f0602 # v5.0.1
uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5.1.0
with:
dotnet-version: '9.0.x'
@@ -26,7 +26,7 @@ jobs:
dotnet build Jellyfin.Server -o ./out
- name: Upload Head
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: abi-head
retention-days: 14
@@ -47,7 +47,7 @@ jobs:
fetch-depth: 0
- name: Setup .NET
uses: actions/setup-dotnet@2016bd2012dba4e32de620c46fe006a3ac9f0602 # v5.0.1
uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5.1.0
with:
dotnet-version: '9.0.x'
@@ -65,7 +65,7 @@ jobs:
dotnet build Jellyfin.Server -o ./out
- name: Upload Head
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: abi-base
retention-days: 14
@@ -85,13 +85,13 @@ jobs:
steps:
- name: Download abi-head
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: abi-head
path: abi-head
- name: Download abi-base
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: abi-base
path: abi-base
@@ -106,7 +106,7 @@ jobs:
{
echo 'body<<EOF'
for file in Jellyfin.Data.dll MediaBrowser.Common.dll MediaBrowser.Controller.dll MediaBrowser.Model.dll Emby.Naming.dll Jellyfin.Extensions.dll Jellyfin.MediaEncoding.Keyframes.dll Jellyfin.Database.Implementations.dll; do
COMPAT_OUTPUT="$( { apicompat --left ./abi-base/${file} --right ./abi-head/${file}; } 2>&1 )"
COMPAT_OUTPUT="$( { apicompat --left ./abi-base/${file} --right ./abi-head/${file}; } 2>&1 || true )"
if [ "APICompat ran successfully without finding any breaking changes." != "${COMPAT_OUTPUT}" ]; then
printf "\n${file}\n${COMPAT_OUTPUT}\n"
fi

View File

@@ -20,14 +20,17 @@ jobs:
with:
ref: ${{ github.event.pull_request.head.sha }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
- name: Setup .NET
uses: actions/setup-dotnet@2016bd2012dba4e32de620c46fe006a3ac9f0602 # v5.0.1
uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5.1.0
with:
dotnet-version: '9.0.x'
- name: Generate openapi.json
run: dotnet test tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj -c Release --filter "Jellyfin.Server.Integration.Tests.OpenApiSpecTests"
- name: Upload openapi.json
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: openapi-head
retention-days: 14
@@ -46,6 +49,7 @@ jobs:
ref: ${{ github.event.pull_request.head.sha }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
fetch-depth: 0
- name: Checkout common ancestor
env:
HEAD_REF: ${{ github.head_ref }}
@@ -54,14 +58,17 @@ jobs:
git -c protocol.version=2 fetch --prune --progress --no-recurse-submodules upstream +refs/heads/*:refs/remotes/upstream/* +refs/tags/*:refs/tags/*
ANCESTOR_REF=$(git merge-base upstream/${{ github.base_ref }} origin/$HEAD_REF)
git checkout --progress --force $ANCESTOR_REF
- name: Setup .NET
uses: actions/setup-dotnet@2016bd2012dba4e32de620c46fe006a3ac9f0602 # v5.0.1
uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5.1.0
with:
dotnet-version: '9.0.x'
- name: Generate openapi.json
run: dotnet test tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj -c Release --filter "Jellyfin.Server.Integration.Tests.OpenApiSpecTests"
- name: Upload openapi.json
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: openapi-base
retention-days: 14
@@ -70,7 +77,7 @@ jobs:
openapi-diff:
permissions:
pull-requests: write # to create or update comment (peter-evans/create-or-update-comment)
pull-requests: write
name: OpenAPI - Difference
if: ${{ github.event_name == 'pull_request_target' }}
@@ -80,71 +87,27 @@ jobs:
- openapi-base
steps:
- name: Download openapi-head
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: openapi-head
path: openapi-head
- name: Download openapi-base
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: openapi-base
path: openapi-base
- name: Workaround openapi-diff issue
run: |
sed -i 's/"allOf"/"oneOf"/g' openapi-head/openapi.json
sed -i 's/"allOf"/"oneOf"/g' openapi-base/openapi.json
- name: Calculate OpenAPI difference
uses: docker://openapitools/openapi-diff
continue-on-error: true
with:
args: --fail-on-changed --markdown openapi-changes.md openapi-base/openapi.json openapi-head/openapi.json
- id: read-diff
name: Read openapi-diff output
run: |
# Read and fix markdown
body=$(cat openapi-changes.md)
# Write to workflow summary
echo "$body" >> $GITHUB_STEP_SUMMARY
# Set ApiChanged var
if [ "$body" != '' ]; then
echo "ApiChanged=1" >> "$GITHUB_OUTPUT"
else
echo "ApiChanged=0" >> "$GITHUB_OUTPUT"
fi
# Add header/footer for diff comment
echo '<!--openapi-diff-workflow-comment-->' > openapi-changes-reply.md
echo "<details>" >> openapi-changes-reply.md
echo "<summary>Changes in OpenAPI specification found. Expand to see details.</summary>" >> openapi-changes-reply.md
echo "" >> openapi-changes-reply.md
echo "$body" >> openapi-changes-reply.md
echo "" >> openapi-changes-reply.md
echo "</details>" >> openapi-changes-reply.md
- name: Find difference comment
uses: peter-evans/find-comment@b30e6a3c0ed37e7c023ccd3f1db5c6c0b0c23aad # v4.0.0
id: find-comment
with:
issue-number: ${{ github.event.pull_request.number }}
direction: last
body-includes: openapi-diff-workflow-comment
- name: Reply or edit difference comment (changed)
uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0
if: ${{ steps.read-diff.outputs.ApiChanged == '1' }}
with:
issue-number: ${{ github.event.pull_request.number }}
comment-id: ${{ steps.find-comment.outputs.comment-id }}
edit-mode: replace
body-path: openapi-changes-reply.md
- name: Edit difference comment (unchanged)
uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0
if: ${{ steps.read-diff.outputs.ApiChanged == '0' && steps.find-comment.outputs.comment-id != '' }}
with:
issue-number: ${{ github.event.pull_request.number }}
comment-id: ${{ steps.find-comment.outputs.comment-id }}
edit-mode: replace
body: |
<!--openapi-diff-workflow-comment-->
No changes to OpenAPI specification found. See history of this comment for previous changes.
- name: Detect OpenAPI changes
id: openapi-diff
uses: jellyfin/openapi-diff-action@9274f6bda9d01ab091942a4a8334baa53692e8a4 # v1.0.0
with:
old-spec: openapi-base/openapi.json
new-spec: openapi-head/openapi.json
markdown: openapi-changelog.md
add-pr-comment: true
github-token: ${{ secrets.GITHUB_TOKEN }}
publish-unstable:
name: OpenAPI - Publish Unstable Spec
@@ -158,7 +121,7 @@ jobs:
run: |-
echo "JELLYFIN_VERSION=$(date +'%Y%m%d%H%M%S')" >> $GITHUB_ENV
- name: Download openapi-head
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: openapi-head
path: openapi-head
@@ -178,7 +141,6 @@ jobs:
username: "${{ secrets.REPO_USER }}"
key: "${{ secrets.REPO_KEY }}"
debug: false
script_stop: false
script: |
if ! test -d /run/workflows; then
sudo mkdir -p /run/workflows
@@ -220,7 +182,7 @@ jobs:
run: |-
echo "JELLYFIN_VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
- name: Download openapi-head
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: openapi-head
path: openapi-head
@@ -240,7 +202,6 @@ jobs:
username: "${{ secrets.REPO_USER }}"
key: "${{ secrets.REPO_KEY }}"
debug: false
script_stop: false
script: |
if ! test -d /run/workflows; then
sudo mkdir -p /run/workflows

View File

@@ -22,7 +22,7 @@ jobs:
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/setup-dotnet@2016bd2012dba4e32de620c46fe006a3ac9f0602 # v5.0.1
- uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5.1.0
with:
dotnet-version: ${{ env.SDK_VERSION }}

View File

@@ -43,13 +43,16 @@ jobs:
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
repository: jellyfin/jellyfin-triage-script
- name: install python
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: '3.14'
cache: 'pip'
- name: install python packages
run: pip install -r rename/requirements.txt
- name: run rename script
run: python3 rename.py
working-directory: ./rename

View File

@@ -13,13 +13,16 @@ jobs:
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
repository: jellyfin/jellyfin-triage-script
- name: install python
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: '3.14'
cache: 'pip'
- name: install python packages
run: pip install -r main-repo-triage/requirements.txt
- name: check and comment issue
working-directory: ./main-repo-triage
run: python3 single_issue_gha.py

View File

@@ -21,6 +21,7 @@ jobs:
with:
project: Current Release
action: delete
column: In progress
repo-token: ${{ secrets.JF_BOT_TOKEN }}
- name: Add to 'Release Next' project

View File

@@ -206,7 +206,10 @@
- [theshoeshiner](https://github.com/theshoeshiner)
- [TokerX](https://github.com/TokerX)
- [GeneMarks](https://github.com/GeneMarks)
- [Kirill Nikiforov](https://github.com/allmazz)
- [bjorntp](https://github.com/bjorntp)
- [martenumberto](https://github.com/martenumberto)
- [ZeusCraft10](https://github.com/ZeusCraft10)
# Emby Contributors

View File

@@ -25,7 +25,7 @@
<PackageVersion Include="Jellyfin.XmlTv" Version="10.8.0" />
<PackageVersion Include="libse" Version="4.0.12" />
<PackageVersion Include="LrcParser" Version="2025.623.0" />
<PackageVersion Include="MetaBrainz.MusicBrainz" Version="6.1.0" />
<PackageVersion Include="MetaBrainz.MusicBrainz" Version="7.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="9.0.11" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.11" />
<PackageVersion Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="4.14.0" />
@@ -74,26 +74,26 @@
<PackageVersion Include="SerilogAnalyzer" Version="0.15.0" />
<PackageVersion Include="SharpFuzz" Version="2.2.0" />
<!-- Pinned to 3.116.1 because https://github.com/jellyfin/jellyfin/pull/14255 -->
<PackageVersion Include="SkiaSharp" Version="3.116.1" />
<PackageVersion Include="SkiaSharp.HarfBuzz" Version="3.116.1" />
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="3.116.1" />
<PackageVersion Include="SkiaSharp" Version="[3.116.1]" />
<PackageVersion Include="SkiaSharp.HarfBuzz" Version="[3.116.1]" />
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="[3.116.1]" />
<PackageVersion Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" />
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />
<PackageVersion Include="Svg.Skia" Version="3.2.1" />
<PackageVersion Include="Swashbuckle.AspNetCore.ReDoc" Version="6.5.0" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.2.3" />
<PackageVersion Include="Swashbuckle.AspNetCore.ReDoc" Version="6.9.0" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.9.0" />
<PackageVersion Include="System.Globalization" Version="4.3.0" />
<PackageVersion Include="System.Linq.Async" Version="6.0.3" />
<PackageVersion Include="System.Text.Encoding.CodePages" Version="9.0.11" />
<PackageVersion Include="System.Text.Json" Version="9.0.11" />
<PackageVersion Include="System.Threading.Tasks.Dataflow" Version="9.0.11" />
<PackageVersion Include="TagLibSharp" Version="2.3.0" />
<PackageVersion Include="z440.atl.core" Version="7.9.0" />
<PackageVersion Include="z440.atl.core" Version="7.10.0" />
<PackageVersion Include="TMDbLib" Version="2.3.0" />
<PackageVersion Include="UTF.Unknown" Version="2.6.0" />
<PackageVersion Include="Xunit.Priority" Version="1.1.6" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
<PackageVersion Include="Xunit.SkippableFact" Version="1.5.23" />
<PackageVersion Include="Xunit.SkippableFact" Version="1.5.61" />
<PackageVersion Include="xunit" Version="2.9.3" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,75 @@
using System.Text.RegularExpressions;
namespace Emby.Naming.Book
{
/// <summary>
/// Helper class to retrieve basic metadata from a book filename.
/// </summary>
public static class BookFileNameParser
{
private const string NameMatchGroup = "name";
private const string IndexMatchGroup = "index";
private const string YearMatchGroup = "year";
private const string SeriesNameMatchGroup = "seriesName";
private static readonly Regex[] _nameMatches =
[
// seriesName (seriesYear) #index (of count) (year) where only seriesName and index are required
new Regex(@"^(?<seriesName>.+?)((\s\((?<seriesYear>[0-9]{4})\))?)\s#(?<index>[0-9]+)((\s\(of\s(?<count>[0-9]+)\))?)((\s\((?<year>[0-9]{4})\))?)$"),
new Regex(@"^(?<name>.+?)\s\((?<seriesName>.+?),\s#(?<index>[0-9]+)\)((\s\((?<year>[0-9]{4})\))?)$"),
new Regex(@"^(?<index>[0-9]+)\s\-\s(?<name>.+?)((\s\((?<year>[0-9]{4})\))?)$"),
new Regex(@"(?<name>.*)\((?<year>[0-9]{4})\)"),
// last resort matches the whole string as the name
new Regex(@"(?<name>.*)")
];
/// <summary>
/// Parse a filename name to retrieve the book name, series name, index, and year.
/// </summary>
/// <param name="name">Book filename to parse for information.</param>
/// <returns>Returns <see cref="BookFileNameParserResult"/> object.</returns>
public static BookFileNameParserResult Parse(string? name)
{
var result = new BookFileNameParserResult();
if (name == null)
{
return result;
}
foreach (var regex in _nameMatches)
{
var match = regex.Match(name);
if (!match.Success)
{
continue;
}
if (match.Groups.TryGetValue(NameMatchGroup, out Group? nameGroup) && nameGroup.Success)
{
result.Name = nameGroup.Value.Trim();
}
if (match.Groups.TryGetValue(IndexMatchGroup, out Group? indexGroup) && indexGroup.Success && int.TryParse(indexGroup.Value, out var index))
{
result.Index = index;
}
if (match.Groups.TryGetValue(YearMatchGroup, out Group? yearGroup) && yearGroup.Success && int.TryParse(yearGroup.Value, out var year))
{
result.Year = year;
}
if (match.Groups.TryGetValue(SeriesNameMatchGroup, out Group? seriesGroup) && seriesGroup.Success)
{
result.SeriesName = seriesGroup.Value.Trim();
}
break;
}
return result;
}
}
}

View File

@@ -0,0 +1,41 @@
using System;
namespace Emby.Naming.Book
{
/// <summary>
/// Data object used to pass metadata parsed from a book filename.
/// </summary>
public class BookFileNameParserResult
{
/// <summary>
/// Initializes a new instance of the <see cref="BookFileNameParserResult"/> class.
/// </summary>
public BookFileNameParserResult()
{
Name = null;
Index = null;
Year = null;
SeriesName = null;
}
/// <summary>
/// Gets or sets the name of the book.
/// </summary>
public string? Name { get; set; }
/// <summary>
/// Gets or sets the book index.
/// </summary>
public int? Index { get; set; }
/// <summary>
/// Gets or sets the publication year.
/// </summary>
public int? Year { get; set; }
/// <summary>
/// Gets or sets the series name.
/// </summary>
public string? SeriesName { get; set; }
}
}

View File

@@ -36,7 +36,7 @@
<PropertyGroup>
<Authors>Jellyfin Contributors</Authors>
<PackageId>Jellyfin.Naming</PackageId>
<VersionPrefix>10.11.4</VersionPrefix>
<VersionPrefix>10.12.0</VersionPrefix>
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
</PropertyGroup>

View File

@@ -17,6 +17,13 @@ namespace Emby.Naming.TV
[GeneratedRegex(@"((?<a>[^\._]{2,})[\._]*)|([\._](?<b>[^\._]{2,}))")]
private static partial Regex SeriesNameRegex();
/// <summary>
/// Regex that matches titles with year in parentheses. Captures the title (which may be
/// numeric) before the year, i.e. turns "1923 (2022)" into "1923".
/// </summary>
[GeneratedRegex(@"(?<title>.+?)\s*\(\d{4}\)")]
private static partial Regex TitleWithYearRegex();
/// <summary>
/// Resolve information about series from path.
/// </summary>
@@ -27,6 +34,20 @@ namespace Emby.Naming.TV
{
string seriesName = Path.GetFileName(path);
// First check if the filename matches a title with year pattern (handles numeric titles)
if (!string.IsNullOrEmpty(seriesName))
{
var titleWithYearMatch = TitleWithYearRegex().Match(seriesName);
if (titleWithYearMatch.Success)
{
seriesName = titleWithYearMatch.Groups["title"].Value.Trim();
return new SeriesInfo(path)
{
Name = seriesName
};
}
}
SeriesPathParserResult result = SeriesPathParser.Parse(options, path);
if (result.Success)
{

View File

@@ -39,22 +39,24 @@ namespace Emby.Server.Implementations.Cryptography
{
if (string.Equals(hash.Id, "PBKDF2", StringComparison.Ordinal))
{
var iterations = GetIterationsParameter(hash);
return hash.Hash.SequenceEqual(
Rfc2898DeriveBytes.Pbkdf2(
password,
hash.Salt,
int.Parse(hash.Parameters["iterations"], CultureInfo.InvariantCulture),
iterations,
HashAlgorithmName.SHA1,
32));
}
if (string.Equals(hash.Id, "PBKDF2-SHA512", StringComparison.Ordinal))
{
var iterations = GetIterationsParameter(hash);
return hash.Hash.SequenceEqual(
Rfc2898DeriveBytes.Pbkdf2(
password,
hash.Salt,
int.Parse(hash.Parameters["iterations"], CultureInfo.InvariantCulture),
iterations,
HashAlgorithmName.SHA512,
DefaultOutputLength));
}
@@ -62,6 +64,27 @@ namespace Emby.Server.Implementations.Cryptography
throw new NotSupportedException($"Can't verify hash with id: {hash.Id}");
}
/// <summary>
/// Extracts and validates the iterations parameter from a password hash.
/// </summary>
/// <param name="hash">The password hash containing parameters.</param>
/// <returns>The number of iterations.</returns>
/// <exception cref="FormatException">Thrown when iterations parameter is missing or invalid.</exception>
private static int GetIterationsParameter(PasswordHash hash)
{
if (!hash.Parameters.TryGetValue("iterations", out var iterationsStr))
{
throw new FormatException($"Password hash with id '{hash.Id}' is missing required 'iterations' parameter.");
}
if (!int.TryParse(iterationsStr, CultureInfo.InvariantCulture, out var iterations))
{
throw new FormatException($"Password hash with id '{hash.Id}' has invalid 'iterations' parameter: '{iterationsStr}'.");
}
return iterations;
}
/// <inheritdoc />
public byte[] GenerateSalt()
=> GenerateSalt(DefaultSaltLength);

View File

@@ -2144,7 +2144,7 @@ namespace Emby.Server.Implementations.Library
item.ValidateImages();
_itemRepository.SaveImages(item);
await _itemRepository.SaveImagesAsync(item).ConfigureAwait(false);
RegisterItem(item);
}

View File

@@ -5,12 +5,12 @@
using System;
using System.IO;
using System.Linq;
using Emby.Naming.Book;
using Jellyfin.Data.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities;
namespace Emby.Server.Implementations.Library.Resolvers.Books
{
@@ -35,17 +35,22 @@ namespace Emby.Server.Implementations.Library.Resolvers.Books
var extension = Path.GetExtension(args.Path.AsSpan());
if (_validExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase))
if (!_validExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase))
{
// It's a book
return new Book
{
Path = args.Path,
IsInMixedFolder = true
};
return null;
}
return null;
var result = BookFileNameParser.Parse(Path.GetFileNameWithoutExtension(args.Path));
return new Book
{
Path = args.Path,
Name = result.Name ?? string.Empty,
IndexNumber = result.Index,
ProductionYear = result.Year,
SeriesName = result.SeriesName ?? Path.GetFileName(Path.GetDirectoryName(args.Path)),
IsInMixedFolder = true,
};
}
private Book GetBook(ItemResolveArgs args)
@@ -59,15 +64,22 @@ namespace Emby.Server.Implementations.Library.Resolvers.Books
StringComparison.OrdinalIgnoreCase);
}).ToList();
// Don't return a Book if there is more (or less) than one document in the directory
// directory is only considered a book when it contains exactly one supported file
// other library structures with multiple books to a directory will get picked up as individual files
if (bookFiles.Count != 1)
{
return null;
}
var result = BookFileNameParser.Parse(Path.GetFileName(args.Path));
return new Book
{
Path = bookFiles[0].FullName
Path = bookFiles[0].FullName,
Name = result.Name ?? string.Empty,
IndexNumber = result.Index,
ProductionYear = result.Year,
SeriesName = result.SeriesName ?? string.Empty,
};
}
}

View File

@@ -42,7 +42,7 @@ namespace Emby.Server.Implementations.Library
results = results.GetRange(query.StartIndex.Value, totalRecordCount - query.StartIndex.Value);
}
if (query.Limit.HasValue)
if (query.Limit.HasValue && query.Limit.Value > 0)
{
results = results.GetRange(0, Math.Min(query.Limit.Value, results.Count));
}

View File

@@ -2,13 +2,13 @@
"Albums": "ألبومات",
"AppDeviceValues": "تطبيق: {0}, جهاز: {1}",
"Application": "تطبيق",
"Artists": "الفنانون",
"Artists": "فنانون",
"AuthenticationSucceededWithUserName": "نجحت عملية التوثيق بـ {0}",
"Books": "الكتب",
"CameraImageUploadedFrom": "رُفعت صورة الكاميرا الجديدة من {0}",
"Channels": "القنوات",
"ChapterNameValue": "الفصل {0}",
"Collections": "المجموعات",
"Collections": "مجموعات",
"DeviceOfflineWithName": "قُطِع الاتصال ب{0}",
"DeviceOnlineWithName": "{0} متصل",
"FailedLoginAttemptWithUserName": "محاولة تسجيل الدخول فاشلة من {0}",
@@ -16,7 +16,7 @@
"Folders": "المجلدات",
"Genres": "التصنيفات",
"HeaderAlbumArtists": "فناني الألبوم",
"HeaderContinueWatching": "إستئناف المشاهدة",
"HeaderContinueWatching": "متابعة المشاهدة",
"HeaderFavoriteAlbums": "الألبومات المفضلة",
"HeaderFavoriteArtists": "الفنانون المفضلون",
"HeaderFavoriteEpisodes": "الحلقات المفضلة",

View File

@@ -16,7 +16,7 @@
"Collections": "Калекцыі",
"Default": "Па змаўчанні",
"FailedLoginAttemptWithUserName": "Няўдалая спроба ўваходу з {0}",
"Folders": "Тэчкі",
"Folders": "Папкі",
"Favorites": "Абранае",
"External": "Знешні",
"Genres": "Жанры",
@@ -95,7 +95,7 @@
"ServerNameNeedsToBeRestarted": "{0} патрабуе перазапуску",
"Shows": "Шоу",
"StartupEmbyServerIsLoading": "Jellyfin Server загружаецца. Калі ласка, паўтарыце спробу крыху пазней.",
"SubtitleDownloadFailureFromForItem": "Не атрымалася спампаваць субтытры з {0} для {1}",
"SubtitleDownloadFailureFromForItem": "Субцітры для {1} не ўдалося спампаваць з {0}",
"TvShows": "Тэлепраграма",
"Undefined": "Нявызначана",
"UserLockedOutWithName": "Карыстальнік {0} быў заблакіраваны",
@@ -104,7 +104,7 @@
"UserStartedPlayingItemWithValues": "{0} прайграваецца {1} на {2}",
"UserStoppedPlayingItemWithValues": "{0} скончыў прайграванне {1} на {2}",
"ValueHasBeenAddedToLibrary": "{0} быў дададзены ў вашу медыятэку",
"ValueSpecialEpisodeName": "Спецэпізод - {0}",
"ValueSpecialEpisodeName": "Спецвыпуск - {0}",
"VersionNumber": "Версія {0}",
"TasksMaintenanceCategory": "Абслугоўванне",
"TasksLibraryCategory": "Бібліятэка",
@@ -114,7 +114,7 @@
"TaskCleanCacheDescription": "Выдаляе файлы кэша, якія больш не патрэбныя сістэме.",
"TaskRefreshChapterImages": "Вынуць выявы раздзелаў",
"TaskRefreshLibrary": "Сканаваць бібліятэку",
"TaskRefreshLibraryDescription": "Скануе вашу медыятэку на наяўнасць новых файлаў і абнаўляе метададзеныя.",
"TaskRefreshLibraryDescription": "Сканіруе вашу медыятэку на наяўнасць новых файлаў і абнаўляе метаданыя.",
"TaskCleanLogs": "Ачысціць журнал",
"TaskRefreshPeople": "Абнавіць выканаўцаў",
"TaskRefreshPeopleDescription": "Абнаўленне метаданых для акцёраў і рэжысёраў у вашай медыятэцы.",
@@ -137,5 +137,5 @@
"TaskExtractMediaSegments": "Сканіраванне медыя-сегмента",
"TaskMoveTrickplayImages": "Перанесці месцазнаходжанне выявы Trickplay",
"CleanupUserDataTask": "Задача па ачыстцы дадзеных карыстальніка",
"CleanupUserDataTaskDescription": "Ачысьціць усе дадзеныя карыстальніка (стан прагляду, абранае і г.д.) для медыяфайлаў, што адсутнічаюць больш за 90 дзён."
"CleanupUserDataTaskDescription": "Ачышчае ўсе даныя карыстальніка (стан прагляду, абранае і г.д.) для медыяфайлаў, што адсутнічаюць больш за 90 дзён."
}

View File

@@ -8,7 +8,7 @@
"CameraImageUploadedFrom": "Mae delwedd camera newydd wedi'i lanlwytho o {0}",
"Books": "Llyfrau",
"AuthenticationSucceededWithUserName": "{0} wedii ddilysun llwyddiannus",
"Artists": "Artistiaid",
"Artists": "Crewyr",
"AppDeviceValues": "Ap: {0}, Dyfais: {1}",
"Albums": "Albwmau",
"Genres": "Genres",
@@ -67,7 +67,7 @@
"NotificationOptionAudioPlayback": "Dechreuwyd chwarae sain",
"MessageServerConfigurationUpdated": "Mae gosodiadau gweinydd wedi'i ddiweddaru",
"MessageNamedServerConfigurationUpdatedWithValue": "Mae adran gosodiadau gweinydd {0} wedi'i diweddaru",
"FailedLoginAttemptWithUserName": "Cais mewngofnodi wedi methu gan {0}",
"FailedLoginAttemptWithUserName": "Cais mewngofnodi wedi methu o {0}",
"ValueHasBeenAddedToLibrary": "{0} wedi'i hychwanegu at eich llyfrgell gyfryngau",
"UserStoppedPlayingItemWithValues": "{0} wedi gorffen chwarae {1} ar {2}",
"UserStartedPlayingItemWithValues": "{0} yn chwarae {1} ar {2}",
@@ -123,5 +123,14 @@
"TaskRefreshChapterImages": "Echdynnu Lluniau Pennod",
"TaskCleanCacheDescription": "Dileu ffeiliau cache nad oes eu hangen ar y system mwyach.",
"TaskCleanCache": "Gwaghau Ffolder Cache",
"HearingImpaired": "Nam ar y clyw"
"HearingImpaired": "Nam ar y clyw",
"TaskAudioNormalization": "Gwastatau Sain",
"TaskAudioNormalizationDescription": "Yn sganio ffeiliau am ddata gwastatau sain.",
"TaskRefreshTrickplayImages": "Creuwch lluniau Trickplay",
"TaskRefreshTrickplayImagesDescription": "Creu rhagolygon Trickplay ar gyfer fideos mewn llyfrgelloedd gweithredol.",
"TaskDownloadMissingLyrics": "Lawrlwytho geiriau coll",
"TaskDownloadMissingLyricsDescription": "Lawrlwytho geiriau caneuon",
"TaskCleanCollectionsAndPlaylists": "Glanhau casgliadau a rhestrau chwarae",
"TaskCleanCollectionsAndPlaylistsDescription": "Dileu eitemau o gasgliadau a rhestrau chwarae sydd ddim yn bodoli bellach.",
"TaskExtractMediaSegments": "Sganio Darnau Cyfryngau"
}

View File

@@ -9,9 +9,9 @@
"Channels": "Kanäle",
"ChapterNameValue": "Kapitel {0}",
"Collections": "Sammlungen",
"DeviceOfflineWithName": "{0} hat die Verbindung getrennt",
"DeviceOnlineWithName": "{0} ist verbunden",
"FailedLoginAttemptWithUserName": "Fehlgeschlagener Anmeldeversuch von {0}",
"DeviceOfflineWithName": "{0} ist offline",
"DeviceOnlineWithName": "{0} ist online",
"FailedLoginAttemptWithUserName": "Anmeldung von {0} fehlgeschlagen",
"Favorites": "Favoriten",
"Folders": "Verzeichnisse",
"Genres": "Genres",
@@ -21,7 +21,7 @@
"HeaderFavoriteArtists": "Lieblingsinterpreten",
"HeaderFavoriteEpisodes": "Lieblingsepisoden",
"HeaderFavoriteShows": "Lieblingsserien",
"HeaderFavoriteSongs": "Lieblingslieder",
"HeaderFavoriteSongs": "Lieblingssongs",
"HeaderLiveTV": "Live TV",
"HeaderNextUp": "Als Nächstes",
"HeaderRecordingGroups": "Aufnahme-Gruppen",
@@ -46,7 +46,7 @@
"NewVersionIsAvailable": "Eine neue Jellyfin-Serverversion steht zum Download bereit.",
"NotificationOptionApplicationUpdateAvailable": "Anwendungsaktualisierung verfügbar",
"NotificationOptionApplicationUpdateInstalled": "Anwendungsaktualisierung installiert",
"NotificationOptionAudioPlayback": "Audiowiedergabe gestartet",
"NotificationOptionAudioPlayback": "Audio wird abgespielt",
"NotificationOptionAudioPlaybackStopped": "Audiowiedergabe gestoppt",
"NotificationOptionCameraImageUploaded": "Foto hochgeladen",
"NotificationOptionInstallationFailed": "Installation fehlgeschlagen",
@@ -57,8 +57,8 @@
"NotificationOptionPluginUpdateInstalled": "Pluginaktualisierung installiert",
"NotificationOptionServerRestartRequired": "Serverneustart notwendig",
"NotificationOptionTaskFailed": "Geplante Aufgabe fehlgeschlagen",
"NotificationOptionUserLockedOut": "Benutzer ausgeschlossen",
"NotificationOptionVideoPlayback": "Videowiedergabe gestartet",
"NotificationOptionUserLockedOut": "Benutzer gesperrt",
"NotificationOptionVideoPlayback": "Video wird abgespielt",
"NotificationOptionVideoPlaybackStopped": "Videowiedergabe gestoppt",
"Photos": "Fotos",
"Playlists": "Wiedergabelisten",
@@ -82,7 +82,7 @@
"UserCreatedWithName": "Benutzer {0} wurde erstellt",
"UserDeletedWithName": "Benutzer {0} wurde gelöscht",
"UserDownloadingItemWithValues": "{0} lädt {1} herunter",
"UserLockedOutWithName": "Benutzer {0} wurde ausgeschlossen",
"UserLockedOutWithName": "Benutzer {0} wurde gesperrt",
"UserOfflineFromDevice": "{0} wurde getrennt von {1}",
"UserOnlineFromDevice": "{0} ist online von {1}",
"UserPasswordChangedWithName": "Das Passwort für Benutzer {0} wurde geändert",
@@ -97,25 +97,25 @@
"TaskRefreshChannelsDescription": "Aktualisiert Internet-Kanal-Informationen.",
"TaskRefreshChannels": "Kanäle aktualisieren",
"TaskCleanTranscodeDescription": "Löscht Transkodierungsdateien, die älter als einen Tag sind.",
"TaskCleanTranscode": "Transkodierungs-Verzeichnis aufräumen",
"TaskCleanTranscode": "Transkodierungsverzeichnis leeren",
"TaskUpdatePluginsDescription": "Lädt Updates für Plugins herunter, welche für automatische Updates konfiguriert sind und installiert diese.",
"TaskUpdatePlugins": "Plugins aktualisieren",
"TaskRefreshPeopleDescription": "Aktualisiert Metadaten für Schauspieler und Regisseure in deinen Bibliotheken.",
"TaskRefreshPeople": "Personen aktualisieren",
"TaskCleanLogsDescription": "Lösche Log-Dateien, die älter als {0} Tage sind.",
"TaskCleanLogs": "Log-Verzeichnis aufräumen",
"TaskRefreshLibraryDescription": "Durchsucht alle Bibliotheken nach neu hinzugefügten Dateien und aktualisiert Metadaten.",
"TaskCleanLogs": "Protokollverzeichnis leeren",
"TaskRefreshLibraryDescription": "Durchsucht deine Medienbibliothek nach neuen Dateien und aktualisiert Metadaten.",
"TaskRefreshLibrary": "Medien-Bibliothek scannen",
"TaskRefreshChapterImagesDescription": "Erstellt Vorschaubilder für Videos, die Kapitel besitzen.",
"TaskRefreshChapterImages": "Kapitel-Bilder extrahieren",
"TaskCleanCacheDescription": "Löscht vom System nicht mehr benötigte Zwischenspeicherdateien.",
"TaskCleanCache": "Zwischenspeicher-Verzeichnis aufräumen",
"TaskRefreshChapterImagesDescription": "Erstellt Vorschaubilder für Videokapitel.",
"TaskRefreshChapterImages": "Kapitelvorschauen erstellen",
"TaskCleanCacheDescription": "Löscht Cache-Dateien, die vom System nicht mehr benötigt werden.",
"TaskCleanCache": "Cache-Verzeichnis leeren",
"TasksChannelsCategory": "Internet-Kanäle",
"TasksApplicationCategory": "Anwendung",
"TasksLibraryCategory": "Bibliothek",
"TasksMaintenanceCategory": "Wartung",
"TaskCleanActivityLogDescription": "Löscht Aktivitätsprotokolleinträge, die älter als das konfigurierte Alter sind.",
"TaskCleanActivityLog": "Aktivitätsprotokolle aufräumen",
"TaskCleanActivityLog": "Aktivitätsverlauf bereinigen",
"Undefined": "Undefiniert",
"Forced": "Erzwungen",
"Default": "Standard",

View File

@@ -70,7 +70,7 @@
"ScheduledTaskFailedWithName": "{0} falló",
"ScheduledTaskStartedWithName": "{0} iniciado",
"ServerNameNeedsToBeRestarted": "{0} necesita ser reiniciado",
"Shows": "Programas",
"Shows": "Series",
"Songs": "Canciones",
"StartupEmbyServerIsLoading": "El servidor Jellyfin se está cargando. Vuelve a intentarlo en breve.",
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",

View File

@@ -30,7 +30,7 @@
"ItemAddedWithName": "{0} fue agregado a la biblioteca",
"ItemRemovedWithName": "{0} fue removido de la biblioteca",
"LabelIpAddressValue": "Dirección IP: {0}",
"LabelRunningTimeValue": "Tiempo de reproducción: {0}",
"LabelRunningTimeValue": "Tiempo corriendo: {0}",
"Latest": "Recientes",
"MessageApplicationUpdated": "El servidor Jellyfin ha sido actualizado",
"MessageApplicationUpdatedTo": "El servidor Jellyfin ha sido actualizado a {0}",

View File

@@ -137,5 +137,5 @@
"TaskExtractMediaSegmentsDescription": "Eraldab või võtab meediasegmendid MediaSegment'i lubavatest pluginatest.",
"TaskMoveTrickplayImages": "Muuda trickplay piltide asukoht",
"CleanupUserDataTask": "Puhasta kasutajaandmed",
"CleanupUserDataTaskDescription": "Puhastab kõik kasutajaandmed (vaatamise olek, lemmikute olek jne) meediast, mis pole enam vähemalt 90 päeva saadaval olnud."
"CleanupUserDataTaskDescription": "Puhastab kõik kasutajaandmed (vaatamise olek, lemmikute olek jne) meediast, mida pole enam vähemalt 90 päeva saadaval olnud."
}

View File

@@ -11,7 +11,7 @@
"Collections": "Sammlungen",
"DeviceOfflineWithName": "{0} wurde getrennt",
"DeviceOnlineWithName": "{0} ist verbunden",
"FailedLoginAttemptWithUserName": "Fehlgeschlagener Anmeldeversuch von {0}",
"FailedLoginAttemptWithUserName": "Fählgschlagene Ameldeversuech vo {0}",
"Favorites": "Favorite",
"Folders": "Ordner",
"Genres": "Genre",

View File

@@ -129,5 +129,12 @@
"TaskAudioNormalization": "श्रव्य सामान्यीकरण",
"TaskAudioNormalizationDescription": "श्रव्य सामान्यीकरण के लिए फाइलें अन्वेषण करें",
"TaskDownloadMissingLyrics": "लापता गानों के बोल डाउनलोड करेँ",
"TaskDownloadMissingLyricsDescription": "गानों के बोल डाउनलोड करता है"
"TaskDownloadMissingLyricsDescription": "गानों के बोल डाउनलोड करता है",
"TaskExtractMediaSegments": "मीडिया सेगमेंट स्कैन",
"TaskExtractMediaSegmentsDescription": "मीडियासेगमेंट सक्षम प्लगइन्स से मीडिया सेगमेंट निकालता है या प्राप्त करता है।",
"TaskMoveTrickplayImages": "ट्रिकप्ले छवि स्थान माइग्रेट करें",
"TaskMoveTrickplayImagesDescription": "लाइब्रेरी सेटिंग्स के अनुसार मौजूदा ट्रिकप्ले फ़ाइलों को स्थानांतरित करता है।",
"TaskCleanCollectionsAndPlaylistsDescription": "संग्रहों और प्लेलिस्टों से उन आइटमों को हटाता है जो अब मौजूद नहीं हैं।",
"TaskCleanCollectionsAndPlaylists": "संग्रह और प्लेलिस्ट साफ़ करें",
"CleanupUserDataTask": "यूज़र डेटा की सफाई करता है।"
}

View File

@@ -136,5 +136,7 @@
"TaskMoveTrickplayImages": "트릭플레이 이미지 위치 마이그레이션",
"TaskMoveTrickplayImagesDescription": "추출된 트릭플레이 이미지를 라이브러리 설정에 따라 이동합니다.",
"TaskDownloadMissingLyrics": "누락된 가사 다운로드",
"TaskDownloadMissingLyricsDescription": "가사 다운로드"
"TaskDownloadMissingLyricsDescription": "가사 다운로드",
"CleanupUserDataTask": "사용자 데이터 정리 작업",
"CleanupUserDataTaskDescription": "최소 90일 이상 존재하지 않는 미디어에 대한 사용자 데이터(시청 상태, 즐겨찾기 등)를 정리합니다."
}

View File

@@ -0,0 +1,9 @@
{
"Albums": "Pukaemi",
"AppDeviceValues": "Taupānga: {0}, Pūrere: {1}",
"Application": "Taupānga",
"Artists": "Kaiwaiata",
"AuthenticationSucceededWithUserName": "{0} has been successfully authenticated",
"Books": "Ngā pukapuka",
"CameraImageUploadedFrom": "Kua tuku ake he whakaahua kāmera hou mai i {0}"
}

View File

@@ -2,12 +2,12 @@
"AppDeviceValues": "അപ്ലിക്കേഷൻ: {0}, ഉപകരണം: {1}",
"Application": "അപ്ലിക്കേഷൻ",
"AuthenticationSucceededWithUserName": "{0} വിജയകരമായി പ്രാമാണീകരിച്ചു",
"CameraImageUploadedFrom": "Camera 0 from എന്നതിൽ നിന്ന് ഒരു പുതിയ ക്യാമറ ചിത്രം അപ്‌ലോഡുചെയ്‌തു",
"CameraImageUploadedFrom": "{0} എന്നതിൽ നിന്ന് ഒരു പുതിയ ക്യാമറ ചിത്രം അപ്‌ലോഡുചെയ്‌തു",
"ChapterNameValue": "അധ്യായം {0}",
"DeviceOfflineWithName": "{0} വിച്ഛേദിച്ചു",
"DeviceOnlineWithName": "{0} ബന്ധിപ്പിച്ചു",
"FailedLoginAttemptWithUserName": "{0}ൽ നിന്നുള്ള പ്രവേശന ശ്രമം പരാജയപ്പെട്ടു",
"Forced": "നിർബന്ധിച്ചു",
"Forced": "നിർബന്ധിതമായി",
"HeaderFavoriteAlbums": "പ്രിയപ്പെട്ട ആൽബങ്ങൾ",
"HeaderFavoriteArtists": "പ്രിയപ്പെട്ട കലാകാരന്മാർ",
"HeaderFavoriteEpisodes": "പ്രിയപ്പെട്ട എപ്പിസോഡുകൾ",
@@ -114,7 +114,7 @@
"Artists": "കലാകാരന്മാർ",
"Shows": "ഷോകൾ",
"Default": "സ്ഥിരസ്ഥിതി",
"Favorites": "പ്രിയങ്കരങ്ങൾ",
"Favorites": "പ്രിയപ്പെട്ടവ",
"Books": "പുസ്തകങ്ങൾ",
"Genres": "വിഭാഗങ്ങൾ",
"Channels": "ചാനലുകൾ",

View File

@@ -3,7 +3,7 @@
"HeaderNextUp": "Дараа нь",
"HeaderContinueWatching": "Үргэлжлүүлэн үзэх",
"Songs": "Дуунууд",
"Playlists": "Playlist-ууд",
"Playlists": "Тоглуулах жагсаалтууд",
"Movies": "Кинонууд",
"Latest": "Сүүлийн үеийн",
"Genres": "Төрлүүд",
@@ -71,7 +71,7 @@
"Forced": "Хүчээр",
"HeaderAlbumArtists": "Цомгийн уран бүтээлчид",
"HeaderFavoriteAlbums": "Дуртай цомгууд",
"HeaderLiveTV": "Шууд",
"HeaderLiveTV": "Шууд ТВ",
"HeaderRecordingGroups": "Бичлэгийн бүлгүүд",
"HearingImpaired": "Сонсголын бэрхшээлтэй",
"HomeVideos": "Үндсэн дүрсүүд",
@@ -109,7 +109,7 @@
"ScheduledTaskStartedWithName": "{0}-г эхлүүлэв",
"ServerNameNeedsToBeRestarted": "{0}-г дахин асаана уу",
"Shows": "Шоу",
"Sync": "Дахин",
"Sync": "Синхрончлох",
"System": "Систем",
"TvShows": "ТВ нэвтрүүлгүүд",
"Undefined": "Танисангүй",

View File

@@ -132,5 +132,10 @@
"TaskDownloadMissingLyrics": "उपलब्ध नसलेली गीतपट्टी (Lyrics) डाउनलोड करा",
"TaskAudioNormalization": "ऑडिओ सामान्यीकरण",
"TaskAudioNormalizationDescription": "ऑडिओ सामान्यीकरणाचा डाटा स्कॅन करतो.",
"TaskDownloadMissingLyricsDescription": "गाण्यांची गीतपट्टी (Lyrics) डाउनलोड करतो"
"TaskDownloadMissingLyricsDescription": "गाण्यांची गीतपट्टी (Lyrics) डाउनलोड करतो",
"TaskExtractMediaSegmentsDescription": "सक्रिय असलेल्या प्लगिनमधून मीडिया विभाग प्राप्त करते.",
"TaskMoveTrickplayImagesDescription": "लायब्ररीच्या सेटिंग्जप्रमाणे आधीपासून अस्तित्वात असलेल्या ट्रिकप्ले फाइल्सचे स्थान बदलते.",
"TaskCleanCollectionsAndPlaylistsDescription": "जे संग्रह आणि प्लेलिस्ट आता अस्तित्वात नाहीत, त्यांमधील घटक हटवते.",
"CleanupUserDataTask": "वापरकर्ता डेटाची स्वच्छता प्रक्रिया",
"CleanupUserDataTaskDescription": "९० दिवसांहून अधिक काळ अनुपस्थित असलेल्या माध्यमांवरील सर्व वापरकर्ता माहिती (जसे पाहण्याची स्थिती, आवडी इ.) हटवते."
}

View File

@@ -0,0 +1 @@
{}

View File

@@ -134,6 +134,8 @@
"TaskCleanCollectionsAndPlaylistsDescription": "ਕਲੈਕਸ਼ਨਾਂ ਅਤੇ ਪਲੇਲਿਸਟਾਂ ਵਿੱਚੋਂ ਉਹ ਆਈਟਮ ਹਟਾਉਂਦਾ ਹੈ ਜੋ ਹੁਣ ਮੌਜੂਦ ਨਹੀਂ ਹਨ।",
"TaskCleanCollectionsAndPlaylists": "ਕਲੈਕਸ਼ਨਾਂ ਅਤੇ ਪਲੇਲਿਸਟਾਂ ਨੂੰ ਸਾਫ ਕਰੋ",
"TaskAudioNormalization": "ਆਵਾਜ਼ ਸਧਾਰਣੀਕਰਨ",
"TaskRefreshTrickplayImagesDescription": "ਚਲ ਰਹੀ ਲਾਇਬ੍ਰੇਰੀਆਂ ਵਿੱਚ ਵੀਡੀਓਜ਼ ਲਈ ਟ੍ਰਿਕਪਲੇ ਪ੍ਰੀਵਿਊ ਬਣਾਉਂਦਾ ਹੈ।",
"TaskKeyframeExtractorDescription": "ਕੀ-ਫ੍ਰੇਮਜ਼ ਨੂੰ ਵੀਡੀਓ ਫਾਈਲਾਂ ਵਿੱਚੋਂ ਨਿਕਾਲਦਾ ਹੈ ਤਾਂ ਜੋ ਹੋਰ ਜ਼ਿਆਦਾ ਸਟਿਕ ਹੋਣ ਵਾਲੀਆਂ HLS ਪਲੇਲਿਸਟਾਂ ਬਣਾਈਆਂ ਜਾ ਸਕਣ। ਇਹ ਕੰਮ ਲੰਬੇ ਸਮੇਂ ਤੱਕ ਚੱਲ ਸਕਦਾ ਹੈ।"
"TaskRefreshTrickplayImagesDescription": "ਵੀਡੀਓ ਲਈ ਟ੍ਰਿਕਪਲੇ ਪ੍ਰੀਵਿਊ ਬਣਾਉਂਦਾ ਹੈ (ਜੇ ਲਾਇਬ੍ਰੇਰੀ ਵਿੱਚ ਚੁਣਿਆ ਗਿਆ ਹੈ)।",
"TaskKeyframeExtractorDescription": "ਕੀ-ਫ੍ਰੇਮਜ਼ ਨੂੰ ਵੀਡੀਓ ਫਾਈਲਾਂ ਵਿੱਚੋਂ ਨਿਕਾਲਦਾ ਹੈ ਤਾਂ ਜੋ ਹੋਰ ਜ਼ਿਆਦਾ ਸਟਿਕ ਹੋਣ ਵਾਲੀਆਂ HLS ਪਲੇਲਿਸਟਾਂ ਬਣਾਈਆਂ ਜਾ ਸਕਣ। ਇਹ ਕੰਮ ਲੰਬੇ ਸਮੇਂ ਤੱਕ ਚੱਲ ਸਕਦਾ ਹੈ।",
"CleanupUserDataTaskDescription": "ਘੱਟੋ-ਘੱਟ 90 ਦਿਨਾਂ ਤੋਂ ਮੌਜੂਦ ਨਾ ਹੋਣ ਵਾਲੇ ਮੀਡੀਆ ਤੋਂ ਸਾਰੇ ਉਪਭੋਗਤਾ ਡੇਟਾ (ਵਾਚ ਸਟੇਟ, ਮਨਪਸੰਦ ਸਟੇਟਸ ਆਦਿ) ਨੂੰ ਸਾਫ਼ ਕਰਦਾ ਹੈ।",
"CleanupUserDataTask": "ਯੂਜ਼ਰ ਡਾਟਾ ਸਾਫ਼ ਕਰਨ ਦਾ ਕੰਮ"
}

View File

@@ -125,8 +125,8 @@
"TaskKeyframeExtractorDescription": "Wyodrębnia klatki kluczowe z plików wideo w celu utworzenia bardziej precyzyjnych list odtwarzania HLS. To zadanie może trwać przez długi czas.",
"TaskKeyframeExtractor": "Ekstraktor klatek kluczowych",
"HearingImpaired": "Niedosłyszący",
"TaskRefreshTrickplayImages": "Generuj obrazy trickplay",
"TaskRefreshTrickplayImagesDescription": "Tworzy podglądy trickplay dla filmów we włączonych bibliotekach.",
"TaskRefreshTrickplayImages": "Generuj obrazy Trickplay",
"TaskRefreshTrickplayImagesDescription": "Tworzy podglądy Trickplay dla filmów we włączonych bibliotekach.",
"TaskCleanCollectionsAndPlaylistsDescription": "Usuwa elementy z kolekcji i list odtwarzania, które już nie istnieją.",
"TaskCleanCollectionsAndPlaylists": "Oczyść kolekcje i listy odtwarzania",
"TaskAudioNormalization": "Normalizacja dźwięku",

View File

@@ -16,7 +16,7 @@
"Collections": "Barrels",
"ItemAddedWithName": "{0} is now with yer treasure",
"Default": "Normal-like",
"FailedLoginAttemptWithUserName": "Ye failed to get in, try from {0}",
"FailedLoginAttemptWithUserName": "Ye failed to enter from {0}",
"Favorites": "Finest Loot",
"ItemRemovedWithName": "{0} was taken from yer treasure",
"LabelIpAddressValue": "Ship's coordinates: {0}",
@@ -113,5 +113,10 @@
"TaskCleanCache": "Sweep the Cache Chest",
"TaskRefreshChapterImages": "Claim chapter portraits",
"TaskRefreshChapterImagesDescription": "Paints wee portraits fer videos that own chapters.",
"TaskRefreshLibrary": "Scan the Treasure Trove"
"TaskRefreshLibrary": "Scan the Treasure Trove",
"TasksChannelsCategory": "Channels o' thy Internet",
"TaskRefreshTrickplayImages": "Summon the picture tricks",
"TaskRefreshTrickplayImagesDescription": "Summons picture trick previews for videos in ye enabled book roost",
"TaskUpdatePlugins": "Resummon yer Plugins",
"TaskCleanTranscode": "Swab Ye Transcode Directory"
}

View File

@@ -5,7 +5,7 @@
"Artists": "Artistas",
"AuthenticationSucceededWithUserName": "{0} autenticado com sucesso",
"Books": "Livros",
"CameraImageUploadedFrom": "Uma nova imagem de câmara foi enviada a partir de {0}",
"CameraImageUploadedFrom": "Uma nova imagem da câmara foi enviada a partir de {0}",
"Channels": "Canais",
"ChapterNameValue": "Capítulo {0}",
"Collections": "Coleções",
@@ -125,8 +125,8 @@
"TaskKeyframeExtractor": "Extrator de Quadros-chave",
"External": "Externo",
"HearingImpaired": "Surdo",
"TaskRefreshTrickplayImages": "Gerar imagens de truques",
"TaskRefreshTrickplayImagesDescription": "Cria vizualizações de truques para videos nas librarias ativas.",
"TaskRefreshTrickplayImages": "Gerar Imagens de Trickplay",
"TaskRefreshTrickplayImagesDescription": "Cria ficheiros de trickplay para vídeos nas bibliotecas ativas.",
"TaskCleanCollectionsAndPlaylistsDescription": "Remove itens de coleções e listas de reprodução que já não existem.",
"TaskCleanCollectionsAndPlaylists": "Limpar coleções e listas de reprodução",
"TaskAudioNormalizationDescription": "Analisa os ficheiros para obter dados de normalização de áudio.",

View File

@@ -0,0 +1 @@
{}

View File

@@ -135,5 +135,7 @@
"TaskExtractMediaSegments": "การสแกนส่วนของสื่อมีเดีย",
"TaskMoveTrickplayImagesDescription": "ย้ายไฟล์ Trickplay ตามการตั้งค่าของไลบรารี",
"TaskExtractMediaSegmentsDescription": "แยกหรือดึงส่วนของสื่อจากปลั๊กอินที่เปิดใช้งาน MediaSegment",
"TaskMoveTrickplayImages": "ย้ายตำแหน่งเก็บภาพตัวอย่าง Trickplay"
"TaskMoveTrickplayImages": "ย้ายตำแหน่งเก็บภาพตัวอย่าง Trickplay",
"CleanupUserDataTask": "ส่วนงานล้างข้อมูลผู้ใช้",
"CleanupUserDataTaskDescription": "ล้างข้อมูลผู้ใช้ทั้งหมด (สถานะการรับชม สถานะรายการโปรด ฯลฯ) จากสื่อที่ไม่ได้ใช้งานแล้วอย่างน้อย 90 วัน"
}

View File

@@ -39,7 +39,7 @@
"TasksMaintenanceCategory": "Bảo Trì",
"VersionNumber": "Phiên Bản {0}",
"ValueHasBeenAddedToLibrary": "{0} đã được thêm vào thư viện của bạn",
"UserStoppedPlayingItemWithValues": "{0} đã phát xong {1} trên {2}",
"UserStoppedPlayingItemWithValues": "{0} đã kết thúc phát {1} trên {2}",
"UserStartedPlayingItemWithValues": "{0} đang phát {1} trên {2}",
"UserPolicyUpdatedWithName": "Chính sách người dùng đã được cập nhật cho {0}",
"UserPasswordChangedWithName": "Mật khẩu đã được thay đổi cho người dùng {0}",

View File

@@ -23,7 +23,7 @@
"HeaderFavoriteShows": "最愛的節目",
"HeaderFavoriteSongs": "最愛的歌曲",
"HeaderLiveTV": "電視直播",
"HeaderNextUp": "接著播放",
"HeaderNextUp": "繼續觀看",
"HeaderRecordingGroups": "錄製組",
"HomeVideos": "家庭影片",
"Inherit": "繼承",
@@ -127,8 +127,8 @@
"HearingImpaired": "聽力障礙",
"TaskRefreshTrickplayImages": "建立 Trickplay 圖像",
"TaskRefreshTrickplayImagesDescription": "為已啟用 Trickplay 的媒體庫內的影片建立 Trickplay 預覽圖。",
"TaskExtractMediaSegments": "掃描媒體段落",
"TaskExtractMediaSegmentsDescription": "從MediaSegment中被允許的插件獲取媒體段。",
"TaskExtractMediaSegments": "掃描媒體分段資訊",
"TaskExtractMediaSegmentsDescription": "從允許MediaSegment 功能的插件獲取媒體段。",
"TaskDownloadMissingLyrics": "下載欠缺歌詞",
"TaskDownloadMissingLyricsDescription": "下載歌詞",
"TaskCleanCollectionsAndPlaylists": "整理媒體與播放清單",
@@ -137,5 +137,6 @@
"TaskCleanCollectionsAndPlaylistsDescription": "從資料庫及播放清單中移除已不存在的項目。",
"TaskMoveTrickplayImagesDescription": "根據媒體庫設定移動現有的 Trickplay 檔案。",
"TaskMoveTrickplayImages": "轉移 Trickplay 影像位置",
"CleanupUserDataTask": "用戶資料清理工作"
"CleanupUserDataTask": "用戶資料清理工作",
"CleanupUserDataTaskDescription": "從用戶數據中清除已經被刪除超過 90 日的媒體相關資料。"
}

View File

@@ -38,6 +38,7 @@ namespace Emby.Server.Implementations.Localization
private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options;
private readonly ConcurrentDictionary<string, CultureDto?> _cultureCache = new(StringComparer.OrdinalIgnoreCase);
private List<CultureDto> _cultures = [];
private FrozenDictionary<string, string> _iso6392BtoT = null!;
@@ -161,6 +162,7 @@ namespace Emby.Server.Implementations.Localization
list.Add(new CultureDto(name, displayname, twoCharName, threeLetterNames));
}
_cultureCache.Clear();
_cultures = list;
_iso6392BtoT = iso6392BtoTdict.ToFrozenDictionary(StringComparer.OrdinalIgnoreCase);
}
@@ -169,20 +171,31 @@ namespace Emby.Server.Implementations.Localization
/// <inheritdoc />
public CultureDto? FindLanguageInfo(string language)
{
// TODO language should ideally be a ReadOnlySpan but moq cannot mock ref structs
for (var i = 0; i < _cultures.Count; i++)
if (string.IsNullOrEmpty(language))
{
var culture = _cultures[i];
if (language.Equals(culture.DisplayName, StringComparison.OrdinalIgnoreCase)
|| language.Equals(culture.Name, StringComparison.OrdinalIgnoreCase)
|| culture.ThreeLetterISOLanguageNames.Contains(language, StringComparison.OrdinalIgnoreCase)
|| language.Equals(culture.TwoLetterISOLanguageName, StringComparison.OrdinalIgnoreCase))
{
return culture;
}
return null;
}
return default;
return _cultureCache.GetOrAdd(
language,
static (lang, cultures) =>
{
// TODO language should ideally be a ReadOnlySpan but moq cannot mock ref structs
for (var i = 0; i < cultures.Count; i++)
{
var culture = cultures[i];
if (lang.Equals(culture.DisplayName, StringComparison.OrdinalIgnoreCase)
|| lang.Equals(culture.Name, StringComparison.OrdinalIgnoreCase)
|| culture.ThreeLetterISOLanguageNames.Contains(lang, StringComparison.OrdinalIgnoreCase)
|| lang.Equals(culture.TwoLetterISOLanguageName, StringComparison.OrdinalIgnoreCase))
{
return culture;
}
}
return null;
},
_cultures);
}
/// <inheritdoc />
@@ -311,15 +324,19 @@ namespace Emby.Server.Implementations.Localization
else
{
// Fall back to server default language for ratings check
// If it has no ratings, use the US ratings
var ratingsDictionary = GetParentalRatingsDictionary() ?? GetParentalRatingsDictionary("us");
var ratingsDictionary = GetParentalRatingsDictionary();
if (ratingsDictionary is not null && ratingsDictionary.TryGetValue(rating, out ParentalRatingScore? value))
{
return value;
}
}
// If we don't find anything, check all ratings systems
// If we don't find anything, check all ratings systems, starting with US
if (_allParentalRatings.TryGetValue("us", out var usRatings) && usRatings.TryGetValue(rating, out var usValue))
{
return usValue;
}
foreach (var dictionary in _allParentalRatings.Values)
{
if (dictionary.TryGetValue(rating, out var value))

View File

@@ -347,8 +347,8 @@ pli||pi|Pali|pali
pol||pl|Polish|polonais
pon|||Pohnpeian|pohnpei
por||pt|Portuguese|portugais
pop||pt-pt|Portuguese (Portugal)|portugais (pt-pt)
pob||pt-br|Portuguese (Brazil)|portugais (pt-br)
por||pt-pt|Portuguese (Portugal)|portugais (pt-pt)
por||pt-br|Portuguese (Brazil)|portugais (pt-br)
pra|||Prakrit languages|prâkrit, langues
pro|||Provençal, Old (to 1500)|provençal ancien (jusqu'à 1500)
pus||ps|Pushto; Pashto|pachto

View File

@@ -266,7 +266,7 @@ namespace Emby.Server.Implementations.TV
items = items.Skip(query.StartIndex.Value);
}
if (query.Limit.HasValue)
if (query.Limit.HasValue && query.Limit.Value > 0)
{
items = items.Take(query.Limit.Value);
}

View File

@@ -156,6 +156,11 @@ namespace Emby.Server.Implementations.Updates
_logger.LogError(ex, "The URL configured for the plugin repository manifest URL is not valid: {Manifest}", manifest);
return Array.Empty<PackageInfo>();
}
catch (NotSupportedException ex)
{
_logger.LogError(ex, "The URL scheme configured for the plugin repository is not supported: {Manifest}", manifest);
return Array.Empty<PackageInfo>();
}
catch (HttpRequestException ex)
{
_logger.LogError(ex, "An error occurred while accessing the plugin manifest: {Manifest}", manifest);

View File

@@ -1,13 +1,16 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Jellyfin.Api.Constants;
using Jellyfin.Data.Enums;
using Jellyfin.Data.Queries;
using Jellyfin.Database.Implementations.Enums;
using MediaBrowser.Common.Api;
using MediaBrowser.Model.Activity;
using MediaBrowser.Model.Querying;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace Jellyfin.Api.Controllers;
@@ -32,10 +35,20 @@ public class ActivityLogController : BaseJellyfinApiController
/// <summary>
/// Gets activity log entries.
/// </summary>
/// <param name="startIndex">Optional. The record index to start at. All items with a lower index will be dropped from the results.</param>
/// <param name="limit">Optional. The maximum number of records to return.</param>
/// <param name="minDate">Optional. The minimum date. Format = ISO.</param>
/// <param name="hasUserId">Optional. Filter log entries if it has user id, or not.</param>
/// <param name="startIndex">The record index to start at. All items with a lower index will be dropped from the results.</param>
/// <param name="limit">The maximum number of records to return.</param>
/// <param name="minDate">The minimum date.</param>
/// <param name="maxDate">The maximum date.</param>
/// <param name="hasUserId">Filter log entries if it has user id, or not.</param>
/// <param name="name">Filter by name.</param>
/// <param name="overview">Filter by overview.</param>
/// <param name="shortOverview">Filter by short overview.</param>
/// <param name="type">Filter by type.</param>
/// <param name="itemId">Filter by item id.</param>
/// <param name="username">Filter by username.</param>
/// <param name="severity">Filter by log severity.</param>
/// <param name="sortBy">Specify one or more sort orders. Format: SortBy=Name,Type.</param>
/// <param name="sortOrder">Sort Order..</param>
/// <response code="200">Activity log returned.</response>
/// <returns>A <see cref="QueryResult{ActivityLogEntry}"/> containing the log entries.</returns>
[HttpGet("Entries")]
@@ -44,14 +57,62 @@ public class ActivityLogController : BaseJellyfinApiController
[FromQuery] int? startIndex,
[FromQuery] int? limit,
[FromQuery] DateTime? minDate,
[FromQuery] bool? hasUserId)
[FromQuery] DateTime? maxDate,
[FromQuery] bool? hasUserId,
[FromQuery] string? name,
[FromQuery] string? overview,
[FromQuery] string? shortOverview,
[FromQuery] string? type,
[FromQuery] Guid? itemId,
[FromQuery] string? username,
[FromQuery] LogLevel? severity,
[FromQuery] ActivityLogSortBy[]? sortBy,
[FromQuery] SortOrder[]? sortOrder)
{
return await _activityManager.GetPagedResultAsync(new ActivityLogQuery
var query = new ActivityLogQuery
{
Skip = startIndex,
Limit = limit,
MinDate = minDate,
HasUserId = hasUserId
}).ConfigureAwait(false);
MaxDate = maxDate,
HasUserId = hasUserId,
Name = name,
Overview = overview,
ShortOverview = shortOverview,
Type = type,
ItemId = itemId,
Username = username,
Severity = severity,
OrderBy = GetOrderBy(sortBy ?? [], sortOrder ?? []),
};
return await _activityManager.GetPagedResultAsync(query).ConfigureAwait(false);
}
private static (ActivityLogSortBy SortBy, SortOrder SortOrder)[] GetOrderBy(
IReadOnlyList<ActivityLogSortBy> sortBy,
IReadOnlyList<SortOrder> requestedSortOrder)
{
if (sortBy.Count == 0)
{
return [];
}
var result = new (ActivityLogSortBy, SortOrder)[sortBy.Count];
var i = 0;
for (; i < requestedSortOrder.Count; i++)
{
result[i] = (sortBy[i], requestedSortOrder[i]);
}
// Add remaining elements with the first specified SortOrder
// or the default one if no SortOrders are specified
var order = requestedSortOrder.Count > 0 ? requestedSortOrder[0] : SortOrder.Ascending;
for (; i < sortBy.Count; i++)
{
result[i] = (sortBy[i], order);
}
return result;
}
}

View File

@@ -122,7 +122,6 @@ public class ArtistsController : BaseJellyfinApiController
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
User? user = null;
@@ -326,7 +325,6 @@ public class ArtistsController : BaseJellyfinApiController
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
User? user = null;
@@ -467,7 +465,7 @@ public class ArtistsController : BaseJellyfinApiController
public ActionResult<BaseItemDto> GetArtistByName([FromRoute, Required] string name, [FromQuery] Guid? userId)
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions().AddClientFields(User);
var dtoOptions = new DtoOptions();
var item = _libraryManager.GetArtist(name, dtoOptions);

View File

@@ -65,7 +65,7 @@ public class CollectionController : BaseJellyfinApiController
UserIds = new[] { userId }
}).ConfigureAwait(false);
var dtoOptions = new DtoOptions().AddClientFields(User);
var dtoOptions = new DtoOptions();
var dto = _dtoService.GetBaseItemDto(item, dtoOptions);

View File

@@ -1839,8 +1839,9 @@ public class DynamicHlsController : BaseJellyfinApiController
{
if (isActualOutputVideoCodecHevc)
{
// Prefer dvh1 to dvhe
args += " -tag:v:0 dvh1 -strict -2";
// Use hvc1 for 8.4. This is what Dolby uses for its official sample streams. Tagging with dvh1 would break some players with strict tag checking like Apple Safari.
var codecTag = state.VideoStream.VideoRangeType == VideoRangeType.DOVIWithHLG ? "hvc1" : "dvh1";
args += $" -tag:v:0 {codecTag} -strict -2";
}
else if (isActualOutputVideoCodecAv1)
{

View File

@@ -94,7 +94,6 @@ public class GenresController : BaseJellyfinApiController
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, false, imageTypeLimit, enableImageTypes);
User? user = userId.IsNullOrEmpty()
@@ -159,8 +158,7 @@ public class GenresController : BaseJellyfinApiController
public ActionResult<BaseItemDto> GetGenre([FromRoute, Required] string genreName, [FromQuery] Guid? userId)
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions()
.AddClientFields(User);
var dtoOptions = new DtoOptions();
Genre? item;
if (genreName.Contains(BaseItem.SlugChar, StringComparison.OrdinalIgnoreCase))

View File

@@ -90,7 +90,6 @@ public class InstantMixController : BaseJellyfinApiController
}
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions);
return GetResult(items, user, limit, dtoOptions);
@@ -134,7 +133,6 @@ public class InstantMixController : BaseJellyfinApiController
}
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions);
return GetResult(items, user, limit, dtoOptions);
@@ -178,7 +176,6 @@ public class InstantMixController : BaseJellyfinApiController
}
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions);
return GetResult(items, user, limit, dtoOptions);
@@ -214,7 +211,6 @@ public class InstantMixController : BaseJellyfinApiController
? null
: _userManager.GetUserById(userId.Value);
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var items = _musicManager.GetInstantMixFromGenres(new[] { name }, user, dtoOptions);
return GetResult(items, user, limit, dtoOptions);
@@ -258,7 +254,6 @@ public class InstantMixController : BaseJellyfinApiController
}
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions);
return GetResult(items, user, limit, dtoOptions);
@@ -302,7 +297,6 @@ public class InstantMixController : BaseJellyfinApiController
}
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions);
return GetResult(items, user, limit, dtoOptions);
@@ -385,7 +379,6 @@ public class InstantMixController : BaseJellyfinApiController
}
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions);
return GetResult(items, user, limit, dtoOptions);

View File

@@ -180,11 +180,14 @@ public class ItemUpdateController : BaseJellyfinApiController
info.ContentTypeOptions = GetContentTypeOptions(true).ToArray();
info.ContentType = configuredContentType;
if (inheritedContentType is null || inheritedContentType == CollectionType.tvshows)
if (inheritedContentType is null
|| inheritedContentType == CollectionType.tvshows
|| inheritedContentType == CollectionType.movies)
{
info.ContentTypeOptions = info.ContentTypeOptions
.Where(i => string.IsNullOrWhiteSpace(i.Value)
|| string.Equals(i.Value, "TvShows", StringComparison.OrdinalIgnoreCase))
|| string.Equals(i.Value, "TvShows", StringComparison.OrdinalIgnoreCase)
|| string.Equals(i.Value, "Movies", StringComparison.OrdinalIgnoreCase))
.ToArray();
}
}

View File

@@ -268,7 +268,6 @@ public class ItemsController : BaseJellyfinApiController
}
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
if (includeItemTypes.Length == 1
@@ -849,7 +848,6 @@ public class ItemsController : BaseJellyfinApiController
var parentIdGuid = parentId ?? Guid.Empty;
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var ancestorIds = Array.Empty<Guid>();

View File

@@ -188,7 +188,7 @@ public class LibraryController : BaseJellyfinApiController
item = parent;
}
var dtoOptions = new DtoOptions().AddClientFields(User);
var dtoOptions = new DtoOptions();
var items = themeItems
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item))
.ToArray();
@@ -261,7 +261,7 @@ public class LibraryController : BaseJellyfinApiController
item = parent;
}
var dtoOptions = new DtoOptions().AddClientFields(User);
var dtoOptions = new DtoOptions();
var items = themeItems
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item))
.ToArray();
@@ -497,7 +497,7 @@ public class LibraryController : BaseJellyfinApiController
var baseItemDtos = new List<BaseItemDto>();
var dtoOptions = new DtoOptions().AddClientFields(User);
var dtoOptions = new DtoOptions();
BaseItem? parent = item.GetParent();
while (parent is not null)
@@ -557,7 +557,7 @@ public class LibraryController : BaseJellyfinApiController
items = items.Where(i => i.IsHidden == val).ToList();
}
var dtoOptions = new DtoOptions().AddClientFields(User);
var dtoOptions = new DtoOptions();
var resultArray = _dtoService.GetBaseItemDtos(items, dtoOptions);
return new QueryResult<BaseItemDto>(resultArray);
}
@@ -759,8 +759,7 @@ public class LibraryController : BaseJellyfinApiController
return new QueryResult<BaseItemDto>();
}
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User);
var dtoOptions = new DtoOptions { Fields = fields };
var program = item as IHasProgramAttributes;
bool? isMovie = item is Movie || (program is not null && program.IsMovie) || item is Trailer;

View File

@@ -170,7 +170,6 @@ public class LiveTvController : BaseJellyfinApiController
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var channelResult = _liveTvManager.GetInternalChannels(
@@ -242,8 +241,7 @@ public class LiveTvController : BaseJellyfinApiController
return NotFound();
}
var dtoOptions = new DtoOptions()
.AddClientFields(User);
var dtoOptions = new DtoOptions();
return _dtoService.GetBaseItemDto(item, dtoOptions, user);
}
@@ -297,7 +295,6 @@ public class LiveTvController : BaseJellyfinApiController
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
return await _liveTvManager.GetRecordingsAsync(
@@ -444,8 +441,7 @@ public class LiveTvController : BaseJellyfinApiController
return NotFound();
}
var dtoOptions = new DtoOptions()
.AddClientFields(User);
var dtoOptions = new DtoOptions();
return _dtoService.GetBaseItemDto(item, dtoOptions, user);
}
@@ -635,7 +631,6 @@ public class LiveTvController : BaseJellyfinApiController
}
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
return await _liveTvManager.GetPrograms(query, dtoOptions, CancellationToken.None).ConfigureAwait(false);
}
@@ -690,7 +685,6 @@ public class LiveTvController : BaseJellyfinApiController
}
var dtoOptions = new DtoOptions { Fields = body.Fields ?? [] }
.AddClientFields(User)
.AddAdditionalDtoOptions(body.EnableImages, body.EnableUserData, body.ImageTypeLimit, body.EnableImageTypes ?? []);
return await _liveTvManager.GetPrograms(query, dtoOptions, CancellationToken.None).ConfigureAwait(false);
}
@@ -760,7 +754,6 @@ public class LiveTvController : BaseJellyfinApiController
};
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
return await _liveTvManager.GetRecommendedProgramsAsync(query, dtoOptions, CancellationToken.None).ConfigureAwait(false);
}

View File

@@ -74,8 +74,7 @@ public class MoviesController : BaseJellyfinApiController
var user = userId.IsNullOrEmpty()
? null
: _userManager.GetUserById(userId.Value);
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User);
var dtoOptions = new DtoOptions { Fields = fields };
var categories = new List<RecommendationDto>();

View File

@@ -94,7 +94,6 @@ public class MusicGenresController : BaseJellyfinApiController
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, false, imageTypeLimit, enableImageTypes);
User? user = userId.IsNullOrEmpty()
@@ -148,7 +147,7 @@ public class MusicGenresController : BaseJellyfinApiController
public ActionResult<BaseItemDto> GetMusicGenre([FromRoute, Required] string genreName, [FromQuery] Guid? userId)
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions().AddClientFields(User);
var dtoOptions = new DtoOptions();
MusicGenre? item;

View File

@@ -81,7 +81,6 @@ public class PersonsController : BaseJellyfinApiController
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
User? user = userId.IsNullOrEmpty()
@@ -121,8 +120,7 @@ public class PersonsController : BaseJellyfinApiController
public ActionResult<BaseItemDto> GetPerson([FromRoute, Required] string name, [FromQuery] Guid? userId)
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions()
.AddClientFields(User);
var dtoOptions = new DtoOptions();
var item = _libraryManager.GetPerson(name);
if (item is null)

View File

@@ -548,7 +548,6 @@ public class PlaylistsController : BaseJellyfinApiController
}
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var dtos = _dtoService.GetBaseItemDtos(items.Select(i => i.Item2).ToList(), dtoOptions, user);

View File

@@ -89,7 +89,6 @@ public class StudiosController : BaseJellyfinApiController
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
User? user = userId.IsNullOrEmpty()
@@ -142,7 +141,7 @@ public class StudiosController : BaseJellyfinApiController
public ActionResult<BaseItemDto> GetStudio([FromRoute, Required] string name, [FromQuery] Guid? userId)
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions().AddClientFields(User);
var dtoOptions = new DtoOptions();
var item = _libraryManager.GetStudio(name);
if (!userId.IsNullOrEmpty())

View File

@@ -77,7 +77,7 @@ public class SuggestionsController : BaseJellyfinApiController
user = _userManager.GetUserById(requestUserId);
}
var dtoOptions = new DtoOptions().AddClientFields(User);
var dtoOptions = new DtoOptions();
var result = _libraryManager.GetItemsResult(new InternalItemsQuery(user)
{
OrderBy = new[] { (ItemSortBy.Random, SortOrder.Descending) },

View File

@@ -99,7 +99,6 @@ public class TvShowsController : BaseJellyfinApiController
}
var options = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var result = _tvSeriesManager.GetNextUp(
@@ -161,7 +160,6 @@ public class TvShowsController : BaseJellyfinApiController
var parentIdGuid = parentId ?? Guid.Empty;
var options = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user)
@@ -231,7 +229,6 @@ public class TvShowsController : BaseJellyfinApiController
List<BaseItem> episodes;
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var shouldIncludeMissingEpisodes = (user is not null && user.DisplayMissingEpisodes) || User.GetIsApiKey();
@@ -360,7 +357,6 @@ public class TvShowsController : BaseJellyfinApiController
});
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var returnItems = _dtoService.GetBaseItemDtos(seasons, dtoOptions, user);

View File

@@ -13,6 +13,7 @@ using Jellyfin.Extensions;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Dto;
@@ -94,7 +95,7 @@ public class UserLibraryController : BaseJellyfinApiController
await RefreshItemOnDemandIfNeeded(item).ConfigureAwait(false);
var dtoOptions = new DtoOptions().AddClientFields(User);
var dtoOptions = new DtoOptions();
return _dtoService.GetBaseItemDto(item, dtoOptions, user);
}
@@ -133,7 +134,7 @@ public class UserLibraryController : BaseJellyfinApiController
}
var item = _libraryManager.GetUserRootFolder();
var dtoOptions = new DtoOptions().AddClientFields(User);
var dtoOptions = new DtoOptions();
return _dtoService.GetBaseItemDto(item, dtoOptions, user);
}
@@ -180,7 +181,7 @@ public class UserLibraryController : BaseJellyfinApiController
}
var items = await _libraryManager.GetIntros(item, user).ConfigureAwait(false);
var dtoOptions = new DtoOptions().AddClientFields(User);
var dtoOptions = new DtoOptions();
var dtos = items.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user)).ToArray();
return new QueryResult<BaseItemDto>(dtos);
@@ -422,7 +423,7 @@ public class UserLibraryController : BaseJellyfinApiController
return NotFound();
}
var dtoOptions = new DtoOptions().AddClientFields(User);
var dtoOptions = new DtoOptions();
if (item is IHasTrailers hasTrailers)
{
var trailers = hasTrailers.LocalTrailers;
@@ -478,7 +479,7 @@ public class UserLibraryController : BaseJellyfinApiController
return NotFound();
}
var dtoOptions = new DtoOptions().AddClientFields(User);
var dtoOptions = new DtoOptions();
return Ok(item
.GetExtras()
@@ -549,7 +550,6 @@ public class UserLibraryController : BaseJellyfinApiController
}
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var list = _userViewManager.GetLatestItems(
@@ -569,7 +569,7 @@ public class UserLibraryController : BaseJellyfinApiController
var item = i.Item2[0];
var childCount = 0;
if (i.Item1 is not null && (i.Item2.Count > 1 || i.Item1 is MusicAlbum))
if (i.Item1 is not null && (i.Item2.Count > 1 || i.Item1 is MusicAlbum || i.Item1 is Series ))
{
item = i.Item1;
childCount = i.Item2.Count;

View File

@@ -86,7 +86,7 @@ public class UserViewsController : BaseJellyfinApiController
var folders = _userViewManager.GetUserViews(query);
var dtoOptions = new DtoOptions().AddClientFields(User);
var dtoOptions = new DtoOptions();
dtoOptions.Fields = [..dtoOptions.Fields, ItemFields.PrimaryImageAspectRatio, ItemFields.DisplayPreferencesId];
var dtos = Array.ConvertAll(folders, i => _dtoService.GetBaseItemDto(i, dtoOptions, user));

View File

@@ -111,7 +111,6 @@ public class VideosController : BaseJellyfinApiController
}
var dtoOptions = new DtoOptions();
dtoOptions = dtoOptions.AddClientFields(User);
BaseItemDto[] items;
if (item is Video video)

View File

@@ -89,7 +89,6 @@ public class YearsController : BaseJellyfinApiController
{
userId = RequestHelpers.GetUserId(User, userId);
var dtoOptions = new DtoOptions { Fields = fields }
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
User? user = userId.IsNullOrEmpty()
@@ -182,8 +181,7 @@ public class YearsController : BaseJellyfinApiController
return NotFound();
}
var dtoOptions = new DtoOptions()
.AddClientFields(User);
var dtoOptions = new DtoOptions();
if (!userId.IsNullOrEmpty())
{

View File

@@ -1,10 +1,6 @@
using System;
using System.Collections.Generic;
using System.Security.Claims;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
namespace Jellyfin.Api.Extensions;
@@ -13,55 +9,6 @@ namespace Jellyfin.Api.Extensions;
/// </summary>
public static class DtoExtensions
{
/// <summary>
/// Add additional fields depending on client.
/// </summary>
/// <remarks>
/// Use in place of GetDtoOptions.
/// Legacy order: 2.
/// </remarks>
/// <param name="dtoOptions">DtoOptions object.</param>
/// <param name="user">Current claims principal.</param>
/// <returns>Modified DtoOptions object.</returns>
internal static DtoOptions AddClientFields(
this DtoOptions dtoOptions, ClaimsPrincipal user)
{
string? client = user.GetClient();
// No client in claim
if (string.IsNullOrEmpty(client))
{
return dtoOptions;
}
if (!dtoOptions.ContainsField(ItemFields.RecursiveItemCount))
{
if (client.Contains("kodi", StringComparison.OrdinalIgnoreCase) ||
client.Contains("wmc", StringComparison.OrdinalIgnoreCase) ||
client.Contains("media center", StringComparison.OrdinalIgnoreCase) ||
client.Contains("classic", StringComparison.OrdinalIgnoreCase))
{
dtoOptions.Fields = [..dtoOptions.Fields, ItemFields.RecursiveItemCount];
}
}
if (!dtoOptions.ContainsField(ItemFields.ChildCount))
{
if (client.Contains("kodi", StringComparison.OrdinalIgnoreCase) ||
client.Contains("wmc", StringComparison.OrdinalIgnoreCase) ||
client.Contains("media center", StringComparison.OrdinalIgnoreCase) ||
client.Contains("classic", StringComparison.OrdinalIgnoreCase) ||
client.Contains("roku", StringComparison.OrdinalIgnoreCase) ||
client.Contains("samsung", StringComparison.OrdinalIgnoreCase) ||
client.Contains("androidtv", StringComparison.OrdinalIgnoreCase))
{
dtoOptions.Fields = [..dtoOptions.Fields, ItemFields.ChildCount];
}
}
return dtoOptions;
}
/// <summary>
/// Add additional DtoOptions.
/// </summary>

View File

@@ -154,7 +154,7 @@ public class DynamicHlsHelper
// from universal audio service, need to override the AudioCodec when the actual request differs from original query
if (!string.Equals(state.OutputAudioCodec, _httpContextAccessor.HttpContext.Request.Query["AudioCodec"].ToString(), StringComparison.OrdinalIgnoreCase))
{
var newQuery = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(_httpContextAccessor.HttpContext.Request.QueryString.ToString());
var newQuery = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(queryString);
newQuery["AudioCodec"] = state.OutputAudioCodec;
queryString = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(string.Empty, newQuery);
}
@@ -173,10 +173,21 @@ public class DynamicHlsHelper
queryString += "&TranscodeReasons=" + state.Request.TranscodeReasons;
}
// Main stream
var playlistUrl = isLiveStream ? "live.m3u8" : "main.m3u8";
// Video rotation metadata is only supported in fMP4 remuxing
if (state.VideoStream is not null
&& state.VideoRequest is not null
&& (state.VideoStream?.Rotation ?? 0) != 0
&& EncodingHelper.IsCopyCodec(state.OutputVideoCodec)
&& !string.IsNullOrWhiteSpace(state.Request.SegmentContainer)
&& !string.Equals(state.Request.SegmentContainer, "mp4", StringComparison.OrdinalIgnoreCase))
{
queryString += "&AllowVideoStreamCopy=false";
}
playlistUrl += queryString;
// Main stream
var baseUrl = isLiveStream ? "live.m3u8" : "main.m3u8";
var playlistUrl = baseUrl + queryString;
var playlistQuery = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(queryString);
var subtitleStreams = state.MediaSource
.MediaStreams
@@ -198,37 +209,36 @@ public class DynamicHlsHelper
AddSubtitles(state, subtitleStreams, builder, _httpContextAccessor.HttpContext.User);
}
// Video rotation metadata is only supported in fMP4 remuxing
if (state.VideoStream is not null
&& state.VideoRequest is not null
&& (state.VideoStream?.Rotation ?? 0) != 0
&& EncodingHelper.IsCopyCodec(state.OutputVideoCodec)
&& !string.IsNullOrWhiteSpace(state.Request.SegmentContainer)
&& !string.Equals(state.Request.SegmentContainer, "mp4", StringComparison.OrdinalIgnoreCase))
{
playlistUrl += "&AllowVideoStreamCopy=false";
}
var basicPlaylist = AppendPlaylist(builder, state, playlistUrl, totalBitrate, subtitleGroup);
if (state.VideoStream is not null && state.VideoRequest is not null)
{
var encodingOptions = _serverConfigurationManager.GetEncodingOptions();
// Provide SDR HEVC entrance for backward compatibility.
if (encodingOptions.AllowHevcEncoding
&& !encodingOptions.AllowAv1Encoding
&& EncodingHelper.IsCopyCodec(state.OutputVideoCodec)
&& state.VideoStream.VideoRange == VideoRange.HDR
&& string.Equals(state.ActualOutputVideoCodec, "hevc", StringComparison.OrdinalIgnoreCase))
// Provide AV1 and HEVC SDR entrances for backward compatibility.
foreach (var sdrVideoCodec in new[] { "av1", "hevc" })
{
var requestedVideoProfiles = state.GetRequestedProfiles("hevc");
if (requestedVideoProfiles is not null && requestedVideoProfiles.Length > 0)
var isAv1EncodingAllowed = encodingOptions.AllowAv1Encoding
&& string.Equals(sdrVideoCodec, "av1", StringComparison.OrdinalIgnoreCase)
&& string.Equals(state.ActualOutputVideoCodec, "av1", StringComparison.OrdinalIgnoreCase);
var isHevcEncodingAllowed = encodingOptions.AllowHevcEncoding
&& string.Equals(sdrVideoCodec, "hevc", StringComparison.OrdinalIgnoreCase)
&& string.Equals(state.ActualOutputVideoCodec, "hevc", StringComparison.OrdinalIgnoreCase);
var isEncodingAllowed = isAv1EncodingAllowed || isHevcEncodingAllowed;
if (isEncodingAllowed
&& EncodingHelper.IsCopyCodec(state.OutputVideoCodec)
&& state.VideoStream.VideoRange == VideoRange.HDR)
{
// Force HEVC Main Profile and disable video stream copy.
state.OutputVideoCodec = "hevc";
var sdrVideoUrl = ReplaceProfile(playlistUrl, "hevc", string.Join(',', requestedVideoProfiles), "main");
sdrVideoUrl += "&AllowVideoStreamCopy=false";
// Force AV1 and HEVC Main Profile and disable video stream copy.
state.OutputVideoCodec = sdrVideoCodec;
var sdrPlaylistQuery = playlistQuery;
sdrPlaylistQuery["VideoCodec"] = sdrVideoCodec;
sdrPlaylistQuery[sdrVideoCodec + "-profile"] = "main";
sdrPlaylistQuery["AllowVideoStreamCopy"] = "false";
var sdrVideoUrl = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(baseUrl, sdrPlaylistQuery);
// HACK: Use the same bitrate so that the client can choose by other attributes, such as color range.
AppendPlaylist(builder, state, sdrVideoUrl, totalBitrate, subtitleGroup);
@@ -238,12 +248,30 @@ public class DynamicHlsHelper
}
}
// Provide H.264 SDR entrance for backward compatibility.
if (EncodingHelper.IsCopyCodec(state.OutputVideoCodec)
&& state.VideoStream.VideoRange == VideoRange.HDR)
{
// Force H.264 and disable video stream copy.
state.OutputVideoCodec = "h264";
var sdrPlaylistQuery = playlistQuery;
sdrPlaylistQuery["VideoCodec"] = "h264";
sdrPlaylistQuery["AllowVideoStreamCopy"] = "false";
var sdrVideoUrl = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(baseUrl, sdrPlaylistQuery);
// HACK: Use the same bitrate so that the client can choose by other attributes, such as color range.
AppendPlaylist(builder, state, sdrVideoUrl, totalBitrate, subtitleGroup);
// Restore the video codec
state.OutputVideoCodec = "copy";
}
// Provide Level 5.0 entrance for backward compatibility.
// e.g. Apple A10 chips refuse the master playlist containing SDR HEVC Main Level 5.1 video,
// but in fact it is capable of playing videos up to Level 6.1.
if (encodingOptions.AllowHevcEncoding
&& !encodingOptions.AllowAv1Encoding
&& EncodingHelper.IsCopyCodec(state.OutputVideoCodec)
if (EncodingHelper.IsCopyCodec(state.OutputVideoCodec)
&& state.VideoStream.Level.HasValue
&& state.VideoStream.Level > 150
&& state.VideoStream.VideoRange == VideoRange.SDR
@@ -273,12 +301,15 @@ public class DynamicHlsHelper
var variation = GetBitrateVariation(totalBitrate);
var newBitrate = totalBitrate - variation;
var variantUrl = ReplaceVideoBitrate(playlistUrl, requestedVideoBitrate, requestedVideoBitrate - variation);
var variantQuery = playlistQuery;
variantQuery["VideoBitrate"] = (requestedVideoBitrate - variation).ToString(CultureInfo.InvariantCulture);
var variantUrl = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(baseUrl, variantQuery);
AppendPlaylist(builder, state, variantUrl, newBitrate, subtitleGroup);
variation *= 2;
newBitrate = totalBitrate - variation;
variantUrl = ReplaceVideoBitrate(playlistUrl, requestedVideoBitrate, requestedVideoBitrate - variation);
variantQuery["VideoBitrate"] = (requestedVideoBitrate - variation).ToString(CultureInfo.InvariantCulture);
variantUrl = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(baseUrl, variantQuery);
AppendPlaylist(builder, state, variantUrl, newBitrate, subtitleGroup);
}
@@ -723,7 +754,9 @@ public class DynamicHlsHelper
{
if (string.Equals(state.ActualOutputAudioCodec, "aac", StringComparison.OrdinalIgnoreCase))
{
string? profile = state.GetRequestedProfiles("aac").FirstOrDefault();
string? profile = EncodingHelper.IsCopyCodec(state.OutputAudioCodec)
? state.AudioStream?.Profile : state.GetRequestedProfiles("aac").FirstOrDefault();
return HlsCodecStringHelpers.GetAACString(profile);
}
@@ -757,6 +790,19 @@ public class DynamicHlsHelper
return HlsCodecStringHelpers.GetOPUSString();
}
if (string.Equals(state.ActualOutputAudioCodec, "truehd", StringComparison.OrdinalIgnoreCase))
{
return HlsCodecStringHelpers.GetTRUEHDString();
}
if (string.Equals(state.ActualOutputAudioCodec, "dts", StringComparison.OrdinalIgnoreCase))
{
// lavc only support encoding DTS core profile
string? profile = EncodingHelper.IsCopyCodec(state.OutputAudioCodec) ? state.AudioStream?.Profile : "DTS";
return HlsCodecStringHelpers.GetDTSString(profile);
}
return string.Empty;
}
@@ -863,23 +909,6 @@ public class DynamicHlsHelper
return variation;
}
private string ReplaceVideoBitrate(string url, int oldValue, int newValue)
{
return url.Replace(
"videobitrate=" + oldValue.ToString(CultureInfo.InvariantCulture),
"videobitrate=" + newValue.ToString(CultureInfo.InvariantCulture),
StringComparison.OrdinalIgnoreCase);
}
private string ReplaceProfile(string url, string codec, string oldValue, string newValue)
{
string profileStr = codec + "-profile=";
return url.Replace(
profileStr + oldValue,
profileStr + newValue,
StringComparison.OrdinalIgnoreCase);
}
private string ReplacePlaylistCodecsField(StringBuilder playlist, StringBuilder oldValue, StringBuilder newValue)
{
var oldPlaylist = playlist.ToString();

View File

@@ -41,6 +41,11 @@ public static class HlsCodecStringHelpers
/// </summary>
public const string OPUS = "Opus";
/// <summary>
/// Codec name for TRUEHD.
/// </summary>
public const string TRUEHD = "mlpa";
/// <summary>
/// Gets a MP3 codec string.
/// </summary>
@@ -59,7 +64,7 @@ public static class HlsCodecStringHelpers
{
StringBuilder result = new StringBuilder("mp4a", 9);
if (string.Equals(profile, "HE", StringComparison.OrdinalIgnoreCase))
if (string.Equals(profile, "HE-AAC", StringComparison.OrdinalIgnoreCase))
{
result.Append(".40.5");
}
@@ -117,6 +122,46 @@ public static class HlsCodecStringHelpers
return OPUS;
}
/// <summary>
/// Gets an TRUEHD codec string.
/// </summary>
/// <returns>TRUEHD codec string.</returns>
public static string GetTRUEHDString()
{
return TRUEHD;
}
/// <summary>
/// Gets an DTS codec string.
/// </summary>
/// <param name="profile">DTS profile.</param>
/// <returns>DTS codec string.</returns>
public static string GetDTSString(string? profile)
{
if (string.Equals(profile, "DTS", StringComparison.OrdinalIgnoreCase)
|| string.Equals(profile, "DTS-ES", StringComparison.OrdinalIgnoreCase)
|| string.Equals(profile, "DTS 96/24", StringComparison.OrdinalIgnoreCase))
{
return "dtsc";
}
if (string.Equals(profile, "DTS-HD HRA", StringComparison.OrdinalIgnoreCase)
|| string.Equals(profile, "DTS-HD MA", StringComparison.OrdinalIgnoreCase)
|| string.Equals(profile, "DTS-HD MA + DTS:X", StringComparison.OrdinalIgnoreCase)
|| string.Equals(profile, "DTS-HD MA + DTS:X IMAX", StringComparison.OrdinalIgnoreCase))
{
return "dtsh";
}
if (string.Equals(profile, "DTS Express", StringComparison.OrdinalIgnoreCase))
{
return "dtse";
}
// Default to DTS core if profile is invalid
return "dtsc";
}
/// <summary>
/// Gets a H.264 codec string.
/// </summary>

View File

@@ -1,53 +0,0 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
namespace Jellyfin.Api.Middleware;
/// <summary>
/// Removes /emby and /mediabrowser from requested route.
/// </summary>
public class LegacyEmbyRouteRewriteMiddleware
{
private const string EmbyPath = "/emby";
private const string MediabrowserPath = "/mediabrowser";
private readonly RequestDelegate _next;
private readonly ILogger<LegacyEmbyRouteRewriteMiddleware> _logger;
/// <summary>
/// Initializes a new instance of the <see cref="LegacyEmbyRouteRewriteMiddleware"/> class.
/// </summary>
/// <param name="next">The next delegate in the pipeline.</param>
/// <param name="logger">The logger.</param>
public LegacyEmbyRouteRewriteMiddleware(
RequestDelegate next,
ILogger<LegacyEmbyRouteRewriteMiddleware> logger)
{
_next = next;
_logger = logger;
}
/// <summary>
/// Executes the middleware action.
/// </summary>
/// <param name="httpContext">The current HTTP context.</param>
/// <returns>The async task.</returns>
public async Task Invoke(HttpContext httpContext)
{
var localPath = httpContext.Request.Path.ToString();
if (localPath.StartsWith(EmbyPath, StringComparison.OrdinalIgnoreCase))
{
httpContext.Request.Path = localPath[EmbyPath.Length..];
_logger.LogDebug("Removing {EmbyPath} from route.", EmbyPath);
}
else if (localPath.StartsWith(MediabrowserPath, StringComparison.OrdinalIgnoreCase))
{
httpContext.Request.Path = localPath[MediabrowserPath.Length..];
_logger.LogDebug("Removing {MediabrowserPath} from route.", MediabrowserPath);
}
await _next(httpContext).ConfigureAwait(false);
}
}

View File

@@ -0,0 +1,49 @@
namespace Jellyfin.Data.Enums;
/// <summary>
/// Activity log sorting options.
/// </summary>
public enum ActivityLogSortBy
{
/// <summary>
/// Sort by name.
/// </summary>
Name = 0,
/// <summary>
/// Sort by overview.
/// </summary>
Overiew = 1,
/// <summary>
/// Sort by short overview.
/// </summary>
ShortOverview = 2,
/// <summary>
/// Sort by type.
/// </summary>
Type = 3,
/*
/// <summary>
/// Sort by item name.
/// </summary>
Item = 4,
*/
/// <summary>
/// Sort by date.
/// </summary>
DateCreated = 5,
/// <summary>
/// Sort by username.
/// </summary>
Username = 6,
/// <summary>
/// Sort by severity.
/// </summary>
LogSeverity = 7
}

View File

@@ -18,7 +18,7 @@
<PropertyGroup>
<Authors>Jellyfin Contributors</Authors>
<PackageId>Jellyfin.Data</PackageId>
<VersionPrefix>10.11.4</VersionPrefix>
<VersionPrefix>10.12.0</VersionPrefix>
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
</PropertyGroup>

View File

@@ -1,20 +1,68 @@
using System;
using System.Collections.Generic;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Enums;
using Microsoft.Extensions.Logging;
namespace Jellyfin.Data.Queries
namespace Jellyfin.Data.Queries;
/// <summary>
/// A class representing a query to the activity logs.
/// </summary>
public class ActivityLogQuery : PaginatedQuery
{
/// <summary>
/// A class representing a query to the activity logs.
/// Gets or sets a value indicating whether to take entries with a user id.
/// </summary>
public class ActivityLogQuery : PaginatedQuery
{
/// <summary>
/// Gets or sets a value indicating whether to take entries with a user id.
/// </summary>
public bool? HasUserId { get; set; }
public bool? HasUserId { get; set; }
/// <summary>
/// Gets or sets the minimum date to query for.
/// </summary>
public DateTime? MinDate { get; set; }
}
/// <summary>
/// Gets or sets the minimum date to query for.
/// </summary>
public DateTime? MinDate { get; set; }
/// <summary>
/// Gets or sets the maximum date to query for.
/// </summary>
public DateTime? MaxDate { get; set; }
/// <summary>
/// Gets or sets the name filter.
/// </summary>
public string? Name { get; set; }
/// <summary>
/// Gets or sets the overview filter.
/// </summary>
public string? Overview { get; set; }
/// <summary>
/// Gets or sets the short overview filter.
/// </summary>
public string? ShortOverview { get; set; }
/// <summary>
/// Gets or sets the type filter.
/// </summary>
public string? Type { get; set; }
/// <summary>
/// Gets or sets the item filter.
/// </summary>
public Guid? ItemId { get; set; }
/// <summary>
/// Gets or sets the username filter.
/// </summary>
public string? Username { get; set; }
/// <summary>
/// Gets or sets the log level filter.
/// </summary>
public LogLevel? Severity { get; set; }
/// <summary>
/// Gets or sets the result ordering.
/// </summary>
public IReadOnlyCollection<(ActivityLogSortBy, SortOrder)>? OrderBy { get; set; }
}

View File

@@ -1,103 +1,213 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Jellyfin.Data.Enums;
using Jellyfin.Data.Events;
using Jellyfin.Data.Queries;
using Jellyfin.Database.Implementations;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Model.Activity;
using MediaBrowser.Model.Querying;
using Microsoft.EntityFrameworkCore;
namespace Jellyfin.Server.Implementations.Activity
namespace Jellyfin.Server.Implementations.Activity;
/// <summary>
/// Manages the storage and retrieval of <see cref="ActivityLog"/> instances.
/// </summary>
public class ActivityManager : IActivityManager
{
private readonly IDbContextFactory<JellyfinDbContext> _provider;
/// <summary>
/// Manages the storage and retrieval of <see cref="ActivityLog"/> instances.
/// Initializes a new instance of the <see cref="ActivityManager"/> class.
/// </summary>
public class ActivityManager : IActivityManager
/// <param name="provider">The Jellyfin database provider.</param>
public ActivityManager(IDbContextFactory<JellyfinDbContext> provider)
{
private readonly IDbContextFactory<JellyfinDbContext> _provider;
_provider = provider;
}
/// <summary>
/// Initializes a new instance of the <see cref="ActivityManager"/> class.
/// </summary>
/// <param name="provider">The Jellyfin database provider.</param>
public ActivityManager(IDbContextFactory<JellyfinDbContext> provider)
/// <inheritdoc/>
public event EventHandler<GenericEventArgs<ActivityLogEntry>>? EntryCreated;
/// <inheritdoc/>
public async Task CreateAsync(ActivityLog entry)
{
var dbContext = await _provider.CreateDbContextAsync().ConfigureAwait(false);
await using (dbContext.ConfigureAwait(false))
{
_provider = provider;
dbContext.ActivityLogs.Add(entry);
await dbContext.SaveChangesAsync().ConfigureAwait(false);
}
/// <inheritdoc/>
public event EventHandler<GenericEventArgs<ActivityLogEntry>>? EntryCreated;
EntryCreated?.Invoke(this, new GenericEventArgs<ActivityLogEntry>(ConvertToOldModel(entry)));
}
/// <inheritdoc/>
public async Task CreateAsync(ActivityLog entry)
/// <inheritdoc/>
public async Task<QueryResult<ActivityLogEntry>> GetPagedResultAsync(ActivityLogQuery query)
{
// TODO allow sorting and filtering by item id. Currently not possible because ActivityLog stores the item id as a string.
var dbContext = await _provider.CreateDbContextAsync().ConfigureAwait(false);
await using (dbContext.ConfigureAwait(false))
{
var dbContext = await _provider.CreateDbContextAsync().ConfigureAwait(false);
await using (dbContext.ConfigureAwait(false))
// TODO switch to LeftJoin in .NET 10.
var entries = from a in dbContext.ActivityLogs
join u in dbContext.Users on a.UserId equals u.Id into ugj
from u in ugj.DefaultIfEmpty()
select new ExpandedActivityLog { ActivityLog = a, Username = u.Username };
if (query.HasUserId is not null)
{
dbContext.ActivityLogs.Add(entry);
await dbContext.SaveChangesAsync().ConfigureAwait(false);
entries = entries.Where(e => e.ActivityLog.UserId.Equals(default) != query.HasUserId.Value);
}
EntryCreated?.Invoke(this, new GenericEventArgs<ActivityLogEntry>(ConvertToOldModel(entry)));
}
/// <inheritdoc/>
public async Task<QueryResult<ActivityLogEntry>> GetPagedResultAsync(ActivityLogQuery query)
{
var dbContext = await _provider.CreateDbContextAsync().ConfigureAwait(false);
await using (dbContext.ConfigureAwait(false))
if (query.MinDate is not null)
{
var entries = dbContext.ActivityLogs
.OrderByDescending(entry => entry.DateCreated)
.Where(entry => query.MinDate == null || entry.DateCreated >= query.MinDate)
.Where(entry => !query.HasUserId.HasValue || entry.UserId.Equals(default) != query.HasUserId.Value);
return new QueryResult<ActivityLogEntry>(
query.Skip,
await entries.CountAsync().ConfigureAwait(false),
await entries
.Skip(query.Skip ?? 0)
.Take(query.Limit ?? 100)
.Select(entity => new ActivityLogEntry(entity.Name, entity.Type, entity.UserId)
{
Id = entity.Id,
Overview = entity.Overview,
ShortOverview = entity.ShortOverview,
ItemId = entity.ItemId,
Date = entity.DateCreated,
Severity = entity.LogSeverity
})
.ToListAsync()
.ConfigureAwait(false));
entries = entries.Where(e => e.ActivityLog.DateCreated >= query.MinDate.Value);
}
}
/// <inheritdoc />
public async Task CleanAsync(DateTime startDate)
{
var dbContext = await _provider.CreateDbContextAsync().ConfigureAwait(false);
await using (dbContext.ConfigureAwait(false))
if (query.MaxDate is not null)
{
await dbContext.ActivityLogs
.Where(entry => entry.DateCreated <= startDate)
.ExecuteDeleteAsync()
.ConfigureAwait(false);
entries = entries.Where(e => e.ActivityLog.DateCreated <= query.MaxDate.Value);
}
}
private static ActivityLogEntry ConvertToOldModel(ActivityLog entry)
{
return new ActivityLogEntry(entry.Name, entry.Type, entry.UserId)
if (!string.IsNullOrEmpty(query.Name))
{
Id = entry.Id,
Overview = entry.Overview,
ShortOverview = entry.ShortOverview,
ItemId = entry.ItemId,
Date = entry.DateCreated,
Severity = entry.LogSeverity
};
entries = entries.Where(e => EF.Functions.Like(e.ActivityLog.Name, $"%{query.Name}%"));
}
if (!string.IsNullOrEmpty(query.Overview))
{
entries = entries.Where(e => EF.Functions.Like(e.ActivityLog.Overview, $"%{query.Overview}%"));
}
if (!string.IsNullOrEmpty(query.ShortOverview))
{
entries = entries.Where(e => EF.Functions.Like(e.ActivityLog.ShortOverview, $"%{query.ShortOverview}%"));
}
if (!string.IsNullOrEmpty(query.Type))
{
entries = entries.Where(e => EF.Functions.Like(e.ActivityLog.Type, $"%{query.Type}%"));
}
if (!query.ItemId.IsNullOrEmpty())
{
var itemId = query.ItemId.Value.ToString("N");
entries = entries.Where(e => e.ActivityLog.ItemId == itemId);
}
if (!string.IsNullOrEmpty(query.Username))
{
entries = entries.Where(e => EF.Functions.Like(e.Username, $"%{query.Username}%"));
}
if (query.Severity is not null)
{
entries = entries.Where(e => e.ActivityLog.LogSeverity == query.Severity);
}
return new QueryResult<ActivityLogEntry>(
query.Skip,
await entries.CountAsync().ConfigureAwait(false),
await ApplyOrdering(entries, query.OrderBy)
.Skip(query.Skip ?? 0)
.Take(query.Limit ?? 100)
.Select(entity => new ActivityLogEntry(entity.ActivityLog.Name, entity.ActivityLog.Type, entity.ActivityLog.UserId)
{
Id = entity.ActivityLog.Id,
Overview = entity.ActivityLog.Overview,
ShortOverview = entity.ActivityLog.ShortOverview,
ItemId = entity.ActivityLog.ItemId,
Date = entity.ActivityLog.DateCreated,
Severity = entity.ActivityLog.LogSeverity
})
.ToListAsync()
.ConfigureAwait(false));
}
}
/// <inheritdoc />
public async Task CleanAsync(DateTime startDate)
{
var dbContext = await _provider.CreateDbContextAsync().ConfigureAwait(false);
await using (dbContext.ConfigureAwait(false))
{
await dbContext.ActivityLogs
.Where(entry => entry.DateCreated <= startDate)
.ExecuteDeleteAsync()
.ConfigureAwait(false);
}
}
private static ActivityLogEntry ConvertToOldModel(ActivityLog entry)
{
return new ActivityLogEntry(entry.Name, entry.Type, entry.UserId)
{
Id = entry.Id,
Overview = entry.Overview,
ShortOverview = entry.ShortOverview,
ItemId = entry.ItemId,
Date = entry.DateCreated,
Severity = entry.LogSeverity
};
}
private IOrderedQueryable<ExpandedActivityLog> ApplyOrdering(IQueryable<ExpandedActivityLog> query, IReadOnlyCollection<(ActivityLogSortBy, SortOrder)>? sorting)
{
if (sorting is null || sorting.Count == 0)
{
return query.OrderByDescending(e => e.ActivityLog.DateCreated);
}
IOrderedQueryable<ExpandedActivityLog> ordered = null!;
foreach (var (sortBy, sortOrder) in sorting)
{
var orderBy = MapOrderBy(sortBy);
if (ordered == null)
{
ordered = sortOrder == SortOrder.Ascending
? query.OrderBy(orderBy)
: query.OrderByDescending(orderBy);
}
else
{
ordered = sortOrder == SortOrder.Ascending
? ordered.ThenBy(orderBy)
: ordered.ThenByDescending(orderBy);
}
}
return ordered;
}
private Expression<Func<ExpandedActivityLog, object?>> MapOrderBy(ActivityLogSortBy sortBy)
{
return sortBy switch
{
ActivityLogSortBy.Name => e => e.ActivityLog.Name,
ActivityLogSortBy.Overiew => e => e.ActivityLog.Overview,
ActivityLogSortBy.ShortOverview => e => e.ActivityLog.ShortOverview,
ActivityLogSortBy.Type => e => e.ActivityLog.Type,
ActivityLogSortBy.DateCreated => e => e.ActivityLog.DateCreated,
ActivityLogSortBy.Username => e => e.Username,
ActivityLogSortBy.LogSeverity => e => e.ActivityLog.LogSeverity,
_ => throw new ArgumentOutOfRangeException(nameof(sortBy), sortBy, "Unhandled ActivityLogSortBy")
};
}
private class ExpandedActivityLog
{
public ActivityLog ActivityLog { get; set; } = null!;
public string? Username { get; set; }
}
}

View File

@@ -158,7 +158,7 @@ namespace Jellyfin.Server.Implementations.Devices
devices = devices.Skip(query.Skip.Value);
}
if (query.Limit.HasValue)
if (query.Limit.HasValue && query.Limit.Value > 0)
{
devices = devices.Take(query.Limit.Value);
}

View File

@@ -250,7 +250,7 @@ public sealed class BaseItemRepository
public QueryResult<BaseItemDto> GetItems(InternalItemsQuery filter)
{
ArgumentNullException.ThrowIfNull(filter);
if (!filter.EnableTotalRecordCount || (!filter.Limit.HasValue && (filter.StartIndex ?? 0) == 0))
if (!filter.EnableTotalRecordCount || ((filter.Limit ?? 0) == 0 && (filter.StartIndex ?? 0) == 0))
{
var returnList = GetItemList(filter);
return new QueryResult<BaseItemDto>(
@@ -275,8 +275,9 @@ public sealed class BaseItemRepository
}
dbQuery = ApplyQueryPaging(dbQuery, filter);
dbQuery = ApplyNavigations(dbQuery, filter);
result.Items = GetEntities(dbQuery, context, filter).Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)).ToArray();
result.Items = dbQuery.AsEnumerable().Where(e => e is not null).Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)).Where(dto => dto is not null).ToArray()!;
result.StartIndex = filter.StartIndex ?? 0;
return result;
}
@@ -294,8 +295,9 @@ public sealed class BaseItemRepository
dbQuery = ApplyGroupingFilter(context, dbQuery, filter);
dbQuery = ApplyQueryPaging(dbQuery, filter);
dbQuery = ApplyNavigations(dbQuery, filter);
return GetEntities(dbQuery, context, filter).Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)).ToArray();
return dbQuery.AsEnumerable().Where(e => e is not null).Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)).Where(dto => dto is not null).ToArray()!;
}
/// <inheritdoc/>
@@ -324,7 +326,7 @@ public sealed class BaseItemRepository
.OrderByDescending(g => g.MaxDateCreated)
.Select(g => g);
if (filter.Limit.HasValue)
if (filter.Limit.HasValue && filter.Limit.Value > 0)
{
subqueryGrouped = subqueryGrouped.Take(filter.Limit.Value);
}
@@ -337,7 +339,9 @@ public sealed class BaseItemRepository
mainquery = ApplyGroupingFilter(context, mainquery, filter);
mainquery = ApplyQueryPaging(mainquery, filter);
return GetEntities(mainquery, context, filter).Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)).ToArray();
mainquery = ApplyNavigations(mainquery, filter);
return mainquery.AsEnumerable().Where(e => e is not null).Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)).Where(dto => dto is not null).ToArray()!;
}
/// <inheritdoc />
@@ -363,7 +367,7 @@ public sealed class BaseItemRepository
.OrderByDescending(g => g.LastPlayedDate)
.Select(g => g.Key!);
if (filter.Limit.HasValue)
if (filter.Limit.HasValue && filter.Limit.Value > 0)
{
query = query.Take(filter.Limit.Value);
}
@@ -404,21 +408,46 @@ public sealed class BaseItemRepository
return dbQuery;
}
private static IQueryable<BaseItemEntity> ApplyNavigations(IQueryable<BaseItemEntity> dbQuery, InternalItemsQuery filter)
{
if (filter.TrailerTypes.Length > 0 || filter.IncludeItemTypes.Contains(BaseItemKind.Trailer))
{
dbQuery = dbQuery.Include(e => e.TrailerTypes);
}
if (filter.DtoOptions.ContainsField(ItemFields.ProviderIds))
{
dbQuery = dbQuery.Include(e => e.Provider);
}
if (filter.DtoOptions.ContainsField(ItemFields.Settings))
{
dbQuery = dbQuery.Include(e => e.LockedFields);
}
if (filter.DtoOptions.EnableUserData)
{
dbQuery = dbQuery.Include(e => e.UserData);
}
if (filter.DtoOptions.EnableImages)
{
dbQuery = dbQuery.Include(e => e.Images);
}
return dbQuery;
}
private IQueryable<BaseItemEntity> ApplyQueryPaging(IQueryable<BaseItemEntity> dbQuery, InternalItemsQuery filter)
{
if (filter.Limit.HasValue || filter.StartIndex.HasValue)
if (filter.StartIndex.HasValue && filter.StartIndex.Value > 0)
{
var offset = filter.StartIndex ?? 0;
dbQuery = dbQuery.Skip(filter.StartIndex.Value);
}
if (offset > 0)
{
dbQuery = dbQuery.Skip(offset);
}
if (filter.Limit.HasValue)
{
dbQuery = dbQuery.Take(filter.Limit.Value);
}
if (filter.Limit.HasValue && filter.Limit.Value > 0)
{
dbQuery = dbQuery.Take(filter.Limit.Value);
}
return dbQuery;
@@ -429,6 +458,7 @@ public sealed class BaseItemRepository
dbQuery = TranslateQuery(dbQuery, context, filter);
dbQuery = ApplyGroupingFilter(context, dbQuery, filter);
dbQuery = ApplyQueryPaging(dbQuery, filter);
dbQuery = ApplyNavigations(dbQuery, filter);
return dbQuery;
}
@@ -440,79 +470,6 @@ public sealed class BaseItemRepository
return dbQuery;
}
private IReadOnlyList<BaseItemEntity> GetEntities(IQueryable<BaseItemEntity> dbQuery, JellyfinDbContext context, InternalItemsQuery filter)
{
var items = dbQuery.Where(e => e != null).ToDictionary(e => e.Id, e => e);
var itemIds = items.Keys.ToArray();
if (itemIds.Length == 0)
{
return [];
}
if (filter.TrailerTypes.Length > 0 || filter.IncludeItemTypes.Contains(BaseItemKind.Trailer))
{
var values = context.BaseItemTrailerTypes.WhereOneOrMany(itemIds, e => e.ItemId).GroupBy(x => x.ItemId).ToArray();
foreach (var value in values)
{
if (items.TryGetValue(value.Key, out var item))
{
item.TrailerTypes = value.ToArray();
}
}
}
if (filter.DtoOptions.ContainsField(ItemFields.ProviderIds))
{
var values = context.BaseItemProviders.WhereOneOrMany(itemIds, e => e.ItemId).GroupBy(x => x.ItemId).ToArray();
foreach (var value in values)
{
if (items.TryGetValue(value.Key, out var item))
{
item.Provider = value.ToArray();
}
}
}
if (filter.DtoOptions.ContainsField(ItemFields.Settings))
{
var values = context.BaseItemMetadataFields.WhereOneOrMany(itemIds, e => e.ItemId).GroupBy(x => x.ItemId).ToArray();
foreach (var value in values)
{
if (items.TryGetValue(value.Key, out var item))
{
item.LockedFields = value.ToArray();
}
}
}
if (filter.DtoOptions.EnableImages)
{
var values = context.BaseItemImageInfos.WhereOneOrMany(itemIds, e => e.ItemId).GroupBy(x => x.ItemId).ToArray();
foreach (var value in values)
{
if (items.TryGetValue(value.Key, out var item))
{
item.Images = value.ToArray();
}
}
}
if (filter.DtoOptions.EnableUserData)
{
var values = context.UserData.WhereOneOrMany(itemIds, e => e.ItemId).GroupBy(x => x.ItemId).ToArray();
foreach (var value in values)
{
if (items.TryGetValue(value.Key, out var item))
{
item.UserData = value.ToArray();
}
}
}
return items.Values.ToArray();
}
/// <inheritdoc/>
public int GetCount(InternalItemsQuery filter)
{
@@ -605,22 +562,34 @@ public sealed class BaseItemRepository
}
/// <inheritdoc />
public void SaveImages(BaseItemDto item)
public async Task SaveImagesAsync(BaseItemDto item, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(item);
var images = item.ImageInfos.Select(e => Map(item.Id, e));
using var context = _dbProvider.CreateDbContext();
var images = item.ImageInfos.Select(e => Map(item.Id, e)).ToArray();
if (!context.BaseItems.Any(bi => bi.Id == item.Id))
var context = await _dbProvider.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
await using (context.ConfigureAwait(false))
{
_logger.LogWarning("Unable to save ImageInfo for non existing BaseItem");
return;
}
if (!await context.BaseItems
.AnyAsync(bi => bi.Id == item.Id, cancellationToken)
.ConfigureAwait(false))
{
_logger.LogWarning("Unable to save ImageInfo for non existing BaseItem");
return;
}
context.BaseItemImageInfos.Where(e => e.ItemId == item.Id).ExecuteDelete();
context.BaseItemImageInfos.AddRange(images);
context.SaveChanges();
await context.BaseItemImageInfos
.Where(e => e.ItemId == item.Id)
.ExecuteDeleteAsync(cancellationToken)
.ConfigureAwait(false);
await context.BaseItemImageInfos
.AddRangeAsync(images, cancellationToken)
.ConfigureAwait(false);
await context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
}
}
/// <inheritdoc />
@@ -1190,7 +1159,7 @@ public sealed class BaseItemRepository
return type.GetCustomAttribute<RequiresSourceSerialisationAttribute>() == null;
}
private BaseItemDto DeserializeBaseItem(BaseItemEntity baseItemEntity, bool skipDeserialization = false)
private BaseItemDto? DeserializeBaseItem(BaseItemEntity baseItemEntity, bool skipDeserialization = false)
{
ArgumentNullException.ThrowIfNull(baseItemEntity, nameof(baseItemEntity));
if (_serverConfigurationManager?.Configuration is null)
@@ -1213,11 +1182,19 @@ public sealed class BaseItemRepository
/// <param name="logger">Logger.</param>
/// <param name="appHost">The application server Host.</param>
/// <param name="skipDeserialization">If only mapping should be processed.</param>
/// <returns>A mapped BaseItem.</returns>
/// <exception cref="InvalidOperationException">Will be thrown if an invalid serialisation is requested.</exception>
public static BaseItemDto DeserializeBaseItem(BaseItemEntity baseItemEntity, ILogger logger, IServerApplicationHost? appHost, bool skipDeserialization = false)
/// <returns>A mapped BaseItem, or null if the item type is unknown.</returns>
public static BaseItemDto? DeserializeBaseItem(BaseItemEntity baseItemEntity, ILogger logger, IServerApplicationHost? appHost, bool skipDeserialization = false)
{
var type = GetType(baseItemEntity.Type) ?? throw new InvalidOperationException("Cannot deserialize unknown type.");
var type = GetType(baseItemEntity.Type);
if (type is null)
{
logger.LogWarning(
"Skipping item {ItemId} with unknown type '{ItemType}'. This may indicate a removed plugin or database corruption.",
baseItemEntity.Id,
baseItemEntity.Type);
return null;
}
BaseItemDto? dto = null;
if (TypeRequiresDeserialization(type) && baseItemEntity.Data is not null && !skipDeserialization)
{
@@ -1243,7 +1220,7 @@ public sealed class BaseItemRepository
{
ArgumentNullException.ThrowIfNull(filter);
if (!filter.Limit.HasValue)
if (!(filter.Limit.HasValue && filter.Limit.Value > 0))
{
filter.EnableTotalRecordCount = false;
}
@@ -1322,19 +1299,14 @@ public sealed class BaseItemRepository
result.TotalRecordCount = query.Count();
}
if (filter.Limit.HasValue || filter.StartIndex.HasValue)
if (filter.StartIndex.HasValue && filter.StartIndex.Value > 0)
{
var offset = filter.StartIndex ?? 0;
query = query.Skip(filter.StartIndex.Value);
}
if (offset > 0)
{
query = query.Skip(offset);
}
if (filter.Limit.HasValue)
{
query = query.Take(filter.Limit.Value);
}
if (filter.Limit.HasValue && filter.Limit.Value > 0)
{
query = query.Take(filter.Limit.Value);
}
IQueryable<BaseItemEntity>? itemCountQuery = null;
@@ -1389,10 +1361,9 @@ public sealed class BaseItemRepository
.. resultQuery
.AsEnumerable()
.Where(e => e is not null)
.Select(e =>
{
return (DeserializeBaseItem(e.item, filter.SkipDeserialization), e.itemCount);
})
.Select(e => (Item: DeserializeBaseItem(e.item, filter.SkipDeserialization), e.itemCount))
.Where(e => e.Item is not null)
.Select(e => (e.Item!, e.itemCount))
];
}
else
@@ -1403,10 +1374,9 @@ public sealed class BaseItemRepository
.. query
.AsEnumerable()
.Where(e => e is not null)
.Select<BaseItemEntity, (BaseItemDto, ItemCounts?)>(e =>
{
return (DeserializeBaseItem(e, filter.SkipDeserialization), null);
})
.Select(e => (Item: DeserializeBaseItem(e, filter.SkipDeserialization), ItemCounts: (ItemCounts?)null))
.Where(e => e.Item is not null)
.Select(e => (e.Item!, e.ItemCounts))
];
}
@@ -1415,7 +1385,7 @@ public sealed class BaseItemRepository
private static void PrepareFilterQuery(InternalItemsQuery query)
{
if (query.Limit.HasValue && query.EnableGroupByMetadataKey)
if (query.Limit.HasValue && query.Limit.Value > 0 && query.EnableGroupByMetadataKey)
{
query.Limit = query.Limit.Value + 4;
}
@@ -1426,14 +1396,54 @@ public sealed class BaseItemRepository
}
}
private string GetCleanValue(string value)
/// <summary>
/// Gets the clean value for search and sorting purposes.
/// </summary>
/// <param name="value">The value to clean.</param>
/// <returns>The cleaned value.</returns>
public static string GetCleanValue(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
return value;
}
return value.RemoveDiacritics().ToLowerInvariant();
var noDiacritics = value.RemoveDiacritics();
// Build a string where any punctuation or symbol is treated as a separator (space).
var sb = new StringBuilder(noDiacritics.Length);
var previousWasSpace = false;
foreach (var ch in noDiacritics)
{
char outCh;
if (char.IsLetterOrDigit(ch) || char.IsWhiteSpace(ch))
{
outCh = ch;
}
else
{
outCh = ' ';
}
// normalize any whitespace character to a single ASCII space.
if (char.IsWhiteSpace(outCh))
{
if (!previousWasSpace)
{
sb.Append(' ');
previousWasSpace = true;
}
}
else
{
sb.Append(outCh);
previousWasSpace = false;
}
}
// trim leading/trailing spaces that may have been added.
var collapsed = sb.ToString().Trim();
return collapsed.ToLowerInvariant();
}
private List<(ItemValueType MagicNumber, string Value)> GetItemValuesToSave(BaseItemDto item, List<string> inheritedTags)
@@ -2485,35 +2495,24 @@ public sealed class BaseItemRepository
if (filter.ExcludeInheritedTags.Length > 0)
{
var excludedTags = filter.ExcludeInheritedTags;
baseQuery = baseQuery.Where(e =>
!e.ItemValues!.Any(f => f.ItemValue.Type == ItemValueType.Tags && filter.ExcludeInheritedTags.Contains(f.ItemValue.CleanValue))
&& (e.Type != _itemTypeLookup.BaseItemKindNames[BaseItemKind.Episode] || !e.SeriesId.HasValue ||
!context.ItemValuesMap.Any(f => f.ItemId == e.SeriesId.Value && f.ItemValue.Type == ItemValueType.Tags && filter.ExcludeInheritedTags.Contains(f.ItemValue.CleanValue))));
!e.ItemValues!.Any(f => f.ItemValue.Type == ItemValueType.Tags && excludedTags.Contains(f.ItemValue.CleanValue))
&& (!e.SeriesId.HasValue || !context.ItemValuesMap.Any(f => f.ItemId == e.SeriesId.Value && f.ItemValue.Type == ItemValueType.Tags && excludedTags.Contains(f.ItemValue.CleanValue))));
}
if (filter.IncludeInheritedTags.Length > 0)
{
// For seasons and episodes, we also need to check the parent series' tags.
if (includeTypes.Any(t => t == BaseItemKind.Episode || t == BaseItemKind.Season))
{
baseQuery = baseQuery.Where(e =>
e.ItemValues!.Any(f => f.ItemValue.Type == ItemValueType.Tags && filter.IncludeInheritedTags.Contains(f.ItemValue.CleanValue))
|| (e.SeriesId.HasValue && context.ItemValuesMap.Any(f => f.ItemId == e.SeriesId.Value && f.ItemValue.Type == ItemValueType.Tags && filter.IncludeInheritedTags.Contains(f.ItemValue.CleanValue))));
}
var includeTags = filter.IncludeInheritedTags;
var isPlaylistOnlyQuery = includeTypes.Length == 1 && includeTypes.FirstOrDefault() == BaseItemKind.Playlist;
baseQuery = baseQuery.Where(e =>
e.ItemValues!.Any(f => f.ItemValue.Type == ItemValueType.Tags && includeTags.Contains(f.ItemValue.CleanValue))
// A playlist should be accessible to its owner regardless of allowed tags.
else if (includeTypes.Length == 1 && includeTypes.FirstOrDefault() is BaseItemKind.Playlist)
{
baseQuery = baseQuery.Where(e =>
e.ItemValues!.Any(f => f.ItemValue.Type == ItemValueType.Tags && filter.IncludeInheritedTags.Contains(f.ItemValue.CleanValue))
|| e.Data!.Contains($"OwnerUserId\":\"{filter.User!.Id:N}\""));
// d ^^ this is stupid it hate this.
}
else
{
baseQuery = baseQuery.Where(e =>
e.ItemValues!.Any(f => f.ItemValue.Type == ItemValueType.Tags && filter.IncludeInheritedTags.Contains(f.ItemValue.CleanValue)));
}
// For seasons and episodes, we also need to check the parent series' tags.
|| (e.SeriesId.HasValue && context.ItemValuesMap.Any(f => f.ItemId == e.SeriesId.Value && f.ItemValue.Type == ItemValueType.Tags && includeTags.Contains(f.ItemValue.CleanValue)))
// A playlist should be accessible to its owner regardless of allowed tags
|| (isPlaylistOnlyQuery && e.Data!.Contains($"OwnerUserId\":\"{filter.User!.Id:N}\"")));
}
if (filter.SeriesStatuses.Length > 0)
@@ -2667,6 +2666,6 @@ public sealed class BaseItemRepository
.Where(e => artistNames.Contains(e.Name))
.ToArray();
return artists.GroupBy(e => e.Name).ToDictionary(e => e.Key!, e => e.Select(f => DeserializeBaseItem(f)).Cast<MusicArtist>().ToArray());
return artists.GroupBy(e => e.Name).ToDictionary(e => e.Key!, e => e.Select(f => DeserializeBaseItem(f)).Where(dto => dto is not null).Cast<MusicArtist>().ToArray());
}
}

View File

@@ -59,7 +59,7 @@ namespace Jellyfin.Server.Implementations.Users
}
// As long as jellyfin supports password-less users, we need this little block here to accommodate
if (!HasPassword(resolvedUser) && string.IsNullOrEmpty(password))
if (string.IsNullOrEmpty(resolvedUser.Password) && string.IsNullOrEmpty(password))
{
return Task.FromResult(new ProviderAuthenticationResult
{
@@ -93,10 +93,6 @@ namespace Jellyfin.Server.Implementations.Users
});
}
/// <inheritdoc />
public bool HasPassword(User user)
=> !string.IsNullOrEmpty(user?.Password);
/// <inheritdoc />
public Task ChangePassword(User user, string newPassword)
{

View File

@@ -21,12 +21,6 @@ namespace Jellyfin.Server.Implementations.Users
throw new AuthenticationException("User Account cannot login with this provider. The Normal provider for this user cannot be found");
}
/// <inheritdoc />
public bool HasPassword(User user)
{
return true;
}
/// <inheritdoc />
public Task ChangePassword(User user, string newPassword)
{

View File

@@ -306,15 +306,12 @@ namespace Jellyfin.Server.Implementations.Users
/// <inheritdoc/>
public UserDto GetUserDto(User user, string? remoteEndPoint = null)
{
var hasPassword = GetAuthenticationProvider(user).HasPassword(user);
var castReceiverApplications = _serverConfigurationManager.Configuration.CastReceiverApplications;
return new UserDto
{
Name = user.Username,
Id = user.Id,
ServerId = _appHost.SystemId,
HasPassword = hasPassword,
HasConfiguredPassword = hasPassword,
EnableAutoLogin = user.EnableAutoLogin,
LastLoginDate = user.LastLoginDate,
LastActivityDate = user.LastActivityDate,

View File

@@ -117,18 +117,5 @@ namespace Jellyfin.Server.Extensions
{
return appBuilder.UseMiddleware<RobotsRedirectionMiddleware>();
}
/// <summary>
/// Adds /emby and /mediabrowser route trimming to the application pipeline.
/// </summary>
/// <remarks>
/// This must be injected before any path related middleware.
/// </remarks>
/// <param name="appBuilder">The application builder.</param>
/// <returns>The updated application builder.</returns>
public static IApplicationBuilder UsePathTrim(this IApplicationBuilder appBuilder)
{
return appBuilder.UseMiddleware<LegacyEmbyRouteRewriteMiddleware>();
}
}
}

View File

@@ -255,6 +255,7 @@ namespace Jellyfin.Server.Extensions
c.AddSwaggerTypeMappings();
c.SchemaFilter<IgnoreEnumSchemaFilter>();
c.SchemaFilter<FlagsEnumSchemaFilter>();
c.OperationFilter<RetryOnTemporarilyUnavailableFilter>();
c.OperationFilter<SecurityRequirementsOperationFilter>();
c.OperationFilter<FileResponseFilter>();
@@ -342,25 +343,6 @@ namespace Jellyfin.Server.Extensions
}
});
/*
* Support BlurHash dictionary
*/
options.MapType<Dictionary<ImageType, Dictionary<string, string>>>(() =>
new OpenApiSchema
{
Type = "object",
Properties = typeof(ImageType).GetEnumNames().ToDictionary(
name => name,
_ => new OpenApiSchema
{
Type = "object",
AdditionalProperties = new OpenApiSchema
{
Type = "string"
}
})
});
// Support dictionary with nullable string value.
options.MapType<Dictionary<string, string?>>(() =>
new OpenApiSchema
@@ -373,21 +355,6 @@ namespace Jellyfin.Server.Extensions
}
});
// Manually describe Flags enum.
options.MapType<TranscodeReason>(() =>
new OpenApiSchema
{
Type = "array",
Items = new OpenApiSchema
{
Reference = new OpenApiReference
{
Id = nameof(TranscodeReason),
Type = ReferenceType.Schema,
}
}
});
// Swashbuckle doesn't use JsonOptions to describe responses, so we need to manually describe it.
options.MapType<Version>(() => new OpenApiSchema
{

View File

@@ -225,15 +225,6 @@ namespace Jellyfin.Server.Filters
context.SchemaGenerator.GenerateSchema(configuration.ConfigurationType, context.SchemaRepository);
}
context.SchemaRepository.AddDefinition(nameof(TranscodeReason), new OpenApiSchema
{
Type = "string",
Enum = Enum.GetNames<TranscodeReason>()
.Select(e => new OpenApiString(e))
.Cast<IOpenApiAny>()
.ToArray()
});
}
}
}

View File

@@ -1,7 +1,8 @@
using System;
using System.Threading;
using AsyncKeyedLock;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Swagger;
@@ -17,12 +18,13 @@ internal sealed class CachingOpenApiProvider : ISwaggerProvider
private const string CacheKey = "openapi.json";
private static readonly MemoryCacheEntryOptions _cacheOptions = new() { SlidingExpiration = TimeSpan.FromMinutes(5) };
private static readonly SemaphoreSlim _lock = new(1, 1);
private static readonly AsyncNonKeyedLocker _lock = new(1);
private static readonly TimeSpan _lockTimeout = TimeSpan.FromSeconds(1);
private readonly IMemoryCache _memoryCache;
private readonly SwaggerGenerator _swaggerGenerator;
private readonly SwaggerGeneratorOptions _swaggerGeneratorOptions;
private readonly ILogger<CachingOpenApiProvider> _logger;
/// <summary>
/// Initializes a new instance of the <see cref="CachingOpenApiProvider"/> class.
@@ -31,15 +33,18 @@ internal sealed class CachingOpenApiProvider : ISwaggerProvider
/// <param name="apiDescriptionsProvider">The api descriptions provider.</param>
/// <param name="schemaGenerator">The schema generator.</param>
/// <param name="memoryCache">The memory cache.</param>
/// <param name="logger">The logger.</param>
public CachingOpenApiProvider(
IOptions<SwaggerGeneratorOptions> optionsAccessor,
IApiDescriptionGroupCollectionProvider apiDescriptionsProvider,
ISchemaGenerator schemaGenerator,
IMemoryCache memoryCache)
IMemoryCache memoryCache,
ILogger<CachingOpenApiProvider> logger)
{
_swaggerGeneratorOptions = optionsAccessor.Value;
_swaggerGenerator = new SwaggerGenerator(_swaggerGeneratorOptions, apiDescriptionsProvider, schemaGenerator);
_memoryCache = memoryCache;
_logger = logger;
}
/// <inheritdoc />
@@ -50,30 +55,29 @@ internal sealed class CachingOpenApiProvider : ISwaggerProvider
return AdjustDocument(openApiDocument, host, basePath);
}
var acquired = _lock.Wait(_lockTimeout);
try
using var acquired = _lock.LockOrNull(_lockTimeout);
if (_memoryCache.TryGetValue(CacheKey, out openApiDocument) && openApiDocument is not null)
{
if (_memoryCache.TryGetValue(CacheKey, out openApiDocument) && openApiDocument is not null)
{
return AdjustDocument(openApiDocument, host, basePath);
}
if (!acquired)
{
throw new InvalidOperationException("OpenApi document is generating");
}
openApiDocument = _swaggerGenerator.GetSwagger(documentName);
_memoryCache.Set(CacheKey, openApiDocument, _cacheOptions);
return AdjustDocument(openApiDocument, host, basePath);
}
finally
if (acquired is null)
{
if (acquired)
{
_lock.Release();
}
throw new InvalidOperationException("OpenApi document is generating");
}
try
{
openApiDocument = _swaggerGenerator.GetSwagger(documentName);
}
catch (Exception ex)
{
_logger.LogError(ex, "OpenAPI generation error");
throw;
}
_memoryCache.Set(CacheKey, openApiDocument, _cacheOptions);
return AdjustDocument(openApiDocument, host, basePath);
}
private OpenApiDocument AdjustDocument(OpenApiDocument document, string? host, string? basePath)

View File

@@ -0,0 +1,53 @@
using System;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace Jellyfin.Server.Filters;
/// <summary>
/// Schema filter to ensure flags enums are represented correctly in OpenAPI.
/// </summary>
/// <remarks>
/// For flags enums:
/// - The enum schema definition is set to type "string" (not integer).
/// - Properties using flags enums are transformed to arrays referencing the enum schema.
/// </remarks>
public class FlagsEnumSchemaFilter : ISchemaFilter
{
/// <inheritdoc />
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
var type = context.Type.IsEnum ? context.Type : Nullable.GetUnderlyingType(context.Type);
if (type is null || !type.IsEnum)
{
return;
}
// Check if enum has [Flags] attribute
if (!type.IsDefined(typeof(FlagsAttribute), false))
{
return;
}
if (context.MemberInfo is null)
{
// Processing the enum definition itself - ensure it's type "string" not "integer"
schema.Type = "string";
schema.Format = null;
}
else
{
// Processing a property that uses the flags enum - transform to array
// Generate the enum schema to ensure it exists in the repository
var enumSchema = context.SchemaGenerator.GenerateSchema(type, context.SchemaRepository);
// Flags enums should be represented as arrays referencing the enum schema
// since multiple values can be combined
schema.Type = "array";
schema.Format = null;
schema.Enum = null;
schema.AllOf = null;
schema.Items = enumSchema;
}
}
}

View File

@@ -0,0 +1,32 @@
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Configuration;
namespace Jellyfin.Server.Migrations.Routines;
/// <summary>
/// Migration to disable legacy authorization in the system config.
/// </summary>
[JellyfinMigration("2025-11-18T16:00:00", nameof(DisableLegacyAuthorization))]
public class DisableLegacyAuthorization : IAsyncMigrationRoutine
{
private readonly IServerConfigurationManager _serverConfigurationManager;
/// <summary>
/// Initializes a new instance of the <see cref="DisableLegacyAuthorization"/> class.
/// </summary>
/// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
public DisableLegacyAuthorization(IServerConfigurationManager serverConfigurationManager)
{
_serverConfigurationManager = serverConfigurationManager;
}
/// <inheritdoc />
public Task PerformAsync(CancellationToken cancellationToken)
{
_serverConfigurationManager.Configuration.EnableLegacyAuthorization = false;
_serverConfigurationManager.SaveConfiguration();
return Task.CompletedTask;
}
}

View File

@@ -1247,8 +1247,11 @@ internal class MigrateLibraryDb : IDatabaseMigrationRoutine
}
var baseItem = BaseItemRepository.DeserializeBaseItem(entity, _logger, null, false);
var dataKeys = baseItem.GetUserDataKeys();
userDataKeys.AddRange(dataKeys);
if (baseItem is not null)
{
var dataKeys = baseItem.GetUserDataKeys();
userDataKeys.AddRange(dataKeys);
}
return (entity, userDataKeys.ToArray());
}

View File

@@ -0,0 +1,105 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Database.Implementations;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Extensions;
using Jellyfin.Server.Implementations.Item;
using Jellyfin.Server.ServerSetupApp;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace Jellyfin.Server.Migrations.Routines;
/// <summary>
/// Migration to refresh CleanName values for all library items.
/// </summary>
[JellyfinMigration("2025-10-08T12:00:00", nameof(RefreshCleanNames))]
[JellyfinMigrationBackup(JellyfinDb = true)]
public class RefreshCleanNames : IAsyncMigrationRoutine
{
private readonly IStartupLogger<RefreshCleanNames> _logger;
private readonly IDbContextFactory<JellyfinDbContext> _dbProvider;
/// <summary>
/// Initializes a new instance of the <see cref="RefreshCleanNames"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
/// <param name="dbProvider">Instance of the <see cref="IDbContextFactory{JellyfinDbContext}"/> interface.</param>
public RefreshCleanNames(
IStartupLogger<RefreshCleanNames> logger,
IDbContextFactory<JellyfinDbContext> dbProvider)
{
_logger = logger;
_dbProvider = dbProvider;
}
/// <inheritdoc />
public async Task PerformAsync(CancellationToken cancellationToken)
{
const int Limit = 1000;
int itemCount = 0;
var sw = Stopwatch.StartNew();
using var context = _dbProvider.CreateDbContext();
var records = context.BaseItems.Count(b => !string.IsNullOrEmpty(b.Name));
_logger.LogInformation("Refreshing CleanName for {Count} library items", records);
var processedInPartition = 0;
await foreach (var item in context.BaseItems
.Where(b => !string.IsNullOrEmpty(b.Name))
.OrderBy(e => e.Id)
.WithPartitionProgress((partition) => _logger.LogInformation("Processed: {Offset}/{Total} - Updated: {UpdatedCount} - Time: {Elapsed}", partition * Limit, records, itemCount, sw.Elapsed))
.PartitionEagerAsync(Limit, cancellationToken)
.WithCancellation(cancellationToken)
.ConfigureAwait(false))
{
try
{
var newCleanName = string.IsNullOrWhiteSpace(item.Name) ? string.Empty : BaseItemRepository.GetCleanValue(item.Name);
if (!string.Equals(newCleanName, item.CleanName, StringComparison.Ordinal))
{
_logger.LogDebug(
"Updating CleanName for item {Id}: '{OldValue}' -> '{NewValue}'",
item.Id,
item.CleanName,
newCleanName);
item.CleanName = newCleanName;
itemCount++;
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to update CleanName for item {Id} ({Name})", item.Id, item.Name);
}
processedInPartition++;
if (processedInPartition >= Limit)
{
await context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
// Clear tracked entities to avoid memory growth across partitions
context.ChangeTracker.Clear();
processedInPartition = 0;
}
}
// Save any remaining changes after the loop
if (processedInPartition > 0)
{
await context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
context.ChangeTracker.Clear();
}
_logger.LogInformation(
"Refreshed CleanName for {UpdatedCount} out of {TotalCount} items in {Time}",
itemCount,
records,
sw.Elapsed);
}
}

View File

@@ -11,7 +11,7 @@
{
"Name": "Console",
"Args": {
"outputTemplate": "[{Timestamp:HH:mm:ss}] [{Level:u3}] [{ThreadId}] {SourceContext}: {Message:lj}{NewLine}{Exception}"
"outputTemplate": "[{Timestamp:HH:mm:ss.fff}] [{Level:u3}] [{ThreadId}] {SourceContext}: {Message:lj}{NewLine}{Exception}"
}
},
{

View File

@@ -249,6 +249,7 @@ public sealed class SetupServer : IDisposable
{
{ "isInReportingMode", _isUnhealthy },
{ "retryValue", retryAfterValue },
{ "version", typeof(Emby.Server.Implementations.ApplicationHost).Assembly.GetName().Version! },
{ "logs", startupLogEntries },
{ "networkManagerReady", networkManager is not null },
{ "localNetworkRequest", networkManager is not null && context.Connection.RemoteIpAddress is not null && networkManager.IsInLocalNetwork(context.Connection.RemoteIpAddress) }

View File

@@ -173,7 +173,7 @@
<header class="flex-row">
{{^IF isInReportingMode}}
<p>Jellyfin Server still starting. Please wait.</p>
<p>Jellyfin Server {{version}} still starting. Please wait.</p>
{{#ELSE}}
<p>Jellyfin Server has encountered an error and was not able to start.</p>
{{/ELSE}}

View File

@@ -173,9 +173,6 @@ namespace Jellyfin.Server
mainApp.UseHttpsRedirection();
}
// This must be injected before any path related middleware.
mainApp.UsePathTrim();
if (appConfig.HostWebClient())
{
var extensionProvider = new FileExtensionContentTypeProvider();

View File

@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30503.244
# Visual Studio Version 18
VisualStudioVersion = 18.0.11222.15 d18.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jellyfin.Server", "Jellyfin.Server\Jellyfin.Server.csproj", "{07E39F42-A2C6-4B32-AF8C-725F957A73FF}"
EndProject
@@ -30,6 +30,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{41093F42-C7CC-4D07-956B-6182CBEDE2EC}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
Directory.Packages.props = Directory.Packages.props
SharedVersion.cs = SharedVersion.cs
EndProjectSection
EndProject

View File

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<!-- ProjectGuid is only included as a requirement for SonarQube analysis -->
<PropertyGroup>
@@ -8,7 +8,7 @@
<PropertyGroup>
<Authors>Jellyfin Contributors</Authors>
<PackageId>Jellyfin.Common</PackageId>
<VersionPrefix>10.11.4</VersionPrefix>
<VersionPrefix>10.12.0</VersionPrefix>
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
</PropertyGroup>

View File

@@ -14,8 +14,6 @@ namespace MediaBrowser.Controller.Authentication
Task<ProviderAuthenticationResult> Authenticate(string username, string password);
bool HasPassword(User user);
Task ChangePassword(User user, string newPassword);
}

View File

@@ -214,7 +214,7 @@ namespace MediaBrowser.Controller.Entities.TV
query.AncestorWithPresentationUniqueKey = null;
query.SeriesPresentationUniqueKey = seriesKey;
query.IncludeItemTypes = new[] { BaseItemKind.Season };
query.OrderBy = new[] { (ItemSortBy.IndexNumber, SortOrder.Ascending) };
query.OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) };
if (user is not null && !user.DisplayMissingEpisodes)
{
@@ -247,6 +247,10 @@ namespace MediaBrowser.Controller.Entities.TV
query.AncestorWithPresentationUniqueKey = null;
query.SeriesPresentationUniqueKey = seriesKey;
if (query.OrderBy.Count == 0)
{
query.OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) };
}
if (query.IncludeItemTypes.Length == 0)
{

View File

@@ -455,7 +455,7 @@ namespace MediaBrowser.Controller.Entities
var itemsArray = totalRecordLimit.HasValue ? items.Take(totalRecordLimit.Value).ToArray() : items.ToArray();
var totalCount = itemsArray.Length;
if (query.Limit.HasValue)
if (query.Limit.HasValue && query.Limit.Value > 0)
{
itemsArray = itemsArray.Skip(query.StartIndex ?? 0).Take(query.Limit.Value).ToArray();
}

View File

@@ -8,7 +8,7 @@
<PropertyGroup>
<Authors>Jellyfin Contributors</Authors>
<PackageId>Jellyfin.Controller</PackageId>
<VersionPrefix>10.11.4</VersionPrefix>
<VersionPrefix>10.12.0</VersionPrefix>
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
</PropertyGroup>

View File

@@ -6359,6 +6359,21 @@ namespace MediaBrowser.Controller.MediaEncoding
}
}
// Block unsupported H.264 Hi422P and Hi444PP profiles, which can be encoded with 4:2:0 pixel format
if (string.Equals(videoStream.Codec, "h264", StringComparison.OrdinalIgnoreCase))
{
if (videoStream.Profile.Contains("4:2:2", StringComparison.OrdinalIgnoreCase)
|| videoStream.Profile.Contains("4:4:4", StringComparison.OrdinalIgnoreCase))
{
// VideoToolbox on Apple Silicon has H.264 Hi444PP and theoretically also has Hi422P
if (!(hardwareAccelerationType == HardwareAccelerationType.videotoolbox
&& RuntimeInformation.OSArchitecture.Equals(Architecture.Arm64)))
{
return null;
}
}
}
var decoder = hardwareAccelerationType switch
{
HardwareAccelerationType.vaapi => GetVaapiVidDecoder(state, options, videoStream, bitDepth),

Some files were not shown because too many files have changed in this diff Show More