]> git.ipfire.org Git - people/ms/libloc.git/blob - src/python/database.c
python: Handle error codes when searching for an AS
[people/ms/libloc.git] / src / python / database.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/database.h>
21
22 #include "locationmodule.h"
23 #include "as.h"
24 #include "database.h"
25 #include "network.h"
26
27 static PyObject* Database_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
28 DatabaseObject* self = (DatabaseObject*)type->tp_alloc(type, 0);
29
30 return (PyObject*)self;
31 }
32
33 static void Database_dealloc(DatabaseObject* self) {
34 if (self->db)
35 loc_database_unref(self->db);
36
37 Py_TYPE(self)->tp_free((PyObject* )self);
38 }
39
40 static int Database_init(DatabaseObject* self, PyObject* args, PyObject* kwargs) {
41 const char* path = NULL;
42
43 if (!PyArg_ParseTuple(args, "s", &path))
44 return -1;
45
46 // Open the file for reading
47 FILE* f = fopen(path, "r");
48 if (!f)
49 return -1;
50
51 // Load the database
52 int r = loc_database_new(loc_ctx, &self->db, f);
53 fclose(f);
54
55 // Return on any errors
56 if (r)
57 return -1;
58
59 return 0;
60 }
61
62 static PyObject* Database_get_description(DatabaseObject* self) {
63 const char* description = loc_database_get_description(self->db);
64
65 return PyUnicode_FromString(description);
66 }
67
68 static PyObject* Database_get_vendor(DatabaseObject* self) {
69 const char* vendor = loc_database_get_vendor(self->db);
70
71 return PyUnicode_FromString(vendor);
72 }
73
74 static PyObject* Database_get_created_at(DatabaseObject* self) {
75 time_t created_at = loc_database_created_at(self->db);
76
77 return PyLong_FromLong(created_at);
78 }
79
80 static PyObject* Database_get_as(DatabaseObject* self, PyObject* args) {
81 struct loc_as* as = NULL;
82 uint32_t number = 0;
83
84 if (!PyArg_ParseTuple(args, "i", &number))
85 return NULL;
86
87 // Try to retrieve the AS
88 int r = loc_database_get_as(self->db, &as, number);
89
90 // We got an AS
91 if (r == 0) {
92 PyObject* obj = new_as(&ASType, as);
93 loc_as_unref(as);
94
95 return obj;
96
97 // Nothing found
98 } else if (r == 1) {
99 Py_RETURN_NONE;
100 }
101
102 // Unexpected error
103 return NULL;
104 }
105
106 static PyObject* Database_lookup(DatabaseObject* self, PyObject* args) {
107 struct loc_network* network = NULL;
108 const char* address = NULL;
109
110 if (!PyArg_ParseTuple(args, "s", &address))
111 return NULL;
112
113 // Try to retrieve a matching network
114 int r = loc_database_lookup_from_string(self->db, address, &network);
115
116 // We got a network
117 if (r == 0) {
118 PyObject* obj = new_network(&NetworkType, network);
119 loc_network_unref(network);
120
121 return obj;
122
123 // Nothing found
124 } else if (r == 1) {
125 Py_RETURN_NONE;
126 }
127
128 // Unexpected error
129 return NULL;
130 }
131
132 static struct PyMethodDef Database_methods[] = {
133 {
134 "get_as",
135 (PyCFunction)Database_get_as,
136 METH_VARARGS,
137 NULL,
138 },
139 {
140 "lookup",
141 (PyCFunction)Database_lookup,
142 METH_VARARGS,
143 NULL,
144 },
145 { NULL },
146 };
147
148 static struct PyGetSetDef Database_getsetters[] = {
149 {
150 "created_at",
151 (getter)Database_get_created_at,
152 NULL,
153 NULL,
154 NULL,
155 },
156 {
157 "description",
158 (getter)Database_get_description,
159 NULL,
160 NULL,
161 NULL,
162 },
163 {
164 "vendor",
165 (getter)Database_get_vendor,
166 NULL,
167 NULL,
168 NULL,
169 },
170 { NULL },
171 };
172
173 PyTypeObject DatabaseType = {
174 PyVarObject_HEAD_INIT(NULL, 0)
175 tp_name: "location.Database",
176 tp_basicsize: sizeof(DatabaseObject),
177 tp_flags: Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
178 tp_new: Database_new,
179 tp_dealloc: (destructor)Database_dealloc,
180 tp_init: (initproc)Database_init,
181 tp_doc: "Database object",
182 tp_methods: Database_methods,
183 tp_getset: Database_getsetters,
184 };