Implement check for invalid playlist entries.
authorAndre Noll <maan@systemlinux.org>
Sun, 23 Sep 2007 17:34:17 +0000 (19:34 +0200)
committerAndre Noll <maan@systemlinux.org>
Sun, 23 Sep 2007 17:34:17 +0000 (19:34 +0200)
Also some minor improvements for the audio file table checks.

afs.c
afs.h
aft.c
blob.c
playlist.c

diff --git a/afs.c b/afs.c
index 44eeacc..a95ca41 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -860,8 +860,8 @@ int com_init(int fd, int argc, char * const * const argv)
 
 enum com_check_flags {
        CHECK_AFT = 1,
-       CHECK_MOODS_TABLE = 8,
-       CHECK_PLAYLISTS = 16
+       CHECK_MOODS = 2,
+       CHECK_PLAYLISTS = 4
 };
 
 int com_check(int fd, int argc, char * const * const argv)
@@ -886,6 +886,10 @@ int com_check(int fd, int argc, char * const * const argv)
                        flags |= CHECK_PLAYLISTS;
                        continue;
                }
+               if (!strcmp(arg, "-m")) {
+                       flags |= CHECK_MOODS;
+                       continue;
+               }
                return -E_AFS_SYNTAX;
        }
        if (i < argc)
@@ -903,5 +907,16 @@ int com_check(int fd, int argc, char * const * const argv)
                                return ret;
                }
        }
+       if (flags & CHECK_PLAYLISTS) {
+               ret = send_callback_request(playlist_check_callback, NULL, &result);
+               if (ret < 0)
+                       return ret;
+               if (ret > 0) {
+                       ret = send_buffer(fd, (char *) result.data);
+                       free(result.data);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
        return 1;
 }
diff --git a/afs.h b/afs.h
index 7adb54b..d6d0a86 100644 (file)
--- a/afs.h
+++ b/afs.h
@@ -151,6 +151,8 @@ int mood_delete_audio_file(const struct osl_row *aft_row);
 int playlist_open(char *name);
 void playlist_close(void);
 int playlist_update_audio_file(struct osl_row *aft_row);
+int playlist_check_callback(__a_unused const struct osl_object *query,
+       struct osl_object *result);
 
 /** evaluates to 1 if x < y, to -1 if x > y and to 0 if x == y */
 #define NUM_COMPARE(x, y) ((int)((x) < (y)) - (int)((x) > (y)))
diff --git a/aft.c b/aft.c
index 1a0fdc7..0f15cd2 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -1722,10 +1722,12 @@ static int check_audio_file(struct osl_row *row, void *data)
        }
        ret = lyr_get_name_by_id(afsi.lyrics_id, &blob_name);
        if (ret < 0)
-               para_printf(pb, "%s lyrics id: %s\n", path, PARA_STRERROR(-ret));
+               para_printf(pb, "%s lyrics id %u: %s\n", path, afsi.lyrics_id,
+                       PARA_STRERROR(-ret));
        ret = img_get_name_by_id(afsi.image_id, &blob_name);
        if (ret < 0)
-               para_printf(pb, "%s image id: %s\n", path, PARA_STRERROR(-ret));
+               para_printf(pb, "%s image id %u: %s\n", path, afsi.image_id,
+                       PARA_STRERROR(-ret));
        return 1;
 }
 
