diff --git a/DESIGN b/DESIGN index 79d3121f..65a00db5 100644 --- a/DESIGN +++ b/DESIGN @@ -528,48 +528,234 @@ Idle queue: -Playlists: (lib/playlist.cpp) - Playlists are a new feature in Ocarina 6 and are modeled after Gmail - labels. Ocarina 6.0 will support two different playlists that the - user can add tracks to: banned and favorites. +Artist Tag: + The arist tag is used to collect basic information about the various + artists that have been added to the library. - Future releases will add support for more playlists. +- Artist: + class Artist : public DatabaseEntry { + public: + std::string name; + std::string lower; -- Database: - Database playlist_db + Artist(); + Artist(const std::string &); + const std::string primary_key(); + void read(File &); + void write(File &); + }; -- Default playlists: - Favorites: - The user will add music they really like to this playlist. +- File Format: + File << name; - Banned: - The user should add music they do not like to this playlist. - Tracks should be removed from the Library playqueue when they - are banned and added back to the playqueue when they are - un-banned. +- API: + Artist(); + Initialize an invalid Artist instance. -- API - void playlist :: init(): - Load the playlist database. + Artist(const std::string &artist_name); + Use artist_name to set name and lower. - void playlist :: add(name, track_id); - Add the track_id to the playlist named "name". Save the - database to disk. - Throw -EEXIST if "name" does not exist. + const std::string Artist :: primary_key(); + Use artist name as primary key. - void playlist :: del(name, track_id); - Remove the track_id from the playlist named "name". Save the - database to disk. Attempting to remove a track_id that does - not exist is not an error. - Throw -EEXIST if "name" does not exist. + void Artist :: read(File &f); + Read artist name from file and add to the filter. - const std::set &playlist :: get_tracks(name); - Return the set of tracks representing the requested group. - Throw -EEXIST if "name" does not exist. + void Artist :: write(File &f); + Write artist name to file. - void playlist :: clear(); - This function only exists if CONFIG_TEST is enabled. Clear - (reset) the playlist database. + + +Album Tag: + The album tag is used to collect information about each artist's albums. + +- Album: + class Album : public DatabaseEntry { + public: + std::string name; + std::string lower; + unsigned int year; + unsigned int artist_id; + + Album(); + Album(const std::string &, unsigned int, unsigned int); + const std::string primary_key(); + void read(File &); + void write(File &); + }; + +- File Format: + File << artist_id << year << name; + +- API: + Album(); + Initialize an invalid Album instance. + + Album(const std::string &album_name, unsigned int album_year, + unsigned int album_artist); + Set name from album name and find the lowercased form. + Set year from album_year and artist_id from album_artist. + + const std::string Album :: primary_key(); + Return the string: "$name.$year.$artist_id" + + void Album :: read(File &f); + Read artist_id, year, and name from file. Then add album name + to the filter. + + void Artist :: write(File &f); + Write album information to file. + + + +Genre Tag: + The genre tag is used to collect basic information about the various + genres of songs in the library. + +- Genre: + class Genre : public DatabaseEntry { + public: + std::string genre; + std::string lower; + + Genre(); + Genre(const std::string &); + const std::string primary_key(); + void read(File &); + void write(File &); + }; + +- File Format: + File << name; + +- API: + Genre(); + Initialize an invalid Genre instance. + + Genre(const std::string &genre_name); + Use genre_name to set genre and lower. + + const std::string Genre :: primary_key(); + Use genre as primary key. + + void Genre :: read(File &f); + Read genre from file and add to the filter. + + void Genre :: write(File &f); + Write genre to file. + + + +Library Tag: + The library tag is used to store a single directory added to Ocarina + by the user. It is not an ID3 tag, and is instead something I use + internally to keep track of paths added by the user. + +- Library: + class library :: Library : public DatabaseEntry { + public: + string root_path; /* primary_key */ + unsigned int count; + bool enabled; + + Library(); + Library(const std::string &); + const std::string primary_key(); + void read(File &); + void write(File &); + }; + +- File Format: + File << enabled << root_path + +- API: + Library(); + Initialize an invalid Library instance. + + Library(const std::string &path); + Set root_path from the provided path. + Set enabled = true. + + const std::string Library :: primary_key(); + Use root_path as the primary key, + + void read(File &f); + Read a library path from file. + + void write(File &f); + Write a library path to file. + + + +Track Tag: + The track tag is used to store information about a single track in the + user's music collection. + +- Track: + class Track : public DatabaseEntry { + public: + Library *library; + Artist *artist; + Album *album; + Genre *genre; + + unsigned int track; + unsigned int length; + unsigned int play_count; + unsigned int last_year; + unsigned int last_month; + unsigned int last_day; + + std :: string title; + std :: string title_lower; + std :: string filepath; + std :: string length_str; + + Track(); + Track(Library *, Artist *, Album *, Genre *, unsigned int, + unsigned int, const std::string &, const std::string &); + const std::string primary_key(); + const std::string path(); + void read(File &); + void write(File &); + }; + +- File Format: + File << library->id << artist->id << album->id << genre->id; + File << track << last_year << last_month << last_day << play_count; + File << length << length_str << endl + File << title << endl; + File << filepath << endl; + +- API: + Track(); + Initialize an invalid Track instance. + + Track(Library *lib, Artist *art, Album *alb, Genre *gen, + unsigned int track, unsigned int length, + const std::string &track_title, const std::string &full_path); + - Set Library, Artist, Album and Genre pointers. + - Set track and length variables. + - Set play_count, last_year, last_month and last_day = 0. + - Set title from track_title. + - Strip library path from prams.full_path and use the result to + set filepath. + - Set lowercase title and find the string form of length. + + const std::string Track :: primary_key(); + return path(); + + const std::string Track :: path(); + Combine library->path and filepath to find the full path to + the audio file. + + void read(File &f); + Read track information from file. Look up the corresponding + Library, Artist, Album and Genre pointers and add title to + the filter. + + void write(File &f); + Write track information to file. @@ -579,90 +765,10 @@ Library: (lib/library.cpp) storing content. The library will exist in a library namespace to to make functions and classes more unique. -- Databases: - enum DB_Type { - DB_ALBUM, - DB_ARTIST, - DB_GENRE, - DB_LIBRARY, - DB_TRACK, - }; - -- Album: - class library :: Album : public DatabaseEntry { - public: - /* primary_key = "$name.$year.$artist_id" */ - string name; - string name_lower; - unsigned int year; - unsigned int artist_id; - }; - - File << artist_id << year << name - -- Artist and Genre: - class library :: AGInfo : public DatabaseEntry { - public: - string name; /* primary key */ - string name_lower; - }; - - File << name - -- Library: - class library :: Library : public DatabaseEntry { - public: - string root_path; /* primary_key */ - 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: - /* primary_key = library.root_path + "/" + filepath */ - 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; - - string length_str; - string title; - string title_lower; - string filepath; - }; - - File << library_id << artist_id << album_id << genre_id; - File << track << last_year << last_month << last_day << play_count; - File << length << length_str << endl - File << title << endl; - File << filepath << endl; - -- Song: - struct Song { - library :: Album *album; - library :: AGInfo *artist; - library :: AGInfo *genre; - library :: Library *library; - library :: Track *track; - }; - - Databases: Database album_db(album.db); - Database artist_db(artist.db); - Database genre_db(genre.db); + Database artist_db(artist.db); + Database genre_db(genre.db); Database library_db(library.db); Database track_db(track.db); @@ -751,14 +857,50 @@ Library: (lib/library.cpp) Call this function to import an Ocarina 5.11 style library, following the "Importing" section above. -#ifdef CONFIG_TEST - 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_TEST */ +Playlists: (lib/playlist.cpp) + Playlists are a new feature in Ocarina 6 and are modeled after Gmail + labels. Ocarina 6.0 will support two different playlists that the + user can add tracks to: banned and favorites. + + Future releases will add support for more playlists. + +- Database: + Database playlist_db + +- Default playlists: + Favorites: + The user will add music they really like to this playlist. + + Banned: + The user should add music they do not like to this playlist. + Tracks should be removed from the Library playqueue when they + are banned and added back to the playqueue when they are + un-banned. + +- API + void playlist :: init(): + Load the playlist database. + + void playlist :: add(name, track_id); + Add the track_id to the playlist named "name". Save the + database to disk. + Throw -EEXIST if "name" does not exist. + + void playlist :: del(name, track_id); + Remove the track_id from the playlist named "name". Save the + database to disk. Attempting to remove a track_id that does + not exist is not an error. + Throw -EEXIST if "name" does not exist. + + const std::set &playlist :: get_tracks(name); + Return the set of tracks representing the requested group. + Throw -EEXIST if "name" does not exist. + + void playlist :: clear(); + This function only exists if CONFIG_TEST is enabled. Clear + (reset) the playlist database.