1 commit a6f1e3463d4c2085c203ad58072d7a154b663904
2 Author: Michael Tremer <michael.tremer@ipfire.org>
3 Date: Wed Jun 3 17:06:13 2020 +0000
5 Move location-downloader functionality into location-query
7 The commands are very long and confusion. Hence we merge this
10 Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
12 diff --git a/Makefile.am b/Makefile.am
13 index 31869e0..c0b1300 100644
16 @@ -146,6 +146,7 @@ CLEANFILES += \
17 dist_pkgpython_PYTHON = \
18 src/python/__init__.py \
19 src/python/database.py \
20 + src/python/downloader.py \
22 src/python/importer.py \
24 @@ -234,19 +235,16 @@ uninstall-perl:
25 $(DESTDIR)/$(prefix)/man/man3/Location.3pm
28 - src/python/location-downloader \
29 src/python/location-exporter \
30 src/python/location-importer \
31 src/python/location-query
34 - src/python/location-downloader.in \
35 src/python/location-exporter.in \
36 src/python/location-importer.in \
37 src/python/location-query.in
40 - src/python/location-downloader \
41 src/python/location-exporter \
42 src/python/location-importer \
43 src/python/location-query
44 diff --git a/src/python/location-downloader.in b/src/python/downloader.py
46 rename from src/python/location-downloader.in
47 rename to src/python/downloader.py
48 index bf0d682..c9e6e00 100644
49 --- a/src/python/location-downloader.in
50 +++ b/src/python/downloader.py
53 # libloc - A library to determine the location of someone on the Internet #
55 -# Copyright (C) 2019 IPFire Development Team <info@ipfire.org> #
56 +# Copyright (C) 2020 IPFire Development Team <info@ipfire.org> #
58 # This library is free software; you can redistribute it and/or #
59 # modify it under the terms of the GNU Lesser General Public #
62 ###############################################################################
79 -# Load our location module
81 -from location.i18n import _
82 +from _location import Database, DATABASE_VERSION_LATEST
84 DATABASE_FILENAME = "location.db.xz"
86 @@ -46,9 +40,11 @@ log = logging.getLogger("location.downloader")
89 class Downloader(object):
90 - def __init__(self, version, mirrors):
91 + def __init__(self, version=DATABASE_VERSION_LATEST, mirrors=None):
92 self.version = version
93 - self.mirrors = list(mirrors)
95 + # Set mirrors or use defaults
96 + self.mirrors = list(mirrors or MIRRORS)
99 random.shuffle(self.mirrors)
100 @@ -117,9 +113,10 @@ class Downloader(object):
104 - def download(self, url, public_key, timestamp=None, tmpdir=None, **kwargs):
106 + def download(self, public_key, timestamp=None, tmpdir=None, **kwargs):
107 + url = "%s/%s" % (self.version, DATABASE_FILENAME)
111 headers["If-Modified-Since"] = timestamp.strftime(
112 "%a, %d %b %Y %H:%M:%S GMT",
113 @@ -191,7 +188,7 @@ class Downloader(object):
115 log.debug("Opening downloaded database at %s" % f.name)
117 - db = location.Database(f.name)
118 + db = Database(f.name)
120 # Database is not recent
121 if timestamp and db.created_at < timestamp.timestamp():
122 @@ -208,141 +205,3 @@ class Downloader(object):
129 - def __init__(self):
130 - # Which version are we downloading?
131 - self.version = location.DATABASE_VERSION_LATEST
133 - self.downloader = Downloader(version=self.version, mirrors=MIRRORS)
135 - def parse_cli(self):
136 - parser = argparse.ArgumentParser(
137 - description=_("Location Downloader Command Line Interface"),
139 - subparsers = parser.add_subparsers()
141 - # Global configuration flags
142 - parser.add_argument("--debug", action="store_true",
143 - help=_("Enable debug output"))
144 - parser.add_argument("--quiet", action="store_true",
145 - help=_("Enable quiet mode"))
148 - parser.add_argument("--version", action="version",
149 - version="%(prog)s @VERSION@")
152 - parser.add_argument("--database", "-d",
153 - default="@databasedir@/database.db", help=_("Path to database"),
157 - parser.add_argument("--public-key", "-k",
158 - default="@databasedir@/signing-key.pem", help=_("Public Signing Key"),
162 - update = subparsers.add_parser("update", help=_("Update database"))
163 - update.set_defaults(func=self.handle_update)
166 - verify = subparsers.add_parser("verify",
167 - help=_("Verify the downloaded database"))
168 - verify.set_defaults(func=self.handle_verify)
170 - args = parser.parse_args()
172 - # Configure logging
174 - location.logger.set_level(logging.DEBUG)
176 - location.logger.set_level(logging.WARNING)
178 - # Print usage if no action was given
179 - if not "func" in args:
180 - parser.print_usage()
186 - # Parse command line arguments
187 - args = self.parse_cli()
190 - ret = args.func(args)
192 - # Return with exit code
196 - # Otherwise just exit
199 - def handle_update(self, ns):
200 - # Fetch the timestamp we need from DNS
201 - t = location.discover_latest_version(self.version)
203 - # Parse timestamp into datetime format
204 - timestamp = datetime.datetime.fromtimestamp(t) if t else None
208 - db = location.Database(ns.database)
210 - # Check if we are already on the latest version
211 - if timestamp and db.created_at >= timestamp.timestamp():
212 - log.info("Already on the latest version")
215 - except FileNotFoundError as e:
218 - # Download the database into the correct directory
219 - tmpdir = os.path.dirname(ns.database)
221 - # Try downloading a new database
223 - t = self.downloader.download("%s/%s" % (self.version, DATABASE_FILENAME),
224 - public_key=ns.public_key, timestamp=timestamp, tmpdir=tmpdir)
226 - # If no file could be downloaded, log a message
227 - except FileNotFoundError as e:
228 - log.error("Could not download a new database")
231 - # If we have not received a new file, there is nothing to do
235 - # Move temporary file to destination
236 - shutil.move(t.name, ns.database)
240 - def handle_verify(self, ns):
242 - db = location.Database(ns.database)
243 - except FileNotFoundError as e:
244 - log.error("%s: %s" % (ns.database, e))
247 - # Verify the database
248 - with open(ns.public_key, "r") as f:
249 - if not db.verify(f):
250 - log.error("Could not verify database")
254 - log.debug("Database successfully verified")
259 - # Run the command line interface
264 diff --git a/src/python/location-query.in b/src/python/location-query.in
265 index dfdff8c..0291786 100644
266 --- a/src/python/location-query.in
267 +++ b/src/python/location-query.in
269 ###############################################################################
281 # Load our location module
283 +import location.downloader
284 from location.i18n import _
287 +log = logging.getLogger("location")
291 class OutputFormatter(object):
292 @@ -157,6 +164,15 @@ class CLI(object):
293 dump.add_argument("output", nargs="?", type=argparse.FileType("w"))
294 dump.set_defaults(func=self.handle_dump)
297 + update = subparsers.add_parser("update", help=_("Update database"))
298 + update.set_defaults(func=self.handle_update)
301 + verify = subparsers.add_parser("verify",
302 + help=_("Verify the downloaded database"))
303 + verify.set_defaults(func=self.handle_verify)
306 get_as = subparsers.add_parser("get-as",
307 help=_("Get information about one or multiple Autonomous Systems"),
308 @@ -423,6 +439,59 @@ class CLI(object):
309 for a in db.search_as(query):
312 + def handle_update(self, db, ns):
313 + # Fetch the timestamp we need from DNS
314 + t = location.discover_latest_version()
316 + # Parse timestamp into datetime format
317 + timestamp = datetime.datetime.fromtimestamp(t) if t else None
319 + # Check the version of the local database
320 + if db and timestamp and db.created_at >= timestamp.timestamp():
321 + log.info("Already on the latest version")
324 + # Download the database into the correct directory
325 + tmpdir = os.path.dirname(ns.database)
327 + # Create a downloader
328 + d = location.downloader.Downloader()
330 + # Try downloading a new database
332 + t = d.download(public_key=ns.public_key, timestamp=timestamp, tmpdir=tmpdir)
334 + # If no file could be downloaded, log a message
335 + except FileNotFoundError as e:
336 + log.error("Could not download a new database")
339 + # If we have not received a new file, there is nothing to do
343 + # Move temporary file to destination
344 + shutil.move(t.name, ns.database)
348 + def handle_verify(self, ns):
350 + db = location.Database(ns.database)
351 + except FileNotFoundError as e:
352 + log.error("%s: %s" % (ns.database, e))
355 + # Verify the database
356 + with open(ns.public_key, "r") as f:
357 + if not db.verify(f):
358 + log.error("Could not verify database")
362 + log.debug("Database successfully verified")
365 def __get_output_formatter(self, ns):
367 cls = self.output_formats[ns.output_format]
368 diff --git a/src/python/locationmodule.c b/src/python/locationmodule.c
369 index a04cab7..5b72be9 100644
370 --- a/src/python/locationmodule.c
371 +++ b/src/python/locationmodule.c
372 @@ -50,9 +50,9 @@ static PyObject* set_log_level(PyObject* m, PyObject* args) {
375 static PyObject* discover_latest_version(PyObject* m, PyObject* args) {
376 - unsigned int version = 0;
377 + unsigned int version = LOC_DATABASE_VERSION_LATEST;
379 - if (!PyArg_ParseTuple(args, "i", &version))
380 + if (!PyArg_ParseTuple(args, "|i", &version))