@@ -1733,9 +1735,8 @@ int aft_check_callback(__a_unused const struct osl_object *query, struct osl_obj
 {
        struct para_buffer pb = {.buf = NULL};
 
+       para_printf(&pb, "checking audio file table...\n");
        audio_file_loop(&pb, check_audio_file);
-       if (!pb.size)
-               return 0;
        result->data = pb.buf;
        result->size = pb.size;
        return 1;
diff --git a/blob.c b/blob.c
index b396ef7..2015124 100644 (file)
--- a/blob.c
+++ b/blob.c
@@ -338,6 +338,7 @@ static int blob_get_name_by_id(struct osl_table *table, uint32_t id,
        *name = (char *)obj.data;
        return 1;
 }
+
 /** Define the \p get_name_by_id function for this blob type. */
 #define DEFINE_GET_NAME_BY_ID(table_name, cmd_prefix) \
        int cmd_prefix ## _get_name_by_id(uint32_t id, char **name) \
index 272f25a..429ad2b 100644 (file)
@@ -28,72 +28,72 @@ int playlist_update_audio_file(struct osl_row *aft_row)
        return score_update(aft_row, 0);
 }
 
-static int add_playlist_entry(char *line, void *data)
+static int add_playlist_entry(char *path, void *data)
 {
        struct playlist_info *playlist = data;
        struct osl_row *aft_row;
-       int ret = aft_get_row_of_path(line, &aft_row);
+       int ret = aft_get_row_of_path(path, &aft_row);
 
        if (ret < 0) {
-               PARA_NOTICE_LOG("path not found in audio file table: %s\n",
-                       line);
+               PARA_NOTICE_LOG("%s: %s\n", path, PARA_STRERROR(-ret));
                return 1;
        }
        ret = score_add(aft_row, -playlist->length);
        if (ret < 0) {
-               PARA_ERROR_LOG("failed to add %s: %d\n", line, ret);
+               PARA_ERROR_LOG("failed to add %s: %d\n", path, ret);
                return ret;
        }
        playlist->length++;
        return 1;
 }
 
-static int load_playlist(struct osl_row *row, struct playlist_info *playlist)
+static int get_playlist_data(struct osl_row *row, char **playlist_name,
+               struct osl_object *playlist_def)
 {
        struct osl_object obj;
-       int ret;
-
-       ret = osl_get_object(playlists_table, row, BLOBCOL_NAME, &obj);
+       int ret = osl_get_object(playlists_table, row, BLOBCOL_NAME, &obj);
        if (ret < 0)
                return ret;
-       playlist->name = para_strdup(obj.data);
-       playlist->length = 0;
-       ret = osl_open_disk_object(playlists_table, row, BLOBCOL_DEF, &obj);
+       *playlist_name = obj.data;
+       return osl_open_disk_object(playlists_table, row, BLOBCOL_DEF,
+               playlist_def);
+}
+
+/* returns -E_PLAYLIST_LOADED on _success_ to terminate the loop */
+static int load_playlist(struct osl_row *row, void *data)
+{
+       struct playlist_info *playlist = data;
+       struct osl_object playlist_def;
+       char *playlist_name;
+       int ret;
+
+       ret = get_playlist_data(row, &playlist_name, &playlist_def);
        if (ret < 0)
                goto err;
-       ret = for_each_line_ro(obj.data, obj.size, add_playlist_entry,
-               playlist);
-       osl_close_disk_object(&obj);
+       playlist->length = 0;
+       ret = for_each_line_ro(playlist_def.data, playlist_def.size,
+               add_playlist_entry, playlist);
+       osl_close_disk_object(&playlist_def);
        if (ret < 0)
                goto err;
        ret = -E_PLAYLIST_EMPTY;
        if (!playlist->length)
                goto err;
+       playlist->name = para_strdup(playlist_name);
        PARA_NOTICE_LOG("loaded playlist %s (%u files)\n", playlist->name,
                playlist->length);
-       return 1;
-err:
-       free(playlist->name);
-       return ret;
-}
-
-/* returns -E_PLAYLIST_LOADED on _success_ to terminate the loop */
-static int playlist_loop(struct osl_row *row, void *data)
-{
-       struct playlist_info *playlist = data;
-       int ret = load_playlist(row, playlist);
-       if (ret < 0) {
-               if (ret != -E_DUMMY_ROW)
-                       PARA_NOTICE_LOG("unable to load playlist, trying next\n");
-               return 1;
-       }
        return -E_PLAYLIST_LOADED;
+err:
+       if (ret != -E_DUMMY_ROW)
+               PARA_NOTICE_LOG("unable to load playlist (%s)\n",
+                       PARA_STRERROR(-ret));
+       return 1;
 }
 
 static int load_first_available_playlist(struct playlist_info *playlist)
 {
        int ret = osl_rbtree_loop(playlists_table, BLOBCOL_NAME, playlist,
-               playlist_loop);
+               load_playlist);
        if (ret == -E_PLAYLIST_LOADED) /* success */
                return 1;
        if (ret < 0)
@@ -102,6 +102,51 @@ static int load_first_available_playlist(struct playlist_info *playlist)
        return -E_NO_PLAYLIST;
 }
 
+static int check_playlist_path(char *path, void *data)
+{
+       struct para_buffer *pb = data;
+       struct osl_row *aft_row;
+       int ret = aft_get_row_of_path(path, &aft_row);
+
+       if (ret < 0)
+               para_printf(pb, "%s: %s\n", path, PARA_STRERROR(-ret));
+       return 1;
+}
+
+static int check_playlist(struct osl_row *row, void *data)
+{
+       struct para_buffer *pb = data;
+       struct osl_object playlist_def;
+       char *playlist_name;
+       int ret = get_playlist_data(row, &playlist_name, &playlist_def);
+
+       if (ret < 0) {
+               para_printf(pb, "failed to get playlist data: %s\n",
+                       PARA_STRERROR(-ret));
+               return 1;
+       }
+       if (*playlist_name) { /* skip dummy row */
+               para_printf(pb, "checking playlist %s...\n", playlist_name);
+               for_each_line_ro(playlist_def.data, playlist_def.size,
+                       check_playlist_path, pb);
+       }
+       osl_close_disk_object(&playlist_def);
+       return 1;
+}
+
+int playlist_check_callback(__a_unused const struct osl_object *query,
+               struct osl_object *result)
+{
+       struct para_buffer pb = {.buf = NULL};
+
+       para_printf(&pb, "checking playlists...\n");
+       osl_rbtree_loop(playlists_table, BLOBCOL_ID, &pb,
+               check_playlist);
+       result->data = pb.buf;
+       result->size = pb.size;
+       return 1;
+}
+
 /**
  * Close the current playlist.
  *