Navigation Menu

Skip to content

Commit

Permalink
Notification support via the libnotify library
Browse files Browse the repository at this point in the history
  • Loading branch information
arkq committed May 17, 2014
1 parent 7b64508 commit 9a31a24
Show file tree
Hide file tree
Showing 10 changed files with 179 additions and 22 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -26,6 +26,7 @@
/autom4te.cache/
/build*/
/aclocal.m4
/compile
/configure
/depcomp
/install-sh
Expand Down
3 changes: 2 additions & 1 deletion README.md
Expand Up @@ -9,6 +9,7 @@ Features:
* Listening now notification support
* Off-line played track cache for later submission
* POSIX ERE-based file name parser
* Desktop notification support (optionally)
* Small memory footprint

When discography is correctly tagged - at least artist and title field - scrobbling needs no
Expand Down Expand Up @@ -47,7 +48,7 @@ Instalation

$ autoreconf --install
$ mkdir build && cd build
$ ../configure
$ ../configure --enable-libnotify
$ make && make install


Expand Down
14 changes: 14 additions & 0 deletions configure.ac
Expand Up @@ -6,6 +6,7 @@ AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([foreign -Wall -Werror])

AC_PROG_CC
AM_PROG_CC_C_O

AC_CHECK_HEADERS(
[curl/curl.h],
Expand Down Expand Up @@ -33,5 +34,18 @@ AS_IF([test "x$enable_debug" = "xyes"],
[AC_DEFINE([DEBUG], [1], [Define to 1 if the debugging is enabled])]
)

# support for libnotify
AC_ARG_ENABLE(
[libnotify],
AS_HELP_STRING([--enable-libnotify], [enable libnotify support])
)
AM_CONDITIONAL([ENABLE_LIBNOTIFY], [test "x$enable_libnotify" = "xyes"])
AS_IF([test "x$enable_libnotify" = "xyes"], [
PKG_CHECK_MODULES(
[libnotify], [libnotify >= 0.7],
[AC_DEFINE([ENABLE_LIBNOTIFY], [1], [Define to 1 if the libnotify is enabled])]
)
])

AC_CONFIG_FILES([Makefile src/Makefile])
AC_OUTPUT
9 changes: 8 additions & 1 deletion src/Makefile.am
Expand Up @@ -2,7 +2,14 @@
# Copyright (c) 2014 Arkadiusz Bokowy

AM_CFLAGS = -Wall -Wextra
AM_LDFLAGS =

bin_PROGRAMS = cmusfm
cmusfm_SOURCES = main.c libscrobbler2.c cache.c config.c server.c
cmusfm_CFLAGS =
cmusfm_LDADD =

if ENABLE_LIBNOTIFY
cmusfm_SOURCES += notify.c
cmusfm_CFLAGS += @libnotify_CFLAGS@
cmusfm_LDADD += @libnotify_LIBS@
endif
14 changes: 14 additions & 0 deletions src/config.c
Expand Up @@ -72,7 +72,14 @@ int cmusfm_config_read(const char *fname, struct cmusfm_config *conf)
FILE *f;
char line[128];

// initialize configuration defaults
memset(conf, 0, sizeof(*conf));
strcpy(conf->format_localfile, "^(?A.+) - (?T.+)\\.[^.]+$");
strcpy(conf->format_shoutcast, "^(?A.+) - (?T.+)$");
conf->nowplaying_localfile = 1;
conf->nowplaying_shoutcast = 1;
conf->submit_localfile = 1;
conf->submit_shoutcast = 1;

if((f = fopen(fname, "r")) == NULL)
return -1;
Expand All @@ -94,6 +101,10 @@ int cmusfm_config_read(const char *fname, struct cmusfm_config *conf)
conf->submit_localfile = decode_config_bool(get_config_value(line));
else if(strncmp(line, CMCONF_SUBMIT_SHOUTCAST, sizeof(CMCONF_SUBMIT_SHOUTCAST) - 1) == 0)
conf->submit_shoutcast = decode_config_bool(get_config_value(line));
#ifdef ENABLE_LIBNOTIFY
else if(strncmp(line, CMCONF_NOTIFICATION, sizeof(CMCONF_NOTIFICATION) - 1) == 0)
conf->notification = decode_config_bool(get_config_value(line));
#endif
}

