← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2297: Group search extensions with the "GR" param

 

------------------------------------------------------------
revno: 2297
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Fri 2010-11-19 16:11:20 +0100
message:
  Group search extensions with the "GR" param
modified:
  changelog.txt
  dcpp/AdcHub.cpp
  dcpp/AdcHub.h
  dcpp/SettingsManager.cpp
  dcpp/ShareManager.cpp
  dcpp/ShareManager.h
  win32/SearchFrame.cpp


--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk

Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'changelog.txt'
--- changelog.txt	2010-11-18 19:35:18 +0000
+++ changelog.txt	2010-11-19 15:11:20 +0000
@@ -32,6 +32,7 @@
 * Added notice about the original C implementation of Tiger (you must include this in mods!) (ullner)
 * Add a menu to change the group of a fav hub more easily (poy)
 * [ADC] Support hidden users as per the ADC ext spec (poy)
+* [ADC] Group search extensions with the "GR" param (poy)
 
 -- 0.770 2010-07-05 --
 * [L#550300] Catch more potential file corruptions (thanks bigmuscle)

=== modified file 'dcpp/AdcHub.cpp'
--- dcpp/AdcHub.cpp	2010-11-01 21:55:40 +0000
+++ dcpp/AdcHub.cpp	2010-11-19 15:11:20 +0000
@@ -713,6 +713,84 @@
 	}
 }
 
