New patches: [play-lastfm-streams.dpatch Tassilo Horn **20061227205745 This patch has two major parts: 1. Make emms-lastfm.el conforming to other emms plugins, meaning that there are those three user functions: `emms-lastfm' -- The usual prefix arg toggle `emms-lastfm-enable' `emms-lastfm-disable' 2. It adds the ability to play lastfm:// streams. New user functions: `emms-lastfm-playback' `emms-lastfm-playback-similar-artists' `emms-lastfm-playback-global-tag' Sadly there are 2 FIXMEs in the code: 1. Major problem: It doesn't work for lastfm urls which contain blanks. If someone is familiar with the url library, he could tell me how to fix it. (retrieving urls with whitespaces) 2. Minor problem: There's some ugly (but working) code to ensure the execution doesn't continue before a sentinel has been run. ] { hunk ./emms-lastfm.el 38 -;; `M-x emms-lastfm-activate' +;; `M-x emms-lastfm-enable' hunk ./emms-lastfm.el 41 -;; `C-u -1 M-x emms-lastfm-activate' +;; `M-x emms-lastfm-disable' hunk ./emms-lastfm.el 59 - "The version regitered at last.fm. Don't change it!") + "The version registered at last.fm. Don't change it!") hunk ./emms-lastfm.el 102 -(defun emms-lastfm-activate (&optional ARG) +(defun emms-lastfm (&optional ARG) hunk ./emms-lastfm.el 152 -(defun read-line () - (buffer-substring-no-properties (line-beginning-position) - (line-end-position))) +(defalias 'emms-lastfm-activate 'emms-lastfm + "Obsolete! Use `emms-lastfm-enable', `emms-lastfm-disable' or +`emms-lastfm'.") + +(defun emms-lastfm-enable () + "Enable the emms last.fm plugin." + (interactive) + (emms-lastfm 1)) + +(defun emms-lastfm-disable () + "Disable the emms last.fm plugin." + (interactive) + (emms-lastfm -1)) hunk ./emms-lastfm.el 251 +;;; Playback of lastfm:// streams + +(defvar emms-lastfm-playback-base-url "http://ws.audioscrobbler.com" + "The base URL for playing lastfm:// stream.") + +(defvar emms-lastfm-playback-session nil "-- only used internally --") +(defvar emms-lastfm-playback-stream-url nil "-- only used internally --") + +(defun emms-lastfm-playback-get-handshake-url () + (concat emms-lastfm-playback-base-url + "/radio/handshake.php?version=" (number-to-string + emms-lastfm-client-version) + "&platform=" emms-lastfm-client-id + "&username=" emms-lastfm-username + "&passwordmd5=" (md5 emms-lastfm-password) + "&debug=" (number-to-string 9))) + +(defun emms-lastfm-playback-handshake () + "Handshakes with the last.fm server." + (let ((url-request-method "GET")) + (setq emms-lastfm-buffer + (url-retrieve (emms-lastfm-playback-get-handshake-url) + 'emms-lastfm-playback-handshake-sentinel)))) + +(defun emms-lastfm-playback-handshake-sentinel (&rest args) + (save-excursion + (set-buffer emms-lastfm-buffer) + (setq emms-lastfm-playback-session (key-value "session")) + (setq emms-lastfm-playback-stream-url (key-value "stream_url")) + (if (and emms-lastfm-playback-session emms-lastfm-playback-stream-url) + (message "EMMS: Handshaking for Last.fm playback successful.") + (message "EMMS: Failed handshaking for Last.fm playback.")))) + +;; FIXME: This function doesn't work with lastfm-urls containing blanks, +;; e.g. the global tag radio for the tag "Death Metal" ar the similar artist +;; radio for the "Backstreet Boys". If someone is familiar with the `url' +;; library, please help me. +(defun emms-lastfm-playback (lastfm-url) + "Plays the stream associated with the given Last.fm URL. (A +Last.fm URL has the form lastfm://foo/bar/baz, e.g. + + lastfm://artist/Manowar/similarartists + +or + + lastfm://globaltags/metal." + (interactive "sLast.fm URL: ") + ;; Streamed songs must not be added to the lastfm profile + (emms-lastfm-disable) + (when (not (and emms-lastfm-playback-session + emms-lastfm-playback-stream-url)) + (emms-lastfm-playback-handshake)) + ;; FIXME: Is there some better code to ensure that execution resumes not + ;; before the handshake sentinel has finished??? + (let ((waits 0)) + (while (and (not (and emms-lastfm-playback-session + emms-lastfm-playback-stream-url)) + (< waits 10)) + (setq waits (1+ waits)) + (sit-for 1))) + ;; END of FIXME + (if (and emms-lastfm-playback-session + emms-lastfm-playback-stream-url) + (let ((url-request-method "GET")) + (setq emms-lastfm-buffer + (url-retrieve (concat emms-lastfm-playback-base-url + "/radio/adjust.php?" + "session=" emms-lastfm-playback-session + "&url=" lastfm-url + "&debug=" (number-to-string 0)) + 'emms-lastfm-playback-sentinel))) + (message "EMMS: Cannot play Last.fm stream."))) + +(defun emms-lastfm-playback-sentinel (&rest args) + (save-excursion + (set-buffer emms-lastfm-buffer) + (if (string= (key-value "response") "OK") + (progn + (emms-play-url emms-lastfm-playback-stream-url) + (message "EMMS: Playing Last.fm stream.")) + (message "EMMS: Bad response from Last.fm.")))) + +(defun emms-lastfm-playback-similar-artists (artist) + "Plays the similar artist radio of ARTIST." + (interactive "sArtist: ") + (emms-lastfm-playback (concat "lastfm://artist/" + artist + "/similarartists"))) + +(defun emms-lastfm-playback-global-tag (tag) + "Plays the global tag radio of TAG." + (interactive "sGlobal Tag: ") + (emms-lastfm-playback (concat "lastfm://globaltags/" tag))) + + +;;; Utility functions + +(defun read-line () + (buffer-substring-no-properties (line-beginning-position) + (line-end-position))) + +(defun key-value (key) + "Returns the value of KEY. The buffer has to contain a +key-value list like: + +foo=bar +x=17" + (goto-char (point-min)) + (when (re-search-forward (concat "^" key "=")) + (buffer-substring-no-properties (point) (line-end-position)))) + } Context: [replace-next-line-with-forward-line.dpatch Tassilo Horn **20061220205010 The docstring of `next-line' suggest to use `forward-line' instead, so use that... ] [warn-if-playing-time-deactivated.dpatch Tassilo Horn **20061219085443 New emms-lastfm-activate warns the user if he disabled emms-playing-time completely and points him to the right docs. ] [emms.texinfo: Update emms-playing-time info. address@hidden [emms-playing-time: Add stuffs for controlling displaying on mode line address@hidden while still enabling emms-playing-time module at backgrond. ] [emms-mode-line: Rename `emms-playing-time-toggle' to `emms-mode-line-toggle'. address@hidden [fix-regression-in-lastfm.dpatch Tassilo Horn **20061216132209 My last path enabled emms-lastfm.el to submit tracks even if you paused them. I tested this extensively! But I didn't test if it still submits them if you don't pause it. Of course it didn't. ;-) The problem was that I rely on `emms-playing-time' to calculate when a track has to be submitted. But in `emms-player-started-hook' my new track function was run *before* `emms-playing-time' was set to 0 again. ] [submitting-when-paused.dpatch Tassilo Horn **20061212200324 This patch enables emms-lastfm.el to submit the current track even if the playback has been paused and resumed. It's done by canceling the `emms-lastfm-timer' when pausing and reenabling it on resume. ] [emms-lyrics: Make `emms-lyrics-find-lyric-function' customizable and add address@hidden `emms-lyrics-find-current-lyric'. ] [change raise/lower-function to change-functon, add change-amount Ye Wenbin **20061208052114] [Remove emms-volume-amixer-raise/lower commands, use emms-volume-change-function Ye Wenbin **20061208052019] [emms-i18n: Rename functions to match file name. address@hidden [emms-setup: Add `emms-i18n' to `emms-devel'. address@hidden [emms-info-mp3info: Make use of `emms-i18n-call-process-simple'. address@hidden [emms-player-mpd: Document how to use MusicPD to change the volume via emms-volume.el Michael Olson **20061208223509] [Fix various byte-compiler warnings throughout Michael Olson **20061207143511] [emms-tag-editor: Rename functions to match file name Michael Olson **20061207142310] [Rename emms-mp3tag.el to emms-tag-editor.el Michael Olson **20061207141945] [emms.el: Improve `emms-uniq-list' to not use cl.el. address@hidden [emms-i18n changes, add playlist navigate command, uniq playlist command Ye Wenbin **20061207063510] [emms-mp3tag support ogg, add more documentation. fix some error Ye Wenbin **20061206153528] [emms-lastfm.dpatch Tassilo Horn **20061206112823 This patch adds emms-lastfm.el, its setup to emms-setup.el and myself to AUTHORS. ] [Fix a silly bug in emms-mp3tag. Remove timestamp. Ye Wenbin **20061206020710] [AUTHORS: Added Ye Wenbin address@hidden [Fix lyrics minibuffer display. Amixer display playback and more useful commands Wenbin Ye **20061127154113] [Edit all track, set tag to file for mp3 Wenbin Ye **20061205112209] [Add emms-mp3tag and emms-i18n Wenbin Ye **20061205065407] [Add emms-mark and emms-history address@hidden [emms-info-mp3info.el: Replace `emms-iconv' with decode-coding-string and address@hidden encode-coding-string. ] [emms.el: Fix bug introduced by recent changes to emms-playlist-set-playlist-buffer Michael Olson **20061119204738] [Default to current buffer when setting the current EMMS playlist buffer. Michael Olson **20061119053410] [manual: Add documentation for new emms-playlist-mode keybindings Michael Olson **20061119052935] [emms-playlist-mode: Bind "b" key to emms-playlist-set-playlist-buffer. Michael Olson **20061119052907] [emms-playlist-mode: Implement adding the thing at point to the current playlist. If it is a playlist, add its contents instead. Map this to the "a" key. Michael Olson **20061119052254] [emms.el: In emms-playlist-set-playlist-buffer, prompt user from available EMMS playlist buffers rather than all buffers, and display feedback upon setting the current buffer, since this is not an easy change to see Michael Olson **20061119052023] [emms.el: Fix compiler warning Michael Olson **20061119051946] [Don't add subdirectories for directory and playlist-directory source insert methods Michael Olson **20061119041900] [emms-playing-time.el: New variable `emms-playing-time-style', it address@hidden supports two styles at present, `time' and `bar'. ] [bind SPC to `scroll-up' in emms-playlist-mode and update manual. address@hidden [emms-player-mpd: Deal with change in output when getting supported file types Michael Olson **20061028042119] [emms.el: Move macros to the top of the file. address@hidden [NEWS: Add entry for recent emms-player-mpd change Michael Olson **20061023125738] [emms-player-mpd: Handle errors that occur when we begin playback Michael Olson **20061022215310] [NEWS: Version 2 is version 2.0 address@hidden [emms-playlist-mode: Handle case where selection has not been set but user wants to delete a region Michael Olson **20061022201724] [emms-playlist-mode: Fix typo in hook name Michael Olson **20061022022812] [emms-player-mpd: Update version recommendation Michael Olson **20061022012223] [emms-player-mpd: Work properly with tracks inserted by emms-browser Michael Olson **20061022011050] [Add NEWS items since version 2.1 Michael Olson **20061017222117] [emms-player-mplayer.el: Mplayer also supports .vob files. address@hidden [emms-player-mpd: When using the emms-volume interface, allow the user to specify the amount of change in the volume Michael Olson **20061017220404] [Documentation cleanups in emms-player-mpd and emms-source-playlist Michael Olson **20061017215345] [Since emms-player-seeked-to-functions and emms-player-time-set-functions hooks do the same thing, replace the former with the latter Michael Olson **20061017210238] [emms-browser: Fix compiler warning Michael Olson **20061017205310] [emms-player-mpd: Implement seek-to support Michael Olson **20061017205106] [FluidSynth midi file player address@hidden [Added delYsid address@hidden [jackd-support-for-emacs address@hidden jackd is a pro-audio server which can be used as a backend for alsaplayer, mplayer, and lots of other linux audio apps. This module allows to start jackd from within emacs, and connect/disconnect jack client ports. ] [browser: ensure the RNG is seeded before use Damien Elmes **20061011151535] [browser: require sort (fixes bug with sort-fold-case being void) Damien Elmes **20061010125718] [fix faulty emms-playlist-mode keybinding, fix due to William and Damien. address@hidden [Added seeking to the playlist keymap, and updated the manual. address@hidden [emms-player-mpd: Only display error if we are certain that url.el is not up-to-date Michael Olson **20061004032213] [seek-for-alsaplayer address@hidden Add relative seek support for alsaplayer ] [midi-files-via-timidity address@hidden A simple-player definition for timidity ] [emms-playing-time.el: Minor cleanups. address@hidden [emms-lyrics.el: Minor Cleanups. address@hidden [pause-for-alsaplayer address@hidden Get pause/resume working for alsaplayer ] [mms-for-mplayer address@hidden mplayer also supports mms:// URLs ] [DoTheRightThing with player pausing and emms-bookmarks.el address@hidden [Added emms-bookmarks.el address@hidden [Added `emms-pause' to emms-playlist-mode.el bound to to ``P''. address@hidden [browser: add deletion started/finished message Damien Elmes **20060923051128] [Added a link to the online version of the manual. address@hidden [emms-playing-time.el now works with `seek-to'. address@hidden [Added `seek-to' to emms.el and emms-player-mplayer.el. address@hidden [browser/cache: support deleting files, make emms-cache-dirty a defsubst Damien Elmes **20060922090553] [TAG 2.1 address@hidden Patch bundle hash: 07186e55b157ff4287aa3defda2c8a1b7116a808