Fix warnings

This commit is contained in:
Bond_009 2020-08-07 19:26:28 +02:00 committed by Bond_009
parent 634ee2d1e9
commit 2b400c99ef
46 changed files with 365 additions and 301 deletions

View File

@ -54,11 +54,15 @@ namespace Emby.Dlna
_appHost = appHost; _appHost = appHost;
} }
private string UserProfilesPath => Path.Combine(_appPaths.ConfigurationDirectoryPath, "dlna", "user");
private string SystemProfilesPath => Path.Combine(_appPaths.ConfigurationDirectoryPath, "dlna", "system");
public async Task InitProfilesAsync() public async Task InitProfilesAsync()
{ {
try try
{ {
await ExtractSystemProfilesAsync(); await ExtractSystemProfilesAsync().ConfigureAwait(false);
LoadProfiles(); LoadProfiles();
} }
catch (Exception ex) catch (Exception ex)
@ -240,7 +244,7 @@ namespace Emby.Dlna
} }
else else
{ {
var headerString = string.Join(", ", headers.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray()); var headerString = string.Join(", ", headers.Select(i => string.Format(CultureInfo.InvariantCulture, "{0}={1}", i.Key, i.Value)));
_logger.LogDebug("No matching device profile found. {0}", headerString); _logger.LogDebug("No matching device profile found. {0}", headerString);
} }
@ -280,10 +284,6 @@ namespace Emby.Dlna
return false; return false;
} }
private string UserProfilesPath => Path.Combine(_appPaths.ConfigurationDirectoryPath, "dlna", "user");
private string SystemProfilesPath => Path.Combine(_appPaths.ConfigurationDirectoryPath, "dlna", "system");
private IEnumerable<DeviceProfile> GetProfiles(string path, DeviceProfileType type) private IEnumerable<DeviceProfile> GetProfiles(string path, DeviceProfileType type)
{ {
try try

View File

@ -19,6 +19,8 @@ namespace Emby.Dlna.PlayTo
{ {
public class Device : IDisposable public class Device : IDisposable
{ {
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
private Timer _timer; private Timer _timer;
public DeviceInfo Properties { get; set; } public DeviceInfo Properties { get; set; }
@ -55,16 +57,13 @@ namespace Emby.Dlna.PlayTo
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IServerConfigurationManager _config;
public Action OnDeviceUnavailable { get; set; } public Action OnDeviceUnavailable { get; set; }
public Device(DeviceInfo deviceProperties, IHttpClient httpClient, ILogger logger, IServerConfigurationManager config) public Device(DeviceInfo deviceProperties, IHttpClient httpClient, ILogger logger)
{ {
Properties = deviceProperties; Properties = deviceProperties;
_httpClient = httpClient; _httpClient = httpClient;
_logger = logger; _logger = logger;
_config = config;
} }
public void Start() public void Start()
@ -275,7 +274,7 @@ namespace Emby.Dlna.PlayTo
throw new InvalidOperationException("Unable to find service"); throw new InvalidOperationException("Unable to find service");
} }
await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, string.Format("{0:hh}:{0:mm}:{0:ss}", value), "REL_TIME")) await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, string.Format(CultureInfo.InvariantCulture, "{0:hh}:{0:mm}:{0:ss}", value), "REL_TIME"))
.ConfigureAwait(false); .ConfigureAwait(false);
RestartTimer(true); RestartTimer(true);
@ -285,7 +284,7 @@ namespace Emby.Dlna.PlayTo
{ {
var avCommands = await GetAVProtocolAsync(cancellationToken).ConfigureAwait(false); var avCommands = await GetAVProtocolAsync(cancellationToken).ConfigureAwait(false);
url = url.Replace("&", "&amp;"); url = url.Replace("&", "&amp;", StringComparison.Ordinal);
_logger.LogDebug("{0} - SetAvTransport Uri: {1} DlnaHeaders: {2}", Properties.Name, url, header); _logger.LogDebug("{0} - SetAvTransport Uri: {1} DlnaHeaders: {2}", Properties.Name, url, header);
@ -297,8 +296,8 @@ namespace Emby.Dlna.PlayTo
var dictionary = new Dictionary<string, string> var dictionary = new Dictionary<string, string>
{ {
{"CurrentURI", url}, { "CurrentURI", url },
{"CurrentURIMetaData", CreateDidlMeta(metaData)} { "CurrentURIMetaData", CreateDidlMeta(metaData) }
}; };
var service = GetAvTransportService(); var service = GetAvTransportService();
@ -732,10 +731,10 @@ namespace Emby.Dlna.PlayTo
} }
var trackUriElem = result.Document.Descendants(uPnpNamespaces.AvTransport + "GetPositionInfoResponse").Select(i => i.Element("TrackURI")).FirstOrDefault(i => i != null); var trackUriElem = result.Document.Descendants(uPnpNamespaces.AvTransport + "GetPositionInfoResponse").Select(i => i.Element("TrackURI")).FirstOrDefault(i => i != null);
var trackUri = trackUriElem == null ? null : trackUriElem.Value; var trackUri = trackUriElem?.Value;
var durationElem = result.Document.Descendants(uPnpNamespaces.AvTransport + "GetPositionInfoResponse").Select(i => i.Element("TrackDuration")).FirstOrDefault(i => i != null); var durationElem = result.Document.Descendants(uPnpNamespaces.AvTransport + "GetPositionInfoResponse").Select(i => i.Element("TrackDuration")).FirstOrDefault(i => i != null);
var duration = durationElem == null ? null : durationElem.Value; var duration = durationElem?.Value;
if (!string.IsNullOrWhiteSpace(duration) if (!string.IsNullOrWhiteSpace(duration)
&& !string.Equals(duration, "NOT_IMPLEMENTED", StringComparison.OrdinalIgnoreCase)) && !string.Equals(duration, "NOT_IMPLEMENTED", StringComparison.OrdinalIgnoreCase))
@ -748,7 +747,7 @@ namespace Emby.Dlna.PlayTo
} }
var positionElem = result.Document.Descendants(uPnpNamespaces.AvTransport + "GetPositionInfoResponse").Select(i => i.Element("RelTime")).FirstOrDefault(i => i != null); var positionElem = result.Document.Descendants(uPnpNamespaces.AvTransport + "GetPositionInfoResponse").Select(i => i.Element("RelTime")).FirstOrDefault(i => i != null);
var position = positionElem == null ? null : positionElem.Value; var position = positionElem?.Value;
if (!string.IsNullOrWhiteSpace(position) && !string.Equals(position, "NOT_IMPLEMENTED", StringComparison.OrdinalIgnoreCase)) if (!string.IsNullOrWhiteSpace(position) && !string.Equals(position, "NOT_IMPLEMENTED", StringComparison.OrdinalIgnoreCase))
{ {
@ -819,7 +818,7 @@ namespace Emby.Dlna.PlayTo
// some devices send back invalid xml // some devices send back invalid xml
try try
{ {
return XElement.Parse(xml.Replace("&", "&amp;")); return XElement.Parse(xml.Replace("&", "&amp;", StringComparison.Ordinal));
} }
catch (XmlException) catch (XmlException)
{ {
@ -848,7 +847,7 @@ namespace Emby.Dlna.PlayTo
ParentId = container.GetAttributeValue(uPnpNamespaces.ParentId), ParentId = container.GetAttributeValue(uPnpNamespaces.ParentId),
Title = container.GetValue(uPnpNamespaces.title), Title = container.GetValue(uPnpNamespaces.title),
IconUrl = container.GetValue(uPnpNamespaces.Artwork), IconUrl = container.GetValue(uPnpNamespaces.Artwork),
SecondText = "", SecondText = string.Empty,
Url = url, Url = url,
ProtocolInfo = GetProtocolInfo(container), ProtocolInfo = GetProtocolInfo(container),
MetaData = container.ToString() MetaData = container.ToString()
@ -941,12 +940,12 @@ namespace Emby.Dlna.PlayTo
return url; return url;
} }
if (!url.Contains("/")) if (!url.Contains('/', StringComparison.Ordinal))
{ {
url = "/dmr/" + url; url = "/dmr/" + url;
} }
if (!url.StartsWith("/")) if (!url.StartsWith("/", StringComparison.Ordinal))
{ {
url = "/" + url; url = "/" + url;
} }
@ -981,7 +980,7 @@ namespace Emby.Dlna.PlayTo
var deviceProperties = new DeviceInfo() var deviceProperties = new DeviceInfo()
{ {
Name = string.Join(" ", friendlyNames), Name = string.Join(" ", friendlyNames),
BaseUrl = string.Format("http://{0}:{1}", url.Host, url.Port) BaseUrl = string.Format(CultureInfo.InvariantCulture, "http://{0}:{1}", url.Host, url.Port)
}; };
var model = document.Descendants(uPnpNamespaces.ud.GetName("modelName")).FirstOrDefault(); var model = document.Descendants(uPnpNamespaces.ud.GetName("modelName")).FirstOrDefault();
@ -1068,10 +1067,9 @@ namespace Emby.Dlna.PlayTo
} }
} }
return new Device(deviceProperties, httpClient, logger, config); return new Device(deviceProperties, httpClient, logger);
} }
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
private static DeviceIcon CreateIcon(XElement element) private static DeviceIcon CreateIcon(XElement element)
{ {
if (element == null) if (element == null)
@ -1222,7 +1220,7 @@ namespace Emby.Dlna.PlayTo
public override string ToString() public override string ToString()
{ {
return string.Format("{0} - {1}", Properties.Name, Properties.BaseUrl); return string.Format(CultureInfo.InvariantCulture, "{0} - {1}", Properties.Name, Properties.BaseUrl);
} }
} }
} }

View File

@ -2,6 +2,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Xml.Linq; using System.Xml.Linq;
using Emby.Dlna.Common; using Emby.Dlna.Common;
@ -11,14 +12,16 @@ namespace Emby.Dlna.PlayTo
{ {
public class TransportCommands public class TransportCommands
{ {
private const string CommandBase = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" + "<SOAP-ENV:Body>" + "<m:{0} xmlns:m=\"{1}\">" + "{2}" + "</m:{0}>" + "</SOAP-ENV:Body></SOAP-ENV:Envelope>";
private List<StateVariable> _stateVariables = new List<StateVariable>(); private List<StateVariable> _stateVariables = new List<StateVariable>();
private List<ServiceAction> _serviceActions = new List<ServiceAction>();
public List<StateVariable> StateVariables public List<StateVariable> StateVariables
{ {
get => _stateVariables; get => _stateVariables;
set => _stateVariables = value; set => _stateVariables = value;
} }
private List<ServiceAction> _serviceActions = new List<ServiceAction>();
public List<ServiceAction> ServiceActions public List<ServiceAction> ServiceActions
{ {
get => _serviceActions; get => _serviceActions;
@ -123,7 +126,7 @@ namespace Emby.Dlna.PlayTo
} }
} }
return string.Format(CommandBase, action.Name, xmlNamespace, stateString); return string.Format(CultureInfo.InvariantCulture, CommandBase, action.Name, xmlNamespace, stateString);
} }
public string BuildPost(ServiceAction action, string xmlNamesapce, object value, string commandParameter = "") public string BuildPost(ServiceAction action, string xmlNamesapce, object value, string commandParameter = "")
@ -147,7 +150,7 @@ namespace Emby.Dlna.PlayTo
} }
} }
return string.Format(CommandBase, action.Name, xmlNamesapce, stateString); return string.Format(CultureInfo.InvariantCulture, CommandBase, action.Name, xmlNamesapce, stateString);
} }
public string BuildPost(ServiceAction action, string xmlNamesapce, object value, Dictionary<string, string> dictionary) public string BuildPost(ServiceAction action, string xmlNamesapce, object value, Dictionary<string, string> dictionary)
@ -170,7 +173,7 @@ namespace Emby.Dlna.PlayTo
} }
} }
return string.Format(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 = "")
@ -183,12 +186,10 @@ namespace Emby.Dlna.PlayTo
state.AllowedValues.FirstOrDefault() ?? state.AllowedValues.FirstOrDefault() ??
value; value;
return string.Format("<{0} xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"{1}\">{2}</{0}>", argument.Name, state.DataType ?? "string", sendValue); return string.Format(CultureInfo.InvariantCulture, "<{0} xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"{1}\">{2}</{0}>", argument.Name, state.DataType ?? "string", sendValue);
} }
return string.Format("<{0}>{1}</{0}>", argument.Name, value); return string.Format(CultureInfo.InvariantCulture, "<{0}>{1}</{0}>", argument.Name, value);
} }
private const string CommandBase = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" + "<SOAP-ENV:Body>" + "<m:{0} xmlns:m=\"{1}\">" + "{2}" + "</m:{0}>" + "</SOAP-ENV:Body></SOAP-ENV:Envelope>";
} }
} }

