Fix warnings

pull/3841/head
Bond_009 4 years ago committed by Bond_009
parent 634ee2d1e9
commit 2b400c99ef

@ -54,11 +54,15 @@ namespace Emby.Dlna
_appHost = appHost;
}
private string UserProfilesPath => Path.Combine(_appPaths.ConfigurationDirectoryPath, "dlna", "user");
private string SystemProfilesPath => Path.Combine(_appPaths.ConfigurationDirectoryPath, "dlna", "system");
public async Task InitProfilesAsync()
{
try
{
await ExtractSystemProfilesAsync();
await ExtractSystemProfilesAsync().ConfigureAwait(false);
LoadProfiles();
}
catch (Exception ex)
@ -240,7 +244,7 @@ namespace Emby.Dlna
}
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);
}
@ -280,10 +284,6 @@ namespace Emby.Dlna
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)
{
try

@ -19,6 +19,8 @@ namespace Emby.Dlna.PlayTo
{
public class Device : IDisposable
{
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
private Timer _timer;
public DeviceInfo Properties { get; set; }
@ -55,16 +57,13 @@ namespace Emby.Dlna.PlayTo
private readonly ILogger _logger;
private readonly IServerConfigurationManager _config;
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;
_httpClient = httpClient;
_logger = logger;
_config = config;
}
public void Start()
@ -275,7 +274,7 @@ namespace Emby.Dlna.PlayTo
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);
RestartTimer(true);
@ -285,7 +284,7 @@ namespace Emby.Dlna.PlayTo
{
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);
@ -297,8 +296,8 @@ namespace Emby.Dlna.PlayTo
var dictionary = new Dictionary<string, string>
{
{"CurrentURI", url},
{"CurrentURIMetaData", CreateDidlMeta(metaData)}
{ "CurrentURI", url },
{ "CurrentURIMetaData", CreateDidlMeta(metaData) }
};
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 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 duration = durationElem == null ? null : durationElem.Value;
var duration = durationElem?.Value;
if (!string.IsNullOrWhiteSpace(duration)
&& !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 position = positionElem == null ? null : positionElem.Value;
var position = positionElem?.Value;
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
try
{
return XElement.Parse(xml.Replace("&", "&amp;"));
return XElement.Parse(xml.Replace("&", "&amp;", StringComparison.Ordinal));
}
catch (XmlException)
{
@ -848,7 +847,7 @@ namespace Emby.Dlna.PlayTo
ParentId = container.GetAttributeValue(uPnpNamespaces.ParentId),
Title = container.GetValue(uPnpNamespaces.title),
IconUrl = container.GetValue(uPnpNamespaces.Artwork),
SecondText = "",
SecondText = string.Empty,
Url = url,
ProtocolInfo = GetProtocolInfo(container),
MetaData = container.ToString()
@ -941,12 +940,12 @@ namespace Emby.Dlna.PlayTo
return url;
}
if (!url.Contains("/"))
if (!url.Contains('/', StringComparison.Ordinal))
{
url = "/dmr/" + url;
}
if (!url.StartsWith("/"))
if (!url.StartsWith("/", StringComparison.Ordinal))
{
url = "/" + url;
}
@ -981,7 +980,7 @@ namespace Emby.Dlna.PlayTo
var deviceProperties = new DeviceInfo()
{
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();
@ -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)
{
if (element == null)
@ -1222,7 +1220,7 @@ namespace Emby.Dlna.PlayTo
public override string ToString()
{
return string.Format("{0} - {1}", Properties.Name, Properties.BaseUrl);
return string.Format(CultureInfo.InvariantCulture, "{0} - {1}", Properties.Name, Properties.BaseUrl);
}
}
}

@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Xml.Linq;
using Emby.Dlna.Common;
@ -11,14 +12,16 @@ namespace Emby.Dlna.PlayTo
{
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<ServiceAction> _serviceActions = new List<ServiceAction>();
public List<StateVariable> StateVariables
{
get => _stateVariables;
set => _stateVariables = value;
}
private List<ServiceAction> _serviceActions = new List<ServiceAction>();
public List<ServiceAction> 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 = "")
@ -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)
@ -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 = "")
@ -183,12 +186,10 @@ namespace Emby.Dlna.PlayTo
state.AllowedValues.FirstOrDefault() ??
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>";
}
}

