Remove special None handling and video
This commit is contained in:
@@ -1,168 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Emeric Poupon
|
||||
*
|
||||
* This file is part of LMS.
|
||||
*
|
||||
* LMS is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LMS is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Types.hpp"
|
||||
#include "SqlQuery.hpp"
|
||||
|
||||
#include "utils/Logger.hpp"
|
||||
|
||||
namespace Database
|
||||
{
|
||||
|
||||
Artist::Artist(const std::string& name, const std::string& MBID)
|
||||
: _name(std::string(name, 0 , _maxNameLength)),
|
||||
_MBID(MBID)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::vector<Artist::pointer>
|
||||
Artist::getByName(Wt::Dbo::Session& session, const std::string& name)
|
||||
{
|
||||
Wt::Dbo::collection<Artist::pointer> res = session.find<Artist>().where("name = ?").bind( std::string(name, 0, _maxNameLength) );
|
||||
return std::vector<Artist::pointer>(res.begin(), res.end());
|
||||
}
|
||||
|
||||
Artist::pointer
|
||||
Artist::getByMBID(Wt::Dbo::Session& session, const std::string& mbid)
|
||||
{
|
||||
return session.find<Artist>().where("mbid = ?").bind(mbid);
|
||||
}
|
||||
|
||||
Artist::pointer
|
||||
Artist::getById(Wt::Dbo::Session& session, Artist::id_type id)
|
||||
{
|
||||
return session.find<Artist>().where("id = ?").bind(id);
|
||||
}
|
||||
|
||||
Artist::pointer
|
||||
Artist::create(Wt::Dbo::Session& session, const std::string& name, const std::string& MBID)
|
||||
{
|
||||
return session.add(new Artist(name, MBID));
|
||||
}
|
||||
|
||||
Artist::pointer
|
||||
Artist::getNone(Wt::Dbo::Session& session)
|
||||
{
|
||||
std::vector<pointer> res = getByName(session, "<None>");
|
||||
if (res.empty())
|
||||
return create(session, "<None>");
|
||||
|
||||
return res.front();
|
||||
}
|
||||
|
||||
std::vector<Artist::pointer>
|
||||
Artist::getAll(Wt::Dbo::Session& session, int offset, int size)
|
||||
{
|
||||
Wt::Dbo::collection<pointer> res = session.find<Artist>().offset(offset).limit(size);
|
||||
return std::vector<pointer>(res.begin(), res.end());
|
||||
}
|
||||
|
||||
std::vector<Artist::pointer>
|
||||
Artist::getAllOrphans(Wt::Dbo::Session& session)
|
||||
{
|
||||
Wt::Dbo::collection<Artist::pointer> res = session.query< Wt::Dbo::ptr<Artist> >("select a from artist a LEFT OUTER JOIN Track t ON a.id = t.artist_id WHERE t.id IS NULL");
|
||||
|
||||
return std::vector<pointer>(res.begin(), res.end());
|
||||
}
|
||||
|
||||
std::vector<Artist::pointer>
|
||||
Artist::getByFilter(Wt::Dbo::Session& session, SearchFilter filter, int offset, int size)
|
||||
{
|
||||
Wt::Dbo::collection<Artist::pointer> res = getQuery(session, filter).limit(size).offset(offset);
|
||||
|
||||
return std::vector<pointer>(res.begin(), res.end());
|
||||
}
|
||||
|
||||
std::vector<Artist::pointer>
|
||||
Artist::getByFilter(Wt::Dbo::Session& session, SearchFilter filter, int offset, int size, bool& moreResults)
|
||||
{
|
||||
auto res = getByFilter(session, filter, offset, size + 1);
|
||||
|
||||
if (size != -1 && res.size() == static_cast<std::size_t>(size) + 1)
|
||||
{
|
||||
moreResults = true;
|
||||
res.pop_back();
|
||||
}
|
||||
else
|
||||
moreResults = false;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::vector<Wt::Dbo::ptr<Release> >
|
||||
Artist::getReleases() const
|
||||
{
|
||||
assert(self());
|
||||
assert(self()->id() != Wt::Dbo::dbo_traits<Artist>::invalidId() );
|
||||
assert(session());
|
||||
|
||||
Wt::Dbo::collection< Wt::Dbo::ptr<Release> > res = session()->query<Wt::Dbo::ptr<Release> >("SELECT r FROM release r INNER JOIN artist a ON t.artist_id = a.id INNER JOIN track t ON t.release_id = r.id").where("a.id = ?").bind(id());
|
||||
|
||||
return std::vector< Wt::Dbo::ptr<Release> > (res.begin(), res.end());
|
||||
}
|
||||
|
||||
Wt::Dbo::Query<Artist::pointer>
|
||||
Artist::getQuery(Wt::Dbo::Session& session, SearchFilter filter)
|
||||
{
|
||||
SqlQuery sqlQuery = generatePartialQuery(filter);
|
||||
|
||||
Wt::Dbo::Query<pointer> query
|
||||
= session.query<pointer>( "SELECT a FROM artist a INNER JOIN track t ON t.artist_id = a.id INNER JOIN release r ON r.id = t.release_id INNER JOIN cluster c ON c.id = t_c.cluster_id INNER JOIN track_cluster t_c ON t_c.track_id = t.id " + sqlQuery.where().get()).groupBy("a.id").orderBy("a.name");
|
||||
|
||||
for (const std::string& bindArg : sqlQuery.where().getBindArgs())
|
||||
query.bind(bindArg);
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
Wt::Dbo::Query<Artist::UIQueryResult>
|
||||
Artist::getUIQuery(Wt::Dbo::Session& session, SearchFilter filter)
|
||||
{
|
||||
SqlQuery sqlQuery = generatePartialQuery(filter);
|
||||
|
||||
Wt::Dbo::Query<UIQueryResult> query
|
||||
= session.query<UIQueryResult>( "SELECT a.id, a.name, COUNT(DISTINCT r.id), COUNT(DISTINCT t.id) FROM artist a INNER JOIN track t ON t.artist_id = a.id INNER JOIN release r ON r.id = t.release_id INNER JOIN cluster c ON c.id = t_c.cluster_id INNER JOIN track_cluster t_c ON t_c.track_id = t.id " + sqlQuery.where().get()).groupBy("a.id").orderBy("a.name");
|
||||
|
||||
for (const std::string& bindArg : sqlQuery.where().getBindArgs())
|
||||
query.bind(bindArg);
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
void
|
||||
Artist::updateUIQueryModel(Wt::Dbo::Session& session, Wt::Dbo::QueryModel<UIQueryResult>& model, SearchFilter filter, const std::vector<Wt::WString>& columnNames)
|
||||
{
|
||||
Wt::Dbo::Query<UIQueryResult> query = getUIQuery(session, filter);
|
||||
|
||||
model.setQuery(query, columnNames.empty() ? true : false);
|
||||
|
||||
// TODO do something better
|
||||
if (columnNames.size() == 3)
|
||||
{
|
||||
model.addColumn( "a.name", columnNames.at(0));
|
||||
model.addColumn( "COUNT(DISTINCT r.id)", columnNames.at(1) );
|
||||
model.addColumn( "COUNT(DISTINCT t.id)", columnNames.at(2) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace Database
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Emeric Poupon
|
||||
*
|
||||
* This file is part of LMS.
|
||||
*
|
||||
* LMS is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LMS is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _DB_ARTIST_HPP_
|
||||
#define _DB_ARTIST_HPP_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <Wt/Dbo/Dbo>
|
||||
#include <Wt/Dbo/QueryModel>
|
||||
|
||||
#include "SearchFilter.hpp"
|
||||
|
||||
namespace Database
|
||||
{
|
||||
|
||||
class Track;
|
||||
class Cluster;
|
||||
class Release;
|
||||
|
||||
class Artist : public Wt::Dbo::Dbo<Artist>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Wt::Dbo::ptr<Artist> pointer;
|
||||
typedef Wt::Dbo::dbo_traits<Artist>::IdType id_type;
|
||||
|
||||
Artist() {}
|
||||
Artist(const std::string& name, const std::string& MBID = "");
|
||||
|
||||
// Accessors
|
||||
static pointer getByMBID(Wt::Dbo::Session& session, const std::string& MBID);
|
||||
static pointer getById(Wt::Dbo::Session& session, id_type id);
|
||||
static pointer getNone(Wt::Dbo::Session& session); // Special entry
|
||||
static std::vector<pointer> getByName(Wt::Dbo::Session& session, const std::string& name);
|
||||
static std::vector<pointer> getByFilter(Wt::Dbo::Session& session, SearchFilter filter, int offset = -1, int size = -1);
|
||||
static std::vector<pointer> getByFilter(Wt::Dbo::Session& session, SearchFilter filter, int offset, int size, bool& moreExpected);
|
||||
|
||||
static std::vector<pointer> getAll(Wt::Dbo::Session& session, int offset = -1, int size = -1);
|
||||
static std::vector<pointer> getAllOrphans(Wt::Dbo::Session& session);
|
||||
|
||||
// Accessors
|
||||
std::string getName(void) const { return _name; }
|
||||
std::string getMBID(void) const { return _MBID; }
|
||||
|
||||
// Get the releases that have at least one track for this artist
|
||||
std::vector<Wt::Dbo::ptr<Release> > getReleases() const;
|
||||
|
||||
void setMBID(std::string mbid) { _MBID = mbid; }
|
||||
|
||||
// Create
|
||||
static pointer create(Wt::Dbo::Session& session, const std::string& name, const std::string& MBID = "");
|
||||
|
||||
// MVC models for the user interface
|
||||
// ID, Artist name, albums, tracks
|
||||
typedef boost::tuple<id_type, std::string, int, int> UIQueryResult;
|
||||
static Wt::Dbo::Query<UIQueryResult> getUIQuery(Wt::Dbo::Session& session, SearchFilter filter);
|
||||
static void updateUIQueryModel(Wt::Dbo::Session& session, Wt::Dbo::QueryModel<UIQueryResult>& model, SearchFilter filter, const std::vector<Wt::WString>& columnNames = std::vector<Wt::WString>());
|
||||
|
||||
bool isNone(void) const;
|
||||
|
||||
template<class Action>
|
||||
void persist(Action& a)
|
||||
{
|
||||
Wt::Dbo::field(a, _name, "name");
|
||||
Wt::Dbo::field(a, _MBID, "mbid");
|
||||
|
||||
Wt::Dbo::hasMany(a, _tracks, Wt::Dbo::ManyToOne, "artist");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static Wt::Dbo::Query<pointer> getQuery(Wt::Dbo::Session& session, SearchFilter filter);
|
||||
|
||||
static const std::size_t _maxNameLength = 128;
|
||||
|
||||
std::string _name;
|
||||
std::string _MBID; // Musicbrainz Identifier
|
||||
|
||||
Wt::Dbo::collection< Wt::Dbo::ptr<Track> > _tracks; // Tracks of this artist
|
||||
};
|
||||
|
||||
} // namespace Database
|
||||
|
||||
#endif
|
||||
@@ -87,7 +87,6 @@ Handler::Handler(Wt::Dbo::SqlConnectionPool& connectionPool)
|
||||
_session.mapClass<Database::Playlist>("playlist");
|
||||
_session.mapClass<Database::PlaylistEntry>("playlist_entry");
|
||||
_session.mapClass<Database::Release>("release");
|
||||
_session.mapClass<Database::Video>("video");
|
||||
_session.mapClass<Database::MediaDirectory>("media_directory");
|
||||
_session.mapClass<Database::Setting>("setting");
|
||||
|
||||
|
||||
@@ -57,22 +57,6 @@ Artist::create(Wt::Dbo::Session& session, const std::string& name, const std::st
|
||||
return session.add(new Artist(name, MBID));
|
||||
}
|
||||
|
||||
Artist::pointer
|
||||
Artist::getNone(Wt::Dbo::Session& session)
|
||||
{
|
||||
std::vector<pointer> res = getByName(session, "<None>");
|
||||
if (res.empty())
|
||||
return create(session, "<None>");
|
||||
|
||||
return res.front();
|
||||
}
|
||||
|
||||
bool
|
||||
Artist::isNone() const
|
||||
{
|
||||
return _name == "<None>";
|
||||
}
|
||||
|
||||
std::vector<Artist::pointer>
|
||||
Artist::getAll(Wt::Dbo::Session& session, int offset, int size)
|
||||
{
|
||||
|
||||
@@ -48,7 +48,6 @@ class Artist : public Wt::Dbo::Dbo<Artist>
|
||||
// Accessors
|
||||
static pointer getByMBID(Wt::Dbo::Session& session, const std::string& MBID);
|
||||
static pointer getById(Wt::Dbo::Session& session, id_type id);
|
||||
static pointer getNone(Wt::Dbo::Session& session); // Special entry
|
||||
static std::vector<pointer> getByName(Wt::Dbo::Session& session, const std::string& name);
|
||||
static std::vector<pointer> getByFilter(Wt::Dbo::Session& session,
|
||||
const std::set<id_type>& clusters, // at least one track that belongs to these clusters
|
||||
@@ -72,7 +71,6 @@ class Artist : public Wt::Dbo::Dbo<Artist>
|
||||
// Create
|
||||
static pointer create(Wt::Dbo::Session& session, const std::string& name, const std::string& MBID = "");
|
||||
|
||||
bool isNone(void) const;
|
||||
|
||||
template<class Action>
|
||||
void persist(Action& a)
|
||||
|
||||
@@ -36,7 +36,6 @@ class MediaDirectory
|
||||
|
||||
enum Type {
|
||||
Audio = 1,
|
||||
Video = 2,
|
||||
};
|
||||
|
||||
MediaDirectory() {}
|
||||
|
||||
@@ -56,22 +56,6 @@ Release::create(Wt::Dbo::Session& session, const std::string& name, const std::s
|
||||
return session.add(new Release(name, MBID));
|
||||
}
|
||||
|
||||
bool
|
||||
Release::isNone() const
|
||||
{
|
||||
return _name == "<None>";
|
||||
}
|
||||
|
||||
Release::pointer
|
||||
Release::getNone(Wt::Dbo::Session& session)
|
||||
{
|
||||
std::vector<pointer> res = getByName(session, "<None>");
|
||||
if (res.empty())
|
||||
return create(session, "<None>");
|
||||
|
||||
return res.front();
|
||||
}
|
||||
|
||||
std::vector<Release::pointer>
|
||||
Release::getAll(Wt::Dbo::Session& session, int offset, int size)
|
||||
{
|
||||
|
||||
@@ -46,7 +46,6 @@ class Release : public Wt::Dbo::Dbo<Release>
|
||||
static pointer getByMBID(Wt::Dbo::Session& session, const std::string& MBID);
|
||||
static std::vector<pointer> getByName(Wt::Dbo::Session& session, const std::string& name);
|
||||
static pointer getById(Wt::Dbo::Session& session, id_type id);
|
||||
static pointer getNone(Wt::Dbo::Session& session); // Special entry
|
||||
static std::vector<pointer> getAllOrphans(Wt::Dbo::Session& session); // no track related
|
||||
static std::vector<pointer> getAll(Wt::Dbo::Session& session, int offset, int size);
|
||||
|
||||
@@ -68,7 +67,6 @@ class Release : public Wt::Dbo::Dbo<Release>
|
||||
// Accessors
|
||||
std::string getName() const { return _name; }
|
||||
std::string getMBID() const { return _MBID; }
|
||||
bool isNone(void) const;
|
||||
boost::posix_time::time_duration getDuration(void) const;
|
||||
|
||||
// Get the artists of this release
|
||||
|
||||
@@ -240,21 +240,6 @@ Cluster::getByType(Wt::Dbo::Session& session, std::string type)
|
||||
return std::vector<Cluster::pointer>(res.begin(), res.end());
|
||||
}
|
||||
|
||||
Cluster::pointer
|
||||
Cluster::getNone(Wt::Dbo::Session& session)
|
||||
{
|
||||
pointer res = get(session, "<None>", "<None>");
|
||||
if (!res)
|
||||
res = create(session, "<None>", "<None>");
|
||||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
Cluster::isNone(void) const
|
||||
{
|
||||
return (_type == "<None>" && _name == "<None>");
|
||||
}
|
||||
|
||||
Cluster::pointer
|
||||
Cluster::create(Wt::Dbo::Session& session, std::string type, std::string name)
|
||||
{
|
||||
|
||||
@@ -59,7 +59,6 @@ class Cluster
|
||||
|
||||
// Find utility
|
||||
static pointer get(Wt::Dbo::Session& session, std::string type, std::string name);
|
||||
static pointer getNone(Wt::Dbo::Session& session);
|
||||
static std::vector<pointer> getByFilter(Wt::Dbo::Session& session, SearchFilter filter, int offset = -1, int size = -1);
|
||||
static Wt::Dbo::collection<pointer> getAll(Wt::Dbo::Session& session);
|
||||
static std::vector<std::string> getAllTypes(Wt::Dbo::Session& session);
|
||||
@@ -74,7 +73,6 @@ class Cluster
|
||||
// Accessors
|
||||
const std::string& getName(void) const { return _name; }
|
||||
const std::string& getType(void) const { return _type; }
|
||||
bool isNone(void) const;
|
||||
const Wt::Dbo::collection< Wt::Dbo::ptr<Track> >& getTracks() const { return _tracks;}
|
||||
|
||||
void addTrack(Wt::Dbo::Session& session, Wt::Dbo::dbo_traits<Track>::IdType trackId);
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "Track.hpp"
|
||||
#include "Playlist.hpp"
|
||||
#include "Release.hpp"
|
||||
#include "Video.hpp"
|
||||
#include "MediaDirectory.hpp"
|
||||
#include "User.hpp"
|
||||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Emeric Poupon
|
||||
*
|
||||
* This file is part of LMS.
|
||||
*
|
||||
* LMS is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LMS is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Types.hpp"
|
||||
|
||||
namespace Database {
|
||||
|
||||
Video::Video()
|
||||
{
|
||||
}
|
||||
|
||||
Video::Video(const boost::filesystem::path& p)
|
||||
: _filePath(p.string())
|
||||
{
|
||||
}
|
||||
|
||||
Video::pointer
|
||||
Video::create(Wt::Dbo::Session& session, const boost::filesystem::path& p)
|
||||
{
|
||||
return session.add(new Video(p));
|
||||
}
|
||||
|
||||
Wt::Dbo::collection< Video::pointer >
|
||||
Video::getAll(Wt::Dbo::Session& session)
|
||||
{
|
||||
return session.find<Video>();
|
||||
}
|
||||
|
||||
Video::pointer
|
||||
Video::getByPath(Wt::Dbo::Session& session, const boost::filesystem::path& p)
|
||||
{
|
||||
return session.find<Video>().where("path = ?").bind(p.string());
|
||||
}
|
||||
|
||||
std::vector<boost::filesystem::path>
|
||||
Video::getAllPaths(Wt::Dbo::Session& session)
|
||||
{
|
||||
Wt::Dbo::Transaction transaction(session);
|
||||
Wt::Dbo::collection<std::string> res = session.query<std::string>("SELECT path from video");
|
||||
return std::vector<boost::filesystem::path>(res.begin(), res.end());
|
||||
}
|
||||
|
||||
} // namespace Video
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Emeric Poupon
|
||||
*
|
||||
* This file is part of LMS.
|
||||
*
|
||||
* LMS is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LMS is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _VIDEO_TYPES_HPP
|
||||
#define _VIDEO_TYPES_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <Wt/Dbo/Dbo>
|
||||
#include <Wt/Dbo/WtSqlTraits>
|
||||
|
||||
#include <Wt/WDateTime>
|
||||
|
||||
namespace Database {
|
||||
|
||||
class Video
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Wt::Dbo::ptr<Video> pointer;
|
||||
|
||||
Video();
|
||||
Video( const boost::filesystem::path& p);
|
||||
|
||||
// Find utilities
|
||||
static pointer getByPath(Wt::Dbo::Session& session, const boost::filesystem::path& p);
|
||||
static Wt::Dbo::collection< pointer > getAll(Wt::Dbo::Session& session);
|
||||
static std::vector<boost::filesystem::path> getAllPaths(Wt::Dbo::Session& session);
|
||||
|
||||
// Create utility
|
||||
static pointer create(Wt::Dbo::Session& session, const boost::filesystem::path& p);
|
||||
|
||||
// Modifiers
|
||||
void setName(const std::string& name) { _name = name; }
|
||||
void setDuration(boost::posix_time::time_duration duration) { _duration = duration; }
|
||||
void setLastWriteTime(boost::posix_time::ptime time) { _fileLastWrite = time; }
|
||||
|
||||
// Accessors
|
||||
std::string getName(void) const { return _name; }
|
||||
boost::posix_time::time_duration getDuration(void) const { return _duration; }
|
||||
boost::filesystem::path getPath(void) const { return _filePath; }
|
||||
boost::posix_time::ptime getLastWriteTime(void) const { return _fileLastWrite; }
|
||||
|
||||
template<class Action>
|
||||
void persist(Action& a)
|
||||
{
|
||||
Wt::Dbo::field(a, _name, "name");
|
||||
Wt::Dbo::field(a, _duration, "duration");
|
||||
Wt::Dbo::field(a, _fileLastWrite, "last_write");
|
||||
Wt::Dbo::field(a, _filePath, "path");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::string _name;
|
||||
boost::posix_time::time_duration _duration;
|
||||
std::string _filePath;
|
||||
boost::posix_time::ptime _fileLastWrite;
|
||||
|
||||
}; // Video
|
||||
|
||||
|
||||
} // namespace Database
|
||||
|
||||
#endif
|
||||
|
||||
@@ -240,7 +240,6 @@ Updater::process(boost::system::error_code err)
|
||||
Stats stats;
|
||||
|
||||
checkAudioFiles(stats);
|
||||
checkVideoFiles(stats);
|
||||
|
||||
std::vector<RootDirectory> rootDirectories;
|
||||
{
|
||||
@@ -296,10 +295,6 @@ Updater::updateFileExtensions()
|
||||
_audioFileExtensions.clear();
|
||||
for (auto extension : splitString(Setting::getString(_db->getSession(), "audio_file_extensions"), " "))
|
||||
_audioFileExtensions.push_back( extension );
|
||||
|
||||
_videoFileExtensions.clear();
|
||||
for (auto extension : splitString(Setting::getString(_db->getSession(), "video_file_extensions"), " "))
|
||||
_videoFileExtensions.push_back( extension );
|
||||
}
|
||||
|
||||
Artist::pointer
|
||||
@@ -336,7 +331,7 @@ Updater::getArtist( const boost::filesystem::path& file, const std::string& name
|
||||
return artist;
|
||||
}
|
||||
|
||||
return Artist::getNone( _db->getSession() );
|
||||
return Artist::pointer();
|
||||
}
|
||||
|
||||
Release::pointer
|
||||
@@ -373,7 +368,7 @@ Updater::getRelease( const boost::filesystem::path& file, const std::string& nam
|
||||
return release;
|
||||
}
|
||||
|
||||
return Release::getNone( _db->getSession() );
|
||||
return Release::pointer();
|
||||
}
|
||||
|
||||
std::vector<Cluster::pointer>
|
||||
@@ -390,9 +385,6 @@ Updater::getGenreClusters( const std::list<std::string>& names)
|
||||
genres.push_back( genre );
|
||||
}
|
||||
|
||||
if (genres.empty())
|
||||
genres.push_back( Cluster::getNone( _db->getSession() ));
|
||||
|
||||
return genres;
|
||||
}
|
||||
|
||||
@@ -486,7 +478,6 @@ Updater::processAudioFile( const boost::filesystem::path& file, Stats& stats)
|
||||
// TODO rename
|
||||
genres = getGenreClusters( genreList );
|
||||
}
|
||||
assert( !genres.empty() );
|
||||
|
||||
// ***** Artist
|
||||
Artist::pointer artist;
|
||||
@@ -502,7 +493,6 @@ Updater::processAudioFile( const boost::filesystem::path& file, Stats& stats)
|
||||
|
||||
artist = getArtist(file, artistName, artistMusicBrainzID);
|
||||
}
|
||||
assert(artist);
|
||||
|
||||
// ***** Release
|
||||
Release::pointer release;
|
||||
@@ -543,8 +533,10 @@ Updater::processAudioFile( const boost::filesystem::path& file, Stats& stats)
|
||||
assert(track);
|
||||
|
||||
track.modify()->setChecksum(checksum);
|
||||
track.modify()->setArtist(artist);
|
||||
track.modify()->setRelease(release);
|
||||
if (artist)
|
||||
track.modify()->setArtist(artist);
|
||||
if (release)
|
||||
track.modify()->setRelease(release);
|
||||
track.modify()->setLastWriteTime(lastWriteTime);
|
||||
track.modify()->setName(title);
|
||||
track.modify()->setDuration( boost::any_cast<boost::posix_time::time_duration>(items[MetaData::Type::Duration]) );
|
||||
@@ -631,11 +623,6 @@ Updater::processRootDirectory(RootDirectory rootDirectory, Stats& stats)
|
||||
processAudioFile(path, stats );
|
||||
|
||||
break;
|
||||
|
||||
case Database::MediaDirectory::Video:
|
||||
if (isFileSupported(path, _videoFileExtensions))
|
||||
processVideoFile(path, stats);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -785,101 +772,5 @@ Updater::checkDuplicatedAudioFiles(Stats& stats)
|
||||
LMS_LOG(DBUPDATER, INFO) << "Checking duplicated audio files done!";
|
||||
}
|
||||
|
||||
void
|
||||
Updater::checkVideoFiles( Stats& stats )
|
||||
{
|
||||
std::vector<boost::filesystem::path> rootDirs = getRootDirectoriesByType(_db->getSession(), Database::MediaDirectory::Video);
|
||||
std::vector<boost::filesystem::path> videoPaths = Video::getAllPaths(_db->getSession());
|
||||
|
||||
LMS_LOG(DBUPDATER, DEBUG) << "Checking videos...";
|
||||
for (auto& videoPath : videoPaths)
|
||||
{
|
||||
if (!_running)
|
||||
return;
|
||||
|
||||
if (!checkFile(videoPath, rootDirs, _videoFileExtensions))
|
||||
{
|
||||
Wt::Dbo::Transaction transaction(_db->getSession());
|
||||
|
||||
Video::pointer video = Video::getByPath(_db->getSession(), videoPath);
|
||||
if (video)
|
||||
{
|
||||
video.remove();
|
||||
stats.nbRemoved++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LMS_LOG(DBUPDATER, DEBUG) << "Check video files done!";
|
||||
}
|
||||
|
||||
void
|
||||
Updater::processVideoFile( const boost::filesystem::path& file, Stats& stats)
|
||||
{
|
||||
// Check last update time
|
||||
boost::posix_time::ptime lastWriteTime (boost::posix_time::from_time_t( boost::filesystem::last_write_time( file ) ) );
|
||||
|
||||
Wt::Dbo::Transaction transaction(_db->getSession());
|
||||
|
||||
// Skip file if last write is the same
|
||||
Wt::Dbo::ptr<Video> video = Video::getByPath(_db->getSession(), file);
|
||||
if (video && video->getLastWriteTime() == lastWriteTime)
|
||||
return;
|
||||
|
||||
MetaData::Items items;
|
||||
if (!_metadataParser.parse(file, items))
|
||||
return;
|
||||
|
||||
// We estimate this is a video if:
|
||||
// - we found a least one video stream
|
||||
// - the duration is not null
|
||||
if (items.find(MetaData::Type::VideoStreams) == items.end()
|
||||
|| boost::any_cast<std::vector<MetaData::VideoStream> >(items[MetaData::Type::VideoStreams]).empty())
|
||||
{
|
||||
LMS_LOG(DBUPDATER, ERROR) << "Skipped '" << file << "' (no video stream found)";
|
||||
|
||||
// If the video exists here, delete it!
|
||||
if (video) {
|
||||
video.remove();
|
||||
stats.nbRemoved++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (items.find(MetaData::Type::Duration) == items.end()
|
||||
|| boost::any_cast<boost::posix_time::time_duration>(items[MetaData::Type::Duration]).total_seconds() == 0)
|
||||
{
|
||||
LMS_LOG(DBUPDATER, ERROR) << "Skipped '" << file << "' (no duration or duration 0)";
|
||||
|
||||
// If Track exists here, delete it!
|
||||
if (video) {
|
||||
video.remove();
|
||||
stats.nbRemoved++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If video already exist, update data
|
||||
// Otherwise, create it
|
||||
// Today we are very aggressive, but we could also guess names from path, etc.
|
||||
if (!video)
|
||||
{
|
||||
video = Video::create(_db->getSession(), file);
|
||||
LMS_LOG(DBUPDATER, DEBUG) << "Adding '" << file << "'";
|
||||
stats.nbAdded++;
|
||||
}
|
||||
else
|
||||
{
|
||||
LMS_LOG(DBUPDATER, DEBUG) << "Updating '" << file << "'";
|
||||
stats.nbUpdated++;
|
||||
}
|
||||
|
||||
assert(video);
|
||||
|
||||
video.modify()->setName( file.filename().string() );
|
||||
video.modify()->setDuration( boost::any_cast<boost::posix_time::time_duration>(items[MetaData::Type::Duration]) );
|
||||
video.modify()->setLastWriteTime(lastWriteTime);
|
||||
|
||||
transaction.commit();
|
||||
}
|
||||
|
||||
} // namespace Database
|
||||
|
||||
Reference in New Issue
Block a user