static void asx_start_element(G_GNUC_UNUSED GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer user_data, G_GNUC_UNUSED GError **error) { struct asx_parser *parser = user_data; switch (parser->state) { case ROOT: if (g_ascii_strcasecmp(element_name, "entry") == 0) { parser->state = ENTRY; parser->song = song_remote_new("asx:"); parser->tag = TAG_NUM_OF_ITEM_TYPES; } break; case ENTRY: if (g_ascii_strcasecmp(element_name, "ref") == 0) { const gchar *href = get_attribute(attribute_names, attribute_values, "href"); if (href != NULL) { /* create new song object, and copy the existing tag over; we cannot replace the existing song's URI, because that attribute is immutable */ struct song *song = song_remote_new(href); if (parser->song != NULL) { song->tag = parser->song->tag; parser->song->tag = NULL; song_free(parser->song); } parser->song = song; } } else if (g_ascii_strcasecmp(element_name, "author") == 0) /* is that correct? or should it be COMPOSER or PERFORMER? */ parser->tag = TAG_ARTIST; else if (g_ascii_strcasecmp(element_name, "title") == 0) parser->tag = TAG_TITLE; break; } }
static int handle_end_map(void *ctx) { struct parse_data *data = (struct parse_data *) ctx; if (data->got_url > 1) { data->got_url--; return 1; } if (data->got_url == 0) return 1; /* got_url == 1, track finished, make it into a song */ data->got_url = 0; struct song *s; struct tag *t; char *u; u = g_strconcat(data->stream_url, "?client_id=", soundcloud_config.apikey, NULL); s = song_remote_new(u); g_free(u); t = tag_new(); t->time = data->duration / 1000; if (data->title != NULL) tag_add_item(t, TAG_NAME, data->title); s->tag = t; data->songs = g_slist_prepend(data->songs, s); return 1; }
static void xspf_text(G_GNUC_UNUSED GMarkupParseContext *context, const gchar *text, gsize text_len, gpointer user_data, G_GNUC_UNUSED GError **error) { struct xspf_parser *parser = user_data; switch (parser->state) { case ROOT: case PLAYLIST: case TRACKLIST: break; case TRACK: if (parser->song != NULL && parser->tag != TAG_NUM_OF_ITEM_TYPES) { if (parser->song->tag == NULL) parser->song->tag = tag_new(); tag_add_item_n(parser->song->tag, parser->tag, text, text_len); } break; case LOCATION: if (parser->song == NULL) { char *uri = g_strndup(text, text_len); parser->song = song_remote_new(uri); g_free(uri); } break; } }
static struct song * song_by_uri(const char *uri) { struct song *song; song = db_get_song(uri); if (song != NULL) return song; if (uri_has_scheme(uri)) return song_remote_new(uri); return NULL; }
enum playlist_result spl_append_uri(const char *url, const char *utf8file) { struct song *song; if (uri_has_scheme(url)) { enum playlist_result ret; song = song_remote_new(url); ret = spl_append_song(utf8file, song); song_free(song); return ret; } else { song = db_get_song(url); if (song == NULL) return PLAYLIST_RESULT_NO_SUCH_SONG; return spl_append_song(utf8file, song); } }
static struct song * playlist_check_load_song(const struct song *song, const char *uri, bool secure) { struct song *dest; if (uri_has_scheme(uri)) { dest = song_remote_new(uri); } else if (g_path_is_absolute(uri) && secure) { dest = song_file_load(uri, NULL); if (dest == NULL) return NULL; } else { dest = db_get_song(uri); if (dest == NULL) /* not found in database */ return NULL; } return apply_song_metadata(dest, song); }
bool spl_append_uri(const char *url, const char *utf8file, GError **error_r) { struct song *song; if (uri_has_scheme(url)) { song = song_remote_new(url); bool success = spl_append_song(utf8file, song, error_r); song_free(song); return success; } else { song = db_get_song(url); if (song == NULL) { g_set_error_literal(error_r, playlist_quark(), PLAYLIST_RESULT_NO_SUCH_SONG, "No such song"); return false; } return spl_append_song(utf8file, song, error_r); } }
static void pls_parser(GKeyFile *keyfile, struct pls_playlist *playlist) { gchar *key; gchar *value; int length; GError *error = NULL; int num_entries = g_key_file_get_integer(keyfile, "playlist", "NumberOfEntries", &error); if (error) { g_debug("Invalid PLS file: '%s'", error->message); g_error_free(error); error = NULL; /* Hack to work around shoutcast failure to comform to spec */ num_entries = g_key_file_get_integer(keyfile, "playlist", "numberofentries", &error); if (error) { g_error_free(error); error = NULL; } } while (num_entries > 0) { struct song *song; key = g_strdup_printf("File%i", num_entries); value = g_key_file_get_string(keyfile, "playlist", key, &error); if(error) { g_debug("Invalid PLS entry %s: '%s'",key, error->message); g_error_free(error); g_free(key); return; } g_free(key); song = song_remote_new(value); g_free(value); key = g_strdup_printf("Title%i", num_entries); value = g_key_file_get_string(keyfile, "playlist", key, &error); g_free(key); if(error == NULL && value){ if (song->tag == NULL) song->tag = tag_new(); tag_add_item(song->tag,TAG_TITLE, value); } /* Ignore errors? Most likely value not present */ if(error) g_error_free(error); error = NULL; g_free(value); key = g_strdup_printf("Length%i", num_entries); length = g_key_file_get_integer(keyfile, "playlist", key, &error); g_free(key); if(error == NULL && length > 0){ if (song->tag == NULL) song->tag = tag_new(); song->tag->time = length; } /* Ignore errors? Most likely value not present */ if(error) g_error_free(error); error = NULL; playlist->songs = g_slist_prepend(playlist->songs, song); num_entries--; } }
struct song * playlist_check_translate_song(struct song *song, const char *base_uri) { struct song *dest; if (song_in_database(song)) /* already ok */ return song; char *uri = song->uri; if (uri_has_scheme(uri)) { if (uri_supported_scheme(uri)) /* valid remote song */ return song; else { /* unsupported remote song */ song_free(song); return NULL; } } if (g_path_is_absolute(uri)) { /* XXX fs_charset vs utf8? */ char *prefix = base_uri != NULL ? map_uri_fs(base_uri) : map_directory_fs(db_get_root()); if (prefix == NULL || !g_str_has_prefix(uri, prefix) || uri[strlen(prefix)] != '/') { /* local files must be relative to the music directory */ g_free(prefix); song_free(song); return NULL; } uri += strlen(prefix) + 1; g_free(prefix); } if (base_uri != NULL) uri = g_build_filename(base_uri, uri, NULL); else uri = g_strdup(uri); if (uri_has_scheme(base_uri)) { dest = song_remote_new(uri); g_free(uri); } else { dest = db_get_song(uri); g_free(uri); if (dest == NULL) { /* not found in database */ song_free(song); return dest; } } dest = apply_song_metadata(dest, song); song_free(song); return dest; }
struct song * song_load(FILE *fp, struct directory *parent, const char *uri, GString *buffer, GError **error_r) { struct song *song = parent != NULL ? song_file_new(uri, parent) : song_remote_new(uri); char *line, *colon; enum tag_type type; const char *value; while ((line = read_text_line(fp, buffer)) != NULL && strcmp(line, SONG_END) != 0) { colon = strchr(line, ':'); if (colon == NULL || colon == line) { if (song->tag != NULL) tag_end_add(song->tag); song_free(song); g_set_error(error_r, song_save_quark(), 0, "unknown line in db: %s", line); return NULL; } *colon++ = 0; value = g_strchug(colon); if ((type = tag_name_parse(line)) != TAG_NUM_OF_ITEM_TYPES) { if (!song->tag) { song->tag = tag_new(); tag_begin_add(song->tag); } tag_add_item(song->tag, type, value); } else if (strcmp(line, "Time") == 0) { if (!song->tag) { song->tag = tag_new(); tag_begin_add(song->tag); } song->tag->time = atoi(value); } else if (strcmp(line, SONG_MTIME) == 0) { song->mtime = atoi(value); } else if (strcmp(line, "Range") == 0) { char *endptr; song->start_ms = strtoul(value, &endptr, 10); if (*endptr == '-') song->end_ms = strtoul(endptr + 1, NULL, 10); } else { if (song->tag != NULL) tag_end_add(song->tag); song_free(song); g_set_error(error_r, song_save_quark(), 0, "unknown line in db: %s", line); return NULL; } } if (song->tag != NULL) tag_end_add(song->tag); return song; }
struct song * playlist_check_translate_song(struct song *song, const char *base_uri, bool secure) { struct song *dest; if (song_in_database(song)) /* already ok */ return song; char *uri = song->uri; if (uri_has_scheme(uri)) { if (uri_supported_scheme(uri)) /* valid remote song */ return song; else { /* unsupported remote song */ song_free(song); return NULL; } } if (base_uri != NULL && strcmp(base_uri, ".") == 0) /* g_path_get_dirname() returns "." when there is no directory name in the given path; clear that now, because it would break the database lookup functions */ base_uri = NULL; if (g_path_is_absolute(uri)) { /* XXX fs_charset vs utf8? */ const char *prefix = mapper_get_music_directory(); if (prefix != NULL && g_str_has_prefix(uri, prefix) && uri[strlen(prefix)] == '/') uri += strlen(prefix) + 1; else if (!secure) { /* local files must be relative to the music directory when "secure" is enabled */ song_free(song); return NULL; } base_uri = NULL; } if (base_uri != NULL) uri = g_build_filename(base_uri, uri, NULL); else uri = g_strdup(uri); if (uri_has_scheme(uri)) { dest = song_remote_new(uri); g_free(uri); } else if (g_path_is_absolute(uri) && secure) { dest = song_file_load(uri, NULL); if (dest == NULL) { song_free(song); return NULL; } } else { dest = db_get_song(uri); g_free(uri); if (dest == NULL) { /* not found in database */ song_free(song); return dest; } } dest = apply_song_metadata(dest, song); song_free(song); return dest; }