From 25448507c67822a3fa3433eebcb35a784bfe5be2 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Wed, 19 Jun 2024 10:32:18 +0200 Subject: support custom format at build time... ... and drop the option for oneline formatting. That can be achived differently now. --- README.md | 2 -- config.def.h | 17 ++++++----- mpd-notification.c | 82 +++++++++++++++++++++++++++++++++--------------------- mpd-notification.h | 4 +-- 4 files changed, 60 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index fb93db8..d4b515d 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,6 @@ or `systemctl --user enable mpd-notification`. * *-m MUSIC-DIR*: use *MUSIC-DIR* for artwork lookup * *--notification-file-workaround*: write artwork to file for notification daemons that do required it -* *-o*: Notification text is one line (no line breaks) * *-p PORT*: connect to *PORT* * *-s PIXELS*: scale image to a maximum size *PIXELS* x *PIXELS* pixels, keeping ratio @@ -84,7 +83,6 @@ look like this: host = localhost port = 6600 music-dir = /srv/media/music/ - oneline = true scale = 200 timeout = 20 diff --git a/config.def.h b/config.def.h index bc64e88..f262cfe 100644 --- a/config.def.h +++ b/config.def.h @@ -26,15 +26,14 @@ #define ICON_AUDIO_X_GENERIC "audio-x-generic" /* strings used to display notification messages - * TEXT_PLAY_* need to include one string modifier '%s' each. */ -#define TEXT_TOPIC "MPD Notification" -#define TEXT_PLAY_PAUSE_STATE "%s " -#define TEXT_PLAY_PAUSE_TITLE "%s" -#define TEXT_PLAY_PAUSE_ARTIST "by %s" -#define TEXT_PLAY_PAUSE_ALBUM "from %s" -#define TEXT_STOP "Stopped playback" -#define TEXT_NONE "No action received yet." -#define TEXT_UNKNOWN "(unknown)" + * TEXT_PLAY & TEXT_PAUSE can include several specifiers: + * %t for title, %a for artist and %A for album */ +#define TEXT_TOPIC "MPD Notification" +#define TEXT_PLAY "Playing %t\nby %a\nfrom %A" +#define TEXT_PAUSE "Paused %t\nby %a\nfrom %A" +#define TEXT_STOP "Stopped playback" +#define TEXT_NONE "No action received yet" +#define TEXT_UNKNOWN "(unknown)" /* this is a regular expression that has to match image filename used * for artwork */ diff --git a/mpd-notification.c b/mpd-notification.c index fb3d795..58bab6c 100644 --- a/mpd-notification.c +++ b/mpd-notification.c @@ -18,13 +18,12 @@ #include "mpd-notification.h" -const static char optstring[] = "hH:m:op:s:t:vV"; +const static char optstring[] = "hH:m:p:s:t:vV"; const static struct option options_long[] = { /* name has_arg flag val */ { "help", no_argument, NULL, 'h' }, { "host", required_argument, NULL, 'H' }, { "music-dir", required_argument, NULL, 'm' }, - { "oneline", no_argument, NULL, 'o' }, { "port", required_argument, NULL, 'p' }, { "scale", required_argument, NULL, 's' }, { "timeout", required_argument, NULL, 't' }, @@ -41,7 +40,6 @@ NotifyNotification * notification = NULL; struct mpd_connection * conn = NULL; uint8_t doexit = 0; uint8_t verbose = 0; -uint8_t oneline = 0; #ifdef HAVE_LIBAV magic_t magic = NULL; #endif @@ -214,26 +212,55 @@ done: return pixbuf; } -/*** append_string ***/ -char * append_string(char * string, const char * format, const char delim, const char * s) { - char * tmp, * offset; +/*** format_text ***/ +char * format_text(const char* format, const char* title, const char* artist, const char* album) { + char * formatted, * tmp = NULL; + size_t len; - tmp = g_markup_escape_text(s, -1); + if (format == NULL || strlen(format) == 0) + return NULL; - string = realloc(string, strlen(string) + strlen(format) + strlen(tmp) + 2 /* delim + line break */); + formatted = strdup(""); + len = 0; - offset = string + strlen(string); + do { + if (*format == '%') { + format++; - if (delim > 0) { - *offset = delim; - offset++; - } + switch (*format) { + case 'a': + tmp = g_markup_escape_text(artist, -1); + break; + + case 'A': + tmp = g_markup_escape_text(album, -1); + break; - sprintf(offset, format, tmp); + case 't': + tmp = g_markup_escape_text(title, -1); + break; - free(tmp); + default: + formatted = realloc(formatted, len + 2); + sprintf(formatted + len, "%%"); + format--; + break; + } - return string; + if (tmp != NULL) { + formatted = realloc(formatted, len + strlen(tmp) + 1); + sprintf(formatted + len, "%s", tmp); + free(tmp); + tmp = NULL; + } + } else { + formatted = realloc(formatted, len + 2); + sprintf(formatted + len, "%c", *format); + } + len = strlen(formatted); + } while (*format++); + + return formatted; } /*** main ***/ @@ -274,7 +301,6 @@ int main(int argc, char ** argv) { mpd_port = iniparser_getint(ini, ":port", mpd_port); music_dir = iniparser_getstring(ini, ":music-dir", music_dir); notification_timeout = iniparser_getint(ini, ":timeout", notification_timeout); - oneline = iniparser_getboolean(ini, ":oneline", oneline); scale = iniparser_getint(ini, ":scale", scale); } @@ -284,9 +310,6 @@ int main(int argc, char ** argv) { case 'h': help++; break; - case 'o': - oneline++; - break; case 'v': verbose++; break; @@ -312,7 +335,7 @@ int main(int argc, char ** argv) { " (compiled: " __DATE__ ", " __TIME__ ")\n", program, PROGNAME, VERSION); if (help > 0) - fprintf(stderr, "usage: %s [-h] [-H HOST] [-m MUSIC-DIR] [-o] [-p PORT] [-s PIXELS] [-t TIMEOUT] [-v] [-V]\n", program); + fprintf(stderr, "usage: %s [-h] [-H HOST] [-m MUSIC-DIR] [-p PORT] [-s PIXELS] [-t TIMEOUT] [-v] [-V]\n", program); if (version > 0 || help > 0) return EXIT_SUCCESS; @@ -434,7 +457,9 @@ int main(int argc, char ** argv) { song = mpd_recv_song(conn); - title = mpd_song_get_tag(song, MPD_TAG_TITLE, 0); + title = mpd_song_get_tag(song, MPD_TAG_TITLE, 0); + artist = mpd_song_get_tag(song, MPD_TAG_ARTIST, 0); + album = mpd_song_get_tag(song, MPD_TAG_ALBUM, 0); /* ignore if we have no title */ if (title == NULL) @@ -444,16 +469,9 @@ int main(int argc, char ** argv) { sd_notifyf(0, "READY=1\nSTATUS=%s: %s", state == MPD_STATE_PLAY ? "Playing" : "Paused", title); #endif - /* initial allocation and string termination */ - notifystr = strdup(""); - notifystr = append_string(notifystr, TEXT_PLAY_PAUSE_STATE, 0, state == MPD_STATE_PLAY ? "Playing": "Paused"); - notifystr = append_string(notifystr, TEXT_PLAY_PAUSE_TITLE, 0, title); - - if ((artist = mpd_song_get_tag(song, MPD_TAG_ARTIST, 0)) != NULL) - notifystr = append_string(notifystr, TEXT_PLAY_PAUSE_ARTIST, oneline ? ' ' : '\n', artist); - - if ((album = mpd_song_get_tag(song, MPD_TAG_ALBUM, 0)) != NULL) - notifystr = append_string(notifystr, TEXT_PLAY_PAUSE_ALBUM, oneline ? ' ' : '\n', album); + /* get the formatted notification string */ + notifystr = format_text(state == MPD_STATE_PLAY ? TEXT_PLAY : TEXT_PAUSE, + title, artist ? artist : "unknown artist", album ? album : "unknown album"); uri = mpd_song_get_uri(song); diff --git a/mpd-notification.h b/mpd-notification.h index a7f9453..6a07efc 100644 --- a/mpd-notification.h +++ b/mpd-notification.h @@ -56,8 +56,8 @@ void received_signal(int signal); /*** retrieve_artwork ***/ GdkPixbuf * retrieve_artwork(const char * music_dir, const char * uri); -/*** append_string ***/ -char * append_string(char * string, const char * format, const char delim, const char * s); +/*** format_text ***/ +char * format_text(const char* format, const char* title, const char* artist, const char* album); /*** main ***/ int main(int argc, char ** argv); -- cgit v1.2.3-54-g00ecf