diff --git a/babe.cpp b/babe.cpp index 7fe68e6..f1680a1 100644 --- a/babe.cpp +++ b/babe.cpp @@ -1,523 +1,520 @@ #include "babe.h" #include "db/collectionDB.h" //#include "db/conthread.h" #include "settings/BabeSettings.h" -#include "pulpo/pulpo.h" - #include #include #include #include #include #include #include #include #include "services/local/taginfo.h" //#include "Python.h" #ifdef STATIC_MAUIKIT #include "fm.h" #else #include #endif #if (defined (Q_OS_LINUX) && !defined (Q_OS_ANDROID)) #include #include "kde/notify.h" #endif using namespace BAE; Babe::Babe(QObject *parent) : QObject(parent) { this->settings = new BabeSettings(this); /*use another thread for the db to perfom heavy dutty actions*/ // this->thread = new ConThread; - this->pulpo = new Pulpo(this); this->db = CollectionDB::getInstance(); - connect(pulpo, &Pulpo::infoReady, [&](const FMH::MODEL &track, const PULPO::RESPONSE &res) - { - qDebug()<<"GOT THE LYRICS"; +// connect(pulpo, &Pulpo::infoReady, [&](const FMH::MODEL &track, const PULPO::RESPONSES &res) +// { +// qDebug()<<"GOT THE LYRICS"; - if(!res[PULPO::ONTOLOGY::TRACK][PULPO::INFO::LYRICS].isEmpty()) - { - auto lyrics = res[PULPO::ONTOLOGY::TRACK][PULPO::INFO::LYRICS][PULPO::CONTEXT::LYRIC].toString(); +// if(!res[PULPO::ONTOLOGY::TRACK][PULPO::INFO::LYRICS].isEmpty()) +// { +// auto lyrics = res[PULPO::ONTOLOGY::TRACK][PULPO::INFO::LYRICS][PULPO::CONTEXT::LYRIC].toString(); - this->db->lyricsTrack(track, lyrics); - emit this->trackLyricsReady(lyrics, track[FMH::MODEL_KEY::URL]); - } - }); +// this->db->lyricsTrack(track, lyrics); +// emit this->trackLyricsReady(lyrics, track[FMH::MODEL_KEY::URL]); +// } +// }); connect(settings, &BabeSettings::refreshTables, [this](int size) { emit this->refreshTables(size); }); connect(settings, &BabeSettings::refreshATable, [this](BAE::TABLE table) { switch(table) { case BAE::TABLE::TRACKS: emit this->refreshTracks(); break; case BAE::TABLE::ALBUMS: emit this->refreshAlbums(); break; case BAE::TABLE::ARTISTS: emit this->refreshArtists(); break; default: break; } }); /*The local streaming connection still unfinished*/ // connect(&link, &Linking::parseAsk, this, &Babe::linkDecoder); // connect(&link, &Linking::bytesFrame, [this](QByteArray array) // { // this->player.appendBuffe(array); // }); // connect(&link, &Linking::arrayReady, [this](QByteArray array) // { // qDebug()<<"trying to play the array"; // Q_UNUSED(array); // this->player.playBuffer(); // }); #if (defined (Q_OS_LINUX) && !defined (Q_OS_ANDROID)) this->nof = new Notify(this); connect(this->nof,&Notify::babeSong,[this]() { emit this->babeIt(); }); connect(this->nof,&Notify::skipSong,[this]() { emit this->skipTrack(); }); #elif defined (Q_OS_ANDROID) #endif } Babe::~Babe(){} //void Babe::runPy() //{ // QFile cat (BAE::CollectionDBPath+"cat"); // qDebug()<db->getDBDataQML(queryTxt); } QVariantList Babe::getList(const QStringList &urls) { return Babe::transformData(this->db->getDBData(urls)); } //void Babe::set(const QString &table, const QVariantList &wheres) //{ // this->thread->start(table, wheres); //} //void Babe::trackPlaylist(const QStringList &urls, const QString &playlist) //{ // QVariantList data; // for(auto url : urls) // { // QVariantMap map {{FMH::MODEL_NAME[FMH::MODEL_KEY::PLAYLIST],playlist}, // {FMH::MODEL_NAME[FMH::MODEL_KEY::URL],url}, // {FMH::MODEL_NAME[FMH::MODEL_KEY::ADDDATE],QDateTime::currentDateTime()}}; // data << map; // } // this->thread->start(BAE::TABLEMAP[TABLE::TRACKS_PLAYLISTS], data); //} void Babe::trackLyrics(const QString &url) { auto track = this->db->getDBData(QString("SELECT * FROM %1 WHERE %2 = \"%3\"").arg(TABLEMAP[TABLE::TRACKS], FMH::MODEL_NAME[FMH::MODEL_KEY::URL], url)); if(track.isEmpty()) return; // qDebug()<< "Getting lyrics for track"<< track.first()[FMH::MODEL_KEY::TITLE]; // if(!track.first()[FMH::MODEL_KEY::LYRICS].isEmpty() && track.first()[FMH::MODEL_KEY::LYRICS] != SLANG[W::NONE]) // emit this->trackLyricsReady(track.first()[FMH::MODEL_KEY::LYRICS], url); // else this->fetchTrackLyrics(track.first()); } QString Babe::artistArt(const QString &artist) { auto artwork = this->db->getDBData(QString("SELECT %1 FROM %2 WHERE %3 = \"%4\"").arg(FMH::MODEL_NAME[FMH::MODEL_KEY::ARTWORK], TABLEMAP[TABLE::ARTISTS], FMH::MODEL_NAME[FMH::MODEL_KEY::ARTIST],artist)); if(!artwork.isEmpty()) if(!artwork.first()[FMH::MODEL_KEY::ARTWORK].isEmpty() && artwork.first()[FMH::MODEL_KEY::ARTWORK] != SLANG[W::NONE]) return artwork.first()[FMH::MODEL_KEY::ARTWORK]; return ""; } QString Babe::artistWiki(const QString &artist) { auto wiki = this->db->getDBData(QString("SELECT %1 FROM %2 WHERE %3 = \"%4\"").arg(FMH::MODEL_NAME[FMH::MODEL_KEY::WIKI], TABLEMAP[TABLE::ARTISTS], FMH::MODEL_NAME[FMH::MODEL_KEY::ARTIST],artist)); if(!wiki.isEmpty()) return wiki.first()[FMH::MODEL_KEY::WIKI]; return ""; } QString Babe::albumArt(const QString &album, const QString &artist) { auto queryStr = QString("SELECT %1 FROM %2 WHERE %3 = \"%4\" AND %5 = \"%6\"").arg(FMH::MODEL_NAME[FMH::MODEL_KEY::ARTWORK], TABLEMAP[TABLE::ALBUMS], FMH::MODEL_NAME[FMH::MODEL_KEY::ALBUM], album, FMH::MODEL_NAME[FMH::MODEL_KEY::ARTIST], artist); auto albumCover = this->db->getDBData(queryStr); if(!albumCover.isEmpty()) if(!albumCover.first()[FMH::MODEL_KEY::ARTWORK].isEmpty() && albumCover.first()[FMH::MODEL_KEY::ARTWORK] != SLANG[W::NONE]) return albumCover.first()[FMH::MODEL_KEY::ARTWORK]; return ""; } void Babe::fetchTrackLyrics(FMH::MODEL &song) {/* auto p = new Pulpo(this); connect(p, &Pulpo::infoReady, [=](const FMH::MODEL &track, const PULPO::RESPONSE &res) { qDebug()<<"GOT THE LYRICS"; if(!res[PULPO::ONTOLOGY::TRACK][PULPO::INFO::LYRICS].isEmpty()) { auto lyrics = res[PULPO::ONTOLOGY::TRACK][PULPO::INFO::LYRICS][PULPO::CONTEXT::LYRIC].toString(); // this->db->lyricsTrack(track, lyrics); emit this->trackLyricsReady(lyrics, track[FMH::MODEL_KEY::URL]); p->deleteLater(); } }); p->registerServices({SERVICES::Genius}); p->setOntology(PULPO::ONTOLOGY::TRACK); p->setInfo(PULPO::INFO::LYRICS); qDebug()<<"STARTED FETCHING LYRICS"; p->feed(song, PULPO::RECURSIVE::OFF); qDebug()<<"DONE FETCHING LYRICS";*/ } //void Babe::linkDecoder(QString json) //{ // qDebug()<<"DECODING LINKER MSG"<(code)) // { // case LINK::CODE::CONNECTED : // { // this->link.deviceName = msg; // emit this->link.serverConReady(msg); // break; // } // case LINK::CODE::QUERY : // case LINK::CODE::FILTER : // case LINK::CODE::PLAYLISTS : // { // auto res = this->db->getDBDataQML(msg); // link.sendToClient(link.packResponse(static_cast(code), res)); // break; // } // case LINK::CODE::SEARCHFOR : // { //// auto res = this->searchFor(msg.split(",")); //// link.sendToClient(link.packResponse(static_cast(code), res)); // break; // } // case LINK::CODE::PLAY : // { // QFile file(msg); // sound dir // file.open(QIODevice::ReadOnly); // QByteArray arr = file.readAll(); // qDebug()<<"Preparing track array"<db->getDBData(queryStr); if(!wiki.isEmpty()) return wiki.first()[FMH::MODEL_KEY::WIKI]; return ""; } QVariantList Babe::getFolders() { auto sources = this->db->getDBData("select * from sources"); QVariantList res; for(auto item : sources) res << FMH::getDirInfo(item[FMH::MODEL_KEY::URL]); qDebug()<<"FOLDERS:"<< res; return res; } QStringList Babe::getSourceFolders() { return this->db->getSourcesFolders(); } void Babe::notify(const QString &title, const QString &body) { #if (defined (Q_OS_LINUX) && !defined (Q_OS_ANDROID)) this->nof->notify(title, body); #elif defined (Q_OS_ANDROID) Q_UNUSED(title); Q_UNUSED(body); #endif } void Babe::notifySong(const QString &url) { #if (defined (Q_OS_LINUX) && !defined (Q_OS_ANDROID)) if(!this->db->check_existance(BAE::TABLEMAP[BAE::TABLE::TRACKS], FMH::MODEL_NAME[FMH::MODEL_KEY::URL], url)) return; auto query = QString("select t.*, al.artwork from tracks t inner join albums al on al.album = t.album and al.artist = t.artist where url = \"%1\"").arg(url); auto track = this->db->getDBData(query); this->nof->notifySong(track.first()); #else Q_UNUSED(url); #endif } void Babe::scanDir(const QString &url) { emit this->settings->collectionPathChanged({url}); } void Babe::brainz(const bool &on) { qDebug()<< "Changed vvae brainz state"<< on; this->settings->startBrainz(on); } bool Babe::brainzState() { return FM::loadSettings("AUTO", "BRAINZ", false).toBool(); } void Babe::refreshCollection() { this->settings->refreshCollection(); } void Babe::getYoutubeTrack(const QString &message) { this->settings->fetchYoutubeTrack(message); } void Babe::savePlaylist(const QStringList &list) { FM::saveSettings("LASTPLAYLIST", list, "PLAYLIST"); } QStringList Babe::lastPlaylist() { return FM::loadSettings("LASTPLAYLIST","PLAYLIST", QStringList()).toStringList(); } void Babe::savePlaylistPos(const int &pos) { BAE::saveSettings("PLAYLIST_POS", pos, "MAINWINDOW"); } int Babe::lastPlaylistPos() { return BAE::loadSettings("PLAYLIST_POS","MAINWINDOW",QVariant(0)).toInt(); } void Babe::showFolder(const QStringList &urls) { for(auto url : urls) FM::openUrl(QUrl::fromLocalFile(QFileInfo(url).dir().absolutePath()).toString()); } QString Babe::babeColor() { return "#f84172"; } void Babe::openUrls(const QStringList &urls) { if(urls.isEmpty()) return; QVariantList data; TagInfo info; for(auto url : urls) if(this->db->check_existance(BAE::TABLEMAP[BAE::TABLE::TRACKS], FMH::MODEL_NAME[FMH::MODEL_KEY::URL], url)) data << this->getList({url}).first().toMap(); else { if(info.feed(url)) { auto album = BAE::fixString(info.getAlbum()); auto track= info.getTrack(); auto title = BAE::fixString(info.getTitle()); /* to fix*/ auto artist = BAE::fixString(info.getArtist()); auto genre = info.getGenre(); auto sourceUrl = QFileInfo(url).dir().path(); auto duration = info.getDuration(); auto year = info.getYear(); data << QVariantMap({ {FMH::MODEL_NAME[FMH::MODEL_KEY::URL], url}, {FMH::MODEL_NAME[FMH::MODEL_KEY::TRACK], QString::number(track)}, {FMH::MODEL_NAME[FMH::MODEL_KEY::TITLE], title}, {FMH::MODEL_NAME[FMH::MODEL_KEY::ARTIST], artist}, {FMH::MODEL_NAME[FMH::MODEL_KEY::ALBUM], album}, {FMH::MODEL_NAME[FMH::MODEL_KEY::DURATION],QString::number(duration)}, {FMH::MODEL_NAME[FMH::MODEL_KEY::GENRE], genre}, {FMH::MODEL_NAME[FMH::MODEL_KEY::SOURCE], sourceUrl}, {FMH::MODEL_NAME[FMH::MODEL_KEY::FAV],"0"}, {FMH::MODEL_NAME[FMH::MODEL_KEY::RELEASEDATE], QString::number(year)} }); } } qDebug()<< data; emit this->openFiles(data); } QString Babe::moodColor(const int &pos) { if(pos < BAE::MoodColors.size()) return BAE::MoodColors.at(pos); else return ""; } QStringList Babe::defaultSources() { return BAE::defaultSources; } void Babe::loadCover(const QString &url) { auto map = this->db->getDBData(QStringList() << url); if(map.isEmpty()) return; auto track = map.first(); auto artist = track[FMH::MODEL_KEY::ARTIST]; auto album = track[FMH::MODEL_KEY::ALBUM]; auto title = track[FMH::MODEL_KEY::TITLE]; auto artistImg = this->artistArt(artist); auto albumImg = this->albumArt(album, artist); if(!albumImg.isEmpty() && albumImg != BAE::SLANG[W::NONE]) emit this->coverReady(albumImg); else if (!artistImg.isEmpty() && artistImg != BAE::SLANG[W::NONE]) emit this->coverReady(artistImg); else this->fetchCoverArt(track); } void Babe::fetchCoverArt(FMH::MODEL &song) { - auto pulpo = new Pulpo; +// auto pulpo = new Pulpo; - if(BAE::artworkCache(song, FMH::MODEL_KEY::ALBUM)) emit this->coverReady(song[FMH::MODEL_KEY::ARTWORK]); - if(BAE::artworkCache(song, FMH::MODEL_KEY::ARTIST)) emit this->coverReady(song[FMH::MODEL_KEY::ARTWORK]); +// if(BAE::artworkCache(song, FMH::MODEL_KEY::ALBUM)) emit this->coverReady(song[FMH::MODEL_KEY::ARTWORK]); +// if(BAE::artworkCache(song, FMH::MODEL_KEY::ARTIST)) emit this->coverReady(song[FMH::MODEL_KEY::ARTWORK]); - pulpo->registerServices({SERVICES::LastFm, SERVICES::Spotify}); - pulpo->setOntology(PULPO::ONTOLOGY::ALBUM); - pulpo->setInfo(PULPO::INFO::ARTWORK); +// pulpo->registerServices({SERVICES::LastFm, SERVICES::Spotify}); +// pulpo->setOntology(PULPO::ONTOLOGY::ALBUM); +// pulpo->setInfo(PULPO::INFO::ARTWORK); - connect(pulpo, &Pulpo::infoReady, [&](const FMH::MODEL &track,const PULPO::RESPONSE &res) - { - Q_UNUSED(track); - if(!res[PULPO::ONTOLOGY::ALBUM][PULPO::INFO::ARTWORK].isEmpty()) - { - auto artwork = res[PULPO::ONTOLOGY::ALBUM][PULPO::INFO::ARTWORK][PULPO::CONTEXT::IMAGE].toByteArray(); - BAE::saveArt(song, artwork, BAE::CachePath); - emit this->coverReady(song[FMH::MODEL_KEY::ARTWORK]); - } - }); +// connect(pulpo, &Pulpo::infoReady, [&](const FMH::MODEL &track,const PULPO::RESPONSE &res) +// { +// Q_UNUSED(track); +// if(!res[PULPO::ONTOLOGY::ALBUM][PULPO::INFO::ARTWORK].isEmpty()) +// { +// auto artwork = res[PULPO::ONTOLOGY::ALBUM][PULPO::INFO::ARTWORK][PULPO::CONTEXT::IMAGE].toByteArray(); +// BAE::saveArt(song, artwork, BAE::CachePath); +// emit this->coverReady(song[FMH::MODEL_KEY::ARTWORK]); +// } +// }); - pulpo->feed(song, PULPO::RECURSIVE::OFF); +// pulpo->feed(song, PULPO::RECURSIVE::OFF); } QVariantList Babe::transformData(const FMH::MODEL_LIST &dbList) { QVariantList res; for(FMH::MODEL data : dbList) { FMH::MODEL copy = data; res << FM::toMap(copy); } return res; } diff --git a/babe.h b/babe.h index 91cdc79..2c227fd 100644 --- a/babe.h +++ b/babe.h @@ -1,116 +1,115 @@ #ifndef BABE_H #define BABE_H #include #include #include "utils/bae.h" #include "db/collectionDB.h" //#include "services/local/linking.h" #if (defined (Q_OS_LINUX) && !defined (Q_OS_ANDROID)) class Notify; #elif defined (Q_OS_ANDROID) //class NotificationClient; #endif class CollectionDB; class Pulpo; class BabeSettings; class ConThread; using namespace BAE; class Babe : public QObject { Q_OBJECT public: explicit Babe(QObject *parent = nullptr); ~Babe(); BabeSettings *settings; // Linking link; // Q_INVOKABLE void runPy(); /* DATABASE INTERFACES */ Q_INVOKABLE QVariantList get(const QString &queryTxt); Q_INVOKABLE QVariantList getList(const QStringList &urls); // Q_INVOKABLE void set(const QString &table, const QVariantList &wheres); // Q_INVOKABLE void trackPlaylist(const QStringList &urls, const QString &playlist); /***MOVE ALL THIS TO A INFO MODEL ***/ Q_INVOKABLE void trackLyrics(const QString &url); Q_INVOKABLE QString artistArt(const QString &artist); Q_INVOKABLE QString albumArt(const QString &album, const QString &artist); Q_INVOKABLE QString artistWiki(const QString &artist); Q_INVOKABLE QString albumWiki(const QString &album, const QString &artist); Q_INVOKABLE void loadCover(const QString &url); /**************************************/ Q_INVOKABLE QVariantList getFolders(); Q_INVOKABLE QStringList getSourceFolders(); /* SETTINGS */ Q_INVOKABLE void scanDir(const QString &url); Q_INVOKABLE void brainz(const bool &on); Q_INVOKABLE bool brainzState(); Q_INVOKABLE void refreshCollection(); Q_INVOKABLE void getYoutubeTrack(const QString &message); /* STATIC METHODS */ Q_INVOKABLE static void savePlaylist(const QStringList &list); Q_INVOKABLE static QStringList lastPlaylist(); Q_INVOKABLE static void savePlaylistPos(const int &pos); Q_INVOKABLE static int lastPlaylistPos(); Q_INVOKABLE static void showFolder(const QStringList &urls); /*COLORS*/ Q_INVOKABLE static QString babeColor(); /*UTILS*/ Q_INVOKABLE void openUrls(const QStringList &urls); Q_INVOKABLE static QString moodColor(const int &pos); Q_INVOKABLE static QStringList defaultSources(); /*KDE*/ Q_INVOKABLE void notify(const QString &title, const QString &body); Q_INVOKABLE void notifySong(const QString &url); public slots: private: - Pulpo *pulpo; // ConThread *thread; CollectionDB *db; #if (defined (Q_OS_LINUX) && !defined (Q_OS_ANDROID)) Notify *nof; #elif defined (Q_OS_ANDROID) // NotificationClient *nof; #endif void fetchCoverArt(FMH::MODEL &song); static QVariantList transformData(const FMH::MODEL_LIST &dbList); void fetchTrackLyrics(FMH::MODEL &song); // void linkDecoder(QString json); signals: void refreshTables(int size); void refreshTracks(); void refreshAlbums(); void refreshArtists(); void trackLyricsReady(QString lyrics, QString url); void skipTrack(); void babeIt(); void message(QString msg); void openFiles(QVariantList tracks); void coverReady(const QString &path); }; #endif // BABE_H diff --git a/pulpo/enums.h b/pulpo/enums.h index ead86dc..d4d13f2 100644 --- a/pulpo/enums.h +++ b/pulpo/enums.h @@ -1,135 +1,162 @@ #ifndef ENUMS_H #define ENUMS_H +#ifdef STATIC_MAUIKIT +#include "../mauikit/src/fm/fmh.h" +#else +#include +#endif + #include #include +#include + + namespace PULPO { - enum class SERVICES : uint8_t - { - LastFm, - Spotify, - iTunes, - MusicBrainz, - Genius, - LyricWikia, - Wikipedia, - WikiLyrics, - Deezer, - ALL, - NONE - }; - - enum class ONTOLOGY : uint8_t - { - ARTIST, - ALBUM, - TRACK, - NONE - }; - - enum class INFO : uint8_t - { - ARTWORK, - WIKI, - TAGS, - METADATA, - LYRICS, - ALL, - NONE - }; - - /*Generic context names. It's encouraged to use these instead of a unkown string*/ - enum class CONTEXT : uint8_t - { - TRACK_STAT, - TRACK_NUMBER, - TRACK_TITLE, - TRACK_DATE, - TRACK_TEAM, - TRACK_AUTHOR, - TRACK_LANGUAGE, - TRACK_SIMILAR, - - ALBUM_TEAM, - ALBUM_STAT, - ALBUM_TITLE, - ALBUM_DATE, - ALBUM_LANGUAGE, - ALBUM_SIMILAR, - ALBUM_LABEL, - - ARTIST_STAT, - ARTIST_TITLE, - ARTIST_DATE, - ARTIST_LANGUAGE, - ARTIST_PLACE, - ARTIST_SIMILAR, - ARTIST_TEAM, - ARTIST_ALIAS, - ARTIST_GENDER, - - GENRE, - TAG, - WIKI, - IMAGE, - LYRIC, - SOURCE - - }; - - static const QMap CONTEXT_MAP = - { - {CONTEXT::ALBUM_STAT, "album_stat"}, - {CONTEXT::ALBUM_TITLE, "album_title"}, - {CONTEXT::ALBUM_DATE, "album_date"}, - {CONTEXT::ALBUM_LANGUAGE, "album_language"}, - {CONTEXT::ALBUM_SIMILAR, "album_similar"}, - {CONTEXT::ALBUM_LABEL, "album_label"}, - {CONTEXT::ALBUM_TEAM, "album_team"}, - - {CONTEXT::ARTIST_STAT, "artist_stat"}, - {CONTEXT::ARTIST_TITLE, "artist_title"}, - {CONTEXT::ARTIST_DATE, "artist_date"}, - {CONTEXT::ARTIST_LANGUAGE, "artist_language"}, - {CONTEXT::ARTIST_PLACE, "artist_place"}, - {CONTEXT::ARTIST_SIMILAR, "artist_similar"}, - {CONTEXT::ARTIST_ALIAS, "artist_alias"}, - {CONTEXT::ARTIST_GENDER, "artist_gender"}, - {CONTEXT::ARTIST_TEAM, "artist_team"}, - - {CONTEXT::TRACK_STAT, "track_stat"}, - {CONTEXT::TRACK_DATE, "track_date"}, - {CONTEXT::TRACK_TITLE, "track_title"}, - {CONTEXT::TRACK_NUMBER, "track_number"}, - {CONTEXT::TRACK_TEAM, "track_team"}, - {CONTEXT::TRACK_AUTHOR, "track_author"}, - {CONTEXT::TRACK_LANGUAGE, "track_language"}, - {CONTEXT::TRACK_SIMILAR, "track_similar"}, - - {CONTEXT::GENRE, "genre"}, - {CONTEXT::TAG, "tag"}, - {CONTEXT::WIKI, "wiki"}, - {CONTEXT::IMAGE, "image"}, - {CONTEXT::LYRIC, "lyric"}, - {CONTEXT::SOURCE, "source"} - - }; - - enum class RECURSIVE : bool - { - ON = true, - OFF = false - }; - - typedef QMap VALUE; - typedef QMap INFO_K; - typedef QMap RESPONSE; - - typedef QMap> AVAILABLE; +enum class SERVICES : uint8_t +{ + LastFm, + Spotify, + iTunes, + MusicBrainz, + Genius, + LyricWikia, + Wikipedia, + WikiLyrics, + Deezer, + ALL, + NONE +}; + +enum class ONTOLOGY : uint8_t +{ + ARTIST, + ALBUM, + TRACK +}; + +enum class INFO : uint8_t +{ + ARTWORK, + WIKI, + TAGS, + METADATA, + LYRICS, + ALL, + NONE +}; + +/*Generic context names. It's encouraged to use these instead of a unkown string*/ +enum class CONTEXT : uint8_t +{ + TRACK_STAT, + TRACK_NUMBER, + TRACK_TITLE, + TRACK_DATE, + TRACK_TEAM, + TRACK_AUTHOR, + TRACK_LANGUAGE, + TRACK_SIMILAR, + + ALBUM_TEAM, + ALBUM_STAT, + ALBUM_TITLE, + ALBUM_DATE, + ALBUM_LANGUAGE, + ALBUM_SIMILAR, + ALBUM_LABEL, + + ARTIST_STAT, + ARTIST_TITLE, + ARTIST_DATE, + ARTIST_LANGUAGE, + ARTIST_PLACE, + ARTIST_SIMILAR, + ARTIST_TEAM, + ARTIST_ALIAS, + ARTIST_GENDER, + + GENRE, + TAG, + WIKI, + IMAGE, + LYRIC, + SOURCE + +}; + +static const QMap CONTEXT_MAP = +{ + {CONTEXT::ALBUM_STAT, "album_stat"}, + {CONTEXT::ALBUM_TITLE, "album_title"}, + {CONTEXT::ALBUM_DATE, "album_date"}, + {CONTEXT::ALBUM_LANGUAGE, "album_language"}, + {CONTEXT::ALBUM_SIMILAR, "album_similar"}, + {CONTEXT::ALBUM_LABEL, "album_label"}, + {CONTEXT::ALBUM_TEAM, "album_team"}, + + {CONTEXT::ARTIST_STAT, "artist_stat"}, + {CONTEXT::ARTIST_TITLE, "artist_title"}, + {CONTEXT::ARTIST_DATE, "artist_date"}, + {CONTEXT::ARTIST_LANGUAGE, "artist_language"}, + {CONTEXT::ARTIST_PLACE, "artist_place"}, + {CONTEXT::ARTIST_SIMILAR, "artist_similar"}, + {CONTEXT::ARTIST_ALIAS, "artist_alias"}, + {CONTEXT::ARTIST_GENDER, "artist_gender"}, + {CONTEXT::ARTIST_TEAM, "artist_team"}, + + {CONTEXT::TRACK_STAT, "track_stat"}, + {CONTEXT::TRACK_DATE, "track_date"}, + {CONTEXT::TRACK_TITLE, "track_title"}, + {CONTEXT::TRACK_NUMBER, "track_number"}, + {CONTEXT::TRACK_TEAM, "track_team"}, + {CONTEXT::TRACK_AUTHOR, "track_author"}, + {CONTEXT::TRACK_LANGUAGE, "track_language"}, + {CONTEXT::TRACK_SIMILAR, "track_similar"}, + + {CONTEXT::GENRE, "genre"}, + {CONTEXT::TAG, "tag"}, + {CONTEXT::WIKI, "wiki"}, + {CONTEXT::IMAGE, "image"}, + {CONTEXT::LYRIC, "lyric"}, + {CONTEXT::SOURCE, "source"} + +}; + +enum class RECURSIVE : bool +{ + ON = true, + OFF = false +}; + +typedef QMap VALUE; +typedef QMap INFO_K; +// typedef QMap RESPONSE; + +typedef QMap> SCOPE; + +struct RESPONSE +{ + CONTEXT context; + QVariant value; +}; +typedef QList RESPONSES; + +struct REQUEST +{ + FMH::MODEL track; + + PULPO::ONTOLOGY ontology; + QList info; + QList services; + + std::function callback; +}; + } #endif // ENUMS_H diff --git a/pulpo/pulpo.cpp b/pulpo/pulpo.cpp index 17c4638..2eec99f 100644 --- a/pulpo/pulpo.cpp +++ b/pulpo/pulpo.cpp @@ -1,305 +1,86 @@ /* Babe - tiny music player Copyright (C) 2017 Camilo Higuita This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "pulpo.h" #include "services/lastfmService.h" -#include "services/spotifyService.h" -#include "services/lyricwikiaService.h" -#include "services/geniusService.h" -#include "services/musicbrainzService.h" -#include "services/deezerService.h" +//#include "services/spotifyService.h" +//#include "services/lyricwikiaService.h" +//#include "services/geniusService.h" +//#include "services/musicbrainzService.h" +//#include "services/deezerService.h" -//#include "qgumbodocument.h" +//#include "qgumbodocument.h"p //#include "qgumbonode.h" -Pulpo::Pulpo(const FMH::MODEL &song, QObject *parent) - : QObject(parent), track(song) {} - Pulpo::Pulpo(QObject *parent): QObject(parent) {} Pulpo::~Pulpo() { qDebug()<< "DELETING PULPO INSTANCE"; - for(auto &instance : this->serviceInstances) - delete instance; } -bool Pulpo::feed(const FMH::MODEL &song, const RECURSIVE &recursive) +void Pulpo::request(const PULPO::REQUEST &request) { - if(song.isEmpty()) - return false; - - this->track = song; - this->recursive = recursive; - - if(this->registeredServices.isEmpty()) return false; - - this->initServices(); + this->req = request; - return true; -} - -void Pulpo::registerServices(const QList &services) -{ - this->registeredServices = services; -} - -void Pulpo::setInfo(const PULPO::INFO &info) -{ - this->info = info; -} - -void Pulpo::setOntology(const PULPO::ONTOLOGY &ontology) -{ - this->ontology = ontology; -} + if(this->req.track.isEmpty()) + { + emit this->error(); + return; + } -ONTOLOGY Pulpo::getOntology() -{ - return this->ontology; -} + if(this->req.services.isEmpty()) + { + qWarning()<< "Please register at least one Pulpo Service"; + emit this->error(); + return; + } -void Pulpo::setRecursive(const RECURSIVE &state) -{ - this->recursive=state; + this->start(); } -QStringList Pulpo::queryHtml(const QByteArray &array, const QString &className) -{ - QStringList res; - - // auto doc = QGumboDocument::parse(array); - // auto root = doc.rootNode(); - - // auto nodes = root.getElementsByTagName(HtmlTag::TITLE); - // Q_ASSERT(nodes.size() == 1); - - // auto title = nodes.front(); - // qDebug() << "title is: " << title.innerText(); - // auto container = root.getElementsByClassName(className); - // // if(container.size() == 1) - // // return res; - - // auto children = container.front().children(); - // for(const auto &i : children) - // res << i.innerText(); - - - return res; -} - -void Pulpo::initServices() +void Pulpo::start() { - for(auto service : this->registeredServices) + for(const auto &service : this->req.services) switch (service) { - case SERVICES::LastFm: - { - auto lastfm = new class lastfm(this->track); - this->serviceInstances.push_back(lastfm); - connect(lastfm, &lastfm::infoReady,[=](FMH::MODEL track, PULPO::RESPONSE response) - { - this->passSignal(track, response); -// lastfm->deleteLater(); - }); - - if(lastfm->setUpService(this->ontology, this->info)) - { - if(recursive == RECURSIVE::OFF) return; - - }else qDebug()<<"Error settingUp lastfm service"; - - break; - } - - case SERVICES::Spotify: - { - spotify spotify(this->track); - connect(&spotify, &spotify::infoReady, this, &Pulpo::passSignal); - - if(spotify.setUpService(this->ontology,this->info)) - { - if(recursive== RECURSIVE::OFF) return; - - }else qDebug()<<"Error settingUp spotify service"; - - break; - } - case SERVICES::Genius: - { - auto genius = new class genius(this->track); - connect(genius, &genius::infoReady, this, &Pulpo::passSignal); - - if(genius->setUpService(this->ontology,this->info)) - { - if(recursive== RECURSIVE::OFF) return; - - }else qDebug()<<"Error settingUp genius service"; - - break; - } - case SERVICES::MusicBrainz: - { - musicBrainz musicbrainz(this->track); - connect(&musicbrainz, &musicBrainz::infoReady, this, &Pulpo::passSignal); - - if(musicbrainz.setUpService(this->ontology,this->info)) - { - if(recursive== RECURSIVE::OFF) return; - - }else qDebug()<<"Error settingUp musicBrainz service"; - - break; - } - case SERVICES::iTunes: - { - break; - } - case SERVICES::WikiLyrics: - { - break; - } - case SERVICES::LyricWikia: - { - auto lyricwikia = new lyricWikia(this->track); - connect(lyricwikia, &lyricWikia::infoReady, this, &Pulpo::passSignal); - - if(lyricwikia->setUpService(this->ontology, this->info)) - { - if(recursive == RECURSIVE::OFF) return; - - }else qDebug()<<"Error settingUp lyricwikia service"; - - break; - } - case SERVICES::Wikipedia: - { - break; - } - - case SERVICES::Deezer: + case SERVICES::LastFm: + { + auto lastfm = new class lastfm(); + connect(lastfm, &lastfm::responseReady,[=](PULPO::REQUEST request, PULPO::RESPONSES responses) { - deezer deezer(this->track); - connect(&deezer, &deezer::infoReady, this, &Pulpo::passSignal); - - if(deezer.setUpService(this->ontology, this->info)) - { - if(recursive== RECURSIVE::OFF) return; + this->passSignal(request, responses); + lastfm->deleteLater(); + }); - }else qDebug()<<"Error settingUp deezer service"; - - break; - } - case SERVICES::ALL: - { - break; - } - case SERVICES::NONE: - { - break; - } + lastfm->set(this->req); + break; } -} - -void Pulpo::passSignal(const FMH::MODEL &track, const PULPO::RESPONSE &response) -{ - emit this->infoReady(track, response); -} - -PULPO::RESPONSE Pulpo::packResponse(const PULPO::ONTOLOGY ontology, const PULPO::INFO &infoKey, const PULPO::CONTEXT &context, const QVariant &value) -{ - return {{ ontology, {{ infoKey, {{ context, value }} }} }}; -} - -PULPO::RESPONSE Pulpo::packResponse(const ONTOLOGY ontology, const PULPO::INFO &infoKey, const PULPO::VALUE &map) -{ - return {{ ontology, { {infoKey, map} }} }; -} - -bool Pulpo::parseArray() -{ - if(this->ontology == PULPO::ONTOLOGY::NONE) - return false; - - switch(this->ontology) - { - case PULPO::ONTOLOGY::ALBUM: return this->parseAlbum(); - case PULPO::ONTOLOGY::ARTIST: return this->parseArtist(); - case PULPO::ONTOLOGY::TRACK: return this->parseTrack(); - default: return false; - } -} - -QByteArray Pulpo::startConnection(const QString &url, const QMap &headers) -{ - if(!url.isEmpty()) - { - QUrl mURL(url); - QNetworkAccessManager manager; - QNetworkRequest request (mURL); - - if(!headers.isEmpty()) - for(auto key: headers.keys()) - request.setRawHeader(key.toLocal8Bit(), headers[key].toLocal8Bit()); - - QNetworkReply *reply = manager.get(request); - QEventLoop loop; - connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); - - connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), &loop, SLOT(quit())); - - loop.exec(); - - if(reply->error()) - { - qDebug() << reply->error(); - return QByteArray(); - } - - if(reply->bytesAvailable()) - { - auto data = reply->readAll(); - reply->deleteLater(); - - return data; } - } - - return QByteArray(); } -void Pulpo::startConnectionAsync(const QString &url, const QMap &headers) +void Pulpo::passSignal(REQUEST request, RESPONSES responses) { - if(!url.isEmpty()) - { - auto downloader = new FMH::Downloader; - connect(downloader, &FMH::Downloader::dataReady, [=](QByteArray array) - { -// qDebug()<< "DATA READY << " << array; - emit this->arrayReady(array); - downloader->deleteLater(); - }); - -// qDebug()<< "trying to get ASYNC DOWNLOADER for "<< url; - downloader->getArray(url); - } -} - - + if(request.callback) + request.callback(request, responses); + else + emit this->infoReady(request, responses); + emit this->finished(); +} diff --git a/pulpo/pulpo.h b/pulpo/pulpo.h index 2e894e1..8c0f622 100644 --- a/pulpo/pulpo.h +++ b/pulpo/pulpo.h @@ -1,79 +1,42 @@ #ifndef PULPO_H #define PULPO_H #include #include #include #include #include -#include #include #include -#include -#include -#include -#include -#include #include #include "../utils/bae.h" #include "enums.h" using namespace PULPO; class Pulpo : public QObject { Q_OBJECT public: - explicit Pulpo(const FMH::MODEL &song, QObject *parent = nullptr); explicit Pulpo(QObject *parent = nullptr); ~Pulpo(); - bool feed(const FMH::MODEL &song, const PULPO::RECURSIVE &recursive = PULPO::RECURSIVE::ON ); - void registerServices(const QList &services); - void setInfo(const PULPO::INFO &info); - void setOntology(const PULPO::ONTOLOGY &ontology); - PULPO::ONTOLOGY getOntology(); - void setRecursive(const PULPO::RECURSIVE &state); - - QStringList queryHtml(const QByteArray &array, const QString &className = QString()); + void request(const PULPO::REQUEST &request); private: - void initServices(); - PULPO::RECURSIVE recursive = PULPO::RECURSIVE::ON; - QList registeredServices = {}; - - void passSignal(const FMH::MODEL &track, const PULPO::RESPONSE &response); - QNetworkAccessManager *manager; - QNetworkReply *reply; - - QList serviceInstances; - -protected: - QByteArray array; - FMH::MODEL track; - PULPO::INFO info = INFO::NONE; - PULPO::ONTOLOGY ontology = ONTOLOGY::NONE; - PULPO::AVAILABLE availableInfo; - - PULPO::RESPONSE packResponse(const PULPO::ONTOLOGY ontology, const PULPO::INFO &infoKey, const PULPO::CONTEXT &contextName, const QVariant &value); - PULPO::RESPONSE packResponse(const PULPO::ONTOLOGY ontology, const PULPO::INFO &infoKey, const PULPO::VALUE &map); + void start(); + QList services = {}; - QByteArray startConnection(const QString &url, const QMap &headers = {}); - void startConnectionAsync(const QString &url, const QMap &headers = {}); - bool parseArray(); + PULPO::REQUEST req; - /* expected methods to be overrided by services */ - bool setUpService(const PULPO::ONTOLOGY &ontology, const PULPO::INFO &info); - virtual bool parseArtist() {return false;} - virtual bool parseAlbum() {return false;} - virtual bool parseTrack() {return false;} + void passSignal(PULPO::REQUEST request, PULPO::RESPONSES responses); signals: - void infoReady(FMH::MODEL track, PULPO::RESPONSE response); - void serviceFail(const QString &message); - void arrayReady(QByteArray array); + void infoReady(PULPO::REQUEST request, PULPO::RESPONSES responses); + void error(); + void finished(); }; #endif // ARTWORK_H diff --git a/pulpo/pulpo.pri b/pulpo/pulpo.pri index f7b4e28..f600c01 100644 --- a/pulpo/pulpo.pri +++ b/pulpo/pulpo.pri @@ -1,37 +1,38 @@ QT += network QT += xml CONFIG += ordered - SOURCES += \ - $$PWD/services/deezerService.cpp \ +# $$PWD/services/deezerService.cpp \ $$PWD/services/lastfmService.cpp \ - $$PWD/services/spotifyService.cpp \ - $$PWD/services/musicbrainzService.cpp \ - $$PWD/services/geniusService.cpp \ - $$PWD/services/lyricwikiaService.cpp \ +# $$PWD/services/spotifyService.cpp \ +# $$PWD/services/musicbrainzService.cpp \ +# $$PWD/services/geniusService.cpp \ +# $$PWD/services/lyricwikiaService.cpp \ $$PWD/pulpo.cpp \ - $$PWD/htmlparser.cpp \ +# $$PWD/htmlparser.cpp \ + $$PWD/service.cpp HEADERS += \ - $$PWD/services/spotifyService.h \ - $$PWD/services/geniusService.h \ - $$PWD/services/musicbrainzService.h \ - $$PWD/services/deezerService.h \ - $$PWD/services/lyricwikiaService.h \ +# $$PWD/services/spotifyService.h \ +# $$PWD/services/geniusService.h \ +# $$PWD/services/musicbrainzService.h \ +# $$PWD/services/deezerService.h \ +# $$PWD/services/lyricwikiaService.h \ $$PWD/services/lastfmService.h \ $$PWD/enums.h \ $$PWD/pulpo.h \ - $$PWD/htmlparser.h \ +# $$PWD/htmlparser.h \ + $$PWD/service.h DEPENDPATH += \ $$PWD \ $$PWD/services \ INCLUDEPATH += \ $$PWD \ $$PWD/services \ #include($$PWD/QGumboParser/QGumboParser.pri) diff --git a/pulpo/service.cpp b/pulpo/service.cpp new file mode 100644 index 0000000..345b70a --- /dev/null +++ b/pulpo/service.cpp @@ -0,0 +1,45 @@ +#include "service.h" + + +Service::Service(QObject *parent) : QObject(parent) +{ + +} + +void Service::set(const PULPO::REQUEST &request) +{ + this->request = request; +} + +void Service::parse(const QByteArray &array) +{ + switch(this->request.ontology) + { + case PULPO::ONTOLOGY::ALBUM: + this->parseAlbum(array); + break; + case PULPO::ONTOLOGY::ARTIST: + this->parseArtist(array); + break; + case PULPO::ONTOLOGY::TRACK: + this->parseTrack(array); + break; + } +} + +void Service::retrieve(const QString &url, const QMap &headers) +{ + if(!url.isEmpty()) + { + auto downloader = new FMH::Downloader; + connect(downloader, &FMH::Downloader::dataReady, [=](QByteArray array) + { + // qDebug()<< "DATA READY << " << array; + emit this->arrayReady(array); + downloader->deleteLater(); + }); + + // qDebug()<< "trying to get ASYNC DOWNLOADER for "<< url; + downloader->getArray(url, headers); + } +} diff --git a/pulpo/service.h b/pulpo/service.h new file mode 100644 index 0000000..06dfc10 --- /dev/null +++ b/pulpo/service.h @@ -0,0 +1,45 @@ +#ifndef SERVICE_H +#define SERVICE_H + +#include +#include +#include +#include +#include + +#include "enums.h" +#include "../utils/bae.h" + +class Service : public QObject +{ + Q_OBJECT + +private: + +public: + explicit Service(QObject *parent = nullptr); + +protected: + PULPO::REQUEST request; //the main request. the track info, the ontology and info type + PULPO::SCOPE scope; //what ontology and info can the service parse + PULPO::RESPONSES responses; + + void parse(const QByteArray &array); + + virtual void set(const PULPO::REQUEST &request); + virtual void parseArtist(const QByteArray &array) {} + virtual void parseAlbum(const QByteArray &array) {} + virtual void parseTrack(const QByteArray &array) {} + + void retrieve(const QString &url, const QMap &headers = {}); + + static PULPO::RESPONSE packResponse(const PULPO::ONTOLOGY &ontology, const PULPO::INFO &info, const PULPO::VALUE &value); + +signals: + void arrayReady(QByteArray array); + void responseReady(PULPO::REQUEST request, PULPO::RESPONSES responses); + +public slots: +}; + +#endif // SERVICE_H diff --git a/pulpo/services/lastfmService.cpp b/pulpo/services/lastfmService.cpp index 3ef4759..3bbb2ad 100644 --- a/pulpo/services/lastfmService.cpp +++ b/pulpo/services/lastfmService.cpp @@ -1,426 +1,413 @@ #include "lastfmService.h" +using namespace PULPO; -lastfm::lastfm(const FMH::MODEL &song) +lastfm::lastfm() { - this->availableInfo.insert(ONTOLOGY::ALBUM, {INFO::ARTWORK, INFO::WIKI, INFO::TAGS}); - this->availableInfo.insert(ONTOLOGY::ARTIST, {INFO::ARTWORK, INFO::WIKI, INFO::TAGS}); - this->availableInfo.insert(ONTOLOGY::TRACK, {INFO::TAGS, INFO::WIKI, INFO::ARTWORK, INFO::METADATA}); + this->scope.insert(ONTOLOGY::ALBUM, {INFO::ARTWORK, INFO::WIKI, INFO::TAGS}); + this->scope.insert(ONTOLOGY::ARTIST, {INFO::ARTWORK, INFO::WIKI, INFO::TAGS}); + this->scope.insert(ONTOLOGY::TRACK, {INFO::TAGS, INFO::WIKI, INFO::ARTWORK, INFO::METADATA}); - this->track = song; - - connect(this, &lastfm::arrayReady, [this](QByteArray data) - { - qDebug()<< "GOT THE ARRAY ON LASTFM"; - this->array = data; - if(!this->parseArray()) - emit this->infoReady(this->track, PULPO::RESPONSE{}); - }); + connect(this, &lastfm::arrayReady, this, &lastfm::parse); } lastfm::~lastfm() { qDebug()<< "DELETING LASTFM INSTANCE"; } -bool lastfm::setUpService(const PULPO::ONTOLOGY &ontology, const PULPO::INFO &info) +void lastfm::set(const PULPO::REQUEST &request) { - this->ontology = ontology; - this->info = info; + this->request = request; - if(!this->availableInfo[this->ontology].contains(this->info)) - return false; + // if(!this->scope[this->request.ontology].contains(this->request.info)) + // { + // qWarning()<< "Requested info is not in the ontology scope of lastfm service"; + // emit this->responseReady(this->request, {}); + // return; + // } auto url = this->API; - QUrl encodedArtist(this->track[FMH::MODEL_KEY::ARTIST]); + QUrl encodedArtist(this->request.track[FMH::MODEL_KEY::ARTIST]); encodedArtist.toEncoded(QUrl::FullyEncoded); - switch(this->ontology) + switch(this->request.ontology) { - case PULPO::ONTOLOGY::ARTIST: - { - url.append("?method=artist.getinfo"); - url.append(KEY); - url.append("&artist=" + encodedArtist.toString()); - break; - } - - case PULPO::ONTOLOGY::ALBUM: - { - QUrl encodedAlbum(this->track[FMH::MODEL_KEY::ALBUM]); - encodedAlbum.toEncoded(QUrl::FullyEncoded); - - url.append("?method=album.getinfo"); - url.append(KEY); - url.append("&artist=" + encodedArtist.toString()); - url.append("&album=" + encodedAlbum.toString()); - break; - } + case PULPO::ONTOLOGY::ARTIST: + { + url.append("?method=artist.getinfo"); + url.append(KEY); + url.append("&artist=" + encodedArtist.toString()); + break; + } - case PULPO::ONTOLOGY::TRACK: - { - QUrl encodedTrack(this->track[FMH::MODEL_KEY::TITLE]); - encodedTrack.toEncoded(QUrl::FullyEncoded); + case PULPO::ONTOLOGY::ALBUM: + { + QUrl encodedAlbum(this->request.track[FMH::MODEL_KEY::ALBUM]); + encodedAlbum.toEncoded(QUrl::FullyEncoded); - url.append("?method=track.getinfo"); - url.append(KEY); - url.append("&artist=" + encodedArtist.toString()); - url.append("&track=" + encodedTrack.toString()); - url.append("&format=json"); + url.append("?method=album.getinfo"); + url.append(KEY); + url.append("&artist=" + encodedArtist.toString()); + url.append("&album=" + encodedAlbum.toString()); + break; + } - break; - } + case PULPO::ONTOLOGY::TRACK: + { + QUrl encodedTrack(this->request.track[FMH::MODEL_KEY::TITLE]); + encodedTrack.toEncoded(QUrl::FullyEncoded); - default: return false; + url.append("?method=track.getinfo"); + url.append(KEY); + url.append("&artist=" + encodedArtist.toString()); + url.append("&track=" + encodedTrack.toString()); + url.append("&format=json"); + break; + } } qDebug()<< "[lastfm service]: "<< url; - this->startConnectionAsync(url); - return true; + this->retrieve(url); } -bool lastfm::parseArtist() -{ - QString xmlData(array); - QDomDocument doc; +//void lastfm::parseArtist(const QByteArray &array) +//{ +// QString xmlData(array); +// QDomDocument doc; - if (!doc.setContent(xmlData)) return false; +// if (!doc.setContent(xmlData)) return false; - QStringList artistTags; - QByteArray artistSimilarArt; - QStringList artistSimilar; - QStringList artistStats; +// QStringList artistTags; +// QByteArray artistSimilarArt; +// QStringList artistSimilar; +// QStringList artistStats; - if (doc.documentElement().toElement().attributes().namedItem("status").nodeValue()!="ok") - return false; +// if (doc.documentElement().toElement().attributes().namedItem("status").nodeValue()!="ok") +// return; - const QDomNodeList nodeList = doc.documentElement().namedItem("artist").childNodes(); +// const QDomNodeList nodeList = doc.documentElement().namedItem("artist").childNodes(); - for (int i = 0; i < nodeList.count(); i++) - { - QDomNode n = nodeList.item(i); +// for (int i = 0; i < nodeList.count(); i++) +// { +// QDomNode n = nodeList.item(i); - if (n.isElement()) - { - //Here retrieve the artist image - if(this->info == INFO::ARTWORK || this->info == INFO::ALL) - { - if(n.nodeName() == "image" && n.hasAttributes()) - { - auto imgSize = n.attributes().namedItem("size").nodeValue(); +// if (n.isElement()) +// { +// //Here retrieve the artist image +// if(this->info == INFO::ARTWORK || this->info == INFO::ALL) +// { +// if(n.nodeName() == "image" && n.hasAttributes()) +// { +// auto imgSize = n.attributes().namedItem("size").nodeValue(); - if (imgSize == "medium" && n.isElement()) - { - auto artistArt_url = n.toElement().text(); +// if (imgSize == "medium" && n.isElement()) +// { +// auto artistArt_url = n.toElement().text(); - emit this->infoReady(this->track,this->packResponse(ONTOLOGY::ARTIST, INFO::ARTWORK,CONTEXT::IMAGE,startConnection(artistArt_url))); +// emit this->infoReady(this->track,this->packResponse(ONTOLOGY::ARTIST, INFO::ARTWORK,CONTEXT::IMAGE,startConnection(artistArt_url))); - if(this->info == INFO::ARTWORK) return true; - else continue; +// if(this->info == INFO::ARTWORK) return true; +// else continue; - }else if(this->info == INFO::ARTWORK) continue; - } - } +// }else if(this->info == INFO::ARTWORK) continue; +// } +// } - //Here retrieve the artist wiki (bio) - if(this->info == INFO::WIKI || this->info == INFO::ALL) - { - if (n.nodeName() == "bio") - { - auto artistWiki = n.childNodes().item(2).toElement().text(); - //qDebug()<<"Fetching ArtistWiki LastFm[]"; +// //Here retrieve the artist wiki (bio) +// if(this->info == INFO::WIKI || this->info == INFO::ALL) +// { +// if (n.nodeName() == "bio") +// { +// auto artistWiki = n.childNodes().item(2).toElement().text(); +// //qDebug()<<"Fetching ArtistWiki LastFm[]"; - emit this->infoReady(this->track, this->packResponse(ONTOLOGY::ARTIST, INFO::WIKI,CONTEXT::WIKI,artistWiki)); +// emit this->infoReady(this->track, this->packResponse(ONTOLOGY::ARTIST, INFO::WIKI,CONTEXT::WIKI,artistWiki)); - if(this->info == INFO::WIKI) return true; - else continue; - }else if(this->info == INFO::WIKI) continue; - } +// if(this->info == INFO::WIKI) return true; +// else continue; +// }else if(this->info == INFO::WIKI) continue; +// } - //Here retrieve the artist similar artists - if(this->info == INFO::TAGS || this->info == INFO::ALL) - { - if(n.nodeName() == "similar") - { - auto similarList = n.toElement().childNodes(); +// //Here retrieve the artist similar artists +// if(this->info == INFO::TAGS || this->info == INFO::ALL) +// { +// if(n.nodeName() == "similar") +// { +// auto similarList = n.toElement().childNodes(); - for(int i=0; iinfoReady(this->track,this->packResponse(ONTOLOGY::ARTIST, INFO::TAGS,CONTEXT::ARTIST_SIMILAR,artistSimilar)); +// emit this->infoReady(this->track,this->packResponse(ONTOLOGY::ARTIST, INFO::TAGS,CONTEXT::ARTIST_SIMILAR,artistSimilar)); - }else if(n.nodeName() == "tags") - { - auto tagsList = n.toElement().childNodes(); - //qDebug()<<"Fetching ArtistTags LastFm[]"; +// }else if(n.nodeName() == "tags") +// { +// auto tagsList = n.toElement().childNodes(); +// //qDebug()<<"Fetching ArtistTags LastFm[]"; - for(int i=0; iinfoReady(this->track,this->packResponse(ONTOLOGY::ARTIST, INFO::TAGS,CONTEXT::TAG,artistTags)); +// emit this->infoReady(this->track,this->packResponse(ONTOLOGY::ARTIST, INFO::TAGS,CONTEXT::TAG,artistTags)); - }else if(n.nodeName() == "stats") - { - QVariant stat; - auto stats = n.toElement().childNodes(); - //qDebug()<<"Fetching ArtistTags LastFm[]"; +// }else if(n.nodeName() == "stats") +// { +// QVariant stat; +// auto stats = n.toElement().childNodes(); +// //qDebug()<<"Fetching ArtistTags LastFm[]"; - for(int i=0; iinfoReady(this->track,this->packResponse(ONTOLOGY::ARTIST, INFO::TAGS, CONTEXT::ARTIST_STAT,artistStats)); +// emit this->infoReady(this->track,this->packResponse(ONTOLOGY::ARTIST, INFO::TAGS, CONTEXT::ARTIST_STAT,artistStats)); - }else if(this->info == INFO::TAGS) continue; - } +// }else if(this->info == INFO::TAGS) continue; +// } - } - } +// } +// } - /*********NOW WE WANT TO PARSE SIMILAR ARTISTS***********/ - if(this->info == INFO::TAGS || this->info == INFO::ALL) - { - auto url = this->API; - QUrl encodedTrack(this->track[FMH::MODEL_KEY::TITLE]); - encodedTrack.toEncoded(QUrl::FullyEncoded); - QUrl encodedArtist(this->track[FMH::MODEL_KEY::ARTIST]); - encodedArtist.toEncoded(QUrl::FullyEncoded); - url.append("?method=artist.getSimilar"); - url.append(KEY); - url.append("&artist=" + encodedArtist.toString()); - url.append("&format=json"); +// /*********NOW WE WANT TO PARSE SIMILAR ARTISTS***********/ +// if(this->info == INFO::TAGS || this->info == INFO::ALL) +// { +// auto url = this->API; +// QUrl encodedTrack(this->track[FMH::MODEL_KEY::TITLE]); +// encodedTrack.toEncoded(QUrl::FullyEncoded); +// QUrl encodedArtist(this->track[FMH::MODEL_KEY::ARTIST]); +// encodedArtist.toEncoded(QUrl::FullyEncoded); +// url.append("?method=artist.getSimilar"); +// url.append(KEY); +// url.append("&artist=" + encodedArtist.toString()); +// url.append("&format=json"); - qDebug()<< "[lastfm service]: "<< url; +// qDebug()<< "[lastfm service]: "<< url; - this->array = this->startConnection(url); +// this->array = this->startConnection(url); - if(!this->array.isEmpty()) - this->parseSimilar(); - } +// if(!this->array.isEmpty()) +// this->parseSimilar(); +// } - return true; -} +// return true; +//} -bool lastfm::parseAlbum() +void lastfm::parseAlbum(const QByteArray &array) { - qDebug()<< "PARSING ALBUM ON LASTFM"; - - QString xmlData(this->array); + QString xmlData(array); QDomDocument doc; if (!doc.setContent(xmlData)) { - qDebug()<< "LASTFM XML FAILED 1"; - return false; + qDebug()<< "LASTFM XML FAILED 1" << this->request.track; + emit this->responseReady(this->request, this->responses); + + return; } if (doc.documentElement().toElement().attributes().namedItem("status").nodeValue()!="ok") { - qDebug()<< "LASTFM XML FAILED 2"; - return false; + qDebug()<< "LASTFM XML FAILED 2" << this->request.track; + emit this->responseReady(this->request, this->responses); + + return; } const auto nodeList = doc.documentElement().namedItem("album").childNodes(); for (int i = 0; i < nodeList.count(); i++) { QDomNode n = nodeList.item(i); if (n.isElement()) { //Here retrieve the artist image - if(this->info == INFO::ARTWORK || this->info == INFO::ALL) + if(n.nodeName() == "image" && n.hasAttributes()) { - if(n.nodeName() == "image" && n.hasAttributes()) + if(this->request.info.contains(INFO::ARTWORK)) { auto imgSize = n.attributes().namedItem("size").nodeValue(); if (imgSize == "large" && n.isElement()) { auto albumArt_url = n.toElement().text(); + this->responses << PULPO::RESPONSE {CONTEXT::IMAGE, albumArt_url}; - qDebug()<< "GOT THE ARTWORK URL" << albumArt_url; - emit this->infoReady(this->track, - this->packResponse(ONTOLOGY::ALBUM, - INFO::ARTWORK, - CONTEXT::IMAGE, - albumArt_url)); - - if(this->info == INFO::ARTWORK) return true; + if(this->request.info.size() == 1) break; else continue; }else continue; - }else if(this->info == INFO::ARTWORK) continue; + }else continue; } - if(this->info == INFO::WIKI || this->info == INFO::ALL) + if (n.nodeName() == "wiki") { - if (n.nodeName() == "wiki") + if(this->request.info.contains(INFO::WIKI)) { auto albumWiki = n.childNodes().item(1).toElement().text(); //qDebug()<<"Fetching AlbumWiki LastFm[]"; - emit this->infoReady(this->track,this->packResponse(ONTOLOGY::ALBUM, INFO::WIKI,CONTEXT::WIKI,albumWiki)); + this->responses << PULPO::RESPONSE {CONTEXT::WIKI, albumWiki}; - if(this->info == INFO::WIKI) return true; + if(this->request.info.size() == 1) break; else continue; - }else if(this->info == INFO::WIKI) continue; + }else continue; } - if(this->info == INFO::TAGS || this->info == INFO::ALL) + if (n.nodeName() == "tags") { - ////qDebug()<<"lastfm[AlbumTags]"; - - if (n.nodeName() == "tags") + if(this->request.info.contains(INFO::TAGS)) { auto tagsList = n.toElement().childNodes(); QStringList albumTags; for(int i=0; iinfoReady(this->track, this->packResponse(ONTOLOGY::ALBUM, INFO::TAGS,CONTEXT::TAG,albumTags)); - if(this->info == INFO::TAGS) return true; + this->responses << PULPO::RESPONSE {CONTEXT::TAG, albumTags}; + + if(this->request.info.size() == 1) break; else continue; - }else if(this->info == INFO::TAGS) continue; + }else continue; } } } - return true; + emit this->responseReady(this->request, this->responses); } -bool lastfm::parseTrack() -{ - QJsonParseError jsonParseError; - QJsonDocument jsonResponse = QJsonDocument::fromJson(static_cast(this->array).toUtf8(), &jsonParseError); +//void lastfm::parseTrack(const QByteArray &array) +//{ +//QJsonParseError jsonParseError; +//QJsonDocument jsonResponse = QJsonDocument::fromJson(static_cast(array).toUtf8(), &jsonParseError); - if (jsonParseError.error != QJsonParseError::NoError) - return false; +//if (jsonParseError.error != QJsonParseError::NoError) +//return false; - if (!jsonResponse.isObject()) - return false; +//if (!jsonResponse.isObject()) +//return false; - QJsonObject mainJsonObject(jsonResponse.object()); - auto data = mainJsonObject.toVariantMap(); - auto itemMap = data.value("track").toMap(); +//QJsonObject mainJsonObject(jsonResponse.object()); +//auto data = mainJsonObject.toVariantMap(); +//auto itemMap = data.value("track").toMap(); - if(itemMap.isEmpty()) return false; +//if(itemMap.isEmpty()) return false; - if(this->info == INFO::TAGS || this->info == INFO::ALL) - { +//if(this->info == INFO::TAGS || this->info == INFO::ALL) +//{ - auto listeners = itemMap.value("listeners").toString(); - auto playcount = itemMap.value("playcount").toString(); - QStringList stats = {listeners,playcount}; +// auto listeners = itemMap.value("listeners").toString(); +// auto playcount = itemMap.value("playcount").toString(); +// QStringList stats = {listeners,playcount}; - QStringList tags; - for(auto tag : itemMap.value("toptags").toMap().value("tag").toList()) - tags<infoReady(this->track, this->packResponse(ONTOLOGY::TRACK, INFO::TAGS, contexts)); +// emit this->infoReady(this->track, this->packResponse(ONTOLOGY::TRACK, INFO::TAGS, contexts)); - if(this->info == INFO::TAGS ) return true; - } +// if(this->info == INFO::TAGS ) return true; +//} - if(this->info == INFO::METADATA || this->info == INFO::ALL) - { - auto albumTitle = itemMap.value("album").toMap().value("title").toString(); - auto trackNumber = itemMap.value("album").toMap().value("@attr").toMap().value("position").toString(); +//if(this->info == INFO::METADATA || this->info == INFO::ALL) +//{ +// auto albumTitle = itemMap.value("album").toMap().value("title").toString(); +// auto trackNumber = itemMap.value("album").toMap().value("@attr").toMap().value("position").toString(); - emit this->infoReady(this->track, this->packResponse(ONTOLOGY::TRACK, INFO::METADATA, {{CONTEXT::TRACK_NUMBER,trackNumber}, {CONTEXT::ALBUM_TITLE,albumTitle}})); +// emit this->infoReady(this->track, this->packResponse(ONTOLOGY::TRACK, INFO::METADATA, {{CONTEXT::TRACK_NUMBER,trackNumber}, {CONTEXT::ALBUM_TITLE,albumTitle}})); - if(this->info == INFO::METADATA ) return true; - } +// if(this->info == INFO::METADATA ) return true; +//} - if(this->info == INFO::WIKI || this->info == INFO::ALL) - { - auto wiki = itemMap.value("wiki").toMap().value("content").toString(); - emit this->infoReady(this->track, this->packResponse(ONTOLOGY::TRACK, INFO::WIKI, CONTEXT::WIKI,wiki)); - if(wiki.isEmpty() && this->info == INFO::WIKI) return false; - } +//if(this->info == INFO::WIKI || this->info == INFO::ALL) +//{ +// auto wiki = itemMap.value("wiki").toMap().value("content").toString(); +// emit this->infoReady(this->track, this->packResponse(ONTOLOGY::TRACK, INFO::WIKI, CONTEXT::WIKI,wiki)); +// if(wiki.isEmpty() && this->info == INFO::WIKI) return false; +//} - if(this->info == INFO::ARTWORK || this->info == INFO::ALL) - { - auto images = itemMap.value("album").toMap().value("image").toList(); +//if(this->info == INFO::ARTWORK || this->info == INFO::ALL) +//{ +// auto images = itemMap.value("album").toMap().value("image").toList(); - QString artwork; +// QString artwork; - for(auto image : images) - if(image.toMap().value("size").toString()=="extralarge") - artwork = image.toMap().value("#text").toString(); +// for(auto image : images) +// if(image.toMap().value("size").toString()=="extralarge") +// artwork = image.toMap().value("#text").toString(); - emit this->infoReady(this->track, this->packResponse(ONTOLOGY::TRACK, INFO::ARTWORK, CONTEXT::IMAGE,this->startConnection(artwork))); - if(artwork.isEmpty() && this->info == INFO::ARTWORK) return false; - } +// emit this->infoReady(this->track, this->packResponse(ONTOLOGY::TRACK, INFO::ARTWORK, CONTEXT::IMAGE,this->startConnection(artwork))); +// if(artwork.isEmpty() && this->info == INFO::ARTWORK) return false; +//} - return false; -} +//return false; +//} -bool lastfm::parseSimilar() -{ +//void lastfm::parseSimilar() +//{ - QJsonParseError jsonParseError; - QJsonDocument jsonResponse = QJsonDocument::fromJson(static_cast(this->array).toUtf8(), &jsonParseError); +//QJsonParseError jsonParseError; +//QJsonDocument jsonResponse = QJsonDocument::fromJson(static_cast(array).toUtf8(), &jsonParseError); - if (jsonParseError.error != QJsonParseError::NoError) - return false; +//if (jsonParseError.error != QJsonParseError::NoError) +//return false; - if (!jsonResponse.isObject()) - return false; +//if (!jsonResponse.isObject()) +//return false; - QJsonObject mainJsonObject(jsonResponse.object()); - auto data = mainJsonObject.toVariantMap(); - auto itemMap = data.value("similarartists").toMap().value("artist"); +//QJsonObject mainJsonObject(jsonResponse.object()); +//auto data = mainJsonObject.toVariantMap(); +//auto itemMap = data.value("similarartists").toMap().value("artist"); - if(itemMap.isNull()) return false; +//if(itemMap.isNull()) return false; - QList items = itemMap.toList(); +//QList items = itemMap.toList(); - if(items.isEmpty()) return false; +//if(items.isEmpty()) return false; - if(this->info == INFO::TAGS || this->info == INFO::ALL) - { - QStringList artistSimilar; +//if(this->info == INFO::TAGS || this->info == INFO::ALL) +//{ +// QStringList artistSimilar; - for(auto item : items) - artistSimilar<infoReady(this->track, this->packResponse(ONTOLOGY::ARTIST, INFO::TAGS, CONTEXT::ARTIST_SIMILAR,artistSimilar)); +// emit this->infoReady(this->track, this->packResponse(ONTOLOGY::ARTIST, INFO::TAGS, CONTEXT::ARTIST_SIMILAR,artistSimilar)); - if(this->info == INFO::TAGS && !artistSimilar.isEmpty() ) return true; - } +// if(this->info == INFO::TAGS && !artistSimilar.isEmpty() ) return true; +//} - return false; -} +//return false; +//} diff --git a/pulpo/services/lastfmService.h b/pulpo/services/lastfmService.h index 24f9aaf..2831033 100644 --- a/pulpo/services/lastfmService.h +++ b/pulpo/services/lastfmService.h @@ -1,33 +1,34 @@ #ifndef LASTFMSERVICE_H #define LASTFMSERVICE_H #include -#include "../pulpo.h" +#include "../service.h" -class lastfm : public Pulpo +class lastfm : public Service { Q_OBJECT private: const QString API = "http://ws.audioscrobbler.com/2.0/"; const QString KEY = "&api_key=ba6f0bd3c887da9101c10a50cf2af133"; - bool parseSimilar(); + void parseSimilar(); public: - explicit lastfm(const FMH::MODEL &song); - virtual ~lastfm(); - virtual bool setUpService(const PULPO::ONTOLOGY &ontology, const PULPO::INFO &info); + explicit lastfm(); + ~lastfm(); + + void set(const PULPO::REQUEST &request) override final; protected: - virtual bool parseArtist(); - virtual bool parseAlbum(); - virtual bool parseTrack(); +// virtual void parseArtist(const QByteArray &array); + virtual void parseAlbum(const QByteArray &array) override final; +// virtual void parseTrack(const QByteArray &array); /*INTERNAL IMPLEMENTATION*/ }; #endif // LASTFM_H diff --git a/services/local/youtubedl.cpp b/services/local/youtubedl.cpp index e9b36ec..e79ccd1 100644 --- a/services/local/youtubedl.cpp +++ b/services/local/youtubedl.cpp @@ -1,214 +1,214 @@ /* Babe - tiny music player Copyright (C) 2017 Camilo Higuita This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "youtubedl.h" #include "../../pulpo/pulpo.h" #include "../../db/collectionDB.h" #include "../../utils/babeconsole.h" #if (defined (Q_OS_LINUX) && !defined (Q_OS_ANDROID)) #include "kde/notify.h" #endif using namespace BAE; youtubedl::youtubedl(QObject *parent) : QObject(parent) { #if (defined (Q_OS_LINUX) && !defined (Q_OS_ANDROID)) this->nof = new Notify(this); #endif } youtubedl::~youtubedl(){} void youtubedl::fetch(const QString &json) { QJsonParseError jsonParseError; auto jsonResponse = QJsonDocument::fromJson(json.toUtf8(), &jsonParseError); if (jsonParseError.error != QJsonParseError::NoError) return; if (!jsonResponse.isObject()) return; QJsonObject mainJsonObject(jsonResponse.object()); auto data = mainJsonObject.toVariantMap(); auto id = data.value("id").toString().trimmed(); auto title = data.value("title").toString().trimmed(); auto artist = data.value("artist").toString().trimmed(); auto album = data.value("album").toString().trimmed(); auto playlist = data.value("playlist").toString().trimmed(); auto page = data.value("page").toString().replace('"',"").trimmed(); bDebug::Instance()->msg("Fetching from Youtube: "+id+" "+title+" "+artist); FMH::MODEL infoMap; infoMap.insert(FMH::MODEL_KEY::TITLE, title); infoMap.insert(FMH::MODEL_KEY::ARTIST, artist); infoMap.insert(FMH::MODEL_KEY::ALBUM, album); infoMap.insert(FMH::MODEL_KEY::URL, page); infoMap.insert(FMH::MODEL_KEY::ID, id); infoMap.insert(FMH::MODEL_KEY::PLAYLIST, playlist); if(!this->ids.contains(infoMap[FMH::MODEL_KEY::ID])) { this->ids << infoMap[FMH::MODEL_KEY::ID]; auto process = new QProcess(this); process->setWorkingDirectory(YoutubeCachePath); //connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(processFinished())); //connect(process, SIGNAL(finished(int)), this, SLOT(processFinished_totally(int))); connect(process, static_cast(&QProcess::finished), [=](int exitCode, QProcess::ExitStatus exitStatus) { // qDebug()<<"processFinished_totally"<deleteLater(); }); #if (defined (Q_OS_LINUX) && !defined (Q_OS_ANDROID)) this->nof->notify("Song received!", infoMap[FMH::MODEL_KEY::TITLE]+ " - "+ infoMap[FMH::MODEL_KEY::ARTIST]+".\nWait a sec while the track is added to your collection :)"); #endif auto command = ydl; command = command.replace("$$$",infoMap[FMH::MODEL_KEY::ID])+" "+infoMap[FMH::MODEL_KEY::ID]; bDebug::Instance()->msg(command); process->start(command); } } void youtubedl::processFinished_totally(const int &state,const FMH::MODEL &info,const QProcess::ExitStatus &exitStatus) { - auto track = info; - - auto doneId = track[FMH::MODEL_KEY::ID]; - auto file = YoutubeCachePath+doneId+".m4a"; - - if(!BAE::fileExists(file)) return; - - ids.removeAll(doneId); - track.insert(FMH::MODEL_KEY::URL,file); - bDebug::Instance()->msg("Finished collection track with youtube-dl"); - - // qDebug()<msg("Trying to collect metadata of downloaded track"); - Pulpo pulpo; - pulpo.registerServices({PULPO::SERVICES::LastFm, PULPO::SERVICES::Spotify}); - pulpo.setOntology(PULPO::ONTOLOGY::TRACK); - pulpo.setInfo(PULPO::INFO::METADATA); - - QEventLoop loop; - QTimer timer; - connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit); - - timer.setSingleShot(true); - timer.setInterval(1000); - - connect(&pulpo, &Pulpo::infoReady, [&loop](const FMH::MODEL &track, const PULPO::RESPONSE &res) - { - bDebug::Instance()->msg("Setting collected track metadata"); - if(!res[PULPO::ONTOLOGY::TRACK][PULPO::INFO::METADATA].isEmpty()) - { - bDebug::Instance()->msg(res[PULPO::ONTOLOGY::TRACK][PULPO::INFO::METADATA][PULPO::CONTEXT::ALBUM_TITLE].toString()); - bDebug::Instance()->msg(res[PULPO::ONTOLOGY::TRACK][PULPO::INFO::METADATA][PULPO::CONTEXT::TRACK_NUMBER].toString()); - - TagInfo tag; - tag.feed(track[FMH::MODEL_KEY::URL]); - - auto albumRes = res[PULPO::ONTOLOGY::TRACK][PULPO::INFO::METADATA][PULPO::CONTEXT::ALBUM_TITLE].toString(); - - if(!albumRes.isEmpty() && albumRes != BAE::SLANG[W::UNKNOWN]) - tag.setAlbum(res[PULPO::ONTOLOGY::TRACK][PULPO::INFO::METADATA][PULPO::CONTEXT::ALBUM_TITLE].toString()); - else tag.setAlbum(track[FMH::MODEL_KEY::TITLE]); - - if(!res[PULPO::ONTOLOGY::TRACK][PULPO::INFO::METADATA][PULPO::CONTEXT::TRACK_NUMBER].toString().isEmpty()) - tag.setTrack(res[PULPO::ONTOLOGY::TRACK][PULPO::INFO::METADATA][PULPO::CONTEXT::TRACK_NUMBER].toInt()); - } - - loop.quit(); - }); - - pulpo.feed(track, PULPO::RECURSIVE::OFF); - - timer.start(); - loop.exec(); - timer.stop(); - - bDebug::Instance()->msg("Process finished totally for "+QString(state)+" "+doneId+" "+QString(exitStatus)); - - bDebug::Instance()->msg("Need to delete the id "+ doneId); - bDebug::Instance()->msg("Ids left to process: " + this->ids.join(",")); - } - } - - - tag.feed(file); - auto album = BAE::fixString(tag.getAlbum()); - auto trackNum = tag.getTrack(); - auto title = BAE::fixString(tag.getTitle()); /* to fix*/ - auto artist = BAE::fixString(tag.getArtist()); - auto genre = tag.getGenre(); - auto sourceUrl = QFileInfo(file).dir().path(); - auto duration = tag.getDuration(); - auto year = tag.getYear(); - - FMH::MODEL trackMap = - { - {FMH::MODEL_KEY::URL,file}, - {FMH::MODEL_KEY::TRACK,QString::number(trackNum)}, - {FMH::MODEL_KEY::TITLE,title}, - {FMH::MODEL_KEY::ARTIST,artist}, - {FMH::MODEL_KEY::ALBUM,album}, - {FMH::MODEL_KEY::DURATION,QString::number(duration)}, - {FMH::MODEL_KEY::GENRE,genre}, - {FMH::MODEL_KEY::SOURCE,sourceUrl}, - {FMH::MODEL_KEY::FAV, file.startsWith(BAE::YoutubeCachePath)?"1":"0"}, - {FMH::MODEL_KEY::RELEASEDATE,QString::number(year)} - }; - - auto con = CollectionDB::getInstance(); - con->addTrack(trackMap); - con->trackPlaylist({file}, track[FMH::MODEL_KEY::PLAYLIST]); - - if(this->ids.isEmpty()) emit this->done(); - - con->deleteLater(); +// auto track = info; + +// auto doneId = track[FMH::MODEL_KEY::ID]; +// auto file = YoutubeCachePath+doneId+".m4a"; + +// if(!BAE::fileExists(file)) return; + +// ids.removeAll(doneId); +// track.insert(FMH::MODEL_KEY::URL,file); +// bDebug::Instance()->msg("Finished collection track with youtube-dl"); + +// // qDebug()<msg("Trying to collect metadata of downloaded track"); +// Pulpo pulpo; +// pulpo.registerServices({PULPO::SERVICES::LastFm, PULPO::SERVICES::Spotify}); +// pulpo.setOntology(PULPO::ONTOLOGY::TRACK); +// pulpo.setInfo(PULPO::INFO::METADATA); + +// QEventLoop loop; +// QTimer timer; +// connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit); + +// timer.setSingleShot(true); +// timer.setInterval(1000); + +// connect(&pulpo, &Pulpo::infoReady, [&loop](const FMH::MODEL &track, const PULPO::RESPONSE &res) +// { +// bDebug::Instance()->msg("Setting collected track metadata"); +// if(!res[PULPO::ONTOLOGY::TRACK][PULPO::INFO::METADATA].isEmpty()) +// { +// bDebug::Instance()->msg(res[PULPO::ONTOLOGY::TRACK][PULPO::INFO::METADATA][PULPO::CONTEXT::ALBUM_TITLE].toString()); +// bDebug::Instance()->msg(res[PULPO::ONTOLOGY::TRACK][PULPO::INFO::METADATA][PULPO::CONTEXT::TRACK_NUMBER].toString()); + +// TagInfo tag; +// tag.feed(track[FMH::MODEL_KEY::URL]); + +// auto albumRes = res[PULPO::ONTOLOGY::TRACK][PULPO::INFO::METADATA][PULPO::CONTEXT::ALBUM_TITLE].toString(); + +// if(!albumRes.isEmpty() && albumRes != BAE::SLANG[W::UNKNOWN]) +// tag.setAlbum(res[PULPO::ONTOLOGY::TRACK][PULPO::INFO::METADATA][PULPO::CONTEXT::ALBUM_TITLE].toString()); +// else tag.setAlbum(track[FMH::MODEL_KEY::TITLE]); + +// if(!res[PULPO::ONTOLOGY::TRACK][PULPO::INFO::METADATA][PULPO::CONTEXT::TRACK_NUMBER].toString().isEmpty()) +// tag.setTrack(res[PULPO::ONTOLOGY::TRACK][PULPO::INFO::METADATA][PULPO::CONTEXT::TRACK_NUMBER].toInt()); +// } + +// loop.quit(); +// }); + +// pulpo.feed(track, PULPO::RECURSIVE::OFF); + +// timer.start(); +// loop.exec(); +// timer.stop(); + +// bDebug::Instance()->msg("Process finished totally for "+QString(state)+" "+doneId+" "+QString(exitStatus)); + +// bDebug::Instance()->msg("Need to delete the id "+ doneId); +// bDebug::Instance()->msg("Ids left to process: " + this->ids.join(",")); +// } +// } + + +// tag.feed(file); +// auto album = BAE::fixString(tag.getAlbum()); +// auto trackNum = tag.getTrack(); +// auto title = BAE::fixString(tag.getTitle()); /* to fix*/ +// auto artist = BAE::fixString(tag.getArtist()); +// auto genre = tag.getGenre(); +// auto sourceUrl = QFileInfo(file).dir().path(); +// auto duration = tag.getDuration(); +// auto year = tag.getYear(); + +// FMH::MODEL trackMap = +// { +// {FMH::MODEL_KEY::URL,file}, +// {FMH::MODEL_KEY::TRACK,QString::number(trackNum)}, +// {FMH::MODEL_KEY::TITLE,title}, +// {FMH::MODEL_KEY::ARTIST,artist}, +// {FMH::MODEL_KEY::ALBUM,album}, +// {FMH::MODEL_KEY::DURATION,QString::number(duration)}, +// {FMH::MODEL_KEY::GENRE,genre}, +// {FMH::MODEL_KEY::SOURCE,sourceUrl}, +// {FMH::MODEL_KEY::FAV, file.startsWith(BAE::YoutubeCachePath)?"1":"0"}, +// {FMH::MODEL_KEY::RELEASEDATE,QString::number(year)} +// }; + +// auto con = CollectionDB::getInstance(); +// con->addTrack(trackMap); +// con->trackPlaylist({file}, track[FMH::MODEL_KEY::PLAYLIST]); + +// if(this->ids.isEmpty()) emit this->done(); + +// con->deleteLater(); } void youtubedl::processFinished() { /* QByteArray processOutput; processOutput = process->readAllStandardOutput(); if (!QString(processOutput).isEmpty()) qDebug() << "Output: " << QString(processOutput);*/ } diff --git a/utils/bae.h b/utils/bae.h index ecb1b88..1a263cc 100644 --- a/utils/bae.h +++ b/utils/bae.h @@ -1,494 +1,494 @@ #ifndef BAE_H #define BAE_H #include "string" #include #include #include #include #include #include #include #include #include #include #include #ifdef STATIC_MAUIKIT #include "../mauikit/src/fm/fmh.h" #else #include #endif #include #define BABE_MAJOR_VERSION 0 #define BABE_MINOR_VERSION 1 #define BABE_PATCH_VERSION 0 #define BABE_VERSION_STR "0.1.0" #define BABE_VERSION KDE_MAKE_VERSION(0,1,0) using namespace std; namespace BAE { Q_NAMESPACE inline bool isMobile() { #if defined(Q_OS_ANDROID) return true; #elif defined(Q_OS_LINUX) return false; #elif defined(Q_OS_WIN32) return false; #elif defined(Q_OS_WIN64) return false; #elif defined(Q_OS_MACOS) return false; #elif defined(Q_OS_IOS) return true; #elif defined(Q_OS_HAIKU) return false; #endif } inline bool isAndroid() { #if defined(Q_OS_ANDROID) return true; #elif defined(Q_OS_LINUX) return false; #elif defined(Q_OS_WIN32) return false; #elif defined(Q_OS_WIN64) return false; #elif defined(Q_OS_MACOS) return false; #elif defined(Q_OS_IOS) return false; #elif defined(Q_OS_HAIKU) return false; #endif } enum SEG { HALF = 500, ONE = 1000, ONEHALF = 1500, TWO = 2000, THREE = 3000 }; enum SearchT { LIKE, SIMILAR }; typedef QMap SEARCH; static const SEARCH SearchTMap { { BAE::SearchT::LIKE, "like" }, { BAE::SearchT::SIMILAR, "similar" } }; enum class W : uint_fast8_t { ALL, NONE, LIKE, TAG, SIMILAR, UNKNOWN, DONE, DESC, ASC, CODE, MSG }; static const QMap SLANG = { {W::ALL, "ALL"}, {W::NONE, "NONE"}, {W::LIKE, "LIKE"}, {W::SIMILAR, "SIMILAR"}, {W::UNKNOWN, "UNKNOWN"}, {W::DONE, "DONE"}, {W::DESC, "DESC"}, {W::ASC, "ASC"}, {W::TAG, "TAG"}, {W::MSG, "MSG"}, {W::CODE, "CODE"} }; enum class TABLE : uint8_t { ALBUMS, ARTISTS, MOODS, PLAYLISTS, SOURCES, SOURCES_TYPES, TRACKS, TRACKS_MOODS, TRACKS_PLAYLISTS, TAGS, ALBUMS_TAGS, ARTISTS_TAGS, TRACKS_TAGS, LOGS, FOLDERS, ALL, NONE }; static const QMap TABLEMAP = { {TABLE::ALBUMS,"albums"}, {TABLE::ARTISTS,"artists"}, {TABLE::MOODS,"moods"}, {TABLE::PLAYLISTS,"playlists"}, {TABLE::SOURCES,"sources"}, {TABLE::SOURCES_TYPES,"sources_types"}, {TABLE::TRACKS,"tracks"}, {TABLE::TRACKS_MOODS,"tracks_moods"}, {TABLE::TRACKS_PLAYLISTS,"tracks_playlists"}, {TABLE::TAGS,"tags"}, {TABLE::ALBUMS_TAGS,"albums_tags"}, {TABLE::ARTISTS_TAGS,"artists_tags"}, {TABLE::TRACKS_TAGS,"tracks_tags"}, {TABLE::LOGS,"logs"}, {TABLE::FOLDERS,"folders"} }; enum class KEY :uint8_t { URL = 0, SOURCES_URL = 1, TRACK = 2, TITLE = 3, ARTIST = 4, ALBUM = 5, DURATION = 6, PLAYED = 7, BABE = 8, STARS = 9, RELEASE_DATE = 10, ADD_DATE = 11, LYRICS = 12, GENRE = 13, ART = 14, TAG = 15, MOOD = 16, PLAYLIST = 17, ARTWORK = 18, WIKI = 19, SOURCE_TYPE = 20, CONTEXT = 21, RETRIEVAL_DATE = 22, COMMENT = 23, ID = 24, SQL = 25, NONE = 26 }; typedef QMap DB; typedef QList DB_LIST; static const DB KEYMAP = { {KEY::URL, "url"}, {KEY::SOURCES_URL, "sources_url"}, {KEY::TRACK, "track"}, {KEY::TITLE, "title"}, {KEY::ARTIST, "artist"}, {KEY::ALBUM, "album"}, {KEY::DURATION, "duration"}, {KEY::PLAYED, "played"}, {KEY::BABE, "babe"}, {KEY::STARS, "stars"}, {KEY::RELEASE_DATE, "releaseDate"}, {KEY::ADD_DATE, "addDate"}, {KEY::LYRICS, "lyrics"}, {KEY::GENRE, "genre"}, {KEY::ART, "art"}, {KEY::TAG, "tag"}, {KEY::MOOD, "mood"}, {KEY::PLAYLIST, "playlist"}, {KEY::ARTWORK, "artwork"}, {KEY::WIKI, "wiki"}, {KEY::SOURCE_TYPE, "source_types_id"}, {KEY::CONTEXT, "context"}, {KEY::RETRIEVAL_DATE, "retrieval_date"}, {KEY::ID, "id"}, {KEY::COMMENT, "comment"}, {KEY::SQL, "sql"} }; static const DB TracksColsMap = { {KEY::URL, KEYMAP[KEY::URL]}, {KEY::SOURCES_URL, KEYMAP[KEY::SOURCES_URL]}, {KEY::TRACK, KEYMAP[KEY::TRACK]}, {KEY::TITLE, KEYMAP[KEY::TITLE]}, {KEY::ARTIST, KEYMAP[KEY::ARTIST]}, {KEY::ALBUM, KEYMAP[KEY::ALBUM]}, {KEY::DURATION, KEYMAP[KEY::DURATION]}, {KEY::PLAYED, KEYMAP[KEY::PLAYED]}, {KEY::BABE, KEYMAP[KEY::BABE]}, {KEY::STARS, KEYMAP[KEY::STARS]}, {KEY::RELEASE_DATE, KEYMAP[KEY::RELEASE_DATE]}, {KEY::ADD_DATE, KEYMAP[KEY::ADD_DATE]}, {KEY::LYRICS, KEYMAP[KEY::LYRICS]}, {KEY::GENRE, KEYMAP[KEY::GENRE]}, {KEY::ART, KEYMAP[KEY::ART]} }; inline QString transformTime(const qint64 &value) { QString tStr; if (value) { QTime time((value/3600)%60, (value/60)%60, value%60, (value*1000)%1000); QString format = "mm:ss"; if (value > 3600) format = "hh:mm:ss"; tStr = time.toString(format); } return tStr.isEmpty() ? "00:00" : tStr; } inline QString getNameFromLocation(const QString &str) { QString ret; int index = 0; for(int i = str.size() - 1; i >= 0; i--) if(str[i] == '/') { index = i + 1; i = -1; } for(; index < str.size(); index++) ret.push_back(str[index]); return ret; } const QString SettingPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)+"/vvave/"; const QString ArtworkPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+"/vvave/artwork/"; const QString CollectionDBPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+"/vvave/"; const QString CachePath = BAE::isMobile() ? BAE::ArtworkPath : QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation)+"/vvave/"; const QString YoutubeCachePath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation)+"/vvave/youtube/"; const QString NotifyDir = SettingPath; const QStringList MusicPaths = QStandardPaths::standardLocations(QStandardPaths::MusicLocation); const QStringList DownloadsPaths = QStandardPaths::standardLocations(QStandardPaths::DownloadLocation); const QString MusicPath = FMH::MusicPath; const QString HomePath = FMH::HomePath; const QString DownloadsPath = FMH::DownloadsPath; const QString BabePort = "8483"; const QString LinkPort = "3333"; const QString App = "vvave"; const QString Description = "vvave music player"; const QString Version = BABE_VERSION_STR; const QString DBName = "collection.db"; const QStringList MoodColors = {"#F0FF01","#01FF5B","#3DAEFD","#B401FF","#E91E63"}; const QStringList defaultSources = QStringList() << BAE::MusicPath << BAE::DownloadsPath << BAE::MusicPaths << BAE::DownloadsPaths << BAE::YoutubeCachePath; inline QString fixTitle(const QString &title,const QString &s,const QString &e) { QString newTitle; for(int i=0; i«»,.?/{}\'\"\\\[\\\]\\\\]"))); QString title = str; title = title.remove(QChar::Null); title = title.contains(QChar('\u0000')) ? title.replace(QChar('\u0000'),"") : title; title = title.contains("(") && title.contains(")") ? fixTitle(title, "(",")") : title; title = title.contains("[") && title.contains("]") ? fixTitle(title, "[","]") : title; title = title.contains("{") && title.contains("}") ? fixTitle(title, "{","}") : title; title = title.contains("ft", Qt::CaseInsensitive) ? removeSubstring(title, "ft") : title; title = title.contains("ft.", Qt::CaseInsensitive) ? removeSubstring(title, "ft.") : title; title = title.contains("featuring", Qt::CaseInsensitive) ? removeSubstring(title, "featuring"):title; title = title.contains("feat", Qt::CaseInsensitive) ? removeSubstring(title, "feat") : title; title = title.contains("official video", Qt::CaseInsensitive) ? removeSubstring(title, "official video"):title; title = title.contains("live", Qt::CaseInsensitive) ? removeSubstring(title, "live") : title; title = title.contains("...") ? title.replace("..." ,"") : title; title = title.contains("|") ? title.replace("|", "") : title; title = title.contains("|") ? removeSubstring(title, "|") : title; title = title.contains('"') ? title.replace('"', "") : title; title = title.contains(":") ? title.replace(":", "") : title; // title=title.contains("&")? title.replace("&", "and"):title; //qDebug()<<"fixed string:"<bytesAvailable()) return true; else return false; } } #endif // BAE_H diff --git a/utils/brain.cpp b/utils/brain.cpp index d366d5e..5c6a7c2 100644 --- a/utils/brain.cpp +++ b/utils/brain.cpp @@ -1,642 +1,677 @@ #include "brain.h" #include "../services/local/taginfo.h" #include "../utils/babeconsole.h" #include "../db/collectionDB.h" Brain::Brain() : QObject (nullptr) { this->db = CollectionDB::getInstance(); qRegisterMetaType("FMH::MODEL"); qRegisterMetaType("TABLE"); qRegisterMetaType("PULPO::RESPONSE"); this->pulpo = new Pulpo(this); - connect(pulpo, &Pulpo::infoReady, this, &Brain::connectionParser); + connect(pulpo, &Pulpo::finished, [this]() + { + if(this->queue.hasNext()) + { +// this->t.msleep(3000); + this->pulpo->request(this->queue.next()); + }else + { + qDebug()<< "NOTHING ELSE IN QUEUE"; + emit this->done(TABLE::ALBUMS); + } + }); this->moveToThread(&t); this->t.start(); } Brain::~Brain() { qDebug()<<"Deleting Brainz obj"; this->stop(); } void Brain::start() { if(this->isRunning()) return; this->go = true; QMetaObject::invokeMethod(this, "synapse"); } void Brain::stop() { this->go = false; this->t.quit(); this->t.wait(); } void Brain::pause() { this->go = false; } bool Brain::isRunning() const { return this->go; } void Brain::setInterval(const uint &value) { qDebug()<< "reseting the interval brainz"; this->interval = value; } void Brain::appendRequest(const REQUEST &request) { this->queue << request; } void Brain::synapse() { if(this->go) { this->artworks(); // this->trackLyrics(); // this->tags(); // this->wikis(); } if(this->queue.hasNext()) - { - const auto request = this->queue.next(); + this->pulpo->request(this->queue.next()); - this->pulpo->registerServices(request.services); - this->pulpo->setOntology(request.ontology); - this->pulpo->setInfo(request.info); - this->pulpo->feed(request.data, request.recursive); - } this->go = false; } -void Brain::connectionParser(FMH::MODEL track, RESPONSE response) +void Brain::connectionParser(PULPO::REQUEST request, PULPO::RESPONSES responses) { - if(this->queue.hasNext()) { - const auto request = this->queue.next(); - - this->pulpo->registerServices(request.services); - this->pulpo->setOntology(request.ontology); - this->pulpo->setInfo(request.info); - this->t.msleep(this->interval); - - this->pulpo->feed(request.data, request.recursive); - + this->pulpo->request(this->queue.next()); }else { qDebug()<< "NOTHING ELSE IN QUEUE"; emit this->done(TABLE::ALBUMS); } - - for(auto res : response.keys()) - { - switch(res) - { - case ONTOLOGY::ALBUM: this->parseAlbumInfo(track, response[res]); break; - case ONTOLOGY::ARTIST: this->parseArtistInfo(track, response[res]); break; - case ONTOLOGY::TRACK: this->parseTrackInfo(track, response[res]); break; - default: break; - } - } + for(auto res : responses) + qDebug()<< PULPO::CONTEXT_MAP[res.context] << res.value; +// for(const auto &res : responses) +// { +// for(const auto &onto : res.keys()) +// switch(onto) +// { +// case ONTOLOGY::ALBUM: this->parseAlbumInfo(request.track, res[onto]); break; +// case ONTOLOGY::ARTIST: this->parseArtistInfo(request.track, res[onto]); break; +// case ONTOLOGY::TRACK: this->parseTrackInfo(request.track, response[res]); break; +// } +// } } void Brain::parseAlbumInfo(FMH::MODEL &track, const INFO_K &response) { for(auto info : response.keys()) switch(info) { - case PULPO::INFO::TAGS: - { - for(auto context : response[info].keys()) + case PULPO::INFO::TAGS: + { + for(auto context : response[info].keys()) - if(!response[info][context].toMap().isEmpty()) - { - for(auto tag : response[info][context].toMap().keys() ) - this->db->tagsAlbum(track, tag, CONTEXT_MAP[context]); + if(!response[info][context].toMap().isEmpty()) + { + for(auto tag : response[info][context].toMap().keys() ) + this->db->tagsAlbum(track, tag, CONTEXT_MAP[context]); - }else if (!response[info][context].toStringList().isEmpty()) - { - for(auto tag : response[info][context].toStringList() ) - this->db->tagsAlbum(track, tag, CONTEXT_MAP[context]); + }else if (!response[info][context].toStringList().isEmpty()) + { + for(auto tag : response[info][context].toStringList() ) + this->db->tagsAlbum(track, tag, CONTEXT_MAP[context]); - } else if (!response[info][context].toString().isEmpty()) - { - this->db->tagsAlbum(track, response[info][context].toString(), CONTEXT_MAP[context]); - } - break; - } + } else if (!response[info][context].toString().isEmpty()) + { + this->db->tagsAlbum(track, response[info][context].toString(), CONTEXT_MAP[context]); + } + break; + } - case PULPO::INFO::ARTWORK: - { - if(!response[info].isEmpty()) + case PULPO::INFO::ARTWORK: + { + if(!response[info].isEmpty()) - if(!response[info][CONTEXT::IMAGE].toString().isEmpty()) - { - qDebug()<<"SAVING ARTWORK FOR: " << track[FMH::MODEL_KEY::ALBUM]; - auto downloader = new FMH::Downloader; + if(!response[info][CONTEXT::IMAGE].toString().isEmpty()) + { + qDebug()<<"SAVING ARTWORK FOR: " << track[FMH::MODEL_KEY::ALBUM]; + auto downloader = new FMH::Downloader; - connect(downloader, &FMH::Downloader::fileSaved, [=](QString path) - { - qDebug()<< "Saving artwork file to" << path; - FMH::MODEL newTrack = track; - newTrack[FMH::MODEL_KEY::ARTWORK] = path; - this->db->insertArtwork(newTrack); + connect(downloader, &FMH::Downloader::fileSaved, [=](QString path) + { + qDebug()<< "Saving artwork file to" << path; + FMH::MODEL newTrack = track; + newTrack[FMH::MODEL_KEY::ARTWORK] = path; + this->db->insertArtwork(newTrack); - downloader->deleteLater(); + downloader->deleteLater(); - }); + }); - QStringList filePathList = response[info][CONTEXT::IMAGE].toString().split('/'); - const auto format = "." + filePathList.at(filePathList.count() - 1).split(".").last(); - QString name = !track[FMH::MODEL_KEY::ALBUM].isEmpty() ? track[FMH::MODEL_KEY::ARTIST] + "_" + track[FMH::MODEL_KEY::ALBUM] : track[FMH::MODEL_KEY::ARTIST]; - name.replace("/", "-"); - name.replace("&", "-"); - downloader->setFile(response[info][CONTEXT::IMAGE].toString(), BAE::CachePath + name + format); - } + QStringList filePathList = response[info][CONTEXT::IMAGE].toString().split('/'); + const auto format = "." + filePathList.at(filePathList.count() - 1).split(".").last(); + QString name = !track[FMH::MODEL_KEY::ALBUM].isEmpty() ? track[FMH::MODEL_KEY::ARTIST] + "_" + track[FMH::MODEL_KEY::ALBUM] : track[FMH::MODEL_KEY::ARTIST]; + name.replace("/", "-"); + name.replace("&", "-"); + downloader->setFile(response[info][CONTEXT::IMAGE].toString(), BAE::CachePath + name + format); + } - break; - } + break; + } - case PULPO::INFO::WIKI: - { - if(!response[info].isEmpty()) - for (auto context : response[info].keys()) - this->db->wikiAlbum(track, response[info][context].toString()); - break; - } + case PULPO::INFO::WIKI: + { + if(!response[info].isEmpty()) + for (auto context : response[info].keys()) + this->db->wikiAlbum(track, response[info][context].toString()); + break; + } - default: continue; + default: continue; } } void Brain::parseArtistInfo(FMH::MODEL &track, const INFO_K &response) { for(auto info : response.keys()) { switch(info) { - case PULPO::INFO::TAGS: + case PULPO::INFO::TAGS: + { + if(!response[info].isEmpty()) { - if(!response[info].isEmpty()) + for(auto context : response[info].keys()) { - for(auto context : response[info].keys()) + if(!response[info][context].toMap().isEmpty()) { - if(!response[info][context].toMap().isEmpty()) - { - for(auto tag : response[info][context].toMap().keys() ) - this->db->tagsArtist(track, tag, CONTEXT_MAP[context]); - - }else if(!response[info][context].toStringList().isEmpty()) - { - for(auto tag : response[info][context].toStringList() ) - this->db->tagsArtist(track, tag, CONTEXT_MAP[context]); - - }else if(!response[info][context].toString().isEmpty()) - { - this->db->tagsArtist(track, response[info][context].toString(), CONTEXT_MAP[context]); - } - } + for(auto tag : response[info][context].toMap().keys() ) + this->db->tagsArtist(track, tag, CONTEXT_MAP[context]); - } break; - } + }else if(!response[info][context].toStringList().isEmpty()) + { + for(auto tag : response[info][context].toStringList() ) + this->db->tagsArtist(track, tag, CONTEXT_MAP[context]); - case PULPO::INFO::ARTWORK: - { - if(!response[info].isEmpty()) - { - if(!response[info][CONTEXT::IMAGE].toByteArray().isEmpty()) + }else if(!response[info][context].toString().isEmpty()) { - BAE::saveArt(track, response[info][CONTEXT::IMAGE].toByteArray(), BAE::CachePath); - this->db->insertArtwork(track); + this->db->tagsArtist(track, response[info][context].toString(), CONTEXT_MAP[context]); } } - break; - } + } break; + } - case PULPO::INFO::WIKI: + case PULPO::INFO::ARTWORK: + { + if(!response[info].isEmpty()) { - if(!response[info].isEmpty()) + if(!response[info][CONTEXT::IMAGE].toByteArray().isEmpty()) { - for (auto context : response[info].keys()) - this->db->wikiArtist(track, response[info][context].toString()); + BAE::saveArt(track, response[info][CONTEXT::IMAGE].toByteArray(), BAE::CachePath); + this->db->insertArtwork(track); } + } - break; + break; + } + + case PULPO::INFO::WIKI: + { + if(!response[info].isEmpty()) + { + for (auto context : response[info].keys()) + this->db->wikiArtist(track, response[info][context].toString()); } - default: continue; + break; + } + + default: continue; } } } void Brain::parseTrackInfo(FMH::MODEL &track, const INFO_K &response) { for(auto info : response.keys()) switch(info) { - case PULPO::INFO::TAGS: + case PULPO::INFO::TAGS: + { + if(!response[info].isEmpty()) { - if(!response[info].isEmpty()) + for(auto context : response[info].keys()) { - for(auto context : response[info].keys()) + if (!response[info][context].toStringList().isEmpty()) { - if (!response[info][context].toStringList().isEmpty()) - { - for(auto tag : response[info][context].toStringList() ) - this->db->tagsTrack(track, tag, CONTEXT_MAP[context]); - } - - if (!response[info][context].toString().isEmpty()) - this->db->tagsTrack(track, response[info][context].toString(), CONTEXT_MAP[context]); + for(auto tag : response[info][context].toStringList() ) + this->db->tagsTrack(track, tag, CONTEXT_MAP[context]); } - } - break; + if (!response[info][context].toString().isEmpty()) + this->db->tagsTrack(track, response[info][context].toString(), CONTEXT_MAP[context]); + } } - case PULPO::INFO::WIKI: - { - if(!response[info].isEmpty()) - { - if (!response[info][CONTEXT::WIKI].toString().isEmpty()) - this->db->wikiTrack(track, response[info][CONTEXT::WIKI].toString()); + break; + } - } + case PULPO::INFO::WIKI: + { + if(!response[info].isEmpty()) + { + if (!response[info][CONTEXT::WIKI].toString().isEmpty()) + this->db->wikiTrack(track, response[info][CONTEXT::WIKI].toString()); - break; } - case PULPO::INFO::ARTWORK: + break; + } + + case PULPO::INFO::ARTWORK: + { + if(!response[info].isEmpty()) { - if(!response[info].isEmpty()) + if(!response[info][CONTEXT::IMAGE].toByteArray().isEmpty()) { - if(!response[info][CONTEXT::IMAGE].toByteArray().isEmpty()) - { - BAE::saveArt(track, response[info][CONTEXT::IMAGE].toByteArray(),CachePath); - this->db->insertArtwork(track); - } + BAE::saveArt(track, response[info][CONTEXT::IMAGE].toByteArray(),CachePath); + this->db->insertArtwork(track); } - - break; } - case PULPO::INFO::METADATA: + break; + } + + case PULPO::INFO::METADATA: + { + TagInfo tag; + for(auto context :response[info].keys()) { - TagInfo tag; - for(auto context :response[info].keys()) + switch(context) { - switch(context) + case CONTEXT::ALBUM_TITLE: + { + qDebug()<<"SETTING TRACK MISSING METADATA"; + + tag.feed(track[FMH::MODEL_KEY::URL]); + if(!response[info][context].toString().isEmpty()) { - case CONTEXT::ALBUM_TITLE: - { - qDebug()<<"SETTING TRACK MISSING METADATA"; - - tag.feed(track[FMH::MODEL_KEY::URL]); - if(!response[info][context].toString().isEmpty()) - { - tag.setAlbum(response[info][context].toString()); - this->db->albumTrack(track, response[info][context].toString()); - } - - break; - } - - case CONTEXT::TRACK_NUMBER: - { - tag.feed(track[FMH::MODEL_KEY::URL]); - if(!response[info][context].toString().isEmpty()) - tag.setTrack(response[info][context].toInt()); - - break; - } - - default: continue; + tag.setAlbum(response[info][context].toString()); + this->db->albumTrack(track, response[info][context].toString()); } + + break; } - break; - } + case CONTEXT::TRACK_NUMBER: + { + tag.feed(track[FMH::MODEL_KEY::URL]); + if(!response[info][context].toString().isEmpty()) + tag.setTrack(response[info][context].toInt()); - case PULPO::INFO::LYRICS: - { - if(!response[info][CONTEXT::LYRIC].toString().isEmpty()) - this->db->lyricsTrack(track, response[info][CONTEXT::LYRIC].toString()); - break; + break; + } + + default: continue; + } } - default: continue; + break; + } + + case PULPO::INFO::LYRICS: + { + if(!response[info][CONTEXT::LYRIC].toString().isEmpty()) + this->db->lyricsTrack(track, response[info][CONTEXT::LYRIC].toString()); + break; + } + + default: continue; } } void Brain::trackInfo() { // auto queryTxt = QString("SELECT %1, %2, %3 FROM %4 WHERE %3 = 'UNKNOWN' GROUP BY %2, a.%3 ").arg(KEYMAP[KEY::TITLE], // KEYMAP[KEY::ARTIST],KEYMAP[KEY::ALBUM],TABLEMAP[TABLE::TRACKS]); // QSqlQuery query (queryTxt); // pulpo.setInfo(INFO::METADATA); // for(auto track : this->getDBData(query)) // { // qDebug()<<"UNKOWN TRACK TITLE:"<done(TABLE::TRACKS); this->trackArtworks(); this->trackLyrics(); this->trackTags(); this->trackWikis(); } void Brain::albumInfo() { if(!go) return; this->albumArtworks(); this->albumTags(); this->albumWikis(); } void Brain::artistInfo() { if(!go) return; this->artistArtworks(); this->artistTags(); this->artistWikis(); } void Brain::artworks() { if(!go) return; this->albumArtworks(); // this->artistArtworks(); // this->trackArtworks(); } void Brain::tags() { if(!go) return; this->albumTags(); this->artistTags(); this->trackTags(); } void Brain::wikis() { if(!go) return; this->albumWikis(); this->artistWikis(); this->trackWikis(); } void Brain::albumArtworks() { if(!this->go) return; auto services = {PULPO::SERVICES::LastFm, PULPO::SERVICES::Spotify, PULPO::SERVICES::MusicBrainz}; auto ontology = PULPO::ONTOLOGY::ALBUM; auto queryTxt = QString("SELECT %1, %2 FROM %3 WHERE %4 = ''").arg(KEYMAP[KEY::ALBUM], KEYMAP[KEY::ARTIST], TABLEMAP[TABLE::ALBUMS], KEYMAP[KEY::ARTWORK]); /* BEFORE FETCHING ONLINE LOOK UP IN THE CACHE FOR THE IMAGES*/ auto artworks = this->db->getDBData(queryTxt); for(auto album : artworks) if(BAE::artworkCache(album, FMH::MODEL_KEY::ALBUM)) this->db->insertArtwork(album); artworks = this->db->getDBData(queryTxt); qDebug() << "Getting missing albums artworks"<< artworks.length(); FMH::MODEL_LIST data = { {{FMH::MODEL_KEY::ARTIST, "Kali Uchis"}, {FMH::MODEL_KEY::ALBUM, "Por Vida"}}, + {{FMH::MODEL_KEY::ARTIST, "Laura Marling"}, {FMH::MODEL_KEY::ALBUM, "Once I Was An Eagle"}}, {{FMH::MODEL_KEY::ARTIST, "Lorde"}, {FMH::MODEL_KEY::ALBUM, "Melodrama"}}, - {{FMH::MODEL_KEY::ARTIST, "Chris Isaak"}, {FMH::MODEL_KEY::ALBUM, "Heart Shaped World"}}, - {{FMH::MODEL_KEY::ARTIST, "Choker"}, {FMH::MODEL_KEY::ALBUM, "Peak"}}, - {{FMH::MODEL_KEY::ARTIST, "John Mayer"}, {FMH::MODEL_KEY::ALBUM, "Continuum"}}, - {{FMH::MODEL_KEY::ARTIST, "070 Shake"}, {FMH::MODEL_KEY::ALBUM, "Glitter"}}, - {{FMH::MODEL_KEY::ARTIST, "Snoh Aalegra"}, {FMH::MODEL_KEY::ALBUM, "FEELS"}}, - {{FMH::MODEL_KEY::ARTIST, "Sonder"}, {FMH::MODEL_KEY::ALBUM, "Into"}}, - - {{FMH::MODEL_KEY::ARTIST, "The Weeknd"}, {FMH::MODEL_KEY::ALBUM, "Trilogy"}}, - {{FMH::MODEL_KEY::ARTIST, "Lana Del Rey"}, {FMH::MODEL_KEY::ALBUM, "Honeymoon"}} + {{FMH::MODEL_KEY::ARTIST, "Rihanna"}, {FMH::MODEL_KEY::ALBUM, "ANTI"}}, +// {{FMH::MODEL_KEY::ARTIST, "Chris Isaak"}, {FMH::MODEL_KEY::ALBUM, "Heart Shaped World"}}, +// {{FMH::MODEL_KEY::ARTIST, "Choker"}, {FMH::MODEL_KEY::ALBUM, "Peak"}}, +// {{FMH::MODEL_KEY::ARTIST, "John Mayer"}, {FMH::MODEL_KEY::ALBUM, "Continuum"}}, +// {{FMH::MODEL_KEY::ARTIST, "070 Shake"}, {FMH::MODEL_KEY::ALBUM, "Glitter"}}, +// {{FMH::MODEL_KEY::ARTIST, "Snoh Aalegra"}, {FMH::MODEL_KEY::ALBUM, "FEELS"}}, +// {{FMH::MODEL_KEY::ARTIST, "Sonder"}, {FMH::MODEL_KEY::ALBUM, "Into"}}, +// {{FMH::MODEL_KEY::ARTIST, "JONES"}, {FMH::MODEL_KEY::ALBUM, "New Skin"}}, +// {{FMH::MODEL_KEY::ARTIST, "Artic Monkeys"}, {FMH::MODEL_KEY::ALBUM, "AM"}}, +// {{FMH::MODEL_KEY::ARTIST, "Lady Gaga"}, {FMH::MODEL_KEY::ALBUM, "ARTPOP"}}, +// {{FMH::MODEL_KEY::ARTIST, "Aimee Mann"}, {FMH::MODEL_KEY::ALBUM, "I'm With Stupid"}}, +// {{FMH::MODEL_KEY::ARTIST, "Smith Westerns"}, {FMH::MODEL_KEY::ALBUM, "Dye It Blonde"}}, +// {{FMH::MODEL_KEY::ARTIST, "J. Cole"}, {FMH::MODEL_KEY::ALBUM, "2014 Forest Hills Drive"}}, +// {{FMH::MODEL_KEY::ARTIST, "Frank Ocean"}, {FMH::MODEL_KEY::ALBUM, "Channel Orange"}}, +// {{FMH::MODEL_KEY::ARTIST, "The Weeknd"}, {FMH::MODEL_KEY::ALBUM, "Trilogy"}}, +// {{FMH::MODEL_KEY::ARTIST, "Lana Del Rey"}, {FMH::MODEL_KEY::ALBUM, "Honeymoon"}}, +// {{FMH::MODEL_KEY::ARTIST, "Lana Del Rey"}, {FMH::MODEL_KEY::ALBUM, "Ultraviolence"}} }; for(const auto &item : artworks) { REQUEST request; - request.data = item; + request.track = item; request.ontology = ontology; request.services = services; - request.info = PULPO::INFO::ARTWORK; - request.recursive = PULPO::RECURSIVE::OFF; - request.cb = nullptr; + request.info = {PULPO::INFO::ARTWORK}; + request.callback = [this](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; + connect(downloader, &FMH::Downloader::fileSaved, [=](QString path) + { + qDebug()<< "Saving artwork file to" << path; + FMH::MODEL newTrack = request.track; + newTrack[FMH::MODEL_KEY::ARTWORK] = path; + this->db->insertArtwork(newTrack); + + 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); + + } + } + }; - this->queue << request; +// this->queue << request; } // emit this->done(TABLE::ALBUMS); } void Brain::albumTags() { if(!this->go) return; auto services = {PULPO::SERVICES::LastFm, PULPO::SERVICES::Spotify, PULPO::SERVICES::MusicBrainz}; auto ontology = PULPO::ONTOLOGY::ALBUM; //select album, artist from albums where album not in (select album from albums_tags) and artist not in (select artist from albums_tags) qDebug() << ("Getting missing albums tags"); auto queryTxt = QString("SELECT %1, %2 FROM %3 WHERE %1 NOT IN ( SELECT %1 FROM %4 ) AND %2 NOT IN ( SELECT %2 FROM %4 )").arg(KEYMAP[KEY::ALBUM], KEYMAP[KEY::ARTIST], TABLEMAP[TABLE::ALBUMS], TABLEMAP[TABLE::ALBUMS_TAGS]); // REQUEST request; // request.data = this->db->getDBData(queryTxt); // request.ontology = ontology; // request.services = services; // request.info = PULPO::INFO::TAGS; // request.recursive = PULPO::RECURSIVE::ON; // request.cb = nullptr; // this->appendRequest(request); } void Brain::albumWikis() { if(!this->go) return; auto services = {PULPO::SERVICES::LastFm, PULPO::SERVICES::Spotify, PULPO::SERVICES::MusicBrainz}; auto ontology = PULPO::ONTOLOGY::ALBUM; qDebug() << ("Getting missing albums wikis"); auto queryTxt = QString("SELECT %1, %2 FROM %3 WHERE %4 = '' ").arg(KEYMAP[KEY::ALBUM], KEYMAP[KEY::ARTIST], TABLEMAP[TABLE::ALBUMS], KEYMAP[KEY::WIKI]); // this->setInfo(this->db->getDBData(queryTxt), ontology, services, PULPO::INFO::WIKI, PULPO::RECURSIVE::OFF, nullptr); } void Brain::artistArtworks() { if(!this->go) return; auto services = {PULPO::SERVICES::LastFm, PULPO::SERVICES::Spotify, PULPO::SERVICES::MusicBrainz, PULPO::SERVICES::Genius}; auto ontology = PULPO::ONTOLOGY::ARTIST; qDebug() << ("Getting missing artists artworks"); auto queryTxt = QString("SELECT %1 FROM %2 WHERE %3 = ''").arg(KEYMAP[KEY::ARTIST], TABLEMAP[TABLE::ARTISTS], KEYMAP[KEY::ARTWORK]); auto artworks = this->db->getDBData(queryTxt); /* BEFORE FETCHING ONLINE LOOK UP IN THE CACHE FOR THE IMAGE */ // for(auto artist : artworks) // if(BAE::artworkCache(artist, KEY::ARTIST)) // this->insertArtwork(artist); artworks = this->db->getDBData(queryTxt); // this->setInfo(artworks, ontology, services, PULPO::INFO::ARTWORK, PULPO::RECURSIVE::OFF, nullptr); emit this->done(TABLE::ARTISTS); } void Brain::artistTags() { if(!this->go) return; auto services = {PULPO::SERVICES::LastFm, PULPO::SERVICES::Spotify, PULPO::SERVICES::MusicBrainz, PULPO::SERVICES::Genius}; auto ontology = PULPO::ONTOLOGY::ARTIST; //select artist from artists where artist not in (select album from albums_tags) qDebug() << ("Getting missing artists tags"); auto queryTxt = QString("SELECT %1 FROM %2 WHERE %1 NOT IN ( SELECT %1 FROM %3 ) ").arg(KEYMAP[KEY::ARTIST], TABLEMAP[TABLE::ARTISTS], TABLEMAP[TABLE::ARTISTS_TAGS]); // this->setInfo(this->db->getDBData(queryTxt), ontology, services, PULPO::INFO::TAGS, PULPO::RECURSIVE::ON, nullptr); } void Brain::artistWikis() { if(!this->go) return; auto services = {PULPO::SERVICES::LastFm, PULPO::SERVICES::Spotify, PULPO::SERVICES::MusicBrainz, PULPO::SERVICES::Genius}; auto ontology = PULPO::ONTOLOGY::ARTIST; qDebug() << ("Getting missing artists wikis"); auto queryTxt = QString("SELECT %1 FROM %2 WHERE %3 = '' ").arg(KEYMAP[KEY::ARTIST], TABLEMAP[TABLE::ARTISTS], KEYMAP[KEY::WIKI]); // this->setInfo(this->db->getDBData(queryTxt), ontology, services, PULPO::INFO::WIKI, PULPO::RECURSIVE::OFF, nullptr); } void Brain::trackArtworks() { if(!this->go) return; auto ontology = PULPO::ONTOLOGY::TRACK; auto services = {PULPO::SERVICES::LastFm, PULPO::SERVICES::Spotify, PULPO::SERVICES::MusicBrainz, PULPO::SERVICES::Genius}; qDebug() << ("Getting missing track artwork"); //select url, title, album, artist from tracks t inner join albums a on a.album=t.album and a.artist=t.artist where a.artwork = '' auto queryTxt = QString("SELECT DISTINCT t.%1, t.%2, t.%3, t.%4 FROM %5 t INNER JOIN %6 a ON a.%3 = t.%3 AND a.%4 = t.%4 WHERE a.%7 = '' GROUP BY a.%3, a.%4 ").arg(KEYMAP[KEY::URL], KEYMAP[KEY::TITLE], KEYMAP[KEY::ARTIST], KEYMAP[KEY::ALBUM], TABLEMAP[TABLE::TRACKS], TABLEMAP[TABLE::ALBUMS], KEYMAP[KEY::ARTWORK]); auto artworks = this->db->getDBData(queryTxt); // this->setInfo(artworks, ontology, services, PULPO::INFO::ARTWORK, PULPO::RECURSIVE::OFF); emit this->done(TABLE::ALBUMS); } void Brain::trackLyrics() { if(!this->go) return; auto ontology = PULPO::ONTOLOGY::TRACK; auto services = {PULPO::SERVICES::LyricWikia, PULPO::SERVICES::Genius}; qDebug() << ("Getting missing track lyrics"); auto queryTxt = QString("SELECT %1, %2, %3 FROM %4 WHERE %5 = ''").arg(KEYMAP[KEY::URL], KEYMAP[KEY::TITLE], KEYMAP[KEY::ARTIST], TABLEMAP[TABLE::TRACKS], KEYMAP[KEY::LYRICS]); // this->setInfo(this->db->getDBData(queryTxt), ontology, services, PULPO::INFO::LYRICS, PULPO::RECURSIVE::OFF); } void Brain::trackTags() { if(!this->go) return; auto ontology = PULPO::ONTOLOGY::TRACK; auto services = {PULPO::SERVICES::LastFm, PULPO::SERVICES::Spotify, PULPO::SERVICES::MusicBrainz, PULPO::SERVICES::Genius}; qDebug() << ("Getting missing track tags"); // select title, artist, album from tracks t where url not in (select url from tracks_tags) auto queryTxt = QString("SELECT %1, %2, %3, %4 FROM %5 WHERE %1 NOT IN ( SELECT %1 FROM %6 )").arg(KEYMAP[KEY::URL], KEYMAP[KEY::TITLE], KEYMAP[KEY::ARTIST], KEYMAP[KEY::ALBUM], TABLEMAP[TABLE::TRACKS], TABLEMAP[TABLE::TRACKS_TAGS]); // this->setInfo(this->db->getDBData(queryTxt), ontology, services, PULPO::INFO::TAGS, RECURSIVE::ON, nullptr); } void Brain::trackWikis() { if(!this->go) return; auto ontology = PULPO::ONTOLOGY::TRACK; auto services = {PULPO::SERVICES::LastFm, PULPO::SERVICES::Spotify, PULPO::SERVICES::MusicBrainz, PULPO::SERVICES::Genius}; qDebug() << ("Getting missing track wikis"); auto queryTxt = QString("SELECT %1, %2, %3, %4 FROM %5 WHERE %6 = ''").arg(KEYMAP[KEY::URL], KEYMAP[KEY::TITLE], KEYMAP[KEY::ARTIST], KEYMAP[KEY::ALBUM], TABLEMAP[TABLE::TRACKS], KEYMAP[KEY::WIKI]); // this->setInfo(this->db->getDBData(queryTxt), ontology, services, PULPO::INFO::WIKI, RECURSIVE::OFF); } diff --git a/utils/brain.h b/utils/brain.h index 572b81f..1aac414 100644 --- a/utils/brain.h +++ b/utils/brain.h @@ -1,130 +1,117 @@ #ifndef BRAIN_H #define BRAIN_H /* This deamon keeps on running while there are missing information about a track, * it should have the option to turn it off, but the main idea is to here have the * brains of the app and collection. so this must be a very good a neat implementation */ #include #include #include "bae.h" #include "../pulpo/pulpo.h" using namespace BAE; using namespace PULPO; -struct REQUEST -{ -public: - FMH::MODEL data; - PULPO::ONTOLOGY ontology; - QList services; - PULPO::INFO info; - PULPO::RECURSIVE recursive = PULPO::RECURSIVE::ON; - void (*cb)(FMH::MODEL) = nullptr; -}; struct QUEUE { private: - QList requests; + QList requests; int index = -1; public: - REQUEST next() + PULPO::REQUEST next() { index++; if(index < 0 || index >= requests.size()) - return REQUEST{}; + return PULPO::REQUEST{}; const auto res = requests.at(index); - - qDebug() << index << requests.size() << res.data; - return res; } bool hasNext() const { return index + 1 < requests.size(); } int size() const { return requests.size(); } - void append(const REQUEST &request) + void append(const PULPO::REQUEST &request) { requests << request; } - void operator<< (const REQUEST &request) + void operator<< (const PULPO::REQUEST &request) { append(request); } }; class CollectionDB; class Brain : public QObject { Q_OBJECT public: explicit Brain(); ~Brain(); void start(); void stop(); void pause(); bool isRunning() const; void setInterval(const uint &value); - void appendRequest(const REQUEST &request); + void appendRequest(const PULPO::REQUEST &request); public slots: void synapse(); - void connectionParser(FMH::MODEL track, PULPO::RESPONSE response); + void connectionParser(PULPO::REQUEST request, PULPO::RESPONSES responses); void parseAlbumInfo(FMH::MODEL &track, const PULPO::INFO_K &response); void parseArtistInfo(FMH::MODEL &track, const PULPO::INFO_K &response); void parseTrackInfo(FMH::MODEL &track, const PULPO::INFO_K &response); void trackInfo(); void artistInfo(); void albumInfo(); void artworks(); void tags(); void wikis(); void albumArtworks(); void albumTags(); void albumWikis(); void artistArtworks(); void artistTags(); void artistWikis(); void trackArtworks(); void trackLyrics(); void trackTags(); void trackWikis(); private: QThread t; CollectionDB *db; uint interval = 1500; bool go = false; QUEUE queue; Pulpo *pulpo; signals: void finished(); void done(const TABLE &type); }; #endif // BRAIN_H