mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-05-24 02:02:29 -04:00
Merge branch 'jellyfin:master' into feature/EFUserData
This commit is contained in:
commit
fe1aab034e
@ -1,28 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Development Jellyfin Server - FFmpeg",
|
|
||||||
"image":"mcr.microsoft.com/devcontainers/dotnet:9.0-jammy",
|
|
||||||
// restores nuget packages, installs the dotnet workloads and installs the dev https certificate
|
|
||||||
"postStartCommand": "dotnet restore; dotnet workload update; dotnet dev-certs https --trust; sudo bash \"./.devcontainer/Dev - Server Ffmpeg/install-ffmpeg.sh\"",
|
|
||||||
// reads the extensions list and installs them
|
|
||||||
"postAttachCommand": "cat .vscode/extensions.json | jq -r .recommendations[] | xargs -n 1 code --install-extension",
|
|
||||||
"features": {
|
|
||||||
"ghcr.io/devcontainers/features/dotnet:2": {
|
|
||||||
"version": "none",
|
|
||||||
"dotnetRuntimeVersions": "9.0",
|
|
||||||
"aspNetCoreRuntimeVersions": "9.0"
|
|
||||||
},
|
|
||||||
"ghcr.io/devcontainers-contrib/features/apt-packages:1": {
|
|
||||||
"preserve_apt_list": false,
|
|
||||||
"packages": ["libfontconfig1"]
|
|
||||||
},
|
|
||||||
"ghcr.io/devcontainers/features/docker-in-docker:2": {
|
|
||||||
"dockerDashComposeVersion": "v2"
|
|
||||||
},
|
|
||||||
"ghcr.io/devcontainers/features/github-cli:1": {},
|
|
||||||
"ghcr.io/eitsupi/devcontainer-features/jq-likes:2": {}
|
|
||||||
},
|
|
||||||
"hostRequirements": {
|
|
||||||
"memory": "8gb",
|
|
||||||
"cpus": 4
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "Development Jellyfin Server",
|
"name": "Development Jellyfin Server",
|
||||||
"image":"mcr.microsoft.com/devcontainers/dotnet:9.0-jammy",
|
"image":"mcr.microsoft.com/devcontainers/dotnet:9.0-bookworm",
|
||||||
// restores nuget packages, installs the dotnet workloads and installs the dev https certificate
|
// restores nuget packages, installs the dotnet workloads and installs the dev https certificate
|
||||||
"postStartCommand": "dotnet restore; dotnet workload update; dotnet dev-certs https --trust",
|
"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
|
// reads the extensions list and installs them
|
||||||
"postAttachCommand": "cat .vscode/extensions.json | jq -r .recommendations[] | xargs -n 1 code --install-extension",
|
"postAttachCommand": "cat .vscode/extensions.json | jq -r .recommendations[] | xargs -n 1 code --install-extension",
|
||||||
"features": {
|
"features": {
|
||||||
|
@ -29,4 +29,4 @@ Signed-By: /etc/apt/keyrings/jellyfin.gpg
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
sudo apt update -y
|
sudo apt update -y
|
||||||
sudo apt install jellyfin-ffmpeg6 -y
|
sudo apt install jellyfin-ffmpeg7 -y
|
6
.github/workflows/ci-codeql-analysis.yml
vendored
6
.github/workflows/ci-codeql-analysis.yml
vendored
@ -27,11 +27,11 @@ jobs:
|
|||||||
dotnet-version: '9.0.x'
|
dotnet-version: '9.0.x'
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4
|
uses: github/codeql-action/init@aa578102511db1f4524ed59b8cc2bae4f6e88195 # v3.27.6
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
queries: +security-extended
|
queries: +security-extended
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4
|
uses: github/codeql-action/autobuild@aa578102511db1f4524ed59b8cc2bae4f6e88195 # v3.27.6
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4
|
uses: github/codeql-action/analyze@aa578102511db1f4524ed59b8cc2bae4f6e88195 # v3.27.6
|
||||||
|
4
.github/workflows/ci-openapi.yml
vendored
4
.github/workflows/ci-openapi.yml
vendored
@ -172,7 +172,7 @@ jobs:
|
|||||||
strip_components: 1
|
strip_components: 1
|
||||||
target: "/srv/incoming/openapi/unstable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }}"
|
target: "/srv/incoming/openapi/unstable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }}"
|
||||||
- name: Move openapi.json (unstable) into place
|
- name: Move openapi.json (unstable) into place
|
||||||
uses: appleboy/ssh-action@25ce8cbbcb08177468c7ff7ec5cbfa236f9341e1 # v1.1.0
|
uses: appleboy/ssh-action@7eaf76671a0d7eec5d98ee897acda4f968735a17 # v1.2.0
|
||||||
with:
|
with:
|
||||||
host: "${{ secrets.REPO_HOST }}"
|
host: "${{ secrets.REPO_HOST }}"
|
||||||
username: "${{ secrets.REPO_USER }}"
|
username: "${{ secrets.REPO_USER }}"
|
||||||
@ -234,7 +234,7 @@ jobs:
|
|||||||
strip_components: 1
|
strip_components: 1
|
||||||
target: "/srv/incoming/openapi/stable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }}"
|
target: "/srv/incoming/openapi/stable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }}"
|
||||||
- name: Move openapi.json (stable) into place
|
- name: Move openapi.json (stable) into place
|
||||||
uses: appleboy/ssh-action@25ce8cbbcb08177468c7ff7ec5cbfa236f9341e1 # v1.1.0
|
uses: appleboy/ssh-action@7eaf76671a0d7eec5d98ee897acda4f968735a17 # v1.2.0
|
||||||
with:
|
with:
|
||||||
host: "${{ secrets.REPO_HOST }}"
|
host: "${{ secrets.REPO_HOST }}"
|
||||||
username: "${{ secrets.REPO_USER }}"
|
username: "${{ secrets.REPO_USER }}"
|
||||||
|
11
.vscode/extensions.json
vendored
11
.vscode/extensions.json
vendored
@ -1,12 +1,13 @@
|
|||||||
{
|
{
|
||||||
"recommendations": [
|
"recommendations": [
|
||||||
"ms-dotnettools.csharp",
|
"ms-dotnettools.csharp",
|
||||||
"editorconfig.editorconfig",
|
"editorconfig.editorconfig",
|
||||||
"github.vscode-github-actions",
|
"github.vscode-github-actions",
|
||||||
"ms-dotnettools.vscode-dotnet-runtime",
|
"ms-dotnettools.vscode-dotnet-runtime",
|
||||||
"ms-dotnettools.csdevkit"
|
"ms-dotnettools.csdevkit",
|
||||||
],
|
"alexcvzz.vscode-sqlite"
|
||||||
"unwantedRecommendations": [
|
],
|
||||||
|
"unwantedRecommendations": [
|
||||||
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -192,6 +192,7 @@
|
|||||||
- [jaina heartles](https://github.com/heartles)
|
- [jaina heartles](https://github.com/heartles)
|
||||||
- [oxixes](https://github.com/oxixes)
|
- [oxixes](https://github.com/oxixes)
|
||||||
- [elfalem](https://github.com/elfalem)
|
- [elfalem](https://github.com/elfalem)
|
||||||
|
- [Kenneth Cochran](https://github.com/kennethcochran)
|
||||||
- [benedikt257](https://github.com/benedikt257)
|
- [benedikt257](https://github.com/benedikt257)
|
||||||
- [revam](https://github.com/revam)
|
- [revam](https://github.com/revam)
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<!-- Run "dotnet list package (dash,dash)outdated" to see the latest versions of each package.-->
|
<!-- Run "dotnet list package (dash,dash)outdated" to see the latest versions of each package.-->
|
||||||
<ItemGroup Label="Package Dependencies">
|
<ItemGroup Label="Package Dependencies">
|
||||||
<PackageVersion Include="AsyncKeyedLock" Version="7.1.3" />
|
<PackageVersion Include="AsyncKeyedLock" Version="7.1.4" />
|
||||||
<PackageVersion Include="AutoFixture.AutoMoq" Version="4.18.1" />
|
<PackageVersion Include="AutoFixture.AutoMoq" Version="4.18.1" />
|
||||||
<PackageVersion Include="AutoFixture.Xunit2" Version="4.18.1" />
|
<PackageVersion Include="AutoFixture.Xunit2" Version="4.18.1" />
|
||||||
<PackageVersion Include="AutoFixture" Version="4.18.1" />
|
<PackageVersion Include="AutoFixture" Version="4.18.1" />
|
||||||
@ -47,8 +47,8 @@
|
|||||||
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.0" />
|
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.0" />
|
||||||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.0" />
|
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.0" />
|
||||||
<PackageVersion Include="Microsoft.Extensions.Options" Version="9.0.0" />
|
<PackageVersion Include="Microsoft.Extensions.Options" Version="9.0.0" />
|
||||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
|
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
|
||||||
<PackageVersion Include="MimeTypes" Version="2.4.0" />
|
<PackageVersion Include="MimeTypes" Version="2.5.2" />
|
||||||
<PackageVersion Include="Mono.Nat" Version="3.0.4" />
|
<PackageVersion Include="Mono.Nat" Version="3.0.4" />
|
||||||
<PackageVersion Include="Moq" Version="4.18.4" />
|
<PackageVersion Include="Moq" Version="4.18.4" />
|
||||||
<PackageVersion Include="NEbml" Version="0.11.0" />
|
<PackageVersion Include="NEbml" Version="0.11.0" />
|
||||||
@ -71,7 +71,7 @@
|
|||||||
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.9" />
|
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.9" />
|
||||||
<PackageVersion Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" />
|
<PackageVersion Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" />
|
||||||
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />
|
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />
|
||||||
<PackageVersion Include="Svg.Skia" Version="2.0.0.2" />
|
<PackageVersion Include="Svg.Skia" Version="2.0.0.4" />
|
||||||
<PackageVersion Include="Swashbuckle.AspNetCore.ReDoc" Version="6.5.0" />
|
<PackageVersion Include="Swashbuckle.AspNetCore.ReDoc" Version="6.5.0" />
|
||||||
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.2.3" />
|
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.2.3" />
|
||||||
<PackageVersion Include="System.Globalization" Version="4.3.0" />
|
<PackageVersion Include="System.Globalization" Version="4.3.0" />
|
||||||
@ -80,12 +80,12 @@
|
|||||||
<PackageVersion Include="System.Text.Json" Version="9.0.0" />
|
<PackageVersion Include="System.Text.Json" Version="9.0.0" />
|
||||||
<PackageVersion Include="System.Threading.Tasks.Dataflow" Version="9.0.0" />
|
<PackageVersion Include="System.Threading.Tasks.Dataflow" Version="9.0.0" />
|
||||||
<PackageVersion Include="TagLibSharp" Version="2.3.0" />
|
<PackageVersion Include="TagLibSharp" Version="2.3.0" />
|
||||||
<PackageVersion Include="z440.atl.core" Version="6.8.0" />
|
<PackageVersion Include="z440.atl.core" Version="6.9.0" />
|
||||||
<PackageVersion Include="TMDbLib" Version="2.2.0" />
|
<PackageVersion Include="TMDbLib" Version="2.2.0" />
|
||||||
<PackageVersion Include="UTF.Unknown" Version="2.5.1" />
|
<PackageVersion Include="UTF.Unknown" Version="2.5.1" />
|
||||||
<PackageVersion Include="Xunit.Priority" Version="1.1.6" />
|
<PackageVersion Include="Xunit.Priority" Version="1.1.6" />
|
||||||
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
|
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
|
||||||
<PackageVersion Include="Xunit.SkippableFact" Version="1.4.13" />
|
<PackageVersion Include="Xunit.SkippableFact" Version="1.5.23" />
|
||||||
<PackageVersion Include="xunit" Version="2.9.2" />
|
<PackageVersion Include="xunit" Version="2.9.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -131,5 +131,6 @@
|
|||||||
"TaskRefreshTrickplayImages": "Генерирај слики за прегледување (Trickplay)",
|
"TaskRefreshTrickplayImages": "Генерирај слики за прегледување (Trickplay)",
|
||||||
"TaskAudioNormalization": "Нормализација на звукот",
|
"TaskAudioNormalization": "Нормализација на звукот",
|
||||||
"TaskRefreshTrickplayImagesDescription": "Креира трикплеј прегледи за видеа во овозможените библиотеки.",
|
"TaskRefreshTrickplayImagesDescription": "Креира трикплеј прегледи за видеа во овозможените библиотеки.",
|
||||||
"TaskCleanCollectionsAndPlaylistsDescription": "Отстранува ставки од колекциите и плејлистите што веќе не постојат."
|
"TaskCleanCollectionsAndPlaylistsDescription": "Отстранува ставки од колекциите и плејлистите што веќе не постојат.",
|
||||||
|
"TaskExtractMediaSegments": "Скенирање на сегменти на содржина"
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@
|
|||||||
"HeaderAlbumArtists": "Artiști album",
|
"HeaderAlbumArtists": "Artiști album",
|
||||||
"Genres": "Genuri",
|
"Genres": "Genuri",
|
||||||
"Folders": "Dosare",
|
"Folders": "Dosare",
|
||||||
"Favorites": "Favorite",
|
"Favorites": "Preferate",
|
||||||
"FailedLoginAttemptWithUserName": "Încercare de conectare eșuată pentru {0}",
|
"FailedLoginAttemptWithUserName": "Încercare de conectare eșuată pentru {0}",
|
||||||
"DeviceOnlineWithName": "{0} este conectat",
|
"DeviceOnlineWithName": "{0} este conectat",
|
||||||
"DeviceOfflineWithName": "{0} s-a deconectat",
|
"DeviceOfflineWithName": "{0} s-a deconectat",
|
||||||
|
@ -133,5 +133,6 @@
|
|||||||
"TaskDownloadMissingLyricsDescription": "下載歌詞",
|
"TaskDownloadMissingLyricsDescription": "下載歌詞",
|
||||||
"TaskCleanCollectionsAndPlaylists": "整理媒體與播放清單",
|
"TaskCleanCollectionsAndPlaylists": "整理媒體與播放清單",
|
||||||
"TaskAudioNormalization": "音訊同等化",
|
"TaskAudioNormalization": "音訊同等化",
|
||||||
"TaskAudioNormalizationDescription": "掃描檔案裏的音訊同等化資料。"
|
"TaskAudioNormalizationDescription": "掃描檔案裏的音訊同等化資料。",
|
||||||
|
"TaskCleanCollectionsAndPlaylistsDescription": "從資料庫及播放清單中移除已不存在的項目。"
|
||||||
}
|
}
|
||||||
|
@ -5,23 +5,23 @@ TV-Y,0
|
|||||||
TV-Y7,7
|
TV-Y7,7
|
||||||
TV-Y7-FV,7
|
TV-Y7-FV,7
|
||||||
PG,10
|
PG,10
|
||||||
|
TV-PG,10
|
||||||
|
TV-PG-D,10
|
||||||
|
TV-PG-L,10
|
||||||
|
TV-PG-S,10
|
||||||
|
TV-PG-V,10
|
||||||
|
TV-PG-DL,10
|
||||||
|
TV-PG-DS,10
|
||||||
|
TV-PG-DV,10
|
||||||
|
TV-PG-LS,10
|
||||||
|
TV-PG-LV,10
|
||||||
|
TV-PG-SV,10
|
||||||
|
TV-PG-DLS,10
|
||||||
|
TV-PG-DLV,10
|
||||||
|
TV-PG-DSV,10
|
||||||
|
TV-PG-LSV,10
|
||||||
|
TV-PG-DLSV,10
|
||||||
PG-13,13
|
PG-13,13
|
||||||
TV-PG,13
|
|
||||||
TV-PG-D,13
|
|
||||||
TV-PG-L,13
|
|
||||||
TV-PG-S,13
|
|
||||||
TV-PG-V,13
|
|
||||||
TV-PG-DL,13
|
|
||||||
TV-PG-DS,13
|
|
||||||
TV-PG-DV,13
|
|
||||||
TV-PG-LS,13
|
|
||||||
TV-PG-LV,13
|
|
||||||
TV-PG-SV,13
|
|
||||||
TV-PG-DLS,13
|
|
||||||
TV-PG-DLV,13
|
|
||||||
TV-PG-DSV,13
|
|
||||||
TV-PG-LSV,13
|
|
||||||
TV-PG-DLSV,13
|
|
||||||
TV-14,14
|
TV-14,14
|
||||||
TV-14-D,14
|
TV-14-D,14
|
||||||
TV-14-L,14
|
TV-14-L,14
|
||||||
|
|
@ -785,30 +785,27 @@ namespace Emby.Server.Implementations.Plugins
|
|||||||
|
|
||||||
var cleaned = false;
|
var cleaned = false;
|
||||||
var path = entry.Path;
|
var path = entry.Path;
|
||||||
if (_config.RemoveOldPlugins)
|
// Attempt a cleanup of old folders.
|
||||||
|
try
|
||||||
{
|
{
|
||||||
// Attempt a cleanup of old folders.
|
_logger.LogDebug("Deleting {Path}", path);
|
||||||
try
|
Directory.Delete(path, true);
|
||||||
{
|
cleaned = true;
|
||||||
_logger.LogDebug("Deleting {Path}", path);
|
}
|
||||||
Directory.Delete(path, true);
|
|
||||||
cleaned = true;
|
|
||||||
}
|
|
||||||
#pragma warning disable CA1031 // Do not catch general exception types
|
#pragma warning disable CA1031 // Do not catch general exception types
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
#pragma warning restore CA1031 // Do not catch general exception types
|
#pragma warning restore CA1031 // Do not catch general exception types
|
||||||
{
|
{
|
||||||
_logger.LogWarning(e, "Unable to delete {Path}", path);
|
_logger.LogWarning(e, "Unable to delete {Path}", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cleaned)
|
if (cleaned)
|
||||||
{
|
{
|
||||||
versions.RemoveAt(x);
|
versions.RemoveAt(x);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ChangePluginState(entry, PluginStatus.Deleted);
|
ChangePluginState(entry, PluginStatus.Deleted);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,7 +471,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
IntervalTicks = TimeSpan.FromDays(1).Ticks,
|
IntervalTicks = TimeSpan.FromDays(1).Ticks,
|
||||||
Type = TaskTriggerInfo.TriggerInterval
|
Type = TaskTriggerInfoType.IntervalTrigger
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -616,7 +616,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
MaxRuntimeTicks = info.MaxRuntimeTicks
|
MaxRuntimeTicks = info.MaxRuntimeTicks
|
||||||
};
|
};
|
||||||
|
|
||||||
if (info.Type.Equals(nameof(DailyTrigger), StringComparison.OrdinalIgnoreCase))
|
if (info.Type == TaskTriggerInfoType.DailyTrigger)
|
||||||
{
|
{
|
||||||
if (!info.TimeOfDayTicks.HasValue)
|
if (!info.TimeOfDayTicks.HasValue)
|
||||||
{
|
{
|
||||||
@ -626,7 +626,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
return new DailyTrigger(TimeSpan.FromTicks(info.TimeOfDayTicks.Value), options);
|
return new DailyTrigger(TimeSpan.FromTicks(info.TimeOfDayTicks.Value), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.Type.Equals(nameof(WeeklyTrigger), StringComparison.OrdinalIgnoreCase))
|
if (info.Type == TaskTriggerInfoType.WeeklyTrigger)
|
||||||
{
|
{
|
||||||
if (!info.TimeOfDayTicks.HasValue)
|
if (!info.TimeOfDayTicks.HasValue)
|
||||||
{
|
{
|
||||||
@ -641,7 +641,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
return new WeeklyTrigger(TimeSpan.FromTicks(info.TimeOfDayTicks.Value), info.DayOfWeek.Value, options);
|
return new WeeklyTrigger(TimeSpan.FromTicks(info.TimeOfDayTicks.Value), info.DayOfWeek.Value, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.Type.Equals(nameof(IntervalTrigger), StringComparison.OrdinalIgnoreCase))
|
if (info.Type == TaskTriggerInfoType.IntervalTrigger)
|
||||||
{
|
{
|
||||||
if (!info.IntervalTicks.HasValue)
|
if (!info.IntervalTicks.HasValue)
|
||||||
{
|
{
|
||||||
@ -651,7 +651,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||||||
return new IntervalTrigger(TimeSpan.FromTicks(info.IntervalTicks.Value), options);
|
return new IntervalTrigger(TimeSpan.FromTicks(info.IntervalTicks.Value), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.Type.Equals(nameof(StartupTrigger), StringComparison.OrdinalIgnoreCase))
|
if (info.Type == TaskTriggerInfoType.StartupTrigger)
|
||||||
{
|
{
|
||||||
return new StartupTrigger(options);
|
return new StartupTrigger(options);
|
||||||
}
|
}
|
||||||
|
@ -156,7 +156,7 @@ public partial class AudioNormalizationTask : IScheduledTask
|
|||||||
[
|
[
|
||||||
new TaskTriggerInfo
|
new TaskTriggerInfo
|
||||||
{
|
{
|
||||||
Type = TaskTriggerInfo.TriggerInterval,
|
Type = TaskTriggerInfoType.IntervalTrigger,
|
||||||
IntervalTicks = TimeSpan.FromHours(24).Ticks
|
IntervalTicks = TimeSpan.FromHours(24).Ticks
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -85,7 +85,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
|||||||
[
|
[
|
||||||
new TaskTriggerInfo
|
new TaskTriggerInfo
|
||||||
{
|
{
|
||||||
Type = TaskTriggerInfo.TriggerDaily,
|
Type = TaskTriggerInfoType.DailyTrigger,
|
||||||
TimeOfDayTicks = TimeSpan.FromHours(2).Ticks,
|
TimeOfDayTicks = TimeSpan.FromHours(2).Ticks,
|
||||||
MaxRuntimeTicks = TimeSpan.FromHours(4).Ticks
|
MaxRuntimeTicks = TimeSpan.FromHours(4).Ticks
|
||||||
}
|
}
|
||||||
|
@ -135,6 +135,6 @@ public class CleanupCollectionAndPlaylistPathsTask : IScheduledTask
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
||||||
{
|
{
|
||||||
return [new TaskTriggerInfo() { Type = TaskTriggerInfo.TriggerStartup }];
|
return [new TaskTriggerInfo() { Type = TaskTriggerInfoType.StartupTrigger }];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
|||||||
return
|
return
|
||||||
[
|
[
|
||||||
// Every so often
|
// Every so often
|
||||||
new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks }
|
new TaskTriggerInfo { Type = TaskTriggerInfoType.IntervalTrigger, IntervalTicks = TimeSpan.FromHours(24).Ticks }
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
|||||||
{
|
{
|
||||||
return
|
return
|
||||||
[
|
[
|
||||||
new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks }
|
new TaskTriggerInfo { Type = TaskTriggerInfoType.IntervalTrigger, IntervalTicks = TimeSpan.FromHours(24).Ticks }
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,11 +69,11 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
|||||||
[
|
[
|
||||||
new TaskTriggerInfo
|
new TaskTriggerInfo
|
||||||
{
|
{
|
||||||
Type = TaskTriggerInfo.TriggerStartup
|
Type = TaskTriggerInfoType.StartupTrigger
|
||||||
},
|
},
|
||||||
new TaskTriggerInfo
|
new TaskTriggerInfo
|
||||||
{
|
{
|
||||||
Type = TaskTriggerInfo.TriggerInterval,
|
Type = TaskTriggerInfoType.IntervalTrigger,
|
||||||
IntervalTicks = TimeSpan.FromHours(24).Ticks
|
IntervalTicks = TimeSpan.FromHours(24).Ticks
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -111,7 +111,7 @@ public class MediaSegmentExtractionTask : IScheduledTask
|
|||||||
{
|
{
|
||||||
yield return new TaskTriggerInfo
|
yield return new TaskTriggerInfo
|
||||||
{
|
{
|
||||||
Type = TaskTriggerInfo.TriggerInterval,
|
Type = TaskTriggerInfoType.IntervalTrigger,
|
||||||
IntervalTicks = TimeSpan.FromHours(12).Ticks
|
IntervalTicks = TimeSpan.FromHours(12).Ticks
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
|||||||
return
|
return
|
||||||
[
|
[
|
||||||
// Every so often
|
// Every so often
|
||||||
new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks }
|
new TaskTriggerInfo { Type = TaskTriggerInfoType.IntervalTrigger, IntervalTicks = TimeSpan.FromHours(24).Ticks }
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
|||||||
{
|
{
|
||||||
new TaskTriggerInfo
|
new TaskTriggerInfo
|
||||||
{
|
{
|
||||||
Type = TaskTriggerInfo.TriggerInterval,
|
Type = TaskTriggerInfoType.IntervalTrigger,
|
||||||
IntervalTicks = TimeSpan.FromDays(7).Ticks
|
IntervalTicks = TimeSpan.FromDays(7).Ticks
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -60,10 +60,10 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
|||||||
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
||||||
{
|
{
|
||||||
// At startup
|
// At startup
|
||||||
yield return new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerStartup };
|
yield return new TaskTriggerInfo { Type = TaskTriggerInfoType.StartupTrigger };
|
||||||
|
|
||||||
// Every so often
|
// Every so often
|
||||||
yield return new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks };
|
yield return new TaskTriggerInfo { Type = TaskTriggerInfoType.IntervalTrigger, IntervalTicks = TimeSpan.FromHours(24).Ticks };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
@ -48,7 +48,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
|||||||
{
|
{
|
||||||
yield return new TaskTriggerInfo
|
yield return new TaskTriggerInfo
|
||||||
{
|
{
|
||||||
Type = TaskTriggerInfo.TriggerInterval,
|
Type = TaskTriggerInfoType.IntervalTrigger,
|
||||||
IntervalTicks = TimeSpan.FromHours(12).Ticks
|
IntervalTicks = TimeSpan.FromHours(12).Ticks
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1819,16 +1819,13 @@ public class DynamicHlsController : BaseJellyfinApiController
|
|||||||
if (isActualOutputVideoCodecHevc || isActualOutputVideoCodecAv1)
|
if (isActualOutputVideoCodecHevc || isActualOutputVideoCodecAv1)
|
||||||
{
|
{
|
||||||
var requestedRange = state.GetRequestedRangeTypes(state.ActualOutputVideoCodec);
|
var requestedRange = state.GetRequestedRangeTypes(state.ActualOutputVideoCodec);
|
||||||
var requestHasDOVI = requestedRange.Contains(VideoRangeType.DOVI.ToString(), StringComparison.OrdinalIgnoreCase);
|
// Clients reporting Dolby Vision capabilities with fallbacks may only support the fallback layer.
|
||||||
var requestHasDOVIWithHDR10 = requestedRange.Contains(VideoRangeType.DOVIWithHDR10.ToString(), StringComparison.OrdinalIgnoreCase);
|
// Only enable Dolby Vision remuxing if the client explicitly declares support for profiles without fallbacks.
|
||||||
var requestHasDOVIWithHLG = requestedRange.Contains(VideoRangeType.DOVIWithHLG.ToString(), StringComparison.OrdinalIgnoreCase);
|
var clientSupportsDoVi = requestedRange.Contains(VideoRangeType.DOVI.ToString(), StringComparison.OrdinalIgnoreCase);
|
||||||
var requestHasDOVIWithSDR = requestedRange.Contains(VideoRangeType.DOVIWithSDR.ToString(), StringComparison.OrdinalIgnoreCase);
|
var videoIsDoVi = state.VideoStream.VideoRangeType is VideoRangeType.DOVI or VideoRangeType.DOVIWithHDR10 or VideoRangeType.DOVIWithHLG or VideoRangeType.DOVIWithSDR;
|
||||||
|
|
||||||
if (EncodingHelper.IsCopyCodec(codec)
|
if (EncodingHelper.IsCopyCodec(codec)
|
||||||
&& ((state.VideoStream.VideoRangeType == VideoRangeType.DOVI && requestHasDOVI)
|
&& (videoIsDoVi && clientSupportsDoVi))
|
||||||
|| (state.VideoStream.VideoRangeType == VideoRangeType.DOVIWithHDR10 && requestHasDOVIWithHDR10)
|
|
||||||
|| (state.VideoStream.VideoRangeType == VideoRangeType.DOVIWithHLG && requestHasDOVIWithHLG)
|
|
||||||
|| (state.VideoStream.VideoRangeType == VideoRangeType.DOVIWithSDR && requestHasDOVIWithSDR)))
|
|
||||||
{
|
{
|
||||||
if (isActualOutputVideoCodecHevc)
|
if (isActualOutputVideoCodecHevc)
|
||||||
{
|
{
|
||||||
|
@ -962,9 +962,9 @@ public class LiveTvController : BaseJellyfinApiController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get guid info.
|
/// Get guide info.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <response code="200">Guid info returned.</response>
|
/// <response code="200">Guide info returned.</response>
|
||||||
/// <returns>An <see cref="OkResult"/> containing the guide info.</returns>
|
/// <returns>An <see cref="OkResult"/> containing the guide info.</returns>
|
||||||
[HttpGet("GuideInfo")]
|
[HttpGet("GuideInfo")]
|
||||||
[Authorize(Policy = Policies.LiveTvAccess)]
|
[Authorize(Policy = Policies.LiveTvAccess)]
|
||||||
|
@ -61,7 +61,7 @@ public class MediaSegmentManager : IMediaSegmentManager
|
|||||||
.Where(e => !libraryOptions.DisabledMediaSegmentProviders.Contains(GetProviderId(e.Name)))
|
.Where(e => !libraryOptions.DisabledMediaSegmentProviders.Contains(GetProviderId(e.Name)))
|
||||||
.OrderBy(i =>
|
.OrderBy(i =>
|
||||||
{
|
{
|
||||||
var index = libraryOptions.MediaSegmentProvideOrder.IndexOf(i.Name);
|
var index = libraryOptions.MediaSegmentProviderOrder.IndexOf(i.Name);
|
||||||
return index == -1 ? int.MaxValue : index;
|
return index == -1 ? int.MaxValue : index;
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
@ -30,7 +30,7 @@ namespace Jellyfin.Server.Migrations.Routines
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public Guid Id => Guid.Parse("{67445D54-B895-4B24-9F4C-35CE0690EA07}");
|
public Guid Id => Guid.Parse("{73DAB92A-178B-48CD-B05B-FE18733ACDC8}");
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public string Name => "MigrateRatingLevels";
|
public string Name => "MigrateRatingLevels";
|
||||||
|
@ -15,7 +15,7 @@ namespace MediaBrowser.Model.Configuration
|
|||||||
TypeOptions = Array.Empty<TypeOptions>();
|
TypeOptions = Array.Empty<TypeOptions>();
|
||||||
DisabledSubtitleFetchers = Array.Empty<string>();
|
DisabledSubtitleFetchers = Array.Empty<string>();
|
||||||
DisabledMediaSegmentProviders = Array.Empty<string>();
|
DisabledMediaSegmentProviders = Array.Empty<string>();
|
||||||
MediaSegmentProvideOrder = Array.Empty<string>();
|
MediaSegmentProviderOrder = Array.Empty<string>();
|
||||||
SubtitleFetcherOrder = Array.Empty<string>();
|
SubtitleFetcherOrder = Array.Empty<string>();
|
||||||
DisabledLocalMetadataReaders = Array.Empty<string>();
|
DisabledLocalMetadataReaders = Array.Empty<string>();
|
||||||
DisabledLyricFetchers = Array.Empty<string>();
|
DisabledLyricFetchers = Array.Empty<string>();
|
||||||
@ -99,7 +99,7 @@ namespace MediaBrowser.Model.Configuration
|
|||||||
|
|
||||||
public string[] DisabledMediaSegmentProviders { get; set; }
|
public string[] DisabledMediaSegmentProviders { get; set; }
|
||||||
|
|
||||||
public string[] MediaSegmentProvideOrder { get; set; }
|
public string[] MediaSegmentProviderOrder { get; set; }
|
||||||
|
|
||||||
public bool SkipSubtitlesIfEmbeddedSubtitlesPresent { get; set; }
|
public bool SkipSubtitlesIfEmbeddedSubtitlesPresent { get; set; }
|
||||||
|
|
||||||
|
@ -243,11 +243,6 @@ public class ServerConfiguration : BaseApplicationConfiguration
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int LibraryMetadataRefreshConcurrency { get; set; }
|
public int LibraryMetadataRefreshConcurrency { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether older plugins should automatically be deleted from the plugin folder.
|
|
||||||
/// </summary>
|
|
||||||
public bool RemoveOldPlugins { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether clients should be allowed to upload logs.
|
/// Gets or sets a value indicating whether clients should be allowed to upload logs.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -125,6 +125,7 @@ namespace MediaBrowser.Model.Net
|
|||||||
new("audio/vorbis", ".vorbis"),
|
new("audio/vorbis", ".vorbis"),
|
||||||
new("audio/x-ape", ".ape"),
|
new("audio/x-ape", ".ape"),
|
||||||
new("audio/xsp", ".xsp"),
|
new("audio/xsp", ".xsp"),
|
||||||
|
new("audio/x-aac", ".aac"),
|
||||||
new("audio/x-wavpack", ".wv"),
|
new("audio/x-wavpack", ".wv"),
|
||||||
|
|
||||||
// Type image
|
// Type image
|
||||||
|
@ -8,31 +8,11 @@ namespace MediaBrowser.Model.Tasks
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class TaskTriggerInfo
|
public class TaskTriggerInfo
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The daily trigger.
|
|
||||||
/// </summary>
|
|
||||||
public const string TriggerDaily = "DailyTrigger";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The weekly trigger.
|
|
||||||
/// </summary>
|
|
||||||
public const string TriggerWeekly = "WeeklyTrigger";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The interval trigger.
|
|
||||||
/// </summary>
|
|
||||||
public const string TriggerInterval = "IntervalTrigger";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The startup trigger.
|
|
||||||
/// </summary>
|
|
||||||
public const string TriggerStartup = "StartupTrigger";
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the type.
|
/// Gets or sets the type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The type.</value>
|
/// <value>The type.</value>
|
||||||
public string Type { get; set; }
|
public TaskTriggerInfoType Type { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the time of day.
|
/// Gets or sets the time of day.
|
||||||
|
28
MediaBrowser.Model/Tasks/TaskTriggerInfoType.cs
Normal file
28
MediaBrowser.Model/Tasks/TaskTriggerInfoType.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
namespace MediaBrowser.Model.Tasks
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Enum TaskTriggerInfoType.
|
||||||
|
/// </summary>
|
||||||
|
public enum TaskTriggerInfoType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The daily trigger.
|
||||||
|
/// </summary>
|
||||||
|
DailyTrigger,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The weekly trigger.
|
||||||
|
/// </summary>
|
||||||
|
WeeklyTrigger,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The interval trigger.
|
||||||
|
/// </summary>
|
||||||
|
IntervalTrigger,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The startup trigger.
|
||||||
|
/// </summary>
|
||||||
|
StartupTrigger
|
||||||
|
}
|
||||||
|
}
|
@ -162,7 +162,7 @@ public class LyricScheduledTask : IScheduledTask
|
|||||||
[
|
[
|
||||||
new TaskTriggerInfo
|
new TaskTriggerInfo
|
||||||
{
|
{
|
||||||
Type = TaskTriggerInfo.TriggerInterval,
|
Type = TaskTriggerInfoType.IntervalTrigger,
|
||||||
IntervalTicks = TimeSpan.FromHours(24).Ticks
|
IntervalTicks = TimeSpan.FromHours(24).Ticks
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -217,7 +217,7 @@ namespace MediaBrowser.Providers.MediaInfo
|
|||||||
return new[]
|
return new[]
|
||||||
{
|
{
|
||||||
// Every so often
|
// Every so often
|
||||||
new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks }
|
new TaskTriggerInfo { Type = TaskTriggerInfoType.IntervalTrigger, IntervalTicks = TimeSpan.FromHours(24).Ticks }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ public class TrickplayImagesTask : IScheduledTask
|
|||||||
{
|
{
|
||||||
new TaskTriggerInfo
|
new TaskTriggerInfo
|
||||||
{
|
{
|
||||||
Type = TaskTriggerInfo.TriggerDaily,
|
Type = TaskTriggerInfoType.DailyTrigger,
|
||||||
TimeOfDayTicks = TimeSpan.FromHours(3).Ticks
|
TimeOfDayTicks = TimeSpan.FromHours(3).Ticks
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -79,7 +79,7 @@ namespace Jellyfin.LiveTv.Channels
|
|||||||
// Every so often
|
// Every so often
|
||||||
new TaskTriggerInfo
|
new TaskTriggerInfo
|
||||||
{
|
{
|
||||||
Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks
|
Type = TaskTriggerInfoType.IntervalTrigger, IntervalTicks = TimeSpan.FromHours(24).Ticks
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ public class RefreshGuideScheduledTask : IScheduledTask, IConfigurableScheduledT
|
|||||||
{
|
{
|
||||||
new TaskTriggerInfo
|
new TaskTriggerInfo
|
||||||
{
|
{
|
||||||
Type = TaskTriggerInfo.TriggerInterval,
|
Type = TaskTriggerInfoType.IntervalTrigger,
|
||||||
IntervalTicks = TimeSpan.FromHours(24).Ticks
|
IntervalTicks = TimeSpan.FromHours(24).Ticks
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
50
tests/Jellyfin.LiveTv.Tests/Listings/ListingsManagerTests.cs
Normal file
50
tests/Jellyfin.LiveTv.Tests/Listings/ListingsManagerTests.cs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
using System;
|
||||||
|
using Jellyfin.LiveTv.Configuration;
|
||||||
|
using Jellyfin.LiveTv.Listings;
|
||||||
|
using MediaBrowser.Common.Configuration;
|
||||||
|
using MediaBrowser.Controller.LiveTv;
|
||||||
|
using MediaBrowser.Model.LiveTv;
|
||||||
|
using MediaBrowser.Model.Tasks;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Moq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Jellyfin.LiveTv.Tests.Listings;
|
||||||
|
|
||||||
|
public class ListingsManagerTests
|
||||||
|
{
|
||||||
|
private readonly IConfigurationManager _config;
|
||||||
|
private readonly IListingsProvider[] _listingsProviders;
|
||||||
|
private readonly ILogger<ListingsManager> _logger;
|
||||||
|
private readonly ITaskManager _taskManager;
|
||||||
|
private readonly ITunerHostManager _tunerHostManager;
|
||||||
|
|
||||||
|
public ListingsManagerTests()
|
||||||
|
{
|
||||||
|
_logger = Mock.Of<ILogger<ListingsManager>>();
|
||||||
|
_config = Mock.Of<IConfigurationManager>();
|
||||||
|
_taskManager = Mock.Of<ITaskManager>();
|
||||||
|
_tunerHostManager = Mock.Of<ITunerHostManager>();
|
||||||
|
_listingsProviders = new[] { Mock.Of<IListingsProvider>() };
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DeleteListingsProvider_DeletesProvider()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var id = "MockId";
|
||||||
|
var manager = new ListingsManager(_logger, _config, _taskManager, _tunerHostManager, _listingsProviders);
|
||||||
|
|
||||||
|
Mock.Get(_config)
|
||||||
|
.Setup(x => x.GetConfiguration(It.IsAny<string>()))
|
||||||
|
.Returns(new LiveTvOptions { ListingProviders = [new ListingsProviderInfo { Id = id }] });
|
||||||
|
|
||||||
|
// Act
|
||||||
|
manager.DeleteListingsProvider(id);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.DoesNotContain(
|
||||||
|
_config.GetLiveTvConfiguration().ListingProviders,
|
||||||
|
p => p.Id.Equals(id, StringComparison.Ordinal));
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user