lad1337 / XDM-main-plugin-repo

The official main Plugin Repository
19 stars 11 forks source link

Plugin development #2

Open reallistic opened 11 years ago

reallistic commented 11 years ago

Hello, I would like to create a last.fm provider plugin for music. I am a bit stuck though as I cannot seem to identify firstly the correct data structure and secondly how I should return it/where it should be stored. Can you provide further guidance?

lad1337 commented 11 years ago

i am happy to explain first of a Provider needs to replicate the structure of the MediaTypeManager this is for the music plugin (de.lad1337.music)

Root-+
     |
     +-- Artist 1 --+
                    |
                    + -- Album 1 -- +
                                    |
                                    + -- Song 1
                                    + -- Song 2
                                    + -- Song 3
etc

so your Provider needs to create object that are in this structure needs to implement two methods

first thing when the searchForElement() is called you should call

self.progress.reset()

used here https://github.com/lad1337/XDM-main-plugin-repo/blob/master/Discogs/Discogs.py#L52 this will reset the progress you see in the gui when something is searching.

searchForElement returns a Root Element you can get this root with (i'll call it fakeRoot)

mtm = common.PM.getMediaTypeManager('de.lad1337.music')[0]
fakeRoot = mtm.getFakeRoot(term)

where term is the search term, this is used on the search page to identify the old searches. it can be anything but best is to just use the term that you get from the call.

used here https://github.com/lad1337/XDM-main-plugin-repo/blob/master/Discogs/Discogs.py#L55

now you can call whatever it is that gets you information from last.fm how you go thru this information is upon you and how the data is structured.

to create object that represent the Artist, Albums and Songs you need a mediatype database object you can get this with

mediatype = MediaType.get(MediaType.identifier == 'de.lad1337.music')

this is needed to connect each object to the mediatype (it could be done by traversing back to the root but its just how it is for now)

to create actual objects according to the structure we first need an Artist

            artistElement = Element()
            artistElement.mediaType = mediaType
            artistElement.parent = fakeRoot
            artistElement.type = 'Artist'
            artistElement.setField('name', artistName, self.tag)
            artistElement.setField('id', artistName, self.tag)
            artistElement.saveTemp()

used here: https://github.com/lad1337/XDM-main-plugin-repo/blob/master/Discogs/Discogs.py#L94

the self.tag is an identifier string used to identify information to different providers on one Element is is defined on the class lvl as here https://github.com/lad1337/XDM-main-plugin-repo/blob/master/Discogs/Discogs.py#L32 well actually it is a property that is based on _tag combined with the instance name which is not added if its "default"

adding an album to the artist would then be

            albumElement = Element()
            albumElement.mediaType = mediaType
            albumElement.parent = artistElement
            albumElement.type = 'Album'
            albumElement.setField('name', release.title, self.tag)
            albumElement.setField('year', release.data['year'], self.tag)
            albumElement.setField('id', release.data['id'], self.tag)

note that the .parent is now the just created artistElement this created the tree, do the same with songs for the album

to know what the field names are have a look in the MediaTypeManager https://github.com/lad1337/XDM-main-plugin-repo/blob/master/Music/Music.py and the classes Song, Album and Artist you can however and whatever you want to the Element with the .setField() method and it will be saved. but probably nothing will use it Providers have to add the fields that are defined in the classes i mentioned.

at the end you

return fakeRoot

oh i forgot to mention if you have a total count of you albums (the thing the use wil see in the gui) set self.progress.total used here: https://github.com/lad1337/XDM-main-plugin-repo/blob/master/Discogs/Discogs.py#L75

and when you iterate over one of these use self.progress.addItem() used here https://github.com/lad1337/XDM-main-plugin-repo/blob/master/Discogs/Discogs.py#L78 this will update the loading bar accordingly during search

also start XDM with -D (for debug) and --dev (for development mode)

i am sure i forgot something... anyway i am happy to answer any question

reallistic commented 11 years ago

Thanks for the info. I was finally able to get this off the ground and hit a couple snags. 1) What type of data does discogs return? Json or xml? I ask this because I looked over your code and the Discogs api and it seems that it should be returning xml yet you are using a json decoder. When I run my code to pull xml I get a No json object error.

2) When is the id specified on line? https://github.com/rxsegrxup/XDM-rxse-repo/blob/master/LastFm/Lastfm.py#L56 The lastfm api pulls known albums by artist and/or album and even though it uses mbid's not all results have them.

3) Lastly, is there any direction you can give me on my json parsing? I'm having some difficulty generally understanding when I need to use data.get('nodename') vs data['nodename']