static void song_changed(const struct mpd_song *song) { g_assert(song != NULL); if (mpd_song_get_tag(song, MPD_TAG_ARTIST, 0) == NULL || mpd_song_get_tag(song, MPD_TAG_TITLE, 0) == NULL) { g_message("New song detected with tags missing (%s)", mpd_song_get_uri(song)); g_timer_start(timer); return; } g_timer_start(timer); g_debug("New song detected (%s - %s), id: %u, pos: %u", mpd_song_get_tag(song, MPD_TAG_ARTIST, 0), mpd_song_get_tag(song, MPD_TAG_TITLE, 0), mpd_song_get_id(song), mpd_song_get_pos(song)); as_now_playing(mpd_song_get_tag(song, MPD_TAG_ARTIST, 0), mpd_song_get_tag(song, MPD_TAG_TITLE, 0), mpd_song_get_tag(song, MPD_TAG_ALBUM, 0), mpd_song_get_tag(song, MPD_TAG_MUSICBRAINZ_TRACKID, 0), mpd_song_get_duration(song)); }
static void song_ended(const struct mpd_song *song) { bool long_enough; int elapsed, song_duration, percent_played; GError *error; g_assert(song != NULL); elapsed = g_timer_elapsed(timer, NULL); song_duration = mpd_song_get_duration(song); long_enough = played_long_enough(elapsed, song_duration); percent_played = elapsed * 100 / song_duration; g_debug("Saving old song (%s - %s), id: %u, pos: %u", mpd_song_get_tag(song, MPD_TAG_ARTIST, 0), mpd_song_get_tag(song, MPD_TAG_TITLE, 0), mpd_song_get_id(song), mpd_song_get_pos(song)); error = NULL; if (!db_process(song, long_enough, percent_played, &error)) { g_warning("Saving old song failed: %s", error->message); g_error_free(error); } else if (error != NULL) { g_warning("Skipped saving old song: %s", error->message); g_error_free(error); } }
static bool song_repeated(const struct mpd_song *song, int elapsed, int prev_elapsed) { return elapsed < 60 && prev_elapsed > elapsed && played_long_enough(prev_elapsed - elapsed, mpd_song_get_duration(song)); }
char* getDuration(Config* config, int status) { if (!config->curr_song) { return timeToString(config, 0); } unsigned time = mpd_song_get_duration(config->curr_song); return timeToString(config, time); }
/** * Check if the current song is eligible for submission */ static gboolean current_song_eligible_for_submission(void) { if (!mpd.song) return FALSE; return (mpd.song_state != SONG_SUBMITTED && (g_timer_elapsed(mpd.song_pos, NULL) >= 240 || g_timer_elapsed(mpd.song_pos, NULL) >= mpd_song_get_duration(mpd.song) * 0.5)); }
static void song_ended(const struct mpd_song *song) { int elapsed; g_assert(song != NULL); elapsed = g_timer_elapsed(timer, NULL); if (mpd_song_get_tag(song, MPD_TAG_ARTIST, 0) == NULL || mpd_song_get_tag(song, MPD_TAG_TITLE, 0) == NULL) { g_message("Song (%s) has missing tags, skipping", mpd_song_get_uri(song)); return; } else if (!played_long_enough(elapsed, mpd_song_get_duration(song))) { g_message("Song (%s - %s), id: %u, pos: %u not played long enough, skipping", mpd_song_get_tag(song, MPD_TAG_ARTIST, 0), mpd_song_get_tag(song, MPD_TAG_TITLE, 0), mpd_song_get_id(song), mpd_song_get_pos(song)); return; } g_debug("Submitting old song (%s - %s), id: %u, pos: %u", mpd_song_get_tag(song, MPD_TAG_ARTIST, 0), mpd_song_get_tag(song, MPD_TAG_TITLE, 0), mpd_song_get_id(song), mpd_song_get_pos(song)); /* FIXME: libmpdclient doesn't have any way to fetch the musicbrainz id. */ as_songchange(mpd_song_get_uri(song), mpd_song_get_tag(song, MPD_TAG_ARTIST, 0), mpd_song_get_tag(song, MPD_TAG_TITLE, 0), mpd_song_get_tag(song, MPD_TAG_ALBUM, 0), mpd_song_get_tag(song, MPD_TAG_MUSICBRAINZ_TRACKID, 0), mpd_song_get_duration(song) > 0 ? mpd_song_get_duration(song) : g_timer_elapsed(timer, NULL), NULL); }
/** * MPD stopped playing this song. */ void song_ended(const struct mpd_song *song, bool love) { int elapsed = g_timer_elapsed(timer, NULL); if (!played_long_enough(elapsed, mpd_song_get_duration(song))) return; /* FIXME: libmpdclient doesn't have any way to fetch the musicbrainz id. */ as_songchange(mpd_song_get_uri(song), mpd_song_get_tag(song, MPD_TAG_ARTIST, 0), mpd_song_get_tag(song, MPD_TAG_TITLE, 0), mpd_song_get_tag(song, MPD_TAG_ALBUM, 0), mpd_song_get_tag(song, MPD_TAG_TRACK, 0), mpd_song_get_tag(song, MPD_TAG_MUSICBRAINZ_TRACKID, 0), mpd_song_get_duration(song) > 0 ? mpd_song_get_duration(song) : g_timer_elapsed(timer, NULL), love, NULL); }
Song::Song(struct mpd_song *song) { const char* temp; temp = mpd_song_get_tag(song, MPD_TAG_ARTIST, 0); artist = temp ? temp : ""; temp = mpd_song_get_tag(song, MPD_TAG_TITLE, 0); title = temp ? temp : ""; temp = mpd_song_get_tag(song, MPD_TAG_ALBUM, 0); album = temp ? temp : ""; duration = mpd_song_get_duration(song); }
void queue_add_current_song(void) { const gchar *trackstr = mpd_song_get_tag(mpd.song, MPD_TAG_TRACK, 0); guint track = 0; if (trackstr) track = strtol(trackstr, NULL, 10); queue_add(mpd_song_get_tag(mpd.song, MPD_TAG_ARTIST, 0), mpd_song_get_tag(mpd.song, MPD_TAG_TITLE, 0), mpd_song_get_tag(mpd.song, MPD_TAG_ALBUM, 0), mpd_song_get_duration(mpd.song), track, mpd.song_date); mpd.song_state = SONG_SUBMITTED; }
static void song_changed(const struct mpd_song *song) { g_message("new song detected (%s - %s), id: %u, pos: %u\n", mpd_song_get_tag(song, MPD_TAG_ARTIST, 0), mpd_song_get_tag(song, MPD_TAG_TITLE, 0), mpd_song_get_id(song), mpd_song_get_pos(song)); g_timer_start(timer); as_now_playing(mpd_song_get_tag(song, MPD_TAG_ARTIST, 0), mpd_song_get_tag(song, MPD_TAG_TITLE, 0), mpd_song_get_tag(song, MPD_TAG_ALBUM, 0), mpd_song_get_tag(song, MPD_TAG_TRACK, 0), mpd_song_get_tag(song, MPD_TAG_MUSICBRAINZ_TRACKID, 0), mpd_song_get_duration(song)); }
int mpd_search(char *buffer, char *searchstr) { int i = 0; char *cur = buffer; const char *end = buffer + MAX_SIZE; struct mpd_song *song; if(mpd_search_db_songs(mpd.conn, false) == false) RETURN_ERROR_AND_RECOVER("mpd_search_db_songs"); else if(mpd_search_add_any_tag_constraint(mpd.conn, MPD_OPERATOR_DEFAULT, searchstr) == false) RETURN_ERROR_AND_RECOVER("mpd_search_add_any_tag_constraint"); else if(mpd_search_commit(mpd.conn) == false) RETURN_ERROR_AND_RECOVER("mpd_search_commit"); else { cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"search\",\"data\":[ "); while((song = mpd_recv_song(mpd.conn)) != NULL) { cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"song\",\"uri\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_song_get_uri(song)); cur += json_emit_raw_str(cur, end - cur, ",\"album\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_get_album(song)); cur += json_emit_raw_str(cur, end - cur, ",\"artist\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_get_artist(song)); cur += json_emit_raw_str(cur, end - cur, ",\"duration\":"); cur += json_emit_int(cur, end - cur, mpd_song_get_duration(song)); cur += json_emit_raw_str(cur, end - cur, ",\"title\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_get_title(song)); cur += json_emit_raw_str(cur, end - cur, "},"); mpd_song_free(song); /* Maximum results */ if(i++ >= 300) { cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"wrap\"},"); break; } } /* remove last ',' */ cur--; cur += json_emit_raw_str(cur, end - cur, "]}"); } return cur - buffer; }
char* getTimeBar(Config* config, int status) { if (config->timebar < 3) { return strdup(""); } char* timeBar = calloc(config->timebar + 1, sizeof(char)); unsigned duration; if (config->curr_song) { duration = mpd_song_get_duration(config->curr_song); } else { duration = 0; } unsigned elapsed = mpd_status_get_elapsed_time(config->mpd_status); unsigned blockSize = duration / (config->timebar - 2); unsigned block = 0; if (blockSize) { block = elapsed / blockSize; } timeBar[0] = '['; unsigned i; for (i = 1; i < block; i++) { timeBar[i] = '='; } if (i > config->timebar - 2) { i = config->timebar - 2; } timeBar[i] = '>'; i++; for (; i < config->timebar; i++) { timeBar[i] = '-'; } timeBar[config->timebar - 1] = ']'; timeBar[config->timebar] = 0; return timeBar; }
int mpd_put_queue(char *buffer, unsigned int offset) { char *cur = buffer; const char *end = buffer + MAX_SIZE; struct mpd_entity *entity; if (!mpd_send_list_queue_range_meta(mpd.conn, offset, offset+MAX_ELEMENTS_PER_PAGE)) RETURN_ERROR_AND_RECOVER("mpd_send_list_queue_meta"); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"queue\",\"data\":[ "); while((entity = mpd_recv_entity(mpd.conn)) != NULL) { const struct mpd_song *song; if(mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG) { song = mpd_entity_get_song(entity); cur += json_emit_raw_str(cur, end - cur, "{\"id\":"); cur += json_emit_int(cur, end - cur, mpd_song_get_id(song)); cur += json_emit_raw_str(cur, end - cur, ",\"pos\":"); cur += json_emit_int(cur, end - cur, mpd_song_get_pos(song)); cur += json_emit_raw_str(cur, end - cur, ",\"duration\":"); cur += json_emit_int(cur, end - cur, mpd_song_get_duration(song)); cur += json_emit_raw_str(cur, end - cur, ",\"artist\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_get_artist(song)); cur += json_emit_raw_str(cur, end - cur, ",\"album\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_get_album(song)); cur += json_emit_raw_str(cur, end - cur, ",\"title\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_get_title(song)); cur += json_emit_raw_str(cur, end - cur, "},"); } mpd_entity_free(entity); } /* remove last ',' */ cur--; cur += json_emit_raw_str(cur, end - cur, "]}"); return cur - buffer; }
int mpd_put_browse(char *buffer, char *path, unsigned int offset) { char *cur = buffer; const char *end = buffer + MAX_SIZE; struct mpd_entity *entity; unsigned int entity_count = 0; if (!mpd_send_list_meta(mpd.conn, path)) RETURN_ERROR_AND_RECOVER("mpd_send_list_meta"); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"browse\",\"data\":[ "); while((entity = mpd_recv_entity(mpd.conn)) != NULL) { const struct mpd_song *song; const struct mpd_directory *dir; const struct mpd_playlist *pl; if(offset > entity_count) { mpd_entity_free(entity); entity_count++; continue; } else if(offset + MAX_ELEMENTS_PER_PAGE - 1 < entity_count) { mpd_entity_free(entity); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"wrap\",\"count\":"); cur += json_emit_int(cur, end - cur, entity_count); cur += json_emit_raw_str(cur, end - cur, "} "); break; } switch (mpd_entity_get_type(entity)) { case MPD_ENTITY_TYPE_UNKNOWN: break; case MPD_ENTITY_TYPE_SONG: song = mpd_entity_get_song(entity); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"song\",\"uri\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_song_get_uri(song)); cur += json_emit_raw_str(cur, end - cur, ",\"duration\":"); cur += json_emit_int(cur, end - cur, mpd_song_get_duration(song)); cur += json_emit_raw_str(cur, end - cur, ",\"title\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_get_title(song)); cur += json_emit_raw_str(cur, end - cur, "},"); break; case MPD_ENTITY_TYPE_DIRECTORY: dir = mpd_entity_get_directory(entity); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"directory\",\"dir\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_directory_get_path(dir)); cur += json_emit_raw_str(cur, end - cur, "},"); break; case MPD_ENTITY_TYPE_PLAYLIST: pl = mpd_entity_get_playlist(entity); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"playlist\",\"plist\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_playlist_get_path(pl)); cur += json_emit_raw_str(cur, end - cur, "},"); break; } mpd_entity_free(entity); entity_count++; } if (mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(mpd.conn)) { fprintf(stderr, "MPD mpd_send_list_meta: %s\n", mpd_connection_get_error_message(mpd.conn)); mpd.conn_state = MPD_FAILURE; return 0; } /* remove last ',' */ cur--; cur += json_emit_raw_str(cur, end - cur, "]}"); return cur - buffer; }
static gsize _strfsong(gchar *s, gsize max, const gchar *format, const struct mpd_song *song, const gchar **last) { const gchar *p, *end; gchar *temp; gsize n, length = 0; gboolean found = FALSE; memset(s, 0, max); if (song == NULL) return 0; for (p = format; *p != '\0' && length<max;) { /* OR */ if (p[0] == '|') { ++p; if(!found) { memset(s, 0, max); length = 0; } else { p = skip(p); } continue; } /* AND */ if (p[0] == '&') { ++p; if(!found) { p = skip(p); } else { found = FALSE; } continue; } /* EXPRESSION START */ if (p[0] == '[') { temp = g_malloc0(max); if( _strfsong(temp, max, p+1, song, &p) >0 ) { g_strlcat(s, temp, max); length = strlen(s); found = TRUE; } g_free(temp); continue; } /* EXPRESSION END */ if (p[0] == ']') { if(last) *last = p+1; if(!found && length) { memset(s, 0, max); length = 0; } return length; } /* pass-through non-escaped portions of the format string */ if (p[0] != '#' && p[0] != '%' && length<max) { s[length++] = *p; p++; continue; } /* let the escape character escape itself */ if (p[0] == '#' && p[1] != '\0' && length<max) { s[length++] = *(p+1); p+=2; continue; } /* advance past the esc character */ /* find the extent of this format specifier (stop at \0, ' ', or esc) */ temp = NULL; end = p+1; while(*end >= 'a' && *end <= 'z') { end++; } n = end - p + 1; if(*end != '%') n--; else if (strncmp("%file%", p, n) == 0) temp = utf8_to_locale(mpd_song_get_uri(song)); else if (strncmp("%artist%", p, n) == 0) temp = song_tag_locale(song, MPD_TAG_ARTIST); else if (strncmp("%title%", p, n) == 0) temp = song_tag_locale(song, MPD_TAG_TITLE); else if (strncmp("%album%", p, n) == 0) temp = song_tag_locale(song, MPD_TAG_ALBUM); else if (strncmp("%shortalbum%", p, n) == 0) { temp = song_tag_locale(song, MPD_TAG_ALBUM); if (temp) { gchar *temp2 = g_strndup(temp, 25); if (strlen(temp) > 25) { temp2[24] = '.'; temp2[23] = '.'; temp2[22] = '.'; } g_free(temp); temp = temp2; } } else if (strncmp("%track%", p, n) == 0) temp = song_tag_locale(song, MPD_TAG_TRACK); else if (strncmp("%name%", p, n) == 0) temp = song_tag_locale(song, MPD_TAG_NAME); else if (strncmp("%date%", p, n) == 0) temp = song_tag_locale(song, MPD_TAG_DATE); else if (strncmp("%genre%", p, n) == 0) temp = song_tag_locale(song, MPD_TAG_GENRE); else if (strncmp("%shortfile%", p, n) == 0) { const char *uri = mpd_song_get_uri(song); if (strstr(uri, "://") != NULL) temp = utf8_to_locale(uri); else temp = utf8_to_locale(g_basename(uri)); } else if (strncmp("%time%", p, n) == 0) { unsigned duration = mpd_song_get_duration(song); if (duration > 0) { char buffer[32]; format_duration_short(buffer, sizeof(buffer), duration); temp = g_strdup(buffer); } } if( temp == NULL) { gsize templen=n; /* just pass-through any unknown specifiers (including esc) */ /* drop a null char in so printf stops at the end of this specifier, but put the real character back in (pseudo-const) */ if( length+templen > max ) templen = max-length; g_strlcat(s, p,max); length+=templen; } else { gsize templen = strlen(temp); found = TRUE; if( length+templen > max ) templen = max-length; g_strlcat(s, temp, max); length+=templen; g_free(temp); } /* advance past the specifier */ p += n; } if(last) *last = p; return length; }
static void env_export_song(struct mpd_song *song) { const char *tag; char *envstr; time_t t; char date[DEFAULT_DATE_FORMAT_SIZE] = { 0 }; g_setenv("MPD_SONG_URI", mpd_song_get_uri(song), 1); t = mpd_song_get_last_modified(song); strftime(date, DEFAULT_DATE_FORMAT_SIZE, DEFAULT_DATE_FORMAT, localtime(&t)); g_setenv("MPD_SONG_LAST_MODIFIED", date, 1); envstr = g_strdup_printf("%u", mpd_song_get_duration(song)); g_setenv("MPD_SONG_DURATION", envstr, 1); g_free(envstr); envstr = g_strdup_printf("%u", mpd_song_get_pos(song)); g_setenv("MPD_SONG_POS", envstr, 1); g_free(envstr); envstr = g_strdup_printf("%u", mpd_song_get_id(song)); g_setenv("MPD_SONG_ID", envstr, 1); g_free(envstr); /* Export tags. FIXME: For now we just export the first tag value to * the environment. */ if ((tag = mpd_song_get_tag(song, MPD_TAG_ARTIST, 0)) != NULL) g_setenv("MPD_SONG_TAG_ARTIST", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_ALBUM, 0)) != NULL) g_setenv("MPD_SONG_TAG_ALBUM", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_ALBUM_ARTIST, 0)) != NULL) g_setenv("MPD_SONG_TAG_ALBUM_ARTIST", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_TITLE, 0)) != NULL) g_setenv("MPD_SONG_TAG_TITLE", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_TRACK, 0)) != NULL) g_setenv("MPD_SONG_TAG_TRACK", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_NAME, 0)) != NULL) g_setenv("MPD_SONG_TAG_NAME", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_GENRE, 0)) != NULL) g_setenv("MPD_SONG_TAG_GENRE", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_DATE, 0)) != NULL) g_setenv("MPD_SONG_TAG_DATE", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_COMPOSER, 0)) != NULL) g_setenv("MPD_SONG_TAG_COMPOSER", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_PERFORMER, 0)) != NULL) g_setenv("MPD_SONG_TAG_PERFORMER", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_COMMENT, 0)) != NULL) g_setenv("MPD_SONG_TAG_COMMENT", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_DISC, 0)) != NULL) g_setenv("MPD_SONG_TAG_DISC", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_MUSICBRAINZ_ARTISTID, 0)) != NULL) g_setenv("MPD_SONG_TAG_MUSICBRAINZ_ARTISTID", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_MUSICBRAINZ_ALBUMID, 0)) != NULL) g_setenv("MPD_SONG_TAG_MUSICBRAINZ_ALBUMID", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_MUSICBRAINZ_ALBUMARTISTID, 0)) != NULL) g_setenv("MPD_SONG_TAG_MUSICBRAINZ_ALBUMARTISTID", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_MUSICBRAINZ_TRACKID, 0)) != NULL) g_setenv("MPD_SONG_TAG_MUSICBRAINZ_TRACKID", tag, 1); }
void as_now_playing(void) { gchar *querystring, *tmp, *sig, *artist, *album, *title; const gchar *trackstr, *albumstr, *artiststr, *titlestr; gint ret; guint length, track = 0; if (as_conn.status != CONNECTED) { g_message("Not sending Now Playing notification:" " not connected"); return; } albumstr = mpd_song_get_tag(mpd.song, MPD_TAG_ALBUM, 0); artiststr = mpd_song_get_tag(mpd.song, MPD_TAG_ARTIST, 0); titlestr = mpd_song_get_tag(mpd.song, MPD_TAG_TITLE, 0); trackstr = mpd_song_get_tag(mpd.song, MPD_TAG_TRACK, 0); if (trackstr) track = strtol(trackstr, NULL, 10); length = mpd_song_get_duration(mpd.song); if (!artiststr || !titlestr) { g_message("Not sending Now Playing notification: Missing tags"); return; } tmp = g_strdup_printf("%s%sapi_key" API_KEY "artist%sduration%d" "methodtrack.updateNowPlayingsk%strack%s", (albumstr ? "album" : ""), (albumstr ? albumstr : ""), artiststr, length, as_conn.session_id, titlestr); if (track > 0) { sig = g_strdup(tmp); g_free(tmp); tmp = g_strdup_printf("%strackNumber%d", sig, track); g_free(sig); } sig = g_strdup(tmp); g_free(tmp); tmp = g_strconcat(sig, API_SECRET, NULL); g_free(sig); sig = g_compute_checksum_for_string(G_CHECKSUM_MD5, tmp, -1); g_free(tmp); artist = curl_easy_escape(as_conn.handle, artiststr, 0); title = curl_easy_escape(as_conn.handle, titlestr, 0); if (albumstr) album = curl_easy_escape(as_conn.handle, albumstr, 0); querystring = g_strdup_printf("api_key=" API_KEY "&artist=%s" "&duration=%d&method=track.updateNowPlaying&sk=%s" "&track=%s&api_sig=%s", artist, length, as_conn.session_id, title, sig); if (albumstr) { tmp = strdup(querystring); g_free(querystring); querystring = g_strconcat(tmp, "&album=", album, NULL); g_free(tmp); } if (track > 0) { tmp = strdup(querystring); g_free(querystring); querystring = g_strdup_printf("%s&trackNumber=%d", tmp, track); g_free(tmp); } if (albumstr) curl_free(album); curl_free(artist); curl_free(title); g_free(sig); g_debug("querystring = %s", querystring); curl_easy_setopt(as_conn.handle, CURLOPT_WRITEDATA, buffer); curl_easy_setopt(as_conn.handle, CURLOPT_POSTFIELDS, querystring); curl_easy_setopt(as_conn.handle, CURLOPT_URL, API_URL); ret = curl_easy_perform(as_conn.handle); g_free(querystring); if (ret) { g_warning("Failed to connect to Audioscrobbler: %s", curl_easy_strerror(ret)); g_free(buffer); buffer = NULL; return; } mpd.song_state = SONG_ANNOUNCED; if (strstr(buffer, "<lfm status=\"ok\">")) { g_message("Sent Now Playing notification."); } else if (strstr(buffer, "<lfm status=\"failed\">")) { as_parse_error(buffer); } else { g_debug("Unknown response from Audioscrobbler while " "sending Now Playing notification."); } g_free(buffer); buffer = NULL; }
/* fetch a new db tree on root */ static int fetch_db_tree(DB_NODE **p_root,struct mpd_connection *conn) { if (*p_root) return 1; /* create root */ DB_NODE *root = (DB_NODE*)malloc(sizeof(DB_NODE)); root->type = DB_DIRECTORY; /* use calloc for root->uri to ease free_db_tree() */ root->uri = (char *)calloc(2,sizeof(char)); strncpy(root->uri,"/",1); root->rating = 0; root->duration = 0; root->p = NULL; root->s = NULL; root->c = NULL; root->num_c = 0; /* set top node */ DB_NODE *top = root; if (!mpd_send_list_all_meta(conn,"/")) { clear_or_exit_on_error(conn); return 1; } /* add nodes recursively */ struct mpd_entity *entity; while ((entity = mpd_recv_entity(conn))) { DB_NODE *node = (DB_NODE*)malloc(sizeof(DB_NODE)); const char *name = NULL; switch (mpd_entity_get_type(entity)) { case MPD_ENTITY_TYPE_DIRECTORY: node->type = DB_DIRECTORY; name = mpd_directory_get_path(mpd_entity_get_directory(entity)); assert (name && strlen(name)); node->uri = (char *)calloc(strlen(name)+1,sizeof(char)); strncpy(node->uri,name,strlen(name)); node->rating = 0; node->duration = 0; break; case MPD_ENTITY_TYPE_SONG: node->type = DB_SONG; name = mpd_song_get_uri(mpd_entity_get_song(entity)); assert (name && strlen(name)); node->uri = (char *)calloc(strlen(name)+1,sizeof(char)); strncpy(node->uri,name,strlen(name)); node->rating = 0; node->duration = mpd_song_get_duration(mpd_entity_get_song(entity)); break; case MPD_ENTITY_TYPE_PLAYLIST: node->type = DB_PLAYLIST; name = mpd_playlist_get_path(mpd_entity_get_playlist(entity)); assert (name && strlen(name)); node->uri = (char *)calloc(strlen(name)+1,sizeof(char)); strncpy(node->uri,name,strlen(name)); node->rating = 0; node->duration = 0; break; case MPD_ENTITY_TYPE_UNKNOWN: break; } /* backtrace top until it's parent of node */ while (top != root && !(strstr(node->uri,top->uri) && node->uri[strlen(top->uri)] == '/')) top = top->p; /* if current top already has chlidren */ if (top->c) { DB_NODE *node2 = top->c; /* find the last child */ while (node2->s) node2 = node2->s; node2->s = node; node->p = node2->p; node->p->num_c++; } else { top->c = node; node->p = top; node->p->num_c++; } /* no child, no next sibling */ node->c = NULL; node->s = NULL; node->num_c = 0; /* update top node */ if (node->type == DB_DIRECTORY) top = node; mpd_entity_free(entity); } if (mpd_connection_get_error(conn) == MPD_ERROR_SUCCESS) mpd_response_finish(conn); else if (!mpd_connection_clear_error(conn)) exit_on_error(conn); *p_root = root; return 0; }
unsigned Song::getDuration() const { assert(m_song); return mpd_song_get_duration(m_song.get()); }
int main(int argc, char ** argv) { struct mpd_connection *conn; conn = mpd_connection_new(NULL, 0, 30000); if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) return handle_error(conn); { int i; for(i=0;i<3;i++) { printf("version[%i]: %i\n",i, mpd_connection_get_server_version(conn)[i]); } } if(argc==1) { struct mpd_status * status; struct mpd_song *song; const struct mpd_audio_format *audio_format; mpd_command_list_begin(conn, true); mpd_send_status(conn); mpd_send_current_song(conn); mpd_command_list_end(conn); status = mpd_recv_status(conn); if (status == NULL) return handle_error(conn); printf("volume: %i\n", mpd_status_get_volume(status)); printf("repeat: %i\n", mpd_status_get_repeat(status)); printf("queue version: %u\n", mpd_status_get_queue_version(status)); printf("queue length: %i\n", mpd_status_get_queue_length(status)); if (mpd_status_get_error(status) != NULL) printf("error: %s\n", mpd_status_get_error(status)); if (mpd_status_get_state(status) == MPD_STATE_PLAY || mpd_status_get_state(status) == MPD_STATE_PAUSE) { printf("song: %i\n", mpd_status_get_song_pos(status)); printf("elaspedTime: %i\n",mpd_status_get_elapsed_time(status)); printf("elasped_ms: %u\n", mpd_status_get_elapsed_ms(status)); printf("totalTime: %i\n", mpd_status_get_total_time(status)); printf("bitRate: %i\n", mpd_status_get_kbit_rate(status)); } audio_format = mpd_status_get_audio_format(status); if (audio_format != NULL) { printf("sampleRate: %i\n", audio_format->sample_rate); printf("bits: %i\n", audio_format->bits); printf("channels: %i\n", audio_format->channels); } mpd_status_free(status); if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) return handle_error(conn); mpd_response_next(conn); while ((song = mpd_recv_song(conn)) != NULL) { printf("uri: %s\n", mpd_song_get_uri(song)); print_tag(song, MPD_TAG_ARTIST, "artist"); print_tag(song, MPD_TAG_ALBUM, "album"); print_tag(song, MPD_TAG_TITLE, "title"); print_tag(song, MPD_TAG_TRACK, "track"); print_tag(song, MPD_TAG_NAME, "name"); print_tag(song, MPD_TAG_DATE, "date"); if (mpd_song_get_duration(song) > 0) { printf("time: %u\n", mpd_song_get_duration(song)); } printf("pos: %u\n", mpd_song_get_pos(song)); mpd_song_free(song); } if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(conn)) return handle_error(conn); } else if(argc==3 && strcmp(argv[1],"lsinfo")==0) { struct mpd_entity * entity; if (!mpd_send_list_meta(conn, argv[2])) return handle_error(conn); while ((entity = mpd_recv_entity(conn)) != NULL) { const struct mpd_song *song; const struct mpd_directory *dir; const struct mpd_playlist *pl; switch (mpd_entity_get_type(entity)) { case MPD_ENTITY_TYPE_UNKNOWN: break; case MPD_ENTITY_TYPE_SONG: song = mpd_entity_get_song(entity); printf("uri: %s\n", mpd_song_get_uri(song)); print_tag(song, MPD_TAG_ARTIST, "artist"); print_tag(song, MPD_TAG_ALBUM, "album"); print_tag(song, MPD_TAG_TITLE, "title"); print_tag(song, MPD_TAG_TRACK, "track"); break; case MPD_ENTITY_TYPE_DIRECTORY: dir = mpd_entity_get_directory(entity); printf("directory: %s\n", mpd_directory_get_path(dir)); break; case MPD_ENTITY_TYPE_PLAYLIST: pl = mpd_entity_get_playlist(entity); printf("playlist: %s\n", mpd_playlist_get_path(pl)); break; } mpd_entity_free(entity); } if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(conn)) return handle_error(conn); } else if(argc==2 && strcmp(argv[1],"artists")==0) { struct mpd_pair *pair; if (!mpd_search_db_tags(conn, MPD_TAG_ARTIST) || !mpd_search_commit(conn)) return handle_error(conn); while ((pair = mpd_recv_pair_tag(conn, MPD_TAG_ARTIST)) != NULL) { printf("%s\n", pair->value); mpd_return_pair(conn, pair); } if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(conn)) return handle_error(conn); } else if (argc == 2 && strcmp(argv[1], "playlists") == 0) { if (!mpd_send_list_playlists(conn)) return handle_error(conn); struct mpd_playlist *playlist; while ((playlist = mpd_recv_playlist(conn)) != NULL) { printf("%s\n", mpd_playlist_get_path(playlist)); mpd_playlist_free(playlist); } if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(conn)) return handle_error(conn); } else if (argc == 2 && strcmp(argv[1], "idle") == 0) { enum mpd_idle idle = mpd_run_idle(conn); if (idle == 0 && mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) return handle_error(conn); for (unsigned j = 0;; ++j) { enum mpd_idle i = 1 << j; const char *name = mpd_idle_name(i); if (name == NULL) break; if (idle & i) printf("%s\n", name); } } else if (argc == 3 && strcmp(argv[1], "subscribe") == 0) { /* subscribe to a channel and print all messages */ if (!mpd_run_subscribe(conn, argv[2])) return handle_error(conn); while (mpd_run_idle_mask(conn, MPD_IDLE_MESSAGE) != 0) { if (!mpd_send_read_messages(conn)) return handle_error(conn); struct mpd_message *msg; while ((msg = mpd_recv_message(conn)) != NULL) { printf("%s\n", mpd_message_get_text(msg)); mpd_message_free(msg); } if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(conn)) return handle_error(conn); } return handle_error(conn); } else if (argc == 2 && strcmp(argv[1], "channels") == 0) { /* print a list of channels */ if (!mpd_send_channels(conn)) return handle_error(conn); struct mpd_pair *pair; while ((pair = mpd_recv_channel_pair(conn)) != NULL) { printf("%s\n", pair->value); mpd_return_pair(conn, pair); } if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(conn)) return handle_error(conn); } else if (argc == 4 && strcmp(argv[1], "message") == 0) { /* send a message to a channel */ if (!mpd_run_send_message(conn, argv[2], argv[3])) return handle_error(conn); } mpd_connection_free(conn); return 0; }