Merge pull request #1830 from MediaBrowser/dev

Dev
This commit is contained in:
Luke 2016-06-08 11:25:17 -04:00
commit b6b5a0e6dc
13 changed files with 203 additions and 39 deletions

View File

@ -402,38 +402,23 @@ namespace MediaBrowser.Controller.Entities.TV
public static IEnumerable<Episode> FilterEpisodesBySeason(IEnumerable<Episode> episodes, Season parentSeason, bool includeSpecials) public static IEnumerable<Episode> FilterEpisodesBySeason(IEnumerable<Episode> episodes, Season parentSeason, bool includeSpecials)
{ {
var seasonNumber = parentSeason.IndexNumber; var seasonNumber = parentSeason.IndexNumber;
if (!includeSpecials || (seasonNumber.HasValue && seasonNumber.Value == 0))
{
var seasonPresentationKey = parentSeason.PresentationUniqueKey; var seasonPresentationKey = parentSeason.PresentationUniqueKey;
return episodes.Where(i => var supportSpecialsInSeason = includeSpecials && seasonNumber.HasValue && seasonNumber.Value != 0;
{
if ((i.ParentIndexNumber ?? -1) == seasonNumber)
{
return true;
}
if (!i.ParentIndexNumber.HasValue)
{
var season = i.Season;
return season != null && string.Equals(season.PresentationUniqueKey, seasonPresentationKey, StringComparison.OrdinalIgnoreCase);
}
return false;
});
}
else
{
var seasonPresentationKey = parentSeason.PresentationUniqueKey;
return episodes.Where(episode => return episodes.Where(episode =>
{ {
var currentSeasonNumber = episode.AiredSeasonNumber; var currentSeasonNumber = supportSpecialsInSeason ? episode.AiredSeasonNumber : episode.ParentIndexNumber;
if (currentSeasonNumber.HasValue && seasonNumber.HasValue && currentSeasonNumber.Value == seasonNumber.Value) if (currentSeasonNumber.HasValue && seasonNumber.HasValue && currentSeasonNumber.Value == seasonNumber.Value)
{ {
return true; return true;
} }
if (!currentSeasonNumber.HasValue && !seasonNumber.HasValue && parentSeason.LocationType == LocationType.Virtual)
{
return true;
}
if (!episode.ParentIndexNumber.HasValue) if (!episode.ParentIndexNumber.HasValue)
{ {
var season = episode.Season; var season = episode.Season;
@ -443,7 +428,6 @@ namespace MediaBrowser.Controller.Entities.TV
return false; return false;
}); });
} }
}
protected override bool GetBlockUnratedValue(UserPolicy config) protected override bool GetBlockUnratedValue(UserPolicy config)
{ {

View File

@ -15,5 +15,6 @@ namespace MediaBrowser.Controller.LiveTv
Task AddMetadata(ListingsProviderInfo info, List<ChannelInfo> channels, CancellationToken cancellationToken); Task AddMetadata(ListingsProviderInfo info, List<ChannelInfo> channels, CancellationToken cancellationToken);
Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings); Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings);
Task<List<NameIdPair>> GetLineups(ListingsProviderInfo info, string country, string location); Task<List<NameIdPair>> GetLineups(ListingsProviderInfo info, string country, string location);
Task<List<ChannelInfo>> GetChannels(ListingsProviderInfo info, CancellationToken cancellationToken);
} }
} }

View File

@ -8,6 +8,7 @@ using MediaBrowser.Model.Querying;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Model.Events;
namespace MediaBrowser.Controller.LiveTv namespace MediaBrowser.Controller.LiveTv
{ {
@ -385,5 +386,12 @@ namespace MediaBrowser.Controller.LiveTv
List<NameValuePair> GetSatIniMappings(); List<NameValuePair> GetSatIniMappings();
Task<List<ChannelInfo>> GetSatChannelScanResult(TunerHostInfo info, CancellationToken cancellationToken); Task<List<ChannelInfo>> GetSatChannelScanResult(TunerHostInfo info, CancellationToken cancellationToken);
Task<List<ChannelInfo>> GetChannelsFromListingsProvider(string id, CancellationToken cancellationToken);
event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCancelled;
event EventHandler<GenericEventArgs<TimerEventInfo>> TimerCancelled;
event EventHandler<GenericEventArgs<TimerEventInfo>> TimerCreated;
event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCreated;
} }
} }

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.LiveTv
{
public class TimerEventInfo
{
public string Id { get; set; }
public string ProgramId { get; set; }
}
}

