Change GeoIP database install using license key

This commit is contained in:
JonnyWong16 2019-12-23 23:58:36 -08:00
parent 554be92c39
commit 41c9369b43
5 changed files with 101 additions and 56 deletions

View file

@ -53,14 +53,6 @@ DOCUMENTATION :: END
<td>Newsletter Directory:</td> <td>Newsletter Directory:</td>
<td>${plexpy.CONFIG.NEWSLETTER_DIR}</td> <td>${plexpy.CONFIG.NEWSLETTER_DIR}</td>
</tr> </tr>
<tr>
<td>GeoLite2 Database:</td>
% if plexpy.CONFIG.GEOIP_DB:
<td>${plexpy.CONFIG.GEOIP_DB} | <a class="no-highlight" href="#" id="reinstall_geoip_db">Reinstall / Update</a> | <a class="no-highlight" href="#" id="uninstall_geoip_db">Uninstall</a></td>
% else:
<td><a class="no-highlight" href="#" id="install_geoip_db">Click here to install the GeoLite2 database.</a></td>
% endif
</tr>
% if plexpy.ARGS: % if plexpy.ARGS:
<tr> <tr>
<td>Arguments:</td> <td>Arguments:</td>
@ -102,22 +94,6 @@ DOCUMENTATION :: END
<script> <script>
$(document).ready(function () { $(document).ready(function () {
$("#install_geoip_db, #reinstall_geoip_db").click(function () {
var msg = 'Are you sure you want to install the GeoLite2 database?<br /><br />' +
'The database is used to lookup IP address geolocation info.<br />' +
'The database will be downloaded from <a href="${anon_url("https://dev.maxmind.com/geoip/geoip2/geolite2/")}" target="_blank">MaxMind</a>, <br />' +
'and requires <strong>100MB</strong> of free space to install in your Tautulli directory.<br />'
var url = 'install_geoip_db';
confirmAjaxCall(url, msg, null, 'Installing GeoLite2 database.', getConfigurationTable);
});
$("#uninstall_geoip_db").click(function () {
var msg = 'Are you sure you want to uninstall the GeoLite2 database?<br /><br />' +
'You will not be able to lookup IP address geolocation info.';
var url = 'uninstall_geoip_db';
confirmAjaxCall(url, msg, null, 'Uninstalling GeoLite2 database.', getConfigurationTable);
});
$('.guidelines-modal-link').on('click', function (e) { $('.guidelines-modal-link').on('click', function (e) {
e.preventDefault(); e.preventDefault();
$('#guidelines-type').text($(this).data('id')) $('#guidelines-type').text($(this).data('id'))

View file

@ -1170,6 +1170,30 @@
<p class="help-block">Enable to lookup links to MusicBrainz for music when available.</p> <p class="help-block">Enable to lookup links to MusicBrainz for music when available.</p>
</div> </div>
<div class="form-group">
<label for="maxmind_license_key">MaxMind License Key</label>
<div class="row">
<div class="col-md-6">
<input type="text" class="form-control" id="maxmind_license_key" name="maxmind_license_key" value="${config['maxmind_license_key']}" data-parsley-trigger="change">
</div>
</div>
<p class="help-block">
Enter your MaxMind License Key. You can register for a license key <a href="${anon_url('https://www.maxmind.com/en/geolite2/signup')}" target="_blank">here</a>.
</p>
</div>
<div class="form-group">
<label for="geoip_db">GeoIP Database File</label> ${docker_msg | n}
<div class="row">
<div class="col-md-6">
<input type="text" class="form-control" id="geoip_db" name="geoip_db" value="${config['geoip_db']}" ${docker_setting}>
<div class="btn-group">
<button class="btn btn-form" type="button" id="install_geoip_db">${'Update' if plexpy.CONFIG.GEOIP_DB_INSTALLED else 'Install'}</button>
<button class="btn btn-form" type="button" id="uninstall_geoip_db">Uninstall</button>
</div>
</div>
</div>
</div>
<p><input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully"></p> <p><input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully"></p>
</div> </div>
@ -1796,11 +1820,6 @@ Rating: {rating}/10 --> Rating: /10
async: true, async: true,
complete: function(xhr, status) { complete: function(xhr, status) {
$("#plexpy-configuration-table").html(xhr.responseText); $("#plexpy-configuration-table").html(xhr.responseText);
if ("${kwargs.get('install_geoip')}" == 'true') {
$('#install_geoip_db').removeClass('no-highlight').css('color','#e9a049');
} else if ("${kwargs.get('reinstall_geoip')}" == 'true') {
$('#reinstall_geoip_db').removeClass('no-highlight').css('color','#e9a049');
}
} }
}); });
} }
@ -2798,6 +2817,26 @@ $(document).ready(function() {
$('#resources-xml').on('tripleclick', function () { $('#resources-xml').on('tripleclick', function () {
openPlexXML('/api/resources', true, {includeHttps: 1}); openPlexXML('/api/resources', true, {includeHttps: 1});
}); });
if ("${kwargs.get('install_geoip')}" == 'true') {
gotoSetting('notifications', 'geoip_db')
}
$("#install_geoip_db").click(function () {
var msg = 'Are you sure you want to install the GeoLite2 database?<br /><br />' +
'The database is used to lookup IP address geolocation info.<br />' +
'The database will be downloaded from <a href="${anon_url("https://dev.maxmind.com/geoip/geoip2/geolite2/")}" target="_blank">MaxMind</a>, <br />' +
'and requires <strong>100MB</strong> of free space to install in your Tautulli directory.<br />'
var url = 'install_geoip_db';
confirmAjaxCall(url, msg, null, 'Installing GeoLite2 database.', function () {$('#install_geoip_db').text('Update');});
});
$("#uninstall_geoip_db").click(function () {
var msg = 'Are you sure you want to uninstall the GeoLite2 database?<br /><br />' +
'You will not be able to lookup IP address geolocation info.';
var url = 'uninstall_geoip_db';
confirmAjaxCall(url, msg, null, 'Uninstalling GeoLite2 database.', function () {$('#install_geoip_db').text('Install');});
});
}); });
</script> </script>
</%def> </%def>

