summaryrefslogtreecommitdiffstats
path: root/kftpgrabber/src/directoryscanner.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kftpgrabber/src/directoryscanner.cpp')
-rw-r--r--kftpgrabber/src/directoryscanner.cpp178
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"
+
+