[Database] restored id on Artist, Genre and Release tables. Added basic MusicBrainz ID support. Improved search filters a bit

This commit is contained in:
emeric
2015-07-26 20:29:19 +02:00
parent b8e5113914
commit d59a04f5da
44 changed files with 1600 additions and 686 deletions
+1 -1
View File
@@ -199,7 +199,7 @@ AudioMediaPlayer::load(Database::Track::id_type trackId)
bitrate = CurrentUser()->getAudioBitrate();
trackPath = track->getPath();
_mediaTitle->setText ( Wt::WString::fromUTF8(track->getName()) );
_mediaArtistRelease->setText ( Wt::WString::fromUTF8(track->getArtistName()) + " - " + Wt::WString::fromUTF8(track->getReleaseName()) );
_mediaArtistRelease->setText ( Wt::WString::fromUTF8(track->getArtist()->getName()) + " - " + Wt::WString::fromUTF8(track->getRelease()->getName()) );
_mediaCover->setImageLink( Wt::WLink (LmsApplication::instance()->getCoverResource()->getTrackUrl(trackId, 72)));
}
+23 -16
View File
@@ -52,6 +52,8 @@ void WPopupMenuClear(Wt::WPopupMenu* menu)
namespace UserInterface {
namespace Desktop {
using namespace Database;
// Special playlist generated each time the playque gets changed
// Restored at the beginning of the session
static const std::string CurrentQueuePlaylistName = "__current__";
@@ -269,7 +271,7 @@ Audio::playlistShowSaveDialog(std::string playlistName)
Wt::Dbo::Transaction transaction(DboSession());
// Actually create the dialog only if the given list already exists
if (Database::Playlist::get(DboSession(), playlistName, CurrentUser()))
if (Playlist::get(DboSession(), playlistName, CurrentUser()))
{
Wt::WMessageBox *messageBox = new Wt::WMessageBox
("Overwrite playlist",
@@ -301,25 +303,25 @@ Audio::playlistSaveFromPlayqueue(std::string playlistName)
Wt::Dbo::Transaction transaction(DboSession());
Database::Playlist::pointer playlist = Database::Playlist::get(DboSession(), playlistName, CurrentUser());
Playlist::pointer playlist = Playlist::get(DboSession(), playlistName, CurrentUser());
if (playlist)
{
LMS_LOG(MOD_UI, SEV_INFO) << "Erasing playlist '" << playlistName << "'";
playlist.remove();
}
playlist = Database::Playlist::create(DboSession(), playlistName, false, CurrentUser());
playlist = Playlist::create(DboSession(), playlistName, false, CurrentUser());
std::vector<Database::Track::id_type> trackIds;
std::vector<Track::id_type> trackIds;
_playQueue->getTracks(trackIds);
int pos = 0;
BOOST_FOREACH(Database::Track::id_type trackId, trackIds)
for (Track::id_type trackId : trackIds)
{
Database::Track::pointer track = Database::Track::getById(DboSession(), trackId);
Track::pointer track = Track::getById(DboSession(), trackId);
if (track)
Database::PlaylistEntry::create(DboSession(), track, playlist, pos++);
PlaylistEntry::create(DboSession(), track, playlist, pos++);
}
LMS_LOG(MOD_UI, SEV_INFO) << "Saving playqueue to playlist '" << playlistName << "' done. Contains " << pos << " entries";
@@ -330,16 +332,16 @@ Audio::playlistLoadToPlayqueue(std::string playlistName)
{
LMS_LOG(MOD_UI, SEV_DEBUG) << "Loading playlist '" << playlistName << "' to playqueue";
std::vector<Database::Track::id_type> entries;
std::vector<Track::id_type> entries;
{
Wt::Dbo::Transaction transaction(DboSession());
Database::Playlist::pointer playlist = Database::Playlist::get(DboSession(), playlistName, CurrentUser());
Playlist::pointer playlist = Playlist::get(DboSession(), playlistName, CurrentUser());
if (!playlist)
return;
entries = Database::PlaylistEntry::getEntries(DboSession(), playlist);
entries = PlaylistEntry::getEntries(DboSession(), playlist);
}
_playQueue->clear();
@@ -365,7 +367,7 @@ Audio::playlistShowDeleteDialog(std::string name)
{
Wt::Dbo::Transaction transaction(DboSession());
Database::Playlist::pointer playlist = Database::Playlist::get(DboSession(), name, CurrentUser());
Playlist::pointer playlist = Playlist::get(DboSession(), name, CurrentUser());
if (playlist)
playlist.remove();
@@ -396,9 +398,9 @@ Audio::playlistRefreshMenus()
}));
_popupMenuSave->addSeparator();
std::vector<Database::Playlist::pointer> playlists = Database::Playlist::get(DboSession(), CurrentUser());
std::vector<Playlist::pointer> playlists = Playlist::get(DboSession(), CurrentUser());
BOOST_FOREACH(Database::Playlist::pointer playlist, playlists)
for (Playlist::pointer playlist : playlists)
{
if (playlist->getName() == CurrentQueuePlaylistName)
continue;
@@ -431,7 +433,7 @@ Audio::search(std::string searchText)
void
Audio::addSelectedTracks(void)
{
std::vector<Database::Track::id_type> trackIds;
std::vector<Track::id_type> trackIds;
_trackView->getSelectedTracks(trackIds);
// If nothing is selected, get the whole track list
@@ -444,7 +446,9 @@ Audio::addSelectedTracks(void)
void
Audio::playSelectedTracks(PlayQueueAddType addType)
{
std::vector<Database::Track::id_type> trackIds;
std::vector<Track::id_type> trackIds;
LMS_LOG(MOD_UI, SEV_DEBUG) << "Playing selected tracks... nb selected = " << _trackView->getNbSelectedTracks() << ", add type = " << (addType == PlayQueueAddAllTracks ? "AddAll" : "AddSelected");
_playQueue->clear();
@@ -458,6 +462,9 @@ Audio::playSelectedTracks(PlayQueueAddType addType)
break;
case PlayQueueAddSelectedTracks:
LMS_LOG(MOD_UI, SEV_DEBUG) << "Adding selected tracks...";
// If nothing selected, get all the track and play everything
if (_trackView->getNbSelectedTracks() == 0)
{
@@ -485,7 +492,7 @@ Audio::playSelectedTracks(PlayQueueAddType addType)
}
void
Audio::playTrack(Database::Track::id_type trackId, int pos)
Audio::playTrack(Track::id_type trackId, int pos)
{
{
Wt::Dbo::Transaction transaction(DboSession());
+5 -9
View File
@@ -47,16 +47,12 @@ KeywordSearchFilter::getConstraint(Database::SearchFilter& filter)
boost::algorithm::split(values, _lastEmittedText, boost::is_any_of(" "), boost::token_compress_on);
// For each part, do a global search on all searchable fields
BOOST_FOREACH(std::string value, values)
for (const std::string& value : values)
{
Database::SearchFilter::FieldValues likeMatch;
likeMatch[Database::SearchFilter::Field::Artist].push_back(value);
likeMatch[Database::SearchFilter::Field::Release].push_back(value);
likeMatch[Database::SearchFilter::Field::Genre].push_back(value);
likeMatch[Database::SearchFilter::Field::Track].push_back(value);
filter.likeMatches.push_back(likeMatch);
filter.nameLikeMatch[Database::SearchFilter::Field::Artist].push_back(value);
filter.nameLikeMatch[Database::SearchFilter::Field::Release].push_back(value);
filter.nameLikeMatch[Database::SearchFilter::Field::Genre].push_back(value);
filter.nameLikeMatch[Database::SearchFilter::Field::Track].push_back(value);
}
}
}
+22 -16
View File
@@ -366,12 +366,16 @@ PlayQueue::select(int rowId)
void
PlayQueue::addTracks(const std::vector<Database::Track::id_type>& trackIds)
{
using namespace Database;
LMS_LOG(MOD_UI, SEV_DEBUG) << "Adding " << trackIds.size() << " tracks to play queue";
// Add tracks to model
//
BOOST_FOREACH(Database::Track::id_type trackId, trackIds)
for (Track::id_type trackId : trackIds)
{
Wt::Dbo::Transaction transaction(DboSession());
Database::Track::pointer track (Database::Track::getById(DboSession(), trackId));
Track::pointer track (Track::getById(DboSession(), trackId));
if (track)
{
@@ -382,7 +386,7 @@ PlayQueue::addTracks(const std::vector<Database::Track::id_type>& trackIds)
_model->setData(dataRow, COLUMN_ID_TRACK_ID, track.id(), Wt::UserRole);
std::string coverUrl;
if (track->getCoverType() != Database::Track::CoverType::None)
if (track->getCoverType() != Track::CoverType::None)
coverUrl = LmsApplication::instance()->getCoverResource()->getTrackUrl(track.id(), 64);
else
coverUrl = LmsApplication::instance()->getCoverResource()->getUnknownTrackUrl(64);
@@ -392,8 +396,8 @@ PlayQueue::addTracks(const std::vector<Database::Track::id_type>& trackIds)
TrackInfo trackInfo;
trackInfo.track = Wt::WString::fromUTF8(track->getName());
trackInfo.artist = Wt::WString::fromUTF8(track->getArtistName());
trackInfo.release = Wt::WString::fromUTF8(track->getReleaseName());
trackInfo.artist = Wt::WString::fromUTF8(track->getArtist()->getName());
trackInfo.release = Wt::WString::fromUTF8(track->getRelease()->getName());
_model->setData(dataRow, COLUMN_ID_NAME, trackInfo, TrackInfoRole);
}
}
@@ -455,19 +459,21 @@ PlayQueue::playPrevious(void)
}
}
bool
void
PlayQueue::readTrack(int rowPos)
{
LMS_LOG(MOD_UI, SEV_DEBUG) << "Reading track at pos " << rowPos;
Database::Track::id_type trackId = boost::any_cast<Database::Track::id_type>(_model->data(rowPos, COLUMN_ID_TRACK_ID, Wt::UserRole));
LMS_LOG(MOD_UI, SEV_DEBUG) << "Reading track at pos " << rowPos << ", row count = " << _model->rowCount();
setPlayingTrackPos(rowPos);
if (rowPos < _model->rowCount())
{
Database::Track::id_type trackId = boost::any_cast<Database::Track::id_type>(_model->data(rowPos, COLUMN_ID_TRACK_ID, Wt::UserRole));
_sigTrackPlay.emit(trackId, rowPos);
setPlayingTrackPos(rowPos);
this->scrollTo( _model->index(_trackSelector->getCurrent(), 0));
_sigTrackPlay.emit(trackId, rowPos);
return true;
this->scrollTo( _model->index(_trackSelector->getCurrent(), 0));
}
}
void
@@ -485,7 +491,7 @@ PlayQueue::setPlayingTrackPos(int newRowPos)
if (newRowPos >= 0)
{
_model->setData(newRowPos, COLUMN_ID_NAME, "playqueue-playing", Wt::StyleClassRole);
_model->setData(newRowPos, COLUMN_ID_NAME, std::string("playqueue-playing"), Wt::StyleClassRole);
}
}
@@ -527,7 +533,7 @@ PlayQueue::moveSelectedUp(void)
Wt::WModelIndexSet newIndexSet;
// ordered from up to down
BOOST_FOREACH(Wt::WModelIndex index, indexSet)
for (Wt::WModelIndex index : indexSet)
{
// Do nothing if the first selected index is on the top
if (index.row() == 0)
@@ -570,7 +576,7 @@ PlayQueue::moveSelectedDown(void)
Wt::WModelIndexSet newIndexSet;
// ordered from up to down
BOOST_REVERSE_FOREACH(Wt::WModelIndex index, indexSet)
for (Wt::WModelIndex index : indexSet)
{
// Do nothing if the last selected index is the last one
if (index.row() == _model->rowCount() - 1)
+1 -1
View File
@@ -72,7 +72,7 @@ class PlayQueue : public Wt::WTableView
void layoutSizeChanged (int width, int height);
bool readTrack(int rowId);
void readTrack(int rowId);
void setPlayingTrackPos(int newRowPos);
void renumber(int firstId, int lastId);
+17 -16
View File
@@ -39,7 +39,7 @@ TableFilterGenre::TableFilterGenre(Wt::WContainerWidget* parent)
SearchFilter filter;
Genre::updateGenreQueryModel(DboSession(), _queryModel, filter, columnNames);
Genre::updateUIQueryModel(DboSession(), _queryModel, filter, columnNames);
this->setSelectionMode(Wt::ExtendedSelection);
this->setSortingEnabled(true);
@@ -82,7 +82,7 @@ TableFilterGenre::layoutSizeChanged (int width, int height)
void
TableFilterGenre::refresh(SearchFilter& filter)
{
Genre::updateGenreQueryModel(DboSession(), _queryModel, filter);
Genre::updateUIQueryModel(DboSession(), _queryModel, filter);
}
// Get constraint created by this filter
@@ -91,14 +91,15 @@ TableFilterGenre::getConstraint(SearchFilter& filter)
{
Wt::WModelIndexSet indexSet = this->selectedIndexes();
BOOST_FOREACH(Wt::WModelIndex index, indexSet) {
for (Wt::WModelIndex index : indexSet)
{
if (!index.isValid())
continue;
std::string name = _queryModel.resultRow( index.row() ).get<0>();
// TODO set invisible track id
Database::Genre::id_type id = _queryModel.resultRow( index.row() ).get<0>();
filter.exactMatch[Database::SearchFilter::Field::Genre].push_back(name);
filter.idMatch[Database::SearchFilter::Field::Genre].push_back(id);
}
}
@@ -109,7 +110,7 @@ TableFilterArtist::TableFilterArtist(Wt::WContainerWidget* parent)
SearchFilter filter;
Track::updateArtistQueryModel(DboSession(), _queryModel, filter, columnNames);
Artist::updateUIQueryModel(DboSession(), _queryModel, filter, columnNames);
this->setSelectionMode(Wt::ExtendedSelection);
this->setSortingEnabled(true);
@@ -153,7 +154,7 @@ TableFilterArtist::layoutSizeChanged (int width, int height)
void
TableFilterArtist::refresh(SearchFilter& filter)
{
Track::updateArtistQueryModel(DboSession(), _queryModel, filter);
Artist::updateUIQueryModel(DboSession(), _queryModel, filter);
}
// Get constraint created by this filter
@@ -167,9 +168,9 @@ TableFilterArtist::getConstraint(SearchFilter& filter)
if (!index.isValid())
continue;
std::string name = _queryModel.resultRow( index.row() ).get<0>();
Artist::id_type id = _queryModel.resultRow( index.row() ).get<0>();
filter.exactMatch[Database::SearchFilter::Field::Artist].push_back(name);
filter.idMatch[Database::SearchFilter::Field::Artist].push_back(id);
}
}
@@ -180,7 +181,7 @@ TableFilterRelease::TableFilterRelease(Wt::WContainerWidget* parent)
SearchFilter filter;
Track::updateReleaseQueryModel(DboSession(), _queryModel, filter, columnNames);
Release::updateUIQueryModel(DboSession(), _queryModel, filter, columnNames);
this->setSelectionMode(Wt::ExtendedSelection);
this->setSortingEnabled(true);
@@ -231,7 +232,7 @@ TableFilterRelease::layoutSizeChanged (int width, int height)
void
TableFilterRelease::refresh(SearchFilter& filter)
{
Track::updateReleaseQueryModel(DboSession(), _queryModel, filter);
Release::updateUIQueryModel(DboSession(), _queryModel, filter);
}
// Get constraint created by this filter
@@ -240,14 +241,14 @@ TableFilterRelease::getConstraint(SearchFilter& filter)
{
Wt::WModelIndexSet indexSet = this->selectedIndexes();
BOOST_FOREACH(Wt::WModelIndex index, indexSet) {
for (Wt::WModelIndex index : indexSet)
{
if (!index.isValid())
continue;
std::string name = _queryModel.resultRow( index.row() ).get<0>();
Release::id_type id = _queryModel.resultRow( index.row() ).get<0>();
filter.exactMatch[Database::SearchFilter::Field::Release].push_back(name);
filter.idMatch[Database::SearchFilter::Field::Release].push_back(id);
}
}
+3 -3
View File
@@ -52,7 +52,7 @@ class TableFilterGenre : public Wt::WTableView, public Filter
SigDoubleClicked _sigDoubleClicked;
// Name, track count
Wt::Dbo::QueryModel<Database::Genre::GenreResult> _queryModel;
Wt::Dbo::QueryModel<Database::Genre::UIQueryResult> _queryModel;
};
class TableFilterArtist : public Wt::WTableView, public Filter
@@ -77,7 +77,7 @@ class TableFilterArtist : public Wt::WTableView, public Filter
SigDoubleClicked _sigDoubleClicked;
// Name, track count
Wt::Dbo::QueryModel<Database::Track::ArtistResult> _queryModel;
Wt::Dbo::QueryModel<Database::Artist::UIQueryResult> _queryModel;
};
class TableFilterRelease : public Wt::WTableView, public Filter
@@ -102,7 +102,7 @@ class TableFilterRelease : public Wt::WTableView, public Filter
SigDoubleClicked _sigDoubleClicked;
// Name, track count
Wt::Dbo::QueryModel<Database::Track::ReleaseResult> _queryModel;
Wt::Dbo::QueryModel<Database::Release::UIQueryResult> _queryModel;
};
+15 -12
View File
@@ -50,7 +50,7 @@ TrackView::TrackView(Wt::WContainerWidget* parent)
Database::SearchFilter filter;
Database::Track::updateTracksQueryModel(DboSession(), _queryModel, filter, columnNames);
Database::Track::updateUIQueryModel(DboSession(), _queryModel, filter, columnNames);
_queryModel.setBatchSize(300);
@@ -111,7 +111,7 @@ TrackView::TrackView(Wt::WContainerWidget* parent)
void
TrackView::refresh(Database::SearchFilter& filter)
{
Database::Track::updateTracksQueryModel(DboSession(), _queryModel, filter);
Database::Track::updateUIQueryModel(DboSession(), _queryModel, filter);
}
void
@@ -121,17 +121,17 @@ TrackView::getSelectedTracks(std::vector<Database::Track::id_type>& track_ids)
Wt::WModelIndexSet indexSet = this->selectedIndexes();
BOOST_FOREACH(Wt::WModelIndex index, indexSet)
for (Wt::WModelIndex index : indexSet)
{
if (!index.isValid())
continue;
Database::Track::pointer track = _queryModel.resultRow( index.row() );
Database::Track::id_type id = _queryModel.resultRow( index.row() ).get<0>();
track_ids.push_back(track.id());
track_ids.push_back(id);
}
LMS_LOG(MOD_UI, SEV_DEBUG) << "Getting all selected tracks DONE...";
LMS_LOG(MOD_UI, SEV_DEBUG) << "Getting all selected tracks: " << track_ids.size();
}
std::size_t
@@ -144,7 +144,8 @@ int
TrackView::getFirstSelectedTrackPosition(void)
{
Wt::WModelIndexSet indexSet = this->selectedIndexes();
BOOST_FOREACH(Wt::WModelIndex index, indexSet)
for (Wt::WModelIndex index : indexSet)
{
if (!index.isValid())
continue;
@@ -160,14 +161,16 @@ TrackView::getTracks(std::vector<Database::Track::id_type>& trackIds)
{
LMS_LOG(MOD_UI, SEV_DEBUG) << "Getting all tracks...";
for (int i = 0; i < _queryModel.rowCount(); ++i)
{
Database::Track::pointer track = _queryModel.resultRow(i);
Wt::Dbo::Transaction transaction(DboSession());
Wt::Dbo::collection<Database::Track::UIQueryResult> results = _queryModel.query();
trackIds.push_back(track.id());
for (auto it = results.begin(); it != results.end(); ++it)
{
Database::Track::id_type id = it->get<0>();
trackIds.push_back(id);
}
LMS_LOG(MOD_UI, SEV_DEBUG) << "Getting all tracks done!";
LMS_LOG(MOD_UI, SEV_DEBUG) << "Getting all tracks done! " << trackIds.size() << " tracks!";
}
} // namespace Desktop
+1 -1
View File
@@ -62,7 +62,7 @@ class TrackView : public Wt::WTableView, public Filter
SigTrackDoubleClicked _sigTrackDoubleClicked;
typedef Database::Track::pointer ResultType;
typedef Database::Track::UIQueryResult ResultType;
Wt::Dbo::QueryModel< ResultType > _queryModel;
Wt::WTableView* _tableView;