| 1 | ;;; emms-info.el --- Retrieving track information -*- lexical-binding: t; -*- |
| 2 | |
| 3 | ;; Copyright (C) 2005-2024 Free Software Foundation, Inc. |
| 4 | |
| 5 | ;; Author: Jorgen Schaefer <forcer@forcix.cx> |
| 6 | |
| 7 | ;; This file is part of EMMS. |
| 8 | |
| 9 | ;; EMMS is free software; you can redistribute it and/or |
| 10 | ;; modify it under the terms of the GNU General Public License |
| 11 | ;; as published by the Free Software Foundation; either version 3 |
| 12 | ;; of the License, or (at your option) any later version. |
| 13 | |
| 14 | ;; EMMS is distributed in the hope that it will be useful, |
| 15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 17 | ;; GNU General Public License for more details. |
| 18 | |
| 19 | ;; You should have received a copy of the GNU General Public License |
| 20 | ;; along with EMMS; if not, write to the Free Software |
| 21 | ;; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA |
| 22 | ;; 02110-1301, USA. |
| 23 | |
| 24 | ;;; Commentary: |
| 25 | |
| 26 | ;; This EMMS module provides a way to add information for a track. |
| 27 | ;; This can use an ID3 or OGG comment like syntax. |
| 28 | |
| 29 | ;; The code will add info symbols to the track. The following symbols |
| 30 | ;; are defined: |
| 31 | |
| 32 | ;; info-artist - string naming the artist |
| 33 | ;; info-composer - string naming the composer |
| 34 | ;; info-performer - string naming the performer |
| 35 | ;; info-title - string naming the title of the song |
| 36 | ;; info-album - string naming the album |
| 37 | ;; info-tracknumber - string(?) naming the track number |
| 38 | ;; info-discnumber - string naming the disc number |
| 39 | ;; info-year - string naming the year |
| 40 | ;; info-note - string of free-form entry |
| 41 | ;; info-genre - string naming the genre |
| 42 | ;; info-playing-time - number giving the seconds of playtime |
| 43 | |
| 44 | ;;; Code: |
| 45 | |
| 46 | (require 'emms) |
| 47 | (require 'emms-later-do) |
| 48 | |
| 49 | (defgroup emms-info nil |
| 50 | "*Track information. ID3, OGG, etc." |
| 51 | :group 'emms) |
| 52 | |
| 53 | (defcustom emms-info-auto-update t |
| 54 | "Non-nil when EMMS should update track information if the file changes. |
| 55 | This will cause hard drive activity on track loading. If this is |
| 56 | too annoying for you, set this variable to nil." |
| 57 | :type 'boolean) |
| 58 | |
| 59 | (defcustom emms-info-asynchronously t |
| 60 | "Non-nil when track information should be loaded asynchronously." |
| 61 | :type 'boolean) |
| 62 | |
| 63 | (defcustom emms-info-report-each-num-tracks 200 |
| 64 | "Non-zero will report progress information every number of tracks. |
| 65 | The default is to display a message every 200 tracks. |
| 66 | This variable is only used when adding tracks asynchronously." |
| 67 | :type 'integer) |
| 68 | |
| 69 | (defcustom emms-info-functions nil |
| 70 | "Functions which add information to tracks. |
| 71 | Each is called with a track as argument." |
| 72 | :type 'hook) |
| 73 | |
| 74 | (defcustom emms-info-init-done-hook nil |
| 75 | "Called after asynchronously initializing all tracks." |
| 76 | :type 'hook) |
| 77 | |
| 78 | (defvar emms-info-asynchronous-tracks 0 |
| 79 | "Number of tracks we're waiting for to be done.") |
| 80 | |
| 81 | (defun emms-info-initialize-track (track &optional force) |
| 82 | "Initialize TRACK with emms-info information. |
| 83 | Update TRACK information if it is new or has been modified since |
| 84 | last update, or if FORCE is non-nil. |
| 85 | |
| 86 | This is a suitable value for `emms-track-initialize-functions'." |
| 87 | (if (not emms-info-asynchronously) |
| 88 | (emms-info-really-initialize-track track force) |
| 89 | (setq emms-info-asynchronous-tracks (1+ emms-info-asynchronous-tracks)) |
| 90 | (emms-later-do 'emms-info-really-initialize-track track force))) |
| 91 | |
| 92 | (defun emms-info-really-initialize-track (track &optional force) |
| 93 | "Really initialize TRACK. |
| 94 | Return t when the track got changed." |
| 95 | (let ((file-mtime (when emms-info-auto-update |
| 96 | (emms-info-track-file-mtime track))) |
| 97 | (info-mtime (emms-track-get track 'info-mtime))) |
| 98 | |
| 99 | ;; if the file's been modified or is new |
| 100 | (when (or (not file-mtime) |
| 101 | (not info-mtime) |
| 102 | (emms-time-less-p info-mtime file-mtime) |
| 103 | force) |
| 104 | (run-hook-with-args 'emms-info-functions track) |
| 105 | ;; not set by info functions |
| 106 | (when file-mtime |
| 107 | (emms-track-set track 'info-mtime file-mtime)) |
| 108 | (emms-track-updated track)) |
| 109 | |
| 110 | (when emms-info-asynchronously |
| 111 | (setq emms-info-asynchronous-tracks (1- emms-info-asynchronous-tracks)) |
| 112 | (if (zerop emms-info-asynchronous-tracks) |
| 113 | (progn |
| 114 | (run-hook-with-args 'emms-info-init-done-hook) |
| 115 | (message "EMMS: All track information loaded.")) |
| 116 | (unless (zerop emms-info-report-each-num-tracks) |
| 117 | (if (zerop |
| 118 | (mod emms-info-asynchronous-tracks |
| 119 | emms-info-report-each-num-tracks)) |
| 120 | (message "EMMS: %d tracks to go.." |
| 121 | emms-info-asynchronous-tracks))))))) |
| 122 | |
| 123 | (defun emms-info-track-file-mtime (track) |
| 124 | "Return the mtime of the file of TRACK, if any. |
| 125 | Return nil otherwise." |
| 126 | (if (eq (emms-track-type track) |
| 127 | 'file) |
| 128 | (nth 5 (file-attributes (emms-track-name track))) |
| 129 | nil)) |
| 130 | |
| 131 | (defun emms-info-track-description (track) |
| 132 | "Return a description of TRACK." |
| 133 | (let ((artist (emms-track-get track 'info-artist)) |
| 134 | (album (emms-track-get track 'info-album)) |
| 135 | (composer (emms-track-get track 'info-composer)) |
| 136 | (title (emms-track-get track 'info-title))) |
| 137 | (cond |
| 138 | ((and composer artist title album) |
| 139 | (concat (if (string= composer artist) |
| 140 | artist |
| 141 | (concat artist " - " composer)) |
| 142 | " - " album " - " title)) |
| 143 | ((and artist title album) |
| 144 | (concat artist " - " album " - " title)) |
| 145 | ((and artist title) |
| 146 | (concat artist " - " title)) |
| 147 | (title |
| 148 | title) |
| 149 | (t |
| 150 | (emms-track-simple-description track))))) |
| 151 | |
| 152 | (provide 'emms-info) |
| 153 | ;;; emms-info.el ends here |