emms-help
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[emms-help] Re: emms + last.fm?


From: Tassilo Horn
Subject: [emms-help] Re: emms + last.fm?
Date: Sat, 07 Oct 2006 11:23:19 +0200
User-agent: Gnus/5.110006 (No Gnus v0.6) Emacs/22.0.50 (gnu/linux)

Hi all,

I wrote another version of emms-lastfm.el (I didn't know this thread,
I'm just starting to use EMMS), which doesn't relay on a external
binary, but uses http-emacs [1]. It works, but there's one strange bug
in it right now. (See below...)

--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>.

;; To activate it, run:
;; (emms-lastfm-initialize)

;; -----------------------------------------------------------------------

;; TODO: Have a look at `emms-playing-time'. Stopping the timer may not be
;;       needed.
;; TODO: Why the heck does emms-lastfm-initialize not initialize md5-challenge
;;       etc, but if I step through it with edebug, it does as expected?!?


(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))
  (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 ()
  (interactive)
  (emms-lastfm-handshake)
  ;; Tracks should be submitted, if they played 240 secs or half of their
  ;; length, whichever comes first.
  (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 ()
  (interactive)
  (save-excursion
    (save-window-excursion
      (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)))
      (emms-lastfm-parse-handshake-response))))

(defun emms-lastfm-parse-handshake-response ()
  (switch-to-buffer (process-buffer emms-lastfm-process))
  (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 ()
  (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)))
    (save-excursion
      (save-window-excursion
        (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))
        (switch-to-buffer (process-buffer emms-lastfm-process))
        (if (string-match "^OK$" (read-line))
            (message (concat "\"" title "\" by " artist
                             " submitted to last.fm."))
          (error "Couldn't submit track to last.fm"))))))

(provide 'emms-lastfm)
;;; emms-lastfm.el ends here
--8<---------------cut here---------------end--------------->8---

The second TODO is the thing I don't get. When I do M-x
emms-lastfm-initialize, which calls emms-lastfm-handshake, which calls
emms-lastfm-parse-handshake-response, the two variables
emms-lastfm-md5-challenge and emms-lastfm-submit-url are still nil,
although a *HTTP GET...* buffer with the server response is opened. If I
edebug-defun those functions, all works fine.

I thought I could be that the server response is not in the *HTTP
GET...* buffer when emms-lastfm-parse-handshake-response runs, so I put
a (sleep-for 5) at the beginning of the function, but no luck...

Can anyone find the bug?

Bye and thanks,
Tassilo

Footnotes: 
[1] http://emacswiki.org/cgi-bin/wiki.pl?SimpleWikiEditMode
-- 
          "Emacs is not a development tool but a way of life."
                - David Kastrup in alt.religion.emacs -





reply via email to

[Prev in Thread] Current Thread [Next in Thread]