• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

marble

  • sources
  • kde-4.12
  • kdeedu
  • marble
  • tools
  • osm-sisyphus
upload.cpp
Go to the documentation of this file.
1 //
2 // This file is part of the Marble Virtual Globe.
3 //
4 // This program is free software licensed under the GNU LGPL. You can
5 // find a copy of this license in LICENSE.txt in the top directory of
6 // the source code.
7 //
8 // Copyright 2011 Dennis Nienhüser <earthwings@gentoo.org>
9 //
10 
11 #include "upload.h"
12 
13 #include "logger.h"
14 
15 #include <QDebug>
16 #include <QProcess>
17 #include <QDateTime>
18 #include <QDir>
19 #include <QTemporaryFile>
20 #include <QUrl>
21 #include <QDomDocument>
22 
23 Upload::Upload(QObject *parent) :
24  QObject(parent), m_uploadFiles(true)
25 {
26  // nothing to do
27 }
28 
29 void Upload::changeStatus(const Package &package, const QString &status, const QString &message)
30 {
31  Logger::instance().setStatus( package.region.id() + '_' + package.transport,
32  package.region.name() + QLatin1String( " (" ) + package.transport + ')', status, message);
33 }
34 
35 void Upload::processQueue()
36 {
37  if (m_queue.isEmpty()) {
38  return;
39  }
40 
41  Package const package = m_queue.takeFirst();
42 
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);
46  }
47  deleteFile(package.file);
48  processQueue();
49 }
50 
51 bool Upload::upload(const Package &package)
52 {
53  if (!m_uploadFiles) {
54  return true;
55  }
56 
57  QProcess ssh;
58  QStringList arguments;
59  QString const auth = "marble@filesmaster.kde.org";
60  arguments << auth;
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); // wait up to 10 minutes for mkdir to complete
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());
69  return false;
70  }
71 
72  QProcess scp;
73  arguments.clear();
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); // wait up to 12 hours for upload to complete
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());
82  return false;
83  }
84 
85  return adjustNewstuffFile(package);
86 }
87 
88 void Upload::deleteFile(const QFileInfo &file)
89 {
90  if (!m_jobParameters.cacheData()) {
91  QFile::remove(file.absoluteFilePath());
92  }
93 }
94 
95 bool Upload::adjustNewstuffFile(const Package &package)
96 {
97  if (m_xml.isNull()) {
98  QTemporaryFile tempFile(QDir::tempPath() + "/monav-maps-XXXXXX.xml");
99  tempFile.setAutoRemove(false);
100  tempFile.open();
101  QString monavFilename = tempFile.fileName();
102  tempFile.close();
103  QProcess wget;
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); // wait up to 12 hours for download to complete
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());
110  return false;
111  }
112 
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.");
117  return false;
118  }
119 
120  if ( !m_xml.setContent( &file ) ) {
121  qDebug() << "Cannot parse newstuff xml file.";
122  changeStatus( package, "error", "Failed to parse newstuff .xml file.");
123  return false;
124  }
125 
126  QFile::remove(monavFilename);
127  }
128 
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()) {
137  QString removeFile;
138  QDomNode dateNode = node.namedItem("releasedate");
139  if (!dateNode.isNull()) {
140  dateNode.removeChild(dateNode.firstChild());
141  dateNode.appendChild(m_xml.createTextNode(releaseDate()));
142  }
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)));
148  }
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;
154  }
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));
159  }
160  }
161  }
162 
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);
171  } else {
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);
175  }
176  nameNode.appendChild(m_xml.createTextNode(name));
177 
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"));
180 
181  QDomNode licenseNode = stuff.appendChild(m_xml.createElement("license"));
182  licenseNode.appendChild(m_xml.createTextNode("Creative Commons by-SA 2.0"));
183 
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));
188 
189  QDomNode versionNode = stuff.appendChild(m_xml.createElement("version"));
190  versionNode.appendChild(m_xml.createTextNode("0.1"));
191 
192  QDomNode dateNode = stuff.appendChild(m_xml.createElement("releasedate"));
193  dateNode.appendChild(m_xml.createTextNode(releaseDate()));
194 
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));
199 
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));
205 
206  return uploadNewstuff();
207 }
208 
209 bool Upload::uploadNewstuff()
210 {
211  QTemporaryFile outFile(QDir::tempPath() + "/monav-maps-out-XXXXXX.xml");
212  outFile.open();
213  QTextStream outStream(&outFile);
214  outStream << m_xml.toString(2);
215  outStream.flush();
216 
217  QProcess scp;
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); // wait up to 12 hours for upload to complete
223  if (scp.exitStatus() != QProcess::NormalExit || scp.exitCode() != 0) {
224  qDebug() << "Failed to upload " << outFile.fileName() << ": " << scp.readAllStandardError();
225  return false;
226  }
227 
228  return true;
229 }
230 
231 bool Upload::deleteRemoteFile(const QString &filename)
232 {
233  if (filename.isEmpty()) {
234  return true;
235  }
236 
237  if (!filename.startsWith(QLatin1String( "/home/marble/" ))) {
238  return false;
239  }
240 
241  QProcess ssh;
242  QStringList arguments;
243  arguments << "marble@filesmaster.kde.org" << "rm" << filename;
244  ssh.start("ssh", arguments);
245  ssh.waitForFinished(1000 * 60 * 10); // wait up to 10 minutes for rm to complete
246  if (ssh.exitStatus() != QProcess::NormalExit || ssh.exitCode() != 0) {
247  qDebug() << "Failed to delete remote file " << filename;
248  return false;
249  }
250 
251  return true;
252 }
253 
254 void Upload::uploadAndDelete(const Region &region, const QFileInfo &file, const QString &transport)
255 {
256  Package package;
257  package.region = region;
258  package.file = file;
259  package.transport = transport;
260 
261  m_queue.removeAll(package);
262  m_queue << package;
263  processQueue();
264 }
265 
266 bool Upload::Package::operator ==(const Upload::Package &other) const
267 {
268  return region == other.region;
269 }
270 
271 Upload &Upload::instance()
272 {
273  static Upload m_instance;
274  return m_instance;
275 }
276 
277 bool Upload::uploadFiles() const
278 {
279  return m_uploadFiles;
280 }
281 
282 void Upload::setJobParameters(const JobParameters &parameters)
283 {
284  m_jobParameters = parameters;
285 }
286 
287 void Upload::setUploadFiles(bool arg)
288 {
289  m_uploadFiles = arg;
290 }
291 
292 QString Upload::targetDir() const
293 {
294  QString targetDir = "%1-w%2";
295  targetDir = targetDir.arg(QDateTime::currentDateTime().date().year());
296  targetDir = targetDir.arg(QDateTime::currentDateTime().date().weekNumber());
297  return targetDir;
298 }
299 
300 QString Upload::releaseDate() const
301 {
302  return QDateTime::currentDateTime().toString("MM/dd/yy");
303 }
304 
305 #include "upload.moc"
Upload
Definition: upload.h:22
Upload::uploadAndDelete
void uploadAndDelete(const Region &region, const QFileInfo &file, const QString &transport)
Definition: upload.cpp:254
upload.h
QObject
Marble::operator==
bool operator==(const DownloadPolicyKey &lhs, const DownloadPolicyKey &rhs)
Definition: DownloadPolicy.h:49
Region
Definition: region.h:18
Upload::uploadFiles
bool uploadFiles() const
Logger::setStatus
void setStatus(const QString &id, const QString &name, const QString &status, const QString &message)
Definition: logger.cpp:69
Upload::setJobParameters
void setJobParameters(const JobParameters &parameters)
Definition: upload.cpp:282
Upload::setUploadFiles
void setUploadFiles(bool arg)
Definition: upload.cpp:287
JobParameters
Definition: jobparameters.h:16
Upload::instance
static Upload & instance()
Definition: upload.cpp:271
logger.h
Logger::instance
static Logger & instance()
Definition: logger.cpp:53
Region::fileSize
static QString fileSize(const QFileInfo &file)
Definition: region.cpp:90
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:38:53 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

marble

Skip menu "marble"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal