This repository has been archived by the owner on Jul 30, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
maxmind-geolite-update.py
executable file
·132 lines (101 loc) · 4.77 KB
/
maxmind-geolite-update.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/env python
"""maxmind-geolite-update: Updates the MaxMind geo IP databases"""
# Standard command-line imports
import os, sys, optparse
import ConfigParser
import datetime
import urllib2
import gzip
__author__ = "Alex Dean"
__copyright__ = "Copyright 2012, Psychic Bazaar Ltd"
__status__ = "Production"
__version__ = "0.1"
# Get the default configuration file for this script
CONFIG_FILE = os.path.dirname( os.path.realpath( __file__ ) ) + "/config.cfg"
def controller():
"""Runs program and handles command line options"""
parser = optparse.OptionParser(description='Updates the free MaxMind geo databases',
prog='maxmind-geolite-update',
version='maxmind-geolite-update' + __version__)
parser.add_option('--config', '-c',
help='config file. Default is ' + CONFIG_FILE,
dest='config',
default=CONFIG_FILE)
# Now parse the args
(opts, args) = parser.parse_args()
# Load the configuration file
config = ConfigParser.ConfigParser()
config.read(opts.config)
download_dir = config.get('Local', 'download-dir')
destination_dir = config.get('Local', 'destination-dir')
maxmind_uri = config.get('MaxMind', 'uri')
maxmind_files = config.items("Files")
hipchat_logger = HipChatLogger(config._sections)
# Check directories exist
if not os.path.isdir(download_dir):
raise Exception("Download directory %s does not exist" % download_dir)
if not os.path.isdir(destination_dir):
raise Exception("Destination directory %s does not exist" % destination_dir)
# Iterate through the files and download as necessary
for _, remote in maxmind_files:
local = os.path.basename(remote)
zipped_file = os.path.join(download_dir, local)
return_code = mirror(maxmind_uri + remote, zipped_file)
if (return_code >= 200 and return_code < 400) and return_code != 304:
# Generate the unzipped filename
local_file = os.path.splitext(local)[0]
unzipped_file = os.path.join(download_dir, local_file)
# Unzip the file
gz = gzip.open(zipped_file)
out = open(unzipped_file, 'w')
try:
out.writelines(line for line in gz)
finally:
out.close()
# Finally move the unzipped file, overwriting the old one
final_file = os.path.join(destination_dir, local_file)
os.rename(unzipped_file, final_file)
# Created notification message, print and send to HipChat if poss
notification = "Updated MaxMind database file %s" % final_file
print notification
hipchat_logger.notify(notification)
class HipChatLogger():
"""Simple class to handle notifications to HipChat. Wraps the Bash notification script rather than using python-hipchat (which is more complex)"""
def __init__(self, config):
"""Prepare the HipChat notification command from the config's HipChat dict, if there is one"""
if 'HipChat' in config:
self.hipchat_command = "%(cli-path)s -t %(token)s -r %(room-id)s -c %(color)s -f \"%(from-name)s\"" % config['HipChat']
else:
self.hipchat_command = None
def notify(self, message):
"""Send a message to HipChat"""
if self.hipchat_command is not None:
os.system("echo \"%s\" | %s" % (message, self.hipchat_command))
def mirror(uri, file):
"""Crude approximation of Perl's awesome mirror() function using urllib2"""
# Start building the request
req = urllib2.Request(uri)
# Add the file's datestamp as the If-Modified-Since, if it exists
if os.path.isfile(file):
mtime = os.path.getmtime(file)
if_modified_since = datetime.datetime.fromtimestamp(mtime).strftime("%a, %d %b %Y %H:%M:%S GMT") # e.g. Fri, 02 Feb 2010 22:04:23 GMT
req.add_header("If-Modified-Since", if_modified_since)
# Add the user-agent
req.add_header("User-agent", "maxmind-geolite-update/" + __version__)
opener = urllib2.build_opener(NotModifiedHandler())
resp = opener.open(req)
headers = resp.info()
# Write the file if we need to
if (resp.code >= 200 and resp.code < 400) and resp.code != 304:
local_file = open(file, 'w')
local_file.write(resp.read())
local_file.close()
return resp.code
class NotModifiedHandler(urllib2.BaseHandler):
"""Taken from http://www.artima.com/forums/flat.jsp?forum=122&thread=15024"""
def http_error_304(self, req, fp, code, message, headers):
addinfourl = urllib2.addinfourl(fp, headers, req.get_full_url())
addinfourl.code = code
return addinfourl
if __name__ == '__main__':
controller()