]> git.ipfire.org Git - pakfire.git/blame - src/_pakfire/repo.c
libpakfire: Store description with repository
[pakfire.git] / src / _pakfire / repo.c
CommitLineData
b792d887
MT
1/*#############################################################################
2# #
3# Pakfire - The IPFire package management system #
4# Copyright (C) 2011 Pakfire development team #
5# #
6# This program is free software: you can redistribute it and/or modify #
7# it under the terms of the GNU General Public License as published by #
8# the Free Software Foundation, either version 3 of the License, or #
9# (at your option) any later version. #
10# #
11# This program is distributed in the hope that it will be useful, #
12# but WITHOUT ANY WARRANTY; without even the implied warranty of #
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14# GNU General Public License for more details. #
15# #
16# You should have received a copy of the GNU General Public License #
17# along with this program. If not, see <http://www.gnu.org/licenses/>. #
18# #
19#############################################################################*/
c605d735 20
8276111d 21#include <Python.h>
c605d735 22
a0385c3a
MT
23#include <pakfire/errno.h>
24#include <pakfire/package.h>
25#include <pakfire/repo.h>
a0385c3a
MT
26#include <pakfire/util.h>
27
28#include "package.h"
29#include "repo.h"
c605d735 30
8ef6c388
MT
31PyObject* new_repo(PyTypeObject* type, PakfireRepo repo) {
32 RepoObject* self = (RepoObject *)type->tp_alloc(type, 0);
33 if (self) {
34 self->repo = pakfire_repo_ref(repo);
35 }
b8a51cb6 36
8ef6c388 37 return (PyObject*)self;
b8a51cb6
MT
38}
39
a0385c3a
MT
40static PyObject* Repo_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
41 RepoObject* self = (RepoObject *)type->tp_alloc(type, 0);
42 if (self) {
a0385c3a
MT
43 self->repo = NULL;
44 }
c605d735 45
a0385c3a
MT
46 return (PyObject *)self;
47}
c605d735 48
a0385c3a 49static void Repo_dealloc(RepoObject* self) {
3ff6aee6 50 pakfire_repo_unref(self->repo);
c605d735 51
a0385c3a
MT
52 Py_TYPE(self)->tp_free((PyObject *)self);
53}
c605d735 54
a0385c3a 55static int Repo_init(RepoObject* self, PyObject* args, PyObject* kwds) {
843fcc66 56 PakfireObject* pakfire;
a0385c3a 57 const char* name;
c605d735 58
843fcc66 59 if (!PyArg_ParseTuple(args, "O!s", &PakfireType, &pakfire, &name))
a0385c3a
MT
60 return -1;
61
6029ca33
MT
62 // Create a new repository
63 self->repo = pakfire_repo_create(pakfire->pakfire, name);
a0385c3a
MT
64
65 return 0;
c605d735
MT
66}
67
a0385c3a
MT
68static long Repo_hash(RepoObject* self) {
69 return (long)self->repo;
70}
4069d10c 71
a0385c3a
MT
72static PyObject* Repo_richcompare(RepoObject* self, RepoObject* other, int op) {
73 int r;
74
75 switch (op) {
76 case Py_EQ:
77 if (pakfire_repo_identical(self->repo, other->repo) == 0)
78 Py_RETURN_TRUE;
79
80 Py_RETURN_FALSE;
81 break;
82
83 case Py_LT:
84 r = pakfire_repo_cmp(self->repo, other->repo);
85 if (r < 0)
86 Py_RETURN_TRUE;
87
88 Py_RETURN_FALSE;
89 break;
90
91 default:
92 break;
93 }
94
95 Py_RETURN_NOTIMPLEMENTED;
c605d735
MT
96}
97
a0385c3a
MT
98static Py_ssize_t Repo_len(RepoObject* self) {
99 return pakfire_repo_count(self->repo);
100}
c605d735 101
a0385c3a
MT
102static PyObject* Repo_get_name(RepoObject* self) {
103 const char* name = pakfire_repo_get_name(self->repo);
104
105 return PyUnicode_FromString(name);
c605d735
MT
106}
107
a0385c3a
MT
108static int Repo_set_name(RepoObject* self, PyObject* value) {
109 const char* name = PyUnicode_AsUTF8(value);
c605d735 110
a0385c3a
MT
111 pakfire_repo_set_name(self->repo, name);
112 return 0;
c605d735
MT
113}
114
36641775
MT
115static PyObject* Repo_get_description(RepoObject* self) {
116 const char* description = pakfire_repo_get_description(self->repo);
117
118 return PyUnicode_FromString(description);
119}
120
121static int Repo_set_description(RepoObject* self, PyObject* value) {
122 const char* description = NULL;
123
124 if (value != Py_None)
125 description = PyUnicode_AsUTF8(value);
126
127 return pakfire_repo_set_description(self->repo, description);
128}
129
a0385c3a
MT
130static PyObject* Repo_get_enabled(RepoObject* self) {
131 if (pakfire_repo_get_enabled(self->repo))
c605d735 132 Py_RETURN_TRUE;
c605d735
MT
133
134 Py_RETURN_FALSE;
135}
136
a0385c3a
MT
137static int Repo_set_enabled(RepoObject* self, PyObject* value) {
138 if (PyObject_IsTrue(value))
139 pakfire_repo_set_enabled(self->repo, 1);
140 else
141 pakfire_repo_set_enabled(self->repo, 0);
c605d735 142
a0385c3a
MT
143 return 0;
144}
c605d735 145
a0385c3a
MT
146static PyObject* Repo_get_priority(RepoObject* self) {
147 int priority = pakfire_repo_get_priority(self->repo);
c605d735 148
a0385c3a 149 return PyLong_FromLong(priority);
c605d735
MT
150}
151
a0385c3a
MT
152static int Repo_set_priority(RepoObject* self, PyObject* value) {
153 long priority = PyLong_AsLong(value);
154
155 if (priority > INT_MAX || priority < INT_MIN)
156 return -1;
157
158 pakfire_repo_set_priority(self->repo, priority);
159 return 0;
a7cd7a38
MT
160}
161
7b576a96
MT
162static PyObject* Repo_get_baseurl(RepoObject* self) {
163 const char* baseurl = pakfire_repo_get_baseurl(self->repo);
164
165 return PyUnicode_FromString(baseurl);
166}
167
168static int Repo_set_baseurl(RepoObject* self, PyObject* value) {
e3f9117f
MT
169 const char* baseurl = NULL;
170
171 if (value != Py_None)
172 baseurl = PyUnicode_AsUTF8(value);
7b576a96
MT
173
174 return pakfire_repo_set_baseurl(self->repo, baseurl);
175}
176
1415a20b
MT
177static PyObject* Repo_get_keyfile(RepoObject* self) {
178 const char* keyfile = pakfire_repo_get_keyfile(self->repo);
179
180 return PyUnicode_FromString(keyfile);
181}
182
183static int Repo_set_keyfile(RepoObject* self, PyObject* value) {
184 const char* keyfile = NULL;
185
186 if (value != Py_None)
187 keyfile = PyUnicode_AsUTF8(value);
188
189 return pakfire_repo_set_keyfile(self->repo, keyfile);
190}
191
e6fb5c61
MT
192static PyObject* Repo_get_mirrorlist(RepoObject* self) {
193 const char* mirrorlist = pakfire_repo_get_mirrorlist(self->repo);
194
195 return PyUnicode_FromString(mirrorlist);
196}
197
198static int Repo_set_mirrorlist(RepoObject* self, PyObject* value) {
199 const char* mirrorlist = NULL;
200
201 if (value != Py_None)
202 mirrorlist = PyUnicode_AsUTF8(value);
203
204 return pakfire_repo_set_mirrorlist(self->repo, mirrorlist);
205}
206
8e163f76
MT
207static PyObject* Repo_get_config(RepoObject* self) {
208 char* config = pakfire_repo_get_config(self->repo);
209
210 if (config) {
211 PyObject* obj = PyUnicode_FromString(config);
212 pakfire_free(config);
213
214 return obj;
215 }
216
217 Py_RETURN_NONE;
218}
219
a0385c3a
MT
220static PyObject* Repo_read_solv(RepoObject* self, PyObject* args) {
221 const char* filename = NULL;
a7cd7a38 222
a0385c3a 223 if (!PyArg_ParseTuple(args, "s", &filename))
a7cd7a38 224 return NULL;
a7cd7a38 225
a0385c3a
MT
226 int ret = pakfire_repo_read_solv(self->repo, filename, 0);
227
228 switch (ret) {
229 case 0:
230 Py_RETURN_NONE;
231 break;
232
1230da7d
MT
233 case PAKFIRE_E_SOLV_NOT_SOLV:
234 PyErr_Format(PyExc_ValueError, "File not in SOLV format: %s", filename);
235 break;
236
237 case PAKFIRE_E_SOLV_UNSUPPORTED:
238 PyErr_Format(PyExc_ValueError, "File in an unsupported version"
239 " of the SOLV format: %s", filename);
240 break;
241
242 case PAKFIRE_E_SOLV_CORRUPTED:
243 PyErr_Format(PyExc_ValueError, "SOLV file is corrupted: %s", filename);
244 break;
245
a0385c3a 246 case PAKFIRE_E_IO:
1230da7d 247 PyErr_Format(PyExc_IOError, "Could not read file %s: %s", filename, strerror(errno));
a0385c3a 248 break;
a7cd7a38 249
a0385c3a 250 default:
1230da7d 251 PyErr_Format(PyExc_RuntimeError, "pakfire_repo_read() failed: %s", ret);
a0385c3a
MT
252 break;
253 }
254
255 return NULL;
a7cd7a38
MT
256}
257
a0385c3a
MT
258static PyObject* Repo_write_solv(RepoObject* self, PyObject* args) {
259 const char* filename = NULL;
c605d735 260
a0385c3a 261 if (!PyArg_ParseTuple(args, "s", &filename))
9b68f47c 262 return NULL;
a0385c3a
MT
263
264 int ret = pakfire_repo_write_solv(self->repo, filename, 0);
265
266 switch (ret) {
267 case 0:
268 Py_RETURN_NONE;
269 break;
270
271 case PAKFIRE_E_IO:
272 PyErr_Format(PyExc_IOError, "Could not open file %s", filename);
273 break;
274
275 default:
276 PyErr_Format(PyExc_RuntimeError, "pakfire_repo_write() failed: %d", ret);
277 break;
c605d735
MT
278 }
279
a0385c3a
MT
280 return NULL;
281}
282
283static PyObject* Repo__add_package(RepoObject* self, PyObject* args) {
284 const char* name;
285 const char* evr;
286 const char* arch;
c605d735 287
a0385c3a 288 if (!PyArg_ParseTuple(args, "sss", &name, &evr, &arch))
51b452f0 289 return NULL;
c605d735 290
6029ca33
MT
291 Pakfire pakfire = pakfire_repo_get_pakfire(self->repo);
292 PakfirePackage pkg = pakfire_package_create2(pakfire, self->repo, name, evr, arch);
293
294 PyObject* obj = new_package(&PackageType, pkg);
295
296 pakfire_package_unref(pkg);
297 pakfire_unref(pakfire);
c605d735 298
6029ca33 299 return obj;
c605d735
MT
300}
301
a0385c3a 302static PyObject* Repo_cache_age(RepoObject* self, PyObject* args) {
5ade5e8a 303 const char* path = NULL;
c605d735 304
5ade5e8a 305 if (!PyArg_ParseTuple(args, "s", &path))
9b68f47c 306 return NULL;
c605d735 307
5ade5e8a 308 time_t age = pakfire_repo_cache_age(self->repo, path);
a0385c3a
MT
309 if (age < 0)
310 Py_RETURN_NONE;
d8cfced9 311
5ade5e8a 312 return PyLong_FromLong(age);
d8cfced9
MT
313}
314
a0385c3a 315static PyObject* Repo_cache_exists(RepoObject* self, PyObject* args) {
5ade5e8a 316 const char* path = NULL;
31267a64 317
5ade5e8a 318 if (!PyArg_ParseTuple(args, "s", &path))
a0385c3a 319 return NULL;
8276111d 320
5ade5e8a
MT
321 int r = pakfire_repo_cache_access(self->repo, path, F_OK);
322 if (r == 0)
a0385c3a 323 Py_RETURN_TRUE;
8276111d 324
a0385c3a
MT
325 Py_RETURN_FALSE;
326}
327
328static PyObject* Repo_cache_open(RepoObject* self, PyObject* args) {
5ade5e8a
MT
329 const char* path = NULL;
330 const char* mode = NULL;
a0385c3a 331
5ade5e8a 332 if (!PyArg_ParseTuple(args, "ss", &path, &mode))
a0385c3a 333 return NULL;
8276111d 334
5ade5e8a
MT
335 FILE* f = pakfire_repo_cache_open(self->repo, path, mode);
336 if (!f) {
337 PyErr_Format(PyExc_IOError, "Could not open file %s: %s", path, strerror(errno));
a0385c3a 338 return NULL;
8276111d
MT
339 }
340
a0385c3a 341 // XXX might cause some problems with internal buffering
5ade5e8a 342 return PyFile_FromFd(fileno(f), NULL, mode, 1, NULL, NULL, NULL, 1);
a0385c3a
MT
343}
344
345static PyObject* Repo_cache_path(RepoObject* self, PyObject* args) {
5ade5e8a 346 const char* path = NULL;
a0385c3a 347
5ade5e8a 348 if (!PyArg_ParseTuple(args, "s", &path))
a0385c3a
MT
349 return NULL;
350
5ade5e8a 351 char* cache_path = pakfire_repo_cache_get_path(self->repo, path);
a0385c3a
MT
352
353 PyObject* obj = PyUnicode_FromString(cache_path);
354 pakfire_free(cache_path);
355
356 return obj;
8276111d 357}
a0385c3a 358
b4ac59c6
MT
359static PyObject* Repo_clean(RepoObject* self, PyObject* args) {
360 int r = pakfire_repo_clean(self->repo);
361
362 if (r) {
363 PyErr_SetFromErrno(PyExc_OSError);
364 return NULL;
365 }
366
367 Py_RETURN_NONE;
368}
369
a0385c3a
MT
370static struct PyMethodDef Repo_methods[] = {
371 {
372 "cache_age",
373 (PyCFunction)Repo_cache_age,
374 METH_VARARGS,
375 NULL
376 },
377 {
378 "cache_exists",
379 (PyCFunction)Repo_cache_exists,
380 METH_VARARGS,
381 NULL
382 },
383 {
384 "cache_open",
385 (PyCFunction)Repo_cache_open,
386 METH_VARARGS,
387 NULL
388 },
389 {
390 "cache_path",
391 (PyCFunction)Repo_cache_path,
392 METH_VARARGS,
393 NULL
394 },
b4ac59c6
MT
395 {
396 "clean",
397 (PyCFunction)Repo_clean,
398 METH_VARARGS,
399 NULL,
400 },
8e163f76
MT
401 {
402 "get_config",
403 (PyCFunction)Repo_get_config,
404 METH_NOARGS,
405 NULL,
406 },
a0385c3a
MT
407 {
408 "read_solv",
409 (PyCFunction)Repo_read_solv,
410 METH_VARARGS,
411 NULL
412 },
413 {
414 "write_solv",
415 (PyCFunction)Repo_write_solv,
416 METH_VARARGS,
417 NULL
418 },
419 {
420 "_add_package",
421 (PyCFunction)Repo__add_package,
422 METH_VARARGS,
423 NULL
424 },
425 { NULL }
426};
427
428static struct PyGetSetDef Repo_getsetters[] = {
7b576a96
MT
429 {
430 "baseurl",
431 (getter)Repo_get_baseurl,
432 (setter)Repo_set_baseurl,
433 "The base URL of this repository",
434 NULL
435 },
36641775
MT
436 {
437 "description",
438 (getter)Repo_get_description,
439 (setter)Repo_set_description,
440 NULL,
441 NULL
442 },
1415a20b
MT
443 {
444 "keyfile",
445 (getter)Repo_get_keyfile,
446 (setter)Repo_set_keyfile,
447 NULL,
448 NULL
449 },
e6fb5c61
MT
450 {
451 "mirrorlist",
452 (getter)Repo_get_mirrorlist,
453 (setter)Repo_set_mirrorlist,
454 NULL,
455 NULL
456 },
a0385c3a
MT
457 {
458 "name",
459 (getter)Repo_get_name,
460 (setter)Repo_set_name,
461 "The name of the repository",
462 NULL
463 },
464 {
465 "enabled",
466 (getter)Repo_get_enabled,
467 (setter)Repo_set_enabled,
468 NULL,
469 NULL
470 },
471 {
472 "priority",
473 (getter)Repo_get_priority,
474 (setter)Repo_set_priority,
475 "The priority of the repository",
476 NULL
477 },
478 { NULL }
479};
480
481static PySequenceMethods Repo_sequence = {
482 sq_length: (lenfunc)Repo_len,
483};
484
485PyTypeObject RepoType = {
486 PyVarObject_HEAD_INIT(NULL, 0)
487 tp_name: "_pakfire.Repo",
488 tp_basicsize: sizeof(RepoObject),
489 tp_flags: Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
490 tp_new: Repo_new,
491 tp_dealloc: (destructor)Repo_dealloc,
492 tp_init: (initproc)Repo_init,
493 tp_doc: "Repo object",
494 tp_methods: Repo_methods,
495 tp_getset: Repo_getsetters,
496 tp_as_sequence: &Repo_sequence,
497 tp_hash: (hashfunc)Repo_hash,
498 tp_richcompare: (richcmpfunc)Repo_richcompare,
499};