Anyone willing to collaborate on a Spotify Web API plugin?

Do you have questions about writing plugins or scripts in Python? Meet the coders here.
Post Reply
Septik
Posts: 37
Joined: Sun Feb 15, 2015 1:29 pm

Anyone willing to collaborate on a Spotify Web API plugin?

Post by Septik » Sat Oct 14, 2017 4:35 pm

A short while ago I was playing around with a Python script trying to add the currently playing song to a specific playlist in Spotify. I eventually finished the script, with some help from the community and specifically user yokel22. He kindly offered to collaborate on a more fleshed out plugin, and I accepted the offer. Since then I've started writing the plugin with occasional feedback from yokel22. He isn't "fully" available at the moment however, and I just I'd see if others were interested in helping us out.

The current __init__.py is attached in its current form. If you decide to try it out, you must do the following:
  1. Create a web application over at this page.
  2. Add "http://localhost:8025" to "Redirect URIs" on the same page.
  3. Make sure to activate the EventGhost Webserver plugin and set it up to use port 8025.*
  4. Copy the client ID and client secret from your application page. It will be used when configuring the plugin.
  5. Add the plugin and enter your client ID, client secret and Spotify username.
  6. (For now): Run the "Get initial access token" action.
*You can technically use another port, but then you have to change it in step 2 above as well as in the __init__ file since the port is hardcoded for now. I imagine that when the plugin is finished it'll either automatically check the Webserver port or use another method (OAuth2?) for receiving the access code from its api call.

After following the above steps, you should be able to use the "Add current song to playlist" action. You will have to feed it a playlist ID. If you right click any playlist and click Share > Copy Spotify URI, the ID will be the numbers after the last colon.

Right now I'm trying to make the process of retrieving access/refresh tokens more automatic. It'd also be cool if the plugin didn't have to rely on the Webserver plugin - at least not running on a specific port. After that, it'd be nice if the "Add current song to playlist" function was able to store playlists (preferably their names), and you could select them from a dropdown menu instead of manually getting the ID.

Theoretically, a plugin like this should be able to do pretty much anything the API allows. Moving forward we'll have to figure out what's practical and how to implement it all. This is my first time working on a plugin, so I could use some help/feedback.

Thanks for checking this out.

Edit: Forgot to mention: I've been saving this in plugins\SpotifyWebAPI. Not sure if the folder name matters.

Edit 2: I set up a GitHub repo but have no idea what I'm doing. Feel free to lecture me, I'll take no offense.
Attachments
__init__.py
version 0.1
(9.92 KiB) Downloaded 30 times
Last edited by Septik on Sun Oct 15, 2017 3:28 pm, edited 1 time in total.

User avatar
yokel22
Experienced User
Posts: 229
Joined: Thu Feb 05, 2015 5:56 pm
Location: U.S. - Kansas city

Re: Anyone willing to collaborate on a Spotify Web API plugin?

Post by yokel22 » Sun Oct 15, 2017 6:07 am

I cleaned up the config & fixed the self.variables. They weren't saving properly the way they were setup. Changed all instances of username to userName to fit rest of naming convention. I'm able to get the access token returned but it gives a 404 error on redirect. I didn't have time to delve into that or the threading yet.
spotify_response.jpg
Attachments
__init__.py
(10.63 KiB) Downloaded 27 times

Septik
Posts: 37
Joined: Sun Feb 15, 2015 1:29 pm

Re: Anyone willing to collaborate on a Spotify Web API plugin?

Post by Septik » Sun Oct 15, 2017 11:08 am

