Warning, file /network/angelfish/lib/iconimageprovider.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // SPDX-FileCopyrightText: 2020 Jonah BrĂ¼chert <jbb@kaidan.im>
0002 // SPDX-FileCopyrightText: 2020 Rinigus <rinigus.git@gmail.com>
0003 //
0004 // SPDX-License-Identifier: GPL-2.0-or-later
0005 
0006 #include "iconimageprovider.h"
0007 
0008 #include <QBuffer>
0009 #include <QByteArray>
0010 #include <QImage>
0011 #include <QPixmap>
0012 #include <QQmlApplicationEngine>
0013 #include <QString>
0014 
0015 #include <QCoro/QCoroFuture>
0016 #include <QCoro/QCoroTask>
0017 
0018 #include "browsermanager.h"
0019 
0020 IconImageProvider::IconImageProvider()
0021     : QCoro::ImageProvider()
0022 {
0023 }
0024 
0025 QString IconImageProvider::providerId()
0026 {
0027     return QStringLiteral("angelfish-favicon");
0028 }
0029 
0030 QCoro::Task<QImage> IconImageProvider::asyncRequestImage(const QString &id, const QSize & /*requestedSize*/)
0031 {
0032     auto url = QStringLiteral("image://%1/%2%").arg(providerId(), id);
0033     auto icon = co_await BrowserManager::instance()
0034             ->databaseManager()
0035             ->database()
0036             ->getResult<SingleValue<QByteArray>>(QStringLiteral("SELECT icon FROM icons WHERE url LIKE ? LIMIT 1"), url);
0037 
0038     if (icon) {
0039         co_return QImage::fromData(icon->value);
0040     }
0041 
0042     qWarning() << "Failed to find icon for" << id;
0043     co_return {};
0044 }
0045 
0046 QCoro::Task<QString> storeIcon(QQmlEngine *engine, const QString &iconSource)
0047 {
0048     if (iconSource.isEmpty()) {
0049         co_return {};
0050     }
0051 
0052     const QLatin1String prefix_favicon = QLatin1String("image://favicon/");
0053     if (!iconSource.startsWith(prefix_favicon)) {
0054         // don't know what to do with it, return as it is
0055         qWarning() << Q_FUNC_INFO << "Don't know how to store image" << iconSource;
0056         co_return iconSource;
0057     }
0058 
0059     // new uri for image
0060     QString url = QStringLiteral("image://%1/%2").arg(IconImageProvider::providerId(), iconSource.mid(prefix_favicon.size()));
0061 
0062     // check if we have that image already
0063     bool alreadyExists = (co_await BrowserManager::instance()
0064             ->databaseManager()
0065             ->database()
0066             ->getResult<SingleValue<bool>>(
0067                 QStringLiteral("SELECT COUNT(url) > 0 FROM icons WHERE url = ? LIMIT 1"), url))
0068             .value()
0069             .value;
0070 
0071     if (alreadyExists) {
0072         co_return url;
0073     }
0074 
0075     // Store new icon
0076     QQuickImageProvider *provider = dynamic_cast<QQuickImageProvider *>(engine->imageProvider(QStringLiteral("favicon")));
0077     if (!provider) {
0078         qWarning() << Q_FUNC_INFO << "Failed to load image provider" << url;
0079         co_return iconSource; // as something is wrong
0080     }
0081 
0082     QByteArray data;
0083     QBuffer buffer(&data);
0084     buffer.open(QIODevice::WriteOnly);
0085 
0086     const QSize szRequested;
0087     const QString providerIconName = iconSource.mid(prefix_favicon.size());
0088     switch (provider->imageType()) {
0089     case QQmlImageProviderBase::Image: {
0090         const QImage image = provider->requestImage(providerIconName, nullptr, szRequested);
0091         if (!image.save(&buffer, "PNG")) {
0092             qWarning() << Q_FUNC_INFO << "Failed to save image" << url;
0093             co_return iconSource; // as something is wrong
0094         }
0095         break;
0096     }
0097     case QQmlImageProviderBase::Pixmap: {
0098         const QPixmap image = provider->requestPixmap(providerIconName, nullptr, szRequested);
0099         if (!image.save(&buffer, "PNG")) {
0100             qWarning() << Q_FUNC_INFO << "Failed to save pixmap" << url;
0101             co_return iconSource; // as something is wrong
0102         }
0103         break;
0104     }
0105     default:
0106         qWarning() << Q_FUNC_INFO << "Unsupported image provider" << provider->imageType();
0107         co_return iconSource; // as something is wrong
0108     }
0109 
0110     co_await BrowserManager::instance()
0111             ->databaseManager()
0112             ->database()
0113             ->execute(QStringLiteral("INSERT INTO icons(url, icon) VALUES (?, ?)"), url, data);
0114 
0115     co_return url;
0116 }