@ -4560,13 +4560,13 @@ namespace Emby.Server.Implementations.Data
if (query.AncestorIds.Length > 1)
{
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))
{
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)
{
statement.TryBind("@AncestorWithPresentationUniqueKey", query.AncestorWithPresentationUniqueKey);

@ -230,7 +230,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
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;

@ -237,7 +237,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
&& !programInfo.IsRepeat
&& (programInfo.EpisodeNumber ?? 0) == 0)
{
programInfo.ShowId = programInfo.ShowId + programInfo.StartDate.Ticks.ToString(CultureInfo.InvariantCulture);
programInfo.ShowId += programInfo.StartDate.Ticks.ToString(CultureInfo.InvariantCulture);
}
}
else
@ -246,7 +246,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
}
// 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)
{
@ -296,7 +296,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings
Name = c.DisplayName,
ImageUrl = c.Icon != null && !string.IsNullOrEmpty(c.Icon.Source) ? c.Icon.Source : null,
Number = string.IsNullOrWhiteSpace(c.Number) ? c.Id : c.Number
}).ToList();
}
}

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

@ -182,12 +182,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
var model = await GetModelInfo(info, false, cancellationToken).ConfigureAwait(false);
using (var response = await _httpClient.SendAsync(new HttpRequestOptions()
{
Url = string.Format("{0}/tuners.html", GetApiUrl(info)),
CancellationToken = cancellationToken,
BufferContent = false
}, HttpMethod.Get).ConfigureAwait(false))
using (var response = await _httpClient.SendAsync(
new HttpRequestOptions()
{
Url = string.Format(CultureInfo.InvariantCulture, "{0}/tuners.html", GetApiUrl(info)),
CancellationToken = cancellationToken,
BufferContent = false
},
HttpMethod.Get).ConfigureAwait(false))
using (var stream = response.Content)
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?
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];
while (!cancellationToken.IsCancellationRequested)

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

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

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

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

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

@ -63,7 +63,7 @@ namespace MediaBrowser.Controller.LiveTv
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);
}
}

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

@ -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)
{
@ -880,7 +880,7 @@ namespace MediaBrowser.Controller.MediaEncoding
profileScore = Math.Min(profileScore, 2);
// 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),
crf,
qmin,
@ -904,7 +904,7 @@ namespace MediaBrowser.Controller.MediaEncoding
var framerate = GetFramerateParam(state);
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;
@ -1484,7 +1484,7 @@ namespace MediaBrowser.Controller.MediaEncoding
if (time > 0)
{
return string.Format("-ss {0}", _mediaEncoder.GetTimeParameter(time));
return string.Format(CultureInfo.InvariantCulture, "-ss {0}", _mediaEncoder.GetTimeParameter(time));
}
return string.Empty;

@ -72,7 +72,7 @@ namespace MediaBrowser.Controller.Providers
/// <returns>Task.</returns>
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>
/// Adds the metadata providers.

@ -1,6 +1,7 @@
#pragma warning disable CS1591
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using MediaBrowser.Model.MediaInfo;
@ -14,7 +15,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
var url = inputFiles[0];
return string.Format("\"{0}\"", url);
return string.Format(CultureInfo.InvariantCulture, "\"{0}\"", url);
}
return GetConcatInputArgument(inputFiles);
@ -33,7 +34,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
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
@ -49,13 +50,13 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
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 \
path = NormalizePath(path);
return string.Format("file:\"{0}\"", path);
return string.Format(CultureInfo.InvariantCulture, "file:\"{0}\"", path);
}
/// <summary>

@ -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.
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) :
string.Format("-i {0}{3} -threads 0 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg);
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(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 analyzeDurationArgument = EncodingHelper.GetAnalyzeDurationArgument(1);
@ -570,7 +570,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
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)
@ -641,7 +641,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
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);
@ -684,13 +684,13 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
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);
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 analyzeDurationArgument = EncodingHelper.GetAnalyzeDurationArgument(1);
@ -790,7 +790,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
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);