Building on yokel's work:
  1. Made some grammatical changes (I'm nitpicky, sorry).
  2. Moved one step closer to automatic retrieval of tokens. Running the "Add current song to playlist" action now triggers an attempt to refresh the access token using a refresh token, and if no refresh token is found it tries to start the "initial token" procedure. Right now, however, the line "clientID = self.plugin.clientID" triggers an error "AttributeError: 'NoneType' object has no attribute 'clientID'". Starting the initial token procedure manually still works properly.
  3. Changed all instances of "print 'errormsg'" to "self.PrintError('errormsg')" for clarity.
Regarding number 2, I'm thinking that in the future we should have a separate "authCheck" class or something for checking if the current access token is valid. It would either return true or false, or maybe just perform the necessary operations for updating what's needed.

Edit: Tried to do some more work on #2 above. Leaving the previous file up as I'm not sure I did more good than harm... I was able to prevent some error messages by passing client_id and client_secret as parameters rather than trying to get them from "self.plugin.varName". Now there's some strange behvaiour that I can't explain.

I'm learning Java these days and trying to translate what little I know of it to Python. So I've tried to implement solutions like this a few places in the plugin code (pseudocode follows):

Code: Select all

def someMethod():
    if var == None
        var = someOtherMethod()
    <do some stuff>
    
def someOtherMethod():
    <do some other stuff>
    var = x
    return var
I was thinking that someMethod would then wait for someOtherMethod to return a value, but what seems to happen instead is:
  1. someMethod proceeds with var being None. This causes errors.
  2. someOtherMethod returns var.
  3. someMethod restarts and now has a value for var.
  4. someMethod finishes without error.
I considered adding a wait action (basically "wait until var is not None"), but then I'd have to get threading right. Besides, we probably shouldn't implement threading in many individual cases now if we are implement to implement a single class for authentication stuff in the future.

Anyway, feel free to check out both uploads and work with what you prefer. Another more useful change that I made in the latest version is that I replaced "accessToken" and "refreshToken" with "access_token" and "refresh_token" everywhere. This because those names are used in Spotify URL's, so I thought it made more sense. I also renamed the "getAccessToken" function to "refreshAccessToken" (just because that's what it's actually intended to do).

Edit 2: I did indeed break something in that last upload. Since getFirstAccessToken.__call__() now requires 3 arguments (self, client_id, client_secret), it can't be run manually anymore. Oops. I haven't fixed that, but uploaded a new version that has play and pause actions. Just wanted to try that out! :)
Attachments
__init__.py
Edited upload
(12.15 KiB) Downloaded 28 times
__init__.py
Initial upload
(10.66 KiB) Downloaded 28 times
Last edited by Septik on Sun Oct 15, 2017 12:48 pm, edited 3 times in total.

User avatar
yokel22
Experienced User
Posts: 229
Joined: Thu Feb 05, 2015 5:56 pm
Location: U.S. - Kansas city

Re: Anyone willing to collaborate on a Spotify Web API plugin?

Post by yokel22 » Sun Oct 15, 2017 12:25 pm

:D grammatical errors are my fortay. I kinda take pride in it. Seriously, change whatever you like, it's your plugin. I'm just trying to help where I can.

Septik
Posts: 37
Joined: Sun Feb 15, 2015 1:29 pm

Re: Anyone willing to collaborate on a Spotify Web API plugin?

Post by Septik » Sun Oct 15, 2017 12:46 pm

yokel22 wrote:
Sun Oct 15, 2017 12:25 pm
:D grammatical errors are my fortay. I kinda take pride in it. Seriously, change whatever you like, it's your plugin. I'm just trying to help where I can.
Haha, in that case we'll make sure to keep one or two in the end! :D I've already included you in the author section for your help so far. Wouldn't have gotten so far without you!

Septik
Posts: 37
Joined: Sun Feb 15, 2015 1:29 pm

Re: Anyone willing to collaborate on a Spotify Web API plugin?

Post by Septik » Mon Oct 16, 2017 12:49 pm

Should we maybe create a new thread for development and discussion? Not sure if this is the right place for it. If an admin says the word I'll get that done.

Anyway, after great help from kgschlosser I've managed to get rid of that loop (and separate thread), and the plugin now responds to the "HTTP.code=<access code>" event instead! Right now the parsing of the access code is a little ugly, but that's not a huge issue right now.

I could use some help structuring the code (classes, methods) better now. Apart from that I'd appreciate some more experienced eyes to glance over the code and point out ideas for optimization. When that's done, I think we are ready to start implementing more API calls!

One more thing: While requesting the initial access token, one has to specify a "scope" (basically defining what actions/API calls our plugin can perform). So far I've simply hardcoded the necessary scope for what the plugin can do. I have a couple ideas regarding scope, though. We could:

1) Let the user check decide the scope (by having checkboxes in "def Configure()"). Then dynamically AddAction(s) based on the scope. The downside here is that it'd be hard to inform the user of what's possible and not with the selected scope (unless we added some sort of dynamic list in the GUI?) This solution would clarify what permissions the plugin is asking, but on the other hand I'm pretty sure you get the scope specified while okaying the app for the first time.

2) Request a new access (and refresh) token every time the user triggers a so far unused action.

In both cases, it would be necessary to append or trim the scope variable depending on user interaction. A more bruteforce approach (less favorable in my opinion) is to simply hardcode every permission necessary to perform API calls the plugin can perform.

Ideas? Feedback?

Edit: Oops, forgot to add the Github link!

