commit ee2c32c3f26e0d62c2a169beb342a54a15a94e79
Author: Marc Dequènes (Duck) <Duck@DuckCorp.org>
Date:   Fri Mar 4 00:20:09 2011 +0100

    [evol] Botnet/Interface: '/?' search now return a Hash in order to get the object name easily for further manipulations, updated Librarian accordingly

diff --git a/IDEAS b/IDEAS
index 1229bf1..d8dfc4c 100644
--- a/IDEAS
+++ b/IDEAS
@@ -14,6 +14,12 @@ Postman:
 
     each queue is an internal channel, each processor is a task.
 
+API (all bots):
+  - list manipulators:
+    + /? -> search(<criterias>)
+    + /+ -> create(<data>)
+    + /- -> delete(<name>)
+
 MapMaker:
   - API:
     /Services/DNS -> named info
diff --git a/bin/test_client b/bin/test_client
index c4d733b..975e3d3 100755
--- a/bin/test_client
+++ b/bin/test_client
@@ -41,11 +41,11 @@ module CyborgHood
           ask "Librarian", :info2, "/_cyborg_"
           ask "Librarian", :library, "/Records"
           ask "Librarian", :persons, "/Records/Persons"
-          ask "Librarian", :dns_domains, "/Records/DnsDomains"
+          #ask "Librarian", :dns_domains, "/Records/DnsDomains"
           ask "Librarian", :gorou, "/Records/Persons/gorou"
           ask "Librarian", :guihome_net, "/Records/DnsDomains/guihome.net"
-          ask "Librarian", :person_search, "/Records/Persons/?", {:uidNumber => 10033}
-          ask "Librarian", :person_search_null, "/Records/Persons/?"
+          ask "Librarian", :person_search, "/Records/Persons/?", {:uid => "g*"}
+          #ask "Librarian", :person_search_null, "/Records/Persons/?"
           #ask "MapMaker", :zones, "/Zones"
           #ask "MapMaker", :wanted_failure, "/prout"
           #ask "MapMaker", :dns, "/Services/DNS"
@@ -53,8 +53,8 @@ module CyborgHood
           #ask "MapMaker", :zone_mp, "/Zones/milkypond.org"
           #ask "MapMaker", :dns_check, "/Services/DNS/check_config"
           #ask "MapMaker", :search, "/Zones/?"
-          #ask "MapMaker", :search_master, "/Zones/?", {:master => true}
-          #ask "MapMaker", :search_slave, "/Zones/?", {:master => false}
+          ask "MapMaker", :search_master, "/Zones/?", {:is_master => true}
+          #ask "MapMaker", :search_slave, "/Zones/?", {:is_master => false}
           #know? "MapMaker", :k1, "/Zones"
           #know? "MapMaker", :k2, "/prout"
           on_error do
diff --git a/lib/cyborghood-librarian/interface/0_base.rb b/lib/cyborghood-librarian/interface/0_base.rb
index a0ca755..da00e77 100644
--- a/lib/cyborghood-librarian/interface/0_base.rb
+++ b/lib/cyborghood-librarian/interface/0_base.rb
@@ -16,7 +16,10 @@ node 'Records' do
     end
 
     attr_search_node do |criterias|
-      object_list.call(:search, :criterias => criterias, :format => :data_hash)
+      {
+        :post_filter  => false,
+        :list         => object_list.call(:search, :criterias => criterias, :format => :data_hash)
+      }
     end
 
     node object_list do
diff --git a/lib/cyborghood-librarian/records.rb b/lib/cyborghood-librarian/records.rb
index a1c2c78..e670182 100644
--- a/lib/cyborghood-librarian/records.rb
+++ b/lib/cyborghood-librarian/records.rb
@@ -52,11 +52,11 @@ module CyborgHood
           filter = (filter_parts.size == 1) ? filter_parts.first : '(&' + filter_parts.join + ')'
 
           list = klass.find(:all, :filter => filter)
-          index_result(list, primary_attr) if options[:indexed]
+          list = index_result(list, primary_attr)
           format_result(list, options[:format])
         elsif obj_name == :all
           list = klass.find(:all)
-          index_result(list, primary_attr) if options[:indexed]
+          list = index_result(list, primary_attr)
           format_result(list, options[:format])
         else
           list = klass.find(:all, :attribute => primary_attr, :value => obj_name)
diff --git a/lib/cyborghood/cyborg/botnet/interface.rb b/lib/cyborghood/cyborg/botnet/interface.rb
index ac9de47..19f7361 100644
--- a/lib/cyborghood/cyborg/botnet/interface.rb
+++ b/lib/cyborghood/cyborg/botnet/interface.rb
@@ -284,7 +284,10 @@ module CyborgHood
       end
 
       def search_among_children(request, lookup_node)
-        node_names_list = []
+        criterias = request.args.first
+        return {} unless criterias.is_a? Hash
+
+        node_names_list = {}
 
         lookup_node.__send__(:visible_nodes).each do |match, node|
           if match.is_a? String
@@ -300,8 +303,10 @@ module CyborgHood
             result = node.__send__(:request, request.session)
             next unless result.respond_to? :to_hash
 
-            if hash_match_criterias(result.to_hash, request.args.first)
-              node_names_list << child_node_name
+            child_node_attrs = result.to_hash
+
+            if hash_match_criterias(child_node_attrs, criterias)
+              node_names_list[child_node_name] = child_node_attrs
             end
           end
         end
@@ -311,20 +316,21 @@ module CyborgHood
 
       def search_in_list(request, lookup_node, list)
         criterias = request.args.first
-        return [] unless criterias.is_a? Hash
+        return {} unless criterias.is_a? Hash
 
         if list.is_a? Proc
-          list = list.call(criterias)
-          # if result is an array, then a final list of names is given, return it
-          return list if list.is_a? Array
-          # else it must be a Hash which needs to be filtered
+          data = list.call(criterias)
+
+          return data[:list] unless data[:post_filter]
         end
 
-        node_names_list = []
+        node_names_list = {}
+
+        data[:list].each do |element_name, element|
+          element_attrs = element.to_hash
 
-        list.each do |element_name, element|
-          if hash_match_criterias(element.to_hash, criterias)
-            node_names_list << element_name
+          if hash_match_criterias(element_attrs, criterias)
+            node_names_list[element_name] = element_attrs
           end
         end
 
