ocarina/design/library.txt

207 lines
5.4 KiB
Plaintext

== Files ==
ocarina/include/
library.h
ocarina/lib/
library.cpp
$HOME/.ocarina{-debug}/
album.db
artist.db
genre.db
library.db
track.db
== Depends ==
idle database playlist filter
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.
When a library : Track is created, it should be added to the "Library"
group if it is NOT a member of the banned songs group.
- Databases:
enum DB_Type {
DB_ALBUM,
DB_ARTIST,
DB_GENRE,
DB_LIBRARY,
DB_TRACK,
};
- Album:
class library :: Album : public DatabaseEntry {
public:
string name;
string name_lc;
unsigned int year;
unsigned int artist_id;
};
File << artist_id << year << name
- Artist:
class library :: Artist : public DatabaseEntry {
public:
string name;
string name_lc;
};
File << name
- Genre:
class library :: Genre : public DatabaseEntry {
public:
string name;
string name_lc;
};
File << name
- Library:
class library :: Library : public DatabaseEntry {
public:
string root_path;
unsigned int count;
bool enabled;
};
File << enabled << root_path
- Track:
The primary key for a track is the full filepath (library.root_path +
track.filepath)
class library :: Track : public DatabaseEntry {
public:
unsigned int library_id;
unsigned int artist_id;
unsigned int album_id;
unsigned int genre_id;
unsigned int track;
unsigned int last_year;
unsigned int last_month;
unsigned int last_day;
unsigned int play_count;
unsigned int length;
bool banned;
string title;
string title_lc;
string length_str;
string filepath;
};
File << library_id << artist_id << album_id << genre_id << track << last_year
File << last_month << last_day << play_count << length << banned << endl
File << title << endl;
File << filepath << endl;
- Song:
struct Song {
library :: Album *album;
library :: Artist *artist;
library :: Genre *genre;
library :: Library *library;
library :: Track *track;
};
- 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) For each track currently in the library, check if the track exists
in the filesystem and mark the track invalid if it does not.
2) For each file in the scan directory, check if the track exists in
the track is already in the track_db.
2a) If the file is in the db, do nothing.
2b) Else, add track to the library and the filter index.
3) Save all databases
The taglib library should be used for finding artist, album, etc. tags
for each track.
Use idle tasks for step 2 to break up tagging new files into chunks.
This way the user will still be able to use Ocarina and scanning can
happen while idle.
- 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 treacks 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
Add new row to the library_db table, begin an update only
on the new path.
void library :: del_path(unsigned int lib_id);
Invalidate a library_db row and all tracks owned by that path
void library :: update_path(lib_id);
Update the given library_db row, if valid.
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 :: get_path_info(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.
#ifdef CONFIG_DEBUG
void library :: print_db(DB_Type);
Print the database corresponding to DB_Type
void library :: reset();
Clear all databases, returning the library to an empty state.
endif /* CONFIG_DEBUG */