# need basic help with plugin writing

**URL:** <https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638>\
**Category:** Dev/API Corner\
**Tags:** plugin-dev\
**Created:** [February 1, 2011, 5:03pm UTC](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638 "2011-02-01T17:03:04Z")\
**Posts on this page:** 20\
**Page:** 3

<div class="post-metadata">

**Author:** ![pooploser](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/pooploser/32/133851_2.png) [@pooploser](https://forums.plex.tv/u/pooploser)\
**Post date:** [February 2, 2011, 5:29pm UTC](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638/41 "2011-02-02T17:29:48Z")

</div>

but how do i choose what i wanna grab? my oh my i’m crap at this.…   
  
what variable do i use? i feel like at the beginning again…

---

<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 2, 2011, 5:32pm UTC](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638/42 "2011-02-02T17:32:57Z")

</div>

You’ve got a long way, great. I got a basic python book, can’t remember the title, but I guess any would pretty much work.  
  
  
  
As you’re finding out, xpath knowledge is very useful.   
  
  
  
[XPath 教程](http://zvon.org/xxl/XPathTutorial/General/examples.html)  
  
[http://www.w3schools.com/xpath/default.asp](http://www.w3schools.com/xpath/default.asp).   
  
  
  
Be thankful it’s not regular expressions. The xpath checker, firebug and general web development tools for firefox can also be a godsend when reverse engineering a site or feed.  
  
  
  
RSS namespaces can be a pain, but look at the feed-me plugin, it is a good example of how to deal with multiple namespaces when parsing an rss feed.   
  
  
  
Jonny

> [@](#):
>
> any books/websites you recommend someone wanting to learn go to? Any that you used?

---

<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 2, 2011, 5:38pm UTC](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638/43 "2011-02-02T17:38:58Z")

</div>

If you can post an example rss URL and tell me what items you want to extract from it, I maybe able to take a look sometime today.

> [@](#):
>
> but how do i choose what i wanna grab? my oh my i'm crap at this.…   
> what variable do i use? i feel like at the beginning again..

---

<div class="post-metadata">

**Author:** ![pooploser](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/pooploser/32/133851_2.png) [@pooploser](https://forums.plex.tv/u/pooploser)\
**Post date:** [February 2, 2011, 5:39pm UTC](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638/44 "2011-02-02T17:39:10Z")

</div>

there book feel like advanced grammar explanations to someone who just learned to say “good morning”. :S they look like great tutorials, but no way i’ll find a way through there.  
  
i need it explained in common language rather than   
  
“child::chapter/descendant::para selects the para element descendants of the chapter element children of the context node”

---

<div class="post-metadata">

**Author:** ![pooploser](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/pooploser/32/133851_2.png) [@pooploser](https://forums.plex.tv/u/pooploser)\
**Post date:** [February 2, 2011, 5:44pm UTC](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638/45 "2011-02-02T17:44:10Z")

</div>

thanks for your help.  
  
i did get as far as creating the menu. and when wanting to select a certain picture subcategory, nothing happens. although the rss url is displayed correctly in the console.  
  
here is an example link:  
  
feed://backend.deviantart.com/rss.xml?q=boost%3Apopular+in%3Aphotography%2Fjournalism%2Fperforming+max\_age%3A8h&type=deviation&offset=0  
  
it’s just title, picture, and description.

---

<div class="post-metadata">

**Author:** ![pooploser](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/pooploser/32/133851_2.png) [@pooploser](https://forums.plex.tv/u/pooploser)\
**Post date:** [February 2, 2011, 5:48pm UTC](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638/46 "2011-02-02T17:48:53Z")

</div>

for now, my console says this:  
  
  
  
2/2/11 6:46:39 PM [0x0-0x59059].com.plexapp.plexmediaserver[796] 18:46:39.328769: com.plexapp.plugins.abc : Success!  
  
2/2/11 6:46:40 PM [0x0-0x59059].com.plexapp.plexmediaserver[796] 18:46:40.301275: com.plexapp.plugins.abc : (Framework) Received gzipped response from [http://browse.deviantart.com/photography/still/figures/](http://browse.deviantart.com/photography/still/figures/)  
  
2/2/11 6:46:40 PM [0x0-0x59059].com.plexapp.plexmediaserver[796] 18:46:40.672758: com.plexapp.plugins.abc : (Framework) Received gzipped response from [http://backend.deviantart.com/rss.xml?q=boost%3Apopular+in%3Aphotography%2Fstill%2Ffigures+max\_age%3A8h&type=deviation&offset=0](http://backend.deviantart.com/rss.xml?q=boost%3Apopular+in%3Aphotography%2Fstill%2Ffigures+max_age%3A8h&type=deviation&offset=0)  
  
2/2/11 6:46:40 PM [0x0-0x59059].com.plexapp.plexmediaserver[796] 18:46:40.678490: com.plexapp.plugins.abc : (Framework) Response OK  
  
2/2/11 6:46:43 PM [0x0-0x59059].com.plexapp.plexmediaserver[796] 18:46:43.408271: com.plexapp.plugins.abc : (Framework) Saved shared HTTP data  
  
  
  
  
  
and my code says the following:

```auto

####################################################################################################<br />
def ItemPage3(sender, pageUrl):<br />
    dir = MediaContainer(title2=sender.itemTitle)<br />
    Log("Success!")<br />
    pageUrl= pageUrl<br />
    dir = MediaContainer(mediaType='items') <br />
    content = XML.ElementFromURL(pageUrl, isHTML=True)<br />
    image = 0<br />
    for item in content.xpath('//link[@type="application/rss+xml"]'):<br />
      rssfeed=item.get('href')<br />
      content2=XML.ElementFromURL(rssfeed,isHTML=False)<br />
    return dir<br />

```

  
  
you think it might be "impressive" for a first day of writing, but to be honest, i didn't write any of this. it's just copy pasting stuff together from different other plugins. i still have no idea what dir = MediaContainer(title2=sender.itemTitle) means. or even what XML is. BUT i did manage (with LOTS of help by harley) to "write" a working menu…

---

<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 2, 2011, 5:56pm UTC](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638/47 "2011-02-02T17:56:14Z")

</div>

You are doing really well!  
  
  
  
FYI, here is a plugin I wrote that uses RSS:  
  
[https://github.com/dbl-a/NickJr.bundle/blob/master/Contents/Code/ **init**.py](https://github.com/dbl-a/NickJr.bundle/blob/master/Contents/Code/ __init__.py)  
  
[size=2][size=“3”][color="#000000"][size=3]  
  
[/size][/size][/color][/size]

---

<div class="post-metadata">

**Author:** ![hrcolb0](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/hrcolb0/32/380_2.png) [@hrcolb0](https://forums.plex.tv/u/hrcolb0)\
**Post date:** [February 2, 2011, 6:08pm UTC](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638/48 "2011-02-02T18:08:41Z")

</div>

> [@](#):
>
> for now, my console says this:  
>   
> 2/2/11 6:46:39 PM [0x0-0x59059].com.plexapp.plexmediaserver[796] 18:46:39.328769: com.plexapp.plugins.abc : Success!  
> 2/2/11 6:46:40 PM [0x0-0x59059].com.plexapp.plexmediaserver[796] 18:46:40.301275: com.plexapp.plugins.abc : (Framework) Received gzipped response from http://browse.deviantart.com/photography/still/figures/  
> 2/2/11 6:46:40 PM [0x0-0x59059].com.plexapp.plexmediaserver[796] 18:46:40.672758: com.plexapp.plugins.abc : (Framework) Received gzipped response from http://backend.deviantart.com/rss.xml?q=boost%3Apopular+in%3Aphotography%2Fstill%2Ffigures+max\_age%3A8h&type=deviation&offset=0  
> 2/2/11 6:46:40 PM [0x0-0x59059].com.plexapp.plexmediaserver[796] 18:46:40.678490: com.plexapp.plugins.abc : (Framework) Response OK  
> 2/2/11 6:46:43 PM [0x0-0x59059].com.plexapp.plexmediaserver[796] 18:46:43.408271: com.plexapp.plugins.abc : (Framework) Saved shared HTTP data  
>   
>   
> and my code says the following:  
>   
> 
> ```auto
> 
> ####################################################################################################<br />
> def ItemPage3(sender, pageUrl):<br />
> dir = MediaContainer(title2=sender.itemTitle)<br />
> Log("Success!")<br />
> pageUrl= pageUrl<br />
> dir = MediaContainer(mediaType='items') <br />
> content = XML.ElementFromURL(pageUrl, isHTML=True)<br />
> image = 0<br />
> for item in content.xpath('//link[@type="application/rss+xml"]'):<br />
> rssfeed=item.get('href')<br />
> content2=XML.ElementFromURL(rssfeed,isHTML=False)<br />
> return dir<br />
> 
> ```
> 
>   
>   
> you think it might be "impressive" for a first day of writing, but to be honest, i didn't write any of this. it's just copy pasting stuff together from different other plugins. i still have no idea what dir = MediaContainer(title2=sender.itemTitle) means. or even what XML is. BUT i did manage (with LOTS of help by harley) to "write" a working menu…

  
  
I also don't know what mediacpntainer can really do beside put a title I want at the top of a list. That's all I know of it. I've still been able to do what j want by copying a ton of code and logging items to see if I am doing this right. That's programming, at least from my end. Don't underestimate what you've done. You are more than halfway done in what 4 hours. Took me 2 weeks for my first plugin.

---

<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 2, 2011, 6:47pm UTC](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638/49 "2011-02-02T18:47:49Z")

</div>

A media container is what it’s name says - a container (data structure) for media that the PMS framework knows what to do with. Your job as a plugin writer is to populate those media containers. Consider navigation through the application like a tree with the actual media elements (videos, pictures, etc) as the final leafs, and the intermedidate branch points are DirectoryItem. If you add a DirectoryItem to a media container you create another branch in that tree (a subdirectory sort of). If you add a VideoItem, for example, you’ll get the end leaf.  
  
  
  
So, in your example you don’t actually add anything to the media container, that’s why it’s blank. It looks like in your loop you need to add a DirectoryItem with the title, thumb etc. extracted as values from item, much the same way you extract the rss URL. The directory item itself will delegate to a Function (like you already did at the top level menu) and you’ll pass the rssfeed value as a parameter to that function. The function itself will then parse that feed and extract out the actual media items and add them to the media container created and returned by the function.  
  
  
  
Jonny

> [@](#):
>
> ```auto
> 
> ####################################################################################################<br />
> def ItemPage3(sender, pageUrl):<br />
> dir = MediaContainer(title2=sender.itemTitle)<br />
> Log("Success!")<br />
> pageUrl= pageUrl<br />
> dir = MediaContainer(mediaType='items') <br />
> content = XML.ElementFromURL(pageUrl, isHTML=True)<br />
> image = 0<br />
> for item in content.xpath('//link[@type="application/rss+xml"]'):<br />
> rssfeed=item.get('href')<br />
> content2=XML.ElementFromURL(rssfeed,isHTML=False)<br />
> return dir<br />
> 
> ```
> 
>   
>   
> you think it might be "impressive" for a first day of writing, but to be honest, i didn't write any of this. it's just copy pasting stuff together from different other plugins. i still have no idea what dir = MediaContainer(title2=sender.itemTitle) means. or even what XML is. BUT i did manage (with LOTS of help by harley) to "write" a working menu…

---

<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 2, 2011, 6:53pm UTC](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638/50 "2011-02-02T18:53:42Z")

</div>

xpath is a language for specifying places in an XML file, which is a tree structure. Start with the simple syntax:

```auto

/tag

```

- will get all nodes named tag at the root of the tree  

```auto

//tag

```

- will get all nodes named tag anywhere in the tree  

```auto

//tag//free

```

- will find all nodes named free that occur anywhere under nodes named tag, also anywhere in the tree  
  
  
  
The

```auto

//link[@type="application/rss+xml"]

```

syntax is a predicate language that allows you the further select the nodes returned. This one says within nodes with tag called link only pick those with an attribute type with the specific value of application/rss+xml.  
  
  
  
This is the xpath you’ll use 90% of the time. The rest you can learn later 🙂  
  
  
  
Jonny

> [@](#):
>
> there book feel like advanced grammar explanations to someone who just learned to say "good morning". :S they look like great tutorials, but no way i'll find a way through there.  
> i need it explained in common language rather than   
> "child::chapter/descendant::para selects the para element descendants of the chapter element children of the context node"

---

<div class="post-metadata">

**Author:** ![MTI](https://avatars.discourse-cdn.com/v4/letter/m/fbc32d/32.png) [@MTI](https://forums.plex.tv/u/MTI)\
**Post date:** [February 2, 2011, 7:30pm UTC](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638/51 "2011-02-02T19:30:12Z")

</div>

> [@](#):
>
> It's not that hard, and if you get stuck people will help. They are just more inclined to help if you actually try first rather than just saying 'can you do it for me please'. Just look at the recent thread by MTI in this forum for a great example of just that.

  

> [@](#):
>
> i know, and i agree with you. but between having to move to a different flat, writing a masters thesis on lupus (do you watch House?), and soon entering my 5th year of medical studies, also having to cook, sleep, [...]  
> to MTI and all of you, enjoy & thanks!

  

> [@](#):
>
> Like Jonny said, I started out knowing nothing. I only had a couple of programming classes in high school & college. (Pascal and C+)

  
Well, well, well, just stumbled upon this... Nice to see my name referenced, so I'll return the favor by again acknowledging the great help Jonny and Dbl\_A provided me (I might ask for more as I continue learning and expanding my skills ;)  
  
But I feel your pain, Pooploser: I'm a rheumatologist myself. Defended my PhD just when Plex 9 came out and now I'm well into my postdoctoral fellowship. Wife, 1 year old son and house to "maintain" as well ;)  
But this is actually fun and so I tend to find the time to do it in between all the other duties... How? Well, right now for example, I'm down with the flu (or something equally annoying) :P I guess this is just life: There's SO much exiting stuff to do, and if you have the continued motivation you'll accomplish all/most of what you desire eventually ;)  
  
Happy coding!

---

<div class="post-metadata">

**Author:** ![pooploser](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/pooploser/32/133851_2.png) [@pooploser](https://forums.plex.tv/u/pooploser)\
**Post date:** [February 2, 2011, 7:45pm UTC](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638/52 "2011-02-02T19:45:28Z")

</div>

so jonny, you think i should add a mediaType=‘picture’ to the MediaContainer?  
  
thanks very much for those explanations, they help a lot.  
  
and then i have to make it take the info & pic from the RSS. i don’t know which the commands are here though.  
  
writing  
  
  
  
for item in content.xpath(’//link[@type=“application/rss+xml”]’):  
  
rssfeed=item.get(‘href’)  
  
  
  
will make it find the right rss url. but this is where i am stuck. making it display the images from the rssfeed.   
  
most plugins working with RSS have a “RSS\_FEED=” at the top, but i am not sure how to use that in my case, as every subcategory will have its own rss url, i can’t make them all reference the one on top.   
  
it must be something very easy, to make it read the description & pictures from the rss feeds, but i don’t know what i have to write to make it do that.  
  
thanks very much to everyone and i can only fully agree to what MTI wrote 🙂

---

<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 2, 2011, 8:01pm UTC](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638/53 "2011-02-02T20:01:01Z")

</div>

That just controls the way the media is displayed on the screen. Look at another picture plugin to see what they use.

> [@](#):
>
> so jonny, you think i should add a mediaType='picture' to the MediaContainer?

  
  
So, here you are parsing a top level category and these rssfeeds contain the actual pictures, correct? So your navigation would be Category -\> Subcategory -\> Actual Picutre? Read what I said about the tree, branches etc. above. For each item in this loop you will need to add a DirectoryItem to the MediaContainer. That creates the sub-category branch. You do this the same way you did for the top level branch except the function is refers to will be responsible for parsing the rss feed. You pass the rss feed URL extracted from your category loop as a parameter to that function. In that function you loop through the rss entries and add PhotoItem objects to the media container.  
  
There are many, many examples of plugins doing this, since that's the basic way they are all written.  
  
Jonny  
  

> [@](#):
>
> thanks very much for those explanations, they help a lot.  
> and then i have to make it take the info & pic from the RSS. i don't know which the commands are here though.  
> writing  
>   
> for item in content.xpath('//link[@type="application/rss+xml"]'):  
> rssfeed=item.get('href')  
>   
> will make it find the right rss url. but this is where i am stuck. making it display the images from the rssfeed.   
> most plugins working with RSS have a "RSS\_FEED=" at the top, but i am not sure how to use that in my case, as every subcategory will have its own rss url, i can't make them all reference the one on top.   
> it must be something very easy, to make it read the description & pictures from the rss feeds, but i don't know what i have to write to make it do that.  
> thanks very much to everyone and i can only fully agree to what MTI wrote :)

---

<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 2, 2011, 8:08pm UTC](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638/54 "2011-02-02T20:08:14Z")

</div>

> [@](#):
>
> so jonny, you think i should add a mediaType='picture' to the MediaContainer?  
> thanks very much for those explanations, they help a lot.  
> and then i have to make it take the info & pic from the RSS. i don't know which the commands are here though.  
> writing  
>   
> for item in content.xpath('//link[@type="application/rss+xml"]'):  
> rssfeed=item.get('href')  
>   
> will make it find the right rss url. but this is where i am stuck. making it display the images from the rssfeed.   
> most plugins working with RSS have a "RSS\_FEED=" at the top, but i am not sure how to use that in my case, as every subcategory will have its own rss url, i can't make them all reference the one on top.   
> it must be something very easy, to make it read the description & pictures from the rss feeds, but i don't know what i have to write to make it do that.  
> thanks very much to everyone and i can only fully agree to what MTI wrote :)

  
  
You make it reference the "rssfeed" that you set in your above code.  
  
The RSS\_FEED at the top are just constants for the plugin (they don't change). Whereas, your variable "rssfeed" takes on different values.  
  
you are using this line of code elsewhere in your plug:  

```auto

dir.Append(Function(DirectoryItem(ItemPage3, title), pageUrl = titleUrl))

```

  
This line basically tells Plex to "Append" a "DirectoryItem" named "title" on the menu. (the rest says: "when this menu item is selected, run the ItemPage3 function and pass it the value of pageUrl, which in this case is titleUrl.")  
  
follow?

---

<div class="post-metadata">

**Author:** ![pooploser](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/pooploser/32/133851_2.png) [@pooploser](https://forums.plex.tv/u/pooploser)\
**Post date:** [February 2, 2011, 8:50pm UTC](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638/55 "2011-02-02T20:50:18Z")

</div>

yap, i follow. gracias amigo 🙂   
  
what are the words to make it get the title & the picture from the rss page? and where would i put those two?  
  
in that line i wrote above it finds the correct link as we know, where and what exactly do i write to get the pictures visible inside the plugin?  
  
oh and jonny…i’m trying to look at all the other plugins but so far none of them uses the rss reference the same way i’m intending, or at least i can’t see it…  
  
however as a how-to tutorial they are great to look at 🙂

---

<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 2, 2011, 9:21pm UTC](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638/56 "2011-02-02T21:21:40Z")

</div>

Look at the RssFeedItems function starting on line 318 of the feed-me plugin. It shows how to parse an rss feed whose URL is passed in as a parameter and add the enclosed media items to the media container. It even has a case for PhotoItems. Note that the specific properties you extract may have different names in your feed as photo rss feeds aren’t as standardized as audio and video feeds.  
  
  
  
Jonny

> [@](#):
>
> yap, i follow. gracias amigo :)   
> what are the words to make it get the title & the picture from the rss page? and where would i put those two?  
> in that line i wrote above it finds the correct link as we know, where and what exactly do i write to get the pictures visible inside the plugin?  
> oh and jonny…i'm trying to look at all the other plugins but so far none of them uses the rss reference the same way i'm intending, or at least i can't see it....  
> however as a how-to tutorial they are great to look at :)

---

<div class="post-metadata">

**Author:** ![pooploser](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/pooploser/32/133851_2.png) [@pooploser](https://forums.plex.tv/u/pooploser)\
**Post date:** [February 2, 2011, 10:10pm UTC](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638/57 "2011-02-02T22:10:33Z")

</div>

i’m trying to use this now:  
  
  
  
dir.Append(PhotoItem(media, title=title, subtitle=subtitle, summary=description, thumb=media))  
  
  
  
but console gives me this answer:  
  
2/2/11 11:08:19 PM [0x0-0x59059].com.plexapp.plexmediaserver[796] Traceback (most recent call last):  
  
2/2/11 11:08:19 PM [0x0-0x59059].com.plexapp.plexmediaserver[796] File “/Users/Milos/Library/Application Support/Plex Media Server/Plug-ins/Framework.bundle/Contents/Resources/Versions/1/Python/bootstrap.py”, line 45, in   
  
2/2/11 11:08:19 PM [0x0-0x59059].com.plexapp.plexmediaserver[796] if len(sys.argv) \>= 2: PMS.Plugin.\_\_run(sys.argv[-1])  
  
2/2/11 11:08:19 PM [0x0-0x59059].com.plexapp.plexmediaserver[796] File “/Users/Milos/Library/Application Support/Plex Media Server/Plug-ins/Framework.bundle/Contents/Resources/Versions/1/Python/PMS/Plugin.py”, line 309, in \_\_run  
  
2/2/11 11:08:19 PM [0x0-0x59059].com.plexapp.plexmediaserver[796] import Code as \_plugin  
  
2/2/11 11:08:19 PM [0x0-0x59059].com.plexapp.plexmediaserver[796] File “/Users/Milos/Library/Application Support/Plex Media Server/Plug-ins/ABC (US).bundle/Contents/Code/ **init**.py”, line 90  
  
2/2/11 11:08:19 PM [0x0-0x59059].com.plexapp.plexmediaserver[796] dir.Append(PhotoItem(media, title=title, subtitle=subtitle, summary=description, thumb=media))  
  
  
  
(i used the ABC bundle and edited from there)

---

<div class="post-metadata">

**Author:** ![pooploser](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/pooploser/32/133851_2.png) [@pooploser](https://forums.plex.tv/u/pooploser)\
**Post date:** [February 2, 2011, 10:49pm UTC](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638/58 "2011-02-02T22:49:49Z")

</div>

the FULL code so far:

```auto

# PMS plugin framework<br />
import re, string, datetime<br />
from PMS import *<br />
<br />
##################################################################################################ABC<br />
PLUGIN_PREFIX = "/photos/deviantart"<br />
<br />
DEVIANTART_URL = "http://www.deviantart.com/"<br />
DEVIANTART_CATEGORIES = "http://www.deviantart.com"<br />
<br />
FEED = "feed"<br />
DEBUG = False<br />
abcart ="art-default.png"<br />
abcthumb ="icon-default.png"<br />
<br />
####################################################################################################<br />
<br />
def Start():<br />
  Plugin.AddPrefixHandler(PLUGIN_PREFIX, MainMenu, "Deviant Art","icon-default.jpg", "art-default.jpg")<br />
  Plugin.AddViewGroup("InfoList", viewMode="InfoList", mediaType="items")<br />
  <br />
  MediaContainer.art =R(abcart)<br />
  DirectoryItem.thumb =R(abcthumb)<br />
<br />
####################################################################################################<br />
#def MainMenu():<br />
# dir = MediaContainer(mediaType='items') <br />
# dir.Append(Function(DirectoryItem(all_shows, "Categories"), pageUrl = DEVIANTART_CATEGORIES))<br />
# return dir<br />
    <br />
####################################################################################################<br />
def MainMenu():<br />
    pageUrl= DEVIANTART_CATEGORIES<br />
    dir = MediaContainer(mediaType='items')<br />
    content = XML.ElementFromURL(pageUrl, True)<br />
    Log(content.xpath('//div[@class="sliding-menu "]/ul/li/ul/li/a'))<br />
    for item in content.xpath('//div[@class="sliding-menu "]/ul/li/ul/li/a'):<br />
        Log(item)<br />
        title=item.text <br />
        titleUrl = item.get('href') <br />
<br />
        Log(title)<br />
        Log(titleUrl)<br />
        dir.Append(Function(DirectoryItem(ItemPage, title), pageUrl = titleUrl))<br />
    return dir<br />
####################################################################################################<br />
def ItemPage(sender, pageUrl):<br />
    dir = MediaContainer(title2=sender.itemTitle)<br />
    Log("Success!")<br />
    pageUrl= pageUrl<br />
    dir = MediaContainer(mediaType='items')<br />
    content = XML.ElementFromURL(pageUrl, True)<br />
    Log(content.xpath('//div[@class="sliding-menu "]/ul/li/ul/li/a'))<br />
    for item in content.xpath('//div[@class="sliding-menu "]/ul/li/ul/li/a'):<br />
        Log(item)<br />
        title=item.text <br />
        titleUrl = item.get('href') <br />
<br />
        Log(title)<br />
        Log(titleUrl)<br />
        dir.Append(Function(DirectoryItem(ItemPage2, title), pageUrl = titleUrl))<br />
    return dir<br />
####################################################################################################<br />
def ItemPage2(sender, pageUrl):<br />
    dir = MediaContainer(title2=sender.itemTitle)<br />
    Log("Success!")<br />
    pageUrl= pageUrl<br />
    dir = MediaContainer(mediaType='items')<br />
    content = XML.ElementFromURL(pageUrl, True)<br />
    Log(content.xpath('//div[@class="sliding-menu "]/ul/li/ul/li/a'))<br />
    for item in content.xpath('//div[@class="sliding-menu "]/ul/li/ul/li/a'):<br />
        Log(item)<br />
        title=item.text <br />
        titleUrl = item.get('href') <br />
<br />
        Log(title)<br />
        Log(titleUrl)<br />
        dir.Append(Function(DirectoryItem(RssFeedItems, title), pageUrl = titleUrl))<br />
    return dir<br />
####################################################################################################<br />
def RssFeedItems(sender, pageUrl):<br />
    dir = MediaContainer(title2=sender.itemTitle)<br />
    Log("Success!")<br />
    pageUrl= pageUrl<br />
    dir = MediaContainer(mediaType='items') <br />
    content = XML.ElementFromURL(pageUrl, isHTML=True)<br />
    image = 0<br />
    for item in content.xpath('//link[@type="application/rss+xml"]'):<br />
	  rssfeed = item.get('href')<br />
	  dir.Append(PhotoItem(rssfeed, title, subtitle=subtitle, summary=description, thumb=media))<br />
    return dir<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 2, 2011, 11:04pm UTC](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638/59 "2011-02-02T23:04:38Z")

</div>

Not sure how many levels there are in your hierarchy but the final level should be something like this. The exact xpath predicates and XML attribute names will depend on your specific feed.

```auto

<br />
####################################################################################################<br />
def ItemPage2(sender, pageUrl):<br />
    dir = MediaContainer(title2=sender.itemTitle)<br />
    Log("Success!")<br />
    dir = MediaContainer(mediaType='items')<br />
    content = XML.ElementFromURL(pageUrl, True)<br />
    Log(content.xpath('//div[@class="sliding-menu "]/ul/li/ul/li/a'))<br />
    for item in content.xpath('//link[@type="application/rss+xml"]'):<br />
        rssfeed = item.get('href')<br />
        title = item.get('title')<br />
        dir.Append(Function(DirectoryItem(RssFeedItems, title), pageUrl = rssfeed ))<br />
    return dir<br />
####################################################################################################<br />
def RssFeedItems(sender, pageUrl):<br />
    dir = MediaContainer(title2=sender.itemTitle)<br />
    Log("Success!")<br />
    pageUrl= pageUrl<br />
    dir = MediaContainer(mediaType='items') <br />
    content = XML.ElementFromURL(pageUrl)<br />
    for item in content.xpath('//item'):<br />
          title = item.get('title')<br />
          description= item.get('description')<br />
          subtitle= item.get('subtitle')<br />
          photoUrl= item.get('photoUrl')<br />
          dir.Append(PhotoItem(photoUrl, title, subtitle=subtitle, summary=description))<br />
    return dir<br />

```

---

<div class="post-metadata">

**Author:** ![pooploser](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/pooploser/32/133851_2.png) [@pooploser](https://forums.plex.tv/u/pooploser)\
**Post date:** [February 2, 2011, 11:12pm UTC](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638/60 "2011-02-02T23:12:18Z")

</div>

that gives me:  
  
2/3/11 12:08:02 AM [0x0-0x16d16d].com.plexapp.plexmediaserver[4075] title = item.get(‘title’)  
  
2/3/11 12:08:02 AM [0x0-0x16d16d].com.plexapp.plexmediaserver[4075] ^  
  
2/3/11 12:08:02 AM [0x0-0x16d16d].com.plexapp.plexmediaserver[4075] IndentationError: unexpected indent

[Previous page](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638.md?page=2)

[Next page](https://forums.plex.tv/t/need-basic-help-with-plugin-writing/7638.md?page=4)
