Skip to content

Commit 74d192b

Browse files
committed
GeoIP updater works now. Probably :S
1 parent 230b8a9 commit 74d192b

1 file changed

Lines changed: 42 additions & 16 deletions

File tree

plugins/geoip.py

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
import socket
22
import time
33
import requests
4+
import gzip
45
import asyncio
56
import shutil
7+
import logging
68
import os.path
79
import geoip2.database
810
import geoip2.errors
911

1012
from cloudbot import hook
1113

14+
logger = logging.getLogger("cloudbot")
15+
1216
DB_URL = "http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz"
1317
PATH = "./data/GeoLite2-City.mmdb"
1418

@@ -18,46 +22,68 @@
1822
def fetch_db():
1923
r = requests.get(DB_URL, stream=True)
2024
if r.status_code == 200:
21-
with open(PATH, 'wb') as f:
22-
r.raw.decode_content = True
23-
shutil.copyfileobj(r.raw, f)
25+
with gzip.open(r.raw, 'rb') as infile:
26+
with open(PATH, 'wb') as outfile:
27+
shutil.copyfileobj(infile, outfile)
2428

2529

26-
def update_db():
27-
global geoip_reader
30+
def update_db(existing_reader):
31+
"""
32+
Updates the DB.
33+
"""
2834
if os.path.isfile(PATH):
2935
# check if file is over 2 weeks old
3036
if time.time() - os.path.getmtime(PATH) > (14 * 24 * 60 * 60):
31-
geoip_reader = None
37+
# geoip is outdated, re-download
3238
fetch_db()
33-
geoip_reader = geoip2.database.Reader(PATH)
39+
return geoip2.database.Reader(PATH)
3440
else:
35-
if not geoip_reader:
36-
geoip_reader = geoip2.database.Reader(PATH)
41+
# geoip is good, create a reader or return existing reader
42+
if not existing_reader:
43+
try:
44+
return geoip2.database.Reader(PATH)
45+
except:
46+
fetch_db()
47+
return geoip2.database.Reader(PATH)
48+
else:
49+
return existing_reader
3750
else:
38-
geoip_reader = None
51+
# no geoip file
3952
fetch_db()
40-
geoip_reader = geoip2.database.Reader(PATH)
53+
return geoip2.database.Reader(PATH)
54+
55+
56+
def check_db(loop):
57+
"""
58+
runs update_db in an executor thread and sets geoip_reader to the result
59+
"""
60+
global geoip_reader
61+
db = yield from loop.run_in_executor(None, update_db, geoip_reader)
62+
if db:
63+
geoip_reader = db
4164

4265

4366
@asyncio.coroutine
4467
@hook.onload
4568
def load_geoip(loop):
46-
loop.run_in_executor(None, update_db)
69+
asyncio.async(check_db(loop), loop=loop)
4770

4871

72+
@asyncio.coroutine
4973
@hook.command
50-
def geoip(text, reply):
74+
def geoip(text, reply, loop):
75+
global geoip_reader
76+
5177
if not geoip_reader:
5278
return "GeoIP database is updating, please wait a minute"
5379

5480
try:
55-
ip = socket.gethostbyname(text)
81+
ip = yield from loop.run_in_executor(None, socket.gethostbyname, text)
5682
except socket.gaierror:
5783
return "Invalid input."
5884

5985
try:
60-
location_data = geoip_reader.city(ip)
86+
location_data = yield from loop.run_in_executor(None, geoip_reader.city, ip)
6187
except geoip2.errors.AddressNotFoundError:
6288
return "Sorry, I can't locate that in my database."
6389

@@ -71,4 +97,4 @@ def geoip(text, reply):
7197
reply("\x02Country:\x02 {country} ({cc}), \x02City:\x02 {city}{region}".format(**data))
7298

7399
# check the DB
74-
update_db()
100+
asyncio.async(check_db(loop), loop=loop)

0 commit comments

Comments
 (0)