View File

@ -218,6 +218,7 @@
<Compile Include="LiveTv\ProgramInfo.cs" /> <Compile Include="LiveTv\ProgramInfo.cs" />
<Compile Include="LiveTv\RecordingInfo.cs" /> <Compile Include="LiveTv\RecordingInfo.cs" />
<Compile Include="LiveTv\SeriesTimerInfo.cs" /> <Compile Include="LiveTv\SeriesTimerInfo.cs" />
<Compile Include="LiveTv\TimerEventInfo.cs" />
<Compile Include="LiveTv\TimerInfo.cs" /> <Compile Include="LiveTv\TimerInfo.cs" />
<Compile Include="Localization\ILocalizationManager.cs" /> <Compile Include="Localization\ILocalizationManager.cs" />
<Compile Include="MediaEncoding\ChapterImageRefreshOptions.cs" /> <Compile Include="MediaEncoding\ChapterImageRefreshOptions.cs" />

View File

@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using MediaBrowser.Model.Dto; using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Model.LiveTv namespace MediaBrowser.Model.LiveTv
{ {
@ -90,5 +91,17 @@ namespace MediaBrowser.Model.LiveTv
EnableAllTuners = true; EnableAllTuners = true;
ChannelMappings = new NameValuePair[] {}; ChannelMappings = new NameValuePair[] {};
} }
public string GetMappedChannel(string channelNumber)
{
foreach (NameValuePair mapping in ChannelMappings)
{
if (StringHelper.EqualsIgnoreCase(mapping.Name, channelNumber))
{
return mapping.Value;
}
}
return channelNumber;
}
} }
} }

View File

@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Logging;
namespace MediaBrowser.Server.Implementations.EntryPoints
{
public class RecordingNotifier : IServerEntryPoint
{
private readonly ILiveTvManager _liveTvManager;
private readonly ISessionManager _sessionManager;
private readonly IUserManager _userManager;
private readonly ILogger _logger;
public RecordingNotifier(ISessionManager sessionManager, IUserManager userManager, ILogger logger, ILiveTvManager liveTvManager)
{
_sessionManager = sessionManager;
_userManager = userManager;
_logger = logger;
_liveTvManager = liveTvManager;
}
public void Run()
{
_liveTvManager.TimerCancelled += _liveTvManager_TimerCancelled;
_liveTvManager.SeriesTimerCancelled += _liveTvManager_SeriesTimerCancelled;
_liveTvManager.TimerCreated += _liveTvManager_TimerCreated;
_liveTvManager.SeriesTimerCreated += _liveTvManager_SeriesTimerCreated;
}
private void _liveTvManager_SeriesTimerCreated(object sender, Model.Events.GenericEventArgs<TimerEventInfo> e)
{
SendMessage("SeriesTimerCreated", e.Argument);
}
private void _liveTvManager_TimerCreated(object sender, Model.Events.GenericEventArgs<TimerEventInfo> e)
{
SendMessage("TimerCreated", e.Argument);
}
private void _liveTvManager_SeriesTimerCancelled(object sender, Model.Events.GenericEventArgs<TimerEventInfo> e)
{
SendMessage("SeriesTimerCancelled", e.Argument);
}
private void _liveTvManager_TimerCancelled(object sender, Model.Events.GenericEventArgs<TimerEventInfo> e)
{
SendMessage("TimerCancelled", e.Argument);
}
private async void SendMessage(string name, TimerEventInfo info)
{
var users = _userManager.Users.Where(i => i.Policy.EnableLiveTvAccess).ToList();
foreach (var user in users)
{
try
{
await _sessionManager.SendMessageToUserSessions<TimerEventInfo>(user.Id.ToString("N"), name, info, CancellationToken.None);
}
catch (Exception ex)
{
_logger.ErrorException("Error sending message", ex);
}
}
}
public void Dispose()
{
_liveTvManager.TimerCancelled -= _liveTvManager_TimerCancelled;
_liveTvManager.SeriesTimerCancelled -= _liveTvManager_SeriesTimerCancelled;
_liveTvManager.TimerCreated -= _liveTvManager_TimerCreated;
_liveTvManager.SeriesTimerCreated -= _liveTvManager_SeriesTimerCreated;
}
}
}

View File

