]>
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
31 "https://ftp.afrinic.net/pub/pub/dbase/afrinic.db.gz"
34 # Asia Pacific Network Information Centre
36 "https://ftp.apnic.net/apnic/whois/apnic.db.inet6num.gz",
37 "https://ftp.apnic.net/apnic/whois/apnic.db.inetnum.gz",
38 #"https://ftp.apnic.net/apnic/whois/apnic.db.route6.gz",
39 #"https://ftp.apnic.net/apnic/whois/apnic.db.route.gz",
40 "https://ftp.apnic.net/apnic/whois/apnic.db.aut-num.gz",
41 "https://ftp.apnic.net/apnic/whois/apnic.db.organisation.gz"
44 # American Registry for Internet Numbers
45 # XXX there is nothing useful for us in here
47 # "https://ftp.arin.net/pub/rr/arin.db"
50 # Latin America and Caribbean Network Information Centre
53 # Réseaux IP Européens
55 "https://ftp.ripe.net/ripe/dbase/split/ripe.db.inet6num.gz",
56 "https://ftp.ripe.net/ripe/dbase/split/ripe.db.inetnum.gz",
57 #"https://ftp.ripe.net/ripe/dbase/split/ripe.db.route6.gz",
58 #"https://ftp.ripe.net/ripe/dbase/split/ripe.db.route.gz",
59 "https://ftp.ripe.net/ripe/dbase/split/ripe.db.aut-num.gz",
60 "https://ftp.ripe.net/ripe/dbase/split/ripe.db.organisation.gz"
65 # African Network Information Centre
67 # "https://ftp.afrinic.net/pub/stats/afrinic/delegated-afrinic-extended-latest"
70 # Asia Pacific Network Information Centre
72 # "https://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-extended-latest"
75 # American Registry for Internet Numbers
77 "https://ftp.arin.net/pub/stats/arin/delegated-arin-extended-latest"
80 # Latin America and Caribbean Network Information Centre
82 "https://ftp.lacnic.net/pub/stats/lacnic/delegated-lacnic-extended-latest"
85 # Réseaux IP Européens
87 # "https://ftp.ripe.net/pub/stats/ripencc/delegated-ripencc-extended-latest"
91 class Downloader(object):
95 def set_proxy(self
, url
):
97 Sets a HTTP proxy that is used to perform all requests
99 log
.info("Using proxy %s" % url
)
102 def request(self
, url
, data
=None, return_blocks
=False):
103 req
= urllib
.request
.Request(url
, data
=data
)
107 req
.set_proxy(self
.proxy
, "http")
109 return DownloaderContext(self
, req
, return_blocks
=return_blocks
)
112 class DownloaderContext(object):
113 def __init__(self
, downloader
, request
, return_blocks
=False):
114 self
.downloader
= downloader
115 self
.request
= request
117 # Should we return one block or a single line?
118 self
.return_blocks
= return_blocks
120 # Save the response object
124 log
.info("Retrieving %s..." % self
.request
.full_url
)
127 self
.response
= urllib
.request
.urlopen(self
.request
)
129 # Log the response headers
130 log
.debug("Response Headers:")
131 for header
in self
.headers
:
132 log
.debug(" %s: %s" % (header
, self
.get_header(header
)))
136 def __exit__(self
, type, value
, traceback
):
141 Makes the object iterable by going through each block
143 if self
.return_blocks
:
144 return iterate_over_blocks(self
.body
)
146 return iterate_over_lines(self
.body
)
151 return self
.response
.headers
153 def get_header(self
, name
):
155 return self
.headers
.get(name
)
160 Returns a file-like object with the decoded content
163 content_type
= self
.get_header("Content-Type")
165 # Decompress any gzipped response on the fly
166 if content_type
in ("application/x-gzip", "application/gzip"):
167 return gzip
.GzipFile(fileobj
=self
.response
, mode
="rb")
169 # Return the response by default
174 for block
in iterate_over_blocks(f
):
178 for i
, line
in enumerate(block
):
179 key
, value
= line
.split(":", 1)
181 # The key of the first line defines the type
186 data
[key
] = value
.strip()
190 def iterate_over_blocks(f
, charsets
=("utf-8", "latin1")):
195 for charset
in charsets
:
197 line
= line
.decode(charset
)
198 except UnicodeDecodeError:
203 # Skip commented lines
204 if line
.startswith("#") or line
.startswith("%"):
210 # Remove any comments at the end of line
211 line
, hash, comment
= line
.partition("#")
214 # Strip any whitespace before the comment
217 # If the line is now empty, we move on
225 # End the block on an empty line
232 # Return the last block
237 def iterate_over_lines(f
):