source: smplayer/trunk/src/updatechecker.cpp@ 176

Last change on this file since 176 was 176, checked in by Silvan Scherrer, 9 years ago

smplayer: update trunk to version 16.4

File size: 7.7 KB
Line 
1/* smplayer, GUI front-end for mplayer.
2 Copyright (C) 2006-2016 Ricardo Villalba <rvm@users.sourceforge.net>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17*/
18
19#include "updatechecker.h"
20#include "updatecheckerdata.h"
21#include "version.h"
22#include "links.h"
23#include <QUrl>
24#include <QNetworkAccessManager>
25#include <QNetworkRequest>
26#include <QNetworkReply>
27#include <QRegExp>
28#include <QDate>
29#include <QDateTime>
30#include <QStringList>
31#include <QMessageBox>
32#include <QDesktopServices>
33#include <QTemporaryFile>
34#include <QSettings>
35#include <QDebug>
36
37
38UpdateChecker::UpdateChecker(QWidget * parent, UpdateCheckerData * data) : QObject(parent)
39 , net_manager(0)
40 , d(0)
41{
42 d = data;
43
44 check_url = URL_VERSION_INFO;
45 user_agent = "SMPlayer";
46
47 /*
48 It looks like some distro maintainers disable this update checker...
49 This is a very very bad idea. Main reason: in order to play Youtube videos
50 with SMPlayer a very recent version is required. Distros usually provide
51 ancient versions...
52 If you remove the possibility to inform the user about new versions they will
53 probably use a version with broken support for Youtube like forever.
54
55 If you still want to disable this option, the correct way to do it is by
56 removing the UPDATE_CHECKER define in smplayer.pro, and not by removing the
57 following code.
58 */
59
60 connect(this, SIGNAL(newVersionFound(const QString &)),
61 this, SLOT(reportNewVersionAvailable(const QString &)));
62
63 connect(this, SIGNAL(noNewVersionFound(const QString &)),
64 this, SLOT(reportNoNewVersionFound(const QString &)));
65
66 connect(this, SIGNAL(errorOcurred(int, QString)), this, SLOT(reportError(int, QString)));
67
68 net_manager = new QNetworkAccessManager(this);
69
70 QDate now = QDate::currentDate();
71 //now = now.addDays(27);
72 int days = QDateTime(d->last_checked).daysTo(QDateTime(now));
73
74 qDebug() << "UpdateChecker::UpdateChecker: enabled:" << d->enabled;
75 qDebug() << "UpdateChecker::UpdateChecker: days_to_check:" << d->days_to_check;
76 qDebug() << "UpdateChecker::UpdateChecker: days since last check:" << days;
77
78 if ((!d->enabled) || (days < d->days_to_check)) return;
79
80 QNetworkRequest req(check_url);
81 req.setRawHeader("User-Agent", user_agent);
82 QNetworkReply *reply = net_manager->get(req);
83 connect(reply, SIGNAL(finished()), this, SLOT(gotReply()));
84}
85
86UpdateChecker::~UpdateChecker() {
87}
88
89// Force a check, requested by the user
90void UpdateChecker::check() {
91 qDebug("UpdateChecker::check");
92
93 QNetworkRequest req(check_url);
94 req.setRawHeader("User-Agent", user_agent);
95 QNetworkReply *reply = net_manager->get(req);
96 connect(reply, SIGNAL(finished()), this, SLOT(gotReplyFromUserRequest()));
97}
98
99QString UpdateChecker::parseVersion(const QByteArray & data, const QString & name) {
100 QTemporaryFile tf;
101 tf.open();
102 tf.write(data);
103 tf.close();
104 QString tfile = tf.fileName();
105 qDebug() << "UpdateChecker::parseVersion: tfile:" << tfile;
106
107 #ifdef Q_OS_WIN
108 QString grname = "windows";
109 #elif defined Q_OS_OS2
110 QString grname = "os2";
111 #else
112 QString grname = "linux";
113 #endif
114 QSettings set(tfile, QSettings::IniFormat);
115 set.beginGroup(grname);
116 QString version = set.value(name, "").toString();
117 set.endGroup();
118 return version;
119}
120
121void UpdateChecker::gotReply() {
122 qDebug("UpdateChecker::gotReply");
123
124 QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
125
126 if (reply) {
127 if (reply->error() == QNetworkReply::NoError) {
128 QString version = parseVersion(reply->readAll(), "stable");
129 if (!version.isEmpty()) {
130 d->last_checked = QDate::currentDate();
131 qDebug() << "UpdateChecker::gotReply: last known version:" << d->last_known_version << "received version:" << version;
132 qDebug() << "UpdateChecker::gotReply: installed version:" << Version::with_revision();
133 if ((d->last_known_version != version) && (formattedVersion(version) > formattedVersion(Version::with_revision()))) {
134 qDebug() << "UpdateChecker::gotReply: new version found:" << version;
135 emit newVersionFound(version);
136 }
137 }
138 } else {
139 //get http status code
140 int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
141 qDebug("UpdateChecker::gotReply: status: %d", status);
142 }
143 reply->deleteLater();
144 }
145}
146
147void UpdateChecker::gotReplyFromUserRequest() {
148 qDebug("UpdateChecker::gotReplyFromUserRequest");
149
150 QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
151
152 if (reply) {
153 if (reply->error() == QNetworkReply::NoError) {
154 QString version = parseVersion(reply->readAll(), "unstable");
155 if (!version.isEmpty()) {
156 if ((formattedVersion(version) > formattedVersion(Version::with_revision()))) {
157 qDebug("UpdateChecker::gotReplyFromUserRequest: new version found: %s", version.toUtf8().constData());
158 emit newVersionFound(version);
159 } else {
160 emit noNewVersionFound(version);
161 }
162 } else {
163 emit errorOcurred(1, tr("Failed to get the latest version number") );
164 }
165 } else {
166 int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
167 qDebug("UpdateChecker::gotReplyFromUserRequest: status: %d", status);
168 emit errorOcurred((int)reply->error(), reply->errorString());
169 }
170 reply->deleteLater();
171 }
172}
173
174void UpdateChecker::saveVersion(QString v) {
175 d->last_known_version = v;
176}
177
178QString UpdateChecker::formattedVersion(const QString & version) {
179 int n1 = 0, n2 = 0, n3 = 0, n4 = 0;
180 QStringList l = version.split(".");
181 int c = l.count();
182 if (c >= 1) n1 = l[0].toInt();
183 if (c >= 2) n2 = l[1].toInt();
184 if (c >= 3) n3 = l[2].toInt();
185 if (c >= 4) n4 = l[3].toInt();
186
187 QString res = QString("%1.%2.%3.%4").arg(n1, 2, 10, QChar('0'))
188 .arg(n2, 2, 10, QChar('0'))
189 .arg(n3, 2, 10, QChar('0'))
190 .arg(n4, 4, 10, QChar('0'));
191 //qDebug() << "UpdateChecker::formattedVersion:" << res;
192 return res;
193}
194
195void UpdateChecker::reportNewVersionAvailable(const QString & new_version) {
196 QWidget * p = qobject_cast<QWidget*>(parent());
197
198 QMessageBox::StandardButton button = QMessageBox::information(p, tr("New version available"),
199 tr("A new version of SMPlayer is available.") + "<br><br>" +
200 tr("Installed version: %1").arg(Version::with_revision()) + "<br>" +
201 tr("Available version: %1").arg(new_version) + "<br><br>" +
202 tr("Would you like to know more about this new version?"),
203 QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
204
205 if (button == QMessageBox::Yes) {
206 QDesktopServices::openUrl(QUrl(URL_CHANGES));
207 }
208
209 saveVersion(new_version);
210}
211
212void UpdateChecker::reportNoNewVersionFound(const QString & version) {
213 QWidget * p = qobject_cast<QWidget*>(parent());
214
215 QMessageBox::information(p, tr("Checking for updates"),
216 tr("Congratulations, SMPlayer is up to date.") + "<br><br>" +
217 tr("Installed version: %1").arg(Version::with_revision()) + "<br>" +
218 tr("Available version: %1").arg(version));
219}
220
221void UpdateChecker::reportError(int error_number, QString error_str) {
222 QWidget * p = qobject_cast<QWidget*>(parent());
223 QMessageBox::warning(p, tr("Error"),
224 tr("An error happened while trying to retrieve information about the latest version available.") +
225 "<br>" + tr("Error code: %1").arg(error_number) + "<br>" + error_str);
226}
227
228#include "moc_updatechecker.cpp"
229
Note: See TracBrowser for help on using the repository browser.