[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[emms-help] Last.fm plugin for EMMS
From: |
Tassilo Horn |
Subject: |
[emms-help] Last.fm plugin for EMMS |
Date: |
Mon, 09 Oct 2006 14:11:32 +0200 |
User-agent: |
Gnus/5.110006 (No Gnus v0.6) Emacs/22.0.50 (gnu/linux) |
Hi all,
I've written a plugin for last.fm. Unlike my last version (see
<address@hidden>) this version works. But there's a
bug in http-get.el and http-post.el which needs to be fixed first. I've
sent a patch to its maintainer David Hansen and report back when he
applied it.
I would be happy if emms-lastfm.el could be part of EMMS. Of course I'll
maintain it. What do I have to do?
--8<---------------cut here---------------start------------->8---
;;; emms-lastfm.el --- add your listened songs to your profile at last.fm
;; Copyright (C) 2006 Tassilo Horn <address@hidden>
;; Author: Tassilo Horn <address@hidden>
;; Keywords: emms, mp3, mpeg, multimedia
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
;;; Commentary:
;; This code sends information about what music you are playing to
;; last.fm. See <URL:http://www.last.fm> and
;; <URL:http://www.audioscrobbler.net/wiki/Protocol1.1>.
;; It requires http-get.el and http-post.el which can be get from
;; http://emacswiki.org/cgi-bin/wiki.pl?SimpleWikiEditMode. (You have to get it
;; straight from savannah CVS.)
;; Then tell emacs where those files are:
;; (add-to-list 'load-path "~/elisp/http-emacs")
;; To activate the last.fm emms plugin, run:
;; (emms-lastfm-initialize)
;; -----------------------------------------------------------------------
;; TODO: Have a look at `emms-playing-time'. Stopping the timer may not be
;; needed.
;; TODO: Implement a better error handling and give better infos to the user.
(require 'http-get)
(require 'http-post)
(defvar emms-lastfm-username ""
"Your last.fm username")
(defvar emms-lastfm-password ""
"Your last.fm password")
(defvar emms-lastfm-server "http://post.audioscrobbler.com/")
;; TODO: get an id for emms
(defvar emms-lastfm-client-id "tst")
(defvar emms-lastfm-client-version 1.0)
;; internally used
(defvar emms-lastfm-process nil)
(defvar emms-lastfm-md5-challenge nil)
(defvar emms-lastfm-submit-url nil)
(defvar emms-lastfm-current-track nil)
(defvar emms-lastfm-timer nil)
(defun emms-lastfm-new-track-function ()
(setq emms-lastfm-current-track
(emms-playlist-current-selected-track))
;; Tracks should be submitted, if they played 240 secs or half of their
;; length, whichever comes first.
(let ((secs
(/ (cdr (assoc 'info-playing-time
emms-lastfm-current-track))
2)))
(when (> secs 240)
(setq secs 240))
(unless (< secs 15) ;; Skip titles shorter than 30 seconds
(setq emms-lastfm-timer
(run-with-timer secs nil 'emms-lastfm-submit-track)))))
(defun emms-lastfm-cancel-timer ()
(when emms-lastfm-timer
(cancel-timer emms-lastfm-timer)))
(defun emms-lastfm-initialize ()
"Adds handshaking and submission to the relevant hooks."
(interactive)
(add-hook 'emms-player-started-hook
(lambda ()
(when (not (and emms-lastfm-md5-challenge
emms-lastfm-submit-url))
(emms-lastfm-handshake))))
(add-hook 'emms-player-started-hook
'emms-lastfm-new-track-function)
(add-hook 'emms-player-stopped-hook
'emms-lastfm-cancel-timer)
(add-hook 'emms-player-paused-hook
'emms-lastfm-cancel-timer))
(defun read-line ()
(buffer-substring-no-properties (line-beginning-position)
(line-end-position)))
(defun emms-lastfm-handshake ()
"Handshakes with the last.fm server."
(interactive)
(accept-process-output
(setq emms-lastfm-process
(http-get (concat emms-lastfm-server "?hs=true&p=1.1"
"&c=" emms-lastfm-client-id
"&v=" (number-to-string
emms-lastfm-client-version)
"&u=" emms-lastfm-username)
'(("Connection" . "close"))
'emms-lastfm-handshake-sentinel
1.0))))
(defun emms-lastfm-handshake-sentinel (proc msg)
"Parses the server reponse and act accordingly."
(save-excursion
(set-buffer (process-buffer proc))
(goto-char (point-min))
(if (not (string-match "\\(UPTODATE\\|UPDATE\\)" (read-line)))
(progn
(cond ((string-match "FAILED" (read-line))
(error "Handshake failed"))
((string-match "BADUSER" (read-line))
(error "Wrong username"))))
(goto-line 2)
(setq emms-lastfm-md5-challenge (read-line))
(next-line)
(setq emms-lastfm-submit-url (read-line)))))
(defun emms-lastfm-submit-track ()
"Submits the current track (`emms-lastfm-current-track') to
last.fm."
(let* ((artist (emms-track-get emms-lastfm-current-track 'info-artist))
(title (emms-track-get emms-lastfm-current-track 'info-title))
(album (emms-track-get emms-lastfm-current-track 'info-album))
(musicbrainz-id "")
(track-length (number-to-string
(emms-track-get emms-lastfm-current-track
'info-playing-time)))
(date (format-time-string "%Y-%m-%d %H:%M:%S" (current-time) t)))
(accept-process-output
(setq emms-lastfm-process
(http-post emms-lastfm-submit-url
`(("u" . ,emms-lastfm-username)
("s" . ,(md5 (concat (md5 emms-lastfm-password)
emms-lastfm-md5-challenge)))
("a[0]" . ,artist)
("t[0]" . ,title)
("b[0]" . ,album)
("m[0]" . ,musicbrainz-id)
("l[0]" . ,track-length)
("i[0]" . ,date))
'utf-8
'(("Connection" . "close"))
'emms-lastfm-submission-sentinel
1.0)))))
(defun emms-lastfm-submission-sentinel (proc msg)
"Is called after a track submission to last.fm was made."
(save-excursion
(set-buffer (process-buffer proc))
(goto-char (point-min))
(if (string= "OK" (read-line))
(message "\"%s\" submitted..."
(emms-track-description emms-lastfm-current-track))
;; TODO: Inform the user what went wrong.
(error "Song couldn't be submitted"))
(erase-buffer)))
(provide 'emms-lastfm)
;;; emms-lastfm.el ends here
--8<---------------cut here---------------end--------------->8---
Bye and thanks,
Tassilo
--
My opinions may have changed, but not the fact that I am right.
- [emms-help] Last.fm plugin for EMMS,
Tassilo Horn <=