return fclose(f);
Expand Down Expand Up @@ -124,6 +135,9 @@ int cmusfm_config_write(const char *fname, struct cmusfm_config *conf)
fprintf(f, "%s = \"%s\"\n", CMCONF_NOWPLAYING_SHOUTCAST, encode_config_bool(conf->nowplaying_shoutcast));
fprintf(f, "%s = \"%s\"\n", CMCONF_SUBMIT_LOCALFILE, encode_config_bool(conf->submit_localfile));
fprintf(f, "%s = \"%s\"\n", CMCONF_SUBMIT_SHOUTCAST, encode_config_bool(conf->submit_shoutcast));
#ifdef ENABLE_LIBNOTIFY
fprintf(f, "%s = \"%s\"\n", CMCONF_NOTIFICATION, encode_config_bool(conf->notification));
#endif

return fclose(f);
}
Expand Down
9 changes: 9 additions & 0 deletions src/config.h
Expand Up @@ -21,6 +21,11 @@
#ifndef __CMUSFM_CONFIG_H
#define __CMUSFM_CONFIG_H

#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif


// Configuration file key definitions
#define CMCONF_USER_NAME "user"
#define CMCONF_SESSION_KEY "key"
Expand All @@ -30,6 +35,7 @@
#define CMCONF_NOWPLAYING_SHOUTCAST "now-playing-shoutcast"
#define CMCONF_SUBMIT_LOCALFILE "submit-localfile"
#define CMCONF_SUBMIT_SHOUTCAST "submit-shoutcast"
#define CMCONF_NOTIFICATION "notification"

struct cmusfm_config {
char user_name[64];
Expand All @@ -43,6 +49,9 @@ struct cmusfm_config {
unsigned int nowplaying_shoutcast : 1;
unsigned int submit_localfile : 1;
unsigned int submit_shoutcast : 1;
#ifdef ENABLE_LIBNOTIFY
unsigned int notification : 1;
#endif
};


Expand Down
8 changes: 0 additions & 8 deletions src/main.c
Expand Up @@ -194,14 +194,6 @@ int cmusfm_initialization()
if(strncmp(yesno, "yes", 3) != 0)
fetch_session_key = 0;
}
else { // initialize configuration defaults
strcpy(conf.format_localfile, "^(?A.+) - (?T.+)\\.[^.]+$");
strcpy(conf.format_shoutcast, "^(?A.+) - (?T.+)$");
conf.nowplaying_localfile = 1;
conf.nowplaying_shoutcast = 1;
conf.submit_localfile = 1;
conf.submit_shoutcast = 1;
}

