Beispiel #1
0
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;
}
Beispiel #5
0
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);
}
Beispiel #7
0
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);
    }
}
Beispiel #8
0
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--;
	}

}
Beispiel #9
0
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;
}
Beispiel #10
0
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;
}
Beispiel #11
0
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;
}