Remove special None handling and video

This commit is contained in:
emeric
2018-02-10 16:30:19 +01:00
parent 5cc2a29b59
commit 18a446a0a2
20 changed files with 11 additions and 609 deletions
-8
View File
@@ -8,14 +8,6 @@ AC_LANG_CPLUSPLUS
# Checks for programs
AC_PROG_CXX
AC_ARG_ENABLE([video], AS_HELP_STRING([--enable-video],
[Enable Video support. Default to no.])],
[enable_video="$enableval"],
[enable_video="no"])
AM_CONDITIONAL([VIDEO], [test x$enable_video = xyes])
AS_IF([test x$enable_video = xyes], [AC_DEFINE(HAVE_VIDEO, [1], [Enable Video support])])
PKG_CHECK_MODULES(IMAGEMAGICKXX, "ImageMagick++", [ HAVE_IMAGEMAGICKXX=yes ], [ ])
if test -n "$HAVE_IMAGEMAGICKXX"; then
MAGICKXX_CFLAGS="$IMAGEMAGICKXX_CFLAGS"
-9
View File
@@ -15,7 +15,6 @@ lms_SOURCES = \
$(srcdir)/database/SqlQuery.cpp \
$(srcdir)/database/Track.cpp \
$(srcdir)/database/User.cpp \
$(srcdir)/database/Video.cpp \
$(srcdir)/database/updater/DatabaseUpdater.cpp \
$(srcdir)/database/updater/DatabaseFeatureExtractor.cpp \
$(srcdir)/database/updater/DatabaseHighLevelCluster.cpp \
@@ -45,14 +44,6 @@ lms_SOURCES = \
$(srcdir)/utils/Path.cpp \
$(srcdir)/utils/Utils.cpp
if VIDEO
lms_SOURCES += \
$(srcdir)/ui/video/VideoWidget.cpp \
$(srcdir)/ui/video/VideoDatabaseWidget.cpp \
$(srcdir)/ui/video/VideoMediaPlayerWidget.cpp \
$(srcdir)/ui/video/VideoParametersDialog.cpp
endif
lms_CXXFLAGS=-std=c++11 -Wall -I$(srcdir)/third-party -I$(srcdir)/ui $(MAGICKXX_CFLAGS) -D_REENTRANT -DBOOST_SPIRIT_THREADSAFE
lms_LDADD=$(MAGICKXX_LIBS)
+2 -2
View File
@@ -173,9 +173,9 @@ Grabber::getFromRelease(Wt::Dbo::Session& session, Database::Release::id_type re
Wt::Dbo::Transaction transaction(session);
// If the release does not exist or is the special release "None", do nothing
// If the release does not exist, do nothing
Release::pointer release = Release::getById(session, releaseId);
if (!release || release->isNone())
if (!release)
return std::vector<Image::Image>();
std::vector<Track::pointer> tracks = release->getTracks();
-168
View File
@@ -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
-102
View File
@@ -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
-1
View File
@@ -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");
-16
View File
@@ -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)
{
-2
View File
@@ -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)
-1
View File
@@ -36,7 +36,6 @@ class MediaDirectory
enum Type {
Audio = 1,
Video = 2,
};
MediaDirectory() {}
-16
View File
@@ -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)
{
-2
View File
@@ -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
-15
View File
@@ -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)
{
-2
View File
@@ -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);
-1
View File
@@ -23,7 +23,6 @@
#include "Track.hpp"
#include "Playlist.hpp"
#include "Release.hpp"
#include "Video.hpp"
#include "MediaDirectory.hpp"
#include "User.hpp"
-59
View File
@@ -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
-84
View File
@@ -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
+6 -115
View File
@@ -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
-3
View File
@@ -81,9 +81,6 @@ Artist::refresh()
auto releases = artist->getReleases(_filters->getClusterIds());
for (auto release : releases)
{
if (release->isNone())
continue;
Wt::WTemplate* entry = new Wt::WTemplate(Wt::WString::tr("template-artist-entry"), releasesContainer);
entry->addFunction("tr", Wt::WTemplate::Functions::tr);
+1 -1
View File
@@ -121,7 +121,7 @@ Release::refresh()
entry->bindString("name", Wt::WString::fromUTF8(track->getName()), Wt::PlainText);
if (variousArtists && !track->getArtist()->isNone())
if (variousArtists && track->getArtist())
{
entry->setCondition("if-has-artist", true);
Wt::WAnchor *artistAnchor = new Wt::WAnchor(Wt::WLink(Wt::WLink::InternalPath, "/artist/" + std::to_string(track->getArtist().id())));
+2 -2
View File
@@ -81,7 +81,7 @@ Tracks::refresh(std::vector<std::string> searchKeywords)
entry->bindString("name", Wt::WString::fromUTF8(track->getName()), Wt::PlainText);
auto artist = track->getArtist();
if (!artist->isNone())
if (artist)
{
entry->setCondition("if-has-artist", true);
Wt::WAnchor *artistAnchor = new Wt::WAnchor(Wt::WLink(Wt::WLink::InternalPath, "/artist/" + std::to_string(track->getArtist().id())));
@@ -91,7 +91,7 @@ Tracks::refresh(std::vector<std::string> searchKeywords)
}
auto release = track->getRelease();
if (!release->isNone())
if (release)
{
entry->setCondition("if-has-release", true);
// TODO anchor