# Plugin Help!

**URL:** <https://forums.plex.tv/t/plugin-help/7671>\
**Category:** Dev/API Corner\
**Tags:** plugin-dev\
**Created:** [February 4, 2011, 4:04am UTC](https://forums.plex.tv/t/plugin-help/7671 "2011-02-04T04:04:48Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/plex/original/3X/2/a/2acb9765406f63293d357b4ec509ec39aa28f2ad.png) [@system](https://forums.plex.tv/u/system)\
**Post date:** [February 4, 2011, 4:04am UTC](https://forums.plex.tv/t/plugin-help/7671/1 "2011-02-04T04:04:48Z")

</div>

FromSport.com
Ok. Moving my questions to a dedicated topic.  
  
I think I've got the basics figured out, except XPath and how to navigate my way through the objects that are created, etc.  
  
Also, my site configuration. But one step at a time.  
  
  
I am able to pull out rows of a table that hold the links/info I need. First: I haven't been able to figure out how to cycle through the columns of each row item. Next: It appears that the title of the video (in one of the columns) is generated through a script so I'm not sure how to turn that into a usable form.

---

<div class="post-metadata">

**Author:** ![jwray](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/jwray/32/99832_2.png) [@jwray](https://forums.plex.tv/u/jwray)\
**Post date:** [February 4, 2011, 5:24am UTC](https://forums.plex.tv/t/plugin-help/7671/2 "2011-02-04T05:24:43Z")

</div>

Something like

```auto

<br />
foreach row in context.xpath('//table/tr'):<br />
    columns = row.xpath('./td')<br />
    title = columns[0].text<br />
    etc<br />

```

  
  
maybe?

---

<div class="post-metadata">

**Author:** ![jwray](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/jwray/32/99832_2.png) [@jwray](https://forums.plex.tv/u/jwray)\
**Post date:** [February 4, 2011, 5:28am UTC](https://forums.plex.tv/t/plugin-help/7671/3 "2011-02-04T05:28:34Z")

</div>

Or (just looked at the site)

```auto

<br />
foreach row in content.xpath('//table/tr'):<br />
    title = row.xpath('./td[@class="list_champ"]')[0].text<br />
    thumb = row.xpath('./td[@class="list_flag"]/img')[0].get('src')<br />
<br />
   etc.<br />

```

---

<div class="post-metadata">

**Author:** ![jwray](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/jwray/32/99832_2.png) [@jwray](https://forums.plex.tv/u/jwray)\
**Post date:** [February 4, 2011, 5:36am UTC](https://forums.plex.tv/t/plugin-help/7671/4 "2011-02-04T05:36:31Z")

</div>

As for the title, it’s in an escaped string. Try pasting an example [http://www.linkedresources.com/tools/unescaper\_v0.2b1.html](http://www.linkedresources.com/tools/unescaper_v0.2b1.html) and unescape.  
  
  
  
In the plugin, extract out the escaped string using standard python string commands and then use String.Unquote from the PMS framework to get the actual string.  
  
  
  
Jonny

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/plex/original/3X/2/a/2acb9765406f63293d357b4ec509ec39aa28f2ad.png) [@system](https://forums.plex.tv/u/system)\
**Post date:** [February 4, 2011, 6:02am UTC](https://forums.plex.tv/t/plugin-help/7671/5 "2011-02-04T06:02:05Z")

</div>

I will have to look into the escaped string. The others are working fine except a few. When trying to do

```auto

<br />
row.xpath('./td[@class="list_ball"]/img')[0].get('src')<br />

```

  
  
I am getting 'list index out of range' - can you explain what having the [0] outside of the xpath call is doing (or should be doing)?  
  
  
  
  
  
EDIT:  
NM: was missing an 'a' tag - should be row.xpath('./td[@class="list\_ball"]/a/img')[0].get('src')

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/plex/original/3X/2/a/2acb9765406f63293d357b4ec509ec39aa28f2ad.png) [@system](https://forums.plex.tv/u/system)\
**Post date:** [February 4, 2011, 6:19am UTC](https://forums.plex.tv/t/plugin-help/7671/6 "2011-02-04T06:19:38Z")

</div>

I’m trying to use string.replace(‘replacethis’, ‘withthis’) to manipulate the escaped string but not having any success. I’m I headed in the best direction with that?

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/plex/original/3X/2/a/2acb9765406f63293d357b4ec509ec39aa28f2ad.png) [@system](https://forums.plex.tv/u/system)\
**Post date:** [February 4, 2011, 6:23am UTC](https://forums.plex.tv/t/plugin-help/7671/7 "2011-02-04T06:23:29Z")

</div>

Wow… I figured it out… it’s getting late, need to call it a night.   
  
  
  
Thanks for the help, all. Be back to finish tomorrow.

---

<div class="post-metadata">

**Author:** ![pierre1313](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/pierre1313/32/523_2.png) [@pierre1313](https://forums.plex.tv/u/pierre1313)\
**Post date:** [February 4, 2011, 7:10am UTC](https://forums.plex.tv/t/plugin-help/7671/8 "2011-02-04T07:10:03Z")

</div>

> [@](#):
>
> I will have to look into the escaped string. The others are working fine except a few. When trying to do   
>   
> 
> ```auto
> 
> <br />
> row.xpath('./td[@class="list_ball"]/img')[0].get('src')<br />
> 
> ```
> 
>   
>   
> I am getting 'list index out of range' - can you explain what having the [0] outside of the xpath call is doing (or should be doing)?  
>   
>   
>   
>   
>   
> EDIT:  
> NM: was missing an 'a' tag - should be row.xpath('./td[@class="list\_ball"]/a/img')[0].get('src')

  
  
You could use './td[@class="list\_ball"]//img' (note the // ) that would cause xpath to skip all intermediate elements. xpath is always returning and array, even if there is only one element hence the need for the [0]

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/plex/original/3X/2/a/2acb9765406f63293d357b4ec509ec39aa28f2ad.png) [@system](https://forums.plex.tv/u/system)\
**Post date:** [February 4, 2011, 3:57pm UTC](https://forums.plex.tv/t/plugin-help/7671/9 "2011-02-04T15:57:01Z")

</div>

Awesome. figured out the escaped string and have all my menus populating.   
  
  
  
For those interested, here is what I currently have:

```auto

<br />
# PMS plugin framework<br />
from PMS import *<br />
from PMS.Objects import *<br />
from PMS.Shortcuts import *<br />
import re, string, datetime<br />
######<br />
#TODO: <br />
	# 'Country' SubMenu<br />
	# 'League' SubMenu<br />
		# BOTH?<br />
	# Sort (view might need to change so this is intuitive)<br />
	# Adjust times to a time-zone preference<br />
######<br />
####################################################################################################<br />
VIDEO_PREFIX = "/video/fromsport"<br />
PAGE_ROOT = "http://www.fromsport.com/"<br />
<br />
FOOTBALL = "http://www.fromsport.com/c-1.html"<br />
HOCKEY = "http://www.fromsport.com/c-3.html"<br />
TENNIS = "http://www.fromsport.com/c-4.html"<br />
BASKETBALL	= "http://www.fromsport.com/c-6.html"<br />
BASEBALL = "http://www.fromsport.com/c-7.html"<br />
GOLF = "http://www.fromsport.com/c-8.html"<br />
CYCLING = "http://www.fromsport.com/c-9.html"<br />
MOTORSPORTS	= "http://www.fromsport.com/c-10.html"<br />
OTHER = "http://www.fromsport.com/c-11.html"<br />
<br />
NAME = L('Title')<br />
<br />
# make sure to replace artwork with what you want<br />
# these filenames reference the example files in<br />
# the Contents/Resources/ folder in the bundle<br />
ART = 'art-default.png'<br />
ICON = 'icon-default.png'<br />
<br />
####################################################################################################<br />
<br />
def Start():<br />
	Plugin.AddPrefixHandler(VIDEO_PREFIX, MainMenu, "FromSport", ICON, ART)<br />
<br />
	Plugin.AddViewGroup("InfoList", viewMode = "InfoList", mediaType = "items")<br />
	Plugin.AddViewGroup("List", viewMode = "List", mediaType = "items")<br />
<br />
	MediaContainer.art = R(ART)<br />
	MediaContainer.title1 = NAME<br />
	DirectoryItem.thumb = R(ICON)<br />
<br />
def MainMenu():<br />
	dir = MediaContainer(viewGroup = "InfoList")<br />
	dir.Append(Function(DirectoryItem(VideoPage,"HOME",subtitle = "",summary = "",thumb = R(ICON),art = R(ART)),pageUrl = PAGE_ROOT))<br />
	dir.Append(Function(DirectoryItem(VideoPage,"Football",subtitle = "GOOOOOAAAAAAAAAALLLLLLLLLL!!!!!!",summary = "",thumb = R(ICON),art = R(ART)),pageUrl = FOOTBALL))<br />
	dir.Append(Function(DirectoryItem(VideoPage,"Hockey",subtitle = "pucks n' stuff",summary = "",thumb = R(ICON),art = R(ART)),pageUrl = HOCKEY))<br />
	dir.Append(Function(DirectoryItem(VideoPage,"Tennis",subtitle = "Ace!",summary = "",thumb = R(ICON),art = R(ART)),pageUrl = TENNIS))<br />
	dir.Append(Function(DirectoryItem(VideoPage,"Basketball",subtitle = "at the buzzer....",summary = "",thumb = R(ICON),art = R(ART)),pageUrl = BASKETBALL))<br />
	dir.Append(Function(DirectoryItem(VideoPage,"Baseball",subtitle = "Strike 3!",summary = "",thumb = R(ICON),art = R(ART)),pageUrl = BASEBALL))<br />
	dir.Append(Function(DirectoryItem(VideoPage,"Golf",subtitle = "FORE!",summary = "",thumb = R(ICON),art = R(ART)),pageUrl = GOLF))<br />
	dir.Append(Function(DirectoryItem(VideoPage,"Cycling",subtitle = "Push it",summary = "",thumb = R(ICON),art = R(ART)),pageUrl = CYCLING))<br />
	dir.Append(Function(DirectoryItem(VideoPage,"Motorsports",subtitle = "Vroom",summary = "",thumb = R(ICON),art = R(ART)),pageUrl = MOTORSPORTS))<br />
	dir.Append(Function(DirectoryItem(VideoPage,"Other",subtitle = "Uhhh..",summary = "",thumb = R(ICON),art = R(ART)),pageUrl = OTHER))<br />
	return dir<br />
<br />
def VideoPage(sender, pageUrl):<br />
	dir = MediaContainer(title2 = sender.itemTitle)<br />
	Log("Scraping " + pageUrl)<br />
	content = XML.ElementFromURL(pageUrl, isHTML = True)<br />
<br />
	for row in content.xpath('//table//tr'):<br />
		#un-escape the team names<br />
		teams = row.xpath('./td[@class="list_team"]/a/script')[0].text<br />
		teams = teams.replace("document.write(unescape('", "")<br />
		teams = teams.replace("'))", "")<br />
		teams = String.Unquote(teams)<br />
		teams = teams.replace(";", "")<br />
		<br />
		dateTime = row.xpath('./td[@class="list_date"]')[0].text<br />
		sport = row.xpath('./td[@class="list_ball"]/a/img')[0].get('alt')<br />
		country = row.xpath('./td[@class="list_flag"]/img')[0].get('alt')<br />
		league = row.xpath('./td[@class="list_champ"]')[0].text<br />
		vidLink = row.xpath('./td[@class="list_team"]/a')[0].get('href')<br />
		sportPic = row.xpath('./td[@class="list_ball"]/a/img')[0].get('src') #TODO - find better picture options<br />
		countryPic = row.xpath('./td[@class="list_flag"]/img')[0].get('src')<br />
		<br />
		title = teams + " (" + league + ")"<br />
		subtitle = country + " " + sport + " @ " + dateTime<br />
		link = vidLink<br />
		thumb = sportPic<br />
		<br />
		dir.Append(WebVideoItem(link, subtitle = subtitle, title = title, thumb = thumb))<br />
	return dir<br />
<br />
<br />

```

  
  
  
  
  
  
  
Now on to the site configuration so that they will play.  
  
When I first looked at this site, the videos I looked at all used the same flash plugin. Today, with new videos I'm finding that they may actually be using more than one. Is it possible to set up the site configuration using multiple flash plugins?

---

<div class="post-metadata">

**Author:** ![jwray](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/jwray/32/99832_2.png) [@jwray](https://forums.plex.tv/u/jwray)\
**Post date:** [February 4, 2011, 4:06pm UTC](https://forums.plex.tv/t/plugin-help/7671/10 "2011-02-04T16:06:16Z")

</div>

Yep, just have multiple site config files, one for each player. The Daily Show does this for clips vs full episodes.

> [@](#):
>
> Now on to the site configuration so that they will play.  
>   
> When I first looked at this site, the videos I looked at all used the same flash plugin. Today, with new videos I'm finding that they may actually be using more than one. Is it possible to set up the site configuration using multiple flash plugins?

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/plex/original/3X/2/a/2acb9765406f63293d357b4ec509ec39aa28f2ad.png) [@system](https://forums.plex.tv/u/system)\
**Post date:** [February 5, 2011, 5:17pm UTC](https://forums.plex.tv/t/plugin-help/7671/11 "2011-02-05T17:17:41Z")

</div>

Okay, working on my first configuration for this video: [http://www.fromsport.com/v-0/18/2/v-180373.html](http://www.fromsport.com/v-0/18/2/v-180373.html)  
  
  
  
I found that it’s a [Justin.TV](http://Justin.TV) plugin so my site configuration looks like this (copied from MTV and modified):

```auto

<br />
<?xml version="1.0" encoding="UTF-8"?><br />
<site site="http:/www.fromsport.com"<br />
	    plugin="http://www.justin.tv/widgets/live_embed_player.swf"<br />
			initialState="playing"<br />
			version="1.0"><br />
	<br />
	<crop x="0" y="0" width="560" height="400" /><br />
	<seekbar type="simple"><br />
		<start x="69" y="402" /><br />
		<end x="479" y="402" /><br />
		<played><br />
				<color rgb="666666" /><br />
		</played><br />
	</seekbar><br />
<br />
</site><br />

```

  
  
When trying to open the video in Plex I get 'Error while opening file'

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/plex/original/3X/2/a/2acb9765406f63293d357b4ec509ec39aa28f2ad.png) [@system](https://forums.plex.tv/u/system)\
**Post date:** [February 5, 2011, 6:53pm UTC](https://forums.plex.tv/t/plugin-help/7671/12 "2011-02-05T18:53:43Z")

</div>

Any plugin devs?

---

<div class="post-metadata">

**Author:** ![pierre1313](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/pierre1313/32/523_2.png) [@pierre1313](https://forums.plex.tv/u/pierre1313)\
**Post date:** [February 5, 2011, 7:26pm UTC](https://forums.plex.tv/t/plugin-help/7671/13 "2011-02-05T19:26:55Z")

</div>

I’ve seen I happen for a number of reasons but usually a typo in the site address or the plugin is the culprit. Also try using wildcards to make it more robust to changes.

---

<div class="post-metadata">

**Author:** ![sander1](https://avatars.discourse-cdn.com/v4/letter/s/4bbf92/32.png) [@sander1](https://forums.plex.tv/u/sander1)\
**Post date:** [February 7, 2011, 3:34pm UTC](https://forums.plex.tv/t/plugin-help/7671/14 "2011-02-07T15:34:59Z")

</div>

I checked the url you gave ([http://www.fromsport.com/v-0/18/2/v-180373.html](http://www.fromsport.com/v-0/18/2/v-180373.html)) but I do not see the Flashplayer from your site config (http:\*\*\*\*[//www.justin.tv/widgets/live\_embed\_player.swf](https://www.justin.tv/widgets/live_embed_player.swf)) anywhere on that page… Also, you initialState is set to “playing”, but that state is missing from your site config.

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/plex/original/3X/2/a/2acb9765406f63293d357b4ec509ec39aa28f2ad.png) [@system](https://forums.plex.tv/u/system)\
**Post date:** [February 7, 2011, 4:25pm UTC](https://forums.plex.tv/t/plugin-help/7671/15 "2011-02-07T16:25:55Z")

</div>

> [@](#):
>
> I checked the url you gave (http://www.fromsport.com/v-0/18/2/v-180373.html) but I do not see the Flashplayer from your site config (http:\*\*\*\*//www.justin.tv/widgets/live\_embed\_player.swf) anywhere on that page...

  
  
The video was live, so it is over now. The flashplayer showed up when I 'inspect element' in Chrome or Firefox but not directly in the source (pulled from a script, I believe... does that still work?) While the others might not use the justin.tv player, you should be able to look at other videos to see how they work.  
  
  

> [@](#):
>
> Also, you initialState is set to "playing", but that state is missing from your site config.

  
  
If the initial state is playing, what does the state need to do? Doesn't that just say that the video is playing when the page is opened?

---

<div class="post-metadata">

**Author:** ![Dbl\_A](https://avatars.discourse-cdn.com/v4/letter/d/53a042/32.png) [@Dbl\_A](https://forums.plex.tv/u/Dbl_A)\
**Post date:** [February 7, 2011, 5:04pm UTC](https://forums.plex.tv/t/plugin-help/7671/16 "2011-02-07T17:04:23Z")

</div>

You don’t have ANY Tags. I don’t think it’ll work at all unless you have at least one.  
  
  
  
[http://wiki.plexapp.com/index.php/Creating\_Plugins\_Site\_Config#.3Cstate.3E\_Tag](http://wiki.plexapp.com/index.php/Creating_Plugins_Site_Config#.3Cstate.3E_Tag)

---

<div class="post-metadata">

**Author:** ![sander1](https://avatars.discourse-cdn.com/v4/letter/s/4bbf92/32.png) [@sander1](https://forums.plex.tv/u/sander1)\
**Post date:** [February 7, 2011, 5:30pm UTC](https://forums.plex.tv/t/plugin-help/7671/17 "2011-02-07T17:30:38Z")

</div>

> [@](#):
>
> The video was live, so it is over now. The flashplayer showed up when I 'inspect element' in Chrome or Firefox but not directly in the source (pulled from a script, I believe... does that still work?)

  
Yes, for site configs that's fine.  
  

> [@](#):
>
> If the initial state is playing, what does the state need to do? Doesn't that just say that the video is playing when the page is opened?

  
Even if there's nothing to do (because the site config is for live stream for example), there needs to be at least one state. It doesn't necessarily have to be named "playing", but the state machine needs to be in \*a\* state.  
  
For a live stream you can have something live this:  

```auto

<br />
	<state name="playing"><br />
		<event><br />
			<condition><br />
				<frameLoaded /><br />
			</condition><br />
			<action><br />
				<!-- nothing to do here --><br />
			</action><br />
		</event><br />
	</state><br />

```

---

<div class="post-metadata">

**Author:** ![jwray](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/jwray/32/99832_2.png) [@jwray](https://forums.plex.tv/u/jwray)\
**Post date:** [February 7, 2011, 5:54pm UTC](https://forums.plex.tv/t/plugin-help/7671/18 "2011-02-07T17:54:53Z")

</div>

The way I understand it is as a state machine; the player is in a certain state and events (both user generated and stream generated) are detected that transition the player to another state. The site config file configures all the states and transitions you need to control playback. The initialState parameter you mentioned specifies which state the state machine starts in. As such, that state needs to be defined in the configuration file.  
  
  
  
Jonny

> [@](#):
>
> If the initial state is playing, what does the state need to do? Doesn't that just say that the video is playing when the page is opened?

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/plex/original/3X/2/a/2acb9765406f63293d357b4ec509ec39aa28f2ad.png) [@system](https://forums.plex.tv/u/system)\
**Post date:** [December 20, 2019, 8:59pm UTC](https://forums.plex.tv/t/plugin-help/7671/19 "2019-12-20T20:59:04Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