if(fetch_session_key) { // fetch new session key
if(scrobbler_authentication(sbs, user_authorization) == 0) {
Expand Down
69 changes: 69 additions & 0 deletions src/notify.c
@@ -0,0 +1,69 @@
/*
* cmusfm - notify.c
* Copyright (c) 2014 Arkadiusz Bokowy
*
* This file is a part of a cmusfm.
*
* cmusfm is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* cmusfm is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* If you want to read full version of the GNU General Public License
* see <http://www.gnu.org/licenses/>.
*/

#include <libnotify/notify.h>
#include <stdlib.h>
#include <string.h>
#include "notify.h"


// global notification handler
static NotifyNotification *cmus_notify;


// Show track information via the notification system.
void cmusfm_notify_show(const scrobbler_trackinfo_t *sb_tinf)
{
char *body;
size_t art_len, alb_len;

if(cmus_notify) {
// forcefully close previous notification
notify_notification_close(cmus_notify, NULL);
g_object_unref(G_OBJECT(cmus_notify));
}

// concatenate artist and album (when applicable)
art_len = strlen(sb_tinf->artist);
alb_len = strlen(sb_tinf->album);
body = (char*)malloc(art_len + alb_len + sizeof(" ()") + 1);
strcpy(body, sb_tinf->artist);
if(alb_len > 0)
sprintf(&body[art_len], " (%s)", sb_tinf->album);

cmus_notify = notify_notification_new(sb_tinf->track, body, NULL);
notify_notification_show(cmus_notify, NULL);
free(body);
}

// Initialize notification system.
void cmusfm_notify_initialize()
{
cmus_notify = NULL;
notify_init("cmusfm");
}

// Free notification system resources.
void cmusfm_notify_free()
{
if(cmus_notify)
g_object_unref(G_OBJECT(cmus_notify));
notify_uninit();
}
31 changes: 31 additions & 0 deletions src/notify.h
@@ -0,0 +1,31 @@
/*
* cmusfm - notify.h
* Copyright (c) 2014 Arkadiusz Bokowy
*
* This file is a part of a cmusfm.
*
* cmusfm is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* cmusfm is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* If you want to read full version of the GNU General Public License
* see <http://www.gnu.org/licenses/>.
*/

#ifndef __CMUSFM_NOTIFY_H
#define __CMUSFM_NOTIFY_H

#include "libscrobbler2.h"


void cmusfm_notify_initialize();
void cmusfm_notify_free();
void cmusfm_notify_show(const scrobbler_trackinfo_t *sb_tinf);

#endif
43 changes: 31 additions & 12 deletions src/server.c
Expand Up @@ -34,10 +34,14 @@
#include "server.h"
#include "cache.h"
#include "debug.h"
#ifdef ENABLE_LIBNOTIFY
#include "notify.h"
#endif


void set_trackinfo(scrobbler_trackinfo_t *sbt, const struct sock_data_tag *dt)
{
memset(sbt, 0, sizeof(*sbt));
sbt->duration = dt->duration;
sbt->track_number = dt->tracknb;
sbt->artist = (char *)(dt + 1);
Expand Down Expand Up @@ -70,8 +74,6 @@ void cmusfm_server_process_data(int fd, scrobbler_session_t *sbs)
int new_hash;
char raw_status;

memset(&sb_tinf, 0, sizeof(sb_tinf));

rd_len = read(fd, buffer, sizeof(buffer));
debug("rdlen: %ld, status: %d", rd_len, sock_data->status);

Expand Down Expand Up @@ -152,18 +154,27 @@ void cmusfm_server_process_data(int fd, scrobbler_session_t *sbs)
memcpy(saved_data, sock_data, rd_len);
saved_is_radio = sock_data->status & CMSTATUS_SHOUTCASTMASK;

if(raw_status == CMSTATUS_PLAYING && scrobbler_fail_time == 0) {
// update now-playing indicator if we want it
if((saved_is_radio && config.nowplaying_shoutcast) ||
(!saved_is_radio && config.nowplaying_localfile)) {
set_trackinfo(&sb_tinf, sock_data);
if(scrobbler_update_now_playing(sbs, &sb_tinf) != 0)
scrobbler_fail_time = 1;
}
#if DEBUG
if(raw_status == CMSTATUS_PLAYING) {
set_trackinfo(&sb_tinf, sock_data);

#ifdef ENABLE_LIBNOTIFY
if(config.notification)
cmusfm_notify_show(&sb_tinf);
else
debug("now playing not enabled");
debug("notification not enabled");
#endif

// update now-playing indicator
if(scrobbler_fail_time == 0) {
if((saved_is_radio && config.nowplaying_shoutcast) ||
(!saved_is_radio && config.nowplaying_localfile)) {
if(scrobbler_update_now_playing(sbs, &sb_tinf) != 0)
scrobbler_fail_time = 1;
}
else
debug("now playing not enabled");
}

}
}
}
Expand Down Expand Up @@ -222,6 +233,11 @@ void cmusfm_server_start()
sbs = scrobbler_initialize(SC_api_key, SC_secret);
scrobbler_set_session_key_str(sbs, config.session_key);

#ifdef ENABLE_LIBNOTIFY
// initialize notification library
cmusfm_notify_initialize();
#endif

// catch signals which are used to quit server
memset(&sigact, 0, sizeof(sigact));
sigact.sa_handler = cmusfm_server_stop;
Expand Down Expand Up @@ -252,6 +268,9 @@ void cmusfm_server_start()
}

close(sock);
#ifdef ENABLE_LIBNOTIFY
cmusfm_notify_free();
#endif
scrobbler_free(sbs);
unlink(sock_a.sun_path);
}
Expand Down

0 comments on commit 9a31a24

Please sign in to comment.