static struct playlist_provider * pls_open_stream(struct input_stream *is) { GError *error = NULL; size_t nbytes; char buffer[1024]; bool success; GKeyFile *keyfile; struct pls_playlist *playlist; GString *kf_data = g_string_new(""); do { nbytes = input_stream_lock_read(is, buffer, sizeof(buffer), &error); if (nbytes == 0) { if (error != NULL) { g_string_free(kf_data, TRUE); g_warning("%s", error->message); g_error_free(error); return NULL; } break; } kf_data = g_string_append_len(kf_data, buffer,nbytes); /* Limit to 64k */ } while(kf_data->len < 65536); if (kf_data->len == 0) { g_warning("KeyFile parser failed: No Data"); g_string_free(kf_data, TRUE); return NULL; } keyfile = g_key_file_new(); success = g_key_file_load_from_data(keyfile, kf_data->str, kf_data->len, G_KEY_FILE_NONE, &error); g_string_free(kf_data, TRUE); if (!success) { g_warning("KeyFile parser failed: %s", error->message); g_error_free(error); g_key_file_free(keyfile); return NULL; } playlist = g_new(struct pls_playlist, 1); playlist_provider_init(&playlist->base, &pls_playlist_plugin); playlist->songs = NULL; pls_parser(keyfile, playlist); g_key_file_free(keyfile); return &playlist->base; }
static struct playlist_provider * soundcloud_open_uri(const char *uri, GMutex *mutex, GCond *cond) { struct soundcloud_playlist *playlist = NULL; char *s, *p; char *scheme, *arg, *rest; s = g_strdup(uri); scheme = s; for (p = s; *p; p++) { if (*p == ':' && *(p+1) == '/' && *(p+2) == '/') { *p = 0; p += 3; break; } } arg = p; for (; *p; p++) { if (*p == '/') { *p = 0; p++; break; } } rest = p; if (strcmp(scheme, "soundcloud") != 0) { g_warning("incompatible scheme for soundcloud plugin: %s", scheme); g_free(s); return NULL; } char *u = NULL; if (strcmp(arg, "track") == 0) { u = g_strconcat("http://api.soundcloud.com/tracks/", rest, ".json?client_id=", soundcloud_config.apikey, NULL); } else if (strcmp(arg, "playlist") == 0) { u = g_strconcat("http://api.soundcloud.com/playlists/", rest, ".json?client_id=", soundcloud_config.apikey, NULL); } else if (strcmp(arg, "url") == 0) { /* Translate to soundcloud resolver call. libcurl will automatically follow the redirect to the right resource. */ u = soundcloud_resolve(rest); } g_free(s); if (u == NULL) { g_warning("unknown soundcloud URI"); return NULL; } yajl_handle hand; struct parse_data data; data.got_url = 0; data.songs = NULL; data.title = NULL; data.stream_url = NULL; hand = yajl_alloc(&parse_callbacks, NULL, NULL, (void *) &data); int ret = soundcloud_parse_json(u, hand, mutex, cond); g_free(u); yajl_free(hand); if (data.title != NULL) g_free(data.title); if (data.stream_url != NULL) g_free(data.stream_url); if (ret == -1) return NULL; playlist = g_new(struct soundcloud_playlist, 1); playlist_provider_init(&playlist->base, &soundcloud_playlist_plugin); playlist->songs = g_slist_reverse(data.songs); return &playlist->base; }
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; }