mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-11-04 03:27:21 -05:00 
			
		
		
		
	migrate to IHttpClientFactory in SchedulesDirect
This commit is contained in:
		
							parent
							
								
									50a1e35765
								
							
						
					
					
						commit
						652e688cc1
					
				@ -8,6 +8,8 @@ using System.IO;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Net.Mime;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using MediaBrowser.Common;
 | 
			
		||||
@ -26,7 +28,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
 | 
			
		||||
    {
 | 
			
		||||
        private readonly ILogger<SchedulesDirect> _logger;
 | 
			
		||||
        private readonly IJsonSerializer _jsonSerializer;
 | 
			
		||||
        private readonly IHttpClient _httpClient;
 | 
			
		||||
        private readonly IHttpClientFactory _httpClientFactory;
 | 
			
		||||
        private readonly SemaphoreSlim _tokenSemaphore = new SemaphoreSlim(1, 1);
 | 
			
		||||
        private readonly IApplicationHost _appHost;
 | 
			
		||||
 | 
			
		||||
@ -35,12 +37,12 @@ namespace Emby.Server.Implementations.LiveTv.Listings
 | 
			
		||||
        public SchedulesDirect(
 | 
			
		||||
            ILogger<SchedulesDirect> logger,
 | 
			
		||||
            IJsonSerializer jsonSerializer,
 | 
			
		||||
            IHttpClient httpClient,
 | 
			
		||||
            IHttpClientFactory httpClientFactory,
 | 
			
		||||
            IApplicationHost appHost)
 | 
			
		||||
        {
 | 
			
		||||
            _logger = logger;
 | 
			
		||||
            _jsonSerializer = jsonSerializer;
 | 
			
		||||
            _httpClient = httpClient;
 | 
			
		||||
            _httpClientFactory = httpClientFactory;
 | 
			
		||||
            _appHost = appHost;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -102,38 +104,23 @@ namespace Emby.Server.Implementations.LiveTv.Listings
 | 
			
		||||
            var requestString = _jsonSerializer.SerializeToString(requestList);
 | 
			
		||||
            _logger.LogDebug("Request string for schedules is: {RequestString}", requestString);
 | 
			
		||||
 | 
			
		||||
            var httpOptions = new HttpRequestOptions()
 | 
			
		||||
            {
 | 
			
		||||
                Url = ApiUrl + "/schedules",
 | 
			
		||||
                UserAgent = UserAgent,
 | 
			
		||||
                CancellationToken = cancellationToken,
 | 
			
		||||
                LogErrorResponseBody = true,
 | 
			
		||||
                RequestContent = requestString
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            httpOptions.RequestHeaders["token"] = token;
 | 
			
		||||
 | 
			
		||||
            using (var response = await Post(httpOptions, true, info).ConfigureAwait(false))
 | 
			
		||||
            {
 | 
			
		||||
                var dailySchedules = await _jsonSerializer.DeserializeFromStreamAsync<List<ScheduleDirect.Day>>(response.Content).ConfigureAwait(false);
 | 
			
		||||
            using var options = new HttpRequestMessage(HttpMethod.Post, ApiUrl + "/schedules");
 | 
			
		||||
            options.Content = new StringContent(requestString, Encoding.UTF8, MediaTypeNames.Application.Json);
 | 
			
		||||
            options.Headers.TryAddWithoutValidation("token", token);
 | 
			
		||||
            using var response = await Send(options, true, info, cancellationToken).ConfigureAwait(false);
 | 
			
		||||
            await using var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
 | 
			
		||||
            var dailySchedules = await _jsonSerializer.DeserializeFromStreamAsync<List<ScheduleDirect.Day>>(responseStream).ConfigureAwait(false);
 | 
			
		||||
            _logger.LogDebug("Found {ScheduleCount} programs on {ChannelID} ScheduleDirect", dailySchedules.Count, channelId);
 | 
			
		||||
 | 
			
		||||
                httpOptions = new HttpRequestOptions()
 | 
			
		||||
                {
 | 
			
		||||
                    Url = ApiUrl + "/programs",
 | 
			
		||||
                    UserAgent = UserAgent,
 | 
			
		||||
                    CancellationToken = cancellationToken,
 | 
			
		||||
                    LogErrorResponseBody = true
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                httpOptions.RequestHeaders["token"] = token;
 | 
			
		||||
            using var programRequestOptions = new HttpRequestMessage(HttpMethod.Post, ApiUrl + "/programs");
 | 
			
		||||
            programRequestOptions.Headers.TryAddWithoutValidation("token", token);
 | 
			
		||||
 | 
			
		||||
            var programsID = dailySchedules.SelectMany(d => d.programs.Select(s => s.programID)).Distinct();
 | 
			
		||||
                httpOptions.RequestContent = "[\"" + string.Join("\", \"", programsID) + "\"]";
 | 
			
		||||
            programRequestOptions.Content = new StringContent("[\"" + string.Join("\", \"", programsID) + "\"]", Encoding.UTF8, MediaTypeNames.Application.Json);
 | 
			
		||||
 | 
			
		||||
                using (var innerResponse = await Post(httpOptions, true, info).ConfigureAwait(false))
 | 
			
		||||
                {
 | 
			
		||||
                    var programDetails = await _jsonSerializer.DeserializeFromStreamAsync<List<ScheduleDirect.ProgramDetails>>(innerResponse.Content).ConfigureAwait(false);
 | 
			
		||||
            using var innerResponse = await Send(programRequestOptions, true, info, cancellationToken).ConfigureAwait(false);
 | 
			
		||||
            await using var innerResponseStream = await innerResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
 | 
			
		||||
            var programDetails = await _jsonSerializer.DeserializeFromStreamAsync<List<ScheduleDirect.ProgramDetails>>(innerResponseStream).ConfigureAwait(false);
 | 
			
		||||
            var programDict = programDetails.ToDictionary(p => p.programID, y => y);
 | 
			
		||||
 | 
			
		||||
            var programIdsWithImages =
 | 
			
		||||
@ -190,8 +177,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings
 | 
			
		||||
 | 
			
		||||
            return programsInfo;
 | 
			
		||||
        }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static int GetSizeOrder(ScheduleDirect.ImageData image)
 | 
			
		||||
        {
 | 
			
		||||
@ -482,22 +467,15 @@ namespace Emby.Server.Implementations.LiveTv.Listings
 | 
			
		||||
 | 
			
		||||
            imageIdString = imageIdString.TrimEnd(',') + "]";
 | 
			
		||||
 | 
			
		||||
            var httpOptions = new HttpRequestOptions()
 | 
			
		||||
            {
 | 
			
		||||
                Url = ApiUrl + "/metadata/programs",
 | 
			
		||||
                UserAgent = UserAgent,
 | 
			
		||||
                CancellationToken = cancellationToken,
 | 
			
		||||
                RequestContent = imageIdString,
 | 
			
		||||
                LogErrorResponseBody = true,
 | 
			
		||||
            };
 | 
			
		||||
            using var message = new HttpRequestMessage(HttpMethod.Post, ApiUrl + "/metadata/programs");
 | 
			
		||||
            message.Content = new StringContent(imageIdString, Encoding.UTF8, MediaTypeNames.Application.Json);
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                using (var innerResponse2 = await Post(httpOptions, true, info).ConfigureAwait(false))
 | 
			
		||||
                {
 | 
			
		||||
                using var innerResponse2 = await Send(message, true, info, cancellationToken).ConfigureAwait(false);
 | 
			
		||||
                await using var response = await innerResponse2.Content.ReadAsStreamAsync();
 | 
			
		||||
                return await _jsonSerializer.DeserializeFromStreamAsync<List<ScheduleDirect.ShowImages>>(
 | 
			
		||||
                        innerResponse2.Content).ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
                    response).ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
@ -518,22 +496,15 @@ namespace Emby.Server.Implementations.LiveTv.Listings
 | 
			
		||||
                return lineups;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var options = new HttpRequestOptions()
 | 
			
		||||
            {
 | 
			
		||||
                Url = ApiUrl + "/headends?country=" + country + "&postalcode=" + location,
 | 
			
		||||
                UserAgent = UserAgent,
 | 
			
		||||
                CancellationToken = cancellationToken,
 | 
			
		||||
                LogErrorResponseBody = true
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            options.RequestHeaders["token"] = token;
 | 
			
		||||
            using var options = new HttpRequestMessage(HttpMethod.Get, ApiUrl + "/headends?country=" + country + "&postalcode=" + location);
 | 
			
		||||
            options.Headers.TryAddWithoutValidation("token", token);
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                using (var httpResponse = await Get(options, false, info).ConfigureAwait(false))
 | 
			
		||||
                using (Stream responce = httpResponse.Content)
 | 
			
		||||
                {
 | 
			
		||||
                    var root = await _jsonSerializer.DeserializeFromStreamAsync<List<ScheduleDirect.Headends>>(responce).ConfigureAwait(false);
 | 
			
		||||
                using var httpResponse = await Send(options, false, info, cancellationToken).ConfigureAwait(false);
 | 
			
		||||
                await using var response = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
                var root = await _jsonSerializer.DeserializeFromStreamAsync<List<ScheduleDirect.Headends>>(response).ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
                if (root != null)
 | 
			
		||||
                {
 | 
			
		||||
@ -554,7 +525,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings
 | 
			
		||||
                    _logger.LogInformation("No lineups available");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                _logger.LogError(ex, "Error getting headends");
 | 
			
		||||
@ -633,83 +603,46 @@ namespace Emby.Server.Implementations.LiveTv.Listings
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task<HttpResponseInfo> Post(HttpRequestOptions options,
 | 
			
		||||
        private async Task<HttpResponseMessage> Send(
 | 
			
		||||
            HttpRequestMessage options,
 | 
			
		||||
            bool enableRetry,
 | 
			
		||||
            ListingsProviderInfo providerInfo)
 | 
			
		||||
        {
 | 
			
		||||
            // Schedules direct requires that the client support compression and will return a 400 response without it
 | 
			
		||||
            options.DecompressionMethod = CompressionMethods.Deflate;
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                return await _httpClient.Post(options).ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            catch (HttpException ex)
 | 
			
		||||
            {
 | 
			
		||||
                _tokens.Clear();
 | 
			
		||||
 | 
			
		||||
                if (!ex.StatusCode.HasValue || (int)ex.StatusCode.Value >= 500)
 | 
			
		||||
                {
 | 
			
		||||
                    enableRetry = false;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (!enableRetry)
 | 
			
		||||
                {
 | 
			
		||||
                    throw;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            options.RequestHeaders["token"] = await GetToken(providerInfo, options.CancellationToken).ConfigureAwait(false);
 | 
			
		||||
            return await Post(options, false, providerInfo).ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task<HttpResponseInfo> Get(HttpRequestOptions options,
 | 
			
		||||
            bool enableRetry,
 | 
			
		||||
            ListingsProviderInfo providerInfo)
 | 
			
		||||
        {
 | 
			
		||||
            // Schedules direct requires that the client support compression and will return a 400 response without it
 | 
			
		||||
            options.DecompressionMethod = CompressionMethods.Deflate;
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                return await _httpClient.SendAsync(options, HttpMethod.Get).ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            catch (HttpException ex)
 | 
			
		||||
            {
 | 
			
		||||
                _tokens.Clear();
 | 
			
		||||
 | 
			
		||||
                if (!ex.StatusCode.HasValue || (int)ex.StatusCode.Value >= 500)
 | 
			
		||||
                {
 | 
			
		||||
                    enableRetry = false;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (!enableRetry)
 | 
			
		||||
                {
 | 
			
		||||
                    throw;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            options.RequestHeaders["token"] = await GetToken(providerInfo, options.CancellationToken).ConfigureAwait(false);
 | 
			
		||||
            return await Get(options, false, providerInfo).ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task<string> GetTokenInternal(string username, string password,
 | 
			
		||||
            ListingsProviderInfo providerInfo,
 | 
			
		||||
            CancellationToken cancellationToken)
 | 
			
		||||
        {
 | 
			
		||||
            var httpOptions = new HttpRequestOptions()
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                Url = ApiUrl + "/token",
 | 
			
		||||
                UserAgent = UserAgent,
 | 
			
		||||
                RequestContent = "{\"username\":\"" + username + "\",\"password\":\"" + password + "\"}",
 | 
			
		||||
                CancellationToken = cancellationToken,
 | 
			
		||||
                LogErrorResponseBody = true
 | 
			
		||||
            };
 | 
			
		||||
            // _logger.LogInformation("Obtaining token from Schedules Direct from addres: " + httpOptions.Url + " with body " +
 | 
			
		||||
            // httpOptions.RequestContent);
 | 
			
		||||
                return await _httpClientFactory.CreateClient(NamedClient.Default).SendAsync(options, cancellationToken).ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            catch (HttpException ex)
 | 
			
		||||
            {
 | 
			
		||||
                _tokens.Clear();
 | 
			
		||||
 | 
			
		||||
            using (var response = await Post(httpOptions, false, null).ConfigureAwait(false))
 | 
			
		||||
                if (!ex.StatusCode.HasValue || (int)ex.StatusCode.Value >= 500)
 | 
			
		||||
                {
 | 
			
		||||
                var root = await _jsonSerializer.DeserializeFromStreamAsync<ScheduleDirect.Token>(response.Content).ConfigureAwait(false);
 | 
			
		||||
                    enableRetry = false;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (!enableRetry)
 | 
			
		||||
                {
 | 
			
		||||
                    throw;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            options.Headers.TryAddWithoutValidation("token", await GetToken(providerInfo, cancellationToken).ConfigureAwait(false));
 | 
			
		||||
            return await Send(options, false, providerInfo, cancellationToken).ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task<string> GetTokenInternal(
 | 
			
		||||
            string username,
 | 
			
		||||
            string password,
 | 
			
		||||
            CancellationToken cancellationToken)
 | 
			
		||||
        {
 | 
			
		||||
            using var options = new HttpRequestMessage(HttpMethod.Post, ApiUrl + "/token");
 | 
			
		||||
            options.Content = new StringContent("{\"username\":\"" + username + "\",\"password\":\"" + password + "\"}", Encoding.UTF8, MediaTypeNames.Application.Json);
 | 
			
		||||
 | 
			
		||||
            using var response = await Send(options, false, null, cancellationToken).ConfigureAwait(false);
 | 
			
		||||
            await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
 | 
			
		||||
            var root = await _jsonSerializer.DeserializeFromStreamAsync<ScheduleDirect.Token>(stream).ConfigureAwait(false);
 | 
			
		||||
            if (root.message == "OK")
 | 
			
		||||
            {
 | 
			
		||||
                _logger.LogInformation("Authenticated with Schedules Direct token: " + root.token);
 | 
			
		||||
@ -718,7 +651,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings
 | 
			
		||||
 | 
			
		||||
            throw new Exception("Could not authenticate with Schedules Direct Error: " + root.message);
 | 
			
		||||
        }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task AddLineupToAccount(ListingsProviderInfo info, CancellationToken cancellationToken)
 | 
			
		||||
        {
 | 
			
		||||
@ -736,20 +668,9 @@ namespace Emby.Server.Implementations.LiveTv.Listings
 | 
			
		||||
 | 
			
		||||
            _logger.LogInformation("Adding new LineUp ");
 | 
			
		||||
 | 
			
		||||
            var httpOptions = new HttpRequestOptions()
 | 
			
		||||
            {
 | 
			
		||||
                Url = ApiUrl + "/lineups/" + info.ListingsId,
 | 
			
		||||
                UserAgent = UserAgent,
 | 
			
		||||
                CancellationToken = cancellationToken,
 | 
			
		||||
                LogErrorResponseBody = true,
 | 
			
		||||
                BufferContent = false
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            httpOptions.RequestHeaders["token"] = token;
 | 
			
		||||
 | 
			
		||||
            using (await _httpClient.SendAsync(httpOptions, HttpMethod.Put).ConfigureAwait(false))
 | 
			
		||||
            {
 | 
			
		||||
            }
 | 
			
		||||
            using var options = new HttpRequestMessage(HttpMethod.Put, ApiUrl + "/lineups/" + info.ListingsId);
 | 
			
		||||
            options.Headers.TryAddWithoutValidation("token", token);
 | 
			
		||||
            using var response = await _httpClientFactory.CreateClient(NamedClient.Default).SendAsync(options, cancellationToken).ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task<bool> HasLineup(ListingsProviderInfo info, CancellationToken cancellationToken)
 | 
			
		||||
@ -768,26 +689,18 @@ namespace Emby.Server.Implementations.LiveTv.Listings
 | 
			
		||||
 | 
			
		||||
            _logger.LogInformation("Headends on account ");
 | 
			
		||||
 | 
			
		||||
            var options = new HttpRequestOptions()
 | 
			
		||||
            {
 | 
			
		||||
                Url = ApiUrl + "/lineups",
 | 
			
		||||
                UserAgent = UserAgent,
 | 
			
		||||
                CancellationToken = cancellationToken,
 | 
			
		||||
                LogErrorResponseBody = true
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            options.RequestHeaders["token"] = token;
 | 
			
		||||
            using var options = new HttpRequestMessage(HttpMethod.Get, ApiUrl + "/lineups");
 | 
			
		||||
            options.Headers.TryAddWithoutValidation("token", token);
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                using (var httpResponse = await Get(options, false, null).ConfigureAwait(false))
 | 
			
		||||
                using (var response = httpResponse.Content)
 | 
			
		||||
                {
 | 
			
		||||
                    var root = await _jsonSerializer.DeserializeFromStreamAsync<ScheduleDirect.Lineups>(response).ConfigureAwait(false);
 | 
			
		||||
                using var httpResponse = await Send(options, false, null, cancellationToken).ConfigureAwait(false);
 | 
			
		||||
                await using var stream = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
 | 
			
		||||
                using var response = httpResponse.Content;
 | 
			
		||||
                var root = await _jsonSerializer.DeserializeFromStreamAsync<ScheduleDirect.Lineups>(stream).ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
                return root.lineups.Any(i => string.Equals(info.ListingsId, i.lineup, StringComparison.OrdinalIgnoreCase));
 | 
			
		||||
            }
 | 
			
		||||
            }
 | 
			
		||||
            catch (HttpException ex)
 | 
			
		||||
            {
 | 
			
		||||
                // Apparently we're supposed to swallow this
 | 
			
		||||
@ -851,22 +764,14 @@ namespace Emby.Server.Implementations.LiveTv.Listings
 | 
			
		||||
                throw new Exception("token required");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var httpOptions = new HttpRequestOptions()
 | 
			
		||||
            {
 | 
			
		||||
                Url = ApiUrl + "/lineups/" + listingsId,
 | 
			
		||||
                UserAgent = UserAgent,
 | 
			
		||||
                CancellationToken = cancellationToken,
 | 
			
		||||
                LogErrorResponseBody = true,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            httpOptions.RequestHeaders["token"] = token;
 | 
			
		||||
            using var options = new HttpRequestMessage(HttpMethod.Get, ApiUrl + "/lineups/" + listingsId);
 | 
			
		||||
            options.Headers.TryAddWithoutValidation("token", token);
 | 
			
		||||
 | 
			
		||||
            var list = new List<ChannelInfo>();
 | 
			
		||||
 | 
			
		||||
            using (var httpResponse = await Get(httpOptions, true, info).ConfigureAwait(false))
 | 
			
		||||
            using (var response = httpResponse.Content)
 | 
			
		||||
            {
 | 
			
		||||
                var root = await _jsonSerializer.DeserializeFromStreamAsync<ScheduleDirect.Channel>(response).ConfigureAwait(false);
 | 
			
		||||
            using var httpResponse = await Send(options, true, info, cancellationToken).ConfigureAwait(false);
 | 
			
		||||
            await using var stream = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
 | 
			
		||||
            var root = await _jsonSerializer.DeserializeFromStreamAsync<ScheduleDirect.Channel>(stream).ConfigureAwait(false);
 | 
			
		||||
            _logger.LogInformation("Found {ChannelCount} channels on the lineup on ScheduleDirect", root.map.Count);
 | 
			
		||||
            _logger.LogInformation("Mapping Stations to Channel");
 | 
			
		||||
 | 
			
		||||
@ -879,19 +784,10 @@ namespace Emby.Server.Implementations.LiveTv.Listings
 | 
			
		||||
                var station = allStations.FirstOrDefault(item => string.Equals(item.stationID, map.stationID, StringComparison.OrdinalIgnoreCase));
 | 
			
		||||
                if (station == null)
 | 
			
		||||
                {
 | 
			
		||||
                        station = new ScheduleDirect.Station
 | 
			
		||||
                        {
 | 
			
		||||
                            stationID = map.stationID
 | 
			
		||||
                        };
 | 
			
		||||
                    station = new ScheduleDirect.Station {stationID = map.stationID};
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                    var channelInfo = new ChannelInfo
 | 
			
		||||
                    {
 | 
			
		||||
                        Id = station.stationID,
 | 
			
		||||
                        CallSign = station.callsign,
 | 
			
		||||
                        Number = channelNumber,
 | 
			
		||||
                        Name = string.IsNullOrWhiteSpace(station.name) ? channelNumber : station.name
 | 
			
		||||
                    };
 | 
			
		||||
                var channelInfo = new ChannelInfo {Id = station.stationID, CallSign = station.callsign, Number = channelNumber, Name = string.IsNullOrWhiteSpace(station.name) ? channelNumber : station.name};
 | 
			
		||||
 | 
			
		||||
                if (station.logo != null)
 | 
			
		||||
                {
 | 
			
		||||
@ -900,7 +796,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings
 | 
			
		||||
 | 
			
		||||
                list.Add(channelInfo);
 | 
			
		||||
            }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return list;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user