]> git.ipfire.org Git - people/ms/libloc.git/blame - src/python/writer.c
importer: Drop EDROP as it has been merged into DROP
[people/ms/libloc.git] / src / python / writer.c
CommitLineData
d688e569
MT
1/*
2 libloc - A library to determine the location of someone on the Internet
3
4 Copyright (C) 2017 IPFire Development Team <info@ipfire.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library 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 GNU
14 Lesser General Public License for more details.
15*/
16
17#include <Python.h>
18
c12a1385
MT
19#include <libloc/libloc.h>
20#include <libloc/writer.h>
d688e569
MT
21
22#include "locationmodule.h"
f8710bd6 23#include "as.h"
af208e26 24#include "country.h"
a92adad3 25#include "network.h"
d688e569
MT
26#include "writer.h"
27
28static PyObject* Writer_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
29 WriterObject* self = (WriterObject*)type->tp_alloc(type, 0);
30
31 return (PyObject*)self;
32}
33
34static void Writer_dealloc(WriterObject* self) {
35 if (self->writer)
36 loc_writer_unref(self->writer);
37
38 Py_TYPE(self)->tp_free((PyObject* )self);
39}
40
41static int Writer_init(WriterObject* self, PyObject* args, PyObject* kwargs) {
1164d876
MT
42 PyObject* private_key1 = NULL;
43 PyObject* private_key2 = NULL;
44 FILE* f1 = NULL;
45 FILE* f2 = NULL;
46 int fd;
726f9984
MT
47
48 // Parse arguments
1164d876 49 if (!PyArg_ParseTuple(args, "|OO", &private_key1, &private_key2))
d688e569
MT
50 return -1;
51
1164d876
MT
52 // Ignore None
53 if (private_key1 == Py_None) {
54 Py_DECREF(private_key1);
55 private_key1 = NULL;
56 }
57
58 if (private_key2 == Py_None) {
59 Py_DECREF(private_key2);
60 private_key2 = NULL;
61 }
62
726f9984 63 // Convert into FILE*
1164d876
MT
64 if (private_key1) {
65 fd = PyObject_AsFileDescriptor(private_key1);
726f9984
MT
66 if (fd < 0)
67 return -1;
68
69 // Re-open file descriptor
d31a0aef
MT
70 f1 = fdopen(fd, "r");
71 if (!f1) {
726f9984
MT
72 PyErr_SetFromErrno(PyExc_IOError);
73 return -1;
74 }
75 }
76
1164d876
MT
77 if (private_key2) {
78 fd = PyObject_AsFileDescriptor(private_key2);
79 if (fd < 0)
80 return -1;
726f9984 81
1164d876
MT
82 // Re-open file descriptor
83 f2 = fdopen(fd, "r");
84 if (!f2) {
85 PyErr_SetFromErrno(PyExc_IOError);
86 return -1;
87 }
88 }
89
90 // Create the writer object
91 return loc_writer_new(loc_ctx, &self->writer, f1, f2);
d688e569
MT
92}
93
94static PyObject* Writer_get_vendor(WriterObject* self) {
95 const char* vendor = loc_writer_get_vendor(self->writer);
96
97 return PyUnicode_FromString(vendor);
98}
99
360ae5ad
MT
100static int Writer_set_vendor(WriterObject* self, PyObject* value) {
101 const char* vendor = PyUnicode_AsUTF8(value);
d688e569
MT
102
103 int r = loc_writer_set_vendor(self->writer, vendor);
104 if (r) {
105 PyErr_Format(PyExc_ValueError, "Could not set vendor: %s", vendor);
106 return r;
107 }
108
109 return 0;
110}
111
9224f7ba
MT
112static PyObject* Writer_get_description(WriterObject* self) {
113 const char* description = loc_writer_get_description(self->writer);
114
115 return PyUnicode_FromString(description);
116}
117
118static int Writer_set_description(WriterObject* self, PyObject* value) {
119 const char* description = PyUnicode_AsUTF8(value);
120
121 int r = loc_writer_set_description(self->writer, description);
122 if (r) {
123 PyErr_Format(PyExc_ValueError, "Could not set description: %s", description);
124 return r;
125 }
126
127 return 0;
128}
129
4bf49d00
MT
130static PyObject* Writer_get_license(WriterObject* self) {
131 const char* license = loc_writer_get_license(self->writer);
132
133 return PyUnicode_FromString(license);
134}
135
136static int Writer_set_license(WriterObject* self, PyObject* value) {
137 const char* license = PyUnicode_AsUTF8(value);
138
139 int r = loc_writer_set_license(self->writer, license);
140 if (r) {
141 PyErr_Format(PyExc_ValueError, "Could not set license: %s", license);
142 return r;
143 }
144
145 return 0;
146}
147
f8710bd6
MT
148static PyObject* Writer_add_as(WriterObject* self, PyObject* args) {
149 struct loc_as* as;
150 uint32_t number = 0;
151
152 if (!PyArg_ParseTuple(args, "i", &number))
153 return NULL;
154
155 // Create AS object
156 int r = loc_writer_add_as(self->writer, &as, number);
157 if (r)
158 return NULL;
159
160 PyObject* obj = new_as(&ASType, as);
161 loc_as_unref(as);
162
163 return obj;
164}
165
af208e26
MT
166static PyObject* Writer_add_country(WriterObject* self, PyObject* args) {
167 struct loc_country* country;
168 const char* country_code;
169
170 if (!PyArg_ParseTuple(args, "s", &country_code))
171 return NULL;
172
173 // Create country object
174 int r = loc_writer_add_country(self->writer, &country, country_code);
175 if (r) {
176 switch (r) {
177 case -EINVAL:
178 PyErr_SetString(PyExc_ValueError, "Invalid network");
179 break;
180
181 default:
182 return NULL;
183 }
184 }
185
186 PyObject* obj = new_country(&CountryType, country);
187 loc_country_unref(country);
188
189 return obj;
190}
191
a92adad3
MT
192static PyObject* Writer_add_network(WriterObject* self, PyObject* args) {
193 struct loc_network* network;
194 const char* string = NULL;
195
196 if (!PyArg_ParseTuple(args, "s", &string))
197 return NULL;
198
199 // Create network object
200 int r = loc_writer_add_network(self->writer, &network, string);
dafdb6c8 201 if (r) {
c04005bb
MT
202 switch (r) {
203 case -EINVAL:
204 PyErr_SetString(PyExc_ValueError, "Invalid network");
205 break;
206
207 case -EBUSY:
208 PyErr_SetString(PyExc_IndexError, "A network already exists here");
209 break;
210 }
dafdb6c8 211
a92adad3 212 return NULL;
dafdb6c8 213 }
a92adad3
MT
214
215 PyObject* obj = new_network(&NetworkType, network);
216 loc_network_unref(network);
217
218 return obj;
219}
220
7d278671
MT
221static PyObject* Writer_write(WriterObject* self, PyObject* args) {
222 const char* path = NULL;
22c7b98b 223 int version = LOC_DATABASE_VERSION_UNSET;
7d278671 224
22c7b98b 225 if (!PyArg_ParseTuple(args, "s|i", &path, &version))
7d278671
MT
226 return NULL;
227
726f9984 228 FILE* f = fopen(path, "w+");
7d278671 229 if (!f) {
6cd02f1d 230 PyErr_SetFromErrno(PyExc_OSError);
7d278671
MT
231 return NULL;
232 }
233
22c7b98b 234 int r = loc_writer_write(self->writer, f, (enum loc_database_version)version);
7d278671
MT
235 fclose(f);
236
237 // Raise any errors
238 if (r) {
6cd02f1d 239 PyErr_SetFromErrno(PyExc_OSError);
7d278671
MT
240 return NULL;
241 }
242
243 Py_RETURN_NONE;
244}
245
246static struct PyMethodDef Writer_methods[] = {
f8710bd6
MT
247 {
248 "add_as",
249 (PyCFunction)Writer_add_as,
250 METH_VARARGS,
251 NULL,
252 },
a92adad3 253 {
af208e26
MT
254 "add_country",
255 (PyCFunction)Writer_add_country,
256 METH_VARARGS,
257 NULL,
258 },
259 {
a92adad3
MT
260 "add_network",
261 (PyCFunction)Writer_add_network,
262 METH_VARARGS,
263 NULL,
264 },
7d278671
MT
265 {
266 "write",
267 (PyCFunction)Writer_write,
268 METH_VARARGS,
269 NULL,
270 },
271 { NULL },
272};
273
d688e569 274static struct PyGetSetDef Writer_getsetters[] = {
9224f7ba
MT
275 {
276 "description",
277 (getter)Writer_get_description,
278 (setter)Writer_set_description,
279 NULL,
280 NULL,
281 },
4bf49d00
MT
282 {
283 "license",
284 (getter)Writer_get_license,
285 (setter)Writer_set_license,
286 NULL,
287 NULL,
288 },
d688e569
MT
289 {
290 "vendor",
291 (getter)Writer_get_vendor,
292 (setter)Writer_set_vendor,
293 NULL,
294 NULL,
295 },
296 { NULL },
297};
298
299PyTypeObject WriterType = {
300 PyVarObject_HEAD_INIT(NULL, 0)
d42e1dcd
MT
301 .tp_name = "location.Writer",
302 .tp_basicsize = sizeof(WriterObject),
303 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
304 .tp_new = Writer_new,
305 .tp_dealloc = (destructor)Writer_dealloc,
306 .tp_init = (initproc)Writer_init,
307 .tp_doc = "Writer object",
308 .tp_methods = Writer_methods,
309 .tp_getset = Writer_getsetters,
d688e569 310};