diff options
author | forcer <forcer> | 2005-09-11 20:05:00 +0000 |
---|---|---|
committer | forcer <mwolson@gnu.org> | 2005-09-11 20:05:00 +0000 |
commit | bb65333ef00df02dbf6bd83294b4df49e64ea325 (patch) | |
tree | 5435715fe823d566ac5494bc672088522af5a763 /emms-source-file.el |
Initial commit (CVS 2005-09-11)
darcs-hash:20050911200506-2189f-48a136015e33465c3cf09940ce935ec2203df463.gz
Diffstat (limited to 'emms-source-file.el')
-rw-r--r-- | emms-source-file.el | 288 |
1 files changed, 288 insertions, 0 deletions
diff --git a/emms-source-file.el b/emms-source-file.el new file mode 100644 index 0000000..f2f4846 --- /dev/null +++ b/emms-source-file.el @@ -0,0 +1,288 @@ +;;; emms-source-file.el --- EMMS sources from the filesystem. + +;; Copyright (C) 2003 Jorgen Schäfer + +;; Author: Jorgen Schäfer <forcer@forcix.cx> +;; 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. +;; +;; GNU Emacs 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 contains a track source for EMMS that is based on the +;; file system. You can retrieve single files or whole directories. +;; Also, this file offers the commands to play from these sources. + +;; TODO: + +;;; Code: + +;; Version control +(defvar emms-source-file-version "0.2 $Revision: 1.30 $" + "emms-source-file.el version string") +;; $Id: emms-source-file.el,v 1.30 2005/08/11 06:16:15 yonirabkin Exp $ + +;;; User Customization + +(require 'emms) +(eval-when-compile + (condition-case nil + (require 'locate) + (error nil))) + +(defgroup emms-source-file nil + "*Sources for EMMS that use the file system." + :prefix "emms-source-file-" + :group 'emms-source) + +(defcustom emms-source-file-default-directory nil + "*The default directory to look for media files." + :type 'string + :group 'emms-source-file) + +(defcustom emms-source-file-directory-tree-function + 'emms-source-file-directory-tree-internal + "*A function to call that searches in a given directory all files +that match a given regex. DIR and REGEX are the only arguments passed +to this function. +You have two build-in options: +`emms-source-file-directory-tree-internal' will work always, but might +be slow. +`emms-source-file-directory-tree-find' will work only if you have GNU +find, but it's faster." + :type 'function + :options '(emms-source-file-directory-tree-internal + emms-source-file-directory-tree-find) + :group 'emms-source-file) + +(defcustom emms-source-file-gnu-find "find" + "*The program name for GNU find." + :type 'string + :group 'emms-source-file) + +;; The `read-directory-name' function is not available in Emacs 21. +(defalias 'emms-read-directory-name + (if (fboundp 'read-directory-name) + #'read-directory-name + #'read-file-name)) + +;;; Sources + +;;;###autoload (autoload 'emms-play-file "emms-source-file" t) +;;;###autoload (autoload 'emms-add-file "emms-source-file" t) +(define-emms-source file (file) + "An EMMS source for a single file - either FILE, or queried from the +user." + (interactive (list (read-file-name "Play file: " + emms-source-file-default-directory + emms-source-file-default-directory + t))) + (if (file-directory-p file) + (emms-source-directory file) + (list (emms-track 'file (expand-file-name file))))) + +;;;###autoload (autoload 'emms-play-directory "emms-source-file" t) +;;;###autoload (autoload 'emms-add-directory "emms-source-file" t) +(define-emms-source directory (dir) + "An EMMS source for a whole directory tree - either DIR, or queried +from the user" + (interactive (list + (emms-read-directory-name "Play directory: " + emms-source-file-default-directory + emms-source-file-default-directory + t))) + (mapcar (lambda (file) + (emms-track 'file (expand-file-name file))) + (directory-files dir t (emms-source-file-regex)))) + +;;;###autoload (autoload 'emms-play-directory-tree "emms-source-file" t) +;;;###autoload (autoload 'emms-add-directory-tree "emms-source-file" t) +(define-emms-source directory-tree (dir) + "An EMMS source for multiple directory trees - either DIR, or the +value of `emms-source-file-default-directory'." + (interactive (list + (emms-read-directory-name "Play directory tree: " + emms-source-file-default-directory + emms-source-file-default-directory + t))) + (mapcar (lambda (file) + (emms-track 'file file)) + (emms-source-file-directory-tree (expand-file-name dir) + (emms-source-file-regex)))) + + +;;;###autoload (autoload 'emms-play-find "emms-source-file" t) +;;;###autoload (autoload 'emms-add-find "emms-source-file" t) +(define-emms-source find (dir regex) + "An EMMS source that will find files in DIR or +`emms-source-file-default-directory' that match REGEXP." + (interactive (list + (emms-read-directory-name "Find in directory: " + emms-source-file-default-directory + emms-source-file-default-directory + t) + (read-from-minibuffer "Find files matching: "))) + (mapcar (lambda (file) + (emms-track 'file file)) + (emms-source-file-directory-tree dir regex))) + + +;;;###autoload (autoload 'emms-play-m3u-playlist "emms-source-file" t) +;;;###autoload (autoload 'emms-add-m3u-playlist "emms-source-file" t) +(define-emms-source m3u-playlist (playlist) + "A source for simple .m3u playlists. It ignores empty lines, or +lines starting with '#'." + (interactive (list (read-file-name "Play file: " + emms-source-file-default-directory + emms-source-file-default-directory + t))) + (emms-source-files + (let ((files '()) + (dir (file-name-directory playlist))) + (with-temp-buffer + (insert-file-contents playlist) + (goto-char (point-min)) + (while (re-search-forward "^[^# ].*$" nil t) + (let ((line (match-string 0))) + (setq files (cons (if (file-name-absolute-p line) + line + (concat dir line)) + files))))) + (reverse files)))) + + +;;; Helper functions + +;;;###autoload +(defun emms-source-file-directory-tree (dir regex) + "Return a list of all files under DIR that match REGEX. +This function uses `emms-source-file-directory-tree-function'." + (message "Building playlist...") + (let ((pl (funcall emms-source-file-directory-tree-function + dir + regex))) + (message "Building playlist...done") + pl)) + +(defun emms-source-file-directory-tree-internal (dir regex) + "Return a list of all files under DIR that match REGEX. +This function uses only emacs functions, so it might be a bit slow." + (let ((files '()) + (dirs (list dir))) + (while dirs + (cond + ((file-directory-p (car dirs)) + (if (string-match "/\\.\\.?$" (car dirs)) + (setq dirs (cdr dirs)) + (setq dirs + (condition-case nil + (append (cdr dirs) + (directory-files (car dirs) + t nil t)) + (error + (cdr dirs)))))) + ((string-match regex (car dirs)) + (setq files (cons (car dirs) files) + dirs (cdr dirs))) + (t + (setq dirs (cdr dirs))))) + files)) + +(defun emms-source-file-directory-tree-find (dir regex) + "Return a list of all files under DIR that match REGEX. +This function uses the external find utility. The name for GNU find +may be supplied using `emms-source-file-gnu-find'." + (with-temp-buffer + (call-process emms-source-file-gnu-find + nil t nil + (expand-file-name dir) + "-type" "f" + "-iregex" (concat ".*\\(" regex "\\).*")) + (delete "" + (split-string (buffer-substring (point-min) + (point-max)) + "\n")))) + +;;;###autoload +(defun emms-source-files (files) + "An EMMS source for a list of FILES." + (apply #'append (mapcar #'emms-source-file files))) + +;;;###autoload +(defun emms-source-dired () + "Return all marked files of a dired buffer" + (emms-source-files (dired-get-marked-files))) + +;;;###autoload +(defun emms-source-file-regex () + "Return a regexp that matches everything any player (that supports +files) can play." + (mapconcat (lambda (player) + (or (emms-player-get player 'regex) + "")) + emms-player-list + "\\|")) + +;; Really don't know where to put this, but as the functions for +;; important and playing a playlist are in ths file i suppose it a +;; good place for it. + +(defun emms-save-playlist (filename) + "Export the current playlist as to FILENAME. See also: +`emms-pbi-import-playlist'." + (interactive "FFile to save playlist as: ") + (with-temp-file filename + (mapc (lambda (elt) (insert (cdr (assoc 'name elt)) "\n")) emms-playlist))) + +;; emms-locate should be part of a once to be emms-dired, with maybe +;; file rename after tag functions and so on, but till then i park it +;; here... :) + +;;;###autoload +(defun emms-locate (regexp) + "Search for REGEXP and display the results in a locate buffer" + (interactive "sRegexp to search for: ") + (require 'locate) + (save-window-excursion + (set-buffer (get-buffer-create "*EMMS Find*")) + (locate-mode) + (erase-buffer) + (mapc (lambda (elt) (insert (cdr (assoc 'name elt)) "\n")) + (emms-source-find emms-source-file-default-directory regexp)) + (locate-do-setup regexp)) + (and (not (string-equal (buffer-name) "*EMMS Find*")) + (switch-to-buffer-other-window "*EMMS Find*")) + (run-hooks 'dired-mode-hook) + (dired-next-line 2)) + +;; Strictly speaking, this does not belong in this file (URLs are not +;; real files), but it's close enough :-) + +;;;###autoload (autoload 'emms-play-url "emms-source-file" t) +;;;###autoload (autoload 'emms-add-url "emms-source-file" t) +(define-emms-source url (url) + "An EMMS source for an URL - for example, for streaming." + (interactive "sPlay URL: ") + (list (emms-track 'url url))) + +(define-emms-source playlist (playlist) + "An EMMS source for streaming playlists (usually URLs ending in .pls." + (interactive "sPlay URL: ") + (list (emms-track 'playlist playlist))) + + +(provide 'emms-source-file) +;;; emms-source-file.el ends here |