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