File indexing completed on 2024-05-12 04:58:13

0001 /* ============================================================
0002 * Falkon - Qt web browser
0003 * Copyright (C) 2010-2014  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 "updater.h"
0019 #include "browserwindow.h"
0020 #include "qztools.h"
0021 #include "mainapplication.h"
0022 #include "tabwidget.h"
0023 #include "desktopnotificationsfactory.h"
0024 #include "networkmanager.h"
0025 
0026 #include <QTimer>
0027 #include <QNetworkRequest>
0028 #include <QNetworkReply>
0029 
0030 Updater::Version::Version(const QString &s)
0031     : isValid(false)
0032     , majorVersion(-1)
0033     , minorVersion(-1)
0034     , revisionNumber(-1)
0035 {
0036     isValid = false;
0037 
0038     QStringList v = s.split(QLatin1Char('.'));
0039     if (v.count() != 3) {
0040         return;
0041     }
0042 
0043     bool ok;
0044 
0045     majorVersion = v.at(0).toInt(&ok);
0046     if (!ok) {
0047         return;
0048     }
0049 
0050     minorVersion = v.at(1).toInt(&ok);
0051     if (!ok) {
0052         return;
0053     }
0054 
0055     revisionNumber = v.at(2).toInt(&ok);
0056     if (!ok) {
0057         return;
0058     }
0059 
0060     isValid = majorVersion >= 0 && minorVersion >= 0 && revisionNumber >= 0;
0061 }
0062 
0063 bool Updater::Version::operator <(const Updater::Version &other) const
0064 {
0065     if (this->majorVersion != other.majorVersion) {
0066         return this->majorVersion < other.majorVersion;
0067     }
0068     if (this->minorVersion != other.minorVersion) {
0069         return this->minorVersion < other.minorVersion;
0070     }
0071     if (this->revisionNumber != other.revisionNumber) {
0072         return this->revisionNumber < other.revisionNumber;
0073     }
0074 
0075     return false;
0076 }
0077 
0078 bool Updater::Version::operator >(const Updater::Version &other) const
0079 {
0080     if (*this == other) {
0081         return false;
0082     }
0083     return !operator<(other);
0084 }
0085 
0086 bool Updater::Version::operator ==(const Updater::Version &other) const
0087 {
0088     return (this->majorVersion == other.majorVersion &&
0089             this->minorVersion == other.minorVersion &&
0090             this->revisionNumber == other.revisionNumber);
0091 }
0092 
0093 bool Updater::Version::operator >=(const Updater::Version &other) const
0094 {
0095     if (*this == other) {
0096         return true;
0097     }
0098     return *this > other;
0099 }
0100 
0101 bool Updater::Version::operator <=(const Updater::Version &other) const
0102 {
0103     if (*this == other) {
0104         return true;
0105     }
0106     return *this < other;
0107 }
0108 
0109 QString Updater::Version::versionString() const
0110 {
0111     return QSL("%1.%2.%3").arg(majorVersion, minorVersion, revisionNumber);
0112 }
0113 
0114 Updater::Updater(BrowserWindow* window, QObject* parent)
0115     : QObject(parent)
0116     , m_window(window)
0117 {
0118     QTimer::singleShot(60 * 1000, this, &Updater::start); // Start checking after 1 minute
0119 }
0120 
0121 void Updater::start()
0122 {
0123     QUrl url = QUrl(QSL("%1/update.php?v=%2&os=%3").arg(QString::fromLatin1(Qz::WWWADDRESS),
0124                     QString::fromLatin1(Qz::VERSION),
0125                     QzTools::operatingSystem()));
0126 
0127     startDownloadingUpdateInfo(url);
0128 }
0129 
0130 void Updater::startDownloadingUpdateInfo(const QUrl &url)
0131 {
0132     QNetworkReply *reply = mApp->networkManager()->get(QNetworkRequest(QUrl(url)));
0133 
0134     connect(reply, &QNetworkReply::finished, this, &Updater::downCompleted);
0135 }
0136 
0137 void Updater::downCompleted()
0138 {
0139     auto* reply = qobject_cast<QNetworkReply*>(sender());
0140     if (!reply)
0141         return;
0142 
0143     QString html = QString::fromUtf8(reply->readAll());
0144 
0145     if (html.startsWith(QLatin1String("Version:"))) {
0146         html.remove(QLatin1String("Version:"));
0147         Version current(QString::fromLatin1(Qz::VERSION));
0148         Version updated(html);
0149 
0150         if (current.isValid && updated.isValid && current < updated) {
0151             mApp->desktopNotifications()->showNotification(QIcon(QSL(":icons/falkon.svg")).pixmap(48), tr("Update available"), tr("New version of Falkon is ready to download."));
0152         }
0153     }
0154 
0155     reply->deleteLater();
0156 }
0157 
0158 void Updater::downloadNewVersion()
0159 {
0160     m_window->tabWidget()->addView(
0161         QUrl::fromEncoded(
0162             QByteArray(QByteArray(Qz::WWWADDRESS) + QByteArray("/download"))),
0163         tr("Update"), Qz::NT_NotSelectedTab);
0164 }