update tuner setup
This commit is contained in:
parent
f9f29de05e
commit
3fda8ec5c2
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.LiveTv;
|
||||
|
@ -345,6 +346,31 @@ namespace MediaBrowser.Api.LiveTv
|
|||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
[Route("/LiveTv/ListingProviders", "POST", Summary = "Adds a listing provider")]
|
||||
[Authenticated]
|
||||
public class AddListingProvider : ListingsProviderInfo, IReturn<ListingsProviderInfo>
|
||||
{
|
||||
}
|
||||
|
||||
[Route("/LiveTv/ListingProviders", "DELETE", Summary = "Deletes a listing provider")]
|
||||
[Authenticated]
|
||||
public class DeleteListingProvider : IReturnVoid
|
||||
{
|
||||
[ApiMember(Name = "Id", Description = "Provider id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "DELETE")]
|
||||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
[Route("/LiveTv/ListingProviders/Lineups", "GET", Summary = "Gets available lineups")]
|
||||
[Authenticated]
|
||||
public class GetLineups : IReturn<List<NameIdPair>>
|
||||
{
|
||||
[ApiMember(Name = "Id", Description = "Provider id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string Id { get; set; }
|
||||
|
||||
[ApiMember(Name = "Location", Description = "Location", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string Location { get; set; }
|
||||
}
|
||||
|
||||
public class LiveTvService : BaseApiService
|
||||
{
|
||||
private readonly ILiveTvManager _liveTvManager;
|
||||
|
@ -373,20 +399,27 @@ namespace MediaBrowser.Api.LiveTv
|
|||
}
|
||||
}
|
||||
|
||||
public void Post(AddTunerHost request)
|
||||
public object Post(AddListingProvider request)
|
||||
{
|
||||
var result = _liveTvManager.SaveListingProvider(request).Result;
|
||||
return ToOptimizedResult(result);
|
||||
}
|
||||
|
||||
public void Delete(DeleteListingProvider request)
|
||||
{
|
||||
var config = GetConfiguration();
|
||||
|
||||
config.TunerHosts.Add(new TunerHostInfo
|
||||
{
|
||||
Id = Guid.NewGuid().ToString("N"),
|
||||
Url = request.Url,
|
||||
Type = request.Type
|
||||
});
|
||||
config.ListingProviders = config.ListingProviders.Where(i => !string.Equals(request.Id, i.Id, StringComparison.OrdinalIgnoreCase)).ToList();
|
||||
|
||||
_config.SaveConfiguration("livetv", config);
|
||||
}
|
||||
|
||||
public void Post(AddTunerHost request)
|
||||
{
|
||||
var task = _liveTvManager.SaveTunerHost(request);
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
|
||||
public void Delete(DeleteTunerHost request)
|
||||
{
|
||||
var config = GetConfiguration();
|
||||
|
@ -401,6 +434,13 @@ namespace MediaBrowser.Api.LiveTv
|
|||
return _config.GetConfiguration<LiveTvOptions>("livetv");
|
||||
}
|
||||
|
||||
public async Task<object> Get(GetLineups request)
|
||||
{
|
||||
var info = await _liveTvManager.GetLineups(request.Id, request.Location).ConfigureAwait(false);
|
||||
|
||||
return ToOptimizedSerializedResultUsingCache(info);
|
||||
}
|
||||
|
||||
public async Task<object> Get(GetLiveTvInfo request)
|
||||
{
|
||||
var info = await _liveTvManager.GetLiveTvInfo(CancellationToken.None).ConfigureAwait(false);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Model.LiveTv;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.LiveTv;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
@ -9,7 +10,10 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
public interface IListingsProvider
|
||||
{
|
||||
string Name { get; }
|
||||
string Type { get; }
|
||||
Task<IEnumerable<ProgramInfo>> GetProgramsAsync(ListingsProviderInfo info, ChannelInfo channel, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken);
|
||||
Task AddMetadata(ListingsProviderInfo info, List<ChannelInfo> channels, CancellationToken cancellationToken);
|
||||
Task Validate(ListingsProviderInfo info);
|
||||
Task<List<NameIdPair>> GetLineups(ListingsProviderInfo info, string location);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,9 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
/// Adds the parts.
|
||||
/// </summary>
|
||||
/// <param name="services">The services.</param>
|
||||
void AddParts(IEnumerable<ILiveTvService> services);
|
||||
/// <param name="tunerHosts">The tuner hosts.</param>
|
||||
/// <param name="listingProviders">The listing providers.</param>
|
||||
void AddParts(IEnumerable<ILiveTvService> services, IEnumerable<ITunerHost> tunerHosts, IEnumerable<IListingsProvider> listingProviders);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the channels.
|
||||
|
@ -337,5 +339,24 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
/// <param name="dto">The dto.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
void AddInfoToProgramDto(BaseItem item, BaseItemDto dto, User user = null);
|
||||
/// <summary>
|
||||
/// Saves the tuner host.
|
||||
/// </summary>
|
||||
/// <param name="info">The information.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task SaveTunerHost(TunerHostInfo info);
|
||||
/// <summary>
|
||||
/// Saves the listing provider.
|
||||
/// </summary>
|
||||
/// <param name="info">The information.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task<ListingsProviderInfo> SaveListingProvider(ListingsProviderInfo info);
|
||||
/// <summary>
|
||||
/// Gets the lineups.
|
||||
/// </summary>
|
||||
/// <param name="providerId">The provider identifier.</param>
|
||||
/// <param name="location">The location.</param>
|
||||
/// <returns>Task<List<NameIdPair>>.</returns>
|
||||
Task<List<NameIdPair>> GetLineups(string providerId, string location);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,5 +46,11 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task<MediaSourceInfo>.</returns>
|
||||
Task<MediaSourceInfo> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken);
|
||||
/// <summary>
|
||||
/// Validates the specified information.
|
||||
/// </summary>
|
||||
/// <param name="info">The information.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task Validate(TunerHostInfo info);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,10 +28,11 @@ namespace MediaBrowser.Model.LiveTv
|
|||
|
||||
public class ListingsProviderInfo
|
||||
{
|
||||
public string ProviderName { get; set; }
|
||||
public string Id { get; set; }
|
||||
public string Type { get; set; }
|
||||
public string Username { get; set; }
|
||||
public string Password { get; set; }
|
||||
public string ZipCode { get; set; }
|
||||
public string ListingsId { get; set; }
|
||||
public string ZipCode { get; set; }
|
||||
}
|
||||
}
|
|
@ -30,18 +30,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
private readonly ItemDataProvider<SeriesTimerInfo> _seriesTimerProvider;
|
||||
private readonly TimerManager _timerProvider;
|
||||
|
||||
private readonly List<ITunerHost> _tunerHosts = new List<ITunerHost>();
|
||||
private readonly List<IListingsProvider> _listingProviders = new List<IListingsProvider>();
|
||||
private readonly LiveTvManager _liveTvManager;
|
||||
|
||||
public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IConfigurationManager config)
|
||||
public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IConfigurationManager config, ILiveTvManager liveTvManager)
|
||||
{
|
||||
_appHpst = appHost;
|
||||
_logger = logger;
|
||||
_httpClient = httpClient;
|
||||
_config = config;
|
||||
_liveTvManager = (LiveTvManager)liveTvManager;
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_tunerHosts.AddRange(appHost.GetExports<ITunerHost>());
|
||||
_listingProviders.AddRange(appHost.GetExports<IListingsProvider>());
|
||||
|
||||
_recordingProvider = new ItemDataProvider<RecordingInfo>(jsonSerializer, _logger, Path.Combine(DataPath, "recordings"), (r1, r2) => string.Equals(r1.Id, r2.Id, StringComparison.OrdinalIgnoreCase));
|
||||
_seriesTimerProvider = new SeriesTimerManager(jsonSerializer, _logger, Path.Combine(DataPath, "seriestimers"));
|
||||
|
@ -76,7 +74,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
var status = new LiveTvServiceStatusInfo();
|
||||
var list = new List<LiveTvTunerInfo>();
|
||||
|
||||
foreach (var host in _tunerHosts)
|
||||
foreach (var host in _liveTvManager.TunerHosts)
|
||||
{
|
||||
foreach (var hostInstance in host.GetTunerHosts())
|
||||
{
|
||||
|
@ -104,7 +102,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
{
|
||||
var list = new List<ChannelInfo>();
|
||||
|
||||
foreach (var host in _tunerHosts)
|
||||
foreach (var host in _liveTvManager.TunerHosts)
|
||||
{
|
||||
foreach (var hostInstance in host.GetTunerHosts())
|
||||
{
|
||||
|
@ -288,7 +286,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
return GetConfiguration().ListingProviders
|
||||
.Select(i =>
|
||||
{
|
||||
var provider = _listingProviders.FirstOrDefault(l => string.Equals(l.Name, i.ProviderName, StringComparison.OrdinalIgnoreCase));
|
||||
var provider = _liveTvManager.ListingProviders.FirstOrDefault(l => string.Equals(l.Type, i.Type, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
return provider == null ? null : new Tuple<IListingsProvider, ListingsProviderInfo>(provider, i);
|
||||
})
|
||||
|
|
|
@ -422,7 +422,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
|
|||
return images;
|
||||
}
|
||||
|
||||
public async Task<List<NameIdPair>> GetHeadends(ListingsProviderInfo info, CancellationToken cancellationToken)
|
||||
public async Task<List<NameIdPair>> GetHeadends(ListingsProviderInfo info, string location, CancellationToken cancellationToken)
|
||||
{
|
||||
var token = await GetToken(info, cancellationToken);
|
||||
|
||||
|
@ -437,7 +437,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
|
|||
|
||||
var options = new HttpRequestOptions()
|
||||
{
|
||||
Url = ApiUrl + "/headends?country=USA&postalcode=" + info.ZipCode,
|
||||
Url = ApiUrl + "/headends?country=USA&postalcode=" + location,
|
||||
UserAgent = UserAgent,
|
||||
CancellationToken = cancellationToken
|
||||
};
|
||||
|
@ -483,9 +483,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
|
|||
private readonly ConcurrentDictionary<string, NameValuePair> _tokens = new ConcurrentDictionary<string, NameValuePair>();
|
||||
|
||||
private async Task<string> GetToken(ListingsProviderInfo info, CancellationToken cancellationToken)
|
||||
{
|
||||
await _tokenSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
var username = info.Username;
|
||||
|
||||
|
@ -521,6 +518,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
|
|||
}
|
||||
}
|
||||
|
||||
await _tokenSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
var result = await GetTokenInternal(username, password, cancellationToken).ConfigureAwait(false);
|
||||
savedToken.Name = result;
|
||||
savedToken.Value = DateTime.UtcNow.Ticks.ToString(CultureInfo.InvariantCulture);
|
||||
|
@ -563,6 +563,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
|
|||
get { return "Schedules Direct"; }
|
||||
}
|
||||
|
||||
public string Type
|
||||
{
|
||||
get { return "SchedulesDirect"; }
|
||||
}
|
||||
|
||||
public class ScheduleDirect
|
||||
{
|
||||
public class Token
|
||||
|
@ -842,5 +847,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
|
|||
|
||||
}
|
||||
|
||||
public async Task Validate(ListingsProviderInfo info)
|
||||
{
|
||||
}
|
||||
|
||||
public Task<List<NameIdPair>> GetLineups(ListingsProviderInfo info, string location)
|
||||
{
|
||||
return GetHeadends(info, location, CancellationToken.None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,6 +57,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
|
||||
private readonly ConcurrentDictionary<Guid, Guid> _refreshedPrograms = new ConcurrentDictionary<Guid, Guid>();
|
||||
|
||||
private readonly List<ITunerHost> _tunerHosts = new List<ITunerHost>();
|
||||
private readonly List<IListingsProvider> _listingProviders = new List<IListingsProvider>();
|
||||
|
||||
public LiveTvManager(IApplicationHost appHost, IServerConfigurationManager config, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager, ILibraryManager libraryManager, ITaskManager taskManager, ILocalizationManager localization, IJsonSerializer jsonSerializer, IProviderManager providerManager)
|
||||
{
|
||||
_config = config;
|
||||
|
@ -92,9 +95,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
/// Adds the parts.
|
||||
/// </summary>
|
||||
/// <param name="services">The services.</param>
|
||||
public void AddParts(IEnumerable<ILiveTvService> services)
|
||||
/// <param name="tunerHosts">The tuner hosts.</param>
|
||||
/// <param name="listingProviders">The listing providers.</param>
|
||||
public void AddParts(IEnumerable<ILiveTvService> services, IEnumerable<ITunerHost> tunerHosts, IEnumerable<IListingsProvider> listingProviders)
|
||||
{
|
||||
_services.AddRange(services);
|
||||
_tunerHosts.AddRange(tunerHosts);
|
||||
_listingProviders.AddRange(listingProviders);
|
||||
|
||||
foreach (var service in _services)
|
||||
{
|
||||
|
@ -102,6 +109,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
}
|
||||
}
|
||||
|
||||
public List<ITunerHost> TunerHosts
|
||||
{
|
||||
get { return _tunerHosts; }
|
||||
}
|
||||
|
||||
public List<IListingsProvider> ListingProviders
|
||||
{
|
||||
get { return _listingProviders; }
|
||||
}
|
||||
|
||||
void service_DataSourceChanged(object sender, EventArgs e)
|
||||
{
|
||||
_taskManager.CancelIfRunningAndQueue<RefreshChannelsScheduledTask>();
|
||||
|
@ -2154,5 +2171,84 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
var user = _userManager.GetUserById(userId);
|
||||
return await _libraryManager.GetNamedView(user, name, "livetv", "zz_" + name, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task SaveTunerHost(TunerHostInfo info)
|
||||
{
|
||||
info = (TunerHostInfo)_jsonSerializer.DeserializeFromString(_jsonSerializer.SerializeToString(info), typeof(TunerHostInfo));
|
||||
|
||||
var provider = _tunerHosts.FirstOrDefault(i => string.Equals(info.Type, i.Type, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (provider == null)
|
||||
{
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
|
||||
await provider.Validate(info).ConfigureAwait(false);
|
||||
|
||||
var config = GetConfiguration();
|
||||
|
||||
var index = config.TunerHosts.FindIndex(i => string.Equals(i.Id, info.Id, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (index == -1 || string.IsNullOrWhiteSpace(info.Id))
|
||||
{
|
||||
info.Id = Guid.NewGuid().ToString("N");
|
||||
config.TunerHosts.Add(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
config.TunerHosts[index] = info;
|
||||
}
|
||||
|
||||
_config.SaveConfiguration("livetv", config);
|
||||
}
|
||||
|
||||
public async Task<ListingsProviderInfo> SaveListingProvider(ListingsProviderInfo info)
|
||||
{
|
||||
info = (ListingsProviderInfo)_jsonSerializer.DeserializeFromString(_jsonSerializer.SerializeToString(info), typeof(ListingsProviderInfo));
|
||||
|
||||
var provider = _listingProviders.FirstOrDefault(i => string.Equals(info.Type, i.Type, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (provider == null)
|
||||
{
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
|
||||
await provider.Validate(info).ConfigureAwait(false);
|
||||
|
||||
var config = GetConfiguration();
|
||||
|
||||
var index = config.ListingProviders.FindIndex(i => string.Equals(i.Id, info.Id, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (index == -1 || string.IsNullOrWhiteSpace(info.Id))
|
||||
{
|
||||
info.Id = Guid.NewGuid().ToString("N");
|
||||
config.ListingProviders.Add(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
config.ListingProviders[index] = info;
|
||||
}
|
||||
|
||||
_config.SaveConfiguration("livetv", config);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
public Task<List<NameIdPair>> GetLineups(string providerId, string location)
|
||||
{
|
||||
var config = GetConfiguration();
|
||||
|
||||
var info = config.ListingProviders.FirstOrDefault(i => string.Equals(i.Id, providerId, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
var provider = _listingProviders.FirstOrDefault(i => string.Equals(info.Type, i.Type, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (provider == null)
|
||||
{
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
|
||||
return provider.GetLineups(info, location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ using MediaBrowser.Common.Net;
|
|||
using MediaBrowser.Controller.LiveTv;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Extensions;
|
||||
using MediaBrowser.Model.LiveTv;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.MediaInfo;
|
||||
|
@ -15,7 +14,6 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Server.Implementations.LiveTv.EmbyTV;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
|
||||
{
|
||||
|
@ -222,5 +220,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
|
|||
}
|
||||
throw new ApplicationException("Channel not found.");
|
||||
}
|
||||
|
||||
|
||||
public async Task Validate(TunerHostInfo info)
|
||||
{
|
||||
await GetChannels(info, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -185,5 +185,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
|
|||
{
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Validate(TunerHostInfo info)
|
||||
{
|
||||
if (!File.Exists(info.Url))
|
||||
{
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -820,5 +820,8 @@
|
|||
"MessageConfirmDeleteTunerDevice": "Are you sure you wish to delete this device?",
|
||||
"MessageConfirmDeleteGuideProvider": "Are you sure you wish to delete this guide provider?",
|
||||
"HeaderDeleteProvider": "Delete Provider",
|
||||
"HeaderAddProvider": "Add Provider"
|
||||
"HeaderAddProvider": "Add Provider",
|
||||
"ErrorAddingTunerDevice": "There was an error adding the tuner device. Please ensure it is accessible and try again.",
|
||||
"ErrorSavingTvProvider": "There was an error saving the TV provider. Please ensure it is accessible and try again.",
|
||||
"ErrorGettingTvLineups": "There was an error downloading tv lineups. Please ensure your username and password are correct and try again."
|
||||
}
|
||||
|
|
|
@ -1483,5 +1483,8 @@
|
|||
"TabTuners": "Tuners",
|
||||
"HeaderGuideProviders": "Guide Providers",
|
||||
"AddGuideProviderHelp": "Add a source for TV Guide information",
|
||||
"LabelZipCode": "Zip Code"
|
||||
"LabelZipCode": "Zip Code:",
|
||||
"GuideProviderListingsStep": "Step 2: Select Listings",
|
||||
"GuideProviderLoginStep": "Step 1: Login",
|
||||
"LabelLineup": "Lineup"
|
||||
}
|
||||
|
|
|
@ -784,7 +784,7 @@ namespace MediaBrowser.Server.Startup.Common
|
|||
|
||||
ImageProcessor.AddParts(GetExports<IImageEnhancer>());
|
||||
|
||||
LiveTvManager.AddParts(GetExports<ILiveTvService>());
|
||||
LiveTvManager.AddParts(GetExports<ILiveTvService>(), GetExports<ITunerHost>(), GetExports<IListingsProvider>());
|
||||
|
||||
SubtitleManager.AddParts(GetExports<ISubtitleProvider>());
|
||||
ChapterManager.AddParts(GetExports<IChapterProvider>());
|
||||
|
|
|
@ -183,7 +183,7 @@
|
|||
<Content Include="dashboard-ui\livetvguide.html">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\livetvguidesettings.html">
|
||||
<Content Include="dashboard-ui\livetvguideprovider-scd.html">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\livetvrecordings.html">
|
||||
|
@ -207,7 +207,7 @@
|
|||
<Content Include="dashboard-ui\scripts\homeupcoming.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\scripts\livetvguidesettings.js">
|
||||
<Content Include="dashboard-ui\scripts\livetvguideprovider-scd.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\scripts\mypreferenceshome.js">
|
||||
|
|
Loading…
Reference in New Issue
Block a user