User avatar
yokel22
Experienced User
Posts: 229
Joined: Thu Feb 05, 2015 5:56 pm
Location: U.S. - Kansas city

Re: Anyone willing to collaborate on a Spotify Web API plugin?

Post by yokel22 » Mon Oct 16, 2017 2:53 pm

Personally, I HATE plugins that self load all actions to the tree. I'd say allow the user to select scope from a dropdown or checkbox. Then seperate the scopes actions into seperate folders. That way the user knows which actions can be used.

We can use a dict to hold the different scopes parameters.

I have a bit more fence work to finish up, but I should be able to work on it a little later today.

User avatar
kgschlosser
Site Admin
Posts: 3928
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Anyone willing to collaborate on a Spotify Web API plugin?

Post by kgschlosser » Mon Oct 16, 2017 8:30 pm

yokel22 wrote:
Mon Oct 16, 2017 2:53 pm
Personally, I HATE plugins that self load all actions to the tree. I'd say allow the user to select scope from a dropdown or checkbox. Then seperate the scopes actions into seperate folders. That way the user knows which actions can be used.
you do know that you can click cancel when that add group box comes up right?? :o :shock: 8)


@yokel22
I have added a PR to @Septik's GitHub. I have started work on an API backend. I have created all the containers for the different data sets the API returns. They will need a little tweaking But all in all they are mostly done. If you read the PR message you will get a better idea of what I am trying to do.
If you like the work I have been doing then feel free to Image

Septik
Posts: 37
Joined: Sun Feb 15, 2015 1:29 pm

Re: Anyone willing to collaborate on a Spotify Web API plugin?

Post by Septik » Mon Oct 16, 2017 8:59 pm

kgschlosser wrote:
Mon Oct 16, 2017 8:30 pm
@yokel22
I have added a PR to @Septik's GitHub. I have started work on an API backend. I have created all the containers for the different data sets the API returns. They will need a little tweaking But all in all they are mostly done. If you read the PR message you will get a better idea of what I am trying to do.
Damn, you've been working hard. :D

User avatar
yokel22
Experienced User
Posts: 229
Joined: Thu Feb 05, 2015 5:56 pm
Location: U.S. - Kansas city

Re: Anyone willing to collaborate on a Spotify Web API plugin?

Post by yokel22 » Mon Oct 16, 2017 11:18 pm

I think you've guys have got this covered. I think I'll just step back. I've got plenty on my plate as it is.

User avatar
kgschlosser
Site Admin
Posts: 3928
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Anyone willing to collaborate on a Spotify Web API plugin?

Post by kgschlosser » Tue Oct 17, 2017 9:21 am

@Septik.

I am gong to write the back end of this thing. and then pass off the information to you so you will be able to make up all of the config dialogs.

The dialogs are going to be rather on the complex side of things. but it will give you a huge amount of python knowledge as well as GUI knowledge at the same time. I found wx (the GUI engine) to be a huge pain to learn. But when you get to physically see things appearing on the screen the way you want it's kind of a nice motivating tool.

So I have most of the class structures done for housing the different bits. I have the token end of it done. I have also set up automatic router port forwarding (with removal) and it returns the redirect uri.
If you like the work I have been doing then feel free to Image

Septik
Posts: 37
Joined: Sun Feb 15, 2015 1:29 pm

Re: Anyone willing to collaborate on a Spotify Web API plugin?

Post by Septik » Tue Oct 17, 2017 11:56 am

@kgschlosser

Sounds good to me. I did actually play around with wx yesterday and it definitely seems like a fun tool. I'll look into it more to prepare myself for the task.

Very much appreciate your contribution!

jachin99
Experienced User
Posts: 473
Joined: Sat Feb 13, 2016 8:39 pm

Re: Anyone willing to collaborate on a Spotify Web API plugin?

Post by jachin99 » Mon Oct 23, 2017 1:48 pm

If your able to pull this off then I believe EG will be the ONLY (aside from maybe rainmeter) bit of software to have a Spotify plugin.

EDIT: Kodi has a Spotify plugin but i believe its in beta.

User avatar
kgschlosser
Site Admin
Posts: 3928
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Anyone willing to collaborate on a Spotify Web API plugin?

Post by kgschlosser » Tue Oct 24, 2017 2:45 am

if i pull this off?!?!?


I will tell you what. I was working on it for a while today it has an extremely extensive API. It will be the only fully functional plugin that is made for Spotify. I do know it will be the only fully functional package for python.
If you like the work I have been doing then feel free to Image

Post Reply