]> git.ipfire.org Git - location/libloc.git/blame - src/python/country.c
lua: Fix raising an exception if no network was found
[location/libloc.git] / src / python / country.c
CommitLineData
af208e26
MT
1/*
2 libloc - A library to determine the location of someone on the Internet
3
4 Copyright (C) 2019 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
c12a1385
MT
19#include <libloc/libloc.h>
20#include <libloc/country.h>
af208e26
MT
21
22#include "locationmodule.h"
23#include "country.h"
24
25PyObject* new_country(PyTypeObject* type, struct loc_country* country) {
26 CountryObject* self = (CountryObject*)type->tp_alloc(type, 0);
27 if (self) {
28 self->country = loc_country_ref(country);
29 }
30
31 return (PyObject*)self;
32}
33
34static PyObject* Country_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
35 CountryObject* self = (CountryObject*)type->tp_alloc(type, 0);
36
37 return (PyObject*)self;
38}
39
40static void Country_dealloc(CountryObject* self) {
41 if (self->country)
42 loc_country_unref(self->country);
43
44 Py_TYPE(self)->tp_free((PyObject* )self);
45}
46
47static int Country_init(CountryObject* self, PyObject* args, PyObject* kwargs) {
48 const char* country_code = NULL;
49
50 if (!PyArg_ParseTuple(args, "s", &country_code))
51 return -1;
52
53 // Create the country object
54 int r = loc_country_new(loc_ctx, &self->country, country_code);
55 if (r)
56 return -1;
57
58 return 0;
59}
60
61static PyObject* Country_repr(CountryObject* self) {
62 const char* code = loc_country_get_code(self->country);
63 const char* name = loc_country_get_name(self->country);
64
65 if (name)
66 return PyUnicode_FromFormat("<Country %s (%s)>", code, name);
67
68 return PyUnicode_FromFormat("<Country %s>", code);
69}
70
71static PyObject* Country_get_code(CountryObject* self) {
72 const char* code = loc_country_get_code(self->country);
73
74 return PyUnicode_FromString(code);
75}
76
77static PyObject* Country_str(CountryObject* self) {
78 return Country_get_code(self);
79}
80
81static PyObject* Country_get_name(CountryObject* self) {
82 const char* name = loc_country_get_name(self->country);
83
4ec8f610
MT
84 // Return None if no name has been set
85 if (!name)
86 Py_RETURN_NONE;
87
af208e26
MT
88 return PyUnicode_FromString(name);
89}
90
91static int Country_set_name(CountryObject* self, PyObject* value) {
92 const char* name = PyUnicode_AsUTF8(value);
93
94 int r = loc_country_set_name(self->country, name);
95 if (r) {
96 PyErr_Format(PyExc_ValueError, "Could not set name: %s", name);
97 return r;
98 }
99
100 return 0;
101}
102
103static PyObject* Country_get_continent_code(CountryObject* self) {
104 const char* code = loc_country_get_continent_code(self->country);
105
4ec8f610
MT
106 if (!code)
107 Py_RETURN_NONE;
108
af208e26
MT
109 return PyUnicode_FromString(code);
110}
111
112static int Country_set_continent_code(CountryObject* self, PyObject* value) {
113 const char* code = PyUnicode_AsUTF8(value);
114
115 int r = loc_country_set_continent_code(self->country, code);
116 if (r) {
117 PyErr_Format(PyExc_ValueError, "Could not set continent code: %s", code);
118 return r;
119 }
120
121 return 0;
122}
123
e6471394
MT
124static PyObject* Country_richcompare(CountryObject* self, PyObject* other, int op) {
125 int r;
126
127 // Check for type
128 if (!PyObject_IsInstance(other, (PyObject *)&CountryType))
129 Py_RETURN_NOTIMPLEMENTED;
130
131 CountryObject* o = (CountryObject*)other;
132
133 r = loc_country_cmp(self->country, o->country);
af208e26
MT
134
135 switch (op) {
136 case Py_EQ:
137 if (r == 0)
138 Py_RETURN_TRUE;
139
140 Py_RETURN_FALSE;
141
142 case Py_LT:
143 if (r < 0)
144 Py_RETURN_TRUE;
145
146 Py_RETURN_FALSE;
147
148 default:
149 break;
150 }
151
152 Py_RETURN_NOTIMPLEMENTED;
153}
154
44f35ed1
MT
155static Py_hash_t Country_hash(CountryObject* self) {
156 PyObject* code = NULL;
157 Py_hash_t hash = 0;
158
159 // Fetch the code as Python string
160 code = Country_get_code(self);
161 if (!code)
162 return -1;
163
164 // Fetch the hash of that string
165 hash = PyObject_Hash(code);
166 Py_DECREF(code);
167
168 return hash;
169}
170
af208e26
MT
171static struct PyGetSetDef Country_getsetters[] = {
172 {
173 "code",
174 (getter)Country_get_code,
175 NULL,
176 NULL,
177 NULL,
178 },
179 {
180 "name",
181 (getter)Country_get_name,
182 (setter)Country_set_name,
183 NULL,
184 NULL,
185 },
186 {
187 "continent_code",
188 (getter)Country_get_continent_code,
189 (setter)Country_set_continent_code,
190 NULL,
191 NULL,
192 },
193 { NULL },
194};
195
196PyTypeObject CountryType = {
197 PyVarObject_HEAD_INIT(NULL, 0)
198 .tp_name = "location.Country",
199 .tp_basicsize = sizeof(CountryObject),
200 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
201 .tp_new = Country_new,
202 .tp_dealloc = (destructor)Country_dealloc,
203 .tp_init = (initproc)Country_init,
204 .tp_doc = "Country object",
205 .tp_getset = Country_getsetters,
206 .tp_repr = (reprfunc)Country_repr,
207 .tp_str = (reprfunc)Country_str,
208 .tp_richcompare = (richcmpfunc)Country_richcompare,
44f35ed1 209 .tp_hash = (hashfunc)Country_hash,
af208e26 210};