@ -435,7 +435,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
CreateNoWindow = true,
UseShellExecute = false,
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,
ErrorDialog = false
},

@ -157,7 +157,7 @@ namespace MediaBrowser.Model.Dlna
// flagValue = flagValue | DlnaFlags.TimeBasedSeek;
//}
string dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}",
string dlnaflags = string.Format(CultureInfo.InvariantCulture, ";DLNA.ORG_FLAGS={0}",
DlnaMaps.FlagsToString(flagValue));
ResponseProfile mediaProfile = _profile.GetVideoMediaProfile(container,

@ -1,18 +1,20 @@
#pragma warning disable CS1591
using System.Globalization;
namespace MediaBrowser.Model.Dlna
{
public static class DlnaMaps
{
private static readonly string DefaultStreaming =
FlagsToString(DlnaFlags.StreamingTransferMode |
FlagsToString(DlnaFlags.StreamingTransferMode |
DlnaFlags.BackgroundTransferMode |
DlnaFlags.ConnectionStall |
DlnaFlags.ByteBasedSeek |
DlnaFlags.DlnaV15);
private static readonly string DefaultInteractive =
FlagsToString(DlnaFlags.InteractiveTransferMode |
FlagsToString(DlnaFlags.InteractiveTransferMode |
DlnaFlags.BackgroundTransferMode |
DlnaFlags.ConnectionStall |
DlnaFlags.ByteBasedSeek |
@ -20,7 +22,7 @@ namespace MediaBrowser.Model.Dlna
public static string FlagsToString(DlnaFlags flags)
{
return string.Format("{0:X8}{1:D24}", (ulong)flags, 0);
return string.Format(CultureInfo.InvariantCulture, "{0:X8}{1:D24}", (ulong)flags, 0);
}
public static string GetOrgOpValue(bool hasKnownRuntime, bool isDirectStream, TranscodeSeekInfo profileTranscodeSeekInfo)

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using MediaBrowser.Model.MediaInfo;
@ -142,26 +143,26 @@ namespace MediaBrowser.Model.Dlna
{
if (timestampType == TransportStreamTimestamp.None)
{
return new MediaFormatProfile[] { ValueOf(string.Format("AVC_TS_HP_{0}D_MPEG1_L2_ISO", resolution)) };
return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "AVC_TS_HP_{0}D_MPEG1_L2_ISO", resolution)) };
}
return new MediaFormatProfile[] { ValueOf(string.Format("AVC_TS_HP_{0}D_MPEG1_L2_T", resolution)) };
return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "AVC_TS_HP_{0}D_MPEG1_L2_T", resolution)) };
}
if (string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase))
{
return new MediaFormatProfile[] { ValueOf(string.Format("AVC_TS_MP_{0}D_AAC_MULT5{1}", resolution, suffix)) };
return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "AVC_TS_MP_{0}D_AAC_MULT5{1}", resolution, suffix)) };
}
if (string.Equals(audioCodec, "mp3", StringComparison.OrdinalIgnoreCase))
{
return new MediaFormatProfile[] { ValueOf(string.Format("AVC_TS_MP_{0}D_MPEG1_L3{1}", resolution, suffix)) };
return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "AVC_TS_MP_{0}D_MPEG1_L3{1}", resolution, suffix)) };
}
if (string.IsNullOrEmpty(audioCodec) ||
string.Equals(audioCodec, "ac3", StringComparison.OrdinalIgnoreCase))
{
return new MediaFormatProfile[] { ValueOf(string.Format("AVC_TS_MP_{0}D_AC3{1}", resolution, suffix)) };
return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "AVC_TS_MP_{0}D_AC3{1}", resolution, suffix)) };
}
}
else if (string.Equals(videoCodec, "vc1", StringComparison.OrdinalIgnoreCase))
@ -180,29 +181,29 @@ namespace MediaBrowser.Model.Dlna
{
suffix = string.Equals(suffix, "_ISO", StringComparison.OrdinalIgnoreCase) ? suffix : "_T";
return new MediaFormatProfile[] { ValueOf(string.Format("VC1_TS_HD_DTS{0}", suffix)) };
return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "VC1_TS_HD_DTS{0}", suffix)) };
}
}
else if (string.Equals(videoCodec, "mpeg4", StringComparison.OrdinalIgnoreCase) || string.Equals(videoCodec, "msmpeg4", StringComparison.OrdinalIgnoreCase))
{
if (string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase))
{
return new MediaFormatProfile[] { ValueOf(string.Format("MPEG4_P2_TS_ASP_AAC{0}", suffix)) };
return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "MPEG4_P2_TS_ASP_AAC{0}", suffix)) };
}
if (string.Equals(audioCodec, "mp3", StringComparison.OrdinalIgnoreCase))
{
return new MediaFormatProfile[] { ValueOf(string.Format("MPEG4_P2_TS_ASP_MPEG1_L3{0}", suffix)) };
return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "MPEG4_P2_TS_ASP_MPEG1_L3{0}", suffix)) };
}
if (string.Equals(audioCodec, "mp2", StringComparison.OrdinalIgnoreCase))
{
return new MediaFormatProfile[] { ValueOf(string.Format("MPEG4_P2_TS_ASP_MPEG2_L2{0}", suffix)) };
return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "MPEG4_P2_TS_ASP_MPEG2_L2{0}", suffix)) };
}
if (string.Equals(audioCodec, "ac3", StringComparison.OrdinalIgnoreCase))
{
return new MediaFormatProfile[] { ValueOf(string.Format("MPEG4_P2_TS_ASP_AC3{0}", suffix)) };
return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "MPEG4_P2_TS_ASP_AC3{0}", suffix)) };
}
}

