aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.vscode/launch.json6
-rw-r--r--CONTRIBUTORS.md1
-rw-r--r--Emby.Dlna/PlayTo/PlayToController.cs5
-rw-r--r--Emby.Dlna/Server/DescriptionXmlBuilder.cs16
-rw-r--r--Emby.Server.Implementations/Browser/BrowserLauncher.cs51
-rw-r--r--Emby.Server.Implementations/Data/SqliteItemRepository.cs3
-rw-r--r--Emby.Server.Implementations/Dto/DtoService.cs5
-rw-r--r--Emby.Server.Implementations/EntryPoints/StartupWizard.cs83
-rw-r--r--Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs1
-rw-r--r--Emby.Server.Implementations/IStartupOptions.cs5
-rw-r--r--Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs8
-rw-r--r--Emby.Server.Implementations/LiveTv/LiveTvManager.cs1
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs13
-rw-r--r--Emby.Server.Implementations/Localization/Core/af.json34
-rw-r--r--Emby.Server.Implementations/Localization/Core/th.json10
-rw-r--r--Emby.Server.Implementations/Localization/Core/vi.json2
-rw-r--r--Emby.Server.Implementations/Updates/InstallationManager.cs8
-rw-r--r--Jellyfin.Api/Controllers/ItemLookupController.cs2
-rw-r--r--Jellyfin.Api/Controllers/PackageController.cs10
-rw-r--r--Jellyfin.Api/Controllers/UserController.cs6
-rw-r--r--Jellyfin.Api/Jellyfin.Api.csproj4
-rw-r--r--Jellyfin.Api/Models/UserDtos/ForgotPasswordDto.cs16
-rw-r--r--Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj4
-rw-r--r--Jellyfin.Server/Jellyfin.Server.csproj9
-rw-r--r--Jellyfin.Server/Properties/launchSettings.json12
-rw-r--r--Jellyfin.Server/StartupOptions.cs4
-rw-r--r--MediaBrowser.Controller/Channels/InternalChannelFeatures.cs2
-rw-r--r--MediaBrowser.Controller/Entities/Audio/Audio.cs1
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs2
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs1
-rw-r--r--MediaBrowser.Controller/Entities/IHasMediaSources.cs2
-rw-r--r--MediaBrowser.Controller/Entities/Photo.cs1
-rw-r--r--MediaBrowser.Controller/Entities/TV/Series.cs1
-rw-r--r--MediaBrowser.Controller/Entities/UserViewBuilder.cs1
-rw-r--r--MediaBrowser.Controller/IO/FileData.cs1
-rw-r--r--MediaBrowser.Controller/Library/ILibraryManager.cs2
-rw-r--r--MediaBrowser.Controller/Library/IMediaSourceManager.cs2
-rw-r--r--MediaBrowser.Controller/Library/ItemResolveArgs.cs1
-rw-r--r--MediaBrowser.Controller/LiveTv/ILiveTvManager.cs1
-rw-r--r--MediaBrowser.Controller/LiveTv/ITunerHost.cs1
-rw-r--r--MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs1
-rw-r--r--MediaBrowser.Controller/LiveTv/ProgramInfo.cs7
-rw-r--r--MediaBrowser.Controller/LiveTv/RecordingInfo.cs1
-rw-r--r--MediaBrowser.Controller/LiveTv/TimerInfo.cs1
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs4
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs2
-rw-r--r--MediaBrowser.Controller/Persistence/IItemRepository.cs1
-rw-r--r--MediaBrowser.Controller/Providers/DirectoryService.cs44
-rw-r--r--MediaBrowser.Controller/Resolvers/IItemResolver.cs1
-rw-r--r--MediaBrowser.Controller/Session/SessionInfo.cs1
-rw-r--r--MediaBrowser.Model/Dlna/StreamBuilder.cs14
-rw-r--r--MediaBrowser.Model/Dlna/StreamInfo.cs1
-rw-r--r--MediaBrowser.Model/Dto/BaseItemDto.cs8
-rw-r--r--MediaBrowser.Model/Entities/MediaStream.cs2
-rw-r--r--MediaBrowser.Model/Entities/MetadataProvider.cs4
-rw-r--r--MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs1
-rw-r--r--MediaBrowser.Model/Providers/RemoteImageInfo.cs1
-rw-r--r--MediaBrowser.Model/Providers/RemoteSearchResult.cs1
-rw-r--r--MediaBrowser.Model/Querying/ItemFields.cs1
-rw-r--r--MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs3
-rw-r--r--MediaBrowser.Model/Session/PlaybackProgressInfo.cs3
-rw-r--r--MediaBrowser.Model/Sync/SyncCategory.cs2
-rw-r--r--MediaBrowser.Model/System/SystemInfo.cs5
-rw-r--r--MediaBrowser.Model/Tasks/IConfigurableScheduledTask.cs1
-rw-r--r--MediaBrowser.Model/Updates/PackageInfo.cs10
-rw-r--r--MediaBrowser.Providers/MediaBrowser.Providers.csproj2
-rw-r--r--MediaBrowser.Providers/Plugins/MusicBrainz/ArtistProvider.cs1
-rw-r--r--MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs4
-rw-r--r--MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeImageProvider.cs27
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/Movies/GenericTmdbMovieInfo.cs1
-rw-r--r--MediaBrowser.Providers/TV/DummySeasonProvider.cs1
-rw-r--r--README.md7
-rw-r--r--tests/Jellyfin.Api.Tests/JellyfinApplicationFactory.cs3
73 files changed, 247 insertions, 257 deletions
diff --git a/.vscode/launch.json b/.vscode/launch.json
index bf1bd65cb..05f60cfa6 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -11,7 +11,11 @@
"cwd": "${workspaceFolder}/Jellyfin.Server",
"console": "internalConsole",
"stopAtEntry": false,
- "internalConsoleOptions": "openOnSessionStart"
+ "internalConsoleOptions": "openOnSessionStart",
+ "serverReadyAction": {
+ "action": "openExternally",
+ "pattern": "Overriding address\\(es\\) \\'(https?:\\S+)\\'",
+ }
},
{
"name": ".NET Core Launch (nowebclient)",
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index efd83012e..99060d0b0 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -103,6 +103,7 @@
- [sl1288](https://github.com/sl1288)
- [sorinyo2004](https://github.com/sorinyo2004)
- [sparky8251](https://github.com/sparky8251)
+ - [spookbits](https://github.com/spookbits)
- [stanionascu](https://github.com/stanionascu)
- [stevehayles](https://github.com/stevehayles)
- [SuperSandro2000](https://github.com/SuperSandro2000)
diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs
index 460ac2d8d..63fd8ce5a 100644
--- a/Emby.Dlna/PlayTo/PlayToController.cs
+++ b/Emby.Dlna/PlayTo/PlayToController.cs
@@ -881,7 +881,10 @@ namespace Emby.Dlna.PlayTo
return null;
}
- mediaSource = await _mediaSourceManager.GetMediaSource(Item, MediaSourceId, LiveStreamId, false, cancellationToken).ConfigureAwait(false);
+ if (_mediaSourceManager != null)
+ {
+ mediaSource = await _mediaSourceManager.GetMediaSource(Item, MediaSourceId, LiveStreamId, false, cancellationToken).ConfigureAwait(false);
+ }
return mediaSource;
}
diff --git a/Emby.Dlna/Server/DescriptionXmlBuilder.cs b/Emby.Dlna/Server/DescriptionXmlBuilder.cs
index bca9e81cd..1f429d0de 100644
--- a/Emby.Dlna/Server/DescriptionXmlBuilder.cs
+++ b/Emby.Dlna/Server/DescriptionXmlBuilder.cs
@@ -235,13 +235,13 @@ namespace Emby.Dlna.Server
.Append(SecurityElement.Escape(service.ServiceId ?? string.Empty))
.Append("</serviceId>");
builder.Append("<SCPDURL>")
- .Append(BuildUrl(service.ScpdUrl))
+ .Append(BuildUrl(service.ScpdUrl, true))
.Append("</SCPDURL>");
builder.Append("<controlURL>")
- .Append(BuildUrl(service.ControlUrl))
+ .Append(BuildUrl(service.ControlUrl, true))
.Append("</controlURL>");
builder.Append("<eventSubURL>")
- .Append(BuildUrl(service.EventSubUrl))
+ .Append(BuildUrl(service.EventSubUrl, true))
.Append("</eventSubURL>");
builder.Append("</service>");
@@ -250,7 +250,13 @@ namespace Emby.Dlna.Server
builder.Append("</serviceList>");
}
- private string BuildUrl(string url)
+ /// <summary>
+ /// Builds a valid url for inclusion in the xml.
+ /// </summary>
+ /// <param name="url">Url to include.</param>
+ /// <param name="absoluteUrl">Optional. When set to true, the absolute url is always used.</param>
+ /// <returns>The url to use for the element.</returns>
+ private string BuildUrl(string url, bool absoluteUrl = false)
{
if (string.IsNullOrEmpty(url))
{
@@ -261,7 +267,7 @@ namespace Emby.Dlna.Server
url = "/dlna/" + _serverUdn + "/" + url;
- if (EnableAbsoluteUrls)
+ if (EnableAbsoluteUrls || absoluteUrl)
{
url = _serverAddress.TrimEnd('/') + url;
}
diff --git a/Emby.Server.Implementations/Browser/BrowserLauncher.cs b/Emby.Server.Implementations/Browser/BrowserLauncher.cs
deleted file mode 100644
index f8108d1c2..000000000
--- a/Emby.Server.Implementations/Browser/BrowserLauncher.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using System;
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Configuration;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.Logging;
-
-namespace Emby.Server.Implementations.Browser
-{
- /// <summary>
- /// Assists in opening application URLs in an external browser.
- /// </summary>
- public static class BrowserLauncher
- {
- /// <summary>
- /// Opens the home page of the web client.
- /// </summary>
- /// <param name="appHost">The app host.</param>
- public static void OpenWebApp(IServerApplicationHost appHost)
- {
- TryOpenUrl(appHost, "/web/index.html");
- }
-
- /// <summary>
- /// Opens the swagger API page.
- /// </summary>
- /// <param name="appHost">The app host.</param>
- public static void OpenSwaggerPage(IServerApplicationHost appHost)
- {
- TryOpenUrl(appHost, "/api-docs/swagger");
- }
-
- /// <summary>
- /// Opens the specified URL in an external browser window. Any exceptions will be logged, but ignored.
- /// </summary>
- /// <param name="appHost">The application host.</param>
- /// <param name="relativeUrl">The URL to open, relative to the server base URL.</param>
- private static void TryOpenUrl(IServerApplicationHost appHost, string relativeUrl)
- {
- try
- {
- string baseUrl = appHost.GetLocalApiUrl("localhost");
- appHost.LaunchUrl(baseUrl + relativeUrl);
- }
- catch (Exception ex)
- {
- var logger = appHost.Resolve<ILogger<IServerApplicationHost>>();
- logger?.LogError(ex, "Failed to open browser window with URL {URL}", relativeUrl);
- }
- }
- }
-}
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index ab60cee61..d09f84e17 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -2263,7 +2263,6 @@ namespace Emby.Server.Implementations.Data
return query.IncludeItemTypes.Contains("Trailer", StringComparer.OrdinalIgnoreCase);
}
-
private static readonly HashSet<string> _artistExcludeParentTypes = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"Series",
@@ -3291,7 +3290,6 @@ namespace Emby.Server.Implementations.Data
}
}
-
var isReturningZeroItems = query.Limit.HasValue && query.Limit <= 0;
var statementTexts = new List<string>();
@@ -6006,7 +6004,6 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
}
}
-
/// <summary>
/// Gets the chapter.
/// </summary>
diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs
index 57c1398e9..edb8753fd 100644
--- a/Emby.Server.Implementations/Dto/DtoService.cs
+++ b/Emby.Server.Implementations/Dto/DtoService.cs
@@ -468,7 +468,6 @@ namespace Emby.Server.Implementations.Dto
IncludeItemTypes = new[] { typeof(MusicAlbum).Name },
Name = item.Album,
Limit = 1
-
});
if (parentAlbumIds.Count > 0)
@@ -1139,6 +1138,7 @@ namespace Emby.Server.Implementations.Dto
if (episodeSeries != null)
{
dto.SeriesPrimaryImageTag = GetTagAndFillBlurhash(dto, episodeSeries, ImageType.Primary);
+ AttachPrimaryImageAspectRatio(dto, episodeSeries);
}
}
@@ -1185,6 +1185,7 @@ namespace Emby.Server.Implementations.Dto
if (series != null)
{
dto.SeriesPrimaryImageTag = GetTagAndFillBlurhash(dto, series, ImageType.Primary);
+ AttachPrimaryImageAspectRatio(dto, series);
}
}
}
@@ -1431,7 +1432,7 @@ namespace Emby.Server.Implementations.Dto
return null;
}
- return width / height;
+ return (double)width / height;
}
}
}
diff --git a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs
deleted file mode 100644
index 2e738deeb..000000000
--- a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-using System.Threading.Tasks;
-using Emby.Server.Implementations.Browser;
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Extensions;
-using MediaBrowser.Controller.Plugins;
-using Microsoft.Extensions.Configuration;
-
-namespace Emby.Server.Implementations.EntryPoints
-{
- /// <summary>
- /// Class StartupWizard.
- /// </summary>
- public sealed class StartupWizard : IServerEntryPoint
- {
- private readonly IServerApplicationHost _appHost;
- private readonly IConfiguration _appConfig;
- private readonly IServerConfigurationManager _config;
- private readonly IStartupOptions _startupOptions;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="StartupWizard"/> class.
- /// </summary>
- /// <param name="appHost">The application host.</param>
- /// <param name="appConfig">The application configuration.</param>
- /// <param name="config">The configuration manager.</param>
- /// <param name="startupOptions">The application startup options.</param>
- public StartupWizard(
- IServerApplicationHost appHost,
- IConfiguration appConfig,
- IServerConfigurationManager config,
- IStartupOptions startupOptions)
- {
- _appHost = appHost;
- _appConfig = appConfig;
- _config = config;
- _startupOptions = startupOptions;
- }
-
- /// <inheritdoc />
- public Task RunAsync()
- {
- Run();
- return Task.CompletedTask;
- }
-
- private void Run()
- {
- if (!_appHost.CanLaunchWebBrowser)
- {
- return;
- }
-
- // Always launch the startup wizard if possible when it has not been completed
- if (!_config.Configuration.IsStartupWizardCompleted && _appConfig.HostWebClient())
- {
- BrowserLauncher.OpenWebApp(_appHost);
- return;
- }
-
- // Do nothing if the web app is configured to not run automatically
- if (!_config.Configuration.AutoRunWebApp || _startupOptions.NoAutoRunWebApp)
- {
- return;
- }
-
- // Launch the swagger page if the web client is not hosted, otherwise open the web client
- if (_appConfig.HostWebClient())
- {
- BrowserLauncher.OpenWebApp(_appHost);
- }
- else
- {
- BrowserLauncher.OpenSwaggerPage(_appHost);
- }
- }
-
- /// <inheritdoc />
- public void Dispose()
- {
- }
- }
-}
diff --git a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs
index 3618b88c5..1da717e75 100644
--- a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs
+++ b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs
@@ -28,7 +28,6 @@ namespace Emby.Server.Implementations.EntryPoints
private readonly object _syncLock = new object();
private Timer _updateTimer;
-
public UserDataChangeNotifier(IUserDataManager userDataManager, ISessionManager sessionManager, IUserManager userManager)
{
_userDataManager = userDataManager;
diff --git a/Emby.Server.Implementations/IStartupOptions.cs b/Emby.Server.Implementations/IStartupOptions.cs
index e7e72c686..4bef59543 100644
--- a/Emby.Server.Implementations/IStartupOptions.cs
+++ b/Emby.Server.Implementations/IStartupOptions.cs
@@ -17,11 +17,6 @@ namespace Emby.Server.Implementations
bool IsService { get; }
/// <summary>
- /// Gets the value of the --noautorunwebapp command line option.
- /// </summary>
- bool NoAutoRunWebApp { get; }
-
- /// <summary>
/// Gets the value of the --package-name command line option.
/// </summary>
string PackageName { get; }
diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
index 655ff5853..28aabc159 100644
--- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
+++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
@@ -874,7 +874,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings
public List<Lineup> lineups { get; set; }
}
-
public class Headends
{
public string headend { get; set; }
@@ -886,8 +885,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings
public List<Lineup> lineups { get; set; }
}
-
-
public class Map
{
public string stationID { get; set; }
@@ -971,9 +968,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings
public List<string> date { get; set; }
}
-
-
-
public class Rating
{
public string body { get; set; }
@@ -1017,8 +1011,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings
public string isPremiereOrFinale { get; set; }
}
-
-
public class MetadataSchedule
{
public string modified { get; set; }
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
index a898a564f..5bdd1c23c 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -2135,6 +2135,7 @@ namespace Emby.Server.Implementations.LiveTv
}
private bool _disposed = false;
+
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
index 28e30fac8..2f4c60117 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
@@ -563,6 +563,19 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
protected override async Task<ILiveStream> GetChannelStream(TunerHostInfo info, ChannelInfo channelInfo, string streamId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken)
{
+ var tunerCount = info.TunerCount;
+
+ if (tunerCount > 0)
+ {
+ var tunerHostId = info.Id;
+ var liveStreams = currentLiveStreams.Where(i => string.Equals(i.TunerHostId, tunerHostId, StringComparison.OrdinalIgnoreCase));
+
+ if (liveStreams.Count() >= tunerCount)
+ {
+ throw new LiveTvConflictException("HDHomeRun simultaneous stream limit has been reached.");
+ }
+ }
+
var profile = streamId.Split('_')[0];
Logger.LogInformation("GetChannelStream: channel id: {0}. stream id: {1} profile: {2}", channelInfo.Id, streamId, profile);
diff --git a/Emby.Server.Implementations/Localization/Core/af.json b/Emby.Server.Implementations/Localization/Core/af.json
index e587c37d5..d33e11893 100644
--- a/Emby.Server.Implementations/Localization/Core/af.json
+++ b/Emby.Server.Implementations/Localization/Core/af.json
@@ -1,19 +1,19 @@
{
"Artists": "Kunstenare",
"Channels": "Kanale",
- "Folders": "Fouers",
- "Favorites": "Gunstelinge",
+ "Folders": "Lêergidse",
+ "Favorites": "Gunstellinge",
"HeaderFavoriteShows": "Gunsteling Vertonings",
"ValueSpecialEpisodeName": "Spesiale - {0}",
"HeaderAlbumArtists": "Album Kunstenaars",
"Books": "Boeke",
"HeaderNextUp": "Volgende",
- "Movies": "Rolprente",
- "Shows": "Program",
- "HeaderContinueWatching": "Hou Aan Kyk",
+ "Movies": "Flieks",
+ "Shows": "Televisie Reekse",
+ "HeaderContinueWatching": "Kyk Verder",
"HeaderFavoriteEpisodes": "Gunsteling Episodes",
"Photos": "Fotos",
- "Playlists": "Speellysse",
+ "Playlists": "Snitlyste",
"HeaderFavoriteArtists": "Gunsteling Kunstenaars",
"HeaderFavoriteAlbums": "Gunsteling Albums",
"Sync": "Sinkroniseer",
@@ -23,7 +23,7 @@
"DeviceOfflineWithName": "{0} is ontkoppel",
"Collections": "Versamelings",
"Inherit": "Ontvang",
- "HeaderLiveTV": "Live TV",
+ "HeaderLiveTV": "Lewendige TV",
"Application": "Program",
"AppDeviceValues": "App: {0}, Toestel: {1}",
"VersionNumber": "Weergawe {0}",
@@ -95,5 +95,23 @@
"TasksChannelsCategory": "Internet kanale",
"TasksApplicationCategory": "aansoek",
"TasksLibraryCategory": "biblioteek",
- "TasksMaintenanceCategory": "onderhoud"
+ "TasksMaintenanceCategory": "onderhoud",
+ "TaskCleanCacheDescription": "Vee kasregister lêers uit wat nie meer deur die stelsel benodig word nie.",
+ "TaskCleanCache": "Reinig Kasgeheue Lêergids",
+ "TaskDownloadMissingSubtitlesDescription": "Soek aanlyn vir vermiste onderskrifte gebasseer op metadata verstellings.",
+ "TaskDownloadMissingSubtitles": "Laai vermiste onderskrifte af",
+ "TaskRefreshChannelsDescription": "Vervris internet kanaal inligting.",
+ "TaskRefreshChannels": "Vervris Kanale",
+ "TaskCleanTranscodeDescription": "Vee transkodering lêers uit wat ouer is as een dag.",
+ "TaskCleanTranscode": "Reinig Transkoderings Leêrbinder",
+ "TaskUpdatePluginsDescription": "Laai opgedateerde inprop-sagteware af en installeer inprop-sagteware wat verstel is om outomaties op te dateer.",
+ "TaskUpdatePlugins": "Dateer Inprop-Sagteware Op",
+ "TaskRefreshPeopleDescription": "Vervris metadata oor akteurs en regisseurs in u media versameling.",
+ "TaskRefreshPeople": "Vervris Mense",
+ "TaskCleanLogsDescription": "Vee loglêers wat ouer as {0} dae is uit.",
+ "TaskCleanLogs": "Reinig Loglêer Lêervouer",
+ "TaskRefreshLibraryDescription": "Skandeer u media versameling vir nuwe lêers en verfris metadata.",
+ "TaskRefreshLibrary": "Skandeer Media Versameling",
+ "TaskRefreshChapterImagesDescription": "Maak kleinkiekeis (fotos) vir films wat hoofstukke het.",
+ "TaskRefreshChapterImages": "Verkry Hoofstuk Beelde"
}
diff --git a/Emby.Server.Implementations/Localization/Core/th.json b/Emby.Server.Implementations/Localization/Core/th.json
index 3f6f3b23c..3b77215a3 100644
--- a/Emby.Server.Implementations/Localization/Core/th.json
+++ b/Emby.Server.Implementations/Localization/Core/th.json
@@ -20,8 +20,8 @@
"NotificationOptionCameraImageUploaded": "อัปโหลดภาพถ่ายแล้ว",
"NotificationOptionAudioPlaybackStopped": "หยุดเล่นเสียง",
"NotificationOptionAudioPlayback": "เริ่มเล่นเสียง",
- "NotificationOptionApplicationUpdateInstalled": "ติดตั้งการอัปเดตแอพพลิเคชันแล้ว",
- "NotificationOptionApplicationUpdateAvailable": "มีการอัปเดตแอพพลิเคชัน",
+ "NotificationOptionApplicationUpdateInstalled": "ติดตั้งการอัปเดตแอปพลิเคชันแล้ว",
+ "NotificationOptionApplicationUpdateAvailable": "มีการอัปเดตแอปพลิเคชัน",
"NewVersionIsAvailable": "เวอร์ชันใหม่ของเซิร์ฟเวอร์ Jellyfin พร้อมให้ดาวน์โหลดแล้ว",
"NameSeasonUnknown": "ไม่ทราบซีซัน",
"NameSeasonNumber": "ซีซัน {0}",
@@ -65,8 +65,8 @@
"Books": "หนังสือ",
"AuthenticationSucceededWithUserName": "{0} ยืนยันตัวสำเร็จแล้ว",
"Artists": "ศิลปิน",
- "Application": "แอพพลิเคชัน",
- "AppDeviceValues": "แอพ: {0}, อุปกรณ์: {1}",
+ "Application": "แอปพลิเคชัน",
+ "AppDeviceValues": "แอป: {0}, อุปกรณ์: {1}",
"Albums": "อัลบั้ม",
"ScheduledTaskStartedWithName": "{0} เริ่มต้น",
"ScheduledTaskFailedWithName": "{0} ล้มเหลว",
@@ -92,7 +92,7 @@
"TaskCleanCacheDescription": "ลบไฟล์แคชที่ระบบไม่ต้องการ",
"TaskCleanCache": "ล้างไดเรกทอรีแคช",
"TasksChannelsCategory": "ช่องอินเทอร์เน็ต",
- "TasksApplicationCategory": "แอพพลิเคชัน",
+ "TasksApplicationCategory": "แอปพลิเคชัน",
"TasksLibraryCategory": "ไลบรารี",
"TasksMaintenanceCategory": "ปิดซ่อมบำรุง",
"VersionNumber": "เวอร์ชัน {0}",
diff --git a/Emby.Server.Implementations/Localization/Core/vi.json b/Emby.Server.Implementations/Localization/Core/vi.json
index f190f8298..2392c8347 100644
--- a/Emby.Server.Implementations/Localization/Core/vi.json
+++ b/Emby.Server.Implementations/Localization/Core/vi.json
@@ -15,7 +15,7 @@
"ValueSpecialEpisodeName": "Đặc Biệt - {0}",
"Albums": "Albums",
"Artists": "Các Nghệ Sĩ",
- "TaskDownloadMissingSubtitlesDescription": "Tìm kiếm phụ đề bị thiếu trên Internet dựa trên cấu hình thông tin chi tiết.",
+ "TaskDownloadMissingSubtitlesDescription": "Tìm kiếm phụ đề bị thiếu trên Internet dựa trên cấu hình dữ liệu mô tả.",
"TaskDownloadMissingSubtitles": "Tải xuống phụ đề bị thiếu",
"TaskRefreshChannelsDescription": "Làm mới thông tin kênh internet.",
"TaskRefreshChannels": "Làm Mới Kênh",
diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs
index 8e24bf55c..003cf3c74 100644
--- a/Emby.Server.Implementations/Updates/InstallationManager.cs
+++ b/Emby.Server.Implementations/Updates/InstallationManager.cs
@@ -155,7 +155,12 @@ namespace Emby.Server.Implementations.Updates
var result = new List<PackageInfo>();
foreach (RepositoryInfo repository in _config.Configuration.PluginRepositories)
{
- result.AddRange(await GetPackages(repository.Url, cancellationToken).ConfigureAwait(true));
+ foreach (var package in await GetPackages(repository.Url, cancellationToken).ConfigureAwait(true))
+ {
+ package.repositoryName = repository.Name;
+ package.repositoryUrl = repository.Url;
+ result.Add(package);
+ }
}
return result;
@@ -393,6 +398,7 @@ namespace Emby.Server.Implementations.Updates
// Ignore any exceptions.
}
}
+
stream.Position = 0;
_zipClient.ExtractAllFromZip(stream, targetDir, true);
diff --git a/Jellyfin.Api/Controllers/ItemLookupController.cs b/Jellyfin.Api/Controllers/ItemLookupController.cs
index cf7038650..ab73aa428 100644
--- a/Jellyfin.Api/Controllers/ItemLookupController.cs
+++ b/Jellyfin.Api/Controllers/ItemLookupController.cs
@@ -292,7 +292,7 @@ namespace Jellyfin.Api.Controllers
/// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results.
/// The task result contains an <see cref="NoContentResult"/>.
/// </returns>
- [HttpPost("Items/RemoteSearch/Apply/{id}")]
+ [HttpPost("Items/RemoteSearch/Apply/{itemId}")]
[Authorize(Policy = Policies.RequiresElevation)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<ActionResult> ApplySearchCriteria(
diff --git a/Jellyfin.Api/Controllers/PackageController.cs b/Jellyfin.Api/Controllers/PackageController.cs
index eaf56aa56..1d9de14d2 100644
--- a/Jellyfin.Api/Controllers/PackageController.cs
+++ b/Jellyfin.Api/Controllers/PackageController.cs
@@ -77,6 +77,7 @@ namespace Jellyfin.Api.Controllers
/// <param name="name">Package name.</param>
/// <param name="assemblyGuid">GUID of the associated assembly.</param>
/// <param name="version">Optional version. Defaults to latest version.</param>
+ /// <param name="repositoryUrl">Optional. Specify the repository to install from.</param>
/// <response code="204">Package found.</response>
/// <response code="404">Package not found.</response>
/// <returns>A <see cref="NoContentResult"/> on success, or a <see cref="NotFoundResult"/> if the package could not be found.</returns>
@@ -87,9 +88,16 @@ namespace Jellyfin.Api.Controllers
public async Task<ActionResult> InstallPackage(
[FromRoute, Required] string name,
[FromQuery] string? assemblyGuid,
- [FromQuery] string? version)
+ [FromQuery] string? version,
+ [FromQuery] string? repositoryUrl)
{
var packages = await _installationManager.GetAvailablePackages().ConfigureAwait(false);
+ if (!string.IsNullOrEmpty(repositoryUrl))
+ {
+ packages = packages.Where(p => p.repositoryUrl.Equals(repositoryUrl, StringComparison.OrdinalIgnoreCase))
+ .ToList();
+ }
+
var package = _installationManager.GetCompatibleVersions(
packages,
name,
diff --git a/Jellyfin.Api/Controllers/UserController.cs b/Jellyfin.Api/Controllers/UserController.cs
index 11cf41b83..9e61b2b8a 100644
--- a/Jellyfin.Api/Controllers/UserController.cs
+++ b/Jellyfin.Api/Controllers/UserController.cs
@@ -505,17 +505,17 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Initiates the forgot password process for a local user.
/// </summary>
- /// <param name="enteredUsername">The entered username.</param>
+ /// <param name="forgotPasswordRequest">The forgot password request containing the entered username.</param>
/// <response code="200">Password reset process started.</response>
/// <returns>A <see cref="Task"/> containing a <see cref="ForgotPasswordResult"/>.</returns>
[HttpPost("ForgotPassword")]
[ProducesResponseType(StatusCodes.Status200OK)]
- public async Task<ActionResult<ForgotPasswordResult>> ForgotPassword([FromBody] string? enteredUsername)
+ public async Task<ActionResult<ForgotPasswordResult>> ForgotPassword([FromBody, Required] ForgotPasswordDto forgotPasswordRequest)
{
var isLocal = HttpContext.IsLocal()
|| _networkManager.IsInLocalNetwork(HttpContext.GetNormalizedRemoteIp());
- var result = await _userManager.StartForgotPasswordProcess(enteredUsername, isLocal).ConfigureAwait(false);
+ var result = await _userManager.StartForgotPasswordProcess(forgotPasswordRequest.EnteredUsername, isLocal).ConfigureAwait(false);
return result;
}
diff --git a/Jellyfin.Api/Jellyfin.Api.csproj b/Jellyfin.Api/Jellyfin.Api.csproj
index c27dce8dd..6a00db4b1 100644
--- a/Jellyfin.Api/Jellyfin.Api.csproj
+++ b/Jellyfin.Api/Jellyfin.Api.csproj
@@ -17,8 +17,8 @@
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="3.1.8" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="3.1.8" />
- <PackageReference Include="Swashbuckle.AspNetCore" Version="5.5.1" />
- <PackageReference Include="Swashbuckle.AspNetCore.ReDoc" Version="5.5.1" />
+ <PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
+ <PackageReference Include="Swashbuckle.AspNetCore.ReDoc" Version="5.6.3" />
</ItemGroup>
<ItemGroup>
diff --git a/Jellyfin.Api/Models/UserDtos/ForgotPasswordDto.cs b/Jellyfin.Api/Models/UserDtos/ForgotPasswordDto.cs
new file mode 100644
index 000000000..b31c6539c
--- /dev/null
+++ b/Jellyfin.Api/Models/UserDtos/ForgotPasswordDto.cs
@@ -0,0 +1,16 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace Jellyfin.Api.Models.UserDtos
+{
+ /// <summary>
+ /// Forgot Password request body DTO.
+ /// </summary>
+ public class ForgotPasswordDto
+ {
+ /// <summary>
+ /// Gets or sets the entered username to have its password reset.
+ /// </summary>
+ [Required]
+ public string? EnteredUsername { get; set; }
+ }
+}
diff --git a/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj b/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj
index f86b14244..c11ac5fb3 100644
--- a/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj
+++ b/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj
@@ -18,8 +18,8 @@
</ItemGroup>
<ItemGroup>
- <PackageReference Include="BlurHashSharp" Version="1.1.0" />
- <PackageReference Include="BlurHashSharp.SkiaSharp" Version="1.1.0" />
+ <PackageReference Include="BlurHashSharp" Version="1.1.1" />
+ <PackageReference Include="BlurHashSharp.SkiaSharp" Version="1.1.1" />
<PackageReference Include="SkiaSharp" Version="2.80.2" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.80.2" />
</ItemGroup>
diff --git a/Jellyfin.Server/Jellyfin.Server.csproj b/Jellyfin.Server/Jellyfin.Server.csproj
index 648172fbf..761a92f6d 100644
--- a/Jellyfin.Server/Jellyfin.Server.csproj
+++ b/Jellyfin.Server/Jellyfin.Server.csproj
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk.Web">
<!-- ProjectGuid is only included as a requirement for SonarQube analysis -->
<PropertyGroup>
@@ -13,6 +13,7 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Nullable>enable</Nullable>
+ <DisableImplicitAspNetCoreAnalyzers>true</DisableImplicitAspNetCoreAnalyzers>
</PropertyGroup>
<ItemGroup>
@@ -23,10 +24,6 @@
<EmbeddedResource Include="Resources/Configuration/*" />
</ItemGroup>
- <ItemGroup>
- <FrameworkReference Include="Microsoft.AspNetCore.App" />
- </ItemGroup>
-
<!-- Code Analyzers-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8" PrivateAssets="All" />
@@ -53,7 +50,7 @@
<PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
- <PackageReference Include="Serilog.Sinks.Graylog" Version="2.1.3" />
+ <PackageReference Include="Serilog.Sinks.Graylog" Version="2.2.1" />
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.0.4" />
<PackageReference Include="SQLitePCLRaw.provider.sqlite3.netstandard11" Version="1.1.14" />
</ItemGroup>
diff --git a/Jellyfin.Server/Properties/launchSettings.json b/Jellyfin.Server/Properties/launchSettings.json
index b6e2bcf97..20d432afc 100644
--- a/Jellyfin.Server/Properties/launchSettings.json
+++ b/Jellyfin.Server/Properties/launchSettings.json
@@ -2,6 +2,8 @@
"profiles": {
"Jellyfin.Server": {
"commandName": "Project",
+ "launchBrowser": true,
+ "applicationUrl": "http://localhost:8096",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
@@ -12,6 +14,16 @@
"ASPNETCORE_ENVIRONMENT": "Development"
},
"commandLineArgs": "--nowebclient"
+ },
+ "Jellyfin.Server (API Docs)": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "launchUrl": "api-docs/swagger",
+ "applicationUrl": "http://localhost:8096",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "commandLineArgs": "--nowebclient"
}
}
}
diff --git a/Jellyfin.Server/StartupOptions.cs b/Jellyfin.Server/StartupOptions.cs
index 41a1430d2..b63434092 100644
--- a/Jellyfin.Server/StartupOptions.cs
+++ b/Jellyfin.Server/StartupOptions.cs
@@ -64,10 +64,6 @@ namespace Jellyfin.Server
public bool IsService { get; set; }
/// <inheritdoc />
- [Option("noautorunwebapp", Required = false, HelpText = "Run headless if startup wizard is complete.")]
- public bool NoAutoRunWebApp { get; set; }
-
- /// <inheritdoc />
[Option("package-name", Required = false, HelpText = "Used when packaging Jellyfin (example, synology).")]
public string? PackageName { get; set; }
diff --git a/MediaBrowser.Controller/Channels/InternalChannelFeatures.cs b/MediaBrowser.Controller/Channels/InternalChannelFeatures.cs
index 1074ce435..137f5d095 100644
--- a/MediaBrowser.Controller/Channels/InternalChannelFeatures.cs
+++ b/MediaBrowser.Controller/Channels/InternalChannelFeatures.cs
@@ -42,6 +42,7 @@ namespace MediaBrowser.Controller.Channels
/// Indicates if a sort ascending/descending toggle is supported or not.
/// </summary>
public bool SupportsSortOrderToggle { get; set; }
+
/// <summary>
/// Gets or sets the automatic refresh levels.
/// </summary>
@@ -53,6 +54,7 @@ namespace MediaBrowser.Controller.Channels
/// </summary>
/// <value>The daily download limit.</value>
public int? DailyDownloadLimit { get; set; }
+
/// <summary>
/// Gets or sets a value indicating whether [supports downloading].
/// </summary>
diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs
index 2c6dea02c..8220464b3 100644
--- a/MediaBrowser.Controller/Entities/Audio/Audio.cs
+++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs
@@ -90,7 +90,6 @@ namespace MediaBrowser.Controller.Entities.Audio
var songKey = IndexNumber.HasValue ? IndexNumber.Value.ToString("0000") : string.Empty;
-
if (ParentIndexNumber.HasValue)
{
songKey = ParentIndexNumber.Value.ToString("0000") + "-" + songKey;
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 68126bd8a..2fc7d45c9 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -197,6 +197,7 @@ namespace MediaBrowser.Controller.Entities
public virtual bool SupportsRemoteImageDownloading => true;
private string _name;
+
/// <summary>
/// Gets or sets the name.
/// </summary>
@@ -661,6 +662,7 @@ namespace MediaBrowser.Controller.Entities
}
private string _forcedSortName;
+
/// <summary>
/// Gets or sets the name of the forced sort.
/// </summary>
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index 11542c1ca..901ea875b 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -1386,7 +1386,6 @@ namespace MediaBrowser.Controller.Entities
}
}
-
/// <summary>
/// Gets the linked children.
/// </summary>
diff --git a/MediaBrowser.Controller/Entities/IHasMediaSources.cs b/MediaBrowser.Controller/Entities/IHasMediaSources.cs
index a7b60d168..0f612262a 100644
--- a/MediaBrowser.Controller/Entities/IHasMediaSources.cs
+++ b/MediaBrowser.Controller/Entities/IHasMediaSources.cs
@@ -21,7 +21,5 @@ namespace MediaBrowser.Controller.Entities
List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution);
List<MediaStream> GetMediaStreams();
-
-
}
}
diff --git a/MediaBrowser.Controller/Entities/Photo.cs b/MediaBrowser.Controller/Entities/Photo.cs
index 1485d4c79..2fc66176f 100644
--- a/MediaBrowser.Controller/Entities/Photo.cs
+++ b/MediaBrowser.Controller/Entities/Photo.cs
@@ -16,7 +16,6 @@ namespace MediaBrowser.Controller.Entities
[JsonIgnore]
public override Folder LatestItemsIndexContainer => AlbumEntity;
-
[JsonIgnore]
public PhotoAlbum AlbumEntity
{
diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs
index 72c696c1a..75a746bfb 100644
--- a/MediaBrowser.Controller/Entities/TV/Series.cs
+++ b/MediaBrowser.Controller/Entities/TV/Series.cs
@@ -450,7 +450,6 @@ namespace MediaBrowser.Controller.Entities.TV
});
}
-
protected override bool GetBlockUnratedValue(User user)
{
return user.GetPreference(PreferenceKind.BlockUnratedItems).Contains(UnratedItem.Series.ToString());
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index b384b27d1..068a76769 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -258,7 +258,6 @@ namespace MediaBrowser.Controller.Entities
IncludeItemTypes = new[] { typeof(Movie).Name },
Recursive = true,
EnableTotalRecordCount = false
-
}).Items
.SelectMany(i => i.Genres)
.DistinctNames()
diff --git a/MediaBrowser.Controller/IO/FileData.cs b/MediaBrowser.Controller/IO/FileData.cs
index 9bc4cac39..3db60ae0b 100644
--- a/MediaBrowser.Controller/IO/FileData.cs
+++ b/MediaBrowser.Controller/IO/FileData.cs
@@ -111,5 +111,4 @@ namespace MediaBrowser.Controller.IO
return returnResult;
}
}
-
}
diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs
index 804170d5c..332730bcc 100644
--- a/MediaBrowser.Controller/Library/ILibraryManager.cs
+++ b/MediaBrowser.Controller/Library/ILibraryManager.cs
@@ -77,6 +77,7 @@ namespace MediaBrowser.Controller.Library
MusicArtist GetArtist(string name);
MusicArtist GetArtist(string name, DtoOptions options);
+
/// <summary>
/// Gets a Studio.
/// </summary>
@@ -234,6 +235,7 @@ namespace MediaBrowser.Controller.Library
/// Occurs when [item updated].
/// </summary>
event EventHandler<ItemChangeEventArgs> ItemUpdated;
+
/// <summary>
/// Occurs when [item removed].
/// </summary>
diff --git a/MediaBrowser.Controller/Library/IMediaSourceManager.cs b/MediaBrowser.Controller/Library/IMediaSourceManager.cs
index 9e7b1e608..22bf9488f 100644
--- a/MediaBrowser.Controller/Library/IMediaSourceManager.cs
+++ b/MediaBrowser.Controller/Library/IMediaSourceManager.cs
@@ -28,12 +28,14 @@ namespace MediaBrowser.Controller.Library
/// <param name="itemId">The item identifier.</param>
/// <returns>IEnumerable&lt;MediaStream&gt;.</returns>
List<MediaStream> GetMediaStreams(Guid itemId);
+
/// <summary>
/// Gets the media streams.
/// </summary>
/// <param name="mediaSourceId">The media source identifier.</param>
/// <returns>IEnumerable&lt;MediaStream&gt;.</returns>
List<MediaStream> GetMediaStreams(string mediaSourceId);
+
/// <summary>
/// Gets the media streams.
/// </summary>
diff --git a/MediaBrowser.Controller/Library/ItemResolveArgs.cs b/MediaBrowser.Controller/Library/ItemResolveArgs.cs
index 6a0dbeba2..12a311dc3 100644
--- a/MediaBrowser.Controller/Library/ItemResolveArgs.cs
+++ b/MediaBrowser.Controller/Library/ItemResolveArgs.cs
@@ -156,6 +156,7 @@ namespace MediaBrowser.Controller.Library
}
// REVIEW: @bond
+
/// <summary>
/// Gets the physical locations.
/// </summary>
diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
index 55c330931..6c365caa4 100644
--- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
+++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
@@ -231,6 +231,7 @@ namespace MediaBrowser.Controller.LiveTv
/// Saves the tuner host.
/// </summary>
Task<TunerHostInfo> SaveTunerHost(TunerHostInfo info, bool dataSourceChanged = true);
+
/// <summary>
/// Saves the listing provider.
/// </summary>
diff --git a/MediaBrowser.Controller/LiveTv/ITunerHost.cs b/MediaBrowser.Controller/LiveTv/ITunerHost.cs
index ff92bf856..abca8f239 100644
--- a/MediaBrowser.Controller/LiveTv/ITunerHost.cs
+++ b/MediaBrowser.Controller/LiveTv/ITunerHost.cs
@@ -56,7 +56,6 @@ namespace MediaBrowser.Controller.LiveTv
Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken);
Task<List<TunerHostInfo>> DiscoverDevices(int discoveryDurationMs, CancellationToken cancellationToken);
-
}
public interface IConfigurableTunerHost
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs b/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs
index 02178297b..b62974904 100644
--- a/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs
@@ -42,6 +42,7 @@ namespace MediaBrowser.Controller.LiveTv
/// </summary>
/// <value>The tuners.</value>
public List<LiveTvTunerInfo> Tuners { get; set; }
+
/// <summary>
/// Gets or sets a value indicating whether this instance is visible.
/// </summary>
diff --git a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs
index bdcffd5ca..f9f559ee9 100644
--- a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs
+++ b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs
@@ -35,6 +35,7 @@ namespace MediaBrowser.Controller.LiveTv
/// </summary>
/// <value>The overview.</value>
public string Overview { get; set; }
+
/// <summary>
/// Gets or sets the short overview.
/// </summary>
@@ -169,31 +170,37 @@ namespace MediaBrowser.Controller.LiveTv
/// </summary>
/// <value>The production year.</value>
public int? ProductionYear { get; set; }
+
/// <summary>
/// Gets or sets the home page URL.
/// </summary>
/// <value>The home page URL.</value>
public string HomePageUrl { get; set; }
+
/// <summary>
/// Gets or sets the series identifier.
/// </summary>
/// <value>The series identifier.</value>
public string SeriesId { get; set; }
+
/// <summary>
/// Gets or sets the show identifier.
/// </summary>
/// <value>The show identifier.</value>
public string ShowId { get; set; }
+
/// <summary>
/// Gets or sets the season number.
/// </summary>
/// <value>The season number.</value>
public int? SeasonNumber { get; set; }
+
/// <summary>
/// Gets or sets the episode number.
/// </summary>
/// <value>The episode number.</value>
public int? EpisodeNumber { get; set; }
+
/// <summary>
/// Gets or sets the etag.
/// </summary>
diff --git a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs
index 303882b7e..69190694f 100644
--- a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs
+++ b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs
@@ -187,6 +187,7 @@ namespace MediaBrowser.Controller.LiveTv
/// </summary>
/// <value><c>null</c> if [has image] contains no value, <c>true</c> if [has image]; otherwise, <c>false</c>.</value>
public bool? HasImage { get; set; }
+
/// <summary>
/// Gets or sets the show identifier.
/// </summary>
diff --git a/MediaBrowser.Controller/LiveTv/TimerInfo.cs b/MediaBrowser.Controller/LiveTv/TimerInfo.cs
index bcef4666d..aa5170617 100644
--- a/MediaBrowser.Controller/LiveTv/TimerInfo.cs
+++ b/MediaBrowser.Controller/LiveTv/TimerInfo.cs
@@ -113,6 +113,7 @@ namespace MediaBrowser.Controller.LiveTv
// Program properties
public int? SeasonNumber { get; set; }
+
/// <summary>
/// Gets or sets the episode number.
/// </summary>
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
index 2c30ca458..c5529ad5b 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
@@ -109,7 +109,6 @@ namespace MediaBrowser.Controller.MediaEncoding
}
return _mediaEncoder.SupportsHwaccel("vaapi");
-
}
/// <summary>
@@ -508,6 +507,7 @@ namespace MediaBrowser.Controller.MediaEncoding
arg.Append("-hwaccel qsv ");
}
}
+
// While using SW decoder
else
{
@@ -1441,7 +1441,6 @@ namespace MediaBrowser.Controller.MediaEncoding
var codec = outputAudioCodec ?? string.Empty;
-
int? transcoderChannelLimit;
if (codec.IndexOf("wma", StringComparison.OrdinalIgnoreCase) != -1)
{
@@ -2511,7 +2510,6 @@ namespace MediaBrowser.Controller.MediaEncoding
return inputModifier;
}
-
public void AttachMediaSourceInfo(
EncodingJobInfo state,
MediaSourceInfo mediaSource,
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
index 68bc502a0..c7ec878d2 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
@@ -697,10 +697,12 @@ namespace MediaBrowser.Controller.MediaEncoding
/// The progressive.
/// </summary>
Progressive,
+
/// <summary>
/// The HLS.
/// </summary>
Hls,
+
/// <summary>
/// The dash.
/// </summary>
diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs
index ebc37bd1f..45c6805f0 100644
--- a/MediaBrowser.Controller/Persistence/IItemRepository.cs
+++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs
@@ -100,6 +100,7 @@ namespace MediaBrowser.Controller.Persistence
/// <param name="query">The query.</param>
/// <returns>IEnumerable&lt;Guid&gt;.</returns>
QueryResult<Guid> GetItemIds(InternalItemsQuery query);
+
/// <summary>
/// Gets the items.
/// </summary>
diff --git a/MediaBrowser.Controller/Providers/DirectoryService.cs b/MediaBrowser.Controller/Providers/DirectoryService.cs
index f77455485..16fd1d42b 100644
--- a/MediaBrowser.Controller/Providers/DirectoryService.cs
+++ b/MediaBrowser.Controller/Providers/DirectoryService.cs
@@ -1,6 +1,7 @@
#pragma warning disable CS1591
using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using MediaBrowser.Model.IO;
@@ -11,11 +12,11 @@ namespace MediaBrowser.Controller.Providers
{
private readonly IFileSystem _fileSystem;
- private readonly Dictionary<string, FileSystemMetadata[]> _cache = new Dictionary<string, FileSystemMetadata[]>(StringComparer.OrdinalIgnoreCase);
+ private readonly ConcurrentDictionary<string, FileSystemMetadata[]> _cache = new ConcurrentDictionary<string, FileSystemMetadata[]>(StringComparer.OrdinalIgnoreCase);
- private readonly Dictionary<string, FileSystemMetadata> _fileCache = new Dictionary<string, FileSystemMetadata>(StringComparer.OrdinalIgnoreCase);
+ private readonly ConcurrentDictionary<string, FileSystemMetadata> _fileCache = new ConcurrentDictionary<string, FileSystemMetadata>(StringComparer.OrdinalIgnoreCase);
- private readonly Dictionary<string, List<string>> _filePathCache = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
+ private readonly ConcurrentDictionary<string, List<string>> _filePathCache = new ConcurrentDictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
public DirectoryService(IFileSystem fileSystem)
{
@@ -24,14 +25,7 @@ namespace MediaBrowser.Controller.Providers
public FileSystemMetadata[] GetFileSystemEntries(string path)
{
- if (!_cache.TryGetValue(path, out FileSystemMetadata[] entries))
- {
- entries = _fileSystem.GetFileSystemEntries(path).ToArray();
-
- _cache[path] = entries;
- }
-
- return entries;
+ return _cache.GetOrAdd(path, p => _fileSystem.GetFileSystemEntries(p).ToArray());
}
public List<FileSystemMetadata> GetFiles(string path)
@@ -51,21 +45,19 @@ namespace MediaBrowser.Controller.Providers
public FileSystemMetadata GetFile(string path)
{
- if (!_fileCache.TryGetValue(path, out FileSystemMetadata file))
+ var result = _fileCache.GetOrAdd(path, p =>
{
- file = _fileSystem.GetFileInfo(path);
+ var file = _fileSystem.GetFileInfo(p);
+ return file != null && file.Exists ? file : null;
+ });
- if (file != null && file.Exists)
- {
- _fileCache[path] = file;
- }
- else
- {
- return null;
- }
+ if (result == null)
+ {
+ // lets not store null results in the cache
+ _fileCache.TryRemove(path, out _);
}
- return file;
+ return result;
}
public IReadOnlyList<string> GetFilePaths(string path)
@@ -73,14 +65,12 @@ namespace MediaBrowser.Controller.Providers
public IReadOnlyList<string> GetFilePaths(string path, bool clearCache)
{
- if (clearCache || !_filePathCache.TryGetValue(path, out List<string> result))
+ if (clearCache)
{
- result = _fileSystem.GetFilePaths(path).ToList();
-
- _filePathCache[path] = result;
+ _filePathCache.TryRemove(path, out _);
}
- return result;
+ return _filePathCache.GetOrAdd(path, p => _fileSystem.GetFilePaths(p).ToList());
}
}
}
diff --git a/MediaBrowser.Controller/Resolvers/IItemResolver.cs b/MediaBrowser.Controller/Resolvers/IItemResolver.cs
index b99c46843..eb7fb793a 100644
--- a/MediaBrowser.Controller/Resolvers/IItemResolver.cs
+++ b/MediaBrowser.Controller/Resolvers/IItemResolver.cs
@@ -19,6 +19,7 @@ namespace MediaBrowser.Controller.Resolvers
/// <param name="args">The args.</param>
/// <returns>BaseItem.</returns>
BaseItem ResolvePath(ItemResolveArgs args);
+
/// <summary>
/// Gets the priority.
/// </summary>
diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs
index 054fd33d9..55e44c19d 100644
--- a/MediaBrowser.Controller/Session/SessionInfo.cs
+++ b/MediaBrowser.Controller/Session/SessionInfo.cs
@@ -22,7 +22,6 @@ namespace MediaBrowser.Controller.Session
private readonly ISessionManager _sessionManager;
private readonly ILogger _logger;
-
private readonly object _progressLock = new object();
private Timer _progressTimer;
private PlaybackProgressInfo _lastProgressInfo;
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index cfe862f5a..d9e7e4fbb 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -498,7 +498,6 @@ namespace MediaBrowser.Model.Dlna
}
}
-
if (playMethods.Count > 0)
{
transcodeReasons.Clear();
@@ -1431,6 +1430,7 @@ namespace MediaBrowser.Model.Dlna
break;
}
+
case ProfileConditionValue.AudioChannels:
{
if (string.IsNullOrEmpty(qualifier))
@@ -1466,6 +1466,7 @@ namespace MediaBrowser.Model.Dlna
break;
}
+
case ProfileConditionValue.IsAvc:
{
if (!enableNonQualifiedConditions)
@@ -1487,6 +1488,7 @@ namespace MediaBrowser.Model.Dlna
break;
}
+
case ProfileConditionValue.IsAnamorphic:
{
if (!enableNonQualifiedConditions)
@@ -1508,6 +1510,7 @@ namespace MediaBrowser.Model.Dlna
break;
}
+
case ProfileConditionValue.IsInterlaced:
{
if (string.IsNullOrEmpty(qualifier))
@@ -1539,6 +1542,7 @@ namespace MediaBrowser.Model.Dlna
break;
}
+
case ProfileConditionValue.AudioProfile:
case ProfileConditionValue.Has64BitOffsets:
case ProfileConditionValue.PacketLength:
@@ -1550,6 +1554,7 @@ namespace MediaBrowser.Model.Dlna
// Not supported yet
break;
}
+
case ProfileConditionValue.RefFrames:
{
if (string.IsNullOrEmpty(qualifier))
@@ -1585,6 +1590,7 @@ namespace MediaBrowser.Model.Dlna
break;
}
+
case ProfileConditionValue.VideoBitDepth:
{
if (string.IsNullOrEmpty(qualifier))
@@ -1620,6 +1626,7 @@ namespace MediaBrowser.Model.Dlna
break;
}
+
case ProfileConditionValue.VideoProfile:
{
if (string.IsNullOrEmpty(qualifier))
@@ -1643,6 +1650,7 @@ namespace MediaBrowser.Model.Dlna
break;
}
+
case ProfileConditionValue.Height:
{
if (!enableNonQualifiedConditions)
@@ -1668,6 +1676,7 @@ namespace MediaBrowser.Model.Dlna
break;
}
+
case ProfileConditionValue.VideoBitrate:
{
if (!enableNonQualifiedConditions)
@@ -1693,6 +1702,7 @@ namespace MediaBrowser.Model.Dlna
break;
}
+
case ProfileConditionValue.VideoFramerate:
{
if (!enableNonQualifiedConditions)
@@ -1718,6 +1728,7 @@ namespace MediaBrowser.Model.Dlna
break;
}
+
case ProfileConditionValue.VideoLevel:
{
if (string.IsNullOrEmpty(qualifier))
@@ -1743,6 +1754,7 @@ namespace MediaBrowser.Model.Dlna
break;
}
+
case ProfileConditionValue.Width:
{
if (!enableNonQualifiedConditions)
diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs
index 94d53ab70..9399d21f1 100644
--- a/MediaBrowser.Model/Dlna/StreamInfo.cs
+++ b/MediaBrowser.Model/Dlna/StreamInfo.cs
@@ -276,7 +276,6 @@ namespace MediaBrowser.Model.Dlna
list.Add(new NameValuePair("SubtitleMethod", item.SubtitleStreamIndex.HasValue && item.SubtitleDeliveryMethod != SubtitleDeliveryMethod.External ? item.SubtitleDeliveryMethod.ToString() : string.Empty));
-
if (!item.IsDirectStream)
{
if (item.RequireNonAnamorphic)
diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs
index af3d83ade..fac754177 100644
--- a/MediaBrowser.Model/Dto/BaseItemDto.cs
+++ b/MediaBrowser.Model/Dto/BaseItemDto.cs
@@ -429,6 +429,7 @@ namespace MediaBrowser.Model.Dto
/// </summary>
/// <value>The album id.</value>
public Guid AlbumId { get; set; }
+
/// <summary>
/// Gets or sets the album image tag.
/// </summary>
@@ -599,11 +600,13 @@ namespace MediaBrowser.Model.Dto
/// </summary>
/// <value>The trailer count.</value>
public int? TrailerCount { get; set; }
+
/// <summary>
/// Gets or sets the movie count.
/// </summary>
/// <value>The movie count.</value>
public int? MovieCount { get; set; }
+
/// <summary>
/// Gets or sets the series count.
/// </summary>
@@ -611,16 +614,19 @@ namespace MediaBrowser.Model.Dto
public int? SeriesCount { get; set; }
public int? ProgramCount { get; set; }
+
/// <summary>
/// Gets or sets the episode count.
/// </summary>
/// <value>The episode count.</value>
public int? EpisodeCount { get; set; }
+
/// <summary>
/// Gets or sets the song count.
/// </summary>
/// <value>The song count.</value>
public int? SongCount { get; set; }
+
/// <summary>
/// Gets or sets the album count.
/// </summary>
@@ -628,6 +634,7 @@ namespace MediaBrowser.Model.Dto
public int? AlbumCount { get; set; }
public int? ArtistCount { get; set; }
+
/// <summary>
/// Gets or sets the music video count.
/// </summary>
@@ -768,6 +775,7 @@ namespace MediaBrowser.Model.Dto
/// </summary>
/// <value>The timer identifier.</value>
public string TimerId { get; set; }
+
/// <summary>
/// Gets or sets the current program.
/// </summary>
diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs
index 2d37618c2..fa3c9aaa2 100644
--- a/MediaBrowser.Model/Entities/MediaStream.cs
+++ b/MediaBrowser.Model/Entities/MediaStream.cs
@@ -451,11 +451,13 @@ namespace MediaBrowser.Model.Entities
/// </summary>
/// <value>The method.</value>
public SubtitleDeliveryMethod? DeliveryMethod { get; set; }
+
/// <summary>
/// Gets or sets the delivery URL.
/// </summary>
/// <value>The delivery URL.</value>
public string DeliveryUrl { get; set; }
+
/// <summary>
/// Gets or sets a value indicating whether this instance is external URL.
/// </summary>
diff --git a/MediaBrowser.Model/Entities/MetadataProvider.cs b/MediaBrowser.Model/Entities/MetadataProvider.cs
index 7fecf67b8..e9c098021 100644
--- a/MediaBrowser.Model/Entities/MetadataProvider.cs
+++ b/MediaBrowser.Model/Entities/MetadataProvider.cs
@@ -11,18 +11,22 @@ namespace MediaBrowser.Model.Entities
/// The imdb.
/// </summary>
Imdb = 2,
+
/// <summary>
/// The TMDB.
/// </summary>
Tmdb = 3,
+
/// <summary>
/// The TVDB.
/// </summary>
Tvdb = 4,
+
/// <summary>
/// The tvcom.
/// </summary>
Tvcom = 5,
+
/// <summary>
/// Tmdb Collection Id.
/// </summary>
diff --git a/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs b/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs
index ab74aff28..bcba344cc 100644
--- a/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs
+++ b/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs
@@ -84,6 +84,7 @@ namespace MediaBrowser.Model.LiveTv
/// </summary>
/// <value><c>null</c> if [is kids] contains no value, <c>true</c> if [is kids]; otherwise, <c>false</c>.</value>
public bool? IsKids { get; set; }
+
/// <summary>
/// Gets or sets a value indicating whether this instance is sports.
/// </summary>
diff --git a/MediaBrowser.Model/Providers/RemoteImageInfo.cs b/MediaBrowser.Model/Providers/RemoteImageInfo.cs
index 78ab6c706..fb25999e0 100644
--- a/MediaBrowser.Model/Providers/RemoteImageInfo.cs
+++ b/MediaBrowser.Model/Providers/RemoteImageInfo.cs
@@ -68,5 +68,4 @@ namespace MediaBrowser.Model.Providers
/// <value>The type of the rating.</value>
public RatingType RatingType { get; set; }
}
-
}
diff --git a/MediaBrowser.Model/Providers/RemoteSearchResult.cs b/MediaBrowser.Model/Providers/RemoteSearchResult.cs
index 989741c01..a29e7ad1c 100644
--- a/MediaBrowser.Model/Providers/RemoteSearchResult.cs
+++ b/MediaBrowser.Model/Providers/RemoteSearchResult.cs
@@ -50,6 +50,5 @@ namespace MediaBrowser.Model.Providers
public RemoteSearchResult AlbumArtist { get; set; }
public RemoteSearchResult[] Artists { get; set; }
-
}
}
diff --git a/MediaBrowser.Model/Querying/ItemFields.cs b/MediaBrowser.Model/Querying/ItemFields.cs
index 731d22aaf..ef4698f3f 100644
--- a/MediaBrowser.Model/Querying/ItemFields.cs
+++ b/MediaBrowser.Model/Querying/ItemFields.cs
@@ -168,6 +168,7 @@ namespace MediaBrowser.Model.Querying
Studios,
BasicSyncInfo,
+
/// <summary>
/// The synchronize information.
/// </summary>
diff --git a/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs b/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs
index 2ef6f7c60..eb6239460 100644
--- a/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs
+++ b/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs
@@ -37,16 +37,19 @@ namespace MediaBrowser.Model.Querying
/// </summary>
/// <value>The fields.</value>
public ItemFields[] Fields { get; set; }
+
/// <summary>
/// Gets or sets a value indicating whether [enable images].
/// </summary>
/// <value><c>null</c> if [enable images] contains no value, <c>true</c> if [enable images]; otherwise, <c>false</c>.</value>
public bool? EnableImages { get; set; }
+
/// <summary>
/// Gets or sets the image type limit.
/// </summary>
/// <value>The image type limit.</value>
public int? ImageTypeLimit { get; set; }
+
/// <summary>
/// Gets or sets the enable image types.
/// </summary>
diff --git a/MediaBrowser.Model/Session/PlaybackProgressInfo.cs b/MediaBrowser.Model/Session/PlaybackProgressInfo.cs
index 21bcabf1d..73dbe6a2d 100644
--- a/MediaBrowser.Model/Session/PlaybackProgressInfo.cs
+++ b/MediaBrowser.Model/Session/PlaybackProgressInfo.cs
@@ -88,16 +88,19 @@ namespace MediaBrowser.Model.Session
/// </summary>
/// <value>The play method.</value>
public PlayMethod PlayMethod { get; set; }
+
/// <summary>
/// Gets or sets the live stream identifier.
/// </summary>
/// <value>The live stream identifier.</value>
public string LiveStreamId { get; set; }
+
/// <summary>
/// Gets or sets the play session identifier.
/// </summary>
/// <value>The play session identifier.</value>
public string PlaySessionId { get; set; }
+
/// <summary>
/// Gets or sets the repeat mode.
/// </summary>
diff --git a/MediaBrowser.Model/Sync/SyncCategory.cs b/MediaBrowser.Model/Sync/SyncCategory.cs
index 80ad5f56e..1248c2f73 100644
--- a/MediaBrowser.Model/Sync/SyncCategory.cs
+++ b/MediaBrowser.Model/Sync/SyncCategory.cs
@@ -8,10 +8,12 @@ namespace MediaBrowser.Model.Sync
/// The latest.
/// </summary>
Latest = 0,
+
/// <summary>
/// The next up.
/// </summary>
NextUp = 1,
+
/// <summary>
/// The resume.
/// </summary>
diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs
index 18ca74ee3..4b83fb7e6 100644
--- a/MediaBrowser.Model/System/SystemInfo.cs
+++ b/MediaBrowser.Model/System/SystemInfo.cs
@@ -14,13 +14,16 @@ namespace MediaBrowser.Model.System
{
/// <summary>No path to FFmpeg found.</summary>
NotFound,
+
/// <summary>Path supplied via command line using switch --ffmpeg.</summary>
SetByArgument,
+
/// <summary>User has supplied path via Transcoding UI page.</summary>
Custom,
+
/// <summary>FFmpeg tool found on system $PATH.</summary>
System
- };
+ }
/// <summary>
/// Class SystemInfo.
diff --git a/MediaBrowser.Model/Tasks/IConfigurableScheduledTask.cs b/MediaBrowser.Model/Tasks/IConfigurableScheduledTask.cs
index fbfaed22e..6212d76f7 100644
--- a/MediaBrowser.Model/Tasks/IConfigurableScheduledTask.cs
+++ b/MediaBrowser.Model/Tasks/IConfigurableScheduledTask.cs
@@ -9,6 +9,7 @@ namespace MediaBrowser.Model.Tasks
/// </summary>
/// <value><c>true</c> if this instance is hidden; otherwise, <c>false</c>.</value>
bool IsHidden { get; }
+
/// <summary>
/// Gets a value indicating whether this instance is enabled.
/// </summary>
diff --git a/MediaBrowser.Model/Updates/PackageInfo.cs b/MediaBrowser.Model/Updates/PackageInfo.cs
index d9eb1386e..98b151d55 100644
--- a/MediaBrowser.Model/Updates/PackageInfo.cs
+++ b/MediaBrowser.Model/Updates/PackageInfo.cs
@@ -53,6 +53,16 @@ namespace MediaBrowser.Model.Updates
public IReadOnlyList<VersionInfo> versions { get; set; }
/// <summary>
+ /// Gets or sets the repository name.
+ /// </summary>
+ public string repositoryName { get; set; }
+
+ /// <summary>
+ /// Gets or sets the repository url.
+ /// </summary>
+ public string repositoryUrl { get; set; }
+
+ /// <summary>
/// Initializes a new instance of the <see cref="PackageInfo"/> class.
/// </summary>
public PackageInfo()
diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
index 51ca26361..813dd441f 100644
--- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj
+++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
@@ -21,7 +21,7 @@
<PackageReference Include="Microsoft.Extensions.Http" Version="3.1.8" />
<PackageReference Include="OptimizedPriorityQueue" Version="4.2.0" />
<PackageReference Include="PlaylistsNET" Version="1.1.2" />
- <PackageReference Include="TvDbSharper" Version="3.2.1" />
+ <PackageReference Include="TvDbSharper" Version="3.2.2" />
</ItemGroup>
<PropertyGroup>
diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/ArtistProvider.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/ArtistProvider.cs
index 781b71640..f27da7ce6 100644
--- a/MediaBrowser.Providers/Plugins/MusicBrainz/ArtistProvider.cs
+++ b/MediaBrowser.Providers/Plugins/MusicBrainz/ArtistProvider.cs
@@ -198,6 +198,7 @@ namespace MediaBrowser.Providers.Music
result.Name = reader.ReadElementContentAsString();
break;
}
+
case "annotation":
{
result.Overview = reader.ReadElementContentAsString();
diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs
index 46f8988f2..abfa1c6e7 100644
--- a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs
+++ b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs
@@ -444,6 +444,7 @@ namespace MediaBrowser.Providers.Music
result.Title = reader.ReadElementContentAsString();
break;
}
+
case "date":
{
var val = reader.ReadElementContentAsString();
@@ -454,17 +455,20 @@ namespace MediaBrowser.Providers.Music
break;
}
+
case "annotation":
{
result.Overview = reader.ReadElementContentAsString();
break;
}
+
case "release-group":
{
result.ReleaseGroupId = reader.GetAttribute("id");
reader.Skip();
break;
}
+
case "artist-credit":
{
using (var subReader = reader.ReadSubtree())
diff --git a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeImageProvider.cs b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeImageProvider.cs
index de2f6875f..50a876d6c 100644
--- a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeImageProvider.cs
+++ b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeImageProvider.cs
@@ -57,21 +57,28 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
// Process images
try
{
- var episodeInfo = new EpisodeInfo
+ string episodeTvdbId = null;
+
+ if (episode.IndexNumber.HasValue && episode.ParentIndexNumber.HasValue)
{
- IndexNumber = episode.IndexNumber.Value,
- ParentIndexNumber = episode.ParentIndexNumber.Value,
- SeriesProviderIds = series.ProviderIds,
- SeriesDisplayOrder = series.DisplayOrder
- };
- string episodeTvdbId = await _tvdbClientManager
- .GetEpisodeTvdbId(episodeInfo, language, cancellationToken).ConfigureAwait(false);
+ var episodeInfo = new EpisodeInfo
+ {
+ IndexNumber = episode.IndexNumber.Value,
+ ParentIndexNumber = episode.ParentIndexNumber.Value,
+ SeriesProviderIds = series.ProviderIds,
+ SeriesDisplayOrder = series.DisplayOrder
+ };
+
+ episodeTvdbId = await _tvdbClientManager
+ .GetEpisodeTvdbId(episodeInfo, language, cancellationToken).ConfigureAwait(false);
+ }
+
if (string.IsNullOrEmpty(episodeTvdbId))
{
_logger.LogError(
"Episode {SeasonNumber}x{EpisodeNumber} not found for series {SeriesTvdbId}",
- episodeInfo.ParentIndexNumber,
- episodeInfo.IndexNumber,
+ episode.ParentIndexNumber,
+ episode.IndexNumber,
series.GetProviderId(MetadataProvider.Tvdb));
return imageResult;
}
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/Movies/GenericTmdbMovieInfo.cs b/MediaBrowser.Providers/Plugins/Tmdb/Movies/GenericTmdbMovieInfo.cs
index 01a887eed..3c626f9eb 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/Movies/GenericTmdbMovieInfo.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/Movies/GenericTmdbMovieInfo.cs
@@ -302,7 +302,6 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
{
Url = string.Format(CultureInfo.InvariantCulture, "https://www.youtube.com/watch?v={0}", i.Source),
Name = i.Name
-
}).ToArray();
}
}
diff --git a/MediaBrowser.Providers/TV/DummySeasonProvider.cs b/MediaBrowser.Providers/TV/DummySeasonProvider.cs
index a0f7f6cfd..905cbefd3 100644
--- a/MediaBrowser.Providers/TV/DummySeasonProvider.cs
+++ b/MediaBrowser.Providers/TV/DummySeasonProvider.cs
@@ -217,7 +217,6 @@ namespace MediaBrowser.Providers.TV
new DeleteOptions
{
DeleteFileLocation = true
-
},
false);
diff --git a/README.md b/README.md
index 5e731d210..435e709b3 100644
--- a/README.md
+++ b/README.md
@@ -53,18 +53,19 @@ Jellyfin is a Free Software Media System that puts you in control of managing an
For further details, please see [our documentation page](https://docs.jellyfin.org/). To receive the latest updates, get help with Jellyfin, and join the community, please visit [one of our communication channels](https://docs.jellyfin.org/general/getting-help.html). For more information about the project, please see our [about page](https://docs.jellyfin.org/general/about.html).
<strong>Want to get started?</strong><br/>
-Choose from <a href="https://docs.jellyfin.org/general/administration/installing.html">Prebuilt Packages</a> or <a href="https://docs.jellyfin.org/general/administration/building.html">Build from Source</a>, then see our <a href="https://docs.jellyfin.org/general/quick-start.html">quick start guide</a>.<br/>
+Check out our <a href="https://jellyfin.org/downloads">downloads page</a> or our <a href="https://docs.jellyfin.org/general/administration/installing.html">installation guide</a>, then see our <a href="https://docs.jellyfin.org/general/quick-start.html">quick start guide</a>. You can also <a href="https://docs.jellyfin.org/general/administration/building.html">build from source</a>.<br/>
<strong>Something not working right?</strong><br/>
Open an <a href="https://docs.jellyfin.org/general/contributing/issues.html">Issue</a> on GitHub.<br/>
<strong>Want to contribute?</strong><br/>
-Check out <a href="https://docs.jellyfin.org/general/contributing/index.html">our documentation for guidelines</a>.<br/>
+Check out our <a href="https://jellyfin.org/contribute">contributing choose-your-own-adventure</a> to see where you can help, then see our <a href="https://docs.jellyfin.org/general/contributing/index.html">contributing guide</a> and our <a href="https://jellyfin.org/docs/general/community-standards">community standards</a>.<br/>
<strong>New idea or improvement?</strong><br/>
Check out our <a href="https://features.jellyfin.org/?view=most-wanted">feature request hub</a>.<br/>
-Most of the translations can be found in the web client but we have several other clients that have missing strings. Translations can be improved very easily from our <a href="https://translate.jellyfin.org/projects/jellyfin/jellyfin-core">Weblate</a> instance. Look through the following graphic to see if your native language could use some work!
+<strong>Don't see Jellyfin in your language?</strong><br/>
+Check out our <a href="https://translate.jellyfin.org">Weblate instance</a> to help translate Jellyfin and its subprojects.<br/>
<a href="https://translate.jellyfin.org/engage/jellyfin/?utm_source=widget">
<img src="https://translate.jellyfin.org/widgets/jellyfin/-/jellyfin-web/multi-auto.svg" alt="Detailed Translation Status"/>
diff --git a/tests/Jellyfin.Api.Tests/JellyfinApplicationFactory.cs b/tests/Jellyfin.Api.Tests/JellyfinApplicationFactory.cs
index 939023a95..54f8eb225 100644
--- a/tests/Jellyfin.Api.Tests/JellyfinApplicationFactory.cs
+++ b/tests/Jellyfin.Api.Tests/JellyfinApplicationFactory.cs
@@ -45,8 +45,7 @@ namespace Jellyfin.Api.Tests
// Specify the startup command line options
var commandLineOpts = new StartupOptions
{
- NoWebClient = true,
- NoAutoRunWebApp = true
+ NoWebClient = true
};
// Use a temporary directory for the application paths