aboutsummaryrefslogtreecommitdiff
path: root/emms-mp3tag.el
diff options
context:
space:
mode:
authorMichael Olson <mwolson@gnu.org>2006-12-07 14:19:00 +0000
committerMichael Olson <mwolson@gnu.org>2006-12-07 14:19:00 +0000
commite73db75f5474190399ab6d340cc9c8e0a8e78d6c (patch)
tree9ee0d04be4f13c1bb6189906ad5f040dabe9b5df /emms-mp3tag.el
parent2adff3ed4e9dabb25680880df66b7e67b9f635bb (diff)
Rename emms-mp3tag.el to emms-tag-editor.el
darcs-hash:20061207141945-1bfb2-bec40763ab0162499c3829e073717915ba509653.gz
Diffstat (limited to 'emms-mp3tag.el')
-rw-r--r--emms-mp3tag.el400
1 files changed, 0 insertions, 400 deletions
diff --git a/emms-mp3tag.el b/emms-mp3tag.el
deleted file mode 100644
index 8580393..0000000
--- a/emms-mp3tag.el
+++ /dev/null
@@ -1,400 +0,0 @@
-;;; emms-mp3tag.el --- Edit track tags.
-
-;; Copyright 2006 Ye Wenbin
-;;
-;; Author: wenbinye@163.com
-;; Keywords:
-;; X-URL: not distributed yet
-
-;; This program 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 program 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 this program; if not, write to the Free Software
-;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Commentary:
-
-;;
-
-;; Put this file into your load-path and the following into your ~/.emacs:
-;; (require 'emms-mp3tag)
-
-;;; Code:
-
-(provide 'emms-mp3tag)
-(eval-when-compile
- (require 'cl))
-(require 'emms)
-(require 'emms-info-mp3info)
-(require 'emms-playlist-mode)
-(require 'emms-mark)
-(require 'format-spec)
-
-(defvar emms-mp3tag-tags
- '((info-artist . "a")
- (info-title . "t")
- (info-album . "l")
- (info-tracknumber . "n")
- (info-year . "y")
- (info-genre . "g")
- (info-date . "d")
- (info-note . "c"))
-"A list to setup format.")
-
-(defvar emms-mp3tag-edit-buffer "*EMMS-TAGS*"
- "Buffer name to edit mp3 tags")
-(defvar emms-mp3tag-log-buffer "*EMMS-LOG*"
- "Buffer name of mp3tag edit log")
-
-(defun emms-mp3tag-make-format (tags)
- (format "%%m\n%-16s = %%f\n%s\n\n" "name"
- (mapconcat
- (lambda (tag)
- (concat (propertize (format "%-16s = " (symbol-name tag))
- 'read-only t 'rear-nonsticky t 'face 'bold)
- "%" (cdr (assoc tag emms-mp3tag-tags))))
- tags "\n")))
-
-(defvar emms-mp3tag-formats
- (let* ((tags (mapcar 'car emms-mp3tag-tags))
- (default (emms-mp3tag-make-format (remove 'info-date tags))))
- `(("mp3" . ,default)
- ("ogg" . ,(emms-mp3tag-make-format (remove 'info-year tags)))
- ("default" . ,default)))
- "Format to insert the track. The CAR part is the extension of the
-track name, and the CDR part is the format template. The format
-specification is like:
- m -- Track description
- f -- Track name
- a -- Track info-artist
- t -- Track info-title
- l -- Track info-album
- n -- Track info-tracknumber
- y -- Track info-year
- g -- Track info-genre
- c -- Track info-note
-
-You can add new specification in `emms-mp3tag-tags' and use
-`emms-mp3tag-make-format' to help create a new format.
-
-The CDR part also can be a function, which accept one parameter, the
-track, and should return a string to insert to `emms-mp3tag-edit-buffer'.
-")
-
-(defvar emms-mp3tag-get-format-function 'emms-mp3tag-get-format
- "Function to decide which format to use for format the track.")
-
-(defvar emms-mp3tag-parse-function 'emms-mp3tag-default-parser
- "Function to parse tags in `emms-mp3tag-edit-buffer'. It should find
-all modified tags, and return all the tracks. The tracks which tag has
-been modified should set a property 'tag-modified to t, and if the
-track name have been change, the function should set a new property
-'newname instead set the 'name directly.
-
-See also `emms-mp3tag-default-parser'.")
-
-(defvar emms-mp3tag-tagfile-functions
- '(("mp3" "mp3info"
- ((info-artist . "a")
- (info-title . "t")
- (info-album . "l")
- (info-tracknumber . "n")
- (info-year . "y")
- (info-genre . "g")
- (info-note . "c")))
- ("ogg" . emms-mp3tag-tag-ogg))
- "A List for change tag in files. If the extern program set tag by
-command line options one by one such as mp3info, the list should like:
- (EXTENSION PROGRAM COMMAND_LINE_OPTIONS)
-
-Otherwise, a function that accept a parameter, the track, should be
-given.
-
-See also `emms-mp3tag-tag-file' and `emms-mp3tag-tag-ogg'.
-")
-
-(defun emms-mp3tag-tag-ogg (track)
- (call-process "vorbiscomment" nil nil nil
- "-w" "-t"
- (mapconcat
- (lambda (tag)
- (concat tag "="
- (emms-track-get track (intern (concat "info-" tag)))))
- '("artist" "title" "album" "tracknumber" "date" "genre" "note")
- "\n\t")
- (emms-track-name track)))
-
-(defun emms-mp3tag-tag-file (track program tags)
- "Change tag in FILE use PROGRAM. The TAGS is given in `emms-mp3tag-tagfile-functions'."
- (let (args val)
- (mapc (lambda (tag)
- (when (> (length (setq val (emms-track-get track (car tag)))) 0)
- (setq args (append args (list (concat "-" (cdr tag)) val)))))
- tags)
- (apply 'call-process program
- nil nil nil
- filename args)))
-
-(defun emms-mp3tag-get-format (track)
- (let ((format
- (assoc (file-name-extension (emms-track-name track))
- emms-mp3tag-formats)))
- (if format
- (cdr format)
- (cdr (assoc "default" emms-mp3tag-formats)))))
-
-(defun emms-mp3tag-format-track (track)
- (let ((format (funcall emms-mp3tag-get-format-function track)))
- (if (functionp format)
- (funcall format track)
- (format-spec
- format
- (apply 'format-spec-make
- ?m (emms-propertize (emms-track-force-description track)
- 'face 'emms-playlist-track-face
- 'emms-track (copy-sequence track))
- ?f (emms-track-name track)
- (apply 'append
- (mapcar (lambda (tag)
- (list (string-to-char (cdr tag))
- (or (emms-track-get track (car tag)) "")))
- emms-mp3tag-tags)))))))
-
-(defun emms-mp3tag-track-at (&optional pos)
- (let ((track (emms-playlist-track-at pos))
- newtrack)
- (when track
- (setq newtrack (copy-sequence track))
- (emms-track-set newtrack 'position (point-marker))
- (emms-track-set newtrack 'orig-track track)
- newtrack)))
-
-(defsubst emms-mp3tag-erase-buffer (&optional buf)
- (let ((inhibit-read-only t))
- (save-excursion
- (set-buffer (get-buffer-create buf))
- (erase-buffer))))
-
-(defsubst emms-mp3tag-insert-track (track)
- (and track
- (insert (emms-mp3tag-format-track track))))
-
-(defsubst emms-mp3tag-display-log-buffer-maybe ()
- (if (> (buffer-size (get-buffer emms-mp3tag-log-buffer)) 0)
- (display-buffer emms-mp3tag-log-buffer)))
-
-(defun emms-mp3tag-insert-tracks (tracks)
- (save-excursion
- (emms-mp3tag-erase-buffer emms-mp3tag-log-buffer)
- (emms-mp3tag-erase-buffer emms-mp3tag-edit-buffer)
- (set-buffer (get-buffer emms-mp3tag-edit-buffer))
- (mapc 'emms-mp3tag-insert-track tracks)
- (emms-mp3tag-mode)
- (pop-to-buffer (current-buffer))
- (goto-char (point-min))
- (emms-mp3tag-display-log-buffer-maybe)))
-
-(defun emms-mp3tag-edit-track (track)
- (interactive (list (emms-mp3tag-track-at)))
- (if (null track)
- (message "No track at point!")
- (emms-mp3tag-insert-tracks (list track))))
-
-(defun emms-mp3tag-edit-marked-tracks ()
- (interactive)
- (let ((tracks (emms-mark-mapcar-marked-track 'emms-mp3tag-track-at t)))
- (if (null tracks)
- (message "No track marked!")
- (emms-mp3tag-insert-tracks tracks))))
-
-(defun emms-mp3tag-edit ()
- "Edit tags of track at point or marked tracks"
- (interactive)
- (if (emms-mark-has-markedp)
- (emms-mp3tag-edit-marked-tracks)
- (emms-mp3tag-edit-track (emms-mp3tag-track-at))))
-
-(defvar emms-mp3tag-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map [tab] 'emms-mp3tag-next-field)
- (define-key map [backtab] 'emms-mp3tag-prev-field)
- (define-key map "\C-c\C-n" 'emms-mp3tag-next-track)
- (define-key map "\C-c\C-p" 'emms-mp3tag-prev-track)
- (define-key map "\C-c\C-c" 'emms-mp3tag-submit-and-exit)
- (define-key map "\C-c\C-s" 'emms-mp3tag-submit)
- (define-key map "\C-c\C-r" 'emms-mp3tag-replace-all)
- map))
-(define-key emms-playlist-mode-map "E" 'emms-mp3tag-edit)
-
-(define-derived-mode emms-mp3tag-mode text-mode "Mp3tag"
- "Major mode to edit track tags.
-\\{emms-mp3tag-mode-map}")
-
-(defun emms-mp3tag-replace-all (name value)
- "Replace all track's NAME to VALUE. If turn transient-mark-mode on,
-you can apply the command to a selected region."
- (interactive
- (list (completing-read "Replace tag: "
- emms-mp3tag-tags nil t)
- (read-from-minibuffer "Set tag to: ")))
- (save-excursion
- (save-restriction
- (if (and mark-active transient-mark-mode)
- (narrow-to-region (region-beginning) (region-end)))
- (goto-char (point-min))
- (while (re-search-forward (concat "^" (regexp-quote name)) nil t)
- (skip-chars-forward " \t=")
- (delete-region (point) (line-end-position))
- (insert value)))))
-
-(defun emms-mp3tag-next-field (arg)
- (interactive "p")
- (if (> arg 0)
- (re-search-forward "\\s-*=[ \t]*" nil nil arg)
- (emms-mp3tag-prev-field (- arg))))
-
-(defun emms-mp3tag-prev-field (arg)
- (interactive "p")
- (if (< arg 0)
- (emms-mp3tag-next-field (- arg))
- (skip-chars-backward " \t=")
- (re-search-backward "\\s-*=[ \t]*" nil nil arg)
- (skip-chars-forward " \t=")))
-
-(defun emms-mp3tag-prev-track ()
- (interactive)
- (let ((prev (previous-single-property-change (point)
- 'emms-track)))
- (when (not prev)
- (error "No previous track"))
- (when (not (get-text-property prev 'emms-track))
- (setq prev (or (previous-single-property-change prev 'emms-track)
- (point-min))))
- (when (or (not prev)
- (not (get-text-property prev 'emms-track)))
- (error "No previous track"))
- (goto-char prev)))
-
-(defun emms-mp3tag-next-track ()
- (interactive)
- (let ((next (next-single-property-change (point)
- 'emms-track)))
- (when (not next)
- (error "No next track"))
- (when (not (get-text-property next 'emms-track))
- (setq next (next-single-property-change next 'emms-track)))
- (when (or (not next)
- (= next (point-max)))
- (error "No next track"))
- (goto-char next)))
-
-(defun emms-mp3tag-submit (arg)
- "Make modified tags take affect. With prefiex argument, bury tag
-edit buffer."
- (interactive "P")
- (let ((tracks (funcall emms-mp3tag-parse-function))
- filename func exit old pos val need-sync)
- (if (not (and tracks (y-or-n-p "Submit changes? ")))
- (message "Nothing have to do!")
- (emms-mp3tag-erase-buffer emms-mp3tag-log-buffer)
- (message "Wait while set tags...")
- (save-excursion
- (dolist (track tracks)
- (when (emms-track-get track 'tag-modified)
- (setq filename (emms-track-name track)
- old (emms-track-get track 'orig-track))
- ;; rename local file
- (when (and (emms-track-get track 'newname)
- (eq (emms-track-get track 'type) 'file)
- (file-writable-p (emms-track-name track)))
- (setq filename (emms-track-get track 'newname))
- (rename-file (emms-track-name track) filename)
- (emms-track-set old 'name filename)
- ;; for re-enter this function
- (emms-track-set track 'newname nil)
- (emms-track-set track 'name filename)
- (setq need-sync t)
- ;; register to emms-cache-db
- (funcall emms-cache-modified-function)
- (funcall emms-cache-set-function filename 'file old))
- ;; set tags to original track
- (dolist (tag emms-mp3tag-tags)
- (when (setq val (emms-track-get track (car tag)))
- (emms-track-set old (car tag) val)))
- ;; use mp3info to change tag in mp3 file
- (when (and (eq (emms-track-get track 'type) 'file)
- (file-writable-p (emms-track-name track))
- (setq func (assoc (file-name-extension filename) emms-mp3tag-tagfile-functions)))
- (setq exit
- (if (functionp (cdr func))
- (funcall (cdr func) track)
- (emms-mp3tag-tag-file track (cadr func) (nth 2 func))))
- (if (zerop exit)
- (emms-track-get track 'info-mtime (butlast (current-time)))
- (emms-mp3tag-log "Change tags of %s failed with exit value %d" filename exit)))
- ;; update track in playlist
- (when (and (setq pos (emms-track-get track 'position))
- (marker-position pos))
- (set-buffer (marker-buffer pos))
- (goto-char pos)
- (funcall emms-playlist-update-track-function))
- ;; clear modified tag
- (emms-track-set track 'tag-modified nil))))
- (if (and need-sync (y-or-n-p "You have change some track names, sync the cache? "))
- (emms-cache-sync))
- (emms-mp3tag-display-log-buffer-maybe)
- (message "Set all mp3 tag done!")))
- (if arg (bury-buffer)))
-
-(defun emms-mp3tag-submit-and-exit ()
- (interactive)
- (emms-mp3tag-submit t))
-
-(defun emms-mp3tag-default-parser ()
- (let (next tracks track key val)
- (goto-char (point-min))
- (if (get-text-property (point) 'emms-track)
- (setq next (point))
- (setq next (next-single-property-change (point)
- 'emms-track)))
- (when next
- (while
- (progn
- (goto-char next)
- (setq track (get-text-property (point) 'emms-track))
- (forward-line 1)
- (mapc (lambda (pair)
- (when (string-match "\\s-*=\\s-*" pair)
- (setq key (intern-soft (substring pair 0 (match-beginning 0)))
- val (substring pair (match-end 0)))
- (when (and key
- (> (length val) 0)
- (not (string= val (emms-track-get track key))))
- (if (eq key 'name)
- (emms-track-set track 'newname val)
- (emms-track-set track key val))
- (emms-track-set track 'tag-modified t))))
- (split-string (buffer-substring (point)
- (or
- (setq next (next-single-property-change (point) 'emms-track))
- (point-max)))
- "\n"))
- (if (emms-track-get track 'tag-modified)
- (push track tracks))
- next))
- tracks)))
-
-(defun emms-mp3tag-log (&rest args)
- (with-current-buffer (get-buffer-create emms-mp3tag-log-buffer)
- (goto-char (point-max))
- (insert (apply 'format args) "\n")))
-
-;;; emms-mp3tagedit.el ends here