library: Initial design edits

More to come as I work on this bit of code!

Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2014-05-23 21:56:33 -04:00
parent 59220cc2ce
commit f995538a8c
1 changed files with 93 additions and 104 deletions

197
DESIGN
View File

@ -998,6 +998,99 @@ File Format:
Library:
The library is in charge of scanning and updating library paths added
to the tag database. In addition, the library layer is also in charge
of managing a library queue used by the UI. This queue has a special
file format, and will be saved to the file "library.q".
- Queue:
class LibraryQueue : public Queue {
public:
LibraryQueue();
save();
load();
set_flag(queue_flag);
unset_flag(queue_flag);
sort(sort_t, bool);
};
File << flags << _sort_order.size()
File << _sort_order[N].field << _sort_order[N].ascending << ...
- Validation:
Use a single idle function to loop over each track in the track
database. Check if the track still exists in the filesystem and remove
it from the tagdb if not.
- Updating:
Scan over all files in the current directory directory.
For each encountered directory:
Use the idle queue to call the update function with the new
directory as the "current" directory.
For each encountered file:
Attempt to add the file to the track_db.
Commit the database if at least one new file has been added.
- Testing:
The script tests/library/gen_library.sh will create a sample library
in the /tmp/ directory for testing purposes. All the track files are
complete silence, but the script will fake up tags for each file.
To test importing, create several mock library files and copy them to
~/.ocarina-test/library/ and attempt to read them in.
- LibraryQueue API:
LibraryQueue :: LibraryQueue();
Initialize a Queue with the flags Q_ENABLED and Q_REPEAT. The
default sorting order should be artist, year, track.
LibraryQueue :: save();
Write a library queue to disk.
LibraryQueue :: load();
Read a library queue from disk.
LibraryQueue :: set_flag(queue_flag f);
LibraryQueue :: unset_flag(queue_flag f);
LibraryQueue :: sort(sort_t field, bool reset);
These functions are wrappers around the default Queue
implementation. First call the original function, then use
save() to store the changes.
- API
void library :: init();
Scan the tagdb track list, and add each track to the library
queue.
Library *library :: add_path(string dir);
If dir is not a directory:
return NULL
Add a new path to the tag database, trigger an update, and
then return the corresponding Library tag to the caller.
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 do nothing.
void library :: update_path(unsigned int lib_id);
First, validate all tracks in the given library.
Next, trigger an update on the given library.
void library :: update_all();
Update all valid library paths.
void library :: set_enabled(unsigned int id, bool enabled);
Toggle if a library path is enabled or not. A disabled
library path will have its tracks removed from the
LibraryQueue.
void library :: get_queue();
Return the LibraryQueue to the caller.
Playlist:
Playlists are a new feature in Ocarina 6 and are modeled after Gmail
labels. Ocarina 6.1 will support two different playlists that the
@ -1078,110 +1171,6 @@ Playlist:
- library queue should be set to the default sort order
The default sort order is (SORT_ARTIST, true),
(SORT_YEAR, true), (SORT_TRACK, true).
Library: (lib/library.cpp)
The library manages databases containing track information added by the
user. Ocarina 6 splits the library into multiple database tables for
storing content. The library will exist in a library namespace to
to make functions and classes more unique.
- Databases:
Database<library :: Album> album_db(album.db);
Database<library :: Artist> artist_db(artist.db);
Database<library :: Genre> genre_db(genre.db);
Database<library :: Library> library_db(library.db);
Database<library :: Track> track_db(track.db);
- Updating algorithm:
1) Use a single IdleTask to loop over each track in the library, check
if the track still exists in the filesystem and remove it from
library_db if not.
2) For each directory in the scan directory, create an IdleTask to
scan the next level of directories.
3) For each file in the scan directory, check if the file already
exists in the track_db and add it to the database if not. Save
each database after adding files.
The taglib library should be used for finding artist, album, etc. tags
for each track.
- Importing
Ocarina 5.11 stores library files in ~/.ocarina/library/. Importing
involves reading each file and adding them to the database. If the file
describes a path already in the database then DO NOT overwrite the
current path and instead move on to the next file. If version != 2 then
move on to the next file.
File format:
File << version << endl; /* version == 2 */
File << path << endl;
File << id << enabled << next_track_id << size << endl;
File << <track list>
Track format:
File << filepath << endl;
File << title << endl;
File << artist << endl;
File << album << endl;
File << comment << endl;
File << genre << endl;
File << lenstr << endl;
File << id << year << track << count;
File << last_day << last_month << last_year;
File << length << bitrate << sample << channels << banned << endl;
- Testing:
The script tests/library/gen_library.sh will create a sample library
in the /tmp/ directory for testing purposes. All the track files are
complete silence, but the script will fake up tags for each file.
To test importing, create several mock library files and copy them to
~/.ocarina-test/library/ and attempt to read them in.
- API
void library :: init();
Initialize databases and read files from disk. While reading
the library:
- Update the count of tracks in each library path
- Find the lowercase text of artist, album, genre, track
void library :: add_path(string dir);
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.
void library :: update_path(lib_id);
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.
Throw -EEXIST if there is no track mapping to track_id.
struct library :: Library *library :: lookup_path(unsigned int id);
Return the library path with index id.
Throw -EEXIST if there is no such path.
void library :: import();
Call this function to import an Ocarina 5.11 style library,
following the "Importing" section above.
Deck: (lib/deck.cpp)