diff options
Diffstat (limited to 'kftpgrabber/src/directoryscanner.cpp')
-rw-r--r-- | kftpgrabber/src/directoryscanner.cpp | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/kftpgrabber/src/directoryscanner.cpp b/kftpgrabber/src/directoryscanner.cpp new file mode 100644 index 0000000..5adaf45 --- /dev/null +++ b/kftpgrabber/src/directoryscanner.cpp @@ -0,0 +1,178 @@ +/* + * This file is part of the KFTPGrabber project + * + * Copyright (C) 2003-2006 by the KFTPGrabber developers + * Copyright (C) 2003-2006 Jernej Kos <kostko@jweb-network.net> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and + * NON-INFRINGEMENT. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * + * You must obey the GNU General Public License in all respects + * for all of the code used other than OpenSSL. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you + * do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source + * files in the program, then also delete it here. + */ +#include "directoryscanner.h" +#include "kftpqueue.h" + +#include "misc/config.h" +#include "misc/filter.h" + +#include <kfileitem.h> + +#include <qapplication.h> +#include <qdir.h> + +using namespace KFTPQueue; +using namespace KFTPCore::Filter; +using namespace KFTPEngine; + +DirectoryScanner::DirectoryScanner(Transfer *transfer) +{ + // Lock the transfer + transfer->lock(); + + // Construct a new thread and run it + ScannerThread *thread = new ScannerThread(this, transfer); + thread->start(); +} + +void DirectoryScanner::customEvent(QCustomEvent *e) +{ + if (e->type() == QS_THR_EVENT_ID) { + KFTPQueue::Transfer *transfer = static_cast<KFTPQueue::Transfer*>(e->data()); + transfer->unlock(); + emit completed(); + + // Destroy thiy object + delete this; + } +} + +DirectoryScanner::ScannerThread::ScannerThread(QObject *parent, Transfer *item) + : QThread(), + m_parent(parent), + m_item(item) +{ +} + +void DirectoryScanner::ScannerThread::run() +{ + // First scan the folder + scanFolder(m_item); + + // We are done, post event to notify the GUI + ScannerThreadEvent *e = new ScannerThreadEvent(m_item); + qApp->postEvent(m_parent, e); +} + +void DirectoryScanner::ScannerThread::scanFolder(Transfer *parent) +{ + QDir fs(parent->getSourceUrl().path()); + fs.setFilter(QDir::Readable | QDir::Hidden | QDir::All); + + const QFileInfoList *p_list = fs.entryInfoList(); + QFileInfoListIterator i(*p_list); + QFileInfo *file; + + QValueList<DirectoryEntry> list; + + while ((file = i.current()) != 0) { + ++i; + + if (file->fileName() == "." || file->fileName() == "..") + continue; + + KURL sourceUrl; + sourceUrl.setPath(file->absFilePath()); + + // This is needed, since QFileInfo works with uint for the filesize + filesize_t realSize = KFileItem(KFileItem::Unknown, KFileItem::Unknown, sourceUrl, true).size(); + + // Check if we should skip this entry + const ActionChain *actionChain = Filters::self()->process(sourceUrl, realSize, file->isDir()); + + if (actionChain && actionChain->getAction(Action::Skip)) + continue; + + DirectoryEntry entry; + entry.setFilename(file->fileName()); + entry.setType(file->isDir() ? 'd' : 'f'); + entry.setSize(realSize); + + list.append(entry); + } + + // Sort by priority + qHeapSort(list); + + QValueList<DirectoryEntry>::ConstIterator listEnd = list.end(); + for (QValueList<DirectoryEntry>::ConstIterator j = list.begin(); j != listEnd; ++j) { + // Spawn transfer + KURL destUrlBase = parent->getDestUrl(); + KURL sourceUrlBase = parent->getSourceUrl(); + + destUrlBase.addPath((*j).filename()); + sourceUrlBase.addPath((*j).filename()); + + if ((*j).isDirectory()) { + // Directory + qApp->lock(); + KFTPQueue::TransferDir *transfer = new KFTPQueue::TransferDir(parent); + transfer->setSourceUrl(sourceUrlBase); + transfer->setDestUrl(destUrlBase); + transfer->addSize((*j).size()); + transfer->setTransferType(parent->getTransferType()); + transfer->setId(KFTPQueue::Manager::self()->nextTransferId()); + + emit KFTPQueue::Manager::self()->newTransfer(transfer); + qApp->unlock(); + + // Call this function in recursion + scanFolder(transfer); + + if (KFTPCore::Config::skipEmptyDirs() && !transfer->hasChildren()) { + qApp->lock(); + KFTPQueue::Manager::self()->removeTransfer(transfer, false); + qApp->unlock(); + } + } else { + // File + qApp->lock(); + KFTPQueue::TransferFile *transfer = new KFTPQueue::TransferFile(parent); + transfer->setSourceUrl(sourceUrlBase); + transfer->setDestUrl(destUrlBase); + transfer->addSize((*j).size()); + transfer->setTransferType(parent->getTransferType()); + transfer->setId(KFTPQueue::Manager::self()->nextTransferId()); + + emit KFTPQueue::Manager::self()->newTransfer(transfer); + qApp->unlock(); + } + } +} + +#include "directoryscanner.moc" + + |