library: Implement importing old libraries
This adds backwards-compatibility for Ocarina 5.11 libraries. Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
This commit is contained in:
parent
94fdfda9fb
commit
a2665d4e41
|
@ -10,6 +10,8 @@
|
|||
#include <taglib/tag.h>
|
||||
#include <taglib/fileref.h>
|
||||
|
||||
struct ImportData;
|
||||
|
||||
namespace library
|
||||
{
|
||||
|
||||
|
@ -29,6 +31,7 @@ namespace library
|
|||
|
||||
AGInfo();
|
||||
AGInfo(DB_Type, TagLib :: Tag *);
|
||||
AGInfo(DB_Type, const std::string &);
|
||||
void read(File &);
|
||||
void write(File &);
|
||||
#ifdef CONFIG_DEBUG
|
||||
|
@ -46,6 +49,7 @@ namespace library
|
|||
|
||||
Album();
|
||||
Album(TagLib :: Tag *, unsigned int);
|
||||
Album(const std::string &, unsigned int, unsigned int);
|
||||
void read(File &);
|
||||
void write(File &);
|
||||
#ifdef CONFIG_DEBUG
|
||||
|
@ -83,7 +87,6 @@ namespace library
|
|||
unsigned int play_count;
|
||||
unsigned int length;
|
||||
|
||||
bool banned;
|
||||
std :: string title;
|
||||
std :: string title_lower;
|
||||
std :: string length_str;
|
||||
|
@ -93,6 +96,8 @@ namespace library
|
|||
Track(TagLib :: Tag *, TagLib :: AudioProperties *,
|
||||
unsigned int, unsigned int, unsigned int,
|
||||
unsigned int, const std :: string &);
|
||||
Track(ImportData *, unsigned int, unsigned int,
|
||||
unsigned int, unsigned int);
|
||||
void read(File &);
|
||||
void write(File &);
|
||||
#ifdef CONFIG_DEBUG
|
||||
|
@ -116,6 +121,7 @@ namespace library
|
|||
void update_path(unsigned int);
|
||||
void update_all();
|
||||
void lookup(unsigned int, library :: Song *);
|
||||
void import();
|
||||
#ifdef CONFIG_DEBUG
|
||||
void print_db(DB_Type);
|
||||
void reset();
|
||||
|
|
141
lib/library.cpp
141
lib/library.cpp
|
@ -16,6 +16,17 @@ static Database<library :: Track> track_db("track.db");
|
|||
|
||||
static Database<library :: Library> library_db("library.db");
|
||||
|
||||
struct ImportData {
|
||||
std::string filepath;
|
||||
std::string title;
|
||||
unsigned int track;
|
||||
unsigned int last_day;
|
||||
unsigned int last_month;
|
||||
unsigned int last_year;
|
||||
unsigned int length;
|
||||
unsigned int count;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
@ -39,6 +50,17 @@ library :: AGInfo :: AGInfo(DB_Type type, TagLib :: Tag *tag)
|
|||
key_lower = filter :: to_lowercase(primary_key);
|
||||
}
|
||||
|
||||
library :: AGInfo :: AGInfo(DB_Type type, const std::string &str)
|
||||
: db_type(type)
|
||||
{
|
||||
if ((db_type == DB_ARTIST) || (db_type == DB_GENRE)) {
|
||||
primary_key = str;
|
||||
key_lower = filter :: to_lowercase(primary_key);
|
||||
} else
|
||||
throw -EINVAL;
|
||||
|
||||
}
|
||||
|
||||
void library :: AGInfo :: read(File &f)
|
||||
{
|
||||
primary_key = f.getline();
|
||||
|
@ -80,6 +102,15 @@ library :: Album :: Album(TagLib :: Tag *tag, unsigned int artist)
|
|||
name_lower = filter :: to_lowercase(name);
|
||||
}
|
||||
|
||||
library :: Album :: Album(const std::string &str, unsigned int yr, unsigned int artist)
|
||||
: name(str), year(yr), artist_id(artist)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << artist_id << "." << name << "." << year;
|
||||
primary_key = ss.str();
|
||||
name_lower = filter :: to_lowercase(name);
|
||||
}
|
||||
|
||||
void library :: Album :: read(File &f)
|
||||
{
|
||||
f >> artist_id >> year;
|
||||
|
@ -153,7 +184,7 @@ library :: Track :: Track(TagLib :: Tag *tag, TagLib :: AudioProperties *audio,
|
|||
unsigned int genre, const std :: string &path)
|
||||
: library_id(lib), artist_id(artist), album_id(album), genre_id(genre),
|
||||
track(tag->track()), last_year(0), last_month(0), last_day(0),
|
||||
play_count(0), length(audio->length()), banned(false),
|
||||
play_count(0), length(audio->length()),
|
||||
title(tag->title().stripWhiteSpace().to8Bit(true))
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
@ -172,11 +203,36 @@ library :: Track :: Track(TagLib :: Tag *tag, TagLib :: AudioProperties *audio,
|
|||
length_str = ss.str();
|
||||
}
|
||||
|
||||
library :: Track :: Track(struct ImportData *data, unsigned int lib,
|
||||
unsigned int artist, unsigned int album,
|
||||
unsigned int genre)
|
||||
: library_id(lib), artist_id(artist), album_id(album), genre_id(genre),
|
||||
track(data->track), last_year(data->last_year), last_month(data->last_month),
|
||||
last_day(data->last_day), play_count(data->count), length(data->length),
|
||||
title(data->title)
|
||||
{
|
||||
std::stringstream ss;
|
||||
unsigned int minutes, seconds;
|
||||
|
||||
primary_key = data->filepath;
|
||||
filepath = primary_key.substr(library_db[library_id].root_path.size() + 1);
|
||||
title_lower = filter :: to_lowercase(title);
|
||||
|
||||
minutes = length / 60;
|
||||
seconds = length % 60;
|
||||
ss << minutes << ":";
|
||||
if (seconds < 10)
|
||||
ss << "0";
|
||||
ss << seconds;
|
||||
length_str = ss.str();
|
||||
}
|
||||
|
||||
void library :: Track :: read(File &f)
|
||||
{
|
||||
f >> library_id >> artist_id >> album_id >> genre_id;
|
||||
f >> track >> last_year >> last_month >> last_day;
|
||||
f >> play_count >> length >> banned;
|
||||
f >> play_count >> length;
|
||||
length_str = f.getline();
|
||||
title = f.getline();
|
||||
filepath = f.getline();
|
||||
}
|
||||
|
@ -303,6 +359,66 @@ static void do_update_library(unsigned int lib_id)
|
|||
idle :: schedule(do_scan_path, scan);
|
||||
}
|
||||
|
||||
static void do_import_track(File &f, unsigned int lib_id)
|
||||
{
|
||||
struct ImportData data;
|
||||
std::string artist, album, genre;
|
||||
unsigned int artist_id, album_id, genre_id, year, tmp;
|
||||
|
||||
data.filepath = f.getline();
|
||||
data.title = f.getline();
|
||||
|
||||
artist = f.getline();
|
||||
album = f.getline();
|
||||
f.getline(); /* comment */
|
||||
genre = f.getline();
|
||||
f.getline(); /* lenstr */
|
||||
f >> tmp /* id */ >> year >> data.track >> data.count;
|
||||
f >> data.last_day >> data.last_month >> data.last_year >> data.length;
|
||||
f >> tmp >> tmp >>tmp >> tmp; /* bitrate, sample, channels, banned */
|
||||
f.getline(); /* get rest of line */
|
||||
|
||||
artist_id = artist_db.insert(library :: AGInfo(library :: DB_ARTIST, artist));
|
||||
album_id = album_db.insert(library :: Album(album, year, artist_id));
|
||||
genre_id = genre_db.insert(library :: AGInfo(library :: DB_GENRE, genre));
|
||||
track_db.insert(library :: Track(&data, lib_id, artist_id, album_id, genre_id));
|
||||
}
|
||||
|
||||
static void do_import_library(std::string &s)
|
||||
{
|
||||
unsigned int id, next_id, size;
|
||||
std::string path;
|
||||
bool enabled;
|
||||
File f(s, FILE_TYPE_LEGACY);
|
||||
|
||||
print("Importing: %s\n", f.get_filepath());
|
||||
f.open(OPEN_READ);
|
||||
|
||||
if (f.get_version() != 2) {
|
||||
print("Version mismatch: %u != 2\n", f.get_version());
|
||||
return;
|
||||
}
|
||||
|
||||
path = f.getline();
|
||||
f >> id >> enabled >> next_id >> size;
|
||||
|
||||
/* Assign this path a new id */
|
||||
if (library_db.has_key(path)) {
|
||||
print("Library already contains path: %s, skipping\n", path.c_str());
|
||||
return;
|
||||
}
|
||||
print("Adding path: %s\n", path.c_str());
|
||||
id = library_db.insert(library :: Library(path, enabled));
|
||||
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();
|
||||
|
||||
library :: update_path(id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
@ -355,6 +471,27 @@ void library :: lookup(unsigned int id, library :: Song *song)
|
|||
song->library = &library_db[song->track->library_id];
|
||||
}
|
||||
|
||||
void library :: import()
|
||||
{
|
||||
unsigned int i = 0;
|
||||
std::string name;
|
||||
|
||||
do {
|
||||
std::stringstream ss;
|
||||
ss << i;
|
||||
|
||||
name = ss.str();
|
||||
File f(name, FILE_TYPE_LEGACY);
|
||||
|
||||
if (f.exists() == false)
|
||||
break;
|
||||
|
||||
idle :: schedule(do_import_library, name);
|
||||
ss.clear();
|
||||
i++;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
void library :: print_db(DB_Type type)
|
||||
{
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
1
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -78,3 +78,9 @@ for i in $(seq 0 4); do
|
|||
done
|
||||
|
||||
touch /tmp/library/file
|
||||
|
||||
##
|
||||
# Set up legacy library files
|
||||
#
|
||||
mkdir -p $HOME/.ocarina-test/library/
|
||||
cp tests/library/0 tests/library/1 tests/library/2 tests/library/3 $HOME/.ocarina-test/library/
|
||||
|
|
|
@ -204,6 +204,20 @@ void test_6()
|
|||
library :: update_path(0);
|
||||
run_idle_tasks();
|
||||
library :: print_db(library :: DB_TRACK);
|
||||
print("\n");
|
||||
}
|
||||
|
||||
/* Test importing Ocarina 5.11 libraries */
|
||||
void test_7()
|
||||
{
|
||||
library :: reset();
|
||||
|
||||
test_add_dir("7a", "/tmp/library/2", true);
|
||||
|
||||
print("\n");
|
||||
library :: import();
|
||||
run_idle_tasks();
|
||||
library :: print_db(library :: DB_LIBRARY);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
@ -217,5 +231,6 @@ int main(int argc, char **argv)
|
|||
test_4();
|
||||
test_5();
|
||||
test_6();
|
||||
test_7();
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue