#!/usr/bin/env python
# A wrapper script that interfaces between MOC (Music on console) and
# lastfmsubmit. The problem with just usnig OnSongChange is that it
# will be triggered even if you listen to only one second of a song.
# This script will wait for half the length of the track, checking
# whether MOC is still playing it, before submitting the track to
# last.fm. This way, skipping through a list of tracks will not
# result in lots of tracks submitted.
# To use, put this in your ~/.moc/config file:
# OnSongChange = "/path/to/moc_submit_lastfm --artist %a --title %t --length %d --album %r"
# Author: Luke Plant < http://lukeplant.me.uk/ >
# License: public domain
from datetime import datetime
from optparse import OptionParser
from subprocess import call, Popen, PIPE
import time
parser = OptionParser()
parser.add_option("-a", "--artist", dest="artist")
parser.add_option("-t", "--title", dest="title")
parser.add_option("-A", "--album", dest="album")
parser.add_option("-l", "--length", dest="length")
# Treating everything as bytestrings throughout seems to work OK even
# with non-ASCII characters in song titles etc (at least with a UTF-8
# locale).
def still_playing(artist, album, title):
p = Popen(["mocp", "-i"], stdout=PIPE)
out, err = p.communicate()
lines = out.split("\n")
for s in ["Artist: %s" % artist, "Album: %s" % album, "SongTitle: %s" % title]:
if not s in lines:
return False
return True
def submit_to_lastfm(artist, album, title, length):
args = ["/usr/lib/lastfmsubmitd/lastfmsubmit", "--artist", artist, "--title", title, "--length", length]
if album is not None:
args.extend(["--album", album])
call(args)
def main():
options, args = parser.parse_args()
if any(not options.__dict__.get(k) for k in ["artist", "title", "length"]):
print "All of artist, album, length must be specified"
exit(1)
if ":" in options.length:
mins, secs = options.length.split(":")
length = int(mins) * 60 + int(secs)
else:
length = int(options.length)
# wait until song is half played
wait = length/2
start = datetime.now()
while True:
time.sleep(5)
if not still_playing(options.artist, options.album, options.title):
exit(1)
if (datetime.now() - start).seconds > wait:
submit_to_lastfm(options.artist, options.album, options.title, options.length)
exit(0)
if __name__ == '__main__':
import sys
main()