VicMoore 754 Posted September 21, 2024 Posted September 21, 2024 I am using the TV C# platform code within the VirtualTV Example code created by Luke. In the Emby "Scheduled Task" function, clicking "Refresh Guide" executes the "AddNewItemsToSchedule" function within this plugin. The executed function is illustrated below. private void AddNewItemsToSchedule(TunerHostInfo tuner, string tunerChannelId, ChannelSchedule channelSchedule) Within this function the plugin developer is supposed to add new EPG data to the existing data. I did this by adding the code below to refresh the EPG from the existing data. The C# code is below. channelSchedule = this.EnsureChannelSchedule(tuner, tunerChannelId); My question is this, is the inclusion of the code above sufficient to update the EPG? My second question is, can I somehow call the Javascript code in the plugin to request it to rebuild the EPG. I believe if the user has available the "Scheduled Task" function, then the user is using a browser, and therefore has the Javascript for the plugin loaded. Please keep in mind that I am just a simple programmer trying to learn what I can. Vic
mickle026 650 Posted September 23, 2024 Posted September 23, 2024 Why don't you send the EPG into the server from the javascript using a web route, ie create your own API endpoint, have the c# function build it and if you need the output in the html return it as an object. You can always send that back again or store it and create a second endpoint to load it to the current EPG. That way the function is in your c# and available to the scheduled task to use directly as that function. I hope this makes sense
VicMoore 754 Posted September 23, 2024 Author Posted September 23, 2024 @mickle026WOW that's a great idea. I am going to try it. Thanks so much. Vic
mickle026 650 Posted September 23, 2024 Posted September 23, 2024 (edited) This thread really should be moved to the Developer API section.. Here is a simple example to get you started, apologies if I made any mistakes, typed this quite quicklly but it should help clarify how this works if you are unsure You can then see the webroute and the parametes in your swagger via the dashboard API link, you are just passing a json object too and fro...but you can encode and decode it how you like to send in your EPG you would POST it, see how that works in swagger, by running a "Try it out", it'll show you the call required. C# public partial class TEST_WEBROUTE : IService, IRequiresRequest { [Route("/TESTEWEBPOUTE/testroute", "GET", Summary = "")] public class MyWebRouteClassName : IReturn<object> { /// <summary> /// Whatever you are sending in , its just decoding json /// if you set ApiMemberName (you dont have to) it sets the vaule available to swagger input /// </summary> /// <value></value> /// Examples /// [ApiMember(Name = "CoverType", Description = "Output File Type ie (Poster,Backdrop,)", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] /// public string CoverType { get; set; } /// [ApiMember(Name = "ImageType", Description = "Output Image Type ie (jpg,bmp,png)", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] /// public string ImageType { get; set; } public string Text { get; set; } } // get method that accompanies the route for returning the object to the route/calling a function, same classname (MyWebRouteClassName) public string Get(MyWebRouteClassName result) { /// Call your function here /// the bool value from your call result returns into this "completed" bool bool completed = DoWheteverIWantFromMyWebInput(); /// Serialise and return whatever you want to your browser via the Get Result to the Webroute object - example below. /// yopu can add more elements its just json return JsonSerializer.SerializeToString(new MyWebRouteClassName() { // using $ to subsitute back the True/False "Completed" value // in the javasript the response value Text is available via the dat.Text - That is the Json value from the container: "Text" Text = $"Function Ended with {Completed}<br />" }); } // Here is the function that would be available to your sheduled task public bool DoWheteverIWantFromMyWebInput(string ThePassedInputText) { // Do Whatever bool Completed = false // the building epg was successfull , set completed to true // the building epg was a failure , set completed to false If{comlpeted} { return True } else { return false } } } JAVASCRIPT In the javascript call it like this page.querySelector('#buildepg').addEventListener('click', () => { document.getElementById("buildepgdivtexttoupdate").innerHTML = "Running.."; BuilDEPG(); }); function BuilDEPG() { ApiClient.getJSON(ApiClient.getUrl('/TESTEWEBPOUTE/testroute')).then(response => { var dat = response; document.getElementById("buildepgdivtexttoupdate").innerHTML = dat.Text; }).catch(e => { console.log(e); }); } Javascript POST, you probably know how to do this already keep away from jQuery if you can, Luke has said all onlng he wants to drop jQuery and go completely Vanilla. I have not tried this method, you'll probably have to modify it to work with ApiClient.getUrl https://www.freecodecamp.org/news/javascript-post-request-how-to-send-an-http-post-request-in-js/ fetch("https://jsonplaceholder.typicode.com/todos", { method: "POST", body: JSON.stringify({ userId: 1, title: "Fix my bugs", completed: false }), headers: { "Content-type": "application/json; charset=UTF-8" } }) .then((response) => response.json()) .then((json) => console.log(json)); Edited September 24, 2024 by mickle026 amended to clarify it a bit more
VicMoore 754 Posted September 24, 2024 Author Posted September 24, 2024 @mickle026I will study this code today. Thanks so much. I don't know how to move this thread to the API section. @GrimReaperPerhaps you can help me. Vic
GrimReaper 4739 Posted September 24, 2024 Posted September 24, 2024 2 minutes ago, VicMoore said: I don't know how to move this thread to the API section. *Done* 1
VicMoore 754 Posted September 24, 2024 Author Posted September 24, 2024 @GrimReaperYou are fantastic... Thank you, Vic 1
GrimReaper 4739 Posted September 24, 2024 Posted September 24, 2024 Np, Vic, just shout if you need anything else. Cheers 1
VicMoore 754 Posted September 24, 2024 Author Posted September 24, 2024 (edited) @mickle026I have learned a great deal from your code. Thanks so much for helping me. As I understand your code, the C# sets up an endpoint inside Emby that can be called by the JS code. Is there a way that the C# code can asynchronously send a message to the JS ? Vic Edited September 24, 2024 by VicMoore
mickle026 650 Posted September 24, 2024 Posted September 24, 2024 (edited) Asynchronously, I'm not sure how to do that without signalR or a web socket listener, and I am not at that point yet. I know the basics but not got them working, it would help me a great deal too. Luke will know as he updates progress bars, but I never managed to get him to be more than vague on the subject. I never tried to extract that form the media browser code on the wiki either. I only know how to send back one reply to a JavaScript query as a response per request. You can send in as many endpoint requests as you like so you can create multiple for different things. So you can use an endpoint aggressively to do the progress bar etc.. I'm sure there's some guru about that knows more about this but I have asked the same question before and not got an answer. Edited September 24, 2024 by mickle026
VicMoore 754 Posted September 24, 2024 Author Posted September 24, 2024 I have also tried web sockets several times with very little success. No one would answer my questions either. I appreciate your help. Keep me in mind when you need help with Javascript. Vic
Luke 42077 Posted September 24, 2024 Posted September 24, 2024 There is a way it just needs to be written up and documented.
VicMoore 754 Posted September 24, 2024 Author Posted September 24, 2024 @LukePerhaps we can help each other. Vic 1
mickle026 650 Posted September 25, 2024 Posted September 25, 2024 @VicMoore I have a question which relates to this thread and is Javascript (please excuse spelling, I have dyslexia - I try to correct as much as i can after i have written it) Perharps it should be in a thread of its own, but its about communicting between the web ui and the c# backend. I would like to nest a "do while" inside a promise while waiting for it to resolve. I have written an example below to highlight what I would like it to do. So for example, a real world example: if I want my app to report progress periodically while the first promise is running but not had a response ApiClient.getJSON(ApiClient.getUrl('/TESTEWEBPOUTE/testroute')).then(response => { var dat = response; document.getElementById("buildepgdivtexttoupdate").innerHTML = dat.Text; }).catch(e => { console.log(e); }); how would I do something like this, I know this isnt correct but highlights what I would like to be able to achieve. I know you cannot test if a promise is resolved, but you can test a value and set that value when the promise has resolved. var resolvedvalue=false; ApiClient.getJSON(ApiClient.getUrl('/TESTEWEBPOUTE/testroute')).then( do { // send in another promise.then(update div) var intervalID = window.setInterval(myCallback, 500); } while (resolvedvalue !== true).then( response => { var dat = response; resolvedvalue = true; document.getElementById("buildepgdivtexttoupdate").innerHTML = dat.Text; }).catch(e => { console.log(e); }); function myCallback() { ApiClient.getJSON(ApiClient.getUrl('/TESTEWEBPOUTE/getmyprogress')).then(response => { var dat = response; document.getElementById("propgress").innerHTML = dat.Text; }).catch(e => { console.log(e); }); } Does this make sense? Basically trigger a timer to update a div whilst the first promise is running. The time sends a secod promise to get the progress. This is just an example that i could use to update tables etc whilst something is running.
VicMoore 754 Posted September 25, 2024 Author Posted September 25, 2024 @mickle026I am recovering from a virus. I will send you a code sample later today or in the morning. Vic
VicMoore 754 Posted September 26, 2024 Author Posted September 26, 2024 @mickle026I have tried several possibilities and none have worked. A hurricane is headed my way, and I may lose power. I have a few other ideas that I would like to try. vic
mickle026 650 Posted September 26, 2024 Posted September 26, 2024 Just now, VicMoore said: @mickle026I have tried several possibilities and none have worked. A hurricane is headed my way, and I may lose power. I have a few other ideas that I would like to try. vic Thanks for trying. I'll await to see if you can brainstorm this out. I thought about setting a timer on function start, running the web route query after starting a timer and stopping the timer on resolution of the promise. Triggering the second route request from the timer. This is not ideal, it'll add extra to emby logs, but should function as needed. I would rather start at the first web route call and stop and resolve but it's near enough the same thing.
Neminem 1518 Posted September 26, 2024 Posted September 26, 2024 9 minutes ago, VicMoore said: A hurricane is headed my way, and I may lose power. Oh wow what is it call this time ? Stay safe and be out of harms way.
VicMoore 754 Posted September 26, 2024 Author Posted September 26, 2024 (edited) I tried something similar. I set a timeOut, then fetched System/Info. While waiting for the promise to be satisfied, a while statement types "*" on the console. I think this did not work because the promise and the while statement are on separate threads. I will keep trying. vic test(); function test() { let timerIndex = setTimeout(timerCallback, 5000); let timeOut = false; console.log("#"); ApiClient.getJSON(ApiClient.getUrl('System/Info')).then( (result) => { console.log("===== Result = ", result); clearTimeout(timerIndex); timeOut = true; return; }).catch((msg) => { console.log("=== Erroe Msg = ", msg); clearTimeout(timerIndex); timeOut = true; return; }); while (!timeOut) { console.log("*"); } function timerCallback() { console.log("TimeOut"); timeOut = true; } }; console.log("Done"); Edited September 26, 2024 by VicMoore
Luke 42077 Posted September 26, 2024 Posted September 26, 2024 This is a start of an example: https://github.com/MediaBrowser/Emby.AutoOrganize/blob/master/Emby.AutoOrganize/Configuration/autoorganizelog.js#L522-L554 That is listening for the messages client-side. However do not fully copy the auto-organize example. It is doing one thing wrong on the server and sending out the messages to all admin clients, which is too much messaging. That needs to be restricted so that it's only sent to clients that are currently on that screen and have requested to listen to those events. But you can use this as proof of concept to get started.
VicMoore 754 Posted September 26, 2024 Author Posted September 26, 2024 @LukeThanks so much. I will study the code today. Vic
mickle026 650 Posted September 26, 2024 Posted September 26, 2024 48 minutes ago, VicMoore said: @LukeThanks so much. I will study the code today. Vic Don't forget the imports/defines at the top of the page .
VicMoore 754 Posted September 26, 2024 Author Posted September 26, 2024 @mickle026I don't really understand the imports and defines. I think I know what they do but I don't really understand them. Vic The hurricane just turned cat 4. I am on the edge of the cone. So far the electric has been holding up.
mickle026 650 Posted September 26, 2024 Posted September 26, 2024 I believe they are similar to imports in c# and tell the JavaScript to load the libraries so that the keywords for those library functions work. Without them you will have a keyword that is just a var... I think this makes sense..
VicMoore 754 Posted September 26, 2024 Author Posted September 26, 2024 @mickle026That does make since. I am determined to understand the code. Vic
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