mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-05-04 18:09:12 +03:00
Compare commits
411 Commits
release-10
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6d73ae367 | ||
|
|
2068be1221 | ||
|
|
bdfb6edfa3 | ||
|
|
25e8c6d591 | ||
|
|
c11c33e1a8 | ||
|
|
e8232d31ab | ||
|
|
b456afe00e | ||
|
|
01b3c6f902 | ||
|
|
56a469d8c3 | ||
|
|
2dfebb51be | ||
|
|
716f4c8198 | ||
|
|
9da046abc1 | ||
|
|
01eb56f047 | ||
|
|
94dcaf2ea2 | ||
|
|
37b50fe13c | ||
|
|
6829794aa0 | ||
|
|
06a6c6e16b | ||
|
|
daf88a5ca2 | ||
|
|
b346370dfc | ||
|
|
fc6419685c | ||
|
|
04ffbe5e9a | ||
|
|
d0809ce58b | ||
|
|
a56aa2dd53 | ||
|
|
1311f66f72 | ||
|
|
217068eeb7 | ||
|
|
44d55f7fa3 | ||
|
|
29582ed461 | ||
|
|
ca6d499680 | ||
|
|
3b69859867 | ||
|
|
c1c7de6a81 | ||
|
|
7bcbe20641 | ||
|
|
2edf23bb40 | ||
|
|
074aa7e639 | ||
|
|
a37e83d448 | ||
|
|
d8543351e2 | ||
|
|
dce91cf8c8 | ||
|
|
48e456903e | ||
|
|
2757c18312 | ||
|
|
a1117a1fbd | ||
|
|
f685a65241 | ||
|
|
e73ebc9741 | ||
|
|
18a1cd388a | ||
|
|
6fff4a7bfa | ||
|
|
5aad260767 | ||
|
|
8b5914001d | ||
|
|
5eaaad660d | ||
|
|
de36952f53 | ||
|
|
6b8400cc3d | ||
|
|
a0bf5199ba | ||
|
|
01264c10a6 | ||
|
|
558b31f386 | ||
|
|
5656df4339 | ||
|
|
fa4d51c5e6 | ||
|
|
21bb702fd3 | ||
|
|
4a494271dd | ||
|
|
1f6768178a | ||
|
|
fead4acae1 | ||
|
|
ccd042750d | ||
|
|
e4619556ba | ||
|
|
9f2dc178f5 | ||
|
|
4c751e0a86 | ||
|
|
32d8086121 | ||
|
|
7c200899d7 | ||
|
|
613d72fa26 | ||
|
|
909e2142d6 | ||
|
|
8083ab78b5 | ||
|
|
cbc0138507 | ||
|
|
4f695bc58a | ||
|
|
d1d4fe2e33 | ||
|
|
fc0d268fe5 | ||
|
|
7b10888c95 | ||
|
|
3920ed4b92 | ||
|
|
0a1dd56af6 | ||
|
|
841e4dabb5 | ||
|
|
815a153b94 | ||
|
|
0c274af72c | ||
|
|
6d34f605a3 | ||
|
|
dad6f650bc | ||
|
|
5045c2e448 | ||
|
|
ec4744709d | ||
|
|
91dd146c0f | ||
|
|
4344d75694 | ||
|
|
b97f5b809d | ||
|
|
b9e5cce383 | ||
|
|
565de2d377 | ||
|
|
6ed633ce42 | ||
|
|
cf7150cd9d | ||
|
|
b8d2f1f911 | ||
|
|
360b6bcce1 | ||
|
|
874fd9ac0a | ||
|
|
92f3c8cf15 | ||
|
|
441a41b2eb | ||
|
|
bc6c3b1013 | ||
|
|
a676391af2 | ||
|
|
411a6cced1 | ||
|
|
62474af0c0 | ||
|
|
738d4753f2 | ||
|
|
152d4451ec | ||
|
|
fd71adfba9 | ||
|
|
7151c4ca21 | ||
|
|
05997987ad | ||
|
|
bab4e620e3 | ||
|
|
977d1c38b2 | ||
|
|
d1c97b8e1d | ||
|
|
fb32709259 | ||
|
|
c9b7c5bb56 | ||
|
|
42ff253339 | ||
|
|
c4ffc357a3 | ||
|
|
afcaec0a89 | ||
|
|
09edca8b7a | ||
|
|
f9fd34b11e | ||
|
|
aa666565d1 | ||
|
|
f83e8ee806 | ||
|
|
84ebed1eb7 | ||
|
|
1d7c6af520 | ||
|
|
226da3b371 | ||
|
|
8d052a6cb1 | ||
|
|
ef0409d06c | ||
|
|
b9abf590c5 | ||
|
|
6a9bb060eb | ||
|
|
6a7600a8c6 | ||
|
|
e12131108e | ||
|
|
89b5b99873 | ||
|
|
50dcec1ff5 | ||
|
|
d089537bca | ||
|
|
e70355fbe1 | ||
|
|
140c459ac3 | ||
|
|
098e8c6fed | ||
|
|
1ba8e2c93c | ||
|
|
9e480f6efb | ||
|
|
0892847c2f | ||
|
|
c464ba83f2 | ||
|
|
62e51fd00a | ||
|
|
cf9051c277 | ||
|
|
d270957c82 | ||
|
|
0ee872999d | ||
|
|
c4f4dcc181 | ||
|
|
22ee5113d0 | ||
|
|
e233eee07b | ||
|
|
185849b68a | ||
|
|
e62b6f8339 | ||
|
|
9931537d87 | ||
|
|
82c4df5cde | ||
|
|
103f556c8d | ||
|
|
582a1d9866 | ||
|
|
244757c92c | ||
|
|
0ff869dfcd | ||
|
|
a1e0e4fd9d | ||
|
|
4138214ac3 | ||
|
|
9039077286 | ||
|
|
8a1129bbde | ||
|
|
706a8d2850 | ||
|
|
ba4dbcf5a1 | ||
|
|
bfae788a44 | ||
|
|
e02a2ae48f | ||
|
|
18dc32d735 | ||
|
|
85ff708597 | ||
|
|
23b48a0d0f | ||
|
|
d1055b0b36 | ||
|
|
3c77758b32 | ||
|
|
b564a43d9c | ||
|
|
f08657ab27 | ||
|
|
e5fb071708 | ||
|
|
d28ee6d714 | ||
|
|
2f62a8bb39 | ||
|
|
75f1276119 | ||
|
|
6c8395ff87 | ||
|
|
82b2e7773f | ||
|
|
336958318d | ||
|
|
8a8f7956ef | ||
|
|
c728e97bda | ||
|
|
5c76dd26bc | ||
|
|
7af5ee1812 | ||
|
|
7f0e71578d | ||
|
|
45e881c93e | ||
|
|
b429306f05 | ||
|
|
88acd51ee2 | ||
|
|
3c802a7505 | ||
|
|
928a8458dd | ||
|
|
43797fee42 | ||
|
|
b9158c467a | ||
|
|
252ab45473 | ||
|
|
afc083e9fa | ||
|
|
f867ce3842 | ||
|
|
2a464c316d | ||
|
|
b9cf26db2f | ||
|
|
580585846b | ||
|
|
1af1c72e81 | ||
|
|
5557004375 | ||
|
|
5d50ff5f81 | ||
|
|
8e2ed40a8b | ||
|
|
8461268837 | ||
|
|
8a0b963d2c | ||
|
|
24acd94015 | ||
|
|
c30654c33c | ||
|
|
7bafd13564 | ||
|
|
0e73a56a45 | ||
|
|
f9fec33048 | ||
|
|
934a9c9e32 | ||
|
|
25115e95aa | ||
|
|
7f1a0ff6fc | ||
|
|
8d8d38600e | ||
|
|
172b054f48 | ||
|
|
2168847a45 | ||
|
|
e5a2acd6dd | ||
|
|
ddc613cd72 | ||
|
|
fa99b1d81c | ||
|
|
84f66dd54e | ||
|
|
d446fde009 | ||
|
|
ee676fd568 | ||
|
|
2cca942ce6 | ||
|
|
59d574edb7 | ||
|
|
c170b18155 | ||
|
|
45a49a4fb4 | ||
|
|
12a2f7c1a5 | ||
|
|
d0950c8f09 | ||
|
|
ebf8220f1d | ||
|
|
c4e8180b3c | ||
|
|
771b0a7eab | ||
|
|
4db0ab0f40 | ||
|
|
dd480f96cd | ||
|
|
6b6d54a07c | ||
|
|
428beda1c7 | ||
|
|
baa8d40940 | ||
|
|
c8bdee26b7 | ||
|
|
ef73ed6ef7 | ||
|
|
acb9da6f93 | ||
|
|
d70e0fe9cf | ||
|
|
053cc9406d | ||
|
|
0f85120c5e | ||
|
|
25aef7fabf | ||
|
|
492ea66841 | ||
|
|
8b2a8b94b6 | ||
|
|
f24e80701c | ||
|
|
0b3d6676d1 | ||
|
|
c3a8734adf | ||
|
|
8fd59d6f33 | ||
|
|
da3bff3edf | ||
|
|
45cb5a0008 | ||
|
|
ea097fb1a3 | ||
|
|
a25b48b151 | ||
|
|
873f1d9e83 | ||
|
|
294439bf74 | ||
|
|
6e74be0d46 | ||
|
|
deb81eae10 | ||
|
|
70dcf3f7b3 | ||
|
|
ebcfed83c4 | ||
|
|
5d46278584 | ||
|
|
4f020a947a | ||
|
|
3460d1de3c | ||
|
|
7d2e4cd817 | ||
|
|
8cd6ef37c4 | ||
|
|
e4daaf0d83 | ||
|
|
69c98af9f9 | ||
|
|
7425a493ee | ||
|
|
691c194152 | ||
|
|
2f8896c375 | ||
|
|
6c507b77ae | ||
|
|
6ed0ccd37c | ||
|
|
80e1e42947 | ||
|
|
6ace00eb6a | ||
|
|
a35ffbf17e | ||
|
|
8c02c3be93 | ||
|
|
45669c9b30 | ||
|
|
19c232809e | ||
|
|
301f65af48 | ||
|
|
082ba58e51 | ||
|
|
3b5bdc6bc2 | ||
|
|
b05e91dba1 | ||
|
|
c7703242e5 | ||
|
|
21042ad0c2 | ||
|
|
8904551a59 | ||
|
|
cf1ef22367 | ||
|
|
d95bab41a1 | ||
|
|
820e208bdc | ||
|
|
c08e81c52b | ||
|
|
23e66ae1ea | ||
|
|
37bbdf3fe7 | ||
|
|
f124223015 | ||
|
|
9587a9b13c | ||
|
|
6963d95880 | ||
|
|
67c67df507 | ||
|
|
569f8cfcfc | ||
|
|
aa4ddd139a | ||
|
|
8ac97f5471 | ||
|
|
efabfbc931 | ||
|
|
6b5dc115e8 | ||
|
|
2dc0af667e | ||
|
|
196c243a7d | ||
|
|
55dbff8f30 | ||
|
|
2af43e0131 | ||
|
|
faf1cea63e | ||
|
|
7e25089c08 | ||
|
|
8fa36a38e2 | ||
|
|
5b3f29946b | ||
|
|
c869b5b884 | ||
|
|
a08b6ac266 | ||
|
|
4e68a5a078 | ||
|
|
99c68ddd50 | ||
|
|
d7f628677e | ||
|
|
e51680cf56 | ||
|
|
2e7d7752e9 | ||
|
|
26ac2ccd74 | ||
|
|
de9e653b73 | ||
|
|
e34e7a1d0b | ||
|
|
5a30f108fe | ||
|
|
74c9629372 | ||
|
|
6c5f448787 | ||
|
|
f848b8f12c | ||
|
|
bcec5f2e44 | ||
|
|
7d05c875f3 | ||
|
|
c805c5e2b1 | ||
|
|
c2c4c0adbf | ||
|
|
5ea3910af9 | ||
|
|
06fb300cff | ||
|
|
626ab7e00a | ||
|
|
1d140645b0 | ||
|
|
5182aec13f | ||
|
|
52f0c3dd24 | ||
|
|
b8327dbc9f | ||
|
|
d1722936c0 | ||
|
|
931240a3f5 | ||
|
|
b216a27bfc | ||
|
|
8471a67bcd | ||
|
|
b8a409195f | ||
|
|
1da67e5e10 | ||
|
|
ed1ec7ca6b | ||
|
|
3d7a68beb1 | ||
|
|
32fc57cf17 | ||
|
|
0598c6eaf6 | ||
|
|
0d7b687da0 | ||
|
|
e69754fd3a | ||
|
|
ac81ddd39a | ||
|
|
217ea488df | ||
|
|
f693c9d39f | ||
|
|
96d72788a1 | ||
|
|
0d74a95bb8 | ||
|
|
a7d039b7c6 | ||
|
|
87b02b1316 | ||
|
|
871de372ff | ||
|
|
c9d93b0745 | ||
|
|
1ccd10863e | ||
|
|
4258df4485 | ||
|
|
63f06aad94 | ||
|
|
ffe82be7a7 | ||
|
|
23929a3e70 | ||
|
|
83d0dbdbcb | ||
|
|
573ce9ceaa | ||
|
|
f21fe9f95e | ||
|
|
f92eca3efb | ||
|
|
7d778d7bef | ||
|
|
21f65e2e27 | ||
|
|
28b0657608 | ||
|
|
a489942454 | ||
|
|
423c2654c0 | ||
|
|
4dc826644d | ||
|
|
0f21222a0c | ||
|
|
570b8b2eb9 | ||
|
|
08fd175f5a | ||
|
|
511b5d9c53 | ||
|
|
6514196e8d | ||
|
|
ed6cb30762 | ||
|
|
232c0399e2 | ||
|
|
dbb015441f | ||
|
|
4c1c160990 | ||
|
|
0931d6e4de | ||
|
|
3f2ebc4179 | ||
|
|
14e8194581 | ||
|
|
3c4dc16003 | ||
|
|
54d28d9842 | ||
|
|
adfa520057 | ||
|
|
5deb69b23f | ||
|
|
348b2992d7 | ||
|
|
9f8fb6d588 | ||
|
|
cee16d47cb | ||
|
|
9e53f46ad2 | ||
|
|
53dfcae1a6 | ||
|
|
81f1cc78b2 | ||
|
|
efd659412f | ||
|
|
c31ea251c4 | ||
|
|
285e7c6c4f | ||
|
|
c274336563 | ||
|
|
d5fd5dfe6a | ||
|
|
42ddcfa565 | ||
|
|
6fa69f9fe5 | ||
|
|
0b876365a1 | ||
|
|
cdc8325c7b | ||
|
|
a6a8e29916 | ||
|
|
6fd3847298 | ||
|
|
3ff516a430 | ||
|
|
d8591840f3 | ||
|
|
c5affbbf71 | ||
|
|
788f090f27 | ||
|
|
0e3b6652b3 | ||
|
|
79061f4635 | ||
|
|
d167d59c23 | ||
|
|
f58b4860f7 | ||
|
|
cd9154f110 | ||
|
|
96b7fc0ac0 | ||
|
|
c8ad861590 | ||
|
|
1a1a24cfff | ||
|
|
d43db230fa | ||
|
|
0fb6d930e1 | ||
|
|
2508e8349b | ||
|
|
bd9a44ce7d | ||
|
|
da31d0c6a6 | ||
|
|
2b6febc8da | ||
|
|
aebabb1580 | ||
|
|
d5402718b7 | ||
|
|
fd108ff528 | ||
|
|
22ce1f25d0 |
@@ -3,7 +3,7 @@
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"dotnet-ef": {
|
||||
"version": "9.0.11",
|
||||
"version": "10.0.3",
|
||||
"commands": [
|
||||
"dotnet-ef"
|
||||
]
|
||||
|
||||
@@ -1,17 +1,31 @@
|
||||
{
|
||||
"name": "Development Jellyfin Server",
|
||||
"image": "mcr.microsoft.com/devcontainers/dotnet:9.0-bookworm",
|
||||
"image": "mcr.microsoft.com/devcontainers/dotnet:10.0-noble",
|
||||
"service": "app",
|
||||
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
|
||||
// restores nuget packages, installs the dotnet workloads and installs the dev https certificate
|
||||
"postStartCommand": "sudo dotnet restore; sudo dotnet workload update; sudo dotnet dev-certs https --trust; sudo bash \"./.devcontainer/install-ffmpeg.sh\"",
|
||||
// reads the extensions list and installs them
|
||||
"postAttachCommand": "cat .vscode/extensions.json | jq -r .recommendations[] | xargs -n 1 code --install-extension",
|
||||
// The previous way of installing extensions via the vs command dont work on selfhosted devcontainers
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"ms-dotnettools.csharp",
|
||||
"editorconfig.editorconfig",
|
||||
"github.vscode-github-actions",
|
||||
"ms-dotnettools.vscode-dotnet-runtime",
|
||||
"ms-dotnettools.csdevkit",
|
||||
"alexcvzz.vscode-sqlite",
|
||||
"streetsidesoftware.code-spell-checker",
|
||||
"eamodio.gitlens",
|
||||
"redhat.vscode-xml"
|
||||
]
|
||||
}
|
||||
},
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/dotnet:2": {
|
||||
"version": "none",
|
||||
"dotnetRuntimeVersions": "9.0",
|
||||
"aspNetCoreRuntimeVersions": "9.0"
|
||||
"dotnetRuntimeVersions": "10.0",
|
||||
"aspNetCoreRuntimeVersions": "10.0"
|
||||
},
|
||||
"ghcr.io/devcontainers-extra/features/apt-packages:1": {
|
||||
"preserve_apt_list": false,
|
||||
|
||||
@@ -379,6 +379,9 @@ dotnet_diagnostic.CA1720.severity = suggestion
|
||||
# disable warning CA1724: Type names should not match namespaces
|
||||
dotnet_diagnostic.CA1724.severity = suggestion
|
||||
|
||||
# disable warning CA1873: Avoid potentially expensive logging
|
||||
dotnet_diagnostic.CA1873.severity = suggestion
|
||||
|
||||
# disable warning CA1805: Do not initialize unnecessarily
|
||||
dotnet_diagnostic.CA1805.severity = suggestion
|
||||
|
||||
@@ -400,6 +403,10 @@ dotnet_diagnostic.CA1861.severity = suggestion
|
||||
# disable warning CA2000: Dispose objects before losing scope
|
||||
dotnet_diagnostic.CA2000.severity = suggestion
|
||||
|
||||
# TODO: Reevaluate when false positives are fixed: https://github.com/dotnet/roslyn-analyzers/issues/7699
|
||||
# disable warning CA2025: Do not pass 'IDisposable' instances into unawaited tasks
|
||||
dotnet_diagnostic.CA2025.severity = suggestion
|
||||
|
||||
# disable warning CA2253: Named placeholders should not be numeric values
|
||||
dotnet_diagnostic.CA2253.severity = suggestion
|
||||
|
||||
|
||||
15
.github/CODEOWNERS
vendored
15
.github/CODEOWNERS
vendored
@@ -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
|
||||
|
||||
18
.github/ISSUE_TEMPLATE/issue report.yml
vendored
18
.github/ISSUE_TEMPLATE/issue report.yml
vendored
@@ -87,7 +87,13 @@ body:
|
||||
label: Jellyfin Server version
|
||||
description: What version of Jellyfin are you using?
|
||||
options:
|
||||
- 10.10.0+
|
||||
- 10.11.6
|
||||
- 10.11.5
|
||||
- 10.11.4
|
||||
- 10.11.3
|
||||
- 10.11.2
|
||||
- 10.11.1
|
||||
- 10.11.0
|
||||
- Master
|
||||
- Unstable
|
||||
- Older*
|
||||
@@ -136,13 +142,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 +160,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:
|
||||
|
||||
15
.github/workflows/ci-codeql-analysis.yml
vendored
15
.github/workflows/ci-codeql-analysis.yml
vendored
@@ -20,18 +20,21 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- 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'
|
||||
dotnet-version: '10.0.x'
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6
|
||||
uses: github/codeql-action/init@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
queries: +security-extended
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6
|
||||
uses: github/codeql-action/autobuild@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6
|
||||
uses: github/codeql-action/analyze@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
|
||||
|
||||
22
.github/workflows/ci-compat.yml
vendored
22
.github/workflows/ci-compat.yml
vendored
@@ -11,22 +11,22 @@ jobs:
|
||||
permissions: read-all
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
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'
|
||||
dotnet-version: '10.0.x'
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
dotnet build Jellyfin.Server -o ./out
|
||||
|
||||
- name: Upload Head
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: abi-head
|
||||
retention-days: 14
|
||||
@@ -40,16 +40,16 @@ jobs:
|
||||
permissions: read-all
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
||||
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'
|
||||
dotnet-version: '10.0.x'
|
||||
|
||||
- name: Checkout common ancestor
|
||||
env:
|
||||
@@ -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@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.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@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.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@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.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
|
||||
|
||||
107
.github/workflows/ci-openapi.yml
vendored
107
.github/workflows/ci-openapi.yml
vendored
@@ -16,23 +16,25 @@ jobs:
|
||||
permissions: read-all
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
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'
|
||||
dotnet-version: '10.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@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: openapi-head
|
||||
retention-days: 14
|
||||
if-no-files-found: error
|
||||
path: tests/Jellyfin.Server.Integration.Tests/bin/Release/net9.0/openapi.json
|
||||
path: tests/Jellyfin.Server.Integration.Tests/bin/Release/net10.0/openapi.json
|
||||
|
||||
openapi-base:
|
||||
name: OpenAPI - BASE
|
||||
@@ -41,11 +43,12 @@ jobs:
|
||||
permissions: read-all
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
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,23 +57,25 @@ 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'
|
||||
dotnet-version: '10.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@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: openapi-base
|
||||
retention-days: 14
|
||||
if-no-files-found: error
|
||||
path: tests/Jellyfin.Server.Integration.Tests/bin/Release/net9.0/openapi.json
|
||||
path: tests/Jellyfin.Server.Integration.Tests/bin/Release/net10.0/openapi.json
|
||||
|
||||
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' }}
|
||||
@@ -80,71 +85,27 @@ jobs:
|
||||
- openapi-base
|
||||
steps:
|
||||
- name: Download openapi-head
|
||||
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
|
||||
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.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@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.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 +119,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@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0
|
||||
with:
|
||||
name: openapi-head
|
||||
path: openapi-head
|
||||
@@ -172,13 +133,12 @@ jobs:
|
||||
strip_components: 1
|
||||
target: "/srv/incoming/openapi/unstable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }}"
|
||||
- name: Move openapi.json (unstable) into place
|
||||
uses: appleboy/ssh-action@823bd89e131d8d508129f9443cad5855e9ba96f0 # v1.2.4
|
||||
uses: appleboy/ssh-action@0ff4204d59e8e51228ff73bce53f80d53301dee2 # v1.2.5
|
||||
with:
|
||||
host: "${{ secrets.REPO_HOST }}"
|
||||
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 +180,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@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0
|
||||
with:
|
||||
name: openapi-head
|
||||
path: openapi-head
|
||||
@@ -234,13 +194,12 @@ jobs:
|
||||
strip_components: 1
|
||||
target: "/srv/incoming/openapi/stable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }}"
|
||||
- name: Move openapi.json (stable) into place
|
||||
uses: appleboy/ssh-action@823bd89e131d8d508129f9443cad5855e9ba96f0 # v1.2.4
|
||||
uses: appleboy/ssh-action@0ff4204d59e8e51228ff73bce53f80d53301dee2 # v1.2.5
|
||||
with:
|
||||
host: "${{ secrets.REPO_HOST }}"
|
||||
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
|
||||
|
||||
6
.github/workflows/ci-tests.yml
vendored
6
.github/workflows/ci-tests.yml
vendored
@@ -9,7 +9,7 @@ on:
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
SDK_VERSION: "9.0.x"
|
||||
SDK_VERSION: "10.0.x"
|
||||
|
||||
jobs:
|
||||
run-tests:
|
||||
@@ -20,9 +20,9 @@ jobs:
|
||||
|
||||
runs-on: "${{ matrix.os }}"
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- uses: actions/setup-dotnet@2016bd2012dba4e32de620c46fe006a3ac9f0602 # v5.0.1
|
||||
- uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5.1.0
|
||||
with:
|
||||
dotnet-version: ${{ env.SDK_VERSION }}
|
||||
|
||||
|
||||
9
.github/workflows/commands.yml
vendored
9
.github/workflows/commands.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
||||
reactions: '+1'
|
||||
|
||||
- name: Checkout the latest code
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
token: ${{ secrets.JF_BOT_TOKEN }}
|
||||
fetch-depth: 0
|
||||
@@ -40,16 +40,19 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: pull in script
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
repository: jellyfin/jellyfin-triage-script
|
||||
|
||||
- name: install python
|
||||
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.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
|
||||
|
||||
2
.github/workflows/issue-stale.yml
vendored
2
.github/workflows/issue-stale.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ contains(github.repository, 'jellyfin/') }}
|
||||
steps:
|
||||
- uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1
|
||||
- uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0
|
||||
with:
|
||||
repo-token: ${{ secrets.JF_BOT_TOKEN }}
|
||||
ascending: true
|
||||
|
||||
7
.github/workflows/issue-template-check.yml
vendored
7
.github/workflows/issue-template-check.yml
vendored
@@ -10,16 +10,19 @@ jobs:
|
||||
issues: write
|
||||
steps:
|
||||
- name: pull in script
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
repository: jellyfin/jellyfin-triage-script
|
||||
|
||||
- name: install python
|
||||
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.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
|
||||
|
||||
1
.github/workflows/project-automation.yml
vendored
1
.github/workflows/project-automation.yml
vendored
@@ -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
|
||||
|
||||
2
.github/workflows/pull-request-stale.yaml
vendored
2
.github/workflows/pull-request-stale.yaml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ contains(github.repository, 'jellyfin/') }}
|
||||
steps:
|
||||
- uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1
|
||||
- uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0
|
||||
with:
|
||||
repo-token: ${{ secrets.JF_BOT_TOKEN }}
|
||||
ascending: true
|
||||
|
||||
4
.github/workflows/release-bump-version.yaml
vendored
4
.github/workflows/release-bump-version.yaml
vendored
@@ -33,7 +33,7 @@ jobs:
|
||||
yq-version: v4.9.8
|
||||
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
ref: ${{ env.TAG_BRANCH }}
|
||||
|
||||
@@ -66,7 +66,7 @@ jobs:
|
||||
NEXT_VERSION: ${{ github.event.inputs.NEXT_VERSION }}
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
ref: ${{ env.TAG_BRANCH }}
|
||||
|
||||
|
||||
6
.vscode/launch.json
vendored
6
.vscode/launch.json
vendored
@@ -6,7 +6,7 @@
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Jellyfin.Server/bin/Debug/net9.0/jellyfin.dll",
|
||||
"program": "${workspaceFolder}/Jellyfin.Server/bin/Debug/net10.0/jellyfin.dll",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}/Jellyfin.Server",
|
||||
"console": "internalConsole",
|
||||
@@ -22,7 +22,7 @@
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Jellyfin.Server/bin/Debug/net9.0/jellyfin.dll",
|
||||
"program": "${workspaceFolder}/Jellyfin.Server/bin/Debug/net10.0/jellyfin.dll",
|
||||
"args": ["--nowebclient"],
|
||||
"cwd": "${workspaceFolder}/Jellyfin.Server",
|
||||
"console": "internalConsole",
|
||||
@@ -34,7 +34,7 @@
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Jellyfin.Server/bin/Debug/net9.0/jellyfin.dll",
|
||||
"program": "${workspaceFolder}/Jellyfin.Server/bin/Debug/net10.0/jellyfin.dll",
|
||||
"args": ["--nowebclient", "--ffmpeg", "/usr/lib/jellyfin-ffmpeg/ffmpeg"],
|
||||
"cwd": "${workspaceFolder}/Jellyfin.Server",
|
||||
"console": "internalConsole",
|
||||
|
||||
@@ -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)
|
||||
- [MarcoCoreDuo](https://github.com/MarcoCoreDuo)
|
||||
|
||||
# Emby Contributors
|
||||
@@ -284,3 +287,4 @@
|
||||
- [Martin Reuter](https://github.com/reuterma24)
|
||||
- [Michael McElroy](https://github.com/mcmcelro)
|
||||
- [Soumyadip Auddy](https://github.com/SoumyadipAuddy)
|
||||
- [DerMaddis](https://github.com/dermaddis)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
</PropertyGroup>
|
||||
<!-- Run "dotnet list package (dash,dash)outdated" to see the latest versions of each package.-->
|
||||
<ItemGroup Label="Package Dependencies">
|
||||
<PackageVersion Include="AsyncKeyedLock" Version="7.1.8" />
|
||||
<PackageVersion Include="AsyncKeyedLock" Version="8.0.2" />
|
||||
<PackageVersion Include="AutoFixture.AutoMoq" Version="4.18.1" />
|
||||
<PackageVersion Include="AutoFixture.Xunit2" Version="4.18.1" />
|
||||
<PackageVersion Include="AutoFixture" Version="4.18.1" />
|
||||
@@ -13,8 +13,8 @@
|
||||
<PackageVersion Include="BlurHashSharp.SkiaSharp" Version="1.4.0-pre.1" />
|
||||
<PackageVersion Include="BlurHashSharp" Version="1.4.0-pre.1" />
|
||||
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
||||
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
|
||||
<PackageVersion Include="Diacritics" Version="4.0.17" />
|
||||
<PackageVersion Include="coverlet.collector" Version="8.0.0" />
|
||||
<PackageVersion Include="Diacritics" Version="4.1.4" />
|
||||
<PackageVersion Include="DiscUtils.Udf" Version="0.16.13" />
|
||||
<PackageVersion Include="DotNet.Glob" Version="3.1.3" />
|
||||
<PackageVersion Include="FsCheck.Xunit" Version="3.3.2" />
|
||||
@@ -25,34 +25,29 @@
|
||||
<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="Microsoft.AspNetCore.Authorization" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.11" />
|
||||
<PackageVersion Include="MetaBrainz.MusicBrainz" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="10.0.3" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.3" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="4.14.0" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="4.14.0" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="5.0.0" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.0.0" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0" />
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Http" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Options" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite" Version="10.0.3" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.3" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.3" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.3" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.3" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="10.0.3" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="10.0.3" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.3" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.3" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.3" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="10.0.3" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.3" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Http" Version="10.0.3" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.3" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Options" Version="10.0.3" />
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.3.0" />
|
||||
<PackageVersion Include="MimeTypes" Version="2.5.2" />
|
||||
<PackageVersion Include="Morestachio" Version="5.0.1.631" />
|
||||
<PackageVersion Include="Moq" Version="4.18.4" />
|
||||
@@ -63,10 +58,10 @@
|
||||
<PackageVersion Include="prometheus-net.DotNetRuntime" Version="4.4.1" />
|
||||
<PackageVersion Include="prometheus-net" Version="8.2.1" />
|
||||
<PackageVersion Include="Polly" Version="8.6.5" />
|
||||
<PackageVersion Include="Serilog.AspNetCore" Version="9.0.0" />
|
||||
<PackageVersion Include="Serilog.AspNetCore" Version="10.0.0" />
|
||||
<PackageVersion Include="Serilog.Enrichers.Thread" Version="4.0.0" />
|
||||
<PackageVersion Include="Serilog.Expressions" Version="5.0.0" />
|
||||
<PackageVersion Include="Serilog.Settings.Configuration" Version="9.0.0" />
|
||||
<PackageVersion Include="Serilog.Settings.Configuration" Version="10.0.0" />
|
||||
<PackageVersion Include="Serilog.Sinks.Async" Version="2.1.0" />
|
||||
<PackageVersion Include="Serilog.Sinks.Console" Version="6.1.1" />
|
||||
<PackageVersion Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||
@@ -74,26 +69,22 @@
|
||||
<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="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="Svg.Skia" Version="3.4.1" />
|
||||
<PackageVersion Include="Swashbuckle.AspNetCore.ReDoc" Version="10.1.4" />
|
||||
<PackageVersion Include="Swashbuckle.AspNetCore" Version="10.1.4" />
|
||||
<PackageVersion Include="System.Text.Json" Version="10.0.3" />
|
||||
<PackageVersion Include="TagLibSharp" Version="2.3.0" />
|
||||
<PackageVersion Include="z440.atl.core" Version="7.9.0" />
|
||||
<PackageVersion Include="TMDbLib" Version="2.3.0" />
|
||||
<PackageVersion Include="z440.atl.core" Version="7.11.0" />
|
||||
<PackageVersion Include="TMDbLib" Version="3.0.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>
|
||||
|
||||
75
Emby.Naming/Book/BookFileNameParser.cs
Normal file
75
Emby.Naming/Book/BookFileNameParser.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
41
Emby.Naming/Book/BookFileNameParserResult.cs
Normal file
41
Emby.Naming/Book/BookFileNameParserResult.cs
Normal 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; }
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
@@ -36,7 +36,7 @@
|
||||
<PropertyGroup>
|
||||
<Authors>Jellyfin Contributors</Authors>
|
||||
<PackageId>Jellyfin.Naming</PackageId>
|
||||
<VersionPrefix>10.11.6</VersionPrefix>
|
||||
<VersionPrefix>10.12.0</VersionPrefix>
|
||||
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@ public static class TvParserHelpers
|
||||
/// <param name="status">The status string.</param>
|
||||
/// <param name="enumValue">The <see cref="SeriesStatus"/>.</param>
|
||||
/// <returns>Returns true if parsing was successful.</returns>
|
||||
public static bool TryParseSeriesStatus(string status, out SeriesStatus? enumValue)
|
||||
public static bool TryParseSeriesStatus(string? status, out SeriesStatus? enumValue)
|
||||
{
|
||||
if (Enum.TryParse(status, true, out SeriesStatus seriesStatus))
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
@@ -136,19 +137,27 @@ namespace Emby.Naming.Video
|
||||
|
||||
if (videos.Count > 1)
|
||||
{
|
||||
var groups = videos.GroupBy(x => ResolutionRegex().IsMatch(x.Files[0].FileNameWithoutExtension)).ToList();
|
||||
var groups = videos
|
||||
.Select(x => (filename: x.Files[0].FileNameWithoutExtension.ToString(), value: x))
|
||||
.Select(x => (x.filename, resolutionMatch: ResolutionRegex().Match(x.filename), x.value))
|
||||
.GroupBy(x => x.resolutionMatch.Success)
|
||||
.ToList();
|
||||
|
||||
videos.Clear();
|
||||
|
||||
StringComparer comparer = StringComparer.Create(CultureInfo.InvariantCulture, CompareOptions.NumericOrdering);
|
||||
foreach (var group in groups)
|
||||
{
|
||||
if (group.Key)
|
||||
{
|
||||
videos.InsertRange(0, group
|
||||
.OrderByDescending(x => ResolutionRegex().Match(x.Files[0].FileNameWithoutExtension.ToString()).Value, new AlphanumericComparator())
|
||||
.ThenBy(x => x.Files[0].FileNameWithoutExtension.ToString(), new AlphanumericComparator()));
|
||||
.OrderByDescending(x => x.resolutionMatch.Value, comparer)
|
||||
.ThenBy(x => x.filename, comparer)
|
||||
.Select(x => x.value));
|
||||
}
|
||||
else
|
||||
{
|
||||
videos.AddRange(group.OrderBy(x => x.Files[0].FileNameWithoutExtension.ToString(), new AlphanumericComparator()));
|
||||
videos.AddRange(group.OrderBy(x => x.filename, comparer).Select(x => x.value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" />
|
||||
<PackageReference Include="prometheus-net.DotNetRuntime" />
|
||||
@@ -39,7 +38,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -2144,7 +2144,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
item.ValidateImages();
|
||||
|
||||
_itemRepository.SaveImages(item);
|
||||
await _itemRepository.SaveImagesAsync(item).ConfigureAwait(false);
|
||||
|
||||
RegisterItem(item);
|
||||
}
|
||||
|
||||
@@ -37,15 +37,25 @@ namespace Emby.Server.Implementations.Library
|
||||
while (attributeIndex > -1 && attributeIndex < maxIndex)
|
||||
{
|
||||
var attributeEnd = attributeIndex + attribute.Length;
|
||||
if (attributeIndex > 0
|
||||
&& str[attributeIndex - 1] == '['
|
||||
&& (str[attributeEnd] == '=' || str[attributeEnd] == '-'))
|
||||
if (attributeIndex > 0)
|
||||
{
|
||||
var closingIndex = str[attributeEnd..].IndexOf(']');
|
||||
// Must be at least 1 character before the closing bracket.
|
||||
if (closingIndex > 1)
|
||||
var attributeOpener = str[attributeIndex - 1];
|
||||
var attributeCloser = attributeOpener switch
|
||||
{
|
||||
return str[(attributeEnd + 1)..(attributeEnd + closingIndex)].Trim().ToString();
|
||||
'[' => ']',
|
||||
'(' => ')',
|
||||
'{' => '}',
|
||||
_ => '\0'
|
||||
};
|
||||
if (attributeCloser != '\0' && (str[attributeEnd] == '=' || str[attributeEnd] == '-'))
|
||||
{
|
||||
var closingIndex = str[attributeEnd..].IndexOf(attributeCloser);
|
||||
|
||||
// Must be at least 1 character before the closing bracket.
|
||||
if (closingIndex > 1)
|
||||
{
|
||||
return str[(attributeEnd + 1)..(attributeEnd + closingIndex)].Trim().ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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": "الحلقات المفضلة",
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "العروض",
|
||||
"Songs": "الأغاني",
|
||||
"StartupEmbyServerIsLoading": "يتم تحميل خادم Jellyfin . الرجاء المحاولة بعد قليل.",
|
||||
"SubtitleDownloadFailureForItem": "عملية إنزال الترجمة فشلت لـ{0}",
|
||||
"SubtitleDownloadFailureFromForItem": "فشل تحميل الترجمات من {0} ل {1}",
|
||||
"Sync": "مزامنة",
|
||||
"System": "النظام",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"Playlists": "Плэй-лісты",
|
||||
"Latest": "Апошняе",
|
||||
"LabelIpAddressValue": "IP-адрас: {0}",
|
||||
"ItemAddedWithName": "{0} даданы ў бібліятэку",
|
||||
"ItemAddedWithName": "{0} дададзены ў бібліятэку",
|
||||
"MessageApplicationUpdated": "Сервер Jellyfin абноўлены",
|
||||
"NotificationOptionApplicationUpdateInstalled": "Абнаўленне праграмы ўсталявана",
|
||||
"PluginInstalledWithName": "{0} быў усталяваны",
|
||||
@@ -14,9 +14,9 @@
|
||||
"Channels": "Каналы",
|
||||
"ChapterNameValue": "Раздзел {0}",
|
||||
"Collections": "Калекцыі",
|
||||
"Default": "Па змаўчанні",
|
||||
"Default": "Прадвызначана",
|
||||
"FailedLoginAttemptWithUserName": "Няўдалая спроба ўваходу з {0}",
|
||||
"Folders": "Тэчкі",
|
||||
"Folders": "Папкі",
|
||||
"Favorites": "Абранае",
|
||||
"External": "Знешні",
|
||||
"Genres": "Жанры",
|
||||
@@ -50,7 +50,7 @@
|
||||
"User": "Карыстальнік",
|
||||
"UserDeletedWithName": "Карыстальнік {0} быў выдалены",
|
||||
"UserDownloadingItemWithValues": "{0} спампоўваецца {1}",
|
||||
"TaskOptimizeDatabase": "Аптымізаваць базу дадзеных",
|
||||
"TaskOptimizeDatabase": "Аптымізацыя базы даных",
|
||||
"Artists": "Выканаўцы",
|
||||
"UserOfflineFromDevice": "{0} адлучыўся ад {1}",
|
||||
"UserPolicyUpdatedWithName": "Палітыка карыстальніка абноўлена для {0}",
|
||||
@@ -59,8 +59,8 @@
|
||||
"TaskCleanLogsDescription": "Выдаляе файлы журналу, якім больш за {0} дзён.",
|
||||
"TaskUpdatePluginsDescription": "Спампоўвае і ўсталёўвае абнаўленні для плагінаў, якія сканфігураваныя на аўтаматычнае абнаўленне.",
|
||||
"TaskRefreshChannelsDescription": "Абнаўляе інфармацыю аб інтэрнэт-канале.",
|
||||
"TaskDownloadMissingSubtitlesDescription": "Шукае ў інтэрнэце адсутныя субцітры на аснове канфігурацыі метададзеных.",
|
||||
"TaskOptimizeDatabaseDescription": "Ушчыльняе базу дадзеных і скарачае вольную прастору. Выкананне гэтай задачы пасля сканавання бібліятэкі або ўнясення іншых зменаў, якія прадугледжваюць мадыфікацыю базы дадзеных, можа палепшыць выдайнасць.",
|
||||
"TaskDownloadMissingSubtitlesDescription": "Шукае ў інтэрнэце адсутныя субцітры на аснове канфігурацыі метаданых.",
|
||||
"TaskOptimizeDatabaseDescription": "Сціскае базу даных і вызваляе вольную прастору. Выкананне гэтай задачы пасля сканіравання бібліятэкі або іншых змяненняў, якія мадыфікуюць базу даных, можа палепшыць прадукцыйнасць.",
|
||||
"TaskKeyframeExtractor": "Экстрактар ключавых кадраў",
|
||||
"TasksApplicationCategory": "Праграма",
|
||||
"AppDeviceValues": "Праграма: {0}, Прылада: {1}",
|
||||
@@ -81,8 +81,8 @@
|
||||
"NotificationOptionInstallationFailed": "Збой усталёўкі",
|
||||
"NewVersionIsAvailable": "Новая версія сервера Jellyfin даступная для cпампоўкі.",
|
||||
"NotificationOptionCameraImageUploaded": "Выява камеры запампавана",
|
||||
"NotificationOptionAudioPlaybackStopped": "Прайграванне аўдыё спынена",
|
||||
"NotificationOptionAudioPlayback": "Прайграванне аўдыё пачалося",
|
||||
"NotificationOptionAudioPlaybackStopped": "Прайграванне аўдыя спынена",
|
||||
"NotificationOptionAudioPlayback": "Прайграванне аўдыя пачалося",
|
||||
"NotificationOptionNewLibraryContent": "Дададзены новы кантэнт",
|
||||
"NotificationOptionPluginError": "Збой плагіна",
|
||||
"NotificationOptionPluginUninstalled": "Плагін выдалены",
|
||||
@@ -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": "Абнаўленне метаданых для акцёраў і рэжысёраў у вашай медыятэцы.",
|
||||
@@ -123,10 +123,10 @@
|
||||
"TaskCleanTranscodeDescription": "Выдаляе перакадзіраваныя файлы, старэйшыя за адзін дзень.",
|
||||
"TaskRefreshChannels": "Абнавіць каналы",
|
||||
"TaskDownloadMissingSubtitles": "Спампаваць адсутныя субцітры",
|
||||
"TaskKeyframeExtractorDescription": "Выдае ключавыя кадры з відэафайлаў для стварэння больш дакладных плэй-лістоў HLS. Гэта задача можа працягнуцца шмат часу.",
|
||||
"TaskKeyframeExtractorDescription": "Выдае ключавыя кадры з відэафайлаў для стварэння больш дакладных плэй-лістоў HLS. Гэта задача можа выконвацца доўга.",
|
||||
"TaskRefreshTrickplayImages": "Стварыць выявы Trickplay",
|
||||
"TaskRefreshTrickplayImagesDescription": "Стварае перадпрагляды відэаролікаў для Trickplay у падключаных бібліятэках.",
|
||||
"TaskCleanCollectionsAndPlaylists": "Ачысціце калекцыі і плэй-лісты",
|
||||
"TaskCleanCollectionsAndPlaylists": "Ачысціць калекцыі і плэй-лісты",
|
||||
"TaskCleanCollectionsAndPlaylistsDescription": "Выдаляе элементы з калекцый і плэй-лістоў, якія больш не існуюць.",
|
||||
"TaskAudioNormalizationDescription": "Скануе файлы на прадмет нармалізацыі гуку.",
|
||||
"TaskAudioNormalization": "Нармалізацыя гуку",
|
||||
@@ -136,6 +136,6 @@
|
||||
"TaskDownloadMissingLyricsDescription": "Спампоўвае тэксты для песняў",
|
||||
"TaskExtractMediaSegments": "Сканіраванне медыя-сегмента",
|
||||
"TaskMoveTrickplayImages": "Перанесці месцазнаходжанне выявы Trickplay",
|
||||
"CleanupUserDataTask": "Задача па ачыстцы дадзеных карыстальніка",
|
||||
"CleanupUserDataTaskDescription": "Ачысьціць усе дадзеныя карыстальніка (стан прагляду, абранае і г.д.) для медыяфайлаў, што адсутнічаюць больш за 90 дзён."
|
||||
"CleanupUserDataTask": "Задача па ачыстцы даных карыстальніка",
|
||||
"CleanupUserDataTaskDescription": "Ачышчае ўсе даныя карыстальніка (стан прагляду, абранае і г.д.) для медыяфайлаў, што адсутнічаюць больш за 90 дзён."
|
||||
}
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Сериали",
|
||||
"Songs": "Песни",
|
||||
"StartupEmbyServerIsLoading": "Сървърът зарежда. Моля, опитайте отново след малко.",
|
||||
"SubtitleDownloadFailureForItem": "Неуспешно изтегляне на субтитри за {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Субтитрите за {1} от {0} не можаха да бъдат изтеглени",
|
||||
"Sync": "Синхронизиране",
|
||||
"System": "Система",
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Sèries",
|
||||
"Songs": "Cançons",
|
||||
"StartupEmbyServerIsLoading": "El servidor de Jellyfin s'està carregant. Proveu-ho de nou en una estona.",
|
||||
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Els subtítols per a {1} no s'han pogut baixar de {0}",
|
||||
"Sync": "Sincronitza",
|
||||
"System": "Sistema",
|
||||
@@ -105,7 +104,7 @@
|
||||
"TaskCleanLogsDescription": "Esborra els registres que tinguin més de {0} dies.",
|
||||
"TaskCleanLogs": "Neteja dels registres",
|
||||
"TaskRefreshLibraryDescription": "Escaneja les mediateques, a la cerca de fitxers nous i refresca les metadades.",
|
||||
"TaskRefreshLibrary": "Escaneig de les mediateques",
|
||||
"TaskRefreshLibrary": "Escaneja la mediateca",
|
||||
"TaskRefreshChapterImagesDescription": "Creació de les miniatures dels vídeos que tinguin capítols.",
|
||||
"TaskRefreshChapterImages": "Extracció de les imatges dels capítols",
|
||||
"TaskCleanCacheDescription": "Eliminació de la memòria cau no necessària per al servidor.",
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Seriály",
|
||||
"Songs": "Skladby",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin Server je spouštěn. Zkuste to prosím v brzké době znovu.",
|
||||
"SubtitleDownloadFailureForItem": "Stahování titulků selhalo pro {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Stažení titulků pro {1} z {0} selhalo",
|
||||
"Sync": "Synchronizace",
|
||||
"System": "Systém",
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"CameraImageUploadedFrom": "Mae delwedd camera newydd wedi'i lanlwytho o {0}",
|
||||
"Books": "Llyfrau",
|
||||
"AuthenticationSucceededWithUserName": "{0} wedi’i ddilysu’n 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"
|
||||
}
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Serier",
|
||||
"Songs": "Sange",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin er i gang med at starte. Prøv igen om et øjeblik.",
|
||||
"SubtitleDownloadFailureForItem": "Fejlet i download af undertekster for {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Undertekster kunne ikke hentes fra {0} til {1}",
|
||||
"Sync": "Synkroniser",
|
||||
"System": "System",
|
||||
|
||||
@@ -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",
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Serien",
|
||||
"Songs": "Lieder",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin-Server lädt. Bitte versuche es gleich noch einmal.",
|
||||
"SubtitleDownloadFailureForItem": "Download der Untertitel fehlgeschlagen für {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Untertitel von {0} für {1} konnten nicht heruntergeladen werden",
|
||||
"Sync": "Synchronisation",
|
||||
"System": "System",
|
||||
@@ -82,7 +81,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 +96,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",
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Σειρές",
|
||||
"Songs": "Τραγούδια",
|
||||
"StartupEmbyServerIsLoading": "Ο διακομιστής Jellyfin φορτώνει. Περιμένετε λίγο και δοκιμάστε ξανά.",
|
||||
"SubtitleDownloadFailureForItem": "Οι υπότιτλοι απέτυχαν να κατέβουν για {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Αποτυχίες μεταφόρτωσης υποτίτλων από {0} για {1}",
|
||||
"Sync": "Συγχρονισμός",
|
||||
"System": "Σύστημα",
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Shows",
|
||||
"Songs": "Songs",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin Server is loading. Please try again shortly.",
|
||||
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Subtitles failed to download from {0} for {1}",
|
||||
"Sync": "Sync",
|
||||
"System": "System",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"HeaderFavoriteAlbums": "Álbumes favoritos",
|
||||
"HeaderFavoriteArtists": "Artistas favoritos",
|
||||
"HeaderFavoriteEpisodes": "Capítulos favoritos",
|
||||
"HeaderFavoriteShows": "Programas favoritos",
|
||||
"HeaderFavoriteShows": "Series favoritas",
|
||||
"HeaderFavoriteSongs": "Canciones favoritas",
|
||||
"HeaderLiveTV": "TV en vivo",
|
||||
"HeaderNextUp": "Siguiente",
|
||||
@@ -70,10 +70,9 @@
|
||||
"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}",
|
||||
"SubtitleDownloadFailureFromForItem": "Falló la descarga de subtitulos desde {0} para {1}",
|
||||
"Sync": "Sincronizar",
|
||||
"System": "Sistema",
|
||||
|
||||
@@ -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}",
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Programas",
|
||||
"Songs": "Canciones",
|
||||
"StartupEmbyServerIsLoading": "El servidor Jellyfin está cargando. Por favor, intente de nuevo pronto.",
|
||||
"SubtitleDownloadFailureForItem": "Falló la descarga de subtítulos para {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Falló la descarga de subtítulos desde {0} para {1}",
|
||||
"Sync": "Sincronizar",
|
||||
"System": "Sistema",
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Series",
|
||||
"Songs": "Canciones",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin Server se está cargando. Vuelve a intentarlo en breve.",
|
||||
"SubtitleDownloadFailureForItem": "Error al descargar subtítulos para {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Fallo en la descarga de subtítulos desde {0} para {1}",
|
||||
"Sync": "Sincronizar",
|
||||
"System": "Sistema",
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
"NotificationOptionApplicationUpdateAvailable": "Rakenduse uuendus on saadaval",
|
||||
"NewVersionIsAvailable": "Jellyfin serveri uus versioon on allalaadimiseks saadaval.",
|
||||
"NameSeasonUnknown": "Tundmatu hooaeg",
|
||||
"NameSeasonNumber": "Hooaeg {0}",
|
||||
"NameSeasonNumber": "{0}. hooaeg",
|
||||
"NameInstallFailed": "{0} paigaldamine nurjus",
|
||||
"MusicVideos": "Muusikavideod",
|
||||
"Music": "Muusika",
|
||||
@@ -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."
|
||||
}
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "سریالها",
|
||||
"Songs": "موسیقیها",
|
||||
"StartupEmbyServerIsLoading": "سرور Jellyfin در حال بارگیری است. لطفا کمی بعد دوباره تلاش کنید.",
|
||||
"SubtitleDownloadFailureForItem": "دانلود زیرنویس برای {0} ناموفق بود",
|
||||
"SubtitleDownloadFailureFromForItem": "بارگیری زیرنویس برای {1} از {0} شکست خورد",
|
||||
"Sync": "همگامسازی",
|
||||
"System": "سیستم",
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Séries",
|
||||
"Songs": "Chansons",
|
||||
"StartupEmbyServerIsLoading": "Serveur Jellyfin en cours de chargement. Réessayez dans quelques instants.",
|
||||
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Échec du téléchargement des sous-titres depuis {0} pour {1}",
|
||||
"Sync": "Synchroniser",
|
||||
"System": "Système",
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Séries",
|
||||
"Songs": "Chansons",
|
||||
"StartupEmbyServerIsLoading": "Le serveur Jellyfin est en cours de chargement. Veuillez réessayer dans quelques instants.",
|
||||
"SubtitleDownloadFailureForItem": "Le téléchargement des sous-titres pour {0} a échoué.",
|
||||
"SubtitleDownloadFailureFromForItem": "Échec du téléchargement des sous-titres depuis {0} pour {1}",
|
||||
"Sync": "Synchroniser",
|
||||
"System": "Système",
|
||||
|
||||
@@ -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",
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Serie",
|
||||
"Songs": "Lieder",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin Server ladt. Bitte grad noeinisch probiere.",
|
||||
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Ondertetle vo {0} för {1} hend ned chönne abeglade wärde",
|
||||
"Sync": "Synchronisation",
|
||||
"System": "System",
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "סדרות",
|
||||
"Songs": "שירים",
|
||||
"StartupEmbyServerIsLoading": "שרת Jellyfin בתהליך טעינה. נא לנסות שוב בקרוב.",
|
||||
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "הורדת כתוביות מ־{0} עבור {1} נכשלה",
|
||||
"Sync": "סנכרון",
|
||||
"System": "מערכת",
|
||||
|
||||
@@ -129,5 +129,12 @@
|
||||
"TaskAudioNormalization": "श्रव्य सामान्यीकरण",
|
||||
"TaskAudioNormalizationDescription": "श्रव्य सामान्यीकरण के लिए फाइलें अन्वेषण करें",
|
||||
"TaskDownloadMissingLyrics": "लापता गानों के बोल डाउनलोड करेँ",
|
||||
"TaskDownloadMissingLyricsDescription": "गानों के बोल डाउनलोड करता है"
|
||||
"TaskDownloadMissingLyricsDescription": "गानों के बोल डाउनलोड करता है",
|
||||
"TaskExtractMediaSegments": "मीडिया सेगमेंट स्कैन",
|
||||
"TaskExtractMediaSegmentsDescription": "मीडियासेगमेंट सक्षम प्लगइन्स से मीडिया सेगमेंट निकालता है या प्राप्त करता है।",
|
||||
"TaskMoveTrickplayImages": "ट्रिकप्ले छवि स्थान माइग्रेट करें",
|
||||
"TaskMoveTrickplayImagesDescription": "लाइब्रेरी सेटिंग्स के अनुसार मौजूदा ट्रिकप्ले फ़ाइलों को स्थानांतरित करता है।",
|
||||
"TaskCleanCollectionsAndPlaylistsDescription": "संग्रहों और प्लेलिस्टों से उन आइटमों को हटाता है जो अब मौजूद नहीं हैं।",
|
||||
"TaskCleanCollectionsAndPlaylists": "संग्रह और प्लेलिस्ट साफ़ करें",
|
||||
"CleanupUserDataTask": "यूज़र डेटा की सफाई करता है।"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"CameraImageUploadedFrom": "Nova fotografija sa kamere je učitana iz {0}",
|
||||
"Channels": "Kanali",
|
||||
"ChapterNameValue": "Poglavlje {0}",
|
||||
"Collections": "Kolekcije",
|
||||
"Collections": "Zbirke",
|
||||
"DeviceOfflineWithName": "{0} je prekinuo vezu",
|
||||
"DeviceOnlineWithName": "{0} je povezan",
|
||||
"FailedLoginAttemptWithUserName": "Neuspješan pokušaj prijave od {0}",
|
||||
@@ -70,10 +70,9 @@
|
||||
"ScheduledTaskFailedWithName": "{0} neuspjelo",
|
||||
"ScheduledTaskStartedWithName": "{0} pokrenuto",
|
||||
"ServerNameNeedsToBeRestarted": "{0} treba ponovno pokrenuti",
|
||||
"Shows": "Serije",
|
||||
"Shows": "Emisije",
|
||||
"Songs": "Pjesme",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin server se učitava. Pokušajte ponovo uskoro.",
|
||||
"SubtitleDownloadFailureForItem": "Titlovi prijevoda nisu preuzeti za {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Prijevod nije uspješno preuzet od {0} za {1}",
|
||||
"Sync": "Sinkronizacija",
|
||||
"System": "Sustav",
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
"NotificationOptionPluginInstalled": "Bővítmény telepítve",
|
||||
"NotificationOptionPluginUninstalled": "Bővítmény eltávolítva",
|
||||
"NotificationOptionPluginUpdateInstalled": "Bővítményfrissítés telepítve",
|
||||
"NotificationOptionServerRestartRequired": "A kiszolgáló újraindítása szükséges",
|
||||
"NotificationOptionServerRestartRequired": "A szerver újraindítása szükséges",
|
||||
"NotificationOptionTaskFailed": "Hiba az ütemezett feladatban",
|
||||
"NotificationOptionUserLockedOut": "Felhasználó tiltva",
|
||||
"NotificationOptionVideoPlayback": "Videólejátszás elkezdve",
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Sorozatok",
|
||||
"Songs": "Számok",
|
||||
"StartupEmbyServerIsLoading": "A Jellyfin kiszolgáló betöltődik. Próbálja újra hamarosan.",
|
||||
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Nem sikerült a felirat letöltése innen: {0}, ehhez: {1}",
|
||||
"Sync": "Szinkronizálás",
|
||||
"System": "Rendszer",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"AppDeviceValues": "App: {0}, Dispositivo: {1}",
|
||||
"Application": "Applicazione",
|
||||
"Artists": "Artisti",
|
||||
"AuthenticationSucceededWithUserName": "{0} autenticato con successo",
|
||||
"AuthenticationSucceededWithUserName": "{0} autenticato correttamente",
|
||||
"Books": "Libri",
|
||||
"CameraImageUploadedFrom": "È stata caricata una nuova fotografia da {0}",
|
||||
"Channels": "Canali",
|
||||
@@ -11,36 +11,36 @@
|
||||
"Collections": "Collezioni",
|
||||
"DeviceOfflineWithName": "{0} si è disconnesso",
|
||||
"DeviceOnlineWithName": "{0} è connesso",
|
||||
"FailedLoginAttemptWithUserName": "Tentativo di accesso fallito da {0}",
|
||||
"FailedLoginAttemptWithUserName": "Tentativo di accesso non riuscito da {0}",
|
||||
"Favorites": "Preferiti",
|
||||
"Folders": "Cartelle",
|
||||
"Genres": "Generi",
|
||||
"HeaderAlbumArtists": "Artisti dell'album",
|
||||
"HeaderContinueWatching": "Continua a guardare",
|
||||
"HeaderFavoriteAlbums": "Album Preferiti",
|
||||
"HeaderFavoriteArtists": "Artisti Preferiti",
|
||||
"HeaderFavoriteEpisodes": "Episodi Preferiti",
|
||||
"HeaderFavoriteShows": "Serie TV Preferite",
|
||||
"HeaderFavoriteSongs": "Brani Preferiti",
|
||||
"HeaderFavoriteAlbums": "Album preferiti",
|
||||
"HeaderFavoriteArtists": "Artisti preferiti",
|
||||
"HeaderFavoriteEpisodes": "Episodi preferiti",
|
||||
"HeaderFavoriteShows": "Serie TV preferite",
|
||||
"HeaderFavoriteSongs": "Brani preferiti",
|
||||
"HeaderLiveTV": "Diretta TV",
|
||||
"HeaderNextUp": "Prossimo",
|
||||
"HeaderRecordingGroups": "Gruppi di Registrazione",
|
||||
"HomeVideos": "Video Personali",
|
||||
"HeaderRecordingGroups": "Gruppi di registrazione",
|
||||
"HomeVideos": "Video personali",
|
||||
"Inherit": "Eredita",
|
||||
"ItemAddedWithName": "{0} è stato aggiunto alla libreria",
|
||||
"ItemRemovedWithName": "{0} è stato rimosso dalla libreria",
|
||||
"LabelIpAddressValue": "Indirizzo IP: {0}",
|
||||
"LabelRunningTimeValue": "Durata: {0}",
|
||||
"Latest": "Novità",
|
||||
"MessageApplicationUpdated": "Il Server Jellyfin è stato aggiornato",
|
||||
"MessageApplicationUpdated": "Jellyfin Server è stato aggiornato",
|
||||
"MessageApplicationUpdatedTo": "Jellyfin Server è stato aggiornato a {0}",
|
||||
"MessageNamedServerConfigurationUpdatedWithValue": "La sezione {0} della configurazione server è stata aggiornata",
|
||||
"MessageServerConfigurationUpdated": "La configurazione del server è stata aggiornata",
|
||||
"MixedContent": "Contenuto misto",
|
||||
"Movies": "Film",
|
||||
"Music": "Musica",
|
||||
"MusicVideos": "Video Musicali",
|
||||
"NameInstallFailed": "{0} installazione fallita",
|
||||
"MusicVideos": "Video musicali",
|
||||
"NameInstallFailed": "{0} installazione non riuscita",
|
||||
"NameSeasonNumber": "Stagione {0}",
|
||||
"NameSeasonUnknown": "Stagione sconosciuta",
|
||||
"NewVersionIsAvailable": "Una nuova versione di Jellyfin Server è disponibile per il download.",
|
||||
@@ -49,38 +49,37 @@
|
||||
"NotificationOptionAudioPlayback": "La riproduzione audio è iniziata",
|
||||
"NotificationOptionAudioPlaybackStopped": "La riproduzione audio è stata interrotta",
|
||||
"NotificationOptionCameraImageUploaded": "Immagine fotocamera caricata",
|
||||
"NotificationOptionInstallationFailed": "Installazione fallita",
|
||||
"NotificationOptionInstallationFailed": "Installazione non riuscita",
|
||||
"NotificationOptionNewLibraryContent": "Nuovo contenuto aggiunto",
|
||||
"NotificationOptionPluginError": "Errore del plugin",
|
||||
"NotificationOptionPluginInstalled": "Plugin installato",
|
||||
"NotificationOptionPluginUninstalled": "Plugin disinstallato",
|
||||
"NotificationOptionPluginUpdateInstalled": "Aggiornamento plugin installato",
|
||||
"NotificationOptionServerRestartRequired": "Riavvio del server necessario",
|
||||
"NotificationOptionTaskFailed": "Operazione pianificata fallita",
|
||||
"NotificationOptionTaskFailed": "Operazione pianificata non riuscita",
|
||||
"NotificationOptionUserLockedOut": "Utente bloccato",
|
||||
"NotificationOptionVideoPlayback": "Riproduzione video iniziata",
|
||||
"NotificationOptionVideoPlaybackStopped": "Riproduzione video interrotta",
|
||||
"Photos": "Foto",
|
||||
"Playlists": "Playlist",
|
||||
"Playlists": "Scalette",
|
||||
"Plugin": "Plugin",
|
||||
"PluginInstalledWithName": "{0} è stato Installato",
|
||||
"PluginInstalledWithName": "{0} è stato installato",
|
||||
"PluginUninstalledWithName": "{0} è stato disinstallato",
|
||||
"PluginUpdatedWithName": "{0} è stato aggiornato",
|
||||
"ProviderValue": "Provider: {0}",
|
||||
"ScheduledTaskFailedWithName": "{0} fallito",
|
||||
"ScheduledTaskFailedWithName": "{0} non riuscito",
|
||||
"ScheduledTaskStartedWithName": "{0} avviato",
|
||||
"ServerNameNeedsToBeRestarted": "{0} deve essere riavviato",
|
||||
"Shows": "Serie TV",
|
||||
"Songs": "Brani",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin server si sta avviando. Per favore riprova più tardi.",
|
||||
"SubtitleDownloadFailureForItem": "Impossibile scaricare i sottotitoli per {0}",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin Server si sta avviando. Riprova più tardi.",
|
||||
"SubtitleDownloadFailureFromForItem": "Impossibile scaricare i sottotitoli da {0} per {1}",
|
||||
"Sync": "Sincronizza",
|
||||
"System": "Sistema",
|
||||
"TvShows": "Serie TV",
|
||||
"User": "Utente",
|
||||
"UserCreatedWithName": "L'utente {0} è stato creato",
|
||||
"UserDeletedWithName": "L'utente {0} è stato rimosso",
|
||||
"UserDeletedWithName": "L'utente {0} è stato eliminato",
|
||||
"UserDownloadingItemWithValues": "{0} sta scaricando {1}",
|
||||
"UserLockedOutWithName": "L'utente {0} è stato bloccato",
|
||||
"UserOfflineFromDevice": "{0} si è disconnesso da {1}",
|
||||
@@ -115,20 +114,20 @@
|
||||
"TasksLibraryCategory": "Libreria",
|
||||
"TasksMaintenanceCategory": "Manutenzione",
|
||||
"TaskCleanActivityLog": "Attività di Registro Completate",
|
||||
"TaskCleanActivityLogDescription": "Elimina le voci del registro delle attività più vecchie dell’età configurata.",
|
||||
"Undefined": "Non Definito",
|
||||
"TaskCleanActivityLogDescription": "Elimina le voci del registro delle attività più vecchie dell'età configurata.",
|
||||
"Undefined": "Non specificato",
|
||||
"Forced": "Forzato",
|
||||
"Default": "Predefinito",
|
||||
"TaskOptimizeDatabaseDescription": "Compatta database e tronca spazi liberi. Eseguire questa azione dopo la scansione o dopo aver fatto altre modifiche inerenti il database potrebbe aumentarne le prestazioni.",
|
||||
"TaskOptimizeDatabase": "Ottimizza database",
|
||||
"TaskKeyframeExtractor": "Estrattore di Keyframe",
|
||||
"TaskKeyframeExtractorDescription": "Estrae i keyframe dai video per creare migliori playlist HLS. Questa procedura potrebbe richiedere molto tempo.",
|
||||
"TaskKeyframeExtractorDescription": "Estrae i keyframe dai video per creare migliori scalette HLS. Questa procedura potrebbe richiedere molto tempo.",
|
||||
"External": "Esterno",
|
||||
"HearingImpaired": "Non Udenti",
|
||||
"HearingImpaired": "Non udenti",
|
||||
"TaskRefreshTrickplayImages": "Genera immagini Trickplay",
|
||||
"TaskRefreshTrickplayImagesDescription": "Crea anteprime trickplay per i video nelle librerie abilitate.",
|
||||
"TaskCleanCollectionsAndPlaylists": "Ripulire le collezioni e le playlist",
|
||||
"TaskCleanCollectionsAndPlaylistsDescription": "Rimuove gli elementi dalle collezioni e dalle playlist che non esistono più.",
|
||||
"TaskCleanCollectionsAndPlaylists": "Ripulisci le collezioni e le scalette",
|
||||
"TaskCleanCollectionsAndPlaylistsDescription": "Rimuove gli elementi dalle collezioni e dalle scalette che non esistono più.",
|
||||
"TaskAudioNormalization": "Normalizzazione dell'audio",
|
||||
"TaskAudioNormalizationDescription": "Scansiona i file alla ricerca dei dati per la normalizzazione dell'audio.",
|
||||
"TaskDownloadMissingLyricsDescription": "Scarica testi per le canzoni",
|
||||
|
||||
@@ -43,32 +43,32 @@
|
||||
"NameInstallFailed": "{0}のインストールに失敗しました",
|
||||
"NameSeasonNumber": "シーズン {0}",
|
||||
"NameSeasonUnknown": "シーズン不明",
|
||||
"NewVersionIsAvailable": "新しいバージョンの Jellyfin Server がダウンロード可能です。",
|
||||
"NewVersionIsAvailable": "新しいバージョンの Jellyfin Server がダウンロードできます。",
|
||||
"NotificationOptionApplicationUpdateAvailable": "アプリケーションの更新があります",
|
||||
"NotificationOptionApplicationUpdateInstalled": "アプリケーションは最新です",
|
||||
"NotificationOptionAudioPlayback": "オーディオの再生を開始",
|
||||
"NotificationOptionAudioPlaybackStopped": "オーディオの再生をストップしました",
|
||||
"NotificationOptionAudioPlaybackStopped": "オーディオの再生を停止",
|
||||
"NotificationOptionCameraImageUploaded": "カメライメージがアップロードされました",
|
||||
"NotificationOptionInstallationFailed": "インストール失敗",
|
||||
"NotificationOptionNewLibraryContent": "新しいコンテンツを追加しました",
|
||||
"NotificationOptionPluginError": "プラグインに障害が発生しました",
|
||||
"NotificationOptionPluginInstalled": "プラグインがインストールされました",
|
||||
"NotificationOptionPluginUninstalled": "プラグインがアンインストールされました",
|
||||
"NotificationOptionPluginInstalled": "プラグインをインストールしました",
|
||||
"NotificationOptionPluginUninstalled": "プラグインをアンインストールしました",
|
||||
"NotificationOptionPluginUpdateInstalled": "プラグインのアップデートをインストールしました",
|
||||
"NotificationOptionServerRestartRequired": "サーバーを再起動してください",
|
||||
"NotificationOptionTaskFailed": "スケジュールされていたタスクの失敗",
|
||||
"NotificationOptionUserLockedOut": "ユーザーはロックされています",
|
||||
"NotificationOptionVideoPlayback": "ビデオの再生を開始しました",
|
||||
"NotificationOptionVideoPlaybackStopped": "ビデオを停止しました",
|
||||
"NotificationOptionVideoPlayback": "ビデオの再生を開始",
|
||||
"NotificationOptionVideoPlaybackStopped": "ビデオの再生を停止",
|
||||
"Photos": "フォト",
|
||||
"Playlists": "プレイリスト",
|
||||
"Plugin": "プラグイン",
|
||||
"PluginInstalledWithName": "{0} がインストールされました",
|
||||
"PluginUninstalledWithName": "{0} がアンインストールされました",
|
||||
"PluginUpdatedWithName": "{0} が更新されました",
|
||||
"PluginInstalledWithName": "{0} をインストールしました",
|
||||
"PluginUninstalledWithName": "{0} をアンインストールしました",
|
||||
"PluginUpdatedWithName": "{0} を更新しました",
|
||||
"ProviderValue": "プロバイダ: {0}",
|
||||
"ScheduledTaskFailedWithName": "{0} が失敗しました",
|
||||
"ScheduledTaskStartedWithName": "{0} が開始されました",
|
||||
"ScheduledTaskStartedWithName": "{0} を開始",
|
||||
"ServerNameNeedsToBeRestarted": "{0} を再起動してください",
|
||||
"Shows": "番組",
|
||||
"Songs": "曲",
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Körsetımder",
|
||||
"Songs": "Äuender",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin Server jüktelude. Ärekettı köp ūzamai qaitalañyz.",
|
||||
"SubtitleDownloadFailureForItem": "Субтитрлер {0} үшін жүктеліп алынуы сәтсіз",
|
||||
"SubtitleDownloadFailureFromForItem": "{1} üşın subtitrlerdı {0} közınen jüktep alu sätsız",
|
||||
"Sync": "Ündestıru",
|
||||
"System": "Jüie",
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "시리즈",
|
||||
"Songs": "노래",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin 서버를 불러오고 있습니다. 잠시 후에 다시 시도하십시오.",
|
||||
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "{0}에서 {1} 자막 다운로드에 실패했습니다",
|
||||
"Sync": "동기화",
|
||||
"System": "시스템",
|
||||
@@ -136,5 +135,7 @@
|
||||
"TaskMoveTrickplayImages": "트릭플레이 이미지 위치 마이그레이션",
|
||||
"TaskMoveTrickplayImagesDescription": "추출된 트릭플레이 이미지를 라이브러리 설정에 따라 이동합니다.",
|
||||
"TaskDownloadMissingLyrics": "누락된 가사 다운로드",
|
||||
"TaskDownloadMissingLyricsDescription": "가사 다운로드"
|
||||
"TaskDownloadMissingLyricsDescription": "가사 다운로드",
|
||||
"CleanupUserDataTask": "사용자 데이터 정리 작업",
|
||||
"CleanupUserDataTaskDescription": "최소 90일 이상 존재하지 않는 미디어에 대한 사용자 데이터(시청 상태, 즐겨찾기 등)를 정리합니다."
|
||||
}
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Laidos",
|
||||
"Songs": "Kūriniai",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin Server kraunasi. Netrukus pabandykite dar kartą.",
|
||||
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "{1} subtitrai buvo nesėkmingai parsiųsti iš {0}",
|
||||
"Sync": "Sinchronizuoti",
|
||||
"System": "Sistema",
|
||||
|
||||
9
Emby.Server.Implementations/Localization/Core/mi.json
Normal file
9
Emby.Server.Implementations/Localization/Core/mi.json
Normal 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}"
|
||||
}
|
||||
@@ -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": "ചാനലുകൾ",
|
||||
|
||||
@@ -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": "Танисангүй",
|
||||
|
||||
@@ -132,5 +132,10 @@
|
||||
"TaskDownloadMissingLyrics": "उपलब्ध नसलेली गीतपट्टी (Lyrics) डाउनलोड करा",
|
||||
"TaskAudioNormalization": "ऑडिओ सामान्यीकरण",
|
||||
"TaskAudioNormalizationDescription": "ऑडिओ सामान्यीकरणाचा डाटा स्कॅन करतो.",
|
||||
"TaskDownloadMissingLyricsDescription": "गाण्यांची गीतपट्टी (Lyrics) डाउनलोड करतो"
|
||||
"TaskDownloadMissingLyricsDescription": "गाण्यांची गीतपट्टी (Lyrics) डाउनलोड करतो",
|
||||
"TaskExtractMediaSegmentsDescription": "सक्रिय असलेल्या प्लगिनमधून मीडिया विभाग प्राप्त करते.",
|
||||
"TaskMoveTrickplayImagesDescription": "लायब्ररीच्या सेटिंग्जप्रमाणे आधीपासून अस्तित्वात असलेल्या ट्रिकप्ले फाइल्सचे स्थान बदलते.",
|
||||
"TaskCleanCollectionsAndPlaylistsDescription": "जे संग्रह आणि प्लेलिस्ट आता अस्तित्वात नाहीत, त्यांमधील घटक हटवते.",
|
||||
"CleanupUserDataTask": "वापरकर्ता डेटाची स्वच्छता प्रक्रिया",
|
||||
"CleanupUserDataTaskDescription": "९० दिवसांहून अधिक काळ अनुपस्थित असलेल्या माध्यमांवरील सर्व वापरकर्ता माहिती (जसे पाहण्याची स्थिती, आवडी इ.) हटवते."
|
||||
}
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Tayangan",
|
||||
"Songs": "Lagu-lagu",
|
||||
"StartupEmbyServerIsLoading": "Pelayan Jellyfin sedang dimuatkan. Sila cuba sebentar lagi.",
|
||||
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Muat turun sarikata gagal dari {0} untuk {1}",
|
||||
"Sync": "Segerak",
|
||||
"System": "Sistem",
|
||||
|
||||
@@ -126,5 +126,7 @@
|
||||
"TaskRefreshTrickplayImages": "ထရစ်ခ်ပလေး ပုံများကို ထုတ်မည်",
|
||||
"TaskKeyframeExtractor": "ကီးဖရိန်များကို ထုတ်နုတ်ခြင်း",
|
||||
"TaskCleanCollectionsAndPlaylists": "စုစည်းမှုများနှင့် အစဉ်လိုက်ပြသမှုများကို ရှင်းလင်းမည်",
|
||||
"HearingImpaired": "အကြားအာရုံ ချို့တဲ့သူ"
|
||||
"HearingImpaired": "အကြားအာရုံ ချို့တဲ့သူ",
|
||||
"TaskDownloadMissingLyrics": "ကျန်နေသောသီချင်းစာသားများအား ဒေါင်းလုတ်ဆွဲပါ",
|
||||
"TaskDownloadMissingLyricsDescription": "သီချင်းများအတွက် သီချင်းစာသား ဒေါင်းလုတ်ဆွဲပါ"
|
||||
}
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Serier",
|
||||
"Songs": "Sanger",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin Server laster. Prøv igjen snart.",
|
||||
"SubtitleDownloadFailureForItem": "En feil oppstå under nedlasting av undertekster for {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Kunne ikke laste ned undertekster fra {0} for {1}",
|
||||
"Sync": "Synkroniser",
|
||||
"System": "System",
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Series",
|
||||
"Songs": "Nummers",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin Server is aan het laden. Probeer het later opnieuw.",
|
||||
"SubtitleDownloadFailureForItem": "Downloaden van ondertiteling voor {0} is mislukt",
|
||||
"SubtitleDownloadFailureFromForItem": "Ondertiteling kon niet gedownload worden van {0} voor {1}",
|
||||
"Sync": "Synchronisatie",
|
||||
"System": "Systeem",
|
||||
|
||||
1
Emby.Server.Implementations/Localization/Core/oc.json
Normal file
1
Emby.Server.Implementations/Localization/Core/oc.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -134,6 +134,8 @@
|
||||
"TaskCleanCollectionsAndPlaylistsDescription": "ਕਲੈਕਸ਼ਨਾਂ ਅਤੇ ਪਲੇਲਿਸਟਾਂ ਵਿੱਚੋਂ ਉਹ ਆਈਟਮ ਹਟਾਉਂਦਾ ਹੈ ਜੋ ਹੁਣ ਮੌਜੂਦ ਨਹੀਂ ਹਨ।",
|
||||
"TaskCleanCollectionsAndPlaylists": "ਕਲੈਕਸ਼ਨਾਂ ਅਤੇ ਪਲੇਲਿਸਟਾਂ ਨੂੰ ਸਾਫ ਕਰੋ",
|
||||
"TaskAudioNormalization": "ਆਵਾਜ਼ ਸਧਾਰਣੀਕਰਨ",
|
||||
"TaskRefreshTrickplayImagesDescription": "ਚਲ ਰਹੀ ਲਾਇਬ੍ਰੇਰੀਆਂ ਵਿੱਚ ਵੀਡੀਓਜ਼ ਲਈ ਟ੍ਰਿਕਪਲੇ ਪ੍ਰੀਵਿਊ ਬਣਾਉਂਦਾ ਹੈ।",
|
||||
"TaskKeyframeExtractorDescription": "ਕੀ-ਫ੍ਰੇਮਜ਼ ਨੂੰ ਵੀਡੀਓ ਫਾਈਲਾਂ ਵਿੱਚੋਂ ਨਿਕਾਲਦਾ ਹੈ ਤਾਂ ਜੋ ਹੋਰ ਜ਼ਿਆਦਾ ਸਟਿਕ ਹੋਣ ਵਾਲੀਆਂ HLS ਪਲੇਲਿਸਟਾਂ ਬਣਾਈਆਂ ਜਾ ਸਕਣ। ਇਹ ਕੰਮ ਲੰਬੇ ਸਮੇਂ ਤੱਕ ਚੱਲ ਸਕਦਾ ਹੈ।"
|
||||
"TaskRefreshTrickplayImagesDescription": "ਵੀਡੀਓ ਲਈ ਟ੍ਰਿਕਪਲੇ ਪ੍ਰੀਵਿਊ ਬਣਾਉਂਦਾ ਹੈ (ਜੇ ਲਾਇਬ੍ਰੇਰੀ ਵਿੱਚ ਚੁਣਿਆ ਗਿਆ ਹੈ)।",
|
||||
"TaskKeyframeExtractorDescription": "ਕੀ-ਫ੍ਰੇਮਜ਼ ਨੂੰ ਵੀਡੀਓ ਫਾਈਲਾਂ ਵਿੱਚੋਂ ਨਿਕਾਲਦਾ ਹੈ ਤਾਂ ਜੋ ਹੋਰ ਜ਼ਿਆਦਾ ਸਟਿਕ ਹੋਣ ਵਾਲੀਆਂ HLS ਪਲੇਲਿਸਟਾਂ ਬਣਾਈਆਂ ਜਾ ਸਕਣ। ਇਹ ਕੰਮ ਲੰਬੇ ਸਮੇਂ ਤੱਕ ਚੱਲ ਸਕਦਾ ਹੈ।",
|
||||
"CleanupUserDataTaskDescription": "ਘੱਟੋ-ਘੱਟ 90 ਦਿਨਾਂ ਤੋਂ ਮੌਜੂਦ ਨਾ ਹੋਣ ਵਾਲੇ ਮੀਡੀਆ ਤੋਂ ਸਾਰੇ ਉਪਭੋਗਤਾ ਡੇਟਾ (ਵਾਚ ਸਟੇਟ, ਮਨਪਸੰਦ ਸਟੇਟਸ ਆਦਿ) ਨੂੰ ਸਾਫ਼ ਕਰਦਾ ਹੈ।",
|
||||
"CleanupUserDataTask": "ਯੂਜ਼ਰ ਡਾਟਾ ਸਾਫ਼ ਕਰਨ ਦਾ ਕੰਮ"
|
||||
}
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Seriale",
|
||||
"Songs": "Utwory",
|
||||
"StartupEmbyServerIsLoading": "Trwa wczytywanie serwera Jellyfin. Spróbuj ponownie za chwilę.",
|
||||
"SubtitleDownloadFailureForItem": "Pobieranie napisów dla {0} zakończone niepowodzeniem",
|
||||
"SubtitleDownloadFailureFromForItem": "Nieudane pobieranie napisów z {0} dla {1}",
|
||||
"Sync": "Synchronizacja",
|
||||
"System": "System",
|
||||
@@ -125,8 +124,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",
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Séries",
|
||||
"Songs": "Músicas",
|
||||
"StartupEmbyServerIsLoading": "O Servidor Jellyfin está carregando. Por favor, tente novamente mais tarde.",
|
||||
"SubtitleDownloadFailureForItem": "Download de legendas falhou para {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Houve um problema ao baixar as legendas de {0} para {1}",
|
||||
"Sync": "Sincronizar",
|
||||
"System": "Sistema",
|
||||
|
||||
@@ -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",
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Séries",
|
||||
"Songs": "Músicas",
|
||||
"StartupEmbyServerIsLoading": "O servidor Jellyfin está a iniciar. Tente novamente mais tarde.",
|
||||
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Falha na transferência de legendas a partir de {0} para {1}",
|
||||
"Sync": "Sincronização",
|
||||
"System": "Sistema",
|
||||
@@ -125,8 +124,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 pré-visualizações de trickplay para vídeos nas bibliotecas ativadas.",
|
||||
"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.",
|
||||
|
||||
@@ -124,8 +124,8 @@
|
||||
"HearingImpaired": "Problemas auditivos",
|
||||
"TaskKeyframeExtractor": "Extrator de quadro-chave",
|
||||
"TaskKeyframeExtractorDescription": "Retira frames chave do video para criar listas HLS precisas. Esta tarefa pode correr durante algum tempo.",
|
||||
"TaskRefreshTrickplayImages": "Gerar miniaturas de vídeo",
|
||||
"TaskRefreshTrickplayImagesDescription": "Cria miniaturas de vídeo para vídeos nas bibliotecas definidas.",
|
||||
"TaskRefreshTrickplayImages": "Gerar imagens de trickplay",
|
||||
"TaskRefreshTrickplayImagesDescription": "Cria pré-visualizações de trickplay para vídeos nas bibliotecas ativadas.",
|
||||
"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.",
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Сериалы",
|
||||
"Songs": "Композиции",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin Server загружается. Повторите попытку в ближайшее время.",
|
||||
"SubtitleDownloadFailureForItem": "Субтитры к {0} не удалось загрузить",
|
||||
"SubtitleDownloadFailureFromForItem": "Субтитры к {1} не удалось загрузить с {0}",
|
||||
"Sync": "Синхронизация",
|
||||
"System": "Система",
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Seriály",
|
||||
"Songs": "Skladby",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin Server sa spúšťa. Prosím, skúste to o chvíľu znova.",
|
||||
"SubtitleDownloadFailureForItem": "Sťahovanie titulkov pre {0} zlyhalo",
|
||||
"SubtitleDownloadFailureFromForItem": "Sťahovanie titulkov z {0} pre {1} zlyhalo",
|
||||
"Sync": "Synchronizácia",
|
||||
"System": "Systém",
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Serije",
|
||||
"Songs": "Pesmi",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin strežnik se zaganja. Poskusite ponovno kasneje.",
|
||||
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Neuspešen prenos podnapisov iz {0} za {1}",
|
||||
"Sync": "Sinhroniziraj",
|
||||
"System": "Sistem",
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "Serier",
|
||||
"Songs": "Låtar",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin Server arbetar. Pröva igen snart.",
|
||||
"SubtitleDownloadFailureForItem": "Nerladdning av undertexter för {0} misslyckades",
|
||||
"SubtitleDownloadFailureFromForItem": "Undertexter kunde inte laddas ner från {0} till {1}",
|
||||
"Sync": "Synk",
|
||||
"System": "System",
|
||||
|
||||
1
Emby.Server.Implementations/Localization/Core/sw.json
Normal file
1
Emby.Server.Implementations/Localization/Core/sw.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -135,5 +135,7 @@
|
||||
"TaskExtractMediaSegments": "การสแกนส่วนของสื่อมีเดีย",
|
||||
"TaskMoveTrickplayImagesDescription": "ย้ายไฟล์ Trickplay ตามการตั้งค่าของไลบรารี",
|
||||
"TaskExtractMediaSegmentsDescription": "แยกหรือดึงส่วนของสื่อจากปลั๊กอินที่เปิดใช้งาน MediaSegment",
|
||||
"TaskMoveTrickplayImages": "ย้ายตำแหน่งเก็บภาพตัวอย่าง Trickplay"
|
||||
"TaskMoveTrickplayImages": "ย้ายตำแหน่งเก็บภาพตัวอย่าง Trickplay",
|
||||
"CleanupUserDataTask": "ส่วนงานล้างข้อมูลผู้ใช้",
|
||||
"CleanupUserDataTaskDescription": "ล้างข้อมูลผู้ใช้ทั้งหมด (สถานะการรับชม สถานะรายการโปรด ฯลฯ) จากสื่อที่ไม่ได้ใช้งานแล้วอย่างน้อย 90 วัน"
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
"ItemAddedWithName": "{0} kütüphaneye eklendi",
|
||||
"ItemRemovedWithName": "{0} kütüphaneden silindi",
|
||||
"LabelIpAddressValue": "IP adresi: {0}",
|
||||
"LabelRunningTimeValue": "Çalışma süresi: {0}",
|
||||
"LabelRunningTimeValue": "Oynatma süresi: {0}",
|
||||
"Latest": "En son",
|
||||
"MessageApplicationUpdated": "Jellyfin Sunucusu güncellendi",
|
||||
"MessageApplicationUpdatedTo": "Jellyfin Sunucusu {0} sürümüne güncellendi",
|
||||
@@ -42,7 +42,7 @@
|
||||
"MusicVideos": "Müzik Videoları",
|
||||
"NameInstallFailed": "{0} kurulumu başarısız",
|
||||
"NameSeasonNumber": "{0}. Sezon",
|
||||
"NameSeasonUnknown": "Bilinmeyen Sezon",
|
||||
"NameSeasonUnknown": "Sezon Bilinmiyor",
|
||||
"NewVersionIsAvailable": "Jellyfin Sunucusunun yeni bir sürümü indirmek için hazır.",
|
||||
"NotificationOptionApplicationUpdateAvailable": "Uygulama güncellemesi mevcut",
|
||||
"NotificationOptionApplicationUpdateInstalled": "Uygulama güncellemesi yüklendi",
|
||||
@@ -57,7 +57,7 @@
|
||||
"NotificationOptionPluginUpdateInstalled": "Eklenti güncellemesi yüklendi",
|
||||
"NotificationOptionServerRestartRequired": "Sunucunun yeniden başlatılması gerekiyor",
|
||||
"NotificationOptionTaskFailed": "Zamanlanmış görev hatası",
|
||||
"NotificationOptionUserLockedOut": "Kullanıcı kilitlendi",
|
||||
"NotificationOptionUserLockedOut": "Kullanıcı hesabı kilitlendi",
|
||||
"NotificationOptionVideoPlayback": "Video oynatma başladı",
|
||||
"NotificationOptionVideoPlaybackStopped": "Video oynatma durduruldu",
|
||||
"Photos": "Fotoğraflar",
|
||||
@@ -73,8 +73,7 @@
|
||||
"Shows": "Diziler",
|
||||
"Songs": "Şarkılar",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin Sunucusu yükleniyor. Lütfen kısa süre sonra tekrar deneyin.",
|
||||
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "{1} için alt yazılar {0} sağlayıcısından indirilemedi",
|
||||
"SubtitleDownloadFailureFromForItem": "{1} için altyazılar {0} sağlayıcısından indirilemedi",
|
||||
"Sync": "Eşzamanlama",
|
||||
"System": "Sistem",
|
||||
"TvShows": "Diziler",
|
||||
@@ -82,7 +81,7 @@
|
||||
"UserCreatedWithName": "{0} kullanıcısı oluşturuldu",
|
||||
"UserDeletedWithName": "{0} kullanıcısı silindi",
|
||||
"UserDownloadingItemWithValues": "{0} kullanıcısı {1} medyasını indiriyor",
|
||||
"UserLockedOutWithName": "{0} adlı kullanıcı kilitlendi",
|
||||
"UserLockedOutWithName": "{0} adlı kullanıcı hesabı kilitlendi",
|
||||
"UserOfflineFromDevice": "{0} kullanıcısının {1} ile bağlantısı kesildi",
|
||||
"UserOnlineFromDevice": "{0} kullanıcısı {1} ile çevrimiçi",
|
||||
"UserPasswordChangedWithName": "{0} kullanıcısının parolası değiştirildi",
|
||||
@@ -98,8 +97,8 @@
|
||||
"TasksLibraryCategory": "Kütüphane",
|
||||
"TasksMaintenanceCategory": "Bakım",
|
||||
"TaskRefreshPeopleDescription": "Medya kütüphanenizdeki videoların oyuncu ve yönetmen bilgilerini günceller.",
|
||||
"TaskDownloadMissingSubtitlesDescription": "Meta veri yapılandırmasına dayalı olarak eksik alt yazılar için internette arama yapar.",
|
||||
"TaskDownloadMissingSubtitles": "Eksik alt yazıları indir",
|
||||
"TaskDownloadMissingSubtitlesDescription": "Meta veri yapılandırmasına dayalı olarak eksik altyazılar için internette arama yapar.",
|
||||
"TaskDownloadMissingSubtitles": "Eksik altyazıları indir",
|
||||
"TaskRefreshChannelsDescription": "Internet kanal bilgilerini yenile.",
|
||||
"TaskRefreshChannels": "Kanalları Yenile",
|
||||
"TaskCleanTranscodeDescription": "Bir günden daha eski kod dönüştürme dosyalarını siler.",
|
||||
@@ -125,15 +124,15 @@
|
||||
"TaskKeyframeExtractor": "Ana Kare Çıkarıcı",
|
||||
"External": "Harici",
|
||||
"HearingImpaired": "Duyma Engelli",
|
||||
"TaskRefreshTrickplayImages": "Trickplay Görselleri Oluştur",
|
||||
"TaskRefreshTrickplayImagesDescription": "Etkin kütüphanelerdeki videolar için trickplay önizlemeleri oluşturur.",
|
||||
"TaskRefreshTrickplayImages": "Hızlı Önizleme Görsellerini Oluştur",
|
||||
"TaskRefreshTrickplayImagesDescription": "Etkin kütüphanelerdeki videolar için hızlı önizleme görselleri oluşturur.",
|
||||
"TaskCleanCollectionsAndPlaylistsDescription": "Artık var olmayan koleksiyon ve çalma listelerindeki ögeleri kaldırır.",
|
||||
"TaskCleanCollectionsAndPlaylists": "Koleksiyonları ve çalma listelerini temizleyin",
|
||||
"TaskAudioNormalizationDescription": "Ses normalleştirme verileri için dosyaları tarar.",
|
||||
"TaskAudioNormalization": "Ses Normalleştirme",
|
||||
"TaskExtractMediaSegments": "Medya Segmenti Tarama",
|
||||
"TaskMoveTrickplayImages": "Trickplay Görsel Konumunu Taşıma",
|
||||
"TaskMoveTrickplayImagesDescription": "Mevcut trickplay dosyalarını kütüphane ayarlarına göre taşır.",
|
||||
"TaskMoveTrickplayImages": "Hızlı Önizleme Görsel Konumunu Taşıma",
|
||||
"TaskMoveTrickplayImagesDescription": "Mevcut hızlı önizleme dosyalarını kütüphane ayarlarına göre taşır.",
|
||||
"TaskDownloadMissingLyrics": "Eksik şarkı sözlerini indir",
|
||||
"TaskDownloadMissingLyricsDescription": "Şarkı sözlerini indirir",
|
||||
"TaskExtractMediaSegmentsDescription": "MediaSegment özelliği etkin olan eklentilerden medya segmentlerini çıkarır veya alır.",
|
||||
|
||||
@@ -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}",
|
||||
|
||||
@@ -5,60 +5,60 @@
|
||||
"Artists": "艺术家",
|
||||
"AuthenticationSucceededWithUserName": "{0} 认证成功",
|
||||
"Books": "书籍",
|
||||
"CameraImageUploadedFrom": "新的相机图像已从 {0} 上传",
|
||||
"CameraImageUploadedFrom": "已从 {0} 上传新的相机照片",
|
||||
"Channels": "频道",
|
||||
"ChapterNameValue": "章节 {0}",
|
||||
"Collections": "合集",
|
||||
"DeviceOfflineWithName": "{0} 已断开",
|
||||
"DeviceOfflineWithName": "{0} 已断开连接",
|
||||
"DeviceOnlineWithName": "{0} 已连接",
|
||||
"FailedLoginAttemptWithUserName": "来自 {0} 的登录尝试失败",
|
||||
"Favorites": "我的最爱",
|
||||
"FailedLoginAttemptWithUserName": "来自 {0} 的登录失败",
|
||||
"Favorites": "收藏夹",
|
||||
"Folders": "文件夹",
|
||||
"Genres": "类型",
|
||||
"HeaderAlbumArtists": "专辑艺术家",
|
||||
"HeaderContinueWatching": "继续观看",
|
||||
"HeaderFavoriteAlbums": "收藏的专辑",
|
||||
"HeaderFavoriteArtists": "最爱的艺术家",
|
||||
"HeaderFavoriteEpisodes": "最爱的剧集",
|
||||
"HeaderFavoriteShows": "最爱的节目",
|
||||
"HeaderFavoriteSongs": "最爱的歌曲",
|
||||
"HeaderFavoriteArtists": "收藏的艺术家",
|
||||
"HeaderFavoriteEpisodes": "收藏的剧集",
|
||||
"HeaderFavoriteShows": "收藏的节目",
|
||||
"HeaderFavoriteSongs": "收藏的歌曲",
|
||||
"HeaderLiveTV": "电视直播",
|
||||
"HeaderNextUp": "接下来",
|
||||
"HeaderNextUp": "接下来播放",
|
||||
"HeaderRecordingGroups": "录制组",
|
||||
"HomeVideos": "家庭视频",
|
||||
"Inherit": "继承",
|
||||
"ItemAddedWithName": "{0} 已添加到媒体库",
|
||||
"ItemRemovedWithName": "{0} 已从媒体库中移除",
|
||||
"ItemRemovedWithName": "{0} 已从媒体库移除",
|
||||
"LabelIpAddressValue": "IP 地址:{0}",
|
||||
"LabelRunningTimeValue": "运行时间:{0}",
|
||||
"Latest": "最新",
|
||||
"MessageApplicationUpdated": "Jellyfin 服务器已更新",
|
||||
"MessageApplicationUpdatedTo": "Jellyfin Server 版本已更新为 {0}",
|
||||
"MessageApplicationUpdatedTo": "Jellyfin 服务器版本已更新到 {0}",
|
||||
"MessageNamedServerConfigurationUpdatedWithValue": "服务器配置 {0} 部分已更新",
|
||||
"MessageServerConfigurationUpdated": "服务器配置已更新",
|
||||
"MixedContent": "混合内容",
|
||||
"Movies": "电影",
|
||||
"Music": "音乐",
|
||||
"MusicVideos": "音乐视频",
|
||||
"MusicVideos": "MV",
|
||||
"NameInstallFailed": "{0} 安装失败",
|
||||
"NameSeasonNumber": "第 {0} 季",
|
||||
"NameSeasonUnknown": "未知季",
|
||||
"NewVersionIsAvailable": "Jellyfin Server 有新版本可以下载。",
|
||||
"NewVersionIsAvailable": "Jellyfin 服务器有新版本可供下载。",
|
||||
"NotificationOptionApplicationUpdateAvailable": "有可用的应用程序更新",
|
||||
"NotificationOptionApplicationUpdateInstalled": "应用程序更新已安装",
|
||||
"NotificationOptionAudioPlayback": "音频开始播放",
|
||||
"NotificationOptionAudioPlayback": "音频已开始播放",
|
||||
"NotificationOptionAudioPlaybackStopped": "音频播放已停止",
|
||||
"NotificationOptionCameraImageUploaded": "相机图片已上传",
|
||||
"NotificationOptionCameraImageUploaded": "相机照片已上传",
|
||||
"NotificationOptionInstallationFailed": "安装失败",
|
||||
"NotificationOptionNewLibraryContent": "已添加新内容",
|
||||
"NotificationOptionPluginError": "插件失败",
|
||||
"NotificationOptionPluginError": "插件出错",
|
||||
"NotificationOptionPluginInstalled": "插件已安装",
|
||||
"NotificationOptionPluginUninstalled": "插件已卸载",
|
||||
"NotificationOptionPluginUpdateInstalled": "插件更新已安装",
|
||||
"NotificationOptionPluginUpdateInstalled": "插件已更新",
|
||||
"NotificationOptionServerRestartRequired": "服务器需要重启",
|
||||
"NotificationOptionTaskFailed": "计划任务失败",
|
||||
"NotificationOptionUserLockedOut": "用户已锁定",
|
||||
"NotificationOptionVideoPlayback": "视频开始播放",
|
||||
"NotificationOptionUserLockedOut": "用户已被锁定",
|
||||
"NotificationOptionVideoPlayback": "视频已开始播放",
|
||||
"NotificationOptionVideoPlaybackStopped": "视频播放已停止",
|
||||
"Photos": "照片",
|
||||
"Playlists": "播放列表",
|
||||
@@ -72,23 +72,22 @@
|
||||
"ServerNameNeedsToBeRestarted": "{0} 需要重新启动",
|
||||
"Shows": "节目",
|
||||
"Songs": "歌曲",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin 服务器加载中。请稍后再试。",
|
||||
"SubtitleDownloadFailureForItem": "为 {0} 下载字幕失败",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin 服务器正在启动,请稍后再试。",
|
||||
"SubtitleDownloadFailureFromForItem": "无法从 {0} 下载 {1} 的字幕",
|
||||
"Sync": "同步",
|
||||
"System": "系统",
|
||||
"TvShows": "电视剧",
|
||||
"User": "用户",
|
||||
"UserCreatedWithName": "用户 {0} 已创建",
|
||||
"UserDeletedWithName": "用户 {0} 已删除",
|
||||
"UserCreatedWithName": "已创建用户 {0}",
|
||||
"UserDeletedWithName": "已删除用户 {0}",
|
||||
"UserDownloadingItemWithValues": "{0} 正在下载 {1}",
|
||||
"UserLockedOutWithName": "用户 {0} 已被锁定",
|
||||
"UserOfflineFromDevice": "{0} 已从 {1} 断开",
|
||||
"UserOnlineFromDevice": "{0} 在线,来自 {1}",
|
||||
"UserPasswordChangedWithName": "已为用户 {0} 更改密码",
|
||||
"UserPolicyUpdatedWithName": "用户协议已经被更新为 {0}",
|
||||
"UserStartedPlayingItemWithValues": "{0} 已在 {2} 上开始播放 {1}",
|
||||
"UserStoppedPlayingItemWithValues": "{0} 已在 {2} 上停止播放 {1}",
|
||||
"UserOnlineFromDevice": "{0} 已在 {1} 上线",
|
||||
"UserPasswordChangedWithName": "用户 {0} 的密码已更改",
|
||||
"UserPolicyUpdatedWithName": "用户协议已更新为 {0}",
|
||||
"UserStartedPlayingItemWithValues": "{0} 在 {2} 上开始播放 {1}",
|
||||
"UserStoppedPlayingItemWithValues": "{0} 在 {2} 上停止播放 {1}",
|
||||
"ValueHasBeenAddedToLibrary": "{0} 已添加至您的媒体库中",
|
||||
"ValueSpecialEpisodeName": "特典 - {0}",
|
||||
"VersionNumber": "版本 {0}",
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"HeaderFavoriteShows": "最愛的節目",
|
||||
"HeaderFavoriteSongs": "最愛的歌曲",
|
||||
"HeaderLiveTV": "電視直播",
|
||||
"HeaderNextUp": "接著播放",
|
||||
"HeaderNextUp": "繼續觀看",
|
||||
"HeaderRecordingGroups": "錄製組",
|
||||
"HomeVideos": "家庭影片",
|
||||
"Inherit": "繼承",
|
||||
@@ -73,7 +73,6 @@
|
||||
"Shows": "節目",
|
||||
"Songs": "歌曲",
|
||||
"StartupEmbyServerIsLoading": "正在載入 Jellyfin,請稍後再試。",
|
||||
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "無法從 {0} 下載 {1} 的字幕",
|
||||
"Sync": "同步",
|
||||
"System": "系統",
|
||||
@@ -127,8 +126,8 @@
|
||||
"HearingImpaired": "聽力障礙",
|
||||
"TaskRefreshTrickplayImages": "建立 Trickplay 圖像",
|
||||
"TaskRefreshTrickplayImagesDescription": "為已啟用 Trickplay 的媒體庫內的影片建立 Trickplay 預覽圖。",
|
||||
"TaskExtractMediaSegments": "掃描媒體段落",
|
||||
"TaskExtractMediaSegmentsDescription": "從MediaSegment中被允許的插件獲取媒體段落。",
|
||||
"TaskExtractMediaSegments": "掃描媒體分段資訊",
|
||||
"TaskExtractMediaSegmentsDescription": "從允許MediaSegment 功能的插件中獲取媒體片段。",
|
||||
"TaskDownloadMissingLyrics": "下載欠缺歌詞",
|
||||
"TaskDownloadMissingLyricsDescription": "下載歌詞",
|
||||
"TaskCleanCollectionsAndPlaylists": "整理媒體與播放清單",
|
||||
@@ -137,5 +136,6 @@
|
||||
"TaskCleanCollectionsAndPlaylistsDescription": "從資料庫及播放清單中移除已不存在的項目。",
|
||||
"TaskMoveTrickplayImagesDescription": "根據媒體庫設定移動現有的 Trickplay 檔案。",
|
||||
"TaskMoveTrickplayImages": "轉移 Trickplay 影像位置",
|
||||
"CleanupUserDataTask": "用戶資料清理工作"
|
||||
"CleanupUserDataTask": "用戶資料清理工作",
|
||||
"CleanupUserDataTaskDescription": "從用戶數據中清除已經被刪除超過 90 日的媒體相關資料。"
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -198,17 +198,22 @@ namespace Emby.Server.Implementations.Playlists
|
||||
return Playlist.GetPlaylistItems(items, user, options);
|
||||
}
|
||||
|
||||
public Task AddItemToPlaylistAsync(Guid playlistId, IReadOnlyCollection<Guid> itemIds, Guid userId)
|
||||
public Task AddItemToPlaylistAsync(Guid playlistId, IReadOnlyCollection<Guid> itemIds, int? position, Guid userId)
|
||||
{
|
||||
var user = userId.IsEmpty() ? null : _userManager.GetUserById(userId);
|
||||
|
||||
return AddToPlaylistInternal(playlistId, itemIds, user, new DtoOptions(false)
|
||||
{
|
||||
EnableImages = true
|
||||
});
|
||||
return AddToPlaylistInternal(
|
||||
playlistId,
|
||||
itemIds,
|
||||
user,
|
||||
new DtoOptions(false)
|
||||
{
|
||||
EnableImages = true
|
||||
},
|
||||
position);
|
||||
}
|
||||
|
||||
private async Task AddToPlaylistInternal(Guid playlistId, IReadOnlyCollection<Guid> newItemIds, User user, DtoOptions options)
|
||||
private async Task AddToPlaylistInternal(Guid playlistId, IReadOnlyCollection<Guid> newItemIds, User user, DtoOptions options, int? position = null)
|
||||
{
|
||||
// Retrieve the existing playlist
|
||||
var playlist = _libraryManager.GetItemById(playlistId) as Playlist
|
||||
@@ -243,7 +248,30 @@ namespace Emby.Server.Implementations.Playlists
|
||||
}
|
||||
|
||||
// Update the playlist in the repository
|
||||
playlist.LinkedChildren = [.. playlist.LinkedChildren, .. childrenToAdd];
|
||||
if (position.HasValue)
|
||||
{
|
||||
if (position.Value <= 0)
|
||||
{
|
||||
playlist.LinkedChildren = [.. childrenToAdd, .. playlist.LinkedChildren];
|
||||
}
|
||||
else if (position.Value >= playlist.LinkedChildren.Length)
|
||||
{
|
||||
playlist.LinkedChildren = [.. playlist.LinkedChildren, .. childrenToAdd];
|
||||
}
|
||||
else
|
||||
{
|
||||
playlist.LinkedChildren = [
|
||||
.. playlist.LinkedChildren[0..position.Value],
|
||||
.. childrenToAdd,
|
||||
.. playlist.LinkedChildren[position.Value..playlist.LinkedChildren.Length]
|
||||
];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
playlist.LinkedChildren = [.. playlist.LinkedChildren, .. childrenToAdd];
|
||||
}
|
||||
|
||||
playlist.DateLastMediaAdded = DateTime.UtcNow;
|
||||
|
||||
await UpdatePlaylistInternal(playlist).ConfigureAwait(false);
|
||||
|
||||
@@ -793,6 +793,16 @@ namespace Emby.Server.Implementations.Session
|
||||
PlaySessionId = info.PlaySessionId
|
||||
};
|
||||
|
||||
if (info.Item is not null)
|
||||
{
|
||||
_logger.LogInformation(
|
||||
"User {0} started playback of '{1}' ({2} {3})",
|
||||
session.UserName,
|
||||
info.Item.Name,
|
||||
session.Client,
|
||||
session.ApplicationVersion);
|
||||
}
|
||||
|
||||
await _eventManager.PublishAsync(eventArgs).ConfigureAwait(false);
|
||||
|
||||
// Nothing to save here
|
||||
@@ -1060,11 +1070,12 @@ namespace Emby.Server.Implementations.Session
|
||||
var msString = info.PositionTicks.HasValue ? (info.PositionTicks.Value / 10000).ToString(CultureInfo.InvariantCulture) : "unknown";
|
||||
|
||||
_logger.LogInformation(
|
||||
"Playback stopped reported by app {0} {1} playing {2}. Stopped at {3} ms",
|
||||
session.Client,
|
||||
session.ApplicationVersion,
|
||||
"User {0} stopped playback of '{1}' at {2}ms ({3} {4})",
|
||||
session.UserName,
|
||||
info.Item.Name,
|
||||
msString);
|
||||
msString,
|
||||
session.Client,
|
||||
session.ApplicationVersion);
|
||||
}
|
||||
|
||||
if (info.NowPlayingQueue is not null)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Jellyfin.Data.Enums;
|
||||
using Jellyfin.Extensions;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
using MediaBrowser.Model.Querying;
|
||||
|
||||
namespace Emby.Server.Implementations.Sorting
|
||||
{
|
||||
@@ -28,7 +28,7 @@ namespace Emby.Server.Implementations.Sorting
|
||||
ArgumentNullException.ThrowIfNull(x);
|
||||
ArgumentNullException.ThrowIfNull(y);
|
||||
|
||||
return AlphanumericComparator.CompareValues(x.Studios.FirstOrDefault(), y.Studios.FirstOrDefault());
|
||||
return CultureInfo.InvariantCulture.CompareInfo.Compare(x.Studios.FirstOrDefault(), y.Studios.FirstOrDefault(), CompareOptions.NumericOrdering);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -562,7 +562,7 @@ namespace Emby.Server.Implementations.Updates
|
||||
}
|
||||
|
||||
stream.Position = 0;
|
||||
ZipFile.ExtractToDirectory(stream, targetDir, true);
|
||||
await ZipFile.ExtractToDirectoryAsync(stream, targetDir, true, cancellationToken);
|
||||
|
||||
// Ensure we create one or populate existing ones with missing data.
|
||||
await _pluginManager.PopulateManifest(package.PackageInfo, package.Version, targetDir, status).ConfigureAwait(false);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -50,7 +50,6 @@ public class AudioController : BaseJellyfinApiController
|
||||
/// <param name="enableAutoStreamCopy">Whether or not to allow automatic stream copy if requested values match the original source. Defaults to true.</param>
|
||||
/// <param name="allowVideoStreamCopy">Whether or not to allow copying of the video stream url.</param>
|
||||
/// <param name="allowAudioStreamCopy">Whether or not to allow copying of the audio stream url.</param>
|
||||
/// <param name="breakOnNonKeyFrames">Optional. Whether to break on non key frames.</param>
|
||||
/// <param name="audioSampleRate">Optional. Specify a specific audio sample rate, e.g. 44100.</param>
|
||||
/// <param name="maxAudioBitDepth">Optional. The maximum audio bit depth.</param>
|
||||
/// <param name="audioBitRate">Optional. Specify an audio bitrate to encode to, e.g. 128000. If omitted this will be left to encoder defaults.</param>
|
||||
@@ -107,7 +106,6 @@ public class AudioController : BaseJellyfinApiController
|
||||
[FromQuery] bool? enableAutoStreamCopy,
|
||||
[FromQuery] bool? allowVideoStreamCopy,
|
||||
[FromQuery] bool? allowAudioStreamCopy,
|
||||
[FromQuery] bool? breakOnNonKeyFrames,
|
||||
[FromQuery] int? audioSampleRate,
|
||||
[FromQuery] int? maxAudioBitDepth,
|
||||
[FromQuery] int? audioBitRate,
|
||||
@@ -159,7 +157,6 @@ public class AudioController : BaseJellyfinApiController
|
||||
EnableAutoStreamCopy = enableAutoStreamCopy ?? true,
|
||||
AllowAudioStreamCopy = allowAudioStreamCopy ?? true,
|
||||
AllowVideoStreamCopy = allowVideoStreamCopy ?? true,
|
||||
BreakOnNonKeyFrames = breakOnNonKeyFrames ?? false,
|
||||
AudioSampleRate = audioSampleRate,
|
||||
MaxAudioChannels = maxAudioChannels,
|
||||
AudioBitRate = audioBitRate,
|
||||
@@ -217,7 +214,6 @@ public class AudioController : BaseJellyfinApiController
|
||||
/// <param name="enableAutoStreamCopy">Whether or not to allow automatic stream copy if requested values match the original source. Defaults to true.</param>
|
||||
/// <param name="allowVideoStreamCopy">Whether or not to allow copying of the video stream url.</param>
|
||||
/// <param name="allowAudioStreamCopy">Whether or not to allow copying of the audio stream url.</param>
|
||||
/// <param name="breakOnNonKeyFrames">Optional. Whether to break on non key frames.</param>
|
||||
/// <param name="audioSampleRate">Optional. Specify a specific audio sample rate, e.g. 44100.</param>
|
||||
/// <param name="maxAudioBitDepth">Optional. The maximum audio bit depth.</param>
|
||||
/// <param name="audioBitRate">Optional. Specify an audio bitrate to encode to, e.g. 128000. If omitted this will be left to encoder defaults.</param>
|
||||
@@ -274,7 +270,6 @@ public class AudioController : BaseJellyfinApiController
|
||||
[FromQuery] bool? enableAutoStreamCopy,
|
||||
[FromQuery] bool? allowVideoStreamCopy,
|
||||
[FromQuery] bool? allowAudioStreamCopy,
|
||||
[FromQuery] bool? breakOnNonKeyFrames,
|
||||
[FromQuery] int? audioSampleRate,
|
||||
[FromQuery] int? maxAudioBitDepth,
|
||||
[FromQuery] int? audioBitRate,
|
||||
@@ -326,7 +321,6 @@ public class AudioController : BaseJellyfinApiController
|
||||
EnableAutoStreamCopy = enableAutoStreamCopy ?? true,
|
||||
AllowAudioStreamCopy = allowAudioStreamCopy ?? true,
|
||||
AllowVideoStreamCopy = allowVideoStreamCopy ?? true,
|
||||
BreakOnNonKeyFrames = breakOnNonKeyFrames ?? false,
|
||||
AudioSampleRate = audioSampleRate,
|
||||
MaxAudioChannels = maxAudioChannels,
|
||||
AudioBitRate = audioBitRate,
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ using System.ComponentModel.DataAnnotations;
|
||||
using System.Net.Mime;
|
||||
using System.Text.Json;
|
||||
using Jellyfin.Api.Attributes;
|
||||
using Jellyfin.Api.Constants;
|
||||
using Jellyfin.Api.Models.ConfigurationDtos;
|
||||
using Jellyfin.Extensions.Json;
|
||||
using MediaBrowser.Common.Api;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
@@ -143,22 +141,4 @@ public class ConfigurationController : BaseJellyfinApiController
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the path to the media encoder.
|
||||
/// </summary>
|
||||
/// <param name="mediaEncoderPath">Media encoder path form body.</param>
|
||||
/// <response code="204">Media encoder path updated.</response>
|
||||
/// <returns>Status.</returns>
|
||||
[Obsolete("This endpoint is obsolete.")]
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
[HttpPost("MediaEncoder/Path")]
|
||||
[Authorize(Policy = Policies.FirstTimeSetupOrElevated)]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public ActionResult UpdateMediaEncoderPath([FromBody, Required] MediaEncoderPathDto mediaEncoderPath)
|
||||
{
|
||||
// API ENDPOINT DISABLED (NOOP) FOR SECURITY PURPOSES
|
||||
// _mediaEncoder.UpdateEncoderPath(mediaEncoderPath.Path, mediaEncoderPath.PathType);
|
||||
return NoContent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,9 +191,17 @@ public class DisplayPreferencesController : BaseJellyfinApiController
|
||||
|
||||
foreach (var key in displayPreferences.CustomPrefs.Keys.Where(key => key.StartsWith("landing-", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
if (!Enum.TryParse<ViewType>(displayPreferences.CustomPrefs[key], true, out _))
|
||||
var viewType = displayPreferences.CustomPrefs[key];
|
||||
|
||||
if (string.IsNullOrEmpty(viewType))
|
||||
{
|
||||
_logger.LogError("Invalid ViewType: {LandingScreenOption}", displayPreferences.CustomPrefs[key]);
|
||||
displayPreferences.CustomPrefs.Remove(key);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Enum.TryParse<ViewType>(viewType, true, out _))
|
||||
{
|
||||
_logger.LogError("Invalid ViewType: {LandingScreenOption}", viewType);
|
||||
displayPreferences.CustomPrefs.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +122,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
/// <param name="enableAutoStreamCopy">Whether or not to allow automatic stream copy if requested values match the original source. Defaults to true.</param>
|
||||
/// <param name="allowVideoStreamCopy">Whether or not to allow copying of the video stream url.</param>
|
||||
/// <param name="allowAudioStreamCopy">Whether or not to allow copying of the audio stream url.</param>
|
||||
/// <param name="breakOnNonKeyFrames">Optional. Whether to break on non key frames.</param>
|
||||
/// <param name="audioSampleRate">Optional. Specify a specific audio sample rate, e.g. 44100.</param>
|
||||
/// <param name="maxAudioBitDepth">Optional. The maximum audio bit depth.</param>
|
||||
/// <param name="audioBitRate">Optional. Specify an audio bitrate to encode to, e.g. 128000. If omitted this will be left to encoder defaults.</param>
|
||||
@@ -182,7 +181,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
[FromQuery] bool? enableAutoStreamCopy,
|
||||
[FromQuery] bool? allowVideoStreamCopy,
|
||||
[FromQuery] bool? allowAudioStreamCopy,
|
||||
[FromQuery] bool? breakOnNonKeyFrames,
|
||||
[FromQuery] int? audioSampleRate,
|
||||
[FromQuery] int? maxAudioBitDepth,
|
||||
[FromQuery] int? audioBitRate,
|
||||
@@ -238,7 +236,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
EnableAutoStreamCopy = enableAutoStreamCopy ?? true,
|
||||
AllowAudioStreamCopy = allowAudioStreamCopy ?? true,
|
||||
AllowVideoStreamCopy = allowVideoStreamCopy ?? true,
|
||||
BreakOnNonKeyFrames = breakOnNonKeyFrames ?? false,
|
||||
AudioSampleRate = audioSampleRate,
|
||||
MaxAudioChannels = maxAudioChannels,
|
||||
AudioBitRate = audioBitRate,
|
||||
@@ -364,7 +361,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
/// <param name="enableAutoStreamCopy">Whether or not to allow automatic stream copy if requested values match the original source. Defaults to true.</param>
|
||||
/// <param name="allowVideoStreamCopy">Whether or not to allow copying of the video stream url.</param>
|
||||
/// <param name="allowAudioStreamCopy">Whether or not to allow copying of the audio stream url.</param>
|
||||
/// <param name="breakOnNonKeyFrames">Optional. Whether to break on non key frames.</param>
|
||||
/// <param name="audioSampleRate">Optional. Specify a specific audio sample rate, e.g. 44100.</param>
|
||||
/// <param name="maxAudioBitDepth">Optional. The maximum audio bit depth.</param>
|
||||
/// <param name="audioBitRate">Optional. Specify an audio bitrate to encode to, e.g. 128000. If omitted this will be left to encoder defaults.</param>
|
||||
@@ -425,7 +421,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
[FromQuery] bool? enableAutoStreamCopy,
|
||||
[FromQuery] bool? allowVideoStreamCopy,
|
||||
[FromQuery] bool? allowAudioStreamCopy,
|
||||
[FromQuery] bool? breakOnNonKeyFrames,
|
||||
[FromQuery] int? audioSampleRate,
|
||||
[FromQuery] int? maxAudioBitDepth,
|
||||
[FromQuery] int? audioBitRate,
|
||||
@@ -481,7 +476,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
EnableAutoStreamCopy = enableAutoStreamCopy ?? true,
|
||||
AllowAudioStreamCopy = allowAudioStreamCopy ?? true,
|
||||
AllowVideoStreamCopy = allowVideoStreamCopy ?? true,
|
||||
BreakOnNonKeyFrames = breakOnNonKeyFrames ?? false,
|
||||
AudioSampleRate = audioSampleRate,
|
||||
MaxAudioChannels = maxAudioChannels,
|
||||
AudioBitRate = audioBitRate,
|
||||
@@ -543,7 +537,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
/// <param name="enableAutoStreamCopy">Whether or not to allow automatic stream copy if requested values match the original source. Defaults to true.</param>
|
||||
/// <param name="allowVideoStreamCopy">Whether or not to allow copying of the video stream url.</param>
|
||||
/// <param name="allowAudioStreamCopy">Whether or not to allow copying of the audio stream url.</param>
|
||||
/// <param name="breakOnNonKeyFrames">Optional. Whether to break on non key frames.</param>
|
||||
/// <param name="audioSampleRate">Optional. Specify a specific audio sample rate, e.g. 44100.</param>
|
||||
/// <param name="maxAudioBitDepth">Optional. The maximum audio bit depth.</param>
|
||||
/// <param name="maxStreamingBitrate">Optional. The maximum streaming bitrate.</param>
|
||||
@@ -601,7 +594,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
[FromQuery] bool? enableAutoStreamCopy,
|
||||
[FromQuery] bool? allowVideoStreamCopy,
|
||||
[FromQuery] bool? allowAudioStreamCopy,
|
||||
[FromQuery] bool? breakOnNonKeyFrames,
|
||||
[FromQuery] int? audioSampleRate,
|
||||
[FromQuery] int? maxAudioBitDepth,
|
||||
[FromQuery] int? maxStreamingBitrate,
|
||||
@@ -654,7 +646,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
EnableAutoStreamCopy = enableAutoStreamCopy ?? true,
|
||||
AllowAudioStreamCopy = allowAudioStreamCopy ?? true,
|
||||
AllowVideoStreamCopy = allowVideoStreamCopy ?? true,
|
||||
BreakOnNonKeyFrames = breakOnNonKeyFrames ?? false,
|
||||
AudioSampleRate = audioSampleRate,
|
||||
MaxAudioChannels = maxAudioChannels,
|
||||
AudioBitRate = audioBitRate ?? maxStreamingBitrate,
|
||||
@@ -713,7 +704,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
/// <param name="enableAutoStreamCopy">Whether or not to allow automatic stream copy if requested values match the original source. Defaults to true.</param>
|
||||
/// <param name="allowVideoStreamCopy">Whether or not to allow copying of the video stream url.</param>
|
||||
/// <param name="allowAudioStreamCopy">Whether or not to allow copying of the audio stream url.</param>
|
||||
/// <param name="breakOnNonKeyFrames">Optional. Whether to break on non key frames.</param>
|
||||
/// <param name="audioSampleRate">Optional. Specify a specific audio sample rate, e.g. 44100.</param>
|
||||
/// <param name="maxAudioBitDepth">Optional. The maximum audio bit depth.</param>
|
||||
/// <param name="audioBitRate">Optional. Specify an audio bitrate to encode to, e.g. 128000. If omitted this will be left to encoder defaults.</param>
|
||||
@@ -771,7 +761,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
[FromQuery] bool? enableAutoStreamCopy,
|
||||
[FromQuery] bool? allowVideoStreamCopy,
|
||||
[FromQuery] bool? allowAudioStreamCopy,
|
||||
[FromQuery] bool? breakOnNonKeyFrames,
|
||||
[FromQuery] int? audioSampleRate,
|
||||
[FromQuery] int? maxAudioBitDepth,
|
||||
[FromQuery] int? audioBitRate,
|
||||
@@ -826,7 +815,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
EnableAutoStreamCopy = enableAutoStreamCopy ?? true,
|
||||
AllowAudioStreamCopy = allowAudioStreamCopy ?? true,
|
||||
AllowVideoStreamCopy = allowVideoStreamCopy ?? true,
|
||||
BreakOnNonKeyFrames = breakOnNonKeyFrames ?? false,
|
||||
AudioSampleRate = audioSampleRate,
|
||||
MaxAudioChannels = maxAudioChannels,
|
||||
AudioBitRate = audioBitRate,
|
||||
@@ -887,7 +875,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
/// <param name="enableAutoStreamCopy">Whether or not to allow automatic stream copy if requested values match the original source. Defaults to true.</param>
|
||||
/// <param name="allowVideoStreamCopy">Whether or not to allow copying of the video stream url.</param>
|
||||
/// <param name="allowAudioStreamCopy">Whether or not to allow copying of the audio stream url.</param>
|
||||
/// <param name="breakOnNonKeyFrames">Optional. Whether to break on non key frames.</param>
|
||||
/// <param name="audioSampleRate">Optional. Specify a specific audio sample rate, e.g. 44100.</param>
|
||||
/// <param name="maxAudioBitDepth">Optional. The maximum audio bit depth.</param>
|
||||
/// <param name="maxStreamingBitrate">Optional. The maximum streaming bitrate.</param>
|
||||
@@ -943,7 +930,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
[FromQuery] bool? enableAutoStreamCopy,
|
||||
[FromQuery] bool? allowVideoStreamCopy,
|
||||
[FromQuery] bool? allowAudioStreamCopy,
|
||||
[FromQuery] bool? breakOnNonKeyFrames,
|
||||
[FromQuery] int? audioSampleRate,
|
||||
[FromQuery] int? maxAudioBitDepth,
|
||||
[FromQuery] int? maxStreamingBitrate,
|
||||
@@ -996,7 +982,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
EnableAutoStreamCopy = enableAutoStreamCopy ?? true,
|
||||
AllowAudioStreamCopy = allowAudioStreamCopy ?? true,
|
||||
AllowVideoStreamCopy = allowVideoStreamCopy ?? true,
|
||||
BreakOnNonKeyFrames = breakOnNonKeyFrames ?? false,
|
||||
AudioSampleRate = audioSampleRate,
|
||||
MaxAudioChannels = maxAudioChannels,
|
||||
AudioBitRate = audioBitRate ?? maxStreamingBitrate,
|
||||
@@ -1060,7 +1045,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
/// <param name="enableAutoStreamCopy">Whether or not to allow automatic stream copy if requested values match the original source. Defaults to true.</param>
|
||||
/// <param name="allowVideoStreamCopy">Whether or not to allow copying of the video stream url.</param>
|
||||
/// <param name="allowAudioStreamCopy">Whether or not to allow copying of the audio stream url.</param>
|
||||
/// <param name="breakOnNonKeyFrames">Optional. Whether to break on non key frames.</param>
|
||||
/// <param name="audioSampleRate">Optional. Specify a specific audio sample rate, e.g. 44100.</param>
|
||||
/// <param name="maxAudioBitDepth">Optional. The maximum audio bit depth.</param>
|
||||
/// <param name="audioBitRate">Optional. Specify an audio bitrate to encode to, e.g. 128000. If omitted this will be left to encoder defaults.</param>
|
||||
@@ -1124,7 +1108,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
[FromQuery] bool? enableAutoStreamCopy,
|
||||
[FromQuery] bool? allowVideoStreamCopy,
|
||||
[FromQuery] bool? allowAudioStreamCopy,
|
||||
[FromQuery] bool? breakOnNonKeyFrames,
|
||||
[FromQuery] int? audioSampleRate,
|
||||
[FromQuery] int? maxAudioBitDepth,
|
||||
[FromQuery] int? audioBitRate,
|
||||
@@ -1181,7 +1164,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
EnableAutoStreamCopy = enableAutoStreamCopy ?? true,
|
||||
AllowAudioStreamCopy = allowAudioStreamCopy ?? true,
|
||||
AllowVideoStreamCopy = allowVideoStreamCopy ?? true,
|
||||
BreakOnNonKeyFrames = breakOnNonKeyFrames ?? false,
|
||||
AudioSampleRate = audioSampleRate,
|
||||
MaxAudioChannels = maxAudioChannels,
|
||||
AudioBitRate = audioBitRate,
|
||||
@@ -1247,7 +1229,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
/// <param name="enableAutoStreamCopy">Whether or not to allow automatic stream copy if requested values match the original source. Defaults to true.</param>
|
||||
/// <param name="allowVideoStreamCopy">Whether or not to allow copying of the video stream url.</param>
|
||||
/// <param name="allowAudioStreamCopy">Whether or not to allow copying of the audio stream url.</param>
|
||||
/// <param name="breakOnNonKeyFrames">Optional. Whether to break on non key frames.</param>
|
||||
/// <param name="audioSampleRate">Optional. Specify a specific audio sample rate, e.g. 44100.</param>
|
||||
/// <param name="maxAudioBitDepth">Optional. The maximum audio bit depth.</param>
|
||||
/// <param name="maxStreamingBitrate">Optional. The maximum streaming bitrate.</param>
|
||||
@@ -1309,7 +1290,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
[FromQuery] bool? enableAutoStreamCopy,
|
||||
[FromQuery] bool? allowVideoStreamCopy,
|
||||
[FromQuery] bool? allowAudioStreamCopy,
|
||||
[FromQuery] bool? breakOnNonKeyFrames,
|
||||
[FromQuery] int? audioSampleRate,
|
||||
[FromQuery] int? maxAudioBitDepth,
|
||||
[FromQuery] int? maxStreamingBitrate,
|
||||
@@ -1364,7 +1344,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
EnableAutoStreamCopy = enableAutoStreamCopy ?? true,
|
||||
AllowAudioStreamCopy = allowAudioStreamCopy ?? true,
|
||||
AllowVideoStreamCopy = allowVideoStreamCopy ?? true,
|
||||
BreakOnNonKeyFrames = breakOnNonKeyFrames ?? false,
|
||||
AudioSampleRate = audioSampleRate,
|
||||
MaxAudioChannels = maxAudioChannels,
|
||||
AudioBitRate = audioBitRate ?? maxStreamingBitrate,
|
||||
@@ -1596,16 +1575,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
var videoCodec = _encodingHelper.GetVideoEncoder(state, _encodingOptions);
|
||||
var threads = EncodingHelper.GetNumberOfThreads(state, _encodingOptions, videoCodec);
|
||||
|
||||
if (state.BaseRequest.BreakOnNonKeyFrames)
|
||||
{
|
||||
// FIXME: this is actually a workaround, as ideally it really should be the client which decides whether non-keyframe
|
||||
// breakpoints are supported; but current implementation always uses "ffmpeg input seeking" which is liable
|
||||
// to produce a missing part of video stream before first keyframe is encountered, which may lead to
|
||||
// awkward cases like a few starting HLS segments having no video whatsoever, which breaks hls.js
|
||||
_logger.LogInformation("Current HLS implementation doesn't support non-keyframe breaks but one is requested, ignoring that request");
|
||||
state.BaseRequest.BreakOnNonKeyFrames = false;
|
||||
}
|
||||
|
||||
var mapArgs = state.IsOutputVideo ? _encodingHelper.GetMapArgs(state) : string.Empty;
|
||||
|
||||
var directory = Path.GetDirectoryName(outputPath) ?? throw new ArgumentException($"Provided path ({outputPath}) is not valid.", nameof(outputPath));
|
||||
@@ -1756,11 +1725,6 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
var videoCodec = _encodingHelper.GetVideoEncoder(state, _encodingOptions);
|
||||
var copyArgs = "-codec:a:0 copy" + bitStreamArgs + strictArgs;
|
||||
|
||||
if (EncodingHelper.IsCopyCodec(videoCodec) && state.EnableBreakOnNonKeyFrames(videoCodec))
|
||||
{
|
||||
return copyArgs + " -copypriorss:a:0 0";
|
||||
}
|
||||
|
||||
return copyArgs;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Jellyfin.Api.Constants;
|
||||
using Jellyfin.Api.Models.EnvironmentDtos;
|
||||
using MediaBrowser.Common.Api;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
@@ -128,20 +127,6 @@ public class EnvironmentController : BaseJellyfinApiController
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets network paths.
|
||||
/// </summary>
|
||||
/// <response code="200">Empty array returned.</response>
|
||||
/// <returns>List of entries.</returns>
|
||||
[Obsolete("This endpoint is obsolete.")]
|
||||
[HttpGet("NetworkShares")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public ActionResult<IEnumerable<FileSystemEntryInfo>> GetNetworkShares()
|
||||
{
|
||||
_logger.LogWarning("Obsolete endpoint accessed: /Environment/NetworkShares");
|
||||
return Array.Empty<FileSystemEntryInfo>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets available drives from the server's file system.
|
||||
/// </summary>
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user