'General' Channel Development Questions From A New Developer

@digitalhigh said:
magnanimous:

Heh…You already proved, that you are a real dev…

I simply try here, and not a professional dev, just stubborn if I can’t get stuff to work

@dane22 said:

  1. No idea, since never used it myself

And reason why I set HTTP.CacheTime to zerro was/is, that I don’t code regular channels, but more into the tools buisness

  1. I suggest you check out github for the Sub-Zero plugin…
  2. The dev of that tweaked the framework in ways I simply can’t yet grasp, and it works perfectly for him

@digitalhigh said:
magnanimous:

Heh…You already proved, that you are a real dev…

I simply try here, and nor a professional dev, just stubborn if I can’t get stuff to work

  1. I think once I get a bit more familiarized and poke around in the frameworks more, I may update the API documentation…I cry a little every time I open that PDF and see that the date is “2011”. Same for ArchMageus’ wiki. There are tons of missing methods and parameters, and I’m guessing the API Doc is the same way.

  2. Downloading sub-zero now.

As far as being a “real” dev…I think a lot of the open-source crowd doesn’t consider themselves “real” developers…but it could be all about one single great new idea. I’ve been “tinkering” for years, but don’t consider myself a “real” dev either. I’ve taught myself HTML, CSS, JS, PHP, Java, and fun android stuff. I’ve created skins for XBMC and Winamp way back in the day. But I feel like a real dev wouldn’t have as much trouble as I always do. :smiley:

Sigh. Like now. I’ve got cast discovery and caching more or less working a treat in Linux…but for some reason, zeroconf.py doesn’t seem like it’s binding the socket properly for listening. I wiresharked the outgoing MDNS queries and see the responses coming back, but I don’t see python listening in Windows resource monitor, and it never collects the incoming responses.

I remember having this same issue with my PHP implementation for cast, and wound up fixing it by messing with the SO_REUSEADDR or SO_REUSEPORT flags when creating the socket.

But that isn’t working here, and in testing with just the PHP module and no Plex, I’m still not getting the responses or seeing it listening correctly. So, fun. Something to do with Server 2016, I suspect, but I’ve even disabled IPV6 and deleted my VNIC adapters in Hyper-V to make sure there’s only one interface presented. Still nojoy.

Do you have a windows box you can test it on, to see if it’s just my OS or if it’s all OSes…

Also, yeah, saw your comment about the package name, will fix shortly. If you’re free later, maybe hit me up on Hangouts? I’ve got a bunch of little stuff maybe you could answer, instead of spamming one thread more? I could do this all day. :stuck_out_tongue_winking_eye:

Sorry, but this is about sharing, so it stays here!

And as said, I’m not an expert here, just a dude that touched a bare minimum of the framework, and only started on Python due to Plex as well, and as such, not even skilled with that :frowning:

Chiming in.

@digitalhigh said:
<MediaContainer title1="Cast Devices" noHistory="1" title2="Devices found" noCache="1" size="8" identifier="com.plexapp.plugins.FlexTV" sourceTitle="FlexTV" mediaTagPrefix="/system/bundle/media/flags/"> <Directory thumb="192.168.1.217:8009" duration="1" title="Kitchen Home" summary="audio"/> <Directory thumb="192.168.1.217:42581" duration="1" title="Upstairs" summary="group"/> <Directory thumb="192.168.1.150:8009" duration="1" title="Bathroom" summary="audio"/> <Directory thumb="192.168.1.131:8009" duration="1" title="Basement speaker" summary="audio"/> <Directory thumb="192.168.1.104:8009" duration="1" tagline="E8C28D3C" title="Gavin's Room" summary="cast"/> <Directory thumb="192.168.1.129:8009" duration="1" title="Bedroom TV" summary="cast"/> <Directory thumb="192.168.1.197:8009" duration="1" title="SHIELD" summary="cast"/> <Directory thumb="192.168.1.118:8009" duration="1" title="SHIELD" summary="cast"/> </MediaContainer>

I want to do that, but make it look like the output of plex.tv\api\resources. My scrapers already know how to parse that output. It’s minor to write a new method that scrapes what I’m outputting now, but would be nice to have those fields, just for consistency.

The Device and Connection datatypes aren’t defined and/or exposed inside the Framework anywhere. I doubt you can achieve that using the intended methods.

