Thursday, September 8, 2011

Love current track in MPD on last.fm (Also delete current song)


#!/usr/bin/python2 

import gtk
import pynotify
import os
import pylast

MPD_LIBRARY_LOCATION = "/var/lib/mpd/music/"
API_KEY = "your api key"
API_SECRET = "your secret"
username = "shadyabhi"
#Enter the hash directly.
password_hash = pylast.md5("mysupersecret")

class MPDTest:
        
    def __init__(self):
        #Initing the pynotif
        pynotify.init("mpd")
        n = pynotify.Notification("Action for current song", "What do you wanna do?")
        n.set_urgency(pynotify.URGENCY_LOW)
        n.set_timeout(2)
        n.add_action("action_delete", "Delete", self.deleteSong)
        n.add_action("no_dontdelete", "Hide", self.doNothing)
        n.add_action("love_on_lastfm", "Love on Last.fm", self.love_on_lastfm) 
        n.connect("closed", self.closeit)
        n.show()
        gtk.main()

    def deleteSong(self, notifyObj, action):
        print "Deleting the song"
        mpcProcess = os.popen("mpc -f %file%")
        try:
            # [:-1] to delete the trailing newline
            os.remove(MPD_LIBRARY_LOCATION+mpcProcess.readline()[:-1])
            #Deleting song from playlist
            os.popen("mpc del $(mpc -f %position% | head -n 1)")
        except:
            print "Something really went wrong"
        notifyObj.close()
        gtk.main_quit()

  
    def doNothing(self,notifyObj, action):
        notifyObj.close()
        gtk.main_quit()

    def closeit(self, notifyObj):
        notifyObj.close()
        gtk.main_quit()

    def love_on_lastfm(self, notifyObj, action):
        print "Loving track on last.fm"
        network = pylast.LastFMNetwork(api_key = API_KEY, api_secret = API_SECRET, username = username, password_hash = password_hash)
        
        artist = os.popen('mpc -f "%artist%" | head -n 1').read()
        title = os.popen('mpc -f "%title%" | head -n 1').read()

        track = network.get_track(artist, title)
        notifyObj.close()
        gtk.main_quit()
        track.love()
 
        #Confirming the user that the track has been loved by retrieving the last loved track from last.fm
        last_loved_track = str(network.get_user(username).get_loved_tracks(limit=1)[0][0])
        love_notification = pynotify.Notification("Last loved track confirmation", last_loved_track + " is your last loved track")
        love_notification.set_timeout(1)
        love_notification.show()

if __name__ == "__main__":
    obj = MPDTest()

13 comments:

  1. that's what i've been looking for a while, thanks man. but there's a question about "password_hash = pylast.md5("mysupersecret")" line. what is that - mysupersecret? And btw is there a possibility to just do the things quietly & separately i.e. single command to erase from disk or add to favorites? it would be then much comfortable to bind them shortkeys. thanks

    ReplyDelete
  2. mysupersecret is the password of last.fm. I wrote it that way just to show that I can generate the md5 hash using that function & put the hash directly instead of putting password in plaintext.

    Ofcoarse, I can do all that individually. In that case, I would just make bash scripts instead of using python. Tell me, if you any doubts regarding that. I would be happy to help.

    ReplyDelete
  3. actually it would be great if you do that. I imagine it as a script with 2 options: one for loving track & another for deleting it. notify-osd support would be desirable. I don't know how difficult is that and whether you have time and desire for it but thanks anyway.

    ReplyDelete
  4. hey, I found your previous article http://linux-junky.blogspot.com/2011/02/delete-currently-playing-song-in-mpd.html - so one task less :)

    ReplyDelete
  5. I have hurried a little rejoicing cause I've got this error of kdialog missing. guess it's something from KDE and i don't wanna use excrescent kde libs in this case (

    ReplyDelete
  6. @theone You want two options & you want notify-osd too. I cannot find a reason to have separate script for the two tasks. My script does the same thing, it just shows the two buttons at the same time. What's the harm in that?

    ReplyDelete
  7. @shadyabhi You have to understand me right, i'm not criticizing you script but for me that popping window with it's excessive buttons (here's how it looks at my machine - a bit different from yours on the picture) is unnecessary. I just want to click a button (shortkey) and get track loved click another and get it deleted. I don't know maybe there's an easy way (with little changes in script) to invoke this two commands directly and silently omitting popping dialog.

    ReplyDelete
  8. I get it. You are using some modified version of notification-daemon or your distro uses a patched version of it. Which distro and package?

    Right now, I am on mobile so I cannot test it. All you need to do is remove(or comment them using #) the required lines "n.add_action...". Each of that line actually adds a button (called action for notification-daemon) to that dialog.

    ReplyDelete
  9. yeah, you right. i'm using a modified version of notify-osd (https://launchpad.net/~leolik/+archive/leolik) on ubuntu natty. ok, I'll comment them and try. but I still convinced there must be an easy way to invoke defined button (action) directly w/o dialog window. just tell if i'm wrong and it needs a lot of additional code or complete rewriting - then I'll leave you alone :). thanks

    ReplyDelete
  10. Doing that was easy. I just deleted the extraneous code.

    https://gist.github.com/1309527

    Haven't tested them as right now I am on OSX Leapord. Inform me if there is any error.

    ReplyDelete
  11. works just fine - exactly what I needed!!! thank you again, shadyabhi, and sorry for disturbing you that much :)

    ReplyDelete
  12. @theone That's fine. Happy to help :)

    ReplyDelete
  13. A fascinating discussion is definitely worth comment. I do believe that you should publish more on this topic,
    it might not be a taboo subject but typically folks don't discuss these issues. To the next! All the best!!
    My weblog www.weightloss.com

    ReplyDelete