+namespace {
+static vector<StringList> searchExts;
+
+static void defineSearchExts() {
+	if(!searchExts.empty())
+		return;
+
+	searchExts.resize(6);
+
+	/// @todo simplify this as searchExts[0] = { "mp3", "etc" } when VC++ supports initializer lists
+
+	{
+		StringList& l = searchExts[0];
+		l.push_back("mp3"); l.push_back("flac"); l.push_back("ogg"); l.push_back("mpc");
+		l.push_back("ape"); l.push_back("wma");l.push_back("wav"); l.push_back("m4a");
+		l.push_back("mp2"); l.push_back("mid"); l.push_back("au"); l.push_back("aiff");
+		l.push_back("ra");
+		sort(l.begin(), l.end());
+	}
+
+	{
+		StringList& l = searchExts[1];
+		l.push_back("rar"); l.push_back("7z"); l.push_back("zip"); l.push_back("tar");
+		l.push_back("gz"); l.push_back("bz2"); l.push_back("z"); l.push_back("ace");
+		l.push_back("lha"); l.push_back("lzh"); l.push_back("arj");
+		sort(l.begin(), l.end());
+	}
+
+	{
+		StringList& l = searchExts[2];
+		l.push_back("doc"); l.push_back("xls"); l.push_back("ppt"); l.push_back("docx");
+		l.push_back("xlsx"); l.push_back("pptx"); l.push_back("odf"); l.push_back("odt");
+		l.push_back("ods"); l.push_back("odp"); l.push_back("pdf"); l.push_back("xps");
+		l.push_back("htm"); l.push_back("html"); l.push_back("xml"); l.push_back("txt");
+		l.push_back("nfo"); l.push_back("rtf");
+		sort(l.begin(), l.end());
+	}
+
+	{
+		StringList& l = searchExts[3];
+		l.push_back("exe"); l.push_back("com"); l.push_back("bat"); l.push_back("cmd");
+		l.push_back("dll"); l.push_back("vbs"); l.push_back("ps1"); l.push_back("msi");
+		sort(l.begin(), l.end());
+	}
+
+	{
+		StringList& l = searchExts[4];
+		l.push_back("bmp"); l.push_back("ico"); l.push_back("jpg"); l.push_back("jpeg");
+		l.push_back("png"); l.push_back("gif"); l.push_back("tga"); l.push_back("ai");
+		l.push_back("ps"); l.push_back("pict"); l.push_back("eps"); l.push_back("img");
+		l.push_back("pct"); l.push_back("psp"); l.push_back("tif"); l.push_back("rle");
+		l.push_back("pcx"); l.push_back("sfw"); l.push_back("psd"); l.push_back("cdr");
+		sort(l.begin(), l.end());
+	}
+
+	{
+		StringList& l = searchExts[5];
+		l.push_back("mpg"); l.push_back("avi"); l.push_back("mkv"); l.push_back("wmv");
+		l.push_back("mov"); l.push_back("mp4"); l.push_back("3gp"); l.push_back("qt");
+		l.push_back("asx"); l.push_back("divx"); l.push_back("asf"); l.push_back("pxp");
+		l.push_back("ogm"); l.push_back("flv"); l.push_back("rm"); l.push_back("rmvb");
+		l.push_back("webm"); l.push_back("mpeg");
+		sort(l.begin(), l.end());
+	}
+}
+}
+
+StringList AdcHub::parseSearchExts(int flag) {
+	defineSearchExts();
+	StringList ret;
+	for(auto i = searchExts.cbegin(), iend = searchExts.cend(); i != iend; ++i) {
+		if(flag & (1 << (i - searchExts.cbegin()))) {
+			ret.insert(ret.begin(), i->begin(), i->end());
+		}
+	}
+	return ret;
+}
+
 void AdcHub::search(int aSizeMode, int64_t aSize, int aFileType, const string& aString, const string& aToken, const StringList& aExtList) {
 	if(state != STATE_NORMAL)
 		return;
@@ -721,23 +799,77 @@
 
 	if(aFileType == SearchManager::TYPE_TTH) {
 		c.addParam("TR", aString);
+
 	} else {
 		if(aSizeMode == SearchManager::SIZE_ATLEAST) {
 			c.addParam("GE", Util::toString(aSize));
 		} else if(aSizeMode == SearchManager::SIZE_ATMOST) {
 			c.addParam("LE", Util::toString(aSize));
 		}
+
 		StringTokenizer<string> st(aString, ' ');
 		for(StringIter i = st.getTokens().begin(); i != st.getTokens().end(); ++i) {
 			c.addParam("AN", *i);
 		}
+
 		if(aFileType == SearchManager::TYPE_DIRECTORY) {
 			c.addParam("TY", "2");
 		}
-		if (!aExtList.empty()) {
-			for(StringIterC i = aExtList.begin(); i != aExtList.end(); ++i) {
+
+		if(!aExtList.empty()) {
+			StringList exts = aExtList;
+
+			if(exts.size() > 2) {
+				sort(exts.begin(), exts.end());
+
+				uint8_t gr = 0;
+
+				defineSearchExts();
+				for(auto i = searchExts.cbegin(), iend = searchExts.cend(); i != iend; ++i) {
+					const StringList& def = *i;
+
+					// gather the exts not present in any of the lists
+					StringList temp(def.size() + exts.size());
+					temp = StringList(temp.begin(), set_symmetric_difference(def.begin(), def.end(),
+						exts.begin(), exts.end(), temp.begin()));
+
+					// figure out whether the remaining exts have to be added or removed from the set
+					StringList rm;
+					bool ok = true;
+					for(auto diff = temp.begin(); diff != temp.end();) {
+						if(find(def.cbegin(), def.cend(), *diff) == def.cend()) {
+							++diff; // will be added further below as an "EX"
+						} else {
+							if(rm.size() == 2) {
+								ok = false;
+								break;
+							}
+							rm.push_back(*diff);
+							diff = temp.erase(diff);
+						}
+					}
+					if(!ok) // too many "RM"s necessary - disregard this group
+						continue;
+
+					// let's include this group!
+					gr += 1 << (i - searchExts.cbegin());
+
+					exts = temp; // the exts to still add (that were not defined in the group)
+
+					for(auto rmi = rm.cbegin(), rmiend = rm.cend(); rmi != rmiend; ++rmi)
+						c.addParam("RM", *rmi);
+
+					if(exts.size() <= 2)
+						break;
+					// keep looping to see if there are more exts that can be grouped
+				}
+
+				if(gr)
+					c.addParam("GR", Util::toString(gr));
+			}
+
+			for(auto i = exts.cbegin(), iend = exts.cend(); i != iend; ++i)
 				c.addParam("EX", *i);
-			}
 		}
 	}
 

=== modified file 'dcpp/AdcHub.h'
--- dcpp/AdcHub.h	2010-08-27 13:47:33 +0000
+++ dcpp/AdcHub.h	2010-11-19 15:11:20 +0000
@@ -49,6 +49,9 @@
 	virtual void send(const AdcCommand& cmd);
 
 	string getMySID() { return AdcCommand::fromSID(sid); }
+
+	static StringList parseSearchExts(int flag);
+
 private:
 	friend class ClientManager;
 	friend class CommandHandler<AdcHub>;

=== modified file 'dcpp/SettingsManager.cpp'
--- dcpp/SettingsManager.cpp	2010-10-24 18:06:17 +0000
+++ dcpp/SettingsManager.cpp	2010-11-19 15:11:20 +0000
@@ -543,10 +543,9 @@
 void SettingsManager::setSearchTypeDefaults() {
 	searchTypes.clear();
 
-	// @todo simplify this as searchTypes[string(1, '0' + SearchManager::TYPE_AUDIO)] = { "mp3", "etc" } when VC++ supports initializer lists
+	/// @todo simplify this as searchTypes[string(1, '0' + SearchManager::TYPE_AUDIO)] = { "mp3", "etc" } when VC++ supports initializer lists
 
-	// @todo the default extension list contains some depreciated formats they kept to get all the NMDC-built subset of results for both type 
-	// of hubs. Some of these may worth to be dropped along with NMDC support...
+	/// @todo the default extension list contains some deprecated formats kept around for NMDC, drop them later
 
 	{
 		StringList& l = searchTypes.insert(make_pair(string(1, '0' + SearchManager::TYPE_AUDIO), StringList())).first->second;

=== modified file 'dcpp/ShareManager.cpp'
--- dcpp/ShareManager.cpp	2010-08-30 14:04:10 +0000
+++ dcpp/ShareManager.cpp	2010-11-19 15:11:20 +0000
@@ -27,6 +27,7 @@
 #include "HashManager.h"
 #include "QueueManager.h"
 
+#include "AdcHub.h"
 #include "SimpleXML.h"
 #include "StringTokenizer.h"
 #include "File.h"
@@ -1215,6 +1216,11 @@
 			exclude.push_back(StringSearch(p.substr(2)));
 		} else if(toCode('E', 'X') == cmd) {
 			ext.push_back(p.substr(2));
+		} else if(toCode('G', 'R') == cmd) {
+			auto exts = AdcHub::parseSearchExts(Util::toInt(p.substr(2)));
+			ext.insert(ext.begin(), exts.begin(), exts.end());
+		} else if(toCode('R', 'M') == cmd) {
+			noExt.push_back(p.substr(2));
 		} else if(toCode('G', 'E') == cmd) {
 			gt = Util::toInt64(p.substr(2));
 		} else if(toCode('L', 'E') == cmd) {
@@ -1227,6 +1233,28 @@
 	}
 }
 
+bool ShareManager::AdcSearch::isExcluded(const string& str) {
+	for(StringSearch::List::iterator i = exclude.begin(); i != exclude.end(); ++i) {
+		if(i->match(str))
+			return true;
+	}
+	return false;
+}
+
+bool ShareManager::AdcSearch::hasExt(const string& name) {
+	if(ext.empty())
+		return true;
+	if(!noExt.empty()) {
+		ext = StringList(ext.begin(), set_difference(ext.begin(), ext.end(), noExt.begin(), noExt.end(), ext.begin()));
+		noExt.clear();
+	}
+	for(auto i = ext.cbegin(), iend = ext.cend(); i != iend; ++i) {
+		if(name.length() >= i->length() && Util::stricmp(name.c_str() + name.length() - i->length(), i->c_str()) == 0)
+			return true;
+	}
+	return false;
+}
+
 void ShareManager::Directory::search(SearchResultList& aResults, AdcSearch& aStrings, StringList::size_type maxResults) const throw() {
 	StringSearch::List* cur = aStrings.include;
 	StringSearch::List* old = aStrings.include;

=== modified file 'dcpp/ShareManager.h'
--- dcpp/ShareManager.h	2010-08-30 14:04:10 +0000
+++ dcpp/ShareManager.h	2010-11-19 15:11:20 +0000
@@ -207,28 +207,14 @@
 	struct AdcSearch {
 		AdcSearch(const StringList& params);
 
-		bool isExcluded(const string& str) {
-			for(StringSearch::List::iterator i = exclude.begin(); i != exclude.end(); ++i) {
-				if(i->match(str))
-					return true;
-			}
-			return false;
-		}
-
-		bool hasExt(const string& name) {
-			if(ext.empty())
-				return true;
-			for(StringIter i = ext.begin(); i != ext.end(); ++i) {
-				if(name.length() >= i->length() && Util::stricmp(name.c_str() + name.length() - i->length(), i->c_str()) == 0)
-					return true;
-			}
-			return false;
-		}
+		bool isExcluded(const string& str);
+		bool hasExt(const string& name);
 
 		StringSearch::List* include;
 		StringSearch::List includeX;
 		StringSearch::List exclude;
 		StringList ext;
+		StringList noExt;
 
 		int64_t gt;
 		int64_t lt;

=== modified file 'win32/SearchFrame.cpp'
--- win32/SearchFrame.cpp	2010-07-10 14:36:48 +0000
+++ win32/SearchFrame.cpp	2010-11-19 15:11:20 +0000
@@ -985,7 +985,6 @@
 	setText(str(TF_("Search - %1%") % s));
 
 	if(SearchManager::getInstance()->okToSearch()) {
-		dcdebug("Sent ADC extensions : %s\n",Util::toString(";",extList).c_str());
 		SearchManager::getInstance()->search(clients, Text::fromT(s), llsize,
 			(SearchManager::TypeModes)ftype, searchMode, token, extList);
 		if(BOOLSETTING(CLEAR_SEARCH)) // Only clear if the search was sent