View File

@ -4560,13 +4560,13 @@ namespace Emby.Server.Implementations.Data
if (query.AncestorIds.Length > 1) if (query.AncestorIds.Length > 1)
{ {
var inClause = string.Join(",", query.AncestorIds.Select(i => "'" + i.ToString("N", CultureInfo.InvariantCulture) + "'")); var inClause = string.Join(",", query.AncestorIds.Select(i => "'" + i.ToString("N", CultureInfo.InvariantCulture) + "'"));
whereClauses.Add(string.Format("Guid in (select itemId from AncestorIds where AncestorIdText in ({0}))", inClause)); whereClauses.Add(string.Format(CultureInfo.InvariantCulture, "Guid in (select itemId from AncestorIds where AncestorIdText in ({0}))", inClause));
} }
if (!string.IsNullOrWhiteSpace(query.AncestorWithPresentationUniqueKey)) if (!string.IsNullOrWhiteSpace(query.AncestorWithPresentationUniqueKey))
{ {
var inClause = "select guid from TypedBaseItems where PresentationUniqueKey=@AncestorWithPresentationUniqueKey"; var inClause = "select guid from TypedBaseItems where PresentationUniqueKey=@AncestorWithPresentationUniqueKey";
whereClauses.Add(string.Format("Guid in (select itemId from AncestorIds where AncestorId in ({0}))", inClause)); whereClauses.Add(string.Format(CultureInfo.InvariantCulture, "Guid in (select itemId from AncestorIds where AncestorId in ({0}))", inClause));
if (statement != null) if (statement != null)
{ {
statement.TryBind("@AncestorWithPresentationUniqueKey", query.AncestorWithPresentationUniqueKey); statement.TryBind("@AncestorWithPresentationUniqueKey", query.AncestorWithPresentationUniqueKey);

View File

@ -230,7 +230,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
if (filters.Count > 0) if (filters.Count > 0)
{ {
output += string.Format(" -vf \"{0}\"", string.Join(",", filters.ToArray())); output += string.Format(CultureInfo.InvariantCulture, " -vf \"{0}\"", string.Join(",", filters.ToArray()));
} }
return output; return output;

View File

@ -237,7 +237,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
&& !programInfo.IsRepeat && !programInfo.IsRepeat
&& (programInfo.EpisodeNumber ?? 0) == 0) && (programInfo.EpisodeNumber ?? 0) == 0)
{ {
programInfo.ShowId = programInfo.ShowId + programInfo.StartDate.Ticks.ToString(CultureInfo.InvariantCulture); programInfo.ShowId += programInfo.StartDate.Ticks.ToString(CultureInfo.InvariantCulture);
} }
} }
else else
@ -246,7 +246,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
} }
// Construct an id from the channel and start date // Construct an id from the channel and start date
programInfo.Id = string.Format("{0}_{1:O}", program.ChannelId, program.StartDate); programInfo.Id = string.Format(CultureInfo.InvariantCulture, "{0}_{1:O}", program.ChannelId, program.StartDate);
if (programInfo.IsMovie) if (programInfo.IsMovie)
{ {
@ -296,7 +296,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings
Name = c.DisplayName, Name = c.DisplayName,
ImageUrl = c.Icon != null && !string.IsNullOrEmpty(c.Icon.Source) ? c.Icon.Source : null, ImageUrl = c.Icon != null && !string.IsNullOrEmpty(c.Icon.Source) ? c.Icon.Source : null,
Number = string.IsNullOrWhiteSpace(c.Number) ? c.Id : c.Number Number = string.IsNullOrWhiteSpace(c.Number) ? c.Id : c.Number
}).ToList(); }).ToList();
} }
} }

View File

