From dd8bc1d57d796ba628da34efb6b8f1a8a60c3dbb Mon Sep 17 00:00:00 2001 From: Jon Bergli Heier Date: Fri, 4 Feb 2011 19:47:12 +0100 Subject: Moved music::update() to MusicDirectory::update(). --- music.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'music.cpp') diff --git a/music.cpp b/music.cpp index ee9f2ba..b9cb05d 100644 --- a/music.cpp +++ b/music.cpp @@ -145,13 +145,13 @@ void music::begin_update(const std::string path) { MusicDirectory::p dir = get_directory(path); std::cout << boost::format("updater(%s) called") % path << std::endl; if(dir) { - update(dir->path); + dir->update(); } } /** Recursively update \p dir and its subdirectories. */ -void music::update(const MusicDirectory& dir) { +void MusicDirectory::update() { // TODO: Fix engine-specific SQL syntax inside this function. soci::session sql(config::vm["audist.database"].as()); @@ -196,7 +196,10 @@ void music::update(const MusicDirectory& dir) { } sql.close(); - std::for_each(dir.directories.begin(), dir.directories.end(), update); + for(PathListings::iterator it = directories.begin(); it != directories.end(); it++) { + MusicDirectory dir(*it); + dir.update(); + } } void MusicDirectory::render(HTTP::Connection::p req) { -- cgit v1.2.3 From 67a0e925ff1efc839ecb067d605bb45ebebf866a Mon Sep 17 00:00:00 2001 From: Jon Bergli Heier Date: Fri, 4 Feb 2011 20:45:04 +0100 Subject: Moved all SQL code to database.cpp. --- music.cpp | 107 ++++++++------------------------------------------------------ 1 file changed, 13 insertions(+), 94 deletions(-) (limited to 'music.cpp') diff --git a/music.cpp b/music.cpp index b9cb05d..de5575f 100644 --- a/music.cpp +++ b/music.cpp @@ -3,6 +3,7 @@ #include "encoder.h" #include "tag.h" #include "config.h" +#include "database.h" #include #include @@ -77,65 +78,16 @@ MusicDirectory::p music::get_directory(const std::string& path) { * Does a search on specific fields given by \p search. */ std::vector music::find(std::map search) { - soci::session sql(config::vm["audist.database"].as()); - soci::statement st(sql); - std::string filename, artist, album, title; - st.exchange(soci::into(filename)); - std::string query = "SELECT file_name FROM tracks WHERE "; - std::vector where_conditions; - - if(search.find("artist") != search.end()) { - where_conditions.push_back("artist_id IN (SELECT id FROM artists WHERE name LIKE :artist)"); - artist = "%"+search["artist"]+"%"; - st.exchange(soci::use(artist, "artist")); - } - - if(search.find("album") != search.end()) { - where_conditions.push_back("album_id IN (SELECT id FROM albums WHERE name LIKE :album)"); - album = "%"+search["album"]+"%"; - st.exchange(soci::use(album, "album")); - } - - if(search.find("title") != search.end()) { - where_conditions.push_back("name LIKE :title"); - artist = "%"+search["title"]+"%"; - st.exchange(soci::use(title, "title")); - } - - query += boost::algorithm::join(where_conditions, " AND "); - st.alloc(); - st.prepare(query); - st.define_and_bind(); - st.execute(true); - - std::vector results; - while(st.fetch()) { - MusicListing::p ml(new MusicTrack(filename)); - results.push_back(ml); - } - sql.close(); - - return results; + Database db; + return db.find(search); } /** Find tracks in the database. * Returns tracks where title, artist, album or filename matches \p search. */ std::vector music::find(std::string search) { - soci::session sql(config::vm["audist.database"].as()); - - search = "%"+search+"%"; - soci::rowset rs = (sql.prepare << "SELECT DISTINCT file_name FROM tracks WHERE name LIKE :search OR file_name LIKE :search OR " - "artist_id IN (SELECT id FROM artists WHERE name LIKE :search) OR album_id IN (SELECT id FROM albums WHERE name LIKE :search)", - soci::use(search, "search")); - - std::vector results; - for(soci::rowset::const_iterator it = rs.begin(); it != rs.end(); it++) { - MusicListing::p ml(new MusicTrack(*it)); - results.push_back(ml); - } - - return results; + Database db; + return db.find(search); } /** Initiate an update on \p path and its subdirs. @@ -145,60 +97,27 @@ void music::begin_update(const std::string path) { MusicDirectory::p dir = get_directory(path); std::cout << boost::format("updater(%s) called") % path << std::endl; if(dir) { - dir->update(); + Database db; + dir->update(db); } } /** Recursively update \p dir and its subdirectories. */ -void MusicDirectory::update() { - // TODO: Fix engine-specific SQL syntax inside this function. - soci::session sql(config::vm["audist.database"].as()); - - BOOST_FOREACH(fs::path t, dir.tracks) { - std::cout << "track " << t << std::endl; - Tag::p tag = Tag::load(t.string()); +void MusicDirectory::update(Database& db) { + BOOST_FOREACH(fs::path track, tracks) { + std::cout << "track " << track << std::endl; + Tag::p tag = Tag::load(track.string()); BOOST_FOREACH(Tag::Fields::value_type& f, tag->fields) { std::cout << boost::format(" %s: %s") % f.first % f.second << std::endl; } - int artist_id = 0, album_id = 0, track_id = 0; - - if(tag->has_field("artist")) { - sql << "SELECT id FROM artists WHERE name = :name", soci::use(tag->fields["artist"]), soci::into(artist_id); - if(!sql.got_data()) - sql << "INSERT INTO artists (name) VALUES (:name) RETURNING id", soci::use(tag->fields["artist"]), soci::into(artist_id); - } - - if(tag->has_field("album")) { - std::string query(boost::str(boost::format("SELECT id FROM albums WHERE %s AND name = :name") % - (artist_id ? boost::str(boost::format("artist_id = %d") % artist_id) : "artist_id IS NULL"))); - sql << query, soci::use(tag->fields["album"]), soci::into(album_id); - if(!sql.got_data()) { - soci::indicator ind = (artist_id ? soci::i_ok : soci::i_null); - sql << "INSERT INTO albums (artist_id, name) VALUES (:artist_id, :name) RETURNING id", - soci::use(artist_id, ind), soci::use(tag->fields["album"]), soci::into(album_id); - } - } - - if(tag->has_field("title")) { - std::string query(boost::str(boost::format("SELECT id FROM tracks WHERE %s AND %s AND name = :name") % - (artist_id ? boost::str(boost::format("artist_id = %d") % artist_id) : "artist_id IS NULL") % - (album_id ? boost::str(boost::format("album_id = %d") % album_id) : "album_id IS NULL"))); - sql << query, soci::use(tag->fields["title"]), soci::into(track_id); - if(!sql.got_data()) { - soci::indicator artist_ind = (artist_id ? soci::i_ok : soci::i_null), - album_ind = (album_id ? soci::i_ok : soci::i_null); - sql << "INSERT INTO tracks (artist_id, album_id, name, file_name) VALUES (:artist_id, :album_id, :name, :file_name)", - soci::use(artist_id, artist_ind), soci::use(album_id, album_ind), soci::use(tag->fields["title"]), soci::use(t.string()); - } - } + db.update(track, tag); } - sql.close(); for(PathListings::iterator it = directories.begin(); it != directories.end(); it++) { MusicDirectory dir(*it); - dir.update(); + dir.update(db); } } -- cgit v1.2.3 From 6e7b8f94bf7fdc087cd1eed604eabed6070dffad Mon Sep 17 00:00:00 2001 From: Jon Bergli Heier Date: Wed, 2 Mar 2011 19:22:33 +0100 Subject: Implemented simple caching for transcoded audio data. --- music.cpp | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'music.cpp') diff --git a/music.cpp b/music.cpp index de5575f..51c44a8 100644 --- a/music.cpp +++ b/music.cpp @@ -2,8 +2,8 @@ #include "decoder.h" #include "encoder.h" #include "tag.h" -#include "config.h" #include "database.h" +#include "cache.h" #include #include @@ -170,26 +170,22 @@ MusicDirectory::MusicDirectory(const fs::path root) { void MusicTrack::render(HTTP::Connection::p req) { req->add_header("content-type", "application/octet-stream"); + fs::path file_path = path; if(req->args.count("decoder") && req->args.count("encoder")) { Decoder::p decoder = Decoder::get(req->args["decoder"], path.string()); Encoder::p encoder = Encoder::get(req->args["encoder"], decoder); - - // TODO: Make an encoder-to-istream adapter to get rid of this: - char data[0x10000]; - std::streamsize size = 1; - while(size) { - size = encoder->read(data, 0x10000); - if(size > 0) - req->send_data(data, size); - } - - } else { - fs::ifstream is(path, std::ios::in | std::ios::binary); - is.seekg(0, std::ios::end); - req->add_header("content-length", boost::str(boost::format("%d") % is.tellg())); - is.seekg(0, std::ios::beg); - req->send_data(is); + EncodedCache ec(path, decoder, encoder); + file_path = ec.get_path(); + if(!fs::exists(file_path)) + ec.create_cache(); } + + fs::ifstream is(file_path, std::ios::in | std::ios::binary); + is.seekg(0, std::ios::end); + req->add_header("content-length", boost::str(boost::format("%d") % is.tellg())); + is.seekg(0, std::ios::beg); + + req->send_data(is); } -- cgit v1.2.3