@ -191,7 +191,7 @@ namespace MediaBrowser.Model.Dlna
var encodedValue = pair.Value.Replace(" ", "%20");
list.Add(string.Format("{0}={1}", pair.Name, encodedValue));
list.Add(string.Format(CultureInfo.InvariantCulture, "{0}={1}", pair.Name, encodedValue));
}
string queryString = string.Join("&", list.ToArray());
@ -214,18 +214,18 @@ namespace MediaBrowser.Model.Dlna
{
if (string.Equals(SubProtocol, "hls", StringComparison.OrdinalIgnoreCase))
{
return string.Format("{0}/audio/{1}/master.m3u8?{2}", baseUrl, ItemId, queryString);
return string.Format(CultureInfo.InvariantCulture, "{0}/audio/{1}/master.m3u8?{2}", baseUrl, ItemId, queryString);
}
return string.Format("{0}/audio/{1}/stream{2}?{3}", baseUrl, ItemId, extension, queryString);
return string.Format(CultureInfo.InvariantCulture, "{0}/audio/{1}/stream{2}?{3}", baseUrl, ItemId, extension, queryString);
}
if (string.Equals(SubProtocol, "hls", StringComparison.OrdinalIgnoreCase))
{
return string.Format("{0}/videos/{1}/master.m3u8?{2}", baseUrl, ItemId, queryString);
return string.Format(CultureInfo.InvariantCulture, "{0}/videos/{1}/master.m3u8?{2}", baseUrl, ItemId, queryString);
}
return string.Format("{0}/videos/{1}/stream{2}?{3}", baseUrl, ItemId, extension, queryString);
return string.Format(CultureInfo.InvariantCulture, "{0}/videos/{1}/stream{2}?{3}", baseUrl, ItemId, extension, queryString);
}
private static List<NameValuePair> BuildParams(StreamInfo item, string accessToken)
@ -457,7 +457,7 @@ namespace MediaBrowser.Model.Dlna
{
if (MediaSource.Protocol == MediaProtocol.File || !string.Equals(stream.Codec, subtitleProfile.Format, StringComparison.OrdinalIgnoreCase) || !stream.IsExternal)
{
info.Url = string.Format("{0}/Videos/{1}/{2}/Subtitles/{3}/{4}/Stream.{5}",
info.Url = string.Format(CultureInfo.InvariantCulture, "{0}/Videos/{1}/{2}/Subtitles/{3}/{4}/Stream.{5}",
baseUrl,
ItemId,
MediaSourceId,

@ -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);
}
@ -355,7 +355,7 @@ namespace MediaBrowser.Providers.Manager
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)

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

@ -52,7 +52,6 @@ namespace MediaBrowser.Providers.Manager
public async Task<ItemUpdateType> RefreshMetadata(BaseItem item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken)
{
var itemOfType = (TItemType)item;
var config = ProviderManager.GetMetadataOptions(item);
var updateType = ItemUpdateType.None;
var requiresRefresh = false;
@ -86,7 +85,7 @@ namespace MediaBrowser.Providers.Manager
// Always validate images and check for new locally stored ones.
if (itemImageProvider.ValidateImages(item, allImageProviders.OfType<ILocalImageProvider>(), refreshOptions.DirectoryService))
{
updateType = updateType | ItemUpdateType.ImageUpdate;
updateType |= ItemUpdateType.ImageUpdate;
}
}
catch (Exception ex)
@ -102,7 +101,7 @@ namespace MediaBrowser.Providers.Manager
bool hasRefreshedMetadata = true;
bool hasRefreshedImages = true;
var isFirstRefresh = item.DateLastRefreshed == default(DateTime);
var isFirstRefresh = item.DateLastRefreshed == default;
// Next run metadata providers
if (refreshOptions.MetadataRefreshMode != MetadataRefreshMode.None)
@ -114,7 +113,7 @@ namespace MediaBrowser.Providers.Manager
{
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);
updateType = updateType | result.UpdateType;
updateType |= result.UpdateType;
if (result.Failures > 0)
{
hasRefreshedMetadata = false;
@ -147,9 +146,9 @@ namespace MediaBrowser.Providers.Manager
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)
{
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);
updateType = updateType | beforeSaveResult;
updateType |= beforeSaveResult;
// Save if changes were made, or it's never been saved before
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 (refreshOptions.ForceSave || refreshOptions.ReplaceAllMetadata)
{
updateType = updateType | ItemUpdateType.MetadataDownload;
updateType |= ItemUpdateType.MetadataDownload;
}
if (hasRefreshedMetadata && hasRefreshedImages)
@ -184,11 +183,11 @@ namespace MediaBrowser.Providers.Manager
}
else
{
item.DateLastRefreshed = default(DateTime);
item.DateLastRefreshed = default;
}
// Save to database
SaveItem(metadataResult, libraryOptions, updateType, cancellationToken);
await SaveItemAsync(metadataResult, libraryOptions, updateType, cancellationToken).ConfigureAwait(false);
}
await AfterMetadataRefresh(itemOfType, refreshOptions, cancellationToken).ConfigureAwait(false);
@ -203,26 +202,26 @@ namespace MediaBrowser.Providers.Manager
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)
{
var baseItem = result.Item;
LibraryManager.UpdatePeople(baseItem, result.People);
SavePeopleMetadata(result.People, libraryOptions, cancellationToken);
await SavePeopleMetadataAsync(result.People, libraryOptions, cancellationToken).ConfigureAwait(false);
}
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)
{
cancellationToken.ThrowIfCancellationRequested();
if (person.ProviderIds.Any() || !string.IsNullOrWhiteSpace(person.ImageUrl))
if (person.ProviderIds.Count > 0 || !string.IsNullOrWhiteSpace(person.ImageUrl))
{
var updateType = ItemUpdateType.MetadataDownload;
@ -239,10 +238,10 @@ namespace MediaBrowser.Providers.Manager
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;
updateType = updateType | ItemUpdateType.ImageUpdate;
updateType |= ItemUpdateType.ImageUpdate;
}
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)
//{
// 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,
Type = ImageType.Primary
}, 0);
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,
Type = ImageType.Primary
},
0);
}
protected virtual Task AfterMetadataRefresh(TItemType item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken)

