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