diff --git a/config b/config index 1670ac37..273b3934 100644 --- a/config +++ b/config @@ -37,6 +37,7 @@ class Config: def reset(self, TEST = False, ALL = False): self.AUDIO = ALL + self.CALLBACK = ALL self.DATABASE = ALL self.DECK = ALL self.FILE = ALL diff --git a/design.txt b/design.txt index 9c4adecf..69733ed6 100644 --- a/design.txt +++ b/design.txt @@ -33,6 +33,7 @@ Files: ocarina6.glade ocarina/include/ audio.h + callback.h database.h database.hpp deck.h @@ -48,6 +49,7 @@ Files: version.h ocarina/lib/ audio.cpp + callback.cpp database.cpp deck.cpp file.cpp @@ -104,6 +106,26 @@ API: +Callbacks: (lib/callback.cpp) + Callbacks are used to notify a unit test or the gui that something in + the backend has changed. The callbacks structure should be initialized + with no-op default values and filled in by the user through the + get_callbacks() function. + +- Callback functions: + struct Callbacks { + void (*on_library_add)(unsigned int, library :: Library *); + void (*on_library_update)(unsigned int, library :: Library *); + }; + + static struct Callbacks callbacks; + +- API: + struct Callbacks *get_callbacks(); + Return the Callbacks structure; + + + On-disk files: (lib/file.cpp) Data will be stored in the user's home directory according to the XDG / freedesktop.org specification. This means storing data in @@ -690,6 +712,8 @@ Library: (lib/library.cpp) If dir is not a directory: throw -EINVAL + Trigger the on_library_add() callback on success. + void library :: del_path(unsigned int lib_id); Invalidate a library_db row and all tracks owned by that path if lib_id is not valid, throw -EEXIST. @@ -698,8 +722,11 @@ Library: (lib/library.cpp) Update the given library_db row. If lib_id is not valid, throw -EEXIST. + Trigger the on_library_update() callback. + void library :: update_all(); Update all library paths. + Trigger the on_library_update() callback for each path. struct Song library :: lookup(track_id); Fill out a Song structure for the provided track_id. @@ -1085,6 +1112,8 @@ Future work: to update the library information and the on-disk file. - Album art: (6.1) + (easy) Start with album art fetching script + (hard) Build in to Ocarina - Playlist custom sorting: (6.1) Click column headers to choos sort order @@ -1098,6 +1127,7 @@ Future work: keep it in each individual section instead. XML? Code formatting? + Checkbox for when features are done? (reference commit) - Copy a song group to a different directory: (6.x) This can be useful for keeping an external device (like an @@ -1118,3 +1148,21 @@ Future work: - Some way to enable / disable tests during development - Run tests based on dependencies - Fix tests that will only work on my computer + - Double check that all inputs and outputs are tested + - Simple testing library? + + - Preferences: + - Set default sort + - Save window size + - Set album art size + + - Rip out Ocarina 5.x importing and legacy file support + + - AirPlay / remote audio support + + - Media keys + + - Replaygain support + External script to calculate values? + Calculate value after first playback? + Store in library :: Track structure diff --git a/design/callback.txt b/design/callback.txt new file mode 100644 index 00000000..321b6ae5 --- /dev/null +++ b/design/callback.txt @@ -0,0 +1,26 @@ +== Files == + ocarina/include/ + callback.h + ocarina/lib/ + callback.cpp + +== Depends == +version print + +Callbacks: (lib/callback.cpp) + Callbacks are used to notify a unit test or the gui that something in + the backend has changed. The callbacks structure should be initialized + with no-op default values and filled in by the user through the + get_callbacks() function. + +- Callback functions: + struct Callbacks { + void (*on_library_add)(unsigned int, library :: Library *); + void (*on_library_update)(unsigned int, library :: Library *); + }; + + static struct Callbacks callbacks; + +- API: + struct Callbacks *get_callbacks(); + Return the Callbacks structure; diff --git a/design/footer.txt b/design/footer.txt index 23df2313..6c0e1b51 100644 --- a/design/footer.txt +++ b/design/footer.txt @@ -46,6 +46,8 @@ Future work: to update the library information and the on-disk file. - Album art: (6.1) + (easy) Start with album art fetching script + (hard) Build in to Ocarina - Playlist custom sorting: (6.1) Click column headers to choos sort order @@ -59,6 +61,7 @@ Future work: keep it in each individual section instead. XML? Code formatting? + Checkbox for when features are done? (reference commit) - Copy a song group to a different directory: (6.x) This can be useful for keeping an external device (like an @@ -79,3 +82,21 @@ Future work: - Some way to enable / disable tests during development - Run tests based on dependencies - Fix tests that will only work on my computer + - Double check that all inputs and outputs are tested + - Simple testing library? + + - Preferences: + - Set default sort + - Save window size + - Set album art size + + - Rip out Ocarina 5.x importing and legacy file support + + - AirPlay / remote audio support + + - Media keys + + - Replaygain support + External script to calculate values? + Calculate value after first playback? + Store in library :: Track structure diff --git a/design/library.txt b/design/library.txt index 52207e74..529de853 100644 --- a/design/library.txt +++ b/design/library.txt @@ -163,6 +163,8 @@ Library: (lib/library.cpp) If dir is not a directory: throw -EINVAL + Trigger the on_library_add() callback on success. + void library :: del_path(unsigned int lib_id); Invalidate a library_db row and all tracks owned by that path if lib_id is not valid, throw -EEXIST. @@ -171,8 +173,11 @@ Library: (lib/library.cpp) Update the given library_db row. If lib_id is not valid, throw -EEXIST. + Trigger the on_library_update() callback. + void library :: update_all(); Update all library paths. + Trigger the on_library_update() callback for each path. struct Song library :: lookup(track_id); Fill out a Song structure for the provided track_id. diff --git a/include/callback.h b/include/callback.h new file mode 100644 index 00000000..e9edc864 --- /dev/null +++ b/include/callback.h @@ -0,0 +1,19 @@ +/* + * Copyright 2014 (c) Anna Schumaker. + */ +#ifndef OCARINA_CALLBACK_H +#define OCARINA_CALLBACK_H + +#include + + +struct Callbacks { + void (*on_library_add)(unsigned int, library :: Library *); + void (*on_library_update)(unsigned int, library :: Library *); +}; + + +struct Callbacks *get_callbacks(); + + +#endif /* OCARINA_CALLBACK_H */ diff --git a/lib/Sconscript b/lib/Sconscript index f253e9c3..28b4f2d5 100644 --- a/lib/Sconscript +++ b/lib/Sconscript @@ -16,12 +16,13 @@ modules = { ########################### "AUDIO" : Module("audio.cpp", package = "gstreamer-1.0", depends = [ "DECK" ]), + "CALLBACK" : Module("callback.cpp"), "DATABASE" : Module("database.cpp", depends = [ "FILE" ]), "DECK" : Module("deck.cpp", depends = [ "PLAYQUEUE" ]), "FILE" : Module("file.cpp", package = "glib-2.0"), "FILTER" : Module("filter.cpp", depends = [ "DATABASE" ]), "IDLE" : Module("idle.cpp"), - "LIBRARY" : Module("library.cpp", package = "taglib", depends = [ "DATABASE", "FILTER", "IDLE" ]), + "LIBRARY" : Module("library.cpp", package = "taglib", depends = [ "CALLBACK", "DATABASE", "FILTER", "IDLE" ]), "PLAYLIST" : Module("playlist.cpp", depends = [ "DATABASE" ]), "PLAYQUEUE" : Module("playqueue.cpp", depends = [ "LIBRARY" ]), diff --git a/lib/callback.cpp b/lib/callback.cpp new file mode 100644 index 00000000..4e0f7047 --- /dev/null +++ b/lib/callback.cpp @@ -0,0 +1,19 @@ +/* + * Copyright 2014 (c) Anna Schumaker. + */ +#include + + +static void no_op(unsigned int id, library :: Library *path) {} + + +static struct Callbacks callbacks = { + .on_library_add = no_op, + .on_library_update = no_op, +}; + + +struct Callbacks *get_callbacks() +{ + return &callbacks; +} diff --git a/lib/library.cpp b/lib/library.cpp index 4420abeb..36c8e8e4 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -1,6 +1,7 @@ /* * Copyright 2013 (c) Anna Schumaker. */ +#include #include #include #include @@ -28,7 +29,6 @@ struct ImportData { }; - /* * library :: Artist: Artist tag information */ @@ -298,10 +298,11 @@ static void read_tags(unsigned int lib_id, const std :: string &path) library_db[lib_id].size++; } -static void process_path(unsigned int lib_id, const std :: string &dir, +static bool process_path(unsigned int lib_id, const std :: string &dir, const std :: string &name) { struct scan_info scan; + bool changed = false; std :: string path = dir + "/" + name; if (g_file_test(path.c_str(), G_FILE_TEST_IS_DIR) == true) { @@ -309,9 +310,13 @@ static void process_path(unsigned int lib_id, const std :: string &dir, scan.path = path; idle :: schedule (do_scan_path, scan); } else { - if (track_db.has_key(path) == false) + if (track_db.has_key(path) == false) { read_tags(lib_id, path); + changed = true; + } } + + return changed; } static void save_all_dbs() @@ -326,6 +331,7 @@ static void do_scan_path(struct scan_info &scan) { GDir *dir; const char *name; + bool changed = false; dir = g_dir_open(scan.path.c_str(), 0, NULL); if (dir == NULL) @@ -333,15 +339,22 @@ static void do_scan_path(struct scan_info &scan) name = g_dir_read_name(dir); while (name != NULL) { - process_path(scan.lib_id, scan.path, name); - save_all_dbs(); + if (process_path(scan.lib_id, scan.path, name)) + changed = true; name = g_dir_read_name(dir); } + + if (changed == true) { + save_all_dbs(); + get_callbacks()->on_library_update(scan.lib_id, + &library_db[scan.lib_id]); + } } static void do_validate_library(unsigned int &lib_id) { std :: string path; + bool changed = false; if (track_db.size() == 0) return; @@ -355,8 +368,12 @@ static void do_validate_library(unsigned int &lib_id) dprint("Removing file: %s\n", path.c_str()); track_db.remove(i); library_db[lib_id].size--; + changed = true; } } + + if (changed == true) + get_callbacks()->on_library_update(lib_id, &library_db[lib_id]); } static void do_update_library(unsigned int lib_id) @@ -417,12 +434,14 @@ static void do_import_library(std::string &s) } print("Adding path: %s\n", path.c_str()); id = library_db.insert(library :: Library(path, enabled)); + get_callbacks()->on_library_add(id, &library_db[id]); library_db.save(); f.getline(); /* Get rest of line */ for (unsigned int i = 0; i < size; i++) do_import_track(f, id); save_all_dbs(); + get_callbacks()->on_library_update(id, &library_db[id]); library :: update_path(id); } @@ -435,7 +454,10 @@ static void do_import_library(std::string &s) void library :: init() { + unsigned int i; library_db.load(); + for (i = library_db.first(); i < library_db.num_rows(); i = library_db.next(i)) + get_callbacks()->on_library_add(i, &library_db[i]); } void library :: add_path(const std::string &dir) @@ -446,6 +468,8 @@ void library :: add_path(const std::string &dir) id = library_db.insert(library :: Library(dir, true)); library_db.save(); + + get_callbacks()->on_library_add(id, &library_db[id]); update_path(id); } diff --git a/tests/library/library.cpp b/tests/library/library.cpp index 7af1216b..f41f015a 100644 --- a/tests/library/library.cpp +++ b/tests/library/library.cpp @@ -1,6 +1,7 @@ /* * Copyright 2013 (c) Anna Schumaker. */ +#include #include #include #include @@ -28,6 +29,17 @@ bool check_add_dir(const std::string &dir) } } +void library_added(unsigned int id, library :: Library *path) +{ + print("Added library %u: %s\n", id, path->root_path.c_str()); +} + +void library_updated(unsigned int id, library :: Library *path) +{ + print("Updated library %u: %s (size: %u)\n", + id, path->root_path.c_str(), path->size); +} + void test_add_dir(const std::string &test, const std::string &dir, bool expected) { print("Test %s: ", test.c_str()); @@ -252,10 +264,16 @@ void test_7() library :: print_db(library :: DB_LIBRARY); } + int main(int argc, char **argv) { + struct Callbacks *cb; gen_library(); + cb = get_callbacks(); + cb->on_library_add = library_added; + cb->on_library_update = library_updated; + test_0(); test_1(); test_2(); diff --git a/tests/library/library.good b/tests/library/library.good index 33700ec3..e2a8952d 100644 --- a/tests/library/library.good +++ b/tests/library/library.good @@ -11,7 +11,23 @@ Test 0b: PASSED Allocated rows: 0 Valid rows: 0 -Test 1a: PASSED +Test 1a: Added library 0: /tmp/library/0 +PASSED +Updated library 0: /tmp/library/0 (size: 10) +Updated library 0: /tmp/library/0 (size: 20) +Updated library 0: /tmp/library/0 (size: 30) +Updated library 0: /tmp/library/0 (size: 40) +Updated library 0: /tmp/library/0 (size: 50) +Updated library 0: /tmp/library/0 (size: 60) +Updated library 0: /tmp/library/0 (size: 70) +Updated library 0: /tmp/library/0 (size: 80) +Updated library 0: /tmp/library/0 (size: 90) +Updated library 0: /tmp/library/0 (size: 100) +Updated library 0: /tmp/library/0 (size: 110) +Updated library 0: /tmp/library/0 (size: 120) +Updated library 0: /tmp/library/0 (size: 130) +Updated library 0: /tmp/library/0 (size: 140) +Updated library 0: /tmp/library/0 (size: 150) Allocated rows: 1 Valid rows: 1 db[0] = /tmp/library/0 (enabled), size = 150 @@ -19,16 +35,64 @@ Test 1b Allocated rows: 1 Valid rows: 0 -Test 2a: PASSED +Test 2a: Added library 0: /tmp/library/0 +PASSED +Updated library 0: /tmp/library/0 (size: 10) +Updated library 0: /tmp/library/0 (size: 20) +Updated library 0: /tmp/library/0 (size: 30) +Updated library 0: /tmp/library/0 (size: 40) +Updated library 0: /tmp/library/0 (size: 50) +Updated library 0: /tmp/library/0 (size: 60) +Updated library 0: /tmp/library/0 (size: 70) +Updated library 0: /tmp/library/0 (size: 80) +Updated library 0: /tmp/library/0 (size: 90) +Updated library 0: /tmp/library/0 (size: 100) +Updated library 0: /tmp/library/0 (size: 110) +Updated library 0: /tmp/library/0 (size: 120) +Updated library 0: /tmp/library/0 (size: 130) +Updated library 0: /tmp/library/0 (size: 140) +Updated library 0: /tmp/library/0 (size: 150) Allocated rows: 1 Valid rows: 1 db[0] = /tmp/library/0 (enabled), size = 150 -Test 2b: PASSED +Test 2b: Added library 1: /tmp/library/1 +PASSED +Updated library 1: /tmp/library/1 (size: 10) +Updated library 1: /tmp/library/1 (size: 20) +Updated library 1: /tmp/library/1 (size: 30) +Updated library 1: /tmp/library/1 (size: 40) +Updated library 1: /tmp/library/1 (size: 50) +Updated library 1: /tmp/library/1 (size: 60) +Updated library 1: /tmp/library/1 (size: 70) +Updated library 1: /tmp/library/1 (size: 80) +Updated library 1: /tmp/library/1 (size: 90) +Updated library 1: /tmp/library/1 (size: 100) +Updated library 1: /tmp/library/1 (size: 110) +Updated library 1: /tmp/library/1 (size: 120) +Updated library 1: /tmp/library/1 (size: 130) +Updated library 1: /tmp/library/1 (size: 140) +Updated library 1: /tmp/library/1 (size: 150) Allocated rows: 2 Valid rows: 2 db[0] = /tmp/library/0 (enabled), size = 150 db[1] = /tmp/library/1 (enabled), size = 150 -Test 2c: PASSED +Test 2c: Added library 2: /tmp/library/2 +PASSED +Updated library 2: /tmp/library/2 (size: 10) +Updated library 2: /tmp/library/2 (size: 20) +Updated library 2: /tmp/library/2 (size: 30) +Updated library 2: /tmp/library/2 (size: 40) +Updated library 2: /tmp/library/2 (size: 50) +Updated library 2: /tmp/library/2 (size: 60) +Updated library 2: /tmp/library/2 (size: 70) +Updated library 2: /tmp/library/2 (size: 80) +Updated library 2: /tmp/library/2 (size: 90) +Updated library 2: /tmp/library/2 (size: 100) +Updated library 2: /tmp/library/2 (size: 110) +Updated library 2: /tmp/library/2 (size: 120) +Updated library 2: /tmp/library/2 (size: 130) +Updated library 2: /tmp/library/2 (size: 140) +Updated library 2: /tmp/library/2 (size: 150) Allocated rows: 3 Valid rows: 3 db[0] = /tmp/library/0 (enabled), size = 150 @@ -47,16 +111,64 @@ Test 2f Allocated rows: 3 Valid rows: 0 -Test 3a: PASSED +Test 3a: Added library 0: /tmp/library/0 +PASSED +Updated library 0: /tmp/library/0 (size: 10) +Updated library 0: /tmp/library/0 (size: 20) +Updated library 0: /tmp/library/0 (size: 30) +Updated library 0: /tmp/library/0 (size: 40) +Updated library 0: /tmp/library/0 (size: 50) +Updated library 0: /tmp/library/0 (size: 60) +Updated library 0: /tmp/library/0 (size: 70) +Updated library 0: /tmp/library/0 (size: 80) +Updated library 0: /tmp/library/0 (size: 90) +Updated library 0: /tmp/library/0 (size: 100) +Updated library 0: /tmp/library/0 (size: 110) +Updated library 0: /tmp/library/0 (size: 120) +Updated library 0: /tmp/library/0 (size: 130) +Updated library 0: /tmp/library/0 (size: 140) +Updated library 0: /tmp/library/0 (size: 150) Allocated rows: 1 Valid rows: 1 db[0] = /tmp/library/0 (enabled), size = 150 -Test 3b: PASSED +Test 3b: Added library 1: /tmp/library/1 +PASSED +Updated library 1: /tmp/library/1 (size: 10) +Updated library 1: /tmp/library/1 (size: 20) +Updated library 1: /tmp/library/1 (size: 30) +Updated library 1: /tmp/library/1 (size: 40) +Updated library 1: /tmp/library/1 (size: 50) +Updated library 1: /tmp/library/1 (size: 60) +Updated library 1: /tmp/library/1 (size: 70) +Updated library 1: /tmp/library/1 (size: 80) +Updated library 1: /tmp/library/1 (size: 90) +Updated library 1: /tmp/library/1 (size: 100) +Updated library 1: /tmp/library/1 (size: 110) +Updated library 1: /tmp/library/1 (size: 120) +Updated library 1: /tmp/library/1 (size: 130) +Updated library 1: /tmp/library/1 (size: 140) +Updated library 1: /tmp/library/1 (size: 150) Allocated rows: 2 Valid rows: 2 db[0] = /tmp/library/0 (enabled), size = 150 db[1] = /tmp/library/1 (enabled), size = 150 -Test 3c: PASSED +Test 3c: Added library 2: /tmp/library/2 +PASSED +Updated library 2: /tmp/library/2 (size: 10) +Updated library 2: /tmp/library/2 (size: 20) +Updated library 2: /tmp/library/2 (size: 30) +Updated library 2: /tmp/library/2 (size: 40) +Updated library 2: /tmp/library/2 (size: 50) +Updated library 2: /tmp/library/2 (size: 60) +Updated library 2: /tmp/library/2 (size: 70) +Updated library 2: /tmp/library/2 (size: 80) +Updated library 2: /tmp/library/2 (size: 90) +Updated library 2: /tmp/library/2 (size: 100) +Updated library 2: /tmp/library/2 (size: 110) +Updated library 2: /tmp/library/2 (size: 120) +Updated library 2: /tmp/library/2 (size: 130) +Updated library 2: /tmp/library/2 (size: 140) +Updated library 2: /tmp/library/2 (size: 150) Allocated rows: 3 Valid rows: 3 db[0] = /tmp/library/0 (enabled), size = 150 @@ -66,13 +178,32 @@ Test 3d Allocated rows: 0 Valid rows: 0 Test 3e +Added library 0: /tmp/library/0 +Added library 1: /tmp/library/1 +Added library 2: /tmp/library/2 Allocated rows: 3 Valid rows: 3 db[0] = /tmp/library/0 (enabled), size = 0 db[1] = /tmp/library/1 (enabled), size = 0 db[2] = /tmp/library/2 (enabled), size = 0 -Test 4a: PASSED +Test 4a: Added library 0: /tmp/library/0 +PASSED +Updated library 0: /tmp/library/0 (size: 10) +Updated library 0: /tmp/library/0 (size: 20) +Updated library 0: /tmp/library/0 (size: 30) +Updated library 0: /tmp/library/0 (size: 40) +Updated library 0: /tmp/library/0 (size: 50) +Updated library 0: /tmp/library/0 (size: 60) +Updated library 0: /tmp/library/0 (size: 70) +Updated library 0: /tmp/library/0 (size: 80) +Updated library 0: /tmp/library/0 (size: 90) +Updated library 0: /tmp/library/0 (size: 100) +Updated library 0: /tmp/library/0 (size: 110) +Updated library 0: /tmp/library/0 (size: 120) +Updated library 0: /tmp/library/0 (size: 130) +Updated library 0: /tmp/library/0 (size: 140) +Updated library 0: /tmp/library/0 (size: 150) Allocated rows: 1 Valid rows: 1 db[0] = /tmp/library/0 (enabled), size = 150 @@ -712,7 +843,23 @@ db[149] = 1. Track 1 by Artist 0 from Album 0 (2011) Artist 0/Album 0/1 - Track 1.ogg Test 5a (track_id == 0): PASSED -Test 5b: PASSED +Test 5b: Added library 0: /tmp/library/0 +PASSED +Updated library 0: /tmp/library/0 (size: 10) +Updated library 0: /tmp/library/0 (size: 20) +Updated library 0: /tmp/library/0 (size: 30) +Updated library 0: /tmp/library/0 (size: 40) +Updated library 0: /tmp/library/0 (size: 50) +Updated library 0: /tmp/library/0 (size: 60) +Updated library 0: /tmp/library/0 (size: 70) +Updated library 0: /tmp/library/0 (size: 80) +Updated library 0: /tmp/library/0 (size: 90) +Updated library 0: /tmp/library/0 (size: 100) +Updated library 0: /tmp/library/0 (size: 110) +Updated library 0: /tmp/library/0 (size: 120) +Updated library 0: /tmp/library/0 (size: 130) +Updated library 0: /tmp/library/0 (size: 140) +Updated library 0: /tmp/library/0 (size: 150) Allocated rows: 1 Valid rows: 1 db[0] = /tmp/library/0 (enabled), size = 150 @@ -727,7 +874,23 @@ Test 5f (lib_id == 0): PASSED /tmp/library/0 (enabled) size = 150 Test 5g (lib_id == 1): PASSED -Test 6a: PASSED +Test 6a: Added library 0: /tmp/library/0 +PASSED +Updated library 0: /tmp/library/0 (size: 10) +Updated library 0: /tmp/library/0 (size: 20) +Updated library 0: /tmp/library/0 (size: 30) +Updated library 0: /tmp/library/0 (size: 40) +Updated library 0: /tmp/library/0 (size: 50) +Updated library 0: /tmp/library/0 (size: 60) +Updated library 0: /tmp/library/0 (size: 70) +Updated library 0: /tmp/library/0 (size: 80) +Updated library 0: /tmp/library/0 (size: 90) +Updated library 0: /tmp/library/0 (size: 100) +Updated library 0: /tmp/library/0 (size: 110) +Updated library 0: /tmp/library/0 (size: 120) +Updated library 0: /tmp/library/0 (size: 130) +Updated library 0: /tmp/library/0 (size: 140) +Updated library 0: /tmp/library/0 (size: 150) Allocated rows: 1 Valid rows: 1 db[0] = /tmp/library/0 (enabled), size = 150 @@ -1367,6 +1530,7 @@ Removing file: /tmp/library/0/Artist 2/Album 0/4 - Track 4.ogg Removing file: /tmp/library/0/Artist 2/Album 0/3 - Track 3.ogg Removing file: /tmp/library/0/Artist 2/Album 0/2 - Track 2.ogg Removing file: /tmp/library/0/Artist 2/Album 0/1 - Track 1.ogg +Updated library 0: /tmp/library/0 (size: 120) Allocated rows: 1 Valid rows: 1 db[0] = /tmp/library/0 (enabled), size = 120 @@ -1860,6 +2024,9 @@ Generating library: 2 Generating library: 3 Generating library: 4 +Updated library 0: /tmp/library/0 (size: 130) +Updated library 0: /tmp/library/0 (size: 140) +Updated library 0: /tmp/library/0 (size: 150) Allocated rows: 180 Valid rows: 150 db[30] = 10. Track 10 by Artist 4 from Album 2 (2013) @@ -2463,7 +2630,23 @@ db[179] = 1. Track 1 by Artist 2 from Album 0 (2011) Play count: 0, last played 0/0/0 Artist 2/Album 0/1 - Track 1.ogg -Test 7a: PASSED +Test 7a: Added library 0: /tmp/library/2 +PASSED +Updated library 0: /tmp/library/2 (size: 10) +Updated library 0: /tmp/library/2 (size: 20) +Updated library 0: /tmp/library/2 (size: 30) +Updated library 0: /tmp/library/2 (size: 40) +Updated library 0: /tmp/library/2 (size: 50) +Updated library 0: /tmp/library/2 (size: 60) +Updated library 0: /tmp/library/2 (size: 70) +Updated library 0: /tmp/library/2 (size: 80) +Updated library 0: /tmp/library/2 (size: 90) +Updated library 0: /tmp/library/2 (size: 100) +Updated library 0: /tmp/library/2 (size: 110) +Updated library 0: /tmp/library/2 (size: 120) +Updated library 0: /tmp/library/2 (size: 130) +Updated library 0: /tmp/library/2 (size: 140) +Updated library 0: /tmp/library/2 (size: 150) Allocated rows: 1 Valid rows: 1 db[0] = /tmp/library/2 (enabled), size = 150 @@ -2474,8 +2657,12 @@ Importing: /home/anna/.ocarina-test/library/1 Library already contains path: /tmp/library/2, skipping Importing: /home/anna/.ocarina-test/library/2 Adding path: /tmp/library/3 +Added library 1: /tmp/library/3 +Updated library 1: /tmp/library/3 (size: 150) Importing: /home/anna/.ocarina-test/library/3 Adding path: /tmp/library/4 +Added library 2: /tmp/library/4 +Updated library 2: /tmp/library/4 (size: 150) Allocated rows: 3 Valid rows: 3 db[0] = /tmp/library/2 (enabled), size = 150