-
Notifications
You must be signed in to change notification settings - Fork 819
/
Copy pathHdHomerunDiscovery.cs
154 lines (134 loc) · 5.64 KB
/
HdHomerunDiscovery.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
using MediaBrowser.Common.Configuration;
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;
using System;
using System.Linq;
using System.Threading;
using MediaBrowser.Common.Net;
using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
public class HdHomerunDiscovery : 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;
private readonly IJsonSerializer _json;
public HdHomerunDiscovery(IDeviceDiscovery deviceDiscovery, IServerConfigurationManager config, ILogger logger, ILiveTvManager liveTvManager, IHttpClient httpClient, IJsonSerializer json)
{
_deviceDiscovery = deviceDiscovery;
_config = config;
_logger = logger;
_liveTvManager = liveTvManager;
_httpClient = httpClient;
_json = json;
}
public void Run()
{
_deviceDiscovery.DeviceDiscovered += _deviceDiscovery_DeviceDiscovered;
}
void _deviceDiscovery_DeviceDiscovered(object sender, SsdpMessageEventArgs e)
{
string server = null;
if (e.Headers.TryGetValue("SERVER", out server) && server.IndexOf("HDHomeRun", StringComparison.OrdinalIgnoreCase) != -1)
{
string location;
if (e.Headers.TryGetValue("Location", out location))
{
//_logger.Debug("HdHomerun found at {0}", location);
// Just get the beginning of the url
Uri uri;
if (Uri.TryCreate(location, UriKind.Absolute, out uri))
{
var apiUrl = location.Replace(uri.LocalPath, String.Empty, StringComparison.OrdinalIgnoreCase)
.TrimEnd('/');
//_logger.Debug("HdHomerun api url: {0}", apiUrl);
AddDevice(apiUrl);
}
}
}
}
private async void AddDevice(string url)
{
await _semaphore.WaitAsync().ConfigureAwait(false);
try
{
var options = GetConfiguration();
if (options.TunerHosts.Any(i =>
string.Equals(i.Type, HdHomerunHost.DeviceType, StringComparison.OrdinalIgnoreCase) &&
UriEquals(i.Url, url)))
{
return;
}
// Strip off the port
url = new Uri(url).GetComponents(UriComponents.AbsoluteUri & ~UriComponents.Port, UriFormat.UriEscaped).TrimEnd('/');
// Test it by pulling down the lineup
using (var stream = await _httpClient.Get(new HttpRequestOptions
{
Url = string.Format("{0}/discover.json", url),
CancellationToken = CancellationToken.None
}))
{
var response = _json.DeserializeFromStream<HdHomerunHost.DiscoverResponse>(stream);
var existing = GetConfiguration().TunerHosts
.FirstOrDefault(i => string.Equals(i.Type, HdHomerunHost.DeviceType, StringComparison.OrdinalIgnoreCase) && string.Equals(i.DeviceId, response.DeviceID, StringComparison.OrdinalIgnoreCase));
if (existing == null)
{
await _liveTvManager.SaveTunerHost(new TunerHostInfo
{
Type = HdHomerunHost.DeviceType,
Url = url,
DataVersion = 1,
DeviceId = response.DeviceID
}).ConfigureAwait(false);
}
else
{
if (!string.Equals(existing.Url, url, StringComparison.OrdinalIgnoreCase))
{
existing.Url = url;
await _liveTvManager.SaveTunerHost(existing).ConfigureAwait(false);
}
}
}
}
catch (Exception ex)
{
_logger.ErrorException("Error saving device", ex);
}
finally
{
_semaphore.Release();
}
}
private bool UriEquals(string savedUri, string location)
{
return string.Equals(NormalizeUrl(location), NormalizeUrl(savedUri), StringComparison.OrdinalIgnoreCase);
}
private string NormalizeUrl(string url)
{
if (!url.StartsWith("http", StringComparison.OrdinalIgnoreCase))
{
url = "http://" + url;
}
url = url.TrimEnd('/');
// Strip off the port
return new Uri(url).GetComponents(UriComponents.AbsoluteUri & ~UriComponents.Port, UriFormat.UriEscaped);
}
private LiveTvOptions GetConfiguration()
{
return _config.GetConfiguration<LiveTvOptions>("livetv");
}
public void Dispose()
{
}
}
}