Support "eject" on OS X.
[maemo-rb.git] / rbutil / rbutilqt / base / zipinstaller.cpp
blobc41304e3b47e678fcb62bb964823d244ac4eb81d
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
9 * Copyright (C) 2007 by Dominik Wenger
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
17 ****************************************************************************/
19 #include <QtCore>
20 #include "zipinstaller.h"
21 #include "utils.h"
22 #include "ziputil.h"
24 ZipInstaller::ZipInstaller(QObject* parent): QObject(parent)
26 m_unzip = true;
27 m_usecache = false;
31 void ZipInstaller::install()
33 qDebug() << "[ZipInstall] initializing installation";
35 runner = 0;
36 connect(this, SIGNAL(cont()), this, SLOT(installContinue()));
37 m_url = m_urllist.at(runner);
38 m_logsection = m_loglist.at(runner);
39 m_logver = m_verlist.at(runner);
40 installStart();
44 void ZipInstaller::abort()
46 qDebug() << "[ZipInstall] Aborted";
47 emit internalAborted();
51 void ZipInstaller::installContinue()
53 qDebug() << "[ZipInstall] continuing installation";
55 runner++; // this gets called when a install finished, so increase first.
56 qDebug() << "[ZipInstall] runner done:" << runner << "/" << m_urllist.size();
57 if(runner < m_urllist.size()) {
58 emit logItem(tr("done."), LOGOK);
59 m_url = m_urllist.at(runner);
60 m_logsection = m_loglist.at(runner);
61 if(runner < m_verlist.size()) m_logver = m_verlist.at(runner);
62 else m_logver = "";
63 installStart();
65 else {
66 emit logItem(tr("Package installation finished successfully."), LOGOK);
67 emit done(false);
68 return;
74 void ZipInstaller::installStart()
76 qDebug() << "[ZipInstall] starting installation";
78 emit logItem(tr("Downloading file %1.%2").arg(QFileInfo(m_url).baseName(),
79 QFileInfo(m_url).completeSuffix()),LOGINFO);
81 // temporary file needs to be opened to get the filename
82 // make sure to get a fresh one on each run.
83 // making this a parent of the temporary file ensures the file gets deleted
84 // after the class object gets destroyed.
85 downloadFile = new QTemporaryFile(this);
86 downloadFile->open();
87 m_file = downloadFile->fileName();
88 downloadFile->close();
89 // get the real file.
90 getter = new HttpGet(this);
91 if(m_usecache) {
92 getter->setCache(true);
94 getter->setFile(downloadFile);
96 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
97 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SIGNAL(logProgress(int, int)));
98 connect(this, SIGNAL(internalAborted()), getter, SLOT(abort()));
100 getter->getFile(QUrl(m_url));
104 void ZipInstaller::downloadDone(bool error)
106 qDebug() << "[ZipInstall] download done, error:" << error;
107 QStringList zipContents; // needed later
108 // update progress bar
110 emit logProgress(1, 1);
111 if(getter->httpResponse() != 200 && !getter->isCached()) {
112 emit logItem(tr("Download error: received HTTP error %1.")
113 .arg(getter->httpResponse()),LOGERROR);
114 emit done(true);
115 return;
117 if(getter->isCached())
118 emit logItem(tr("Cached file used."), LOGINFO);
119 if(error) {
120 emit logItem(tr("Download error: %1").arg(getter->errorString()), LOGERROR);
121 emit done(true);
122 return;
124 else emit logItem(tr("Download finished."),LOGOK);
125 QCoreApplication::processEvents();
126 if(m_unzip) {
127 // unzip downloaded file
128 qDebug() << "[ZipInstall] about to unzip " << m_file << "to" << m_mountpoint;
130 emit logItem(tr("Extracting file."), LOGINFO);
131 QCoreApplication::processEvents();
133 ZipUtil zip(this);
134 connect(&zip, SIGNAL(logProgress(int, int)), this, SIGNAL(logProgress(int, int)));
135 connect(&zip, SIGNAL(logItem(QString, int)), this, SIGNAL(logItem(QString, int)));
136 zip.open(m_file, QuaZip::mdUnzip);
137 // check for free space. Make sure after installation will still be
138 // some room for operating (also includes calculation mistakes due to
139 // cluster sizes on the player).
140 if((qint64)Utils::filesystemFree(m_mountpoint)
141 < (zip.totalUncompressedSize(Utils::filesystemClusterSize(m_mountpoint))
142 + 1000000)) {
143 emit logItem(tr("Not enough disk space! Aborting."), LOGERROR);
144 emit logProgress(1, 1);
145 emit done(true);
146 return;
148 zipContents = zip.files();
149 if(!zip.extractArchive(m_mountpoint)) {
150 emit logItem(tr("Extraction failed!"), LOGERROR);
151 emit logProgress(1, 1);
152 emit done(true);
153 return;
155 zip.close();
157 else {
158 // only copy the downloaded file to the output location / name
159 emit logItem(tr("Installing file."), LOGINFO);
160 qDebug() << "[ZipInstall] saving downloaded file (no extraction)";
162 downloadFile->open(); // copy fails if file is not opened (filename issue?)
163 // make sure the required path is existing
164 QString path = QFileInfo(m_mountpoint + m_target).absolutePath();
165 QDir p;
166 p.mkpath(path);
167 // QFile::copy() doesn't overwrite files, so remove old one first
168 QFile(m_mountpoint + m_target).remove();
169 if(!downloadFile->copy(m_mountpoint + m_target)) {
170 emit logItem(tr("Installing file failed."), LOGERROR);
171 emit done(true);
172 return;
175 // add file to log
176 zipContents.append(m_target);
178 if(m_logver.isEmpty()) {
179 // if no version info is set use the timestamp of the server file.
180 m_logver = getter->timestamp().toString(Qt::ISODate);
183 emit logItem(tr("Creating installation log"),LOGINFO);
184 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0);
186 installlog.beginGroup(m_logsection);
187 for(int i = 0; i < zipContents.size(); i++)
189 installlog.setValue(zipContents.at(i), m_logver);
191 installlog.endGroup();
192 installlog.sync();
194 emit cont();