chef 3745 Posted March 5, 2015 Share Posted March 5, 2015 I am almost trough with trial and error. You give me a basic task to build in vb.net and I am your man! But trying to fiddle my way through learning javascript in html5 and I want to completely destroy the computer I am working on, literally through the console through an open window and watch it smash into little pieces. It may be depreciated but I miss vbscript in web browsers! At least it look familiar! So, my question is: Can I build an asp.net web form to use as my plugins configuration page for media browser? I need to code .net in my web form. I am so bad at JavaScript I can't even get alerts to work half the time, and the plugin needs to do some reading and writing to xml. So you can imagine my frustration! Any experts want to weigh in on possible alternatives to JavaScript in html? Link to comment Share on other sites More sharing options...
ebr 14913 Posted March 5, 2015 Share Posted March 5, 2015 It really isn't that hard. You'll get it. We need to maintain the continuity of the configuration experience for the user. We don't want to be jumping out to new pages for some plug-ins. Any actual file manipulation should be done by the main plug-in and not actually the configuration page. The configuration system provides you with your own, customizable config file and a way to read and update it from the js config page. Lots of examples of this in the various repos. If you really require more custom processing, you can also write your own API end points in your plug-in and call those from your config page. A simple example of this is in the "Cleaner" plug-ins which make a simple call to retrieve and display the plug-in version. Link to comment Share on other sites More sharing options...
chef 3745 Posted March 5, 2015 Author Share Posted March 5, 2015 (edited) I don't have a js config page in my project, that could probably be the problem. I have been trying to read online how to call a sub procedure from js in a class in .net that is In the same project, but holy mackerel! I need to add a config js file to my project. Back to the repos I go. Edited March 5, 2015 by chef Link to comment Share on other sites More sharing options...
ebr 14913 Posted March 5, 2015 Share Posted March 5, 2015 The js can be a separate file but, for plug-in config pages, it is easier to just embed it in the html file ( What routine would you need to call from your config page? As I said, to do this, you would write a custom API end point, but first be sure you really need to do it... Link to comment Share on other sites More sharing options...
chef 3745 Posted March 5, 2015 Author Share Posted March 5, 2015 (edited) Edit: If I could access a subroutine in my Plugins class. I could handle everything in vb.net, that would be amazing. If that is possible. Edited March 5, 2015 by chef Link to comment Share on other sites More sharing options...
ebr 14913 Posted March 5, 2015 Share Posted March 5, 2015 But what are you actually trying to do? You could cause a routine in your plug-in to run by creating an API end point - but, depending on what you really need to do, that may not be necessary. Link to comment Share on other sites More sharing options...
chef 3745 Posted March 5, 2015 Author Share Posted March 5, 2015 (edited) In my html page, I have a text box which I need to write the contents to an xml node when a button is pressed. Edited March 5, 2015 by chef Link to comment Share on other sites More sharing options...
ebr 14913 Posted March 5, 2015 Share Posted March 5, 2015 Okay, so your plugin has a configuration file defined in it. It is called PluginConfiguration.cs. You can add whatever properties you wish to this class and it will be serialized and saved and also read in when your plug-in is loaded. When your config html page is loaded, there is an api call that will retrieve this class as a js object and you can access the properties on it. Take the value and put it in the text field on page load and take the text value and put it in the property and then save the configuration when the save button is hit. Just about every plugin in the repo has this basic process in it if it has any configuration. Link to comment Share on other sites More sharing options...
chef 3745 Posted March 6, 2015 Author Share Posted March 6, 2015 (edited) What is the object name which is accessing the Properties? ----- When I build my plugin, and copy it over to the plugin folder, and restart the server, the html page doesn't always update when I choose "settings" on my plugin. I have the "config.html" set as an embedded resource in my solution, is this correct? Edited March 6, 2015 by chef Link to comment Share on other sites More sharing options...
ebr 14913 Posted March 6, 2015 Share Posted March 6, 2015 Your config page will be cached based on the version of the plug-in. So if you change something, the version number needs to change (or you can force refresh with the browser). Your configuration object will be the response to the call to load your configuration. ApiClient.getPluginConfiguration(CoverArt.pluginUniqueId).done(function(config) { CoverArt.config = config; Dashboard.hideLoadingMsg(); }); Link to comment Share on other sites More sharing options...
chef 3745 Posted March 6, 2015 Author Share Posted March 6, 2015 (edited) Wait a minute! I think I am missing javascripts in my plugin solution. Are there supposed to be scripts attached that would decalre "ApiClient"? Because I haven't any. Edited March 6, 2015 by chef Link to comment Share on other sites More sharing options...
ebr 14913 Posted March 6, 2015 Share Posted March 6, 2015 Wrong class. That is the class that defines the plugin configuration page not the configuration file itself. The configuration file itself is PluginConfiguration inheriting from BasePluginConfiguration. Link to comment Share on other sites More sharing options...
chef 3745 Posted March 6, 2015 Author Share Posted March 6, 2015 Right, Sorry there is a lot happening here. Two separate questions I think. thank you for tanking the time to help, by the way. If I learn this properly then I can help others. Inorder to fix my problem, (based on what I see Snazy did in some of his plugins) I went a head and created a new class called "MyPluginConfiguration" it is separate from the "PluginConfiguration" class: "MyPluginConfiguration": Imports System.IO Imports MediaBrowser.Model.Plugins Imports MediaBrowser.Controller.Plugins Imports MediaBrowser.Common.Plugins Public Class MyPluginConfiguration Inherits BasePluginConfiguration Implements IPluginConfigurationPage Public Function IPluginConfigurationPage_GetHtmlStream() As Stream Implements IPluginConfigurationPage.GetHtmlStream Return [GetType]().Assembly.GetManifestResourceStream([GetType]().[Namespace] + ".configPage.html") End Function Public ReadOnly Property IPluginConfigurationPage_ConfigurationPageType() As ConfigurationPageType Implements IPluginConfigurationPage.ConfigurationPageType Get Return ConfigurationPageType.PluginConfiguration End Get End Property Public ReadOnly Property IPluginConfigurationPage_Name() As String Implements IPluginConfigurationPage.Name Get Return "Media Browser Vera Smart Home Control" End Get End Property Public ReadOnly Property IPluginConfigurationPage_Plugin() As IPlugin Implements IPluginConfigurationPage.Plugin Get Return Plugin.Instance End Get End Property End Class Here is my "Plugin" class now: Imports System.Security.Permissions Imports MediaBrowser.Common.Configuration Imports MediaBrowser.Common.Plugins Imports MediaBrowser.Model.Serialization <PermissionSet(SecurityAction.Demand, Name:="FullTrust")> _ <Runtime.InteropServices.ComVisibleAttribute(True)> _ Public Class Plugin Inherits BasePlugin(Of MyPluginConfiguration) Public Sub New(ByVal applicationPaths As IApplicationPaths, ByVal xmlSerializer As IXmlSerializer) MyBase.New(applicationPaths, xmlSerializer) Instance = Me End Sub #Region "Properties" ''' <summary> ''' Gets the instance. ''' </summary> ''' <value>The instance.</value> Public Shared Property Instance() As Plugin Get Return _mInstance End Get Private Set(value As Plugin) _mInstance = value End Set End Property Private Shared _mInstance As Plugin Public Overrides ReadOnly Property Name() As String Get Return "Media Browser Vera Smart Home Control" End Get End Property #End Region End Class And the new class which I believe we were just speaking about is the "PluginConfiguration" class, which is where I think you said all the properties will be written too: ''' <summary> ''' Class MyConfigurationPage ''' </summary> Public Class PluginConfiguration Public Property SerializeThisStirngProperty As String Get Return _test End Get Set(value As String) _test = value End Set End Property Private _test As String = "Horray it Serilaized to the XML" End Class In actuality there are three main classes which the plugin must have... right? Link to comment Share on other sites More sharing options...
ebr 14913 Posted March 6, 2015 Share Posted March 6, 2015 No, you are mixing two things that shouldn't be. Your class that inherits BasePluginConfiguration is just your configuration properties - the things that will be saved to a file and referenced by your plug-in when you need to know options. IPluginConfigurationPage is an interface that defines to the system the existence and location of your actual configuration Page. These should be two separate classes. Link to comment Share on other sites More sharing options...
chef 3745 Posted March 6, 2015 Author Share Posted March 6, 2015 (edited) Okay: "PluginConfiguration" now inherits BasePluginConfiguration (to serialize to xml): Imports MediaBrowser.Model.Plugins ''' <summary> ''' Class ConfigurationPage ''' </summary> Public Class PluginConfiguration Inherits BasePluginConfiguration Public Property SerializeThisStirngProperty As String Get Return _test End Get Set(value As String) _test = value End Set End Property Private _test As String = "Horray it Serilaized to the XML" End Class and "MyPluginConfiguration" now implements the "IPluginConfigurationPage" interface: Imports System.IO Imports MediaBrowser.Model.Plugins Imports MediaBrowser.Controller.Plugins Imports MediaBrowser.Common.Plugins Public Class MyPluginConfiguration Implements IPluginConfigurationPage Public Function IPluginConfigurationPage_GetHtmlStream() As Stream Implements IPluginConfigurationPage.GetHtmlStream Return [GetType]().Assembly.GetManifestResourceStream([GetType]().[Namespace] + ".configPage.html") End Function Public ReadOnly Property IPluginConfigurationPage_ConfigurationPageType() As ConfigurationPageType Implements IPluginConfigurationPage.ConfigurationPageType Get Return ConfigurationPageType.PluginConfiguration End Get End Property Public ReadOnly Property IPluginConfigurationPage_Name() As String Implements IPluginConfigurationPage.Name Get Return "Media Browser Vera Smart Home Control" End Get End Property Public ReadOnly Property IPluginConfigurationPage_Plugin() As IPlugin Implements IPluginConfigurationPage.Plugin Get Return Plugin.Instance End Get End Property End Class Edited March 6, 2015 by chef Link to comment Share on other sites More sharing options...
chef 3745 Posted March 6, 2015 Author Share Posted March 6, 2015 (edited) Finally! When I call the UpdateConfiguration procedure on load, it places my property in the XML file. For the first time in days I finally feel relief. I don't want to destroy the entire world. ....eh... so why doesn't my html doc load properly again?... Edited March 6, 2015 by chef Link to comment Share on other sites More sharing options...
chef 3745 Posted March 6, 2015 Author Share Posted March 6, 2015 ...and I have my html updating! Thank you! Link to comment Share on other sites More sharing options...
chef 3745 Posted March 7, 2015 Author Share Posted March 7, 2015 (edited) @@ebr, can the PluginConfiguration Serialize a Dictionary to xml? Edit: crap I think I have to build an api endpoint To read a dictionary Edited March 7, 2015 by chef Link to comment Share on other sites More sharing options...
ebr 14913 Posted March 7, 2015 Share Posted March 7, 2015 Dictionaries will serialize to json just fine so you can see them in your config page no problem. However, the basic xml serialization we use in the server cannot serialize a dictionary. I have an implementation of an xml serializable dictionary but it is in c#. Link to comment Share on other sites More sharing options...
chef 3745 Posted March 7, 2015 Author Share Posted March 7, 2015 (edited) Dictionaries will serialize to json just fine so you can see them in your config page no problem. However, the basic xml serialization we use in the server cannot serialize a dictionary. I have an implementation of an xml serializable dictionary but it is in c#. That would be great. I wrote a routine which iterates the dictionary and builds the xml I need, but it is useless here: My dictionary is: Dictionary(of String, Dictionary(Of String,String) The first string in the dictionary holds the client name. The value of the dictionary is another dictionary, which holds the key which is a MediaBrowser event name, and the value will be the http request for Vera home automation. I was hoping to serialize an xml which looks like this: <?xml version="1.0"?> <PluginConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" /> <DLNA> <PlaybackStarted>Test Play</PlaybackStarted> <PlaybackStopped>Test Stopped</PlaybackStopped> <PlaybackPaused>Test Paused</PlaybackPaused> <PlaybackUnpaused>Test UnPaused</PlaybackUnpaused> </DLNA> <Dashboard> <PlaybackStarted>Test Play</PlaybackStarted> <PlaybackStopped>Test Stopped</PlaybackStopped> <PlaybackPaused>Test Paused</PlaybackPaused> <PlaybackUnpaused>Test UnPaused</PlaybackUnpaused> </Dashboard> </PluginConfiguration> Edited March 7, 2015 by chef Link to comment Share on other sites More sharing options...
chef 3745 Posted March 8, 2015 Author Share Posted March 8, 2015 Your config page will be cached based on the version of the plug-in. So if you change something, the version number needs to change (or you can force refresh with the browser). Your configuration object will be the response to the call to load your configuration. ApiClient.getPluginConfiguration(CoverArt.pluginUniqueId).done(function(config) { CoverArt.config = config; Dashboard.hideLoadingMsg(); }); @@ebr things are moving along, I spent all night learning jquery and now the code writing is super fast. Earlier in our conversation you mentioned caching the config file. You used "Apiclinet" call. If I needed to take a string selected from a drop downbox in my html form and place it into a property in my configuration file, is this how I would do it? Link to comment Share on other sites More sharing options...
TedA 36 Posted March 9, 2015 Share Posted March 9, 2015 (edited) @@ebr things are moving along, I spent all night learning jquery and now the code writing is super fast. Earlier in our conversation you mentioned caching the config file. You used "Apiclinet" call. If I needed to take a string selected from a drop downbox in my html form and place it into a property in my configuration file, is this how I would do it? Chipping in by virtue of knowing JavaScript, rather than by virtue of being an expert on MediaBrowser, so if I am wrong somebody please correct me The NextPVR configPage.html should give you a good example of how to submit your config page to the API: https://github.com/MediaBrowser/MediaBrowser.Plugins/blob/master/MediaBrowser.Plugins.NextPvr/Configuration/configPage.html The relevant portion of code is lines 70-87: $('.nextpvrConfigurationForm').on('submit', function (e) { Dashboard.showLoadingMsg(); var form = this; ApiClient.getPluginConfiguration(NextPvrConfigurationPage.pluginUniqueId).done(function (config) { config.WebServiceUrl = $('#txtWebServiceUrl', form).val(); config.Pin = $('#txtPin', form).val(); config.EnableDebugLogging = $('#chkDebugLogging', form).checked(); ApiClient.updatePluginConfiguration(NextPvrConfigurationPage.pluginUniqueId, config).done(Dashboard.processPluginConfigurationUpdateResult); }); // Disable default form submission return false; }); This adds an event listener for the 'submit' event on the form (the supplied function will fire when the user submits the form) the ApiClient.updatePluginConfiguration([::myPluginId], [::myConfigObject]) uses the ApiClient JavaScript library to submit your config object to the server. To get the value from your dropdown you would simply do: config.MyPropertyName = $('#mySelectId', form).val(); Prior to the updatePluginConfiguration call. You could probably just use the NextPvr configPage.html as a starting point in your plugin, and just replace the input elements in the form with what you need, and the pluginUniqueId on line 51 with your plugin's ID. Just a thought. Edited March 9, 2015 by TedA 2 Link to comment Share on other sites More sharing options...
chef 3745 Posted March 9, 2015 Author Share Posted March 9, 2015 @@TedA Thank you! I see the code now. JavaScript is new to me. Your through explaination helped me get the result I was looking for. Does Submitting the form mean: when it is loaded, or when a submit button is pressed? Web lingo is new to me as well. Link to comment Share on other sites More sharing options...
ebr 14913 Posted March 9, 2015 Share Posted March 9, 2015 When the submit button is pressed (on an html form). 1 Link to comment Share on other sites More sharing options...
chef 3745 Posted March 10, 2015 Author Share Posted March 10, 2015 @@ebr, sorry, I know you're busy, but after testing numerous lines of javascript (including tedA's code, which I see is all over all the plugin repo, and I know is right), I can not access the property through the ApiClient call in my Configuration class. I can't retrieve any property Values, and I can't set new ones. This is literally what I have in my code (pretty much exactly from the repo): var Vera = { pluginUniqueId: "5a7bb1a0-15d6-4af4-9b22-866cddf39547" }; ApiClient.getPluginConfiguration(Vera.pluginUniqueId).done(function (config) { Vera.config = config; var mConfig = config.Options.filter(function (c) { }); config.Options.push(mConfig); ApiClient.updatePluginConfiguration(Vera.pluginUniqueId, config).done(Dashboard.processPluginConfigurationUpdateResult); }); Does it matter that I get a warning in intellisense that "ApiClient" is possibly never assigned? Does the Plugin DLL get the ApiClient object from the server when it is installed in the "plugins" folder and run? Are there javascript files that I should have added to my project (besides the nuget package DLL mentioned in the Plugin Wiki on Github)? I am sorry about all the questions, but I have spent far to long on this, with it going nowhere for me. Ben Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now