@ -210,10 +210,10 @@ namespace MediaBrowser.Providers.Manager
}
/// <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)
.SaveImage(user, source, path);
.SaveImage(source, path);
}
/// <inheritdoc/>
@ -563,7 +563,7 @@ namespace MediaBrowser.Providers.Manager
var pluginList = summary.Plugins.ToList();
AddMetadataPlugins(pluginList, dummy, libraryOptions, options);
AddImagePlugins(pluginList, dummy, imageProviders);
AddImagePlugins(pluginList, imageProviders);
var subtitleProviders = _subtitleManager.GetSupportedProviders(dummy);
@ -594,14 +594,14 @@ namespace MediaBrowser.Providers.Manager
var providers = GetMetadataProvidersInternal<T>(item, libraryOptions, options, true, true).ToList();
// 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,
Type = MetadataPluginType.LocalMetadataProvider
}));
// 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,
Type = MetadataPluginType.MetadataFetcher
@ -615,11 +615,10 @@ namespace MediaBrowser.Providers.Manager
}));
}
private void AddImagePlugins<T>(List<MetadataPlugin> list, T item, List<IImageProvider> imageProviders)
where T : BaseItem
private void AddImagePlugins(List<MetadataPlugin> list, List<IImageProvider> imageProviders)
{
// 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,
Type = MetadataPluginType.LocalImageProvider
@ -1166,12 +1165,32 @@ namespace MediaBrowser.Providers.Manager
/// <inheritdoc/>
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)
{
_disposeCancellationTokenSource.Cancel();
}
if (disposing)
{
_disposeCancellationTokenSource.Dispose();
}
_disposed = true;
}
}
}

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

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

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

