#include #include #include #include "spider.h" using namespace std; Spider::Spider(QObject *parent) : QObject(parent) { connect(&ftp, SIGNAL(done(bool)), this, SLOT(ftpDone(bool))); connect(&ftp, SIGNAL(listInfo(const QUrlInfo &)), this, SLOT(ftpListInfo(const QUrlInfo &))); } bool Spider::getDirectory(const QUrl &url) { if (!url.isValid()) { cerr << "Error: Invalid URL" << endl; return false; } if (url.scheme() != "ftp") { cerr << "Error: URL must start with 'ftp:'" << endl; return false; } ftp.connectToHost(url.host(), url.port(21)); ftp.login(); QString path = url.path(); if (path.isEmpty()) path = "/"; pendingDirs.append(path); processNextDirectory(); return true; } void Spider::ftpDone(bool error) { if (error) { cerr << "Error: " << qPrintable(ftp.errorString()) << endl; } else { cout << "Downloaded " << qPrintable(currentDir) << " to " << qPrintable(QDir::convertSeparators( QDir(currentLocalDir).canonicalPath())); } qDeleteAll(openedFiles); openedFiles.clear(); processNextDirectory(); } void Spider::ftpListInfo(const QUrlInfo &urlInfo) { if (urlInfo.isFile()) { if (urlInfo.isReadable()) { QFile *file = new QFile(currentLocalDir + "/" + urlInfo.name()); if (!file->open(QIODevice::WriteOnly)) { cerr << "Warning: Cannot open file " << qPrintable( QDir::convertSeparators(file->fileName())) << endl; return; } ftp.get(urlInfo.name(), file); openedFiles.append(file); } } else if (urlInfo.isDir() && !urlInfo.isSymLink()) { pendingDirs.append(currentDir + "/" + urlInfo.name()); } } void Spider::processNextDirectory() { if (!pendingDirs.isEmpty()) { currentDir = pendingDirs.takeFirst(); currentLocalDir = "downloads/" + currentDir; QDir(".").mkpath(currentLocalDir); ftp.cd(currentDir); ftp.list(); } else { emit done(); } }