diff options
Diffstat (limited to 'MediaBrowser.Model')
25 files changed, 221 insertions, 160 deletions
diff --git a/MediaBrowser.Model/Configuration/MediaPathInfo.cs b/MediaBrowser.Model/Configuration/MediaPathInfo.cs index 4f311c58f..a7bc43590 100644 --- a/MediaBrowser.Model/Configuration/MediaPathInfo.cs +++ b/MediaBrowser.Model/Configuration/MediaPathInfo.cs @@ -1,12 +1,22 @@ -#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Configuration { public class MediaPathInfo { + public MediaPathInfo(string path) + { + Path = path; + } + + // Needed for xml serialization + public MediaPathInfo() + { + Path = string.Empty; + } + public string Path { get; set; } - public string NetworkPath { get; set; } + public string? NetworkPath { get; set; } } } diff --git a/MediaBrowser.Model/Configuration/MetadataOptions.cs b/MediaBrowser.Model/Configuration/MetadataOptions.cs index 76b72bd08..384a7997f 100644 --- a/MediaBrowser.Model/Configuration/MetadataOptions.cs +++ b/MediaBrowser.Model/Configuration/MetadataOptions.cs @@ -1,5 +1,5 @@ #nullable disable -#pragma warning disable CS1591 +#pragma warning disable CS1591, CA1819 using System; diff --git a/MediaBrowser.Model/Devices/DeviceInfo.cs b/MediaBrowser.Model/Devices/DeviceInfo.cs index 0cccf931c..7a1c7a738 100644 --- a/MediaBrowser.Model/Devices/DeviceInfo.cs +++ b/MediaBrowser.Model/Devices/DeviceInfo.cs @@ -16,6 +16,11 @@ namespace MediaBrowser.Model.Devices public string Name { get; set; } /// <summary> + /// Gets or sets the access token. + /// </summary> + public string AccessToken { get; set; } + + /// <summary> /// Gets or sets the identifier. /// </summary> /// <value>The identifier.</value> diff --git a/MediaBrowser.Model/Devices/DeviceOptions.cs b/MediaBrowser.Model/Devices/DeviceOptions.cs deleted file mode 100644 index 037ffeb5e..000000000 --- a/MediaBrowser.Model/Devices/DeviceOptions.cs +++ /dev/null @@ -1,9 +0,0 @@ -#pragma warning disable CS1591 - -namespace MediaBrowser.Model.Devices -{ - public class DeviceOptions - { - public string? CustomName { get; set; } - } -} diff --git a/MediaBrowser.Model/Devices/DeviceQuery.cs b/MediaBrowser.Model/Devices/DeviceQuery.cs deleted file mode 100644 index 64e366a56..000000000 --- a/MediaBrowser.Model/Devices/DeviceQuery.cs +++ /dev/null @@ -1,21 +0,0 @@ -#pragma warning disable CS1591 - -using System; - -namespace MediaBrowser.Model.Devices -{ - public class DeviceQuery - { - /// <summary> - /// Gets or sets a value indicating whether [supports synchronize]. - /// </summary> - /// <value><c>null</c> if [supports synchronize] contains no value, <c>true</c> if [supports synchronize]; otherwise, <c>false</c>.</value> - public bool? SupportsSync { get; set; } - - /// <summary> - /// Gets or sets the user identifier. - /// </summary> - /// <value>The user identifier.</value> - public Guid UserId { get; set; } - } -} diff --git a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs index 600a44157..e8fd18ae4 100644 --- a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs +++ b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs @@ -208,7 +208,6 @@ namespace MediaBrowser.Model.Dlna if (string.IsNullOrEmpty(orgPn)) { contentFeatureList.Add(orgOp.TrimStart(';') + orgCi + dlnaflags); - continue; } else { diff --git a/MediaBrowser.Model/Dlna/DirectPlayProfile.cs b/MediaBrowser.Model/Dlna/DirectPlayProfile.cs index fa3ad098f..03c3a7265 100644 --- a/MediaBrowser.Model/Dlna/DirectPlayProfile.cs +++ b/MediaBrowser.Model/Dlna/DirectPlayProfile.cs @@ -1,6 +1,5 @@ #pragma warning disable CS1591 -using System.ComponentModel.DataAnnotations; using System.Xml.Serialization; namespace MediaBrowser.Model.Dlna diff --git a/MediaBrowser.Model/Dlna/MediaFormatProfile.cs b/MediaBrowser.Model/Dlna/MediaFormatProfile.cs index 20e05b8a9..06f6660f4 100644 --- a/MediaBrowser.Model/Dlna/MediaFormatProfile.cs +++ b/MediaBrowser.Model/Dlna/MediaFormatProfile.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591 +#pragma warning disable CS1591, CA1707 namespace MediaBrowser.Model.Dlna { diff --git a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs index 7ce248509..93a9ae615 100644 --- a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs +++ b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Globalization; -using System.Linq; using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.Model.Dlna diff --git a/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs b/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs index 65fccbdd4..94071b419 100644 --- a/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs +++ b/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs @@ -5,7 +5,7 @@ using System; namespace MediaBrowser.Model.Dlna { - public class ResolutionNormalizer + public static class ResolutionNormalizer { private static readonly ResolutionConfiguration[] Configurations = new[] @@ -21,11 +21,7 @@ namespace MediaBrowser.Model.Dlna public static ResolutionOptions Normalize( int? inputBitrate, - int? unused1, - int? unused2, int outputBitrate, - string inputCodec, - string outputCodec, int? maxWidth, int? maxHeight) { diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index f4c69fe8f..84d99d550 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -694,7 +694,7 @@ namespace MediaBrowser.Model.Dlna if (isEligibleForDirectPlay || isEligibleForDirectStream) { // See if it can be direct played - var directPlayInfo = GetVideoDirectPlayProfile(options, item, videoStream, audioStream, isEligibleForDirectPlay, isEligibleForDirectStream); + var directPlayInfo = GetVideoDirectPlayProfile(options, item, videoStream, audioStream, isEligibleForDirectStream); var directPlay = directPlayInfo.Item1; if (directPlay != null) @@ -810,7 +810,7 @@ namespace MediaBrowser.Model.Dlna // Honor requested max channels playlistItem.GlobalMaxAudioChannels = options.MaxAudioChannels; - int audioBitrate = GetAudioBitrate(playlistItem.SubProtocol, options.GetMaxBitrate(false) ?? 0, playlistItem.TargetAudioCodec, audioStream, playlistItem); + int audioBitrate = GetAudioBitrate(options.GetMaxBitrate(false) ?? 0, playlistItem.TargetAudioCodec, audioStream, playlistItem); playlistItem.AudioBitrate = Math.Min(playlistItem.AudioBitrate ?? audioBitrate, audioBitrate); isFirstAppliedCodecProfile = true; @@ -907,7 +907,7 @@ namespace MediaBrowser.Model.Dlna return 192000; } - private static int GetAudioBitrate(string subProtocol, long maxTotalBitrate, string[] targetAudioCodecs, MediaStream audioStream, StreamInfo item) + private static int GetAudioBitrate(long maxTotalBitrate, string[] targetAudioCodecs, MediaStream audioStream, StreamInfo item) { string targetAudioCodec = targetAudioCodecs.Length == 0 ? null : targetAudioCodecs[0]; @@ -1005,7 +1005,6 @@ namespace MediaBrowser.Model.Dlna MediaSourceInfo mediaSource, MediaStream videoStream, MediaStream audioStream, - bool isEligibleForDirectPlay, bool isEligibleForDirectStream) { if (options.ForceDirectPlay) @@ -1146,7 +1145,7 @@ namespace MediaBrowser.Model.Dlna { string audioCodec = audioStream.Codec; conditions = new List<ProfileCondition>(); - bool? isSecondaryAudio = audioStream == null ? null : mediaSource.IsSecondaryAudio(audioStream); + bool? isSecondaryAudio = mediaSource.IsSecondaryAudio(audioStream); foreach (var i in profile.CodecProfiles) { @@ -1230,7 +1229,7 @@ namespace MediaBrowser.Model.Dlna bool result = IsAudioEligibleForDirectPlay(item, maxBitrate, playMethod); - return (result, result ? (TranscodeReason?)null : TranscodeReason.ContainerBitrateExceedsLimit); + return (result, result ? null : TranscodeReason.ContainerBitrateExceedsLimit); } public static SubtitleProfile GetSubtitleProfile( @@ -1262,7 +1261,7 @@ namespace MediaBrowser.Model.Dlna continue; } - if (playMethod == PlayMethod.Transcode && !IsSubtitleEmbedSupported(subtitleStream, profile, transcodingSubProtocol, outputContainer)) + if (playMethod == PlayMethod.Transcode && !IsSubtitleEmbedSupported(outputContainer)) { continue; } @@ -1291,7 +1290,7 @@ namespace MediaBrowser.Model.Dlna continue; } - if (playMethod == PlayMethod.Transcode && !IsSubtitleEmbedSupported(subtitleStream, profile, transcodingSubProtocol, outputContainer)) + if (playMethod == PlayMethod.Transcode && !IsSubtitleEmbedSupported(outputContainer)) { continue; } @@ -1313,7 +1312,7 @@ namespace MediaBrowser.Model.Dlna }; } - private static bool IsSubtitleEmbedSupported(MediaStream subtitleStream, SubtitleProfile subtitleProfile, string transcodingSubProtocol, string transcodingContainer) + private static bool IsSubtitleEmbedSupported(string transcodingContainer) { if (!string.IsNullOrEmpty(transcodingContainer)) { @@ -1728,18 +1727,14 @@ namespace MediaBrowser.Model.Dlna continue; } - if (!string.IsNullOrEmpty(value)) - { - // change from split by | to comma - - // strip spaces to avoid having to encode - var values = value - .Split('|', StringSplitOptions.RemoveEmptyEntries); + // change from split by | to comma + // strip spaces to avoid having to encode + var values = value + .Split('|', StringSplitOptions.RemoveEmptyEntries); - if (condition.Condition == ProfileConditionType.Equals || condition.Condition == ProfileConditionType.EqualsAny) - { - item.SetOption(qualifier, "profile", string.Join(',', values)); - } + if (condition.Condition == ProfileConditionType.Equals || condition.Condition == ProfileConditionType.EqualsAny) + { + item.SetOption(qualifier, "profile", string.Join(',', values)); } break; diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index 252872847..4414415a2 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -133,7 +133,7 @@ namespace MediaBrowser.Model.Dlna var stream = TargetAudioStream; return AudioSampleRate.HasValue && !IsDirectStream ? AudioSampleRate - : stream == null ? null : stream.SampleRate; + : stream?.SampleRate; } } @@ -146,7 +146,7 @@ namespace MediaBrowser.Model.Dlna { if (IsDirectStream) { - return TargetAudioStream == null ? (int?)null : TargetAudioStream.BitDepth; + return TargetAudioStream?.BitDepth; } var targetAudioCodecs = TargetAudioCodec; @@ -156,7 +156,7 @@ namespace MediaBrowser.Model.Dlna return GetTargetAudioBitDepth(audioCodec); } - return TargetAudioStream == null ? (int?)null : TargetAudioStream.BitDepth; + return TargetAudioStream?.BitDepth; } } @@ -169,7 +169,7 @@ namespace MediaBrowser.Model.Dlna { if (IsDirectStream) { - return TargetVideoStream == null ? (int?)null : TargetVideoStream.BitDepth; + return TargetVideoStream?.BitDepth; } var targetVideoCodecs = TargetVideoCodec; @@ -179,7 +179,7 @@ namespace MediaBrowser.Model.Dlna return GetTargetVideoBitDepth(videoCodec); } - return TargetVideoStream == null ? (int?)null : TargetVideoStream.BitDepth; + return TargetVideoStream?.BitDepth; } } @@ -193,7 +193,7 @@ namespace MediaBrowser.Model.Dlna { if (IsDirectStream) { - return TargetVideoStream == null ? (int?)null : TargetVideoStream.RefFrames; + return TargetVideoStream?.RefFrames; } var targetVideoCodecs = TargetVideoCodec; @@ -203,7 +203,7 @@ namespace MediaBrowser.Model.Dlna return GetTargetRefFrames(videoCodec); } - return TargetVideoStream == null ? (int?)null : TargetVideoStream.RefFrames; + return TargetVideoStream?.RefFrames; } } @@ -230,7 +230,7 @@ namespace MediaBrowser.Model.Dlna { if (IsDirectStream) { - return TargetVideoStream == null ? (double?)null : TargetVideoStream.Level; + return TargetVideoStream?.Level; } var targetVideoCodecs = TargetVideoCodec; @@ -240,7 +240,7 @@ namespace MediaBrowser.Model.Dlna return GetTargetVideoLevel(videoCodec); } - return TargetVideoStream == null ? (double?)null : TargetVideoStream.Level; + return TargetVideoStream?.Level; } } @@ -254,7 +254,7 @@ namespace MediaBrowser.Model.Dlna var stream = TargetVideoStream; return !IsDirectStream ? null - : stream == null ? null : stream.PacketLength; + : stream?.PacketLength; } } @@ -267,7 +267,7 @@ namespace MediaBrowser.Model.Dlna { if (IsDirectStream) { - return TargetVideoStream == null ? null : TargetVideoStream.Profile; + return TargetVideoStream?.Profile; } var targetVideoCodecs = TargetVideoCodec; @@ -277,7 +277,7 @@ namespace MediaBrowser.Model.Dlna return GetOption(videoCodec, "profile"); } - return TargetVideoStream == null ? null : TargetVideoStream.Profile; + return TargetVideoStream?.Profile; } } @@ -292,7 +292,7 @@ namespace MediaBrowser.Model.Dlna var stream = TargetVideoStream; return !IsDirectStream ? null - : stream == null ? null : stream.CodecTag; + : stream?.CodecTag; } } @@ -306,7 +306,7 @@ namespace MediaBrowser.Model.Dlna var stream = TargetAudioStream; return AudioBitrate.HasValue && !IsDirectStream ? AudioBitrate - : stream == null ? null : stream.BitRate; + : stream?.BitRate; } } @@ -319,7 +319,7 @@ namespace MediaBrowser.Model.Dlna { if (IsDirectStream) { - return TargetAudioStream == null ? (int?)null : TargetAudioStream.Channels; + return TargetAudioStream?.Channels; } var targetAudioCodecs = TargetAudioCodec; @@ -329,7 +329,7 @@ namespace MediaBrowser.Model.Dlna return GetTargetRefFrames(codec); } - return TargetAudioStream == null ? (int?)null : TargetAudioStream.Channels; + return TargetAudioStream?.Channels; } } @@ -425,7 +425,7 @@ namespace MediaBrowser.Model.Dlna return VideoBitrate.HasValue && !IsDirectStream ? VideoBitrate - : stream == null ? null : stream.BitRate; + : stream?.BitRate; } } @@ -451,7 +451,7 @@ namespace MediaBrowser.Model.Dlna { if (IsDirectStream) { - return TargetVideoStream == null ? null : TargetVideoStream.IsAnamorphic; + return TargetVideoStream?.IsAnamorphic; } return false; @@ -464,7 +464,7 @@ namespace MediaBrowser.Model.Dlna { if (IsDirectStream) { - return TargetVideoStream == null ? (bool?)null : TargetVideoStream.IsInterlaced; + return TargetVideoStream?.IsInterlaced; } var targetVideoCodecs = TargetVideoCodec; @@ -477,7 +477,7 @@ namespace MediaBrowser.Model.Dlna } } - return TargetVideoStream == null ? (bool?)null : TargetVideoStream.IsInterlaced; + return TargetVideoStream?.IsInterlaced; } } @@ -487,7 +487,7 @@ namespace MediaBrowser.Model.Dlna { if (IsDirectStream) { - return TargetVideoStream == null ? null : TargetVideoStream.IsAVC; + return TargetVideoStream?.IsAVC; } return true; @@ -618,30 +618,30 @@ namespace MediaBrowser.Model.Dlna } // Try to keep the url clean by omitting defaults - if (string.Equals(pair.Name, "StartTimeTicks", StringComparison.OrdinalIgnoreCase) && - string.Equals(pair.Value, "0", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(pair.Name, "StartTimeTicks", StringComparison.OrdinalIgnoreCase) + && string.Equals(pair.Value, "0", StringComparison.OrdinalIgnoreCase)) { continue; } - if (string.Equals(pair.Name, "SubtitleStreamIndex", StringComparison.OrdinalIgnoreCase) && - string.Equals(pair.Value, "-1", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(pair.Name, "SubtitleStreamIndex", StringComparison.OrdinalIgnoreCase) + && string.Equals(pair.Value, "-1", StringComparison.OrdinalIgnoreCase)) { continue; } - if (string.Equals(pair.Name, "Static", StringComparison.OrdinalIgnoreCase) && - string.Equals(pair.Value, "false", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(pair.Name, "Static", StringComparison.OrdinalIgnoreCase) + && string.Equals(pair.Value, "false", StringComparison.OrdinalIgnoreCase)) { continue; } - var encodedValue = pair.Value.Replace(" ", "%20"); + var encodedValue = pair.Value.Replace(" ", "%20", StringComparison.Ordinal); list.Add(string.Format(CultureInfo.InvariantCulture, "{0}={1}", pair.Name, encodedValue)); } - string queryString = string.Join("&", list.ToArray()); + string queryString = string.Join('&', list); return GetUrl(baseUrl, queryString); } @@ -681,11 +681,11 @@ namespace MediaBrowser.Model.Dlna string audioCodecs = item.AudioCodecs.Length == 0 ? string.Empty : - string.Join(",", item.AudioCodecs); + string.Join(',', item.AudioCodecs); string videoCodecs = item.VideoCodecs.Length == 0 ? string.Empty : - string.Join(",", item.VideoCodecs); + string.Join(',', item.VideoCodecs); list.Add(new NameValuePair("DeviceProfileId", item.DeviceProfileId ?? string.Empty)); list.Add(new NameValuePair("DeviceId", item.DeviceId ?? string.Empty)); @@ -1024,30 +1024,5 @@ namespace MediaBrowser.Model.Dlna return count; } - - public List<MediaStream> GetSelectableAudioStreams() - { - return GetSelectableStreams(MediaStreamType.Audio); - } - - public List<MediaStream> GetSelectableSubtitleStreams() - { - return GetSelectableStreams(MediaStreamType.Subtitle); - } - - public List<MediaStream> GetSelectableStreams(MediaStreamType type) - { - var list = new List<MediaStream>(); - - foreach (var stream in MediaSource.MediaStreams) - { - if (type == stream.Type) - { - list.Add(stream); - } - } - - return list; - } } } diff --git a/MediaBrowser.Model/Dlna/TranscodingProfile.cs b/MediaBrowser.Model/Dlna/TranscodingProfile.cs index 214578a85..709bdad31 100644 --- a/MediaBrowser.Model/Dlna/TranscodingProfile.cs +++ b/MediaBrowser.Model/Dlna/TranscodingProfile.cs @@ -1,7 +1,6 @@ #pragma warning disable CS1591 using System.ComponentModel; -using System.ComponentModel.DataAnnotations; using System.Xml.Serialization; namespace MediaBrowser.Model.Dlna diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index 9653a8ece..38ac44794 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -255,13 +255,18 @@ namespace MediaBrowser.Model.Entities attributes.Add(string.IsNullOrEmpty(LocalizedForced) ? "Forced" : LocalizedForced); } + if (!string.IsNullOrEmpty(Codec)) + { + attributes.Add(Codec.ToUpperInvariant()); + } + if (!string.IsNullOrEmpty(Title)) { var result = new StringBuilder(Title); foreach (var tag in attributes) { // Keep Tags that are not already in Title. - if (Title.IndexOf(tag, StringComparison.OrdinalIgnoreCase) == -1) + if (!Title.Contains(tag, StringComparison.OrdinalIgnoreCase)) { result.Append(" - ").Append(tag); } diff --git a/MediaBrowser.Model/Entities/PersonType.cs b/MediaBrowser.Model/Entities/PersonType.cs index 81db9c613..b985507f0 100644 --- a/MediaBrowser.Model/Entities/PersonType.cs +++ b/MediaBrowser.Model/Entities/PersonType.cs @@ -1,48 +1,68 @@ namespace MediaBrowser.Model.Entities { /// <summary> - /// Struct PersonType. + /// Types of persons. /// </summary> - public class PersonType + public static class PersonType { /// <summary> - /// The actor. + /// A person whose profession is acting on the stage, in films, or on television. /// </summary> public const string Actor = "Actor"; /// <summary> - /// The director. + /// A person who supervises the actors and other staff in a film, play, or similar production. /// </summary> public const string Director = "Director"; /// <summary> - /// The composer. + /// A person who writes music, especially as a professional occupation. /// </summary> public const string Composer = "Composer"; /// <summary> - /// The writer. + /// A writer of a book, article, or document. Can also be used as a generic term for music writer if there is a lack of specificity. /// </summary> public const string Writer = "Writer"; /// <summary> - /// The guest star. + /// A well-known actor or other performer who appears in a work in which they do not have a regular role. /// </summary> public const string GuestStar = "GuestStar"; /// <summary> - /// The producer. + /// A person responsible for the financial and managerial aspects of the making of a film or broadcast or for staging a play, opera, etc. /// </summary> public const string Producer = "Producer"; /// <summary> - /// The conductor. + /// A person who directs the performance of an orchestra or choir. /// </summary> public const string Conductor = "Conductor"; /// <summary> - /// The lyricist. + /// A person who writes the words to a song or musical. /// </summary> public const string Lyricist = "Lyricist"; + + /// <summary> + /// A person who adapts a musical composition for performance. + /// </summary> + public const string Arranger = "Arranger"; + + /// <summary> + /// An audio engineer who performed a general engineering role. + /// </summary> + public const string Engineer = "Engineer"; + + /// <summary> + /// An engineer responsible for using a mixing console to mix a recorded track into a single piece of music suitable for release. + /// </summary> + public const string Mixer = "Mixer"; + + /// <summary> + /// A person who remixed a recording by taking one or more other tracks, substantially altering them and mixing them together with other material. + /// </summary> + public const string Remixer = "Remixer"; } } diff --git a/MediaBrowser.Model/Extensions/EnumerableExtensions.cs b/MediaBrowser.Model/Extensions/EnumerableExtensions.cs index 712fa381e..a5a6b18aa 100644 --- a/MediaBrowser.Model/Extensions/EnumerableExtensions.cs +++ b/MediaBrowser.Model/Extensions/EnumerableExtensions.cs @@ -18,6 +18,12 @@ namespace MediaBrowser.Model.Extensions /// <returns>The ordered remote image infos.</returns> public static IEnumerable<RemoteImageInfo> OrderByLanguageDescending(this IEnumerable<RemoteImageInfo> remoteImageInfos, string requestedLanguage) { + if (string.IsNullOrWhiteSpace(requestedLanguage)) + { + // Default to English if no requested language is specified. + requestedLanguage = "en"; + } + var isRequestedLanguageEn = string.Equals(requestedLanguage, "en", StringComparison.OrdinalIgnoreCase); return remoteImageInfos.OrderByDescending(i => @@ -27,14 +33,16 @@ namespace MediaBrowser.Model.Extensions return 3; } - if (!isRequestedLanguageEn && string.Equals("en", i.Language, StringComparison.OrdinalIgnoreCase)) + if (string.IsNullOrEmpty(i.Language)) { - return 2; + // Assume empty image language is likely to be English. + return isRequestedLanguageEn ? 3 : 2; } - if (string.IsNullOrEmpty(i.Language)) + if (!isRequestedLanguageEn && string.Equals(i.Language, "en", StringComparison.OrdinalIgnoreCase)) { - return isRequestedLanguageEn ? 3 : 2; + // Prioritize English over non-requested languages. + return 2; } return 0; diff --git a/MediaBrowser.Model/Globalization/ILocalizationManager.cs b/MediaBrowser.Model/Globalization/ILocalizationManager.cs index b213e7aa0..e00157dce 100644 --- a/MediaBrowser.Model/Globalization/ILocalizationManager.cs +++ b/MediaBrowser.Model/Globalization/ILocalizationManager.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Globalization; using MediaBrowser.Model.Entities; namespace MediaBrowser.Model.Globalization @@ -56,10 +55,10 @@ namespace MediaBrowser.Model.Globalization IEnumerable<LocalizationOption> GetLocalizationOptions(); /// <summary> - /// Returns the correct <see cref="CultureInfo" /> for the given language. + /// Returns the correct <see cref="CultureDto" /> for the given language. /// </summary> /// <param name="language">The language.</param> - /// <returns>The correct <see cref="CultureInfo" /> for the given language.</returns> + /// <returns>The correct <see cref="CultureDto" /> for the given language.</returns> CultureDto? FindLanguageInfo(string language); } } diff --git a/MediaBrowser.Model/IO/AsyncFile.cs b/MediaBrowser.Model/IO/AsyncFile.cs new file mode 100644 index 000000000..3c8007d1c --- /dev/null +++ b/MediaBrowser.Model/IO/AsyncFile.cs @@ -0,0 +1,45 @@ +using System.IO; + +namespace MediaBrowser.Model.IO +{ + /// <summary> + /// Helper class to create async <see cref="FileStream" />s. + /// </summary> + public static class AsyncFile + { + /// <summary> + /// Gets the default <see cref="FileStreamOptions"/> for reading files async. + /// </summary> + public static FileStreamOptions ReadOptions => new FileStreamOptions() + { + Options = FileOptions.Asynchronous + }; + + /// <summary> + /// Gets the default <see cref="FileStreamOptions"/> for writing files async. + /// </summary> + public static FileStreamOptions WriteOptions => new FileStreamOptions() + { + Mode = FileMode.OpenOrCreate, + Access = FileAccess.Write, + Share = FileShare.None, + Options = FileOptions.Asynchronous + }; + + /// <summary> + /// Opens an existing file for reading. + /// </summary> + /// <param name="path">The file to be opened for reading.</param> + /// <returns>A read-only <see cref="FileStream" /> on the specified path.</returns> + public static FileStream OpenRead(string path) + => new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous); + + /// <summary> + /// Opens an existing file for writing. + /// </summary> + /// <param name="path">The file to be opened for writing.</param> + /// <returns>An unshared <see cref="FileStream" /> object on the specified path with Write access.</returns> + public static FileStream OpenWrite(string path) + => new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous); + } +} diff --git a/MediaBrowser.Model/IO/IFileSystem.cs b/MediaBrowser.Model/IO/IFileSystem.cs index be4f1e16b..0f77d6b5b 100644 --- a/MediaBrowser.Model/IO/IFileSystem.cs +++ b/MediaBrowser.Model/IO/IFileSystem.cs @@ -51,7 +51,7 @@ namespace MediaBrowser.Model.IO /// <returns>A <see cref="FileSystemMetadata" /> object.</returns> /// <remarks><para>If the specified path points to a directory, the returned <see cref="FileSystemMetadata" /> object's /// <see cref="FileSystemMetadata.IsDirectory" /> property and the <see cref="FileSystemMetadata.Exists" /> property will both be set to false.</para> - /// <para>For automatic handling of files <b>and</b> directories, use <see cref="M:IFileSystem.GetFileSystemInfo(System.String)" />.</para></remarks> + /// <para>For automatic handling of files <b>and</b> directories, use <see cref="GetFileSystemInfo(string)" />.</para></remarks> FileSystemMetadata GetFileInfo(string path); /// <summary> @@ -61,7 +61,7 @@ namespace MediaBrowser.Model.IO /// <returns>A <see cref="FileSystemMetadata" /> object.</returns> /// <remarks><para>If the specified path points to a file, the returned <see cref="FileSystemMetadata" /> object's /// <see cref="FileSystemMetadata.IsDirectory" /> property will be set to true and the <see cref="FileSystemMetadata.Exists" /> property will be set to false.</para> - /// <para>For automatic handling of files <b>and</b> directories, use <see cref="M:IFileSystem.GetFileSystemInfo(System.String)" />.</para></remarks> + /// <para>For automatic handling of files <b>and</b> directories, use <see cref="GetFileSystemInfo(string)" />.</para></remarks> FileSystemMetadata GetDirectoryInfo(string path); /// <summary> diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index a371afc2c..16bc4adf8 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -14,18 +14,13 @@ </PropertyGroup> <PropertyGroup> - <TargetFramework>net5.0</TargetFramework> + <TargetFramework>net6.0</TargetFramework> <GenerateAssemblyInfo>false</GenerateAssemblyInfo> <GenerateDocumentationFile>true</GenerateDocumentationFile> <PublishRepositoryUrl>true</PublishRepositoryUrl> <EmbedUntrackedSources>true</EmbedUntrackedSources> <IncludeSymbols>true</IncludeSymbols> <SymbolPackageFormat>snupkg</SymbolPackageFormat> - <TreatWarningsAsErrors>false</TreatWarningsAsErrors> - </PropertyGroup> - - <PropertyGroup Condition=" '$(Configuration)' == 'Release'"> - <TreatWarningsAsErrors>true</TreatWarningsAsErrors> </PropertyGroup> <PropertyGroup Condition=" '$(Stability)'=='Unstable'"> @@ -35,9 +30,9 @@ <ItemGroup> <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" /> - <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" /> + <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0-rc.2*" /> <PackageReference Include="System.Globalization" Version="4.3.0" /> - <PackageReference Include="System.Text.Json" Version="5.0.2" /> + <PackageReference Include="System.Text.Json" Version="6.0.0-rc.2*" /> </ItemGroup> <ItemGroup> diff --git a/MediaBrowser.Model/Net/MimeTypes.cs b/MediaBrowser.Model/Net/MimeTypes.cs index 96f5ab51a..748170a0e 100644 --- a/MediaBrowser.Model/Net/MimeTypes.cs +++ b/MediaBrowser.Model/Net/MimeTypes.cs @@ -2,8 +2,10 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; +using Jellyfin.Extensions; namespace MediaBrowser.Model.Net { @@ -163,15 +165,16 @@ namespace MediaBrowser.Model.Net return dict; } - public static string? GetMimeType(string path) => GetMimeType(path, true); + public static string GetMimeType(string path) => GetMimeType(path, "application/octet-stream"); /// <summary> /// Gets the type of the MIME. /// </summary> /// <param name="filename">The filename to find the MIME type of.</param> - /// <param name="enableStreamDefault">Whether of not to return a default value if no fitting MIME type is found.</param> - /// <returns>The worrect MIME type for the given filename, or `null` if it wasn't found and <paramref name="enableStreamDefault"/> is false.</returns> - public static string? GetMimeType(string filename, bool enableStreamDefault) + /// <param name="defaultValue">The default value to return if no fitting MIME type is found.</param> + /// <returns>The correct MIME type for the given filename, or <paramref name="defaultValue"/> if it wasn't found.</returns> + [return: NotNullIfNotNullAttribute("defaultValue")] + public static string? GetMimeType(string filename, string? defaultValue = null) { if (filename.Length == 0) { @@ -210,7 +213,7 @@ namespace MediaBrowser.Model.Net return "application/octet-stream"; } - return enableStreamDefault ? "application/octet-stream" : null; + return defaultValue; } public static string? ToExtension(string mimeType) @@ -221,7 +224,7 @@ namespace MediaBrowser.Model.Net } // handle text/html; charset=UTF-8 - mimeType = mimeType.Split(';')[0]; + mimeType = mimeType.AsSpan().LeftPart(';').ToString(); if (_extensionLookup.TryGetValue(mimeType, out string? result)) { diff --git a/MediaBrowser.Model/QuickConnect/QuickConnectResult.cs b/MediaBrowser.Model/QuickConnect/QuickConnectResult.cs index d180d2986..35a82f47c 100644 --- a/MediaBrowser.Model/QuickConnect/QuickConnectResult.cs +++ b/MediaBrowser.Model/QuickConnect/QuickConnectResult.cs @@ -13,17 +13,32 @@ namespace MediaBrowser.Model.QuickConnect /// <param name="secret">The secret used to query the request state.</param> /// <param name="code">The code used to allow the request.</param> /// <param name="dateAdded">The time when the request was created.</param> - public QuickConnectResult(string secret, string code, DateTime dateAdded) + /// <param name="deviceId">The requesting device id.</param> + /// <param name="deviceName">The requesting device name.</param> + /// <param name="appName">The requesting app name.</param> + /// <param name="appVersion">The requesting app version.</param> + public QuickConnectResult( + string secret, + string code, + DateTime dateAdded, + string deviceId, + string deviceName, + string appName, + string appVersion) { Secret = secret; Code = code; DateAdded = dateAdded; + DeviceId = deviceId; + DeviceName = deviceName; + AppName = appName; + AppVersion = appVersion; } /// <summary> - /// Gets a value indicating whether this request is authorized. + /// Gets or sets a value indicating whether this request is authorized. /// </summary> - public bool Authenticated => Authentication != null; + public bool Authenticated { get; set; } /// <summary> /// Gets the secret value used to uniquely identify this request. Can be used to retrieve authentication information. @@ -36,9 +51,24 @@ namespace MediaBrowser.Model.QuickConnect public string Code { get; } /// <summary> - /// Gets or sets the private access token. + /// Gets the requesting device id. /// </summary> - public Guid? Authentication { get; set; } + public string DeviceId { get; } + + /// <summary> + /// Gets the requesting device name. + /// </summary> + public string DeviceName { get; } + + /// <summary> + /// Gets the requesting app name. + /// </summary> + public string AppName { get; } + + /// <summary> + /// Gets the requesting app version. + /// </summary> + public string AppVersion { get; } /// <summary> /// Gets or sets the DateTime that this request was created. diff --git a/MediaBrowser.Model/SyncPlay/PlayQueueUpdate.cs b/MediaBrowser.Model/SyncPlay/PlayQueueUpdate.cs index a851229f7..cce99c77d 100644 --- a/MediaBrowser.Model/SyncPlay/PlayQueueUpdate.cs +++ b/MediaBrowser.Model/SyncPlay/PlayQueueUpdate.cs @@ -16,15 +16,17 @@ namespace MediaBrowser.Model.SyncPlay /// <param name="playlist">The playlist.</param> /// <param name="playingItemIndex">The playing item index in the playlist.</param> /// <param name="startPositionTicks">The start position ticks.</param> + /// <param name="isPlaying">The playing item status.</param> /// <param name="shuffleMode">The shuffle mode.</param> /// <param name="repeatMode">The repeat mode.</param> - public PlayQueueUpdate(PlayQueueUpdateReason reason, DateTime lastUpdate, IReadOnlyList<QueueItem> playlist, int playingItemIndex, long startPositionTicks, GroupShuffleMode shuffleMode, GroupRepeatMode repeatMode) + public PlayQueueUpdate(PlayQueueUpdateReason reason, DateTime lastUpdate, IReadOnlyList<QueueItem> playlist, int playingItemIndex, long startPositionTicks, bool isPlaying, GroupShuffleMode shuffleMode, GroupRepeatMode repeatMode) { Reason = reason; LastUpdate = lastUpdate; Playlist = playlist; PlayingItemIndex = playingItemIndex; StartPositionTicks = startPositionTicks; + IsPlaying = isPlaying; ShuffleMode = shuffleMode; RepeatMode = repeatMode; } @@ -60,6 +62,12 @@ namespace MediaBrowser.Model.SyncPlay public long StartPositionTicks { get; } /// <summary> + /// Gets a value indicating whether the current item is playing. + /// </summary> + /// <value>The playing item status.</value> + public bool IsPlaying { get; } + + /// <summary> /// Gets the shuffle mode. /// </summary> /// <value>The shuffle mode.</value> diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs index e45b2f33a..a82c1c8c0 100644 --- a/MediaBrowser.Model/System/SystemInfo.cs +++ b/MediaBrowser.Model/System/SystemInfo.cs @@ -133,6 +133,7 @@ namespace MediaBrowser.Model.System [Obsolete("This should be handled by the package manager")] public bool HasUpdateAvailable { get; set; } + [Obsolete("This isn't set correctly anymore")] public FFmpegLocation EncoderLocation { get; set; } public Architecture SystemArchitecture { get; set; } diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs index 111070d81..3634d0705 100644 --- a/MediaBrowser.Model/Users/UserPolicy.cs +++ b/MediaBrowser.Model/Users/UserPolicy.cs @@ -1,5 +1,5 @@ #nullable disable -#pragma warning disable CS1591 +#pragma warning disable CS1591, CA1819 using System; using System.Xml.Serialization; |
