diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | configure.ac | 13 | ||||
-rw-r--r-- | tests/Makefile.am | 17 | ||||
-rw-r--r-- | tests/test-ls.c | 122 | ||||
-rw-r--r-- | tests/test-rebuild-db.cc | 250 |
5 files changed, 413 insertions, 1 deletions
@@ -1,5 +1,17 @@ 2006-04-10 Christophe Fergeau <teuf@gnome.org> + * tests/test-ls.c: new test program reading and displaying the iPod + content + * tests/test-rebuild-db.cc: new test program which looks for mp3 files + on the iPod in the Music dir and rebuild an iPod database from that + (it uses taglib to parse the tags, so it's conditionnally built + depending on taglib's availability) + * configure.ac: + * tests/Makefile.am: build system changes to accomodate the 2 new test + programs + +2006-04-10 Christophe Fergeau <teuf@gnome.org> + * src/itdb_device.h: removed dead code * src/itdb_playlist.c: make spl_update2 static, kill spl_update diff --git a/configure.ac b/configure.ac index 9b8a28d..1ad397c 100644 --- a/configure.ac +++ b/configure.ac @@ -55,6 +55,19 @@ PKG_CHECK_MODULES(LIBGPOD, glib-2.0 >= 2.4.0 gobject-2.0) LIBGPOD_CFLAGS="$LIBGPOD_CFLAGS -Wall" dnl ************************************************** +dnl * TagLib is only used by test-rebuild-db +dnl ************************************************** +PKG_CHECK_MODULES(TAGLIB, taglib, have_taglib=yes, have_taglib=no) +if test x"$have_taglib" = xyes; then + AH_TEMPLATE([HAVE_TAGLIB], [Whether TagLib is installed, it's only used in a test program]) + AC_DEFINE_UNQUOTED(HAVE_TAGLIB, 1) +fi +AC_SUBST(TAGLIB_CFLAGS) +AC_SUBST(TAGLIB_LIBS) +AM_CONDITIONAL(HAVE_TAGLIB, test x"$have_taglib" = xyes) + + +dnl ************************************************** dnl * GDKPIXBUF is optional dnl ************************************************** diff --git a/tests/Makefile.am b/tests/Makefile.am index 2986631..62ea218 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -4,7 +4,13 @@ else TESTTHUMBS= endif -noinst_PROGRAMS=test-itdb $(TESTTHUMBS) +if HAVE_TAGLIB +TESTTAGLIB=test-rebuild-db +else +TESTTAGLIB= +endif + +noinst_PROGRAMS=test-itdb test-ls test-rebuild-db $(TESTTHUMBS) $(TESTTAGLIB) INCLUDES=$(LIBGPOD_CFLAGS) -I$(top_srcdir)/src -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" LIBS=$(LIBGPOD_LIBS) $(top_builddir)/src/libgpod.la @@ -12,6 +18,15 @@ LIBS=$(LIBGPOD_LIBS) $(top_builddir)/src/libgpod.la test_itdb_SOURCES = itdb_main.c test_itdb_LDADD = +test_ls_SOURCES = test-ls.c +test_ls_LDADD = + +if HAVE_TAGLIB +test_rebuild_db_SOURCES = test-rebuild-db.cc +test_rebuild_db_LDADD = $(TAGLIB_LIBS) +test_rebuild_db_CXXFLAGS = $(TAGLIB_CFLAGS) +endif + if HAVE_GDKPIXBUF test_thumbnails_SOURCES = test-covers.c test_thumbnails_CFLAGS = $(AM_CFLAGS) diff --git a/tests/test-ls.c b/tests/test-ls.c new file mode 100644 index 0000000..b1376bd --- /dev/null +++ b/tests/test-ls.c @@ -0,0 +1,122 @@ +/* +| Copyright (C) 2002-2003 Jorg Schuler <jcsjcs at users.sourceforge.net> +| Copyright (C) 2006 Christophe Fergeau <teuf@gnome.org> +| +| This program is free software; you can redistribute it and/or modify +| it under the terms of the GNU General Public License as published by +| the Free Software Foundation; either version 2 of the License, or +| (at your option) any later version. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; if not, write to the Free Software +| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +| +| iTunes and iPod are trademarks of Apple +| +| This product is not supported/written/published by Apple! +| +*/ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <libintl.h> + +#include "itdb.h" + +static void +display_track (Itdb_Track *track, const char *prefix) +{ + g_print ("%s%s - %s - %s\n", prefix, + track->artist, track->album, track->title); + g_print ("%s\t%s\n", prefix, track->ipod_path); +} + +static void +display_playlist (Itdb_Playlist *playlist, const char *prefix) +{ + char *track_prefix; + GList *it; + + if (itdb_playlist_is_mpl (playlist)) { + g_print ("%s%s (Master Playlist)\n", prefix, playlist->name); + } else if (itdb_playlist_is_podcasts (playlist)) { + g_print ("%s%s (Podcasts Playlist)\n", prefix, playlist->name); + } else { + g_print ("%s%s\n", prefix, playlist->name); + } + + printf ("%stracks: %d\n", prefix, g_list_length (playlist->members)); + track_prefix = g_strdup_printf ("%s\t", prefix); + for (it = playlist->members; it != NULL; it = it->next) { + Itdb_Track *track; + + track = (Itdb_Track *)it->data; + display_track (track, "\t"); + } + g_print ("\n\n"); + g_free (track_prefix); +} + +int +main (int argc, char *argv[]) +{ + GError *error=NULL; + Itdb_iTunesDB *itdb; + gchar *mountpoint = NULL; + + if (argc >= 2) + mountpoint = argv[1]; + + if (mountpoint == NULL) + { + g_print ("Usage: %s <mountpoint>\n", g_basename(argv[0])); + exit (0); + } + + itdb = itdb_parse (mountpoint, &error); + + if (error) + { + if (error->message) { + g_print("%s\n", error->message); + } + g_error_free (error); + error = NULL; + } + + if (itdb) + { + GList *it; + + printf ("playlists: %d\n", g_list_length (itdb->playlists)); + for (it = itdb->playlists; it != NULL; it = it->next) { + Itdb_Playlist *playlist; + + playlist = (Itdb_Playlist *)it->data; + display_playlist (playlist, ""); + } + + if (error) + { + if (error->message) { + g_print ("%s\n", error->message); + } + g_error_free (error); + error = NULL; + } + } + + itdb_free (itdb); + + return 0; +} diff --git a/tests/test-rebuild-db.cc b/tests/test-rebuild-db.cc new file mode 100644 index 0000000..c5c232c --- /dev/null +++ b/tests/test-rebuild-db.cc @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2006 Christophe Fergeau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <typeinfo> +#include <unistd.h> + +#include <glib/gstdio.h> + +#include <id3v2tag.h> +#include <mpegfile.h> + +#include "itdb.h" + +static char * +itdb_resolve_path (Itdb_iTunesDB *db, const char *filename) +{ + const char *mountpoint; + char *ipod_path; + + mountpoint = itdb_get_mountpoint (db); + if (!g_str_has_prefix (filename, mountpoint)) { + return NULL; + } + if (mountpoint[strlen(mountpoint)-1] == G_DIR_SEPARATOR) { + ipod_path = g_strdup (filename + strlen (mountpoint)-1); + } else { + ipod_path = g_strdup (filename + strlen (mountpoint)); + } + itdb_filename_fs2ipod (ipod_path); +#ifdef VERBOSE + g_print ("Filename: %s\n", filename); + g_print ("Mount point: %s (%d)\n", mountpoint, strlen (mountpoint)); + g_print ("Path resolved to %s\n", ipod_path); +#endif + return ipod_path; +} + +static Itdb_Track * +track_from_file (const char *filename) +{ + TagLib::MPEG::File file(filename); + TagLib::Tag *tag; + Itdb_Track *track; + struct stat st; + + tag = file.tag(); + if (tag == NULL) { + g_print ("Couldn't read tag\n"); + return NULL; + } +/* if (typeid (*tag) != typeid (TagLib::ID3v2::Tag)) { + g_print ("Unknown tag type\n"); + return NULL; + }*/ + + /* FIXME: what happens if we try to open a non-MP3 file? */ +#ifdef VERBOSE + g_print ("%s:\n", filename); + g_print ("\t%s\n", tag->artist().toCString(true)); + g_print ("\t%s\n", tag->album().toCString(true)); + g_print ("\t%s\n", tag->title().toCString(true)); + g_print ("\t%s\n", tag->genre().toCString(true)); + g_print ("\t%d\n", tag->year()); + g_print ("\t%d\n", tag->track()); + g_print ("\n"); +#endif + track = itdb_track_new (); + track->title = g_strdup (tag->title().toCString(true)); + track->album = g_strdup (tag->album().toCString(true)); + track->artist = g_strdup (tag->artist().toCString(true)); + track->genre = g_strdup (tag->genre().toCString(true)); + track->comment = g_strdup (tag->comment().toCString(true)); + track->filetype = g_strdup ("MP3-file"); + if (g_stat (filename, &st) == 0) { + track->size = st.st_size; + } + track->tracklen = file.audioProperties()->length() * 1000; + track->track_nr = tag->track(); + track->bitrate = file.audioProperties()->bitrate(); + track->samplerate = file.audioProperties()->sampleRate(); + track->year = tag->year(); + return track; +} + + +static void +process_one_file (const char *filename, gpointer data) +{ + Itdb_iTunesDB *db; + Itdb_Track *track; + + db = (Itdb_iTunesDB *)data; + track = track_from_file (filename); + track->ipod_path = itdb_resolve_path (db, filename); + if (track->ipod_path == NULL) { + itdb_track_free (track); + return; + } + + itdb_track_add (db, track, -1); + itdb_playlist_add_track (itdb_playlist_mpl(db), track, -1); +} + +typedef void (*DirTraversalFunc)(const char *filename, gpointer data); + +static void +foreach_file (const char *basedir, + DirTraversalFunc func, gpointer data, + GError **error) +{ + GError *tmp_error; + const char *name; + GDir *dir; + + g_assert (func != NULL); + + tmp_error = NULL; + dir = g_dir_open (basedir, 0, &tmp_error); + if (tmp_error != NULL) { + g_propagate_error (error, tmp_error); + return; + } + + name = g_dir_read_name (dir); + while (name != NULL) { + char *absolute_path; + + absolute_path = g_build_filename (basedir, name, NULL); + + if (g_file_test (absolute_path, G_FILE_TEST_IS_DIR)) { + tmp_error = NULL; + foreach_file (absolute_path, func, data, &tmp_error); + if (tmp_error != NULL) { + g_propagate_error (error, tmp_error); + g_free (absolute_path); + g_dir_close (dir); + return; + } + } else if (g_file_test (absolute_path, G_FILE_TEST_IS_REGULAR)){ + func (absolute_path, data); + } + g_free (absolute_path); + name = g_dir_read_name (dir); + } + + g_dir_close (dir); + + +} + +static void +fill_db (Itdb_iTunesDB *db, GError **error) +{ + GError *err = NULL; + char *music_dir; + + music_dir = itdb_get_music_dir (itdb_get_mountpoint (db)); + foreach_file (music_dir, process_one_file, db, &err); + g_free (music_dir); + g_print ("Found %d files\n", + g_list_length (itdb_playlist_mpl(db)->members)); +} + +static Itdb_iTunesDB * +itdb_create (const char *mountpoint) +{ + Itdb_Playlist *mpl; + Itdb_iTunesDB *db; + + db = itdb_new (); + if (db == NULL) { + return NULL; + } + itdb_set_mountpoint (db, mountpoint); + mpl = itdb_playlist_new ("iPod", FALSE); + itdb_playlist_set_mpl (mpl); + itdb_playlist_add (db, mpl, -1); + + return db; +} + +int main (int argc, char **argv) +{ + Itdb_iTunesDB *db; + GError *error; + + if (argc != 2) { + g_print ("Usage:\n"); + g_print ("%s <mountpoint>\n", g_basename (argv[0])); + exit (1); + } + + db = itdb_create (argv[1]); + + if (db == NULL) { + g_print ("Error creating iPod database\n"); + exit (1); + } + + error = NULL; + fill_db (db, &error); + if (error) { + g_print ("Error reading music files\n"); + if (error->message) { + g_print("%s\n", error->message); + } + g_error_free (error); + exit (1); + } + + itdb_write (db, &error); + if (error) { + g_print ("Error writing iPod database\n"); + if (error->message) { + g_print("%s\n", error->message); + } + g_error_free (error); + exit (1); + } + + itdb_free (db); + + return 0; +} |