#############################################################################*/
#include <Python.h>
-#include <errno.h>
-#include <stdbool.h>
-#include <solv/repo.h>
-#include <solv/repo_solv.h>
-#include <solv/repo_write.h>
-
-#include "constants.h"
-#include "pool.h"
-#include "repo.h"
-#include "solvable.h"
-PyTypeObject RepoType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- tp_name: "_pakfire.Repo",
- tp_basicsize: sizeof(RepoObject),
- tp_flags: Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- tp_new : Repo_new,
- tp_dealloc: (destructor) Repo_dealloc,
- tp_doc: "Sat Repo objects",
-};
+#include <pakfire/errno.h>
+#include <pakfire/package.h>
+#include <pakfire/repo.h>
+#include <pakfire/repocache.h>
+#include <pakfire/util.h>
+
+#include "package.h"
+#include "repo.h"
PyObject* new_repo(PoolObject* pool, const char* name) {
PyObject* args = Py_BuildValue("Os", (PyObject *)pool, name);
return repo;
}
-PyObject* Repo_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
- RepoObject *self;
+static PyObject* Repo_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
+ RepoObject* self = (RepoObject *)type->tp_alloc(type, 0);
+ if (self) {
+ self->pool = NULL;
+ self->repo = NULL;
+ }
- PoolObject *pool;
- const char *name;
+ return (PyObject *)self;
+}
- if (!PyArg_ParseTuple(args, "Os", &pool, &name)) {
- return NULL;
- }
+static void Repo_dealloc(RepoObject* self) {
+ if (self->repo)
+ pakfire_repo_free(self->repo);
- assert(pool);
- assert(name);
+ Py_XDECREF(self->pool);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
- self = (RepoObject *)type->tp_alloc(type, 0);
- if (self != NULL) {
- self->_repo = repo_create(pool->_pool, name);
- if (self->_repo == NULL) {
- Py_DECREF(self);
- return NULL;
- }
- }
+static int Repo_init(RepoObject* self, PyObject* args, PyObject* kwds) {
+ PyObject* pool;
+ const char* name;
- return (PyObject *)self;
+ if (!PyArg_ParseTuple(args, "O!s", &PoolType, &pool, &name))
+ return -1;
+
+ self->pool = (PoolObject *)pool;
+ Py_INCREF(self->pool);
+
+ self->repo = pakfire_repo_create(self->pool->pool, name);
+
+ return 0;
}
-PyObject *Repo_dealloc(RepoObject *self) {
- Py_TYPE(self)->tp_free((PyObject *)self);
+static long Repo_hash(RepoObject* self) {
+ return (long)self->repo;
+}
- Py_RETURN_NONE;
+static PyObject* Repo_richcompare(RepoObject* self, RepoObject* other, int op) {
+ int r;
+
+ switch (op) {
+ case Py_EQ:
+ if (pakfire_repo_identical(self->repo, other->repo) == 0)
+ Py_RETURN_TRUE;
+
+ Py_RETURN_FALSE;
+ break;
+
+ case Py_LT:
+ r = pakfire_repo_cmp(self->repo, other->repo);
+ if (r < 0)
+ Py_RETURN_TRUE;
+
+ Py_RETURN_FALSE;
+ break;
+
+ default:
+ break;
+ }
+
+ Py_RETURN_NOTIMPLEMENTED;
}
-PyObject *Repo_name(RepoObject *self) {
- Repo *repo = self->_repo;
+static Py_ssize_t Repo_len(RepoObject* self) {
+ return pakfire_repo_count(self->repo);
+}
- return Py_BuildValue("s", repo->name);
+static PyObject* Repo_get_name(RepoObject* self) {
+ const char* name = pakfire_repo_get_name(self->repo);
+
+ return PyUnicode_FromString(name);
}
-PyObject *Repo_size(RepoObject *self) {
- Repo *repo = self->_repo;
+static int Repo_set_name(RepoObject* self, PyObject* value) {
+ const char* name = PyUnicode_AsUTF8(value);
- return Py_BuildValue("i", repo->nsolvables);
+ pakfire_repo_set_name(self->repo, name);
+ return 0;
}
-PyObject *Repo_get_enabled(RepoObject *self) {
- if (self->_repo->disabled == 0) {
+static PyObject* Repo_get_enabled(RepoObject* self) {
+ if (pakfire_repo_get_enabled(self->repo))
Py_RETURN_TRUE;
- }
Py_RETURN_FALSE;
}
-PyObject *Repo_set_enabled(RepoObject *self, PyObject *args) {
- bool enabled;
+static int Repo_set_enabled(RepoObject* self, PyObject* value) {
+ if (PyObject_IsTrue(value))
+ pakfire_repo_set_enabled(self->repo, 1);
+ else
+ pakfire_repo_set_enabled(self->repo, 0);
- if (!PyArg_ParseTuple(args, "b", &enabled)) {
- return NULL;
- }
+ return 0;
+}
- if (enabled == true) {
- self->_repo->disabled = 0;
- } else {
- self->_repo->disabled = 1;
- }
+static PyObject* Repo_get_priority(RepoObject* self) {
+ int priority = pakfire_repo_get_priority(self->repo);
- Py_RETURN_NONE;
+ return PyLong_FromLong(priority);
}
-PyObject *Repo_get_priority(RepoObject *self) {
- return Py_BuildValue("i", self->_repo->priority);
+static int Repo_set_priority(RepoObject* self, PyObject* value) {
+ long priority = PyLong_AsLong(value);
+
+ if (priority > INT_MAX || priority < INT_MIN)
+ return -1;
+
+ pakfire_repo_set_priority(self->repo, priority);
+ return 0;
}
-PyObject *Repo_set_priority(RepoObject *self, PyObject *args) {
- int priority;
+static PyObject* Repo_read_solv(RepoObject* self, PyObject* args) {
+ const char* filename = NULL;
- if (!PyArg_ParseTuple(args, "i", &priority)) {
- /* XXX raise exception */
+ if (!PyArg_ParseTuple(args, "s", &filename))
return NULL;
- }
- self->_repo->priority = priority;
+ int ret = pakfire_repo_read_solv(self->repo, filename, 0);
+
+ switch (ret) {
+ case 0:
+ Py_RETURN_NONE;
+ break;
+
+ case PAKFIRE_E_IO:
+ PyErr_Format(PyExc_IOError, "Could not read file %s", filename);
+ break;
- Py_RETURN_NONE;
+ default:
+ PyErr_Format(PyExc_RuntimeError, "pakfire_repo_read() failed: %d", ret);
+ break;
+ }
+
+ return NULL;
}
-PyObject *Repo_write(RepoObject *self, PyObject *args) {
- const char *filename;
- char exception[STRING_SIZE];
+static PyObject* Repo_write_solv(RepoObject* self, PyObject* args) {
+ const char* filename = NULL;
- if (!PyArg_ParseTuple(args, "s", &filename)) {
+ if (!PyArg_ParseTuple(args, "s", &filename))
return NULL;
+
+ int ret = pakfire_repo_write_solv(self->repo, filename, 0);
+
+ switch (ret) {
+ case 0:
+ Py_RETURN_NONE;
+ break;
+
+ case PAKFIRE_E_IO:
+ PyErr_Format(PyExc_IOError, "Could not open file %s", filename);
+ break;
+
+ default:
+ PyErr_Format(PyExc_RuntimeError, "pakfire_repo_write() failed: %d", ret);
+ break;
}
- // Prepare the pool and internalize all attributes.
- //_Pool_prepare(self->_repo->pool);
+ return NULL;
+}
+
+static PyObject* Repo__add_package(RepoObject* self, PyObject* args) {
+ const char* name;
+ const char* evr;
+ const char* arch;
- FILE *fp = NULL;
- if ((fp = fopen(filename, "wb")) == NULL) {
- snprintf(exception, STRING_SIZE - 1, "Could not open file for writing: %s (%s).",
- filename, strerror(errno));
- PyErr_SetString(PyExc_RuntimeError, exception);
+ if (!PyArg_ParseTuple(args, "sss", &name, &evr, &arch))
return NULL;
- }
- repo_write(self->_repo, fp);
- fclose(fp);
+ PakfirePool pool = pakfire_repo_pool(self->repo);
+ PakfirePackage pkg = pakfire_package_create2(pool, self->repo, name, evr, arch);
- Py_RETURN_NONE;
+ return new_package(self->pool, pakfire_package_id(pkg));
}
-PyObject *Repo_read(RepoObject *self, PyObject *args) {
- const char *filename;
+static PyObject* Repo_cache_age(RepoObject* self, PyObject* args) {
+ const char* filename = NULL;
- if (!PyArg_ParseTuple(args, "s", &filename)) {
+ if (!PyArg_ParseTuple(args, "s", &filename))
return NULL;
- }
- // XXX catch if file cannot be opened
- FILE *fp = fopen(filename, "rb");
- repo_add_solv(self->_repo, fp, 0);
- fclose(fp);
+ PakfireRepoCache cache = pakfire_repo_get_cache(self->repo);
+ if (!cache)
+ Py_RETURN_NONE;
- Py_RETURN_NONE;
-}
+ int age = pakfire_repocache_age(cache, filename);
-PyObject *Repo_internalize(RepoObject *self) {
- repo_internalize(self->_repo);
+ if (age < 0)
+ Py_RETURN_NONE;
- Py_RETURN_NONE;
+ PyObject* ret = PyLong_FromLong(age);
+ return ret;
}
-PyObject *Repo_clear(RepoObject *self) {
- repo_empty(self->_repo, 1);
+static PyObject* Repo_cache_exists(RepoObject* self, PyObject* args) {
+ const char* filename = NULL;
- Py_RETURN_NONE;
-}
+ if (!PyArg_ParseTuple(args, "s", &filename))
+ return NULL;
-PyObject *Repo_get_all(RepoObject *self) {
- Solvable *s;
- Id p;
- Repo *r = self->_repo;
+ PakfireRepoCache cache = pakfire_repo_get_cache(self->repo);
+ if (!cache)
+ Py_RETURN_NONE;
- assert(r != NULL);
- assert(r->pool != NULL);
+ int ret = pakfire_repocache_has_file(cache, filename);
- PyObject *list = PyList_New(0);
+ if (ret)
+ Py_RETURN_TRUE;
- FOR_REPO_SOLVABLES(r, p, s) {
- SolvableObject *solv;
+ Py_RETURN_FALSE;
+}
+
+static PyObject* Repo_cache_open(RepoObject* self, PyObject* args) {
+ const char* filename = NULL;
+ char* mode = NULL;
+
+ if (!PyArg_ParseTuple(args, "ss", &filename, &mode))
+ return NULL;
- solv = PyObject_New(SolvableObject, &SolvableType);
- if (solv == NULL)
- return NULL;
+ PakfireRepoCache cache = pakfire_repo_get_cache(self->repo);
+ if (!cache)
+ Py_RETURN_NONE;
- solv->_pool = r->pool;
- solv->_id = p;
+ FILE* fp = pakfire_repocache_open(cache, filename, mode);
- PyList_Append(list, (PyObject *)solv);
- Py_DECREF(solv);
+ if (!fp) {
+ PyErr_Format(PyExc_IOError, "Could not open file %s", filename);
+ return NULL;
}
- return list;
+ // XXX might cause some problems with internal buffering
+ return PyFile_FromFd(fileno(fp), NULL, mode, 1, NULL, NULL, NULL, 1);
+}
+
+static PyObject* Repo_cache_path(RepoObject* self, PyObject* args) {
+ const char* filename = NULL;
+
+ if (!PyArg_ParseTuple(args, "s", &filename))
+ return NULL;
+
+ PakfireRepoCache cache = pakfire_repo_get_cache(self->repo);
+ if (!cache)
+ Py_RETURN_NONE;
+
+ char* cache_path = pakfire_repocache_get_full_path(cache, filename);
+
+ PyObject* obj = PyUnicode_FromString(cache_path);
+ pakfire_free(cache_path);
+
+ return obj;
}
+
+static struct PyMethodDef Repo_methods[] = {
+ {
+ "cache_age",
+ (PyCFunction)Repo_cache_age,
+ METH_VARARGS,
+ NULL
+ },
+ {
+ "cache_exists",
+ (PyCFunction)Repo_cache_exists,
+ METH_VARARGS,
+ NULL
+ },
+ {
+ "cache_open",
+ (PyCFunction)Repo_cache_open,
+ METH_VARARGS,
+ NULL
+ },
+ {
+ "cache_path",
+ (PyCFunction)Repo_cache_path,
+ METH_VARARGS,
+ NULL
+ },
+ {
+ "read_solv",
+ (PyCFunction)Repo_read_solv,
+ METH_VARARGS,
+ NULL
+ },
+ {
+ "write_solv",
+ (PyCFunction)Repo_write_solv,
+ METH_VARARGS,
+ NULL
+ },
+ {
+ "_add_package",
+ (PyCFunction)Repo__add_package,
+ METH_VARARGS,
+ NULL
+ },
+ { NULL }
+};
+
+static struct PyGetSetDef Repo_getsetters[] = {
+ {
+ "name",
+ (getter)Repo_get_name,
+ (setter)Repo_set_name,
+ "The name of the repository",
+ NULL
+ },
+ {
+ "enabled",
+ (getter)Repo_get_enabled,
+ (setter)Repo_set_enabled,
+ NULL,
+ NULL
+ },
+ {
+ "priority",
+ (getter)Repo_get_priority,
+ (setter)Repo_set_priority,
+ "The priority of the repository",
+ NULL
+ },
+ { NULL }
+};
+
+static PySequenceMethods Repo_sequence = {
+ sq_length: (lenfunc)Repo_len,
+};
+
+PyTypeObject RepoType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ tp_name: "_pakfire.Repo",
+ tp_basicsize: sizeof(RepoObject),
+ tp_flags: Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
+ tp_new: Repo_new,
+ tp_dealloc: (destructor)Repo_dealloc,
+ tp_init: (initproc)Repo_init,
+ tp_doc: "Repo object",
+ tp_methods: Repo_methods,
+ tp_getset: Repo_getsetters,
+ tp_as_sequence: &Repo_sequence,
+ tp_hash: (hashfunc)Repo_hash,
+ tp_richcompare: (richcmpfunc)Repo_richcompare,
+};
+++ /dev/null
-#!/usr/bin/python
-###############################################################################
-# #
-# Pakfire - The IPFire package management system #
-# Copyright (C) 2011 Pakfire development team #
-# #
-# 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 3 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, see <http://www.gnu.org/licenses/>. #
-# #
-###############################################################################
-
-import os
-
-import logging
-log = logging.getLogger("pakfire")
-
-from .. import packages
-
-class Index(object):
- """
- Wraps around the solvable index in the memory.
- """
-
- def __init__(self, pakfire, repo):
- self.pakfire = pakfire
-
- # Create reference to repository and the solver repo.
- self.repo = repo
- self.solver_repo = repo.solver_repo
-
- def __repr__(self):
- return "<%s %s>" % (self.__class__.__name__, self.repo)
-
- def __del__(self):
- self.clear()
-
- def read(self, filename):
- """
- Read file in SOLV format from filename.
- """
- self.solver_repo.read(filename)
-
- def write(self, filename):
- """
- Write content to filename in SOLV format.
- """
- self.solver_repo.write(filename)
-
- def optimize(self):
- """
- Optimize the index.
- """
- self.solver_repo.internalize()
-
- def add_package(self, pkg):
- log.debug("Adding package to index %s: %s" % (self, pkg))
-
- from .. import satsolver
- solvable = satsolver.Solvable(self.solver_repo, pkg.name,
- pkg.friendly_version, pkg.arch)
-
- assert pkg.uuid
- solvable.set_uuid(pkg.uuid)
-
- hash1 = pkg.hash1
- assert hash1
- solvable.set_hash1(hash1)
-
- # Save metadata.
- if pkg.vendor:
- solvable.set_vendor(pkg.vendor)
-
- if pkg.maintainer:
- solvable.set_maintainer(pkg.maintainer)
-
- if pkg.groups:
- solvable.set_groups(" ".join(pkg.groups))
-
- # Save upstream information (summary, description, license, url).
- if pkg.summary:
- solvable.set_summary(pkg.summary)
-
- if pkg.description:
- solvable.set_description(pkg.description)
-
- if pkg.license:
- solvable.set_license(pkg.license)
-
- if pkg.url:
- solvable.set_url(pkg.url)
-
- # Save build information.
- if pkg.build_host:
- solvable.set_buildhost(pkg.build_host)
-
- if pkg.build_time:
- solvable.set_buildtime(pkg.build_time)
-
- # Save filename.
- filename = os.path.basename(pkg.filename)
- assert filename
- solvable.set_filename(filename)
-
- solvable.set_downloadsize(pkg.size)
- solvable.set_installsize(pkg.inst_size)
-
- # Import all requires.
- requires = pkg.requires
- prerequires = pkg.prerequires
- if prerequires:
- requires.append("solvable:prereqmarker")
- requires += prerequires
-
- for req in requires:
- rel = self.pakfire.pool.create_relation(req)
- solvable.add_requires(rel)
-
- # Import all provides.
- for prov in pkg.provides:
- rel = self.pakfire.pool.create_relation(prov)
- solvable.add_provides(rel)
-
- # Import all conflicts.
- for conf in pkg.conflicts:
- rel = self.pakfire.pool.create_relation(conf)
- solvable.add_conflicts(rel)
-
- # Import all obsoletes.
- for obso in pkg.obsoletes:
- rel = self.pakfire.pool.create_relation(obso)
- solvable.add_obsoletes(rel)
-
- # Import all files that are in the package.
- rel = self.pakfire.pool.create_relation("solvable:filemarker")
- solvable.add_provides(rel)
- for file in pkg.filelist:
- rel = self.pakfire.pool.create_relation(file)
- solvable.add_provides(rel)
-
- # Import all recommends.
- for reco in pkg.recommends:
- rel = self.pakfire.pool.create_relation(reco)
- solvable.add_recommends(rel)
-
- # Import all suggests.
- for sugg in pkg.suggests:
- rel = self.pakfire.pool.create_relation(sugg)
- solvable.add_suggests(rel)
-
- def clear(self):
- """
- Forget all packages from memory.
- """
- self.solver_repo.clear()