@ -41,6 +41,7 @@ namespace Emby.Server.Implementations.LiveTv
/// </summary> /// </summary>
public class LiveTvManager : ILiveTvManager, IDisposable public class LiveTvManager : ILiveTvManager, IDisposable
{ {
private const int MaxGuideDays = 14;
private const string ExternalServiceTag = "ExternalServiceId"; private const string ExternalServiceTag = "ExternalServiceId";
private const string EtagKey = "ProgramEtag"; private const string EtagKey = "ProgramEtag";
@ -560,7 +561,7 @@ namespace Emby.Server.Implementations.LiveTv
item.Audio = info.Audio; item.Audio = info.Audio;
item.ChannelId = channel.Id; item.ChannelId = channel.Id;
item.CommunityRating = item.CommunityRating ?? info.CommunityRating; item.CommunityRating ??= info.CommunityRating;
if ((item.CommunityRating ?? 0).Equals(0)) if ((item.CommunityRating ?? 0).Equals(0))
{ {
item.CommunityRating = null; item.CommunityRating = null;
@ -645,8 +646,8 @@ namespace Emby.Server.Implementations.LiveTv
item.IsSeries = isSeries; item.IsSeries = isSeries;
item.Name = info.Name; item.Name = info.Name;
item.OfficialRating = item.OfficialRating ?? info.OfficialRating; item.OfficialRating ??= info.OfficialRating;
item.Overview = item.Overview ?? info.Overview; item.Overview ??= info.Overview;
item.RunTimeTicks = (info.EndDate - info.StartDate).Ticks; item.RunTimeTicks = (info.EndDate - info.StartDate).Ticks;
item.ProviderIds = info.ProviderIds; item.ProviderIds = info.ProviderIds;
@ -683,19 +684,23 @@ namespace Emby.Server.Implementations.LiveTv
{ {
if (!string.IsNullOrWhiteSpace(info.ImagePath)) if (!string.IsNullOrWhiteSpace(info.ImagePath))
{ {
item.SetImage(new ItemImageInfo item.SetImage(
{ new ItemImageInfo
Path = info.ImagePath, {
Type = ImageType.Primary Path = info.ImagePath,
}, 0); Type = ImageType.Primary
},
0);
} }
else if (!string.IsNullOrWhiteSpace(info.ImageUrl)) else if (!string.IsNullOrWhiteSpace(info.ImageUrl))
{ {
item.SetImage(new ItemImageInfo item.SetImage(
{ new ItemImageInfo
Path = info.ImageUrl, {
Type = ImageType.Primary Path = info.ImageUrl,
}, 0); Type = ImageType.Primary
},
0);
} }
} }
@ -703,11 +708,13 @@ namespace Emby.Server.Implementations.LiveTv
{ {
if (!string.IsNullOrWhiteSpace(info.ThumbImageUrl)) if (!string.IsNullOrWhiteSpace(info.ThumbImageUrl))
{ {
item.SetImage(new ItemImageInfo item.SetImage(
{ new ItemImageInfo
Path = info.ThumbImageUrl, {
Type = ImageType.Thumb Path = info.ThumbImageUrl,
}, 0); Type = ImageType.Thumb
},
0);
} }
} }
@ -715,11 +722,13 @@ namespace Emby.Server.Implementations.LiveTv
{ {
if (!string.IsNullOrWhiteSpace(info.LogoImageUrl)) if (!string.IsNullOrWhiteSpace(info.LogoImageUrl))
{ {
item.SetImage(new ItemImageInfo item.SetImage(
{ new ItemImageInfo
Path = info.LogoImageUrl, {
Type = ImageType.Logo Path = info.LogoImageUrl,
}, 0); Type = ImageType.Logo
},
0);
} }
} }
@ -727,11 +736,13 @@ namespace Emby.Server.Implementations.LiveTv
{ {
if (!string.IsNullOrWhiteSpace(info.BackdropImageUrl)) if (!string.IsNullOrWhiteSpace(info.BackdropImageUrl))
{ {
item.SetImage(new ItemImageInfo item.SetImage(
{ new ItemImageInfo
Path = info.BackdropImageUrl, {
Type = ImageType.Backdrop Path = info.BackdropImageUrl,
}, 0); Type = ImageType.Backdrop
},
0);
} }
} }
@ -786,7 +797,6 @@ namespace Emby.Server.Implementations.LiveTv
if (query.OrderBy.Count == 0) if (query.OrderBy.Count == 0)
{ {
// Unless something else was specified, order by start date to take advantage of a specialized index // Unless something else was specified, order by start date to take advantage of a specialized index
query.OrderBy = new[] query.OrderBy = new[]
{ {
@ -824,7 +834,7 @@ namespace Emby.Server.Implementations.LiveTv
if (!string.IsNullOrWhiteSpace(query.SeriesTimerId)) if (!string.IsNullOrWhiteSpace(query.SeriesTimerId))
{ {
var seriesTimers = await GetSeriesTimersInternal(new SeriesTimerQuery { }, cancellationToken).ConfigureAwait(false); var seriesTimers = await GetSeriesTimersInternal(new SeriesTimerQuery(), cancellationToken).ConfigureAwait(false);
var seriesTimer = seriesTimers.Items.FirstOrDefault(i => string.Equals(_tvDtoService.GetInternalSeriesTimerId(i.Id).ToString("N", CultureInfo.InvariantCulture), query.SeriesTimerId, StringComparison.OrdinalIgnoreCase)); var seriesTimer = seriesTimers.Items.FirstOrDefault(i => string.Equals(_tvDtoService.GetInternalSeriesTimerId(i.Id).ToString("N", CultureInfo.InvariantCulture), query.SeriesTimerId, StringComparison.OrdinalIgnoreCase));
if (seriesTimer != null) if (seriesTimer != null)
{ {
@ -847,13 +857,11 @@ namespace Emby.Server.Implementations.LiveTv
var returnArray = _dtoService.GetBaseItemDtos(queryResult.Items, options, user); var returnArray = _dtoService.GetBaseItemDtos(queryResult.Items, options, user);
var result = new QueryResult<BaseItemDto> return new QueryResult<BaseItemDto>
{ {
Items = returnArray, Items = returnArray,
TotalRecordCount = queryResult.TotalRecordCount TotalRecordCount = queryResult.TotalRecordCount
}; };
return result;
} }
public QueryResult<BaseItem> GetRecommendedProgramsInternal(InternalItemsQuery query, DtoOptions options, CancellationToken cancellationToken) public QueryResult<BaseItem> GetRecommendedProgramsInternal(InternalItemsQuery query, DtoOptions options, CancellationToken cancellationToken)
@ -1173,7 +1181,6 @@ namespace Emby.Server.Implementations.LiveTv
var existingPrograms = _libraryManager.GetItemList(new InternalItemsQuery var existingPrograms = _libraryManager.GetItemList(new InternalItemsQuery
{ {
IncludeItemTypes = new string[] { typeof(LiveTvProgram).Name }, IncludeItemTypes = new string[] { typeof(LiveTvProgram).Name },
ChannelIds = new Guid[] { currentChannel.Id }, ChannelIds = new Guid[] { currentChannel.Id },
DtoOptions = new DtoOptions(true) DtoOptions = new DtoOptions(true)
@ -1298,8 +1305,6 @@ namespace Emby.Server.Implementations.LiveTv
} }
} }
private const int MaxGuideDays = 14;
private double GetGuideDays() private double GetGuideDays()
{ {
var config = GetConfiguration(); var config = GetConfiguration();
@ -1712,7 +1717,7 @@ namespace Emby.Server.Implementations.LiveTv
if (timer == null) if (timer == null)
{ {
throw new ResourceNotFoundException(string.Format("Timer with Id {0} not found", id)); throw new ResourceNotFoundException(string.Format(CultureInfo.InvariantCulture, "Timer with Id {0} not found", id));
} }
var service = GetService(timer.ServiceName); var service = GetService(timer.ServiceName);
@ -1731,7 +1736,7 @@ namespace Emby.Server.Implementations.LiveTv
if (timer == null) if (timer == null)
{ {
throw new ResourceNotFoundException(string.Format("SeriesTimer with Id {0} not found", id)); throw new ResourceNotFoundException(string.Format(CultureInfo.InvariantCulture, "SeriesTimer with Id {0} not found", id));
} }
var service = GetService(timer.ServiceName); var service = GetService(timer.ServiceName);
@ -1743,10 +1748,12 @@ namespace Emby.Server.Implementations.LiveTv
public async Task<TimerInfoDto> GetTimer(string id, CancellationToken cancellationToken) public async Task<TimerInfoDto> GetTimer(string id, CancellationToken cancellationToken)
{ {
var results = await GetTimers(new TimerQuery var results = await GetTimers(
{ new TimerQuery
Id = id {
}, cancellationToken).ConfigureAwait(false); Id = id
},
cancellationToken).ConfigureAwait(false);
return results.Items.FirstOrDefault(i => string.Equals(i.Id, id, StringComparison.OrdinalIgnoreCase)); return results.Items.FirstOrDefault(i => string.Equals(i.Id, id, StringComparison.OrdinalIgnoreCase));
} }
@ -1794,10 +1801,7 @@ namespace Emby.Server.Implementations.LiveTv
} }
var returnArray = timers var returnArray = timers
.Select(i => .Select(i => i.Item1)
{
return i.Item1;
})
.ToArray(); .ToArray();
return new QueryResult<SeriesTimerInfo> return new QueryResult<SeriesTimerInfo>
@ -1968,7 +1972,7 @@ namespace Emby.Server.Implementations.LiveTv
if (service == null) if (service == null)
{ {
service = _services.First(); service = _services[0];
} }
var info = await service.GetNewTimerDefaultsAsync(cancellationToken, programInfo).ConfigureAwait(false); var info = await service.GetNewTimerDefaultsAsync(cancellationToken, programInfo).ConfigureAwait(false);
@ -1994,9 +1998,7 @@ namespace Emby.Server.Implementations.LiveTv
{ {
var info = await GetNewTimerDefaultsInternal(cancellationToken).ConfigureAwait(false); var info = await GetNewTimerDefaultsInternal(cancellationToken).ConfigureAwait(false);
var obj = _tvDtoService.GetSeriesTimerInfoDto(info.Item1, info.Item2, null); return _tvDtoService.GetSeriesTimerInfoDto(info.Item1, info.Item2, null);
return obj;
} }
public async Task<SeriesTimerInfoDto> GetNewTimerDefaults(string programId, CancellationToken cancellationToken) public async Task<SeriesTimerInfoDto> GetNewTimerDefaults(string programId, CancellationToken cancellationToken)
@ -2125,6 +2127,7 @@ namespace Emby.Server.Implementations.LiveTv
public void Dispose() public void Dispose()
{ {
Dispose(true); Dispose(true);
GC.SuppressFinalize(this);
} }
private bool _disposed = false; private bool _disposed = false;
@ -2447,8 +2450,7 @@ namespace Emby.Server.Implementations.LiveTv
.SelectMany(i => i.Locations) .SelectMany(i => i.Locations)
.Distinct(StringComparer.OrdinalIgnoreCase) .Distinct(StringComparer.OrdinalIgnoreCase)
.Select(i => _libraryManager.FindByPath(i, true)) .Select(i => _libraryManager.FindByPath(i, true))
.Where(i => i != null) .Where(i => i != null && i.IsVisibleStandalone(user))
.Where(i => i.IsVisibleStandalone(user))
.SelectMany(i => _libraryManager.GetCollectionFolders(i)) .SelectMany(i => _libraryManager.GetCollectionFolders(i))
.GroupBy(x => x.Id) .GroupBy(x => x.Id)
.Select(x => x.First()) .Select(x => x.First())

View File

@ -182,12 +182,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{ {
var model = await GetModelInfo(info, false, cancellationToken).ConfigureAwait(false); var model = await GetModelInfo(info, false, cancellationToken).ConfigureAwait(false);
using (var response = await _httpClient.SendAsync(new HttpRequestOptions() using (var response = await _httpClient.SendAsync(
{ new HttpRequestOptions()
Url = string.Format("{0}/tuners.html", GetApiUrl(info)), {
CancellationToken = cancellationToken, Url = string.Format(CultureInfo.InvariantCulture, "{0}/tuners.html", GetApiUrl(info)),
BufferContent = false CancellationToken = cancellationToken,
}, HttpMethod.Get).ConfigureAwait(false)) BufferContent = false
},
HttpMethod.Get).ConfigureAwait(false))
using (var stream = response.Content) using (var stream = response.Content)
using (var sr = new StreamReader(stream, System.Text.Encoding.UTF8)) using (var sr = new StreamReader(stream, System.Text.Encoding.UTF8))
{ {
@ -730,7 +732,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
// Need a way to set the Receive timeout on the socket otherwise this might never timeout? // Need a way to set the Receive timeout on the socket otherwise this might never timeout?
try try
{ {
await udpClient.SendToAsync(discBytes, 0, discBytes.Length, new IPEndPoint(IPAddress.Parse("255.255.255.255"), 65001), cancellationToken); await udpClient.SendToAsync(discBytes, 0, discBytes.Length, new IPEndPoint(IPAddress.Parse("255.255.255.255"), 65001), cancellationToken).ConfigureAwait(false);
var receiveBuffer = new byte[8192]; var receiveBuffer = new byte[8192];
while (!cancellationToken.IsCancellationRequested) while (!cancellationToken.IsCancellationRequested)

View File

@ -113,7 +113,7 @@ namespace Jellyfin.Api.Controllers
user.ProfileImage = new Data.Entities.ImageInfo(Path.Combine(userDataPath, "profile" + MimeTypes.ToExtension(mimeType))); user.ProfileImage = new Data.Entities.ImageInfo(Path.Combine(userDataPath, "profile" + MimeTypes.ToExtension(mimeType)));
await _providerManager await _providerManager
.SaveImage(user, memoryStream, mimeType, user.ProfileImage.Path) .SaveImage(memoryStream, mimeType, user.ProfileImage.Path)
.ConfigureAwait(false); .ConfigureAwait(false);
await _userManager.UpdateUserAsync(user).ConfigureAwait(false); await _userManager.UpdateUserAsync(user).ConfigureAwait(false);

View File

@ -1,5 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using System.Threading; using System.Threading;
@ -179,7 +181,7 @@ namespace MediaBrowser.Controller.Entities.Movies
list.Add(new ExternalUrl list.Add(new ExternalUrl
{ {
Name = "Trakt", Name = "Trakt",
Url = string.Format("https://trakt.tv/movies/{0}", imdbId) Url = string.Format(CultureInfo.InvariantCulture, "https://trakt.tv/movies/{0}", imdbId)
}); });
} }

View File

@ -496,7 +496,7 @@ namespace MediaBrowser.Controller.Entities.TV
list.Add(new ExternalUrl list.Add(new ExternalUrl
{ {
Name = "Trakt", Name = "Trakt",
Url = string.Format("https://trakt.tv/shows/{0}", imdbId) Url = string.Format(CultureInfo.InvariantCulture, "https://trakt.tv/shows/{0}", imdbId)
}); });
} }

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using Jellyfin.Data.Enums; using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Providers;
@ -86,7 +87,7 @@ namespace MediaBrowser.Controller.Entities
list.Add(new ExternalUrl list.Add(new ExternalUrl
{ {
Name = "Trakt", Name = "Trakt",
Url = string.Format("https://trakt.tv/movies/{0}", imdbId) Url = string.Format(CultureInfo.InvariantCulture, "https://trakt.tv/movies/{0}", imdbId)
}); });
} }

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace MediaBrowser.Controller.Library namespace MediaBrowser.Controller.Library
@ -13,6 +14,7 @@ namespace MediaBrowser.Controller.Library
/// The name. /// The name.
/// </summary> /// </summary>
readonly string _name; readonly string _name;
/// <summary> /// <summary>
/// The stopwatch. /// The stopwatch.
/// </summary> /// </summary>
@ -44,6 +46,7 @@ namespace MediaBrowser.Controller.Library
public void Dispose() public void Dispose()
{ {
Dispose(true); Dispose(true);
GC.SuppressFinalize(this);
} }
/// <summary> /// <summary>
@ -58,13 +61,19 @@ namespace MediaBrowser.Controller.Library
string message; string message;
if (_stopwatch.ElapsedMilliseconds > 300000) if (_stopwatch.ElapsedMilliseconds > 300000)
{ {
message = string.Format("{0} took {1} minutes.", message = string.Format(
_name, ((float)_stopwatch.ElapsedMilliseconds / 60000).ToString("F")); CultureInfo.InvariantCulture,
"{0} took {1} minutes.",
_name,
((float)_stopwatch.ElapsedMilliseconds / 60000).ToString("F", CultureInfo.InvariantCulture));
} }
else else
{ {
message = string.Format("{0} took {1} seconds.", message = string.Format(
_name, ((float)_stopwatch.ElapsedMilliseconds / 1000).ToString("#0.000")); CultureInfo.InvariantCulture,
"{0} took {1} seconds.",
_name,
((float)_stopwatch.ElapsedMilliseconds / 1000).ToString("#0.000", CultureInfo.InvariantCulture));
} }
_logger.LogInformation(message); _logger.LogInformation(message);

View File

@ -63,7 +63,7 @@ namespace MediaBrowser.Controller.LiveTv
if (double.TryParse(Number, NumberStyles.Any, CultureInfo.InvariantCulture, out number)) if (double.TryParse(Number, NumberStyles.Any, CultureInfo.InvariantCulture, out number))
{ {
return string.Format("{0:00000.0}", number) + "-" + (Name ?? string.Empty); return string.Format(CultureInfo.InvariantCulture, "{0:00000.0}", number) + "-" + (Name ?? string.Empty);
} }
} }

View File

@ -261,7 +261,7 @@ namespace MediaBrowser.Controller.LiveTv
list.Add(new ExternalUrl list.Add(new ExternalUrl
{ {
Name = "Trakt", Name = "Trakt",
Url = string.Format("https://trakt.tv/movies/{0}", imdbId) Url = string.Format(CultureInfo.InvariantCulture, "https://trakt.tv/movies/{0}", imdbId)
}); });
} }
} }

View File

@ -675,7 +675,7 @@ namespace MediaBrowser.Controller.MediaEncoding
// } // }
// } // }
// fallbackFontParam = string.Format(":force_style='FontName=Droid Sans Fallback':fontsdir='{0}'", _mediaEncoder.EscapeSubtitleFilterPath(_fileSystem.GetDirectoryName(fallbackFontPath))); // fallbackFontParam = string.Format(CultureInfo.InvariantCulture, ":force_style='FontName=Droid Sans Fallback':fontsdir='{0}'", _mediaEncoder.EscapeSubtitleFilterPath(_fileSystem.GetDirectoryName(fallbackFontPath)));
if (state.SubtitleStream.IsExternal) if (state.SubtitleStream.IsExternal)
{ {
@ -880,7 +880,7 @@ namespace MediaBrowser.Controller.MediaEncoding
profileScore = Math.Min(profileScore, 2); profileScore = Math.Min(profileScore, 2);
// http://www.webmproject.org/docs/encoder-parameters/ // http://www.webmproject.org/docs/encoder-parameters/
param += string.Format("-speed 16 -quality good -profile:v {0} -slices 8 -crf {1} -qmin {2} -qmax {3}", param += string.Format(CultureInfo.InvariantCulture, "-speed 16 -quality good -profile:v {0} -slices 8 -crf {1} -qmin {2} -qmax {3}",
profileScore.ToString(_usCulture), profileScore.ToString(_usCulture),
crf, crf,
qmin, qmin,
@ -904,7 +904,7 @@ namespace MediaBrowser.Controller.MediaEncoding
var framerate = GetFramerateParam(state); var framerate = GetFramerateParam(state);
if (framerate.HasValue) if (framerate.HasValue)
{ {
param += string.Format(" -r {0}", framerate.Value.ToString(_usCulture)); param += string.Format(CultureInfo.InvariantCulture, " -r {0}", framerate.Value.ToString(_usCulture));
} }
var targetVideoCodec = state.ActualOutputVideoCodec; var targetVideoCodec = state.ActualOutputVideoCodec;
@ -1484,7 +1484,7 @@ namespace MediaBrowser.Controller.MediaEncoding
if (time > 0) if (time > 0)
{ {
return string.Format("-ss {0}", _mediaEncoder.GetTimeParameter(time)); return string.Format(CultureInfo.InvariantCulture, "-ss {0}", _mediaEncoder.GetTimeParameter(time));
} }
return string.Empty; return string.Empty;

View File

@ -72,7 +72,7 @@ namespace MediaBrowser.Controller.Providers
/// <returns>Task.</returns> /// <returns>Task.</returns>
Task SaveImage(BaseItem item, string source, string mimeType, ImageType type, int? imageIndex, bool? saveLocallyWithMedia, CancellationToken cancellationToken); Task SaveImage(BaseItem item, string source, string mimeType, ImageType type, int? imageIndex, bool? saveLocallyWithMedia, CancellationToken cancellationToken);
Task SaveImage(User user, Stream source, string mimeType, string path); Task SaveImage(Stream source, string mimeType, string path);
/// <summary> /// <summary>
/// Adds the metadata providers. /// Adds the metadata providers.

View File

@ -1,6 +1,7 @@
#pragma warning disable CS1591 #pragma warning disable CS1591
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.MediaInfo;
@ -14,7 +15,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
{ {
var url = inputFiles[0]; var url = inputFiles[0];
return string.Format("\"{0}\"", url); return string.Format(CultureInfo.InvariantCulture, "\"{0}\"", url);
} }
return GetConcatInputArgument(inputFiles); return GetConcatInputArgument(inputFiles);
@ -33,7 +34,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
{ {
var files = string.Join("|", inputFiles.Select(NormalizePath)); var files = string.Join("|", inputFiles.Select(NormalizePath));
return string.Format("concat:\"{0}\"", files); return string.Format(CultureInfo.InvariantCulture, "concat:\"{0}\"", files);
} }
// Determine the input path for video files // Determine the input path for video files
@ -49,13 +50,13 @@ namespace MediaBrowser.MediaEncoding.Encoder
{ {
if (path.IndexOf("://") != -1) if (path.IndexOf("://") != -1)
{ {
return string.Format("\"{0}\"", path); return string.Format(CultureInfo.InvariantCulture, "\"{0}\"", path);
} }
// Quotes are valid path characters in linux and they need to be escaped here with a leading \ // Quotes are valid path characters in linux and they need to be escaped here with a leading \
path = NormalizePath(path); path = NormalizePath(path);
return string.Format("file:\"{0}\"", path); return string.Format(CultureInfo.InvariantCulture, "file:\"{0}\"", path);
} }
/// <summary> /// <summary>

View File

@ -552,8 +552,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
// Use ffmpeg to sample 100 (we can drop this if required using thumbnail=50 for 50 frames) frames and pick the best thumbnail. Have a fall back just in case. // Use ffmpeg to sample 100 (we can drop this if required using thumbnail=50 for 50 frames) frames and pick the best thumbnail. Have a fall back just in case.
var thumbnail = enableThumbnail ? ",thumbnail=24" : string.Empty; var thumbnail = enableThumbnail ? ",thumbnail=24" : string.Empty;
var args = useIFrame ? string.Format("-i {0}{3} -threads 0 -v quiet -vframes 1 -vf \"{2}{4}\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg, thumbnail) : var args = useIFrame ? string.Format(CultureInfo.InvariantCulture, "-i {0}{3} -threads 0 -v quiet -vframes 1 -vf \"{2}{4}\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg, thumbnail) :
string.Format("-i {0}{3} -threads 0 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg); string.Format(CultureInfo.InvariantCulture, "-i {0}{3} -threads 0 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg);
var probeSizeArgument = EncodingHelper.GetProbeSizeArgument(1); var probeSizeArgument = EncodingHelper.GetProbeSizeArgument(1);
var analyzeDurationArgument = EncodingHelper.GetAnalyzeDurationArgument(1); var analyzeDurationArgument = EncodingHelper.GetAnalyzeDurationArgument(1);
@ -570,7 +570,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (offset.HasValue) if (offset.HasValue)
{ {
args = string.Format("-ss {0} ", GetTimeParameter(offset.Value)) + args; args = string.Format(CultureInfo.InvariantCulture, "-ss {0} ", GetTimeParameter(offset.Value)) + args;
} }
if (videoStream != null) if (videoStream != null)
@ -641,7 +641,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (exitCode == -1 || !file.Exists || file.Length == 0) if (exitCode == -1 || !file.Exists || file.Length == 0)
{ {
var msg = string.Format("ffmpeg image extraction failed for {0}", inputPath); var msg = string.Format(CultureInfo.InvariantCulture, "ffmpeg image extraction failed for {0}", inputPath);
_logger.LogError(msg); _logger.LogError(msg);
@ -684,13 +684,13 @@ namespace MediaBrowser.MediaEncoding.Encoder
{ {
var maxWidthParam = maxWidth.Value.ToString(_usCulture); var maxWidthParam = maxWidth.Value.ToString(_usCulture);
vf += string.Format(",scale=min(iw\\,{0}):trunc(ow/dar/2)*2", maxWidthParam); vf += string.Format(CultureInfo.InvariantCulture, ",scale=min(iw\\,{0}):trunc(ow/dar/2)*2", maxWidthParam);
} }
Directory.CreateDirectory(targetDirectory); Directory.CreateDirectory(targetDirectory);
var outputPath = Path.Combine(targetDirectory, filenamePrefix + "%05d.jpg"); var outputPath = Path.Combine(targetDirectory, filenamePrefix + "%05d.jpg");
var args = string.Format("-i {0} -threads 0 -v quiet -vf \"{2}\" -f image2 \"{1}\"", inputArgument, outputPath, vf); var args = string.Format(CultureInfo.InvariantCulture, "-i {0} -threads 0 -v quiet -vf \"{2}\" -f image2 \"{1}\"", inputArgument, outputPath, vf);
var probeSizeArgument = EncodingHelper.GetProbeSizeArgument(1); var probeSizeArgument = EncodingHelper.GetProbeSizeArgument(1);
var analyzeDurationArgument = EncodingHelper.GetAnalyzeDurationArgument(1); var analyzeDurationArgument = EncodingHelper.GetAnalyzeDurationArgument(1);
@ -790,7 +790,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (exitCode == -1) if (exitCode == -1)
{ {
var msg = string.Format("ffmpeg image extraction failed for {0}", inputArgument); var msg = string.Format(CultureInfo.InvariantCulture, "ffmpeg image extraction failed for {0}", inputArgument);
_logger.LogError(msg); _logger.LogError(msg);

View File

@ -435,7 +435,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
CreateNoWindow = true, CreateNoWindow = true,
UseShellExecute = false, UseShellExecute = false,
FileName = _mediaEncoder.EncoderPath, FileName = _mediaEncoder.EncoderPath,
Arguments = string.Format("{0} -i \"{1}\" -c:s srt \"{2}\"", encodingParam, inputPath, outputPath), Arguments = string.Format(CultureInfo.InvariantCulture, "{0} -i \"{1}\" -c:s srt \"{2}\"", encodingParam, inputPath, outputPath),
WindowStyle = ProcessWindowStyle.Hidden, WindowStyle = ProcessWindowStyle.Hidden,
ErrorDialog = false ErrorDialog = false
}, },

View File

@ -157,7 +157,7 @@ namespace MediaBrowser.Model.Dlna
// flagValue = flagValue | DlnaFlags.TimeBasedSeek; // 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)); DlnaMaps.FlagsToString(flagValue));
ResponseProfile mediaProfile = _profile.GetVideoMediaProfile(container, ResponseProfile mediaProfile = _profile.GetVideoMediaProfile(container,

View File

@ -1,18 +1,20 @@
#pragma warning disable CS1591 #pragma warning disable CS1591
using System.Globalization;
namespace MediaBrowser.Model.Dlna namespace MediaBrowser.Model.Dlna
{ {
public static class DlnaMaps public static class DlnaMaps
{ {
private static readonly string DefaultStreaming = private static readonly string DefaultStreaming =
FlagsToString(DlnaFlags.StreamingTransferMode | FlagsToString(DlnaFlags.StreamingTransferMode |
DlnaFlags.BackgroundTransferMode | DlnaFlags.BackgroundTransferMode |
DlnaFlags.ConnectionStall | DlnaFlags.ConnectionStall |
DlnaFlags.ByteBasedSeek | DlnaFlags.ByteBasedSeek |
DlnaFlags.DlnaV15); DlnaFlags.DlnaV15);
private static readonly string DefaultInteractive = private static readonly string DefaultInteractive =
FlagsToString(DlnaFlags.InteractiveTransferMode | FlagsToString(DlnaFlags.InteractiveTransferMode |
DlnaFlags.BackgroundTransferMode | DlnaFlags.BackgroundTransferMode |
DlnaFlags.ConnectionStall | DlnaFlags.ConnectionStall |
DlnaFlags.ByteBasedSeek | DlnaFlags.ByteBasedSeek |
@ -20,7 +22,7 @@ namespace MediaBrowser.Model.Dlna
public static string FlagsToString(DlnaFlags flags) 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) public static string GetOrgOpValue(bool hasKnownRuntime, bool isDirectStream, TranscodeSeekInfo profileTranscodeSeekInfo)

View File

@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.MediaInfo;
@ -142,26 +143,26 @@ namespace MediaBrowser.Model.Dlna
{ {
if (timestampType == TransportStreamTimestamp.None) 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)) 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)) 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) || if (string.IsNullOrEmpty(audioCodec) ||
string.Equals(audioCodec, "ac3", StringComparison.OrdinalIgnoreCase)) 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)) 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"; 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)) else if (string.Equals(videoCodec, "mpeg4", StringComparison.OrdinalIgnoreCase) || string.Equals(videoCodec, "msmpeg4", StringComparison.OrdinalIgnoreCase))
{ {
if (string.Equals(audioCodec, "aac", 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)) 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)) 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)) 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)) };
} }
} }

View File

@ -191,7 +191,7 @@ namespace MediaBrowser.Model.Dlna
var encodedValue = pair.Value.Replace(" ", "%20"); 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()); string queryString = string.Join("&", list.ToArray());
@ -214,18 +214,18 @@ namespace MediaBrowser.Model.Dlna
{ {
if (string.Equals(SubProtocol, "hls", StringComparison.OrdinalIgnoreCase)) 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)) 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) private static List<NameValuePair> BuildParams(StreamInfo item, string accessToken)
@ -457,7 +457,7 @@ namespace MediaBrowser.Model.Dlna
{ {
if (MediaSource.Protocol == MediaProtocol.File || !string.Equals(stream.Codec, subtitleProfile.Format, StringComparison.OrdinalIgnoreCase) || !stream.IsExternal) 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, baseUrl,
ItemId, ItemId,
MediaSourceId, MediaSourceId,

View File

@ -187,7 +187,7 @@ namespace MediaBrowser.Providers.Manager
} }
} }
public async Task SaveImage(User user, Stream source, string path) public async Task SaveImage(Stream source, string path)
{ {
await SaveImageToLocation(source, path, path, CancellationToken.None).ConfigureAwait(false); await SaveImageToLocation(source, path, path, CancellationToken.None).ConfigureAwait(false);
} }
@ -355,7 +355,7 @@ namespace MediaBrowser.Providers.Manager
if (string.IsNullOrWhiteSpace(extension)) if (string.IsNullOrWhiteSpace(extension))
{ {
throw new ArgumentException(string.Format("Unable to determine image file extension from mime type {0}", mimeType)); throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Unable to determine image file extension from mime type {0}", mimeType));
} }
if (type == ImageType.Thumb && saveLocally) if (type == ImageType.Thumb && saveLocally)

