summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--configure.ac13
-rw-r--r--tests/Makefile.am17
-rw-r--r--tests/test-ls.c122
-rw-r--r--tests/test-rebuild-db.cc250
5 files changed, 413 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index e4f58f8..1f5afbf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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;
+}