need basic help with plugin writing

ok i’m gettings somewhere, mostly thanks to you guys!

i managed to write the search function all by my self and it’s working :slight_smile: (hear that, jonny? :stuck_out_tongue: )



however, one little question.



first here’s the code:



# Search and extract tag based results<br />
def Search(sender, query):<br />
  dir = MediaContainer(title2=sender.itemTitle)<br />
  pageUrl = SEARCH_URL % query<br />
  content1=XML.ElementFromURL(pageUrl, isHTML="True")<br />
  Log(pageUrl)<br />
  for item in content1.xpath('//link[@type="application/rss+xml"]'): <br />
    	rssfeed=item.get('href') <br />
	Log("rssfeed")<br />
	content = XML.ElementFromURL(rssfeed, isHTML="False") <br />
    	for item in content.xpath('//item'):<br />
		title = item.xpath('.//title', namespaces=NAMESPACES)[0].text<br />
        	Log(title)<br />
		thumb = item.xpath('./content', namespaces=NAMESPACES)[0].get('url')<br />
		dir.Append(PhotoItem(thumb, title=title, thumb=thumb))<br />
  return dir<br />




SEARCH_URL = "http://browse.deviantart.com/?qh=&section=&q=%s"

… so far search works perfectly, however, it only searches using the first word entered as a search query.
for example the search term: 'large tree' will only be searched as 'large'
search url example in this case from the log:
http://browse.deviantart.com/?qh=&section=&q=large tree instead of http://browse.deviantart.com/?qh=&section=&q=large+tree

EDIT: fixed this by adding: (String.Quote(query, usePlus=True))

well i sorted out thumbs, and also the search function except for that little bug seen up there.



will i need the API to be able to log in?

or is there another way?





also i wanna try and make subcategory search.

it should be very easy, i just couldn’t find the right word to write in there.

i wanna do the following:



# Search specific Subcategory<br />
def SearchSection(sender, query, pageUrl):<br />
  dir = MediaContainer(title2=sender.itemTitle)<br />
  pageUrl = pageUrl % query<br />
  Log(pageUrl)<br />
  content1=XML.ElementFromURL(pageUrl, isHTML="True")<br />
  Log(pageUrl)<br />
  for item in content1.xpath('//link[@type="application/rss+xml"]'): <br />
    	rssfeed=item.get('href') <br />
	Log("rssfeed")<br />
	content = XML.ElementFromURL(rssfeed, isHTML="False") <br />
    	for item in content.xpath('//item'):<br />
		title = item.xpath('.//title', namespaces=NAMESPACES)[0].text<br />
        	Log(title)<br />
		thumb = item.xpath('./content', namespaces=NAMESPACES)[0].get('url')<br />
		dir.Append(PhotoItem(thumb, title=title, thumb=thumb))<br />
  return dir<br />




it's basically the SAME as the normal search, except, here, the following needs to be added to the pageUrl. this will display the url with the pictures containing the search term.
?q=%s
and then the query of course would be the %.
when wanting to search the term "flower" in photography, nature, underwater, the resulting website would be f.ex.
http://browse.deviantart.com/photography/nature/underwater/?q=flower
opening that url shows you pictures of underwater flora.
i think you are getting what i mean. instead of having pageurl = pageurl % query, it has to be something like
pageurl = pageurl?q=%s % query
that however doesn't work, and i don't know how to make it work.


To add something to your pageurl variable, which is a string, I find the best thing to do is add a quoted string like this:

pageurl = pageurl + "?q=%s" % query


There are other ways to do it too

pageurl = pageurl + "?q=" + query


should accomplish the same thing. There are probably more too.

It's really great to see your progress. It was only a few months ago that I was in your position. I'm sure Sander and Harley will confirm that I was constantly hanging out in the chat looking for help. I'm still no pro, but it does get easier the more you do :) Keep up the good work.

thanks for the hint. looks good.

but something’s not right.

it wont accept the pageUrl from the subcategories: TypeError: SearchSection() takes exactly 3 non-keyword arguments (2 given)

nevermind, got it to work :smiley:



i’ll upload the new version :smiley: thanks!!

To get your new plugin in the store you need to create a ticket on Lighthouse. The best thing to do is to create an account for yourself on Github and create a repository there for your plugin. That will probably seem pretty daunting at first (it did for me), but there’s a pretty good tutorial on the website. I say that’s the best way because then Sander, or anyone else can easily access the code for review, changes, etc. It’s designed to make version control and integrating changes very simple. If you want to create your Lighthouse ticket before you get yourself setup on Github create a zip archive of your plugin bundle and attache it to the ticket. There’s several good examples of what info to include in the ticket. Apparently the ‘Milestone’ should be set to ‘Appstore Review’ but, I think only certain people have access to set the milestone. So make sure to include something in the ticket title (and/or tags) to indicate that you’re submitting a new plugin.



Thanks to a large number of new plugins, as well as bug fixes etc., there seems to be a backlog of new plugins waiting approval. Don’t be suprised if it takes a while for your plugin to get approved. In the meantime, it might be a good idea to make a page for it on the unsupported plugins page in the wiki. That way there are several ways for people to find it.

cool. thanks!

i might consider the github way.

however one question before that:

as i wrote in the release info in my plugin’s thread under media server plugins, nudity can appear in the plugin images.

nothing pornographic, but artistic nudity such as drawings, or posed photography, all in an artistic way. as it is an art images website, nudity is accepted.

i see the policy states “no +18 plugins”, however i think they mean pornography (such as the redtube plugin).

in netflix plugins you can access movies that are rated R/18, and in the picasa plugin there’s nudity too.

so what do you think? i don’t wanna go through the whole fuss making my github page only for them to say “there’s nudity, we won’t allow it”.

i know america is prude when it comes to nudity, even in a non-sexual way, and it wouldn’t surprise me that the devs would decide against it.

(i’m not saying the devs would be prude, don’t get me wrong, but they might not make fans by making it accessible).

I can’t say whether or not it would be approved. I will say that if you plan on maintaining/updating/upgrading the plugin and/or creating more plugins, it will be worth your while to take the time to get slightly familiar with git. I wasn’t sold on it at first, but even for unsupported plugins, it’s a great way for others to contribute to your plugin. On several occasions and different plugins, I’ve had help from one or more individuals who forked my repository made some improvements and then sent me a pull request.

ok. :slight_smile: i’ll try that next week.

now that the deviantart plugin is done, and i’m full of optimism and euphoria, i’m writing another plugin for euronews no comment, which is a very unique style of on-location video journalism without commentary.

there will one be one menu, listing the 25 most recent no comment reports videos, which you can select to play.

how do i find the NAMESPACE for feedburner?

here’s my code:



## PMS plugin framework<br />
import re, string, datetime<br />
from PMS import *<br />
<br />
PLUGIN_PREFIX   = "/video/euronews"<br />
<br />
RSS_FEED        = "http://feeds.feedburner.com/Euronews-NoComment"<br />
euroart                      = "art-default.png"<br />
eurothumb                    = "icon-default.png"<br />
NAMESPACES = {'xmlns:itunes'="http://www.itunes.com/DTDs/Podcast-1.0.dtd" 'xmlns:media'="http://search.yahoo.com/mrss/" 'xmlns:feedburner'="http://rssnamespace.org/feedburner/ext/1.0"}<br />
<br />
####################################################################################################<br />
<br />
def Start():<br />
   Plugin.AddPrefixHandler(PLUGIN_PREFIX, MainMenu, "euronews: No Comment", "icon-default.jpg", "art-default.jpg")<br />
   Plugin.AddViewGroup("InfoList", viewMode="InfoList", mediaType="videos")<br />
  <br />
   MediaContainer.art        =R(euroart)<br />
   DirectoryItem.thumb       =R(eurothumb)<br />