View File

@ -54,7 +54,12 @@ namespace MediaBrowser.Providers.Manager
return hasChanges; return hasChanges;
} }
public async Task<RefreshResult> RefreshImages(BaseItem item, LibraryOptions libraryOptions, List<IImageProvider> providers, ImageRefreshOptions refreshOptions, MetadataOptions savedOptions, CancellationToken cancellationToken) public async Task<RefreshResult> RefreshImages(
BaseItem item,
LibraryOptions libraryOptions,
List<IImageProvider> providers,
ImageRefreshOptions refreshOptions,
CancellationToken cancellationToken)
{ {
if (refreshOptions.IsReplacingImage(ImageType.Backdrop)) if (refreshOptions.IsReplacingImage(ImageType.Backdrop))
{ {
@ -78,19 +83,15 @@ namespace MediaBrowser.Providers.Manager
foreach (var provider in providers) foreach (var provider in providers)
{ {
var remoteProvider = provider as IRemoteImageProvider; if (provider is IRemoteImageProvider remoteProvider)
if (remoteProvider != null)
{ {
await RefreshFromProvider(item, libraryOptions, remoteProvider, refreshOptions, typeOptions, backdropLimit, screenshotLimit, downloadedImages, result, cancellationToken).ConfigureAwait(false); await RefreshFromProvider(item, libraryOptions, remoteProvider, refreshOptions, typeOptions, backdropLimit, screenshotLimit, downloadedImages, result, cancellationToken).ConfigureAwait(false);
continue; continue;
} }
var dynamicImageProvider = provider as IDynamicImageProvider; if (provider is IDynamicImageProvider dynamicImageProvider)
if (dynamicImageProvider != null)
{ {
await RefreshFromProvider(item, dynamicImageProvider, refreshOptions, typeOptions, libraryOptions, downloadedImages, result, cancellationToken).ConfigureAwait(false); await RefreshFromProvider(item, dynamicImageProvider, refreshOptions, typeOptions, downloadedImages, result, cancellationToken).ConfigureAwait(false);
} }
} }
@ -100,11 +101,11 @@ namespace MediaBrowser.Providers.Manager
/// <summary> /// <summary>
/// Refreshes from provider. /// Refreshes from provider.
/// </summary> /// </summary>
private async Task RefreshFromProvider(BaseItem item, private async Task RefreshFromProvider(
BaseItem item,
IDynamicImageProvider provider, IDynamicImageProvider provider,
ImageRefreshOptions refreshOptions, ImageRefreshOptions refreshOptions,
TypeOptions savedOptions, TypeOptions savedOptions,
LibraryOptions libraryOptions,
ICollection<ImageType> downloadedImages, ICollection<ImageType> downloadedImages,
RefreshResult result, RefreshResult result,
CancellationToken cancellationToken) CancellationToken cancellationToken)
@ -115,7 +116,7 @@ namespace MediaBrowser.Providers.Manager
foreach (var imageType in images) foreach (var imageType in images)
{ {
if (!IsEnabled(savedOptions, imageType, item)) if (!IsEnabled(savedOptions, imageType))
{ {
continue; continue;
} }
@ -133,12 +134,13 @@ namespace MediaBrowser.Providers.Manager
if (response.Protocol == MediaProtocol.Http) if (response.Protocol == MediaProtocol.Http)
{ {
_logger.LogDebug("Setting image url into item {0}", item.Id); _logger.LogDebug("Setting image url into item {0}", item.Id);
item.SetImage(new ItemImageInfo item.SetImage(
{ new ItemImageInfo
Path = response.Path, {
Type = imageType Path = response.Path,
Type = imageType
}, 0); },
0);
} }
else else
{ {
@ -157,7 +159,7 @@ namespace MediaBrowser.Providers.Manager
} }
downloadedImages.Add(imageType); downloadedImages.Add(imageType);
result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate; result.UpdateType |= ItemUpdateType.ImageUpdate;
} }
} }
} }
@ -279,7 +281,7 @@ namespace MediaBrowser.Providers.Manager
foreach (var imageType in _singularImages) foreach (var imageType in _singularImages)
{ {
if (!IsEnabled(savedOptions, imageType, item)) if (!IsEnabled(savedOptions, imageType))
{ {
continue; continue;
} }
@ -299,8 +301,7 @@ namespace MediaBrowser.Providers.Manager
minWidth = savedOptions.GetMinWidth(ImageType.Backdrop); minWidth = savedOptions.GetMinWidth(ImageType.Backdrop);
await DownloadBackdrops(item, libraryOptions, ImageType.Backdrop, backdropLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false); await DownloadBackdrops(item, libraryOptions, ImageType.Backdrop, backdropLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false);
var hasScreenshots = item as IHasScreenshots; if (item is IHasScreenshots hasScreenshots)
if (hasScreenshots != null)
{ {
minWidth = savedOptions.GetMinWidth(ImageType.Screenshot); minWidth = savedOptions.GetMinWidth(ImageType.Screenshot);
await DownloadBackdrops(item, libraryOptions, ImageType.Screenshot, screenshotLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false); await DownloadBackdrops(item, libraryOptions, ImageType.Screenshot, screenshotLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false);
@ -317,7 +318,7 @@ namespace MediaBrowser.Providers.Manager
} }
} }
private bool IsEnabled(TypeOptions options, ImageType type, BaseItem item) private bool IsEnabled(TypeOptions options, ImageType type)
{ {
return options.IsEnabled(type); return options.IsEnabled(type);
} }
@ -452,10 +453,10 @@ namespace MediaBrowser.Providers.Manager
.Where(i => i.Type == type && !(i.Width.HasValue && i.Width.Value < minWidth)) .Where(i => i.Type == type && !(i.Width.HasValue && i.Width.Value < minWidth))
.ToList(); .ToList();
if (EnableImageStub(item, type, libraryOptions) && eligibleImages.Count > 0) if (EnableImageStub(item, libraryOptions) && eligibleImages.Count > 0)
{ {
SaveImageStub(item, type, eligibleImages.Select(i => i.Url)); SaveImageStub(item, type, eligibleImages.Select(i => i.Url));
result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate; result.UpdateType |= ItemUpdateType.ImageUpdate;
return true; return true;
} }
@ -476,7 +477,7 @@ namespace MediaBrowser.Providers.Manager
null, null,
cancellationToken).ConfigureAwait(false); cancellationToken).ConfigureAwait(false);
result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate; result.UpdateType |= ItemUpdateType.ImageUpdate;
return true; return true;
} }
catch (HttpException ex) catch (HttpException ex)
@ -495,7 +496,7 @@ namespace MediaBrowser.Providers.Manager
return false; return false;
} }
private bool EnableImageStub(BaseItem item, ImageType type, LibraryOptions libraryOptions) private bool EnableImageStub(BaseItem item, LibraryOptions libraryOptions)
{ {
if (item is LiveTvProgram) if (item is LiveTvProgram)
{ {
@ -563,10 +564,10 @@ namespace MediaBrowser.Providers.Manager
var url = image.Url; var url = image.Url;
if (EnableImageStub(item, imageType, libraryOptions)) if (EnableImageStub(item, libraryOptions))
{ {
SaveImageStub(item, imageType, new[] { url }); SaveImageStub(item, imageType, new[] { url });
result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate; result.UpdateType |= ItemUpdateType.ImageUpdate;
continue; continue;
} }

View File

@ -52,7 +52,6 @@ namespace MediaBrowser.Providers.Manager
public async Task<ItemUpdateType> RefreshMetadata(BaseItem item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken) public async Task<ItemUpdateType> RefreshMetadata(BaseItem item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken)
{ {
var itemOfType = (TItemType)item; var itemOfType = (TItemType)item;
var config = ProviderManager.GetMetadataOptions(item);
var updateType = ItemUpdateType.None; var updateType = ItemUpdateType.None;
var requiresRefresh = false; var requiresRefresh = false;
@ -86,7 +85,7 @@ namespace MediaBrowser.Providers.Manager
// Always validate images and check for new locally stored ones. // Always validate images and check for new locally stored ones.
if (itemImageProvider.ValidateImages(item, allImageProviders.OfType<ILocalImageProvider>(), refreshOptions.DirectoryService)) if (itemImageProvider.ValidateImages(item, allImageProviders.OfType<ILocalImageProvider>(), refreshOptions.DirectoryService))
{ {
updateType = updateType | ItemUpdateType.ImageUpdate; updateType |= ItemUpdateType.ImageUpdate;
} }
} }
catch (Exception ex) catch (Exception ex)
@ -102,7 +101,7 @@ namespace MediaBrowser.Providers.Manager
bool hasRefreshedMetadata = true; bool hasRefreshedMetadata = true;
bool hasRefreshedImages = true; bool hasRefreshedImages = true;
var isFirstRefresh = item.DateLastRefreshed == default(DateTime); var isFirstRefresh = item.DateLastRefreshed == default;
// Next run metadata providers // Next run metadata providers
if (refreshOptions.MetadataRefreshMode != MetadataRefreshMode.None) if (refreshOptions.MetadataRefreshMode != MetadataRefreshMode.None)
@ -114,7 +113,7 @@ namespace MediaBrowser.Providers.Manager
{ {
if (item.BeforeMetadataRefresh(refreshOptions.ReplaceAllMetadata)) if (item.BeforeMetadataRefresh(refreshOptions.ReplaceAllMetadata))
{ {
updateType = updateType | ItemUpdateType.MetadataImport; updateType |= ItemUpdateType.MetadataImport;
} }
} }
@ -132,7 +131,7 @@ namespace MediaBrowser.Providers.Manager
var result = await RefreshWithProviders(metadataResult, id, refreshOptions, providers, itemImageProvider, cancellationToken).ConfigureAwait(false); var result = await RefreshWithProviders(metadataResult, id, refreshOptions, providers, itemImageProvider, cancellationToken).ConfigureAwait(false);
updateType = updateType | result.UpdateType; updateType |= result.UpdateType;
if (result.Failures > 0) if (result.Failures > 0)
{ {
hasRefreshedMetadata = false; hasRefreshedMetadata = false;
@ -147,9 +146,9 @@ namespace MediaBrowser.Providers.Manager
if (providers.Count > 0) if (providers.Count > 0)
{ {
var result = await itemImageProvider.RefreshImages(itemOfType, libraryOptions, providers, refreshOptions, config, cancellationToken).ConfigureAwait(false); var result = await itemImageProvider.RefreshImages(itemOfType, libraryOptions, providers, refreshOptions, cancellationToken).ConfigureAwait(false);
updateType = updateType | result.UpdateType; updateType |= result.UpdateType;
if (result.Failures > 0) if (result.Failures > 0)
{ {
hasRefreshedImages = false; hasRefreshedImages = false;
@ -158,7 +157,7 @@ namespace MediaBrowser.Providers.Manager
} }
var beforeSaveResult = BeforeSave(itemOfType, isFirstRefresh || refreshOptions.ReplaceAllMetadata || refreshOptions.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || requiresRefresh || refreshOptions.ForceSave, updateType); var beforeSaveResult = BeforeSave(itemOfType, isFirstRefresh || refreshOptions.ReplaceAllMetadata || refreshOptions.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || requiresRefresh || refreshOptions.ForceSave, updateType);
updateType = updateType | beforeSaveResult; updateType |= beforeSaveResult;
// Save if changes were made, or it's never been saved before // Save if changes were made, or it's never been saved before
if (refreshOptions.ForceSave || updateType > ItemUpdateType.None || isFirstRefresh || refreshOptions.ReplaceAllMetadata || requiresRefresh) if (refreshOptions.ForceSave || updateType > ItemUpdateType.None || isFirstRefresh || refreshOptions.ReplaceAllMetadata || requiresRefresh)
@ -175,7 +174,7 @@ namespace MediaBrowser.Providers.Manager
// If any of these properties are set then make sure the updateType is not None, just to force everything to save // If any of these properties are set then make sure the updateType is not None, just to force everything to save
if (refreshOptions.ForceSave || refreshOptions.ReplaceAllMetadata) if (refreshOptions.ForceSave || refreshOptions.ReplaceAllMetadata)
{ {
updateType = updateType | ItemUpdateType.MetadataDownload; updateType |= ItemUpdateType.MetadataDownload;
} }
if (hasRefreshedMetadata && hasRefreshedImages) if (hasRefreshedMetadata && hasRefreshedImages)
@ -184,11 +183,11 @@ namespace MediaBrowser.Providers.Manager
} }
else else
{ {
item.DateLastRefreshed = default(DateTime); item.DateLastRefreshed = default;
} }
// Save to database // Save to database
SaveItem(metadataResult, libraryOptions, updateType, cancellationToken); await SaveItemAsync(metadataResult, libraryOptions, updateType, cancellationToken).ConfigureAwait(false);
} }
await AfterMetadataRefresh(itemOfType, refreshOptions, cancellationToken).ConfigureAwait(false); await AfterMetadataRefresh(itemOfType, refreshOptions, cancellationToken).ConfigureAwait(false);
@ -203,26 +202,26 @@ namespace MediaBrowser.Providers.Manager
lookupInfo.Year = result.ProductionYear; lookupInfo.Year = result.ProductionYear;
} }
protected void SaveItem(MetadataResult<TItemType> result, LibraryOptions libraryOptions, ItemUpdateType reason, CancellationToken cancellationToken) protected async Task SaveItemAsync(MetadataResult<TItemType> result, LibraryOptions libraryOptions, ItemUpdateType reason, CancellationToken cancellationToken)
{ {
if (result.Item.SupportsPeople && result.People != null) if (result.Item.SupportsPeople && result.People != null)
{ {
var baseItem = result.Item; var baseItem = result.Item;
LibraryManager.UpdatePeople(baseItem, result.People); LibraryManager.UpdatePeople(baseItem, result.People);
SavePeopleMetadata(result.People, libraryOptions, cancellationToken); await SavePeopleMetadataAsync(result.People, libraryOptions, cancellationToken).ConfigureAwait(false);
} }
result.Item.UpdateToRepository(reason, cancellationToken); result.Item.UpdateToRepository(reason, cancellationToken);
} }
private void SavePeopleMetadata(List<PersonInfo> people, LibraryOptions libraryOptions, CancellationToken cancellationToken) private async Task SavePeopleMetadataAsync(List<PersonInfo> people, LibraryOptions libraryOptions, CancellationToken cancellationToken)
{ {
foreach (var person in people) foreach (var person in people)
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
if (person.ProviderIds.Any() || !string.IsNullOrWhiteSpace(person.ImageUrl)) if (person.ProviderIds.Count > 0 || !string.IsNullOrWhiteSpace(person.ImageUrl))
{ {
var updateType = ItemUpdateType.MetadataDownload; var updateType = ItemUpdateType.MetadataDownload;
@ -239,10 +238,10 @@ namespace MediaBrowser.Providers.Manager
if (!string.IsNullOrWhiteSpace(person.ImageUrl) && !personEntity.HasImage(ImageType.Primary)) if (!string.IsNullOrWhiteSpace(person.ImageUrl) && !personEntity.HasImage(ImageType.Primary))
{ {
AddPersonImage(personEntity, libraryOptions, person.ImageUrl, cancellationToken); await AddPersonImageAsync(personEntity, libraryOptions, person.ImageUrl, cancellationToken).ConfigureAwait(false);
saveEntity = true; saveEntity = true;
updateType = updateType | ItemUpdateType.ImageUpdate; updateType |= ItemUpdateType.ImageUpdate;
} }
if (saveEntity) if (saveEntity)
@ -253,26 +252,28 @@ namespace MediaBrowser.Providers.Manager
} }
} }
private void AddPersonImage(Person personEntity, LibraryOptions libraryOptions, string imageUrl, CancellationToken cancellationToken) private async Task AddPersonImageAsync(Person personEntity, LibraryOptions libraryOptions, string imageUrl, CancellationToken cancellationToken)
{ {
// if (libraryOptions.DownloadImagesInAdvance) if (libraryOptions.DownloadImagesInAdvance)
//{
// try
// {
// await ProviderManager.SaveImage(personEntity, imageUrl, ImageType.Primary, null, cancellationToken).ConfigureAwait(false);
// return;
// }
// catch (Exception ex)
// {
// Logger.LogError(ex, "Error in AddPersonImage");
// }
//}
personEntity.SetImage(new ItemImageInfo
{ {
Path = imageUrl, try
Type = ImageType.Primary {
}, 0); await ProviderManager.SaveImage(personEntity, imageUrl, ImageType.Primary, null, cancellationToken).ConfigureAwait(false);
return;
}
catch (Exception ex)
{
Logger.LogError(ex, "Error in AddPersonImage");
}
}
personEntity.SetImage(
new ItemImageInfo
{
Path = imageUrl,
Type = ImageType.Primary
},
0);
} }
protected virtual Task AfterMetadataRefresh(TItemType item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken) protected virtual Task AfterMetadataRefresh(TItemType item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken)

View File

@ -210,10 +210,10 @@ namespace MediaBrowser.Providers.Manager
} }
/// <inheritdoc/> /// <inheritdoc/>
public Task SaveImage(User user, Stream source, string mimeType, string path) public Task SaveImage(Stream source, string mimeType, string path)
{ {
return new ImageSaver(_configurationManager, _libraryMonitor, _fileSystem, _logger) return new ImageSaver(_configurationManager, _libraryMonitor, _fileSystem, _logger)
.SaveImage(user, source, path); .SaveImage(source, path);
} }
/// <inheritdoc/> /// <inheritdoc/>
@ -563,7 +563,7 @@ namespace MediaBrowser.Providers.Manager
var pluginList = summary.Plugins.ToList(); var pluginList = summary.Plugins.ToList();
AddMetadataPlugins(pluginList, dummy, libraryOptions, options); AddMetadataPlugins(pluginList, dummy, libraryOptions, options);
AddImagePlugins(pluginList, dummy, imageProviders); AddImagePlugins(pluginList, imageProviders);
var subtitleProviders = _subtitleManager.GetSupportedProviders(dummy); var subtitleProviders = _subtitleManager.GetSupportedProviders(dummy);
@ -594,14 +594,14 @@ namespace MediaBrowser.Providers.Manager
var providers = GetMetadataProvidersInternal<T>(item, libraryOptions, options, true, true).ToList(); var providers = GetMetadataProvidersInternal<T>(item, libraryOptions, options, true, true).ToList();
// Locals // Locals
list.AddRange(providers.Where(i => (i is ILocalMetadataProvider)).Select(i => new MetadataPlugin list.AddRange(providers.Where(i => i is ILocalMetadataProvider).Select(i => new MetadataPlugin
{ {
Name = i.Name, Name = i.Name,
Type = MetadataPluginType.LocalMetadataProvider Type = MetadataPluginType.LocalMetadataProvider
})); }));
// Fetchers // Fetchers
list.AddRange(providers.Where(i => (i is IRemoteMetadataProvider)).Select(i => new MetadataPlugin list.AddRange(providers.Where(i => i is IRemoteMetadataProvider).Select(i => new MetadataPlugin
{ {
Name = i.Name, Name = i.Name,
Type = MetadataPluginType.MetadataFetcher Type = MetadataPluginType.MetadataFetcher
@ -615,11 +615,10 @@ namespace MediaBrowser.Providers.Manager
})); }));
} }
private void AddImagePlugins<T>(List<MetadataPlugin> list, T item, List<IImageProvider> imageProviders) private void AddImagePlugins(List<MetadataPlugin> list, List<IImageProvider> imageProviders)
where T : BaseItem
{ {
// Locals // Locals
list.AddRange(imageProviders.Where(i => (i is ILocalImageProvider)).Select(i => new MetadataPlugin list.AddRange(imageProviders.Where(i => i is ILocalImageProvider).Select(i => new MetadataPlugin
{ {
Name = i.Name, Name = i.Name,
Type = MetadataPluginType.LocalImageProvider Type = MetadataPluginType.LocalImageProvider
@ -1166,12 +1165,32 @@ namespace MediaBrowser.Providers.Manager
/// <inheritdoc/> /// <inheritdoc/>
public void Dispose() public void Dispose()
{ {
_disposed = true; Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Releases unmanaged and optionally managed resources.
/// </summary>
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (!_disposeCancellationTokenSource.IsCancellationRequested) if (!_disposeCancellationTokenSource.IsCancellationRequested)
{ {
_disposeCancellationTokenSource.Cancel(); _disposeCancellationTokenSource.Cancel();
} }
if (disposing)
{
_disposeCancellationTokenSource.Dispose();
}
_disposed = true;
} }
} }
} }

View File

@ -2,11 +2,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
@ -17,7 +15,6 @@ using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Dto; using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Providers.MediaInfo namespace MediaBrowser.Providers.MediaInfo
{ {
@ -25,19 +22,17 @@ namespace MediaBrowser.Providers.MediaInfo
{ {
private readonly IMediaEncoder _mediaEncoder; private readonly IMediaEncoder _mediaEncoder;
private readonly IItemRepository _itemRepo; private readonly IItemRepository _itemRepo;
private readonly IApplicationPaths _appPaths;
private readonly IJsonSerializer _json;
private readonly ILibraryManager _libraryManager; private readonly ILibraryManager _libraryManager;
private readonly IMediaSourceManager _mediaSourceManager; private readonly IMediaSourceManager _mediaSourceManager;
private readonly CultureInfo _usCulture = new CultureInfo("en-US"); public FFProbeAudioInfo(
IMediaSourceManager mediaSourceManager,
public FFProbeAudioInfo(IMediaSourceManager mediaSourceManager, IMediaEncoder mediaEncoder, IItemRepository itemRepo, IApplicationPaths appPaths, IJsonSerializer json, ILibraryManager libraryManager) IMediaEncoder mediaEncoder,
IItemRepository itemRepo,
ILibraryManager libraryManager)
{ {
_mediaEncoder = mediaEncoder; _mediaEncoder = mediaEncoder;
_itemRepo = itemRepo; _itemRepo = itemRepo;
_appPaths = appPaths;
_json = json;
_libraryManager = libraryManager; _libraryManager = libraryManager;
_mediaSourceManager = mediaSourceManager; _mediaSourceManager = mediaSourceManager;
} }

View File

@ -40,19 +40,15 @@ namespace MediaBrowser.Providers.MediaInfo
IHasItemChangeMonitor IHasItemChangeMonitor
{ {
private readonly ILogger<FFProbeProvider> _logger; private readonly ILogger<FFProbeProvider> _logger;
private readonly IIsoManager _isoManager;
private readonly IMediaEncoder _mediaEncoder; private readonly IMediaEncoder _mediaEncoder;
private readonly IItemRepository _itemRepo; private readonly IItemRepository _itemRepo;
private readonly IBlurayExaminer _blurayExaminer; private readonly IBlurayExaminer _blurayExaminer;
private readonly ILocalizationManager _localization; private readonly ILocalizationManager _localization;
private readonly IApplicationPaths _appPaths;
private readonly IJsonSerializer _json;
private readonly IEncodingManager _encodingManager; private readonly IEncodingManager _encodingManager;
private readonly IServerConfigurationManager _config; private readonly IServerConfigurationManager _config;
private readonly ISubtitleManager _subtitleManager; private readonly ISubtitleManager _subtitleManager;
private readonly IChapterManager _chapterManager; private readonly IChapterManager _chapterManager;
private readonly ILibraryManager _libraryManager; private readonly ILibraryManager _libraryManager;
private readonly IChannelManager _channelManager;
private readonly IMediaSourceManager _mediaSourceManager; private readonly IMediaSourceManager _mediaSourceManager;
public string Name => "ffprobe"; public string Name => "ffprobe";
@ -126,14 +122,10 @@ namespace MediaBrowser.Providers.MediaInfo
public FFProbeProvider( public FFProbeProvider(
ILogger<FFProbeProvider> logger, ILogger<FFProbeProvider> logger,
IMediaSourceManager mediaSourceManager, IMediaSourceManager mediaSourceManager,
IChannelManager channelManager,
IIsoManager isoManager,
IMediaEncoder mediaEncoder, IMediaEncoder mediaEncoder,
IItemRepository itemRepo, IItemRepository itemRepo,
IBlurayExaminer blurayExaminer, IBlurayExaminer blurayExaminer,
ILocalizationManager localization, ILocalizationManager localization,
IApplicationPaths appPaths,
IJsonSerializer json,
IEncodingManager encodingManager, IEncodingManager encodingManager,
IServerConfigurationManager config, IServerConfigurationManager config,
ISubtitleManager subtitleManager, ISubtitleManager subtitleManager,
@ -141,19 +133,15 @@ namespace MediaBrowser.Providers.MediaInfo
ILibraryManager libraryManager) ILibraryManager libraryManager)
{ {
_logger = logger; _logger = logger;
_isoManager = isoManager;
_mediaEncoder = mediaEncoder; _mediaEncoder = mediaEncoder;
_itemRepo = itemRepo; _itemRepo = itemRepo;
_blurayExaminer = blurayExaminer; _blurayExaminer = blurayExaminer;
_localization = localization; _localization = localization;
_appPaths = appPaths;
_json = json;
_encodingManager = encodingManager; _encodingManager = encodingManager;
_config = config; _config = config;
_subtitleManager = subtitleManager; _subtitleManager = subtitleManager;
_chapterManager = chapterManager; _chapterManager = chapterManager;
_libraryManager = libraryManager; _libraryManager = libraryManager;
_channelManager = channelManager;
_mediaSourceManager = mediaSourceManager; _mediaSourceManager = mediaSourceManager;
_subtitleResolver = new SubtitleResolver(BaseItem.LocalizationManager); _subtitleResolver = new SubtitleResolver(BaseItem.LocalizationManager);
@ -211,9 +199,9 @@ namespace MediaBrowser.Providers.MediaInfo
private string NormalizeStrmLine(string line) private string NormalizeStrmLine(string line)
{ {
return line.Replace("\t", string.Empty) return line.Replace("\t", string.Empty, StringComparison.Ordinal)
.Replace("\r", string.Empty) .Replace("\r", string.Empty, StringComparison.Ordinal)
.Replace("\n", string.Empty) .Replace("\n", string.Empty, StringComparison.Ordinal)
.Trim(); .Trim();
} }
@ -242,10 +230,11 @@ namespace MediaBrowser.Providers.MediaInfo
FetchShortcutInfo(item); FetchShortcutInfo(item);
} }
var prober = new FFProbeAudioInfo(_mediaSourceManager, _mediaEncoder, _itemRepo, _appPaths, _json, _libraryManager); var prober = new FFProbeAudioInfo(_mediaSourceManager, _mediaEncoder, _itemRepo, _libraryManager);
return prober.Probe(item, options, cancellationToken); return prober.Probe(item, options, cancellationToken);
} }
// Run last // Run last
public int Order => 100; public int Order => 100;
} }

View File

@ -6,7 +6,7 @@ using MediaBrowser.Model.Entities;
namespace MediaBrowser.Providers.Music namespace MediaBrowser.Providers.Music
{ {
public static class Extensions public static class AlbumInfoExtensions
{ {
public static string GetAlbumArtist(this AlbumInfo info) public static string GetAlbumArtist(this AlbumInfo info)
{ {
@ -18,7 +18,7 @@ namespace MediaBrowser.Providers.Music
return id; return id;
} }
return info.AlbumArtists.FirstOrDefault(); return info.AlbumArtists.Count > 0 ? info.AlbumArtists[0] : default;
} }
public static string GetReleaseGroupId(this AlbumInfo info) public static string GetReleaseGroupId(this AlbumInfo info)

View File

@ -276,7 +276,7 @@ namespace MediaBrowser.Providers.Music
private async Task<ReleaseResult> GetReleaseResult(string albumName, string artistId, CancellationToken cancellationToken) private async Task<ReleaseResult> GetReleaseResult(string albumName, string artistId, CancellationToken cancellationToken)
{ {
var url = string.Format("/ws/2/release/?query=\"{0}\" AND arid:{1}", var url = string.Format(CultureInfo.InvariantCulture, "/ws/2/release/?query=\"{0}\" AND arid:{1}",
WebUtility.UrlEncode(albumName), WebUtility.UrlEncode(albumName),
artistId); artistId);

View File

@ -46,7 +46,7 @@ namespace MediaBrowser.Providers.Music
// They seem to throw bad request failures on any term with a slash // They seem to throw bad request failures on any term with a slash
var nameToSearch = searchInfo.Name.Replace('/', ' '); var nameToSearch = searchInfo.Name.Replace('/', ' ');
var url = string.Format("/ws/2/artist/?query=\"{0}\"&dismax=true", UrlEncode(nameToSearch)); var url = string.Format(CultureInfo.InvariantCulture, "/ws/2/artist/?query=\"{0}\"&dismax=true", UrlEncode(nameToSearch));
using (var response = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, cancellationToken).ConfigureAwait(false)) using (var response = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, cancellationToken).ConfigureAwait(false))
await using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) await using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
@ -62,7 +62,7 @@ namespace MediaBrowser.Providers.Music
if (HasDiacritics(searchInfo.Name)) if (HasDiacritics(searchInfo.Name))
{ {
// Try again using the search with accent characters url // Try again using the search with accent characters url
url = string.Format("/ws/2/artist/?query=artistaccent:\"{0}\"", UrlEncode(nameToSearch)); url = string.Format(CultureInfo.InvariantCulture, "/ws/2/artist/?query=artistaccent:\"{0}\"", UrlEncode(nameToSearch));
using var response = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, cancellationToken).ConfigureAwait(false); using var response = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, cancellationToken).ConfigureAwait(false);
await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Net.Http; using System.Net.Http;
using System.Globalization;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Common; using MediaBrowser.Common;
@ -70,7 +71,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
list.Add(new RemoteImageInfo list.Add(new RemoteImageInfo
{ {
ProviderName = Name, ProviderName = Name,
Url = string.Format("https://img.omdbapi.com/?i={0}&apikey=2c9d9507", imdbId) Url = string.Format(CultureInfo.InvariantCulture, "https://img.omdbapi.com/?i={0}&apikey=2c9d9507", imdbId)
}); });
} }
} }

View File

@ -127,7 +127,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
} }
} }
var url = OmdbProvider.GetOmdbUrl(urlQuery, _appHost, cancellationToken); var url = OmdbProvider.GetOmdbUrl(urlQuery);
using var response = await OmdbProvider.GetOmdbResponse(_httpClientFactory.CreateClient(), url, cancellationToken).ConfigureAwait(false); using var response = await OmdbProvider.GetOmdbResponse(_httpClientFactory.CreateClient(), url, cancellationToken).ConfigureAwait(false);
await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);

