]> git.ipfire.org Git - people/ms/libloc.git/blame - src/python/writer.c
writer: Throw better exception when network address was invalid
[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"
a92adad3 24#include "network.h"
d688e569
MT
25#include "writer.h"
26
27static PyObject* Writer_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
28 WriterObject* self = (WriterObject*)type->tp_alloc(type, 0);
29
30 return (PyObject*)self;
31}
32
33static void Writer_dealloc(WriterObject* self) {
34 if (self->writer)
35 loc_writer_unref(self->writer);
36
37 Py_TYPE(self)->tp_free((PyObject* )self);
38}
39
40static int Writer_init(WriterObject* self, PyObject* args, PyObject* kwargs) {
41 // Create the writer object
42 int r = loc_writer_new(loc_ctx, &self->writer);
43 if (r)
44 return -1;
45
46 return 0;
47}
48
49static PyObject* Writer_get_vendor(WriterObject* self) {
50 const char* vendor = loc_writer_get_vendor(self->writer);
51
52 return PyUnicode_FromString(vendor);
53}
54
360ae5ad
MT
55static int Writer_set_vendor(WriterObject* self, PyObject* value) {
56 const char* vendor = PyUnicode_AsUTF8(value);
d688e569
MT
57
58 int r = loc_writer_set_vendor(self->writer, vendor);
59 if (r) {
60 PyErr_Format(PyExc_ValueError, "Could not set vendor: %s", vendor);
61 return r;
62 }
63
64 return 0;
65}
66
9224f7ba
MT
67static PyObject* Writer_get_description(WriterObject* self) {
68 const char* description = loc_writer_get_description(self->writer);
69
70 return PyUnicode_FromString(description);
71}
72
73static int Writer_set_description(WriterObject* self, PyObject* value) {
74 const char* description = PyUnicode_AsUTF8(value);
75
76 int r = loc_writer_set_description(self->writer, description);
77 if (r) {
78 PyErr_Format(PyExc_ValueError, "Could not set description: %s", description);
79 return r;
80 }
81
82 return 0;
83}
84
4bf49d00
MT
85static PyObject* Writer_get_license(WriterObject* self) {
86 const char* license = loc_writer_get_license(self->writer);
87
88 return PyUnicode_FromString(license);
89}
90
91static int Writer_set_license(WriterObject* self, PyObject* value) {
92 const char* license = PyUnicode_AsUTF8(value);
93
94 int r = loc_writer_set_license(self->writer, license);
95 if (r) {
96 PyErr_Format(PyExc_ValueError, "Could not set license: %s", license);
97 return r;
98 }
99
100 return 0;
101}
102
f8710bd6
MT
103static PyObject* Writer_add_as(WriterObject* self, PyObject* args) {
104 struct loc_as* as;
105 uint32_t number = 0;
106
107 if (!PyArg_ParseTuple(args, "i", &number))
108 return NULL;
109
110 // Create AS object
111 int r = loc_writer_add_as(self->writer, &as, number);
112 if (r)
113 return NULL;
114
115 PyObject* obj = new_as(&ASType, as);
116 loc_as_unref(as);
117
118 return obj;
119}
120
a92adad3
MT
121static PyObject* Writer_add_network(WriterObject* self, PyObject* args) {
122 struct loc_network* network;
123 const char* string = NULL;
124
125 if (!PyArg_ParseTuple(args, "s", &string))
126 return NULL;
127
128 // Create network object
129 int r = loc_writer_add_network(self->writer, &network, string);
dafdb6c8
MT
130 if (r) {
131 if (r == -EINVAL)
132 PyErr_SetString(PyExc_ValueError, "Invalid network");
133
a92adad3 134 return NULL;
dafdb6c8 135 }
a92adad3
MT
136
137 PyObject* obj = new_network(&NetworkType, network);
138 loc_network_unref(network);
139
140 return obj;
141}
142
7d278671
MT
143static PyObject* Writer_write(WriterObject* self, PyObject* args) {
144 const char* path = NULL;
145
146 if (!PyArg_ParseTuple(args, "s", &path))
147 return NULL;
148
149 FILE* f = fopen(path, "w");
150 if (!f) {
151 PyErr_Format(PyExc_IOError, strerror(errno));
152 return NULL;
153 }
154
155 int r = loc_writer_write(self->writer, f);
156 fclose(f);
157
158 // Raise any errors
159 if (r) {
160 PyErr_Format(PyExc_IOError, strerror(errno));
161 return NULL;
162 }
163
164 Py_RETURN_NONE;
165}
166
167static struct PyMethodDef Writer_methods[] = {
f8710bd6
MT
168 {
169 "add_as",
170 (PyCFunction)Writer_add_as,
171 METH_VARARGS,
172 NULL,
173 },
a92adad3
MT
174 {
175 "add_network",
176 (PyCFunction)Writer_add_network,
177 METH_VARARGS,
178 NULL,
179 },
7d278671
MT
180 {
181 "write",
182 (PyCFunction)Writer_write,
183 METH_VARARGS,
184 NULL,
185 },
186 { NULL },
187};
188
d688e569 189static struct PyGetSetDef Writer_getsetters[] = {
9224f7ba
MT
190 {
191 "description",
192 (getter)Writer_get_description,
193 (setter)Writer_set_description,
194 NULL,
195 NULL,
196 },
4bf49d00
MT
197 {
198 "license",
199 (getter)Writer_get_license,
200 (setter)Writer_set_license,
201 NULL,
202 NULL,
203 },
d688e569
MT
204 {
205 "vendor",
206 (getter)Writer_get_vendor,
207 (setter)Writer_set_vendor,
208 NULL,
209 NULL,
210 },
211 { NULL },
212};
213
214PyTypeObject WriterType = {
215 PyVarObject_HEAD_INIT(NULL, 0)
216 tp_name: "location.Writer",
217 tp_basicsize: sizeof(WriterObject),
218 tp_flags: Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
219 tp_new: Writer_new,
220 tp_dealloc: (destructor)Writer_dealloc,
221 tp_init: (initproc)Writer_init,
222 tp_doc: "Writer object",
7d278671 223 tp_methods: Writer_methods,
d688e569
MT
224 tp_getset: Writer_getsetters,
225};