/* * Strawberry Music Player * This file was part of Clementine. * Copyright 2010, David Sansome * Copyright 2018-2021, Jonas Kvinge * * Strawberry 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. * * Strawberry 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 Strawberry. If not, see . * */ #ifndef COLLECTIONBACKEND_H #define COLLECTIONBACKEND_H #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "core/song.h" #include "core/sqlquery.h" #include "collectionfilteroptions.h" #include "collectionquery.h" #include "collectiondirectory.h" class QThread; class TaskManager; class Database; class SmartPlaylistSearch; class CollectionBackendInterface : public QObject { Q_OBJECT public: explicit CollectionBackendInterface(QObject *parent = nullptr) : QObject(parent) {} struct Album { Album() : filetype(Song::FileType::Unknown) {} Album(const QString &_album_artist, const QString &_album, const QUrl &_art_automatic, const QUrl &_art_manual, const QList &_urls, const Song::FileType _filetype, const QString &_cue_path) : album_artist(_album_artist), album(_album), art_automatic(_art_automatic), art_manual(_art_manual), urls(_urls), filetype(_filetype), cue_path(_cue_path) {} QString album_artist; QString album; QUrl art_automatic; QUrl art_manual; QList urls; Song::FileType filetype; QString cue_path; }; using AlbumList = QList; virtual QString songs_table() const = 0; virtual QString fts_table() const = 0; virtual Song::Source source() const = 0; virtual Database *db() const = 0; // Get a list of directories in the collection. Emits DirectoriesDiscovered. virtual void LoadDirectoriesAsync() = 0; virtual void UpdateTotalSongCountAsync() = 0; virtual void UpdateTotalArtistCountAsync() = 0; virtual void UpdateTotalAlbumCountAsync() = 0; virtual SongList FindSongsInDirectory(const int id) = 0; virtual SongList SongsWithMissingFingerprint(const int id) = 0; virtual CollectionSubdirectoryList SubdirsInDirectory(const int id) = 0; virtual CollectionDirectoryList GetAllDirectories() = 0; virtual void ChangeDirPath(const int id, const QString &old_path, const QString &new_path) = 0; virtual SongList GetAllSongs() = 0; virtual QStringList GetAllArtists(const CollectionFilterOptions &opt = CollectionFilterOptions()) = 0; virtual QStringList GetAllArtistsWithAlbums(const CollectionFilterOptions &opt = CollectionFilterOptions()) = 0; virtual SongList GetArtistSongs(const QString &effective_albumartist, const CollectionFilterOptions &opt = CollectionFilterOptions()) = 0; virtual SongList GetAlbumSongs(const QString &effective_albumartist, const QString &album, const CollectionFilterOptions &opt = CollectionFilterOptions()) = 0; virtual SongList GetSongsByAlbum(const QString &album, const CollectionFilterOptions &opt = CollectionFilterOptions()) = 0; virtual SongList GetCompilationSongs(const QString &album, const CollectionFilterOptions &opt = CollectionFilterOptions()) = 0; virtual AlbumList GetAllAlbums(const CollectionFilterOptions &opt = CollectionFilterOptions()) = 0; virtual AlbumList GetAlbumsByArtist(const QString &artist, const CollectionFilterOptions &opt = CollectionFilterOptions()) = 0; virtual AlbumList GetCompilationAlbums(const CollectionFilterOptions &opt = CollectionFilterOptions()) = 0; virtual void UpdateManualAlbumArtAsync(const QString &effective_albumartist, const QString &album, const QUrl &cover_url, const bool clear_art_automatic = false) = 0; virtual void UpdateAutomaticAlbumArtAsync(const QString &effective_albumartist, const QString &album, const QUrl &cover_url, const bool clear_art_manual = false) = 0; virtual Album GetAlbumArt(const QString &effective_albumartist, const QString &album) = 0; virtual Song GetSongById(const int id) = 0; virtual SongList GetSongsByFingerprint(const QString &fingerprint) = 0; // Returns all sections of a song with the given filename. If there's just one section the resulting list will have it's size equal to 1. virtual SongList GetSongsByUrl(const QUrl &url, const bool unavailable = false) = 0; // Returns a section of a song with the given filename and beginning. If the section is not present in collection, returns invalid song. // Using default beginning value is suitable when searching for single-section songs. virtual Song GetSongByUrl(const QUrl &url, const qint64 beginning = 0) = 0; virtual void AddDirectory(const QString &path) = 0; virtual void RemoveDirectory(const CollectionDirectory &dir) = 0; }; class CollectionBackend : public CollectionBackendInterface { Q_OBJECT public: Q_INVOKABLE explicit CollectionBackend(QObject *parent = nullptr); void Init(Database *db, TaskManager *task_manager, const Song::Source source, const QString &songs_table, const QString &fts_table, const QString &dirs_table = QString(), const QString &subdirs_table = QString()); void Close(); void ExitAsync(); void ReportErrors(const CollectionQuery &query); Song::Source source() const override { return source_; } Database *db() const override { return db_; } QString songs_table() const override { return songs_table_; } QString fts_table() const override { return fts_table_; } QString dirs_table() const { return dirs_table_; } QString subdirs_table() const { return subdirs_table_; } // Get a list of directories in the collection. Emits DirectoriesDiscovered. void LoadDirectoriesAsync() override; void UpdateTotalSongCountAsync() override; void UpdateTotalArtistCountAsync() override; void UpdateTotalAlbumCountAsync() override; SongList FindSongsInDirectory(const int id) override; SongList SongsWithMissingFingerprint(const int id) override; CollectionSubdirectoryList SubdirsInDirectory(const int id) override; CollectionDirectoryList GetAllDirectories() override; void ChangeDirPath(const int id, const QString &old_path, const QString &new_path) override; SongList GetAllSongs() override; QStringList GetAll(const QString &column, const CollectionFilterOptions &filter_options = CollectionFilterOptions()); QStringList GetAllArtists(const CollectionFilterOptions &opt = CollectionFilterOptions()) override; QStringList GetAllArtistsWithAlbums(const CollectionFilterOptions &opt = CollectionFilterOptions()) override; SongList GetArtistSongs(const QString &effective_albumartist, const CollectionFilterOptions &opt = CollectionFilterOptions()) override; SongList GetAlbumSongs(const QString &effective_albumartist, const QString &album, const CollectionFilterOptions &opt = CollectionFilterOptions()) override; SongList GetSongsByAlbum(const QString &album, const CollectionFilterOptions &opt = CollectionFilterOptions()) override; SongList GetCompilationSongs(const QString &album, const CollectionFilterOptions &opt = CollectionFilterOptions()) override; AlbumList GetAllAlbums(const CollectionFilterOptions &opt = CollectionFilterOptions()) override; AlbumList GetCompilationAlbums(const CollectionFilterOptions &opt = CollectionFilterOptions()) override; AlbumList GetAlbumsByArtist(const QString &artist, const CollectionFilterOptions &opt = CollectionFilterOptions()) override; void UpdateManualAlbumArtAsync(const QString &effective_albumartist, const QString &album, const QUrl &cover_url, const bool clear_art_automatic = false) override; void UpdateAutomaticAlbumArtAsync(const QString &effective_albumartist, const QString &album, const QUrl &cover_url, const bool clear_art_manual = false) override; Album GetAlbumArt(const QString &effective_albumartist, const QString &album) override; Song GetSongById(const int id) override; SongList GetSongsById(const QList &ids); SongList GetSongsById(const QStringList &ids); SongList GetSongsByForeignId(const QStringList &ids, const QString &table, const QString &column); SongList GetSongsByUrl(const QUrl &url, const bool unavailable = false) override; Song GetSongByUrl(const QUrl &url, qint64 beginning = 0) override; void AddDirectory(const QString &path) override; void RemoveDirectory(const CollectionDirectory &dir) override; bool ExecCollectionQuery(CollectionQuery *query, SongList &songs); bool ExecCollectionQuery(CollectionQuery *query, SongMap &songs); void IncrementPlayCountAsync(const int id); void IncrementSkipCountAsync(const int id, const float progress); void ResetPlayStatisticsAsync(const int id, const bool save_tags = false); void ResetPlayStatisticsAsync(const QList &id_list, const bool save_tags = false); void DeleteAllAsync(); Song GetSongBySongId(const QString &song_id); SongList GetSongsBySongId(const QStringList &song_ids); SongList GetSongsByFingerprint(const QString &fingerprint) override; SongList SmartPlaylistsGetAllSongs(); SongList SmartPlaylistsFindSongs(const SmartPlaylistSearch &search); void AddOrUpdateSongsAsync(const SongList &songs); void UpdateSongsBySongIDAsync(const SongMap &new_songs); void UpdateSongRatingAsync(const int id, const float rating, const bool save_tags = false); void UpdateSongsRatingAsync(const QList &ids, const float rating, const bool save_tags = false); public slots: void Exit(); void LoadDirectories(); void UpdateTotalSongCount(); void UpdateTotalArtistCount(); void UpdateTotalAlbumCount(); void AddOrUpdateSongs(const SongList &songs); void UpdateSongsBySongID(const SongMap &new_songs); void UpdateMTimesOnly(const SongList &songs); void DeleteSongs(const SongList &songs); void MarkSongsUnavailable(const SongList &songs, const bool unavailable = true); void AddOrUpdateSubdirs(const CollectionSubdirectoryList &subdirs); void CompilationsNeedUpdating(); void UpdateManualAlbumArt(const QString &effective_albumartist, const QString &album, const QUrl &cover_url, const bool clear_art_automatic = false); void UpdateAutomaticAlbumArt(const QString &effective_albumartist, const QString &album, const QUrl &cover_url, const bool clear_art_manual = false); void ForceCompilation(const QString &album, const QList &artists, const bool on); void IncrementPlayCount(const int id); void IncrementSkipCount(const int id, const float progress); void ResetPlayStatistics(const int id, const bool save_tags = false); void ResetPlayStatistics(const QList &id_list, const bool save_tags = false); bool ResetPlayStatistics(const QStringList &id_str_list); void DeleteAll(); void SongPathChanged(const Song &song, const QFileInfo &new_file, const std::optional new_collection_directory_id); SongList GetSongsBy(const QString &artist, const QString &album, const QString &title); void UpdateLastPlayed(const QString &artist, const QString &album, const QString &title, const qint64 lastplayed); void UpdatePlayCount(const QString &artist, const QString &title, const int playcount, const bool save_tags = false); void UpdateSongRating(const int id, const float rating, const bool save_tags = false); void UpdateSongsRating(const QList &id_list, const float rating, const bool save_tags = false); void UpdateLastSeen(const int directory_id, const int expire_unavailable_songs_days); void ExpireSongs(const int directory_id, const int expire_unavailable_songs_days); signals: void DirectoryDiscovered(CollectionDirectory, CollectionSubdirectoryList); void DirectoryDeleted(CollectionDirectory); void SongsDiscovered(SongList); void SongsDeleted(SongList); void SongsStatisticsChanged(SongList, bool = false); void DatabaseReset(); void TotalSongCountUpdated(int); void TotalArtistCountUpdated(int); void TotalAlbumCountUpdated(int); void SongsRatingChanged(SongList, bool); void ExitFinished(); void Error(QString); private: struct CompilationInfo { CompilationInfo() : has_compilation_detected(0), has_not_compilation_detected(0) {} QList urls; QStringList artists; int has_compilation_detected; int has_not_compilation_detected; }; bool UpdateCompilations(const QSqlDatabase &db, SongList &deleted_songs, SongList &added_songs, const QUrl &url, const bool compilation_detected); AlbumList GetAlbums(const QString &artist, const QString &album_artist, const bool compilation_required = false, const CollectionFilterOptions &opt = CollectionFilterOptions()); AlbumList GetAlbums(const QString &artist, const bool compilation_required, const CollectionFilterOptions &opt = CollectionFilterOptions()); CollectionSubdirectoryList SubdirsInDirectory(const int id, QSqlDatabase &db); Song GetSongById(const int id, QSqlDatabase &db); SongList GetSongsById(const QStringList &ids, QSqlDatabase &db); Song GetSongBySongId(const QString &song_id, QSqlDatabase &db); SongList GetSongsBySongId(const QStringList &song_ids, QSqlDatabase &db); private: Database *db_; TaskManager *task_manager_; Song::Source source_; QString songs_table_; QString dirs_table_; QString subdirs_table_; QString fts_table_; QThread *original_thread_; }; #endif // COLLECTIONBACKEND_H