📄 adlsearch.cpp
字号:
/*
* Copyright (C) 2001-2006 Jacek Sieka, arnetheduck on gmail point com
*
* 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 WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* Automatic Directory Listing Search
* Henrik Engström, henrikengstrom at home se
*/
#include "stdinc.h"
#include "DCPlusPlus.h"
#include "ADLSearch.h"
#include "QueueManager.h"
#include "ClientManager.h"
#include "File.h"
#include "SimpleXML.h"
///////////////////////////////////////////////////////////////////////////////
//
// Load old searches from disk
//
///////////////////////////////////////////////////////////////////////////////
void ADLSearchManager::Load()
{
// Clear current
collection.clear();
// Load file as a string
try {
SimpleXML xml;
xml.fromXML(File(getConfigFile(), File::READ, File::OPEN).read());
if(xml.findChild("ADLSearch")) {
xml.stepIn();
// Predicted several groups of searches to be differentiated
// in multiple categories. Not implemented yet.
if(xml.findChild("SearchGroup")) {
xml.stepIn();
// Loop until no more searches found
while(xml.findChild("Search")) {
xml.stepIn();
// Found another search, load it
ADLSearch search;
if(xml.findChild("SearchString")) {
search.searchString = xml.getChildData();
}
if(xml.findChild("SourceType")) {
search.sourceType = search.StringToSourceType(xml.getChildData());
}
if(xml.findChild("DestDirectory")) {
search.destDir = xml.getChildData();
}
if(xml.findChild("IsActive")) {
search.isActive = (Util::toInt(xml.getChildData()) != 0);
}
if(xml.findChild("MaxSize")) {
search.maxFileSize = Util::toInt64(xml.getChildData());
}
if(xml.findChild("MinSize")) {
search.minFileSize = Util::toInt64(xml.getChildData());
}
if(xml.findChild("SizeType")) {
search.typeFileSize = search.StringToSizeType(xml.getChildData());
}
if(xml.findChild("IsAutoQueue")) {
search.isAutoQueue = (Util::toInt(xml.getChildData()) != 0);
}
// Add search to collection
if(search.searchString.size() > 0) {
collection.push_back(search);
}
// Go to next search
xml.stepOut();
}
}
}
} catch(const SimpleXMLException&) {
return;
} catch(const FileException&) {
return;
}
}
///////////////////////////////////////////////////////////////////////////////
//
// Save current searches to disk
//
///////////////////////////////////////////////////////////////////////////////
void ADLSearchManager::Save()
{
// Prepare xml string for saving
try {
SimpleXML xml;
xml.addTag("ADLSearch");
xml.stepIn();
// Predicted several groups of searches to be differentiated
// in multiple categories. Not implemented yet.
xml.addTag("SearchGroup");
xml.stepIn();
// Save all searches
for(SearchCollection::iterator i = collection.begin(); i != collection.end(); ++i) {
ADLSearch& search = *i;
if(search.searchString.size() == 0) {
continue;
}
string type = "type";
xml.addTag("Search");
xml.stepIn();
xml.addTag("SearchString", search.searchString);
xml.addChildAttrib(type, string("string"));
xml.addTag("SourceType", search.SourceTypeToString(search.sourceType));
xml.addChildAttrib(type, string("string"));
xml.addTag("DestDirectory", search.destDir);
xml.addChildAttrib(type, string("string"));
xml.addTag("IsActive", search.isActive);
xml.addChildAttrib(type, string("int"));
xml.addTag("MaxSize", search.maxFileSize);
xml.addChildAttrib(type, string("int64"));
xml.addTag("MinSize", search.minFileSize);
xml.addChildAttrib(type, string("int64"));
xml.addTag("SizeType", search.SizeTypeToString(search.typeFileSize));
xml.addChildAttrib(type, string("string"));
xml.addTag("IsAutoQueue", search.isAutoQueue);
xml.addChildAttrib(type, string("int"));
xml.stepOut();
}
xml.stepOut();
xml.stepOut();
// Save string to file
try {
File fout(getConfigFile(), File::WRITE, File::CREATE | File::TRUNCATE);
fout.write(SimpleXML::utf8Header);
fout.write(xml.toXML());
fout.close();
} catch(const FileException&) {
return;
}
} catch(const SimpleXMLException&) {
return;
}
}
void ADLSearchManager::MatchesFile(DestDirList& destDirVector, DirectoryListing::File *currentFile, string& fullPath) {
// Add to any substructure being stored
for(DestDirList::iterator id = destDirVector.begin(); id != destDirVector.end(); ++id) {
if(id->subdir != NULL) {
DirectoryListing::File *copyFile = new DirectoryListing::File(*currentFile, true);
dcassert(id->subdir->getAdls());
id->subdir->files.push_back(copyFile);
}
id->fileAdded = false; // Prepare for next stage
}
// Prepare to match searches
if(currentFile->getName().size() < 1) {
return;
}
string filePath = fullPath + "\\" + currentFile->getName();
// Match searches
for(SearchCollection::iterator is = collection.begin(); is != collection.end(); ++is) {
if(destDirVector[is->ddIndex].fileAdded) {
continue;
}
if(is->MatchesFile(currentFile->getName(), filePath, currentFile->getSize())) {
DirectoryListing::File *copyFile = new DirectoryListing::File(*currentFile, true);
destDirVector[is->ddIndex].dir->files.push_back(copyFile);
destDirVector[is->ddIndex].fileAdded = true;
if(is->isAutoQueue){
QueueManager::getInstance()->add(SETTING(DOWNLOAD_DIRECTORY) + currentFile->getName(),
currentFile->getSize(), currentFile->getTTH(), getUser(), currentFile->getName());
}
if(breakOnFirst) {
// Found a match, search no more
break;
}
}
}
}
void ADLSearchManager::MatchesDirectory(DestDirList& destDirVector, DirectoryListing::Directory* currentDir, string& fullPath) {
// Add to any substructure being stored
for(DestDirList::iterator id = destDirVector.begin(); id != destDirVector.end(); ++id) {
if(id->subdir != NULL) {
DirectoryListing::Directory* newDir =
new DirectoryListing::AdlDirectory(fullPath, id->subdir, currentDir->getName());
id->subdir->directories.push_back(newDir);
id->subdir = newDir;
}
}
// Prepare to match searches
if(currentDir->getName().size() < 1) {
return;
}
// Match searches
for(SearchCollection::iterator is = collection.begin(); is != collection.end(); ++is) {
if(destDirVector[is->ddIndex].subdir != NULL) {
continue;
}
if(is->MatchesDirectory(currentDir->getName())) {
destDirVector[is->ddIndex].subdir =
new DirectoryListing::AdlDirectory(fullPath, destDirVector[is->ddIndex].dir, currentDir->getName());
destDirVector[is->ddIndex].dir->directories.push_back(destDirVector[is->ddIndex].subdir);
if(breakOnFirst) {
// Found a match, search no more
break;
}
}
}
}
void ADLSearchManager::PrepareDestinationDirectories(DestDirList& destDirVector, DirectoryListing::Directory* root, StringMap& params) {
// Load default destination directory (index = 0)
destDirVector.clear();
vector<DestDir>::iterator id = destDirVector.insert(destDirVector.end(), DestDir());
id->name = "ADLSearch";
id->dir = new DirectoryListing::Directory(root, "<<<" + id->name + ">>>", true, true);
// Scan all loaded searches
for(SearchCollection::iterator is = collection.begin(); is != collection.end(); ++is) {
// Check empty destination directory
if(is->destDir.size() == 0) {
// Set to default
is->ddIndex = 0;
continue;
}
// Check if exists
bool isNew = true;
long ddIndex = 0;
for(id = destDirVector.begin(); id != destDirVector.end(); ++id, ++ddIndex) {
if(Util::stricmp(is->destDir.c_str(), id->name.c_str()) == 0) {
// Already exists, reuse index
is->ddIndex = ddIndex;
isNew = false;
break;
}
}
if(isNew) {
// Add new destination directory
id = destDirVector.insert(destDirVector.end(), DestDir());
id->name = is->destDir;
id->dir = new DirectoryListing::Directory(root, "<<<" + id->name + ">>>", true, true);
is->ddIndex = ddIndex;
}
}
// Prepare all searches
for(SearchCollection::iterator ip = collection.begin(); ip != collection.end(); ++ip) {
ip->Prepare(params);
}
}
void ADLSearchManager::matchListing(DirectoryListing& aDirList) throw() {
StringMap params;
params["userNI"] = ClientManager::getInstance()->getNicks(aDirList.getUser()->getCID())[0];
params["userCID"] = aDirList.getUser()->getCID().toBase32();
setUser(aDirList.getUser());
DestDirList destDirs;
PrepareDestinationDirectories(destDirs, aDirList.getRoot(), params);
setBreakOnFirst(BOOLSETTING(ADLS_BREAK_ON_FIRST));
string path(aDirList.getRoot()->getName());
matchRecurse(destDirs, aDirList.getRoot(), path);
FinalizeDestinationDirectories(destDirs, aDirList.getRoot());
}
void ADLSearchManager::matchRecurse(DestDirList &aDestList, DirectoryListing::Directory* aDir, string &aPath) {
for(DirectoryListing::Directory::Iter dirIt = aDir->directories.begin(); dirIt != aDir->directories.end(); ++dirIt) {
string tmpPath = aPath + "\\" + (*dirIt)->getName();
MatchesDirectory(aDestList, *dirIt, tmpPath);
matchRecurse(aDestList, *dirIt, tmpPath);
}
for(DirectoryListing::File::Iter fileIt = aDir->files.begin(); fileIt != aDir->files.end(); ++fileIt) {
MatchesFile(aDestList, *fileIt, aPath);
}
StepUpDirectory(aDestList);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -