Пример #1
0
static gboolean queue_track_to_scrobble (gpointer data) {
    AUDDBG("The playing track is going to be ENQUEUED!\n.");
    gchar *tab_remover;

    char *queuepath = g_strconcat(aud_get_path(AUD_PATH_USER_DIR),"/scrobbler.log", NULL);

    char *artist = tuple_get_str(playing_track, FIELD_ARTIST);
    char *title  = tuple_get_str(playing_track, FIELD_TITLE);
    char *album  = tuple_get_str(playing_track, FIELD_ALBUM);

    tab_remover = remove_tabs(artist);
    str_unref(artist);
    artist = tab_remover;

    tab_remover = remove_tabs(title);
    str_unref(title);
    title = tab_remover;

    tab_remover = remove_tabs(album);
    str_unref(album);
    album = tab_remover;
    tab_remover = NULL;

    int number = tuple_get_int(playing_track, FIELD_TRACK_NUMBER);
    int length = tuple_get_int(playing_track, FIELD_LENGTH) / 1000;

    //artist, title and timestamp are required for a successful scrobble
    if (  artist != NULL && strlen(artist) > 0
        && title != NULL && strlen(title)  > 0) {

        pthread_mutex_lock(&log_access_mutex);
        FILE *f = fopen(queuepath, "a");

        if (f == NULL) {
            perror("fopen");
        } else {
            //This isn't exactly the scrobbler.log format because the header
            //is missing, but we're sticking to it anyway...
            //See http://www.audioscrobbler.net/wiki/Portable_Player_Logging
            if (fprintf(f, "%s\t%s\t%s\t%i\t%i\t%s\t%"G_GINT64_FORMAT"\n",
                        artist, (album == NULL ? "" : album), title, number, length, "L", timestamp
                       ) < 0) {
                perror("fprintf");
            } else {
                pthread_mutex_lock(&communication_mutex);
                pthread_cond_signal(&communication_signal);
                pthread_mutex_unlock(&communication_mutex);
            }
            fclose(f);
        }
        pthread_mutex_unlock(&log_access_mutex);
    }
    g_free(queuepath);
    g_free(artist);
    g_free(title);
    g_free(album);

    cleanup_current_track();
    return FALSE;
}
Пример #2
0
static char * strdup_tuple_filename (const Tuple * tuple)
{
    gchar * fpath = tuple_get_str (tuple, FIELD_FILE_PATH, NULL);
    gchar * fname = tuple_get_str (tuple, FIELD_FILE_NAME, NULL);

    gchar * filename = g_strdup_printf ("%s/%s", fpath, fname);

    str_unref (fpath);
    str_unref (fname);

    return filename;
}
Пример #3
0
static void insert_vorbis_comment (FLAC__StreamMetadata * meta,
 const char * name, const Tuple * tuple, int field)
{
    TupleValueType type = tuple_field_get_type (field);
    if (tuple_get_value_type (tuple, field, NULL) != type)
        return;

    char * temp;

    switch (type)
    {
    case TUPLE_INT:;
        int ival = tuple_get_int (tuple, field, NULL);
        temp = g_strdup_printf ("%s=%d", name, ival);
        break;
    case TUPLE_STRING:;
        char * sval = tuple_get_str (tuple, field, NULL);
        temp = g_strdup_printf ("%s=%s", name, sval);
        str_unref (sval);
    default:
        return;
    }

    FLAC__StreamMetadata_VorbisComment_Entry comment;
    comment.length = strlen (temp);
    comment.entry = (unsigned char *) temp;

    FLAC__metadata_object_vorbiscomment_insert_comment (meta,
     meta->data.vorbis_comment.num_comments, comment, TRUE);

    g_free (temp);
}
Пример #4
0
static void set_string_from_tuple (GValue * value, const Tuple * tuple,
 gint field)
{
    gchar *str = tuple ? tuple_get_str (tuple, field, NULL) : NULL;
    g_value_set_string (value, str);
    str_unref(str);
}
Пример #5
0
static void add_frameFromTupleStr (const Tuple * tuple, int field, int
 id3_field, GHashTable * dict)
{
    char * str = tuple_get_str (tuple, field);
    add_text_frame (id3_field, str, dict);
    str_unref (str);
}
Пример #6
0
static bool_t audpl_save (const char * path, VFSFile * file,
 const char * title, Index * filenames, Index * tuples)
{
    if (! write_key (file, "title", title))
        return FALSE;

    int count = index_count (filenames);

    for (int i = 0; i < count; i ++)
    {
        if (! write_key (file, "uri", index_get (filenames, i)))
            return FALSE;

        const Tuple * tuple = tuples ? index_get (tuples, i) : NULL;

        if (tuple)
        {
            int keys = 0;

            for (int f = 0; f < TUPLE_FIELDS; f ++)
            {
                if (f == FIELD_FILE_PATH || f == FIELD_FILE_NAME || f == FIELD_FILE_EXT)
                    continue;

                TupleValueType type = tuple_get_value_type (tuple, f, NULL);

                if (type == TUPLE_STRING)
                {
                    char * str = tuple_get_str (tuple, f, NULL);

                    if (! write_key (file, tuple_field_get_name (f), str))
                    {
                        str_unref (str);
                        return FALSE;
                    }

                    str_unref (str);
                    keys ++;
                }
                else if (type == TUPLE_INT)
                {
                    char buf[32];
                    snprintf (buf, sizeof buf, "%d", tuple_get_int (tuple, f, NULL));

                    if (! write_key (file, tuple_field_get_name (f), buf))
                        return FALSE;

                    keys ++;
                }
            }

            /* distinguish between an empty tuple and no tuple at all */
            if (! keys && ! write_key (file, "empty", "1"))
                return FALSE;
        }
    }

    return TRUE;
}
Пример #7
0
static bool_t id3v24_write_tag (const Tuple * tuple, VFSFile * f)
{
    int version, header_size, data_size, footer_size;
    bool_t syncsafe;
    int64_t offset;

    if (! read_header (f, & version, & syncsafe, & offset, & header_size,
     & data_size, & footer_size))
        return FALSE;

    //read all frames into generic frames;
    GHashTable * dict = g_hash_table_new_full (g_str_hash, g_str_equal,
     (GDestroyNotify) str_unref, (GDestroyNotify) free_frame_list);
    read_all_frames (f, version, syncsafe, data_size, dict);

    //make the new frames from tuple and replace in the dictionary the old frames with the new ones
    add_frameFromTupleStr (tuple, FIELD_TITLE, ID3_TITLE, dict);
    add_frameFromTupleStr (tuple, FIELD_ARTIST, ID3_ARTIST, dict);
    add_frameFromTupleStr (tuple, FIELD_ALBUM, ID3_ALBUM, dict);
    add_frameFromTupleInt (tuple, FIELD_YEAR, ID3_YEAR, dict);
    add_frameFromTupleInt (tuple, FIELD_TRACK_NUMBER, ID3_TRACKNR, dict);
    add_frameFromTupleStr (tuple, FIELD_GENRE, ID3_GENRE, dict);

    char * comment = tuple_get_str (tuple, FIELD_COMMENT);
    add_comment_frame (comment, dict);
    str_unref (comment);

    if (! offset)
    {
        if (! cut_beginning_tag (f, header_size + data_size + footer_size))
            goto ERR;
    }
    else
    {
        if (offset + header_size + data_size + footer_size != vfs_fsize (f))
            goto ERR;
        if (vfs_ftruncate (f, offset))
            goto ERR;
    }

    offset = vfs_fsize (f);

    if (offset < 0 || vfs_fseek (f, offset, SEEK_SET) || ! write_header (f, 0,
     FALSE))
        goto ERR;

    data_size = write_all_frames (f, dict);

    if (! write_header (f, data_size, TRUE) || vfs_fseek (f, offset, SEEK_SET)
     || ! write_header (f, data_size, FALSE))
        goto ERR;

    g_hash_table_destroy (dict);
    return TRUE;

ERR:
    g_hash_table_destroy (dict);
    return FALSE;
}
Пример #8
0
static int tuple_compare_string (const Tuple * a, const Tuple * b, int field)
{
    char * string_a = tuple_get_str (a, field, NULL);
    char * string_b = tuple_get_str (b, field, NULL);
    int ret;

    if (string_a == NULL)
        ret = (string_b == NULL) ? 0 : -1;
    else if (string_b == NULL)
        ret = 1;
    else
        ret = string_compare (string_a, string_b);

    str_unref (string_a);
    str_unref (string_b);
    return ret;
}
Пример #9
0
static void infowin_show (int list, int entry, const char * filename,
 const Tuple * tuple, PluginHandle * decoder, bool_t updating_enabled)
{
    char * tmp;

    if (infowin == NULL)
        create_infowin ();
    else
        clear_infowin ();

    current_file = g_strdup (filename);
    current_decoder = decoder;
    can_write = updating_enabled;

    set_entry_str_from_field (entry_title, tuple, FIELD_TITLE, updating_enabled);
    set_entry_str_from_field (entry_artist, tuple, FIELD_ARTIST,
     updating_enabled);
    set_entry_str_from_field (entry_album, tuple, FIELD_ALBUM, updating_enabled);
    set_entry_str_from_field (entry_comment, tuple, FIELD_COMMENT,
     updating_enabled);
    set_entry_str_from_field (gtk_bin_get_child ((GtkBin *) entry_genre), tuple,
     FIELD_GENRE, updating_enabled);

    tmp = uri_to_display (filename);
    gtk_label_set_text ((GtkLabel *) location_text, tmp);
    g_free (tmp);

    set_entry_int_from_field (entry_year, tuple, FIELD_YEAR, updating_enabled);
    set_entry_int_from_field (entry_track, tuple, FIELD_TRACK_NUMBER,
     updating_enabled);

    infowin_label_set_text (label_format_name, tuple_get_str (tuple, FIELD_CODEC, NULL));
    infowin_label_set_text (label_quality, tuple_get_str (tuple, FIELD_QUALITY, NULL));

    if (tuple_get_value_type (tuple, FIELD_BITRATE, NULL) == TUPLE_INT)
        infowin_label_set_text (label_bitrate, str_printf (_("%d kb/s"),
         tuple_get_int (tuple, FIELD_BITRATE, NULL)));
    else
        infowin_label_set_text (label_bitrate, NULL);

    infowin_entry_set_image (image_artwork, list, entry);

    gtk_window_present ((GtkWindow *) infowin);
}
Пример #10
0
static void set_entry_str_from_field (GtkWidget * widget, const Tuple * tuple,
 int fieldn, bool_t editable)
{
    char * text = tuple_get_str (tuple, fieldn, NULL);

    gtk_entry_set_text ((GtkEntry *) widget, text != NULL ? text : "");
    gtk_editable_set_editable ((GtkEditable *) widget, editable);

    str_unref (text);
}
Пример #11
0
static void add_string_from_tuple (vorbis_comment * vc, const char * name,
 const Tuple * tuple, gint field)
{
    gchar * val = tuple_get_str (tuple, field, NULL);
    if (! val)
        return;

    vorbis_comment_add_tag (vc, name, val);
    str_unref (val);
}
Пример #12
0
void playlist_select_by_patterns (int playlist, const Tuple * patterns)
{
    const int fields[] = {FIELD_TITLE, FIELD_ALBUM, FIELD_ARTIST,
     FIELD_FILE_NAME};

    int entries = playlist_entry_count (playlist);
    int field, entry;

    playlist_select_all (playlist, TRUE);

    for (field = 0; field < G_N_ELEMENTS (fields); field ++)
    {
        char * pattern = tuple_get_str (patterns, fields[field], NULL);
        regex_t regex;

        if (! pattern || ! pattern[0] || regcomp (& regex, pattern, REG_ICASE))
        {
            str_unref (pattern);
            continue;
        }

        for (entry = 0; entry < entries; entry ++)
        {
            if (! playlist_entry_get_selected (playlist, entry))
                continue;

            Tuple * tuple = playlist_entry_get_tuple (playlist, entry, FALSE);
            char * string = tuple ? tuple_get_str (tuple, fields[field], NULL) : NULL;

            if (! string || regexec (& regex, string, 0, NULL, 0))
                playlist_entry_set_selected (playlist, entry, FALSE);

            str_unref (string);
            if (tuple)
                tuple_unref (tuple);
        }

        regfree (& regex);
        str_unref (pattern);
    }
}
Пример #13
0
static void insert_str_tuple_field_to_dictionary (const Tuple * tuple, int
 fieldn, GHashTable * dict, const char * key)
{
    char * val = tuple_get_str (tuple, fieldn);

    if (val && val[0])
        g_hash_table_insert (dict, str_get (key), str_ref (val));
    else
        g_hash_table_remove (dict, key);

    str_unref(val);
}
Пример #14
0
static char * get_nonblank_field (const Tuple * tuple, int field)
{
    char * str = tuple ? tuple_get_str (tuple, field, NULL) : NULL;

    if (str && ! str[0])
    {
        str_unref (str);
        str = NULL;
    }

    return str;
}
Пример #15
0
static void add_text (Tuple * tuple, int field, const char * value)
{
    char * cur = tuple_get_str (tuple, field, NULL);
    if (cur)
    {
        SPRINTF (both, "%s, %s", cur, value);
        tuple_set_str (tuple, field, NULL, both);
    }
    else
        tuple_set_str (tuple, field, NULL, value);

    str_unref(cur);
}
Пример #16
0
static void insert_str_tuple_to_vc (FLAC__StreamMetadata * vc_block,
 const Tuple * tuple, int tuple_name, char * field_name)
{
    FLAC__StreamMetadata_VorbisComment_Entry entry;
    char *val = tuple_get_str(tuple, tuple_name, NULL);

    if (val == NULL)
        return;

    SPRINTF (str, "%s=%s", field_name, val);
    entry.entry = (FLAC__byte *) str;
    entry.length = strlen(str);
    FLAC__metadata_object_vorbiscomment_insert_comment(vc_block,
        vc_block->data.vorbis_comment.num_comments, entry, true);
    str_unref(val);
}
Пример #17
0
static char * strdup_tuple_field (const Tuple * tuple, int field)
{
    char * sval, * dup;
    int ival;

    switch (tuple_get_value_type (tuple, field, NULL))
    {
    case TUPLE_INT:
        ival = tuple_get_int (tuple, field, NULL);
        dup = g_strdup_printf ("%d", ival);
        break;
    case TUPLE_STRING:
        sval = tuple_get_str (tuple, field, NULL);
        dup = g_strdup (sval);
        str_unref (sval);
        break;
    default:
        dup = NULL;
        break;
    }

    return dup;
}
Пример #18
0
static gint mp3_open(void)
{
    int imp3;

    gfp = lame_init();
    if (gfp == NULL)
        return 0;

    /* setup id3 data */
    id3tag_init(gfp);

    if (tuple) {
        /* XXX write UTF-8 even though libmp3lame does id3v2.3. --yaz */
        lameid3.track_name = tuple_get_str (tuple, FIELD_TITLE, NULL);
        id3tag_set_title(gfp, lameid3.track_name);

        lameid3.performer = tuple_get_str (tuple, FIELD_ARTIST, NULL);
        id3tag_set_artist(gfp, lameid3.performer);

        lameid3.album_name = tuple_get_str (tuple, FIELD_ALBUM, NULL);
        id3tag_set_album(gfp, lameid3.album_name);

        lameid3.genre = tuple_get_str (tuple, FIELD_GENRE, NULL);
        id3tag_set_genre(gfp, lameid3.genre);

        lameid3.year = str_printf ("%d", tuple_get_int (tuple, FIELD_YEAR, NULL));
        id3tag_set_year(gfp, lameid3.year);

        lameid3.track_number = str_printf ("%d", tuple_get_int (tuple, FIELD_TRACK_NUMBER, NULL));
        id3tag_set_track(gfp, lameid3.track_number);

        if (force_v2_val) {
            id3tag_add_v2(gfp);
        }
        if (only_v1_val) {
            id3tag_v1_only(gfp);
        }
        if (only_v2_val) {
            id3tag_v2_only(gfp);
        }
    }

    /* input stream description */

    lame_set_in_samplerate(gfp, input.frequency);
    lame_set_num_channels(gfp, input.channels);
    /* Maybe implement this? */
    /* lame_set_scale(lame_global_flags *, float); */
    lame_set_out_samplerate(gfp, out_samplerate_val);

    /* general control parameters */

    lame_set_bWriteVbrTag(gfp, toggle_xing_val);
    lame_set_quality(gfp, algo_quality_val);
    if (audio_mode_val != 4) {
        AUDDBG("set mode to %d\n", audio_mode_val);
        lame_set_mode(gfp, audio_mode_val);
    }

    lame_set_errorf(gfp, lame_debugf);
    lame_set_debugf(gfp, lame_debugf);
    lame_set_msgf(gfp, lame_debugf);

    if (enc_toggle_val == 0 && vbr_on == 0)
        lame_set_brate(gfp, bitrate_val);
    else if (vbr_on == 0)
        lame_set_compression_ratio(gfp, compression_val);

    /* frame params */

    lame_set_copyright(gfp, mark_copyright_val);
    lame_set_original(gfp, mark_original_val);
    lame_set_error_protection(gfp, error_protect_val);
    lame_set_strict_ISO(gfp, enforce_iso_val);

    if (vbr_on != 0) {
        if (vbr_type == 0)
            lame_set_VBR(gfp, 2);
        else
            lame_set_VBR(gfp, 3);
        lame_set_VBR_q(gfp, vbr_quality_val);
        lame_set_VBR_mean_bitrate_kbps(gfp, abr_val);
        lame_set_VBR_min_bitrate_kbps(gfp, vbr_min_val);
        lame_set_VBR_max_bitrate_kbps(gfp, vbr_max_val);
        lame_set_VBR_hard_min(gfp, enforce_min_val);
    }

    /* not to write id3 tag automatically. */
    lame_set_write_id3tag_automatic(gfp, 0);

    if (lame_init_params(gfp) == -1)
        return 0;

    /* write id3v2 header */
    imp3 = lame_get_id3v2_tag(gfp, encbuffer, sizeof(encbuffer));

    if (imp3 > 0) {
        write_output(encbuffer, imp3);
        id3v2_size = imp3;
    }
    else {
        id3v2_size = 0;
    }

    write_buffer = NULL;
    write_buffer_size = 0;

    return 1;
}
Пример #19
0
/* do_command(): do @cmd after replacing the format codes
   @cmd: command to run */
