aboutsummaryrefslogtreecommitdiff
path: root/emms-info.el
diff options
context:
space:
mode:
authorforcer <forcer>2005-09-11 20:05:00 +0000
committerforcer <mwolson@gnu.org>2005-09-11 20:05:00 +0000
commitbb65333ef00df02dbf6bd83294b4df49e64ea325 (patch)
tree5435715fe823d566ac5494bc672088522af5a763 /emms-info.el
Initial commit (CVS 2005-09-11)
darcs-hash:20050911200506-2189f-48a136015e33465c3cf09940ce935ec2203df463.gz
Diffstat (limited to 'emms-info.el')
-rw-r--r--emms-info.el182
1 files changed, 182 insertions, 0 deletions
diff --git a/emms-info.el b/emms-info.el
new file mode 100644
index 0000000..b5148f3
--- /dev/null
+++ b/emms-info.el
@@ -0,0 +1,182 @@
+;;; emms-info.el --- Info system for EMMS
+
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+
+;; Author: Ulrik Jensen <terryp@daimi.au.dk>
+;; Keywords:
+
+;; 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 St, Fifth Floor,
+;; Boston, MA 02110-1301 USA
+
+;;; Commentary:
+
+;; This file provides an interface for different methods of reading
+;; info about the files that EMMS is playing, and displaying it.
+
+;; To create a method for retrieving info about a file, you create an
+;; object like this:
+
+;; (define-emms-info-method emms-info-mp3info
+;; :providep 'emms-info-mp3info-providep
+;; :get 'emms-info-mp3info-get
+;; :set 'emms-info-mp3info-set)
+
+;; Then you register it with emms-info, by adding it to
+;; `emms-info-methods-list'.
+
+;; (add-to-list 'emms-info-methods-list 'emms-info-ogg-comment)
+
+;;; Code:
+(require 'emms)
+
+(eval-when-compile (require 'cl))
+
+(defvar emms-info-version "0.2 $Revision: 1.16 $"
+ "EMMS info version string.")
+;; $Id: emms-info.el,v 1.16 2005/08/12 17:59:30 xwl Exp $
+
+;; Customizations
+(defgroup emms-info nil
+ "*Info system for EMMS"
+ :prefix "emms-info-"
+ :group 'emms)
+
+(defgroup emms-info-methods nil
+ "*Methods to get info for EMMS-info"
+ :group 'emms-info
+ :prefix "emms-info-")
+
+(defcustom emms-info-methods-list nil
+ "List of info-methods. You need to set this."
+ :group 'emms-info
+ :type '(repeat function))
+
+;; Caching
+(defcustom emms-info-cache t
+ "Boolean value, indicating whether or not to use a cache for
+info-structures."
+ :group 'emms-info
+ :type 'boolean)
+
+(defcustom emms-info-format '("%s - %s" (emms-info-artist emms-info-title))
+ "Format the info string.
+The first element of the list is a string with typical format
+instructions, the cdr is a list of functions that get called with
+the struct as argument."
+ :type '(list string (repeat sexp))
+ :group 'emms-pbi)
+
+(defvar emms-info-cache-hash-table nil
+ "A hash-table storing the cached info.
+
+Uses tracks as keys and the emms-info structures as
+values.")
+
+ ;; The structure for info about files:
+(defstruct emms-info title artist album note year genre file
+ playing-time playing-time-min playing-time-sec)
+
+;; Interface
+(defmacro define-emms-info-method (name &rest alist)
+ `(defun ,name (action)
+ (plist-get ',(mapcar (lambda (keyword)
+ (if (not (keywordp keyword))
+ (cadr keyword)
+ (intern (substring (symbol-name keyword) 1))))
+ alist)
+ action)))
+
+;; Methods for the cache
+(defun emms-info-get-cached (track)
+ "Return cached info for the track TRACK, nil of no cache."
+ (if emms-info-cache-hash-table
+ (gethash track emms-info-cache-hash-table nil)
+ nil))
+
+(defun emms-info-set-cached (track info)
+ "Set cached info for TRACK to INFO"
+ (unless emms-info-cache-hash-table
+ ;; No hash-table yet, create one
+ (setq emms-info-cache-hash-table (make-hash-table :test 'equal)))
+ (puthash track info emms-info-cache-hash-table))
+
+;; Retrieve
+(defun emms-info-method-for (track)
+ "Return an info-method suitable for TRACK."
+ (unless emms-info-methods-list
+ (error "There are no info-methods defined at all. You should customize `emms-info-methods-alist'."))
+ ;; find an info-method capable of providing info for this file
+ (let ((curmethod emms-info-methods-list))
+ (while (and curmethod
+ (not (funcall (funcall (car curmethod) 'providep) track)))
+ (setq curmethod (cdr curmethod)))
+ (when curmethod
+ (car curmethod))))
+
+(defun emms-info-get (track &optional dont-use-cached)
+ "Return an emms-info structure representing the track TRACK.
+if DONT-USE-CACHED is non-nil, then always read from the file."
+ ;; extend with methods for caching
+ (let ((method (emms-info-method-for track))
+ (cached (emms-info-get-cached track)))
+ (if (or dont-use-cached (not emms-info-cache) (not cached))
+ ;; read from the file
+ (when method
+ (let ((readinfo (funcall (funcall method 'get) track)))
+ (when emms-info-cache
+ ;; save the cache
+ (emms-info-set-cached track readinfo))
+ ;; return the read version
+ readinfo))
+ ;; else just use the cached
+ cached)))
+
+(defun emms-info-set (track info)
+ "Set the info of the file TRACK to the emms-info structure INFO."
+ (let ((method (emms-info-method-for track)))
+ (when method
+ (when emms-info-cache
+ (emms-info-set-cached track info))
+ (funcall (funcall method 'set) track info))))
+
+(defun emms-info-format-info (format struct)
+ "Take FORMAT and format it with STRUCT.
+For the formaz of FORMAT see `emms-info-format')"
+ (apply 'format (car format)
+ (mapcar (lambda (func)
+ (funcall func struct))
+ (cadr format))))
+
+;; Functions suitable as values of
+;; `emms-playlist-get-file-name-function':
+
+(defun emms-info-file-info-song-artist (track)
+ "Returns a description of TRACK, build from it's comments.
+
+If `emms-info-methods-list' indicates how to retrieve special info
+about it, use this. Otherwise returns the name alone."
+ (if (not (and track (emms-track-name track)))
+ "Invalid track!"
+ (if (emms-info-method-for track)
+ ;; read the info
+ (let ((info (emms-info-get track)))
+ (if (and info (not (string= (emms-info-artist info) "")) (not (string= (emms-info-title info) "")))
+ (concat (emms-info-artist info) " - " (emms-info-title info))
+ (file-name-sans-extension (file-name-nondirectory (emms-track-name track)))))
+ ;; we can't read info for this file, default to the name
+ (file-name-sans-extension (file-name-nondirectory (emms-track-name track))))))
+
+(provide 'emms-info)
+;;; emms-info.el ends here