]> git.ipfire.org Git - people/ms/libloc.git/blame - src/python/writer.c
Fix reading database in newer version
[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
19#include <loc/libloc.h>
20#include <loc/writer.h>
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) {
726f9984
MT
42 PyObject* private_key = NULL;
43 FILE* f = NULL;
44
45 // Parse arguments
22c7b98b 46 if (!PyArg_ParseTuple(args, "|O", &private_key))
d688e569
MT
47 return -1;
48
726f9984 49 // Convert into FILE*
bfa9a0d1 50 if (private_key && private_key != Py_None) {
726f9984
MT
51 int fd = PyObject_AsFileDescriptor(private_key);
52 if (fd < 0)
53 return -1;
54
55 // Re-open file descriptor
56 f = fdopen(fd, "r");
57 if (!f) {
58 PyErr_SetFromErrno(PyExc_IOError);
59 return -1;
60 }
61 }
62
63 // Create the writer object
22c7b98b 64 int r = loc_writer_new(loc_ctx, &self->writer, f);
726f9984
MT
65
66 return r;
d688e569
MT
67}
68
69static PyObject* Writer_get_vendor(WriterObject* self) {
70 const char* vendor = loc_writer_get_vendor(self->writer);
71
72 return PyUnicode_FromString(vendor);
73}
74
360ae5ad
MT
75static int Writer_set_vendor(WriterObject* self, PyObject* value) {
76 const char* vendor = PyUnicode_AsUTF8(value);
d688e569
MT
77
78 int r = loc_writer_set_vendor(self->writer, vendor);
79 if (r) {
80 PyErr_Format(PyExc_ValueError, "Could not set vendor: %s", vendor);
81 return r;
82 }
83
84 return 0;
85}
86
9224f7ba
MT
87static PyObject* Writer_get_description(WriterObject* self) {
88 const char* description = loc_writer_get_description(self->writer);
89
90 return PyUnicode_FromString(description);
91}
92
93static int Writer_set_description(WriterObject* self, PyObject* value) {
94 const char* description = PyUnicode_AsUTF8(value);
95
96 int r = loc_writer_set_description(self->writer, description);
97 if (r) {
98 PyErr_Format(PyExc_ValueError, "Could not set description: %s", description);
99 return r;
100 }
101
102 return 0;
103}
104
4bf49d00
MT
105static PyObject* Writer_get_license(WriterObject* self) {
106 const char* license = loc_writer_get_license(self->writer);
107
108 return PyUnicode_FromString(license);
109}
110
111static int Writer_set_license(WriterObject* self, PyObject* value) {
112 const char* license = PyUnicode_AsUTF8(value);
113
114 int r = loc_writer_set_license(self->writer, license);
115 if (r) {
116 PyErr_Format(PyExc_ValueError, "Could not set license: %s", license);
117 return r;
118 }
119
120 return 0;
121}
122
f8710bd6
MT
123static PyObject* Writer_add_as(WriterObject* self, PyObject* args) {
124 struct loc_as* as;
125 uint32_t number = 0;
126
127 if (!PyArg_ParseTuple(args, "i", &number))
128 return NULL;
129
130 // Create AS object
131 int r = loc_writer_add_as(self->writer, &as, number);
132 if (r)
133 return NULL;
134
135 PyObject* obj = new_as(&ASType, as);
136 loc_as_unref(as);
137
138 return obj;
139}
140
af208e26
MT
141static PyObject* Writer_add_country(WriterObject* self, PyObject* args) {
142 struct loc_country* country;
143 const char* country_code;
144
145 if (!PyArg_ParseTuple(args, "s", &country_code))
146 return NULL;
147
148 // Create country object
149 int r = loc_writer_add_country(self->writer, &country, country_code);
150 if (r) {
151 switch (r) {
152 case -EINVAL:
153 PyErr_SetString(PyExc_ValueError, "Invalid network");
154 break;
155
156 default:
157 return NULL;
158 }
159 }
160
161 PyObject* obj = new_country(&CountryType, country);
162 loc_country_unref(country);
163
164 return obj;
165}
166
a92adad3
MT
167static PyObject* Writer_add_network(WriterObject* self, PyObject* args) {
168 struct loc_network* network;
169 const char* string = NULL;
170
171 if (!PyArg_ParseTuple(args, "s", &string))
172 return NULL;
173
174 // Create network object
175 int r = loc_writer_add_network(self->writer, &network, string);
dafdb6c8 176 if (r) {
c04005bb
MT
177 switch (r) {
178 case -EINVAL:
179 PyErr_SetString(PyExc_ValueError, "Invalid network");
180 break;
181
182 case -EBUSY:
183 PyErr_SetString(PyExc_IndexError, "A network already exists here");
184 break;
185 }
dafdb6c8 186
a92adad3 187 return NULL;
dafdb6c8 188 }
a92adad3
MT
189
190 PyObject* obj = new_network(&NetworkType, network);
191 loc_network_unref(network);
192
193 return obj;
194}
195
7d278671
MT
196static PyObject* Writer_write(WriterObject* self, PyObject* args) {
197 const char* path = NULL;
22c7b98b 198 int version = LOC_DATABASE_VERSION_UNSET;
7d278671 199
22c7b98b 200 if (!PyArg_ParseTuple(args, "s|i", &path, &version))
7d278671
MT
201 return NULL;
202
726f9984 203 FILE* f = fopen(path, "w+");
7d278671
MT
204 if (!f) {
205 PyErr_Format(PyExc_IOError, strerror(errno));
206 return NULL;
207 }
208
22c7b98b 209 int r = loc_writer_write(self->writer, f, (enum loc_database_version)version);
7d278671
MT
210 fclose(f);
211
212 // Raise any errors
213 if (r) {
214 PyErr_Format(PyExc_IOError, strerror(errno));
215 return NULL;
216 }
217
218 Py_RETURN_NONE;
219}
220
221static struct PyMethodDef Writer_methods[] = {
f8710bd6
MT
222 {
223 "add_as",
224 (PyCFunction)Writer_add_as,
225 METH_VARARGS,
226 NULL,
227 },
a92adad3 228 {
af208e26
MT
229 "add_country",
230 (PyCFunction)Writer_add_country,
231 METH_VARARGS,
232 NULL,
233 },
234 {
a92adad3
MT
235 "add_network",
236 (PyCFunction)Writer_add_network,
237 METH_VARARGS,
238 NULL,
239 },
7d278671
MT
240 {
241 "write",
242 (PyCFunction)Writer_write,
243 METH_VARARGS,
244 NULL,
245 },
246 { NULL },
247};
248
d688e569 249static struct PyGetSetDef Writer_getsetters[] = {
9224f7ba
MT
250 {
251 "description",
252 (getter)Writer_get_description,
253 (setter)Writer_set_description,
254 NULL,
255 NULL,
256 },
4bf49d00
MT
257 {
258 "license",
259 (getter)Writer_get_license,
260 (setter)Writer_set_license,
261 NULL,
262 NULL,
263 },
d688e569
MT
264 {
265 "vendor",
266 (getter)Writer_get_vendor,
267 (setter)Writer_set_vendor,
268 NULL,
269 NULL,
270 },
271 { NULL },
272};
273
274PyTypeObject WriterType = {
275 PyVarObject_HEAD_INIT(NULL, 0)
d42e1dcd
MT
276 .tp_name = "location.Writer",
277 .tp_basicsize = sizeof(WriterObject),
278 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
279 .tp_new = Writer_new,
280 .tp_dealloc = (destructor)Writer_dealloc,
281 .tp_init = (initproc)Writer_init,
282 .tp_doc = "Writer object",
283 .tp_methods = Writer_methods,
284 .tp_getset = Writer_getsetters,
d688e569 285};