View File

@ -256,16 +256,16 @@ namespace MediaBrowser.Providers.Plugins.Omdb
return false; return false;
} }
public static string GetOmdbUrl(string query, IApplicationHost appHost, CancellationToken cancellationToken) public static string GetOmdbUrl(string query)
{ {
const string url = "https://www.omdbapi.com?apikey=2c9d9507"; const string Url = "https://www.omdbapi.com?apikey=2c9d9507";
if (string.IsNullOrWhiteSpace(query)) if (string.IsNullOrWhiteSpace(query))
{ {
return url; return Url;
} }
return url + "&" + query; return Url + "&" + query;
} }
private async Task<string> EnsureItemInfo(string imdbId, CancellationToken cancellationToken) private async Task<string> EnsureItemInfo(string imdbId, CancellationToken cancellationToken)
@ -290,7 +290,11 @@ namespace MediaBrowser.Providers.Plugins.Omdb
} }
} }
var url = GetOmdbUrl(string.Format("i={0}&plot=short&tomatoes=true&r=json", imdbParam), _appHost, cancellationToken); var url = GetOmdbUrl(
string.Format(
CultureInfo.InvariantCulture,
"i={0}&plot=short&tomatoes=true&r=json",
imdbParam));
using var response = await GetOmdbResponse(_httpClientFactory.CreateClient(), url, cancellationToken).ConfigureAwait(false); using var response = await GetOmdbResponse(_httpClientFactory.CreateClient(), url, cancellationToken).ConfigureAwait(false);
await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
@ -323,7 +327,12 @@ namespace MediaBrowser.Providers.Plugins.Omdb
} }
} }
var url = GetOmdbUrl(string.Format("i={0}&season={1}&detail=full", imdbParam, seasonId), _appHost, cancellationToken); var url = GetOmdbUrl(
string.Format(
CultureInfo.InvariantCulture,
"i={0}&season={1}&detail=full",
imdbParam,
seasonId));
using var response = await GetOmdbResponse(_httpClientFactory.CreateClient(), url, cancellationToken).ConfigureAwait(false); using var response = await GetOmdbResponse(_httpClientFactory.CreateClient(), url, cancellationToken).ConfigureAwait(false);
await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
@ -348,7 +357,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
var dataPath = Path.Combine(_configurationManager.ApplicationPaths.CachePath, "omdb"); var dataPath = Path.Combine(_configurationManager.ApplicationPaths.CachePath, "omdb");
var filename = string.Format("{0}.json", imdbId); var filename = string.Format(CultureInfo.InvariantCulture, "{0}.json", imdbId);
return Path.Combine(dataPath, filename); return Path.Combine(dataPath, filename);
} }
@ -362,7 +371,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
var dataPath = Path.Combine(_configurationManager.ApplicationPaths.CachePath, "omdb"); var dataPath = Path.Combine(_configurationManager.ApplicationPaths.CachePath, "omdb");
var filename = string.Format("{0}_season_{1}.json", imdbId, seasonId); var filename = string.Format(CultureInfo.InvariantCulture, "{0}_season_{1}.json", imdbId, seasonId);
return Path.Combine(dataPath, filename); return Path.Combine(dataPath, filename);
} }

