• 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
  • src
  • lib
  • marble
  • cloudsync
OwncloudSyncBackend.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 2013 Utku Aydın <utkuaydin34@gmail.com>
9 //
10 
11 #include "OwncloudSyncBackend.h"
12 
13 #include "MarbleDirs.h"
14 #include "MarbleModel.h"
15 #include "MarbleDebug.h"
16 #include "GeoDocument.h"
17 #include "MarbleWidget.h"
18 #include "RenderPlugin.h"
19 #include "RoutingModel.h"
20 #include "GeoDataParser.h"
21 #include "GeoDataFolder.h"
22 #include "RoutingManager.h"
23 #include "GeoDataDocument.h"
24 #include "CloudRouteModel.h"
25 #include "GeoDataPlacemark.h"
26 #include "CloudSyncManager.h"
27 
28 #include <QNetworkAccessManager>
29 #include <QScriptValueIterator>
30 #include <QNetworkRequest>
31 #include <QScriptEngine>
32 #include <QFileInfo>
33 #include <QBuffer>
34 #include <QTimer>
35 #include <QDir>
36 
37 namespace Marble
38 {
39 
40 class OwncloudSyncBackend::Private {
41 
42  public:
43  Private( CloudSyncManager* cloudSyncManager );
44 
45  QDir m_cacheDir;
46  QNetworkAccessManager m_network;
47  QNetworkReply *m_routeUploadReply;
48  QNetworkReply *m_routeListReply;
49  QNetworkReply *m_routeDownloadReply;
50  QNetworkReply *m_routeDeleteReply;
51 
52  QVector<RouteItem> m_routeList;
53 
54  QString m_routeUploadEndpoint;
55  QString m_routeListEndpoint;
56  QString m_routeDownloadEndpoint;
57  QString m_routeDeleteEndpoint;
58  QString m_routePreviewEndpoint;
59 
60  CloudSyncManager* m_cloudSyncManager;
61  QUrl m_apiUrl;
62 };
63 
64 OwncloudSyncBackend::Private::Private( CloudSyncManager* cloudSyncManager ) :
65  m_cacheDir( MarbleDirs::localPath() + "/cloudsync/cache/routes/" ),
66  m_network(),
67  m_routeUploadReply(),
68  m_routeListReply(),
69  m_routeDownloadReply(),
70  m_routeDeleteReply(),
71  m_routeList(),
72  // Route API endpoints
73  m_routeUploadEndpoint( "routes/create" ),
74  m_routeListEndpoint( "routes" ),
75  m_routeDownloadEndpoint( "routes" ),
76  m_routeDeleteEndpoint( "routes/delete" ),
77  m_routePreviewEndpoint( "routes/preview" ),
78  m_cloudSyncManager( cloudSyncManager )
79 {
80 }
81 
82 OwncloudSyncBackend::OwncloudSyncBackend( CloudSyncManager* cloudSyncManager ) :
83  d( new Private( cloudSyncManager ) )
84 {
85 }
86 
87 OwncloudSyncBackend::~OwncloudSyncBackend()
88 {
89  delete d;
90 }
91 
92 void OwncloudSyncBackend::uploadRoute( const QString &timestamp )
93 {
94  QString word = "----MarbleCloudBoundary";
95  QString boundary = QString( "--%0" ).arg( word );
96  QNetworkRequest request( endpointUrl( d->m_routeUploadEndpoint ) );
97  request.setHeader( QNetworkRequest::ContentTypeHeader, QString( "multipart/form-data; boundary=%0" ).arg( word ) );
98 
99  QByteArray data;
100  data.append( QString( boundary + "\r\n" ).toUtf8() );
101 
102  // Timestamp part
103  data.append( "Content-Disposition: form-data; name=\"timestamp\"" );
104  data.append( "\r\n\r\n" );
105  data.append( QString( timestamp + "\r\n" ).toUtf8() );
106  data.append( QString( boundary + "\r\n" ).toUtf8() );
107 
108  // Name part
109  data.append( "Content-Disposition: form-data; name=\"name\"" );
110  data.append( "\r\n\r\n" );
111  data.append( routeName( timestamp ).toUtf8() );
112  data.append( "\r\n" );
113  data.append( QString( boundary + "\r\n" ).toUtf8() );
114 
115  // Duration part
116  data.append( "Content-Disposition: form-data; name=\"duration\"" );
117  data.append( "\r\n\r\n" );
118  data.append( "0\r\n" );
119  data.append( QString( boundary + "\r\n" ).toUtf8() );
120 
121  // Distance part
122  data.append( "Content-Disposition: form-data; name=\"distance\"" );
123  data.append( "\r\n\r\n" );
124  data.append( "0\r\n" );
125  data.append( QString( boundary + "\r\n" ).toUtf8() );
126 
127  // KML part
128  data.append( QString( "Content-Disposition: form-data; name=\"kml\"; filename=\"%0.kml\"" ).arg( timestamp ).toUtf8() );
129  data.append( "\r\n" );
130  data.append( "Content-Type: application/vnd.google-earth.kml+xml" );
131  data.append( "\r\n\r\n" );
132 
133  QFile kmlFile( d->m_cacheDir.absolutePath() + QString( "/%0.kml" ).arg( timestamp ) );
134 
135  if( !kmlFile.open( QFile::ReadOnly ) ) {
136  mDebug() << "Could not open " << timestamp << ".kml. Either it has not been saved" <<
137  " to cache for upload or another application removed it from there.";
138  return;
139  }
140 
141  data.append( kmlFile.readAll() );
142  data.append( "\r\n" );
143  data.append( QString( boundary + "\r\n" ).toUtf8() );
144 
145  kmlFile.close();
146 
147  // Preview part
148  data.append( QString( "Content-Disposition: form-data; name=\"preview\"; filename=\"%0.jpg\"" ).arg( timestamp ).toUtf8() );
149  data.append( "\r\n" );
150  data.append( "Content-Type: image/jpg" );
151  data.append( "\r\n\r\n" );
152 
153  QByteArray previewBytes;
154  QBuffer previewBuffer( &previewBytes );
155  QPixmap preview = createPreview( timestamp );
156  preview.save( &previewBuffer, "JPG" );
157 
158  data.append( previewBytes );
159  data.append( "\r\n" );
160  data.append( QString( boundary + "\r\n" ).toUtf8() );
161 
162  d->m_routeUploadReply = d->m_network.post( request, data );
163  connect( d->m_routeUploadReply, SIGNAL(uploadProgress(qint64,qint64)), this, SIGNAL(routeUploadProgress(qint64,qint64)) );
164 }
165 
166 void OwncloudSyncBackend::downloadRouteList()
167 {
168  QNetworkRequest request( endpointUrl( d->m_routeListEndpoint ) );
169  d->m_routeListReply = d->m_network.get( request );
170  connect( d->m_routeListReply, SIGNAL(downloadProgress(qint64,qint64)), this, SIGNAL(routeListDownloadProgress(qint64,qint64)) );
171  connect( d->m_routeListReply, SIGNAL(finished()), this, SLOT(prepareRouteList()) );
172 }
173 
174 void OwncloudSyncBackend::downloadRoute( const QString &timestamp )
175 {
176  QNetworkRequest routeRequest( endpointUrl( d->m_routeDownloadEndpoint, timestamp ) );
177  d->m_routeDownloadReply = d->m_network.get( routeRequest );
178  connect( d->m_routeDownloadReply, SIGNAL(finished()), this, SLOT(saveDownloadedRoute()) );
179  connect( d->m_routeDownloadReply, SIGNAL(downloadProgress(qint64,qint64)), this, SIGNAL(routeDownloadProgress(qint64,qint64)) );
180 }
181 
182 void OwncloudSyncBackend::deleteRoute( const QString &timestamp )
183 {
184  QUrl url( endpointUrl( d->m_routeDeleteEndpoint, timestamp ) );
185  QNetworkRequest request( url );
186  d->m_routeDeleteReply = d->m_network.deleteResource( request );
187  connect( d->m_routeDeleteReply, SIGNAL(finished()), this, SIGNAL(routeDeleted()) );
188 }
189 
190 QPixmap OwncloudSyncBackend::createPreview( const QString &timestamp )
191 {
192  MarbleWidget *mapWidget = new MarbleWidget;
193  foreach( RenderPlugin* plugin, mapWidget->renderPlugins() ) {
194  plugin->setEnabled( false );
195  }
196 
197  mapWidget->setProjection( Mercator );
198  mapWidget->setMapThemeId( "earth/openstreetmap/openstreetmap.dgml" );
199  mapWidget->resize( 512, 512 );
200 
201  RoutingManager* manager = mapWidget->model()->routingManager();
202  manager->loadRoute( d->m_cacheDir.absolutePath() + QString( "/%0.kml" ).arg( timestamp ) );
203  GeoDataLatLonBox const bbox = manager->routingModel()->route().bounds();
204 
205  if ( !bbox.isEmpty() ) {
206  mapWidget->centerOn( bbox );
207  }
208 
209  QPixmap pixmap = QPixmap::grabWidget( mapWidget );
210  QDir( d->m_cacheDir.absolutePath() ).mkpath( "preview" );
211  pixmap.save( d->m_cacheDir.absolutePath() + "/preview/" + timestamp + ".jpg" );
212 
213  delete mapWidget;
214  return pixmap;
215 }
216 
217 QString OwncloudSyncBackend::routeName( const QString &timestamp )
218 {
219  QFile file( d->m_cacheDir.absolutePath() + QString( "/%0.kml" ).arg( timestamp ) );
220  file.open( QFile::ReadOnly );
221 
222  GeoDataParser parser( GeoData_KML );
223  if( !parser.read( &file ) ) {
224  mDebug() << "Could not read " << timestamp << ".kml. Timestamp will be used as "
225  << "route name because of the problem";
226  return timestamp;
227  }
228  file.close();
229 
230  QString routeName;
231  GeoDocument *geoDoc = parser.releaseDocument();
232  GeoDataDocument *container = dynamic_cast<GeoDataDocument*>( geoDoc );
233  if ( container && container->size() > 0 ) {
234  GeoDataFolder *folder = container->folderList().at( 0 );
235  foreach ( GeoDataPlacemark *placemark, folder->placemarkList() ) {
236  routeName.append( placemark->name() );
237  routeName.append( " - " );
238  }
239  }
240 
241  return routeName.left( routeName.length() - 3 );
242 }
243 
244 void OwncloudSyncBackend::cancelUpload()
245 {
246  d->m_routeUploadReply->abort();
247 }
248 
249 void OwncloudSyncBackend::prepareRouteList()
250 {
251  QString result = d->m_routeListReply->readAll();
252 
253  QScriptEngine engine;
254  QScriptValue response = engine.evaluate( QString( "(%0)" ).arg( result ) );
255  QScriptValue routes = response.property( "data" );
256 
257  d->m_routeList.clear();
258 
259  if( routes.isArray() ) {
260  QScriptValueIterator iterator( routes );
261 
262  while( iterator.hasNext() ) {
263  iterator.next();
264 
265  RouteItem route;
266  route.setIdentifier( iterator.value().property( "timestamp" ).toString() );
267  route.setName ( iterator.value().property( "name" ).toString() );
268  route.setDistance( iterator.value().property( "distance" ).toString() );
269  route.setDuration( iterator.value().property( "duration" ).toString() );
270  route.setPreviewUrl( endpointUrl( d->m_routePreviewEndpoint, route.identifier() ) );
271  route.setOnCloud( true );
272 
273  d->m_routeList.append( route );
274  }
275  }
276 
277  // FIXME Find why an empty item added to the end.
278  if( !d->m_routeList.isEmpty() ) {
279  d->m_routeList.remove( d->m_routeList.count() - 1 );
280  }
281 
282  emit routeListDownloaded( d->m_routeList );
283 }
284 
285 void OwncloudSyncBackend::saveDownloadedRoute()
286 {
287  QString timestamp = QFileInfo( d->m_routeDownloadReply->url().toString() ).fileName();
288 
289  bool pathCreated = d->m_cacheDir.mkpath( d->m_cacheDir.absolutePath() );
290  if ( !pathCreated ) {
291  mDebug() << "Couldn't create the path " << d->m_cacheDir.absolutePath() <<
292  ". Check if your user has sufficent permissions for this operation.";
293  }
294 
295  QString kmlFilePath = QString( "%0/%1.kml").arg( d->m_cacheDir.absolutePath(), timestamp );
296  QFile kmlFile( kmlFilePath );
297  bool fileOpened = kmlFile.open( QFile::ReadWrite );
298 
299  if ( !fileOpened ) {
300  mDebug() << "Failed to open file" << kmlFilePath << " for writing."
301  << " Its directory either is missing or is not writable.";
302  return;
303  }
304 
305  kmlFile.write( d->m_routeDownloadReply->readAll() );
306  kmlFile.close();
307 
308  QString previewPath = QString( "%0/preview/" ).arg( d->m_cacheDir.absolutePath() );
309  bool previewPathCreated = d->m_cacheDir.mkpath( previewPath );
310  if ( !previewPathCreated ) {
311  mDebug() << "Couldn't create the path " << previewPath <<
312  ". Check if your user has sufficent permissions for this operation.";
313  }
314 
315  QString previewFilePath = QString( "%0/preview/%1.jpg").arg( d->m_cacheDir.absolutePath(), timestamp );
316  QFile previewFile( previewFilePath );
317  bool previewFileOpened = previewFile.open( QFile::ReadWrite );
318 
319  if ( !previewFileOpened ) {
320  mDebug() << "Failed to open file" << previewFilePath << "for writing."
321  << " Its directory either is missing or is not writable.";
322  return;
323  }
324 
325  QPixmap preview = createPreview( timestamp );
326  preview.save( &previewFile, "JPG" );
327  previewFile.close();
328 
329  emit routeDownloaded();
330 }
331 
332 void OwncloudSyncBackend::setApiUrl( const QUrl &apiUrl )
333 {
334  d->m_apiUrl = apiUrl;
335 }
336 
337 QUrl OwncloudSyncBackend::endpointUrl( const QString &endpoint )
338 {
339  QString endpointUrl = QString( "%0/%1" ).arg( d->m_apiUrl.toString() ).arg( endpoint );
340  return QUrl( endpointUrl );
341 }
342 
343 QUrl OwncloudSyncBackend::endpointUrl( const QString &endpoint, const QString &parameter )
344 {
345  QString endpointUrl = QString( "%0/%1/%2" ).arg( d->m_apiUrl.toString() ).arg( endpoint ).arg( parameter );
346  return QUrl( endpointUrl );
347 }
348 
349 void OwncloudSyncBackend::removeFromCache( const QDir &cacheDir, const QString &timestamp )
350 {
351  bool fileRemoved = QFile( QString( "%0/%1.kml" ).arg( cacheDir.absolutePath(), timestamp ) ).remove();
352  bool previewRemoved = QFile( QString( "%0/preview/%1.jpg" ).arg( cacheDir.absolutePath(), timestamp ) ).remove();
353  if ( !fileRemoved || !previewRemoved ) {
354  mDebug() << "Failed to remove locally cached route " << timestamp << ". It might "
355  "have been removed already, or its directory is missing / not writable.";
356  }
357 
358  emit removedFromCache( timestamp );
359 }
360 
361 }
362 
363 #include "OwncloudSyncBackend.moc"
GeoDataDocument.h
RoutingModel.h
Marble::GeoDataLatLonBox::isEmpty
virtual bool isEmpty() const
Indicates whether the bounding box is not initialised (and contains nothing).
Definition: GeoDataLatLonBox.cpp:768
Marble::GeoDataDocument
A container for Features, Styles and in the future Schemas.
Definition: GeoDataDocument.h:64
Marble::GeoDataParser
Definition: GeoDataParser.h:40
Marble::OwncloudSyncBackend::uploadRoute
void uploadRoute(const QString &timestamp)
Definition: OwncloudSyncBackend.cpp:92
MarbleModel.h
This file contains the headers for MarbleModel.
Marble::Route::bounds
GeoDataLatLonBox bounds() const
Definition: Route.cpp:46
Marble::OwncloudSyncBackend::routeUploadProgress
void routeUploadProgress(qint64 sent, qint64 total)
Marble::OwncloudSyncBackend::removedFromCache
void removedFromCache(const QString &timestamp)
Marble::MarbleWidget::setProjection
void setProjection(int projection)
Set the Projection used for the map.
Definition: MarbleWidget.cpp:702
Marble::RouteItem::setPreviewUrl
void setPreviewUrl(const QUrl &previewUrl)
Definition: RouteItem.cpp:86
Marble::RouteItem::setIdentifier
void setIdentifier(const QString &identifier)
Definition: RouteItem.cpp:56
GeoDataParser.h
Marble::RouteItem
Definition: RouteItem.h:20
Marble::RoutingModel::route
const Route & route() const
Definition: RoutingModel.cpp:416
MarbleDebug.h
Marble::RouteItem::setDuration
void setDuration(const QString &duration)
Definition: RouteItem.cpp:106
Marble::OwncloudSyncBackend::deleteRoute
void deleteRoute(const QString &timestamp)
Definition: OwncloudSyncBackend.cpp:182
Marble::OwncloudSyncBackend::routeDownloaded
void routeDownloaded()
CloudRouteModel.h
Marble::OwncloudSyncBackend::routeDownloadProgress
void routeDownloadProgress(qint64 received, qint64 total)
Marble::RouteItem::identifier
QString identifier() const
Definition: RouteItem.cpp:51
Marble::MarbleWidget
A widget class that displays a view of the earth.
Definition: MarbleWidget.h:102
Marble::GeoData_KML
Definition: GeoDataParser.h:36
Marble::RoutingManager::routingModel
RoutingModel * routingModel()
Provides access to the routing model which contains a list of routing instructions describing steps t...
Definition: RoutingManager.cpp:260
Marble::MarbleWidget::setMapThemeId
void setMapThemeId(const QString &maptheme)
Set a new map theme.
Definition: MarbleWidget.cpp:865
RoutingManager.h
Marble::GeoParser::read
bool read(QIODevice *)
Main API for reading the XML document.
Definition: GeoParser.cpp:74
Marble::OwncloudSyncBackend::OwncloudSyncBackend
OwncloudSyncBackend(CloudSyncManager *cloudSyncManager)
Definition: OwncloudSyncBackend.cpp:82
Marble::MarbleModel::routingManager
RoutingManager * routingManager()
Definition: MarbleModel.cpp:605
Marble::Mercator
Mercator projection.
Definition: MarbleGlobal.h:47
Marble::RoutingManager::loadRoute
void loadRoute(const QString &filename)
Opens the given filename (kml format) and loads the route contained in it.
Definition: RoutingManager.cpp:336
MarbleDirs.h
Marble::GeoDataContainer::folderList
QVector< GeoDataFolder * > folderList() const
A convenience function that returns all folders in this container.
Definition: GeoDataContainer.cpp:90
Marble::MarbleWidget::model
MarbleModel * model() const
Return the model that this view shows.
Definition: MarbleWidget.cpp:283
GeoDocument.h
Marble::OwncloudSyncBackend::cancelUpload
void cancelUpload()
Definition: OwncloudSyncBackend.cpp:244
Marble::GeoDataContainer::size
int size() const
size of the container
Definition: GeoDataContainer.cpp:179
Marble::RouteItem::setName
void setName(const QString &name)
Definition: RouteItem.cpp:66
Marble::GeoDataFolder
Definition: GeoDataFolder.h:50
GeoDataPlacemark.h
Marble::RoutingManager
Delegates data retrieval and model updates to the appropriate routing provider.
Definition: RoutingManager.h:37
Marble::OwncloudSyncBackend::routeDeleted
void routeDeleted()
Marble::OwncloudSyncBackend::downloadRouteList
void downloadRouteList()
Definition: OwncloudSyncBackend.cpp:166
Marble::MarbleWidget::centerOn
void centerOn(const qreal lon, const qreal lat, bool animated=false)
Center the view on a geographical point.
Definition: MarbleWidget.cpp:626
Marble::OwncloudSyncBackend::createPreview
QPixmap createPreview(const QString &timestamp)
Definition: OwncloudSyncBackend.cpp:190
OwncloudSyncBackend.h
GeoDataFolder.h
Marble::OwncloudSyncBackend::downloadRoute
void downloadRoute(const QString &timestamp)
Definition: OwncloudSyncBackend.cpp:174
Marble::RenderPlugin::setEnabled
void setEnabled(bool enabled)
settting enabled
Definition: RenderPlugin.cpp:137
Marble::OwncloudSyncBackend::setApiUrl
void setApiUrl(const QUrl &apiUrl)
Definition: OwncloudSyncBackend.cpp:332
Marble::GeoDocument
A shared base class between GeoDataDocument/GeoSourceDocument.
Definition: GeoDocument.h:42
Marble::GeoDataFeature::name
QString name() const
The name of the feature.
Definition: GeoDataFeature.cpp:480
RenderPlugin.h
Marble::RouteItem::setOnCloud
void setOnCloud(const bool onCloud)
Definition: RouteItem.cpp:116
Marble::OwncloudSyncBackend::routeListDownloaded
void routeListDownloaded(const QVector< RouteItem > &routeList)
Marble::OwncloudSyncBackend::removeFromCache
void removeFromCache(const QDir &cacheDir, const QString &timestamp)
Removes route with given timestamp from cache.
Definition: OwncloudSyncBackend.cpp:349
MarbleWidget.h
This file contains the headers for MarbleWidget.
Marble::OwncloudSyncBackend::endpointUrl
QUrl endpointUrl(const QString &endpoint)
Generates an endpoint URL by appending endpoint name to API URL.
Definition: OwncloudSyncBackend.cpp:337
Marble::CloudSyncManager
Definition: CloudSyncManager.h:25
Marble::OwncloudSyncBackend::routeName
QString routeName(const QString &timestamp)
Definition: OwncloudSyncBackend.cpp:217
Marble::GeoDataPlacemark
a class representing a point of interest on the map
Definition: GeoDataPlacemark.h:54
CloudSyncManager.h
Marble::mDebug
QDebug mDebug()
a function to replace qDebug() in Marble library code
Definition: MarbleDebug.cpp:31
Marble::OwncloudSyncBackend::routeListDownloadProgress
void routeListDownloadProgress(qint64 received, qint64 total)
Marble::RenderPlugin
The abstract class that creates a renderable item.
Definition: RenderPlugin.h:43
Marble::MarbleWidget::renderPlugins
QList< RenderPlugin * > renderPlugins() const
Returns a list of all RenderPlugins on the widget, this includes float items.
Definition: MarbleWidget.cpp:1251
Marble::RouteItem::setDistance
void setDistance(const QString &distance)
Definition: RouteItem.cpp:96
Marble::OwncloudSyncBackend::~OwncloudSyncBackend
~OwncloudSyncBackend()
Definition: OwncloudSyncBackend.cpp:87
Marble::GeoDataLatLonBox
A class that defines a 2D bounding box for geographic data.
Definition: GeoDataLatLonBox.h:51
Marble::GeoParser::releaseDocument
GeoDocument * releaseDocument()
retrieve the parsed document and reset the parser If parsing was successful, retrieve the resulting d...
Definition: GeoParser.cpp:205
Marble::GeoDataContainer::placemarkList
QVector< GeoDataPlacemark * > placemarkList() const
A convenience function that returns all placemarks in this container.
Definition: GeoDataContainer.cpp:107
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:38:52 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