File indexing completed on 2024-04-21 04:51:52

0001 /*
0002     SPDX-FileCopyrightText: 2021 Julius Künzel <jk.kdedev@smartlab.uber.space>
0003     SPDX-FileCopyrightText: 2011 Jean-Baptiste Mardelle <jb@kdenlive.org>
0004     SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 
0007 #include "providersrepository.hpp"
0008 #include <QDir>
0009 #include <QStandardPaths>
0010 
0011 std::unique_ptr<ProvidersRepository> ProvidersRepository::instance;
0012 std::once_flag ProvidersRepository::m_onceFlag;
0013 ProvidersRepository::ProvidersRepository()
0014 {
0015     refresh();
0016 }
0017 
0018 std::unique_ptr<ProvidersRepository> &ProvidersRepository::get()
0019 {
0020     std::call_once(m_onceFlag, [] { instance.reset(new ProvidersRepository()); });
0021     return instance;
0022 }
0023 
0024 void ProvidersRepository::refresh(bool fullRefresh)
0025 {
0026 
0027     // Lock to avoid changes to config files while reading them
0028     QWriteLocker locker(&m_mutex);
0029 
0030     if (fullRefresh) {
0031         // Reset all providers
0032         m_providers.clear();
0033     }
0034 
0035     // Helper function to check a provider and print debug info
0036     auto check_provider = [&](std::unique_ptr<ProviderModel> &provider, const QString &file) {
0037         if (m_providers.count(file) > 0) {
0038             return false;
0039         }
0040         if (!provider->is_valid()) {
0041             qCWarning(KDENLIVE_LOG) << "//// WARNING: invalid provider found: " << file << ". Ignoring.";
0042             return false;
0043         }
0044         return true;
0045     };
0046 
0047     QStringList profilesFiles;
0048     QStringList addedProviders;
0049     // list providers
0050     QStringList customProfilesDir =
0051         QStandardPaths::locateAll(QStandardPaths::AppDataLocation, QStringLiteral("resourceproviders"), QStandardPaths::LocateDirectory);
0052     for (const auto &dir : qAsConst(customProfilesDir)) {
0053         QStringList files = QDir(dir).entryList(QDir::Files);
0054         for (const auto &file : qAsConst(files)) {
0055             // Ensure we don't add the same file from different locations (for example Appimage reads its own and the system's resourceproviders folder
0056             if (!addedProviders.contains(QFileInfo(file).fileName())) {
0057                 profilesFiles << QDir(dir).absoluteFilePath(file);
0058                 addedProviders << QFileInfo(file).fileName();
0059             }
0060         }
0061     }
0062 
0063     // Iterate through files
0064     for (const auto &file : qAsConst(profilesFiles)) {
0065         std::unique_ptr<ProviderModel> provider(new ProviderModel(file));
0066         if (check_provider(provider, file)) {
0067             m_providers.insert(std::make_pair(file, std::move(provider)));
0068         }
0069     }
0070 }
0071 
0072 QVector<QPair<QString, QString>> ProvidersRepository::getAllProviers() const
0073 {
0074     QReadLocker locker(&m_mutex);
0075 
0076     QVector<QPair<QString, QString>> list;
0077     for (const auto &provider : m_providers) {
0078         list.push_back({provider.second->name(), provider.first});
0079     }
0080     std::sort(list.begin(), list.end());
0081     return list;
0082 }
0083 
0084 std::unique_ptr<ProviderModel> &ProvidersRepository::getProvider(const QString &path)
0085 {
0086     QReadLocker locker(&m_mutex);
0087     if (m_providers.count(path) == 0) {
0088         return (*(m_providers.begin())).second;
0089     }
0090     return m_providers.at(path);
0091 }