[WIP] Added Artist/ReleaseInfo
This commit is contained in:
+25
-25
@@ -31,33 +31,33 @@
|
||||
#include <Wt/Auth/Identity.h>
|
||||
|
||||
#include "config/config.h"
|
||||
#include "cover/CoverArtGrabber.hpp"
|
||||
#include "database/Artist.hpp"
|
||||
#include "database/Cluster.hpp"
|
||||
#include "database/Release.hpp"
|
||||
#include "explore/Explore.hpp"
|
||||
#include "main/Services.hpp"
|
||||
#include "utils/Logger.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
|
||||
#include "explore/Explore.hpp"
|
||||
#include "MediaPlayer.hpp"
|
||||
#include "PlayHistoryView.hpp"
|
||||
#include "PlayQueueView.hpp"
|
||||
#include "SettingsView.hpp"
|
||||
|
||||
#include "admin/InitWizardView.hpp"
|
||||
#include "admin/DatabaseSettingsView.hpp"
|
||||
#include "admin/UserView.hpp"
|
||||
#include "admin/UsersView.hpp"
|
||||
|
||||
#include "resource/ImageResource.hpp"
|
||||
#include "resource/AudioResource.hpp"
|
||||
#include "MediaPlayer.hpp"
|
||||
#include "PlayHistoryView.hpp"
|
||||
#include "PlayQueueView.hpp"
|
||||
#include "SettingsView.hpp"
|
||||
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
std::unique_ptr<Wt::WApplication>
|
||||
LmsApplication::create(const Wt::WEnvironment& env, Wt::Dbo::SqlConnectionPool& connectionPool, LmsApplicationGroupContainer& appGroups, Scanner::MediaScanner& scanner)
|
||||
LmsApplication::create(const Wt::WEnvironment& env, Wt::Dbo::SqlConnectionPool& connectionPool, LmsApplicationGroupContainer& appGroups)
|
||||
{
|
||||
/*
|
||||
* You could read information from the environment to decide whether
|
||||
* the user has permission to start a new application
|
||||
*/
|
||||
return std::make_unique<LmsApplication>(env, connectionPool, appGroups, scanner);
|
||||
return std::make_unique<LmsApplication>(env, connectionPool, appGroups);
|
||||
}
|
||||
|
||||
LmsApplication*
|
||||
@@ -66,19 +66,12 @@ LmsApplication::instance()
|
||||
return reinterpret_cast<LmsApplication*>(Wt::WApplication::instance());
|
||||
}
|
||||
|
||||
/*
|
||||
* The env argument contains information about the new session, and
|
||||
* the initial request. It must be passed to the Wt::WApplication
|
||||
* constructor so it is typically also an argument for your custom
|
||||
* application constructor.
|
||||
*/
|
||||
LmsApplication::LmsApplication(const Wt::WEnvironment& env, Wt::Dbo::SqlConnectionPool& connectionPool, LmsApplicationGroupContainer& appGroups, Scanner::MediaScanner& scanner)
|
||||
LmsApplication::LmsApplication(const Wt::WEnvironment& env,
|
||||
Wt::Dbo::SqlConnectionPool& connectionPool,
|
||||
LmsApplicationGroupContainer& appGroups)
|
||||
: Wt::WApplication(env),
|
||||
_db(connectionPool),
|
||||
_appGroups(appGroups),
|
||||
_scanner(scanner),
|
||||
_imageResource(nullptr),
|
||||
_audioResource(nullptr)
|
||||
_appGroups(appGroups)
|
||||
{
|
||||
auto bootstrapTheme = std::make_unique<Wt::WBootstrapTheme>();
|
||||
bootstrapTheme->setVersion(Wt::BootstrapVersion::v3);
|
||||
@@ -96,6 +89,8 @@ LmsApplication::LmsApplication(const Wt::WEnvironment& env, Wt::Dbo::SqlConnecti
|
||||
messageResourceBundle().use(appRoot() + "admin-users");
|
||||
messageResourceBundle().use(appRoot() + "admin-initwizard");
|
||||
messageResourceBundle().use(appRoot() + "artist");
|
||||
messageResourceBundle().use(appRoot() + "artistinfo");
|
||||
messageResourceBundle().use(appRoot() + "artistlink");
|
||||
messageResourceBundle().use(appRoot() + "artists");
|
||||
messageResourceBundle().use(appRoot() + "artistsinfo");
|
||||
messageResourceBundle().use(appRoot() + "explore");
|
||||
@@ -105,6 +100,8 @@ LmsApplication::LmsApplication(const Wt::WEnvironment& env, Wt::Dbo::SqlConnecti
|
||||
messageResourceBundle().use(appRoot() + "playqueue");
|
||||
messageResourceBundle().use(appRoot() + "playhistory");
|
||||
messageResourceBundle().use(appRoot() + "release");
|
||||
messageResourceBundle().use(appRoot() + "releaseinfo");
|
||||
messageResourceBundle().use(appRoot() + "releaselink");
|
||||
messageResourceBundle().use(appRoot() + "releases");
|
||||
messageResourceBundle().use(appRoot() + "releasesinfo");
|
||||
messageResourceBundle().use(appRoot() + "settings");
|
||||
@@ -112,6 +109,9 @@ LmsApplication::LmsApplication(const Wt::WEnvironment& env, Wt::Dbo::SqlConnecti
|
||||
messageResourceBundle().use(appRoot() + "tracks");
|
||||
messageResourceBundle().use(appRoot() + "tracksinfo");
|
||||
|
||||
// hack since Server does not expose the docRoot
|
||||
getServices().coverArtGrabber->setDefaultCover(Wt::WApplication::instance()->docRoot() + "/images/unknown-cover.jpg");
|
||||
|
||||
// Require js here to avoid async problems
|
||||
requireJQuery("/js/jquery-1.10.2.min.js");
|
||||
require("/js/mediaplayer.js");
|
||||
@@ -462,7 +462,7 @@ LmsApplication::createHome()
|
||||
|
||||
// Events from MediaScanner
|
||||
std::string sessionId = LmsApp->sessionId();
|
||||
_scanner.scanComplete().connect([=] (Scanner::MediaScanner::Stats stats)
|
||||
getServices().mediaScanner->scanComplete().connect([=] (Scanner::MediaScanner::Stats stats)
|
||||
{
|
||||
// Runs from media scanner context
|
||||
Wt::WServer::instance()->post(sessionId, [=]
|
||||
|
||||
+17
-16
@@ -20,25 +20,29 @@
|
||||
#ifndef LMS_APPLICATION_HPP
|
||||
#define LMS_APPLICATION_HPP
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <Wt/WApplication.h>
|
||||
#include <Wt/Dbo/SqlConnectionPool.h>
|
||||
|
||||
#include "database/DatabaseHandler.hpp"
|
||||
#include "scanner/MediaScanner.hpp"
|
||||
|
||||
#include "database/Artist.hpp"
|
||||
#include "database/Cluster.hpp"
|
||||
#include "database/Release.hpp"
|
||||
|
||||
#include "LmsApplicationGroup.hpp"
|
||||
#include "Auth.hpp"
|
||||
|
||||
namespace Database {
|
||||
class Artist;
|
||||
class Cluster;
|
||||
class Release;
|
||||
}
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
class AudioResource;
|
||||
class ImageResource;
|
||||
|
||||
// Events that can be listen to anywhere in the application
|
||||
// Events that can be listen from anywhere in the application
|
||||
struct Events
|
||||
{
|
||||
// Events relative to group
|
||||
@@ -67,10 +71,10 @@ enum class MsgType
|
||||
class LmsApplication : public Wt::WApplication
|
||||
{
|
||||
public:
|
||||
LmsApplication(const Wt::WEnvironment& env, Wt::Dbo::SqlConnectionPool& connectionPool, LmsApplicationGroupContainer& appGroups, Scanner::MediaScanner& scanner);
|
||||
LmsApplication(const Wt::WEnvironment& env, Wt::Dbo::SqlConnectionPool& connectionPool, LmsApplicationGroupContainer& appGroups);
|
||||
|
||||
static std::unique_ptr<Wt::WApplication> create(const Wt::WEnvironment& env,
|
||||
Wt::Dbo::SqlConnectionPool& connectionPool, LmsApplicationGroupContainer& appGroups, Scanner::MediaScanner& scanner);
|
||||
Wt::Dbo::SqlConnectionPool& connectionPool, LmsApplicationGroupContainer& appGroups);
|
||||
static LmsApplication* instance();
|
||||
|
||||
// Session application data
|
||||
@@ -83,8 +87,6 @@ class LmsApplication : public Wt::WApplication
|
||||
Database::User::pointer getUser() { return _db.getCurrentUser(); }
|
||||
Wt::WString getUserIdentity() { return _userIdentity; }
|
||||
|
||||
Scanner::MediaScanner& getMediaScanner() { return _scanner; }
|
||||
|
||||
Events& getEvents() { return _events; }
|
||||
|
||||
// Utils
|
||||
@@ -94,11 +96,11 @@ class LmsApplication : public Wt::WApplication
|
||||
void post(std::function<void()> func);
|
||||
void notifyMsg(MsgType type, const Wt::WString& message, std::chrono::milliseconds duration = std::chrono::milliseconds(4000));
|
||||
|
||||
static Wt::WLink createArtistLink(Database::Artist::pointer artist);
|
||||
static std::unique_ptr<Wt::WAnchor> createArtistAnchor(Database::Artist::pointer artist, bool addText = true);
|
||||
static Wt::WLink createReleaseLink(Database::Release::pointer release);
|
||||
static std::unique_ptr<Wt::WAnchor> createReleaseAnchor(Database::Release::pointer release, bool addText = true);
|
||||
static std::unique_ptr<Wt::WTemplate> createCluster(Database::Cluster::pointer cluster, bool canDelete = false);
|
||||
static Wt::WLink createArtistLink(Wt::Dbo::ptr<Database::Artist> artist);
|
||||
static std::unique_ptr<Wt::WAnchor> createArtistAnchor(Wt::Dbo::ptr<Database::Artist> artist, bool addText = true);
|
||||
static Wt::WLink createReleaseLink(Wt::Dbo::ptr<Database::Release> release);
|
||||
static std::unique_ptr<Wt::WAnchor> createReleaseAnchor(Wt::Dbo::ptr<Database::Release> release, bool addText = true);
|
||||
static std::unique_ptr<Wt::WTemplate> createCluster(Wt::Dbo::ptr<Database::Cluster> cluster, bool canDelete = false);
|
||||
|
||||
// Signal emitted just before the session ends (user may already be logged out)
|
||||
Wt::Signal<>& preQuit() { return _preQuit; }
|
||||
@@ -119,8 +121,7 @@ class LmsApplication : public Wt::WApplication
|
||||
LmsApplicationGroupContainer& _appGroups;
|
||||
Events _events;
|
||||
Wt::WString _userIdentity;
|
||||
Auth* _auth;
|
||||
Scanner::MediaScanner& _scanner;
|
||||
Auth* _auth = nullptr;
|
||||
std::shared_ptr<ImageResource> _imageResource;
|
||||
std::shared_ptr<AudioResource> _audioResource;
|
||||
bool _isAdmin = false;
|
||||
|
||||
@@ -22,9 +22,10 @@
|
||||
#include "av/AvInfo.hpp"
|
||||
#include "utils/Logger.hpp"
|
||||
|
||||
#include "database/Artist.hpp"
|
||||
#include "database/Release.hpp"
|
||||
#include "database/Track.hpp"
|
||||
|
||||
|
||||
#include "resource/ImageResource.hpp"
|
||||
#include "resource/AudioResource.hpp"
|
||||
|
||||
|
||||
+14
-36
@@ -19,15 +19,12 @@
|
||||
|
||||
#include "PlayQueueView.hpp"
|
||||
|
||||
#include <random>
|
||||
|
||||
#include <Wt/WAnchor.h>
|
||||
#include <Wt/WText.h>
|
||||
|
||||
#include "utils/Logger.hpp"
|
||||
|
||||
#include "database/TrackList.hpp"
|
||||
|
||||
#include "main/Services.hpp"
|
||||
#include "similarity/SimilaritySearcher.hpp"
|
||||
#include "utils/Logger.hpp"
|
||||
#include "LmsApplication.hpp"
|
||||
|
||||
namespace UserInterface {
|
||||
@@ -385,45 +382,26 @@ PlayQueue::addSome()
|
||||
void
|
||||
PlayQueue::addRadioTrack()
|
||||
{
|
||||
auto now = std::chrono::system_clock::now();
|
||||
std::mt19937 randGenerator(std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count());
|
||||
|
||||
auto tracklist = getTrackList();
|
||||
|
||||
std::set<Database::IdType> trackIds;
|
||||
{
|
||||
auto ids = tracklist->getTrackIds();
|
||||
trackIds = std::set<Database::IdType>(ids.begin(), ids.end());
|
||||
}
|
||||
|
||||
// Get all the tracks of the tracklist, get the cluster that is mostly used
|
||||
// and reuse it to get the next track
|
||||
auto clusters = tracklist->getClusters();
|
||||
if (clusters.empty())
|
||||
std::vector<Database::IdType> trackIds = getTrackList()->getTrackIds();
|
||||
if (trackIds.empty())
|
||||
return;
|
||||
|
||||
for (auto cluster : clusters)
|
||||
auto res = getServices().similaritySearcher->getSimilarTracks(trackIds, 1);
|
||||
for (auto trackId : res)
|
||||
{
|
||||
std::set<Database::IdType> clusterTrackIds = cluster->getTrackIds();
|
||||
|
||||
std::set<Database::IdType> candidateTrackIds;
|
||||
std::set_difference(clusterTrackIds.begin(), clusterTrackIds.end(),
|
||||
trackIds.begin(), trackIds.end(),
|
||||
std::inserter(candidateTrackIds, candidateTrackIds.end()));
|
||||
|
||||
if (candidateTrackIds.empty())
|
||||
continue;
|
||||
|
||||
std::uniform_int_distribution<int> dist(0, candidateTrackIds.size() - 1);
|
||||
|
||||
auto trackToAdd = Database::Track::getById(LmsApp->getDboSession(), *std::next(candidateTrackIds.begin(), dist(randGenerator)));
|
||||
auto trackToAdd = Database::Track::getById(LmsApp->getDboSession(), trackId);
|
||||
enqueueTrack(trackToAdd);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
LMS_LOG(UI, INFO) << "No more track to be added!";
|
||||
}
|
||||
|
||||
void addRadioTrackFromSimilarity(std::shared_ptr<Similarity::Searcher> similaritySearcher)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // namespace UserInterface
|
||||
|
||||
|
||||
@@ -31,6 +31,11 @@
|
||||
#include "database/TrackList.hpp"
|
||||
#include "database/Track.hpp"
|
||||
|
||||
namespace Similarity
|
||||
{
|
||||
class Finder;
|
||||
}
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
class PlayQueue : public Wt::WTemplate
|
||||
@@ -69,6 +74,9 @@ class PlayQueue : public Wt::WTemplate
|
||||
void load(std::size_t pos, bool play);
|
||||
void stop();
|
||||
|
||||
void addRadioTrackFromSimilarity(std::shared_ptr<Similarity::Finder> similarityFinder);
|
||||
void addRadioTrackFromClusters();
|
||||
|
||||
bool _repeatAll = false;
|
||||
bool _radioMode = false;
|
||||
boost::optional<Database::IdType> _tracklistId;
|
||||
|
||||
@@ -19,19 +19,20 @@
|
||||
|
||||
#include "DatabaseSettingsView.hpp"
|
||||
|
||||
#include <Wt/WString.h>
|
||||
#include <Wt/WPushButton.h>
|
||||
#include <Wt/WComboBox.h>
|
||||
#include <Wt/WFormModel.h>
|
||||
#include <Wt/WLineEdit.h>
|
||||
#include <Wt/WPushButton.h>
|
||||
#include <Wt/WString.h>
|
||||
#include <Wt/WStringListModel.h>
|
||||
#include <Wt/WTemplateFormView.h>
|
||||
|
||||
#include <Wt/WFormModel.h>
|
||||
#include <Wt/WStringListModel.h>
|
||||
|
||||
#include "common/Validators.hpp"
|
||||
#include "database/Cluster.hpp"
|
||||
#include "main/Services.hpp"
|
||||
#include "utils/Logger.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
|
||||
#include "common/Validators.hpp"
|
||||
#include "LmsApplication.hpp"
|
||||
|
||||
namespace UserInterface {
|
||||
@@ -287,7 +288,7 @@ DatabaseSettingsView::refreshView()
|
||||
{
|
||||
model->saveData();
|
||||
|
||||
LmsApp->getMediaScanner().reschedule();
|
||||
getServices().mediaScanner->reschedule();
|
||||
LmsApp->notifyMsg(MsgType::Success, Wt::WString::tr("Lms.Admin.Database.settings-saved"));
|
||||
}
|
||||
|
||||
@@ -304,7 +305,7 @@ DatabaseSettingsView::refreshView()
|
||||
|
||||
immScanBtn->clicked().connect([=] ()
|
||||
{
|
||||
LmsApp->getMediaScanner().scheduleImmediateScan();
|
||||
getServices().mediaScanner->scheduleImmediateScan();
|
||||
LmsApp->notifyMsg(MsgType::Info, Wt::WString::tr("Lms.Admin.Database.scan-launched"));
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 "ArtistInfoView.hpp"
|
||||
|
||||
#include "database/Artist.hpp"
|
||||
#include "main/Services.hpp"
|
||||
#include "similarity/SimilaritySearcher.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
|
||||
#include "ArtistLink.hpp"
|
||||
#include "LmsApplication.hpp"
|
||||
|
||||
using namespace Database;
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
ArtistInfo::ArtistInfo()
|
||||
: Wt::WTemplate(Wt::WString::tr("Lms.Explore.ArtistInfo.template"))
|
||||
{
|
||||
addFunction("tr", &Wt::WTemplate::Functions::tr);
|
||||
|
||||
_similarArtistsContainer = bindNew<Wt::WContainerWidget>("similar-artists");
|
||||
|
||||
wApp->internalPathChanged().connect(std::bind([=]
|
||||
{
|
||||
refresh();
|
||||
}));
|
||||
|
||||
LmsApp->getEvents().dbScanned.connect([=]
|
||||
{
|
||||
refresh();
|
||||
});
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
void
|
||||
ArtistInfo::refresh()
|
||||
{
|
||||
_similarArtistsContainer->clear();
|
||||
|
||||
if (!wApp->internalPathMatches("/artist/"))
|
||||
return;
|
||||
|
||||
auto artistId = readAs<Database::IdType>(wApp->internalPathNextPart("/artist/"));
|
||||
if (!artistId)
|
||||
return;
|
||||
|
||||
auto artistsIds = getServices().similaritySearcher->getSimilarArtists(LmsApp->getDboSession(), *artistId, 5);
|
||||
|
||||
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
|
||||
|
||||
std::vector<Database::Artist::pointer> artists;
|
||||
for (auto artistId : artistsIds)
|
||||
{
|
||||
auto artist = Database::Artist::getById(LmsApp->getDboSession(), artistId);
|
||||
|
||||
if (artist)
|
||||
artists.push_back(artist);
|
||||
}
|
||||
|
||||
for (auto artist : artists)
|
||||
_similarArtistsContainer->addNew<ArtistLink>(artist);
|
||||
}
|
||||
|
||||
} // namespace UserInterface
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Wt/WContainerWidget.h>
|
||||
#include <Wt/WTemplate.h>
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
class ArtistInfo : public Wt::WTemplate
|
||||
{
|
||||
public:
|
||||
ArtistInfo();
|
||||
|
||||
private:
|
||||
void refresh();
|
||||
|
||||
Wt::WContainerWidget* _similarArtistsContainer;
|
||||
};
|
||||
|
||||
} // namespace UserInterface
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 "ArtistLink.hpp"
|
||||
|
||||
#include <Wt/WAnchor.h>
|
||||
|
||||
#include "database/Artist.hpp"
|
||||
#include "LmsApplication.hpp"
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
ArtistLink::ArtistLink(Database::Artist::pointer artist)
|
||||
: Wt::WTemplate(Wt::WString::tr("Lms.Explore.ArtistLink.template"))
|
||||
{
|
||||
bindWidget("name", LmsApplication::createArtistAnchor(artist));
|
||||
}
|
||||
|
||||
} // namespace UserInterface
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Wt/WTemplate.h>
|
||||
|
||||
namespace Database{
|
||||
class Artist;
|
||||
}
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
class ArtistLink : public Wt::WTemplate
|
||||
{
|
||||
public:
|
||||
ArtistLink(Wt::Dbo::ptr<Database::Artist> artist);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <Wt/WText.h>
|
||||
|
||||
#include "database/Artist.hpp"
|
||||
#include "database/Release.hpp"
|
||||
|
||||
#include "utils/Logger.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
|
||||
@@ -19,34 +19,16 @@
|
||||
|
||||
#include "ArtistsInfoView.hpp"
|
||||
|
||||
#include <Wt/WAnchor.h>
|
||||
#include <Wt/WLocalDateTime.h>
|
||||
|
||||
#include "database/Artist.hpp"
|
||||
#include "database/TrackList.hpp"
|
||||
|
||||
#include "utils/Utils.hpp"
|
||||
|
||||
#include "ArtistLink.hpp"
|
||||
#include "LmsApplication.hpp"
|
||||
|
||||
using namespace Database;
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace UserInterface;
|
||||
|
||||
void addEntries(Wt::WContainerWidget *container, const std::vector<Artist::pointer>& artists)
|
||||
{
|
||||
for (auto artist : artists)
|
||||
{
|
||||
Wt::WTemplate* entry = container->addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Explore.ArtistsInfo.template.entry"));
|
||||
|
||||
entry->bindWidget("name", LmsApplication::createArtistAnchor(artist));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
ArtistsInfo::ArtistsInfo()
|
||||
@@ -80,7 +62,8 @@ ArtistsInfo::refreshRecentlyAdded()
|
||||
auto artists = Artist::getLastAdded(LmsApp->getDboSession(), after, 5);
|
||||
|
||||
_recentlyAddedContainer->clear();
|
||||
addEntries(_recentlyAddedContainer, artists);
|
||||
for (auto artist : artists)
|
||||
_recentlyAddedContainer->addNew<ArtistLink>(artist);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -90,7 +73,8 @@ ArtistsInfo::refreshMostPlayed()
|
||||
auto artists = LmsApp->getUser()->getPlayedTrackList()->getTopArtists(5);
|
||||
|
||||
_mostPlayedContainer->clear();
|
||||
addEntries(_mostPlayedContainer, artists);
|
||||
for (auto artist : artists)
|
||||
_mostPlayedContainer->addNew<ArtistLink>(artist);
|
||||
}
|
||||
|
||||
} // namespace UserInterface
|
||||
|
||||
@@ -23,14 +23,18 @@
|
||||
#include <Wt/WTemplate.h>
|
||||
#include <Wt/WText.h>
|
||||
|
||||
#include "database/Artist.hpp"
|
||||
#include "database/Release.hpp"
|
||||
#include "utils/Logger.hpp"
|
||||
|
||||
#include "LmsApplication.hpp"
|
||||
|
||||
#include "ArtistInfoView.hpp"
|
||||
#include "ArtistsInfoView.hpp"
|
||||
#include "ArtistsView.hpp"
|
||||
#include "ArtistView.hpp"
|
||||
#include "Filters.hpp"
|
||||
#include "ReleaseInfoView.hpp"
|
||||
#include "ReleasesInfoView.hpp"
|
||||
#include "ReleasesView.hpp"
|
||||
#include "ReleaseView.hpp"
|
||||
@@ -79,7 +83,9 @@ handleInfoPathChange(Wt::WStackedWidget* stack)
|
||||
{
|
||||
enum Idx
|
||||
{
|
||||
IdxArtists = 0,
|
||||
IdxArtist = 0,
|
||||
IdxArtists,
|
||||
IdxRelease,
|
||||
IdxReleases,
|
||||
IdxTracks,
|
||||
};
|
||||
@@ -87,9 +93,9 @@ handleInfoPathChange(Wt::WStackedWidget* stack)
|
||||
static const std::map<std::string, int> indexes =
|
||||
{
|
||||
{ "/artists", IdxArtists },
|
||||
{ "/artist", IdxArtists },
|
||||
{ "/artist", IdxArtist },
|
||||
{ "/releases", IdxReleases },
|
||||
{ "/release", IdxReleases },
|
||||
{ "/release", IdxRelease },
|
||||
{ "/tracks", IdxTracks },
|
||||
};
|
||||
|
||||
@@ -151,9 +157,15 @@ Explore::Explore()
|
||||
// Info
|
||||
Wt::WStackedWidget* infoStack = bindNew<Wt::WStackedWidget>("info");
|
||||
|
||||
auto artistInfo = std::make_unique<ArtistInfo>();
|
||||
infoStack->addWidget(std::move(artistInfo));
|
||||
|
||||
auto artistsInfo = std::make_unique<ArtistsInfo>();
|
||||
infoStack->addWidget(std::move(artistsInfo));
|
||||
|
||||
auto releaseInfo = std::make_unique<ReleaseInfo>();
|
||||
infoStack->addWidget(std::move(releaseInfo));
|
||||
|
||||
auto releasesInfo = std::make_unique<ReleasesInfo>();
|
||||
infoStack->addWidget(std::move(releasesInfo));
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include <Wt/WPushButton.h>
|
||||
#include <Wt/WTemplate.h>
|
||||
|
||||
#include "database/Cluster.hpp"
|
||||
|
||||
#include "LmsApplication.hpp"
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 "ReleaseInfoView.hpp"
|
||||
|
||||
#include "database/Release.hpp"
|
||||
#include "main/Services.hpp"
|
||||
#include "similarity/SimilaritySearcher.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
|
||||
#include "ReleaseLink.hpp"
|
||||
#include "LmsApplication.hpp"
|
||||
|
||||
using namespace Database;
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
ReleaseInfo::ReleaseInfo()
|
||||
: Wt::WTemplate(Wt::WString::tr("Lms.Explore.ReleaseInfo.template"))
|
||||
{
|
||||
addFunction("tr", &Wt::WTemplate::Functions::tr);
|
||||
|
||||
_similarReleasesContainer = bindNew<Wt::WContainerWidget>("similar-releases");
|
||||
|
||||
wApp->internalPathChanged().connect(std::bind([=]
|
||||
{
|
||||
refresh();
|
||||
}));
|
||||
|
||||
LmsApp->getEvents().dbScanned.connect([=]
|
||||
{
|
||||
refresh();
|
||||
});
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
void
|
||||
ReleaseInfo::refresh()
|
||||
{
|
||||
_similarReleasesContainer->clear();
|
||||
|
||||
if (!wApp->internalPathMatches("/release/"))
|
||||
return;
|
||||
|
||||
auto releaseId = readAs<Database::IdType>(wApp->internalPathNextPart("/release/"));
|
||||
if (!releaseId)
|
||||
return;
|
||||
|
||||
auto releasesIds = getServices().similaritySearcher->getSimilarReleases(LmsApp->getDboSession(), *releaseId, 5);
|
||||
|
||||
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
|
||||
|
||||
std::vector<Database::Release::pointer> releases;
|
||||
for (auto releaseId : releasesIds)
|
||||
{
|
||||
auto release = Database::Release::getById(LmsApp->getDboSession(), releaseId);
|
||||
|
||||
if (release)
|
||||
releases.push_back(release);
|
||||
}
|
||||
|
||||
for (auto release : releases)
|
||||
_similarReleasesContainer->addNew<ReleaseLink>(release);
|
||||
}
|
||||
|
||||
} // namespace UserInterface
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Wt/WContainerWidget.h>
|
||||
#include <Wt/WTemplate.h>
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
class ReleaseInfo : public Wt::WTemplate
|
||||
{
|
||||
public:
|
||||
ReleaseInfo();
|
||||
|
||||
private:
|
||||
void refresh();
|
||||
|
||||
Wt::WContainerWidget* _similarReleasesContainer;
|
||||
};
|
||||
|
||||
} // namespace UserInterface
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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 "ReleaseLink.hpp"
|
||||
|
||||
#include <Wt/WAnchor.h>
|
||||
#include <Wt/WImage.h>
|
||||
|
||||
#include "database/Release.hpp"
|
||||
#include "resource/ImageResource.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
|
||||
#include "LmsApplication.hpp"
|
||||
|
||||
using namespace Database;
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
ReleaseLink::ReleaseLink(Database::Release::pointer release)
|
||||
: Wt::WTemplate(Wt::WString::tr("Lms.Explore.ReleaseLink.template"))
|
||||
{
|
||||
bindWidget("release-name", LmsApplication::createReleaseAnchor(release));
|
||||
|
||||
Wt::WAnchor* anchor = bindWidget("cover", LmsApplication::createReleaseAnchor(release, false));
|
||||
auto cover = std::make_unique<Wt::WImage>();
|
||||
cover->setImageLink(LmsApp->getImageResource()->getReleaseUrl(release.id(), 48));
|
||||
cover->setWidth(48);
|
||||
anchor->setImage(std::move(cover));
|
||||
|
||||
auto artists = release->getArtists();
|
||||
if (artists.size() > 1)
|
||||
{
|
||||
setCondition("if-has-artist", true);
|
||||
bindString("artist-name", Wt::WString::tr("Lms.Explore.various-artists"));
|
||||
}
|
||||
else if (artists.size() == 1)
|
||||
{
|
||||
setCondition("if-has-artist", true);
|
||||
bindWidget("artist-name", LmsApplication::createArtistAnchor(artists.front()));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace UserInterface
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Wt/WTemplate.h>
|
||||
|
||||
namespace Database {
|
||||
class Release;
|
||||
}
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
class ReleaseLink : public Wt::WTemplate
|
||||
{
|
||||
public:
|
||||
ReleaseLink(Wt::Dbo::ptr<Database::Release>);
|
||||
};
|
||||
|
||||
} // namespace UserInterface
|
||||
|
||||
@@ -19,54 +19,16 @@
|
||||
|
||||
#include "ReleasesInfoView.hpp"
|
||||
|
||||
#include <Wt/WAnchor.h>
|
||||
#include <Wt/WImage.h>
|
||||
#include <Wt/WLocalDateTime.h>
|
||||
#include <Wt/WTemplate.h>
|
||||
|
||||
#include "database/Release.hpp"
|
||||
#include "database/TrackList.hpp"
|
||||
|
||||
#include "resource/ImageResource.hpp"
|
||||
|
||||
#include "ReleaseLink.hpp"
|
||||
#include "LmsApplication.hpp"
|
||||
|
||||
using namespace Database;
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace UserInterface;
|
||||
|
||||
void addEntries(Wt::WContainerWidget* container, const std::vector<Release::pointer>& releases)
|
||||
{
|
||||
for (auto release : releases)
|
||||
{
|
||||
Wt::WTemplate* entry = container->addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Explore.ReleasesInfo.template.entry"));
|
||||
|
||||
entry->bindWidget("release-name", LmsApplication::createReleaseAnchor(release));
|
||||
|
||||
Wt::WAnchor* anchor = entry->bindWidget("cover", LmsApplication::createReleaseAnchor(release, false));
|
||||
auto cover = std::make_unique<Wt::WImage>();
|
||||
cover->setImageLink(LmsApp->getImageResource()->getReleaseUrl(release.id(), 48));
|
||||
cover->setWidth(48);
|
||||
anchor->setImage(std::move(cover));
|
||||
|
||||
auto artists = release->getArtists();
|
||||
if (artists.size() > 1)
|
||||
{
|
||||
entry->setCondition("if-has-artist", true);
|
||||
entry->bindString("artist-name", Wt::WString::tr("Lms.Explore.various-artists"));
|
||||
}
|
||||
else if (artists.size() == 1)
|
||||
{
|
||||
entry->setCondition("if-has-artist", true);
|
||||
entry->bindWidget("artist-name", LmsApplication::createArtistAnchor(artists.front()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
ReleasesInfo::ReleasesInfo()
|
||||
@@ -101,7 +63,8 @@ ReleasesInfo::refreshRecentlyAdded()
|
||||
auto releases = Release::getLastAdded(LmsApp->getDboSession(), after, 5);
|
||||
|
||||
_recentlyAddedContainer->clear();
|
||||
addEntries(_recentlyAddedContainer, releases);
|
||||
for (auto release : releases)
|
||||
_recentlyAddedContainer->addNew<ReleaseLink>(release);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -112,7 +75,8 @@ ReleasesInfo::refreshMostPlayed()
|
||||
auto releases = LmsApp->getUser()->getPlayedTrackList()->getTopReleases(5);
|
||||
|
||||
_mostPlayedContainer->clear();
|
||||
addEntries(_mostPlayedContainer, releases);
|
||||
for (auto release : releases)
|
||||
_mostPlayedContainer->addNew<ReleaseLink>(release);
|
||||
}
|
||||
|
||||
} // namespace UserInterface
|
||||
|
||||
@@ -22,16 +22,15 @@
|
||||
#include <Wt/WApplication.h>
|
||||
#include <Wt/Http/Response.h>
|
||||
|
||||
#include "cover/CoverArtGrabber.hpp"
|
||||
#include "database/Track.hpp"
|
||||
#include "main/Services.hpp"
|
||||
#include "utils/Exception.hpp"
|
||||
#include "utils/Logger.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
|
||||
#include "database/Track.hpp"
|
||||
|
||||
#include "LmsApplication.hpp"
|
||||
|
||||
#include "cover/CoverArtGrabber.hpp"
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
static const std::string unknownCoverPath = "/images/unknown-cover.jpg";
|
||||
@@ -81,7 +80,7 @@ ImageResource::handleRequest(const Wt::Http::Request& request, Wt::Http::Respons
|
||||
// transactions are not thread safe
|
||||
{
|
||||
Wt::WApplication::UpdateLock lock(LmsApp);
|
||||
cover = CoverArt::Grabber::instance().getFromTrack(LmsApp->getDboSession(), *trackId, Image::Format::JPEG, *size);
|
||||
cover = getServices().coverArtGrabber->getFromTrack(LmsApp->getDboSession(), *trackId, Image::Format::JPEG, *size);
|
||||
}
|
||||
}
|
||||
else if (releaseIdStr)
|
||||
@@ -93,7 +92,7 @@ ImageResource::handleRequest(const Wt::Http::Request& request, Wt::Http::Respons
|
||||
// transactions are not thread safe
|
||||
{
|
||||
Wt::WApplication::UpdateLock lock(LmsApp);
|
||||
cover = CoverArt::Grabber::instance().getFromRelease(LmsApp->getDboSession(), *releaseId, Image::Format::JPEG, *size);
|
||||
cover = getServices().coverArtGrabber->getFromRelease(LmsApp->getDboSession(), *releaseId, Image::Format::JPEG, *size);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user