static enum playlist_result playlist_open_remote_into_queue(const char *uri, struct playlist *dest) { GError *error = NULL; struct playlist_provider *playlist; struct input_stream *is = NULL; enum playlist_result result; assert(uri_has_scheme(uri)); playlist = playlist_list_open_uri(uri); if (playlist == NULL) { is = input_stream_open(uri, &error); if (is == NULL) { if (error != NULL) { g_warning("Failed to open %s: %s", uri, error->message); g_error_free(error); } return PLAYLIST_RESULT_NO_SUCH_LIST; } playlist = playlist_list_open_stream(is, uri); if (playlist == NULL) { input_stream_close(is); return PLAYLIST_RESULT_NO_SUCH_LIST; } } result = playlist_load_into_queue(uri, playlist, dest); playlist_plugin_close(playlist); if (is != NULL) input_stream_close(is); return result; }
static struct playlist_provider * lastfm_open_uri(const char *uri, GMutex *mutex, GCond *cond) { struct lastfm_playlist *playlist; GError *error = NULL; char *p, *q, *response, *session; /* handshake */ p = g_strconcat("http://ws.audioscrobbler.com/radio/handshake.php?" "version=1.1.1&platform=linux&" "username="******"&" "passwordmd5=", lastfm_config.md5, "&" "debug=0&partner=", NULL); response = lastfm_get(p, mutex, cond); g_free(p); if (response == NULL) return NULL; /* extract session id from response */ session = lastfm_find(response, "session"); g_free(response); if (session == NULL) { g_warning("last.fm handshake failed"); return NULL; } q = g_uri_escape_string(session, NULL, false); g_free(session); session = q; g_debug("session='%s'", session); /* "adjust" last.fm radio */ if (strlen(uri) > 9) { char *escaped_uri; escaped_uri = g_uri_escape_string(uri, NULL, false); p = g_strconcat("http://ws.audioscrobbler.com/radio/adjust.php?" "session=", session, "&url=", escaped_uri, "&debug=0", NULL); g_free(escaped_uri); response = lastfm_get(p, mutex, cond); g_free(response); g_free(p); if (response == NULL) { g_free(session); return NULL; } } /* create the playlist object */ playlist = g_new(struct lastfm_playlist, 1); playlist_provider_init(&playlist->base, &lastfm_playlist_plugin); /* open the last.fm playlist */ p = g_strconcat("http://ws.audioscrobbler.com/radio/xspf.php?" "sk=", session, "&discovery=0&desktop=1.5.1.31879", NULL); g_free(session); playlist->is = input_stream_open(p, mutex, cond, &error); g_free(p); if (playlist->is == NULL) { if (error != NULL) { g_warning("Failed to load XSPF playlist: %s", error->message); g_error_free(error); } else g_warning("Failed to load XSPF playlist"); g_free(playlist); return NULL; } g_mutex_lock(mutex); input_stream_wait_ready(playlist->is); /* last.fm does not send a MIME type, we have to fake it here :-( */ g_free(playlist->is->mime); playlist->is->mime = g_strdup("application/xspf+xml"); g_mutex_unlock(mutex); /* parse the XSPF playlist */ playlist->xspf = playlist_list_open_stream(playlist->is, NULL); if (playlist->xspf == NULL) { input_stream_close(playlist->is); g_free(playlist); g_warning("Failed to parse XSPF playlist"); return NULL; } return &playlist->base; }
int main(int argc, char **argv) { const char *uri; struct input_stream *is = NULL; bool success; GError *error = NULL; struct playlist_provider *playlist; struct song *song; if (argc != 3) { g_printerr("Usage: dump_playlist CONFIG URI\n"); return 1; } uri = argv[2]; /* initialize GLib */ g_thread_init(NULL); g_log_set_default_handler(my_log_func, NULL); /* initialize MPD */ config_global_init(); success = config_read_file(argv[1], &error); if (!success) { g_printerr("%s\n", error->message); g_error_free(error); return 1; } io_thread_init(); if (!io_thread_start(&error)) { g_warning("%s", error->message); g_error_free(error); return EXIT_FAILURE; } if (!input_stream_global_init(&error)) { g_warning("%s", error->message); g_error_free(error); return 2; } playlist_list_global_init(); decoder_plugin_init_all(); /* open the playlist */ GMutex *mutex = g_mutex_new(); GCond *cond = g_cond_new(); playlist = playlist_list_open_uri(uri, mutex, cond); if (playlist == NULL) { /* open the stream and wait until it becomes ready */ is = input_stream_open(uri, mutex, cond, &error); if (is == NULL) { if (error != NULL) { g_warning("%s", error->message); g_error_free(error); } else g_printerr("input_stream_open() failed\n"); return 2; } input_stream_lock_wait_ready(is); /* open the playlist */ playlist = playlist_list_open_stream(is, uri); if (playlist == NULL) { input_stream_close(is); g_printerr("Failed to open playlist\n"); return 2; } } /* dump the playlist */ while ((song = playlist_plugin_read(playlist)) != NULL) { g_print("%s\n", song->uri); if (song->end_ms > 0) g_print("range: %u:%02u..%u:%02u\n", song->start_ms / 60000, (song->start_ms / 1000) % 60, song->end_ms / 60000, (song->end_ms / 1000) % 60); else if (song->start_ms > 0) g_print("range: %u:%02u..\n", song->start_ms / 60000, (song->start_ms / 1000) % 60); if (song->tag != NULL) tag_save(stdout, song->tag); song_free(song); } /* deinitialize everything */ playlist_plugin_close(playlist); if (is != NULL) input_stream_close(is); g_cond_free(cond); g_mutex_free(mutex); decoder_plugin_deinit_all(); playlist_list_global_finish(); input_stream_global_finish(); io_thread_deinit(); config_global_finish(); return 0; }