View file

@ -175,6 +175,7 @@ _CONFIG_DEFINITIONS = {
'FIRST_RUN_COMPLETE': (int, 'General', 0), 'FIRST_RUN_COMPLETE': (int, 'General', 0),
'FREEZE_DB': (int, 'General', 0), 'FREEZE_DB': (int, 'General', 0),
'GEOIP_DB': (str, 'General', ''), 'GEOIP_DB': (str, 'General', ''),
'GEOIP_DB_INSTALLED': (int, 'General', 0),
'GET_FILE_SIZES': (int, 'General', 0), 'GET_FILE_SIZES': (int, 'General', 0),
'GET_FILE_SIZES_HOLD': (dict, 'General', {'section_ids': [], 'rating_keys': []}), 'GET_FILE_SIZES_HOLD': (dict, 'General', {'section_ids': [], 'rating_keys': []}),
'GIT_BRANCH': (str, 'General', 'master'), 'GIT_BRANCH': (str, 'General', 'master'),
@ -289,6 +290,7 @@ _CONFIG_DEFINITIONS = {
'LOG_BLACKLIST': (int, 'General', 1), 'LOG_BLACKLIST': (int, 'General', 1),
'LOG_DIR': (str, 'General', ''), 'LOG_DIR': (str, 'General', ''),
'LOGGING_IGNORE_INTERVAL': (int, 'Monitoring', 120), 'LOGGING_IGNORE_INTERVAL': (int, 'Monitoring', 120),
'MAXMIND_LICENSE_KEY': (str, 'General', ''),
'METADATA_CACHE_SECONDS': (int, 'Advanced', 1800), 'METADATA_CACHE_SECONDS': (int, 'Advanced', 1800),
'MOVIE_LOGGING_ENABLE': (int, 'Monitoring', 1), 'MOVIE_LOGGING_ENABLE': (int, 'Monitoring', 1),
'MOVIE_NOTIFY_ENABLE': (int, 'Monitoring', 0), 'MOVIE_NOTIFY_ENABLE': (int, 'Monitoring', 0),
@ -923,3 +925,10 @@ class Config(object):
self.BUFFER_THRESHOLD = max(self.BUFFER_THRESHOLD, 10) self.BUFFER_THRESHOLD = max(self.BUFFER_THRESHOLD, 10)
self.CONFIG_VERSION = 13 self.CONFIG_VERSION = 13
if self.CONFIG_VERSION == 13:
self.GEOIP_DB_INSTALLED = int(bool(self.GEOIP_DB))
if not self.GEOIP_DB:
self.GEOIP_DB = os.path.join(plexpy.DATA_DIR, 'GeoLite2-City.mmdb')
self.CONFIG_VERSION = 14

View file

@ -36,6 +36,7 @@ import re
import shlex import shlex
import socket import socket
import sys import sys
import tarfile
import time import time
import unicodedata import unicodedata
import urllib, urllib2 import urllib, urllib2
@ -584,61 +585,79 @@ def is_valid_ip(address):
def install_geoip_db(): def install_geoip_db():
maxmind_url = 'http://geolite.maxmind.com/download/geoip/database/' if not plexpy.CONFIG.MAXMIND_LICENSE_KEY:
geolite2_gz = 'GeoLite2-City.mmdb.gz' logger.error(u"Tautulli Helpers :: Failed to download GeoLite2 database file from MaxMind: Missing MaxMindLicense Key")
geolite2_md5 = 'GeoLite2-City.md5' return False
geolite2_db = geolite2_gz[:-3]
md5_checksum = '' maxmind_db = 'GeoLite2-City'
maxmind_url = 'https://download.maxmind.com/app/geoip_download?edition_id={db}&suffix={{suffix}}&license_key={key}'.format(
db=maxmind_db, key=plexpy.CONFIG.MAXMIND_LICENSE_KEY)
geolite2_db_url = maxmind_url.format(suffix='tar.gz')
geolite2_md5_url = maxmind_url.format(suffix='tar.gz.md5')
geolite2_gz = maxmind_db + '.tar.gz'
geolite2_md5 = geolite2_gz + '.md5'
geolite2_db = maxmind_db + '.mmdb'
geolite2_db_path = plexpy.CONFIG.GEOIP_DB or os.path.join(plexpy.DATA_DIR, geolite2_db)
temp_gz = os.path.join(plexpy.CONFIG.CACHE_DIR, geolite2_gz) temp_gz = os.path.join(plexpy.CONFIG.CACHE_DIR, geolite2_gz)
geolite2_db = plexpy.CONFIG.GEOIP_DB or os.path.join(plexpy.DATA_DIR, geolite2_db) temp_md5 = os.path.join(plexpy.CONFIG.CACHE_DIR, geolite2_md5)
# Retrieve the GeoLite2 gzip file # Retrieve the GeoLite2 gzip file
logger.debug(u"Tautulli Helpers :: Downloading GeoLite2 gzip file from MaxMind...") logger.debug(u"Tautulli Helpers :: Downloading GeoLite2 gzip file from MaxMind...")
try: try:
maxmind = urllib.URLopener() maxmind = urllib.URLopener()
maxmind.retrieve(maxmind_url + geolite2_gz, temp_gz) maxmind.retrieve(geolite2_db_url, temp_gz)
md5_checksum = urllib2.urlopen(maxmind_url + geolite2_md5).read() maxmind.retrieve(geolite2_md5_url, temp_md5)
except Exception as e: except Exception as e:
logger.error(u"Tautulli Helpers :: Failed to download GeoLite2 gzip file from MaxMind: %s" % e) logger.error(u"Tautulli Helpers :: Failed to download GeoLite2 gzip file from MaxMind: %s" % e)
return False return False
# Extract the GeoLite2 database file # Check MD5 hash for GeoLite2 tar.gz file
logger.debug(u"Tautulli Helpers :: Extracting GeoLite2 database...") logger.debug(u"Tautulli Helpers :: Checking MD5 checksum for GeoLite2 gzip file...")
try:
with gzip.open(temp_gz, 'rb') as gz:
with open(geolite2_db, 'wb') as db:
db.write(gz.read())
except Exception as e:
logger.error(u"Tautulli Helpers :: Failed to extract the GeoLite2 database: %s" % e)
return False
# Check MD5 hash for GeoLite2 database file
logger.debug(u"Tautulli Helpers :: Checking MD5 checksum for GeoLite2 database...")
try: try:
hash_md5 = hashlib.md5() hash_md5 = hashlib.md5()
with open(geolite2_db, 'rb') as f: with open(temp_gz, 'rb') as f:
for chunk in iter(lambda: f.read(4096), b""): for chunk in iter(lambda: f.read(4096), b""):
hash_md5.update(chunk) hash_md5.update(chunk)
md5_hash = hash_md5.hexdigest() md5_hash = hash_md5.hexdigest()
with open(temp_md5, 'r') as f:
md5_checksum = f.read()
if md5_hash != md5_checksum: if md5_hash != md5_checksum:
logger.error(u"Tautulli Helpers :: MD5 checksum doesn't match for GeoLite2 database. " logger.error(u"Tautulli Helpers :: MD5 checksum doesn't match for GeoLite2 database. "
"Checksum: %s, file hash: %s" % (md5_checksum, md5_hash)) "Checksum: %s, file hash: %s" % (md5_checksum, md5_hash))
return False return False
except Exception as e: except Exception as e:
logger.error(u"Tautulli Helpers :: Failed to generate MD5 checksum for GeoLite2 database: %s" % e) logger.error(u"Tautulli Helpers :: Failed to generate MD5 checksum for GeoLite2 gzip file: %s" % e)
return False
# Extract the GeoLite2 database file
logger.debug(u"Tautulli Helpers :: Extracting GeoLite2 database...")
try:
with tarfile.open(temp_gz, 'r:gz') as tar:
for tarinfo in tar:
if tarinfo.isdir():
member = tar.getmember(os.path.join(tarinfo.name, geolite2_db))
mmdb = tar.extractfile(member)
with open(geolite2_db_path, 'wb') as db:
db.write(mmdb.read())
break
except Exception as e:
logger.error(u"Tautulli Helpers :: Failed to extract the GeoLite2 database: %s" % e)
return False return False
# Delete temportary GeoLite2 gzip file # Delete temportary GeoLite2 gzip file
logger.debug(u"Tautulli Helpers :: Deleting temporary GeoLite2 gzip file...") logger.debug(u"Tautulli Helpers :: Deleting temporary GeoLite2 gzip file...")
try: try:
os.remove(temp_gz) os.remove(temp_gz)
os.remove(temp_md5)
except Exception as e: except Exception as e:
logger.warn(u"Tautulli Helpers :: Failed to remove temporary GeoLite2 gzip file: %s" % e) logger.warn(u"Tautulli Helpers :: Failed to remove temporary GeoLite2 gzip file: %s" % e)
logger.debug(u"Tautulli Helpers :: GeoLite2 database installed successfully.") logger.debug(u"Tautulli Helpers :: GeoLite2 database installed successfully.")
plexpy.CONFIG.__setattr__('GEOIP_DB', geolite2_db) plexpy.CONFIG.__setattr__('GEOIP_DB', geolite2_db_path)
plexpy.CONFIG.__setattr__('GEOIP_DB_INSTALLED', int(time.time()))
plexpy.CONFIG.write() plexpy.CONFIG.write()
return True return True
@ -648,7 +667,7 @@ def uninstall_geoip_db():
logger.debug(u"Tautulli Helpers :: Uninstalling the GeoLite2 database...") logger.debug(u"Tautulli Helpers :: Uninstalling the GeoLite2 database...")
try: try:
os.remove(plexpy.CONFIG.GEOIP_DB) os.remove(plexpy.CONFIG.GEOIP_DB)
plexpy.CONFIG.__setattr__('GEOIP_DB', '') plexpy.CONFIG.__setattr__('GEOIP_DB_INSTALLED', 0)
plexpy.CONFIG.write() plexpy.CONFIG.write()
except Exception as e: except Exception as e:
logger.error(u"Tautulli Helpers :: Failed to uninstall the GeoLite2 database: %s" % e) logger.error(u"Tautulli Helpers :: Failed to uninstall the GeoLite2 database: %s" % e)
@ -659,7 +678,7 @@ def uninstall_geoip_db():
def geoip_lookup(ip_address): def geoip_lookup(ip_address):
if not plexpy.CONFIG.GEOIP_DB: if not plexpy.CONFIG.GEOIP_DB_INSTALLED:
return 'GeoLite2 database not installed. Please install from the ' \ return 'GeoLite2 database not installed. Please install from the ' \
'<a href="settings?install_geoip=true">Settings</a> page.' '<a href="settings?install_geoip=true">Settings</a> page.'
@ -677,7 +696,7 @@ def geoip_lookup(ip_address):
'<a href="settings?install_geoip=true">Settings</a> page.' '<a href="settings?install_geoip=true">Settings</a> page.'
except maxminddb.InvalidDatabaseError as e: except maxminddb.InvalidDatabaseError as e:
return 'Invalid GeoLite2 database. Please reinstall from the ' \ return 'Invalid GeoLite2 database. Please reinstall from the ' \
'<a href="settings?reinstall_geoip=true">Settings</a> page.' '<a href="settings?install_geoip=true">Settings</a> page.'
except geoip2.errors.AddressNotFoundError as e: except geoip2.errors.AddressNotFoundError as e:
return '%s' % e return '%s' % e
except Exception as e: except Exception as e:

View file

@ -2819,7 +2819,9 @@ class WebInterface(object):
"newsletter_password": plexpy.CONFIG.NEWSLETTER_PASSWORD, "newsletter_password": plexpy.CONFIG.NEWSLETTER_PASSWORD,
"newsletter_inline_styles": checked(plexpy.CONFIG.NEWSLETTER_INLINE_STYLES), "newsletter_inline_styles": checked(plexpy.CONFIG.NEWSLETTER_INLINE_STYLES),
"newsletter_custom_dir": plexpy.CONFIG.NEWSLETTER_CUSTOM_DIR, "newsletter_custom_dir": plexpy.CONFIG.NEWSLETTER_CUSTOM_DIR,
"win_sys_tray": checked(plexpy.CONFIG.WIN_SYS_TRAY) "win_sys_tray": checked(plexpy.CONFIG.WIN_SYS_TRAY),
"geoip_db": plexpy.CONFIG.GEOIP_DB,
"maxmind_license_key": plexpy.CONFIG.MAXMIND_LICENSE_KEY
} }
return serve_template(templatename="settings.html", title="Settings", config=config, kwargs=kwargs) return serve_template(templatename="settings.html", title="Settings", config=config, kwargs=kwargs)