diff --git a/.vscode/launch.json b/.vscode/launch.json
index 0f698bfa4..bf1bd65cb 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -6,11 +6,21 @@
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
- // If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/Jellyfin.Server/bin/Debug/netcoreapp3.1/jellyfin.dll",
"args": [],
"cwd": "${workspaceFolder}/Jellyfin.Server",
- // For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window
+ "console": "internalConsole",
+ "stopAtEntry": false,
+ "internalConsoleOptions": "openOnSessionStart"
+ },
+ {
+ "name": ".NET Core Launch (nowebclient)",
+ "type": "coreclr",
+ "request": "launch",
+ "preLaunchTask": "build",
+ "program": "${workspaceFolder}/Jellyfin.Server/bin/Debug/netcoreapp3.1/jellyfin.dll",
+ "args": ["--nowebclient"],
+ "cwd": "${workspaceFolder}/Jellyfin.Server",
"console": "internalConsole",
"stopAtEntry": false,
"internalConsoleOptions": "openOnSessionStart"
diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
index d3e212be1..1adef68aa 100644
--- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj
+++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
@@ -38,7 +38,7 @@
-
+
diff --git a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
index c1068522a..1deef7f72 100644
--- a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
+++ b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
@@ -23,10 +23,12 @@ namespace Emby.Server.Implementations.EntryPoints
public class LibraryChangedNotifier : IServerEntryPoint
{
///
- /// The library manager.
+ /// The library update duration.
///
- private readonly ILibraryManager _libraryManager;
+ private const int LibraryUpdateDuration = 30000;
+ private readonly ILibraryManager _libraryManager;
+ private readonly IProviderManager _providerManager;
private readonly ISessionManager _sessionManager;
private readonly IUserManager _userManager;
private readonly ILogger _logger;
@@ -38,23 +40,10 @@ namespace Emby.Server.Implementations.EntryPoints
private readonly List _foldersAddedTo = new List();
private readonly List _foldersRemovedFrom = new List();
-
private readonly List _itemsAdded = new List();
private readonly List _itemsRemoved = new List();
private readonly List _itemsUpdated = new List();
-
- ///
- /// Gets or sets the library update timer.
- ///
- /// The library update timer.
- private Timer LibraryUpdateTimer { get; set; }
-
- ///
- /// The library update duration.
- ///
- private const int LibraryUpdateDuration = 30000;
-
- private readonly IProviderManager _providerManager;
+ private readonly Dictionary _lastProgressMessageTimes = new Dictionary();
public LibraryChangedNotifier(
ILibraryManager libraryManager,
@@ -70,22 +59,26 @@ namespace Emby.Server.Implementations.EntryPoints
_providerManager = providerManager;
}
+ ///
+ /// Gets or sets the library update timer.
+ ///
+ /// The library update timer.
+ private Timer LibraryUpdateTimer { get; set; }
+
public Task RunAsync()
{
- _libraryManager.ItemAdded += libraryManager_ItemAdded;
- _libraryManager.ItemUpdated += libraryManager_ItemUpdated;
- _libraryManager.ItemRemoved += libraryManager_ItemRemoved;
+ _libraryManager.ItemAdded += OnLibraryItemAdded;
+ _libraryManager.ItemUpdated += OnLibraryItemUpdated;
+ _libraryManager.ItemRemoved += OnLibraryItemRemoved;
- _providerManager.RefreshCompleted += _providerManager_RefreshCompleted;
- _providerManager.RefreshStarted += _providerManager_RefreshStarted;
- _providerManager.RefreshProgress += _providerManager_RefreshProgress;
+ _providerManager.RefreshCompleted += OnProviderRefreshCompleted;
+ _providerManager.RefreshStarted += OnProviderRefreshStarted;
+ _providerManager.RefreshProgress += OnProviderRefreshProgress;
return Task.CompletedTask;
}
- private Dictionary _lastProgressMessageTimes = new Dictionary();
-
- private void _providerManager_RefreshProgress(object sender, GenericEventArgs> e)
+ private void OnProviderRefreshProgress(object sender, GenericEventArgs> e)
{
var item = e.Argument.Item1;
@@ -122,9 +115,11 @@ namespace Emby.Server.Implementations.EntryPoints
foreach (var collectionFolder in collectionFolders)
{
- var collectionFolderDict = new Dictionary();
- collectionFolderDict["ItemId"] = collectionFolder.Id.ToString("N", CultureInfo.InvariantCulture);
- collectionFolderDict["Progress"] = (collectionFolder.GetRefreshProgress() ?? 0).ToString(CultureInfo.InvariantCulture);
+ var collectionFolderDict = new Dictionary
+ {
+ ["ItemId"] = collectionFolder.Id.ToString("N", CultureInfo.InvariantCulture),
+ ["Progress"] = (collectionFolder.GetRefreshProgress() ?? 0).ToString(CultureInfo.InvariantCulture)
+ };
try
{
@@ -136,21 +131,19 @@ namespace Emby.Server.Implementations.EntryPoints
}
}
- private void _providerManager_RefreshStarted(object sender, GenericEventArgs e)
+ private void OnProviderRefreshStarted(object sender, GenericEventArgs e)
{
- _providerManager_RefreshProgress(sender, new GenericEventArgs>(new Tuple(e.Argument, 0)));
+ OnProviderRefreshProgress(sender, new GenericEventArgs>(new Tuple(e.Argument, 0)));
}
- private void _providerManager_RefreshCompleted(object sender, GenericEventArgs e)
+ private void OnProviderRefreshCompleted(object sender, GenericEventArgs e)
{
- _providerManager_RefreshProgress(sender, new GenericEventArgs>(new Tuple(e.Argument, 100)));
+ OnProviderRefreshProgress(sender, new GenericEventArgs>(new Tuple(e.Argument, 100)));
}
private static bool EnableRefreshMessage(BaseItem item)
{
- var folder = item as Folder;
-
- if (folder == null)
+ if (!(item is Folder folder))
{
return false;
}
@@ -183,7 +176,7 @@ namespace Emby.Server.Implementations.EntryPoints
///
/// The source of the event.
/// The instance containing the event data.
- void libraryManager_ItemAdded(object sender, ItemChangeEventArgs e)
+ private void OnLibraryItemAdded(object sender, ItemChangeEventArgs e)
{
if (!FilterItem(e.Item))
{
@@ -205,8 +198,7 @@ namespace Emby.Server.Implementations.EntryPoints
LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite);
}
- var parent = e.Item.GetParent() as Folder;
- if (parent != null)
+ if (e.Item.GetParent() is Folder parent)
{
_foldersAddedTo.Add(parent);
}
@@ -220,7 +212,7 @@ namespace Emby.Server.Implementations.EntryPoints
///
/// The source of the event.
/// The instance containing the event data.
- void libraryManager_ItemUpdated(object sender, ItemChangeEventArgs e)
+ private void OnLibraryItemUpdated(object sender, ItemChangeEventArgs e)
{
if (!FilterItem(e.Item))
{
@@ -231,8 +223,7 @@ namespace Emby.Server.Implementations.EntryPoints
{
if (LibraryUpdateTimer == null)
{
- LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, LibraryUpdateDuration,
- Timeout.Infinite);
+ LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, LibraryUpdateDuration, Timeout.Infinite);
}
else
{
@@ -248,7 +239,7 @@ namespace Emby.Server.Implementations.EntryPoints
///
/// The source of the event.
/// The instance containing the event data.
- void libraryManager_ItemRemoved(object sender, ItemChangeEventArgs e)
+ private void OnLibraryItemRemoved(object sender, ItemChangeEventArgs e)
{
if (!FilterItem(e.Item))
{
@@ -259,16 +250,14 @@ namespace Emby.Server.Implementations.EntryPoints
{
if (LibraryUpdateTimer == null)
{
- LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, LibraryUpdateDuration,
- Timeout.Infinite);
+ LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, LibraryUpdateDuration, Timeout.Infinite);
}
else
{
LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite);
}
- var parent = e.Parent as Folder;
- if (parent != null)
+ if (e.Parent is Folder parent)
{
_foldersRemovedFrom.Add(parent);
}
@@ -486,13 +475,13 @@ namespace Emby.Server.Implementations.EntryPoints
LibraryUpdateTimer = null;
}
- _libraryManager.ItemAdded -= libraryManager_ItemAdded;
- _libraryManager.ItemUpdated -= libraryManager_ItemUpdated;
- _libraryManager.ItemRemoved -= libraryManager_ItemRemoved;
+ _libraryManager.ItemAdded -= OnLibraryItemAdded;
+ _libraryManager.ItemUpdated -= OnLibraryItemUpdated;
+ _libraryManager.ItemRemoved -= OnLibraryItemRemoved;
- _providerManager.RefreshCompleted -= _providerManager_RefreshCompleted;
- _providerManager.RefreshStarted -= _providerManager_RefreshStarted;
- _providerManager.RefreshProgress -= _providerManager_RefreshProgress;
+ _providerManager.RefreshCompleted -= OnProviderRefreshCompleted;
+ _providerManager.RefreshStarted -= OnProviderRefreshStarted;
+ _providerManager.RefreshProgress -= OnProviderRefreshProgress;
}
}
}
diff --git a/Emby.Server.Implementations/Localization/Core/de.json b/Emby.Server.Implementations/Localization/Core/de.json
index eec880208..fcbe9566e 100644
--- a/Emby.Server.Implementations/Localization/Core/de.json
+++ b/Emby.Server.Implementations/Localization/Core/de.json
@@ -5,7 +5,7 @@
"Artists": "Interpreten",
"AuthenticationSucceededWithUserName": "{0} hat sich erfolgreich angemeldet",
"Books": "Bücher",
- "CameraImageUploadedFrom": "Ein neues Foto wurde von {0} hochgeladen",
+ "CameraImageUploadedFrom": "Ein neues Kamerafoto wurde von {0} hochgeladen",
"Channels": "Kanäle",
"ChapterNameValue": "Kapitel {0}",
"Collections": "Sammlungen",
@@ -106,7 +106,7 @@
"TaskCleanLogsDescription": "Lösche Log Dateien die älter als {0} Tage sind.",
"TaskCleanLogs": "Lösche Log Pfad",
"TaskRefreshLibraryDescription": "Scanne alle Bibliotheken für hinzugefügte Datein und erneuere Metadaten.",
- "TaskRefreshLibrary": "Scanne alle Bibliotheken",
+ "TaskRefreshLibrary": "Scanne Medien-Bibliothek",
"TaskRefreshChapterImagesDescription": "Kreiert Vorschaubilder für Videos welche Kapitel haben.",
"TaskRefreshChapterImages": "Extrahiert Kapitel-Bilder",
"TaskCleanCacheDescription": "Löscht Zwischenspeicherdatein die nicht länger von System gebraucht werden.",
diff --git a/Emby.Server.Implementations/Localization/Core/uk.json b/Emby.Server.Implementations/Localization/Core/uk.json
index b2e0b66fe..e673465a4 100644
--- a/Emby.Server.Implementations/Localization/Core/uk.json
+++ b/Emby.Server.Implementations/Localization/Core/uk.json
@@ -1,13 +1,13 @@
{
- "MusicVideos": "Музичні відео",
+ "MusicVideos": "Музичні кліпи",
"Music": "Музика",
"Movies": "Фільми",
- "MessageApplicationUpdatedTo": "Jellyfin Server був оновлений до версії {0}",
- "MessageApplicationUpdated": "Jellyfin Server був оновлений",
+ "MessageApplicationUpdatedTo": "Jellyfin Server оновлено до версії {0}",
+ "MessageApplicationUpdated": "Jellyfin Server оновлено",
"Latest": "Останні",
- "LabelIpAddressValue": "IP-адреси: {0}",
- "ItemRemovedWithName": "{0} видалено з бібліотеки",
- "ItemAddedWithName": "{0} додано до бібліотеки",
+ "LabelIpAddressValue": "IP-адреса: {0}",
+ "ItemRemovedWithName": "{0} видалено з медіатеки",
+ "ItemAddedWithName": "{0} додано до медіатеки",
"HeaderNextUp": "Наступний",
"HeaderLiveTV": "Ефірне ТБ",
"HeaderFavoriteSongs": "Улюблені пісні",
@@ -17,20 +17,101 @@
"HeaderFavoriteAlbums": "Улюблені альбоми",
"HeaderContinueWatching": "Продовжити перегляд",
"HeaderCameraUploads": "Завантажено з камери",
- "HeaderAlbumArtists": "Виконавці альбомів",
+ "HeaderAlbumArtists": "Виконавці альбому",
"Genres": "Жанри",
- "Folders": "Директорії",
+ "Folders": "Каталоги",
"Favorites": "Улюблені",
- "DeviceOnlineWithName": "{0} під'єднано",
- "DeviceOfflineWithName": "{0} від'єднано",
+ "DeviceOnlineWithName": "Пристрій {0} підключився",
+ "DeviceOfflineWithName": "Пристрій {0} відключився",
"Collections": "Колекції",
- "ChapterNameValue": "Глава {0}",
+ "ChapterNameValue": "Розділ {0}",
"Channels": "Канали",
"CameraImageUploadedFrom": "Нова фотографія завантажена з {0}",
"Books": "Книги",
- "AuthenticationSucceededWithUserName": "{0} успішно авторизовані",
+ "AuthenticationSucceededWithUserName": "{0} успішно авторизований",
"Artists": "Виконавці",
"Application": "Додаток",
"AppDeviceValues": "Додаток: {0}, Пристрій: {1}",
- "Albums": "Альбоми"
+ "Albums": "Альбоми",
+ "NotificationOptionServerRestartRequired": "Необхідно перезапустити сервер",
+ "NotificationOptionPluginUpdateInstalled": "Встановлено оновлення плагіна",
+ "NotificationOptionPluginUninstalled": "Плагін видалено",
+ "NotificationOptionPluginInstalled": "Плагін встановлено",
+ "NotificationOptionPluginError": "Помилка плагіна",
+ "NotificationOptionNewLibraryContent": "Додано новий контент",
+ "HomeVideos": "Домашнє відео",
+ "FailedLoginAttemptWithUserName": "Невдала спроба входу від {0}",
+ "LabelRunningTimeValue": "Тривалість: {0}",
+ "TaskDownloadMissingSubtitlesDescription": "Шукає в Інтернеті відсутні субтитри на основі конфігурації метаданих.",
+ "TaskDownloadMissingSubtitles": "Завантажити відсутні субтитри",
+ "TaskRefreshChannelsDescription": "Оновлення інформації про Інтернет-канали.",
+ "TaskRefreshChannels": "Оновити канали",
+ "TaskCleanTranscodeDescription": "Вилучає файли для перекодування старше одного дня.",
+ "TaskCleanTranscode": "Очистити каталог перекодування",
+ "TaskUpdatePluginsDescription": "Завантажує та встановлює оновлення для плагінів, налаштованих на автоматичне оновлення.",
+ "TaskUpdatePlugins": "Оновити плагіни",
+ "TaskRefreshPeopleDescription": "Оновлення метаданих для акторів та режисерів у вашій медіатеці.",
+ "TaskRefreshPeople": "Оновити людей",
+ "TaskCleanLogsDescription": "Видаляє файли журналу, яким більше {0} днів.",
+ "TaskCleanLogs": "Очистити журнали",
+ "TaskRefreshLibraryDescription": "Сканує медіатеку на нові файли та оновлює метадані.",
+ "TaskRefreshLibrary": "Сканувати медіатеку",
+ "TaskRefreshChapterImagesDescription": "Створює ескізи для відео, які мають розділи.",
+ "TaskRefreshChapterImages": "Створити ескізи розділів",
+ "TaskCleanCacheDescription": "Видаляє файли кешу, які більше не потрібні системі.",
+ "TaskCleanCache": "Очистити кеш",
+ "TasksChannelsCategory": "Інтернет-канали",
+ "TasksApplicationCategory": "Додаток",
+ "TasksLibraryCategory": "Медіатека",
+ "TasksMaintenanceCategory": "Обслуговування",
+ "VersionNumber": "Версія {0}",
+ "ValueSpecialEpisodeName": "Спецепізод - {0}",
+ "ValueHasBeenAddedToLibrary": "{0} додано до медіатеки",
+ "UserStoppedPlayingItemWithValues": "{0} закінчив відтворення {1} на {2}",
+ "UserStartedPlayingItemWithValues": "{0} відтворює {1} на {2}",
+ "UserPolicyUpdatedWithName": "Політика користувача оновлена для {0}",
+ "UserPasswordChangedWithName": "Пароль змінено для користувача {0}",
+ "UserOnlineFromDevice": "{0} підключився з {1}",
+ "UserOfflineFromDevice": "{0} відключився від {1}",
+ "UserLockedOutWithName": "Користувача {0} заблоковано",
+ "UserDownloadingItemWithValues": "{0} завантажує {1}",
+ "UserDeletedWithName": "Користувача {0} видалено",
+ "UserCreatedWithName": "Користувача {0} створено",
+ "User": "Користувач",
+ "TvShows": "ТВ-шоу",
+ "System": "Система",
+ "Sync": "Синхронізація",
+ "SubtitleDownloadFailureFromForItem": "Не вдалося завантажити субтитри з {0} для {1}",
+ "StartupEmbyServerIsLoading": "Jellyfin Server завантажується. Будь ласка, спробуйте трішки пізніше.",
+ "Songs": "Пісні",
+ "Shows": "Шоу",
+ "ServerNameNeedsToBeRestarted": "{0} потрібно перезапустити",
+ "ScheduledTaskStartedWithName": "{0} розпочато",
+ "ScheduledTaskFailedWithName": "Помилка {0}",
+ "ProviderValue": "Постачальник: {0}",
+ "PluginUpdatedWithName": "{0} оновлено",
+ "PluginUninstalledWithName": "{0} видалено",
+ "PluginInstalledWithName": "{0} встановлено",
+ "Plugin": "Плагін",
+ "Playlists": "Плейлисти",
+ "Photos": "Фотографії",
+ "NotificationOptionVideoPlaybackStopped": "Відтворення відео зупинено",
+ "NotificationOptionVideoPlayback": "Розпочато відтворення відео",
+ "NotificationOptionUserLockedOut": "Користувача заблоковано",
+ "NotificationOptionTaskFailed": "Помилка запланованого завдання",
+ "NotificationOptionInstallationFailed": "Помилка встановлення",
+ "NotificationOptionCameraImageUploaded": "Фотографію завантажено",
+ "NotificationOptionAudioPlaybackStopped": "Відтворення аудіо зупинено",
+ "NotificationOptionAudioPlayback": "Розпочато відтворення аудіо",
+ "NotificationOptionApplicationUpdateInstalled": "Встановлено оновлення додатка",
+ "NotificationOptionApplicationUpdateAvailable": "Доступне оновлення додатка",
+ "NewVersionIsAvailable": "Для завантаження доступна нова версія Jellyfin Server.",
+ "NameSeasonUnknown": "Сезон Невідомий",
+ "NameSeasonNumber": "Сезон {0}",
+ "NameInstallFailed": "Не вдалося встановити {0}",
+ "MixedContent": "Змішаний контент",
+ "MessageServerConfigurationUpdated": "Конфігурація сервера оновлена",
+ "MessageNamedServerConfigurationUpdatedWithValue": "Розділ конфігурації сервера {0} оновлено",
+ "Inherit": "Успадкувати",
+ "HeaderRecordingGroups": "Групи запису"
}
diff --git a/Jellyfin.Api/Auth/FirstTimeOrIgnoreParentalControlSetupPolicy/FirstTimeOrIgnoreParentalControlSetupHandler.cs b/Jellyfin.Api/Auth/FirstTimeOrIgnoreParentalControlSetupPolicy/FirstTimeOrIgnoreParentalControlSetupHandler.cs
index 2a02f8bc7..31482a930 100644
--- a/Jellyfin.Api/Auth/FirstTimeOrIgnoreParentalControlSetupPolicy/FirstTimeOrIgnoreParentalControlSetupHandler.cs
+++ b/Jellyfin.Api/Auth/FirstTimeOrIgnoreParentalControlSetupPolicy/FirstTimeOrIgnoreParentalControlSetupHandler.cs
@@ -1,5 +1,4 @@
using System.Threading.Tasks;
-using Jellyfin.Api.Auth.IgnoreParentalControlPolicy;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Library;
@@ -11,7 +10,7 @@ namespace Jellyfin.Api.Auth.FirstTimeOrIgnoreParentalControlSetupPolicy
///
/// Ignore parental control schedule and allow before startup wizard has been completed.
///
- public class FirstTimeOrIgnoreParentalControlSetupHandler : BaseAuthorizationHandler
+ public class FirstTimeOrIgnoreParentalControlSetupHandler : BaseAuthorizationHandler
{
private readonly IConfigurationManager _configurationManager;
@@ -33,7 +32,7 @@ namespace Jellyfin.Api.Auth.FirstTimeOrIgnoreParentalControlSetupPolicy
}
///
- protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, IgnoreParentalControlRequirement requirement)
+ protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, FirstTimeOrIgnoreParentalControlSetupRequirement requirement)
{
if (!_configurationManager.CommonConfiguration.IsStartupWizardCompleted)
{
diff --git a/Jellyfin.Api/Controllers/UserController.cs b/Jellyfin.Api/Controllers/UserController.cs
index d897f07b7..272312522 100644
--- a/Jellyfin.Api/Controllers/UserController.cs
+++ b/Jellyfin.Api/Controllers/UserController.cs
@@ -386,7 +386,7 @@ namespace Jellyfin.Api.Controllers
var user = _userManager.GetUserById(userId);
// If removing admin access
- if (!(newPolicy.IsAdministrator && user.HasPermission(PermissionKind.IsAdministrator)))
+ if (!newPolicy.IsAdministrator && user.HasPermission(PermissionKind.IsAdministrator))
{
if (_userManager.Users.Count(i => i.HasPermission(PermissionKind.IsAdministrator)) == 1)
{
diff --git a/Jellyfin.Api/Jellyfin.Api.csproj b/Jellyfin.Api/Jellyfin.Api.csproj
index db20e8267..24bc07b66 100644
--- a/Jellyfin.Api/Jellyfin.Api.csproj
+++ b/Jellyfin.Api/Jellyfin.Api.csproj
@@ -18,7 +18,7 @@
-
+
diff --git a/Jellyfin.Drawing.Skia/StripCollageBuilder.cs b/Jellyfin.Drawing.Skia/StripCollageBuilder.cs
index b08c3750d..10bb59648 100644
--- a/Jellyfin.Drawing.Skia/StripCollageBuilder.cs
+++ b/Jellyfin.Drawing.Skia/StripCollageBuilder.cs
@@ -115,7 +115,7 @@ namespace Jellyfin.Drawing.Skia
// resize to the same aspect as the original
int iWidth = Math.Abs(iHeight * currentBitmap.Width / currentBitmap.Height);
- using var resizedImage = SkiaEncoder.ResizeImage(bitmap, new SKImageInfo(iWidth, iHeight, currentBitmap.ColorType, currentBitmap.AlphaType, currentBitmap.ColorSpace));
+ using var resizedImage = SkiaEncoder.ResizeImage(currentBitmap, new SKImageInfo(iWidth, iHeight, currentBitmap.ColorType, currentBitmap.AlphaType, currentBitmap.ColorSpace));
// crop image
int ix = Math.Abs((iWidth - iSlice) / 2);
@@ -177,7 +177,7 @@ namespace Jellyfin.Drawing.Skia
// Scale image. The FromBitmap creates a copy
var imageInfo = new SKImageInfo(cellWidth, cellHeight, currentBitmap.ColorType, currentBitmap.AlphaType, currentBitmap.ColorSpace);
- using var resizedBitmap = SKBitmap.FromImage(SkiaEncoder.ResizeImage(bitmap, imageInfo));
+ using var resizedBitmap = SKBitmap.FromImage(SkiaEncoder.ResizeImage(currentBitmap, imageInfo));
// draw this image into the strip at the next position
var xPos = x * cellWidth;
diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs
index 2d6935a0b..bbd7166e6 100644
--- a/MediaBrowser.Providers/Manager/ProviderManager.cs
+++ b/MediaBrowser.Providers/Manager/ProviderManager.cs
@@ -4,6 +4,8 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
+using System.Net;
+using System.Net.Mime;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
@@ -22,6 +24,7 @@ using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Net;
using MediaBrowser.Model.Providers;
using Microsoft.Extensions.Logging;
using Priority_Queue;
@@ -169,6 +172,15 @@ namespace MediaBrowser.Providers.Manager
}
}
+ // thetvdb will sometimes serve a rubbish 404 html page with a 200 OK code, because reasons...
+ if (response.ContentType.Equals(MediaTypeNames.Text.Html, StringComparison.OrdinalIgnoreCase))
+ {
+ throw new HttpException("Invalid image received.")
+ {
+ StatusCode = HttpStatusCode.NotFound
+ };
+ }
+
await SaveImage(item, response.Content, response.ContentType, type, imageIndex, cancellationToken).ConfigureAwait(false);
}
diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
index 09879997a..7c0b54250 100644
--- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj
+++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
@@ -20,7 +20,7 @@
-
+
diff --git a/README.md b/README.md
index a41bfbca8..55d6917ae 100644
--- a/README.md
+++ b/README.md
@@ -166,3 +166,5 @@ To instruct the server not to host the web content, there is a `nowebclient` con
switch `--nowebclient` or the environment variable `JELLYFIN_NOWEBCONTENT=true`.
Since this is a common scenario, there is also a separate launch profile defined for Visual Studio called `Jellyfin.Server (nowebcontent)` that can be selected from the 'Start Debugging' dropdown in the main toolbar.
+
+**NOTE:** The setup wizard can not be run if the web client is hosted separately.
diff --git a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj
index 4011e4aa8..f77eba376 100644
--- a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj
+++ b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj
@@ -17,7 +17,7 @@
-
+
diff --git a/tests/Jellyfin.Common.Tests/Jellyfin.Common.Tests.csproj b/tests/Jellyfin.Common.Tests/Jellyfin.Common.Tests.csproj
index 4cb1da994..746474044 100644
--- a/tests/Jellyfin.Common.Tests/Jellyfin.Common.Tests.csproj
+++ b/tests/Jellyfin.Common.Tests/Jellyfin.Common.Tests.csproj
@@ -13,7 +13,7 @@
-
+
diff --git a/tests/Jellyfin.Controller.Tests/Jellyfin.Controller.Tests.csproj b/tests/Jellyfin.Controller.Tests/Jellyfin.Controller.Tests.csproj
index 18724f31c..1559f70ab 100644
--- a/tests/Jellyfin.Controller.Tests/Jellyfin.Controller.Tests.csproj
+++ b/tests/Jellyfin.Controller.Tests/Jellyfin.Controller.Tests.csproj
@@ -13,7 +13,7 @@
-
+
diff --git a/tests/Jellyfin.MediaEncoding.Tests/Jellyfin.MediaEncoding.Tests.csproj b/tests/Jellyfin.MediaEncoding.Tests/Jellyfin.MediaEncoding.Tests.csproj
index 646ef00fd..e1a089547 100644
--- a/tests/Jellyfin.MediaEncoding.Tests/Jellyfin.MediaEncoding.Tests.csproj
+++ b/tests/Jellyfin.MediaEncoding.Tests/Jellyfin.MediaEncoding.Tests.csproj
@@ -19,7 +19,7 @@
-
+
diff --git a/tests/Jellyfin.Naming.Tests/Jellyfin.Naming.Tests.csproj b/tests/Jellyfin.Naming.Tests/Jellyfin.Naming.Tests.csproj
index 1434cce96..0e9e91563 100644
--- a/tests/Jellyfin.Naming.Tests/Jellyfin.Naming.Tests.csproj
+++ b/tests/Jellyfin.Naming.Tests/Jellyfin.Naming.Tests.csproj
@@ -13,7 +13,7 @@
-
+
diff --git a/tests/MediaBrowser.Api.Tests/MediaBrowser.Api.Tests.csproj b/tests/MediaBrowser.Api.Tests/MediaBrowser.Api.Tests.csproj
index 93bc8433a..a4ef10648 100644
--- a/tests/MediaBrowser.Api.Tests/MediaBrowser.Api.Tests.csproj
+++ b/tests/MediaBrowser.Api.Tests/MediaBrowser.Api.Tests.csproj
@@ -9,7 +9,7 @@
-
+