1 /**
2 * UGENE - Integrated Bioinformatics Tools.
3 * Copyright (C) 2008-2021 UniPro <ugene@unipro.ru>
4 * http://ugene.net
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 */
21
22 #include "CheckUpdatesTask.h"
23
24 #include <QMainWindow>
25 #include <QMessageBox>
26 #include <QNetworkReply>
27 #include <QPushButton>
28
29 #include <U2Core/AppContext.h>
30 #include <U2Core/AppSettings.h>
31 #include <U2Core/NetworkConfiguration.h>
32 #include <U2Core/Settings.h>
33 #include <U2Core/SyncHttp.h>
34 #include <U2Core/U2SafePoints.h>
35
36 #include <U2Gui/MainWindow.h>
37
38 #include "update/UgeneUpdater.h"
39
40 namespace U2 {
41
CheckUpdatesTask(bool startUp)42 CheckUpdatesTask::CheckUpdatesTask(bool startUp)
43 : Task(tr("Check for updates"), TaskFlag_SilentCancelOnShutdown) {
44 runOnStartup = startUp;
45 setVerboseLogMode(true);
46 startError = false;
47 }
48
49 #define SITE_URL QString("ugene.net")
50 #ifdef Q_OS_WIN
51 # define PAGE_NAME QString("/current_version_win.html")
52 #elif defined(Q_OS_DARWIN)
53 # define PAGE_NAME QString("/current_version_mac.html")
54 #elif defined(Q_OS_LINUX)
55 # define PAGE_NAME QString("/current_version_linux.html")
56 #else
57 # define PAGE_NAME QString("/current_version.html")
58 #endif
59
run()60 void CheckUpdatesTask::run() {
61 stateInfo.setDescription(tr("Connecting to updates server"));
62 NetworkConfiguration *nc = AppContext::getAppSettings()->getNetworkConfiguration();
63 SAFE_POINT(nc != nullptr, "Network configuration is null", );
64
65 bool isProxy = nc->isProxyUsed(QNetworkProxy::HttpProxy);
66 bool isException = nc->getExceptionsList().contains(SITE_URL);
67 SyncHttp http(stateInfo);
68 if (isProxy && !isException) {
69 http.setProxy(nc->getProxy(QNetworkProxy::HttpProxy));
70 }
71 // The following call blocks some UI tasks (Close project), so don't make it run long.
72 QString siteVersionText = http.syncGet(QUrl("http://" + SITE_URL + PAGE_NAME), 5000);
73 if (siteVersionText.isEmpty()) {
74 if (!runOnStartup) {
75 stateInfo.setError(tr("Cannot load the current version."));
76 } else {
77 uiLog.error(tr("Cannot load the current version."));
78 startError = true;
79 }
80 }
81 siteVersion = Version::parseVersion(siteVersionText);
82 stateInfo.setDescription(QString());
83
84 if (http.error() != QNetworkReply::NoError) {
85 if (!runOnStartup) {
86 stateInfo.setError(tr("Connection error while checking for updates: %1").arg(http.errorString()));
87 } else {
88 uiLog.error(tr("Connection error while checking for updates: %1").arg(http.errorString()));
89 startError = true;
90 }
91 return;
92 }
93 }
94
report()95 Task::ReportResult CheckUpdatesTask::report() {
96 if (hasError() || startError) {
97 return ReportResult_Finished;
98 }
99
100 Version thisVersion = Version::appVersion();
101
102 Answer answer = DoNothing;
103 if (runOnStartup) {
104 if (siteVersion > thisVersion && !UgeneUpdater::isUpdateSkipped(siteVersion)) {
105 UpdateMessage message(siteVersion.text);
106 answer = message.getAnswer();
107 }
108 } else {
109 VersionMessage message(siteVersion);
110 answer = message.getAnswer();
111 }
112
113 switch (answer) {
114 case Update:
115 UgeneUpdater::getInstance()->update();
116 break;
117 case Skip:
118 UgeneUpdater::skipUpdate(siteVersion);
119 break;
120 case DoNothing:
121 default:
122 break;
123 }
124 return ReportResult_Finished;
125 }
126
sl_registerInTaskScheduler()127 void CheckUpdatesTask::sl_registerInTaskScheduler() {
128 AppContext::getTaskScheduler()->registerTopLevelTask(this);
129 }
130
131 /************************************************************************/
132 /* UpdateMessage */
133 /************************************************************************/
UpdateMessage(const QString & newVersion)134 UpdateMessage::UpdateMessage(const QString &newVersion) {
135 QWidget *parent = AppContext::getMainWindow()->getQMainWindow();
136 const QString message = tr("UGENE %1 is available for downloading.\nWould you like to download and install it?").arg(newVersion);
137 const QString title = tr("New Updates");
138
139 dialog = new QMessageBox(QMessageBox::Question, title, message, QMessageBox::NoButton, parent);
140
141 updateButton = dialog->addButton(tr("Update now"), QMessageBox::ActionRole);
142 postponeButton = dialog->addButton(tr("Ask later"), QMessageBox::ActionRole);
143 dialog->addButton(tr("Skip this update"), QMessageBox::ActionRole);
144 }
145
getAnswer() const146 CheckUpdatesTask::Answer UpdateMessage::getAnswer() const {
147 dialog->exec();
148 CHECK(!dialog.isNull(), CheckUpdatesTask::DoNothing);
149
150 if (updateButton == dialog->clickedButton()) {
151 return CheckUpdatesTask::Update;
152 }
153 if (postponeButton == dialog->clickedButton()) {
154 return CheckUpdatesTask::DoNothing;
155 }
156 return CheckUpdatesTask::Skip;
157 }
158
159 /************************************************************************/
160 /* VersionMessage */
161 /************************************************************************/
VersionMessage(const Version & newVersion)162 VersionMessage::VersionMessage(const Version &newVersion) {
163 QWidget *parent = AppContext::getMainWindow()->getQMainWindow();
164 const QString message = getMessageText(Version::appVersion(), newVersion);
165 const QString title = tr("Version Information");
166
167 dialog = new QMessageBox(QMessageBox::Information, title, message, QMessageBox::NoButton, parent);
168 dialog->addButton(QMessageBox::Ok);
169 updateButton = nullptr;
170 if (Version::appVersion() < newVersion) {
171 updateButton = dialog->addButton(tr("Update Now"), QMessageBox::ActionRole);
172 }
173 }
174
getAnswer() const175 CheckUpdatesTask::Answer VersionMessage::getAnswer() const {
176 dialog->exec();
177 CHECK(!dialog.isNull(), CheckUpdatesTask::DoNothing);
178
179 if (dialog->clickedButton() == updateButton) {
180 return CheckUpdatesTask::Update;
181 }
182 return CheckUpdatesTask::DoNothing;
183 }
184
getMessageText(const Version & thisVersion,const Version & newVersion) const185 QString VersionMessage::getMessageText(const Version &thisVersion, const Version &newVersion) const {
186 QString message = QString("<table>"
187 " <tr><td>%1</td><td><b> %2</b></td></tr>"
188 " <tr><td>%3</td><td><b> %4</b></td></tr>"
189 "</table>")
190 .arg(tr("Your version:"), thisVersion.text, tr("Latest version:"), newVersion.text);
191
192 if (thisVersion >= newVersion) {
193 message += "<p>" + tr("You have the latest version") + "</p>";
194 }
195 return message;
196 }
197
198 } // namespace U2
199