ocarina/core/tags/track.cpp

202 lines
4.6 KiB
C++

/**
* Copyright 2014 (c) Anna Schumaker.
*/
#include <core/filter.h>
#include <core/string.h>
#include <core/tags/track.h>
#include <glib.h>
#include <stdlib.h>
static Database<Track> track_db("track.db", false);
Track :: Track()
: GenericTag(),
_album(NULL), _artist(NULL), _genre(NULL), _library(NULL),
_count(0), _length(0), _track(0)
{}
Track :: Track(Album *album, Artist *artist, Genre *genre, Library *library,
const std::string &filepath, const std::string &name,
unsigned int length, unsigned int track)
: GenericTag(name),
_album(album), _artist(artist), _genre(genre), _library(library),
_count(0), _length(length), _track(track), _path(filepath)
{
_date.d_day = 0;
_date.d_month = 0;
_date.d_year = 0;
filter :: add(this->name(), index());
filter :: add(_artist->name(), index());
filter :: add(_album->name(), index());
_library->inc_size();
}
Track :: Track(const Track &track)
: GenericTag(track),
_album(track._album), _artist(track._artist), _genre(track._genre),
_library(track._library), _count(track._count), _length(track._length),
_track(track._track), _date(track._date), _path(track._path)
{
_library->inc_size();
}
Track :: ~Track()
{
if (_library)
_library->dec_size();
}
Album *Track :: album() { return _album; }
Artist *Track :: artist() { return _artist; }
Genre *Track :: genre() { return _genre; }
Library *Track :: library() { return _library; }
unsigned int Track :: count() { return _count; }
unsigned int Track :: length() { return _length; }
unsigned int Track :: track() { return _track; }
const std::string Track :: date() const
{
struct tm tm;
char buffer[20];
std::string res = "Never";
if (_count > 0) {
tm.tm_mday = _date.d_day;
tm.tm_mon = _date.d_month - 1;
tm.tm_year = _date.d_year - 1900;
strftime(buffer, 20, "%Ex", &tm);
res = buffer;
}
return res;
}
const std::string Track :: path() const
{
if (_library)
return _library->primary_key() + "/" + _path;
return "";
}
const std::string Track :: primary_key() const
{
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;
}
void Track :: played()
{
time_t rawtime = time(NULL);
struct tm *now = localtime(&rawtime);
_count++;
_date.d_day = now->tm_mday;
_date.d_month = now->tm_mon + 1;
_date.d_year = now->tm_year + 1900;
tags :: commit_track_db();
}
int Track :: compare_date(const Track *rhs)
{
int ret = _date.d_year - rhs->_date.d_year;
if (ret == 0) {
ret = _date.d_month - rhs->_date.d_month;
if (ret == 0)
ret = _date.d_day - rhs->_date.d_day;
}
return ret;
}
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 %u %u %u %u %u", &library_id,
&artist_id, &album_id, &genre_id, &_track, &_date.d_year,
&_date.d_month, &_date.d_day, &_count, &_length);
GenericTag :: read(file);
path = file_readl(&file);
_path = path;
g_free(path);
_library = tags :: get_library(library_id);
_artist = tags :: get_artist(artist_id);
_album = tags :: get_album(album_id);
_genre = tags :: get_genre(genre_id);
filter :: add(name(), index());
filter :: add(_artist->name(), index());
filter :: add(_album->name(), index());
_library->inc_size();
}
void Track :: write(file &file)
{
file_writef(&file, "%u %u %u %u %u %u %u %u %u %u ", _library->index(),
_artist->index(), _album->index(), _genre->index(), _track,
_date.d_year, _date.d_month, _date.d_day, _count, _length);
GenericTag :: write(file);
file_writef(&file, "\n%s\n", _path.c_str());
}
void tags :: init_track_db()
{
track_db.load();
}
Track *tags :: add_track(Album *album, Artist *artist, Genre *genre,
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);
return track_db.insert(Track(album, artist, genre, library, path,
name, length, track));
}
Track *tags :: get_track(const unsigned int index)
{
return track_db.at(index);
}
void tags :: remove_track(Track *track)
{
track_db.remove(track->index());
}
void tags :: remove_library_tracks(Library *library)
{
Database<Track>::iterator it;
for (it = track_db.begin(); it != track_db.end(); it = track_db.next(it)) {
if ((*it)->library() == library)
track_db.remove((*it)->index());
}
tags :: commit_track_db();
}
unsigned int tags :: track_size()
{
return track_db.actual_size();
}
void tags :: commit_track_db()
{
track_db.save();
}