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