10 Commits
Author SHA1 Message Date
knackebrot d38c1595d8 Update for Jellyfin 10.9 2024-06-22 20:16:55 +02:00
knackebrot 309e7c4110 Merge pull request #13 from tiagoqpinto/jellyfin
Add Transcoding option to settings
2022-08-22 21:42:48 +02:00
Tiago Pinto 09336872ed Add transcoding port setting 2022-08-17 10:59:48 +01:00
Tiago Pinto aff7687078 Add Transcoding option to settings 2022-07-19 15:12:45 +01:00
knackebrot a2e9686898 Update for Jellyfin 10.8
- Change branding from Vu+ to Enigma2

- Fix wrong default hostname

- Add new options UseLoginForStreams, UseHTTPSForStreams

- Use new GUID to avoid clashing with the older version of plugin
2022-06-29 02:40:53 +02:00
knackebrot 4a41cf4b74 Update for Jellyfin 10.7 2021-03-14 19:24:59 +01:00
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
17 changed files with 1147 additions and 763 deletions
+199
View File
@@ -0,0 +1,199 @@
# With more recent updates Visual Studio 2017 supports EditorConfig files out of the box
# Visual Studio Code needs an extension: https://github.com/editorconfig/editorconfig-vscode
# For emacs, vim, np++ and other editors, see here: https://github.com/editorconfig
###############################
# Core EditorConfig Options #
###############################
root = true
# All files
[*]
indent_style = space
indent_size = 4
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = lf
max_line_length = 9999
# YAML indentation
[*.{yml,yaml}]
indent_size = 2
# XML indentation
[*.{csproj,xml}]
indent_size = 2
###############################
# .NET Coding Conventions #
###############################
[*.{cs,vb}]
# Organize usings
dotnet_sort_system_directives_first = true
# this. preferences
dotnet_style_qualification_for_field = false:silent
dotnet_style_qualification_for_property = false:silent
dotnet_style_qualification_for_method = false:silent
dotnet_style_qualification_for_event = false:silent
# Language keywords vs BCL types preferences
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
dotnet_style_predefined_type_for_member_access = true:silent
# Parentheses preferences
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
# Modifier preferences
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
dotnet_style_readonly_field = true:suggestion
# Expression-level preferences
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_auto_properties = true:silent
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
###############################
# Naming Conventions #
###############################
# Style Definitions (From Roslyn)
# Non-private static fields are PascalCase
dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.symbols = non_private_static_fields
dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.style = non_private_static_field_style
dotnet_naming_symbols.non_private_static_fields.applicable_kinds = field
dotnet_naming_symbols.non_private_static_fields.applicable_accessibilities = public, protected, internal, protected_internal, private_protected
dotnet_naming_symbols.non_private_static_fields.required_modifiers = static
dotnet_naming_style.non_private_static_field_style.capitalization = pascal_case
# Constants are PascalCase
dotnet_naming_rule.constants_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.constants_should_be_pascal_case.symbols = constants
dotnet_naming_rule.constants_should_be_pascal_case.style = constant_style
dotnet_naming_symbols.constants.applicable_kinds = field, local
dotnet_naming_symbols.constants.required_modifiers = const
dotnet_naming_style.constant_style.capitalization = pascal_case
# Static fields are camelCase and start with s_
dotnet_naming_rule.static_fields_should_be_camel_case.severity = suggestion
dotnet_naming_rule.static_fields_should_be_camel_case.symbols = static_fields
dotnet_naming_rule.static_fields_should_be_camel_case.style = static_field_style
dotnet_naming_symbols.static_fields.applicable_kinds = field
dotnet_naming_symbols.static_fields.required_modifiers = static
dotnet_naming_style.static_field_style.capitalization = camel_case
dotnet_naming_style.static_field_style.required_prefix = _
# Instance fields are camelCase and start with _
dotnet_naming_rule.instance_fields_should_be_camel_case.severity = suggestion
dotnet_naming_rule.instance_fields_should_be_camel_case.symbols = instance_fields
dotnet_naming_rule.instance_fields_should_be_camel_case.style = instance_field_style
dotnet_naming_symbols.instance_fields.applicable_kinds = field
dotnet_naming_style.instance_field_style.capitalization = camel_case
dotnet_naming_style.instance_field_style.required_prefix = _
# Locals and parameters are camelCase
dotnet_naming_rule.locals_should_be_camel_case.severity = suggestion
dotnet_naming_rule.locals_should_be_camel_case.symbols = locals_and_parameters
dotnet_naming_rule.locals_should_be_camel_case.style = camel_case_style
dotnet_naming_symbols.locals_and_parameters.applicable_kinds = parameter, local
dotnet_naming_style.camel_case_style.capitalization = camel_case
# Local functions are PascalCase
dotnet_naming_rule.local_functions_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.local_functions_should_be_pascal_case.symbols = local_functions
dotnet_naming_rule.local_functions_should_be_pascal_case.style = local_function_style
dotnet_naming_symbols.local_functions.applicable_kinds = local_function
dotnet_naming_style.local_function_style.capitalization = pascal_case
# By default, name items with PascalCase
dotnet_naming_rule.members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.members_should_be_pascal_case.symbols = all_members
dotnet_naming_rule.members_should_be_pascal_case.style = pascal_case_style
dotnet_naming_symbols.all_members.applicable_kinds = *
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
###############################
# C# Coding Conventions #
###############################
[*.cs]
# var preferences
csharp_style_var_for_built_in_types = true:silent
csharp_style_var_when_type_is_apparent = true:silent
csharp_style_var_elsewhere = true:silent
# Expression-bodied members
csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_constructors = false:silent
csharp_style_expression_bodied_operators = false:silent
csharp_style_expression_bodied_properties = true:silent
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_accessors = true:silent
# Pattern matching preferences
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
# Null-checking preferences
csharp_style_throw_expression = true:suggestion
csharp_style_conditional_delegate_call = true:suggestion
# Modifier preferences
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
# Expression-level preferences
csharp_prefer_braces = true:silent
csharp_style_deconstructed_variable_declaration = true:suggestion
csharp_prefer_simple_default_expression = true:suggestion
csharp_style_pattern_local_over_anonymous_function = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
###############################
# C# Formatting Rules #
###############################
# New line preferences
csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_between_query_expression_clauses = true
# Indentation preferences
csharp_indent_case_contents = true
csharp_indent_switch_labels = true
csharp_indent_labels = flush_left
# Space preferences
csharp_space_after_cast = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_around_binary_operators = before_and_after
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
# Wrapping preferences
csharp_preserve_single_line_statements = true
csharp_preserve_single_line_blocks = true
+2
View File
@@ -106,3 +106,5 @@ Generated_Code #added for RIA/Silverlight projects
_UpgradeReport_Files/ _UpgradeReport_Files/
Backup*/ Backup*/
UpgradeLog*.XML UpgradeLog*.XML
.vs
+41
View File
@@ -0,0 +1,41 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/Jellyfin.Plugin.Enigma2/Jellyfin.Plugin.Enigma2.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/Jellyfin.Plugin.Enigma2/Jellyfin.Plugin.Enigma2.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/Jellyfin.Plugin.Enigma2/Jellyfin.Plugin.Enigma2.csproj"
],
"problemMatcher": "$msCompile"
}
]
}
@@ -1,9 +1,14 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15 # Visual Studio Version 17
VisualStudioVersion = 15.0.26730.3 VisualStudioVersion = 17.2.32616.157
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Plugins.VuPlus", "MediaBrowser.Plugins.VuPlus\MediaBrowser.Plugins.VuPlus.csproj", "{52B1ABDF-09C1-450E-B808-BBA0A9C19848}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jellyfin.Plugin.Enigma2", "Jellyfin.Plugin.Enigma2\Jellyfin.Plugin.Enigma2.csproj", "{52B1ABDF-09C1-450E-B808-BBA0A9C19848}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A968FB09-8732-407C-8748-6DB383EB5D91}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
EndProjectSection
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -1,7 +1,6 @@
using System;
using MediaBrowser.Model.Plugins; using MediaBrowser.Model.Plugins;
namespace MediaBrowser.Plugins.VuPlus.Configuration namespace Jellyfin.Plugin.Enigma2.Configuration
{ {
/// <summary> /// <summary>
/// Class PluginConfiguration /// Class PluginConfiguration
@@ -13,26 +12,34 @@ namespace MediaBrowser.Plugins.VuPlus.Configuration
public string WebInterfacePort { get; set; } public string WebInterfacePort { get; set; }
public string WebInterfaceUsername { get; set; } public string WebInterfaceUsername { get; set; }
public string WebInterfacePassword { get; set; } public string WebInterfacePassword { get; set; }
public Boolean UseSecureHTTPS { get; set; } public bool UseLoginForStreams { get; set; }
public Boolean OnlyOneBouquet { get; set; } public bool UseSecureHTTPS { get; set; }
public bool UseSecureHTTPSForStreams { get; set; }
public bool OnlyOneBouquet { get; set; }
public string TVBouquet { get; set; } public string TVBouquet { get; set; }
public Boolean ZapToChannel { get; set; } public bool ZapToChannel { get; set; }
public Boolean FetchPiconsFromWebInterface { get; set; } public bool FetchPiconsFromWebInterface { get; set; }
public string PiconsPath { get; set; } public string PiconsPath { get; set; }
public string RecordingPath { get; set; } public string RecordingPath { get; set; }
public Boolean EnableDebugLogging { get; set; } public bool TranscodedStream { get; set; }
public string TranscodingPort { get; set; }
public bool EnableDebugLogging { get; set; }
public PluginConfiguration() public PluginConfiguration()
{ {
HostName = "http://localhost"; HostName = "localhost";
StreamingPort = "8001"; StreamingPort = "8001";
WebInterfacePort = "8000"; WebInterfacePort = "8000";
WebInterfaceUsername= ""; WebInterfaceUsername = "";
WebInterfacePassword = ""; WebInterfacePassword = "";
UseLoginForStreams = false;
UseSecureHTTPS = false; UseSecureHTTPS = false;
UseSecureHTTPSForStreams = false;
OnlyOneBouquet = true; OnlyOneBouquet = true;
TVBouquet = "Favourites (TV)"; TVBouquet = "Favourites (TV)";
ZapToChannel = false; ZapToChannel = false;
@@ -41,8 +48,10 @@ namespace MediaBrowser.Plugins.VuPlus.Configuration
RecordingPath = ""; RecordingPath = "";
EnableDebugLogging = false; TranscodedStream = false;
TranscodingPort = "8002";
EnableDebugLogging = false;
} }
} }
} }
@@ -0,0 +1,228 @@
<!DOCTYPE html>
<html>
<head>
<title>Enigma2</title>
</head>
<body>
<div data-role="page" id="Enigma2ConfigurationPage" class="page type-interior pluginConfigurationPage Enigma2ConfigurationPage" data-require="emby-button,emby-checkbox,emby-input">
<div data-role="content">
<div class="content-primary">
<h1>Enigma2</h1>
<form id="Enigma2ConfigurationForm" class="Enigma2ConfigurationForm">
<div class="inputContainer">
<input is="emby-input" id="txtHostName" type="text" label="Enigma2 hostname or ip address:" />
<div class="fieldDescription">
The host name (address) or ip address of your receiver
</div>
</div>
<div class="inputContainer">
<input is="emby-input" id="txtStreamingPort" type="text" label="Enigma2 streaming port:" />
<div class="fieldDescription">
The Streaming port of your receiver eg. 8001
</div>
</div>
<div class="inputContainer">
<input is="emby-input" id="txtWebInterfacePort" type="text" label="Enigma2 Web Interface port:" />
<div class="fieldDescription">
The web interface port of your receiver eg. 8000
</div>
</div>
<div class="inputContainer">
<input is="emby-input" id="txtWebInterfaceUsername" type="text" label="Enigma2 Web Interface username:" />
<div class="fieldDescription">
The web interface username of your receiver (optional)
</div>
</div>
<div class="inputContainer">
<input is="emby-input" id="txtWebInterfacePassword" type="password" label="Enigma2 Web Interface password:" />
<div class="fieldDescription">
The web interface password of your receiver (optional)
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="chkUseLoginForStreams" />
<span>Use login for streaming</span>
</label>
<div class="fieldDescription checkboxFieldDescription">
Use web interface login for streaming
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="chkUseSecureHTTPS" />
<span>Use secure HTTP (HTTPS)</span>
</label>
<div class="fieldDescription checkboxFieldDescription">
Use HTTPS to connect to your receiver
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="chkUseSecureHTTPSForStreams" />
<span>Use secure HTTP (HTTPS) for streams</span>
</label>
<div class="fieldDescription checkboxFieldDescription">
Use HTTPS to connect to streaming port
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="chkOnlyOneBouquet" />
<span>Fetch Only one TV bouquet</span>
</label>
<div class="fieldDescription checkboxFieldDescription">
Limit channels to only those contained within the specified TV Bouquet below (optional)
</div>
</div>
<div class="inputContainer">
<input is="emby-input" id="txtTVBouquet" type="text" label="Enigma2 TVBouquet:" />
<div class="fieldDescription">
The TV Bouquet to load channels for (optional)
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="chkZapToChannel" />
<span>Zap before Channel switch (single tuner)</span>
</label>
<div class="fieldDescription checkboxFieldDescription">
Set if only one tuner within receiver
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="chkFetchPiconsFromWebInterface" />
<span>Fetch picons from webinterface</span>
</label>
<div class="fieldDescription checkboxFieldDescription">
Set if you want to retrieve Picons from the web interface of the receiver
</div>
</div>
<div class="inputContainer">
<input is="emby-input" id="txtPiconsPath" type="text" label="Picons Path:" />
<div class="fieldDescription">
The local location of your Picons eg. C:\Picons\ (optional)
</div>
</div>
<div class="inputContainer">
<input is="emby-input" id="txtRecordingPath" type="text" label="Recording Path:" />
<div class="fieldDescription">
The location to store your recordings on your receiver eg. /hdd/movie/ (optional)
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="chkTranscodedStream" />
<span>Request Transcoded Stream</span>
</label>
<div class="fieldDescription checkboxFieldDescription">
Request Transcoded Stream (h264, 720p, 1Mpbs and mp4 as default)
</div>
</div>
<div class="inputContainer">
<input is="emby-input" id="txtTranscodingPort" type="text" label="Enigma2 transcoding port:" />
<div class="fieldDescription">
The Transcoding port of your receiver eg. 8002
</div>
</div>
<label class="checkboxContainer">
<input is="emby-checkbox" type="checkbox" id="chkDebugLogging" />
<span>Enable Enigma2 debug logging</span>
</label>
<div>
<button is="emby-button" type="submit" class="raised button-submit block"><span>Save</span></button>
</div>
</form>
</div>
</div>
<script type="text/javascript">
var Enigma2ConfigurationPage = {
pluginUniqueId: "193f29f9-ea6c-4595-a6f6-55e79d7c590a",
loadConfiguration: function () {
Dashboard.showLoadingMsg();
ApiClient.getPluginConfiguration(Enigma2ConfigurationPage.pluginUniqueId).then(function (config) {
document.getElementById('txtHostName').value = config.HostName || "";
document.getElementById('txtStreamingPort').value = config.StreamingPort || "";
document.getElementById('txtWebInterfacePort').value = config.WebInterfacePort || "";
document.getElementById('txtWebInterfaceUsername').value = config.WebInterfaceUsername || "";
document.getElementById('txtWebInterfacePassword').value = config.WebInterfacePassword || "";
document.getElementById('chkUseLoginForStreams').checked = config.UseLoginForStreams || false;
document.getElementById('chkUseSecureHTTPS').checked = config.UseSecureHTTPS || false;
document.getElementById('chkUseSecureHTTPSForStreams').checked = config.UseSecureHTTPSForStreams || false;
document.getElementById('chkOnlyOneBouquet').checked = config.OnlyOneBouquet || false;
document.getElementById('txtTVBouquet').value = config.TVBouquet || "";
document.getElementById('chkZapToChannel').checked = config.ZapToChannel || false;
document.getElementById('chkFetchPiconsFromWebInterface').checked = config.FetchPiconsFromWebInterface || false;
document.getElementById('txtPiconsPath').value = config.PiconsPath || "";
document.getElementById('txtRecordingPath').value = config.RecordingPath || "";
document.getElementById('chkTranscodedStream').checked = config.TranscodedStream || false;
document.getElementById('txtTranscodingPort').value = config.TranscodingPort || "";
document.getElementById('chkDebugLogging').checked = config.EnableDebugLogging || false;
Dashboard.hideLoadingMsg();
});
},
saveConfiguration: function () {
Dashboard.showLoadingMsg();
ApiClient.getPluginConfiguration(Enigma2ConfigurationPage.pluginUniqueId).then(function (config) {
config.HostName = document.getElementById('txtHostName').value;
config.StreamingPort = document.getElementById('txtStreamingPort').value;
config.WebInterfacePort = document.getElementById('txtWebInterfacePort').value;
config.WebInterfaceUsername = document.getElementById('txtWebInterfaceUsername').value;
config.WebInterfacePassword = document.getElementById('txtWebInterfacePassword').value;
config.UseLoginForStreams = document.getElementById('chkUseLoginForStreams').checked;
config.UseSecureHTTPS = document.getElementById('chkUseSecureHTTPS').checked;
config.UseSecureHTTPSForStreams = document.getElementById('chkUseSecureHTTPSForStreams').checked;
config.OnlyOneBouquet = document.getElementById('chkOnlyOneBouquet').checked;
config.TVBouquet = document.getElementById('txtTVBouquet').value;
config.ZapToChannel = document.getElementById('chkZapToChannel').checked;
config.FetchPiconsFromWebInterface = document.getElementById('chkFetchPiconsFromWebInterface').checked;
config.PiconsPath = document.getElementById('txtPiconsPath').value;
config.RecordingPath = document.getElementById('txtRecordingPath').value;
config.TranscodedStream = document.getElementById('chkTranscodedStream').checked;
config.TranscodingPort = document.getElementById('txtTranscodingPort').value;
config.EnableDebugLogging = document.getElementById('chkDebugLogging').checked;
ApiClient.updatePluginConfiguration(Enigma2ConfigurationPage.pluginUniqueId, config).then(Dashboard.processPluginConfigurationUpdateResult);
});
}
}
document.getElementById('Enigma2ConfigurationPage').addEventListener('pageshow', function () {
Enigma2ConfigurationPage.loadConfiguration();
});
document.getElementById('Enigma2ConfigurationForm').addEventListener('submit', function (e) {
e.preventDefault();
Enigma2ConfigurationPage.saveConfiguration();
});
</script>
</div>
</body>
</html>
@@ -1,14 +1,14 @@
using MediaBrowser.Model.LiveTv;
using System; using System;
using MediaBrowser.Model.Logging; using MediaBrowser.Model.LiveTv;
using Microsoft.Extensions.Logging;
namespace MediaBrowser.Plugins.VuPlus.Helpers namespace Jellyfin.Plugin.Enigma2.Helpers
{ {
public static class ChannelHelper public static class ChannelHelper
{ {
public static ChannelType GetChannelType(string channelType) public static ChannelType GetChannelType(string channelType)
{ {
ChannelType type = new ChannelType(); var type = new ChannelType();
if (channelType == "0x1") if (channelType == "0x1")
{ {
@@ -25,14 +25,14 @@ 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; var enableDebugLogging = config.EnableDebugLogging;
if (enableDebugLogging) if (enableDebugLogging)
{ {
logger.Debug(message); logger.LogDebug(message);
} }
} }

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

@@ -0,0 +1,35 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<AssemblyVersion>6.0.0.0</AssemblyVersion>
<FileVersion>6.0.0.0</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net6.0|AnyCPU'">
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net8.0|AnyCPU'">
<DebugType>none</DebugType>
</PropertyGroup>
<ItemGroup>
<None Remove="Configuration\configPage.html" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Configuration\configPage.html" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Jellyfin.Common" Version="10.9.0" />
<PackageReference Include="Jellyfin.Naming" Version="10.9.0" />
<PackageReference Include="Jellyfin.Controller" Version="10.9.0" />
<PackageReference Include="Jellyfin.Model" Version="10.9.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
</ItemGroup>
</Project>
@@ -4,17 +4,19 @@ using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Plugins; 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 Jellyfin.Plugin.Enigma2.Configuration;
namespace MediaBrowser.Plugins.VuPlus namespace Jellyfin.Plugin.Enigma2
{ {
/// <summary> /// <summary>
/// Class Plugin /// Class Plugin
/// </summary> /// </summary>
public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
{ {
public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer) public Plugin(
: base(applicationPaths, xmlSerializer) IApplicationPaths applicationPaths,
IXmlSerializer xmlSerializer
) : base(applicationPaths, xmlSerializer)
{ {
Instance = this; Instance = this;
} }
@@ -23,28 +25,16 @@ namespace MediaBrowser.Plugins.VuPlus
/// Gets the name of the plugin /// Gets the name of the plugin
/// </summary> /// </summary>
/// <value>The name.</value> /// <value>The name.</value>
public override string Name public override string Name => "Enigma2";
{
get { return "VuPlus"; }
}
/// <summary> /// <summary>
/// Gets the description. /// Gets the description.
/// </summary> /// </summary>
/// <value>The description.</value> /// <value>The description.</value>
public override string Description public override string Description => "Provides live TV using Enigma2 PVR as a back-end.";
{
get
{
return "Provides live tv using Vu+ / Enigma2 pvr as a back-end.";
}
}
private Guid _id = new Guid("9564ac10-af23-39bc-449f-624f23cfa48f"); private Guid _id = new Guid("193f29f9-ea6c-4595-a6f6-55e79d7c590a");
public override Guid Id public override Guid Id => _id;
{
get { return _id; }
}
/// <summary> /// <summary>
/// Gets the instance. /// Gets the instance.
@@ -58,8 +48,8 @@ namespace MediaBrowser.Plugins.VuPlus
{ {
new PluginPageInfo new PluginPageInfo
{ {
Name = "vuplus", Name = "enigma2",
EmbeddedResourcePath = "MediaBrowser.Plugins.VuPlus.Configuration.configPage.html" EmbeddedResourcePath = "Jellyfin.Plugin.Enigma2.Configuration.configPage.html"
} }
}; };
} }
@@ -1,82 +1,53 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Globalization;
using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; 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.Common.Extensions;
using MediaBrowser.Model.Dto; using MediaBrowser.Controller.Channels;
using System.Globalization;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.MediaInfo;
using Microsoft.Extensions.Logging;
namespace MediaBrowser.Plugins.VuPlus namespace Jellyfin.Plugin.Enigma2
{ {
public class RecordingsChannel : IChannel, IHasCacheKey, ISupportsDelete, ISupportsLatestMedia, ISupportsMediaProbe, IHasFolderAttributes public class RecordingsChannel : IChannel, IHasCacheKey, ISupportsDelete, ISupportsLatestMedia, ISupportsMediaProbe, IHasFolderAttributes
{ {
public ILiveTvManager _liveTvManager; private readonly ILogger<LiveTvService> _logger;
public RecordingsChannel(ILiveTvManager liveTvManager) public RecordingsChannel(ILoggerFactory loggerFactory)
{ {
_liveTvManager = liveTvManager; _logger = loggerFactory.CreateLogger<LiveTvService>();
_logger.LogDebug("[Enigma2] RecordingsChannel()");
} }
public string Name public string Name => "Enigma2 Recordings";
{
get
{
return "VuPlus Recordings";
}
}
public string[] Attributes public string[] Attributes => new[] { "Recordings" };
{
get
{
return new[] { "Recordings" };
}
}
public string Description public string Description => "Enigma2 Recordings";
{
get
{
return "VuPlus Recordings";
}
}
public string DataVersion public string DataVersion => "1";
{
get
{
return "1";
}
}
public string HomePageUrl public string HomePageUrl => null;
{
get { return null; }
}
public ChannelParentalRating ParentalRating public ChannelParentalRating ParentalRating => ChannelParentalRating.GeneralAudience;
{
get { return ChannelParentalRating.GeneralAudience; }
}
public string GetCacheKey(string userId) public string GetCacheKey(string userId)
{ {
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
var values = new List<string>(); var values = new List<string>
{
values.Add(now.DayOfYear.ToString(CultureInfo.InvariantCulture)); now.DayOfYear.ToString(CultureInfo.InvariantCulture),
values.Add(now.Hour.ToString(CultureInfo.InvariantCulture)); now.Hour.ToString(CultureInfo.InvariantCulture)
};
double minute = now.Minute; double minute = now.Minute;
minute /= 5; minute /= 5;
@@ -94,8 +65,8 @@ namespace MediaBrowser.Plugins.VuPlus
{ {
ContentTypes = new List<ChannelMediaContentType> ContentTypes = new List<ChannelMediaContentType>
{ {
ChannelMediaContentType.Movie, ChannelMediaContentType.Movie,
ChannelMediaContentType.Episode, ChannelMediaContentType.Episode,
ChannelMediaContentType.Clip ChannelMediaContentType.Clip
}, },
MediaTypes = new List<ChannelMediaType> MediaTypes = new List<ChannelMediaType>
@@ -140,7 +111,7 @@ namespace MediaBrowser.Plugins.VuPlus
private LiveTvService GetService() private LiveTvService GetService()
{ {
return _liveTvManager.Services.OfType<LiveTvService>().First(); return LiveTvService.Instance;
} }
public bool CanDelete(BaseItem item) public bool CanDelete(BaseItem item)
@@ -211,14 +182,10 @@ namespace MediaBrowser.Plugins.VuPlus
var service = GetService(); var service = GetService();
var allRecordings = await service.GetAllRecordingsAsync(cancellationToken).ConfigureAwait(false); var allRecordings = await service.GetAllRecordingsAsync(cancellationToken).ConfigureAwait(false);
var result = new ChannelItemResult() return new ChannelItemResult()
{ {
Items = new List<ChannelItemInfo>() Items = allRecordings.Where(filter).Select(ConvertToChannelItem).ToList()
}; };
result.Items.AddRange(allRecordings.Where(filter).Select(ConvertToChannelItem));
return result;
} }
private ChannelItemInfo ConvertToChannelItem(MyRecordingInfo item) private ChannelItemInfo ConvertToChannelItem(MyRecordingInfo item)
@@ -237,7 +204,7 @@ namespace MediaBrowser.Plugins.VuPlus
//HomePageUrl = item.HomePageUrl //HomePageUrl = item.HomePageUrl
Id = item.Id, Id = item.Id,
//IndexNumber = item.IndexNumber, //IndexNumber = item.IndexNumber,
MediaType = item.ChannelType == Model.LiveTv.ChannelType.TV ? ChannelMediaType.Video : ChannelMediaType.Audio, MediaType = item.ChannelType == ChannelType.TV ? ChannelMediaType.Video : ChannelMediaType.Audio,
MediaSources = new List<MediaSourceInfo> MediaSources = new List<MediaSourceInfo>
{ {
new MediaSourceInfo new MediaSourceInfo
@@ -255,7 +222,7 @@ namespace MediaBrowser.Plugins.VuPlus
DateModified = item.DateLastUpdated, DateModified = item.DateLastUpdated,
Overview = item.Overview, Overview = item.Overview,
//People = item.People //People = item.People
IsLiveStream = item.Status == Model.LiveTv.RecordingStatus.InProgress, IsLiveStream = item.Status == RecordingStatus.InProgress,
Etag = item.Status.ToString() Etag = item.Status.ToString()
}; };
@@ -267,16 +234,14 @@ namespace MediaBrowser.Plugins.VuPlus
var service = GetService(); var service = GetService();
var allRecordings = await service.GetAllRecordingsAsync(cancellationToken).ConfigureAwait(false); var allRecordings = await service.GetAllRecordingsAsync(cancellationToken).ConfigureAwait(false);
var result = new ChannelItemResult()
{
Items = new List<ChannelItemInfo>()
};
var series = allRecordings var series = allRecordings
.Where(i => i.IsSeries) .Where(i => i.IsSeries)
.ToLookup(i => i.Name, StringComparer.OrdinalIgnoreCase); .ToLookup(i => i.Name, StringComparer.OrdinalIgnoreCase);
result.Items.AddRange(series.OrderBy(i => i.Key).Select(i => new ChannelItemInfo var items = new List<ChannelItemInfo>();
items.AddRange(series.OrderBy(i => i.Key).Select(i => new ChannelItemInfo
{ {
Name = i.Key, Name = i.Key,
FolderType = ChannelFolderType.Container, FolderType = ChannelFolderType.Container,
@@ -289,7 +254,7 @@ namespace MediaBrowser.Plugins.VuPlus
if (kids != null) if (kids != null)
{ {
result.Items.Add(new ChannelItemInfo items.Add(new ChannelItemInfo
{ {
Name = "Kids", Name = "Kids",
FolderType = ChannelFolderType.Container, FolderType = ChannelFolderType.Container,
@@ -302,7 +267,7 @@ namespace MediaBrowser.Plugins.VuPlus
var movies = allRecordings.FirstOrDefault(i => i.IsMovie); var movies = allRecordings.FirstOrDefault(i => i.IsMovie);
if (movies != null) if (movies != null)
{ {
result.Items.Add(new ChannelItemInfo items.Add(new ChannelItemInfo
{ {
Name = "Movies", Name = "Movies",
FolderType = ChannelFolderType.Container, FolderType = ChannelFolderType.Container,
@@ -315,7 +280,7 @@ namespace MediaBrowser.Plugins.VuPlus
var news = allRecordings.FirstOrDefault(i => i.IsNews); var news = allRecordings.FirstOrDefault(i => i.IsNews);
if (news != null) if (news != null)
{ {
result.Items.Add(new ChannelItemInfo items.Add(new ChannelItemInfo
{ {
Name = "News", Name = "News",
FolderType = ChannelFolderType.Container, FolderType = ChannelFolderType.Container,
@@ -328,7 +293,7 @@ namespace MediaBrowser.Plugins.VuPlus
var sports = allRecordings.FirstOrDefault(i => i.IsSports); var sports = allRecordings.FirstOrDefault(i => i.IsSports);
if (sports != null) if (sports != null)
{ {
result.Items.Add(new ChannelItemInfo items.Add(new ChannelItemInfo
{ {
Name = "Sports", Name = "Sports",
FolderType = ChannelFolderType.Container, FolderType = ChannelFolderType.Container,
@@ -341,7 +306,7 @@ namespace MediaBrowser.Plugins.VuPlus
var other = allRecordings.FirstOrDefault(i => !i.IsSports && !i.IsNews && !i.IsMovie && !i.IsKids && !i.IsSeries); var other = allRecordings.FirstOrDefault(i => !i.IsSports && !i.IsNews && !i.IsMovie && !i.IsKids && !i.IsSeries);
if (other != null) if (other != null)
{ {
result.Items.Add(new ChannelItemInfo items.Add(new ChannelItemInfo
{ {
Name = "Others", Name = "Others",
FolderType = ChannelFolderType.Container, FolderType = ChannelFolderType.Container,
@@ -351,7 +316,10 @@ namespace MediaBrowser.Plugins.VuPlus
}); });
} }
return result; return new ChannelItemResult()
{
Items = items
};
} }
} }
public class MyRecordingInfo public class MyRecordingInfo
@@ -0,0 +1,20 @@
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Controller;
using Microsoft.Extensions.DependencyInjection;
using System.Net.Http;
using Jellyfin.Plugin.Enigma2.Helpers;
namespace Jellyfin.Plugin.Enigma2
{
public class ServiceRegistrator : IPluginServiceRegistrator
{
/// <inheritdoc />
public void RegisterServices(IServiceCollection serviceCollection, IServerApplicationHost applicationHost)
{
serviceCollection.AddSingleton<ILiveTvService, LiveTvService>();
serviceCollection.AddSingleton<IChannel, RecordingsChannel>();
}
}
}
+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.
@@ -1,204 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Vu+</title>
</head>
<body>
<div data-role="page" class="page type-interior pluginConfigurationPage VuPlusConfigurationPage" data-require="emby-button,emby-checkbox,emby-input">
<div data-role="content">
<div class="content-primary">
<h1>VuPlus</h1>
<form class="VuPlusConfigurationForm">
<div class="inputContainer">
<input is="emby-input" id="txtHostName" type="text" label="Vu+ hostname or ip address:" />
<div class="fieldDescription">
The host name (address) or ip address of your receiver
</div>
</div>
<div class="inputContainer">
<input is="emby-input" id="txtStreamingPort" type="text" label="Vu+ streaming port:" />
<div class="fieldDescription">
The Streaming port of your receiver eg. 8001
</div>
</div>
<div class="inputContainer">
<input is="emby-input" id="txtWebInterfacePort" type="text" label="Vu+ Web Interface port:" />
<div class="fieldDescription">
The web Interface port of your receiver eg. 8000
</div>
</div>
<div class="inputContainer">
<input is="emby-input" id="txtWebInterfaceUsername" type="text" label="Vu+ Web Interface username:" />
<div class="fieldDescription">
The web Interface username of your receiver (optional)
</div>
</div>
<div class="inputContainer">
<input is="emby-input" id="txtWebInterfacePassword" type="text" label="Vu+ Web Interface password:" />
<div class="fieldDescription">
The web Interface password of your receiver (optional)
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="chkUseSecureHTTPS" />
<span>Use secure HTTP (HTTPS)</span>
</label>
<div class="fieldDescription checkboxFieldDescription">
Use HTTPS to connect to your receiver
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="chkOnlyOneBouquet" />
<span>Fetch Only one TV bouquet</span>
</label>
<div class="fieldDescription checkboxFieldDescription">
Limit channels to only those contained within the specified TV Bouquet below (optional)
</div>
</div>
<div class="inputContainer">
<input is="emby-input" id="txtTVBouquet" type="text" label="Vu+ TVBouquet:" />
<div class="fieldDescription">
The TV Bouquet to load channels for (optional)
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="chkZapToChannel" />
<span>Zap before Channel switch (single tuner)</span>
</label>
<div class="fieldDescription checkboxFieldDescription">
Set if only one tuner within receiver
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="chkFetchPiconsFromWebInterface" />
<span>Fetch picons from webinterface</span>
</label>
<div class="fieldDescription checkboxFieldDescription">
Set if you want to retrieve Picons from the web interface of the receiver
</div>
</div>
<div class="inputContainer">
<input is="emby-input" id="txtPiconsPath" type="text" label="Picons Path:" />
<div class="fieldDescription">
The local location of your Picons eg. C:\Picons\ (optional)
</div>
</div>
<div class="inputContainer">
<input is="emby-input" id="txtRecordingPath" type="text" label="Recording Path:" />
<div class="fieldDescription">
The location to store your recordings on your receiver eg. /hdd/movie/ (optional)
</div>
</div>
<label class="checkboxContainer">
<input is="emby-checkbox" type="checkbox" id="chkDebugLogging" />
<span>Enable VuPlus debug logging</span>
</label>
<div>
<button is="emby-button" type="submit" class="raised button-submit block"><span>Save</span></button>
</div>
</form>
</div>
</div>
<script type="text/javascript">
var VuPlusConfigurationPage = {
pluginUniqueId: "9564ac10-af23-39bc-449f-624f23cfa48f"
};
$('.VuPlusConfigurationPage').on('pageshow', function (event) {
Dashboard.showLoadingMsg();
var page = this;
ApiClient.getPluginConfiguration(VuPlusConfigurationPage.pluginUniqueId).then(function (config) {
$('#txtHostName', page).val(config.HostName || "");
$('#txtStreamingPort', page).val(config.StreamingPort || "");
$('#txtWebInterfacePort', page).val(config.WebInterfacePort || "");
$('#txtWebInterfaceUsername', page).val(config.WebInterfaceUsername || "");
$('#txtWebInterfacePassword', page).val(config.WebInterfacePassword || "");
$('#chkUseSecureHTTPS', page).checked(config.UseSecureHTTPS || false).checkboxradio("refresh");
$('#chkOnlyOneBouquet', page).checked(config.OnlyOneBouquet || false).checkboxradio("refresh");
$('#txtTVBouquet', page).val(config.TVBouquet || "");
$('#chkZapToChannel', page).checked(config.ZapToChannel || false).checkboxradio("refresh");
$('#chkFetchPiconsFromWebInterface', page).checked(config.FetchPiconsFromWebInterface || false).checkboxradio("refresh");
$('#txtPiconsPath', page).val(config.PiconsPath || "");
$('#txtRecordingPath', page).val(config.RecordingPath || "");
$('#chkDebugLogging', page).checked(config.EnableDebugLogging || false).checkboxradio("refresh");
Dashboard.hideLoadingMsg();
});
});
$('.VuPlusConfigurationForm').on('submit', function (e) {
Dashboard.showLoadingMsg();
var form = this;
ApiClient.getPluginConfiguration(VuPlusConfigurationPage.pluginUniqueId).then(function (config) {
//reset TV bouquet reference if TV Bouquet changed
//if (config.TVBouquet != $('#txtTVBouquet', form).val()) {
// config.tvBouquetSRef = '';
//}
//reset TV bouquet reference if Only 1 Bouquet not set
//if ($('#chkOnlyOneBouquet', form).checked()) {
//}
//else
//{
// config.tvBouquetSRef = '';
//}
config.HostName = $('#txtHostName', form).val();
config.StreamingPort = $('#txtStreamingPort', form).val();
config.WebInterfacePort = $('#txtWebInterfacePort', form).val();
config.WebInterfaceUsername = $('#txtWebInterfaceUsername', form).val();
config.WebInterfacePassword = $('#txtWebInterfacePassword', form).val();
config.UseSecureHTTPS = $('#chkUseSecureHTTPS', form).checked();
config.OnlyOneBouquet = $('#chkOnlyOneBouquet', form).checked();
config.TVBouquet = $('#txtTVBouquet', form).val();
config.ZapToChannel = $('#chkZapToChannel', form).checked();
config.FetchPiconsFromWebInterface = $('#chkFetchPiconsFromWebInterface', form).checked();
config.PiconsPath = $('#txtPiconsPath', form).val();
config.RecordingPath = $('#txtRecordingPath', form).val();
config.EnableDebugLogging = $('#chkDebugLogging', form).checked();
ApiClient.updatePluginConfiguration(VuPlusConfigurationPage.pluginUniqueId, config).then(Dashboard.processPluginConfigurationUpdateResult);
});
// Disable default form submission
return false;
});
</script>
</div>
</body>
</html>
@@ -1,21 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net46</TargetFrameworks>
<AssemblyVersion>3.1.8</AssemblyVersion>
<FileVersion>3.1.8</FileVersion>
</PropertyGroup>
<ItemGroup>
<None Remove="Configuration\configPage.html" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Configuration\configPage.html" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="mediabrowser.server.core" Version="3.3.28" />
</ItemGroup>
</Project>
+44
View File
@@ -0,0 +1,44 @@
---
# The name of the plugin; official plugins always start "jellyfin-plugin-"
name: "jellyfin-plugin-enigma2"
# The GUID of the plugin, found in Plugin.cs
guid: "193f29f9-ea6c-4595-a6f6-55e79d7c590a"
# 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: "5.0.1.0" # 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.8.0.0" # The earliest binary-compatible version
framework: "net6.0"
# 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: "Enigma2"
# A longer and more detailed description of the plugin; use multiple
# lines as required for readability.
description: >
Live TV plugin for watching Enigma 2 channels and recordings
# 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:
- "Jellyfin.Plugin.Enigma2.dll"
# Build information values for the build infrastructure; these should
# not need to be changed usually.
build_type: "dotnet"
dotnet_configuration: "Release"
dotnet_framework: "net6.0"