@ -1000,7 +1000,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
result.Item3.Release(); result.Item3.Release();
} }
_libraryMonitor.ReportFileSystemChangeComplete(recordPath, false); _libraryMonitor.ReportFileSystemChangeComplete(recordPath, true);
} }
} }
catch (OperationCanceledException) catch (OperationCanceledException)

View File

@ -869,6 +869,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
return GetHeadends(info, country, location, CancellationToken.None); return GetHeadends(info, country, location, CancellationToken.None);
} }
public async Task<List<ChannelInfo>> GetChannels(ListingsProviderInfo info, CancellationToken cancellationToken)
{
return new List<ChannelInfo>();
}
public class ScheduleDirect public class ScheduleDirect
{ {
public class Token public class Token

View File

@ -107,11 +107,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
var reader = new XmlTvReader(info.Path, GetLanguage(), null); var reader = new XmlTvReader(info.Path, GetLanguage(), null);
var results = reader.GetChannels().ToList(); var results = reader.GetChannels().ToList();
if (channels != null && channels.Count > 0) if (channels != null)
{ {
channels.ForEach(c => channels.ForEach(c =>
{ {
var match = results.FirstOrDefault(r => r.Id == c.Id); var channelNumber = info.GetMappedChannel(c.Number);
var match = results.FirstOrDefault(r => string.Equals(r.Id, channelNumber, StringComparison.OrdinalIgnoreCase));
if (match != null && match.Icon != null && !String.IsNullOrEmpty(match.Icon.Source)) if (match != null && match.Icon != null && !String.IsNullOrEmpty(match.Icon.Source))
{ {
c.ImageUrl = match.Icon.Source; c.ImageUrl = match.Icon.Source;
@ -142,5 +144,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
// Should this method be async? // Should this method be async?
return Task.FromResult(results.Select(c => new NameIdPair() { Id = c.Id, Name = c.DisplayName }).ToList()); return Task.FromResult(results.Select(c => new NameIdPair() { Id = c.Id, Name = c.DisplayName }).ToList());
} }
public async Task<List<ChannelInfo>> GetChannels(ListingsProviderInfo info, CancellationToken cancellationToken)
{
return new List<ChannelInfo>();
}
} }
} }

View File

@ -30,6 +30,8 @@ using System.Threading.Tasks;
using CommonIO; using CommonIO;
using IniParser; using IniParser;
using IniParser.Model; using IniParser.Model;
using MediaBrowser.Common.Events;
using MediaBrowser.Model.Events;
namespace MediaBrowser.Server.Implementations.LiveTv namespace MediaBrowser.Server.Implementations.LiveTv
{ {
@ -64,6 +66,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
private readonly List<IListingsProvider> _listingProviders = new List<IListingsProvider>(); private readonly List<IListingsProvider> _listingProviders = new List<IListingsProvider>();
private readonly IFileSystem _fileSystem; private readonly IFileSystem _fileSystem;
public event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCancelled;
public event EventHandler<GenericEventArgs<TimerEventInfo>> TimerCancelled;
public event EventHandler<GenericEventArgs<TimerEventInfo>> TimerCreated;
public event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCreated;
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, IFileSystem fileSystem) 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, IFileSystem fileSystem)
{ {
_config = config; _config = config;
@ -1759,6 +1766,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv
await service.CancelTimerAsync(timer.ExternalId, CancellationToken.None).ConfigureAwait(false); await service.CancelTimerAsync(timer.ExternalId, CancellationToken.None).ConfigureAwait(false);
_lastRecordingRefreshTime = DateTime.MinValue; _lastRecordingRefreshTime = DateTime.MinValue;
EventHelper.QueueEventIfNotNull(TimerCancelled, this, new GenericEventArgs<TimerEventInfo>
{
Argument = new TimerEventInfo
{
Id = id
}
}, _logger);
} }
public async Task CancelSeriesTimer(string id) public async Task CancelSeriesTimer(string id)
@ -1774,6 +1789,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv
await service.CancelSeriesTimerAsync(timer.ExternalId, CancellationToken.None).ConfigureAwait(false); await service.CancelSeriesTimerAsync(timer.ExternalId, CancellationToken.None).ConfigureAwait(false);
_lastRecordingRefreshTime = DateTime.MinValue; _lastRecordingRefreshTime = DateTime.MinValue;
EventHelper.QueueEventIfNotNull(SeriesTimerCancelled, this, new GenericEventArgs<TimerEventInfo>
{
Argument = new TimerEventInfo
{
Id = id
}
}, _logger);
} }
public async Task<BaseItemDto> GetRecording(string id, DtoOptions options, CancellationToken cancellationToken, User user = null) public async Task<BaseItemDto> GetRecording(string id, DtoOptions options, CancellationToken cancellationToken, User user = null)
@ -1993,6 +2016,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv
await service.CreateTimerAsync(info, cancellationToken).ConfigureAwait(false); await service.CreateTimerAsync(info, cancellationToken).ConfigureAwait(false);
_lastRecordingRefreshTime = DateTime.MinValue; _lastRecordingRefreshTime = DateTime.MinValue;
_logger.Info("New recording scheduled"); _logger.Info("New recording scheduled");
EventHelper.QueueEventIfNotNull(TimerCreated, this, new GenericEventArgs<TimerEventInfo>
{
Argument = new TimerEventInfo
{
ProgramId = info.ProgramId
}
}, _logger);
} }
public async Task CreateSeriesTimer(SeriesTimerInfoDto timer, CancellationToken cancellationToken) public async Task CreateSeriesTimer(SeriesTimerInfoDto timer, CancellationToken cancellationToken)
@ -2007,6 +2038,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv
await service.CreateSeriesTimerAsync(info, cancellationToken).ConfigureAwait(false); await service.CreateSeriesTimerAsync(info, cancellationToken).ConfigureAwait(false);
_lastRecordingRefreshTime = DateTime.MinValue; _lastRecordingRefreshTime = DateTime.MinValue;
EventHelper.QueueEventIfNotNull(SeriesTimerCreated, this, new GenericEventArgs<TimerEventInfo>
{
Argument = new TimerEventInfo
{
ProgramId = info.ProgramId
}
}, _logger);
} }
public async Task UpdateTimer(TimerInfoDto timer, CancellationToken cancellationToken) public async Task UpdateTimer(TimerInfoDto timer, CancellationToken cancellationToken)
@ -2521,5 +2560,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv
{ {
return new TunerHosts.SatIp.ChannelScan(_logger).Scan(info, cancellationToken); return new TunerHosts.SatIp.ChannelScan(_logger).Scan(info, cancellationToken);
} }
public Task<List<ChannelInfo>> GetChannelsFromListingsProvider(string id, CancellationToken cancellationToken)
{
var info = GetConfiguration().ListingProviders.First(i => string.Equals(i.Id, id, StringComparison.OrdinalIgnoreCase));
var provider = _listingProviders.First(i => string.Equals(i.Type, info.Type, StringComparison.OrdinalIgnoreCase));
return provider.GetChannels(info, cancellationToken);
}
} }
} }

