| 1 | ;;; emms-last-played.el --- Support for last-played-time of a track -*- lexical-binding: t; -*- |
| 2 | |
| 3 | ;; Copyright (C) 2006-2021 Free Software Foundation, Inc. |
| 4 | |
| 5 | ;; Author: Lucas Bonnet <lucas@rincevent.net> |
| 6 | ;; Keywords: emms, mp3, mpeg, multimedia |
| 7 | |
| 8 | ;; This file is part of EMMS. |
| 9 | |
| 10 | ;; EMMS is free software; you can redistribute it and/or modify |
| 11 | ;; it under the terms of the GNU General Public License as published by |
| 12 | ;; the Free Software Foundation; either version 3, or (at your option) |
| 13 | ;; any later version. |
| 14 | |
| 15 | ;; EMMS is distributed in the hope that it will be useful, |
| 16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 18 | ;; GNU General Public License for more details. |
| 19 | |
| 20 | ;; You should have received a copy of the GNU General Public License |
| 21 | ;; along with EMMS; see the file COPYING. If not, write to the |
| 22 | ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 23 | ;; Boston, MA 02110-1301, USA. |
| 24 | |
| 25 | ;;; Commentary: |
| 26 | |
| 27 | ;; Records when the track was last played. |
| 28 | ;; Big portions of the time handling fuctions are copied from |
| 29 | ;; gnus-util.el, and slightly adapted. |
| 30 | |
| 31 | ;;; Code: |
| 32 | |
| 33 | (require 'emms) |
| 34 | |
| 35 | (defvar emms-last-played-keep-count t |
| 36 | "Specifies if EMMS should record the number of times you play a track. |
| 37 | Set it to t if you want such a feature, and to nil if you don't.") |
| 38 | |
| 39 | (defvar emms-last-played-format-alist |
| 40 | '(((emms-last-played-seconds-today) . "%k:%M") |
| 41 | (604800 . "%a %k:%M") ;;that's one week |
| 42 | ((emms-last-played-seconds-month) . "%a %d") |
| 43 | ((emms-last-played-seconds-year) . "%b %d") |
| 44 | (t . "%b %d '%y")) ;;this one is used when no |
| 45 | ;;other does match |
| 46 | "Specifies date format depending on when a track was last played. |
| 47 | This is an alist of items (AGE . FORMAT). AGE can be a number (of |
| 48 | seconds) or a Lisp expression evaluating to a number. When the age of |
| 49 | the track is less than this number, then use `format-time-string' |
| 50 | with the corresponding FORMAT for displaying the date of the track. |
| 51 | If AGE is not a number or a Lisp expression evaluating to a |
| 52 | non-number, then the corresponding FORMAT is used as a default value. |
| 53 | |
| 54 | Note that the list is processed from the beginning, so it should be |
| 55 | sorted by ascending AGE. Also note that items following the first |
| 56 | non-number AGE will be ignored. |
| 57 | |
| 58 | You can use the functions `emms-last-played-seconds-today', |
| 59 | `emms-last-played-seconds-month' and |
| 60 | `emms-last-played-seconds-year' in the AGE spec. They return the |
| 61 | number of seconds passed since the start of today, of this month, |
| 62 | of this year, respectively.") |
| 63 | |
| 64 | |
| 65 | (defun emms-last-played-update-track (track) |
| 66 | "Updates the last-played time of TRACK." |
| 67 | (emms-track-set track 'last-played (current-time))) |
| 68 | |
| 69 | (defun emms-last-played-increment-count (track) |
| 70 | "Increments the play-count property of TRACK. |
| 71 | If non-existent, it is set to 1." |
| 72 | (let ((play-count (emms-track-get track 'play-count))) |
| 73 | (if play-count |
| 74 | (emms-track-set track 'play-count (1+ play-count)) |
| 75 | (emms-track-set track 'play-count 1)))) |
| 76 | |
| 77 | (defun emms-last-played-update-current () |
| 78 | "Updates the current track." |
| 79 | (emms-last-played-update-track (emms-playlist-current-selected-track)) |
| 80 | (if emms-last-played-keep-count |
| 81 | (emms-last-played-increment-count (emms-playlist-current-selected-track)))) |
| 82 | |
| 83 | (defun emms-last-played-seconds-today () |
| 84 | "Return the number of seconds passed today." |
| 85 | (let ((now (decode-time (current-time)))) |
| 86 | (+ (car now) (* (car (cdr now)) 60) (* (car (nthcdr 2 now)) 3600)))) |
| 87 | |
| 88 | (defun emms-last-played-seconds-month () |
| 89 | "Return the number of seconds passed this month." |
| 90 | (let ((now (decode-time (current-time)))) |
| 91 | (+ (car now) (* (car (cdr now)) 60) (* (car (nthcdr 2 now)) 3600) |
| 92 | (* (- (car (nthcdr 3 now)) 1) 3600 24)))) |
| 93 | |
| 94 | (defun emms-last-played-seconds-year () |
| 95 | "Return the number of seconds passed this year." |
| 96 | (let ((now (decode-time (current-time))) |
| 97 | (days (format-time-string "%j" (current-time)))) |
| 98 | (+ (car now) (* (car (cdr now)) 60) (* (car (nthcdr 2 now)) 3600) |
| 99 | (* (- (string-to-number days) 1) 3600 24)))) |
| 100 | |
| 101 | (defun emms-last-played-format-date (messy-date) |
| 102 | "Format the messy-date according to `emms-last-played-format-alist'. |
| 103 | Returns \" ? \" if there's bad input or if an other error occurs. |
| 104 | Input should look like this: \"Sun, 14 Oct 2001 13:34:39 +0200\"." |
| 105 | (condition-case () |
| 106 | (let* ((messy-date (float-time messy-date)) |
| 107 | (now (float-time (current-time))) |
| 108 | ;;If we don't find something suitable we'll use this one |
| 109 | (my-format "%b %d '%y")) |
| 110 | (let* ((difference (- now messy-date)) |
| 111 | (templist emms-last-played-format-alist) |
| 112 | (top (eval (caar templist) t))) |
| 113 | (while (if (numberp top) (< top difference) (not top)) |
| 114 | (progn |
| 115 | (setq templist (cdr templist)) |
| 116 | (setq top (eval (caar templist) t)))) |
| 117 | (if (stringp (cdr (car templist))) |
| 118 | (setq my-format (cdr (car templist))))) |
| 119 | (format-time-string (eval my-format t) (seconds-to-time messy-date))) |
| 120 | (error "Never."))) |
| 121 | |
| 122 | (provide 'emms-last-played) |
| 123 | ;;; emms-last-played.el ends here |