song_format.c (2719B)
1 // SPDX-License-Identifier: GPL-2.0-or-later 2 // Copyright The Music Player Daemon Project 3 4 #include "song_format.h" 5 #include "audio_format.h" 6 #include "format.h" 7 #include "charset.h" 8 9 #include <mpd/client.h> 10 11 #include <stdio.h> 12 #include <string.h> 13 #include <stdlib.h> 14 15 static const char * 16 format_mtime(char *buffer, size_t buffer_size, 17 const struct mpd_song *song, const char *format) 18 { 19 time_t t = mpd_song_get_last_modified(song); 20 if (t == 0) 21 return NULL; 22 23 struct tm tm; 24 #ifdef _WIN32 25 tm = *localtime(&t); 26 #else 27 localtime_r(&t, &tm); 28 #endif 29 30 strftime(buffer, buffer_size, format, &tm); 31 return buffer; 32 } 33 34 /** 35 * Extract an attribute from a song object. 36 * 37 * @param song the song object 38 * @param name the attribute name 39 * @return the attribute value; NULL if the attribute name is invalid; 40 * an empty string if the attribute name is valid, but not present in 41 * the song 42 */ 43 gcc_pure 44 static const char * 45 song_value(const struct mpd_song *song, const char *name) 46 { 47 static char buffer[40]; 48 const char *value; 49 50 if (strcmp(name, "file") == 0) 51 value = mpd_song_get_uri(song); 52 else if (strcmp(name, "time") == 0) { 53 unsigned duration = mpd_song_get_duration(song); 54 55 if (duration > 0) { 56 snprintf(buffer, sizeof(buffer), "%u:%02u", 57 duration / 60, duration % 60); 58 value = buffer; 59 } else 60 value = NULL; 61 } else if (strcmp(name, "position") == 0) { 62 unsigned pos = mpd_song_get_pos(song); 63 snprintf(buffer, sizeof(buffer), "%u", pos+1); 64 value = buffer; 65 } else if (strcmp(name, "id") == 0) { 66 snprintf(buffer, sizeof(buffer), "%u", mpd_song_get_id(song)); 67 value = buffer; 68 } else if (strcmp(name, "prio") == 0) { 69 snprintf(buffer, sizeof(buffer), "%u", 70 mpd_song_get_prio(song)); 71 value = buffer; 72 } else if (strcmp(name, "mtime") == 0) { 73 value = format_mtime(buffer, sizeof(buffer), song, "%c"); 74 } else if (strcmp(name, "mdate") == 0) { 75 value = format_mtime(buffer, sizeof(buffer), song, "%x"); 76 } else if (strcmp(name, "audioformat") == 0) { 77 const struct mpd_audio_format *audio_format = mpd_song_get_audio_format(song); 78 if (audio_format == NULL) 79 return NULL; 80 81 format_audio_format(buffer, sizeof(buffer), audio_format); 82 value = buffer; 83 } else { 84 enum mpd_tag_type tag_type = mpd_tag_name_iparse(name); 85 if (tag_type == MPD_TAG_UNKNOWN) 86 return NULL; 87 88 value = mpd_song_get_tag(song, tag_type, 0); 89 } 90 91 if (value != NULL) 92 value = charset_from_utf8(value); 93 else 94 value = ""; 95 96 return value; 97 } 98 99 static const char * 100 song_getter(const void *object, const char *name) 101 { 102 return song_value((const struct mpd_song *)object, name); 103 } 104 105 char * 106 format_song(const struct mpd_song *song, const char *format) 107 { 108 return format_object(format, song, song_getter); 109 }