jellyfin-server/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs

231 lines
7.9 KiB
C#
Raw Normal View History

2016-01-25 21:33:36 +00:00
using System;
using System.Collections.Generic;
2016-02-19 06:20:18 +00:00
using System.IO;
2016-01-25 21:33:36 +00:00
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
2016-02-19 06:20:18 +00:00
using System.Xml;
2016-01-25 21:33:36 +00:00
using MediaBrowser.Common.Configuration;
2016-02-19 06:20:18 +00:00
using MediaBrowser.Common.Extensions;
2016-01-25 21:33:36 +00:00
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Logging;
2016-02-19 06:20:18 +00:00
using MediaBrowser.Model.Serialization;
2016-01-25 21:33:36 +00:00
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
{
public class SatIpDiscovery : IServerEntryPoint
{
private readonly IDeviceDiscovery _deviceDiscovery;
private readonly IServerConfigurationManager _config;
private readonly ILogger _logger;
private readonly ILiveTvManager _liveTvManager;
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
private readonly IHttpClient _httpClient;
2016-02-19 06:20:18 +00:00
private readonly IJsonSerializer _json;
2016-01-25 21:33:36 +00:00
2016-02-19 06:20:18 +00:00
public static SatIpDiscovery Current;
private readonly List<TunerHostInfo> _discoveredHosts = new List<TunerHostInfo>();
public List<TunerHostInfo> DiscoveredHosts
{
get { return _discoveredHosts.ToList(); }
}
public SatIpDiscovery(IDeviceDiscovery deviceDiscovery, IServerConfigurationManager config, ILogger logger, ILiveTvManager liveTvManager, IHttpClient httpClient, IJsonSerializer json)
2016-01-25 21:33:36 +00:00
{
_deviceDiscovery = deviceDiscovery;
_config = config;
_logger = logger;
_liveTvManager = liveTvManager;
_httpClient = httpClient;
2016-02-19 06:20:18 +00:00
_json = json;
Current = this;
2016-01-25 21:33:36 +00:00
}
public void Run()
{
_deviceDiscovery.DeviceDiscovered += _deviceDiscovery_DeviceDiscovered;
}
void _deviceDiscovery_DeviceDiscovered(object sender, SsdpMessageEventArgs e)
{
2016-02-15 05:47:23 +00:00
string st = null;
2016-02-17 21:24:01 +00:00
string nt = null;
e.Headers.TryGetValue("ST", out st);
e.Headers.TryGetValue("NT", out nt);
if (string.Equals(st, "urn:ses-com:device:SatIPServer:1", StringComparison.OrdinalIgnoreCase) ||
string.Equals(nt, "urn:ses-com:device:SatIPServer:1", StringComparison.OrdinalIgnoreCase))
2016-02-15 05:47:23 +00:00
{
string location;
if (e.Headers.TryGetValue("Location", out location) && !string.IsNullOrWhiteSpace(location))
{
_logger.Debug("SAT IP found at {0}", location);
2016-01-25 21:33:36 +00:00
2016-02-15 05:47:23 +00:00
// Just get the beginning of the url
AddDevice(location);
}
}
2016-01-25 21:33:36 +00:00
}
2016-02-15 05:47:23 +00:00
private async void AddDevice(string location)
2016-01-25 21:33:36 +00:00
{
await _semaphore.WaitAsync().ConfigureAwait(false);
try
{
2016-02-19 06:20:18 +00:00
if (_discoveredHosts.Any(i => string.Equals(i.Type, SatIpHost.DeviceType, StringComparison.OrdinalIgnoreCase) && string.Equals(location, i.Url, StringComparison.OrdinalIgnoreCase)))
{
return;
}
2016-01-25 21:33:36 +00:00
2016-02-19 06:20:18 +00:00
_logger.Debug("Will attempt to add SAT device {0}", location);
var info = await GetInfo(location, CancellationToken.None).ConfigureAwait(false);
2016-02-15 05:47:23 +00:00
2016-02-19 06:20:18 +00:00
_discoveredHosts.Add(info);
}
catch (OperationCanceledException)
{
2016-01-25 21:33:36 +00:00
2016-02-19 06:20:18 +00:00
}
catch (NotImplementedException)
{
2016-01-25 21:33:36 +00:00
}
catch (Exception ex)
{
_logger.ErrorException("Error saving device", ex);
}
finally
{
_semaphore.Release();
}
}
2016-02-19 06:20:18 +00:00
public void Dispose()
2016-01-25 21:33:36 +00:00
{
2016-02-19 06:20:18 +00:00
}
public async Task<SatIpTunerHostInfo> GetInfo(string url, CancellationToken cancellationToken)
{
var result = new SatIpTunerHostInfo
2016-01-25 21:33:36 +00:00
{
2016-02-19 06:20:18 +00:00
Url = url,
IsEnabled = true,
Type = SatIpHost.DeviceType,
Tuners = 1,
TunersAvailable = 1
};
using (var stream = await _httpClient.Get(url, cancellationToken).ConfigureAwait(false))
{
using (var streamReader = new StreamReader(stream))
{
// Use XmlReader for best performance
using (var reader = XmlReader.Create(streamReader))
{
reader.MoveToContent();
// Loop through each element
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "device":
using (var subtree = reader.ReadSubtree())
{
FillFromDeviceNode(result, subtree);
}
break;
default:
reader.Skip();
break;
}
}
}
}
}
}
if (string.IsNullOrWhiteSpace(result.Id))
2016-01-25 21:33:36 +00:00
{
2016-02-19 06:20:18 +00:00
throw new NotImplementedException();
2016-01-25 21:33:36 +00:00
}
2016-02-19 17:14:42 +00:00
// Device hasn't implemented an m3u list
2016-02-19 06:20:18 +00:00
if (string.IsNullOrWhiteSpace(result.M3UUrl))
{
2016-02-19 17:14:42 +00:00
result.IsEnabled = false;
2016-02-19 06:20:18 +00:00
}
2016-01-25 21:33:36 +00:00
2016-02-19 17:14:42 +00:00
else if (!result.M3UUrl.StartsWith("http", StringComparison.OrdinalIgnoreCase))
2016-01-25 21:33:36 +00:00
{
2016-02-19 06:20:18 +00:00
var fullM3uUrl = url.Substring(0, url.LastIndexOf('/'));
result.M3UUrl = fullM3uUrl + "/" + result.M3UUrl.TrimStart('/');
2016-01-25 21:33:36 +00:00
}
2016-02-19 06:20:18 +00:00
_logger.Debug("SAT device result: {0}", _json.SerializeToString(result));
2016-01-25 21:33:36 +00:00
2016-02-19 06:20:18 +00:00
return result;
2016-01-25 21:33:36 +00:00
}
2016-02-19 06:20:18 +00:00
private void FillFromDeviceNode(SatIpTunerHostInfo info, XmlReader reader)
2016-01-25 21:33:36 +00:00
{
2016-02-19 06:20:18 +00:00
reader.MoveToContent();
2016-01-25 21:33:36 +00:00
2016-02-19 06:20:18 +00:00
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
2016-02-20 02:45:12 +00:00
switch (reader.LocalName)
2016-02-19 06:20:18 +00:00
{
case "UDN":
{
info.Id = reader.ReadElementContentAsString();
break;
}
2016-02-19 17:14:42 +00:00
case "satip:X_SATIPCAP":
2016-02-19 06:20:18 +00:00
case "X_SATIPCAP":
{
2016-02-19 06:23:59 +00:00
// <satip:X_SATIPCAP xmlns:satip="urn:ses-com:satip">DVBS2-2</satip:X_SATIPCAP>
2016-02-19 06:20:18 +00:00
var value = reader.ReadElementContentAsString();
// TODO
break;
}
2016-02-19 17:14:42 +00:00
case "satip:X_SATIPM3U":
2016-02-19 06:20:18 +00:00
case "X_SATIPM3U":
{
2016-02-19 06:23:59 +00:00
// <satip:X_SATIPM3U xmlns:satip="urn:ses-com:satip">/channellist.lua?select=m3u</satip:X_SATIPM3U>
2016-02-19 06:20:18 +00:00
info.M3UUrl = reader.ReadElementContentAsString();
break;
}
default:
reader.Skip();
break;
}
}
}
2016-01-25 21:33:36 +00:00
}
}
2016-02-19 06:20:18 +00:00
public class SatIpTunerHostInfo : TunerHostInfo
{
public int Tuners { get; set; }
public int TunersAvailable { get; set; }
public string M3UUrl { get; set; }
}
2016-01-25 21:33:36 +00:00
}