From 76926159194e180003aa78de97e5f287bf4325a5 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 20:07:41 +0200 Subject: Adding upstream version 2.7.6. Signed-off-by: Daniel Baumann --- python/acquire.cc | 424 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 424 insertions(+) create mode 100644 python/acquire.cc (limited to 'python/acquire.cc') diff --git a/python/acquire.cc b/python/acquire.cc new file mode 100644 index 0000000..aab899f --- /dev/null +++ b/python/acquire.cc @@ -0,0 +1,424 @@ +/* acquire.cc - Wrapper for pkgAcquire. + * + * Copyright 2004-2009 Canonical Ltd + * Copyright 2009 Julian Andres Klode + * + * Authors: Michael Vogt + * Julian Andres Klode + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include "generic.h" +#include "apt_pkgmodule.h" +#include "progress.h" + +#include +#include + + +static PyObject *acquireworker_get_current_item(PyObject *self, void *closure) +{ + pkgAcquire::Worker *worker = GetCpp(self); + pkgAcquire::ItemDesc *desc = worker->CurrentItem; + if (desc == NULL) { + Py_RETURN_NONE; + } + PyObject *PyAcq = GetOwner(self); + PyObject *PyItem = PyAcquireItem_FromCpp(desc->Owner, false, PyAcq); + PyObject *PyDesc = PyAcquireItemDesc_FromCpp(desc, false, PyItem); + Py_XDECREF(PyItem); + return PyDesc; +} + +static PyObject *acquireworker_get_status(PyObject *self, void *closure) +{ + return CppPyString(GetCpp(self)->Status); +} + +static PyObject *acquireworker_get_current_size(PyObject *self, void *closure) +{ + if (GetCpp(self)->CurrentItem == nullptr) + return 0; + return MkPyNumber(GetCpp(self)->CurrentItem->CurrentSize); +} + +static PyObject *acquireworker_get_total_size(PyObject *self, void *closure) +{ + if (GetCpp(self)->CurrentItem == nullptr) + return 0; + return MkPyNumber(GetCpp(self)->CurrentItem->TotalSize); +} + +static PyObject *acquireworker_get_resumepoint(PyObject *self, void *closure) +{ + if (GetCpp(self)->CurrentItem == nullptr) + return 0; + return MkPyNumber(GetCpp(self)->CurrentItem->ResumePoint); +} + +static PyGetSetDef acquireworker_getset[] = { + {"current_item",acquireworker_get_current_item,0, + "The item currently being fetched, as an apt_pkg.AcquireItemDesc object."}, + {"status",acquireworker_get_status,0, + "The status of the worker, as a string."}, + {"current_size",acquireworker_get_current_size,0, + "The amount of data fetched so far for the current item."}, + {"total_size",acquireworker_get_total_size,0, + "The total size of the item."}, + {"resumepoint",acquireworker_get_resumepoint,0, + "The amount of data which was already available when the download was\n" + "started."}, + {NULL} +}; + +static const char *acquireworker_doc = + "Represent a sub-process responsible for fetching files from\n" + "remote locations. This sub-process uses 'methods' located in\n" + "the directory specified by the configuration option\n" + "Dir::Bin::Methods."; +PyTypeObject PyAcquireWorker_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.AcquireWorker", // tp_name + sizeof(CppPyObject),// tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT| // tp_flags + Py_TPFLAGS_HAVE_GC, + acquireworker_doc, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + acquireworker_getset, // tp_getset +}; + + +static pkgAcquire::ItemDesc* acquireitemdesc_tocpp(PyObject *self) { + pkgAcquire::ItemDesc *item = GetCpp(self); + if (item == NULL) + PyErr_SetString(PyExc_ValueError, "Acquire has been shutdown"); + return item; +} + +static PyObject *acquireitemdesc_get_uri(PyObject *self, void *closure) +{ + pkgAcquire::ItemDesc *item = acquireitemdesc_tocpp(self); + return item ? CppPyString(item->URI) : NULL; +} +static PyObject *acquireitemdesc_get_description(PyObject *self, void *closure) +{ + pkgAcquire::ItemDesc *item = acquireitemdesc_tocpp(self); + return item ? CppPyString(item->Description) : NULL; +} +static PyObject *acquireitemdesc_get_shortdesc(PyObject *self, void *closure) +{ + pkgAcquire::ItemDesc *item = acquireitemdesc_tocpp(self); + return item ? CppPyString(item->ShortDesc) : NULL; +} +static PyObject *acquireitemdesc_get_owner(CppPyObject *self, void *closure) +{ + if (self->Owner != NULL) { + Py_INCREF(self->Owner); + return self->Owner; + } + else if (self->Object) { + self->Owner = PyAcquireItem_FromCpp(self->Object->Owner, false, NULL); + Py_INCREF(self->Owner); + return self->Owner; + } + Py_RETURN_NONE; +} + +static PyGetSetDef acquireitemdesc_getset[] = { + {"uri",acquireitemdesc_get_uri,0, + "The URI from which this item would be downloaded."}, + {"description",acquireitemdesc_get_description,0, + "A string describing the item."}, + {"shortdesc",acquireitemdesc_get_shortdesc,0, + "A short string describing the item (e.g. package name)."}, + {"owner",(getter)acquireitemdesc_get_owner,0, + "The owner of the item, an apt_pkg.AcquireItem object."}, + {NULL} +}; + +static char *acquireitemdesc_doc = + "Provide the description of an item and the URI the item is\n" + "fetched from. Progress classes make use of such objects to\n" + "retrieve description and other information about an item."; +PyTypeObject PyAcquireItemDesc_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.AcquireItemDesc", // tp_name + sizeof(CppPyObject),// tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_HAVE_GC), + acquireitemdesc_doc, // tp_doc + CppTraverse,// tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + acquireitemdesc_getset, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + 0, // tp_new +}; + +static PyObject *PkgAcquireRun(PyObject *Self,PyObject *Args) +{ + pkgAcquire *fetcher = GetCpp(Self); + + int pulseInterval = 500000; + if (PyArg_ParseTuple(Args, "|i", &pulseInterval) == 0) + return 0; + + pkgAcquire::RunResult run = fetcher->Run(pulseInterval); + + return HandleErrors(MkPyNumber(run)); +} + + +static PyObject *PkgAcquireShutdown(PyObject *Self,PyObject *Args) +{ + pkgAcquire *fetcher = GetCpp(Self); + if (PyArg_ParseTuple(Args, "") == 0) + return 0; + fetcher->Shutdown(); + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static PyObject *PkgAcquireGetLock(PyObject *Self,PyObject *Args) +{ + pkgAcquire *fetcher = GetCpp(Self); + PyApt_Filename path; + if (PyArg_ParseTuple(Args, "O&", PyApt_Filename::Converter, &path) == 0) + return 0; + fetcher->GetLock(path); + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + + + +static PyMethodDef PkgAcquireMethods[] = { + {"run",PkgAcquireRun,METH_VARARGS, + "run() -> int\n\nRun the fetcher and return one of RESULT_CANCELLED,\n" + "RESULT_CONTINUE, RESULT_FAILED.\n\n" + "RESULT_CONTINUE means that all items which where queued prior to\n" + "calling run() have been fetched successfully or failed transiently.\n\n" + "RESULT_CANCELLED means canceled by the progress class.\n\n" + "RESULT_FAILED means a generic failure."}, + {"shutdown",PkgAcquireShutdown, METH_VARARGS, + "shutdown()\n\n" + "Shut the fetcher down, removing all items from it. Future access to\n" + "queued AcquireItem objects will cause a segfault. The partial result\n" + "is kept on the disk and not removed and APT might reuse it."}, + {"get_lock",PkgAcquireGetLock, METH_VARARGS, + "get_lock(log: str)\n\n" + "Acquires a log for the given directory, using a file 'lock' in it."}, + {} +}; + +#define fetcher (GetCpp(Self)) +static PyObject *PkgAcquireGetTotalNeeded(PyObject *Self,void*) +{ + return MkPyNumber(fetcher->TotalNeeded()); +} +static PyObject *PkgAcquireGetFetchNeeded(PyObject *Self,void*) +{ + return MkPyNumber(fetcher->FetchNeeded()); +} +static PyObject *PkgAcquireGetPartialPresent(PyObject *Self,void*) +{ + return MkPyNumber(fetcher->PartialPresent()); +} +#undef fetcher + +static PyObject *PkgAcquireGetWorkers(PyObject *self, void *closure) +{ + PyObject *List = PyList_New(0); + pkgAcquire *Owner = GetCpp(self); + PyObject *PyWorker = NULL; + for (pkgAcquire::Worker *Worker = Owner->WorkersBegin(); + Worker != 0; Worker = Owner->WorkerStep(Worker)) { + PyWorker = PyAcquireWorker_FromCpp(Worker, false, self); + PyList_Append(List, PyWorker); + Py_DECREF(PyWorker); + } + return List; +} +static PyObject *PkgAcquireGetItems(PyObject *Self,void*) +{ + pkgAcquire *fetcher = GetCpp(Self); + PyObject *List = PyList_New(0); + PyObject *Obj; + for (pkgAcquire::ItemIterator I = fetcher->ItemsBegin(); + I != fetcher->ItemsEnd(); I++) { + Obj = PyAcquireItem_FromCpp(*I, false, Self); + PyList_Append(List,Obj); + Py_DECREF(Obj); + } + return List; +} + +static PyGetSetDef PkgAcquireGetSet[] = { + {"fetch_needed",PkgAcquireGetFetchNeeded,0, + "The total amount of data to be fetched (number of bytes)."}, + {"items",PkgAcquireGetItems,0, + "A list of all items as apt_pkg.AcquireItem objects, including already\n" + "fetched ones and to be fetched ones."}, + {"workers",PkgAcquireGetWorkers,0, + "A list of all active workers as apt_pkg.AcquireWorker objects."}, + {"partial_present",PkgAcquireGetPartialPresent,0, + "The amount of data which is already available (number of bytes)."}, + {"total_needed",PkgAcquireGetTotalNeeded,0, + "The amount of data that needs to fetched plus the amount of data\n" + "which has already been fetched (number of bytes)."}, + {} +}; + +static PyObject *PkgAcquireNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) +{ + pkgAcquire *fetcher; + + PyObject *pyFetchProgressInst = NULL; + char *kwlist[] = {"progress", 0}; + if (PyArg_ParseTupleAndKeywords(Args,kwds,"|O",kwlist,&pyFetchProgressInst) == 0) + return 0; + + PyFetchProgress *progress = 0; + if (pyFetchProgressInst != NULL) { + // FIXME: memleak? + progress = new PyFetchProgress(); + progress->setCallbackInst(pyFetchProgressInst); + } + + fetcher = new pkgAcquire(); + fetcher->SetLog(progress); + + PyObject *FetcherObj = CppPyObject_NEW(NULL, type, fetcher); + + if (progress != 0) + progress->setPyAcquire(FetcherObj); + // prepare our map of items. + return HandleErrors(FetcherObj); +} + +/** + * Create a new apt_pkg.Acquire Python object from the pkgAcquire object. + */ +PyObject *PyAcquire_FromCpp(pkgAcquire *fetcher, bool Delete, PyObject *owner) { + CppPyObject *obj = CppPyObject_NEW(owner, &PyAcquire_Type, fetcher); + obj->NoDelete = (!Delete); + return obj; +} + +static char *doc_PkgAcquire = + "Acquire([progress: apt.progress.base.AcquireProgress])\n\n" + "Coordinate the retrieval of files via network or local file system\n" + "(using 'copy:/path/to/file' style URIs). The optional argument\n" + "'progress' takes an apt.progress.base.AcquireProgress object\n" + "which may report progress information."; + +PyTypeObject PyAcquire_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.Acquire", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDeallocPtr, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE), + doc_PkgAcquire, // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgAcquireMethods, // tp_methods + 0, // tp_members + PkgAcquireGetSet, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + PkgAcquireNew, // tp_new +}; + + -- cgit v1.2.3