diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f01a2ce7..36bababc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1085,7 +1085,6 @@ link_directories( ${GOBJECT_LIBRARY_DIRS} ${GNUTLS_LIBRARY_DIRS} ${SQLITE_LIBRARY_DIRS} - ${TAGLIB_LIBRARY_DIRS} ${SINGLEAPPLICATION_LIBRARY_DIRS} ${SINGLECOREAPPLICATION_LIBRARY_DIRS} ${QTSPARKLE_LIBRARY_DIRS} @@ -1160,7 +1159,6 @@ target_include_directories(strawberry_lib SYSTEM PUBLIC ${GOBJECT_INCLUDE_DIRS} ${GNUTLS_INCLUDE_DIRS} ${SQLITE_INCLUDE_DIRS} - ${TAGLIB_INCLUDE_DIRS} ) if(HAVE_QPA_QPLATFORMNATIVEINTERFACE_H) @@ -1185,7 +1183,6 @@ target_link_libraries(strawberry_lib PUBLIC ${GOBJECT_LIBRARIES} ${GNUTLS_LIBRARIES} ${SQLITE_LIBRARIES} - ${TAGLIB_LIBRARIES} ${QT_LIBRARIES} ${SINGLEAPPLICATION_LIBRARIES} ${SINGLECOREAPPLICATION_LIBRARIES} diff --git a/src/collection/collectionbackend.cpp b/src/collection/collectionbackend.cpp index 4b0edd2f..a082175c 100644 --- a/src/collection/collectionbackend.cpp +++ b/src/collection/collectionbackend.cpp @@ -374,11 +374,12 @@ void CollectionBackend::SongPathChanged(const Song &song, const QFileInfo &new_f // Take a song and update its path Song updated_song = song; - updated_song.InitFromFilePartial(new_file.absoluteFilePath()); updated_song.set_source(source_); - SongList updated_songs; - updated_songs << updated_song; - AddOrUpdateSongs(updated_songs); + updated_song.set_url(QUrl::fromLocalFile(new_file.absoluteFilePath())); + updated_song.set_basefilename(new_file.fileName()); + updated_song.InitArtManual(); + + AddOrUpdateSongs(SongList() << updated_song); } diff --git a/src/core/song.cpp b/src/core/song.cpp index df3fa9a2..10664681 100644 --- a/src/core/song.cpp +++ b/src/core/song.cpp @@ -23,9 +23,6 @@ #include -#include -#include - #ifdef HAVE_LIBGPOD # include # include @@ -155,7 +152,11 @@ const QString Song::kVariousArtists("various artists"); const QStringList Song::kArticles = QStringList() << "the " << "a " << "an "; -const QStringList Song::kAcceptedExtensions = QStringList() << "aac" << "ac3" << "dts"; +const QStringList Song::kAcceptedExtensions = QStringList() << "wav" << "flac" << "wv" << "ogg" << "oga" << "opus" << "spx" << "ape" << "mpc" + << "mp2" << "mp3" << "m4a" << "mp4" << "aac" << "asf" << "asx" << "wma" + << "aif << aiff" << "mka" << "tta" << "dsf" << "dsd" + << "cue" << "m3u" << "m3u8" << "pls" << "xspf" << "asxini" + << "ac3" << "dts"; struct Song::Private : public QSharedData { @@ -229,8 +230,6 @@ struct Song::Private : public QSharedData { bool init_from_file_; // Whether this song was loaded from a file using taglib. bool suspicious_tags_; // Whether our encoding guesser thinks these tags might be incorrectly encoded. - QString error_; // Song load error set by song loader. - }; Song::Private::Private(Song::Source source) @@ -405,8 +404,6 @@ bool Song::art_manual_is_valid() const { bool Song::has_valid_art() const { return art_automatic_is_valid() || art_manual_is_valid(); } -const QString &Song::error() const { return d->error_; } - void Song::set_id(int id) { d->id_ = id; } void Song::set_valid(bool v) { d->valid_ = v; } @@ -766,10 +763,6 @@ void Song::Init(const QString &title, const QString &artist, const QString &albu } -void Song::set_genre_id3(int id) { - set_genre(TStringToQString(TagLib::ID3v1::genre(id))); -} - void Song::InitFromProtobuf(const spb::tagreader::SongMetadata &pb) { if (d->source_ == Source_Unknown) d->source_ = Source_LocalFile; @@ -1058,29 +1051,15 @@ void Song::InitFromQuery(const SqlRow &q, bool reliable_metadata, int col) { } -void Song::InitFromFilePartial(const QString &filename) { +void Song::InitFromFilePartial(const QString &filename, const QFileInfo &fileinfo) { set_url(QUrl::fromLocalFile(filename)); - QFileInfo info(filename); - d->basefilename_ = info.fileName(); - - TagLib::FileRef fileref(QFile::encodeName(filename).constData()); - if (fileref.file()) { - d->valid_ = true; - d->source_ = Source_LocalFile; - if (d->art_manual_.isEmpty()) InitArtManual(); - } - else if (kAcceptedExtensions.contains(info.suffix(), Qt::CaseInsensitive)) { - d->valid_ = true; - d->source_ = Source_LocalFile; - d->filetype_ = FiletypeByExtension(info.suffix()); - d->title_ = info.fileName(); - if (d->art_manual_.isEmpty()) InitArtManual(); - } - else { - d->valid_ = false; - d->error_ = QObject::tr("File %1 is not recognized as a valid audio file.").arg(filename); - } + d->valid_ = true; + d->source_ = Source_LocalFile; + d->filetype_ = FiletypeByExtension(fileinfo.suffix()); + d->basefilename_ = fileinfo.fileName(); + d->title_ = fileinfo.fileName(); + if (d->art_manual_.isEmpty()) InitArtManual(); } diff --git a/src/core/song.h b/src/core/song.h index f0645040..78a27b9a 100644 --- a/src/core/song.h +++ b/src/core/song.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -159,8 +160,8 @@ class Song { void Init(const QString &title, const QString &artist, const QString &album, qint64 beginning, qint64 end); void InitFromProtobuf(const spb::tagreader::SongMetadata &pb); void InitFromQuery(const SqlRow &query, bool reliable_metadata, int col = 0); - void InitFromFilePartial(const QString &filename); // Just store the filename: incomplete but fast - void InitArtManual(); // Check if there is already a art in the cache and store the filename in art_manual + void InitFromFilePartial(const QString &filename, const QFileInfo &fileinfo); + void InitArtManual(); void InitArtAutomatic(); bool MergeFromSimpleMetaBundle(const Engine::SimpleMetaBundle &bundle); @@ -289,8 +290,6 @@ class Song { const QUrl &effective_stream_url() const; const QImage &image() const; - const QString &error() const; - // Pretty accessors QString PrettyTitle() const; QString PrettyTitleWithArtist() const; @@ -319,7 +318,6 @@ class Song { void set_year(int v); void set_originalyear(int v); void set_genre(const QString &v); - void set_genre_id3(int id); void set_compilation(bool v); void set_composer(const QString &v); void set_performer(const QString &v); diff --git a/src/core/songloader.cpp b/src/core/songloader.cpp index 667f2063..e2733c86 100644 --- a/src/core/songloader.cpp +++ b/src/core/songloader.cpp @@ -158,22 +158,33 @@ SongLoader::Result SongLoader::LoadFilenamesBlocking() { SongLoader::Result SongLoader::LoadLocalPartial(const QString &filename) { qLog(Debug) << "Fast Loading local file" << filename; + + QFileInfo fileinfo(filename); + + if (!fileinfo.exists()) { + errors_ << tr("File %1 does not exist.").arg(filename); + return Error; + } + // First check to see if it's a directory - if so we can load all the songs inside right away. - if (QFileInfo(filename).isDir()) { + if (fileinfo.isDir()) { LoadLocalDirectory(filename); return Success; } - Song song(Song::Source_LocalFile); - song.InitFromFilePartial(filename); - if (song.is_valid()) { - songs_ << song; - return Success; - } - else { - errors_ << song.error(); - return Error; + + // Assume it's just a normal file + if (TagReaderClient::Instance()->IsMediaFileBlocking(filename) || Song::kAcceptedExtensions.contains(fileinfo.suffix(), Qt::CaseInsensitive)) { + Song song(Song::Source_LocalFile); + song.InitFromFilePartial(filename, fileinfo); + if (song.is_valid()) { + songs_ << song; + return Success; + } } + errors_ << QObject::tr("File %1 is not recognized as a valid audio file.").arg(filename); + return Error; + } SongLoader::Result SongLoader::LoadAudioCD() { @@ -253,8 +264,15 @@ SongLoader::Result SongLoader::LoadLocal(const QString &filename) { SongLoader::Result SongLoader::LoadLocalAsync(const QString &filename) { + QFileInfo fileinfo(filename); + + if (!fileinfo.exists()) { + errors_ << tr("File %1 does not exist.").arg(filename); + return Error; + } + // First check to see if it's a directory - if so we will load all the songs inside right away. - if (QFileInfo(filename).isDir()) { + if (fileinfo.isDir()) { LoadLocalDirectory(filename); return Success; } @@ -270,7 +288,7 @@ SongLoader::Result SongLoader::LoadLocalAsync(const QString &filename) { ParserBase *parser = playlist_parser_->ParserForMagic(data); if (!parser) { // Check the file extension as well, maybe the magic failed, or it was a basic M3U file which is just a plain list of filenames. - parser = playlist_parser_->ParserForExtension(QFileInfo(filename).suffix().toLower()); + parser = playlist_parser_->ParserForExtension(fileinfo.suffix().toLower()); } if (parser) { // It's a playlist! @@ -279,32 +297,33 @@ SongLoader::Result SongLoader::LoadLocalAsync(const QString &filename) { return Success; } - // Check if it's a cue file + // Check if it's a CUE file QString matching_cue = filename.section('.', 0, -2) + ".cue"; if (QFile::exists(matching_cue)) { - // it's a cue - create virtual tracks + // It's a CUE - create virtual tracks QFile cue(matching_cue); - cue.open(QIODevice::ReadOnly); - - SongList song_list = cue_parser_->Load(&cue, matching_cue, QDir(filename.section('/', 0, -2))); - for (const Song &song : song_list) { - if (song.is_valid()) songs_ << song; + if (cue.open(QIODevice::ReadOnly)) { + const SongList songs = cue_parser_->Load(&cue, matching_cue, QDir(filename.section('/', 0, -2))); + for (const Song &song : songs) { + if (song.is_valid()) songs_ << song; + } + return Success; } - return Success; } // Assume it's just a normal file - Song song(Song::Source_LocalFile); - song.InitFromFilePartial(filename); - if (song.is_valid()) { - songs_ << song; - return Success; - } - else { - errors_ << song.error(); - return Error; + if (TagReaderClient::Instance()->IsMediaFileBlocking(filename) || Song::kAcceptedExtensions.contains(fileinfo.suffix(), Qt::CaseInsensitive)) { + Song song(Song::Source_LocalFile); + song.InitFromFilePartial(filename, fileinfo); + if (song.is_valid()) { + songs_ << song; + return Success; + } } + errors_ << QObject::tr("File %1 is not recognized as a valid audio file.").arg(filename); + return Error; + } void SongLoader::LoadMetadataBlocking() {