mirror of
https://github.com/jellyfin/jellyfin-plugin-nextpvr.git
synced 2024-11-23 05:59:41 +00:00
Initial changes for 10.9.1 (#48)
This commit is contained in:
parent
4e170ab567
commit
d375758b21
2
.gitignore
vendored
2
.gitignore
vendored
@ -230,5 +230,3 @@ pip-log.txt
|
|||||||
.mr.developer.cfg
|
.mr.developer.cfg
|
||||||
|
|
||||||
.idea
|
.idea
|
||||||
artifacts
|
|
||||||
.idea
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>0.0.0.0</Version>
|
<Version>9.0.0.0</Version>
|
||||||
<AssemblyVersion>0.0.0.0</AssemblyVersion>
|
<AssemblyVersion>9.0.0.0</AssemblyVersion>
|
||||||
<FileVersion>0.0.0.0</FileVersion>
|
<FileVersion>9.0.0.0</FileVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
17
Jellyfin.Plugin.NextPVR/Helpers/ChannelHelper.cs
Normal file
17
Jellyfin.Plugin.NextPVR/Helpers/ChannelHelper.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using MediaBrowser.Model.LiveTv;
|
||||||
|
|
||||||
|
namespace Jellyfin.Plugin.NextPVR.Helpers;
|
||||||
|
public static class ChannelHelper
|
||||||
|
{
|
||||||
|
public static ChannelType GetChannelType(int channelType)
|
||||||
|
{
|
||||||
|
ChannelType type = channelType switch
|
||||||
|
{
|
||||||
|
1 => ChannelType.TV,
|
||||||
|
10 => ChannelType.Radio,
|
||||||
|
_ => ChannelType.TV
|
||||||
|
};
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Jellyfin.Plugin.NextPVR.Configuration;
|
using Jellyfin.Plugin.NextPVR.Configuration;
|
||||||
@ -45,29 +45,29 @@ public class GenreMapper
|
|||||||
{
|
{
|
||||||
if (genreMappings != null)
|
if (genreMappings != null)
|
||||||
{
|
{
|
||||||
if (_configuration.GenreMappings.ContainsKey(GenreMovie) && _configuration.GenreMappings[GenreMovie] != null)
|
if (_configuration.GenreMappings.TryGetValue(GenreMovie, out var value) && value != null)
|
||||||
{
|
{
|
||||||
_movieGenres.AddRange(_configuration.GenreMappings[GenreMovie]);
|
_movieGenres.AddRange(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_configuration.GenreMappings.ContainsKey(GenreSport) && _configuration.GenreMappings[GenreSport] != null)
|
if (_configuration.GenreMappings.TryGetValue(GenreSport, out value) && value != null)
|
||||||
{
|
{
|
||||||
_sportGenres.AddRange(_configuration.GenreMappings[GenreSport]);
|
_sportGenres.AddRange(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_configuration.GenreMappings.ContainsKey(GenreNews) && _configuration.GenreMappings[GenreNews] != null)
|
if (_configuration.GenreMappings.TryGetValue(GenreNews, out value) && value != null)
|
||||||
{
|
{
|
||||||
_newsGenres.AddRange(_configuration.GenreMappings[GenreNews]);
|
_newsGenres.AddRange(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_configuration.GenreMappings.ContainsKey(GenreKids) && _configuration.GenreMappings[GenreKids] != null)
|
if (_configuration.GenreMappings.TryGetValue(GenreKids, out value) && value != null)
|
||||||
{
|
{
|
||||||
_kidsGenres.AddRange(_configuration.GenreMappings[GenreKids]);
|
_kidsGenres.AddRange(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_configuration.GenreMappings.ContainsKey(GenreLive) && _configuration.GenreMappings[GenreLive] != null)
|
if (_configuration.GenreMappings.TryGetValue(GenreLive, out value) && value != null)
|
||||||
{
|
{
|
||||||
_liveGenres.AddRange(_configuration.GenreMappings[GenreLive]);
|
_liveGenres.AddRange(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,7 @@
|
|||||||
using MediaBrowser.Model.LiveTv;
|
using MediaBrowser.Model.LiveTv;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Jellyfin.Plugin.NextPVR.Helpers;
|
namespace Jellyfin.Plugin.NextPVR.Helpers;
|
||||||
|
|
||||||
public static class ChannelHelper
|
|
||||||
{
|
|
||||||
public static ChannelType GetChannelType(int channelType)
|
|
||||||
{
|
|
||||||
ChannelType type = channelType switch
|
|
||||||
{
|
|
||||||
1 => ChannelType.TV,
|
|
||||||
10 => ChannelType.Radio,
|
|
||||||
_ => ChannelType.TV
|
|
||||||
};
|
|
||||||
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class UtilsHelper
|
public static class UtilsHelper
|
||||||
{
|
{
|
||||||
public static void DebugInformation(ILogger<LiveTvService> logger, string message)
|
public static void DebugInformation(ILogger<LiveTvService> logger, string message)
|
@ -1,7 +1,9 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<AssemblyVersion>6.0.0.0</AssemblyVersion>
|
||||||
|
<FileVersion>6.0.0.0</FileVersion>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
|
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
@ -20,12 +22,9 @@
|
|||||||
<PackageReference Include="Jellyfin.Controller" Version="10.*-*" />
|
<PackageReference Include="Jellyfin.Controller" Version="10.*-*" />
|
||||||
<PackageReference Include="Jellyfin.Extensions" Version="10.*-*" />
|
<PackageReference Include="Jellyfin.Extensions" Version="10.*-*" />
|
||||||
<PackageReference Include="System.Memory" Version="4.5.*" />
|
<PackageReference Include="System.Memory" Version="4.5.*" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
|
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.376" PrivateAssets="All" />
|
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.435" PrivateAssets="All" />
|
||||||
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
|
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -35,10 +36,13 @@ public class LiveTvService : ILiveTvService
|
|||||||
_httpClientFactory = httpClientFactory;
|
_httpClientFactory = httpClientFactory;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
LastUpdatedSidDateTime = DateTime.UtcNow;
|
LastUpdatedSidDateTime = DateTime.UtcNow;
|
||||||
|
Instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string Sid { get; set; }
|
private string Sid { get; set; }
|
||||||
|
|
||||||
|
public static LiveTvService Instance { get; private set; }
|
||||||
|
|
||||||
public bool IsActive => Sid != null;
|
public bool IsActive => Sid != null;
|
||||||
|
|
||||||
private DateTimeOffset LastUpdatedSidDateTime { get; set; }
|
private DateTimeOffset LastUpdatedSidDateTime { get; set; }
|
||||||
@ -58,7 +62,7 @@ public class LiveTvService : ILiveTvService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||||
private async Task EnsureConnectionAsync(CancellationToken cancellationToken)
|
public async Task EnsureConnectionAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var config = Plugin.Instance.Configuration;
|
var config = Plugin.Instance.Configuration;
|
||||||
|
|
||||||
@ -132,7 +136,7 @@ public class LiveTvService : ILiveTvService
|
|||||||
private string GetMd5Hash(string value)
|
private string GetMd5Hash(string value)
|
||||||
{
|
{
|
||||||
#pragma warning disable CA5351
|
#pragma warning disable CA5351
|
||||||
var hashValue = MD5.Create().ComputeHash(new UTF8Encoding().GetBytes(value));
|
var hashValue = MD5.HashData(new UTF8Encoding().GetBytes(value));
|
||||||
#pragma warning restore CA5351
|
#pragma warning restore CA5351
|
||||||
// Bit convertor return the byte to string as all caps hex values separated by "-"
|
// Bit convertor return the byte to string as all caps hex values separated by "-"
|
||||||
return BitConverter.ToString(hashValue).Replace("-", string.Empty, StringComparison.Ordinal).ToLowerInvariant();
|
return BitConverter.ToString(hashValue).Replace("-", string.Empty, StringComparison.Ordinal).ToLowerInvariant();
|
||||||
@ -587,19 +591,19 @@ public class LiveTvService : ILiveTvService
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ImageStream> GetChannelImageAsync(string channelId, CancellationToken cancellationToken)
|
public Task<Stream> GetChannelImageAsync(string channelId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Leave as is. This is handled by supplying image url to ChannelInfo
|
// Leave as is. This is handled by supplying image url to ChannelInfo
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ImageStream> GetProgramImageAsync(string programId, string channelId, CancellationToken cancellationToken)
|
public Task<Stream> GetProgramImageAsync(string programId, string channelId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Leave as is. This is handled by supplying image url to ProgramInfo
|
// Leave as is. This is handled by supplying image url to ProgramInfo
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ImageStream> GetRecordingImageAsync(string recordingId, CancellationToken cancellationToken)
|
public Task<Stream> GetRecordingImageAsync(string recordingId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Leave as is. This is handled by supplying image url to RecordingInfo
|
// Leave as is. This is handled by supplying image url to RecordingInfo
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -8,7 +8,6 @@ using Jellyfin.Plugin.NextPVR.Entities;
|
|||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller.Channels;
|
using MediaBrowser.Controller.Channels;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.LiveTv;
|
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Channels;
|
using MediaBrowser.Model.Channels;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
@ -20,7 +19,6 @@ namespace Jellyfin.Plugin.NextPVR;
|
|||||||
|
|
||||||
public class RecordingsChannel : IChannel, IHasCacheKey, ISupportsDelete, ISupportsLatestMedia, ISupportsMediaProbe, IHasFolderAttributes, IDisposable
|
public class RecordingsChannel : IChannel, IHasCacheKey, ISupportsDelete, ISupportsLatestMedia, ISupportsMediaProbe, IHasFolderAttributes, IDisposable
|
||||||
{
|
{
|
||||||
private readonly ILiveTvManager _liveTvManager;
|
|
||||||
private readonly CancellationTokenSource _cancellationToken;
|
private readonly CancellationTokenSource _cancellationToken;
|
||||||
private Timer _updateTimer;
|
private Timer _updateTimer;
|
||||||
private DateTimeOffset _lastUpdate = DateTimeOffset.FromUnixTimeSeconds(0);
|
private DateTimeOffset _lastUpdate = DateTimeOffset.FromUnixTimeSeconds(0);
|
||||||
@ -28,9 +26,8 @@ public class RecordingsChannel : IChannel, IHasCacheKey, ISupportsDelete, ISuppo
|
|||||||
private IEnumerable<MyRecordingInfo> _allRecordings;
|
private IEnumerable<MyRecordingInfo> _allRecordings;
|
||||||
private bool _useCachedRecordings;
|
private bool _useCachedRecordings;
|
||||||
|
|
||||||
public RecordingsChannel(ILiveTvManager liveTvManager)
|
public RecordingsChannel()
|
||||||
{
|
{
|
||||||
_liveTvManager = liveTvManager;
|
|
||||||
var interval = TimeSpan.FromSeconds(20);
|
var interval = TimeSpan.FromSeconds(20);
|
||||||
_updateTimer = new Timer(OnUpdateTimerCallbackAsync, null, interval, interval);
|
_updateTimer = new Timer(OnUpdateTimerCallbackAsync, null, interval, interval);
|
||||||
if (_updateTimer != null)
|
if (_updateTimer != null)
|
||||||
@ -116,7 +113,13 @@ public class RecordingsChannel : IChannel, IHasCacheKey, ISupportsDelete, ISuppo
|
|||||||
|
|
||||||
private LiveTvService GetService()
|
private LiveTvService GetService()
|
||||||
{
|
{
|
||||||
return _liveTvManager.Services.OfType<LiveTvService>().FirstOrDefault();
|
LiveTvService service = LiveTvService.Instance;
|
||||||
|
if (service is not null && !service.IsActive)
|
||||||
|
{
|
||||||
|
service.EnsureConnectionAsync(new System.Threading.CancellationToken(false)).Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
return service;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanDelete(BaseItem item)
|
public bool CanDelete(BaseItem item)
|
||||||
@ -338,12 +341,7 @@ public class RecordingsChannel : IChannel, IHasCacheKey, ISupportsDelete, ISuppo
|
|||||||
private async void OnUpdateTimerCallbackAsync(object state)
|
private async void OnUpdateTimerCallbackAsync(object state)
|
||||||
{
|
{
|
||||||
var service = GetService();
|
var service = GetService();
|
||||||
if (service is null)
|
if (service is not null && service.IsActive)
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (service.IsActive)
|
|
||||||
{
|
{
|
||||||
var backendUpdate = await service.GetLastUpdate(_cancellationToken.Token).ConfigureAwait(false);
|
var backendUpdate = await service.GetLastUpdate(_cancellationToken.Token).ConfigureAwait(false);
|
||||||
if (backendUpdate > _lastUpdate)
|
if (backendUpdate > _lastUpdate)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Extensions.Json;
|
using Jellyfin.Extensions.Json;
|
||||||
@ -24,7 +24,7 @@ public class CancelDeleteRecordingResponse
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RootObject
|
private sealed class RootObject
|
||||||
{
|
{
|
||||||
public string Stat { get; set; }
|
public string Stat { get; set; }
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -49,7 +49,7 @@ public class ChannelResponse
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Classes created with http://json2csharp.com/
|
// Classes created with http://json2csharp.com/
|
||||||
private class Channel
|
private sealed class Channel
|
||||||
{
|
{
|
||||||
public int ChannelId { get; set; }
|
public int ChannelId { get; set; }
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ public class ChannelResponse
|
|||||||
public bool ChannelIcon { get; set; }
|
public bool ChannelIcon { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RootObject
|
private sealed class RootObject
|
||||||
{
|
{
|
||||||
public List<Channel> Channels { get; set; }
|
public List<Channel> Channels { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Extensions.Json;
|
using Jellyfin.Extensions.Json;
|
||||||
@ -25,7 +25,7 @@ public class InitializeResponse
|
|||||||
throw new JsonException("Failed to validate your connection with NextPVR.");
|
throw new JsonException("Failed to validate your connection with NextPVR.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RootObject
|
private sealed class RootObject
|
||||||
{
|
{
|
||||||
public string Stat { get; set; }
|
public string Stat { get; set; }
|
||||||
|
|
||||||
|
@ -19,18 +19,16 @@ public class LastUpdateResponse
|
|||||||
UtilsHelper.DebugInformation(logger, $"[NextPVR] LastUpdate Response: {JsonSerializer.Serialize(root, _jsonOptions)}");
|
UtilsHelper.DebugInformation(logger, $"[NextPVR] LastUpdate Response: {JsonSerializer.Serialize(root, _jsonOptions)}");
|
||||||
return DateTimeOffset.FromUnixTimeSeconds(root.LastUpdate);
|
return DateTimeOffset.FromUnixTimeSeconds(root.LastUpdate);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private sealed class RootObject
|
||||||
// Classes created with http://json2csharp.com/
|
{
|
||||||
|
[JsonPropertyName("last_update")]
|
||||||
public class RootObject
|
public int LastUpdate { get; set; }
|
||||||
{
|
|
||||||
[JsonPropertyName("last_update")]
|
public string Stat { get; set; }
|
||||||
public int LastUpdate { get; set; }
|
|
||||||
|
public int Code { get; set; }
|
||||||
public string Stat { get; set; }
|
|
||||||
|
public string Msg { get; set; }
|
||||||
public int Code { get; set; }
|
}
|
||||||
|
|
||||||
public string Msg { get; set; }
|
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ public class ListingsResponse
|
|||||||
|
|
||||||
// Classes created with http://json2csharp.com/
|
// Classes created with http://json2csharp.com/
|
||||||
|
|
||||||
private class Listing
|
private sealed class Listing
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ public class ListingsResponse
|
|||||||
public int RecordingId { get; set; }
|
public int RecordingId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RootObject
|
private sealed class RootObject
|
||||||
{
|
{
|
||||||
public List<Listing> Listings { get; set; }
|
public List<Listing> Listings { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ public class RecordingResponse
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
info.Url = $"{_baseUrl}/live?recording={i.Id}";
|
info.Url = $"{_baseUrl}/live?recording={i.Id}&sid=jellyfin";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,7 +215,7 @@ public class RecordingResponse
|
|||||||
return RecordingStatus.New;
|
return RecordingStatus.New;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Recording
|
private sealed class Recording
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
@ -280,7 +280,7 @@ public class RecordingResponse
|
|||||||
public int? Year { get; set; }
|
public int? Year { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RootObject
|
private sealed class RootObject
|
||||||
{
|
{
|
||||||
public List<Recording> Recordings { get; set; }
|
public List<Recording> Recordings { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -12,7 +12,7 @@ using Microsoft.Extensions.Logging;
|
|||||||
|
|
||||||
namespace Jellyfin.Plugin.NextPVR.Responses;
|
namespace Jellyfin.Plugin.NextPVR.Responses;
|
||||||
|
|
||||||
internal class RecurringResponse
|
internal sealed class RecurringResponse
|
||||||
{
|
{
|
||||||
private readonly ILogger<LiveTvService> _logger;
|
private readonly ILogger<LiveTvService> _logger;
|
||||||
private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.CamelCaseOptions;
|
private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.CamelCaseOptions;
|
||||||
@ -70,7 +70,7 @@ internal class RecurringResponse
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Recurring
|
private sealed class Recurring
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ internal class RecurringResponse
|
|||||||
public string AdvancedRules { get; set; }
|
public string AdvancedRules { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RootObject
|
private sealed class RootObject
|
||||||
{
|
{
|
||||||
public List<Recurring> Recurrings { get; set; }
|
public List<Recurring> Recurrings { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -31,7 +31,7 @@ public class SettingResponse
|
|||||||
|
|
||||||
// Classes created with http://json2csharp.com/
|
// Classes created with http://json2csharp.com/
|
||||||
|
|
||||||
private class ScheduleSettings
|
private sealed class ScheduleSettings
|
||||||
{
|
{
|
||||||
public string Version { get; set; }
|
public string Version { get; set; }
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ public class SettingResponse
|
|||||||
public int TimeEpoch { get; set; }
|
public int TimeEpoch { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SettingValue
|
private sealed class SettingValue
|
||||||
{
|
{
|
||||||
public string Value { get; set; }
|
public string Value { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -14,27 +14,29 @@ public class TunerResponse
|
|||||||
{
|
{
|
||||||
private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.CamelCaseOptions;
|
private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.CamelCaseOptions;
|
||||||
|
|
||||||
public async Task<List<LiveTvTunerInfo>> LiveTvTunerInfos(Stream stream)
|
public async Task<List<TunerHostInfo>> LiveTvTunerInfo(Stream stream)
|
||||||
{
|
{
|
||||||
var root = await JsonSerializer.DeserializeAsync<RootObject>(stream, _jsonOptions).ConfigureAwait(false);
|
var root = await JsonSerializer.DeserializeAsync<RootObject>(stream, _jsonOptions).ConfigureAwait(false);
|
||||||
return root.Tuners.Select(GetTunerInformation).ToList();
|
return root.Tuners.Select(GetTunerInformation).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private LiveTvTunerInfo GetTunerInformation(Tuner i)
|
private TunerHostInfo GetTunerInformation(Tuner i)
|
||||||
{
|
{
|
||||||
LiveTvTunerInfo tunerinfo = new LiveTvTunerInfo();
|
TunerHostInfo tunerinfo = new TunerHostInfo();
|
||||||
|
|
||||||
tunerinfo.Name = i.TunerName;
|
tunerinfo.FriendlyName = i.TunerName;
|
||||||
|
/*
|
||||||
tunerinfo.Status = GetStatus(i);
|
tunerinfo.Status = GetStatus(i);
|
||||||
|
|
||||||
if (i.Recordings.Count > 0)
|
if (i.Recordings.Count > 0)
|
||||||
{
|
{
|
||||||
tunerinfo.ChannelId = i.Recordings.Single().Recording.ChannelOid.ToString(CultureInfo.InvariantCulture);
|
tunerinfo.ChannelId = i.Recordings.Single().Recording.ChannelOid.ToString(CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
return tunerinfo;
|
return tunerinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
private LiveTvTunerStatus GetStatus(Tuner i)
|
private LiveTvTunerStatus GetStatus(Tuner i)
|
||||||
{
|
{
|
||||||
if (i.Recordings.Count > 0)
|
if (i.Recordings.Count > 0)
|
||||||
@ -49,8 +51,9 @@ public class TunerResponse
|
|||||||
|
|
||||||
return LiveTvTunerStatus.Available;
|
return LiveTvTunerStatus.Available;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
private class Recording
|
private sealed class Recording
|
||||||
{
|
{
|
||||||
public int TunerOid { get; set; }
|
public int TunerOid { get; set; }
|
||||||
|
|
||||||
@ -61,12 +64,12 @@ public class TunerResponse
|
|||||||
public int RecordingOid { get; set; }
|
public int RecordingOid { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Recordings
|
private sealed class Recordings
|
||||||
{
|
{
|
||||||
public Recording Recording { get; set; }
|
public Recording Recording { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Tuner
|
private sealed class Tuner
|
||||||
{
|
{
|
||||||
public string TunerName { get; set; }
|
public string TunerName { get; set; }
|
||||||
|
|
||||||
@ -77,7 +80,7 @@ public class TunerResponse
|
|||||||
public List<object> LiveTv { get; set; }
|
public List<object> LiveTv { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RootObject
|
private sealed class RootObject
|
||||||
{
|
{
|
||||||
public List<Tuner> Tuners { get; set; }
|
public List<Tuner> Tuners { get; set; }
|
||||||
}
|
}
|
||||||
|
23
Jellyfin.Plugin.NextPVR/ServiceRegistrator.cs
Normal file
23
Jellyfin.Plugin.NextPVR/ServiceRegistrator.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using Jellyfin.Plugin.NextPVR;
|
||||||
|
using MediaBrowser.Controller;
|
||||||
|
using MediaBrowser.Controller.Authentication;
|
||||||
|
using MediaBrowser.Controller.Channels;
|
||||||
|
using MediaBrowser.Controller.LiveTv;
|
||||||
|
using MediaBrowser.Controller.Plugins;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Jellyfin.Plugin.NextPVR;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Register NextPVR services.
|
||||||
|
/// </summary>
|
||||||
|
///
|
||||||
|
public class ServiceRegistrator : IPluginServiceRegistrator
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void RegisterServices(IServiceCollection serviceCollection, IServerApplicationHost applicationHost)
|
||||||
|
{
|
||||||
|
serviceCollection.AddSingleton<ILiveTvService, LiveTvService>();
|
||||||
|
serviceCollection.AddSingleton<IChannel, RecordingsChannel>();
|
||||||
|
}
|
||||||
|
}
|
@ -26,7 +26,7 @@ This plugin provides access to live TV, program guide, and recordings from a [Ne
|
|||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
1. To build this plugin you will need [.Net 5.x](https://dotnet.microsoft.com/download/dotnet/5.0).
|
1. To build this plugin you will need [.Net 8.x](https://dotnet.microsoft.com/download/dotnet/8.0).
|
||||||
|
|
||||||
2. Build plugin with following command
|
2. Build plugin with following command
|
||||||
```
|
```
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
name: "NextPVR"
|
name: "NextPVR"
|
||||||
guid: "9574ac10-bf23-49bc-949f-924f23cfa48f"
|
guid: "9574ac10-bf23-49bc-949f-924f23cfa48f"
|
||||||
imageUrl: "https://repo.jellyfin.org/releases/plugin/images/jellyfin-plugin-nextpvr.png"
|
imageUrl: "https://repo.jellyfin.org/releases/plugin/images/jellyfin-plugin-nextpvr.png"
|
||||||
version: "8"
|
version: 9
|
||||||
targetAbi: "10.8.0.0"
|
targetAbi: "10.9.0.0"
|
||||||
framework: "net6.0"
|
framework: "net8.0"
|
||||||
overview: "Live TV plugin for NextPVR"
|
overview: "Live TV plugin for NextPVR"
|
||||||
description: >
|
description: >
|
||||||
Provides access to live TV, program guide, and recordings from NextPVR.
|
Provides access to live TV, program guide, and recordings from NextPVR.
|
||||||
|
Loading…
Reference in New Issue
Block a user