00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "FileSource.h"
00017 #include "ProgressPrinter.h"
00018
00019 #include "base/TempDirectory.h"
00020 #include "base/Exceptions.h"
00021
00022 #include <QHttp>
00023 #include <QFtp>
00024 #include <QFileInfo>
00025 #include <QDir>
00026 #include <QApplication>
00027 #include <QProgressDialog>
00028 #include <QHttpResponseHeader>
00029
00030 #include <iostream>
00031
00032 #define DEBUG_FILE_SOURCE 1
00033
00034 int
00035 FileSource::m_count = 0;
00036
00037 QMutex
00038 FileSource::m_fileCreationMutex;
00039
00040 FileSource::RemoteRefCountMap
00041 FileSource::m_refCountMap;
00042
00043 FileSource::RemoteLocalMap
00044 FileSource::m_remoteLocalMap;
00045
00046 QMutex
00047 FileSource::m_mapMutex;
00048
00049 FileSource::FileSource(QString fileOrUrl, ShowProgressType progressType) :
00050 m_url(fileOrUrl),
00051 m_ftp(0),
00052 m_http(0),
00053 m_localFile(0),
00054 m_ok(false),
00055 m_lastStatus(0),
00056 m_remote(isRemote(fileOrUrl)),
00057 m_done(false),
00058 m_leaveLocalFile(false),
00059 m_progressType(progressType),
00060 m_progressPrinter(0),
00061 m_progressDialog(0),
00062 m_progressShowTimer(this),
00063 m_refCounted(false)
00064 {
00065 #ifdef DEBUG_FILE_SOURCE
00066 std::cerr << "FileSource::FileSource(" << fileOrUrl.toStdString() << ")" << std::endl;
00067 #endif
00068
00069 if (!canHandleScheme(m_url)) {
00070 std::cerr << "FileSource::FileSource: ERROR: Unsupported scheme in URL \"" << m_url.toString().toStdString() << "\"" << std::endl;
00071 m_errorString = tr("Unsupported scheme in URL");
00072 return;
00073 }
00074
00075 init();
00076
00077 if (isRemote() &&
00078 (fileOrUrl.contains('%') ||
00079 fileOrUrl.contains("--"))) {
00080
00081 waitForStatus();
00082
00083 if (!isAvailable()) {
00084
00085
00086
00087
00088 std::cerr << "FileSource::FileSource: Failed to retrieve URL \""
00089 << fileOrUrl.toStdString()
00090 << "\" as human-readable URL; "
00091 << "trying again treating it as encoded URL"
00092 << std::endl;
00093
00094
00095
00096
00097
00098
00099 deleteCacheFile();
00100
00101 m_url.setEncodedUrl(fileOrUrl.toAscii());
00102
00103 m_ok = false;
00104 m_done = false;
00105 m_lastStatus = 0;
00106 init();
00107 }
00108 }
00109
00110 if (!isRemote()) {
00111 emit statusAvailable();
00112 emit ready();
00113 }
00114 }
00115
00116 FileSource::FileSource(QUrl url, ShowProgressType progressType) :
00117 m_url(url),
00118 m_ftp(0),
00119 m_http(0),
00120 m_localFile(0),
00121 m_ok(false),
00122 m_lastStatus(0),
00123 m_remote(isRemote(url.toString())),
00124 m_done(false),
00125 m_leaveLocalFile(false),
00126 m_progressType(progressType),
00127 m_progressPrinter(0),
00128 m_progressDialog(0),
00129 m_progressShowTimer(this),
00130 m_refCounted(false)
00131 {
00132 #ifdef DEBUG_FILE_SOURCE
00133 std::cerr << "FileSource::FileSource(" << url.toString().toStdString() << ") [as url]" << std::endl;
00134 #endif
00135
00136 if (!canHandleScheme(m_url)) {
00137 std::cerr << "FileSource::FileSource: ERROR: Unsupported scheme in URL \"" << m_url.toString().toStdString() << "\"" << std::endl;
00138 m_errorString = tr("Unsupported scheme in URL");
00139 return;
00140 }
00141
00142 init();
00143 }
00144
00145 FileSource::FileSource(const FileSource &rf) :
00146 QObject(),
00147 m_url(rf.m_url),
00148 m_ftp(0),
00149 m_http(0),
00150 m_localFile(0),
00151 m_ok(rf.m_ok),
00152 m_lastStatus(rf.m_lastStatus),
00153 m_remote(rf.m_remote),
00154 m_done(false),
00155 m_leaveLocalFile(false),
00156 m_progressType(rf.m_progressType),
00157 m_progressPrinter(0),
00158 m_progressDialog(0),
00159 m_progressShowTimer(0),
00160 m_refCounted(false)
00161 {
00162 #ifdef DEBUG_FILE_SOURCE
00163 std::cerr << "FileSource::FileSource(" << m_url.toString().toStdString() << ") [copy ctor]" << std::endl;
00164 #endif
00165
00166 if (!canHandleScheme(m_url)) {
00167 std::cerr << "FileSource::FileSource: ERROR: Unsupported scheme in URL \"" << m_url.toString().toStdString() << "\"" << std::endl;
00168 m_errorString = tr("Unsupported scheme in URL");
00169 return;
00170 }
00171
00172 if (!isRemote()) {
00173 m_localFilename = rf.m_localFilename;
00174 } else {
00175 QMutexLocker locker(&m_mapMutex);
00176 #ifdef DEBUG_FILE_SOURCE
00177 std::cerr << "FileSource::FileSource(copy ctor): ref count is "
00178 << m_refCountMap[m_url] << std::endl;
00179 #endif
00180 if (m_refCountMap[m_url] > 0) {
00181 m_refCountMap[m_url]++;
00182 #ifdef DEBUG_FILE_SOURCE
00183 std::cerr << "raised it to " << m_refCountMap[m_url] << std::endl;
00184 #endif
00185 m_localFilename = m_remoteLocalMap[m_url];
00186 m_refCounted = true;
00187 } else {
00188 m_ok = false;
00189 m_lastStatus = 404;
00190 }
00191 }
00192
00193 m_done = true;
00194 }
00195
00196 FileSource::~FileSource()
00197 {
00198 #ifdef DEBUG_FILE_SOURCE
00199 std::cerr << "FileSource(" << m_url.toString().toStdString() << ")::~FileSource" << std::endl;
00200 #endif
00201
00202 cleanup();
00203
00204 if (isRemote() && !m_leaveLocalFile) deleteCacheFile();
00205 }
00206
00207 void
00208 FileSource::init()
00209 {
00210 if (!isRemote()) {
00211 #ifdef DEBUG_FILE_SOURCE
00212 std::cerr << "FileSource::init: Not a remote URL" << std::endl;
00213 #endif
00214 bool literal = false;
00215 m_localFilename = m_url.toLocalFile();
00216 if (m_localFilename == "") {
00217
00218 m_localFilename = m_url.toString();
00219 literal = true;
00220 }
00221 #ifdef DEBUG_FILE_SOURCE
00222 std::cerr << "FileSource::init: URL translates to local filename \""
00223 << m_localFilename.toStdString() << "\"" << std::endl;
00224 #endif
00225 m_ok = true;
00226 m_lastStatus = 200;
00227
00228 if (!QFileInfo(m_localFilename).exists()) {
00229 if (literal) {
00230 m_lastStatus = 404;
00231 } else {
00232
00233
00234 m_localFilename = m_url.toString();
00235 literal = true;
00236 if (!QFileInfo(m_localFilename).exists()) {
00237 m_lastStatus = 404;
00238 }
00239 }
00240 }
00241
00242 m_done = true;
00243 return;
00244 }
00245
00246 if (createCacheFile()) {
00247 #ifdef DEBUG_FILE_SOURCE
00248 std::cerr << "FileSource::init: Already have this one" << std::endl;
00249 #endif
00250 m_ok = true;
00251 if (!QFileInfo(m_localFilename).exists()) {
00252 m_lastStatus = 404;
00253 } else {
00254 m_lastStatus = 200;
00255 }
00256 m_done = true;
00257 return;
00258 }
00259
00260 if (m_localFilename == "") return;
00261 m_localFile = new QFile(m_localFilename);
00262 m_localFile->open(QFile::WriteOnly);
00263
00264 QString scheme = m_url.scheme().toLower();
00265
00266 #ifdef DEBUG_FILE_SOURCE
00267 std::cerr << "FileSource::init: Don't have local copy of \""
00268 << m_url.toString().toStdString() << "\", retrieving" << std::endl;
00269 #endif
00270
00271 if (scheme == "http") {
00272 initHttp();
00273 std::cerr << "FileSource: initHttp succeeded" << std::endl;
00274 } else if (scheme == "ftp") {
00275 initFtp();
00276 } else {
00277 m_remote = false;
00278 m_ok = false;
00279 }
00280
00281 if (m_ok) {
00282
00283 QMutexLocker locker(&m_mapMutex);
00284
00285 if (m_refCountMap[m_url] > 0) {
00286
00287
00288 cleanup();
00289 m_refCountMap[m_url]++;
00290 #ifdef DEBUG_FILE_SOURCE
00291 std::cerr << "FileSource::init: Another FileSource has got there first, abandoning our download and using theirs" << std::endl;
00292 #endif
00293 m_localFilename = m_remoteLocalMap[m_url];
00294 m_refCounted = true;
00295 m_ok = true;
00296 if (!QFileInfo(m_localFilename).exists()) {
00297 m_lastStatus = 404;
00298 }
00299 m_done = true;
00300 return;
00301 }
00302
00303 m_remoteLocalMap[m_url] = m_localFilename;
00304 m_refCountMap[m_url]++;
00305 m_refCounted = true;
00306
00307 switch (m_progressType) {
00308
00309 case ProgressNone: break;
00310
00311 case ProgressDialog:
00312 m_progressDialog = new QProgressDialog
00313 (tr("Downloading %1...").arg(m_url.toString()),
00314 tr("Cancel"), 0, 100);
00315 m_progressDialog->hide();
00316 connect(&m_progressShowTimer, SIGNAL(timeout()),
00317 this, SLOT(showProgressDialog()));
00318 connect(m_progressDialog, SIGNAL(canceled()),
00319 this, SLOT(cancelled()));
00320 m_progressShowTimer.setSingleShot(true);
00321 m_progressShowTimer.start(2000);
00322 break;
00323
00324 case ProgressToConsole:
00325 m_progressPrinter = new ProgressPrinter(tr("Downloading..."));
00326 connect(this, SIGNAL(progress(int)),
00327 m_progressPrinter, SLOT(progress(int)));
00328 break;
00329 }
00330 }
00331 }
00332
00333 void
00334 FileSource::initHttp()
00335 {
00336 m_ok = true;
00337 m_http = new QHttp(m_url.host(), m_url.port(80));
00338 connect(m_http, SIGNAL(done(bool)), this, SLOT(done(bool)));
00339 connect(m_http, SIGNAL(dataReadProgress(int, int)),
00340 this, SLOT(dataReadProgress(int, int)));
00341 connect(m_http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)),
00342 this, SLOT(httpResponseHeaderReceived(const QHttpResponseHeader &)));
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386 QString path = "/" + QString(m_url.toEncoded()).section('/', 3);
00387
00388 #ifdef DEBUG_FILE_SOURCE
00389 std::cerr << "FileSource: path is \""
00390 << path.toStdString() << "\"" << std::endl;
00391 #endif
00392
00393 m_http->get(path, m_localFile);
00394 }
00395
00396 void
00397 FileSource::initFtp()
00398 {
00399 m_ok = true;
00400 m_ftp = new QFtp;
00401 connect(m_ftp, SIGNAL(done(bool)), this, SLOT(done(bool)));
00402 connect(m_ftp, SIGNAL(commandFinished(int, bool)),
00403 this, SLOT(ftpCommandFinished(int, bool)));
00404 connect(m_ftp, SIGNAL(dataTransferProgress(qint64, qint64)),
00405 this, SLOT(dataTransferProgress(qint64, qint64)));
00406 m_ftp->connectToHost(m_url.host(), m_url.port(21));
00407
00408 QString username = m_url.userName();
00409 if (username == "") {
00410 username = "anonymous";
00411 }
00412
00413 QString password = m_url.password();
00414 if (password == "") {
00415 password = QString("%1@%2").arg(getenv("USER")).arg(getenv("HOST"));
00416 }
00417
00418 m_ftp->login(username, password);
00419
00420 QString dirpath = m_url.path().section('/', 0, -2);
00421 QString filename = m_url.path().section('/', -1);
00422
00423 if (dirpath == "") dirpath = "/";
00424 m_ftp->cd(dirpath);
00425 m_ftp->get(filename, m_localFile);
00426 }
00427
00428 void
00429 FileSource::cleanup()
00430 {
00431 m_done = true;
00432 if (m_http) {
00433 QHttp *h = m_http;
00434 m_http = 0;
00435 h->abort();
00436 h->deleteLater();
00437 }
00438 if (m_ftp) {
00439 QFtp *f = m_ftp;
00440 m_ftp = 0;
00441 f->abort();
00442 f->deleteLater();
00443 }
00444 delete m_progressDialog;
00445 m_progressDialog = 0;
00446 delete m_progressPrinter;
00447 m_progressPrinter = 0;
00448 delete m_localFile;
00449 m_localFile = 0;
00450 }
00451
00452 bool
00453 FileSource::isRemote(QString fileOrUrl)
00454 {
00455
00456 QString scheme = QUrl(fileOrUrl).scheme().toLower();
00457 if (scheme == "" || scheme == "file" || scheme.length() == 1) return false;
00458 return true;
00459 }
00460
00461 bool
00462 FileSource::canHandleScheme(QUrl url)
00463 {
00464
00465 QString scheme = url.scheme().toLower();
00466 return (scheme == "http" || scheme == "ftp" ||
00467 scheme == "file" || scheme == "" || scheme.length() == 1);
00468 }
00469
00470 bool
00471 FileSource::isAvailable()
00472 {
00473 waitForStatus();
00474 bool available = true;
00475 if (!m_ok) available = false;
00476 else available = (m_lastStatus / 100 == 2);
00477 #ifdef DEBUG_FILE_SOURCE
00478 std::cerr << "FileSource::isAvailable: " << (available ? "yes" : "no")
00479 << std::endl;
00480 #endif
00481 return available;
00482 }
00483
00484 void
00485 FileSource::waitForStatus()
00486 {
00487 while (m_ok && (!m_done && m_lastStatus == 0)) {
00488
00489 QApplication::processEvents();
00490 }
00491 }
00492
00493 void
00494 FileSource::waitForData()
00495 {
00496 while (m_ok && !m_done) {
00497
00498 QApplication::processEvents();
00499 }
00500 }
00501
00502 void
00503 FileSource::setLeaveLocalFile(bool leave)
00504 {
00505 m_leaveLocalFile = leave;
00506 }
00507
00508 bool
00509 FileSource::isOK() const
00510 {
00511 return m_ok;
00512 }
00513
00514 bool
00515 FileSource::isDone() const
00516 {
00517 return m_done;
00518 }
00519
00520 bool
00521 FileSource::isRemote() const
00522 {
00523 return m_remote;
00524 }
00525
00526 QString
00527 FileSource::getLocation() const
00528 {
00529 return m_url.toString();
00530 }
00531
00532 QString
00533 FileSource::getLocalFilename() const
00534 {
00535 return m_localFilename;
00536 }
00537
00538 QString
00539 FileSource::getContentType() const
00540 {
00541 return m_contentType;
00542 }
00543
00544 QString
00545 FileSource::getExtension() const
00546 {
00547 if (m_localFilename != "") {
00548 return QFileInfo(m_localFilename).suffix().toLower();
00549 } else {
00550 return QFileInfo(m_url.toLocalFile()).suffix().toLower();
00551 }
00552 }
00553
00554 QString
00555 FileSource::getErrorString() const
00556 {
00557 return m_errorString;
00558 }
00559
00560 void
00561 FileSource::dataReadProgress(int done, int total)
00562 {
00563 dataTransferProgress(done, total);
00564 }
00565
00566 void
00567 FileSource::httpResponseHeaderReceived(const QHttpResponseHeader &resp)
00568 {
00569 m_lastStatus = resp.statusCode();
00570 if (m_lastStatus / 100 >= 4) {
00571 m_errorString = QString("%1 %2")
00572 .arg(resp.statusCode()).arg(resp.reasonPhrase());
00573 #ifdef DEBUG_FILE_SOURCE
00574 std::cerr << "FileSource::responseHeaderReceived: "
00575 << m_errorString.toStdString() << std::endl;
00576 #endif
00577 } else {
00578 #ifdef DEBUG_FILE_SOURCE
00579 std::cerr << "FileSource::responseHeaderReceived: "
00580 << m_lastStatus << std::endl;
00581 #endif
00582 if (resp.hasContentType()) m_contentType = resp.contentType();
00583 }
00584 emit statusAvailable();
00585 }
00586
00587 void
00588 FileSource::ftpCommandFinished(int id, bool error)
00589 {
00590 #ifdef DEBUG_FILE_SOURCE
00591 std::cerr << "FileSource::ftpCommandFinished(" << id << ", " << error << ")" << std::endl;
00592 #endif
00593
00594 if (!m_ftp) return;
00595
00596 QFtp::Command command = m_ftp->currentCommand();
00597
00598 if (!error) {
00599 #ifdef DEBUG_FILE_SOURCE
00600 std::cerr << "FileSource::ftpCommandFinished: success for command "
00601 << command << std::endl;
00602 #endif
00603 return;
00604 }
00605
00606 if (command == QFtp::ConnectToHost) {
00607 m_errorString = tr("Failed to connect to FTP server");
00608 } else if (command == QFtp::Login) {
00609 m_errorString = tr("Login failed");
00610 } else if (command == QFtp::Cd) {
00611 m_errorString = tr("Failed to change to correct directory");
00612 } else if (command == QFtp::Get) {
00613 m_errorString = tr("FTP download aborted");
00614 }
00615
00616 m_lastStatus = 400;
00617 }
00618
00619 void
00620 FileSource::dataTransferProgress(qint64 done, qint64 total)
00621 {
00622 int percent = int((double(done) / double(total)) * 100.0 - 0.1);
00623 emit progress(percent);
00624
00625 if (!m_progressDialog) return;
00626
00627 if (percent > 0) {
00628 m_progressDialog->setValue(percent);
00629 m_progressDialog->show();
00630 }
00631 }
00632
00633 void
00634 FileSource::cancelled()
00635 {
00636 m_done = true;
00637 cleanup();
00638
00639 m_ok = false;
00640 m_errorString = tr("Download cancelled");
00641 }
00642
00643 void
00644 FileSource::done(bool error)
00645 {
00646 emit progress(100);
00647
00648 #ifdef DEBUG_FILE_SOURCE
00649 std::cerr << "FileSource::done(" << error << ")" << std::endl;
00650 #endif
00651
00652 if (m_done) return;
00653
00654 if (error) {
00655 if (m_http) {
00656 m_errorString = m_http->errorString();
00657 } else if (m_ftp) {
00658 m_errorString = m_ftp->errorString();
00659 }
00660 }
00661
00662 if (m_lastStatus / 100 >= 4) {
00663 error = true;
00664 }
00665
00666 cleanup();
00667
00668 if (!error) {
00669 QFileInfo fi(m_localFilename);
00670 if (!fi.exists()) {
00671 m_errorString = tr("Failed to create local file %1").arg(m_localFilename);
00672 error = true;
00673 } else if (fi.size() == 0) {
00674 m_errorString = tr("File contains no data!");
00675 error = true;
00676 }
00677 }
00678
00679 if (error) {
00680 #ifdef DEBUG_FILE_SOURCE
00681 std::cerr << "FileSource::done: error is " << error << ", deleting cache file" << std::endl;
00682 #endif
00683 deleteCacheFile();
00684 }
00685
00686 m_ok = !error;
00687 m_done = true;
00688 emit ready();
00689 }
00690
00691 void
00692 FileSource::deleteCacheFile()
00693 {
00694 #ifdef DEBUG_FILE_SOURCE
00695 std::cerr << "FileSource::deleteCacheFile(\"" << m_localFilename.toStdString() << "\")" << std::endl;
00696 #endif
00697
00698 cleanup();
00699
00700 if (m_localFilename == "") {
00701 return;
00702 }
00703
00704 if (!isRemote()) {
00705 #ifdef DEBUG_FILE_SOURCE
00706 std::cerr << "not a cache file" << std::endl;
00707 #endif
00708 return;
00709 }
00710
00711 if (m_refCounted) {
00712
00713 QMutexLocker locker(&m_mapMutex);
00714 m_refCounted = false;
00715
00716 if (m_refCountMap[m_url] > 0) {
00717 m_refCountMap[m_url]--;
00718 #ifdef DEBUG_FILE_SOURCE
00719 std::cerr << "reduced ref count to " << m_refCountMap[m_url] << std::endl;
00720 #endif
00721 if (m_refCountMap[m_url] > 0) {
00722 m_done = true;
00723 return;
00724 }
00725 }
00726 }
00727
00728 m_fileCreationMutex.lock();
00729
00730 if (!QFile(m_localFilename).remove()) {
00731 #ifdef DEBUG_FILE_SOURCE
00732 std::cerr << "FileSource::deleteCacheFile: ERROR: Failed to delete file \"" << m_localFilename.toStdString() << "\"" << std::endl;
00733 #endif
00734 } else {
00735 #ifdef DEBUG_FILE_SOURCE
00736 std::cerr << "FileSource::deleteCacheFile: Deleted cache file \"" << m_localFilename.toStdString() << "\"" << std::endl;
00737 #endif
00738 m_localFilename = "";
00739 }
00740
00741 m_fileCreationMutex.unlock();
00742
00743 m_done = true;
00744 }
00745
00746 void
00747 FileSource::showProgressDialog()
00748 {
00749 if (m_progressDialog) m_progressDialog->show();
00750 }
00751
00752 bool
00753 FileSource::createCacheFile()
00754 {
00755 {
00756 QMutexLocker locker(&m_mapMutex);
00757
00758 #ifdef DEBUG_FILE_SOURCE
00759 std::cerr << "FileSource::createCacheFile: refcount is " << m_refCountMap[m_url] << std::endl;
00760 #endif
00761
00762 if (m_refCountMap[m_url] > 0) {
00763 m_refCountMap[m_url]++;
00764 m_localFilename = m_remoteLocalMap[m_url];
00765 #ifdef DEBUG_FILE_SOURCE
00766 std::cerr << "raised it to " << m_refCountMap[m_url] << std::endl;
00767 #endif
00768 m_refCounted = true;
00769 return true;
00770 }
00771 }
00772
00773 QDir dir;
00774 try {
00775 dir = TempDirectory::getInstance()->getSubDirectoryPath("download");
00776 } catch (DirectoryCreationFailed f) {
00777 #ifdef DEBUG_FILE_SOURCE
00778 std::cerr << "FileSource::createCacheFile: ERROR: Failed to create temporary directory: " << f.what() << std::endl;
00779 #endif
00780 return "";
00781 }
00782
00783 QString filepart = m_url.path().section('/', -1, -1,
00784 QString::SectionSkipEmpty);
00785
00786 QString extension = filepart.section('.', -1);
00787 QString base = filepart;
00788 if (extension != "") {
00789 base = base.left(base.length() - extension.length() - 1);
00790 }
00791 if (base == "") base = "remote";
00792
00793 QString filename;
00794
00795 if (extension == "") {
00796 filename = base;
00797 } else {
00798 filename = QString("%1.%2").arg(base).arg(extension);
00799 }
00800
00801 QString filepath(dir.filePath(filename));
00802
00803 #ifdef DEBUG_FILE_SOURCE
00804 std::cerr << "FileSource::createCacheFile: URL is \"" << m_url.toString().toStdString() << "\", dir is \"" << dir.path().toStdString() << "\", base \"" << base.toStdString() << "\", extension \"" << extension.toStdString() << "\", filebase \"" << filename.toStdString() << "\", filename \"" << filepath.toStdString() << "\"" << std::endl;
00805 #endif
00806
00807 QMutexLocker fcLocker(&m_fileCreationMutex);
00808
00809 ++m_count;
00810
00811 if (QFileInfo(filepath).exists() ||
00812 !QFile(filepath).open(QFile::WriteOnly)) {
00813
00814 #ifdef DEBUG_FILE_SOURCE
00815 std::cerr << "FileSource::createCacheFile: Failed to create local file \""
00816 << filepath.toStdString() << "\" for URL \""
00817 << m_url.toString().toStdString() << "\" (or file already exists): appending suffix instead" << std::endl;
00818 #endif
00819
00820 if (extension == "") {
00821 filename = QString("%1_%2").arg(base).arg(m_count);
00822 } else {
00823 filename = QString("%1_%2.%3").arg(base).arg(m_count).arg(extension);
00824 }
00825 filepath = dir.filePath(filename);
00826
00827 if (QFileInfo(filepath).exists() ||
00828 !QFile(filepath).open(QFile::WriteOnly)) {
00829
00830 #ifdef DEBUG_FILE_SOURCE
00831 std::cerr << "FileSource::createCacheFile: ERROR: Failed to create local file \""
00832 << filepath.toStdString() << "\" for URL \""
00833 << m_url.toString().toStdString() << "\" (or file already exists)" << std::endl;
00834 #endif
00835
00836 return "";
00837 }
00838 }
00839
00840 #ifdef DEBUG_FILE_SOURCE
00841 std::cerr << "FileSource::createCacheFile: url "
00842 << m_url.toString().toStdString() << " -> local filename "
00843 << filepath.toStdString() << std::endl;
00844 #endif
00845
00846 m_localFilename = filepath;
00847
00848 return false;
00849 }
00850