Skip to content
This repository has been archived by the owner on Oct 26, 2024. It is now read-only.

Plugin development #2

Open
reallistic opened this issue Aug 8, 2013 · 2 comments
Open

Plugin development #2

reallistic opened this issue Aug 8, 2013 · 2 comments

Comments

@reallistic
Copy link

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
Copy link
Owner

lad1337 commented Aug 8, 2013

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

  • searchForElement(self, term='')
  • getElement(self, id, element=None)

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

  • mediatype is the mediatype db object
  • fakeroot is the root we created with the term
  • artistElement.type needs to be "Artist" (thats defined by the MediaTypeManager)
  • you need to use .setField() on the artistElement to set any information because you also need to set the so called tag -> self.tag see below
  • use .saveTemp() to save the object don't use save()
  • in this case the "id" and "name" are the same because its from the discogs provider and i don't have a proper id for the artist

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
Copy link
Author

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']

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants