mpc-bar

macOS menu bar client for the Music Player Daemon
Log | Files | Refs | README | LICENSE

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 }