]>
Commit | Line | Data |
---|---|---|
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 |
31 | PyObject* 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 |
40 | static 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 | 49 | static 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 | 55 | static 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 |
68 | static long Repo_hash(RepoObject* self) { |
69 | return (long)self->repo; | |
70 | } | |
4069d10c | 71 | |
a0385c3a MT |
72 | static 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 |
98 | static Py_ssize_t Repo_len(RepoObject* self) { |
99 | return pakfire_repo_count(self->repo); | |
100 | } | |
c605d735 | 101 | |
a0385c3a MT |
102 | static 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 |
108 | static 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 |
115 | static PyObject* Repo_get_description(RepoObject* self) { |
116 | const char* description = pakfire_repo_get_description(self->repo); | |
117 | ||
118 | return PyUnicode_FromString(description); | |
119 | } | |
120 | ||
121 | static 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 |
130 | static 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 |
137 | static 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 |
146 | static 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 |
152 | static 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 |
162 | static PyObject* Repo_get_baseurl(RepoObject* self) { |
163 | const char* baseurl = pakfire_repo_get_baseurl(self->repo); | |
164 | ||
165 | return PyUnicode_FromString(baseurl); | |
166 | } | |
167 | ||
168 | static 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 |
177 | static PyObject* Repo_get_keyfile(RepoObject* self) { |
178 | const char* keyfile = pakfire_repo_get_keyfile(self->repo); | |
179 | ||
180 | return PyUnicode_FromString(keyfile); | |
181 | } | |
182 | ||
183 | static 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 |
192 | static PyObject* Repo_get_mirrorlist(RepoObject* self) { |
193 | const char* mirrorlist = pakfire_repo_get_mirrorlist(self->repo); | |
194 | ||
195 | return PyUnicode_FromString(mirrorlist); | |
196 | } | |
197 | ||
198 | static 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 |
207 | static 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 |
220 | static 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 |
258 | static 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 | ||
283 | static 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 | 302 | static 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 | 315 | static 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 | ||
328 | static 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 | ||
345 | static 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 |
359 | static 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 |
370 | static 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 | ||
428 | static 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 | ||
481 | static PySequenceMethods Repo_sequence = { | |
482 | sq_length: (lenfunc)Repo_len, | |
483 | }; | |
484 | ||
485 | PyTypeObject 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 | }; |