www.pudn.com > DCPlusPlus-src.zip > ADLSearch.cpp


/*  
* Copyright (C) 2001-2004 Jacek Sieka, j_s at telia 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@home.se 
*/ 
 
#include "stdinc.h" 
#include "DCPlusPlus.h" 
 
#include "ADLSearch.h" 
#include "QueueManager.h" 
 
#include "File.h" 
#include "SimpleXML.h" 
 
#define ADLS_STORE_FILENAME "ADLSearch.xml" 
 
/////////////////////////////////////////////////////////////////////////////// 
// 
//	Load old searches from disk 
// 
/////////////////////////////////////////////////////////////////////////////// 
void ADLSearchManager::Load() 
{ 
	// Clear current 
	collection.clear(); 
 
	// Load file as a string 
	try { 
		SimpleXML xml; 
		xml.fromXML(File(Util::getAppPath() + ADLS_STORE_FILENAME, 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()); 
					} 
 
					// 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.stepOut(); 
		} 
 
		xml.stepOut(); 
 
		xml.stepOut(); 
 
		// Save string to file			 
		try { 
			File fout(Util::getAppPath() + ADLS_STORE_FILENAME, 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); 
			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); 
			destDirVector[is->ddIndex].dir->files.push_back(copyFile); 
			destDirVector[is->ddIndex].fileAdded = true; 
 
			if(is->isAutoQueue){ 
				QueueManager::getInstance()->add(currentFile->getName(), currentFile->getSize(), getUser(), Util::getTempPath() + currentFile->getName(), currentFile->getTTH()); 
			} 
 
			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::iterator id = destDirVector.insert(destDirVector.end(), DestDir()); 
	id->name = "ADLSearch"; 
	id->dir  = new DirectoryListing::Directory(root, "<<<" + id->name + ">>>", 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); 
			is->ddIndex = ddIndex; 
		} 
	} 
	// Prepare all searches 
	for(SearchCollection::iterator ip = collection.begin(); ip != collection.end(); ++ip) { 
		ip->Prepare(params); 
	} 
} 
 
/** 
* @file 
* $Id: ADLSearch.cpp,v 1.15 2004/09/24 20:48:27 arnetheduck Exp $ 
*/