ocarina/core/tags/track.cpp

197 lines
4.6 KiB
C++
Raw Normal View History

/**
* Copyright 2014 (c) Anna Schumaker.
*/
#include <core/filter.h>
#include <core/string.h>
#include <core/tags/track.h>
#include <glib.h>
static database<struct track> track_db;
static const std::string make_key(struct library *library, const std::string &path)
{
std :: string res;
if (library) {
gchar *g_res = g_strdup_printf("%u/%s", library->index(),
path.c_str());
res = g_res;
g_free(g_res);
}
return res;
}
track :: track()
: GenericTag(),
tr_album(NULL), tr_artist(NULL), tr_genre(NULL), tr_library(NULL),
tr_count(0), tr_length(0), tr_track(0)
{}
track :: track(struct album *album, struct artist *artist, struct genre *genre,
struct library *library, const std::string &filepath,
const std::string &name, unsigned int length, unsigned int track)
: GenericTag(name),
tr_album(album), tr_artist(artist), tr_genre(genre),
tr_library(library), tr_count(0), tr_length(length), tr_track(track),
tr_path(filepath)
{
date_set(&tr_date, 0, 0, 0);
filter :: add(this->name(), index());
filter :: add(tr_artist->ar_name, index());
filter :: add(tr_album->al_name, index());
tr_library->li_size++;
}
track :: track(const struct track &track)
: GenericTag(track),
tr_album(track.tr_album), tr_artist(track.tr_artist),
tr_genre(track.tr_genre), tr_library(track.tr_library),
tr_count(track.tr_count), tr_length(track.tr_length),
tr_track(track.tr_track), tr_date(track.tr_date),
tr_path(track.tr_path)
{
tr_library->li_size++;
}
track :: ~track()
{
if (tr_library)
tr_library->li_size--;
}
struct album *track :: album() { return tr_album; }
struct artist *track :: artist() { return tr_artist; }
struct genre *track :: genre() { return tr_genre; }
struct library *track :: library() { return tr_library; }
unsigned int track :: count() { return tr_count; }
unsigned int track :: length() { return tr_length; }
unsigned int track :: track_nr() { return tr_track; }
const std::string track :: date() const
{
char *buf;
std::string res = "Never";
if (tr_count > 0) {
buf = date_string(&tr_date);
res = buf;
g_free(buf);
}
return res;
}
const std::string track :: path() const
{
if (tr_library)
return library_file(tr_library, tr_path);
return "";
}
const std::string track :: primary_key() const
{
return make_key(tr_library, tr_path);
}
void track :: played()
{
tr_count++;
date_today(&tr_date);
tags :: commit_track_db();
}
int track :: compare_date(const struct track *rhs)
{
return date_compare(&tr_date, &rhs->tr_date);
}
void track :: read(file &file)
{
unsigned int library_id, artist_id, album_id, genre_id;
gchar *path;
file_readf(&file, "%u %u %u %u %u", &library_id, &artist_id,
&album_id, &genre_id, &tr_track);
date_read(&file, &tr_date);
file_readf(&file, "%u %u", &tr_count, &tr_length);
GenericTag :: read(file);
path = file_readl(&file);
tr_path = path;
g_free(path);
tr_library = library_get(library_id);
tr_artist = artist_get(artist_id);
tr_album = album_get(album_id);
tr_genre = genre_get(genre_id);
filter :: add(name(), index());
filter :: add(tr_artist->ar_name, index());
filter :: add(tr_album->al_name, index());
tr_library->li_size++;
}
void track :: write(file &file)
{
file_writef(&file, "%u %u %u %u %u ", tr_library->index(),
tr_artist->index(), tr_album->index(),
tr_genre->index(), tr_track);
date_write(&file, &tr_date);
file_writef(&file, " %u %u ", tr_count, tr_length);
GenericTag :: write(file);
file_writef(&file, "\n%s\n", tr_path.c_str());
}
void tags :: init_track_db()
{
db_init(&track_db, "track.db", false);
db_load(&track_db);
}
struct track *track_add(struct album *album, struct artist *artist,
struct genre *genre, struct library *library,
const std::string &filepath, const std::string &name,
unsigned int length, unsigned int track)
{
std::string path = filepath.substr(library->primary_key().size() + 1);
if (db_get(&track_db, make_key(library, path).c_str()))
return NULL;
return db_insert(&track_db, new struct track(album, artist, genre, library,
path, name, length, track));
}
void tags :: remove_track(struct track *track)
{
db_remove(&track_db, track);
}
void tags :: remove_library_tracks(struct library *library)
{
struct track *it, *next;
db_for_each(it, next, &track_db) {
if (it->library() == library)
db_remove(&track_db, it);
}
tags :: commit_track_db();
}
struct track *track_get(const unsigned int index)
{
return db_at(&track_db, index);
}
unsigned int tags :: track_size()
{
return db_actual_size(&track_db);
}
void tags :: commit_track_db()
{
db_save(&track_db);
}