View File

@ -2,6 +2,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@ -19,7 +20,6 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
{ {
private const string DefaultLanguage = "en"; private const string DefaultLanguage = "en";
private readonly SemaphoreSlim _cacheWriteLock = new SemaphoreSlim(1, 1);
private readonly IMemoryCache _cache; private readonly IMemoryCache _cache;
private readonly TvDbClient _tvDbClient; private readonly TvDbClient _tvDbClient;
private DateTime _tokenCreatedAt; private DateTime _tokenCreatedAt;
@ -176,7 +176,7 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
string language, string language,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
searchInfo.SeriesProviderIds.TryGetValue(MetadataProvider.Tvdb.ToString(), searchInfo.SeriesProviderIds.TryGetValue(nameof(MetadataProvider.Tvdb),
out var seriesTvdbId); out var seriesTvdbId);
var episodeQuery = new EpisodeQuery(); var episodeQuery = new EpisodeQuery();
@ -203,10 +203,10 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
else if (searchInfo.PremiereDate.HasValue) else if (searchInfo.PremiereDate.HasValue)
{ {
// tvdb expects yyyy-mm-dd format // tvdb expects yyyy-mm-dd format
episodeQuery.FirstAired = searchInfo.PremiereDate.Value.ToString("yyyy-MM-dd"); episodeQuery.FirstAired = searchInfo.PremiereDate.Value.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
} }
return GetEpisodeTvdbId(Convert.ToInt32(seriesTvdbId), episodeQuery, language, cancellationToken); return GetEpisodeTvdbId(Convert.ToInt32(seriesTvdbId, CultureInfo.InvariantCulture), episodeQuery, language, cancellationToken);
} }
public async Task<string> GetEpisodeTvdbId( public async Task<string> GetEpisodeTvdbId(
@ -218,7 +218,7 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
var episodePage = var episodePage =
await GetEpisodesPageAsync(Convert.ToInt32(seriesTvdbId), episodeQuery, language, cancellationToken) await GetEpisodesPageAsync(Convert.ToInt32(seriesTvdbId), episodeQuery, language, cancellationToken)
.ConfigureAwait(false); .ConfigureAwait(false);
return episodePage.Data.FirstOrDefault()?.Id.ToString(); return episodePage.Data.FirstOrDefault()?.Id.ToString(CultureInfo.InvariantCulture);
} }
public Task<TvDbResponse<EpisodeRecord[]>> GetEpisodesPageAsync( public Task<TvDbResponse<EpisodeRecord[]>> GetEpisodesPageAsync(
@ -276,23 +276,10 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
return cachedValue; return cachedValue;
} }
await _cacheWriteLock.WaitAsync().ConfigureAwait(false); _tvDbClient.AcceptedLanguage = TvdbUtils.NormalizeLanguage(language) ?? DefaultLanguage;
try var result = await resultFactory.Invoke().ConfigureAwait(false);
{ _cache.Set(key, result, TimeSpan.FromHours(1));
if (_cache.TryGetValue(key, out cachedValue)) return result;
{
return cachedValue;
}
_tvDbClient.AcceptedLanguage = TvdbUtils.NormalizeLanguage(language) ?? DefaultLanguage;
var result = await resultFactory.Invoke().ConfigureAwait(false);
_cache.Set(key, result, TimeSpan.FromHours(1));
return result;
}
finally
{
_cacheWriteLock.Release();
}
} }
private static string GenerateKey(params object[] objects) private static string GenerateKey(params object[] objects)

