19 #include <QTemporaryFile>
21 #include <QDomDocument>
23 Upload::Upload(
QObject *parent) :
24 QObject(parent), m_uploadFiles(true)
29 void Upload::changeStatus(
const Package &package,
const QString &status,
const QString &message)
32 package.region.name() + QLatin1String(
" (" ) + package.transport +
')', status, message);
35 void Upload::processQueue()
37 if (m_queue.isEmpty()) {
41 Package
const package = m_queue.takeFirst();
43 if (upload(package)) {
44 QString
const message = QString(
"File %1 (%2) successfully created and uploaded").arg(package.file.fileName()).arg(
Region::fileSize(package.file));
45 changeStatus( package,
"finished", message);
47 deleteFile(package.file);
51 bool Upload::upload(
const Package &package)
58 QStringList arguments;
59 QString
const auth =
"marble@filesmaster.kde.org";
61 arguments <<
"mkdir" <<
"-p";
62 QString remoteDir = QString(
"/home/marble/web/monav/") + targetDir();
63 arguments << remoteDir;
64 ssh.start(
"ssh", arguments);
65 ssh.waitForFinished(1000 * 60 * 10);
66 if (ssh.exitStatus() != QProcess::NormalExit || ssh.exitCode() != 0) {
67 qDebug() <<
"Failed to create remote directory " << remoteDir;
68 changeStatus( package,
"error",
"Failed to create remote directory: " + ssh.readAllStandardError());
74 arguments << package.file.absoluteFilePath();
75 QString target = remoteDir +
'/' + package.file.fileName();
76 arguments << auth +
':' + target;
77 scp.start(
"scp", arguments);
78 scp.waitForFinished(1000 * 60 * 60 * 12);
79 if (scp.exitStatus() != QProcess::NormalExit || scp.exitCode() != 0) {
80 qDebug() <<
"Failed to upload " << target;
81 changeStatus( package,
"error",
"Failed to upload file: " + scp.readAllStandardError());
85 return adjustNewstuffFile(package);
88 void Upload::deleteFile(
const QFileInfo &file)
90 if (!m_jobParameters.cacheData()) {
91 QFile::remove(file.absoluteFilePath());
95 bool Upload::adjustNewstuffFile(
const Package &package)
98 QTemporaryFile tempFile(QDir::tempPath() +
"/monav-maps-XXXXXX.xml");
99 tempFile.setAutoRemove(
false);
101 QString monavFilename = tempFile.fileName();
104 QStringList
const arguments = QStringList() <<
"http://filesmaster.kde.org/marble/newstuff/maps-monav.xml" <<
"-O" << monavFilename;
105 wget.start(
"wget", arguments);
106 wget.waitForFinished(1000 * 60 * 60 * 12);
107 if (wget.exitStatus() != QProcess::NormalExit || wget.exitCode() != 0) {
108 qDebug() <<
"Failed to download newstuff file from filesmaster.kde.org";
109 changeStatus( package,
"error",
"Failed to sync newstuff file: " + wget.readAllStandardError());
113 QFile file(monavFilename);
114 if (!file.open(QFile::ReadOnly)) {
115 qDebug() <<
"Failed to open newstuff file" << monavFilename;
116 changeStatus( package,
"error",
"Failed to open newstuff file.");
120 if ( !m_xml.setContent( &file ) ) {
121 qDebug() <<
"Cannot parse newstuff xml file.";
122 changeStatus( package,
"error",
"Failed to parse newstuff .xml file.");
126 QFile::remove(monavFilename);
129 QDomElement root = m_xml.documentElement();
130 QDomNodeList regions = root.elementsByTagName(
"stuff" );
131 for (
unsigned int i = 0; i < regions.length(); ++i ) {
132 QDomNode node = regions.item( i );
133 if (!node.namedItem(
"payload").isNull()) {
134 QUrl url = node.namedItem(
"payload").toElement().text();
135 QFileInfo fileInfo(url.path());
136 if (fileInfo.fileName() == package.file.fileName()) {
138 QDomNode dateNode = node.namedItem(
"releasedate");
139 if (!dateNode.isNull()) {
140 dateNode.removeChild(dateNode.firstChild());
141 dateNode.appendChild(m_xml.createTextNode(releaseDate()));
143 QDomNode versionNode = node.namedItem(
"version");
144 if (!versionNode.isNull()) {
145 double version = versionNode.toElement().text().toDouble();
146 versionNode.removeChild(versionNode.firstChild());
147 versionNode.appendChild(m_xml.createTextNode(QString::number(version+0.1,
'f', 1)));
149 QDomNode payloadNode = node.namedItem(
"payload");
150 payloadNode.removeChild(payloadNode.firstChild());
151 if (fileInfo.dir().dirName() != targetDir()) {
152 removeFile = QString(
"/home/marble/web/monav/%1/%2").arg(fileInfo.dir().dirName()).arg(package.file.fileName());
153 qDebug() <<
"Going to remove the old file " << removeFile;
155 QString payload =
"http://files.kde.org/marble/monav/%1/%2";
156 payload = payload.arg(targetDir()).arg(package.file.fileName());
157 payloadNode.appendChild(m_xml.createTextNode(payload));
158 return removeFile.isEmpty() ? uploadNewstuff() : (uploadNewstuff() && deleteRemoteFile(removeFile));
163 QDomNode stuff = root.appendChild(m_xml.createElement(
"stuff"));
164 stuff.toElement().setAttribute(
"category",
"marble/routing/monav");
165 QDomNode nameNode = stuff.appendChild(m_xml.createElement(
"name"));
166 nameNode.toElement().setAttribute(
"lang",
"en");
167 QString name =
"%1 / %2 (%3)";
168 if (package.region.country().isEmpty()) {
169 name = name.arg(package.region.continent()).arg(package.region.name());
170 name = name.arg(package.transport);
172 name =
"%1 / %2 / %3 (%4)";
173 name = name.arg(package.region.continent()).arg(package.region.country());
174 name = name.arg(package.region.name()).arg(package.transport);
176 nameNode.appendChild(m_xml.createTextNode(name));
178 QDomNode authorNode = stuff.appendChild(m_xml.createElement(
"author"));
179 authorNode.appendChild(m_xml.createTextNode(
"Automatically created from map data assembled by the OpenStreetMap community"));
181 QDomNode licenseNode = stuff.appendChild(m_xml.createElement(
"license"));
182 licenseNode.appendChild(m_xml.createTextNode(
"Creative Commons by-SA 2.0"));
184 QDomNode summaryNode = stuff.appendChild(m_xml.createElement(
"summary"));
185 QString summary =
"Requires KDE >= 4.6: Offline Routing in %1, %2";
186 summary = summary.arg(package.region.name()).arg(package.region.continent());
187 summaryNode.appendChild(m_xml.createTextNode(summary));
189 QDomNode versionNode = stuff.appendChild(m_xml.createElement(
"version"));
190 versionNode.appendChild(m_xml.createTextNode(
"0.1"));
192 QDomNode dateNode = stuff.appendChild(m_xml.createElement(
"releasedate"));
193 dateNode.appendChild(m_xml.createTextNode(releaseDate()));
195 QDomNode previewNode = stuff.appendChild(m_xml.createElement(
"preview"));
196 QString preview =
"http://files.kde.org/marble/monav/previews/%1-preview.png";
197 preview = preview.arg(package.region.id());
198 previewNode.appendChild(m_xml.createTextNode(preview));
200 QDomNode payloadNode = stuff.appendChild(m_xml.createElement(
"payload"));
201 payloadNode.toElement().setAttribute(
"lang",
"en");
202 QString payload =
"http://files.kde.org/marble/monav/%1/%2";
203 payload = payload.arg(targetDir()).arg(package.file.fileName());
204 payloadNode.appendChild(m_xml.createTextNode(payload));
206 return uploadNewstuff();
209 bool Upload::uploadNewstuff()
211 QTemporaryFile outFile(QDir::tempPath() +
"/monav-maps-out-XXXXXX.xml");
213 QTextStream outStream(&outFile);
214 outStream << m_xml.toString(2);
218 QStringList arguments;
219 arguments << outFile.fileName();
220 arguments <<
"marble@filesmaster.kde.org:/home/marble/web/newstuff/maps-monav.xml";
221 scp.start(
"scp", arguments);
222 scp.waitForFinished(1000 * 60 * 60 * 12);
223 if (scp.exitStatus() != QProcess::NormalExit || scp.exitCode() != 0) {
224 qDebug() <<
"Failed to upload " << outFile.fileName() <<
": " << scp.readAllStandardError();
231 bool Upload::deleteRemoteFile(
const QString &filename)
233 if (filename.isEmpty()) {
237 if (!filename.startsWith(QLatin1String(
"/home/marble/" ))) {
242 QStringList arguments;
243 arguments <<
"marble@filesmaster.kde.org" <<
"rm" << filename;
244 ssh.start(
"ssh", arguments);
245 ssh.waitForFinished(1000 * 60 * 10);
246 if (ssh.exitStatus() != QProcess::NormalExit || ssh.exitCode() != 0) {
247 qDebug() <<
"Failed to delete remote file " << filename;
257 package.region = region;
259 package.transport = transport;
261 m_queue.removeAll(package);
268 return region == other.region;
279 return m_uploadFiles;
284 m_jobParameters = parameters;
292 QString Upload::targetDir()
const
294 QString targetDir =
"%1-w%2";
295 targetDir = targetDir.arg(QDateTime::currentDateTime().date().year());
296 targetDir = targetDir.arg(QDateTime::currentDateTime().date().weekNumber());
300 QString Upload::releaseDate()
const
302 return QDateTime::currentDateTime().toString(
"MM/dd/yy");
305 #include "upload.moc"
void uploadAndDelete(const Region ®ion, const QFileInfo &file, const QString &transport)
bool operator==(const DownloadPolicyKey &lhs, const DownloadPolicyKey &rhs)
void setStatus(const QString &id, const QString &name, const QString &status, const QString &message)
void setJobParameters(const JobParameters ¶meters)
void setUploadFiles(bool arg)
static Upload & instance()
static Logger & instance()
static QString fileSize(const QFileInfo &file)