aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2015-06-01 13:07:55 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2015-06-01 13:07:55 -0400
commit418bb8787869b13eca2da0095e94be6b22f2f10d (patch)
treeaacac83852e3c7f0f797cf9006810d1590a42600
parent17fe8caee47a5de0184649feaec434ac8c076019 (diff)
update recording database
-rw-r--r--MediaBrowser.Controller/Entities/IHasId.cs9
-rw-r--r--MediaBrowser.Controller/Entities/IHasImages.cs9
-rw-r--r--MediaBrowser.Controller/Entities/IHasMediaSources.cs9
-rw-r--r--MediaBrowser.Controller/Entities/IHasProgramAttributes.cs12
-rw-r--r--MediaBrowser.Controller/Entities/IHasUserData.cs9
-rw-r--r--MediaBrowser.Controller/LiveTv/ILiveTvItem.cs5
-rw-r--r--MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs20
-rw-r--r--MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs23
-rw-r--r--MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs23
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj1
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs2
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs207
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/RecordingImageProvider.cs14
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs28
-rw-r--r--MediaBrowser.Server.Implementations/Session/SessionManager.cs10
-rw-r--r--Nuget/MediaBrowser.Common.Internal.nuspec4
-rw-r--r--Nuget/MediaBrowser.Common.nuspec2
-rw-r--r--Nuget/MediaBrowser.Model.Signed.nuspec2
-rw-r--r--Nuget/MediaBrowser.Server.Core.nuspec4
19 files changed, 259 insertions, 134 deletions
diff --git a/MediaBrowser.Controller/Entities/IHasId.cs b/MediaBrowser.Controller/Entities/IHasId.cs
new file mode 100644
index 000000000..9698adf7a
--- /dev/null
+++ b/MediaBrowser.Controller/Entities/IHasId.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace MediaBrowser.Controller.Entities
+{
+ public interface IHasId
+ {
+ Guid Id { get; }
+ }
+}
diff --git a/MediaBrowser.Controller/Entities/IHasImages.cs b/MediaBrowser.Controller/Entities/IHasImages.cs
index 1871d7b68..ffb351c94 100644
--- a/MediaBrowser.Controller/Entities/IHasImages.cs
+++ b/MediaBrowser.Controller/Entities/IHasImages.cs
@@ -1,13 +1,12 @@
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
-using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Entities
{
- public interface IHasImages : IHasProviderIds
+ public interface IHasImages : IHasProviderIds, IHasId
{
/// <summary>
/// Gets the name.
@@ -28,12 +27,6 @@ namespace MediaBrowser.Controller.Entities
string FileNameWithoutExtension { get; }
/// <summary>
- /// Gets the identifier.
- /// </summary>
- /// <value>The identifier.</value>
- Guid Id { get; }
-
- /// <summary>
/// Gets the type of the location.
/// </summary>
/// <value>The type of the location.</value>
diff --git a/MediaBrowser.Controller/Entities/IHasMediaSources.cs b/MediaBrowser.Controller/Entities/IHasMediaSources.cs
index 17a147806..85ce3c781 100644
--- a/MediaBrowser.Controller/Entities/IHasMediaSources.cs
+++ b/MediaBrowser.Controller/Entities/IHasMediaSources.cs
@@ -1,18 +1,11 @@
using MediaBrowser.Model.Dto;
-using System;
using System.Collections.Generic;
namespace MediaBrowser.Controller.Entities
{
- public interface IHasMediaSources
+ public interface IHasMediaSources : IHasId
{
/// <summary>
- /// Gets the identifier.
- /// </summary>
- /// <value>The identifier.</value>
- Guid Id { get; }
-
- /// <summary>
/// Gets the media sources.
/// </summary>
/// <param name="enablePathSubstitution">if set to <c>true</c> [enable path substitution].</param>
diff --git a/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs b/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs
index 1878d8d2c..391c8f7a7 100644
--- a/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs
+++ b/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs
@@ -1,9 +1,19 @@
-
+using MediaBrowser.Model.LiveTv;
+using System;
+
namespace MediaBrowser.Controller.Entities
{
public interface IHasProgramAttributes
{
bool IsMovie { get; set; }
bool IsSports { get; set; }
+ bool IsNews { get; set; }
+ bool IsKids { get; set; }
+ bool IsRepeat { get; set; }
+ bool? IsHD { get; set; }
+ bool IsLive { get; set; }
+ bool IsPremiere { get; set; }
+ ProgramAudio? Audio { get; set; }
+ DateTime? OriginalAirDate { get; set; }
}
}
diff --git a/MediaBrowser.Controller/Entities/IHasUserData.cs b/MediaBrowser.Controller/Entities/IHasUserData.cs
index d576d90c4..34a820853 100644
--- a/MediaBrowser.Controller/Entities/IHasUserData.cs
+++ b/MediaBrowser.Controller/Entities/IHasUserData.cs
@@ -1,20 +1,13 @@
using MediaBrowser.Model.Dto;
-using System;
namespace MediaBrowser.Controller.Entities
{
/// <summary>
/// Interface IHasUserData
/// </summary>
- public interface IHasUserData
+ public interface IHasUserData : IHasId
{
/// <summary>
- /// Gets or sets the identifier.
- /// </summary>
- /// <value>The identifier.</value>
- Guid Id { get; set; }
-
- /// <summary>
/// Gets the user data key.
/// </summary>
/// <returns>System.String.</returns>
diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvItem.cs b/MediaBrowser.Controller/LiveTv/ILiveTvItem.cs
index 6c277a2e1..313675fb7 100644
--- a/MediaBrowser.Controller/LiveTv/ILiveTvItem.cs
+++ b/MediaBrowser.Controller/LiveTv/ILiveTvItem.cs
@@ -1,10 +1,9 @@
-using System;
+using MediaBrowser.Controller.Entities;
namespace MediaBrowser.Controller.LiveTv
{
- public interface ILiveTvItem
+ public interface ILiveTvItem : IHasId
{
- Guid Id { get; }
string ServiceName { get; set; }
}
}
diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs
index 93e1e576a..1dd267c93 100644
--- a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs
+++ b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs
@@ -2,19 +2,21 @@
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Library;
+using MediaBrowser.Model.LiveTv;
+using System;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.LiveTv
{
- public interface ILiveTvRecording : IHasImages, IHasMediaSources, IHasUserData, ILiveTvItem
+ public interface ILiveTvRecording : IHasImages, IHasMediaSources, IHasUserData, ILiveTvItem, IHasStartDate, IHasProgramAttributes
{
+ string ChannelId { get; }
+ string ProgramId { get; set; }
string MediaType { get; }
string Container { get; }
- RecordingInfo RecordingInfo { get; set; }
-
long? RunTimeTicks { get; set; }
string GetClientTypeName();
@@ -28,5 +30,17 @@ namespace MediaBrowser.Controller.LiveTv
bool CanDelete();
bool CanDelete(User user);
+
+ string ProviderImagePath { get; set; }
+
+ string ProviderImageUrl { get; set; }
+
+ string ExternalId { get; set; }
+ string EpisodeTitle { get; set; }
+ bool IsSeries { get; set; }
+ string SeriesTimerId { get; set; }
+ RecordingStatus Status { get; set; }
+ DateTime? EndDate { get; set; }
+ ChannelType ChannelType { get; set; }
}
}
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs
index 0dc296d5a..20bde7483 100644
--- a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs
@@ -3,7 +3,9 @@ using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Users;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
@@ -12,6 +14,27 @@ namespace MediaBrowser.Controller.LiveTv
{
public class LiveTvAudioRecording : Audio, ILiveTvRecording
{
+ public string ExternalId { get; set; }
+ public string ProviderImagePath { get; set; }
+ public string ProviderImageUrl { get; set; }
+ public string EpisodeTitle { get; set; }
+ public bool IsSeries { get; set; }
+ public string SeriesTimerId { get; set; }
+ public DateTime StartDate { get; set; }
+ public RecordingStatus Status { get; set; }
+ public bool IsSports { get; set; }
+ public bool IsNews { get; set; }
+ public bool IsKids { get; set; }
+ public bool IsRepeat { get; set; }
+ public bool IsMovie { get; set; }
+ public bool? IsHD { get; set; }
+ public bool IsLive { get; set; }
+ public bool IsPremiere { get; set; }
+ public ChannelType ChannelType { get; set; }
+ public string ProgramId { get; set; }
+ public ProgramAudio? Audio { get; set; }
+ public DateTime? OriginalAirDate { get; set; }
+
/// <summary>
/// Gets the user data key.
/// </summary>
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs
index 3669f9440..a9028989f 100644
--- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs
@@ -2,7 +2,9 @@
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Users;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
@@ -11,6 +13,27 @@ namespace MediaBrowser.Controller.LiveTv
{
public class LiveTvVideoRecording : Video, ILiveTvRecording
{
+ public string ExternalId { get; set; }
+ public string ProviderImagePath { get; set; }
+ public string ProviderImageUrl { get; set; }
+ public string EpisodeTitle { get; set; }
+ public bool IsSeries { get; set; }
+ public string SeriesTimerId { get; set; }
+ public DateTime StartDate { get; set; }
+ public RecordingStatus Status { get; set; }
+ public bool IsSports { get; set; }
+ public bool IsNews { get; set; }
+ public bool IsKids { get; set; }
+ public bool IsRepeat { get; set; }
+ public bool IsMovie { get; set; }
+ public bool? IsHD { get; set; }
+ public bool IsLive { get; set; }
+ public bool IsPremiere { get; set; }
+ public ChannelType ChannelType { get; set; }
+ public string ProgramId { get; set; }
+ public ProgramAudio? Audio { get; set; }
+ public DateTime? OriginalAirDate { get; set; }
+
/// <summary>
/// Gets the user data key.
/// </summary>
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index e1a18164e..216f1cf81 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -142,6 +142,7 @@
<Compile Include="Entities\IHasBudget.cs" />
<Compile Include="Entities\IHasCriticRating.cs" />
<Compile Include="Entities\IHasDisplayOrder.cs" />
+ <Compile Include="Entities\IHasId.cs" />
<Compile Include="Entities\IHasImages.cs" />
<Compile Include="Entities\IHasKeywords.cs" />
<Compile Include="Entities\IHasMediaSources.cs" />
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs
index f24fe0019..72fea2c79 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs
@@ -290,7 +290,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
public Guid GetInternalRecordingId(string serviceName, string externalId)
{
- var name = serviceName + externalId + InternalVersionNumber;
+ var name = serviceName + externalId + InternalVersionNumber + "0";
return name.ToLower().GetMBId(typeof(ILiveTvRecording));
}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
index 47e862b9f..e6dc268d5 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -53,6 +53,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
private readonly ConcurrentDictionary<string, LiveStreamData> _openStreams =
new ConcurrentDictionary<string, LiveStreamData>();
+ private readonly SemaphoreSlim _refreshRecordingsLock = new SemaphoreSlim(1, 1);
+
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;
@@ -359,8 +361,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
isVideo = !string.Equals(recording.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase);
var service = GetService(recording);
- _logger.Info("Opening recording stream from {0}, external recording Id: {1}", service.Name, recording.RecordingInfo.Id);
- info = await service.GetRecordingStream(recording.RecordingInfo.Id, null, cancellationToken).ConfigureAwait(false);
+ _logger.Info("Opening recording stream from {0}, external recording Id: {1}", service.Name, recording.ExternalId);
+ info = await service.GetRecordingStream(recording.ExternalId, null, cancellationToken).ConfigureAwait(false);
info.RequiresClosing = true;
if (info.RequiresClosing)
@@ -618,7 +620,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return item;
}
- private async Task<ILiveTvRecording> GetRecording(RecordingInfo info, string serviceName, CancellationToken cancellationToken)
+ private async Task<Guid> CreateRecordingRecord(RecordingInfo info, string serviceName, CancellationToken cancellationToken)
{
var isNew = false;
@@ -653,14 +655,36 @@ namespace MediaBrowser.Server.Implementations.LiveTv
isNew = true;
}
+ item.ChannelId = _tvDtoService.GetInternalChannelId(serviceName, info.ChannelId).ToString("N");
item.CommunityRating = info.CommunityRating;
item.OfficialRating = info.OfficialRating;
item.Overview = info.Overview;
item.EndDate = info.EndDate;
+ item.Genres = info.Genres;
var recording = (ILiveTvRecording)item;
- recording.RecordingInfo = info;
+ recording.ProgramId = _tvDtoService.GetInternalProgramId(serviceName, info.ProgramId).ToString("N");
+ recording.Audio = info.Audio;
+ recording.ChannelType = info.ChannelType;
+ recording.EndDate = info.EndDate;
+ recording.EpisodeTitle = info.EpisodeTitle;
+ recording.ProviderImagePath = info.ImagePath;
+ recording.ProviderImageUrl = info.ImageUrl;
+ recording.IsHD = info.IsHD;
+ recording.IsKids = info.IsKids;
+ recording.IsLive = info.IsLive;
+ recording.IsMovie = info.IsMovie;
+ recording.IsNews = info.IsNews;
+ recording.IsPremiere = info.IsPremiere;
+ recording.IsRepeat = info.IsRepeat;
+ recording.IsSeries = info.IsSeries;
+ recording.IsSports = info.IsSports;
+ recording.OriginalAirDate = info.OriginalAirDate;
+ recording.SeriesTimerId = info.SeriesTimerId;
+ recording.StartDate = info.StartDate;
+ recording.Status = info.Status;
+
recording.ServiceName = serviceName;
var originalPath = item.Path;
@@ -676,15 +700,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var pathChanged = !string.Equals(originalPath, item.Path);
- await item.RefreshMetadata(new MetadataRefreshOptions
+ if (isNew)
{
- ForceSave = isNew || pathChanged
-
- }, cancellationToken);
+ await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
+ }
+ else if (pathChanged)
+ {
+ await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
+ }
- _libraryManager.RegisterItem(item);
+ _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions());
- return recording;
+ return item.Id;
}
public async Task<BaseItemDto> GetProgram(string id, CancellationToken cancellationToken, User user = null)
@@ -1006,8 +1033,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
progress.Report(100 * percent);
}
- await CleanDatabaseInternal(newChannelIdList, typeof(LiveTvChannel).Name, progress, cancellationToken).ConfigureAwait(false);
- await CleanDatabaseInternal(newProgramIdList, typeof(LiveTvProgram).Name, progress, cancellationToken).ConfigureAwait(false);
+ await CleanDatabaseInternal(newChannelIdList, new[] { typeof(LiveTvChannel).Name }, progress, cancellationToken).ConfigureAwait(false);
+ await CleanDatabaseInternal(newProgramIdList, new[] { typeof(LiveTvProgram).Name }, progress, cancellationToken).ConfigureAwait(false);
// Load these now which will prefetch metadata
var dtoOptions = new DtoOptions();
@@ -1017,7 +1044,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
progress.Report(100);
}
- private async Task<Tuple<List<Guid>,List<Guid>>> RefreshChannelsInternal(ILiveTvService service, IProgress<double> progress, CancellationToken cancellationToken)
+ private async Task<Tuple<List<Guid>, List<Guid>>> RefreshChannelsInternal(ILiveTvService service, IProgress<double> progress, CancellationToken cancellationToken)
{
progress.Report(10);
@@ -1103,14 +1130,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv
}
progress.Report(100);
- return new Tuple<List<Guid>,List<Guid>>(channels, programs);
+ return new Tuple<List<Guid>, List<Guid>>(channels, programs);
}
- private async Task CleanDatabaseInternal(List<Guid> currentIdList, string typeName, IProgress<double> progress, CancellationToken cancellationToken)
+ private async Task CleanDatabaseInternal(List<Guid> currentIdList, string[] validTypes, IProgress<double> progress, CancellationToken cancellationToken)
{
var list = _itemRepo.GetItemIds(new InternalItemsQuery
{
- IncludeItemTypes = new[] { typeName }
+ IncludeItemTypes = validTypes
}).Items.ToList();
@@ -1163,64 +1190,103 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return channels.Select(i => new Tuple<string, ChannelInfo>(service.Name, i));
}
- public async Task<QueryResult<BaseItem>> GetInternalRecordings(RecordingQuery query, CancellationToken cancellationToken)
+ private DateTime _lastRecordingRefreshTime;
+ private async Task RefreshRecordings(CancellationToken cancellationToken)
{
- var tasks = _services.Select(async i =>
+ const int cacheMinutes = 5;
+
+ if ((DateTime.UtcNow - _lastRecordingRefreshTime).TotalMinutes < cacheMinutes)
{
- try
+ return;
+ }
+
+ await _refreshRecordingsLock.WaitAsync(cancellationToken).ConfigureAwait(false);
+
+ try
+ {
+ if ((DateTime.UtcNow - _lastRecordingRefreshTime).TotalMinutes < cacheMinutes)
{
- var recs = await i.GetRecordingsAsync(cancellationToken).ConfigureAwait(false);
- return recs.Select(r => new Tuple<RecordingInfo, ILiveTvService>(r, i));
+ return;
}
- catch (Exception ex)
+
+ var tasks = _services.Select(async i =>
{
- _logger.ErrorException("Error getting recordings", ex);
- return new List<Tuple<RecordingInfo, ILiveTvService>>();
- }
- });
- var results = await Task.WhenAll(tasks).ConfigureAwait(false);
- var recordings = results.SelectMany(i => i.ToList());
+ try
+ {
+ var recs = await i.GetRecordingsAsync(cancellationToken).ConfigureAwait(false);
+ return recs.Select(r => new Tuple<RecordingInfo, ILiveTvService>(r, i));
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error getting recordings", ex);
+ return new List<Tuple<RecordingInfo, ILiveTvService>>();
+ }
+ });
- var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
+ var results = await Task.WhenAll(tasks).ConfigureAwait(false);
+
+ var recordingTasks = results.SelectMany(i => i.ToList()).Select(i => CreateRecordingRecord(i.Item1, i.Item2.Name, cancellationToken));
+
+ var idList = await Task.WhenAll(recordingTasks).ConfigureAwait(false);
+
+ CleanDatabaseInternal(idList.ToList(), new[] { typeof(LiveTvVideoRecording).Name, typeof(LiveTvAudioRecording).Name }, new Progress<double>(), cancellationToken).ConfigureAwait(false);
+ _lastRecordingRefreshTime = DateTime.UtcNow;
+ }
+ finally
+ {
+ _refreshRecordingsLock.Release();
+ }
+ }
+
+ public async Task<QueryResult<BaseItem>> GetInternalRecordings(RecordingQuery query, CancellationToken cancellationToken)
+ {
+ var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
if (user != null && !IsLiveTvEnabled(user))
{
- recordings = new List<Tuple<RecordingInfo, ILiveTvService>>();
+ return new QueryResult<BaseItem>();
}
- if (!string.IsNullOrEmpty(query.ChannelId))
+ await RefreshRecordings(cancellationToken).ConfigureAwait(false);
+
+ var internalQuery = new InternalItemsQuery
{
- var guid = new Guid(query.ChannelId);
+ IncludeItemTypes = new[] { typeof(LiveTvVideoRecording).Name, typeof(LiveTvAudioRecording).Name }
+ };
- recordings = recordings
- .Where(i => _tvDtoService.GetInternalChannelId(i.Item2.Name, i.Item1.ChannelId) == guid);
+ if (!string.IsNullOrEmpty(query.ChannelId))
+ {
+ internalQuery.ChannelIds = new[] { query.ChannelId };
}
+ var queryResult = _libraryManager.GetItems(internalQuery);
+ IEnumerable<ILiveTvRecording> recordings = queryResult.Items.Cast<ILiveTvRecording>();
+
if (!string.IsNullOrEmpty(query.Id))
{
var guid = new Guid(query.Id);
recordings = recordings
- .Where(i => _tvDtoService.GetInternalRecordingId(i.Item2.Name, i.Item1.Id) == guid);
+ .Where(i => i.Id == guid);
}
if (!string.IsNullOrEmpty(query.GroupId))
{
var guid = new Guid(query.GroupId);
- recordings = recordings.Where(i => GetRecordingGroupIds(i.Item1).Contains(guid));
+ recordings = recordings.Where(i => GetRecordingGroupIds(i).Contains(guid));
}
if (query.IsInProgress.HasValue)
{
var val = query.IsInProgress.Value;
- recordings = recordings.Where(i => (i.Item1.Status == RecordingStatus.InProgress) == val);
+ recordings = recordings.Where(i => (i.Status == RecordingStatus.InProgress) == val);
}
if (query.Status.HasValue)
{
var val = query.Status.Value;
- recordings = recordings.Where(i => (i.Item1.Status == val));
+ recordings = recordings.Where(i => (i.Status == val));
}
if (!string.IsNullOrEmpty(query.SeriesTimerId))
@@ -1228,21 +1294,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var guid = new Guid(query.SeriesTimerId);
recordings = recordings
- .Where(i => _tvDtoService.GetInternalSeriesTimerId(i.Item2.Name, i.Item1.SeriesTimerId) == guid);
+ .Where(i => _tvDtoService.GetInternalSeriesTimerId(i.ServiceName, i.SeriesTimerId) == guid);
}
- recordings = recordings.OrderByDescending(i => i.Item1.StartDate);
-
- IEnumerable<ILiveTvRecording> entities = await GetEntities(recordings, cancellationToken).ConfigureAwait(false);
-
if (user != null)
{
var currentUser = user;
- entities = entities.Where(i => i.IsParentalAllowed(currentUser));
+ recordings = recordings.Where(i => i.IsParentalAllowed(currentUser));
}
- var entityList = entities.ToList();
- entities = entityList;
+ recordings = recordings.OrderByDescending(i => i.StartDate);
+
+ var entityList = recordings.ToList();
+ IEnumerable<ILiveTvRecording> entities = entityList;
if (query.StartIndex.HasValue)
{
@@ -1270,7 +1334,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
dto.Id = _tvDtoService.GetInternalProgramId(service.Name, program.ExternalId).ToString("N");
- dto.ChannelId = channel.Id.ToString("N");
+ dto.ChannelId = item.ChannelId;
dto.StartDate = program.StartDate;
dto.IsRepeat = program.IsRepeat;
@@ -1303,16 +1367,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var recording = (ILiveTvRecording)item;
var service = GetService(recording);
- var channel = string.IsNullOrEmpty(recording.RecordingInfo.ChannelId) ? null : GetInternalChannel(_tvDtoService.GetInternalChannelId(service.Name, recording.RecordingInfo.ChannelId));
+ var channel = string.IsNullOrWhiteSpace(recording.ChannelId) ? null : GetInternalChannel(recording.ChannelId);
- var info = recording.RecordingInfo;
+ var info = recording;
- dto.Id = _tvDtoService.GetInternalRecordingId(service.Name, info.Id).ToString("N");
+ dto.Id = item.Id.ToString("N");
dto.SeriesTimerId = string.IsNullOrEmpty(info.SeriesTimerId)
? null
: _tvDtoService.GetInternalSeriesTimerId(service.Name, info.SeriesTimerId).ToString("N");
- dto.ChannelId = _tvDtoService.GetInternalChannelId(service.Name, info.ChannelId).ToString("N");
+ dto.ChannelId = item.ChannelId;
dto.StartDate = info.StartDate;
dto.RecordingStatus = info.Status;
@@ -1344,11 +1408,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
dto.MediaStreams = dto.MediaSources.SelectMany(i => i.MediaStreams).ToList();
}
- if (info.Status == RecordingStatus.InProgress)
+ if (info.Status == RecordingStatus.InProgress && info.EndDate.HasValue)
{
var now = DateTime.UtcNow.Ticks;
var start = info.StartDate.Ticks;
- var end = info.EndDate.Ticks;
+ var end = info.EndDate.Value.Ticks;
var pct = now - start;
pct /= end;
@@ -1356,10 +1420,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
dto.CompletionPercentage = pct;
}
- if (!string.IsNullOrEmpty(info.ProgramId))
- {
- dto.ProgramId = _tvDtoService.GetInternalProgramId(service.Name, info.ProgramId).ToString("N");
- }
+ dto.ProgramId = info.ProgramId;
if (channel != null)
{
@@ -1394,13 +1455,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
};
}
- private Task<ILiveTvRecording[]> GetEntities(IEnumerable<Tuple<RecordingInfo, ILiveTvService>> recordings, CancellationToken cancellationToken)
- {
- var tasks = recordings.Select(i => GetRecording(i.Item1, i.Item2.Name, cancellationToken));
-
- return Task.WhenAll(tasks);
- }
-
public async Task<QueryResult<TimerInfoDto>> GetTimers(TimerQuery query, CancellationToken cancellationToken)
{
var tasks = _services.Select(async i =>
@@ -1468,7 +1522,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var service = GetService(recording.ServiceName);
- await service.DeleteRecordingAsync(recording.RecordingInfo.Id, CancellationToken.None).ConfigureAwait(false);
+ await service.DeleteRecordingAsync(recording.ExternalId, CancellationToken.None).ConfigureAwait(false);
+ _lastRecordingRefreshTime = DateTime.MinValue;
}
public async Task CancelTimer(string id)
@@ -1483,6 +1538,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var service = GetService(timer.ServiceName);
await service.CancelTimerAsync(timer.ExternalId, CancellationToken.None).ConfigureAwait(false);
+ _lastRecordingRefreshTime = DateTime.MinValue;
}
public async Task CancelSeriesTimer(string id)
@@ -1497,6 +1553,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var service = GetService(timer.ServiceName);
await service.CancelSeriesTimerAsync(timer.ExternalId, CancellationToken.None).ConfigureAwait(false);
+ _lastRecordingRefreshTime = DateTime.MinValue;
}
public async Task<BaseItemDto> GetRecording(string id, DtoOptions options, CancellationToken cancellationToken, User user = null)
@@ -1705,6 +1762,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
info.Priority = defaultValues.Priority;
await service.CreateTimerAsync(info, cancellationToken).ConfigureAwait(false);
+ _lastRecordingRefreshTime = DateTime.MinValue;
}
public async Task CreateSeriesTimer(SeriesTimerInfoDto timer, CancellationToken cancellationToken)
@@ -1718,6 +1776,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
info.Priority = defaultValues.Priority;
await service.CreateSeriesTimerAsync(info, cancellationToken).ConfigureAwait(false);
+ _lastRecordingRefreshTime = DateTime.MinValue;
}
public async Task UpdateTimer(TimerInfoDto timer, CancellationToken cancellationToken)
@@ -1727,6 +1786,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var service = GetService(timer.ServiceName);
await service.UpdateTimerAsync(info, cancellationToken).ConfigureAwait(false);
+ _lastRecordingRefreshTime = DateTime.MinValue;
}
public async Task UpdateSeriesTimer(SeriesTimerInfoDto timer, CancellationToken cancellationToken)
@@ -1736,9 +1796,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var service = GetService(timer.ServiceName);
await service.UpdateSeriesTimerAsync(info, cancellationToken).ConfigureAwait(false);
+ _lastRecordingRefreshTime = DateTime.MinValue;
}
- private IEnumerable<string> GetRecordingGroupNames(RecordingInfo recording)
+ private IEnumerable<string> GetRecordingGroupNames(ILiveTvRecording recording)
{
var list = new List<string>();
@@ -1775,7 +1836,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return list;
}
- private List<Guid> GetRecordingGroupIds(RecordingInfo recording)
+ private List<Guid> GetRecordingGroupIds(ILiveTvRecording recording)
{
return GetRecordingGroupNames(recording).Select(i => i.ToLower()
.GetMD5())
@@ -1795,7 +1856,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var groups = new List<BaseItemDto>();
var series = recordings
- .Where(i => i.RecordingInfo.IsSeries)
+ .Where(i => i.IsSeries)
.ToLookup(i => i.Name, StringComparer.OrdinalIgnoreCase)
.ToList();
@@ -1808,31 +1869,31 @@ namespace MediaBrowser.Server.Implementations.LiveTv
groups.Add(new BaseItemDto
{
Name = "Kids",
- RecordingCount = recordings.Count(i => i.RecordingInfo.IsKids)
+ RecordingCount = recordings.Count(i => i.IsKids)
});
groups.Add(new BaseItemDto
{
Name = "Movies",
- RecordingCount = recordings.Count(i => i.RecordingInfo.IsMovie)
+ RecordingCount = recordings.Count(i => i.IsMovie)
});
groups.Add(new BaseItemDto
{
Name = "News",
- RecordingCount = recordings.Count(i => i.RecordingInfo.IsNews)
+ RecordingCount = recordings.Count(i => i.IsNews)
});
groups.Add(new BaseItemDto
{
Name = "Sports",
- RecordingCount = recordings.Count(i => i.RecordingInfo.IsSports)
+ RecordingCount = recordings.Count(i => i.IsSports)
});
groups.Add(new BaseItemDto
{
Name = "Others",
- RecordingCount = recordings.Count(i => !i.RecordingInfo.IsSports && !i.RecordingInfo.IsNews && !i.RecordingInfo.IsMovie && !i.RecordingInfo.IsKids && !i.RecordingInfo.IsSeries)
+ RecordingCount = recordings.Count(i => !i.IsSports && !i.IsNews && !i.IsMovie && !i.IsKids && !i.IsSeries)
});
groups = groups
diff --git a/MediaBrowser.Server.Implementations/LiveTv/RecordingImageProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/RecordingImageProvider.cs
index 710247da7..adf1e7516 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/RecordingImageProvider.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/RecordingImageProvider.cs
@@ -36,17 +36,17 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var imageResponse = new DynamicImageResponse();
- if (!string.IsNullOrEmpty(liveTvItem.RecordingInfo.ImagePath))
+ if (!string.IsNullOrEmpty(liveTvItem.ProviderImagePath))
{
- imageResponse.Path = liveTvItem.RecordingInfo.ImagePath;
+ imageResponse.Path = liveTvItem.ProviderImagePath;
imageResponse.HasImage = true;
}
- else if (!string.IsNullOrEmpty(liveTvItem.RecordingInfo.ImageUrl))
+ else if (!string.IsNullOrEmpty(liveTvItem.ProviderImageUrl))
{
var options = new HttpRequestOptions
{
CancellationToken = cancellationToken,
- Url = liveTvItem.RecordingInfo.ImageUrl
+ Url = liveTvItem.ProviderImageUrl
};
var response = await _httpClient.GetResponse(options).ConfigureAwait(false);
@@ -62,7 +62,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
_logger.Error("Provider did not return an image content type.");
}
}
- else if (liveTvItem.RecordingInfo.HasImage ?? true)
+ else
{
var service = _liveTvManager.Services.FirstOrDefault(i => string.Equals(i.Name, liveTvItem.ServiceName, StringComparison.OrdinalIgnoreCase));
@@ -70,7 +70,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
{
try
{
- var response = await service.GetRecordingImageAsync(liveTvItem.RecordingInfo.Id, cancellationToken).ConfigureAwait(false);
+ var response = await service.GetRecordingImageAsync(liveTvItem.ExternalId, cancellationToken).ConfigureAwait(false);
if (response != null)
{
@@ -109,7 +109,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
if (liveTvItem != null)
{
- return !liveTvItem.HasImage(ImageType.Primary) && (liveTvItem.RecordingInfo.HasImage ?? true);
+ return !liveTvItem.HasImage(ImageType.Primary) && (!string.IsNullOrWhiteSpace(liveTvItem.ProviderImagePath) || !string.IsNullOrWhiteSpace(liveTvItem.ProviderImageUrl));
}
return false;
}
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
index 19aca1cf9..8b93c36a5 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
@@ -759,14 +759,17 @@ namespace MediaBrowser.Server.Implementations.Persistence
whereClauses.Add("IsSports=@IsSports");
cmd.Parameters.Add(cmd, "@IsSports", DbType.Boolean).Value = query.IsSports;
}
- if (query.IncludeItemTypes.Length == 1)
+
+ var includeTypes = query.IncludeItemTypes.SelectMany(MapIncludeItemTypes).ToArray();
+
+ if (includeTypes.Length == 1)
{
whereClauses.Add("type=@type");
- cmd.Parameters.Add(cmd, "@type", DbType.String).Value = MapIncludeItemType(query.IncludeItemTypes[0]);
+ cmd.Parameters.Add(cmd, "@type", DbType.String).Value = includeTypes[0];
}
- if (query.IncludeItemTypes.Length > 1)
+ if (includeTypes.Length > 1)
{
- var inClause = string.Join(",", query.IncludeItemTypes.Select(i => "'" + MapIncludeItemType(i) + "'").ToArray());
+ var inClause = string.Join(",", includeTypes.Select(i => "'" + i + "'").ToArray());
whereClauses.Add(string.Format("type in ({0})", inClause));
}
if (query.ChannelIds.Length == 1)
@@ -818,7 +821,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
whereClauses.Add("(StartDate>@IsAiringDate OR EndDate < @IsAiringDate)");
cmd.Parameters.Add(cmd, "@IsAiringDate", DbType.Date).Value = DateTime.UtcNow;
- }
+ }
}
if (addPaging)
@@ -839,21 +842,24 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
// Not crazy about having this all the way down here, but at least it's in one place
- readonly Dictionary<string, string> _types = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
+ readonly Dictionary<string, string[]> _types = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase)
{
- {typeof(LiveTvProgram).Name, typeof(LiveTvProgram).FullName},
- {typeof(LiveTvChannel).Name, typeof(LiveTvChannel).FullName}
+ {typeof(LiveTvProgram).Name, new []{typeof(LiveTvProgram).FullName}},
+ {typeof(LiveTvChannel).Name, new []{typeof(LiveTvChannel).FullName}},
+ {typeof(LiveTvVideoRecording).Name, new []{typeof(LiveTvVideoRecording).FullName}},
+ {typeof(LiveTvAudioRecording).Name, new []{typeof(LiveTvAudioRecording).FullName}},
+ {"Recording", new []{typeof(LiveTvAudioRecording).FullName, typeof(LiveTvVideoRecording).FullName}}
};
- private string MapIncludeItemType(string value)
+ private IEnumerable<string> MapIncludeItemTypes(string value)
{
- string result;
+ string[] result;
if (_types.TryGetValue(value, out result))
{
return result;
}
- return value;
+ return new[] { value };
}
public IEnumerable<Guid> GetItemIdsOfType(Type type)
diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
index 1baaa952a..f657d5403 100644
--- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs
+++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
@@ -1528,16 +1528,16 @@ namespace MediaBrowser.Server.Implementations.Session
}
var recording = item as ILiveTvRecording;
- if (recording != null && recording.RecordingInfo != null)
+ if (recording != null)
{
- if (recording.RecordingInfo.IsSeries)
+ if (recording.IsSeries)
{
- info.Name = recording.RecordingInfo.EpisodeTitle;
- info.SeriesName = recording.RecordingInfo.Name;
+ info.Name = recording.EpisodeTitle;
+ info.SeriesName = recording.Name;
if (string.IsNullOrWhiteSpace(info.Name))
{
- info.Name = recording.RecordingInfo.Name;
+ info.Name = recording.Name;
}
}
}
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index f2d46de3e..57c619976 100644
--- a/Nuget/MediaBrowser.Common.Internal.nuspec
+++ b/Nuget/MediaBrowser.Common.Internal.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common.Internal</id>
- <version>3.0.622</version>
+ <version>3.0.624</version>
<title>MediaBrowser.Common.Internal</title>
<authors>Luke</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption.</description>
<copyright>Copyright © Emby 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.622" />
+ <dependency id="MediaBrowser.Common" version="3.0.624" />
<dependency id="NLog" version="3.2.1" />
<dependency id="SimpleInjector" version="2.8.0" />
</dependencies>
diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec
index ab7d095f3..dcd913774 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common</id>
- <version>3.0.622</version>
+ <version>3.0.624</version>
<title>MediaBrowser.Common</title>
<authors>Emby Team</authors>
<owners>ebr,Luke,scottisafool</owners>
diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec
index 67385bc3d..10cee8dc2 100644
--- a/Nuget/MediaBrowser.Model.Signed.nuspec
+++ b/Nuget/MediaBrowser.Model.Signed.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Model.Signed</id>
- <version>3.0.622</version>
+ <version>3.0.624</version>
<title>MediaBrowser.Model - Signed Edition</title>
<authors>Emby Team</authors>
<owners>ebr,Luke,scottisafool</owners>
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index e91b97464..d171dab17 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MediaBrowser.Server.Core</id>
- <version>3.0.622</version>
+ <version>3.0.624</version>
<title>Media Browser.Server.Core</title>
<authors>Emby Team</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains core components required to build plugins for Emby Server.</description>
<copyright>Copyright © Emby 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.622" />
+ <dependency id="MediaBrowser.Common" version="3.0.624" />
<dependency id="Interfaces.IO" version="1.0.0.5" />
</dependencies>
</metadata>