From f5f61361590257394d2f67d1990601e783f7a06e Mon Sep 17 00:00:00 2001 From: emeric Date: Fri, 21 Sep 2018 14:00:15 +0200 Subject: [PATCH] Add copyright/copyrightURL support and display it in the release view --- approot/messages.xml | 3 +++ approot/release.xml | 7 ++++++ src/av/AvTranscoder.hpp | 4 ++-- src/cover/CoverArtGrabber.cpp | 7 +++--- src/database/Release.cpp | 44 +++++++++++++++++++++++++++++++++- src/database/Release.hpp | 2 ++ src/database/Track.cpp | 12 ++++++++++ src/database/Track.hpp | 26 +++++++++++--------- src/metadata/MetaData.hpp | 2 ++ src/metadata/TagLibParser.cpp | 8 +++++++ src/scanner/MediaScanner.cpp | 13 +++++++++- src/ui/explore/ReleaseView.cpp | 22 +++++++++++++++++ tools/metadata/LmsMetadata.cpp | 8 +++++++ 13 files changed, 139 insertions(+), 19 deletions(-) diff --git a/approot/messages.xml b/approot/messages.xml index 5a606c24..cc421dab 100644 --- a/approot/messages.xml +++ b/approot/messages.xml @@ -79,6 +79,9 @@ Recently added Top artists + +Copyright + Recently added Top releases diff --git a/approot/release.xml b/approot/release.xml index 51b9bc9d..ea9191ec 100644 --- a/approot/release.xml +++ b/approot/release.xml @@ -16,6 +16,13 @@ ${play-btn}${add-btn} ${tracks} + ${} + + ${}${copyright}${} + ${}${copyright-url}${} + ${} diff --git a/src/av/AvTranscoder.hpp b/src/av/AvTranscoder.hpp index 40df78fe..c91ac9c5 100644 --- a/src/av/AvTranscoder.hpp +++ b/src/av/AvTranscoder.hpp @@ -48,9 +48,9 @@ struct TranscodeParameters Encoding encoding = Encoding::MP3; std::size_t bitrate = 128000; boost::optional stream = boost::none; // Id of the stream to be transcoded (auto detect by default) - boost::optional offset; + boost::optional offset = boost::none;; - TranscodeParameters() {} + TranscodeParameters() = default; }; class Transcoder diff --git a/src/cover/CoverArtGrabber.cpp b/src/cover/CoverArtGrabber.cpp index ce688492..96732e46 100644 --- a/src/cover/CoverArtGrabber.cpp +++ b/src/cover/CoverArtGrabber.cpp @@ -178,15 +178,14 @@ Grabber::getFromTrack(Wt::Dbo::Session& session, Database::IdType trackId, std:: Track::pointer track = Track::getById(session, trackId); if (track) { - Track::CoverType coverType = track->getCoverType(); + bool hasCover = track->hasCover(); boost::filesystem::path trackPath = track->getPath(); transaction.commit(); - if (coverType == Track::CoverType::Embedded) + if (hasCover) cover = getFromTrack(trackPath); - - if (!cover) + else cover = getFromDirectory(trackPath.parent_path()); } } diff --git a/src/database/Release.cpp b/src/database/Release.cpp index 7cabd1d8..6ca6cebb 100644 --- a/src/database/Release.cpp +++ b/src/database/Release.cpp @@ -19,6 +19,8 @@ #include "Release.hpp" +#include "utils/Logger.hpp" + #include "Artist.hpp" #include "Cluster.hpp" #include "SqlQuery.hpp" @@ -163,7 +165,7 @@ Release::getReleaseYear(bool original) const .groupBy(field) .bind(this->id()); - /* various dates, no date */ + // various dates => no date if (dates.empty() || dates.size() > 1) return boost::none; @@ -175,6 +177,46 @@ Release::getReleaseYear(bool original) const return boost::none; } +boost::optional +Release::getCopyright() const +{ + assert(session()); + + Wt::Dbo::collection copyrights = session()->query + ("SELECT copyright FROM track t INNER JOIN release r ON r.id = t.release_id") + .where("r.id = ?") + .groupBy("copyright") + .bind(this->id()); + + std::vector values(copyrights.begin(), copyrights.end()); + + // various copyrights => no copyright + if (values.empty() || values.size() > 1 || values.front().empty()) + return boost::none; + + return values.front(); +} + +boost::optional +Release::getCopyrightURL() const +{ + assert(session()); + + Wt::Dbo::collection copyrights = session()->query + ("SELECT copyright_url FROM track t INNER JOIN release r ON r.id = t.release_id") + .where("r.id = ?") + .groupBy("copyright_url") + .bind(this->id()); + + std::vector values(copyrights.begin(), copyrights.end()); + + // various copyright URLs => no copyright URL + if (values.empty() || values.size() > 1 || values.front().empty()) + return boost::none; + + return values.front(); +} + std::vector> Release::getArtists() const { diff --git a/src/database/Release.hpp b/src/database/Release.hpp index 1122314a..86584919 100644 --- a/src/database/Release.hpp +++ b/src/database/Release.hpp @@ -69,6 +69,8 @@ class Release : public Wt::Dbo::Dbo // Utility functions boost::optional getReleaseYear(bool originalDate = false) const; // 0 if unknown or various + boost::optional getCopyright() const; + boost::optional getCopyrightURL() const; // Accessors std::string getName() const { return _name; } diff --git a/src/database/Track.cpp b/src/database/Track.cpp index d7535afe..6729fd24 100644 --- a/src/database/Track.cpp +++ b/src/database/Track.cpp @@ -224,6 +224,18 @@ Track::getOriginalYear() const return (_originalYear > 0) ? boost::make_optional(_originalYear) : boost::none; } +boost::optional +Track::getCopyright() const +{ + return _copyright != "" ? boost::make_optional(_copyright) : boost::none; +} + +boost::optional +Track::getCopyrightURL() const +{ + return _copyrightURL != "" ? boost::make_optional(_copyrightURL) : boost::none; +} + std::vector> Track::getClusterGroups(std::vector clusterTypes, std::size_t size) const { diff --git a/src/database/Track.hpp b/src/database/Track.hpp index 334ce2d9..33bc30f5 100644 --- a/src/database/Track.hpp +++ b/src/database/Track.hpp @@ -49,12 +49,6 @@ class Track : public Wt::Dbo::Dbo Track() {} Track(const boost::filesystem::path& p); - enum class CoverType - { - Embedded, // Contains embedded cover - None, // No local cover available - }; - // Find utility functions static pointer getByPath(Wt::Dbo::Session& session, const boost::filesystem::path& p); static pointer getById(Wt::Dbo::Session& session, IdType id); @@ -95,8 +89,10 @@ class Track : public Wt::Dbo::Dbo void setYear(int year) { _year = year; } void setOriginalYear(int year) { _originalYear = year; } void setGenres(const std::string& genreList) { _genreList = genreList; } - void setCoverType(CoverType coverType) { _coverType = coverType; } + void setHasCover(bool hasCover) { _hasCover = hasCover; } void setMBID(const std::string& MBID) { _MBID = MBID; } + void setCopyright(const std::string& copyright) { _copyright = std::string(copyright, 0, _maxCopyrightLength); } + void setCopyrightURL(const std::string& copyrightURL) { _copyrightURL = std::string(copyrightURL, 0, _maxCopyrightURLLength); } void setArtist(Wt::Dbo::ptr artist) { _artist = artist; } void setRelease(Wt::Dbo::ptr release) { _release = release; } @@ -113,8 +109,10 @@ class Track : public Wt::Dbo::Dbo Wt::WDateTime getLastWriteTime() const { return _fileLastWrite; } Wt::WDateTime getAddedTime() const { return _fileAdded; } const std::vector& getChecksum() const { return _fileChecksum; } - CoverType getCoverType() const { return _coverType; } + bool hasCover() const { return _hasCover; } const std::string& getMBID() const { return _MBID; } + boost::optional getCopyright() const; + boost::optional getCopyrightURL() const; Wt::Dbo::ptr getArtist() const { return _artist; } Wt::Dbo::ptr getRelease() const { return _release; } std::vector> getClusters() const; @@ -138,8 +136,10 @@ class Track : public Wt::Dbo::Dbo Wt::Dbo::field(a, _fileLastWrite, "file_last_write"); Wt::Dbo::field(a, _fileAdded, "file_added"); Wt::Dbo::field(a, _fileChecksum, "checksum"); - Wt::Dbo::field(a, _coverType, "cover_type"); + Wt::Dbo::field(a, _hasCover, "has_cover"); Wt::Dbo::field(a, _MBID, "mbid"); + Wt::Dbo::field(a, _copyright, "copyright"); + Wt::Dbo::field(a, _copyrightURL, "copyright_url"); Wt::Dbo::belongsTo(a, _release, "release", Wt::Dbo::OnDeleteCascade); Wt::Dbo::belongsTo(a, _artist, "artist", Wt::Dbo::OnDeleteCascade); Wt::Dbo::hasMany(a, _clusters, Wt::Dbo::ManyToMany, "track_cluster", "", Wt::Dbo::OnDeleteCascade); @@ -149,6 +149,8 @@ class Track : public Wt::Dbo::Dbo private: static const std::size_t _maxNameLength = 128; + static const std::size_t _maxCopyrightLength = 128; + static const std::size_t _maxCopyrightURLLength = 128; int _scanVersion = 0; int _trackNumber = 0; @@ -166,8 +168,10 @@ class Track : public Wt::Dbo::Dbo std::vector _fileChecksum; Wt::WDateTime _fileLastWrite; Wt::WDateTime _fileAdded; - CoverType _coverType = CoverType::None; - std::string _MBID = ""; // Musicbrainz Identifier + bool _hasCover; + std::string _MBID; // Musicbrainz Identifier + std::string _copyright; + std::string _copyrightURL; Wt::Dbo::ptr _artist; Wt::Dbo::ptr _release; diff --git a/src/metadata/MetaData.hpp b/src/metadata/MetaData.hpp index 9cef1e80..46192deb 100644 --- a/src/metadata/MetaData.hpp +++ b/src/metadata/MetaData.hpp @@ -50,6 +50,8 @@ namespace MetaData MusicBrainzTrackID, // string MusicBrainzRecordingID, // string AcoustID, // string + Copyright, // string + CopyrightURL, // string }; // Used by Streams diff --git a/src/metadata/TagLibParser.cpp b/src/metadata/TagLibParser.cpp index 47440e47..f916c8ab 100644 --- a/src/metadata/TagLibParser.cpp +++ b/src/metadata/TagLibParser.cpp @@ -194,6 +194,14 @@ TagLibParser::parse(const boost::filesystem::path& p, bool debug) if (items.find(MetaData::Type::HasCover) == items.end()) items.insert( std::make_pair(MetaData::Type::HasCover, true)); } + else if (tag == "COPYRIGHT") + { + items.insert(std::make_pair(MetaData::Type::Copyright, values.front().to8Bit())); + } + else if (tag == "COPYRIGHTURL") + { + items.insert(std::make_pair(MetaData::Type::CopyrightURL, values.front().to8Bit())); + } else if (_clusterTypeNames.find(tag) != _clusterTypeNames.end()) { std::set clusterNames; diff --git a/src/scanner/MediaScanner.cpp b/src/scanner/MediaScanner.cpp index 229295d3..fa6bac8f 100644 --- a/src/scanner/MediaScanner.cpp +++ b/src/scanner/MediaScanner.cpp @@ -566,7 +566,18 @@ MediaScanner::scanAudioFile(const boost::filesystem::path& file, bool forceScan, { bool hasCover = boost::any_cast((*items)[MetaData::Type::HasCover]); - track.modify()->setCoverType( hasCover ? Track::CoverType::Embedded : Track::CoverType::None ); + track.modify()->setHasCover(hasCover); + } + + if ((*items).find(MetaData::Type::Copyright) != (*items).end()) + { + + track.modify()->setCopyright( boost::any_cast((*items)[MetaData::Type::Copyright]) ); + } + + if ((*items).find(MetaData::Type::CopyrightURL) != (*items).end()) + { + track.modify()->setCopyrightURL( boost::any_cast((*items)[MetaData::Type::CopyrightURL]) ); } transaction.commit(); diff --git a/src/ui/explore/ReleaseView.cpp b/src/ui/explore/ReleaseView.cpp index f6b4015f..f03ff4a0 100644 --- a/src/ui/explore/ReleaseView.cpp +++ b/src/ui/explore/ReleaseView.cpp @@ -94,6 +94,28 @@ Release::refresh() } } + boost::optional copyright = release->getCopyright(); + boost::optional copyrightURL = release->getCopyrightURL(); + + t->setCondition("if-has-copyright-or-copyright-url", copyright || copyrightURL); + + if (copyrightURL) + { + t->setCondition("if-has-copyright-url", true); + + Wt::WLink link(*copyrightURL); + link.setTarget(Wt::LinkTarget::NewWindow); + Wt::WAnchor* anchor = t->bindNew("copyright-url", link); + anchor->setTextFormat(Wt::TextFormat::Plain); + anchor->setText(Wt::WString::fromUTF8(*copyrightURL)); + } + + if (copyright) + { + t->setCondition("if-has-copyright", true); + t->bindString("copyright", Wt::WString::fromUTF8(*copyright), Wt::TextFormat::Plain); + } + { auto artists = release->getArtists(); if (artists.size() > 1) diff --git a/tools/metadata/LmsMetadata.cpp b/tools/metadata/LmsMetadata.cpp index 2bab33e2..6afd04ba 100644 --- a/tools/metadata/LmsMetadata.cpp +++ b/tools/metadata/LmsMetadata.cpp @@ -112,6 +112,14 @@ int main(int argc, char *argv[]) std::cout << "AcoustID: " << boost::any_cast(item.second) << std::endl; break; + case MetaData::Type::Copyright: + std::cout << "Copyright: " << boost::any_cast(item.second) << std::endl; + break; + + case MetaData::Type::CopyrightURL: + std::cout << "CopyrightURL: " << boost::any_cast(item.second) << std::endl; + break; + default: break; }