File indexing completed on 2024-04-14 04:44:02
0001 /* 0002 SPDX-FileCopyrightText: 2018 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr> 0003 0004 SPDX-License-Identifier: LGPL-3.0-or-later 0005 */ 0006 0007 #include "modeldataloader.h" 0008 0009 #include "filescanner.h" 0010 #include "filewriter.h" 0011 0012 #include <QFileInfo> 0013 0014 class ModelDataLoaderPrivate 0015 { 0016 public: 0017 0018 DatabaseInterface *mDatabase = nullptr; 0019 0020 ElisaUtils::PlayListEntryType mModelType = ElisaUtils::Unknown; 0021 0022 ModelDataLoader::FilterType mFilterType = ModelDataLoader::FilterType::UnknownFilter; 0023 0024 QString mArtist; 0025 0026 QString mAlbumTitle; 0027 0028 QString mAlbumArtist; 0029 0030 QString mGenre; 0031 0032 qulonglong mDatabaseId = 0; 0033 0034 FileScanner mFileScanner; 0035 0036 FileWriter mFileWriter; 0037 }; 0038 0039 ModelDataLoader::ModelDataLoader(QObject *parent) : QObject(parent), d(std::make_unique<ModelDataLoaderPrivate>()) 0040 { 0041 } 0042 0043 ModelDataLoader::~ModelDataLoader() = default; 0044 0045 void ModelDataLoader::setDatabase(DatabaseInterface *database) 0046 { 0047 d->mDatabase = database; 0048 0049 connect(database, &DatabaseInterface::genresAdded, 0050 this, &ModelDataLoader::genresAdded); 0051 connect(database, &DatabaseInterface::albumsAdded, 0052 this, &ModelDataLoader::databaseAlbumsAdded); 0053 connect(database, &DatabaseInterface::albumModified, 0054 this, &ModelDataLoader::albumModified); 0055 connect(database, &DatabaseInterface::albumRemoved, 0056 this, &ModelDataLoader::albumRemoved); 0057 connect(database, &DatabaseInterface::tracksAdded, 0058 this, &ModelDataLoader::databaseTracksAdded); 0059 connect(database, &DatabaseInterface::trackModified, 0060 this, &ModelDataLoader::trackModified); 0061 connect(database, &DatabaseInterface::trackRemoved, 0062 this, &ModelDataLoader::trackRemoved); 0063 connect(database, &DatabaseInterface::artistsAdded, 0064 this, &ModelDataLoader::databaseArtistsAdded); 0065 connect(database, &DatabaseInterface::artistRemoved, 0066 this, &ModelDataLoader::artistRemoved); 0067 connect(this, &ModelDataLoader::saveTrackModified, 0068 database, &DatabaseInterface::insertTracksList); 0069 connect(this, &ModelDataLoader::removeRadio, 0070 database, &DatabaseInterface::removeRadio); 0071 connect(database, &DatabaseInterface::radioAdded, 0072 this, &ModelDataLoader::radioAdded); 0073 connect(database, &DatabaseInterface::radioModified, 0074 this, &ModelDataLoader::radioModified); 0075 connect(database, &DatabaseInterface::radioRemoved, 0076 this, &ModelDataLoader::radioRemoved); 0077 connect(database, &DatabaseInterface::cleanedDatabase, 0078 this, &ModelDataLoader::clearedDatabase); 0079 } 0080 0081 void ModelDataLoader::loadData(ElisaUtils::PlayListEntryType dataType) 0082 { 0083 if (!d->mDatabase) { 0084 return; 0085 } 0086 0087 d->mFilterType = ModelDataLoader::FilterType::NoFilter; 0088 0089 switch (dataType) 0090 { 0091 case ElisaUtils::Album: 0092 Q_EMIT allAlbumsData(d->mDatabase->allAlbumsData()); 0093 break; 0094 case ElisaUtils::Artist: 0095 Q_EMIT allArtistsData(d->mDatabase->allArtistsData()); 0096 break; 0097 case ElisaUtils::Composer: 0098 break; 0099 case ElisaUtils::Genre: 0100 Q_EMIT allGenresData(d->mDatabase->allGenresData()); 0101 break; 0102 case ElisaUtils::Lyricist: 0103 break; 0104 case ElisaUtils::Track: 0105 Q_EMIT allTracksData(d->mDatabase->allTracksData()); 0106 break; 0107 case ElisaUtils::FileName: 0108 case ElisaUtils::Unknown: 0109 case ElisaUtils::Container: 0110 case ElisaUtils::PlayList: 0111 break; 0112 case ElisaUtils::Radio: 0113 Q_EMIT allRadiosData(d->mDatabase->allRadiosData()); 0114 break; 0115 } 0116 } 0117 0118 void ModelDataLoader::loadDataByAlbumId(ElisaUtils::PlayListEntryType dataType, qulonglong databaseId) 0119 { 0120 if (!d->mDatabase) { 0121 return; 0122 } 0123 0124 d->mFilterType = ModelDataLoader::FilterType::FilterById; 0125 d->mDatabaseId = databaseId; 0126 0127 switch (dataType) 0128 { 0129 case ElisaUtils::Album: 0130 break; 0131 case ElisaUtils::Artist: 0132 break; 0133 case ElisaUtils::Composer: 0134 break; 0135 case ElisaUtils::Genre: 0136 break; 0137 case ElisaUtils::Lyricist: 0138 break; 0139 case ElisaUtils::Track: 0140 Q_EMIT allTracksData(d->mDatabase->albumData(databaseId)); 0141 break; 0142 case ElisaUtils::FileName: 0143 case ElisaUtils::Unknown: 0144 case ElisaUtils::Radio: 0145 case ElisaUtils::Container: 0146 case ElisaUtils::PlayList: 0147 break; 0148 } 0149 } 0150 0151 void ModelDataLoader::loadDataByGenre(ElisaUtils::PlayListEntryType dataType, const QString &genre) 0152 { 0153 if (!d->mDatabase) { 0154 return; 0155 } 0156 0157 d->mFilterType = ModelDataLoader::FilterType::FilterByGenre; 0158 d->mGenre = genre; 0159 0160 switch (dataType) 0161 { 0162 case ElisaUtils::Artist: 0163 Q_EMIT allArtistsData(d->mDatabase->allArtistsDataByGenre(genre)); 0164 break; 0165 case ElisaUtils::Album: 0166 case ElisaUtils::Composer: 0167 case ElisaUtils::Track: 0168 case ElisaUtils::Genre: 0169 case ElisaUtils::Lyricist: 0170 case ElisaUtils::FileName: 0171 case ElisaUtils::Unknown: 0172 case ElisaUtils::Radio: 0173 case ElisaUtils::Container: 0174 case ElisaUtils::PlayList: 0175 break; 0176 } 0177 } 0178 0179 void ModelDataLoader::loadDataByArtist(ElisaUtils::PlayListEntryType dataType, const QString &artist) 0180 { 0181 if (!d->mDatabase) { 0182 return; 0183 } 0184 0185 d->mFilterType = ModelDataLoader::FilterType::FilterByArtist; 0186 d->mArtist = artist; 0187 0188 switch (dataType) 0189 { 0190 case ElisaUtils::Album: 0191 Q_EMIT allAlbumsData(d->mDatabase->allAlbumsDataByArtist(artist)); 0192 break; 0193 case ElisaUtils::Artist: 0194 case ElisaUtils::Composer: 0195 case ElisaUtils::Track: 0196 case ElisaUtils::Genre: 0197 case ElisaUtils::Lyricist: 0198 case ElisaUtils::FileName: 0199 case ElisaUtils::Unknown: 0200 case ElisaUtils::Radio: 0201 case ElisaUtils::Container: 0202 case ElisaUtils::PlayList: 0203 break; 0204 } 0205 } 0206 0207 void ModelDataLoader::loadDataByGenreAndArtist(ElisaUtils::PlayListEntryType dataType, const QString &genre, const QString &artist) 0208 { 0209 if (!d->mDatabase) { 0210 return; 0211 } 0212 0213 d->mFilterType = ModelDataLoader::FilterType::FilterByGenreAndArtist; 0214 d->mArtist = artist; 0215 d->mGenre = genre; 0216 0217 switch (dataType) 0218 { 0219 case ElisaUtils::Album: 0220 Q_EMIT allAlbumsData(d->mDatabase->allAlbumsDataByGenreAndArtist(genre, artist)); 0221 break; 0222 case ElisaUtils::Artist: 0223 case ElisaUtils::Composer: 0224 case ElisaUtils::Genre: 0225 case ElisaUtils::Lyricist: 0226 case ElisaUtils::Track: 0227 case ElisaUtils::FileName: 0228 case ElisaUtils::Unknown: 0229 case ElisaUtils::Radio: 0230 case ElisaUtils::Container: 0231 case ElisaUtils::PlayList: 0232 break; 0233 } 0234 } 0235 0236 void ModelDataLoader::loadDataByDatabaseIdAndUrl(ElisaUtils::PlayListEntryType dataType, 0237 qulonglong databaseId, const QUrl &url) 0238 { 0239 if (!d->mDatabase) { 0240 return; 0241 } 0242 0243 d->mFilterType = ModelDataLoader::FilterType::FilterById; 0244 d->mDatabaseId = databaseId; 0245 0246 switch (dataType) 0247 { 0248 case ElisaUtils::FileName: 0249 case ElisaUtils::Track: 0250 Q_EMIT allTrackData(d->mDatabase->trackDataFromDatabaseIdAndUrl(databaseId, url)); 0251 break; 0252 case ElisaUtils::Radio: 0253 Q_EMIT allRadioData(d->mDatabase->radioDataFromDatabaseId(databaseId)); 0254 break; 0255 case ElisaUtils::Album: 0256 case ElisaUtils::Artist: 0257 case ElisaUtils::Composer: 0258 case ElisaUtils::Genre: 0259 case ElisaUtils::Lyricist: 0260 case ElisaUtils::Unknown: 0261 case ElisaUtils::Container: 0262 case ElisaUtils::PlayList: 0263 break; 0264 } 0265 } 0266 0267 void ModelDataLoader::loadDataByUrl(ElisaUtils::PlayListEntryType dataType, const QUrl &url) 0268 { 0269 if (!d->mDatabase) { 0270 return; 0271 } 0272 0273 d->mFilterType = ModelDataLoader::FilterType::UnknownFilter; 0274 0275 switch (dataType) 0276 { 0277 case ElisaUtils::FileName: 0278 case ElisaUtils::Track: 0279 { 0280 auto databaseId = d->mDatabase->trackIdFromFileName(url); 0281 if (databaseId != 0) { 0282 Q_EMIT allTrackData(d->mDatabase->trackDataFromDatabaseIdAndUrl(databaseId, url)); 0283 } else { 0284 auto result = d->mFileScanner.scanOneFile(url); 0285 Q_EMIT allTrackData(result); 0286 } 0287 break; 0288 } 0289 case ElisaUtils::Radio: 0290 { 0291 auto databaseId = d->mDatabase->radioIdFromFileName(url); 0292 if (databaseId != 0) { 0293 Q_EMIT allRadioData(d->mDatabase->radioDataFromDatabaseId(databaseId)); 0294 } else { 0295 auto result = d->mFileScanner.scanOneFile(url); 0296 Q_EMIT allRadioData(result); 0297 } 0298 break; 0299 } 0300 case ElisaUtils::Album: 0301 case ElisaUtils::Artist: 0302 case ElisaUtils::Composer: 0303 case ElisaUtils::Genre: 0304 case ElisaUtils::Lyricist: 0305 case ElisaUtils::Unknown: 0306 case ElisaUtils::Container: 0307 case ElisaUtils::PlayList: 0308 break; 0309 } 0310 } 0311 0312 void ModelDataLoader::loadRecentlyPlayedData(ElisaUtils::PlayListEntryType dataType) 0313 { 0314 if (!d->mDatabase) { 0315 return; 0316 } 0317 0318 d->mFilterType = ModelDataLoader::FilterType::FilterByRecentlyPlayed; 0319 0320 switch (dataType) 0321 { 0322 case ElisaUtils::Track: 0323 Q_EMIT allTracksData(d->mDatabase->recentlyPlayedTracksData(50)); 0324 break; 0325 case ElisaUtils::Album: 0326 case ElisaUtils::Artist: 0327 case ElisaUtils::Composer: 0328 case ElisaUtils::Genre: 0329 case ElisaUtils::Lyricist: 0330 case ElisaUtils::FileName: 0331 case ElisaUtils::Unknown: 0332 case ElisaUtils::Radio: 0333 case ElisaUtils::Container: 0334 case ElisaUtils::PlayList: 0335 break; 0336 } 0337 } 0338 0339 void ModelDataLoader::loadFrequentlyPlayedData(ElisaUtils::PlayListEntryType dataType) 0340 { 0341 if (!d->mDatabase) { 0342 return; 0343 } 0344 0345 d->mFilterType = ModelDataLoader::FilterType::FilterByFrequentlyPlayed; 0346 0347 switch (dataType) 0348 { 0349 case ElisaUtils::Track: 0350 Q_EMIT allTracksData(d->mDatabase->frequentlyPlayedTracksData(50)); 0351 break; 0352 case ElisaUtils::Album: 0353 case ElisaUtils::Artist: 0354 case ElisaUtils::Composer: 0355 case ElisaUtils::Genre: 0356 case ElisaUtils::Lyricist: 0357 case ElisaUtils::FileName: 0358 case ElisaUtils::Unknown: 0359 case ElisaUtils::Radio: 0360 case ElisaUtils::Container: 0361 case ElisaUtils::PlayList: 0362 break; 0363 } 0364 } 0365 0366 void ModelDataLoader::databaseTracksAdded(const ListTrackDataType &newData) 0367 { 0368 switch(d->mFilterType) { 0369 case ModelDataLoader::FilterType::NoFilter: 0370 Q_EMIT tracksAdded(newData); 0371 break; 0372 case ModelDataLoader::FilterType::FilterById: 0373 { 0374 auto filteredData = newData; 0375 0376 auto new_end = std::remove_if(filteredData.begin(), filteredData.end(), 0377 [&](const auto &oneTrack) { return oneTrack.albumId() != d->mDatabaseId; }); 0378 filteredData.erase(new_end, filteredData.end()); 0379 0380 Q_EMIT tracksAdded(filteredData); 0381 break; 0382 } 0383 case ModelDataLoader::FilterType::FilterByGenre: 0384 case ModelDataLoader::FilterType::FilterByGenreAndArtist: 0385 case ModelDataLoader::FilterType::FilterByArtist: 0386 case ModelDataLoader::FilterType::FilterByRecentlyPlayed: 0387 case ModelDataLoader::FilterType::FilterByFrequentlyPlayed: 0388 case ModelDataLoader::FilterType::FilterByPath: 0389 case ModelDataLoader::FilterType::UnknownFilter: 0390 break; 0391 } 0392 } 0393 0394 void ModelDataLoader::databaseArtistsAdded(const ListArtistDataType &newData) 0395 { 0396 switch(d->mFilterType) { 0397 case ModelDataLoader::FilterType::FilterByGenre: 0398 { 0399 auto filteredData = newData; 0400 auto new_end = std::remove_if(filteredData.begin(), filteredData.end(), 0401 [&](const auto &oneArtist){return !d->mDatabase->internalArtistMatchGenre(oneArtist.databaseId(), d->mGenre);}); 0402 filteredData.erase(new_end, filteredData.end()); 0403 0404 Q_EMIT artistsAdded(filteredData); 0405 0406 break; 0407 } 0408 case ModelDataLoader::FilterType::NoFilter: 0409 Q_EMIT artistsAdded(newData); 0410 break; 0411 case ModelDataLoader::FilterType::FilterByGenreAndArtist: 0412 case ModelDataLoader::FilterType::FilterByArtist: 0413 case ModelDataLoader::FilterType::FilterById: 0414 case ModelDataLoader::FilterType::FilterByRecentlyPlayed: 0415 case ModelDataLoader::FilterType::FilterByFrequentlyPlayed: 0416 case ModelDataLoader::FilterType::FilterByPath: 0417 case ModelDataLoader::FilterType::UnknownFilter: 0418 break; 0419 } 0420 } 0421 0422 void ModelDataLoader::databaseAlbumsAdded(const ListAlbumDataType &newData) 0423 { 0424 switch(d->mFilterType) { 0425 case ModelDataLoader::FilterType::FilterByArtist: 0426 { 0427 auto filteredData = newData; 0428 auto new_end = std::remove_if(filteredData.begin(), filteredData.end(), 0429 [&](const auto &oneAlbum){return oneAlbum.artist() != d->mArtist;}); 0430 filteredData.erase(new_end, filteredData.end()); 0431 0432 Q_EMIT albumsAdded(filteredData); 0433 0434 break; 0435 } 0436 case ModelDataLoader::FilterType::NoFilter: 0437 Q_EMIT albumsAdded(newData); 0438 break; 0439 case ModelDataLoader::FilterType::FilterByGenreAndArtist: 0440 { 0441 auto filteredData = newData; 0442 auto new_end = std::remove_if(filteredData.begin(), filteredData.end(), 0443 [&](const auto &oneAlbum){ 0444 const auto &allGenres = oneAlbum.genres(); 0445 return oneAlbum.artist() != d->mArtist || !allGenres.contains(d->mGenre); 0446 }); 0447 filteredData.erase(new_end, filteredData.end()); 0448 0449 Q_EMIT albumsAdded(filteredData); 0450 0451 break; 0452 } 0453 case ModelDataLoader::FilterType::FilterByGenre: 0454 case ModelDataLoader::FilterType::FilterById: 0455 case ModelDataLoader::FilterType::FilterByRecentlyPlayed: 0456 case ModelDataLoader::FilterType::FilterByFrequentlyPlayed: 0457 case ModelDataLoader::FilterType::FilterByPath: 0458 case ModelDataLoader::FilterType::UnknownFilter: 0459 break; 0460 } 0461 } 0462 0463 void ModelDataLoader::trackHasBeenModified(ModelDataLoader::ListTrackDataType trackDataType, const QHash<QString, QUrl> &covers) 0464 { 0465 for(auto &oneTrack : trackDataType) { 0466 if (oneTrack.elementType() == ElisaUtils::Track) { 0467 d->mFileWriter.writeAllMetaDataToFile(oneTrack.resourceURI(), oneTrack); 0468 0469 QFileInfo trackFile{oneTrack.resourceURI().toLocalFile()}; 0470 0471 oneTrack[DataTypes::FileModificationTime] = trackFile.fileTime(QFileDevice::FileModificationTime); 0472 0473 erase_if(oneTrack, [](const auto &trackDataItr) {return trackDataItr->isNull();}); 0474 } 0475 } 0476 0477 Q_EMIT saveTrackModified(trackDataType, covers); 0478 } 0479 0480 void ModelDataLoader::updateFileMetaData(const DataTypes::TrackDataType &trackDataType, const QUrl &url) 0481 { 0482 d->mFileWriter.writeAllMetaDataToFile(url, trackDataType); 0483 } 0484 0485 void ModelDataLoader::updateSingleFileMetaData(const QUrl &url, DataTypes::ColumnsRoles role, const QVariant &data) 0486 { 0487 d->mFileWriter.writeSingleMetaDataToFile(url, role, data); 0488 } 0489 0490 #include "moc_modeldataloader.cpp"