33#include < QtCore/QFileInfo>
44#include < QtCore/QDir>
55#include < QtCore/QProcess>
6+ #include < QtCore/QUuid>
67#include < QtNetwork/QNetworkReply>
78using namespace QtAutoUpdater ;
89
@@ -26,6 +27,15 @@ void QWebQueryUpdateInstaller::cancelInstall()
2627
2728void QWebQueryUpdateInstaller::eulaHandled (const QVariant &id, bool accepted)
2829{
30+ if (_eulaCache.remove (id.toUuid ())) {
31+ if (accepted) {
32+ if (_eulaCache.isEmpty ())
33+ startDownload ();
34+ } else {
35+ _eulaCache.clear ();
36+ abort (tr (" EULA was rejected!" ));
37+ }
38+ }
2939}
3040
3141void QWebQueryUpdateInstaller::restartApplication ()
@@ -48,72 +58,30 @@ void QWebQueryUpdateInstaller::startInstallImpl()
4858 return ;
4959 }
5060 _info = comps[0 ];
51- const auto data = _info.data ();
52-
53- // TODO handle eulas
54-
55- // get the download url
56- auto url = generateUrl (_config->value (Install::KeyDownloadUrl));
57- if (_config->value (Install::KeyUseInfoDownload, Install::DefaultUseInfoDownloads).toBool ()) {
58- if (const auto key = QStringLiteral (" download" ); data.contains (key)) {
59- auto infoUrl = data[key].toUrl ();
60- if (infoUrl.isRelative () && url)
61- url = url->resolved (infoUrl);
62- }
63- }
64- if (!url) {
65- qCCritical (logWebInstaller) << " Unable to generate the download URL!" ;
66- abort (tr (" Invalid update details!" ));
67- return ;
68- }
69-
70- // extract hashsum info
71- if (auto hash = extractHash (data); hash) {
72- _hash.reset (new QCryptographicHash{hash->first });
73- _hashResult = std::move (hash->second );
74- }
75-
76- // prepare the download file
77- const auto fileNamePattern = QDir::temp ().absoluteFilePath (QStringLiteral (" qtautoupdater_XXXXXX.%1" ))
78- .arg (QFileInfo{url->path (QUrl::FullyDecoded)}.completeSuffix ());
79- _file = new QTemporaryFile{fileNamePattern, this };
80- if (!_file->open ()) {
81- qCCritical (logWebInstaller) << " Unabled to create a temporary file for the download with error:"
82- << qUtf8Printable (_file->errorString ());
83- abort (tr (" Unabled to cache downloaded updates!" ));
84- return ;
85- }
86-
87- emit updateGlobalProgress (0.0 , tr (" Downloading update files…" ));
8861
89- QNetworkRequest request{*url};
90- if (const auto useSpdy = _config->value (Check::KeySpdy); useSpdy)
91- request.setAttribute (QNetworkRequest::SpdyAllowedAttribute, *useSpdy);
92- if (const auto useHttp2 = _config->value (Check::KeyHttp2); useHttp2)
93- request.setAttribute (QNetworkRequest::HTTP2AllowedAttribute, *useHttp2);
94- // optional ssl config
95- #ifndef QT_NO_SSL
96- if (const auto sslConf = _config->value (Check::KeySslConfiguration); sslConf)
97- request.setSslConfiguration (sslConf->value <QSslConfiguration>());
98- #endif
99- // optional headers
100- if (const auto cnt = _config->value (Install::Headers::KeySize); cnt) {
101- for (auto i = 0 ; i < cnt->toInt (); ++i) {
102- request.setRawHeader (_config->value (Install::Headers::KeyKey.arg (i))->toByteArray (),
103- _config->value (Install::Headers::KeyValue.arg (i)).value_or (QVariant{}).toByteArray ());
62+ // handle eulas
63+ _eulaCache.clear ();
64+ const auto data = _info.data ();
65+ if (data.contains (QStringLiteral (" eulas" ))) {
66+ const auto eulas = data.value (QStringLiteral (" eulas" )).toList ();
67+ for (const auto &eulaVal : eulas) {
68+ QString text;
69+ auto required = false ;
70+ if (eulaVal.userType () == QMetaType::QVariantMap) {
71+ const auto eulaMap = eulaVal.toMap ();
72+ text = eulaMap.value (QStringLiteral (" text" )).toString ();
73+ required = eulaMap.value (QStringLiteral (" required" )).toBool ();
74+ } else
75+ text = eulaVal.toString ();
76+ const auto id = QUuid::createUuid ();
77+ if (required)
78+ _eulaCache.insert (id);
79+ emit showEula (id, text, required);
10480 }
10581 }
10682
107- auto reply = _nam->get (request);
108- connect (this , &QWebQueryUpdateInstaller::cancelDownloads,
109- reply, &QNetworkReply::abort);
110- connect (reply, &QNetworkReply::readyRead,
111- this , &QWebQueryUpdateInstaller::replyData);
112- connect (reply, &QNetworkReply::downloadProgress,
113- this , &QWebQueryUpdateInstaller::replyProgress);
114- connect (reply, &QNetworkReply::finished,
115- this , &QWebQueryUpdateInstaller::replyDone,
116- Qt::QueuedConnection);
83+ if (_eulaCache.isEmpty ())
84+ startDownload ();
11785}
11886
11987void QWebQueryUpdateInstaller::replyDone ()
@@ -199,6 +167,74 @@ void QWebQueryUpdateInstaller::installerDone(bool success)
199167 emit installFailed (tr (" Update installer tool failed!" ));
200168}
201169
170+ void QWebQueryUpdateInstaller::startDownload ()
171+ {
172+ const auto data = _info.data ();
173+
174+ // get the download url
175+ auto url = generateUrl (_config->value (Install::KeyDownloadUrl));
176+ if (_config->value (Install::KeyUseInfoDownload, Install::DefaultUseInfoDownloads).toBool ()) {
177+ if (const auto key = QStringLiteral (" download" ); data.contains (key)) {
178+ auto infoUrl = data[key].toUrl ();
179+ if (infoUrl.isRelative () && url)
180+ url = url->resolved (infoUrl);
181+ }
182+ }
183+ if (!url) {
184+ qCCritical (logWebInstaller) << " Unable to generate the download URL!" ;
185+ abort (tr (" Invalid update details!" ));
186+ return ;
187+ }
188+
189+ // extract hashsum info
190+ if (auto hash = extractHash (data); hash) {
191+ _hash.reset (new QCryptographicHash{hash->first });
192+ _hashResult = std::move (hash->second );
193+ }
194+
195+ // prepare the download file
196+ const auto fileNamePattern = QDir::temp ().absoluteFilePath (QStringLiteral (" qtautoupdater_XXXXXX.%1" ))
197+ .arg (QFileInfo{url->path (QUrl::FullyDecoded)}.completeSuffix ());
198+ _file = new QTemporaryFile{fileNamePattern, this };
199+ if (!_file->open ()) {
200+ qCCritical (logWebInstaller) << " Unabled to create a temporary file for the download with error:"
201+ << qUtf8Printable (_file->errorString ());
202+ abort (tr (" Unabled to cache downloaded updates!" ));
203+ return ;
204+ }
205+
206+ emit updateGlobalProgress (0.0 , tr (" Downloading update files…" ));
207+
208+ QNetworkRequest request{*url};
209+ if (const auto useSpdy = _config->value (Check::KeySpdy); useSpdy)
210+ request.setAttribute (QNetworkRequest::SpdyAllowedAttribute, *useSpdy);
211+ if (const auto useHttp2 = _config->value (Check::KeyHttp2); useHttp2)
212+ request.setAttribute (QNetworkRequest::HTTP2AllowedAttribute, *useHttp2);
213+ // optional ssl config
214+ #ifndef QT_NO_SSL
215+ if (const auto sslConf = _config->value (Check::KeySslConfiguration); sslConf)
216+ request.setSslConfiguration (sslConf->value <QSslConfiguration>());
217+ #endif
218+ // optional headers
219+ if (const auto cnt = _config->value (Install::Headers::KeySize); cnt) {
220+ for (auto i = 0 ; i < cnt->toInt (); ++i) {
221+ request.setRawHeader (_config->value (Install::Headers::KeyKey.arg (i))->toByteArray (),
222+ _config->value (Install::Headers::KeyValue.arg (i)).value_or (QVariant{}).toByteArray ());
223+ }
224+ }
225+
226+ auto reply = _nam->get (request);
227+ connect (this , &QWebQueryUpdateInstaller::cancelDownloads,
228+ reply, &QNetworkReply::abort);
229+ connect (reply, &QNetworkReply::readyRead,
230+ this , &QWebQueryUpdateInstaller::replyData);
231+ connect (reply, &QNetworkReply::downloadProgress,
232+ this , &QWebQueryUpdateInstaller::replyProgress);
233+ connect (reply, &QNetworkReply::finished,
234+ this , &QWebQueryUpdateInstaller::replyDone,
235+ Qt::QueuedConnection);
236+ }
237+
202238std::optional<QUrl> QWebQueryUpdateInstaller::generateUrl (const std::optional<QVariant> &base)
203239{
204240 if (base) {
0 commit comments