3 * Copyright (C) 2011 Roman Moravcik
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "medarddownloader.h"
27 #define DOWNLOAD_CACHE_DIR ".cache/medard-downloader"
29 #define MEDARD_URL "http://www.medard-online.cz"
30 #define MEDARD_IMAGE_URL "http://www.medard-online.cz/scripts/getimage.php?initDate=%1&domain=%2&variable=%3&offset=%4"
32 #define FC_SEA_LEVEL_PRESSURE "slp"
33 #define FC_PRECIPITATION "precip"
34 #define FC_WIND_VELOCITY "wv"
35 #define FC_CLOUDINESS "cloud"
36 #define FC_TEMPERATURE "temp"
39 #define FD_CZECH_REPUBLIC "2"
44 #define IMAGE_WIDTH 556
45 #ifdef MEEGO_EDITION_HARMATTAN
46 #define IMAGE_HEIGHT 369
48 #define IMAGE_HEIGHT 408
51 #define MAX_DOWNLOAD_RETRIES 3
52 #define RETRY_TIMEOUT 5000
54 MedardDownloader::MedardDownloader() : QObject()
56 m_forecastType = FC_SEA_LEVEL_PRESSURE;
57 m_forecastDomain = FD_EUROPE;
58 m_forecastInitialDateCode.clear();
59 m_forecastDateOffset = 0;
61 m_network = new QNetworkAccessManager();
65 m_retryTimer = new QTimer();
66 connect(m_retryTimer, SIGNAL(timeout()), this, SLOT(retryTimerEvent()));
68 m_cachePath = QString("%1/%2")
69 .arg(QDir().homePath())
70 .arg(DOWNLOAD_CACHE_DIR);
72 createCacheDirectory();
75 MedardDownloader::~MedardDownloader()
77 if (m_retryTimer->isActive())
86 QSize MedardDownloader::imageSize()
88 return QSize(IMAGE_WIDTH, IMAGE_HEIGHT);
91 void MedardDownloader::setForecastType(ForecastType type)
94 case SeaLevelPressure:
95 m_forecastType = FC_SEA_LEVEL_PRESSURE;
99 m_forecastType = FC_PRECIPITATION;
103 m_forecastType = FC_WIND_VELOCITY;
107 m_forecastType = FC_CLOUDINESS;
111 m_forecastType = FC_TEMPERATURE;
116 void MedardDownloader::setForecastDomain(ForecastDomain domain)
120 m_forecastDomain = FD_EUROPE;
124 m_forecastDomain = FD_CZECH_REPUBLIC;
129 void MedardDownloader::setForecastInitialDate(QDateTime date)
133 m_forecastInitialDate = date.toUTC();
135 if (date.toUTC().time().hour() >= 18) {
136 m_forecastInitialDate.setTime(QTime(18, 0, 0));
138 } else if (date.toUTC().time().hour() >= 12) {
139 m_forecastInitialDate.setTime(QTime(12, 0, 0));
141 } else if (date.toUTC().time().hour() >= 6) {
142 m_forecastInitialDate.setTime(QTime(6, 0, 0));
145 m_forecastInitialDate.setTime(QTime(0, 0, 0));
149 if (offset == "18") {
150 /* use previous day */
151 m_forecastInitialDateCode = QString("%1_%2")
152 .arg(date.addDays(-1).toUTC().toString("yyMMdd"))
155 /* use current day */
156 m_forecastInitialDateCode = QString("%1_%2")
157 .arg(date.toUTC().toString("yyMMdd"))
161 cleanCacheDirectory();
164 QDateTime MedardDownloader::forecastInitialDate()
166 return m_forecastInitialDate.toLocalTime();
169 QDateTime MedardDownloader::forecastDate()
171 return m_forecastInitialDate.addSecs(3600 * m_forecastDateOffset).toLocalTime();
174 void MedardDownloader::setForecastDateOffset(int offset)
176 m_forecastDateOffset = offset;
177 if (m_forecastDateOffset > MAX_OFFSET)
178 m_forecastDateOffset = MAX_OFFSET;
180 if (m_forecastDateOffset < MIN_OFFSET)
181 m_forecastDateOffset = MIN_OFFSET;
184 void MedardDownloader::retryTimerEvent()
186 if (m_retryTimer->isActive())
187 m_retryTimer->stop();
192 void MedardDownloader::tryDownloadImageAgain()
196 if (m_retryCounter < MAX_DOWNLOAD_RETRIES) {
197 m_retryTimer->setInterval(RETRY_TIMEOUT * (m_retryCounter + 1));
198 m_retryTimer->start();
201 emit downloadFailed();
205 void MedardDownloader::clearDownloadRequest()
211 void MedardDownloader::downloadImageFinished()
213 QByteArray picture = m_reply->readAll();
215 if (picture.isNull() || picture.size() <= 0)
221 if (!image.loadFromData(picture, "png"))
224 QString filename = QString("%1/%2_%3_%4_%5.png")
227 .arg(m_forecastDomain)
228 .arg(m_forecastInitialDateCode)
229 .arg(QString().number(m_forecastDateOffset));
231 if ((image.width() == 512) && (image.height() == 512)) {
232 QImage croped(512, 400, QImage::Format_ARGB32_Premultiplied);
233 croped = image.copy(0, 52, 512, IMAGE_HEIGHT);
234 croped.save(filename, "png");
236 QImage croped(560, 400, QImage::Format_ARGB32_Premultiplied);
237 croped = image.copy(10, 96, IMAGE_WIDTH, IMAGE_HEIGHT);
238 croped.save(filename, "png");
241 emit downloadFinished(filename, forecastDate());
243 QTimer::singleShot(0, this, SLOT(clearDownloadRequest()));
246 void MedardDownloader::downloadImageError(QNetworkReply::NetworkError /* code */)
248 tryDownloadImageAgain();
249 QTimer::singleShot(0, this, SLOT(clearDownloadRequest()));
252 void MedardDownloader::downloadImage()
254 if (m_forecastInitialDateCode.isNull()) {
255 retrieveForecastInitialDate();
256 tryDownloadImageAgain();
260 QString filename = QString("%1/%2_%3_%4_%5.png")
263 .arg(m_forecastDomain)
264 .arg(m_forecastInitialDateCode)
265 .arg(QString().number(m_forecastDateOffset));
267 if (isDownloaded(filename)) {
268 emit downloadFinished(filename, forecastDate());
272 QString imageUrl = QString(MEDARD_IMAGE_URL)
273 .arg(m_forecastInitialDateCode)
274 .arg(m_forecastDomain)
276 .arg(QString().number(m_forecastDateOffset));
279 QNetworkRequest request(url);
282 clearDownloadRequest();
283 m_reply = m_network->get(request);
285 connect(m_reply, SIGNAL(finished()), this, SLOT(downloadImageFinished()));
286 connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)), this,
287 SLOT(downloadImageError(QNetworkReply::NetworkError)));
290 bool MedardDownloader::isDownloaded(const QString filename)
292 return QFile(filename).exists();
295 int MedardDownloader::forecastDateOffset()
297 return m_forecastDateOffset;
300 int MedardDownloader::minForecastDateOffset()
305 int MedardDownloader::maxForecastDateOffset()
310 void MedardDownloader::retrieveForecastInitialDateFinished()
312 QByteArray data = m_reply->readAll();
314 int index1 = data.indexOf("var fcst_initDatestamp=\"", 0);
315 int index2 = data.indexOf("\";", index1);
318 for (int i = index1 + 24; i < index2; i++) {
319 temp.append(data.at(i));
321 QDateTime date = QDateTime::fromTime_t(temp.toULong() + 6 * 3600);
322 if (!date.isNull()) {
323 setForecastInitialDate(date.toLocalTime());
325 int forecastDateOffset = date.toLocalTime().secsTo(QDateTime().currentDateTime()) / 3600;
326 setForecastDateOffset(forecastDateOffset);
331 QTimer::singleShot(0, this, SLOT(clearDownloadRequest()));
334 void MedardDownloader::retrieveForecastInitialDateError(QNetworkReply::NetworkError /* code */)
338 void MedardDownloader::retrieveForecastInitialDate()
340 QString serverUrl = QString(MEDARD_URL);
343 QNetworkRequest request(url);
346 clearDownloadRequest();
347 m_reply = m_network->get(request);
349 connect(m_reply, SIGNAL(finished()), this, SLOT(retrieveForecastInitialDateFinished()));
350 connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)), this,
351 SLOT(retrieveForecastInitialDateError(QNetworkReply::NetworkError)));
354 void MedardDownloader::createCacheDirectory()
356 QDir cacheDir(m_cachePath);
357 if (!cacheDir.exists())
358 cacheDir.mkpath(cacheDir.path());
361 void MedardDownloader::cleanCacheDirectory()
363 QDir cacheDir(m_cachePath);
364 QStringList list = cacheDir.entryList();
365 for (int i = 0; i < list.size(); i++) {
366 if (!list.at(i).contains(m_forecastInitialDateCode)) {
367 QFile(m_cachePath + "/" + list.at(i)).remove();