finished updating song functionality
This commit is contained in:
@@ -14,15 +14,16 @@ namespace manager
|
|||||||
CoverArtManager(const std::string&);
|
CoverArtManager(const std::string&);
|
||||||
CoverArtManager(const model::BinaryPath& bConf);
|
CoverArtManager(const model::BinaryPath& bConf);
|
||||||
|
|
||||||
model::Cover saveCover(const model::Song&, std::string&,
|
model::Cover saveCover(const model::Song&);
|
||||||
const std::string&);
|
|
||||||
|
|
||||||
std::pair<bool, std::string> defaultCover(const model::Cover&);
|
std::pair<bool, std::string> defaultCover(const model::Cover&);
|
||||||
|
|
||||||
void deleteCover(const model::Song&);
|
void deleteCover(const model::Song&);
|
||||||
void updateCover(const model::Song&);
|
void updateCover(const model::Song&, const model::Song&);
|
||||||
void updateCoverRecord(const model::Song&);
|
void updateCoverRecord(const model::Song&);
|
||||||
private:
|
private:
|
||||||
|
std::string createImagePath(const model::Song&);
|
||||||
|
|
||||||
model::BinaryPath m_bConf;
|
model::BinaryPath m_bConf;
|
||||||
std::string path;
|
std::string path;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -33,12 +33,15 @@ namespace manager
|
|||||||
private:
|
private:
|
||||||
std::map<type::SongChanged, bool> changesInSong(const model::Song&, const model::Song&);
|
std::map<type::SongChanged, bool> changesInSong(const model::Song&, const model::Song&);
|
||||||
|
|
||||||
|
std::string createSongPath(const model::Song&);
|
||||||
|
|
||||||
void assignMiscId(model::Song&, const model::Song&);
|
void assignMiscId(model::Song&, const model::Song&);
|
||||||
void assignMiscFields(std::map<type::SongChanged, bool>&, model::Song&,
|
void assignMiscFields(std::map<type::SongChanged, bool>&, model::Song&,
|
||||||
const model::Song&);
|
const model::Song&);
|
||||||
void saveSongTemp(model::Song&);
|
void saveSongTemp(model::Song&);
|
||||||
void saveMisc(model::Song&);
|
void saveMisc(model::Song&);
|
||||||
void deleteMisc(const model::Song&);
|
void deleteMisc(const model::Song&);
|
||||||
|
void deleteMiscExceptCoverArt(const model::Song&);
|
||||||
void updateMisc(const std::map<type::SongChanged, bool>&,
|
void updateMisc(const std::map<type::SongChanged, bool>&,
|
||||||
model::Song&, const model::Song&);
|
model::Song&, const model::Song&);
|
||||||
void modifySongOnFilesystem(model::Song&, const model::Song&);
|
void modifySongOnFilesystem(model::Song&, const model::Song&);
|
||||||
|
|||||||
@@ -12,7 +12,12 @@ namespace utility
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
model::Song retrieveMetadata(std::string&);
|
model::Song retrieveMetadata(std::string&);
|
||||||
|
|
||||||
model::Cover updateCoverArt(const model::Song&, model::Cover&, const std::string&);
|
model::Cover updateCoverArt(const model::Song&, model::Cover&, const std::string&);
|
||||||
|
model::Cover applyStockCoverArt(const model::Song&, model::Cover&, const std::string&);
|
||||||
|
model::Cover applyCoverArt(const model::Song&, model::Cover&);
|
||||||
|
|
||||||
|
bool songContainsCoverArt(const model::Song&);
|
||||||
|
|
||||||
void updateMetadata(model::Song&, const model::Song&);
|
void updateMetadata(model::Song&, const model::Song&);
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -18,14 +18,24 @@ manager::CoverArtManager::CoverArtManager(const model::BinaryPath& bConf) : m_bC
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
model::Cover manager::CoverArtManager::saveCover(const model::Song& song, std::string& rootPath, const std::string& stockCoverPath)
|
model::Cover manager::CoverArtManager::saveCover(const model::Song& song)
|
||||||
{
|
{
|
||||||
|
auto pathConfigContent = manager::DirectoryManager::pathConfigContent(m_bConf);
|
||||||
|
auto stockCoverPath = manager::DirectoryManager::configPath(m_bConf);
|
||||||
|
stockCoverPath.append("/CoverArt.png");
|
||||||
|
|
||||||
utility::MetadataRetriever meta;
|
utility::MetadataRetriever meta;
|
||||||
model::Cover cov;
|
model::Cover cov;
|
||||||
cov.imagePath = rootPath;
|
|
||||||
cov = meta.updateCoverArt(song, cov, stockCoverPath);
|
|
||||||
cov.songTitle = song.title;
|
cov.songTitle = song.title;
|
||||||
|
|
||||||
|
if (meta.songContainsCoverArt(song)) {
|
||||||
|
cov.imagePath = createImagePath(song);
|
||||||
|
cov = meta.applyCoverArt(song, cov);
|
||||||
|
} else {
|
||||||
|
cov.imagePath = pathConfigContent["cover_root_path"].get<std::string>();
|
||||||
|
cov = meta.applyStockCoverArt(song, cov, stockCoverPath);
|
||||||
|
}
|
||||||
|
|
||||||
database::CoverArtRepository covRepo(m_bConf);
|
database::CoverArtRepository covRepo(m_bConf);
|
||||||
if (!covRepo.doesCoverArtExist(cov, type::CoverFilter::songTitle)) {
|
if (!covRepo.doesCoverArtExist(cov, type::CoverFilter::songTitle)) {
|
||||||
std::cout << "saving image record to the database" << std::endl;
|
std::cout << "saving image record to the database" << std::endl;
|
||||||
@@ -76,12 +86,14 @@ void manager::CoverArtManager::deleteCover(const model::Song& song)
|
|||||||
const auto coverArtPath = result.second;
|
const auto coverArtPath = result.second;
|
||||||
} else {
|
} else {
|
||||||
std::cout << "song contains the stock cover art, will not delete" << std::endl;
|
std::cout << "song contains the stock cover art, will not delete" << std::endl;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
manager::DirectoryManager::deleteDirectories(song, result.second);
|
manager::DirectoryManager::deleteDirectories(song, result.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
void manager::CoverArtManager::updateCover(const model::Song& updatedSong)
|
void manager::CoverArtManager::updateCover(const model::Song& updatedSong,
|
||||||
|
const model::Song& currSong)
|
||||||
{
|
{
|
||||||
database::CoverArtRepository covRepo(m_bConf);
|
database::CoverArtRepository covRepo(m_bConf);
|
||||||
model::Cover cover(updatedSong.coverArtId);
|
model::Cover cover(updatedSong.coverArtId);
|
||||||
@@ -93,30 +105,38 @@ void manager::CoverArtManager::updateCover(const model::Song& updatedSong)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto imagePath = manager::DirectoryManager::createDirectoryProcess(
|
auto imagePath = createImagePath(updatedSong);
|
||||||
updatedSong, m_bConf, type::PathType::coverArt);
|
|
||||||
imagePath.append(updatedSong.title);
|
|
||||||
imagePath.append(".png");
|
|
||||||
|
|
||||||
if (cover.imagePath.find(".png") == std::string::npos) {
|
|
||||||
std::cout << "no file extension on image path" << std::endl;
|
|
||||||
cover.imagePath.append(".png");
|
|
||||||
}
|
|
||||||
|
|
||||||
fs::copy(cover.imagePath, imagePath);
|
fs::copy(cover.imagePath, imagePath);
|
||||||
fs::remove(cover.imagePath);
|
fs::remove(cover.imagePath);
|
||||||
|
|
||||||
|
manager::DirectoryManager::deleteDirectories(currSong, result.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
void manager::CoverArtManager::updateCoverRecord(const model::Song& updatedSong)
|
void manager::CoverArtManager::updateCoverRecord(const model::Song& updatedSong)
|
||||||
{
|
{
|
||||||
model::Cover updatedCover(updatedSong);
|
model::Cover updatedCover(updatedSong);
|
||||||
auto updatedImagePath = manager::DirectoryManager::createDirectoryProcess(
|
auto updatedImagePath = createImagePath(updatedSong);
|
||||||
updatedSong, m_bConf, type::PathType::coverArt);
|
|
||||||
updatedImagePath.append(updatedSong.title);
|
|
||||||
|
|
||||||
updatedCover.imagePath = std::move(updatedImagePath);
|
|
||||||
updatedCover.imagePath.append(".png");
|
|
||||||
|
|
||||||
database::CoverArtRepository covRepo(m_bConf);
|
database::CoverArtRepository covRepo(m_bConf);
|
||||||
covRepo.updateRecord(updatedCover);
|
covRepo.updateRecord(updatedCover);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string manager::CoverArtManager::createImagePath(const model::Song& song)
|
||||||
|
{
|
||||||
|
auto imagePath = manager::DirectoryManager::createDirectoryProcess(
|
||||||
|
song, m_bConf, type::PathType::coverArt);
|
||||||
|
|
||||||
|
if (song.track != 0) {
|
||||||
|
imagePath.append("track");
|
||||||
|
auto trackNum = (song.track > 9) ?
|
||||||
|
std::to_string(song.track) : "0" + std::to_string(song.track);
|
||||||
|
imagePath.append(trackNum);
|
||||||
|
} else {
|
||||||
|
imagePath.append(song.title);
|
||||||
|
}
|
||||||
|
imagePath.append(".png");
|
||||||
|
|
||||||
|
return imagePath;
|
||||||
|
}
|
||||||
|
|||||||
+53
-15
@@ -157,6 +157,7 @@ model::Song manager::SongManager::songDtoConv(dto::SongDto::ObjectWrapper& songD
|
|||||||
return song;
|
return song;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void manager::SongManager::printSong(const model::Song& song)
|
void manager::SongManager::printSong(const model::Song& song)
|
||||||
{
|
{
|
||||||
std::cout << "\nsong" << std::endl;
|
std::cout << "\nsong" << std::endl;
|
||||||
@@ -210,12 +211,32 @@ std::map<type::SongChanged, bool> manager::SongManager::changesInSong(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string manager::SongManager::createSongPath(const model::Song& song)
|
||||||
|
{
|
||||||
|
auto songPath = manager::DirectoryManager::createDirectoryProcess(
|
||||||
|
song, m_bConf, type::PathType::music);
|
||||||
|
|
||||||
|
if (song.track != 0) {
|
||||||
|
songPath.append("track");
|
||||||
|
auto trackNum = (song.track > 9) ?
|
||||||
|
std::to_string(song.track) : "0" + std::to_string(song.track);
|
||||||
|
songPath.append(trackNum);
|
||||||
|
} else {
|
||||||
|
songPath.append(song.title);
|
||||||
|
}
|
||||||
|
songPath.append(".mp3");
|
||||||
|
|
||||||
|
return songPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// used to prevent empty values to appear in the updated song
|
// used to prevent empty values to appear in the updated song
|
||||||
void manager::SongManager::assignMiscFields(
|
void manager::SongManager::assignMiscFields(
|
||||||
std::map<type::SongChanged, bool>& songChanges, model::Song& updatedSong,
|
std::map<type::SongChanged, bool>& songChanges, model::Song& updatedSong,
|
||||||
const model::Song& currSong)
|
const model::Song& currSong)
|
||||||
{
|
{
|
||||||
std::cout << "assigning miscellanes fields to updated song" << std::endl;
|
std::cout << "assigning miscellanes fields to updated song" << std::endl;
|
||||||
|
updatedSong.track = currSong.track;
|
||||||
for (auto scIter = songChanges.begin(); scIter != songChanges.end(); ++scIter) {
|
for (auto scIter = songChanges.begin(); scIter != songChanges.end(); ++scIter) {
|
||||||
type::SongChanged key = scIter->first;
|
type::SongChanged key = scIter->first;
|
||||||
bool changed = songChanges.at(key);
|
bool changed = songChanges.at(key);
|
||||||
@@ -260,6 +281,7 @@ void manager::SongManager::assignMiscId(model::Song& updatedSong,
|
|||||||
updatedSong.coverArtId = currSong.coverArtId;
|
updatedSong.coverArtId = currSong.coverArtId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// saves song to a temporary path
|
||||||
void manager::SongManager::saveSongTemp(model::Song& song)
|
void manager::SongManager::saveSongTemp(model::Song& song)
|
||||||
{
|
{
|
||||||
auto config = manager::DirectoryManager::pathConfigContent(m_bConf);
|
auto config = manager::DirectoryManager::pathConfigContent(m_bConf);
|
||||||
@@ -283,25 +305,22 @@ void manager::SongManager::saveMisc(model::Song& song)
|
|||||||
{
|
{
|
||||||
CoverArtManager covMgr(m_bConf);
|
CoverArtManager covMgr(m_bConf);
|
||||||
auto pathConfigContent = manager::DirectoryManager::pathConfigContent(m_bConf);
|
auto pathConfigContent = manager::DirectoryManager::pathConfigContent(m_bConf);
|
||||||
auto coverRootPath = pathConfigContent["cover_root_path"].get<std::string>();
|
|
||||||
auto musicRootPath = pathConfigContent["root_music_path"].get<std::string>();
|
auto musicRootPath = pathConfigContent["root_music_path"].get<std::string>();
|
||||||
|
|
||||||
auto stockCoverPath = manager::DirectoryManager::configPath(m_bConf);
|
auto cov = covMgr.saveCover(song);
|
||||||
stockCoverPath.append("/CoverArt.png");
|
|
||||||
|
|
||||||
auto cov = covMgr.saveCover(song, coverRootPath, stockCoverPath);
|
auto songPath = createSongPath(song);
|
||||||
|
|
||||||
auto songPath = manager::DirectoryManager::createDirectoryProcess(song, musicRootPath);
|
|
||||||
songPath.append(song.title);
|
|
||||||
songPath.append(".mp3");
|
|
||||||
if (fs::exists(songPath)) {
|
if (fs::exists(songPath)) {
|
||||||
std::cout << "deleting old song with the same metadata" << std::endl;
|
std::cout << "deleting old song with the same metadata" << std::endl;
|
||||||
fs::remove(songPath);
|
fs::remove(songPath);
|
||||||
}
|
}
|
||||||
std::cout << "copying song to the appropriate directory" << std::endl;
|
std::cout << "copying song to the appropriate directory" << std::endl;
|
||||||
|
std::cout << song.songPath << std::endl;
|
||||||
|
std::cout << songPath << std::endl;
|
||||||
fs::copy(song.songPath, songPath);
|
fs::copy(song.songPath, songPath);
|
||||||
fs::remove(song.songPath);
|
fs::remove(song.songPath);
|
||||||
song.songPath = std::move(songPath);
|
song.songPath = std::move(songPath);
|
||||||
|
std::cout << "copied song to the appropriate directory" << std::endl;
|
||||||
|
|
||||||
AlbumManager albMgr(m_bConf);
|
AlbumManager albMgr(m_bConf);
|
||||||
auto album = albMgr.saveAlbum(song);
|
auto album = albMgr.saveAlbum(song);
|
||||||
@@ -311,7 +330,6 @@ void manager::SongManager::saveMisc(model::Song& song)
|
|||||||
ArtistManager artMgr(m_bConf);
|
ArtistManager artMgr(m_bConf);
|
||||||
auto artist = artMgr.saveArtist(song);
|
auto artist = artMgr.saveArtist(song);
|
||||||
artist = artMgr.retrieveArtist(artist);
|
artist = artMgr.retrieveArtist(artist);
|
||||||
std::cout << "out" << std::endl;
|
|
||||||
manager::ArtistManager::printArtist(artist);
|
manager::ArtistManager::printArtist(artist);
|
||||||
|
|
||||||
GenreManager gnrMgr(m_bConf);
|
GenreManager gnrMgr(m_bConf);
|
||||||
@@ -351,6 +369,22 @@ void manager::SongManager::deleteMisc(const model::Song& song)
|
|||||||
yrMgr.deleteYear(song);
|
yrMgr.deleteYear(song);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deletes miscellanes records
|
||||||
|
void manager::SongManager::deleteMiscExceptCoverArt(const model::Song& song)
|
||||||
|
{
|
||||||
|
manager::AlbumManager albMgr(m_bConf);
|
||||||
|
albMgr.deleteAlbum(song);
|
||||||
|
|
||||||
|
manager::ArtistManager artMgr(m_bConf);
|
||||||
|
artMgr.deleteArtist(song);
|
||||||
|
|
||||||
|
manager::GenreManager gnrMgr(m_bConf);
|
||||||
|
gnrMgr.deleteGenre(song);
|
||||||
|
|
||||||
|
manager::YearManager yrMgr(m_bConf);
|
||||||
|
yrMgr.deleteYear(song);
|
||||||
|
}
|
||||||
|
|
||||||
void manager::SongManager::updateMisc(
|
void manager::SongManager::updateMisc(
|
||||||
const std::map<type::SongChanged, bool>& songChanges,
|
const std::map<type::SongChanged, bool>& songChanges,
|
||||||
model::Song& updatedSong, const model::Song& currSong)
|
model::Song& updatedSong, const model::Song& currSong)
|
||||||
@@ -386,17 +420,15 @@ void manager::SongManager::updateMisc(
|
|||||||
|
|
||||||
database::SongRepository songRepo(m_bConf);
|
database::SongRepository songRepo(m_bConf);
|
||||||
songRepo.updateRecord(updatedSong);
|
songRepo.updateRecord(updatedSong);
|
||||||
|
|
||||||
|
deleteMiscExceptCoverArt(currSong);
|
||||||
}
|
}
|
||||||
|
|
||||||
void manager::SongManager::modifySongOnFilesystem(model::Song& updatedSong,
|
void manager::SongManager::modifySongOnFilesystem(model::Song& updatedSong,
|
||||||
const model::Song& currSong)
|
const model::Song& currSong)
|
||||||
{
|
{
|
||||||
std::cout << "preparing to modify song" << std::endl;
|
std::cout << "preparing to modify song" << std::endl;
|
||||||
printSong(updatedSong);
|
auto songPath = createSongPath(updatedSong);
|
||||||
auto songPath = manager::DirectoryManager::createDirectoryProcess(
|
|
||||||
updatedSong, m_bConf, type::PathType::music);
|
|
||||||
songPath.append(updatedSong.title);
|
|
||||||
songPath.append(".mp3");
|
|
||||||
updatedSong.songPath = std::move(songPath);
|
updatedSong.songPath = std::move(songPath);
|
||||||
|
|
||||||
std::cout << "new path " << updatedSong.songPath << std::endl;
|
std::cout << "new path " << updatedSong.songPath << std::endl;
|
||||||
@@ -404,6 +436,12 @@ void manager::SongManager::modifySongOnFilesystem(model::Song& updatedSong,
|
|||||||
fs::copy(currSong.songPath, updatedSong.songPath);
|
fs::copy(currSong.songPath, updatedSong.songPath);
|
||||||
fs::remove(currSong.songPath);
|
fs::remove(currSong.songPath);
|
||||||
|
|
||||||
|
auto paths = manager::DirectoryManager::pathConfigContent(m_bConf);
|
||||||
|
const auto musicRootPath =
|
||||||
|
paths[manager::DirectoryManager::retrievePathType(
|
||||||
|
type::PathType::music)].get<std::string>();
|
||||||
|
manager::DirectoryManager::deleteDirectories(currSong, musicRootPath);
|
||||||
|
|
||||||
manager::CoverArtManager covMgr(m_bConf);
|
manager::CoverArtManager covMgr(m_bConf);
|
||||||
covMgr.updateCover(updatedSong);
|
covMgr.updateCover(updatedSong, currSong);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,6 +92,64 @@ model::Cover utility::MetadataRetriever::updateCoverArt(const model::Song& song,
|
|||||||
return cov;
|
return cov;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tags song with the stock cover art
|
||||||
|
model::Cover utility::MetadataRetriever::applyStockCoverArt(
|
||||||
|
const model::Song& song, model::Cover& cov,
|
||||||
|
const std::string& stockCoverPath)
|
||||||
|
{
|
||||||
|
TagLib::MPEG::File songFile(song.songPath.c_str());
|
||||||
|
auto tag = songFile.ID3v2Tag();
|
||||||
|
|
||||||
|
utility::ImageFile stockImg(cov.imagePath.c_str());
|
||||||
|
TagLib::ID3v2::AttachedPictureFrame *pic =
|
||||||
|
new TagLib::ID3v2::AttachedPictureFrame;
|
||||||
|
|
||||||
|
pic->setPicture(stockImg.data());
|
||||||
|
pic->setType(TagLib::ID3v2::AttachedPictureFrame::FrontCover);
|
||||||
|
|
||||||
|
tag->addFrame(pic);
|
||||||
|
|
||||||
|
songFile.save();
|
||||||
|
std::cout << "applied stock cover art" << std::endl;
|
||||||
|
|
||||||
|
delete pic;
|
||||||
|
|
||||||
|
return cov;
|
||||||
|
}
|
||||||
|
|
||||||
|
// extracts cover art from the song and save it to the
|
||||||
|
// appropriate directory
|
||||||
|
model::Cover utility::MetadataRetriever::applyCoverArt(const model::Song& song,
|
||||||
|
model::Cover& cov)
|
||||||
|
{
|
||||||
|
TagLib::MPEG::File songFile(song.songPath.c_str());
|
||||||
|
auto tag = songFile.ID3v2Tag();
|
||||||
|
auto frameList = tag->frameListMap()["APIC"];
|
||||||
|
|
||||||
|
auto frame = dynamic_cast<TagLib::ID3v2::AttachedPictureFrame*>(
|
||||||
|
frameList.front());
|
||||||
|
|
||||||
|
std::fstream imgSave(cov.imagePath, std::ios::out |
|
||||||
|
std::ios::binary);
|
||||||
|
imgSave.write(frame->picture().data(), frame->picture().size());
|
||||||
|
imgSave.close();
|
||||||
|
|
||||||
|
std::cout << "saved to " << cov.imagePath << std::endl;
|
||||||
|
|
||||||
|
return cov;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool utility::MetadataRetriever::songContainsCoverArt(const model::Song& song)
|
||||||
|
{
|
||||||
|
TagLib::MPEG::File songFile(song.songPath.c_str());
|
||||||
|
auto tag = songFile.ID3v2Tag();
|
||||||
|
auto frameList = tag->frameListMap()["APIC"];
|
||||||
|
|
||||||
|
return !frameList.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void utility::MetadataRetriever::updateMetadata(model::Song& sngUpdated, const model::Song& sngOld)
|
void utility::MetadataRetriever::updateMetadata(model::Song& sngUpdated, const model::Song& sngOld)
|
||||||
{
|
{
|
||||||
std::cout<<"updating metadata"<<std::endl;
|
std::cout<<"updating metadata"<<std::endl;
|
||||||
|
|||||||
Reference in New Issue
Block a user