If you can live with a “detached” channel function that doesn’t work when navigated to from the channel menu, but has to be opened separately, take a look at my custom HTTP response returns in interface/menu_helpers.py:195 and the usage in interface/advanced.py:288. You can return arbitrary data and not only ObjectContainers in channel functions as long as what you return derives from the internal Object class, which I stole from the base class of Redirect: interface/menu_helpers.py:192 (Framework.bundle/Contents/Resources/Versions/2/Python/Framework/objects.py:35, Framework.bundle/Contents/Resources/Versions/2/Python/Framework/components/runtime.py:973).

Keep in mind that this is highly unsupported, although core changes to the framework are most unlikely after all these years.

Edit: I’m talking about the Sub-Zero source.
Edit 2: Looking at my last quoted line in the Framework, you might be able to simply return an etree._Element as well, which would make life easier for you because you could use lxml to construct the response
(Framework.bundle/Contents/Resources/Versions/2/Python/Framework/components/runtime.py:1008).

@panni said:

If you can live with a “detached” channel function that doesn’t work when navigated to from the channel menu, but has to be opened separately, take a look at my custom HTTP response returns in interface/menu_helpers.py:195 and the usage in interface/advanced.py:288. You can return arbitrary data and not only ObjectContainers in channel functions as long as what you return derives from the internal Object class, which I stole from the base class of Redirect: interface/menu_helpers.py:192 (Framework.bundle/Contents/Resources/Versions/2/Python/Framework/objects.py:35, Framework.bundle/Contents/Resources/Versions/2/Python/Framework/components/runtime.py:973).

Keep in mind that this is highly unsupported, although core changes to the framework are most unlikely after all these years.

Edit: I’m talking about the Sub-Zero source.
Edit 2: Looking at my last quoted line in the Framework, you might be able to simply return an etree._Element as well, which would make life easier for you because you could use lxml to construct the response
(Framework.bundle/Contents/Resources/Versions/2/Python/Framework/components/runtime.py:1008).

NICE!

I think I can. It’d be “nice” for it to work from the UI, just for a simple way to view the cast devices, but I’m absolutely not set in stone with this. Also, I could theoretically return “normal” XML with my /MainMenu endpoint, and then schlep custom data into the /Devices and/or /Play and /Cmd endpoints.

Either way…this should let me do what I want, more or less. Thanks for the tip. :smiley:

@panni said:
Chiming in…

Thanks again for this! I was able to copy your class’ structure, then modify it to return proper XML in the format like you see on Plex.tv/api/resources. Current incarnation is a little hacky yet and can be made a lot more elegant, but considering as how I’ve been doing python for like a week now, I’m happy with the result, and can work on extending it more down the road.

In the implementation I have now, I’m setting it up to send the required data in the headers.

Are you aware of a way of reading other query params from the URL? Like, if I did “myserver.com:32400/applications/FlexTV/Play?key=xxx&server=yyy&client=zzz&type=audio”, is there a way to cheat and read those params?

Again, not earth-shattering if I can’t, but it’d make testing/development a little easier…

I’m not sure, but you might be able to look at the URL poking around in Request.Headers.
You can also try to define them inside your @route definitions - again, not sure.

Edit: You can also try digging a little deeper into Framework.bundle/Contents/Resources/Versions/2/Python/Framework/code/context.py:37, and try accessing getattr(Context, "_request") for example.
Edit 2: Context.request is exposed.

@panni said:
I’m not sure, but you might be able to look at the URL poking around in Request.Headers.
You can also try to define them inside your @route definitions - again, not sure.

Edit: You can also try digging a little deeper into Framework.bundle/Contents/Resources/Versions/2/Python/Framework/code/context.py:37, and try accessing getattr(Context, "_request") for example.
Edit 2: Context.request is exposed.

Hmmmm…

I see it, but without a code example, I’m having a tough time figuring out how to use it. I’m getting errors that “Context/context” doesn’t exist, and I can’t seem to import it?

Edit:

Interestingly enough, while playing around with other options, I’ve discovered you can basically add X-Plex-FOO as a tag in the params, and they automagically get sorted into the Request.Headers field.

Interesting. I thought Context was exposed. Might be getattr(Core, "_context") then, I’m not sure (I don’t have the framework source right now).

@panni said:
Interesting. I thought Context was exposed. Might be getattr(Core, "_context") then, I’m not sure (I don’t have the framework source right now).

No biggie. I’m able to fudge it just fine using X-Plex-… in the query.

Curious, is there a right way to pass the Plex log handler to the handlers defined in the helper libraries?

@digitalhigh I’m not sure what you mean, but I’ve “stolen” this approach from the channel I forked SZ from years ago. (And this for usage)

BTW: You might want to join the SZ Slack so we can have some more indepth conversations :wink:

Edit: I’m pretty sure what you mean. Follow all the links! :smiley: