#include "albumsmodel.h" #include "db/collectionDB.h" #include "utils/brain.h" #include AlbumsModel::AlbumsModel(QObject *parent) : BaseList(parent) { this->db = CollectionDB::getInstance(); connect(this, &AlbumsModel::queryChanged, this, &AlbumsModel::setList); } AlbumsModel::~AlbumsModel() {} FMH::MODEL_LIST AlbumsModel::items() const { return this->list; } void AlbumsModel::setQuery(const QUERY &query) { if(this->query == query) return; this->query = query; emit this->queryChanged(); } AlbumsModel::QUERY AlbumsModel::getQuery() const { return this->query; } void AlbumsModel::setSortBy(const SORTBY &sort) { if(this->sort == sort) return; this->sort = sort; emit this->preListChanged(); this->sortList(); emit this->postListChanged(); emit this->sortByChanged(); } AlbumsModel::SORTBY AlbumsModel::getSortBy() const { return this->sort; } void AlbumsModel::sortList() { const auto key = static_cast(this->sort); qDebug()<< "SORTING LIST BY"<< this->sort; std::sort(this->list.begin(), this->list.end(), [key](const FMH::MODEL &e1, const FMH::MODEL &e2) -> bool { const auto role = key; switch(role) { case FMH::MODEL_KEY::RELEASEDATE: { if(e1[role].toDouble() > e2[role].toDouble()) return true; break; } case FMH::MODEL_KEY::ADDDATE: { const auto date1 = QDateTime::fromString(e1[role], Qt::TextDate); const auto date2 = QDateTime::fromString(e2[role], Qt::TextDate); if(date1.secsTo(QDateTime::currentDateTime()) < date2.secsTo(QDateTime::currentDateTime())) return true; break; } case FMH::MODEL_KEY::ARTIST: case FMH::MODEL_KEY::ALBUM: { const auto str1 = QString(e1[role]).toLower(); const auto str2 = QString(e2[role]).toLower(); if(str1 < str2) return true; break; } default: if(e1[role] < e2[role]) return true; } return false; }); } void AlbumsModel::setList() { emit this->preListChanged(); QString m_Query; if(this->query == AlbumsModel::QUERY::ALBUMS) m_Query = "select * from albums order by album asc"; else if(this->query == AlbumsModel::QUERY::ARTISTS) m_Query = "select * from artists order by artist asc"; //get albums data with modifier for missing images for artworks this->list = this->db->getDBData(m_Query, [&](FMH::MODEL &item) { if(!item[FMH::MODEL_KEY::ARTWORK].isEmpty() && !FMH::fileExists(item[FMH::MODEL_KEY::ARTWORK])) { this->db->removeArtwork(FMH::MODEL_NAME[static_cast(this->query)], FM::toMap(item)); item[FMH::MODEL_KEY::ARTWORK] = ""; } }); this->sortList(); emit this->postListChanged(); } void AlbumsModel::fetchInformation() { qDebug() << "RNUNGING BRAIN EFFORRTS"; QFutureWatcher *watcher = new QFutureWatcher; QObject::connect(watcher, &QFutureWatcher::finished, watcher, &QFutureWatcher::deleteLater); // QObject::connect(this, &AlbumsModel::destroyed, watcher, &QFutureWatcher::waitForFinished); auto func = [&, stop = bool()]() mutable { stop = false; QList requests; int index = -1; for(auto album : this->list) { index++; if(!album[FMH::MODEL_KEY::ARTWORK].isEmpty()) continue; if(BAE::artworkCache(album, FMH::MODEL_KEY::ALBUM)) { this->db->insertArtwork(album); emit this->updateModel(index, {FMH::MODEL_KEY::ARTWORK}); continue; } PULPO::REQUEST request; request.track = album; request.ontology = this->query == AlbumsModel::QUERY::ALBUMS ? PULPO::ONTOLOGY::ALBUM : PULPO::ONTOLOGY::ARTIST; request.services = {PULPO::SERVICES::LastFm, PULPO::SERVICES::Spotify, PULPO::SERVICES::MusicBrainz}; request.info = {PULPO::INFO::ARTWORK}; request.callback = [&, index](PULPO::REQUEST request, PULPO::RESPONSES responses) { qDebug() << "DONE WITH " << request.track ; for(const auto &res : responses) { if(res.context == PULPO::CONTEXT::IMAGE && !res.value.toString().isEmpty()) { qDebug()<<"SAVING ARTWORK FOR: " << request.track[FMH::MODEL_KEY::ALBUM]; auto downloader = new FMH::Downloader; QObject::connect(downloader, &FMH::Downloader::fileSaved, [&, index, request, downloader = std::move(downloader)](QString path) { qDebug()<< "Saving artwork file to" << path; FMH::MODEL newTrack = request.track; newTrack[FMH::MODEL_KEY::ARTWORK] = path; this->db->insertArtwork(newTrack); this->updateArtwork(index, path); downloader->deleteLater(); }); QStringList filePathList = res.value.toString().split('/'); const auto format = "." + filePathList.at(filePathList.count() - 1).split(".").last(); QString name = !request.track[FMH::MODEL_KEY::ALBUM].isEmpty() ? request.track[FMH::MODEL_KEY::ARTIST] + "_" + request.track[FMH::MODEL_KEY::ALBUM] : request.track[FMH::MODEL_KEY::ARTIST]; name.replace("/", "-"); name.replace("&", "-"); downloader->setFile(res.value.toString(), BAE::CachePath + name + format); } } }; requests << request; } Pulpo pulpo; QEventLoop loop; QObject::connect(&pulpo, &Pulpo::finished, &loop, &QEventLoop::quit); QObject::connect(this, &AlbumsModel::destroyed, [&stop]() { qDebug()<< stop << &stop; stop = true; qDebug()<< stop << &stop; }); for(const auto &req : requests) { pulpo.request(req); if(stop) { qDebug()<< "TRYING EXITING THREAD LOADINFO" << loop.isRunning(); if(loop.isRunning()) loop.quit(); qDebug()<< "EXITING THREAD LOADINFO" << loop.isRunning(); break; }else { loop.exec(); } } }; QFuture t1 = QtConcurrent::run(func); watcher->setFuture(t1); } void AlbumsModel::updateArtwork(const int index, const QString &artwork) { if(index >= this->list.size() || index < 0) return; this->list[index][FMH::MODEL_KEY::ARTWORK] = artwork; emit this->updateModel(index, {FMH::MODEL_KEY::ARTWORK}); } QVariantMap AlbumsModel::get(const int &index) const { if(index >= this->list.size() || index < 0) return QVariantMap(); return FM::toMap(this->list.at(index)); } void AlbumsModel::append(const QVariantMap &item) { if(item.isEmpty()) return; emit this->preItemAppended(); FMH::MODEL model; for(auto key : item.keys()) model.insert(FMH::MODEL_NAME_KEY[key], item[key].toString()); this->list << model; emit this->postItemAppended(); } void AlbumsModel::append(const QVariantMap &item, const int &at) { if(item.isEmpty()) return; if(at > this->list.size() || at < 0) return; qDebug()<< "trying to append at" << at << item["title"]; emit this->preItemAppendedAt(at); FMH::MODEL model; for(auto key : item.keys()) model.insert(FMH::MODEL_NAME_KEY[key], item[key].toString()); this->list.insert(at, model); emit this->postItemAppended(); } void AlbumsModel::refresh() { this->setList(); }