# Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import datetime import functools import time from geoip import geolite2 import astral import astral.sun import dateutil.tz import flask import requests import prometheus_flask_exporter # type: ignore app = flask.Flask(__name__) _ = prometheus_flask_exporter.PrometheusMetrics(app) def _to_sec(dt): return dt.hour * 60 * 60 + dt.minute * 60 + dt.second @functools.lru_cache(maxsize=5) def _external_ip(): r = requests.get('https://api.ipify.org?format=json') return r.json().get('ip') @app.route('/now') def now(): ip = flask.request.args.get('ip') if not ip: ip = flask.request.remote_addr if ip.startswith('192.168.') or ip.startswith('10.') or ip.startswith( '127.0.'): ip = _external_ip() loc = geolite2.lookup(ip) if loc is None: flask.abort( 400, 'LOOKUP_FAILURE: unable to resolve the location of IP address %r' % ip) tz = dateutil.tz.gettz(loc.timezone) epoch = time.time() now = datetime.datetime.now(tz) city = astral.LocationInfo((loc.ip, loc.country, loc.location[0], loc.location[1], loc.timezone, 0)) sun = astral.sun.sun(city.observer, date=now) dawn = sun['dawn'] dusk = sun['dusk'] resp = dict(ip=loc.ip, country=loc.country, latitude=loc.location[0], longitude=loc.location[1], timezone=loc.timezone, dawn=dawn, dawn_sec=_to_sec(dawn), dusk=dusk, dusk_sec=_to_sec(dusk), local_time=now, day_sec=_to_sec(now), posix_sec=int(epoch)) return flask.jsonify(resp)