00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "debug.h"
00023 #include "misc.h"
00024 #include "playlist.h"
00025 #include "plugin.h"
00026 #include "plugins.h"
00027
00028 static const gchar * get_extension (const gchar * filename, gboolean quiet)
00029 {
00030 const gchar * s = strrchr (filename, '/');
00031 if (! s)
00032 goto FAIL;
00033
00034 const gchar * p = strrchr (s + 1, '.');
00035 if (! p)
00036 goto FAIL;
00037
00038 return p + 1;
00039
00040 FAIL:
00041 if (! quiet)
00042 fprintf (stderr, "Failed to parse playlist filename %s.\n", filename);
00043 return NULL;
00044 }
00045
00046 gboolean filename_is_playlist (const gchar * filename)
00047 {
00048 const gchar * ext = get_extension (filename, TRUE);
00049 if (! ext)
00050 return FALSE;
00051
00052 return playlist_plugin_for_extension (ext) ? TRUE : FALSE;
00053 }
00054
00055 static PlaylistPlugin * get_plugin (const gchar * filename)
00056 {
00057 const gchar * ext = get_extension (filename, FALSE);
00058 if (! ext)
00059 return NULL;
00060
00061 PluginHandle * plugin = playlist_plugin_for_extension (ext);
00062 if (! plugin)
00063 {
00064 fprintf (stderr, "Unrecognized playlist file type \"%s\".\n", ext);
00065 return NULL;
00066 }
00067
00068 return plugin_get_header (plugin);
00069 }
00070
00071 gboolean playlist_load (const gchar * filename, gchar * * title,
00072 struct index * * filenames_p, struct index * * tuples_p)
00073 {
00074 AUDDBG ("Loading playlist %s.\n", filename);
00075 PlaylistPlugin * pp = get_plugin (filename);
00076 g_return_val_if_fail (pp && PLUGIN_HAS_FUNC (pp, load), FALSE);
00077
00078 VFSFile * file = vfs_fopen (filename, "r");
00079 if (! file)
00080 return FALSE;
00081
00082 struct index * filenames = index_new ();
00083 struct index * tuples = index_new ();
00084 gboolean success = pp->load (filename, file, title, filenames, tuples);
00085
00086 vfs_fclose (file);
00087
00088 if (! success)
00089 {
00090 index_free (filenames);
00091 index_free (tuples);
00092 return FALSE;
00093 }
00094
00095 if (index_count (tuples))
00096 g_return_val_if_fail (index_count (tuples) == index_count (filenames),
00097 FALSE);
00098 else
00099 {
00100 index_free (tuples);
00101 tuples = NULL;
00102 }
00103
00104 * filenames_p = filenames;
00105 * tuples_p = tuples;
00106 return TRUE;
00107 }
00108
00109 gboolean playlist_insert_playlist_raw (gint list, gint at,
00110 const gchar * filename)
00111 {
00112 gchar * title = NULL;
00113 struct index * filenames, * tuples;
00114
00115 if (! playlist_load (filename, & title, & filenames, & tuples))
00116 return FALSE;
00117
00118 if (title && ! playlist_entry_count (list))
00119 playlist_set_title (list, title);
00120
00121 playlist_entry_insert_batch_raw (list, at, filenames, tuples, NULL);
00122
00123 g_free (title);
00124 return TRUE;
00125 }
00126
00127 gboolean playlist_save (gint list, const gchar * filename)
00128 {
00129 AUDDBG ("Saving playlist %s.\n", filename);
00130 PlaylistPlugin * pp = get_plugin (filename);
00131 g_return_val_if_fail (pp && PLUGIN_HAS_FUNC (pp, save), FALSE);
00132
00133 gboolean fast = get_bool (NULL, "metadata_on_play");
00134
00135 VFSFile * file = vfs_fopen (filename, "w");
00136 if (! file)
00137 return FALSE;
00138
00139 gchar * title = playlist_get_title (list);
00140
00141 gint entries = playlist_entry_count (list);
00142 struct index * filenames = index_new ();
00143 index_allocate (filenames, entries);
00144 struct index * tuples = index_new ();
00145 index_allocate (tuples, entries);
00146
00147 for (gint i = 0; i < entries; i ++)
00148 {
00149 index_append (filenames, (void *) playlist_entry_get_filename (list, i));
00150 index_append (tuples, (void *) playlist_entry_get_tuple (list, i, fast));
00151 }
00152
00153 gboolean success = pp->save (filename, file, title, filenames, tuples);
00154
00155 vfs_fclose (file);
00156 g_free (title);
00157
00158 for (gint i = 0; i < entries; i ++)
00159 {
00160 g_free (index_get (filenames, i));
00161 Tuple * tuple = index_get (tuples, i);
00162 if (tuple)
00163 tuple_free (tuple);
00164 }
00165
00166 index_free (filenames);
00167 index_free (tuples);
00168
00169 return success;
00170 }