View File

@ -142,6 +142,7 @@
<Compile Include="EntryPoints\LoadRegistrations.cs" /> <Compile Include="EntryPoints\LoadRegistrations.cs" />
<Compile Include="EntryPoints\Notifications\Notifications.cs" /> <Compile Include="EntryPoints\Notifications\Notifications.cs" />
<Compile Include="EntryPoints\Notifications\WebSocketNotifier.cs" /> <Compile Include="EntryPoints\Notifications\WebSocketNotifier.cs" />
<Compile Include="EntryPoints\RecordingNotifier.cs" />
<Compile Include="EntryPoints\RefreshUsersMetadata.cs" /> <Compile Include="EntryPoints\RefreshUsersMetadata.cs" />
<Compile Include="EntryPoints\UsageEntryPoint.cs" /> <Compile Include="EntryPoints\UsageEntryPoint.cs" />
<Compile Include="Connect\ConnectEntryPoint.cs" /> <Compile Include="Connect\ConnectEntryPoint.cs" />

View File

@ -381,7 +381,8 @@ namespace MediaBrowser.Server.Startup.Common
new OmdbEpisodeProviderMigration(ServerConfigurationManager), new OmdbEpisodeProviderMigration(ServerConfigurationManager),
new MovieDbEpisodeProviderMigration(ServerConfigurationManager), new MovieDbEpisodeProviderMigration(ServerConfigurationManager),
new DbMigration(ServerConfigurationManager, TaskManager), new DbMigration(ServerConfigurationManager, TaskManager),
new FolderViewSettingMigration(ServerConfigurationManager, UserManager) new FolderViewSettingMigration(ServerConfigurationManager, UserManager),
new CollectionGroupingMigration(ServerConfigurationManager, UserManager)
}; };
foreach (var task in migrations) foreach (var task in migrations)