Chris@208
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@208
|
2
|
Chris@208
|
3 /*
|
Chris@208
|
4 Sonic Visualiser
|
Chris@208
|
5 An audio file viewer and annotation editor.
|
Chris@208
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@208
|
7 This file copyright 2007 QMUL.
|
Chris@208
|
8
|
Chris@208
|
9 This program is free software; you can redistribute it and/or
|
Chris@208
|
10 modify it under the terms of the GNU General Public License as
|
Chris@208
|
11 published by the Free Software Foundation; either version 2 of the
|
Chris@208
|
12 License, or (at your option) any later version. See the file
|
Chris@208
|
13 COPYING included with this distribution for more information.
|
Chris@208
|
14 */
|
Chris@208
|
15
|
Chris@208
|
16 #include "RemoteFile.h"
|
Chris@208
|
17 #include "base/TempDirectory.h"
|
Chris@208
|
18 #include "base/Exceptions.h"
|
Chris@208
|
19
|
Chris@208
|
20 #include <QHttp>
|
Chris@208
|
21 #include <QFtp>
|
Chris@208
|
22 #include <QFileInfo>
|
Chris@208
|
23 #include <QDir>
|
Chris@208
|
24 #include <QApplication>
|
Chris@208
|
25 #include <QProgressDialog>
|
Chris@210
|
26 #include <QHttpResponseHeader>
|
Chris@208
|
27
|
Chris@208
|
28 #include <iostream>
|
Chris@208
|
29
|
Chris@208
|
30 int
|
Chris@208
|
31 RemoteFile::m_count = 0;
|
Chris@208
|
32
|
Chris@208
|
33 QMutex
|
Chris@208
|
34 RemoteFile::m_fileCreationMutex;
|
Chris@208
|
35
|
Chris@304
|
36 RemoteFile::RemoteRefCountMap
|
Chris@304
|
37 RemoteFile::m_refCountMap;
|
Chris@304
|
38
|
Chris@304
|
39 RemoteFile::RemoteLocalMap
|
Chris@304
|
40 RemoteFile::m_remoteLocalMap;
|
Chris@304
|
41
|
Chris@304
|
42 QMutex
|
Chris@304
|
43 RemoteFile::m_mapMutex;
|
Chris@304
|
44
|
Chris@208
|
45 RemoteFile::RemoteFile(QUrl url) :
|
Chris@304
|
46 m_url(url),
|
Chris@208
|
47 m_ftp(0),
|
Chris@208
|
48 m_http(0),
|
Chris@208
|
49 m_localFile(0),
|
Chris@208
|
50 m_ok(false),
|
Chris@210
|
51 m_lastStatus(0),
|
Chris@208
|
52 m_done(false),
|
Chris@210
|
53 m_progressDialog(0),
|
Chris@304
|
54 m_progressShowTimer(this),
|
Chris@304
|
55 m_referenced(false)
|
Chris@208
|
56 {
|
Chris@208
|
57 if (!canHandleScheme(url)) {
|
Chris@208
|
58 std::cerr << "RemoteFile::RemoteFile: ERROR: Unsupported scheme in URL \"" << url.toString().toStdString() << "\"" << std::endl;
|
Chris@208
|
59 return;
|
Chris@208
|
60 }
|
Chris@208
|
61
|
Chris@304
|
62 QMutexLocker locker(&m_mapMutex);
|
Chris@304
|
63
|
Chris@304
|
64 std::cerr << "RemoteFile::RemoteFile: refcount is " << m_refCountMap[m_url] << std::endl;
|
Chris@304
|
65
|
Chris@304
|
66 if (m_refCountMap[m_url] > 0) {
|
Chris@304
|
67 m_refCountMap[m_url]++;
|
Chris@304
|
68 m_localFilename = m_remoteLocalMap[m_url];
|
Chris@304
|
69 std::cerr << "raising it" << std::endl;
|
Chris@304
|
70 m_ok = true;
|
Chris@304
|
71 m_done = true;
|
Chris@304
|
72 m_referenced = true;
|
Chris@304
|
73 return;
|
Chris@304
|
74 }
|
Chris@304
|
75
|
Chris@208
|
76 m_localFilename = createLocalFile(url);
|
Chris@208
|
77 if (m_localFilename == "") return;
|
Chris@208
|
78 m_localFile = new QFile(m_localFilename);
|
Chris@208
|
79 m_localFile->open(QFile::WriteOnly);
|
Chris@208
|
80
|
Chris@208
|
81 QString scheme = url.scheme().toLower();
|
Chris@208
|
82
|
Chris@208
|
83 if (scheme == "http") {
|
Chris@208
|
84
|
Chris@211
|
85 m_ok = true;
|
Chris@208
|
86 m_http = new QHttp(url.host(), url.port(80));
|
Chris@208
|
87 connect(m_http, SIGNAL(done(bool)), this, SLOT(done(bool)));
|
Chris@208
|
88 connect(m_http, SIGNAL(dataReadProgress(int, int)),
|
Chris@208
|
89 this, SLOT(dataReadProgress(int, int)));
|
Chris@210
|
90 connect(m_http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)),
|
Chris@214
|
91 this, SLOT(httpResponseHeaderReceived(const QHttpResponseHeader &)));
|
Chris@279
|
92
|
Chris@279
|
93 // I don't quite understand this. url.path() returns a path
|
Chris@279
|
94 // without percent encoding; for example, spaces appear as
|
Chris@279
|
95 // literal spaces. This generally won't work if sent to the
|
Chris@279
|
96 // server directly. You can retrieve a correctly encoded URL
|
Chris@279
|
97 // from QUrl using url.toEncoded(), but that gives you the
|
Chris@279
|
98 // whole URL; there doesn't seem to be any way to retrieve
|
Chris@279
|
99 // only an encoded path. Furthermore there doesn't seem to be
|
Chris@279
|
100 // any way to convert a retrieved path into an encoded path
|
Chris@279
|
101 // without explicitly specifying that you don't want the path
|
Chris@279
|
102 // separators ("/") to be encoded. (Besides being painful to
|
Chris@279
|
103 // manage, I don't see how this can work correctly in any case
|
Chris@279
|
104 // where a percent-encoded "/" is supposed to appear within a
|
Chris@279
|
105 // path element?) There also seems to be no way to retrieve
|
Chris@279
|
106 // the path plus query string, i.e. everything that I need to
|
Chris@279
|
107 // send to the HTTP server. And no way for QHttp to take a
|
Chris@279
|
108 // QUrl argument. I'm obviously missing something.
|
Chris@279
|
109
|
Chris@279
|
110 // So, two ways to do this: query the bits from the URL,
|
Chris@279
|
111 // encode them individually, and glue them back together
|
Chris@279
|
112 // again...
|
Chris@279
|
113 /*
|
Chris@279
|
114 QString path = QUrl::toPercentEncoding(url.path(), "/");
|
Chris@279
|
115 QList<QPair<QString, QString> > query = url.queryItems();
|
Chris@279
|
116 if (!query.empty()) {
|
Chris@279
|
117 QStringList q2;
|
Chris@279
|
118 for (QList<QPair<QString, QString> >::iterator i = query.begin();
|
Chris@279
|
119 i != query.end(); ++i) {
|
Chris@279
|
120 q2.push_back(QString("%1=%3")
|
Chris@279
|
121 .arg(QString(QUrl::toPercentEncoding(i->first)))
|
Chris@279
|
122 .arg(QString(QUrl::toPercentEncoding(i->second))));
|
Chris@279
|
123 }
|
Chris@279
|
124 path = QString("%1%2%3")
|
Chris@279
|
125 .arg(path).arg("?")
|
Chris@279
|
126 .arg(q2.join("&"));
|
Chris@279
|
127 }
|
Chris@279
|
128 */
|
Chris@279
|
129
|
Chris@279
|
130 // ...or, much simpler but relying on knowledge about the
|
Chris@279
|
131 // scheme://host/path/path/query etc format of the URL, we can
|
Chris@279
|
132 // get the whole URL ready-encoded and then split it on "/" as
|
Chris@279
|
133 // appropriate...
|
Chris@279
|
134
|
Chris@279
|
135 QString path = "/" + QString(url.toEncoded()).section('/', 3);
|
Chris@279
|
136
|
Chris@279
|
137 std::cerr << "RemoteFile: path is \""
|
Chris@279
|
138 << path.toStdString() << "\"" << std::endl;
|
Chris@279
|
139
|
Chris@278
|
140 m_http->get(path, m_localFile);
|
Chris@208
|
141
|
Chris@208
|
142 } else if (scheme == "ftp") {
|
Chris@208
|
143
|
Chris@211
|
144 m_ok = true;
|
Chris@208
|
145 m_ftp = new QFtp;
|
Chris@208
|
146 connect(m_ftp, SIGNAL(done(bool)), this, SLOT(done(bool)));
|
Chris@214
|
147 connect(m_ftp, SIGNAL(commandFinished(int, bool)),
|
Chris@214
|
148 this, SLOT(ftpCommandFinished(int, bool)));
|
Chris@208
|
149 connect(m_ftp, SIGNAL(dataTransferProgress(qint64, qint64)),
|
Chris@208
|
150 this, SLOT(dataTransferProgress(qint64, qint64)));
|
Chris@208
|
151 m_ftp->connectToHost(url.host(), url.port(21));
|
Chris@208
|
152
|
Chris@208
|
153 QString username = url.userName();
|
Chris@208
|
154 if (username == "") {
|
Chris@208
|
155 username = "anonymous";
|
Chris@208
|
156 }
|
Chris@208
|
157
|
Chris@208
|
158 QString password = url.password();
|
Chris@208
|
159 if (password == "") {
|
Chris@208
|
160 password = QString("%1@%2").arg(getenv("USER")).arg(getenv("HOST"));
|
Chris@208
|
161 }
|
Chris@208
|
162
|
Chris@214
|
163 m_ftp->login(username, password);
|
Chris@214
|
164
|
Chris@214
|
165 QString dirpath = url.path().section('/', 0, -2);
|
Chris@214
|
166 QString filename = url.path().section('/', -1);
|
Chris@214
|
167
|
Chris@214
|
168 if (dirpath == "") dirpath = "/";
|
Chris@214
|
169 m_ftp->cd(dirpath);
|
Chris@214
|
170 m_ftp->get(filename, m_localFile);
|
Chris@208
|
171 }
|
Chris@208
|
172
|
Chris@208
|
173 if (m_ok) {
|
Chris@304
|
174
|
Chris@304
|
175 m_remoteLocalMap[m_url] = m_localFilename;
|
Chris@304
|
176 m_refCountMap[m_url]++;
|
Chris@304
|
177 m_referenced = true;
|
Chris@304
|
178
|
Chris@208
|
179 m_progressDialog = new QProgressDialog(tr("Downloading %1...").arg(url.toString()), tr("Cancel"), 0, 100);
|
Chris@210
|
180 m_progressDialog->hide();
|
Chris@210
|
181 connect(&m_progressShowTimer, SIGNAL(timeout()),
|
Chris@210
|
182 this, SLOT(showProgressDialog()));
|
Chris@210
|
183 connect(m_progressDialog, SIGNAL(canceled()), this, SLOT(cancelled()));
|
Chris@210
|
184 m_progressShowTimer.setSingleShot(true);
|
Chris@210
|
185 m_progressShowTimer.start(2000);
|
Chris@208
|
186 }
|
Chris@208
|
187 }
|
Chris@208
|
188
|
Chris@208
|
189 RemoteFile::~RemoteFile()
|
Chris@208
|
190 {
|
Chris@211
|
191 cleanup();
|
Chris@211
|
192 }
|
Chris@211
|
193
|
Chris@211
|
194 void
|
Chris@211
|
195 RemoteFile::cleanup()
|
Chris@211
|
196 {
|
Chris@211
|
197 m_done = true;
|
Chris@214
|
198 if (m_http) {
|
Chris@287
|
199 QHttp *h = m_http;
|
Chris@214
|
200 m_http = 0;
|
Chris@287
|
201 h->abort();
|
Chris@287
|
202 h->deleteLater();
|
Chris@214
|
203 }
|
Chris@214
|
204 if (m_ftp) {
|
Chris@287
|
205 QFtp *f = m_ftp;
|
Chris@214
|
206 m_ftp = 0;
|
Chris@287
|
207 f->abort();
|
Chris@287
|
208 f->deleteLater();
|
Chris@214
|
209 }
|
Chris@211
|
210 delete m_progressDialog;
|
Chris@211
|
211 m_progressDialog = 0;
|
Chris@304
|
212 delete m_localFile; // does not actually delete the file
|
Chris@211
|
213 m_localFile = 0;
|
Chris@208
|
214 }
|
Chris@208
|
215
|
Chris@208
|
216 bool
|
Chris@304
|
217 RemoteFile::isRemote(QString fileOrUrl)
|
Chris@304
|
218 {
|
Chris@304
|
219 return (fileOrUrl.startsWith("http:") || fileOrUrl.startsWith("ftp:"));
|
Chris@304
|
220 }
|
Chris@304
|
221
|
Chris@304
|
222 bool
|
Chris@208
|
223 RemoteFile::canHandleScheme(QUrl url)
|
Chris@208
|
224 {
|
Chris@208
|
225 QString scheme = url.scheme().toLower();
|
Chris@208
|
226 return (scheme == "http" || scheme == "ftp");
|
Chris@208
|
227 }
|
Chris@208
|
228
|
Chris@210
|
229 bool
|
Chris@210
|
230 RemoteFile::isAvailable()
|
Chris@210
|
231 {
|
Chris@211
|
232 while (m_ok && (!m_done && m_lastStatus == 0)) {
|
Chris@210
|
233 QApplication::processEvents();
|
Chris@210
|
234 }
|
Chris@211
|
235 bool available = true;
|
Chris@211
|
236 if (!m_ok) available = false;
|
Chris@211
|
237 else available = (m_lastStatus / 100 == 2);
|
Chris@211
|
238 std::cerr << "RemoteFile::isAvailable: " << (available ? "yes" : "no")
|
Chris@211
|
239 << std::endl;
|
Chris@211
|
240 return available;
|
Chris@210
|
241 }
|
Chris@210
|
242
|
Chris@208
|
243 void
|
Chris@208
|
244 RemoteFile::wait()
|
Chris@208
|
245 {
|
Chris@211
|
246 while (m_ok && !m_done) {
|
Chris@208
|
247 QApplication::processEvents();
|
Chris@208
|
248 }
|
Chris@208
|
249 }
|
Chris@208
|
250
|
Chris@208
|
251 bool
|
Chris@208
|
252 RemoteFile::isOK() const
|
Chris@208
|
253 {
|
Chris@208
|
254 return m_ok;
|
Chris@208
|
255 }
|
Chris@208
|
256
|
Chris@208
|
257 bool
|
Chris@208
|
258 RemoteFile::isDone() const
|
Chris@208
|
259 {
|
Chris@208
|
260 return m_done;
|
Chris@208
|
261 }
|
Chris@208
|
262
|
Chris@208
|
263 QString
|
Chris@208
|
264 RemoteFile::getLocalFilename() const
|
Chris@208
|
265 {
|
Chris@208
|
266 return m_localFilename;
|
Chris@208
|
267 }
|
Chris@208
|
268
|
Chris@208
|
269 QString
|
Chris@208
|
270 RemoteFile::getErrorString() const
|
Chris@208
|
271 {
|
Chris@208
|
272 return m_errorString;
|
Chris@208
|
273 }
|
Chris@208
|
274
|
Chris@208
|
275 void
|
Chris@208
|
276 RemoteFile::dataReadProgress(int done, int total)
|
Chris@208
|
277 {
|
Chris@208
|
278 dataTransferProgress(done, total);
|
Chris@208
|
279 }
|
Chris@208
|
280
|
Chris@208
|
281 void
|
Chris@214
|
282 RemoteFile::httpResponseHeaderReceived(const QHttpResponseHeader &resp)
|
Chris@210
|
283 {
|
Chris@210
|
284 m_lastStatus = resp.statusCode();
|
Chris@210
|
285 if (m_lastStatus / 100 >= 4) {
|
Chris@210
|
286 m_errorString = QString("%1 %2")
|
Chris@210
|
287 .arg(resp.statusCode()).arg(resp.reasonPhrase());
|
Chris@211
|
288 std::cerr << "RemoteFile::responseHeaderReceived: "
|
Chris@211
|
289 << m_errorString.toStdString() << std::endl;
|
Chris@211
|
290 } else {
|
Chris@211
|
291 std::cerr << "RemoteFile::responseHeaderReceived: "
|
Chris@211
|
292 << m_lastStatus << std::endl;
|
Chris@315
|
293 if (resp.hasContentType()) m_contentType = resp.contentType();
|
Chris@211
|
294 }
|
Chris@210
|
295 }
|
Chris@210
|
296
|
Chris@210
|
297 void
|
Chris@214
|
298 RemoteFile::ftpCommandFinished(int id, bool error)
|
Chris@214
|
299 {
|
Chris@214
|
300 std::cerr << "RemoteFile::ftpCommandFinished(" << id << ", " << error << ")" << std::endl;
|
Chris@214
|
301
|
Chris@214
|
302 if (!m_ftp) return;
|
Chris@214
|
303
|
Chris@214
|
304 QFtp::Command command = m_ftp->currentCommand();
|
Chris@214
|
305
|
Chris@214
|
306 if (!error) {
|
Chris@214
|
307 std::cerr << "RemoteFile::ftpCommandFinished: success for command "
|
Chris@214
|
308 << command << std::endl;
|
Chris@214
|
309 return;
|
Chris@214
|
310 }
|
Chris@214
|
311
|
Chris@214
|
312 if (command == QFtp::ConnectToHost) {
|
Chris@214
|
313 m_errorString = tr("Failed to connect to FTP server");
|
Chris@214
|
314 } else if (command == QFtp::Login) {
|
Chris@214
|
315 m_errorString = tr("Login failed");
|
Chris@214
|
316 } else if (command == QFtp::Cd) {
|
Chris@214
|
317 m_errorString = tr("Failed to change to correct directory");
|
Chris@214
|
318 } else if (command == QFtp::Get) {
|
Chris@214
|
319 m_errorString = tr("FTP download aborted");
|
Chris@214
|
320 }
|
Chris@214
|
321
|
Chris@214
|
322 m_lastStatus = 400; // for done()
|
Chris@214
|
323 }
|
Chris@214
|
324
|
Chris@214
|
325 void
|
Chris@208
|
326 RemoteFile::dataTransferProgress(qint64 done, qint64 total)
|
Chris@208
|
327 {
|
Chris@211
|
328 if (!m_progressDialog) return;
|
Chris@211
|
329
|
Chris@208
|
330 int percent = int((double(done) / double(total)) * 100.0 - 0.1);
|
Chris@208
|
331 emit progress(percent);
|
Chris@208
|
332
|
Chris@211
|
333 if (percent > 0) {
|
Chris@211
|
334 m_progressDialog->setValue(percent);
|
Chris@211
|
335 m_progressDialog->show();
|
Chris@211
|
336 }
|
Chris@210
|
337 }
|
Chris@210
|
338
|
Chris@210
|
339 void
|
Chris@210
|
340 RemoteFile::cancelled()
|
Chris@210
|
341 {
|
Chris@211
|
342 deleteLocalFile();
|
Chris@210
|
343 m_done = true;
|
Chris@210
|
344 m_ok = false;
|
Chris@210
|
345 m_errorString = tr("Download cancelled");
|
Chris@208
|
346 }
|
Chris@208
|
347
|
Chris@208
|
348 void
|
Chris@208
|
349 RemoteFile::done(bool error)
|
Chris@208
|
350 {
|
Chris@214
|
351 std::cerr << "RemoteFile::done(" << error << ")" << std::endl;
|
Chris@211
|
352
|
Chris@211
|
353 if (m_done) return;
|
Chris@211
|
354
|
Chris@208
|
355 emit progress(100);
|
Chris@210
|
356
|
Chris@208
|
357 if (error) {
|
Chris@208
|
358 if (m_http) {
|
Chris@208
|
359 m_errorString = m_http->errorString();
|
Chris@208
|
360 } else if (m_ftp) {
|
Chris@208
|
361 m_errorString = m_ftp->errorString();
|
Chris@208
|
362 }
|
Chris@208
|
363 }
|
Chris@208
|
364
|
Chris@210
|
365 if (m_lastStatus / 100 >= 4) {
|
Chris@211
|
366 error = true;
|
Chris@210
|
367 }
|
Chris@210
|
368
|
Chris@211
|
369 cleanup();
|
Chris@208
|
370
|
Chris@211
|
371 if (!error) {
|
Chris@208
|
372 QFileInfo fi(m_localFilename);
|
Chris@208
|
373 if (!fi.exists()) {
|
Chris@208
|
374 m_errorString = tr("Failed to create local file %1").arg(m_localFilename);
|
Chris@211
|
375 error = true;
|
Chris@208
|
376 } else if (fi.size() == 0) {
|
Chris@208
|
377 m_errorString = tr("File contains no data!");
|
Chris@211
|
378 error = true;
|
Chris@208
|
379 }
|
Chris@208
|
380 }
|
Chris@211
|
381
|
Chris@211
|
382 if (error) {
|
Chris@211
|
383 deleteLocalFile();
|
Chris@211
|
384 }
|
Chris@211
|
385
|
Chris@211
|
386 m_ok = !error;
|
Chris@211
|
387 m_done = true;
|
Chris@304
|
388 emit ready();
|
Chris@211
|
389 }
|
Chris@211
|
390
|
Chris@211
|
391 void
|
Chris@211
|
392 RemoteFile::deleteLocalFile()
|
Chris@211
|
393 {
|
Chris@211
|
394 // std::cerr << "RemoteFile::deleteLocalFile" << std::endl;
|
Chris@211
|
395
|
Chris@211
|
396 cleanup();
|
Chris@211
|
397
|
Chris@211
|
398 if (m_localFilename == "") return;
|
Chris@211
|
399
|
Chris@304
|
400 if (m_referenced) {
|
Chris@304
|
401
|
Chris@304
|
402 QMutexLocker locker(&m_mapMutex);
|
Chris@304
|
403 m_referenced = false;
|
Chris@304
|
404
|
Chris@304
|
405 if (m_refCountMap[m_url] > 0) {
|
Chris@304
|
406 m_refCountMap[m_url]--;
|
Chris@304
|
407 if (m_refCountMap[m_url] > 0) {
|
Chris@304
|
408 m_done = true;
|
Chris@304
|
409 return;
|
Chris@304
|
410 }
|
Chris@304
|
411 }
|
Chris@304
|
412 }
|
Chris@304
|
413
|
Chris@211
|
414 m_fileCreationMutex.lock();
|
Chris@211
|
415
|
Chris@211
|
416 if (!QFile(m_localFilename).remove()) {
|
Chris@211
|
417 std::cerr << "RemoteFile::deleteLocalFile: ERROR: Failed to delete file \"" << m_localFilename.toStdString() << "\"" << std::endl;
|
Chris@211
|
418 } else {
|
Chris@211
|
419 m_localFilename = "";
|
Chris@211
|
420 }
|
Chris@211
|
421
|
Chris@211
|
422 m_fileCreationMutex.unlock();
|
Chris@211
|
423
|
Chris@208
|
424 m_done = true;
|
Chris@208
|
425 }
|
Chris@208
|
426
|
Chris@210
|
427 void
|
Chris@210
|
428 RemoteFile::showProgressDialog()
|
Chris@210
|
429 {
|
Chris@210
|
430 if (m_progressDialog) m_progressDialog->show();
|
Chris@210
|
431 }
|
Chris@210
|
432
|
Chris@208
|
433 QString
|
Chris@208
|
434 RemoteFile::createLocalFile(QUrl url)
|
Chris@208
|
435 {
|
Chris@208
|
436 QDir dir;
|
Chris@208
|
437 try {
|
Chris@208
|
438 dir = TempDirectory::getInstance()->getSubDirectoryPath("download");
|
Chris@208
|
439 } catch (DirectoryCreationFailed f) {
|
Chris@208
|
440 std::cerr << "RemoteFile::createLocalFile: ERROR: Failed to create temporary directory: " << f.what() << std::endl;
|
Chris@208
|
441 return "";
|
Chris@208
|
442 }
|
Chris@208
|
443
|
Chris@208
|
444 QString filepart = url.path().section('/', -1, -1,
|
Chris@208
|
445 QString::SectionSkipEmpty);
|
Chris@208
|
446
|
Chris@208
|
447 QString extension = filepart.section('.', -1);
|
Chris@208
|
448 QString base = filepart;
|
Chris@208
|
449 if (extension != "") {
|
Chris@208
|
450 base = base.left(base.length() - extension.length() - 1);
|
Chris@208
|
451 }
|
Chris@208
|
452 if (base == "") base = "remote";
|
Chris@208
|
453
|
Chris@208
|
454 QString filename;
|
Chris@208
|
455
|
Chris@208
|
456 if (extension == "") {
|
Chris@208
|
457 filename = base;
|
Chris@208
|
458 } else {
|
Chris@208
|
459 filename = QString("%1.%2").arg(base).arg(extension);
|
Chris@208
|
460 }
|
Chris@208
|
461
|
Chris@208
|
462 QString filepath(dir.filePath(filename));
|
Chris@208
|
463
|
Chris@208
|
464 std::cerr << "RemoteFile::createLocalFile: URL is \"" << url.toString().toStdString() << "\", dir is \"" << dir.path().toStdString() << "\", base \"" << base.toStdString() << "\", extension \"" << extension.toStdString() << "\", filebase \"" << filename.toStdString() << "\", filename \"" << filepath.toStdString() << "\"" << std::endl;
|
Chris@208
|
465
|
Chris@208
|
466 m_fileCreationMutex.lock();
|
Chris@208
|
467 ++m_count;
|
Chris@208
|
468
|
Chris@208
|
469 if (QFileInfo(filepath).exists() ||
|
Chris@208
|
470 !QFile(filepath).open(QFile::WriteOnly)) {
|
Chris@208
|
471
|
Chris@208
|
472 std::cerr << "RemoteFile::createLocalFile: Failed to create local file \""
|
Chris@208
|
473 << filepath.toStdString() << "\" for URL \""
|
Chris@208
|
474 << url.toString().toStdString() << "\" (or file already exists): appending suffix instead" << std::endl;
|
Chris@208
|
475
|
Chris@208
|
476
|
Chris@208
|
477 if (extension == "") {
|
Chris@208
|
478 filename = QString("%1_%2").arg(base).arg(m_count);
|
Chris@208
|
479 } else {
|
Chris@208
|
480 filename = QString("%1_%2.%3").arg(base).arg(m_count).arg(extension);
|
Chris@208
|
481 }
|
Chris@208
|
482 filepath = dir.filePath(filename);
|
Chris@208
|
483
|
Chris@208
|
484 if (QFileInfo(filepath).exists() ||
|
Chris@208
|
485 !QFile(filepath).open(QFile::WriteOnly)) {
|
Chris@208
|
486
|
Chris@208
|
487 std::cerr << "RemoteFile::createLocalFile: ERROR: Failed to create local file \""
|
Chris@208
|
488 << filepath.toStdString() << "\" for URL \""
|
Chris@208
|
489 << url.toString().toStdString() << "\" (or file already exists)" << std::endl;
|
Chris@208
|
490
|
Chris@208
|
491 m_fileCreationMutex.unlock();
|
Chris@208
|
492 return "";
|
Chris@208
|
493 }
|
Chris@208
|
494 }
|
Chris@208
|
495
|
Chris@208
|
496 m_fileCreationMutex.unlock();
|
Chris@208
|
497
|
Chris@208
|
498 std::cerr << "RemoteFile::createLocalFile: url "
|
Chris@208
|
499 << url.toString().toStdString() << " -> local filename "
|
Chris@208
|
500 << filepath.toStdString() << std::endl;
|
Chris@208
|
501
|
Chris@208
|
502 return filepath;
|
Chris@208
|
503 }
|