|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <Python.h> |
|
#include "apt_pkgmodule.h" |
|
#include "generic.h" |
|
#include <apt-pkg/pkgcache.h> |
|
|
|
struct PyGroup : CppPyObject<pkgCache::GrpIterator> { |
|
pkgCache::PkgIterator current; |
|
int nextIndex; |
|
}; |
|
|
|
static PyObject *group_new(PyTypeObject *type,PyObject *args, |
|
PyObject *kwds) |
|
{ |
|
PyObject *pyCache; |
|
char *name; |
|
char *kwlist[] = {"cache", "name", NULL}; |
|
if (PyArg_ParseTupleAndKeywords(args, kwds, "O!s", kwlist, |
|
&PyCache_Type, &pyCache, |
|
&name) == 0) |
|
return 0; |
|
|
|
pkgCache *cache = GetCpp<pkgCache *>(pyCache); |
|
|
|
pkgCache::GrpIterator grp = cache->FindGrp(name); |
|
|
|
if (!grp.end()) { |
|
return PyGroup_FromCpp(grp, true, pyCache); |
|
} else { |
|
PyErr_SetString(PyExc_KeyError, name); |
|
return NULL; |
|
} |
|
} |
|
|
|
static const char group_find_package_doc[] = |
|
"find_package(architecture: str) -> Package\n\n" |
|
"Return a package for the given architecture, or None if none exists"; |
|
static PyObject *group_find_package(PyObject *self,PyObject *args) |
|
{ |
|
pkgCache::GrpIterator grp = GetCpp<pkgCache::GrpIterator>(self); |
|
PyObject *owner = GetOwner<pkgCache::GrpIterator>(self); |
|
|
|
char *architecture; |
|
if (PyArg_ParseTuple(args, "s", &architecture) == 0) |
|
return 0; |
|
|
|
pkgCache::PkgIterator pkg = grp.FindPkg(architecture); |
|
|
|
if (pkg.end()) { |
|
Py_RETURN_NONE; |
|
} else { |
|
return PyPackage_FromCpp(pkg, true, owner ? owner : self); |
|
} |
|
} |
|
|
|
static const char group_find_preferred_package_doc[] = |
|
"find_preferred_package(prefer_non_virtual: bool = True) -> Package\n\n" |
|
"Return a package for the best architecture, either the native one\n" |
|
"or the first found one. If none exists, return None. If non_virtual\n" |
|
"is True, prefer non-virtual packages over virtual ones."; |
|
static PyObject *group_find_preferred_package(PyObject *self,PyObject *args, |
|
PyObject *kwds) |
|
{ |
|
pkgCache::GrpIterator grp = GetCpp<pkgCache::GrpIterator>(self); |
|
PyObject *owner = GetOwner<pkgCache::GrpIterator>(self); |
|
char nonvirtual = 1; |
|
char *kwlist[] = {"prefer_non_virtual", NULL}; |
|
if (PyArg_ParseTupleAndKeywords(args, kwds, "|b", kwlist, &nonvirtual) == 0) |
|
return 0; |
|
pkgCache::PkgIterator pkg = grp.FindPreferredPkg(nonvirtual); |
|
|
|
if (pkg.end()) { |
|
Py_RETURN_NONE; |
|
} else { |
|
return PyPackage_FromCpp(pkg, true, owner); |
|
} |
|
} |
|
|
|
static PyMethodDef group_methods[] = { |
|
{"find_package",group_find_package,METH_VARARGS,group_find_package_doc}, |
|
{"find_preferred_package",(PyCFunction) group_find_preferred_package, |
|
METH_VARARGS|METH_KEYWORDS,group_find_preferred_package_doc}, |
|
{} |
|
}; |
|
|
|
static PyObject *group_seq_item(PyObject *pySelf,Py_ssize_t index) |
|
{ |
|
PyGroup *self = static_cast<PyGroup *>(pySelf); |
|
pkgCache::GrpIterator grp = GetCpp<pkgCache::GrpIterator>(self); |
|
PyObject *owner = GetOwner<pkgCache::GrpIterator>(self); |
|
|
|
if (self->nextIndex > index || self->nextIndex == 0) { |
|
self->nextIndex = 1; |
|
new (&self->current) pkgCache::PkgIterator(grp.PackageList()); |
|
} |
|
|
|
if (self->nextIndex != index + 1) { |
|
while (self->nextIndex <= index && !self->current.end()) { |
|
self->current = grp.NextPkg(self->current); |
|
self->nextIndex++; |
|
} |
|
} |
|
|
|
if (self->current.end()) |
|
return PyErr_Format(PyExc_IndexError, "Out of range: %zd", index); |
|
|
|
return PyPackage_FromCpp(self->current, true, owner); |
|
} |
|
|
|
|
|
static PySequenceMethods group_as_sequence = |
|
{ |
|
0, |
|
0, |
|
0, |
|
group_seq_item, |
|
0, |
|
0, |
|
0 |
|
}; |
|
|
|
|
|
static const char group_doc[] = "Group(cache, name)\n\n" |
|
"Group of packages with the same name.\n\n" |
|
"Provides access to all packages sharing a name. Can be used this\n" |
|
"like a list, or by using the special find_*() methods. If you use\n" |
|
"it as a sequence, make sure to access it linearly, as this uses a\n" |
|
"linked list internally."; |
|
PyTypeObject PyGroup_Type = { |
|
PyVarObject_HEAD_INIT(&PyType_Type, 0) |
|
"apt_pkg.Group", |
|
sizeof(PyGroup), |
|
0, |
|
|
|
CppDealloc<pkgCache::GrpIterator>, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
&group_as_sequence, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
Py_TPFLAGS_DEFAULT, |
|
group_doc, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
group_methods, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
group_new, |
|
}; |
|
|