File indexing completed on 2024-05-19 04:59:16

0001 /* ============================================================
0002 * GreaseMonkey plugin for Falkon
0003 * Copyright (C) 2012-2017 David Rosca <nowrep@gmail.com>
0004 *
0005 * This program is free software: you can redistribute it and/or modify
0006 * it under the terms of the GNU General Public License as published by
0007 * the Free Software Foundation, either version 3 of the License, or
0008 * (at your option) any later version.
0009 *
0010 * This program is distributed in the hope that it will be useful,
0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013 * GNU General Public License for more details.
0014 *
0015 * You should have received a copy of the GNU General Public License
0016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0017 * ============================================================ */
0018 #include "gm_downloader.h"
0019 #include "gm_manager.h"
0020 #include "gm_script.h"
0021 
0022 #include "webpage.h"
0023 #include "mainapplication.h"
0024 #include "networkmanager.h"
0025 #include "qztools.h"
0026 
0027 #include <QFile>
0028 #include <QSettings>
0029 #include <QNetworkReply>
0030 
0031 GM_Downloader::GM_Downloader(const QUrl &url, GM_Manager *manager, Mode mode)
0032     : QObject()
0033     , m_manager(manager)
0034 {
0035     m_reply = mApp->networkManager()->get(QNetworkRequest(url));
0036     if (mode == DownloadMainScript) {
0037         connect(m_reply, &QNetworkReply::finished, this, &GM_Downloader::scriptDownloaded);
0038     } else {
0039         connect(m_reply, &QNetworkReply::finished, this, &GM_Downloader::requireDownloaded);
0040     }
0041 }
0042 
0043 void GM_Downloader::updateScript(const QString &fileName)
0044 {
0045     m_fileName = fileName;
0046 }
0047 
0048 void GM_Downloader::scriptDownloaded()
0049 {
0050     Q_ASSERT(m_reply == qobject_cast<QNetworkReply*>(sender()));
0051 
0052     deleteLater();
0053     m_reply->deleteLater();
0054 
0055     if (m_reply->error() != QNetworkReply::NoError) {
0056         qWarning() << "GreaseMonkey: Cannot download script" << m_reply->errorString();
0057         Q_EMIT error();
0058         return;
0059     }
0060 
0061     const QByteArray response = QString::fromUtf8(m_reply->readAll()).toUtf8();
0062 
0063     if (!response.contains(QByteArray("// ==UserScript=="))) {
0064         qWarning() << "GreaseMonkey: Script does not contain UserScript header" << m_reply->request().url();
0065         Q_EMIT error();
0066         return;
0067     }
0068 
0069     if (m_fileName.isEmpty()) {
0070         const QString filePath = QSL("%1/%2").arg(m_manager->scriptsDirectory(), QzTools::getFileNameFromUrl(m_reply->url()));
0071         m_fileName = QzTools::ensureUniqueFilename(filePath);
0072     }
0073 
0074     QFile file(m_fileName);
0075 
0076     if (!file.open(QFile::WriteOnly)) {
0077         qWarning() << "GreaseMonkey: Cannot open file for writing" << m_fileName;
0078         Q_EMIT error();
0079         return;
0080     }
0081 
0082     file.write(response);
0083     file.close();
0084 
0085     Q_EMIT finished(m_fileName);
0086 }
0087 
0088 void GM_Downloader::requireDownloaded()
0089 {
0090     Q_ASSERT(m_reply == qobject_cast<QNetworkReply*>(sender()));
0091 
0092     deleteLater();
0093     m_reply->deleteLater();
0094 
0095     if (m_reply != qobject_cast<QNetworkReply*>(sender())) {
0096         Q_EMIT error();
0097         return;
0098     }
0099 
0100     if (m_reply->error() != QNetworkReply::NoError) {
0101         qWarning() << "GreaseMonkey: Cannot download require script" << m_reply->errorString();
0102         Q_EMIT error();
0103         return;
0104     }
0105 
0106     const QByteArray response = QString::fromUtf8(m_reply->readAll()).toUtf8();
0107 
0108     if (response.isEmpty()) {
0109         qWarning() << "GreaseMonkey: Empty script downloaded" << m_reply->request().url();
0110         Q_EMIT error();
0111         return;
0112     }
0113 
0114     QSettings settings(m_manager->settingsPath() + QL1S("/greasemonkey/requires/requires.ini"), QSettings::IniFormat);
0115     settings.beginGroup("Files");
0116 
0117     if (m_fileName.isEmpty()) {
0118         m_fileName = settings.value(m_reply->request().url().toString()).toString();
0119         if (m_fileName.isEmpty()) {
0120             QString name = QFileInfo(m_reply->request().url().path()).fileName();
0121             if (name.isEmpty()) {
0122                 name = QSL("require.js");
0123             } else if (!name.endsWith(QL1S(".js"))) {
0124                 name.append(QSL(".js"));
0125             }
0126             const QString filePath = m_manager->settingsPath() + QL1S("/greasemonkey/requires/") + name;
0127             m_fileName = QzTools::ensureUniqueFilename(filePath, QSL("%1"));
0128         }
0129         if (!QFileInfo(m_fileName).isAbsolute()) {
0130             m_fileName.prepend(m_manager->settingsPath() + QL1S("/greasemonkey/requires/"));
0131         }
0132     }
0133 
0134     QFile file(m_fileName);
0135 
0136     if (!file.open(QFile::WriteOnly)) {
0137         qWarning() << "GreaseMonkey: Cannot open file for writing" << m_fileName;
0138         Q_EMIT error();
0139         return;
0140     }
0141 
0142     file.write(response);
0143     file.close();
0144 
0145     settings.setValue(m_reply->request().url().toString(), QFileInfo(m_fileName).fileName());
0146 
0147     Q_EMIT finished(m_fileName);
0148 }