tags 298734 + patch
block 603269 by 298734
thanks

Attached patch contains a group policy named `site' for grouping
packages according to their origin site (server).

- origin site is obtained from PkgFileIterator::Site()
- packages available from multiple sites appear *once* under each

---[Example]
sources.list:
# Will provide 3 distinct versions of iceweasel.
deb http://ftp.au.debian.org/debian squeeze main
deb http://ftp.au.debian.org/debian sid main
deb http://mozilla.debian.net/ experimental iceweasel-beta

package view:
# With group policy "status,site" and view limit "^iceweasel".
--\ Not Installed Packages (91)
  --\ ftp.au.debian.org (89)
p  U iceweasel
p  U iceweasel-dbg
  [...]
  --\ mozilla.debian.net (2)
p  U iceweasel
p  U iceweasel-dbg
---

apt_preferences refers to this data using the keyword `origin',
however, I have decided to use `site' for the group policy as I intend
to now work on an equivilent search term and `?origin' is already in
use.

Using the keyword `origin' for this data seems more descriptive to me.
I think that the group policy could be `origin' and the search term
`?origin-site', any opinions on this?


On 9 Mar 2005, Michelle Konzack <[email protected]> wrote:
> I have more then 20 Servers in my /etc/apt/sources.list and I like
> to see aptitude seperating the menu by servers like:
>
> --\ Installed Packages
>   --\ ftp.de.debian.org
>     --- admin
>     --- base
>     ...
>   --\ security.debian.org
>     --- admin
>     --- base
>     ...

With attached patch, this layout is achieved by inserting `site'
before `section' in your group policy:

  "task,status,site,section(subdirs,passthrough),section(topdir)"

> And third whis is, if only ONE Flaveour of "main", "contrib" or
> "non-free" is used hide it...

Note that this request is a dupe of #244434.


I consider the patch to be fairly complete, however opinions and
naming suggestions are welcome.

Aptitude is an excellent tool :)
diff --git a/src/load_grouppolicy.cc b/src/load_grouppolicy.cc
index a75e21e..e47b764 100644
--- a/src/load_grouppolicy.cc
+++ b/src/load_grouppolicy.cc
@@ -548,6 +548,18 @@ public:
   }
 };
 
+class site_policy_parser : public string_policy_parser
+{
+public:
+  group_policy_parse_node *create_node(const vector<string> &args)
+  {
+    if(args.size()!=0)
+      throw GroupParseException(_("Too many arguments to by-site grouping policy"));
+
+    return new policy_node0<pkg_grouppolicy_site_factory>;
+  }
+};
+
 class ver_policy_parser : public string_policy_parser
 {
   group_policy_parse_node *create_node(const vector<string> &args)
@@ -771,6 +783,7 @@ static void init_parse_types()
       parse_types["filter"]=new filter_policy_parser;
       parse_types["firstchar"]=new firstchar_policy_parser;
       parse_types["source"]=new source_policy_parser;
+      parse_types["site"]=new site_policy_parser;
 
       parse_types["versions"]=new ver_policy_parser;
       parse_types["deps"]=new dep_policy_parser;
diff --git a/src/pkg_grouppolicy.cc b/src/pkg_grouppolicy.cc
index 29eee4b..258040d 100644
--- a/src/pkg_grouppolicy.cc
+++ b/src/pkg_grouppolicy.cc
@@ -49,6 +49,8 @@
 #include <sigc++/functors/mem_fun.h>
 #include <sigc++/trackable.h>
 
+#include <boost/tuple/tuple.hpp>
+
 using namespace std;
 
 namespace cw = cwidget;
@@ -1723,3 +1725,77 @@ pkg_grouppolicy *pkg_grouppolicy_source_factory::instantiate(pkg_signal *sig,
 {
   return new pkg_grouppolicy_source(chain, sig, desc_sig);
 }
+
+
+/*****************************************************************************/
+
+// Groups packages by site (origin server)
+class pkg_grouppolicy_site:public pkg_grouppolicy
+{
+  typedef map<string,
+	      boost::tuple<pkg_grouppolicy *, pkg_subtree *, bool> > childmap;
+
+  childmap children;
+  pkg_grouppolicy_factory *chain;
+  pkg_grouppolicy *spillover;
+
+public:
+  pkg_grouppolicy_site(pkg_grouppolicy_factory *_chain,
+		       pkg_signal *_sig, desc_signal *_desc_sig)
+    :pkg_grouppolicy(_sig, _desc_sig),
+     chain(_chain),
+     spillover(_chain->instantiate(get_sig(), get_desc_sig()))
+  {
+  }
+
+  ~pkg_grouppolicy_site()
+  {
+    for(childmap::iterator i = children.begin(); i != children.end(); ++i)
+      delete i->second.get<0>();
+  }
+
+  void add_package(const pkgCache::PkgIterator &pkg, pkg_subtree *root)
+  {
+    // Keep track of which children we have added pkg to.  Need to do
+    // this otherwise packages with multiple versions available from
+    // a single site will appear there more than once.
+    for(childmap::iterator i = children.begin(); i != children.end(); ++i)
+      i->second.get<2>() = false;
+
+    for(pkgCache::VerIterator v = pkg.VersionList(); !v.end(); ++v)
+      {
+	std::string origin_site = v.FileList().File().Site();
+	if(origin_site == "")
+	  origin_site = "Local";
+
+	childmap::iterator found = children.find(origin_site);
+	if(found != children.end())
+	  {
+	    if(found->second.get<2>() == false)
+	      {
+		found->second.get<0>()->add_package(pkg, found->second.get<1>());
+		found->second.get<2>() = true;
+	      }
+	  }
+	else
+	  {
+	    pkg_subtree *newtree = new pkg_subtree(cw::util::transcode(origin_site),
+						   L"", get_desc_sig());
+	    pkg_grouppolicy *newchild = chain->instantiate(get_sig(),
+							   get_desc_sig());
+	    children[origin_site].get<0>() = newchild;
+	    children[origin_site].get<1>() = newtree;
+	    children[origin_site].get<2>() = true;
+	    root->add_child(newtree);
+	    newtree->set_num_packages_parent(root);
+	    newchild->add_package(pkg, newtree);
+	  }
+      }
+  }
+};
+
+pkg_grouppolicy *pkg_grouppolicy_site_factory::instantiate(pkg_signal *sig,
+							   desc_signal *desc_sig)
+{
+  return new pkg_grouppolicy_site(chain, sig, desc_sig);
+}
diff --git a/src/pkg_grouppolicy.h b/src/pkg_grouppolicy.h
index f9169e2..f57d9fb 100644
--- a/src/pkg_grouppolicy.h
+++ b/src/pkg_grouppolicy.h
@@ -391,4 +391,18 @@ public:
   {delete chain;}
 };
 
+// Groups by origin site
+class pkg_grouppolicy_site_factory:public pkg_grouppolicy_factory
+{
+  pkg_grouppolicy_factory *chain;
+public:
+  pkg_grouppolicy_site_factory(pkg_grouppolicy_factory *_chain):chain(_chain) {}
+
+  pkg_grouppolicy *instantiate(pkg_signal *_sig,
+			       desc_signal *_desc_sig);
+
+  virtual ~pkg_grouppolicy_site_factory()
+  {delete chain;}
+};
+
 #endif
diff --git a/doc/en/aptitude.xml b/doc/en/aptitude.xml
index 438a995..592ada0 100644
--- a/doc/en/aptitude.xml
+++ b/doc/en/aptitude.xml
@@ -7728,6 +7728,16 @@ e: Examine  !: Apply  .: Next  ,: Previous</screen>
 	      </listitem>
 	    </varlistentry>
 
+            <varlistentry>
+              <term><synopsis>site</synopsis></term>
+
+              <listitem>
+                <para>
+                  Groups packages according to their origin site (server).
+                </para>
+              </listitem>
+            </varlistentry>
+
 	    <varlistentry>
 	      <term><synopsis>status</synopsis></term>
 
_______________________________________________
Aptitude-devel mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/aptitude-devel

Reply via email to