static void do_command (char * cmd)
{
    int playlist = aud_playlist_get_playing ();
    int pos = aud_playlist_get_position (playlist);

    char *shstring = NULL, *temp, numbuf[32];
    gboolean playing;
    Formatter *formatter;

    if (cmd && strlen(cmd) > 0)
    {
        formatter = formatter_new();

        char * ctitle = aud_playlist_entry_get_title (playlist, pos, FALSE);
        if (ctitle)
        {
            temp = escape_shell_chars (ctitle);
            formatter_associate(formatter, 's', temp);
            formatter_associate(formatter, 'n', temp);
            g_free(temp);
            str_unref (ctitle);
        }
        else
        {
            formatter_associate(formatter, 's', "");
            formatter_associate(formatter, 'n', "");
        }

        char * filename = aud_playlist_entry_get_filename (playlist, pos);
        if (filename)
        {
            temp = escape_shell_chars (filename);
            formatter_associate(formatter, 'f', temp);
            g_free(temp);
            str_unref (filename);
        }
        else
            formatter_associate(formatter, 'f', "");

        g_snprintf(numbuf, sizeof(numbuf), "%02d", pos + 1);
        formatter_associate(formatter, 't', numbuf);

        int length = aud_playlist_entry_get_length (playlist, pos, FALSE);
        if (length > 0)
        {
            g_snprintf(numbuf, sizeof(numbuf), "%d", length);
            formatter_associate(formatter, 'l', numbuf);
        }
        else
            formatter_associate(formatter, 'l', "0");

        playing = aud_drct_get_playing();
        g_snprintf(numbuf, sizeof(numbuf), "%d", playing);
        formatter_associate(formatter, 'p', numbuf);

        if (playing)
        {
            int brate, srate, chans;
            aud_drct_get_info (& brate, & srate, & chans);
            snprintf (numbuf, sizeof numbuf, "%d", brate);
            formatter_associate (formatter, 'r', numbuf);
            snprintf (numbuf, sizeof numbuf, "%d", srate);
            formatter_associate (formatter, 'F', numbuf);
            snprintf (numbuf, sizeof numbuf, "%d", chans);
            formatter_associate (formatter, 'c', numbuf);
        }

        Tuple * tuple = aud_playlist_entry_get_tuple
            (aud_playlist_get_active (), pos, 0);

        char * artist = tuple ? tuple_get_str (tuple, FIELD_ARTIST, NULL) : NULL;
        if (artist)
        {
            formatter_associate(formatter, 'a', artist);
            str_unref(artist);
        }
        else
            formatter_associate(formatter, 'a', "");

        char * album = tuple ? tuple_get_str (tuple, FIELD_ALBUM, NULL) : NULL;
        if (album)
        {
            formatter_associate(formatter, 'b', album);
            str_unref(album);
        }
        else
            formatter_associate(formatter, 'b', "");

        char * title = tuple ? tuple_get_str (tuple, FIELD_TITLE, NULL) : NULL;
        if (title)
        {
            formatter_associate(formatter, 'T', title);
            str_unref(title);
        }
        else
            formatter_associate(formatter, 'T', "");

        if (tuple)
            tuple_unref (tuple);

        shstring = formatter_format(formatter, cmd);
        formatter_destroy(formatter);

        if (shstring)
        {
            execute_command(shstring);
            /* FIXME: This can possibly be freed too early */
            g_free(shstring);
        }
    }
}
static void send_now_playing() {

  gchar *error_code = NULL;
  gchar *error_detail = NULL;
  /*
   * now_playing_track can be set to something else while we this method is
   * running. Creating a local variable avoids to get data for different tracks,
   * while now_playing_track was updated concurrently.
   */
  Tuple *curr_track = now_playing_track;

  gchar *tab_remover;

  gchar *artist = tuple_get_str(curr_track, FIELD_ARTIST, NULL);
  gchar *album = tuple_get_str(curr_track, FIELD_ALBUM, NULL);
  gchar *title = tuple_get_str(curr_track, FIELD_TITLE, NULL);

  tab_remover = remove_tabs(artist);
  str_unref(artist);
  artist = tab_remover;

  tab_remover = remove_tabs(album);
  str_unref(album);
  album = tab_remover;

  tab_remover = remove_tabs(title);
  str_unref(title);
  title = tab_remover;

  tab_remover = NULL;

  gchar *number = g_strdup_printf("%i", tuple_get_int(curr_track, FIELD_TRACK_NUMBER, NULL));
  gchar *length = g_strdup_printf("%i", tuple_get_int(curr_track, FIELD_LENGTH, NULL) / 1000);
  tuple_unref(curr_track);


  if (artist != NULL && strlen(artist) > 0 &&
       title != NULL && strlen(title)  > 0) {

    gchar *playingmsg = create_message_to_lastfm("track.updateNowPlaying",
                                            7,
                                           "artist", artist,
                                           "album", (album == NULL ? "" : album),
                                           "track", title,
                                           "trackNumber", number,
                                           "duration", length,
                                           "api_key", SCROBBLER_API_KEY,
                                           "sk", session_key);
    g_free(artist);
    g_free(album);
    g_free(title);
    g_free(number);
    g_free(length);

    bool_t success = send_message_to_lastfm(playingmsg);
    g_free(playingmsg);
    if (success == FALSE) {
      AUDDBG("Network problems. Could not send \"now playing\" to last.fm\n");
      scrobbling_enabled = FALSE;
      return;
    }

    if (read_scrobble_result(&error_code, &error_detail) == TRUE) {
      //see scrobble_cached_queue()
      AUDDBG("NOW PLAYING OK.\n");
    } else {
      AUDDBG("NOW PLAYING NOT OK. Error code: %s. Error detail: %s.\n", error_code, error_detail);
      //From the API: Now Playing requests that fail should not be retried.

      if (g_strcmp0(error_code, "9") == 0) {
        //Bad Session. Reauth.
        //We don't really care about any other errors.
        scrobbling_enabled = FALSE;
        g_free(session_key);
        session_key = NULL;
        aud_set_string("scrobbler", "session_key", "");
      }

    }
    g_free(error_code);
    g_free(error_detail);
    //We don't care if the now playing was not accepted, no need to read the result from the server.

  }
}
Пример #21
0
static gboolean update_song_tuple(const Tuple * tuple, VFSFile *file)
{
#if _AUD_PLUGIN_VERSION < 38
#define vfs_get_filename(file)  g_filename_from_uri(file->uri, NULL, NULL)
#define tuple_get_str  tuple_get_string
#define str_unref(s)
	const char *s;
#else
	char *s;
#endif
	/* read file */
	const char *filename = vfs_get_filename(file);
	unsigned char module[ASAPInfo_MAX_MODULE_LENGTH];
	int module_len = load_module(filename, file, module);
	ASAPInfo *info;
	int year;
	ByteWriter bw;
	gboolean ok;
	if (module_len <= 0)
		return FALSE;
	info = ASAPInfo_New();
	if (info == NULL)
		return FALSE;
	if (!ASAPInfo_Load(info, filename, module, module_len)) {
		ASAPInfo_Delete(info);
		return FALSE;
	}

	/* apply new tags */
	s = tuple_get_str(tuple, FIELD_ARTIST, NULL);
	if (s != NULL) {
		if (!ASAPInfo_SetAuthor(info, s)) {
			str_unref(s);
			ASAPInfo_Delete(info);
			return FALSE;
		}
		str_unref(s);
	}
	else
		ASAPInfo_SetAuthor(info, "");
	s = tuple_get_str(tuple, FIELD_TITLE, NULL);
	if (s != NULL) {
		if (!ASAPInfo_SetTitle(info, s)) {
			str_unref(s);
			ASAPInfo_Delete(info);
			return FALSE;
		}
		str_unref(s);
	}
	else
		ASAPInfo_SetTitle(info, "");
	year = tuple_get_int(tuple, FIELD_YEAR, NULL);
	if (year == 0)
		year = -1;
	/* check if year changed so that we don't lose other date parts */
	if (year != ASAPInfo_GetYear(info)) {
		if (year <= 0)
			ASAPInfo_SetDate(info, "");
		else {
			char d[16];
			sprintf(d, "%d", year);
			ASAPInfo_SetDate(info, d);
		}
	}

	/* write file */
	vfs_rewind(file);
	bw.obj = file;
	bw.func = write_byte;
	ok = ASAPWriter_Write(filename, bw, info, module, module_len, TRUE) && vfs_ftruncate(file, vfs_ftell(file)) == 0;
	ASAPInfo_Delete(info);
	return ok;
}
Пример #22
0
static gboolean xspf_playlist_save (const gchar * filename, VFSFile * file,
 const gchar * title, Index * filenames, Index * tuples)
{
    gint entries = index_count (filenames);
    xmlDocPtr doc;
    xmlNodePtr rootnode, tracklist;
    gint count;

    doc = xmlNewDoc((xmlChar *)"1.0");
    doc->charset = XML_CHAR_ENCODING_UTF8;
    doc->encoding = xmlStrdup((xmlChar *)"UTF-8");

    rootnode = xmlNewNode(NULL, (xmlChar *)XSPF_ROOT_NODE_NAME);
    xmlSetProp(rootnode, (xmlChar *)"version", (xmlChar *)"1");
    xmlSetProp(rootnode, (xmlChar *)"xmlns", (xmlChar *)XSPF_XMLNS);

    /* common */
    xmlDocSetRootElement(doc, rootnode);

    if (title)
        xspf_add_node (rootnode, TUPLE_STRING, FALSE, "title", title, 0);

    tracklist = xmlNewNode(NULL, (xmlChar *)"trackList");
    xmlAddChild(rootnode, tracklist);

    for (count = 0; count < entries; count ++)
    {
        const gchar * filename = index_get (filenames, count);
        const Tuple * tuple = index_get (tuples, count);
        xmlNodePtr track, location;
        gchar *scratch = NULL;
        gint scratchi = 0;

        track = xmlNewNode(NULL, (xmlChar *)"track");
        location = xmlNewNode(NULL, (xmlChar *)"location");

        xmlAddChild(location, xmlNewText((xmlChar *)filename));
        xmlAddChild(track, location);
        xmlAddChild(tracklist, track);

        if (tuple != NULL)
        {
            gint i;
            for (i = 0; i < xspf_nentries; i++) {
                const xspf_entry_t *xs = &xspf_entries[i];
                gboolean isOK = (tuple_get_value_type (tuple, xs->tupleField,
                 NULL) == xs->type);

                switch (xs->type) {
                    case TUPLE_STRING:
                        scratch = tuple_get_str (tuple, xs->tupleField, NULL);
                        if (! scratch)
                            isOK = FALSE;
                        str_unref(scratch);
                        break;
                    case TUPLE_INT:
                        scratchi = tuple_get_int (tuple, xs->tupleField, NULL);
                        break;
                    default:
                        break;
                }

                if (isOK)
                    xspf_add_node(track, xs->type, xs->isMeta, xs->xspfName, scratch, scratchi);
            }
        }
    }

    xmlSaveCtxt * save = xmlSaveToIO (write_cb, close_cb, file, NULL,
     XML_SAVE_FORMAT);
    if (! save)
        goto ERR;

    if (xmlSaveDoc (save, doc) < 0 || xmlSaveClose (save) < 0)
        goto ERR;

    xmlFreeDoc(doc);
    return TRUE;

ERR:
    xmlFreeDoc (doc);
    return FALSE;
}