View File

@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net.Http; using System.Net.Http;
using System.Globalization;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
@ -76,7 +77,7 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
var episodeResult = var episodeResult =
await _tvdbClientManager await _tvdbClientManager
.GetEpisodesAsync(Convert.ToInt32(episodeTvdbId), language, cancellationToken) .GetEpisodesAsync(Convert.ToInt32(episodeTvdbId, CultureInfo.InvariantCulture), language, cancellationToken)
.ConfigureAwait(false); .ConfigureAwait(false);
var image = GetImageInfo(episodeResult.Data); var image = GetImageInfo(episodeResult.Data);
@ -103,8 +104,8 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
return new RemoteImageInfo return new RemoteImageInfo
{ {
Width = Convert.ToInt32(episode.ThumbWidth), Width = Convert.ToInt32(episode.ThumbWidth, CultureInfo.InvariantCulture),
Height = Convert.ToInt32(episode.ThumbHeight), Height = Convert.ToInt32(episode.ThumbHeight, CultureInfo.InvariantCulture),
ProviderName = Name, ProviderName = Name,
Url = TvdbUtils.BannerUrl + episode.Filename, Url = TvdbUtils.BannerUrl + episode.Filename,
Type = ImageType.Primary Type = ImageType.Primary

View File

@ -180,7 +180,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
if (!string.IsNullOrEmpty(language)) if (!string.IsNullOrEmpty(language))
{ {
url += string.Format("&language={0}", TmdbMovieProvider.NormalizeLanguage(language)); url += string.Format(CultureInfo.InvariantCulture, "&language={0}", TmdbMovieProvider.NormalizeLanguage(language));
// Get images in english and with no language // Get images in english and with no language
url += "&include_image_language=" + TmdbMovieProvider.GetImageLanguagesParam(language); url += "&include_image_language=" + TmdbMovieProvider.GetImageLanguagesParam(language);
@ -250,7 +250,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
{ {
var path = GetDataPath(appPaths, tmdbId); var path = GetDataPath(appPaths, tmdbId);
var filename = string.Format("all-{0}.json", preferredLanguage ?? string.Empty); var filename = string.Format(CultureInfo.InvariantCulture, "all-{0}.json", preferredLanguage ?? string.Empty);
return Path.Combine(path, filename); return Path.Combine(path, filename);
} }

View File

@ -300,7 +300,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
{ {
movie.RemoteTrailers = movieData.Trailers.Youtube.Select(i => new MediaUrl movie.RemoteTrailers = movieData.Trailers.Youtube.Select(i => new MediaUrl
{ {
Url = string.Format("https://www.youtube.com/watch?v={0}", i.Source), Url = string.Format(CultureInfo.InvariantCulture, "https://www.youtube.com/watch?v={0}", i.Source),
Name = i.Name Name = i.Name
}).ToArray(); }).ToArray();

View File

@ -37,7 +37,8 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
).* # Match rest of string", ).* # Match rest of string",
RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase); RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase);
private const string _searchURL = TmdbUtils.BaseTmdbApiUrl + @"3/search/{3}?api_key={1}&query={0}&language={2}"; private const string SearchUrl = TmdbUtils.BaseTmdbApiUrl + @"3/search/{3}?api_key={1}&query={0}&language={2}";
private const string SearchUrlWithYear = TmdbUtils.BaseTmdbApiUrl + @"3/search/{3}?api_key={1}&query={0}&language={2}&first_air_date_year={4}";
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IJsonSerializer _json; private readonly IJsonSerializer _json;
@ -124,7 +125,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
name2 = name2.Trim(); name2 = name2.Trim();
// Search again if the new name is different // Search again if the new name is different
if (!string.Equals(name2, name) && !string.IsNullOrWhiteSpace(name2)) if (!string.Equals(name2, name, StringComparison.Ordinal) && !string.IsNullOrWhiteSpace(name2))
{ {
_logger.LogInformation("TmdbSearch: Finding id for item: {0} ({1})", name2, year); _logger.LogInformation("TmdbSearch: Finding id for item: {0} ({1})", name2, year);
results = await GetSearchResults(name2, searchType, year, language, tmdbImageUrl, cancellationToken).ConfigureAwait(false); results = await GetSearchResults(name2, searchType, year, language, tmdbImageUrl, cancellationToken).ConfigureAwait(false);
@ -164,10 +165,30 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
{ {
if (string.IsNullOrWhiteSpace(name)) if (string.IsNullOrWhiteSpace(name))
{ {
throw new ArgumentException("name"); throw new ArgumentException("String can't be null or empty.", nameof(name));
} }
var url3 = string.Format(_searchURL, WebUtility.UrlEncode(name), TmdbUtils.ApiKey, language, type); string url3;
if (year != null && string.Equals(type, "movie", StringComparison.OrdinalIgnoreCase))
{
url3 = string.Format(
CultureInfo.InvariantCulture,
SearchUrl,
WebUtility.UrlEncode(name),
TmdbUtils.ApiKey,
language,
type) + "&primary_release_year=" + year;
}
else
{
url3 = string.Format(
CultureInfo.InvariantCulture,
SearchUrl,
WebUtility.UrlEncode(name),
TmdbUtils.ApiKey,
language,
type);
}
var requestMessage = new HttpRequestMessage(HttpMethod.Get, url3); var requestMessage = new HttpRequestMessage(HttpMethod.Get, url3);
foreach (var header in TmdbUtils.AcceptHeaders) foreach (var header in TmdbUtils.AcceptHeaders)
@ -207,10 +228,31 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
{ {
if (string.IsNullOrWhiteSpace(name)) if (string.IsNullOrWhiteSpace(name))
{ {
throw new ArgumentException("name"); throw new ArgumentException("String can't be null or empty.", nameof(name));
} }
var url3 = string.Format(_searchURL, WebUtility.UrlEncode(name), TmdbUtils.ApiKey, language, "tv"); string url3;
if (year == null)
{
url3 = string.Format(
CultureInfo.InvariantCulture,
SearchUrl,
WebUtility.UrlEncode(name),
TmdbUtils.ApiKey,
language,
"tv");
}
else
{
url3 = string.Format(
CultureInfo.InvariantCulture,
SearchUrlWithYear,
WebUtility.UrlEncode(name),
TmdbUtils.ApiKey,
language,
"tv",
year);
}
var requestMessage = new HttpRequestMessage(HttpMethod.Get, url3); var requestMessage = new HttpRequestMessage(HttpMethod.Get, url3);
foreach (var header in TmdbUtils.AcceptHeaders) foreach (var header in TmdbUtils.AcceptHeaders)

View File

@ -131,7 +131,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
{ {
if (video.Site.Equals("youtube", System.StringComparison.OrdinalIgnoreCase)) if (video.Site.Equals("youtube", System.StringComparison.OrdinalIgnoreCase))
{ {
var videoUrl = string.Format("http://www.youtube.com/watch?v={0}", video.Key); var videoUrl = string.Format(CultureInfo.InvariantCulture, "http://www.youtube.com/watch?v={0}", video.Key);
item.AddTrailerUrl(videoUrl); item.AddTrailerUrl(videoUrl);
} }
} }

View File

@ -92,7 +92,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
var path = TmdbSeriesProvider.GetSeriesDataPath(_configurationManager.ApplicationPaths, tmdbId); var path = TmdbSeriesProvider.GetSeriesDataPath(_configurationManager.ApplicationPaths, tmdbId);
var filename = string.Format("season-{0}-episode-{1}-{2}.json", var filename = string.Format(CultureInfo.InvariantCulture, "season-{0}-episode-{1}-{2}.json",
seasonNumber.ToString(CultureInfo.InvariantCulture), seasonNumber.ToString(CultureInfo.InvariantCulture),
episodeNumber.ToString(CultureInfo.InvariantCulture), episodeNumber.ToString(CultureInfo.InvariantCulture),
preferredLanguage); preferredLanguage);
@ -116,7 +116,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
if (!string.IsNullOrEmpty(language)) if (!string.IsNullOrEmpty(language))
{ {
url += string.Format("&language={0}", language); url += string.Format(CultureInfo.InvariantCulture, "&language={0}", language);
} }
var includeImageLanguageParam = TmdbMovieProvider.GetImageLanguagesParam(language); var includeImageLanguageParam = TmdbMovieProvider.GetImageLanguagesParam(language);

View File

@ -180,7 +180,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
var path = TmdbSeriesProvider.GetSeriesDataPath(_configurationManager.ApplicationPaths, tmdbId); var path = TmdbSeriesProvider.GetSeriesDataPath(_configurationManager.ApplicationPaths, tmdbId);
var filename = string.Format("season-{0}-{1}.json", var filename = string.Format(CultureInfo.InvariantCulture, "season-{0}-{1}.json",
seasonNumber.ToString(CultureInfo.InvariantCulture), seasonNumber.ToString(CultureInfo.InvariantCulture),
preferredLanguage); preferredLanguage);
@ -203,7 +203,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
if (!string.IsNullOrEmpty(language)) if (!string.IsNullOrEmpty(language))
{ {
url += string.Format("&language={0}", TmdbMovieProvider.NormalizeLanguage(language)); url += string.Format(CultureInfo.InvariantCulture, "&language={0}", TmdbMovieProvider.NormalizeLanguage(language));
} }
var includeImageLanguageParam = TmdbMovieProvider.GetImageLanguagesParam(language); var includeImageLanguageParam = TmdbMovieProvider.GetImageLanguagesParam(language);

View File

@ -496,7 +496,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
var path = GetSeriesDataPath(_configurationManager.ApplicationPaths, tmdbId); var path = GetSeriesDataPath(_configurationManager.ApplicationPaths, tmdbId);
var filename = string.Format("series-{0}.json", preferredLanguage ?? string.Empty); var filename = string.Format(CultureInfo.InvariantCulture, "series-{0}.json", preferredLanguage ?? string.Empty);
return Path.Combine(path, filename); return Path.Combine(path, filename);
} }

View File

@ -2,6 +2,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net.Http; using System.Net.Http;
@ -100,7 +101,7 @@ namespace MediaBrowser.Providers.Studios
private string GetUrl(string image, string filename) private string GetUrl(string image, string filename)
{ {
return string.Format("https://raw.github.com/MediaBrowser/MediaBrowser.Resources/master/images/imagesbyname/studios/{0}/{1}.jpg", image, filename); return string.Format(CultureInfo.InvariantCulture, "https://raw.github.com/MediaBrowser/MediaBrowser.Resources/master/images/imagesbyname/studios/{0}/{1}.jpg", image, filename);
} }
private Task<string> EnsureThumbsList(string file, CancellationToken cancellationToken) private Task<string> EnsureThumbsList(string file, CancellationToken cancellationToken)