4 Commits
Author SHA1 Message Date
knackebrot ad8da4b6ee Create LICENSE 2021-01-19 16:19:32 +01:00
knackebrot 52a3da9f6e Add build.yaml 2020-09-20 12:05:37 +02:00
knackebrot bdb5fecf6b Jellyfin port: update for 10.6.0 2020-09-20 11:17:03 +02:00
knackebrot 82f2ddaadd Jellyfin port 2019-08-29 14:59:21 +02:00
8 changed files with 315 additions and 156 deletions
+121
View File
@@ -0,0 +1,121 @@
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.
@@ -140,16 +140,16 @@
$('#txtWebInterfacePort', page).val(config.WebInterfacePort || ""); $('#txtWebInterfacePort', page).val(config.WebInterfacePort || "");
$('#txtWebInterfaceUsername', page).val(config.WebInterfaceUsername || ""); $('#txtWebInterfaceUsername', page).val(config.WebInterfaceUsername || "");
$('#txtWebInterfacePassword', page).val(config.WebInterfacePassword || ""); $('#txtWebInterfacePassword', page).val(config.WebInterfacePassword || "");
page.querySelector('#chkUseSecureHTTPS').checked = config.UseSecureHTTPS || false; $('#chkUseSecureHTTPS', page).checked(config.UseSecureHTTPS || false).checkboxradio("refresh");
page.querySelector('#chkOnlyOneBouquet').checked = config.OnlyOneBouquet || false; $('#chkOnlyOneBouquet', page).checked(config.OnlyOneBouquet || false).checkboxradio("refresh");
page.querySelector('#txtTVBouquet', page).val(config.TVBouquet || ""); $('#txtTVBouquet', page).val(config.TVBouquet || "");
page.querySelector('#chkZapToChannel').checked = config.ZapToChannel || false; $('#chkZapToChannel', page).checked(config.ZapToChannel || false).checkboxradio("refresh");
page.querySelector('#chkFetchPiconsFromWebInterface').checked = config.FetchPiconsFromWebInterface || false; $('#chkFetchPiconsFromWebInterface', page).checked(config.FetchPiconsFromWebInterface || false).checkboxradio("refresh");
$('#txtPiconsPath', page).val(config.PiconsPath || ""); $('#txtPiconsPath', page).val(config.PiconsPath || "");
$('#txtRecordingPath', page).val(config.RecordingPath || ""); $('#txtRecordingPath', page).val(config.RecordingPath || "");
page.querySelector('#chkDebugLogging').checked = config.EnableDebugLogging || false; $('#chkDebugLogging', page).checked(config.EnableDebugLogging || false).checkboxradio("refresh");
Dashboard.hideLoadingMsg(); Dashboard.hideLoadingMsg();
}); });
@@ -169,7 +169,7 @@
//} //}
//reset TV bouquet reference if Only 1 Bouquet not set //reset TV bouquet reference if Only 1 Bouquet not set
//if (form.querySelector('#chkOnlyOneBouquet').checked) { //if ($('#chkOnlyOneBouquet', form).checked()) {
//} //}
//else //else
//{ //{
@@ -181,16 +181,16 @@
config.WebInterfacePort = $('#txtWebInterfacePort', form).val(); config.WebInterfacePort = $('#txtWebInterfacePort', form).val();
config.WebInterfaceUsername = $('#txtWebInterfaceUsername', form).val(); config.WebInterfaceUsername = $('#txtWebInterfaceUsername', form).val();
config.WebInterfacePassword = $('#txtWebInterfacePassword', form).val(); config.WebInterfacePassword = $('#txtWebInterfacePassword', form).val();
config.UseSecureHTTPS = form.querySelector('#chkUseSecureHTTPS').checked; config.UseSecureHTTPS = $('#chkUseSecureHTTPS', form).checked();
config.OnlyOneBouquet = form.querySelector('#chkOnlyOneBouquet').checked; config.OnlyOneBouquet = $('#chkOnlyOneBouquet', form).checked();
config.TVBouquet = $('#txtTVBouquet', form).val(); config.TVBouquet = $('#txtTVBouquet', form).val();
config.ZapToChannel = form.querySelector('#chkZapToChannel').checked; config.ZapToChannel = $('#chkZapToChannel', form).checked();
config.FetchPiconsFromWebInterface = form.querySelector('#chkFetchPiconsFromWebInterface').checked; config.FetchPiconsFromWebInterface = $('#chkFetchPiconsFromWebInterface', form).checked();
config.PiconsPath = $('#txtPiconsPath', form).val(); config.PiconsPath = $('#txtPiconsPath', form).val();
config.RecordingPath = $('#txtRecordingPath', form).val(); config.RecordingPath = $('#txtRecordingPath', form).val();
config.EnableDebugLogging = form.querySelector('#chkDebugLogging').checked; config.EnableDebugLogging = $('#chkDebugLogging', form).checked();
ApiClient.updatePluginConfiguration(VuPlusConfigurationPage.pluginUniqueId, config).then(Dashboard.processPluginConfigurationUpdateResult); ApiClient.updatePluginConfiguration(VuPlusConfigurationPage.pluginUniqueId, config).then(Dashboard.processPluginConfigurationUpdateResult);
}); });
@@ -1,6 +1,6 @@
using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.LiveTv;
using System; using System;
using MediaBrowser.Model.Logging; using Microsoft.Extensions.Logging;
namespace MediaBrowser.Plugins.VuPlus.Helpers namespace MediaBrowser.Plugins.VuPlus.Helpers
{ {
@@ -25,16 +25,47 @@ namespace MediaBrowser.Plugins.VuPlus.Helpers
public static class UtilsHelper public static class UtilsHelper
{ {
public static void DebugInformation(ILogger logger, string message) public static void DebugInformation(ILogger<LiveTvService> logger, string message)
{ {
var config = Plugin.Instance.Configuration; var config = Plugin.Instance.Configuration;
bool enableDebugLogging = config.EnableDebugLogging; bool enableDebugLogging = config.EnableDebugLogging;
if (enableDebugLogging) if (enableDebugLogging)
{ {
logger.Debug(message); logger.LogDebug(message);
} }
} }
} }
public static class RecordingHelper
{
}
public static class ApiHelper
{
private static readonly DateTime UnixEpoch =
new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static long GetCurrentUnixTimestampMillis()
{
return (long)(DateTime.UtcNow - UnixEpoch).TotalMilliseconds;
}
public static DateTime DateTimeFromUnixTimestampMillis(long millis)
{
return UnixEpoch.AddMilliseconds(millis);
}
public static long GetCurrentUnixTimestampSeconds(DateTime date)
{
return (long)(date - UnixEpoch).TotalSeconds;
}
public static DateTime DateTimeFromUnixTimestampSeconds(long seconds)
{
return UnixEpoch.AddSeconds(seconds);
}
}
} }
+82 -82
View File
@@ -5,7 +5,7 @@ using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Model.Dto; using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging; using Microsoft.Extensions.Logging;
using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Net; using MediaBrowser.Model.Net;
using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Serialization;
@@ -36,16 +36,16 @@ namespace MediaBrowser.Plugins.VuPlus
{ {
private readonly IHttpClient _httpClient; private readonly IHttpClient _httpClient;
private readonly CultureInfo _usCulture = new CultureInfo("en-US"); private readonly CultureInfo _usCulture = new CultureInfo("en-US");
private readonly ILogger _logger; private readonly ILogger<LiveTvService> _logger;
private int _liveStreams; private int _liveStreams;
private readonly Dictionary<int, int> _heartBeat = new Dictionary<int, int>(); private readonly Dictionary<int, int> _heartBeat = new Dictionary<int, int>();
private String tvBouquetSRef; private String tvBouquetSRef;
List<ChannelInfo> tvChannelInfos = new List<ChannelInfo>(); List<ChannelInfo> tvChannelInfos = new List<ChannelInfo>();
public DateTimeOffset LastRecordingChange = DateTimeOffset.MinValue; public DateTime LastRecordingChange = DateTime.MinValue;
public LiveTvService(IHttpClient httpClient, IJsonSerializer jsonSerializer, ILogger logger) public LiveTvService(IHttpClient httpClient, IJsonSerializer jsonSerializer, ILogger<LiveTvService> logger)
{ {
_httpClient = httpClient; _httpClient = httpClient;
_logger = logger; _logger = logger;
@@ -59,47 +59,47 @@ namespace MediaBrowser.Plugins.VuPlus
/// <returns></returns> /// <returns></returns>
private async Task EnsureConnectionAsync(CancellationToken cancellationToken) private async Task EnsureConnectionAsync(CancellationToken cancellationToken)
{ {
_logger.Info("[VuPlus] Start EnsureConnectionAsync"); _logger.LogInformation("[VuPlus] Start EnsureConnectionAsync");
var config = Plugin.Instance.Configuration; var config = Plugin.Instance.Configuration;
// log settings // log settings
_logger.Info(string.Format("[VuPlus] EnsureConnectionAsync HostName: {0}", config.HostName)); _logger.LogInformation(string.Format("[VuPlus] EnsureConnectionAsync HostName: {0}", config.HostName));
_logger.Info(string.Format("[VuPlus] EnsureConnectionAsync StreamingPort: {0}", config.StreamingPort)); _logger.LogInformation(string.Format("[VuPlus] EnsureConnectionAsync StreamingPort: {0}", config.StreamingPort));
_logger.Info(string.Format("[VuPlus] EnsureConnectionAsync WebInterfacePort: {0}", config.WebInterfacePort)); _logger.LogInformation(string.Format("[VuPlus] EnsureConnectionAsync WebInterfacePort: {0}", config.WebInterfacePort));
if (string.IsNullOrEmpty(config.WebInterfaceUsername)) if (string.IsNullOrEmpty(config.WebInterfaceUsername))
_logger.Info("[VuPlus] EnsureConnectionAsync WebInterfaceUsername: "); _logger.LogInformation("[VuPlus] EnsureConnectionAsync WebInterfaceUsername: ");
else else
_logger.Info(string.Format("[VuPlus] EnsureConnectionAsync WebInterfaceUsername: {0}", "********")); _logger.LogInformation(string.Format("[VuPlus] EnsureConnectionAsync WebInterfaceUsername: {0}", "********"));
if (string.IsNullOrEmpty(config.WebInterfacePassword)) if (string.IsNullOrEmpty(config.WebInterfacePassword))
_logger.Info("[VuPlus] EnsureConnectionAsync WebInterfacePassword: "); _logger.LogInformation("[VuPlus] EnsureConnectionAsync WebInterfacePassword: ");
else else
_logger.Info(string.Format("[VuPlus] EnsureConnectionAsync WebInterfaceUsername: {0}", "********")); _logger.LogInformation(string.Format("[VuPlus] EnsureConnectionAsync WebInterfaceUsername: {0}", "********"));
_logger.Info(string.Format("[VuPlus] EnsureConnectionAsync UseSecureHTTPS: {0}", config.UseSecureHTTPS)); _logger.LogInformation(string.Format("[VuPlus] EnsureConnectionAsync UseSecureHTTPS: {0}", config.UseSecureHTTPS));
_logger.Info(string.Format("[VuPlus] EnsureConnectionAsync OnlyOneBouquet: {0}", config.OnlyOneBouquet)); _logger.LogInformation(string.Format("[VuPlus] EnsureConnectionAsync OnlyOneBouquet: {0}", config.OnlyOneBouquet));
_logger.Info(string.Format("[VuPlus] EnsureConnectionAsync TVBouquet: {0}", config.TVBouquet)); _logger.LogInformation(string.Format("[VuPlus] EnsureConnectionAsync TVBouquet: {0}", config.TVBouquet));
_logger.Info(string.Format("[VuPlus] EnsureConnectionAsync ZapToChannel: {0}", config.ZapToChannel)); _logger.LogInformation(string.Format("[VuPlus] EnsureConnectionAsync ZapToChannel: {0}", config.ZapToChannel));
_logger.Info(string.Format("[VuPlus] EnsureConnectionAsync FetchPiconsFromWebInterface: {0}", config.FetchPiconsFromWebInterface)); _logger.LogInformation(string.Format("[VuPlus] EnsureConnectionAsync FetchPiconsFromWebInterface: {0}", config.FetchPiconsFromWebInterface));
_logger.Info(string.Format("[VuPlus] EnsureConnectionAsync PiconsPath: {0}", config.PiconsPath)); _logger.LogInformation(string.Format("[VuPlus] EnsureConnectionAsync PiconsPath: {0}", config.PiconsPath));
_logger.Info(string.Format("[VuPlus] EnsureConnectionAsync RecordingPath: {0}", config.RecordingPath)); _logger.LogInformation(string.Format("[VuPlus] EnsureConnectionAsync RecordingPath: {0}", config.RecordingPath));
_logger.Info(string.Format("[VuPlus] EnsureConnectionAsync EnableDebugLogging: {0}", config.EnableDebugLogging)); _logger.LogInformation(string.Format("[VuPlus] EnsureConnectionAsync EnableDebugLogging: {0}", config.EnableDebugLogging));
// validate settings // validate settings
if (string.IsNullOrEmpty(config.HostName)) if (string.IsNullOrEmpty(config.HostName))
{ {
_logger.Error("[VuPlus] HostName must be configured."); _logger.LogError("[VuPlus] HostName must be configured.");
throw new InvalidOperationException("VuPlus HostName must be configured."); throw new InvalidOperationException("VuPlus HostName must be configured.");
} }
if (string.IsNullOrEmpty(config.StreamingPort)) if (string.IsNullOrEmpty(config.StreamingPort))
{ {
_logger.Error("[VuPlus] Streaming Port must be configured."); _logger.LogError("[VuPlus] Streaming Port must be configured.");
throw new InvalidOperationException("VuPlus Streaming Port must be configured."); throw new InvalidOperationException("VuPlus Streaming Port must be configured.");
} }
if (string.IsNullOrEmpty(config.WebInterfacePort)) if (string.IsNullOrEmpty(config.WebInterfacePort))
{ {
_logger.Error("[VuPlus] Web Interface Port must be configured."); _logger.LogError("[VuPlus] Web Interface Port must be configured.");
throw new InvalidOperationException("VuPlus Web Interface Port must be configured."); throw new InvalidOperationException("VuPlus Web Interface Port must be configured.");
} }
@@ -107,7 +107,7 @@ namespace MediaBrowser.Plugins.VuPlus
{ {
if (string.IsNullOrEmpty(config.TVBouquet)) if (string.IsNullOrEmpty(config.TVBouquet))
{ {
_logger.Error("[VuPlus] TV Bouquet must be configured if Fetch only one TV bouquet selected."); _logger.LogError("[VuPlus] TV Bouquet must be configured if Fetch only one TV bouquet selected.");
throw new InvalidOperationException("VuPlus TVBouquet must be configured if Fetch only one TV bouquet selected."); throw new InvalidOperationException("VuPlus TVBouquet must be configured if Fetch only one TV bouquet selected.");
} }
} }
@@ -116,12 +116,12 @@ namespace MediaBrowser.Plugins.VuPlus
{ {
if (string.IsNullOrEmpty(config.PiconsPath)) if (string.IsNullOrEmpty(config.PiconsPath))
{ {
_logger.Error("[VuPlus] Picons location must be configured if Fetch Picons from Web Service is disabled."); _logger.LogError("[VuPlus] Picons location must be configured if Fetch Picons from Web Service is disabled.");
throw new InvalidOperationException("VuPlus Picons location must be configured if Fetch Picons from Web Service is disabled."); throw new InvalidOperationException("VuPlus Picons location must be configured if Fetch Picons from Web Service is disabled.");
} }
} }
_logger.Info("[VuPlus] EnsureConnectionAsync Validation of config parameters completed"); _logger.LogInformation("[VuPlus] EnsureConnectionAsync Validation of config parameters completed");
if (config.OnlyOneBouquet) if (config.OnlyOneBouquet)
{ {
@@ -145,7 +145,7 @@ namespace MediaBrowser.Plugins.VuPlus
/// <returns>Task{String>}.</returns> /// <returns>Task{String>}.</returns>
public async Task<String> InitiateSession(CancellationToken cancellationToken, String tvBouquet) public async Task<String> InitiateSession(CancellationToken cancellationToken, String tvBouquet)
{ {
_logger.Info("[VuPlus] Start InitiateSession, validates connection and returns Bouquet reference if required"); _logger.LogInformation("[VuPlus] Start InitiateSession, validates connection and returns Bouquet reference if required");
//await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false); //await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false);
var protocol = "http"; var protocol = "http";
@@ -216,7 +216,7 @@ namespace MediaBrowser.Plugins.VuPlus
// make sure we have found the TV Bouquet // make sure we have found the TV Bouquet
if (!string.IsNullOrEmpty(tvBouquet)) if (!string.IsNullOrEmpty(tvBouquet))
{ {
_logger.Error("[VuPlus] Failed to find TV Bouquet specified in VuPlus configuration."); _logger.LogError("[VuPlus] Failed to find TV Bouquet specified in VuPlus configuration.");
throw new ApplicationException("Failed to find TV Bouquet specified in VuPlus configuration."); throw new ApplicationException("Failed to find TV Bouquet specified in VuPlus configuration.");
} }
} }
@@ -224,8 +224,8 @@ namespace MediaBrowser.Plugins.VuPlus
} }
catch (Exception e) catch (Exception e)
{ {
_logger.Error("[VuPlus] Failed to parse services information."); _logger.LogError("[VuPlus] Failed to parse services information.");
_logger.Error(string.Format("[VuPlus] InitiateSession error: {0}", e.Message)); _logger.LogError(string.Format("[VuPlus] InitiateSession error: {0}", e.Message));
throw new ApplicationException("Failed to connect to VuPlus."); throw new ApplicationException("Failed to connect to VuPlus.");
} }
@@ -241,7 +241,7 @@ namespace MediaBrowser.Plugins.VuPlus
/// <returns>Task{IEnumerable{ChannelInfo}}.</returns> /// <returns>Task{IEnumerable{ChannelInfo}}.</returns>
public async Task<IEnumerable<ChannelInfo>> GetChannelsAsync(CancellationToken cancellationToken) public async Task<IEnumerable<ChannelInfo>> GetChannelsAsync(CancellationToken cancellationToken)
{ {
_logger.Info("[VuPlus] Start GetChannelsAsync, retrieve all channels"); _logger.LogInformation("[VuPlus] Start GetChannelsAsync, retrieve all channels");
await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false); await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false);
var protocol = "http"; var protocol = "http";
@@ -298,7 +298,7 @@ namespace MediaBrowser.Plugins.VuPlus
if (string.IsNullOrEmpty(tvBouquetSRef)) if (string.IsNullOrEmpty(tvBouquetSRef))
{ {
// Load channels from all TV Bouquets // Load channels from all TV Bouquets
_logger.Info("[VuPlus] GetChannelsAsync for all TV Bouquets"); _logger.LogInformation("[VuPlus] GetChannelsAsync for all TV Bouquets");
XmlNodeList e2services = xml.GetElementsByTagName("e2service"); XmlNodeList e2services = xml.GetElementsByTagName("e2service");
foreach (XmlNode xmlNode in e2services) foreach (XmlNode xmlNode in e2services)
@@ -392,7 +392,7 @@ namespace MediaBrowser.Plugins.VuPlus
} }
else else
{ {
_logger.Info("[VuPlus] ignoring channel label " + e2servicereference); _logger.LogInformation("[VuPlus] ignoring channel label " + e2servicereference);
} }
} }
} }
@@ -401,8 +401,8 @@ namespace MediaBrowser.Plugins.VuPlus
} }
catch (Exception e) catch (Exception e)
{ {
_logger.Error("[VuPlus] Failed to parse channel information."); _logger.LogError("[VuPlus] Failed to parse channel information.");
_logger.Error(string.Format("[VuPlus] GetChannelsAsync error: {0}", e.Message)); _logger.LogError(string.Format("[VuPlus] GetChannelsAsync error: {0}", e.Message));
throw new ApplicationException("Failed to parse channel information."); throw new ApplicationException("Failed to parse channel information.");
} }
} }
@@ -417,7 +417,7 @@ namespace MediaBrowser.Plugins.VuPlus
/// <returns>Task{List<ChannelInfo>}.</returns> /// <returns>Task{List<ChannelInfo>}.</returns>
public async Task<List<ChannelInfo>> GetChannelsForTVBouquetAsync(CancellationToken cancellationToken, String sRef) public async Task<List<ChannelInfo>> GetChannelsForTVBouquetAsync(CancellationToken cancellationToken, String sRef)
{ {
_logger.Info("[VuPlus] Start GetChannelsForTVBouquetAsync, retrieve all channels for TV Bouquet " + sRef); _logger.LogInformation("[VuPlus] Start GetChannelsForTVBouquetAsync, retrieve all channels for TV Bouquet " + sRef);
await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false); await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false);
var protocol = "http"; var protocol = "http";
@@ -533,8 +533,8 @@ namespace MediaBrowser.Plugins.VuPlus
} }
catch (Exception e) catch (Exception e)
{ {
_logger.Error("[VuPlus] Failed to parse channel information."); _logger.LogError("[VuPlus] Failed to parse channel information.");
_logger.Error(string.Format("[VuPlus] GetChannelsForTVBouquetAsync error: {0}", e.Message)); _logger.LogError(string.Format("[VuPlus] GetChannelsForTVBouquetAsync error: {0}", e.Message));
throw new ApplicationException("Failed to parse channel information."); throw new ApplicationException("Failed to parse channel information.");
} }
} }
@@ -554,7 +554,7 @@ namespace MediaBrowser.Plugins.VuPlus
public async Task<IEnumerable<MyRecordingInfo>> GetAllRecordingsAsync(CancellationToken cancellationToken) public async Task<IEnumerable<MyRecordingInfo>> GetAllRecordingsAsync(CancellationToken cancellationToken)
{ {
_logger.Info("[VuPlus] Start GetRecordingsAsync, retrieve all 'Inprogress' and 'Completed' recordings "); _logger.LogInformation("[VuPlus] Start GetRecordingsAsync, retrieve all 'Inprogress' and 'Completed' recordings ");
await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false); await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false);
var protocol = "http"; var protocol = "http";
@@ -675,7 +675,7 @@ namespace MediaBrowser.Plugins.VuPlus
recordingInfo.CommunityRating = 0; recordingInfo.CommunityRating = 0;
long sdated = Int64.Parse(e2time); long sdated = Int64.Parse(e2time);
var sdate = DateTimeOffset.FromUnixTimeSeconds(sdated); DateTime sdate = ApiHelper.DateTimeFromUnixTimestampSeconds(sdated);
recordingInfo.StartDate = sdate.ToUniversalTime(); recordingInfo.StartDate = sdate.ToUniversalTime();
//length in format mm:ss //length in format mm:ss
@@ -683,7 +683,7 @@ namespace MediaBrowser.Plugins.VuPlus
long mins = Int64.Parse(words[0]); long mins = Int64.Parse(words[0]);
long seconds = Int64.Parse(words[1]); long seconds = Int64.Parse(words[1]);
long edated = Int64.Parse(e2time) + (mins * 60) + (seconds); long edated = Int64.Parse(e2time) + (mins * 60) + (seconds);
var edate = DateTimeOffset.FromUnixTimeSeconds(edated); DateTime edate = ApiHelper.DateTimeFromUnixTimestampSeconds(edated);
recordingInfo.EndDate = edate.ToUniversalTime(); recordingInfo.EndDate = edate.ToUniversalTime();
//recordingInfo.EpisodeTitle = e2title; //recordingInfo.EpisodeTitle = e2title;
@@ -721,8 +721,8 @@ namespace MediaBrowser.Plugins.VuPlus
} }
catch (Exception e) catch (Exception e)
{ {
_logger.Error("[VuPlus] Failed to parse timer information."); _logger.LogError("[VuPlus] Failed to parse timer information.");
_logger.Error(string.Format("[VuPlus] GetRecordingsAsync error: {0}", e.Message)); _logger.LogError(string.Format("[VuPlus] GetRecordingsAsync error: {0}", e.Message));
throw new ApplicationException("Failed to parse timer information."); throw new ApplicationException("Failed to parse timer information.");
} }
} }
@@ -737,7 +737,7 @@ namespace MediaBrowser.Plugins.VuPlus
/// <returns></returns> /// <returns></returns>
public async Task DeleteRecordingAsync(string recordingId, CancellationToken cancellationToken) public async Task DeleteRecordingAsync(string recordingId, CancellationToken cancellationToken)
{ {
_logger.Info(string.Format("[VuPlus] Start Delete Recording Async for recordingId: {0}", recordingId)); _logger.LogInformation(string.Format("[VuPlus] Start Delete Recording Async for recordingId: {0}", recordingId));
await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false); await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false);
var protocol = "http"; var protocol = "http";
@@ -796,16 +796,16 @@ namespace MediaBrowser.Plugins.VuPlus
if (e2state != "True") if (e2state != "True")
{ {
_logger.Error("[VuPlus] Failed to delete recording information."); _logger.LogError("[VuPlus] Failed to delete recording information.");
_logger.Error(string.Format("[VuPlus] DeleteRecordingAsync e2statetext: {0}", e2statetext)); _logger.LogError(string.Format("[VuPlus] DeleteRecordingAsync e2statetext: {0}", e2statetext));
throw new ApplicationException("Failed to delete recording."); throw new ApplicationException("Failed to delete recording.");
} }
} }
} }
catch (Exception e) catch (Exception e)
{ {
_logger.Error("[VuPlus] Failed to parse delete recording information."); _logger.LogError("[VuPlus] Failed to parse delete recording information.");
_logger.Error(string.Format("[VuPlus] DeleteRecordingAsync error: {0}", e.Message)); _logger.LogError(string.Format("[VuPlus] DeleteRecordingAsync error: {0}", e.Message));
throw new ApplicationException("Failed to parse delete recording information."); throw new ApplicationException("Failed to parse delete recording information.");
} }
} }
@@ -821,7 +821,7 @@ namespace MediaBrowser.Plugins.VuPlus
/// <returns></returns> /// <returns></returns>
public async Task CancelTimerAsync(string timerId, CancellationToken cancellationToken) public async Task CancelTimerAsync(string timerId, CancellationToken cancellationToken)
{ {
_logger.Info(string.Format("[VuPlus] Start CancelTimerAsync for recordingId: {0}", timerId)); _logger.LogInformation(string.Format("[VuPlus] Start CancelTimerAsync for recordingId: {0}", timerId));
await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false); await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false);
// extract sRef, id, begin and end from passed timerId // extract sRef, id, begin and end from passed timerId
@@ -887,16 +887,16 @@ namespace MediaBrowser.Plugins.VuPlus
if (e2state != "True") if (e2state != "True")
{ {
_logger.Error("[VuPlus] Failed to cancel timer."); _logger.LogError("[VuPlus] Failed to cancel timer.");
_logger.Error(string.Format("[VuPlus] CancelTimerAsync e2statetext: {0}", e2statetext)); _logger.LogError(string.Format("[VuPlus] CancelTimerAsync e2statetext: {0}", e2statetext));
throw new ApplicationException("Failed to cancel timer."); throw new ApplicationException("Failed to cancel timer.");
} }
} }
} }
catch (Exception e) catch (Exception e)
{ {
_logger.Error("[VuPlus] Failed to parse cancel timer information."); _logger.LogError("[VuPlus] Failed to parse cancel timer information.");
_logger.Error(string.Format("[VuPlus] CancelTimerAsync error: {0}", e.Message)); _logger.LogError(string.Format("[VuPlus] CancelTimerAsync error: {0}", e.Message));
throw new ApplicationException("Failed to parse cancel timer information."); throw new ApplicationException("Failed to parse cancel timer information.");
} }
} }
@@ -912,7 +912,7 @@ namespace MediaBrowser.Plugins.VuPlus
/// <returns></returns> /// <returns></returns>
public async Task CreateTimerAsync(TimerInfo info, CancellationToken cancellationToken) public async Task CreateTimerAsync(TimerInfo info, CancellationToken cancellationToken)
{ {
_logger.Info(string.Format("[VuPlus] Start CreateTimerAsync for ChannelId: {0} & Name: {1}", info.ChannelId, info.Name)); _logger.LogInformation(string.Format("[VuPlus] Start CreateTimerAsync for ChannelId: {0} & Name: {1}", info.ChannelId, info.Name));
await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false); await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false);
// extract eventid from info.ProgramId // extract eventid from info.ProgramId
@@ -981,16 +981,16 @@ namespace MediaBrowser.Plugins.VuPlus
if (e2state != "True") if (e2state != "True")
{ {
_logger.Error("[VuPlus] Failed to create timer."); _logger.LogError("[VuPlus] Failed to create timer.");
_logger.Error(string.Format("[VuPlus] CreateTimerAsync e2statetext: {0}", e2statetext)); _logger.LogError(string.Format("[VuPlus] CreateTimerAsync e2statetext: {0}", e2statetext));
throw new ApplicationException("Failed to create timer."); throw new ApplicationException("Failed to create timer.");
} }
} }
} }
catch (Exception e) catch (Exception e)
{ {
_logger.Error("[VuPlus] Failed to parse create timer information."); _logger.LogError("[VuPlus] Failed to parse create timer information.");
_logger.Error(string.Format("[VuPlus] CreateTimerAsync error: {0}", e.Message)); _logger.LogError(string.Format("[VuPlus] CreateTimerAsync error: {0}", e.Message));
throw new ApplicationException("Failed to parse create timer information."); throw new ApplicationException("Failed to parse create timer information.");
} }
} }
@@ -1005,7 +1005,7 @@ namespace MediaBrowser.Plugins.VuPlus
/// <returns>IEnumerable<TimerInfo></returns> /// <returns>IEnumerable<TimerInfo></returns>
public async Task<IEnumerable<TimerInfo>> GetTimersAsync(CancellationToken cancellationToken) public async Task<IEnumerable<TimerInfo>> GetTimersAsync(CancellationToken cancellationToken)
{ {
_logger.Info("[VuPlus] Start GetTimerAsync, retrieve the 'Pending' recordings"); _logger.LogInformation("[VuPlus] Start GetTimerAsync, retrieve the 'Pending' recordings");
await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false); await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false);
var protocol = "http"; var protocol = "http";
@@ -1098,7 +1098,7 @@ namespace MediaBrowser.Plugins.VuPlus
timerInfo.ChannelId = e2servicereference; timerInfo.ChannelId = e2servicereference;
long edated = Int64.Parse(e2timeend); long edated = Int64.Parse(e2timeend);
var edate = DateTimeOffset.FromUnixTimeSeconds(edated); DateTime edate = ApiHelper.DateTimeFromUnixTimestampSeconds(edated);
timerInfo.EndDate = edate.ToUniversalTime(); timerInfo.EndDate = edate.ToUniversalTime();
timerInfo.Id = e2servicereference + "~" + e2eit + "~" + e2timebegin + "~" + e2timeend + "~" + count; timerInfo.Id = e2servicereference + "~" + e2eit + "~" + e2timebegin + "~" + e2timeend + "~" + count;
@@ -1114,7 +1114,7 @@ namespace MediaBrowser.Plugins.VuPlus
timerInfo.SeriesTimerId = null; timerInfo.SeriesTimerId = null;
long sdated = Int64.Parse(e2timebegin); long sdated = Int64.Parse(e2timebegin);
var sdate = DateTimeOffset.FromUnixTimeSeconds(sdated); DateTime sdate = ApiHelper.DateTimeFromUnixTimestampSeconds(sdated);
timerInfo.StartDate = sdate.ToUniversalTime(); timerInfo.StartDate = sdate.ToUniversalTime();
if (e2state == "0") if (e2state == "0")
@@ -1127,15 +1127,15 @@ namespace MediaBrowser.Plugins.VuPlus
} }
else else
{ {
_logger.Info("[VuPlus] ignoring timer " + e2name); _logger.LogInformation("[VuPlus] ignoring timer " + e2name);
} }
} }
return timerInfos; return timerInfos;
} }
catch (Exception e) catch (Exception e)
{ {
_logger.Error("[VuPlus] Failed to parse timer information."); _logger.LogError("[VuPlus] Failed to parse timer information.");
_logger.Error(string.Format("[VuPlus] GetTimersAsync error: {0}", e.Message)); _logger.LogError(string.Format("[VuPlus] GetTimersAsync error: {0}", e.Message));
throw new ApplicationException("Failed to parse timer information."); throw new ApplicationException("Failed to parse timer information.");
} }
} }
@@ -1159,7 +1159,7 @@ namespace MediaBrowser.Plugins.VuPlus
/// <returns>MediaSourceInfo</returns> /// <returns>MediaSourceInfo</returns>
public async Task<MediaSourceInfo> GetChannelStream(string channelOid, string mediaSourceId, CancellationToken cancellationToken) public async Task<MediaSourceInfo> GetChannelStream(string channelOid, string mediaSourceId, CancellationToken cancellationToken)
{ {
_logger.Info("[VuPlus] Start GetChannelStream"); _logger.LogInformation("[VuPlus] Start GetChannelStream");
var protocol = "http"; var protocol = "http";
if (Plugin.Instance.Configuration.UseSecureHTTPS) if (Plugin.Instance.Configuration.UseSecureHTTPS)
@@ -1214,7 +1214,7 @@ namespace MediaBrowser.Plugins.VuPlus
/// <returns></returns> /// <returns></returns>
public async Task ZapToChannel(CancellationToken cancellationToken, String channelOid) public async Task ZapToChannel(CancellationToken cancellationToken, String channelOid)
{ {
_logger.Info("[VuPlus] Start ZapToChannel"); _logger.LogInformation("[VuPlus] Start ZapToChannel");
await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false); await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false);
var protocol = "http"; var protocol = "http";
@@ -1273,16 +1273,16 @@ namespace MediaBrowser.Plugins.VuPlus
if (e2state != "True") if (e2state != "True")
{ {
_logger.Error("[VuPlus] Failed to zap to channel."); _logger.LogError("[VuPlus] Failed to zap to channel.");
_logger.Error(string.Format("[VuPlus] ZapToChannel e2statetext: {0}", e2statetext)); _logger.LogError(string.Format("[VuPlus] ZapToChannel e2statetext: {0}", e2statetext));
throw new ApplicationException("Failed to zap to channel."); throw new ApplicationException("Failed to zap to channel.");
} }
} }
} }
catch (Exception e) catch (Exception e)
{ {
_logger.Error("[VuPlus] Failed to parse create timer information."); _logger.LogError("[VuPlus] Failed to parse create timer information.");
_logger.Error(string.Format("[VuPlus] ZapToChannel error: {0}", e.Message)); _logger.LogError(string.Format("[VuPlus] ZapToChannel error: {0}", e.Message));
throw new ApplicationException("Failed to parse zap to channel information."); throw new ApplicationException("Failed to parse zap to channel information.");
} }
} }
@@ -1300,7 +1300,7 @@ namespace MediaBrowser.Plugins.VuPlus
/// <returns>SeriesTimerInfo</returns> /// <returns>SeriesTimerInfo</returns>
public async Task<SeriesTimerInfo> GetNewTimerDefaultsAsync(CancellationToken cancellationToken, ProgramInfo program = null) public async Task<SeriesTimerInfo> GetNewTimerDefaultsAsync(CancellationToken cancellationToken, ProgramInfo program = null)
{ {
_logger.Info("[VuPlus] Start GetNewTimerDefaultsAsync"); _logger.LogInformation("[VuPlus] Start GetNewTimerDefaultsAsync");
SeriesTimerInfo seriesTimerInfo = new SeriesTimerInfo(); SeriesTimerInfo seriesTimerInfo = new SeriesTimerInfo();
@@ -1316,9 +1316,9 @@ namespace MediaBrowser.Plugins.VuPlus
/// <param name="endDateUtc">end date/time</param> /// <param name="endDateUtc">end date/time</param>
/// <param name="cancellationToken">The CancellationToken</param> /// <param name="cancellationToken">The CancellationToken</param>
/// <returns>IEnumerable<ProgramInfo></returns> /// <returns>IEnumerable<ProgramInfo></returns>
public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(string channelId, DateTimeOffset startDateUtc, DateTimeOffset endDateUtc, CancellationToken cancellationToken) public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
{ {
_logger.Info("[VuPlus] Start GetProgramsAsync"); _logger.LogInformation("[VuPlus] Start GetProgramsAsync");
await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false); await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false);
Random rnd = new Random(); Random rnd = new Random();
@@ -1420,7 +1420,7 @@ namespace MediaBrowser.Plugins.VuPlus
} }
long sdated = Int64.Parse(e2eventstart); long sdated = Int64.Parse(e2eventstart);
var sdate = DateTimeOffset.FromUnixTimeSeconds(sdated); DateTime sdate = ApiHelper.DateTimeFromUnixTimestampSeconds(sdated);
// Check whether the current element is within the time range passed // Check whether the current element is within the time range passed
if (sdate > endDateUtc) if (sdate > endDateUtc)
@@ -1463,7 +1463,7 @@ namespace MediaBrowser.Plugins.VuPlus
programInfo.Overview = e2eventdescriptionextended; programInfo.Overview = e2eventdescriptionextended;
long edated = Int64.Parse(e2eventstart) + Int64.Parse(e2eventduration); long edated = Int64.Parse(e2eventstart) + Int64.Parse(e2eventduration);
var edate = DateTimeOffset.FromUnixTimeSeconds(edated); DateTime edate = ApiHelper.DateTimeFromUnixTimestampSeconds(edated);
programInfo.StartDate = sdate.ToUniversalTime(); programInfo.StartDate = sdate.ToUniversalTime();
programInfo.EndDate = edate.ToUniversalTime(); programInfo.EndDate = edate.ToUniversalTime();
@@ -1494,8 +1494,8 @@ namespace MediaBrowser.Plugins.VuPlus
} }
catch (Exception e) catch (Exception e)
{ {
_logger.Error("[VuPlus] Failed to parse program information."); _logger.LogError("[VuPlus] Failed to parse program information.");
_logger.Error(string.Format("[VuPlus] GetProgramsAsync error: {0}", e.Message)); _logger.LogError(string.Format("[VuPlus] GetProgramsAsync error: {0}", e.Message));
throw new ApplicationException("Failed to parse channel information."); throw new ApplicationException("Failed to parse channel information.");
} }
} }
@@ -1510,7 +1510,7 @@ namespace MediaBrowser.Plugins.VuPlus
/// <returns>LiveTvServiceStatusInfo</returns> /// <returns>LiveTvServiceStatusInfo</returns>
public async Task<LiveTvServiceStatusInfo> GetStatusInfoAsync(CancellationToken cancellationToken) public async Task<LiveTvServiceStatusInfo> GetStatusInfoAsync(CancellationToken cancellationToken)
{ {
_logger.Info("[VuPlus] Start GetStatusInfoAsync Async, retrieve status details"); _logger.LogInformation("[VuPlus] Start GetStatusInfoAsync Async, retrieve status details");
await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false); await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false);
//TODO: Version check //TODO: Version check
@@ -1591,8 +1591,8 @@ namespace MediaBrowser.Plugins.VuPlus
} }
catch (Exception e) catch (Exception e)
{ {
_logger.Error("[VuPlus] Failed to parse tuner information."); _logger.LogError("[VuPlus] Failed to parse tuner information.");
_logger.Error(string.Format("[VuPlus] GetStatusInfoAsync error: {0}", e.Message)); _logger.LogError(string.Format("[VuPlus] GetStatusInfoAsync error: {0}", e.Message));
throw new ApplicationException("Failed to parse tuner information."); throw new ApplicationException("Failed to parse tuner information.");
} }
@@ -1635,7 +1635,7 @@ namespace MediaBrowser.Plugins.VuPlus
public async Task CopyFilesAsync(StreamReader source, StreamWriter destination) public async Task CopyFilesAsync(StreamReader source, StreamWriter destination)
{ {
_logger.Info("[VuPlus] Start CopyFiles Async"); _logger.LogInformation("[VuPlus] Start CopyFiles Async");
char[] buffer = new char[0x1000]; char[] buffer = new char[0x1000];
int numRead; int numRead;
while ((numRead = await source.ReadAsync(buffer, 0, buffer.Length)) != 0) while ((numRead = await source.ReadAsync(buffer, 0, buffer.Length)) != 0)
@@ -1658,7 +1658,7 @@ namespace MediaBrowser.Plugins.VuPlus
/// <returns></returns> /// <returns></returns>
public async Task<IEnumerable<SeriesTimerInfo>> GetSeriesTimersAsync(CancellationToken cancellationToken) public async Task<IEnumerable<SeriesTimerInfo>> GetSeriesTimersAsync(CancellationToken cancellationToken)
{ {
_logger.Info("[VuPlus] Start GetSeriesTimersAsync"); _logger.LogInformation("[VuPlus] Start GetSeriesTimersAsync");
List<SeriesTimerInfo> seriesTimerInfo = new List<SeriesTimerInfo>(); List<SeriesTimerInfo> seriesTimerInfo = new List<SeriesTimerInfo>();
return seriesTimerInfo; return seriesTimerInfo;
@@ -1,24 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;</TargetFrameworks> <TargetFrameworks>netstandard2.1</TargetFrameworks>
<AssemblyVersion>3.2.1</AssemblyVersion> <AssemblyVersion>3.1.8</AssemblyVersion>
<FileVersion>3.2.1</FileVersion> <FileVersion>3.1.8</FileVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<None Remove="Configuration\configPage.html" /> <None Remove="Configuration\configPage.html" />
<None Remove="Images\thumb.png" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Configuration\configPage.html" /> <EmbeddedResource Include="Configuration\configPage.html" />
<EmbeddedResource Include="Images\thumb.png" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="mediabrowser.server.core" Version="4.1.0.26" /> <PackageReference Include="Jellyfin.Common" Version="10.6.0" />
<PackageReference Include="System.Memory" Version="4.5.2" /> <PackageReference Include="Jellyfin.Naming" Version="10.6.0" />
<PackageReference Include="Jellyfin.Controller" Version="10.6.0" />
<PackageReference Include="Jellyfin.Model" Version="10.6.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>
+1 -17
View File
@@ -5,15 +5,13 @@ using MediaBrowser.Common.Plugins;
using MediaBrowser.Model.Plugins; using MediaBrowser.Model.Plugins;
using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Serialization;
using MediaBrowser.Plugins.VuPlus.Configuration; using MediaBrowser.Plugins.VuPlus.Configuration;
using System.IO;
using MediaBrowser.Model.Drawing;
namespace MediaBrowser.Plugins.VuPlus namespace MediaBrowser.Plugins.VuPlus
{ {
/// <summary> /// <summary>
/// Class Plugin /// Class Plugin
/// </summary> /// </summary>
public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages, IHasThumbImage public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
{ {
public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer) public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer)
: base(applicationPaths, xmlSerializer) : base(applicationPaths, xmlSerializer)
@@ -65,19 +63,5 @@ namespace MediaBrowser.Plugins.VuPlus
} }
}; };
} }
public Stream GetThumbImage()
{
var type = GetType();
return type.Assembly.GetManifestResourceStream(type.Namespace + ".Images.thumb.png");
}
public ImageFormat ThumbImageFormat
{
get
{
return ImageFormat.Png;
}
}
} }
} }
@@ -18,41 +18,13 @@ using MediaBrowser.Model.LiveTv;
namespace MediaBrowser.Plugins.VuPlus namespace MediaBrowser.Plugins.VuPlus
{ {
public class RecordingsChannel : IChannel, IHasCacheKey, ISupportsDelete, ISupportsLatestMedia, ISupportsMediaProbe, IHasFolderAttributes, IHasChangeEvent public class RecordingsChannel : IChannel, IHasCacheKey, ISupportsDelete, ISupportsLatestMedia, ISupportsMediaProbe, IHasFolderAttributes
{ {
public ILiveTvManager _liveTvManager; public ILiveTvManager _liveTvManager;
public event EventHandler ContentChanged;
private Timer _updateTimer;
public void OnContentChanged()
{
if (ContentChanged != null)
{
ContentChanged(this, EventArgs.Empty);
}
}
private void OnUpdateTimerCallback(object state)
{
OnContentChanged();
}
public RecordingsChannel(ILiveTvManager liveTvManager) public RecordingsChannel(ILiveTvManager liveTvManager)
{ {
_liveTvManager = liveTvManager; _liveTvManager = liveTvManager;
var interval = TimeSpan.FromMinutes(15);
_updateTimer = new Timer(OnUpdateTimerCallback, null, interval, interval);
}
public void Dispose()
{
if (_updateTimer != null)
{
_updateTimer.Dispose();
_updateTimer = null;
}
} }
public string Name public string Name
@@ -99,7 +71,7 @@ namespace MediaBrowser.Plugins.VuPlus
public string GetCacheKey(string userId) public string GetCacheKey(string userId)
{ {
var now = DateTimeOffset.UtcNow; var now = DateTime.UtcNow;
var values = new List<string>(); var values = new List<string>();
@@ -141,7 +113,7 @@ namespace MediaBrowser.Plugins.VuPlus
{ {
return Task.FromResult(new DynamicImageResponse return Task.FromResult(new DynamicImageResponse
{ {
Path = "https://github.com/MediaBrowser/MediaBrowser.Plugins.VuPlus/raw/master/MediaBrowser.Plugins.VuPlus/Images/thumb.png", Path = "https://github.com/CompoUK/MediaBrowser.Plugins.VuPlus/blob/master/src/Images/Vu+.png?raw=true",
Protocol = MediaProtocol.Http, Protocol = MediaProtocol.Http,
HasImage = true HasImage = true
}); });
@@ -181,6 +153,13 @@ namespace MediaBrowser.Plugins.VuPlus
return GetService().DeleteRecordingAsync(id, cancellationToken); return GetService().DeleteRecordingAsync(id, cancellationToken);
} }
public async Task<IEnumerable<ChannelItemInfo>> GetLatestMedia(ChannelLatestMediaSearch request, CancellationToken cancellationToken)
{
var result = await GetChannelItems(new InternalChannelItemQuery(), i => true, cancellationToken).ConfigureAwait(false);
return result.Items.OrderByDescending(i => i.DateCreated ?? DateTime.MinValue);
}
public Task<ChannelItemResult> GetChannelItems(InternalChannelItemQuery query, CancellationToken cancellationToken) public Task<ChannelItemResult> GetChannelItems(InternalChannelItemQuery query, CancellationToken cancellationToken)
{ {
if (string.IsNullOrWhiteSpace(query.FolderId)) if (string.IsNullOrWhiteSpace(query.FolderId))
@@ -431,12 +410,12 @@ namespace MediaBrowser.Plugins.VuPlus
/// <summary> /// <summary>
/// The start date of the recording, in UTC. /// The start date of the recording, in UTC.
/// </summary> /// </summary>
public DateTimeOffset StartDate { get; set; } public DateTime StartDate { get; set; }
/// <summary> /// <summary>
/// The end date of the recording, in UTC. /// The end date of the recording, in UTC.
/// </summary> /// </summary>
public DateTimeOffset EndDate { get; set; } public DateTime EndDate { get; set; }
/// <summary> /// <summary>
/// Gets or sets the program identifier. /// Gets or sets the program identifier.
@@ -483,7 +462,7 @@ namespace MediaBrowser.Plugins.VuPlus
/// Gets or sets the original air date. /// Gets or sets the original air date.
/// </summary> /// </summary>
/// <value>The original air date.</value> /// <value>The original air date.</value>
public DateTimeOffset? OriginalAirDate { get; set; } public DateTime? OriginalAirDate { get; set; }
/// <summary> /// <summary>
/// Gets or sets a value indicating whether this instance is movie. /// Gets or sets a value indicating whether this instance is movie.
@@ -566,7 +545,7 @@ namespace MediaBrowser.Plugins.VuPlus
/// Gets or sets the date last updated. /// Gets or sets the date last updated.
/// </summary> /// </summary>
/// <value>The date last updated.</value> /// <value>The date last updated.</value>
public DateTimeOffset DateLastUpdated { get; set; } public DateTime DateLastUpdated { get; set; }
public MyRecordingInfo() public MyRecordingInfo()
{ {
+44
View File
@@ -0,0 +1,44 @@
---
# The name of the plugin; official plugins always start "jellyfin-plugin-"
name: "jellyfin-plugin-vuplus"
# The GUID of the plugin, found in Plugin.cs
guid: "9564ac10-af23-39bc-449f-624f23cfa48f"
# The version of the plugin, starting at 1. Note that the AssemblyVersion
# and FileVersion flags in the `.csproj` file must have two additional
# fiels, e.g. 1.0.0 to be built correctly.
version: "3.1.8" # Please increment with each pull request
# The supported Jellyfin version, usually the earliest binary-compatible
# version. Based on the Jellyfin components from NuGet.
targetAbi: "10.6.0" # The earliest binary-compatible version
# The owner name of the plugin, "jellyfin" for official plugins. Change
# to your own name if you wish to remain a 3rd-party plugin.
owner: "knackebrot"
# A short description of the plugin
overview: "VU+"
# A longer and more detailed description of the plugin; use multiple
# lines as required for readability.
description: >
Plugin for Jellyfin to allow it to view channels, browse epg, set and delete timers, play recordings etc.
# The plugin category, in a general sense. These fields are dynamic.
category: "Live TV"
# A list of built artifacts to be bundled into the ZIP for installation.
# Include the main output file, as well as any dependency `.dll`s that
# might be required for the plugin to run.
artifacts:
- "MediaBrowser.Plugins.VuPlus.dll"
# Build information values for the build infrastructure; these should
# not need to be changed usually.
build_type: "dotnet"
dotnet_configuration: "Release"
dotnet_framework: "netstandard2.1"