<br />
<br />
####################################################################################################<br />
def MainMenu():<br />
    pageUrl= RSS_FEED<br />
    dir = MediaContainer(mediaType='video')<br />
    content = XML.ElementFromURL(pageUrl, isHTML="False")<br />
    Log("Success!")<br />
    for item in content.xpath('//div[@class="apple-rss-article-head"]'):<br />
	title=item.xpath('//div[@class="apple-rss-summary"]', namespaces=NAMESPACES).text<br />
        subtitle= item.xpath('//div[@class="apple-rss-subject"]', namespaces=NAMESPACES).text<br />
	Log("Success!")<br />
	Log(subtitle)<br />
	vidUrl = item.xpath('//div[@class="apple-rss-subject"]/a', namespaces=NAMESPACES).get('href') <br />
        dir.Append(VideoItem(vidUrl, title=title, subtitle=subtitle, duration=duration, summary=summary))<br />
	return dir<br />
#########################################<br />
<br />




the namespaces are in the header of the XML source:

<rss xmlns:itunes="http://www.itunes.com/DTDs/Podcast-1.0.dtd" xmlns:media="http://search.yahoo.com/mrss/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0"

thanks. i updated the code in the post above. is that how you’re meant to write in the namespaces?

Not quite. The format is Python’s way of defining a dict, (or hash map, associative array) and you don’t need the xmlns: in the key.



<br />
<br />
NAMESPACES = {'itunes':"http://www.itunes.com/DTDs/Podcast-1.0.dtd", 'media':"http://search.yahoo.com/mrss/", 'feedburner':"http://rssnamespace.org/feedburner/ext/1.0"}<br />




Notice the : not = and you missed commas between entries.

edit: nevermind, managed to get login to work myself :smiley:



another question.

i want to use a URL, where one part will be the username stored under Prefs.Get(“Username”)

like this.

http://%s.deviantart.com/favourites where as the %s should be the username.

how do i add that to the prefixes?

i have this so far:

FAVOURITES_URL = “http://%s.deviantart.com/favourites


Hey!
This looks like the login from Vimeo. It could be that you don't need any login token. Also, you're writing a plugin for the v1 of the framework, whereas the Prefs[] notation is v2.

**v1**

def Login():<br />
  values = {<br />
    'username' : Prefs.Get('username'),<br />
    'password' : Prefs.Get('password')<br />
  }<br />
<br />
  x = HTTP.Request('https://www.deviantart.com/users/login', values)<br />




**v2**

def Login():<br />
  values = {<br />
    'username' : Prefs['username'],<br />
    'password' : Prefs['password']<br />
  }<br />
<br />
  x = HTTP.Request('https://www.deviantart.com/users/login', values).content<br />


i made it work already before your post but thanks lots anyways! :slight_smile: check my updated post above for a new problem.



First check if the user has set a username (and password) in preferences, then you can build the url like so:

fav_url = FAVOURITES_URL % Prefs.Get("Username")

excellent! :slight_smile: thank you!

EDIT:

found it out myself. :slight_smile:

did you remember our “div” discussion from the other day?

yup! :slight_smile: that was a typo. i fixed it right after :slight_smile:

i am getting really somewhere with this. you’ll be surprised to see :smiley:



i have one last question to dump before i can complete it though:



  for item in content.xpath('//td[contains(@id,"large_groupid_")]'):<br />
    Log(item)<br />
    title = item.xpath('./a/img')[0].get('title')<br />
    Log(title)<br />
    thumb = XXXXXXXXX<br />
    url = item.xpath('./a')[0].get('href')<br />
    Log(url)<br />
    dir.Append(Function(DirectoryItem(PTPTorrent, title=title, thumb=thumb), thumb=thumb, url=url))<br />
  return dir<br />




i want to add a completely different xpath for where the XXXXXX is. it's not within the //td[contains(@id,"large_groupid_")]'
how do i write that? just write a random example. :)

for item in content.xpath('//td[contains(@id,"large_groupid_")]'):<br />
  Log(item)<br />
  title = item.xpath('./a/img')[0].get('title')<br />
  Log(title)<br />
  thumb = content.xpath('//your code here')<br />
  url = item.xpath('./a')[0].get('href')<br />
  Log(url)<br />
  dir.Append(Function(DirectoryItem(PTPTorrent, title=title, thumb=thumb), thumb=thumb, url=url))<br />
return dir