-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmaxmind.py
executable file
·106 lines (85 loc) · 3.4 KB
/
maxmind.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/usr/bin/env python3
import os
import sys
import tempfile
from optparse import OptionParser
from string import Template
import urllib.request
import hashlib
import tarfile
import zipfile
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
url = "https://geolite.maxmind.com/download/geoip/database/"
template = Template('GeoLite2-$db$suffix')
database = {"asn": "ASN", "city": "City", "country": "Country"}
suffix = {"csv": "-CSV.zip", "binary": ".tar.gz"}
def download(url, path):
logger.info("downloading: %s", url)
filename = os.path.join(path, os.path.basename(url))
urllib.request.urlretrieve(url, filename)
return filename
def binary_files(members):
for info in members:
if info.name.endswith(".mmdb"):
info.name = os.path.basename(info.name)
logger.info("extracting: %s", info.name)
yield info
def csv_files(members):
for info in members:
if info.filename.endswith(".csv"):
info.filename = os.path.basename(info.filename)
logger.info("extracting: %s", info.filename)
yield info
def main():
usage = "usage: %prog [options]"
parser = OptionParser(usage=usage)
parser.add_option("-d", "--db", "--database",
dest="db",
choices=["asn", "city", "country"],
default="city",
help="database (asn|city|country) [default: %default]")
parser.add_option("-f", "--format",
dest="format",
choices=["csv", "binary"],
default="binary",
help="database format (binary|csv) [default: %default]")
parser.add_option("-p", "--path",
dest="path",
default=".",
help="path to extract the files [default: %default]")
parser.add_option("-q", "--quiet",
dest="quiet",
action="store_true",
default=False,
help="don't print any messages")
(options, args) = parser.parse_args()
if options.quiet:
logger.setLevel(logging.ERROR)
filename = template.substitute(db=database[options.db],
suffix=suffix[options.format])
with tempfile.TemporaryDirectory(prefix='maxmind_') as tmp:
logger.info("created tmp directory: %s", tmp)
try:
filepath = download(url + filename, tmp)
md5path = download(url + filename + '.md5', tmp)
except urllib.error.HTTPError as e:
logger.error("download failed, %s", e)
sys.exit(1)
logger.info("verifying checksum...")
checksum = hashlib.md5(open(filepath, 'rb').read()).hexdigest()
md5sum = open(md5path, 'r').read()
if checksum != md5sum:
logger.error("file checksum mismatch!")
sys.exit(1)
logger.info("extracting files to: '%s/'", options.path)
if tarfile.is_tarfile(filepath):
with tarfile.open(filepath) as tar:
tar.extractall(members=binary_files(tar), path=options.path)
elif zipfile.is_zipfile(filepath):
with zipfile.ZipFile(filepath) as zip:
zip.extractall(members=csv_files(zip.infolist()),
path=options.path)
if __name__ == "__main__":
main()