mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-06-04 22:24:35 -04:00
Merge branch 'master' into comparisons
This commit is contained in:
commit
97c2c523a8
2
.github/workflows/automation.yml
vendored
2
.github/workflows/automation.yml
vendored
@ -2,8 +2,6 @@ name: Automation
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
issues:
|
|
||||||
issue_comment:
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
main:
|
main:
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
namespace Emby.Dlna.Configuration
|
namespace Emby.Dlna.Configuration
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using Emby.Dlna.Configuration;
|
using Emby.Dlna.Configuration;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -9,7 +9,7 @@ namespace Emby.Dlna.Didl
|
|||||||
{
|
{
|
||||||
public class StringWriterWithEncoding : StringWriter
|
public class StringWriterWithEncoding : StringWriter
|
||||||
{
|
{
|
||||||
private readonly Encoding _encoding;
|
private readonly Encoding? _encoding;
|
||||||
|
|
||||||
public StringWriterWithEncoding()
|
public StringWriterWithEncoding()
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<!-- Code Analyzers-->
|
<!-- Code Analyzers-->
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -46,7 +46,7 @@ namespace Emby.Dlna.PlayTo
|
|||||||
{
|
{
|
||||||
var serviceAction = new ServiceAction
|
var serviceAction = new ServiceAction
|
||||||
{
|
{
|
||||||
Name = container.GetValue(UPnpNamespaces.Svc + "name"),
|
Name = container.GetValue(UPnpNamespaces.Svc + "name") ?? string.Empty,
|
||||||
};
|
};
|
||||||
|
|
||||||
var argumentList = serviceAction.ArgumentList;
|
var argumentList = serviceAction.ArgumentList;
|
||||||
@ -68,9 +68,9 @@ namespace Emby.Dlna.PlayTo
|
|||||||
|
|
||||||
return new Argument
|
return new Argument
|
||||||
{
|
{
|
||||||
Name = container.GetValue(UPnpNamespaces.Svc + "name"),
|
Name = container.GetValue(UPnpNamespaces.Svc + "name") ?? string.Empty,
|
||||||
Direction = container.GetValue(UPnpNamespaces.Svc + "direction"),
|
Direction = container.GetValue(UPnpNamespaces.Svc + "direction") ?? string.Empty,
|
||||||
RelatedStateVariable = container.GetValue(UPnpNamespaces.Svc + "relatedStateVariable")
|
RelatedStateVariable = container.GetValue(UPnpNamespaces.Svc + "relatedStateVariable") ?? string.Empty
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,8 +89,8 @@ namespace Emby.Dlna.PlayTo
|
|||||||
|
|
||||||
return new StateVariable
|
return new StateVariable
|
||||||
{
|
{
|
||||||
Name = container.GetValue(UPnpNamespaces.Svc + "name"),
|
Name = container.GetValue(UPnpNamespaces.Svc + "name") ?? string.Empty,
|
||||||
DataType = container.GetValue(UPnpNamespaces.Svc + "dataType"),
|
DataType = container.GetValue(UPnpNamespaces.Svc + "dataType") ?? string.Empty,
|
||||||
AllowedValues = allowedValues
|
AllowedValues = allowedValues
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -166,7 +166,7 @@ namespace Emby.Dlna.PlayTo
|
|||||||
return string.Format(CultureInfo.InvariantCulture, CommandBase, action.Name, xmlNamesapce, stateString);
|
return string.Format(CultureInfo.InvariantCulture, CommandBase, action.Name, xmlNamesapce, stateString);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string BuildArgumentXml(Argument argument, string value, string commandParameter = "")
|
private string BuildArgumentXml(Argument argument, string? value, string commandParameter = "")
|
||||||
{
|
{
|
||||||
var state = StateVariables.FirstOrDefault(a => string.Equals(a.Name, argument.RelatedStateVariable, StringComparison.OrdinalIgnoreCase));
|
var state = StateVariables.FirstOrDefault(a => string.Equals(a.Name, argument.RelatedStateVariable, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -250,7 +250,8 @@ namespace Emby.Dlna.Server
|
|||||||
|
|
||||||
url = _serverAddress.TrimEnd('/') + "/dlna/" + _serverUdn + "/" + url.TrimStart('/');
|
url = _serverAddress.TrimEnd('/') + "/dlna/" + _serverUdn + "/" + url.TrimStart('/');
|
||||||
|
|
||||||
return SecurityElement.Escape(url);
|
// TODO: @bond remove null-coalescing operator when https://github.com/dotnet/runtime/pull/52442 is merged/released
|
||||||
|
return SecurityElement.Escape(url) ?? string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<DeviceIcon> GetIcons()
|
private IEnumerable<DeviceIcon> GetIcons()
|
||||||
|
@ -47,7 +47,7 @@ namespace Emby.Dlna.Service
|
|||||||
|
|
||||||
private async Task<ControlResponse> ProcessControlRequestInternalAsync(ControlRequest request)
|
private async Task<ControlResponse> ProcessControlRequestInternalAsync(ControlRequest request)
|
||||||
{
|
{
|
||||||
ControlRequestInfo requestInfo;
|
ControlRequestInfo? requestInfo = null;
|
||||||
|
|
||||||
using (var streamReader = new StreamReader(request.InputXml, Encoding.UTF8))
|
using (var streamReader = new StreamReader(request.InputXml, Encoding.UTF8))
|
||||||
{
|
{
|
||||||
@ -151,7 +151,7 @@ namespace Emby.Dlna.Service
|
|||||||
|
|
||||||
private async Task<ControlRequestInfo> ParseBodyTagAsync(XmlReader reader)
|
private async Task<ControlRequestInfo> ParseBodyTagAsync(XmlReader reader)
|
||||||
{
|
{
|
||||||
string namespaceURI = null, localName = null;
|
string? namespaceURI = null, localName = null;
|
||||||
|
|
||||||
await reader.MoveToContentAsync().ConfigureAwait(false);
|
await reader.MoveToContentAsync().ConfigureAwait(false);
|
||||||
await reader.ReadAsync().ConfigureAwait(false);
|
await reader.ReadAsync().ConfigureAwait(false);
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -7,21 +7,21 @@ namespace Emby.Dlna.Ssdp
|
|||||||
{
|
{
|
||||||
public static class SsdpExtensions
|
public static class SsdpExtensions
|
||||||
{
|
{
|
||||||
public static string GetValue(this XElement container, XName name)
|
public static string? GetValue(this XElement container, XName name)
|
||||||
{
|
{
|
||||||
var node = container.Element(name);
|
var node = container.Element(name);
|
||||||
|
|
||||||
return node?.Value;
|
return node?.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetAttributeValue(this XElement container, XName name)
|
public static string? GetAttributeValue(this XElement container, XName name)
|
||||||
{
|
{
|
||||||
var node = container.Attribute(name);
|
var node = container.Attribute(name);
|
||||||
|
|
||||||
return node?.Value;
|
return node?.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetDescendantValue(this XElement container, XName name)
|
public static string? GetDescendantValue(this XElement container, XName name)
|
||||||
=> container.Descendants(name).FirstOrDefault()?.Value;
|
=> container.Descendants(name).FirstOrDefault()?.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,11 @@ namespace Emby.Server.Implementations.Library
|
|||||||
|
|
||||||
// Make sure DateCreated and DateModified have values
|
// Make sure DateCreated and DateModified have values
|
||||||
var fileInfo = directoryService.GetFile(item.Path);
|
var fileInfo = directoryService.GetFile(item.Path);
|
||||||
|
if (fileInfo == null)
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException("Can't find item path.", item.Path);
|
||||||
|
}
|
||||||
|
|
||||||
SetDateCreated(item, fileInfo);
|
SetDateCreated(item, fileInfo);
|
||||||
|
|
||||||
EnsureName(item, fileInfo);
|
EnsureName(item, fileInfo);
|
||||||
|
@ -10,6 +10,7 @@ using System.Text.Json;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Json;
|
using MediaBrowser.Common.Json;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
@ -307,13 +308,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||||||
{
|
{
|
||||||
using (var reader = new StreamReader(source))
|
using (var reader = new StreamReader(source))
|
||||||
{
|
{
|
||||||
while (!reader.EndOfStream)
|
await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
var line = await reader.ReadLineAsync().ConfigureAwait(false);
|
|
||||||
|
|
||||||
var bytes = Encoding.UTF8.GetBytes(Environment.NewLine + line);
|
var bytes = Encoding.UTF8.GetBytes(Environment.NewLine + line);
|
||||||
|
|
||||||
await target.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
|
await target.WriteAsync(bytes.AsMemory()).ConfigureAwait(false);
|
||||||
await target.FlushAsync().ConfigureAwait(false);
|
await target.FlushAsync().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,16 +182,16 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||||||
await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
|
await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
|
||||||
using var sr = new StreamReader(stream, System.Text.Encoding.UTF8);
|
using var sr = new StreamReader(stream, System.Text.Encoding.UTF8);
|
||||||
var tuners = new List<LiveTvTunerInfo>();
|
var tuners = new List<LiveTvTunerInfo>();
|
||||||
while (!sr.EndOfStream)
|
await foreach (var line in sr.ReadAllLinesAsync().ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
string line = StripXML(sr.ReadLine());
|
string stripedLine = StripXML(line);
|
||||||
if (line.Contains("Channel", StringComparison.Ordinal))
|
if (stripedLine.Contains("Channel", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
LiveTvTunerStatus status;
|
LiveTvTunerStatus status;
|
||||||
var index = line.IndexOf("Channel", StringComparison.OrdinalIgnoreCase);
|
var index = stripedLine.IndexOf("Channel", StringComparison.OrdinalIgnoreCase);
|
||||||
var name = line.Substring(0, index - 1);
|
var name = stripedLine.Substring(0, index - 1);
|
||||||
var currentChannel = line.Substring(index + 7);
|
var currentChannel = stripedLine.Substring(index + 7);
|
||||||
if (currentChannel != "none")
|
if (string.Equals(currentChannel, "none", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
status = LiveTvTunerStatus.LiveTv;
|
status = LiveTvTunerStatus.LiveTv;
|
||||||
}
|
}
|
||||||
|
@ -35,16 +35,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
// Read the file and display it line by line.
|
// Read the file and display it line by line.
|
||||||
using (var reader = new StreamReader(await GetListingsStream(info, cancellationToken).ConfigureAwait(false)))
|
using (var reader = new StreamReader(await GetListingsStream(info, cancellationToken).ConfigureAwait(false)))
|
||||||
{
|
{
|
||||||
return GetChannels(reader, channelIdPrefix, info.Id);
|
return await GetChannelsAsync(reader, channelIdPrefix, info.Id).ConfigureAwait(false);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ChannelInfo> ParseString(string text, string channelIdPrefix, string tunerHostId)
|
|
||||||
{
|
|
||||||
// Read the file and display it line by line.
|
|
||||||
using (var reader = new StringReader(text))
|
|
||||||
{
|
|
||||||
return GetChannels(reader, channelIdPrefix, tunerHostId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,43 +61,42 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
|
|
||||||
private const string ExtInfPrefix = "#EXTINF:";
|
private const string ExtInfPrefix = "#EXTINF:";
|
||||||
|
|
||||||
private List<ChannelInfo> GetChannels(TextReader reader, string channelIdPrefix, string tunerHostId)
|
private async Task<List<ChannelInfo>> GetChannelsAsync(TextReader reader, string channelIdPrefix, string tunerHostId)
|
||||||
{
|
{
|
||||||
var channels = new List<ChannelInfo>();
|
var channels = new List<ChannelInfo>();
|
||||||
string line;
|
|
||||||
string extInf = string.Empty;
|
string extInf = string.Empty;
|
||||||
|
|
||||||
while ((line = reader.ReadLine()) != null)
|
await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
line = line.Trim();
|
var trimmedLine = line.Trim();
|
||||||
if (string.IsNullOrWhiteSpace(line))
|
if (string.IsNullOrWhiteSpace(trimmedLine))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line.StartsWith("#EXTM3U", StringComparison.OrdinalIgnoreCase))
|
if (trimmedLine.StartsWith("#EXTM3U", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line.StartsWith(ExtInfPrefix, StringComparison.OrdinalIgnoreCase))
|
if (trimmedLine.StartsWith(ExtInfPrefix, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
extInf = line.Substring(ExtInfPrefix.Length).Trim();
|
extInf = trimmedLine.Substring(ExtInfPrefix.Length).Trim();
|
||||||
_logger.LogInformation("Found m3u channel: {0}", extInf);
|
_logger.LogInformation("Found m3u channel: {0}", extInf);
|
||||||
}
|
}
|
||||||
else if (!string.IsNullOrWhiteSpace(extInf) && !line.StartsWith('#'))
|
else if (!string.IsNullOrWhiteSpace(extInf) && !trimmedLine.StartsWith('#'))
|
||||||
{
|
{
|
||||||
var channel = GetChannelnfo(extInf, tunerHostId, line);
|
var channel = GetChannelnfo(extInf, tunerHostId, trimmedLine);
|
||||||
if (string.IsNullOrWhiteSpace(channel.Id))
|
if (string.IsNullOrWhiteSpace(channel.Id))
|
||||||
{
|
{
|
||||||
channel.Id = channelIdPrefix + line.GetMD5().ToString("N", CultureInfo.InvariantCulture);
|
channel.Id = channelIdPrefix + trimmedLine.GetMD5().ToString("N", CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
channel.Id = channelIdPrefix + channel.Id.GetMD5().ToString("N", CultureInfo.InvariantCulture);
|
channel.Id = channelIdPrefix + channel.Id.GetMD5().ToString("N", CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
channel.Path = line;
|
channel.Path = trimmedLine;
|
||||||
channels.Add(channel);
|
channels.Add(channel);
|
||||||
extInf = string.Empty;
|
extInf = string.Empty;
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Json;
|
using MediaBrowser.Common.Json;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
@ -72,8 +73,7 @@ namespace Emby.Server.Implementations.Localization
|
|||||||
using (var str = _assembly.GetManifestResourceStream(resource))
|
using (var str = _assembly.GetManifestResourceStream(resource))
|
||||||
using (var reader = new StreamReader(str))
|
using (var reader = new StreamReader(str))
|
||||||
{
|
{
|
||||||
string line;
|
await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false))
|
||||||
while ((line = await reader.ReadLineAsync().ConfigureAwait(false)) != null)
|
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(line))
|
if (string.IsNullOrWhiteSpace(line))
|
||||||
{
|
{
|
||||||
@ -118,10 +118,8 @@ namespace Emby.Server.Implementations.Localization
|
|||||||
using (var stream = _assembly.GetManifestResourceStream(ResourcePath))
|
using (var stream = _assembly.GetManifestResourceStream(ResourcePath))
|
||||||
using (var reader = new StreamReader(stream))
|
using (var reader = new StreamReader(stream))
|
||||||
{
|
{
|
||||||
while (!reader.EndOfStream)
|
await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
var line = await reader.ReadLineAsync().ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(line))
|
if (string.IsNullOrWhiteSpace(line))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -179,7 +177,7 @@ namespace Emby.Server.Implementations.Localization
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IEnumerable<CountryInfo> GetCountries()
|
public IEnumerable<CountryInfo> GetCountries()
|
||||||
{
|
{
|
||||||
StreamReader reader = new StreamReader(_assembly.GetManifestResourceStream("Emby.Server.Implementations.Localization.countries.json"));
|
using StreamReader reader = new StreamReader(_assembly.GetManifestResourceStream("Emby.Server.Implementations.Localization.countries.json"));
|
||||||
|
|
||||||
return JsonSerializer.Deserialize<IEnumerable<CountryInfo>>(reader.ReadToEnd(), _jsonOptions);
|
return JsonSerializer.Deserialize<IEnumerable<CountryInfo>>(reader.ReadToEnd(), _jsonOptions);
|
||||||
}
|
}
|
||||||
|
@ -77,8 +77,9 @@ namespace Jellyfin.Api.Auth
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var ip = _httpContextAccessor.HttpContext.GetNormalizedRemoteIp();
|
var isInLocalNetwork = _httpContextAccessor.HttpContext != null
|
||||||
var isInLocalNetwork = _networkManager.IsInLocalNetwork(ip);
|
&& _networkManager.IsInLocalNetwork(_httpContextAccessor.HttpContext.GetNormalizedRemoteIp());
|
||||||
|
|
||||||
// User cannot access remotely and user is remote
|
// User cannot access remotely and user is remote
|
||||||
if (!user.HasPermission(PermissionKind.EnableRemoteAccess) && !isInLocalNetwork)
|
if (!user.HasPermission(PermissionKind.EnableRemoteAccess) && !isInLocalNetwork)
|
||||||
{
|
{
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Net.Mime;
|
using System.Net.Mime;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
@ -94,6 +95,11 @@ namespace Jellyfin.Api.Controllers
|
|||||||
{
|
{
|
||||||
var configurationType = _configurationManager.GetConfigurationType(key);
|
var configurationType = _configurationManager.GetConfigurationType(key);
|
||||||
var configuration = await JsonSerializer.DeserializeAsync(Request.Body, configurationType, _serializerOptions).ConfigureAwait(false);
|
var configuration = await JsonSerializer.DeserializeAsync(Request.Body, configurationType, _serializerOptions).ConfigureAwait(false);
|
||||||
|
if (configuration == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Body doesn't contain a valid configuration");
|
||||||
|
}
|
||||||
|
|
||||||
_configurationManager.SaveConfiguration(key, configuration);
|
_configurationManager.SaveConfiguration(key, configuration);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
@ -600,7 +600,7 @@ namespace Jellyfin.Api.Controllers
|
|||||||
{
|
{
|
||||||
foreach (var item in dto.Updates)
|
foreach (var item in dto.Updates)
|
||||||
{
|
{
|
||||||
_libraryMonitor.ReportFileSystemChanged(item.Path);
|
_libraryMonitor.ReportFileSystemChanged(item.Path ?? throw new ArgumentException("Item path can't be null."));
|
||||||
}
|
}
|
||||||
|
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
@ -118,10 +118,7 @@ namespace Jellyfin.Api.Helpers
|
|||||||
/// <returns>The playlist text as a string.</returns>
|
/// <returns>The playlist text as a string.</returns>
|
||||||
public static string GetLivePlaylistText(string path, StreamState state)
|
public static string GetLivePlaylistText(string path, StreamState state)
|
||||||
{
|
{
|
||||||
using var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
var text = File.ReadAllText(path);
|
||||||
using var reader = new StreamReader(stream);
|
|
||||||
|
|
||||||
var text = reader.ReadToEnd();
|
|
||||||
|
|
||||||
var segmentFormat = EncodingHelper.GetSegmentFileExtension(state.Request.SegmentContainer).TrimStart('.');
|
var segmentFormat = EncodingHelper.GetSegmentFileExtension(state.Request.SegmentContainer).TrimStart('.');
|
||||||
if (string.Equals(segmentFormat, "mp4", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(segmentFormat, "mp4", StringComparison.OrdinalIgnoreCase))
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace MediaBrowser.Common.Configuration
|
namespace MediaBrowser.Common.Configuration
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#nullable disable
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
namespace MediaBrowser.Common.Configuration
|
namespace MediaBrowser.Common.Configuration
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
#nullable enable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -17,7 +17,7 @@ namespace MediaBrowser.Common.Events
|
|||||||
/// <param name="sender">The sender.</param>
|
/// <param name="sender">The sender.</param>
|
||||||
/// <param name="args">The <see cref="EventArgs" /> instance containing the event data.</param>
|
/// <param name="args">The <see cref="EventArgs" /> instance containing the event data.</param>
|
||||||
/// <param name="logger">The logger.</param>
|
/// <param name="logger">The logger.</param>
|
||||||
public static void QueueEventIfNotNull(EventHandler handler, object sender, EventArgs args, ILogger logger)
|
public static void QueueEventIfNotNull(EventHandler? handler, object sender, EventArgs args, ILogger logger)
|
||||||
{
|
{
|
||||||
if (handler != null)
|
if (handler != null)
|
||||||
{
|
{
|
||||||
@ -43,7 +43,7 @@ namespace MediaBrowser.Common.Events
|
|||||||
/// <param name="sender">The sender.</param>
|
/// <param name="sender">The sender.</param>
|
||||||
/// <param name="args">The args.</param>
|
/// <param name="args">The args.</param>
|
||||||
/// <param name="logger">The logger.</param>
|
/// <param name="logger">The logger.</param>
|
||||||
public static void QueueEventIfNotNull<T>(EventHandler<T> handler, object sender, T args, ILogger logger)
|
public static void QueueEventIfNotNull<T>(EventHandler<T>? handler, object sender, T args, ILogger logger)
|
||||||
{
|
{
|
||||||
if (handler != null)
|
if (handler != null)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace MediaBrowser.Common.Extensions
|
namespace MediaBrowser.Common.Extensions
|
||||||
|
@ -17,7 +17,7 @@ namespace MediaBrowser.Common.Extensions
|
|||||||
{
|
{
|
||||||
return (context.Connection.LocalIpAddress == null
|
return (context.Connection.LocalIpAddress == null
|
||||||
&& context.Connection.RemoteIpAddress == null)
|
&& context.Connection.RemoteIpAddress == null)
|
||||||
|| context.Connection.LocalIpAddress.Equals(context.Connection.RemoteIpAddress);
|
|| Equals(context.Connection.LocalIpAddress, context.Connection.RemoteIpAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace MediaBrowser.Common.Extensions
|
namespace MediaBrowser.Common.Extensions
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace MediaBrowser.Common.Extensions
|
namespace MediaBrowser.Common.Extensions
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#nullable enable
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
#pragma warning disable CA1034
|
#pragma warning disable CA1034
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -35,11 +33,11 @@ namespace MediaBrowser.Common.Extensions
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads all lines in the <see cref="StreamReader" />.
|
/// Reads all lines in the <see cref="TextReader" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="reader">The <see cref="StreamReader" /> to read from.</param>
|
/// <param name="reader">The <see cref="TextReader" /> to read from.</param>
|
||||||
/// <returns>All lines in the stream.</returns>
|
/// <returns>All lines in the stream.</returns>
|
||||||
public static IEnumerable<string> ReadAllLines(this StreamReader reader)
|
public static IEnumerable<string> ReadAllLines(this TextReader reader)
|
||||||
{
|
{
|
||||||
string? line;
|
string? line;
|
||||||
while ((line = reader.ReadLine()) != null)
|
while ((line = reader.ReadLine()) != null)
|
||||||
@ -47,5 +45,19 @@ namespace MediaBrowser.Common.Extensions
|
|||||||
yield return line;
|
yield return line;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads all lines in the <see cref="TextReader" />.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reader">The <see cref="TextReader" /> to read from.</param>
|
||||||
|
/// <returns>All lines in the stream.</returns>
|
||||||
|
public static async IAsyncEnumerable<string> ReadAllLinesAsync(this TextReader reader)
|
||||||
|
{
|
||||||
|
string? line;
|
||||||
|
while ((line = await reader.ReadLineAsync().ConfigureAwait(false)) != null)
|
||||||
|
{
|
||||||
|
yield return line;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
@ -9,67 +9,16 @@ namespace MediaBrowser.Common.Json.Converters
|
|||||||
/// Convert comma delimited string to array of type.
|
/// Convert comma delimited string to array of type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">Type to convert to.</typeparam>
|
/// <typeparam name="T">Type to convert to.</typeparam>
|
||||||
public class JsonCommaDelimitedArrayConverter<T> : JsonConverter<T[]>
|
public sealed class JsonCommaDelimitedArrayConverter<T> : JsonDelimitedArrayConverter<T>
|
||||||
{
|
{
|
||||||
private readonly TypeConverter _typeConverter;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="JsonCommaDelimitedArrayConverter{T}"/> class.
|
/// Initializes a new instance of the <see cref="JsonCommaDelimitedArrayConverter{T}"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public JsonCommaDelimitedArrayConverter()
|
public JsonCommaDelimitedArrayConverter() : base()
|
||||||
{
|
{
|
||||||
_typeConverter = TypeDescriptor.GetConverter(typeof(T));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override T[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
protected override char Delimiter => ',';
|
||||||
{
|
|
||||||
if (reader.TokenType == JsonTokenType.String)
|
|
||||||
{
|
|
||||||
var stringEntries = reader.GetString().Split(',', StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
if (stringEntries.Length == 0)
|
|
||||||
{
|
|
||||||
return Array.Empty<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
var parsedValues = new object[stringEntries.Length];
|
|
||||||
var convertedCount = 0;
|
|
||||||
for (var i = 0; i < stringEntries.Length; i++)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
parsedValues[i] = _typeConverter.ConvertFrom(stringEntries[i].Trim());
|
|
||||||
convertedCount++;
|
|
||||||
}
|
|
||||||
catch (FormatException)
|
|
||||||
{
|
|
||||||
// TODO log when upgraded to .Net6
|
|
||||||
// https://github.com/dotnet/runtime/issues/42975
|
|
||||||
// _logger.LogDebug(e, "Error converting value.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var typedValues = new T[convertedCount];
|
|
||||||
var typedValueIndex = 0;
|
|
||||||
for (var i = 0; i < stringEntries.Length; i++)
|
|
||||||
{
|
|
||||||
if (parsedValues[i] != null)
|
|
||||||
{
|
|
||||||
typedValues.SetValue(parsedValues[i], typedValueIndex);
|
|
||||||
typedValueIndex++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return typedValues;
|
|
||||||
}
|
|
||||||
|
|
||||||
return JsonSerializer.Deserialize<T[]>(ref reader, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void Write(Utf8JsonWriter writer, T[] value, JsonSerializerOptions options)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,10 @@ namespace MediaBrowser.Common.Json.Converters
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
|
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
|
||||||
{
|
{
|
||||||
var structType = typeToConvert.GetElementType() ?? typeToConvert.GenericTypeArguments[0];
|
var structType = typeToConvert.GetElementType() ?? typeToConvert.GenericTypeArguments[0];
|
||||||
return (JsonConverter)Activator.CreateInstance(typeof(JsonCommaDelimitedArrayConverter<>).MakeGenericType(structType));
|
return (JsonConverter?)Activator.CreateInstance(typeof(JsonCommaDelimitedArrayConverter<>).MakeGenericType(structType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,81 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Common.Json.Converters
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Convert delimited string to array of type.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Type to convert to.</typeparam>
|
||||||
|
public abstract class JsonDelimitedArrayConverter<T> : JsonConverter<T[]?>
|
||||||
|
{
|
||||||
|
private readonly TypeConverter _typeConverter;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="JsonDelimitedArrayConverter{T}"/> class.
|
||||||
|
/// </summary>
|
||||||
|
protected JsonDelimitedArrayConverter()
|
||||||
|
{
|
||||||
|
_typeConverter = TypeDescriptor.GetConverter(typeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the array delimiter.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual char Delimiter { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override T[]? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (reader.TokenType == JsonTokenType.String)
|
||||||
|
{
|
||||||
|
// GetString can't return null here because we already handled it above
|
||||||
|
var stringEntries = reader.GetString()?.Split(Delimiter, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if (stringEntries == null || stringEntries.Length == 0)
|
||||||
|
{
|
||||||
|
return Array.Empty<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
var parsedValues = new object[stringEntries.Length];
|
||||||
|
var convertedCount = 0;
|
||||||
|
for (var i = 0; i < stringEntries.Length; i++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
parsedValues[i] = _typeConverter.ConvertFrom(stringEntries[i].Trim());
|
||||||
|
convertedCount++;
|
||||||
|
}
|
||||||
|
catch (FormatException)
|
||||||
|
{
|
||||||
|
// TODO log when upgraded to .Net6
|
||||||
|
// https://github.com/dotnet/runtime/issues/42975
|
||||||
|
// _logger.LogDebug(e, "Error converting value.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var typedValues = new T[convertedCount];
|
||||||
|
var typedValueIndex = 0;
|
||||||
|
for (var i = 0; i < stringEntries.Length; i++)
|
||||||
|
{
|
||||||
|
if (parsedValues[i] != null)
|
||||||
|
{
|
||||||
|
typedValues.SetValue(parsedValues[i], typedValueIndex);
|
||||||
|
typedValueIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return typedValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
return JsonSerializer.Deserialize<T[]>(ref reader, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void Write(Utf8JsonWriter writer, T[]? value, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -18,10 +18,10 @@ namespace MediaBrowser.Common.Json.Converters
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
|
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
|
||||||
{
|
{
|
||||||
var structType = typeToConvert.GenericTypeArguments[0];
|
var structType = typeToConvert.GenericTypeArguments[0];
|
||||||
return (JsonConverter)Activator.CreateInstance(typeof(JsonNullableStructConverter<>).MakeGenericType(structType));
|
return (JsonConverter?)Activator.CreateInstance(typeof(JsonNullableStructConverter<>).MakeGenericType(structType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,15 +7,21 @@ namespace MediaBrowser.Common.Json.Converters
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts a string <c>N/A</c> to <c>string.Empty</c>.
|
/// Converts a string <c>N/A</c> to <c>string.Empty</c>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class JsonOmdbNotAvailableStringConverter : JsonConverter<string>
|
public class JsonOmdbNotAvailableStringConverter : JsonConverter<string?>
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
{
|
{
|
||||||
|
if (reader.TokenType == JsonTokenType.Null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (reader.TokenType == JsonTokenType.String)
|
if (reader.TokenType == JsonTokenType.String)
|
||||||
{
|
{
|
||||||
var str = reader.GetString();
|
// GetString can't return null here because we already handled it above
|
||||||
if (str != null && str.Equals("N/A", StringComparison.OrdinalIgnoreCase))
|
var str = reader.GetString()!;
|
||||||
|
if (str.Equals("N/A", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -23,11 +29,11 @@ namespace MediaBrowser.Common.Json.Converters
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
return JsonSerializer.Deserialize<string>(ref reader, options);
|
return JsonSerializer.Deserialize<string?>(ref reader, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
|
public override void Write(Utf8JsonWriter writer, string? value, JsonSerializerOptions options)
|
||||||
{
|
{
|
||||||
writer.WriteStringValue(value);
|
writer.WriteStringValue(value);
|
||||||
}
|
}
|
||||||
|
@ -9,67 +9,16 @@ namespace MediaBrowser.Common.Json.Converters
|
|||||||
/// Convert Pipe delimited string to array of type.
|
/// Convert Pipe delimited string to array of type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">Type to convert to.</typeparam>
|
/// <typeparam name="T">Type to convert to.</typeparam>
|
||||||
public class JsonPipeDelimitedArrayConverter<T> : JsonConverter<T[]>
|
public sealed class JsonPipeDelimitedArrayConverter<T> : JsonDelimitedArrayConverter<T>
|
||||||
{
|
{
|
||||||
private readonly TypeConverter _typeConverter;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="JsonPipeDelimitedArrayConverter{T}"/> class.
|
/// Initializes a new instance of the <see cref="JsonPipeDelimitedArrayConverter{T}"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public JsonPipeDelimitedArrayConverter()
|
public JsonPipeDelimitedArrayConverter() : base()
|
||||||
{
|
{
|
||||||
_typeConverter = TypeDescriptor.GetConverter(typeof(T));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override T[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
protected override char Delimiter => '|';
|
||||||
{
|
|
||||||
if (reader.TokenType == JsonTokenType.String)
|
|
||||||
{
|
|
||||||
var stringEntries = reader.GetString()?.Split('|', StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
if (stringEntries == null || stringEntries.Length == 0)
|
|
||||||
{
|
|
||||||
return Array.Empty<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
var parsedValues = new object[stringEntries.Length];
|
|
||||||
var convertedCount = 0;
|
|
||||||
for (var i = 0; i < stringEntries.Length; i++)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
parsedValues[i] = _typeConverter.ConvertFrom(stringEntries[i].Trim());
|
|
||||||
convertedCount++;
|
|
||||||
}
|
|
||||||
catch (FormatException)
|
|
||||||
{
|
|
||||||
// TODO log when upgraded to .Net6
|
|
||||||
// https://github.com/dotnet/runtime/issues/42975
|
|
||||||
// _logger.LogDebug(e, "Error converting value.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var typedValues = new T[convertedCount];
|
|
||||||
var typedValueIndex = 0;
|
|
||||||
for (var i = 0; i < stringEntries.Length; i++)
|
|
||||||
{
|
|
||||||
if (parsedValues[i] != null)
|
|
||||||
{
|
|
||||||
typedValues.SetValue(parsedValues[i], typedValueIndex);
|
|
||||||
typedValueIndex++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return typedValues;
|
|
||||||
}
|
|
||||||
|
|
||||||
return JsonSerializer.Deserialize<T[]>(ref reader, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void Write(Utf8JsonWriter writer, T[] value, JsonSerializerOptions options)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,10 @@ namespace MediaBrowser.Common.Json.Converters
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
|
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
|
||||||
{
|
{
|
||||||
var structType = typeToConvert.GetElementType() ?? typeToConvert.GenericTypeArguments[0];
|
var structType = typeToConvert.GetElementType() ?? typeToConvert.GenericTypeArguments[0];
|
||||||
return (JsonConverter)Activator.CreateInstance(typeof(JsonPipeDelimitedArrayConverter<>).MakeGenericType(structType));
|
return (JsonConverter?)Activator.CreateInstance(typeof(JsonPipeDelimitedArrayConverter<>).MakeGenericType(structType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,10 @@ namespace MediaBrowser.Common.Json.Converters
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converter to allow the serializer to read strings.
|
/// Converter to allow the serializer to read strings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class JsonStringConverter : JsonConverter<string>
|
public class JsonStringConverter : JsonConverter<string?>
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
{
|
{
|
||||||
return reader.TokenType switch
|
return reader.TokenType switch
|
||||||
{
|
{
|
||||||
@ -23,7 +23,7 @@ namespace MediaBrowser.Common.Json.Converters
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
|
public override void Write(Utf8JsonWriter writer, string? value, JsonSerializerOptions options)
|
||||||
{
|
{
|
||||||
writer.WriteStringValue(value);
|
writer.WriteStringValue(value);
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ namespace MediaBrowser.Common.Json.Converters
|
|||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Version Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
public override Version Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
=> new Version(reader.GetString());
|
=> new Version(reader.GetString()!); // Will throw ArgumentNullException on null
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Write(Utf8JsonWriter writer, Version value, JsonSerializerOptions options)
|
public override void Write(Utf8JsonWriter writer, Version value, JsonSerializerOptions options)
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
|
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
|
||||||
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
using System;
|
using System;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
using System;
|
using System;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
#nullable disable
|
||||||
#pragma warning disable SA1649 // File name should match first type name
|
#pragma warning disable SA1649 // File name should match first type name
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using MediaBrowser.Model.Plugins;
|
using MediaBrowser.Model.Plugins;
|
||||||
|
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using MediaBrowser.Model.Plugins;
|
using MediaBrowser.Model.Plugins;
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using MediaBrowser.Model.Plugins;
|
using MediaBrowser.Model.Plugins;
|
||||||
|
@ -14,9 +14,9 @@ namespace MediaBrowser.Common.Progress
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _actions.
|
/// The _actions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private Action<T> _action;
|
private Action<T>? _action;
|
||||||
|
|
||||||
public event EventHandler<T> ProgressChanged;
|
public event EventHandler<T>? ProgressChanged;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Registers the action.
|
/// Registers the action.
|
||||||
|
@ -7,7 +7,7 @@ namespace MediaBrowser.Common.Progress
|
|||||||
{
|
{
|
||||||
public class SimpleProgress<T> : IProgress<T>
|
public class SimpleProgress<T> : IProgress<T>
|
||||||
{
|
{
|
||||||
public event EventHandler<T> ProgressChanged;
|
public event EventHandler<T>? ProgressChanged;
|
||||||
|
|
||||||
public void Report(T value)
|
public void Report(T value)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
#nullable enable
|
using System;
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace MediaBrowser.Common.Providers
|
namespace MediaBrowser.Common.Providers
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using MediaBrowser.Model.Updates;
|
using MediaBrowser.Model.Updates;
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#nullable disable
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Model.Configuration;
|
using MediaBrowser.Model.Configuration;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Channels
|
namespace MediaBrowser.Controller.Channels
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Channels
|
namespace MediaBrowser.Controller.Channels
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user