@ -276,7 +276,7 @@ namespace MediaBrowser.Providers.Music
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),
artistId);

@ -46,7 +46,7 @@ namespace MediaBrowser.Providers.Music
// They seem to throw bad request failures on any term with a slash
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))
await using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
@ -62,7 +62,7 @@ namespace MediaBrowser.Providers.Music
if (HasDiacritics(searchInfo.Name))
{
// 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);
await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Net.Http;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common;
@ -70,7 +71,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
list.Add(new RemoteImageInfo
{
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)
});
}
}

@ -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);
await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);

@ -256,16 +256,16 @@ namespace MediaBrowser.Providers.Plugins.Omdb
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))
{
return url;
return Url;
}
return url + "&" + query;
return Url + "&" + query;
}
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);
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);
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 filename = string.Format("{0}.json", imdbId);
var filename = string.Format(CultureInfo.InvariantCulture, "{0}.json", imdbId);
return Path.Combine(dataPath, filename);
}
@ -362,7 +371,7 @@ namespace MediaBrowser.Providers.Plugins.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);
}

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

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

@ -180,7 +180,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
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
url += "&include_image_language=" + TmdbMovieProvider.GetImageLanguagesParam(language);
@ -250,7 +250,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
{
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);
}

@ -300,7 +300,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
{
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
}).ToArray();

@ -37,7 +37,8 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
).* # Match rest of string",
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 IJsonSerializer _json;
@ -124,7 +125,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
name2 = name2.Trim();
// 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);
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))
{
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);
foreach (var header in TmdbUtils.AcceptHeaders)
@ -207,10 +228,31 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
{
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);
foreach (var header in TmdbUtils.AcceptHeaders)

@ -131,7 +131,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
{
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);
}
}

@ -92,7 +92,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
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),
episodeNumber.ToString(CultureInfo.InvariantCulture),
preferredLanguage);
@ -116,7 +116,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
if (!string.IsNullOrEmpty(language))
{
url += string.Format("&language={0}", language);
url += string.Format(CultureInfo.InvariantCulture, "&language={0}", language);
}
var includeImageLanguageParam = TmdbMovieProvider.GetImageLanguagesParam(language);

@ -180,7 +180,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
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),
preferredLanguage);
@ -203,7 +203,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
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);

@ -496,7 +496,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
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);
}

@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
@ -100,7 +101,7 @@ namespace MediaBrowser.Providers.Studios
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)

Loading…
Cancel
Save