]>
git.ipfire.org Git - people/ms/libloc.git/blob - src/python/importer.py
2 ###############################################################################
4 # libloc - A library to determine the location of someone on the Internet #
6 # Copyright (C) 2020 IPFire Development Team <info@ipfire.org> #
8 # This library is free software; you can redistribute it and/or #
9 # modify it under the terms of the GNU Lesser General Public #
10 # License as published by the Free Software Foundation; either #
11 # version 2.1 of the License, or (at your option) any later version. #
13 # This library is distributed in the hope that it will be useful, #
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU #
16 # Lesser General Public License for more details. #
18 ###############################################################################
25 log
= logging
.getLogger("location.importer")
29 # African Network Information Centre
30 "https://ftp.afrinic.net/pub/pub/dbase/afrinic.db.gz",
32 # Asia Pacific Network Information Centre
33 #"https://ftp.apnic.net/apnic/whois/apnic.db.inet6num.gz",
34 #"https://ftp.apnic.net/apnic/whois/apnic.db.inetnum.gz",
35 #"https://ftp.apnic.net/apnic/whois/apnic.db.route6.gz",
36 #"https://ftp.apnic.net/apnic/whois/apnic.db.route.gz",
37 "https://ftp.apnic.net/apnic/whois/apnic.db.aut-num.gz",
38 "https://ftp.apnic.net/apnic/whois/apnic.db.organisation.gz",
40 # American Registry for Internet Numbers
41 # XXX there is nothing useful for us in here
42 #"https://ftp.arin.net/pub/rr/arin.db",
44 # Latin America and Caribbean Network Information Centre
47 # Réseaux IP Européens
48 #"https://ftp.ripe.net/ripe/dbase/split/ripe.db.inet6num.gz",
49 #"https://ftp.ripe.net/ripe/dbase/split/ripe.db.inetnum.gz",
50 #"https://ftp.ripe.net/ripe/dbase/split/ripe.db.route6.gz",
51 #"https://ftp.ripe.net/ripe/dbase/split/ripe.db.route.gz",
52 "https://ftp.ripe.net/ripe/dbase/split/ripe.db.aut-num.gz",
53 "https://ftp.ripe.net/ripe/dbase/split/ripe.db.organisation.gz",
57 # African Network Information Centre
58 "https://ftp.afrinic.net/pub/stats/afrinic/delegated-afrinic-extended-latest",
60 # Asia Pacific Network Information Centre
61 "https://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-extended-latest",
63 # American Registry for Internet Numbers
64 "https://ftp.arin.net/pub/stats/arin/delegated-arin-extended-latest",
66 # Latin America and Caribbean Network Information Centre
67 "http://ftp.lacnic.net/pub/stats/lacnic/delegated-lacnic-extended-latest",
69 # Réseaux IP Européens
70 "https://ftp.ripe.net/pub/stats/ripencc/delegated-ripencc-extended-latest",
73 class Downloader(object):
77 def set_proxy(self
, url
):
79 Sets a HTTP proxy that is used to perform all requests
81 log
.info("Using proxy %s" % url
)
84 def request(self
, url
, data
=None, return_blocks
=False):
85 req
= urllib
.request
.Request(url
, data
=data
)
89 req
.set_proxy(self
.proxy
, "http")
91 return DownloaderContext(self
, req
, return_blocks
=return_blocks
)
94 class DownloaderContext(object):
95 def __init__(self
, downloader
, request
, return_blocks
=False):
96 self
.downloader
= downloader
97 self
.request
= request
99 # Should we return one block or a single line?
100 self
.return_blocks
= return_blocks
102 # Save the response object
106 log
.info("Retrieving %s..." % self
.request
.full_url
)
109 self
.response
= urllib
.request
.urlopen(self
.request
)
111 # Log the response headers
112 log
.debug("Response Headers:")
113 for header
in self
.headers
:
114 log
.debug(" %s: %s" % (header
, self
.get_header(header
)))
118 def __exit__(self
, type, value
, traceback
):
123 Makes the object iterable by going through each block
125 if self
.return_blocks
:
126 return iterate_over_blocks(self
.body
)
128 return iterate_over_lines(self
.body
)
133 return self
.response
.headers
135 def get_header(self
, name
):
137 return self
.headers
.get(name
)
142 Returns a file-like object with the decoded content
145 content_type
= self
.get_header("Content-Type")
147 # Decompress any gzipped response on the fly
148 if content_type
in ("application/x-gzip", "application/gzip"):
149 return gzip
.GzipFile(fileobj
=self
.response
, mode
="rb")
151 # Return the response by default
156 for block
in iterate_over_blocks(f
):
160 for i
, line
in enumerate(block
):
161 key
, value
= line
.split(":", 1)
163 # The key of the first line defines the type
168 data
[key
] = value
.strip()
172 def iterate_over_blocks(f
, charsets
=("utf-8", "latin1")):
177 for charset
in charsets
:
179 line
= line
.decode(charset
)
180 except UnicodeDecodeError:
185 # Skip commented lines
186 if line
.startswith("#") or line
.startswith("%"):
192 # Remove any comments at the end of line
193 line
, hash, comment
= line
.partition("#")
196 # Strip any whitespace before the comment
199 # If the line is now empty, we move on
207 # End the block on an empty line
214 # Return the last block
219 def iterate_over_lines(f
):