Object links to "normal" TVShow page?

plugin-dev

#1

I am working on a plugin that filters TV Shows in your library and presents a list of the shows for you to watch. I've gotten the list of shows that I want to display, but am not finding the right Object (or values) to put into the ObjectContainer. I've tried both TVShowObjects and DirectoryObjects, and both display the item correctly, but when I click it just takes me to a page that again displays the thumbnail.

show_object = TVShowObject(
        key='/library/metadata/365',
        rating_key='365', 
        title=show_details['title'], 
        summary=unicode(show_details['summary']),

It takes me to:
/channel/%2Fvideo%2Ftvmonitor/%2Flibrary%2Fmetadata%2F365

But I want to go to:
/details?key=%2Flibrary%2Fmetadata%2F365

I've also tried setting 'url' in the TVShowObject, (with both '/library/metadata/365' and '/details?key=%2Flibrary%2Fmetadata%2F365') but it tells me no service exists for those URLs...

Is there an object that just links to the standard TV show page from a plugin?

Thanks.


#2

Though I am more familiar with the plugin framework than the Plex Web API , in a plugin, the directory objects for a show needs to have a callback to a function that creates the episode objects for each video to produce a list of playable episodes.

Using a TVShowObject() versus a DirectoryObject() just provides different attributes for the metadata that is included in the listing. You still have to link that to a function that builds the individual episode objects from the PMS XML data. Otherwise the various Plex players would not know what to do next.


#3

Yeah I know that typically it would require a callback if I were trying to replicate that page, but I really just want to fully redirect the user to the normal page they'd get to if they clicked "TV Shows" and then clicked the show name, rather than attempting to replicate anything on that page. I imagine some Object (or some settings on the TVShowObject) would cause that redirection, but I can't figure out what.


#4

@edank said:
Yeah I know that typically it would require a callback if I were trying to replicate that page, but I really just want to fully redirect the user to the normal page they'd get to if they clicked "TV Shows" and then clicked the show name, rather than attempting to replicate anything on that page. I imagine some Object (or some settings on the TVShowObject) would cause that redirection, but I can't figure out what.

I may be wrong and hopefully someone will chime in if I am.

But I am pretty sure that each Plex player app is programmed to read the channel XML differently than reads the local media XML. So I am not sure if the player apps can switch from reading channel XML for a directory to using the Plex player apps method of reading the directory data for local media.

But you may want to ask within the General (Third-Party Development) section since that section can provide more insight on how the various player apps are programmed to read the local media XML.


#5

Thanks, I'll check there. I wasn't really sure what belonged in which of those two forums...


#6

@edank I don't know if it's going to work in the end, but I may know of a way for you to find out. You can output any XML (or anything else) out of Plex channel, but you'll have to build it yourself, without the use of the object model. Which may be okay for a test. Then, if you were able to "fool" a Plex client into opening a TV show in a local library, you'd be presented with a greater challenge of how to implement the solution elegantly.

@route(PREFIX+'/test')
def Test():
     return DataObject('<?xml .... ', 'application/xml')

You may copy your regular XML stub that you have generated in your channel, manually replace a link to the library, then add that whole ugly string as a 1st argument of the DataObject, and see what happens.


#7

Another approach would be to try to redirect the client to TV library and use callback to that function in TVShowObject:

def Menu():
    ...
    show_object = TVShowObject(
        key=Callback(Test, media_id='365'),
        rating_key='365', 
        title=show_details['title'], 
        summary=unicode(show_details['summary']),
    ...

@route(PREFIX+'/test')
def Test(media_id):
    library_url = ?  # /details?key=%2Flibrary%2Fmetadata%2F365
    return Redirect(library_url)

#8

OK, that looks like it has potential. It'll be a few days til I can work on it again, but I'll try that out!

Thanks!


#9

Finally was able to get back on this, and I’m still not figuring out how to get it to work… With the library_url being either just “/details/etc…” or the full “http://192…” the Redirect just does nothing and gives no error…

But I wonder, would this be easier if there were just a standard Plex URL Service? Then I could just build a standard “https://app.plex.tv/desktop#!/server/12345/details?key=%2Flibrary%2Fmetadata%2F12345” URL and use the power of URL Services.

This is probably better as a new thread (that I’ll make next…), but can you think of any reason why there isn’t (or couldn’t be) a URL Service for Plex URLs?


#10

Hmm… Thinking about that more, I’m doubting that direction… I think the URL Service might conceptually allow you to watch the episode, but likely wouldn’t go through the normal flow and therefore wouldn’t mark the episode as watched, which defeats the whole purpose.


#11

@edank is there nothing even in the logs, both Plex Server and client? I would expect to find at least some mention of a problem.

As for the URL Service, the way I understand it, it is to allow to play a content from a web page using its URL, and not necessarily having to navigate to it within a channel. Then, if you have URL Service implemented, you may reuse its logic in the channel so you don’t have to develop some of the functionality twice. So I see it as a completely optional part of a Plex channel which may be useful, but at the same time applying certain limitation regarding functions of Plex Framework that can be used.

Moreover, after seeing how the XML from the library looks, I doubt Plex Framework will be able to generate the exact same XML. If redirecting to library details pages cannot be made to work, it still might be possible to achieve what you want, but you’ll need to examine Plex Web API and call it from your channel.


#12

@czukowski said:
@edank is there nothing even in the logs, both Plex Server and client? I would expect to find at least some mention of a problem.

This is my first attempt at a plugin, so I may be overlooking something. I didn’t see anything in the plugin log. Maybe I need to look into a different log for the redirect error?


#13

@edank the channel should be issuing a standard HTTP redirect (you can make sure by navigating the channel XML in your web browser). Then it is up to Plex client to follow that redirect, but it may be that redirecting to library URLs is not supported or allowed in it for some reason and if something like that is happening, it will likely be mentioned in the client log file. Now depending on the client app you use, the log file location may vary or it might not store logs at all.

I know that OpenPHT on Windows does write quite detailed logs to %AppData%\OpenPHT\OpenPHT.log. You may try that one not only in case you can’t find the log files from your client app, but also to compare how different Plex clients behave, since redirecting to library URLs is likely a ‘non-standard’ functionality and might not work the same in different clients.

By the way, if you’re planning to share your plug-in when you develop it, then this approach may not be the best, exactly for compatibility reasons.

Also do try the XML in your browser. HTTP redirects are ‘transparent’ and should work by default, unless the client app does any special validation on the redirected URLs. Since the browser is not a Plex client, it should redirect right away, so it may be a good idea to make sure it works in the browser first, then you’ll know the redirect is being issued correctly and then focus on whether Plex clients actually take that or not.


#14

@czukowski said:
By the way, if you’re planning to share your plug-in when you develop it, then this approach may not be the best, exactly for compatibility reasons.

Ideally, I’d like to make it publicly available, as it seems like it is a useful feature… “On Deck” just doesn’t cut it, and even it doesn’t exist everywhere… So I definitely have concerns that the Redirect will likely eventually work in a browser, but even then won’t work on the Roku client, which is my own personal target. I think the most likely case is that getting directed from a plugin to a standard item page is going to require new backend functionality…

I’m really surprised that nobody has run into this use case before!


#15

@edank said:
I’m really surprised that nobody has run into this use case before!

Well, maybe somebody has, but there’s not a lot of people browsing this corner of the forums nowadays. As for me, my purpose of using plugins is only to make some content from the web available to Plex to watch on the big screen.

Anyway, if you want to implement it “correctly”, you’ll have to accept that you’re going to do a lot more work, that is to authenticate against your Plex server (since your channel will act as a client when accessing the library) and then use the Web API to browse the library, thus probably having to recreate all the objects and do whatever the Web API allows you to do.

On the contrary, the approach with Redirect is assuming that the Plex client is already authenticated with the server and can already access both library and channels freely, and also since Plex server-client communication is using HTTP protocol, which does not limit what may be redirected where, there is no principal reason for redirects not to work. Then if the channel could just redirect the client to the library page (although it needs to know about that library page somehow, which is another question), then it would “just work” automatically. Though it’s obviously a ‘hack’, I see it as an elegant one, so I would first go to see if that’s really possible before reverting to the other solution.


#16

I think I’m likely doing something wrong that should be obvious, but I’m just too clueless to see it…

I’ve tried just hardcoding in the Redirect to my full show URL… So my code is:

def DisplayShows(tracked_shows):
	oc = ObjectContainer(title2="TVMonitor")
	for show_id, show_details in tracked_shows.items():
		show_object = TVShowObject(
			key=Callback(TVShow, media_id=show_details['key_id']),
			rating_key=show_details['key_id'], 
			title=show_details['title'], 
			summary=unicode(show_details['summary']),
#			thumb=cover, 
#			art=R(art)
		)
		oc.add(show_object)
	return oc

@route(PREFIX + '/tvshow')
def TVShow(media_id):
	library_url = 'https://app.plex.tv/desktop#!/server/123451234512345/details?key=%2Flibrary%2Fmetadata%2F' + media_id
	Log('TVShow says: '+ library_url)
	return Redirect(library_url)

In my plugin log file, I do see “Response: [200] Redirect, 0 bytes”, but nothing gets displayed, and in the inspector I just have:

<ul class="list media-list"></ul> == $0

#17

I see two possible issues here:

  1. In the log file it says [200] Redirect, but 200 is an HTTP code for when a “normal” response is being sent, for redirect it should be 301 or 302. But I’m not sure why it does that, since you’re clearly returning a Redirect object.
  2. You’re redirecting to an external URL rather than to the local server, that might cause the issue above, although that’s just a guess. Also I’m not sure what does that URL belong to. If it’s a Plex Web URL, it wouldn’t work, you need one that leads to the XML generated by the library. Try to do a local redirect (ie to the same server the channel is running on), use only the path to the library item and see what happens, eg:
return Redirect('/library/metadata/%s' % media_id)

#18

Aha, I was using Redirect() quite incorrectly! I tried your code, and got duplicate /library/metadata/library/metadata/%s, so just switched to %s. On the Windows/HTTP client, nothing still. BUT, on the Roku Plex client, it works! Woohoo!

I’ll have to try other clients to see which work and which don’t… There might be a more universal solution, but at least it works on my primary client. :slight_smile:


#19

Glad you got it working!

As for the other client (I’m assuming you’re referring to Plex Web, ie the one that runs in the browser and accessible by double-clicking Plex tray icon), maybe that has to do with how Plex Web works: it does its requests using XHR and by looking at them in the browser’s Dev tools Network tab, I can see it adds a bunch of other parameters to it, such as authentication token, client identification and some others. I think it breaks because Plex Web uses query parameters instead of HTTP headers to send that information and since the redirected URL doesn’t have any of those parameters, the redirected request reaches Plex Server as unauthenticated. It should be possible to fix that by copying all parameters from the current URL query to the redirected URL if there were any, that shouldn’t affect compatibility with other clients.