add recordings channel

This commit is contained in:
Luke Pulverenti 2018-02-02 12:29:20 -05:00
parent ae48951b51
commit 90b6e23b70
3 changed files with 356 additions and 5 deletions

View File

@ -39,6 +39,8 @@ namespace MediaBrowser.Plugins.NextPvr
private ICryptoProvider _cryptoProvider;
private IFileSystem _fileSystem;
public DateTime LastRecordingChange = DateTime.MinValue;
public LiveTvService(IHttpClient httpClient, IJsonSerializer jsonSerializer, ILogger logger, ICryptoProvider cryptoProvider, IFileSystem fileSystem)
{
_httpClient = httpClient;
@ -246,6 +248,8 @@ namespace MediaBrowser.Plugins.NextPvr
using (var stream = await _httpClient.Get(options).ConfigureAwait(false))
{
LastRecordingChange = DateTime.UtcNow;
bool? error = new CancelDeleteRecordingResponse().RecordingError(stream, _jsonSerializer, _logger);
if (error == null || error == true)
@ -287,6 +291,7 @@ namespace MediaBrowser.Plugins.NextPvr
using (var stream = await _httpClient.Get(options).ConfigureAwait(false))
{
LastRecordingChange = DateTime.UtcNow;
bool? error = new CancelDeleteRecordingResponse().RecordingError(stream, _jsonSerializer, _logger);
if (error == null || error == true)
@ -606,9 +611,11 @@ namespace MediaBrowser.Plugins.NextPvr
try
{
await _httpClient.Post(options).ConfigureAwait((false));
LastRecordingChange = DateTime.UtcNow;
}
catch (HttpException ex)
{
LastRecordingChange = DateTime.UtcNow;
_logger.Error(string.Format("[NextPvr] UpdateTimer Async with exception: {0}", ex.Message));
throw new LiveTvConflictException();
}
@ -728,7 +735,8 @@ namespace MediaBrowser.Plugins.NextPvr
}
},
Container = "mpegts"
Container = "mpegts",
SupportsProbing = false
};
}
}
@ -757,7 +765,8 @@ namespace MediaBrowser.Plugins.NextPvr
}
},
Container = "mpegts"
Container = "mpegts",
SupportsProbing = false
};
}

View File

@ -2,8 +2,8 @@
<PropertyGroup>
<TargetFrameworks>netstandard1.3;</TargetFrameworks>
<AssemblyVersion>3.1.8.0</AssemblyVersion>
<FileVersion>3.1.8.0</FileVersion>
<AssemblyVersion>3.1.9.0</AssemblyVersion>
<FileVersion>3.1.9.0</FileVersion>
</PropertyGroup>
<ItemGroup>
@ -15,7 +15,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="mediabrowser.server.core" Version="3.3.20" />
<PackageReference Include="mediabrowser.server.core" Version="3.3.22-beta" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,342 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Channels;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Controller.LiveTv;
using System.Linq;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Model.Dto;
using System.Globalization;
using MediaBrowser.Controller.Entities;
namespace MediaBrowser.Plugins.NextPvr
{
public class RecordingsChannel : IChannel, IIndexableChannel, IHasCacheKey, ISupportsDelete
{
public ILiveTvManager _liveTvManager;
public RecordingsChannel(ILiveTvManager liveTvManager)
{
_liveTvManager = liveTvManager;
}
public string Name
{
get
{
return "Next Pvr Recordings";
}
}
public string Description
{
get
{
return "Next Pvr Recordings";
}
}
public string DataVersion
{
get
{
return "1";
}
}
public string HomePageUrl
{
get { return "http://www.nextpvr.com/"; }
}
public ChannelParentalRating ParentalRating
{
get { return ChannelParentalRating.GeneralAudience; }
}
public string GetCacheKey(string userId)
{
var now = DateTime.UtcNow;
var values = new List<string>();
values.Add(now.DayOfYear.ToString(CultureInfo.InvariantCulture));
values.Add(now.Hour.ToString(CultureInfo.InvariantCulture));
double minute = now.Minute;
minute /= 5;
values.Add(Math.Floor(minute).ToString(CultureInfo.InvariantCulture));
values.Add(GetService().LastRecordingChange.Ticks.ToString(CultureInfo.InvariantCulture));
return string.Join("-", values.ToArray());
}
public InternalChannelFeatures GetChannelFeatures()
{
return new InternalChannelFeatures
{
ContentTypes = new List<ChannelMediaContentType>
{
ChannelMediaContentType.Movie,
ChannelMediaContentType.Episode,
ChannelMediaContentType.Clip
},
MediaTypes = new List<ChannelMediaType>
{
ChannelMediaType.Audio,
ChannelMediaType.Video
},
SupportsContentDownloading = true
};
}
public Task<DynamicImageResponse> GetChannelImage(ImageType type, CancellationToken cancellationToken)
{
if (type == ImageType.Primary)
{
return Task.FromResult(new DynamicImageResponse
{
Path = "https://raw.githubusercontent.com/MediaBrowser/MediaBrowser.Resources/master/images/catalog/nextpvr.png",
Protocol = MediaProtocol.Http,
HasImage = true
});
}
return Task.FromResult(new DynamicImageResponse
{
HasImage = false
});
}
public IEnumerable<ImageType> GetSupportedChannelImages()
{
return new List<ImageType>
{
ImageType.Primary
};
}
public bool IsEnabledFor(string userId)
{
return true;
}
private LiveTvService GetService()
{
return _liveTvManager.Services.OfType<LiveTvService>().First();
}
public bool CanDelete(BaseItem item)
{
return !item.IsFolder;
}
public Task DeleteItem(string id, CancellationToken cancellationToken)
{
return GetService().DeleteRecordingAsync(id, cancellationToken);
}
public Task<ChannelItemResult> GetAllMedia(InternalAllChannelMediaQuery query, CancellationToken cancellationToken)
{
return GetChannelItems(new InternalChannelItemQuery(), i => true, cancellationToken);
}
public Task<ChannelItemResult> GetChannelItems(InternalChannelItemQuery query, CancellationToken cancellationToken)
{
if (string.IsNullOrWhiteSpace(query.FolderId))
{
return GetRecordingGroups(query, cancellationToken);
}
if (query.FolderId.StartsWith("series_", StringComparison.OrdinalIgnoreCase))
{
var hash = query.FolderId.Split('_')[1];
return GetChannelItems(query, i => i.IsSeries && string.Equals(i.Name.GetMD5().ToString("N"), hash, StringComparison.Ordinal), cancellationToken);
}
if (string.Equals(query.FolderId, "kids", StringComparison.OrdinalIgnoreCase))
{
return GetChannelItems(query, i => i.IsKids, cancellationToken);
}
if (string.Equals(query.FolderId, "movies", StringComparison.OrdinalIgnoreCase))
{
return GetChannelItems(query, i => i.IsMovie, cancellationToken);
}
if (string.Equals(query.FolderId, "news", StringComparison.OrdinalIgnoreCase))
{
return GetChannelItems(query, i => i.IsNews, cancellationToken);
}
if (string.Equals(query.FolderId, "sports", StringComparison.OrdinalIgnoreCase))
{
return GetChannelItems(query, i => i.IsSports, cancellationToken);
}
if (string.Equals(query.FolderId, "others", StringComparison.OrdinalIgnoreCase))
{
return GetChannelItems(query, i => !i.IsSports && !i.IsNews && !i.IsMovie && !i.IsKids && !i.IsSeries, cancellationToken);
}
var result = new ChannelItemResult()
{
Items = new List<ChannelItemInfo>()
};
return Task.FromResult(result);
}
public async Task<ChannelItemResult> GetChannelItems(InternalChannelItemQuery query, Func<RecordingInfo, bool> filter, CancellationToken cancellationToken)
{
var service = GetService();
var allRecordings = await service.GetRecordingsAsync(cancellationToken).ConfigureAwait(false);
var result = new ChannelItemResult()
{
Items = new List<ChannelItemInfo>()
};
result.Items.AddRange(allRecordings.Where(filter).Select(ConvertToChannelItem));
return result;
}
private ChannelItemInfo ConvertToChannelItem(RecordingInfo item)
{
var channelItem = new ChannelItemInfo
{
Name = string.IsNullOrEmpty(item.EpisodeTitle) ? item.Name : item.EpisodeTitle,
SeriesName = !string.IsNullOrEmpty(item.EpisodeTitle) || item.IsSeries ? item.Name : null,
OfficialRating = item.OfficialRating,
CommunityRating = item.CommunityRating,
ContentType = item.IsMovie ? ChannelMediaContentType.Movie : (item.IsSeries ? ChannelMediaContentType.Episode : ChannelMediaContentType.Clip),
Genres = item.Genres,
ImageUrl = item.ImageUrl,
//HomePageUrl = item.HomePageUrl
Id = item.Id,
//IndexNumber = item.IndexNumber,
MediaType = item.ChannelType == Model.LiveTv.ChannelType.TV ? ChannelMediaType.Video : ChannelMediaType.Audio,
MediaSources = new List<MediaSourceInfo>
{
new MediaSourceInfo
{
Path = item.Path,
Protocol = item.Path.StartsWith("http", StringComparison.OrdinalIgnoreCase) ? MediaProtocol.Http : MediaProtocol.File,
Id = item.Id
}
},
//ParentIndexNumber = item.ParentIndexNumber,
PremiereDate = item.OriginalAirDate,
//ProductionYear = item.ProductionYear,
//Studios = item.Studios,
Type = ChannelItemType.Media,
DateModified = item.DateLastUpdated,
Overview = item.Overview,
//People = item.People
};
return channelItem;
}
private async Task<ChannelItemResult> GetRecordingGroups(InternalChannelItemQuery query, CancellationToken cancellationToken)
{
var service = GetService();
var allRecordings = await service.GetRecordingsAsync(cancellationToken).ConfigureAwait(false);
var result = new ChannelItemResult()
{
Items = new List<ChannelItemInfo>()
};
var series = allRecordings
.Where(i => i.IsSeries)
.ToLookup(i => i.Name, StringComparer.OrdinalIgnoreCase);
result.Items.AddRange(series.OrderBy(i => i.Key).Select(i => new ChannelItemInfo
{
Name = i.Key,
FolderType = ChannelFolderType.Container,
Id = "series_" + i.Key.GetMD5().ToString("N"),
Type = ChannelItemType.Folder,
ImageUrl = i.First().ImageUrl
}));
var kids = allRecordings.FirstOrDefault(i => i.IsKids);
if (kids != null)
{
result.Items.Add(new ChannelItemInfo
{
Name = "Kids",
FolderType = ChannelFolderType.Container,
Id = "kids",
Type = ChannelItemType.Folder,
ImageUrl = kids.ImageUrl
});
}
var movies = allRecordings.FirstOrDefault(i => i.IsMovie);
if (movies != null)
{
result.Items.Add(new ChannelItemInfo
{
Name = "Movies",
FolderType = ChannelFolderType.Container,
Id = "movies",
Type = ChannelItemType.Folder,
ImageUrl = movies.ImageUrl
});
}
var news = allRecordings.FirstOrDefault(i => i.IsNews);
if (news != null)
{
result.Items.Add(new ChannelItemInfo
{
Name = "News",
FolderType = ChannelFolderType.Container,
Id = "news",
Type = ChannelItemType.Folder,
ImageUrl = news.ImageUrl
});
}
var sports = allRecordings.FirstOrDefault(i => i.IsSports);
if (sports != null)
{
result.Items.Add(new ChannelItemInfo
{
Name = "Sports",
FolderType = ChannelFolderType.Container,
Id = "sports",
Type = ChannelItemType.Folder,
ImageUrl = sports.ImageUrl
});
}
var other = allRecordings.FirstOrDefault(i => !i.IsSports && !i.IsNews && !i.IsMovie && !i.IsKids && !i.IsSeries);
if (other != null)
{
result.Items.Add(new ChannelItemInfo
{
Name = "Others",
FolderType = ChannelFolderType.Container,
Id = "others",
Type = ChannelItemType.Folder,
ImageUrl = other.ImageUrl
});
}
return result;
}
}
}