mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-03-24 19:16:32 +00:00
Merge remote-tracking branch 'upstream/master' into fonts
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Data.Entities;
|
||||
using MediaBrowser.Model.Events;
|
||||
using Jellyfin.Data.Events;
|
||||
using Jellyfin.Data.Queries;
|
||||
using MediaBrowser.Model.Querying;
|
||||
|
||||
namespace MediaBrowser.Model.Activity
|
||||
@@ -13,15 +13,15 @@ namespace MediaBrowser.Model.Activity
|
||||
{
|
||||
event EventHandler<GenericEventArgs<ActivityLogEntry>> EntryCreated;
|
||||
|
||||
void Create(ActivityLog entry);
|
||||
|
||||
Task CreateAsync(ActivityLog entry);
|
||||
|
||||
QueryResult<ActivityLogEntry> GetPagedResult(int? startIndex, int? limit);
|
||||
Task<QueryResult<ActivityLogEntry>> GetPagedResultAsync(ActivityLogQuery query);
|
||||
|
||||
QueryResult<ActivityLogEntry> GetPagedResult(
|
||||
Func<IQueryable<ActivityLog>, IQueryable<ActivityLog>> func,
|
||||
int? startIndex,
|
||||
int? limit);
|
||||
/// <summary>
|
||||
/// Remove all activity logs before the specified date.
|
||||
/// </summary>
|
||||
/// <param name="startDate">Activity log start date.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
Task CleanAsync(DateTime startDate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ namespace MediaBrowser.Model.Configuration
|
||||
|
||||
public double DownMixAudioBoost { get; set; }
|
||||
|
||||
public int MaxMuxingQueueSize { get; set; }
|
||||
|
||||
public bool EnableThrottling { get; set; }
|
||||
|
||||
public int ThrottleDelaySeconds { get; set; }
|
||||
@@ -33,12 +35,30 @@ namespace MediaBrowser.Model.Configuration
|
||||
|
||||
public string VaapiDevice { get; set; }
|
||||
|
||||
public string OpenclDevice { get; set; }
|
||||
|
||||
public bool EnableTonemapping { get; set; }
|
||||
|
||||
public string TonemappingAlgorithm { get; set; }
|
||||
|
||||
public string TonemappingRange { get; set; }
|
||||
|
||||
public double TonemappingDesat { get; set; }
|
||||
|
||||
public double TonemappingThreshold { get; set; }
|
||||
|
||||
public double TonemappingPeak { get; set; }
|
||||
|
||||
public double TonemappingParam { get; set; }
|
||||
|
||||
public int H264Crf { get; set; }
|
||||
|
||||
public int H265Crf { get; set; }
|
||||
|
||||
public string EncoderPreset { get; set; }
|
||||
|
||||
public bool DeinterlaceDoubleRate { get; set; }
|
||||
|
||||
public string DeinterlaceMethod { get; set; }
|
||||
|
||||
public bool EnableDecodingColorDepth10Hevc { get; set; }
|
||||
@@ -55,13 +75,26 @@ namespace MediaBrowser.Model.Configuration
|
||||
{
|
||||
EnableFallbackFont = false;
|
||||
DownMixAudioBoost = 2;
|
||||
MaxMuxingQueueSize = 2048;
|
||||
EnableThrottling = false;
|
||||
ThrottleDelaySeconds = 180;
|
||||
EncodingThreadCount = -1;
|
||||
// This is a DRM device that is almost guaranteed to be there on every intel platform, plus it's the default one in ffmpeg if you don't specify anything
|
||||
// This is a DRM device that is almost guaranteed to be there on every intel platform,
|
||||
// plus it's the default one in ffmpeg if you don't specify anything
|
||||
VaapiDevice = "/dev/dri/renderD128";
|
||||
// This is the OpenCL device that is used for tonemapping.
|
||||
// The left side of the dot is the platform number, and the right side is the device number on the platform.
|
||||
OpenclDevice = "0.0";
|
||||
EnableTonemapping = false;
|
||||
TonemappingAlgorithm = "reinhard";
|
||||
TonemappingRange = "auto";
|
||||
TonemappingDesat = 0;
|
||||
TonemappingThreshold = 0.8;
|
||||
TonemappingPeak = 0;
|
||||
TonemappingParam = 0;
|
||||
H264Crf = 23;
|
||||
H265Crf = 28;
|
||||
DeinterlaceDoubleRate = false;
|
||||
DeinterlaceMethod = "yadif";
|
||||
EnableDecodingColorDepth10Hevc = true;
|
||||
EnableDecodingColorDepth10Vp9 = true;
|
||||
|
||||
@@ -25,8 +25,6 @@ namespace MediaBrowser.Model.Configuration
|
||||
|
||||
public bool EnableInternetProviders { get; set; }
|
||||
|
||||
public bool ImportMissingEpisodes { get; set; }
|
||||
|
||||
public bool EnableAutomaticSeriesGrouping { get; set; }
|
||||
|
||||
public bool EnableEmbeddedTitles { get; set; }
|
||||
|
||||
@@ -78,7 +78,10 @@ namespace MediaBrowser.Model.Configuration
|
||||
/// <value><c>true</c> if this instance is port authorized; otherwise, <c>false</c>.</value>
|
||||
public bool IsPortAuthorized { get; set; }
|
||||
|
||||
public bool AutoRunWebApp { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets if quick connect is available for use on this server.
|
||||
/// </summary>
|
||||
public bool QuickConnectAvailable { get; set; }
|
||||
|
||||
public bool EnableRemoteAccess { get; set; }
|
||||
|
||||
@@ -161,12 +164,6 @@ namespace MediaBrowser.Model.Configuration
|
||||
/// <value><c>true</c> if [enable dashboard response caching]; otherwise, <c>false</c>.</value>
|
||||
public bool EnableDashboardResponseCaching { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a custom path to serve the dashboard from.
|
||||
/// </summary>
|
||||
/// <value>The dashboard source path, or null if the default path should be used.</value>
|
||||
public string DashboardSourcePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the image saving convention.
|
||||
/// </summary>
|
||||
@@ -264,6 +261,21 @@ namespace MediaBrowser.Model.Configuration
|
||||
/// </summary>
|
||||
public long SlowResponseThresholdMs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the cors hosts.
|
||||
/// </summary>
|
||||
public string[] CorsHosts { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the known proxies.
|
||||
/// </summary>
|
||||
public string[] KnownProxies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the number of days we should retain activity logs.
|
||||
/// </summary>
|
||||
public int? ActivityLogRetentionDays { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ServerConfiguration" /> class.
|
||||
/// </summary>
|
||||
@@ -297,8 +309,8 @@ namespace MediaBrowser.Model.Configuration
|
||||
DisableLiveTvChannelUserDataName = true;
|
||||
EnableNewOmdbSupport = true;
|
||||
|
||||
AutoRunWebApp = true;
|
||||
EnableRemoteAccess = true;
|
||||
QuickConnectAvailable = false;
|
||||
|
||||
EnableUPnP = false;
|
||||
MinResumePct = 5;
|
||||
@@ -372,6 +384,9 @@ namespace MediaBrowser.Model.Configuration
|
||||
|
||||
EnableSlowResponseWarning = true;
|
||||
SlowResponseThresholdMs = 500;
|
||||
CorsHosts = new[] { "*" };
|
||||
KnownProxies = Array.Empty<string>();
|
||||
ActivityLogRetentionDays = 30;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
/// <summary>
|
||||
/// The application's configured quality setting.
|
||||
/// </summary>
|
||||
public long? MaxBitrate { get; set; }
|
||||
public int? MaxBitrate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the context.
|
||||
@@ -67,7 +67,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
/// Gets the maximum bitrate.
|
||||
/// </summary>
|
||||
/// <returns>System.Nullable<System.Int32>.</returns>
|
||||
public long? GetMaxBitrate(bool isAudio)
|
||||
public int? GetMaxBitrate(bool isAudio)
|
||||
{
|
||||
if (MaxBitrate.HasValue)
|
||||
{
|
||||
|
||||
@@ -38,7 +38,8 @@ namespace MediaBrowser.Model.Dlna
|
||||
";DLNA.ORG_FLAGS={0}",
|
||||
DlnaMaps.FlagsToString(flagValue));
|
||||
|
||||
ResponseProfile mediaProfile = _profile.GetImageMediaProfile(container,
|
||||
ResponseProfile mediaProfile = _profile.GetImageMediaProfile(
|
||||
container,
|
||||
width,
|
||||
height);
|
||||
|
||||
@@ -157,10 +158,11 @@ namespace MediaBrowser.Model.Dlna
|
||||
// flagValue = flagValue | DlnaFlags.TimeBasedSeek;
|
||||
//}
|
||||
|
||||
string dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}",
|
||||
string dlnaflags = string.Format(CultureInfo.InvariantCulture, ";DLNA.ORG_FLAGS={0}",
|
||||
DlnaMaps.FlagsToString(flagValue));
|
||||
|
||||
ResponseProfile mediaProfile = _profile.GetVideoMediaProfile(container,
|
||||
ResponseProfile mediaProfile = _profile.GetVideoMediaProfile(
|
||||
container,
|
||||
audioCodec,
|
||||
videoCodec,
|
||||
width,
|
||||
@@ -221,7 +223,8 @@ namespace MediaBrowser.Model.Dlna
|
||||
private static string GetImageOrgPnValue(string container, int? width, int? height)
|
||||
{
|
||||
MediaFormatProfile? format = new MediaFormatProfileResolver()
|
||||
.ResolveImageFormat(container,
|
||||
.ResolveImageFormat(
|
||||
container,
|
||||
width,
|
||||
height);
|
||||
|
||||
@@ -231,7 +234,8 @@ namespace MediaBrowser.Model.Dlna
|
||||
private static string GetAudioOrgPnValue(string container, int? audioBitrate, int? audioSampleRate, int? audioChannels)
|
||||
{
|
||||
MediaFormatProfile? format = new MediaFormatProfileResolver()
|
||||
.ResolveAudioFormat(container,
|
||||
.ResolveAudioFormat(
|
||||
container,
|
||||
audioBitrate,
|
||||
audioSampleRate,
|
||||
audioChannels);
|
||||
|
||||
@@ -37,12 +37,6 @@ namespace MediaBrowser.Model.Dlna
|
||||
/// <value>The model description.</value>
|
||||
public string ModelDescription { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the device description.
|
||||
/// </summary>
|
||||
/// <value>The device description.</value>
|
||||
public string DeviceDescription { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the model URL.
|
||||
/// </summary>
|
||||
|
||||
@@ -62,9 +62,9 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
public int? MaxIconHeight { get; set; }
|
||||
|
||||
public long? MaxStreamingBitrate { get; set; }
|
||||
public int? MaxStreamingBitrate { get; set; }
|
||||
|
||||
public long? MaxStaticBitrate { get; set; }
|
||||
public int? MaxStaticBitrate { get; set; }
|
||||
|
||||
public int? MusicStreamingTranscodingBitrate { get; set; }
|
||||
|
||||
@@ -277,7 +277,8 @@ namespace MediaBrowser.Model.Dlna
|
||||
return null;
|
||||
}
|
||||
|
||||
public ResponseProfile GetVideoMediaProfile(string container,
|
||||
public ResponseProfile GetVideoMediaProfile(
|
||||
string container,
|
||||
string audioCodec,
|
||||
string videoCodec,
|
||||
int? width,
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Globalization;
|
||||
|
||||
namespace MediaBrowser.Model.Dlna
|
||||
{
|
||||
public static class DlnaMaps
|
||||
{
|
||||
private static readonly string DefaultStreaming =
|
||||
FlagsToString(DlnaFlags.StreamingTransferMode |
|
||||
FlagsToString(DlnaFlags.StreamingTransferMode |
|
||||
DlnaFlags.BackgroundTransferMode |
|
||||
DlnaFlags.ConnectionStall |
|
||||
DlnaFlags.ByteBasedSeek |
|
||||
DlnaFlags.DlnaV15);
|
||||
|
||||
private static readonly string DefaultInteractive =
|
||||
FlagsToString(DlnaFlags.InteractiveTransferMode |
|
||||
FlagsToString(DlnaFlags.InteractiveTransferMode |
|
||||
DlnaFlags.BackgroundTransferMode |
|
||||
DlnaFlags.ConnectionStall |
|
||||
DlnaFlags.ByteBasedSeek |
|
||||
@@ -20,7 +22,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
public static string FlagsToString(DlnaFlags flags)
|
||||
{
|
||||
return string.Format("{0:X8}{1:D24}", (ulong)flags, 0);
|
||||
return string.Format(CultureInfo.InvariantCulture, "{0:X8}{1:D24}", (ulong)flags, 0);
|
||||
}
|
||||
|
||||
public static string GetOrgOpValue(bool hasKnownRuntime, bool isDirectStream, TranscodeSeekInfo profileTranscodeSeekInfo)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using MediaBrowser.Model.Events;
|
||||
using Jellyfin.Data.Events;
|
||||
|
||||
namespace MediaBrowser.Model.Dlna
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Model.MediaInfo;
|
||||
|
||||
@@ -142,26 +143,26 @@ namespace MediaBrowser.Model.Dlna
|
||||
{
|
||||
if (timestampType == TransportStreamTimestamp.None)
|
||||
{
|
||||
return new MediaFormatProfile[] { ValueOf(string.Format("AVC_TS_HP_{0}D_MPEG1_L2_ISO", resolution)) };
|
||||
return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "AVC_TS_HP_{0}D_MPEG1_L2_ISO", resolution)) };
|
||||
}
|
||||
|
||||
return new MediaFormatProfile[] { ValueOf(string.Format("AVC_TS_HP_{0}D_MPEG1_L2_T", resolution)) };
|
||||
return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "AVC_TS_HP_{0}D_MPEG1_L2_T", resolution)) };
|
||||
}
|
||||
|
||||
if (string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new MediaFormatProfile[] { ValueOf(string.Format("AVC_TS_MP_{0}D_AAC_MULT5{1}", resolution, suffix)) };
|
||||
return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "AVC_TS_MP_{0}D_AAC_MULT5{1}", resolution, suffix)) };
|
||||
}
|
||||
|
||||
if (string.Equals(audioCodec, "mp3", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new MediaFormatProfile[] { ValueOf(string.Format("AVC_TS_MP_{0}D_MPEG1_L3{1}", resolution, suffix)) };
|
||||
return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "AVC_TS_MP_{0}D_MPEG1_L3{1}", resolution, suffix)) };
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(audioCodec) ||
|
||||
string.Equals(audioCodec, "ac3", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new MediaFormatProfile[] { ValueOf(string.Format("AVC_TS_MP_{0}D_AC3{1}", resolution, suffix)) };
|
||||
return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "AVC_TS_MP_{0}D_AC3{1}", resolution, suffix)) };
|
||||
}
|
||||
}
|
||||
else if (string.Equals(videoCodec, "vc1", StringComparison.OrdinalIgnoreCase))
|
||||
@@ -180,29 +181,29 @@ namespace MediaBrowser.Model.Dlna
|
||||
{
|
||||
suffix = string.Equals(suffix, "_ISO", StringComparison.OrdinalIgnoreCase) ? suffix : "_T";
|
||||
|
||||
return new MediaFormatProfile[] { ValueOf(string.Format("VC1_TS_HD_DTS{0}", suffix)) };
|
||||
return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "VC1_TS_HD_DTS{0}", suffix)) };
|
||||
}
|
||||
}
|
||||
else if (string.Equals(videoCodec, "mpeg4", StringComparison.OrdinalIgnoreCase) || string.Equals(videoCodec, "msmpeg4", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new MediaFormatProfile[] { ValueOf(string.Format("MPEG4_P2_TS_ASP_AAC{0}", suffix)) };
|
||||
return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "MPEG4_P2_TS_ASP_AAC{0}", suffix)) };
|
||||
}
|
||||
|
||||
if (string.Equals(audioCodec, "mp3", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new MediaFormatProfile[] { ValueOf(string.Format("MPEG4_P2_TS_ASP_MPEG1_L3{0}", suffix)) };
|
||||
return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "MPEG4_P2_TS_ASP_MPEG1_L3{0}", suffix)) };
|
||||
}
|
||||
|
||||
if (string.Equals(audioCodec, "mp2", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new MediaFormatProfile[] { ValueOf(string.Format("MPEG4_P2_TS_ASP_MPEG2_L2{0}", suffix)) };
|
||||
return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "MPEG4_P2_TS_ASP_MPEG2_L2{0}", suffix)) };
|
||||
}
|
||||
|
||||
if (string.Equals(audioCodec, "ac3", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new MediaFormatProfile[] { ValueOf(string.Format("MPEG4_P2_TS_ASP_AC3{0}", suffix)) };
|
||||
return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "MPEG4_P2_TS_ASP_AC3{0}", suffix)) };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
new ResolutionConfiguration(720, 950000),
|
||||
new ResolutionConfiguration(1280, 2500000),
|
||||
new ResolutionConfiguration(1920, 4000000),
|
||||
new ResolutionConfiguration(2560, 8000000),
|
||||
new ResolutionConfiguration(3840, 35000000)
|
||||
};
|
||||
|
||||
|
||||
@@ -455,9 +455,11 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
if (directPlayProfile == null)
|
||||
{
|
||||
_logger.LogInformation("Profile: {0}, No direct play profiles found for Path: {1}",
|
||||
_logger.LogInformation(
|
||||
"Profile: {0}, No audio direct play profiles found for {1} with codec {2}",
|
||||
options.Profile.Name ?? "Unknown Profile",
|
||||
item.Path ?? "Unknown path");
|
||||
item.Path ?? "Unknown path",
|
||||
audioStream.Codec ?? "Unknown codec");
|
||||
|
||||
return (Enumerable.Empty<PlayMethod>(), GetTranscodeReasonsFromDirectPlayProfile(item, null, audioStream, options.Profile.DirectPlayProfiles));
|
||||
}
|
||||
@@ -498,7 +500,6 @@ namespace MediaBrowser.Model.Dlna
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (playMethods.Count > 0)
|
||||
{
|
||||
transcodeReasons.Clear();
|
||||
@@ -679,7 +680,8 @@ namespace MediaBrowser.Model.Dlna
|
||||
bool isEligibleForDirectPlay = options.EnableDirectPlay && (options.ForceDirectPlay || directPlayEligibilityResult.Item1);
|
||||
bool isEligibleForDirectStream = options.EnableDirectStream && (options.ForceDirectStream || directStreamEligibilityResult.Item1);
|
||||
|
||||
_logger.LogInformation("Profile: {0}, Path: {1}, isEligibleForDirectPlay: {2}, isEligibleForDirectStream: {3}",
|
||||
_logger.LogInformation(
|
||||
"Profile: {0}, Path: {1}, isEligibleForDirectPlay: {2}, isEligibleForDirectStream: {3}",
|
||||
options.Profile.Name ?? "Unknown Profile",
|
||||
item.Path ?? "Unknown path",
|
||||
isEligibleForDirectPlay,
|
||||
@@ -973,9 +975,11 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
if (directPlay == null)
|
||||
{
|
||||
_logger.LogInformation("Profile: {0}, No direct play profiles found for Path: {1}",
|
||||
_logger.LogInformation(
|
||||
"Profile: {0}, No video direct play profiles found for {1} with codec {2}",
|
||||
profile.Name ?? "Unknown Profile",
|
||||
mediaSource.Path ?? "Unknown path");
|
||||
mediaSource.Path ?? "Unknown path",
|
||||
videoStream.Codec ?? "Unknown codec");
|
||||
|
||||
return (null, GetTranscodeReasonsFromDirectPlayProfile(mediaSource, videoStream, audioStream, profile.DirectPlayProfiles));
|
||||
}
|
||||
@@ -1136,7 +1140,8 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
private void LogConditionFailure(DeviceProfile profile, string type, ProfileCondition condition, MediaSourceInfo mediaSource)
|
||||
{
|
||||
_logger.LogInformation("Profile: {0}, DirectPlay=false. Reason={1}.{2} Condition: {3}. ConditionValue: {4}. IsRequired: {5}. Path: {6}",
|
||||
_logger.LogInformation(
|
||||
"Profile: {0}, DirectPlay=false. Reason={1}.{2} Condition: {3}. ConditionValue: {4}. IsRequired: {5}. Path: {6}",
|
||||
type,
|
||||
profile.Name ?? "Unknown Profile",
|
||||
condition.Property,
|
||||
@@ -1341,7 +1346,8 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
if (itemBitrate > requestedMaxBitrate)
|
||||
{
|
||||
_logger.LogInformation("Bitrate exceeds {PlayBackMethod} limit: media bitrate: {MediaBitrate}, max bitrate: {MaxBitrate}",
|
||||
_logger.LogInformation(
|
||||
"Bitrate exceeds {PlayBackMethod} limit: media bitrate: {MediaBitrate}, max bitrate: {MaxBitrate}",
|
||||
playMethod, itemBitrate, requestedMaxBitrate);
|
||||
return false;
|
||||
}
|
||||
@@ -1431,6 +1437,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ProfileConditionValue.AudioChannels:
|
||||
{
|
||||
if (string.IsNullOrEmpty(qualifier))
|
||||
@@ -1466,6 +1473,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ProfileConditionValue.IsAvc:
|
||||
{
|
||||
if (!enableNonQualifiedConditions)
|
||||
@@ -1487,6 +1495,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ProfileConditionValue.IsAnamorphic:
|
||||
{
|
||||
if (!enableNonQualifiedConditions)
|
||||
@@ -1508,6 +1517,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ProfileConditionValue.IsInterlaced:
|
||||
{
|
||||
if (string.IsNullOrEmpty(qualifier))
|
||||
@@ -1539,6 +1549,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ProfileConditionValue.AudioProfile:
|
||||
case ProfileConditionValue.Has64BitOffsets:
|
||||
case ProfileConditionValue.PacketLength:
|
||||
@@ -1550,6 +1561,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
// Not supported yet
|
||||
break;
|
||||
}
|
||||
|
||||
case ProfileConditionValue.RefFrames:
|
||||
{
|
||||
if (string.IsNullOrEmpty(qualifier))
|
||||
@@ -1585,6 +1597,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ProfileConditionValue.VideoBitDepth:
|
||||
{
|
||||
if (string.IsNullOrEmpty(qualifier))
|
||||
@@ -1620,6 +1633,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ProfileConditionValue.VideoProfile:
|
||||
{
|
||||
if (string.IsNullOrEmpty(qualifier))
|
||||
@@ -1643,6 +1657,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ProfileConditionValue.Height:
|
||||
{
|
||||
if (!enableNonQualifiedConditions)
|
||||
@@ -1668,6 +1683,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ProfileConditionValue.VideoBitrate:
|
||||
{
|
||||
if (!enableNonQualifiedConditions)
|
||||
@@ -1693,6 +1709,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ProfileConditionValue.VideoFramerate:
|
||||
{
|
||||
if (!enableNonQualifiedConditions)
|
||||
@@ -1718,6 +1735,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ProfileConditionValue.VideoLevel:
|
||||
{
|
||||
if (string.IsNullOrEmpty(qualifier))
|
||||
@@ -1743,6 +1761,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ProfileConditionValue.Width:
|
||||
{
|
||||
if (!enableNonQualifiedConditions)
|
||||
|
||||
@@ -191,7 +191,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
var encodedValue = pair.Value.Replace(" ", "%20");
|
||||
|
||||
list.Add(string.Format("{0}={1}", pair.Name, encodedValue));
|
||||
list.Add(string.Format(CultureInfo.InvariantCulture, "{0}={1}", pair.Name, encodedValue));
|
||||
}
|
||||
|
||||
string queryString = string.Join("&", list.ToArray());
|
||||
@@ -214,18 +214,18 @@ namespace MediaBrowser.Model.Dlna
|
||||
{
|
||||
if (string.Equals(SubProtocol, "hls", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return string.Format("{0}/audio/{1}/master.m3u8?{2}", baseUrl, ItemId, queryString);
|
||||
return string.Format(CultureInfo.InvariantCulture, "{0}/audio/{1}/master.m3u8?{2}", baseUrl, ItemId, queryString);
|
||||
}
|
||||
|
||||
return string.Format("{0}/audio/{1}/stream{2}?{3}", baseUrl, ItemId, extension, queryString);
|
||||
return string.Format(CultureInfo.InvariantCulture, "{0}/audio/{1}/stream{2}?{3}", baseUrl, ItemId, extension, queryString);
|
||||
}
|
||||
|
||||
if (string.Equals(SubProtocol, "hls", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return string.Format("{0}/videos/{1}/master.m3u8?{2}", baseUrl, ItemId, queryString);
|
||||
return string.Format(CultureInfo.InvariantCulture, "{0}/videos/{1}/master.m3u8?{2}", baseUrl, ItemId, queryString);
|
||||
}
|
||||
|
||||
return string.Format("{0}/videos/{1}/stream{2}?{3}", baseUrl, ItemId, extension, queryString);
|
||||
return string.Format(CultureInfo.InvariantCulture, "{0}/videos/{1}/stream{2}?{3}", baseUrl, ItemId, extension, queryString);
|
||||
}
|
||||
|
||||
private static List<NameValuePair> BuildParams(StreamInfo item, string accessToken)
|
||||
@@ -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)
|
||||
@@ -457,7 +456,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
{
|
||||
if (MediaSource.Protocol == MediaProtocol.File || !string.Equals(stream.Codec, subtitleProfile.Format, StringComparison.OrdinalIgnoreCase) || !stream.IsExternal)
|
||||
{
|
||||
info.Url = string.Format("{0}/Videos/{1}/{2}/Subtitles/{3}/{4}/Stream.{5}",
|
||||
info.Url = string.Format(CultureInfo.InvariantCulture, "{0}/Videos/{1}/{2}/Subtitles/{3}/{4}/Stream.{5}",
|
||||
baseUrl,
|
||||
ItemId,
|
||||
MediaSourceId,
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -35,6 +35,18 @@ namespace MediaBrowser.Model.Entities
|
||||
/// <value>The language.</value>
|
||||
public string Language { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color range.
|
||||
/// </summary>
|
||||
/// <value>The color range.</value>
|
||||
public string ColorRange { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color space.
|
||||
/// </summary>
|
||||
/// <value>The color space.</value>
|
||||
public string ColorSpace { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color transfer.
|
||||
/// </summary>
|
||||
@@ -47,12 +59,6 @@ namespace MediaBrowser.Model.Entities
|
||||
/// <value>The color primaries.</value>
|
||||
public string ColorPrimaries { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color space.
|
||||
/// </summary>
|
||||
/// <value>The color space.</value>
|
||||
public string ColorSpace { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the comment.
|
||||
/// </summary>
|
||||
@@ -445,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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Model.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a generic EventArgs subclass that can hold any kind of object.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class GenericEventArgs<T> : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the argument.
|
||||
/// </summary>
|
||||
/// <value>The argument.</value>
|
||||
public T Argument { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GenericEventArgs{T}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="arg">The argument.</param>
|
||||
public GenericEventArgs(T arg)
|
||||
{
|
||||
Argument = arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
46
MediaBrowser.Model/Extensions/EnumerableExtensions.cs
Normal file
46
MediaBrowser.Model/Extensions/EnumerableExtensions.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Model.Providers;
|
||||
|
||||
namespace MediaBrowser.Model.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for <see cref="IEnumerable{T}"/>.
|
||||
/// </summary>
|
||||
public static class EnumerableExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Orders <see cref="RemoteImageInfo"/> by requested language in descending order, prioritizing "en" over other non-matches.
|
||||
/// </summary>
|
||||
/// <param name="remoteImageInfos">The remote image infos.</param>
|
||||
/// <param name="requestedLanguage">The requested language for the images.</param>
|
||||
/// <returns>The ordered remote image infos.</returns>
|
||||
public static IEnumerable<RemoteImageInfo> OrderByLanguageDescending(this IEnumerable<RemoteImageInfo> remoteImageInfos, string requestedLanguage)
|
||||
{
|
||||
var isRequestedLanguageEn = string.Equals(requestedLanguage, "en", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
return remoteImageInfos.OrderByDescending(i =>
|
||||
{
|
||||
if (string.Equals(requestedLanguage, i.Language, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (!isRequestedLanguageEn && string.Equals("en", i.Language, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(i.Language))
|
||||
{
|
||||
return isRequestedLanguageEn ? 3 : 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
})
|
||||
.ThenByDescending(i => i.CommunityRating ?? 0)
|
||||
.ThenByDescending(i => i.VoteCount ?? 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@ namespace MediaBrowser.Model.IO
|
||||
public DateTime CreationTimeUtc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is directory.
|
||||
/// Gets or sets a value indicating whether this instance is directory.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is directory; otherwise, <c>false</c>.</value>
|
||||
public bool IsDirectory { get; set; }
|
||||
|
||||
@@ -201,9 +201,9 @@ namespace MediaBrowser.Model.IO
|
||||
IEnumerable<string> GetFileSystemEntryPaths(string path, bool recursive = false);
|
||||
|
||||
void SetHidden(string path, bool isHidden);
|
||||
void SetReadOnly(string path, bool readOnly);
|
||||
|
||||
void SetAttributes(string path, bool isHidden, bool readOnly);
|
||||
|
||||
List<FileSystemMetadata> GetDrives();
|
||||
void SetExecutable(string path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ namespace MediaBrowser.Model.IO
|
||||
/// </summary>
|
||||
/// <param name="shortcutPath">The shortcut path.</param>
|
||||
/// <param name="targetPath">The target path.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
void Create(string shortcutPath, string targetPath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,6 @@ namespace MediaBrowser.Model.IO
|
||||
|
||||
Task CopyToAsync(Stream source, Stream destination, int bufferSize, int emptyReadLimit, CancellationToken cancellationToken);
|
||||
|
||||
Task<int> CopyToAsync(Stream source, Stream destination, CancellationToken cancellationToken);
|
||||
|
||||
Task CopyToAsync(Stream source, Stream destination, long copyLength, CancellationToken cancellationToken);
|
||||
|
||||
Task CopyUntilCancelled(Stream source, Stream target, int bufferSize, CancellationToken cancellationToken);
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace MediaBrowser.Model.IO
|
||||
void ExtractAll(Stream source, string targetPath, bool overwriteExistingFiles);
|
||||
|
||||
void ExtractAllFromGz(Stream source, string targetPath, bool overwriteExistingFiles);
|
||||
|
||||
void ExtractFirstFileFromGz(Stream source, string targetPath, string defaultFileName);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
<PropertyGroup>
|
||||
<Authors>Jellyfin Contributors</Authors>
|
||||
<PackageId>Jellyfin.Model</PackageId>
|
||||
<PackageLicenseUrl>https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt</PackageLicenseUrl>
|
||||
<VersionPrefix>10.7.0</VersionPrefix>
|
||||
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
@@ -19,13 +20,23 @@
|
||||
<TreatWarningsAsErrors Condition=" '$(Configuration)' == 'Release' ">true</TreatWarningsAsErrors>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Stability)'=='Unstable'">
|
||||
<!-- Include all symbols in the main nupkg until Azure Artifact Feed starts supporting ingesting NuGet symbol packages. -->
|
||||
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="3.1.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="3.1.9" />
|
||||
<PackageReference Include="System.Globalization" Version="4.3.0" />
|
||||
<PackageReference Include="System.Text.Json" Version="4.7.2" />
|
||||
<PackageReference Include="System.Text.Json" Version="5.0.0-preview.8.20407.11" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace MediaBrowser.Model.MediaInfo
|
||||
|
||||
public string PlaySessionId { get; set; }
|
||||
|
||||
public long? MaxStreamingBitrate { get; set; }
|
||||
public int? MaxStreamingBitrate { get; set; }
|
||||
|
||||
public long? StartTimeTicks { get; set; }
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ namespace MediaBrowser.Model.Net
|
||||
{ ".wmv", "video/x-ms-wmv" },
|
||||
|
||||
// Type audio
|
||||
{ ".aac", "audio/mp4" },
|
||||
{ ".aac", "audio/aac" },
|
||||
{ ".ac3", "audio/ac3" },
|
||||
{ ".ape", "audio/x-ape" },
|
||||
{ ".dsf", "audio/dsf" },
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using MediaBrowser.Model.Session;
|
||||
|
||||
namespace MediaBrowser.Model.Net
|
||||
{
|
||||
@@ -15,7 +16,7 @@ namespace MediaBrowser.Model.Net
|
||||
/// Gets or sets the type of the message.
|
||||
/// </summary>
|
||||
/// <value>The type of the message.</value>
|
||||
public string MessageType { get; set; }
|
||||
public SessionMessageType MessageType { get; set; }
|
||||
|
||||
public Guid MessageId { get; set; }
|
||||
|
||||
|
||||
@@ -68,5 +68,4 @@ namespace MediaBrowser.Model.Providers
|
||||
/// <value>The type of the rating.</value>
|
||||
public RatingType RatingType { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -50,6 +50,5 @@ namespace MediaBrowser.Model.Providers
|
||||
public RemoteSearchResult AlbumArtist { get; set; }
|
||||
|
||||
public RemoteSearchResult[] Artists { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,6 +168,7 @@ namespace MediaBrowser.Model.Querying
|
||||
Studios,
|
||||
|
||||
BasicSyncInfo,
|
||||
|
||||
/// <summary>
|
||||
/// The synchronize information.
|
||||
/// </summary>
|
||||
|
||||
@@ -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>
|
||||
|
||||
40
MediaBrowser.Model/QuickConnect/QuickConnectResult.cs
Normal file
40
MediaBrowser.Model/QuickConnect/QuickConnectResult.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Model.QuickConnect
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores the result of an incoming quick connect request.
|
||||
/// </summary>
|
||||
public class QuickConnectResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this request is authorized.
|
||||
/// </summary>
|
||||
public bool Authenticated => !string.IsNullOrEmpty(Authentication);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the secret value used to uniquely identify this request. Can be used to retrieve authentication information.
|
||||
/// </summary>
|
||||
public string? Secret { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the user facing code used so the user can quickly differentiate this request from others.
|
||||
/// </summary>
|
||||
public string? Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the private access token.
|
||||
/// </summary>
|
||||
public string? Authentication { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an error message.
|
||||
/// </summary>
|
||||
public string? Error { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the DateTime that this request was created.
|
||||
/// </summary>
|
||||
public DateTime? DateAdded { get; set; }
|
||||
}
|
||||
}
|
||||
23
MediaBrowser.Model/QuickConnect/QuickConnectState.cs
Normal file
23
MediaBrowser.Model/QuickConnect/QuickConnectState.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
namespace MediaBrowser.Model.QuickConnect
|
||||
{
|
||||
/// <summary>
|
||||
/// Quick connect state.
|
||||
/// </summary>
|
||||
public enum QuickConnectState
|
||||
{
|
||||
/// <summary>
|
||||
/// This feature has not been opted into and is unavailable until the server administrator chooses to opt-in.
|
||||
/// </summary>
|
||||
Unavailable = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The feature is enabled for use on the server but is not currently accepting connection requests.
|
||||
/// </summary>
|
||||
Available = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The feature is actively accepting connection requests.
|
||||
/// </summary>
|
||||
Active = 2
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
#nullable disable
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Model.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Identifies a single API endpoint.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
|
||||
public class ApiMemberAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets verb to which applies attribute. By default applies to all verbs.
|
||||
/// </summary>
|
||||
public string Verb { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets parameter type: It can be only one of the following: path, query, body, form, or header.
|
||||
/// </summary>
|
||||
public string ParameterType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets unique name for the parameter. Each name must be unique, even if they are associated with different paramType values.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Other notes on the name field:
|
||||
/// If paramType is body, the name is used only for UI and codegeneration.
|
||||
/// If paramType is path, the name field must correspond to the associated path segment from the path field in the api object.
|
||||
/// If paramType is query, the name field corresponds to the query param name.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the human-readable description for the parameter.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// For path, query, and header paramTypes, this field must be a primitive. For body, this can be a complex or container datatype.
|
||||
/// </summary>
|
||||
public string DataType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// For path, this is always true. Otherwise, this field tells the client whether or not the field must be supplied.
|
||||
/// </summary>
|
||||
public bool IsRequired { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// For query params, this specifies that a comma-separated list of values can be passed to the API. For path and body types, this field cannot be true.
|
||||
/// </summary>
|
||||
public bool AllowMultiple { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets route to which applies attribute, matches using StartsWith. By default applies to all routes.
|
||||
/// </summary>
|
||||
public string Route { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to exclude this property from being included in the ModelSchema.
|
||||
/// </summary>
|
||||
public bool ExcludeInSchema { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Model.Services
|
||||
{
|
||||
public interface IAsyncStreamWriter
|
||||
{
|
||||
Task WriteToAsync(Stream responseStream, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Model.Services
|
||||
{
|
||||
public interface IHasHeaders
|
||||
{
|
||||
IDictionary<string, string> Headers { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace MediaBrowser.Model.Services
|
||||
{
|
||||
public interface IHasRequestFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the order in which Request Filters are executed.
|
||||
/// <0 Executed before global request filters.
|
||||
/// >0 Executed after global request filters.
|
||||
/// </summary>
|
||||
int Priority { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The request filter is executed before the service.
|
||||
/// </summary>
|
||||
/// <param name="req">The http request wrapper.</param>
|
||||
/// <param name="res">The http response wrapper.</param>
|
||||
/// <param name="requestDto">The request DTO.</param>
|
||||
void RequestFilter(IRequest req, HttpResponse res, object requestDto);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Model.Services
|
||||
{
|
||||
public interface IHttpRequest : IRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the HTTP Verb.
|
||||
/// </summary>
|
||||
string HttpMethod { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the Accept HTTP Request Header.
|
||||
/// </summary>
|
||||
string Accept { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
#nullable disable
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Net;
|
||||
|
||||
namespace MediaBrowser.Model.Services
|
||||
{
|
||||
public interface IHttpResult : IHasHeaders
|
||||
{
|
||||
/// <summary>
|
||||
/// The HTTP Response Status.
|
||||
/// </summary>
|
||||
int Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The HTTP Response Status Code.
|
||||
/// </summary>
|
||||
HttpStatusCode StatusCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The HTTP Response ContentType.
|
||||
/// </summary>
|
||||
string ContentType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Response DTO.
|
||||
/// </summary>
|
||||
object Response { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds the request call context.
|
||||
/// </summary>
|
||||
IRequest RequestContext { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
#nullable disable
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace MediaBrowser.Model.Services
|
||||
{
|
||||
public interface IRequest
|
||||
{
|
||||
HttpResponse Response { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the service being called (e.g. Request DTO Name)
|
||||
/// </summary>
|
||||
string OperationName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Verb / HttpMethod or Action for this request
|
||||
/// </summary>
|
||||
string Verb { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The request ContentType.
|
||||
/// </summary>
|
||||
string ContentType { get; }
|
||||
|
||||
bool IsLocal { get; }
|
||||
|
||||
string UserAgent { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The expected Response ContentType for this request.
|
||||
/// </summary>
|
||||
string ResponseContentType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Attach any data to this request that all filters and services can access.
|
||||
/// </summary>
|
||||
Dictionary<string, object> Items { get; }
|
||||
|
||||
IHeaderDictionary Headers { get; }
|
||||
|
||||
IQueryCollection QueryString { get; }
|
||||
|
||||
string RawUrl { get; }
|
||||
|
||||
string AbsoluteUri { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The Remote Ip as reported by X-Forwarded-For, X-Real-IP or Request.UserHostAddress
|
||||
/// </summary>
|
||||
string RemoteIp { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The value of the Authorization Header used to send the Api Key, null if not available.
|
||||
/// </summary>
|
||||
string Authorization { get; }
|
||||
|
||||
string[] AcceptTypes { get; }
|
||||
|
||||
string PathInfo { get; }
|
||||
|
||||
Stream InputStream { get; }
|
||||
|
||||
long ContentLength { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The value of the Referrer, null if not available.
|
||||
/// </summary>
|
||||
Uri UrlReferrer { get; }
|
||||
}
|
||||
|
||||
public interface IHttpFile
|
||||
{
|
||||
string Name { get; }
|
||||
|
||||
string FileName { get; }
|
||||
|
||||
long ContentLength { get; }
|
||||
|
||||
string ContentType { get; }
|
||||
|
||||
Stream InputStream { get; }
|
||||
}
|
||||
|
||||
public interface IRequiresRequest
|
||||
{
|
||||
IRequest Request { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace MediaBrowser.Model.Services
|
||||
{
|
||||
public interface IRequiresRequestStream
|
||||
{
|
||||
/// <summary>
|
||||
/// The raw Http Request Input Stream.
|
||||
/// </summary>
|
||||
Stream RequestStream { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Model.Services
|
||||
{
|
||||
// marker interface
|
||||
public interface IService
|
||||
{
|
||||
}
|
||||
|
||||
public interface IReturn { }
|
||||
|
||||
public interface IReturn<T> : IReturn { }
|
||||
|
||||
public interface IReturnVoid : IReturn { }
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace MediaBrowser.Model.Services
|
||||
{
|
||||
public interface IStreamWriter
|
||||
{
|
||||
void WriteTo(Stream responseStream);
|
||||
}
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
#nullable disable
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Model.Dto;
|
||||
|
||||
namespace MediaBrowser.Model.Services
|
||||
{
|
||||
// Remove this garbage class, it's just a bastard copy of NameValueCollection
|
||||
public class QueryParamCollection : List<NameValuePair>
|
||||
{
|
||||
public QueryParamCollection()
|
||||
{
|
||||
}
|
||||
|
||||
private static StringComparison GetStringComparison()
|
||||
{
|
||||
return StringComparison.OrdinalIgnoreCase;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new query parameter.
|
||||
/// </summary>
|
||||
public void Add(string key, string value)
|
||||
{
|
||||
Add(new NameValuePair(key, value));
|
||||
}
|
||||
|
||||
private void Set(string key, string value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
var parameters = GetItems(key);
|
||||
|
||||
foreach (var p in parameters)
|
||||
{
|
||||
Remove(p);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var pair in this)
|
||||
{
|
||||
var stringComparison = GetStringComparison();
|
||||
|
||||
if (string.Equals(key, pair.Name, stringComparison))
|
||||
{
|
||||
pair.Value = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Add(key, value);
|
||||
}
|
||||
|
||||
private string Get(string name)
|
||||
{
|
||||
var stringComparison = GetStringComparison();
|
||||
|
||||
foreach (var pair in this)
|
||||
{
|
||||
if (string.Equals(pair.Name, name, stringComparison))
|
||||
{
|
||||
return pair.Value;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<NameValuePair> GetItems(string name)
|
||||
{
|
||||
var stringComparison = GetStringComparison();
|
||||
|
||||
var list = new List<NameValuePair>();
|
||||
|
||||
foreach (var pair in this)
|
||||
{
|
||||
if (string.Equals(pair.Name, name, stringComparison))
|
||||
{
|
||||
list.Add(pair);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public virtual List<string> GetValues(string name)
|
||||
{
|
||||
var stringComparison = GetStringComparison();
|
||||
|
||||
var list = new List<string>();
|
||||
|
||||
foreach (var pair in this)
|
||||
{
|
||||
if (string.Equals(pair.Name, name, stringComparison))
|
||||
{
|
||||
list.Add(pair.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public IEnumerable<string> Keys
|
||||
{
|
||||
get
|
||||
{
|
||||
var keys = new string[this.Count];
|
||||
|
||||
for (var i = 0; i < keys.Length; i++)
|
||||
{
|
||||
keys[i] = this[i].Name;
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a query parameter value by name. A query may contain multiple values of the same name
|
||||
/// (i.e. "x=1&x=2"), in which case the value is an array, which works for both getting and setting.
|
||||
/// </summary>
|
||||
/// <param name="name">The query parameter name.</param>
|
||||
/// <returns>The query parameter value or array of values.</returns>
|
||||
public string this[string name]
|
||||
{
|
||||
get => Get(name);
|
||||
set => Set(name, value);
|
||||
}
|
||||
|
||||
private string GetQueryStringValue(NameValuePair pair)
|
||||
{
|
||||
return pair.Name + "=" + pair.Value;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var vals = this.Select(GetQueryStringValue).ToArray();
|
||||
|
||||
return string.Join("&", vals);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
#nullable disable
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Model.Services
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
|
||||
public class RouteAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>Initializes an instance of the <see cref="RouteAttribute"/> class.</para>
|
||||
/// </summary>
|
||||
/// <param name="path">
|
||||
/// <para>The path template to map to the request. See
|
||||
/// <see cref="Path">RouteAttribute.Path</see>
|
||||
/// for details on the correct format.</para>
|
||||
/// </param>
|
||||
public RouteAttribute(string path)
|
||||
: this(path, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Initializes an instance of the <see cref="RouteAttribute"/> class.</para>
|
||||
/// </summary>
|
||||
/// <param name="path">
|
||||
/// <para>The path template to map to the request. See
|
||||
/// <see cref="Path">RouteAttribute.Path</see>
|
||||
/// for details on the correct format.</para>
|
||||
/// </param>
|
||||
/// <param name="verbs">A comma-delimited list of HTTP verbs supported by the
|
||||
/// service. If unspecified, all verbs are assumed to be supported.</param>
|
||||
public RouteAttribute(string path, string verbs)
|
||||
{
|
||||
Path = path;
|
||||
Verbs = verbs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the path template to be mapped to the request.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="String"/> value providing the path mapped to
|
||||
/// the request. Never <see langword="null"/>.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// <para>Some examples of valid paths are:</para>
|
||||
///
|
||||
/// <list>
|
||||
/// <item>"/Inventory"</item>
|
||||
/// <item>"/Inventory/{Category}/{ItemId}"</item>
|
||||
/// <item>"/Inventory/{ItemPath*}"</item>
|
||||
/// </list>
|
||||
///
|
||||
/// <para>Variables are specified within "{}"
|
||||
/// brackets. Each variable in the path is mapped to the same-named property
|
||||
/// on the request DTO. At runtime, ServiceStack will parse the
|
||||
/// request URL, extract the variable values, instantiate the request DTO,
|
||||
/// and assign the variable values into the corresponding request properties,
|
||||
/// prior to passing the request DTO to the service object for processing.</para>
|
||||
///
|
||||
/// <para>It is not necessary to specify all request properties as
|
||||
/// variables in the path. For unspecified properties, callers may provide
|
||||
/// values in the query string. For example: the URL
|
||||
/// "http://services/Inventory?Category=Books&ItemId=12345" causes the same
|
||||
/// request DTO to be processed as "http://services/Inventory/Books/12345",
|
||||
/// provided that the paths "/Inventory" (which supports the first URL) and
|
||||
/// "/Inventory/{Category}/{ItemId}" (which supports the second URL)
|
||||
/// are both mapped to the request DTO.</para>
|
||||
///
|
||||
/// <para>Please note that while it is possible to specify property values
|
||||
/// in the query string, it is generally considered to be less RESTful and
|
||||
/// less desirable than to specify them as variables in the path. Using the
|
||||
/// query string to specify property values may also interfere with HTTP
|
||||
/// caching.</para>
|
||||
///
|
||||
/// <para>The final variable in the path may contain a "*" suffix
|
||||
/// to grab all remaining segments in the path portion of the request URL and assign
|
||||
/// them to a single property on the request DTO.
|
||||
/// For example, if the path "/Inventory/{ItemPath*}" is mapped to the request DTO,
|
||||
/// then the request URL "http://services/Inventory/Books/12345" will result
|
||||
/// in a request DTO whose ItemPath property contains "Books/12345".
|
||||
/// You may only specify one such variable in the path, and it must be positioned at
|
||||
/// the end of the path.</para>
|
||||
/// </remarks>
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets short summary of what the route does.
|
||||
/// </summary>
|
||||
public string Summary { get; set; }
|
||||
|
||||
public string Description { get; set; }
|
||||
|
||||
public bool IsHidden { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets longer text to explain the behaviour of the route.
|
||||
/// </summary>
|
||||
public string Notes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a comma-delimited list of HTTP verbs supported by the service, such as
|
||||
/// "GET,PUT,POST,DELETE".
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="String"/> providing a comma-delimited list of HTTP verbs supported
|
||||
/// by the service, <see langword="null"/> or empty if all verbs are supported.
|
||||
/// </value>
|
||||
public string Verbs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Used to rank the precedences of route definitions in reverse routing.
|
||||
/// i.e. Priorities below 0 are auto-generated have less precedence.
|
||||
/// </summary>
|
||||
public int Priority { get; set; }
|
||||
|
||||
protected bool Equals(RouteAttribute other)
|
||||
{
|
||||
return base.Equals(other)
|
||||
&& string.Equals(Path, other.Path)
|
||||
&& string.Equals(Summary, other.Summary)
|
||||
&& string.Equals(Notes, other.Notes)
|
||||
&& string.Equals(Verbs, other.Verbs)
|
||||
&& Priority == other.Priority;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != this.GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((RouteAttribute)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = base.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ (Path != null ? Path.GetHashCode() : 0);
|
||||
hashCode = (hashCode * 397) ^ (Summary != null ? Summary.GetHashCode() : 0);
|
||||
hashCode = (hashCode * 397) ^ (Notes != null ? Notes.GetHashCode() : 0);
|
||||
hashCode = (hashCode * 397) ^ (Verbs != null ? Verbs.GetHashCode() : 0);
|
||||
hashCode = (hashCode * 397) ^ Priority;
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ namespace MediaBrowser.Model.Session
|
||||
{
|
||||
public string[] PlayableMediaTypes { get; set; }
|
||||
|
||||
public string[] SupportedCommands { get; set; }
|
||||
public GeneralCommandType[] SupportedCommands { get; set; }
|
||||
|
||||
public bool SupportsMediaControl { get; set; }
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace MediaBrowser.Model.Session
|
||||
public ClientCapabilities()
|
||||
{
|
||||
PlayableMediaTypes = Array.Empty<string>();
|
||||
SupportedCommands = Array.Empty<string>();
|
||||
SupportedCommands = Array.Empty<GeneralCommandType>();
|
||||
SupportsPersistentIdentifier = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace MediaBrowser.Model.Session
|
||||
{
|
||||
public class GeneralCommand
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public GeneralCommandType Name { get; set; }
|
||||
|
||||
public Guid ControllingUserId { get; set; }
|
||||
|
||||
|
||||
@@ -43,6 +43,11 @@ namespace MediaBrowser.Model.Session
|
||||
Guide = 32,
|
||||
ToggleStats = 33,
|
||||
PlayMediaSource = 34,
|
||||
PlayTrailers = 35
|
||||
PlayTrailers = 35,
|
||||
SetShuffleQueue = 36,
|
||||
PlayState = 37,
|
||||
PlayNext = 38,
|
||||
ToggleOsdMenu = 39,
|
||||
Play = 40
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using MediaBrowser.Model.Services;
|
||||
|
||||
namespace MediaBrowser.Model.Session
|
||||
{
|
||||
@@ -15,21 +14,18 @@ namespace MediaBrowser.Model.Session
|
||||
/// Gets or sets the item ids.
|
||||
/// </summary>
|
||||
/// <value>The item ids.</value>
|
||||
[ApiMember(Name = "ItemIds", Description = "The ids of the items to play, comma delimited", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST", AllowMultiple = true)]
|
||||
public Guid[] ItemIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the start position ticks that the first item should be played at.
|
||||
/// </summary>
|
||||
/// <value>The start position ticks.</value>
|
||||
[ApiMember(Name = "StartPositionTicks", Description = "The starting position of the first item.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
|
||||
public long? StartPositionTicks { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the play command.
|
||||
/// </summary>
|
||||
/// <value>The play command.</value>
|
||||
[ApiMember(Name = "PlayCommand", Description = "The type of play command to issue (PlayNow, PlayNext, PlayLast). Clients who have not yet implemented play next and play last may play now.", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
|
||||
public PlayCommand PlayCommand { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -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>
|
||||
|
||||
50
MediaBrowser.Model/Session/SessionMessageType.cs
Normal file
50
MediaBrowser.Model/Session/SessionMessageType.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Model.Session
|
||||
{
|
||||
/// <summary>
|
||||
/// The different kinds of messages that are used in the WebSocket api.
|
||||
/// </summary>
|
||||
public enum SessionMessageType
|
||||
{
|
||||
// Server -> Client
|
||||
ForceKeepAlive,
|
||||
GeneralCommand,
|
||||
UserDataChanged,
|
||||
Sessions,
|
||||
Play,
|
||||
SyncPlayCommand,
|
||||
SyncPlayGroupUpdate,
|
||||
PlayState,
|
||||
RestartRequired,
|
||||
ServerShuttingDown,
|
||||
ServerRestarting,
|
||||
LibraryChanged,
|
||||
UserDeleted,
|
||||
UserUpdated,
|
||||
SeriesTimerCreated,
|
||||
TimerCreated,
|
||||
SeriesTimerCancelled,
|
||||
TimerCancelled,
|
||||
RefreshProgress,
|
||||
ScheduledTaskEnded,
|
||||
PackageInstallationCancelled,
|
||||
PackageInstallationFailed,
|
||||
PackageInstallationCompleted,
|
||||
PackageInstalling,
|
||||
PackageUninstalled,
|
||||
ActivityLogEntry,
|
||||
ScheduledTasksInfo,
|
||||
|
||||
// Client -> Server
|
||||
ActivityLogEntryStart,
|
||||
ActivityLogEntryStop,
|
||||
SessionsStart,
|
||||
SessionsStop,
|
||||
ScheduledTasksInfoStart,
|
||||
ScheduledTasksInfoStop,
|
||||
|
||||
// Shared
|
||||
KeepAlive,
|
||||
}
|
||||
}
|
||||
@@ -8,10 +8,12 @@ namespace MediaBrowser.Model.Sync
|
||||
/// The latest.
|
||||
/// </summary>
|
||||
Latest = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The next up.
|
||||
/// </summary>
|
||||
NextUp = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The resume.
|
||||
/// </summary>
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace MediaBrowser.Model.System
|
||||
public string Version { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The product name. This is the AssemblyProduct name.
|
||||
/// Gets or sets the product name. This is the AssemblyProduct name.
|
||||
/// </summary>
|
||||
public string ProductName { get; set; }
|
||||
|
||||
@@ -39,5 +39,14 @@ namespace MediaBrowser.Model.System
|
||||
/// </summary>
|
||||
/// <value>The id.</value>
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the startup wizard is completed.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Nullable for OpenAPI specification only to retain backwards compatibility in apiclients.
|
||||
/// </remarks>
|
||||
/// <value>The startup completion status.</value>]
|
||||
public bool? StartupWizardCompleted { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#nullable disable
|
||||
using System;
|
||||
using MediaBrowser.Model.Events;
|
||||
using Jellyfin.Data.Events;
|
||||
|
||||
namespace MediaBrowser.Model.Tasks
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Events;
|
||||
using Jellyfin.Data.Events;
|
||||
|
||||
namespace MediaBrowser.Model.Tasks
|
||||
{
|
||||
|
||||
@@ -52,6 +52,16 @@ namespace MediaBrowser.Model.Updates
|
||||
/// <value>The versions.</value>
|
||||
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>
|
||||
|
||||
@@ -80,11 +80,11 @@ namespace MediaBrowser.Model.Users
|
||||
|
||||
public bool EnableAllDevices { get; set; }
|
||||
|
||||
public string[] EnabledChannels { get; set; }
|
||||
public Guid[] EnabledChannels { get; set; }
|
||||
|
||||
public bool EnableAllChannels { get; set; }
|
||||
|
||||
public string[] EnabledFolders { get; set; }
|
||||
public Guid[] EnabledFolders { get; set; }
|
||||
|
||||
public bool EnableAllFolders { get; set; }
|
||||
|
||||
@@ -92,11 +92,13 @@ namespace MediaBrowser.Model.Users
|
||||
|
||||
public int LoginAttemptsBeforeLockout { get; set; }
|
||||
|
||||
public int MaxActiveSessions { get; set; }
|
||||
|
||||
public bool EnablePublicSharing { get; set; }
|
||||
|
||||
public string[] BlockedMediaFolders { get; set; }
|
||||
public Guid[] BlockedMediaFolders { get; set; }
|
||||
|
||||
public string[] BlockedChannels { get; set; }
|
||||
public Guid[] BlockedChannels { get; set; }
|
||||
|
||||
public int RemoteClientBitrateLimit { get; set; }
|
||||
|
||||
@@ -144,11 +146,13 @@ namespace MediaBrowser.Model.Users
|
||||
|
||||
LoginAttemptsBeforeLockout = -1;
|
||||
|
||||
MaxActiveSessions = 0;
|
||||
|
||||
EnableAllChannels = true;
|
||||
EnabledChannels = Array.Empty<string>();
|
||||
EnabledChannels = Array.Empty<Guid>();
|
||||
|
||||
EnableAllFolders = true;
|
||||
EnabledFolders = Array.Empty<string>();
|
||||
EnabledFolders = Array.Empty<Guid>();
|
||||
|
||||
EnabledDevices = Array.Empty<string>();
|
||||
EnableAllDevices = true;
|
||||
|
||||
Reference in New Issue
Block a user