Merge branch 'master' of https://github.com/jellyfin/jellyfin into HEAD

This commit is contained in:
sushilicious 2021-08-04 23:15:48 -07:00
commit 7fdef4b82b
19 changed files with 179 additions and 236 deletions

View File

@ -1,6 +1,5 @@
using System; using System;
using System.IO; using System.IO;
using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Emby.Naming.Audio; using Emby.Naming.Audio;
using Emby.Naming.Common; using Emby.Naming.Common;

View File

@ -303,7 +303,7 @@ namespace Jellyfin.Server.Extensions
{ {
description.TryGetMethodInfo(out MethodInfo methodInfo); description.TryGetMethodInfo(out MethodInfo methodInfo);
// Attribute name, method name, none. // Attribute name, method name, none.
return description?.ActionDescriptor?.AttributeRouteInfo?.Name return description?.ActionDescriptor.AttributeRouteInfo?.Name
?? methodInfo?.Name ?? methodInfo?.Name
?? null; ?? null;
}); });
@ -341,7 +341,7 @@ namespace Jellyfin.Server.Extensions
{ {
foreach (var address in host.GetAddresses()) foreach (var address in host.GetAddresses())
{ {
AddIpAddress(config, options, addr.Address, addr.PrefixLength); AddIpAddress(config, options, address, address.AddressFamily == AddressFamily.InterNetwork ? 32 : 128);
} }
} }
} }
@ -397,7 +397,7 @@ namespace Jellyfin.Server.Extensions
Type = "object", Type = "object",
Properties = typeof(ImageType).GetEnumNames().ToDictionary( Properties = typeof(ImageType).GetEnumNames().ToDictionary(
name => name, name => name,
name => new OpenApiSchema _ => new OpenApiSchema
{ {
Type = "object", Type = "object",
AdditionalProperties = new OpenApiSchema AdditionalProperties = new OpenApiSchema

View File

@ -137,11 +137,6 @@ namespace Jellyfin.Server.Middleware
private string NormalizeExceptionMessage(string msg) private string NormalizeExceptionMessage(string msg)
{ {
if (msg == null)
{
return string.Empty;
}
// Strip any information we don't want to reveal // Strip any information we don't want to reveal
return msg.Replace( return msg.Replace(
_configuration.ApplicationPaths.ProgramSystemPath, _configuration.ApplicationPaths.ProgramSystemPath,

View File

@ -40,7 +40,7 @@ namespace Jellyfin.Server.Migrations
.Select(m => ActivatorUtilities.CreateInstance(host.ServiceProvider, m)) .Select(m => ActivatorUtilities.CreateInstance(host.ServiceProvider, m))
.OfType<IMigrationRoutine>() .OfType<IMigrationRoutine>()
.ToArray(); .ToArray();
var migrationOptions = ((IConfigurationManager)host.ConfigurationManager).GetConfiguration<MigrationOptions>(MigrationsListStore.StoreKey); var migrationOptions = host.ConfigurationManager.GetConfiguration<MigrationOptions>(MigrationsListStore.StoreKey);
if (!host.ConfigurationManager.Configuration.IsStartupWizardCompleted && migrationOptions.Applied.Count == 0) if (!host.ConfigurationManager.Configuration.IsStartupWizardCompleted && migrationOptions.Applied.Count == 0)
{ {

View File

@ -92,7 +92,7 @@ namespace Jellyfin.Server.Migrations.Routines
if (entry[6].SQLiteType != SQLiteType.Null && !Guid.TryParse(entry[6].ToString(), out guid)) if (entry[6].SQLiteType != SQLiteType.Null && !Guid.TryParse(entry[6].ToString(), out guid))
{ {
// This is not a valid Guid, see if it is an internal ID from an old Emby schema // This is not a valid Guid, see if it is an internal ID from an old Emby schema
_logger.LogWarning("Invalid Guid in UserId column: ", entry[6].ToString()); _logger.LogWarning("Invalid Guid in UserId column: {Guid}", entry[6].ToString());
using var statement = userDbConnection.PrepareStatement("SELECT guid FROM LocalUsersv2 WHERE Id=@Id"); using var statement = userDbConnection.PrepareStatement("SELECT guid FROM LocalUsersv2 WHERE Id=@Id");
statement.TryBind("@Id", entry[6].ToString()); statement.TryBind("@Id", entry[6].ToString());

View File

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text.Json; using System.Text.Json;

View File

@ -5,7 +5,6 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -121,11 +120,11 @@ namespace Jellyfin.Server
// Log uncaught exceptions to the logging instead of std error // Log uncaught exceptions to the logging instead of std error
AppDomain.CurrentDomain.UnhandledException -= UnhandledExceptionToConsole; AppDomain.CurrentDomain.UnhandledException -= UnhandledExceptionToConsole;
AppDomain.CurrentDomain.UnhandledException += (sender, e) AppDomain.CurrentDomain.UnhandledException += (_, e)
=> _logger.LogCritical((Exception)e.ExceptionObject, "Unhandled Exception"); => _logger.LogCritical((Exception)e.ExceptionObject, "Unhandled Exception");
// Intercept Ctrl+C and Ctrl+Break // Intercept Ctrl+C and Ctrl+Break
Console.CancelKeyPress += (sender, e) => Console.CancelKeyPress += (_, e) =>
{ {
if (_tokenSource.IsCancellationRequested) if (_tokenSource.IsCancellationRequested)
{ {
@ -139,7 +138,7 @@ namespace Jellyfin.Server
}; };
// Register a SIGTERM handler // Register a SIGTERM handler
AppDomain.CurrentDomain.ProcessExit += (sender, e) => AppDomain.CurrentDomain.ProcessExit += (_, _) =>
{ {
if (_tokenSource.IsCancellationRequested) if (_tokenSource.IsCancellationRequested)
{ {
@ -180,7 +179,7 @@ namespace Jellyfin.Server
"The server is expected to host the web client, but the provided content directory is either " + "The server is expected to host the web client, but the provided content directory is either " +
$"invalid or empty: {webContentPath}. If you do not want to host the web client with the " + $"invalid or empty: {webContentPath}. If you do not want to host the web client with the " +
"server, you may set the '--nowebclient' command line flag, or set" + "server, you may set the '--nowebclient' command line flag, or set" +
$"'{MediaBrowser.Controller.Extensions.ConfigurationExtensions.HostWebClientKey}=false' in your config settings."); $"'{ConfigurationExtensions.HostWebClientKey}=false' in your config settings.");
} }
} }
@ -543,7 +542,7 @@ namespace Jellyfin.Server
// Get a stream of the resource contents // Get a stream of the resource contents
// NOTE: The .csproj name is used instead of the assembly name in the resource path // NOTE: The .csproj name is used instead of the assembly name in the resource path
const string ResourcePath = "Jellyfin.Server.Resources.Configuration.logging.json"; const string ResourcePath = "Jellyfin.Server.Resources.Configuration.logging.json";
await using Stream? resource = typeof(Program).Assembly.GetManifestResourceStream(ResourcePath) await using Stream resource = typeof(Program).Assembly.GetManifestResourceStream(ResourcePath)
?? throw new InvalidOperationException($"Invalid resource path: '{ResourcePath}'"); ?? throw new InvalidOperationException($"Invalid resource path: '{ResourcePath}'");
// Copy the resource contents to the expected file path for the config file // Copy the resource contents to the expected file path for the config file

View File

@ -40,7 +40,7 @@ namespace MediaBrowser.Common.Extensions
// Add an event handler for the process exit event // Add an event handler for the process exit event
var tcs = new TaskCompletionSource<bool>(); var tcs = new TaskCompletionSource<bool>();
process.Exited += (sender, args) => tcs.TrySetResult(true); process.Exited += (_, _) => tcs.TrySetResult(true);
// Return immediately if the process has already exited // Return immediately if the process has already exited
if (process.HasExitedSafe()) if (process.HasExitedSafe())

View File

@ -18,7 +18,7 @@ namespace MediaBrowser.Common.Providers
/// <param name="text">The text to parse.</param> /// <param name="text">The text to parse.</param>
/// <param name="imdbId">The parsed IMDb id.</param> /// <param name="imdbId">The parsed IMDb id.</param>
/// <returns>True if parsing was successful, false otherwise.</returns> /// <returns>True if parsing was successful, false otherwise.</returns>
public static bool TryFindImdbId(ReadOnlySpan<char> text, [NotNullWhen(true)] out ReadOnlySpan<char> imdbId) public static bool TryFindImdbId(ReadOnlySpan<char> text, out ReadOnlySpan<char> imdbId)
{ {
// imdb id is at least 9 chars (tt + 7 numbers) // imdb id is at least 9 chars (tt + 7 numbers)
while (text.Length >= 2 + ImdbMinNumbers) while (text.Length >= 2 + ImdbMinNumbers)
@ -62,7 +62,7 @@ namespace MediaBrowser.Common.Providers
/// <param name="text">The text with the url to parse.</param> /// <param name="text">The text with the url to parse.</param>
/// <param name="tmdbId">The parsed TMDb id.</param> /// <param name="tmdbId">The parsed TMDb id.</param>
/// <returns>True if parsing was successful, false otherwise.</returns> /// <returns>True if parsing was successful, false otherwise.</returns>
public static bool TryFindTmdbMovieId(ReadOnlySpan<char> text, [NotNullWhen(true)] out ReadOnlySpan<char> tmdbId) public static bool TryFindTmdbMovieId(ReadOnlySpan<char> text, out ReadOnlySpan<char> tmdbId)
=> TryFindProviderId(text, "themoviedb.org/movie/", out tmdbId); => TryFindProviderId(text, "themoviedb.org/movie/", out tmdbId);
/// <summary> /// <summary>
@ -71,7 +71,7 @@ namespace MediaBrowser.Common.Providers
/// <param name="text">The text with the url to parse.</param> /// <param name="text">The text with the url to parse.</param>
/// <param name="tmdbId">The parsed TMDb id.</param> /// <param name="tmdbId">The parsed TMDb id.</param>
/// <returns>True if parsing was successful, false otherwise.</returns> /// <returns>True if parsing was successful, false otherwise.</returns>
public static bool TryFindTmdbSeriesId(ReadOnlySpan<char> text, [NotNullWhen(true)] out ReadOnlySpan<char> tmdbId) public static bool TryFindTmdbSeriesId(ReadOnlySpan<char> text, out ReadOnlySpan<char> tmdbId)
=> TryFindProviderId(text, "themoviedb.org/tv/", out tmdbId); => TryFindProviderId(text, "themoviedb.org/tv/", out tmdbId);
/// <summary> /// <summary>
@ -80,7 +80,7 @@ namespace MediaBrowser.Common.Providers
/// <param name="text">The text with the url to parse.</param> /// <param name="text">The text with the url to parse.</param>
/// <param name="tvdbId">The parsed TVDb id.</param> /// <param name="tvdbId">The parsed TVDb id.</param>
/// <returns>True if parsing was successful, false otherwise.</returns> /// <returns>True if parsing was successful, false otherwise.</returns>
public static bool TryFindTvdbId(ReadOnlySpan<char> text, [NotNullWhen(true)] out ReadOnlySpan<char> tvdbId) public static bool TryFindTvdbId(ReadOnlySpan<char> text, out ReadOnlySpan<char> tvdbId)
=> TryFindProviderId(text, "thetvdb.com/?tab=series&id=", out tvdbId); => TryFindProviderId(text, "thetvdb.com/?tab=series&id=", out tvdbId);
private static bool TryFindProviderId(ReadOnlySpan<char> text, ReadOnlySpan<char> searchString, [NotNullWhen(true)] out ReadOnlySpan<char> providerId) private static bool TryFindProviderId(ReadOnlySpan<char> text, ReadOnlySpan<char> searchString, [NotNullWhen(true)] out ReadOnlySpan<char> providerId)

View File

@ -22,12 +22,22 @@ namespace MediaBrowser.Controller.LiveTv
/// </summary> /// </summary>
public interface ILiveTvManager public interface ILiveTvManager
{ {
event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCancelled;
event EventHandler<GenericEventArgs<TimerEventInfo>> TimerCancelled;
event EventHandler<GenericEventArgs<TimerEventInfo>> TimerCreated;
event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCreated;
/// <summary> /// <summary>
/// Gets the services. /// Gets the services.
/// </summary> /// </summary>
/// <value>The services.</value> /// <value>The services.</value>
IReadOnlyList<ILiveTvService> Services { get; } IReadOnlyList<ILiveTvService> Services { get; }
IListingsProvider[] ListingProviders { get; }
/// <summary> /// <summary>
/// Gets the new timer defaults asynchronous. /// Gets the new timer defaults asynchronous.
/// </summary> /// </summary>
@ -86,6 +96,7 @@ namespace MediaBrowser.Controller.LiveTv
/// </summary> /// </summary>
/// <param name="query">The query.</param> /// <param name="query">The query.</param>
/// <param name="options">The options.</param> /// <param name="options">The options.</param>
/// <returns>A recording.</returns>
QueryResult<BaseItemDto> GetRecordings(RecordingQuery query, DtoOptions options); QueryResult<BaseItemDto> GetRecordings(RecordingQuery query, DtoOptions options);
/// <summary> /// <summary>
@ -176,11 +187,16 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="query">The query.</param> /// <param name="query">The query.</param>
/// <param name="options">The options.</param> /// <param name="options">The options.</param>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Recommended programs.</returns>
QueryResult<BaseItemDto> GetRecommendedPrograms(InternalItemsQuery query, DtoOptions options, CancellationToken cancellationToken); QueryResult<BaseItemDto> GetRecommendedPrograms(InternalItemsQuery query, DtoOptions options, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Gets the recommended programs internal. /// Gets the recommended programs internal.
/// </summary> /// </summary>
/// <param name="query">The query.</param>
/// <param name="options">The options.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Recommended programs.</returns>
QueryResult<BaseItem> GetRecommendedProgramsInternal(InternalItemsQuery query, DtoOptions options, CancellationToken cancellationToken); QueryResult<BaseItem> GetRecommendedProgramsInternal(InternalItemsQuery query, DtoOptions options, CancellationToken cancellationToken);
/// <summary> /// <summary>
@ -202,6 +218,7 @@ namespace MediaBrowser.Controller.LiveTv
/// Gets the live tv folder. /// Gets the live tv folder.
/// </summary> /// </summary>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Live TV folder.</returns>
Folder GetInternalLiveTvFolder(CancellationToken cancellationToken); Folder GetInternalLiveTvFolder(CancellationToken cancellationToken);
/// <summary> /// <summary>
@ -213,11 +230,18 @@ namespace MediaBrowser.Controller.LiveTv
/// <summary> /// <summary>
/// Gets the internal channels. /// Gets the internal channels.
/// </summary> /// </summary>
/// <param name="query">The query.</param>
/// <param name="dtoOptions">The options.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Internal channels.</returns>
QueryResult<BaseItem> GetInternalChannels(LiveTvChannelQuery query, DtoOptions dtoOptions, CancellationToken cancellationToken); QueryResult<BaseItem> GetInternalChannels(LiveTvChannelQuery query, DtoOptions dtoOptions, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Gets the channel media sources. /// Gets the channel media sources.
/// </summary> /// </summary>
/// <param name="item">Item to search for.</param>
/// <param name="cancellationToken">CancellationToken to use for operation.</param>
/// <returns>Channel media sources wrapped in a task.</returns>
Task<IEnumerable<MediaSourceInfo>> GetChannelMediaSources(BaseItem item, CancellationToken cancellationToken); Task<IEnumerable<MediaSourceInfo>> GetChannelMediaSources(BaseItem item, CancellationToken cancellationToken);
/// <summary> /// <summary>
@ -232,6 +256,9 @@ namespace MediaBrowser.Controller.LiveTv
/// <summary> /// <summary>
/// Saves the tuner host. /// Saves the tuner host.
/// </summary> /// </summary>
/// <param name="info">Turner host to save.</param>
/// <param name="dataSourceChanged">Option to specify that data source has changed.</param>
/// <returns>Tuner host information wrapped in a task.</returns>
Task<TunerHostInfo> SaveTunerHost(TunerHostInfo info, bool dataSourceChanged = true); Task<TunerHostInfo> SaveTunerHost(TunerHostInfo info, bool dataSourceChanged = true);
/// <summary> /// <summary>
@ -271,20 +298,10 @@ namespace MediaBrowser.Controller.LiveTv
Task<List<ChannelInfo>> GetChannelsFromListingsProviderData(string id, CancellationToken cancellationToken); Task<List<ChannelInfo>> GetChannelsFromListingsProviderData(string id, CancellationToken cancellationToken);
IListingsProvider[] ListingProviders { get; }
List<NameIdPair> GetTunerHostTypes(); List<NameIdPair> GetTunerHostTypes();
Task<List<TunerHostInfo>> DiscoverTuners(bool newDevicesOnly, CancellationToken cancellationToken); Task<List<TunerHostInfo>> DiscoverTuners(bool newDevicesOnly, CancellationToken cancellationToken);
event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCancelled;
event EventHandler<GenericEventArgs<TimerEventInfo>> TimerCancelled;
event EventHandler<GenericEventArgs<TimerEventInfo>> TimerCreated;
event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCreated;
string GetEmbyTvActiveRecordingPath(string id); string GetEmbyTvActiveRecordingPath(string id);
ActiveRecordingInfo GetActiveRecordingInfo(string path); ActiveRecordingInfo GetActiveRecordingInfo(string path);

View File

@ -30,6 +30,8 @@ namespace MediaBrowser.Controller.LiveTv
/// <summary> /// <summary>
/// Gets the channels. /// Gets the channels.
/// </summary> /// </summary>
/// <param name="enableCache">Option to enable using cache.</param>
/// <param name="cancellationToken">The CancellationToken for this operation.</param>
/// <returns>Task&lt;IEnumerable&lt;ChannelInfo&gt;&gt;.</returns> /// <returns>Task&lt;IEnumerable&lt;ChannelInfo&gt;&gt;.</returns>
Task<List<ChannelInfo>> GetChannels(bool enableCache, CancellationToken cancellationToken); Task<List<ChannelInfo>> GetChannels(bool enableCache, CancellationToken cancellationToken);
@ -47,6 +49,7 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="streamId">The stream identifier.</param> /// <param name="streamId">The stream identifier.</param>
/// <param name="currentLiveStreams">The current live streams.</param> /// <param name="currentLiveStreams">The current live streams.</param>
/// <param name="cancellationToken">The cancellation token to cancel operation.</param> /// <param name="cancellationToken">The cancellation token to cancel operation.</param>
/// <returns>Live stream wrapped in a task.</returns>
Task<ILiveStream> GetChannelStream(string channelId, string streamId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken); Task<ILiveStream> GetChannelStream(string channelId, string streamId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken);
/// <summary> /// <summary>

View File

@ -18,23 +18,6 @@ namespace MediaBrowser.Controller.LiveTv
{ {
public class LiveTvChannel : BaseItem, IHasMediaSources, IHasProgramAttributes public class LiveTvChannel : BaseItem, IHasMediaSources, IHasProgramAttributes
{ {
public override List<string> GetUserDataKeys()
{
var list = base.GetUserDataKeys();
if (!ConfigurationManager.Configuration.DisableLiveTvChannelUserDataName)
{
list.Insert(0, GetClientTypeName() + "-" + Name);
}
return list;
}
public override UnratedItem GetBlockUnratedType()
{
return UnratedItem.LiveTvChannel;
}
[JsonIgnore] [JsonIgnore]
public override bool SupportsPositionTicksResume => false; public override bool SupportsPositionTicksResume => false;
@ -59,6 +42,67 @@ namespace MediaBrowser.Controller.LiveTv
[JsonIgnore] [JsonIgnore]
public override LocationType LocationType => LocationType.Remote; public override LocationType LocationType => LocationType.Remote;
[JsonIgnore]
public override string MediaType => ChannelType == ChannelType.Radio ? Model.Entities.MediaType.Audio : Model.Entities.MediaType.Video;
[JsonIgnore]
public bool IsMovie { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is sports.
/// </summary>
/// <value><c>true</c> if this instance is sports; otherwise, <c>false</c>.</value>
[JsonIgnore]
public bool IsSports { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is series.
/// </summary>
/// <value><c>true</c> if this instance is series; otherwise, <c>false</c>.</value>
[JsonIgnore]
public bool IsSeries { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is news.
/// </summary>
/// <value><c>true</c> if this instance is news; otherwise, <c>false</c>.</value>
[JsonIgnore]
public bool IsNews { get; set; }
/// <summary>
/// Gets a value indicating whether this instance is kids.
/// </summary>
/// <value><c>true</c> if this instance is kids; otherwise, <c>false</c>.</value>
[JsonIgnore]
public bool IsKids => Tags.Contains("Kids", StringComparer.OrdinalIgnoreCase);
[JsonIgnore]
public bool IsRepeat { get; set; }
/// <summary>
/// Gets or sets the episode title.
/// </summary>
/// <value>The episode title.</value>
[JsonIgnore]
public string EpisodeTitle { get; set; }
public override List<string> GetUserDataKeys()
{
var list = base.GetUserDataKeys();
if (!ConfigurationManager.Configuration.DisableLiveTvChannelUserDataName)
{
list.Insert(0, GetClientTypeName() + "-" + Name);
}
return list;
}
public override UnratedItem GetBlockUnratedType()
{
return UnratedItem.LiveTvChannel;
}
protected override string CreateSortName() protected override string CreateSortName()
{ {
if (!string.IsNullOrEmpty(Number)) if (!string.IsNullOrEmpty(Number))
@ -74,9 +118,6 @@ namespace MediaBrowser.Controller.LiveTv
return (Number ?? string.Empty) + "-" + (Name ?? string.Empty); return (Number ?? string.Empty) + "-" + (Name ?? string.Empty);
} }
[JsonIgnore]
public override string MediaType => ChannelType == ChannelType.Radio ? Model.Entities.MediaType.Audio : Model.Entities.MediaType.Video;
public override string GetClientTypeName() public override string GetClientTypeName()
{ {
return "TvChannel"; return "TvChannel";
@ -122,46 +163,5 @@ namespace MediaBrowser.Controller.LiveTv
{ {
return false; return false;
} }
[JsonIgnore]
public bool IsMovie { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is sports.
/// </summary>
/// <value><c>true</c> if this instance is sports; otherwise, <c>false</c>.</value>
[JsonIgnore]
public bool IsSports { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is series.
/// </summary>
/// <value><c>true</c> if this instance is series; otherwise, <c>false</c>.</value>
[JsonIgnore]
public bool IsSeries { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is news.
/// </summary>
/// <value><c>true</c> if this instance is news; otherwise, <c>false</c>.</value>
[JsonIgnore]
public bool IsNews { get; set; }
/// <summary>
/// Gets a value indicating whether this instance is kids.
/// </summary>
/// <value><c>true</c> if this instance is kids; otherwise, <c>false</c>.</value>
[JsonIgnore]
public bool IsKids => Tags.Contains("Kids", StringComparer.OrdinalIgnoreCase);
[JsonIgnore]
public bool IsRepeat { get; set; }
/// <summary>
/// Gets or sets the episode title.
/// </summary>
/// <value>The episode title.</value>
[JsonIgnore]
public string EpisodeTitle { get; set; }
} }
} }

View File

@ -1,6 +1,6 @@
#nullable disable #nullable disable
#pragma warning disable CS1591 #pragma warning disable CS1591, SA1306
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -19,54 +19,14 @@ namespace MediaBrowser.Controller.LiveTv
{ {
public class LiveTvProgram : BaseItem, IHasLookupInfo<ItemLookupInfo>, IHasStartDate, IHasProgramAttributes public class LiveTvProgram : BaseItem, IHasLookupInfo<ItemLookupInfo>, IHasStartDate, IHasProgramAttributes
{ {
private static string EmbyServiceName = "Emby";
public LiveTvProgram() public LiveTvProgram()
{ {
IsVirtualItem = true; IsVirtualItem = true;
} }
public override List<string> GetUserDataKeys() public string SeriesName { get; set; }
{
var list = base.GetUserDataKeys();
if (!IsSeries)
{
var key = this.GetProviderId(MetadataProvider.Imdb);
if (!string.IsNullOrEmpty(key))
{
list.Insert(0, key);
}
key = this.GetProviderId(MetadataProvider.Tmdb);
if (!string.IsNullOrEmpty(key))
{
list.Insert(0, key);
}
}
else if (!string.IsNullOrEmpty(EpisodeTitle))
{
var name = GetClientTypeName();
list.Insert(0, name + "-" + Name + (EpisodeTitle ?? string.Empty));
}
return list;
}
private static string EmbyServiceName = "Emby";
public override double GetDefaultPrimaryImageAspectRatio()
{
var serviceName = ServiceName;
if (string.Equals(serviceName, EmbyServiceName, StringComparison.OrdinalIgnoreCase) || string.Equals(serviceName, "Next Pvr", StringComparison.OrdinalIgnoreCase))
{
return 2.0 / 3;
}
else
{
return 16.0 / 9;
}
}
[JsonIgnore] [JsonIgnore]
public override SourceType SourceType => SourceType.LiveTV; public override SourceType SourceType => SourceType.LiveTV;
@ -182,6 +142,66 @@ namespace MediaBrowser.Controller.LiveTv
} }
} }
[JsonIgnore]
public override bool SupportsPeople
{
get
{
// Optimization
if (IsNews || IsSports)
{
return false;
}
return base.SupportsPeople;
}
}
[JsonIgnore]
public override bool SupportsAncestors => false;
public override List<string> GetUserDataKeys()
{
var list = base.GetUserDataKeys();
if (!IsSeries)
{
var key = this.GetProviderId(MetadataProvider.Imdb);
if (!string.IsNullOrEmpty(key))
{
list.Insert(0, key);
}
key = this.GetProviderId(MetadataProvider.Tmdb);
if (!string.IsNullOrEmpty(key))
{
list.Insert(0, key);
}
}
else if (!string.IsNullOrEmpty(EpisodeTitle))
{
var name = GetClientTypeName();
list.Insert(0, name + "-" + Name + (EpisodeTitle ?? string.Empty));
}
return list;
}
public override double GetDefaultPrimaryImageAspectRatio()
{
var serviceName = ServiceName;
if (string.Equals(serviceName, EmbyServiceName, StringComparison.OrdinalIgnoreCase) || string.Equals(serviceName, "Next Pvr", StringComparison.OrdinalIgnoreCase))
{
return 2.0 / 3;
}
else
{
return 16.0 / 9;
}
}
public override string GetClientTypeName() public override string GetClientTypeName()
{ {
return "Program"; return "Program";
@ -202,24 +222,6 @@ namespace MediaBrowser.Controller.LiveTv
return false; return false;
} }
[JsonIgnore]
public override bool SupportsPeople
{
get
{
// Optimization
if (IsNews || IsSports)
{
return false;
}
return base.SupportsPeople;
}
}
[JsonIgnore]
public override bool SupportsAncestors => false;
private LiveTvOptions GetConfiguration() private LiveTvOptions GetConfiguration()
{ {
return ConfigurationManager.GetConfiguration<LiveTvOptions>("livetv"); return ConfigurationManager.GetConfiguration<LiveTvOptions>("livetv");
@ -273,7 +275,5 @@ namespace MediaBrowser.Controller.LiveTv
return list; return list;
} }
public string SeriesName { get; set; }
} }
} }

View File

@ -81,7 +81,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
var id = info.Key + "Id"; var id = info.Key + "Id";
if (!_validProviderIds.ContainsKey(id)) if (!_validProviderIds.ContainsKey(id))
{ {
_validProviderIds.Add(id, info.Key!); _validProviderIds.Add(id, info.Key);
} }
} }
@ -750,46 +750,6 @@ namespace MediaBrowser.LocalMetadata.Parsers
item.Shares = list.ToArray(); item.Shares = list.ToArray();
} }
private Share GetShareFromNode(XmlReader reader)
{
var share = new Share();
reader.MoveToContent();
reader.Read();
// Loop through each element
while (!reader.EOF && reader.ReadState == ReadState.Interactive)
{
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "UserId":
{
share.UserId = reader.ReadElementContentAsString();
break;
}
case "CanEdit":
{
share.CanEdit = string.Equals(reader.ReadElementContentAsString(), true.ToString(CultureInfo.InvariantCulture), StringComparison.OrdinalIgnoreCase);
break;
}
default:
reader.Skip();
break;
}
}
else
{
reader.Read();
}
}
return share;
}
private void FetchFromCountriesNode(XmlReader reader) private void FetchFromCountriesNode(XmlReader reader)
{ {
reader.MoveToContent(); reader.MoveToContent();
@ -1101,7 +1061,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
switch (reader.Name) switch (reader.Name)
{ {
case "Name": case "Name":
name = reader.ReadElementContentAsString() ?? string.Empty; name = reader.ReadElementContentAsString();
break; break;
case "Type": case "Type":
@ -1270,8 +1230,6 @@ namespace MediaBrowser.LocalMetadata.Parsers
/// <returns>IEnumerable{System.String}.</returns> /// <returns>IEnumerable{System.String}.</returns>
private IEnumerable<string> SplitNames(string value) private IEnumerable<string> SplitNames(string value)
{ {
value ??= string.Empty;
// Only split by comma if there is no pipe in the string // Only split by comma if there is no pipe in the string
// We have to be careful to not split names like Matthew, Jr. // We have to be careful to not split names like Matthew, Jr.
var separator = !value.Contains('|', StringComparison.Ordinal) var separator = !value.Contains('|', StringComparison.Ordinal)

View File

@ -33,16 +33,12 @@ namespace MediaBrowser.LocalMetadata.Savers
/// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param> /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
/// <param name="configurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param> /// <param name="configurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param> /// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
/// <param name="userDataManager">Instance of the <see cref="IUserDataManager"/> interface.</param>
/// <param name="logger">Instance of the <see cref="ILogger{BaseXmlSaver}"/> interface.</param> /// <param name="logger">Instance of the <see cref="ILogger{BaseXmlSaver}"/> interface.</param>
protected BaseXmlSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager, ILogger<BaseXmlSaver> logger) protected BaseXmlSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, ILogger<BaseXmlSaver> logger)
{ {
FileSystem = fileSystem; FileSystem = fileSystem;
ConfigurationManager = configurationManager; ConfigurationManager = configurationManager;
LibraryManager = libraryManager; LibraryManager = libraryManager;
UserManager = userManager;
UserDataManager = userDataManager;
Logger = logger; Logger = logger;
} }
@ -61,16 +57,6 @@ namespace MediaBrowser.LocalMetadata.Savers
/// </summary> /// </summary>
protected ILibraryManager LibraryManager { get; private set; } protected ILibraryManager LibraryManager { get; private set; }
/// <summary>
/// Gets the user manager.
/// </summary>
protected IUserManager UserManager { get; private set; }
/// <summary>
/// Gets the user data manager.
/// </summary>
protected IUserDataManager UserDataManager { get; private set; }
/// <summary> /// <summary>
/// Gets the logger. /// Gets the logger.
/// </summary> /// </summary>
@ -334,7 +320,7 @@ namespace MediaBrowser.LocalMetadata.Savers
if (runTimeTicks.HasValue) if (runTimeTicks.HasValue)
{ {
var timespan = TimeSpan.FromTicks(runTimeTicks!.Value); var timespan = TimeSpan.FromTicks(runTimeTicks.Value);
writer.WriteElementString("RunningTime", Math.Floor(timespan.TotalMinutes).ToString(_usCulture)); writer.WriteElementString("RunningTime", Math.Floor(timespan.TotalMinutes).ToString(_usCulture));
} }

View File

@ -20,11 +20,9 @@ namespace MediaBrowser.LocalMetadata.Savers
/// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param> /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
/// <param name="configurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param> /// <param name="configurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param> /// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
/// <param name="userDataManager">Instance of the <see cref="IUserDataManager"/> interface.</param>
/// <param name="logger">Instance of the <see cref="ILogger{BoxSetXmlSaver}"/> interface.</param> /// <param name="logger">Instance of the <see cref="ILogger{BoxSetXmlSaver}"/> interface.</param>
public BoxSetXmlSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager, ILogger<BoxSetXmlSaver> logger) public BoxSetXmlSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, ILogger<BoxSetXmlSaver> logger)
: base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger) : base(fileSystem, configurationManager, libraryManager, logger)
{ {
} }

View File

@ -25,11 +25,9 @@ namespace MediaBrowser.LocalMetadata.Savers
/// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param> /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
/// <param name="configurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param> /// <param name="configurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param> /// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
/// <param name="userDataManager">Instance of the <see cref="IUserDataManager"/> interface.</param>
/// <param name="logger">Instance of the <see cref="ILogger{PlaylistXmlSaver}"/> interface.</param> /// <param name="logger">Instance of the <see cref="ILogger{PlaylistXmlSaver}"/> interface.</param>
public PlaylistXmlSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager, ILogger<PlaylistXmlSaver> logger) public PlaylistXmlSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, ILogger<PlaylistXmlSaver> logger)
: base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger) : base(fileSystem, configurationManager, libraryManager, logger)
{ {
} }

View File

@ -1,9 +0,0 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Users
{
public enum UserActionType
{
PlayedItem = 0
}
}

View File

@ -1205,7 +1205,7 @@ namespace MediaBrowser.XbmcMetadata.Parsers
switch (reader.Name) switch (reader.Name)
{ {
case "name": case "name":
name = reader.ReadElementContentAsString() ?? string.Empty; name = reader.ReadElementContentAsString();
break; break;
case "role": case "role":