| 
									
										
										
										
											2020-12-01 21:15:19 +01:00
										 |  |  | # 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. | 
					
						
							| 
									
										
										
										
											2018-11-30 16:38:29 +00:00
										 |  |  | import datetime | 
					
						
							| 
									
										
										
										
											2020-01-05 13:44:19 +01:00
										 |  |  | import functools | 
					
						
							| 
									
										
										
										
											2018-11-30 16:38:29 +00:00
										 |  |  | import time | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from geoip import geolite2 | 
					
						
							|  |  |  | import astral | 
					
						
							| 
									
										
										
										
											2020-10-25 19:53:32 +00:00
										 |  |  | import astral.sun | 
					
						
							| 
									
										
										
										
											2018-11-30 16:38:29 +00:00
										 |  |  | import dateutil.tz | 
					
						
							|  |  |  | import flask | 
					
						
							| 
									
										
										
										
											2018-12-09 16:07:46 +01:00
										 |  |  | import requests | 
					
						
							| 
									
										
										
										
											2020-01-02 15:40:29 +01:00
										 |  |  | import prometheus_flask_exporter  # type: ignore | 
					
						
							| 
									
										
										
										
											2018-11-30 16:38:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | app = flask.Flask(__name__) | 
					
						
							| 
									
										
										
										
											2020-01-02 15:40:29 +01:00
										 |  |  | _ = prometheus_flask_exporter.PrometheusMetrics(app) | 
					
						
							| 
									
										
										
										
											2018-11-30 16:38:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-05 13:44:19 +01:00
										 |  |  | def _to_sec(dt): | 
					
						
							| 
									
										
										
										
											2018-11-30 16:38:29 +00:00
										 |  |  |     return dt.hour * 60 * 60 + dt.minute * 60 + dt.second | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-05 13:44:19 +01:00
										 |  |  | @functools.lru_cache(maxsize=5) | 
					
						
							|  |  |  | def _external_ip(): | 
					
						
							|  |  |  |     r = requests.get('https://api.ipify.org?format=json') | 
					
						
							|  |  |  |     return r.json().get('ip') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-09 16:07:46 +01:00
										 |  |  | @app.route('/now') | 
					
						
							|  |  |  | def now(): | 
					
						
							| 
									
										
										
										
											2018-11-30 16:38:29 +00:00
										 |  |  |     ip = flask.request.args.get('ip') | 
					
						
							|  |  |  |     if not ip: | 
					
						
							|  |  |  |         ip = flask.request.remote_addr | 
					
						
							| 
									
										
										
										
											2020-01-02 11:37:04 +01:00
										 |  |  |         if ip.startswith('192.168.') or ip.startswith('10.') or ip.startswith( | 
					
						
							|  |  |  |                 '127.0.'): | 
					
						
							| 
									
										
										
										
											2020-01-05 13:44:19 +01:00
										 |  |  |             ip = _external_ip() | 
					
						
							| 
									
										
										
										
											2018-11-30 16:38:29 +00:00
										 |  |  |     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) | 
					
						
							| 
									
										
										
										
											2020-10-25 19:53:32 +00:00
										 |  |  |     city = astral.LocationInfo((loc.ip, loc.country, loc.location[0], | 
					
						
							| 
									
										
										
										
											2020-12-01 21:15:19 +01:00
										 |  |  |                                 loc.location[1], loc.timezone, 0)) | 
					
						
							| 
									
										
										
										
											2020-10-25 19:53:32 +00:00
										 |  |  |     sun = astral.sun.sun(city.observer, date=now) | 
					
						
							| 
									
										
										
										
											2020-01-02 11:32:47 +01:00
										 |  |  |     dawn = sun['dawn'] | 
					
						
							|  |  |  |     dusk = sun['dusk'] | 
					
						
							| 
									
										
										
										
											2018-11-30 16:38:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-02 11:32:47 +01:00
										 |  |  |     resp = dict(ip=loc.ip, | 
					
						
							|  |  |  |                 country=loc.country, | 
					
						
							|  |  |  |                 latitude=loc.location[0], | 
					
						
							|  |  |  |                 longitude=loc.location[1], | 
					
						
							|  |  |  |                 timezone=loc.timezone, | 
					
						
							|  |  |  |                 dawn=dawn, | 
					
						
							| 
									
										
										
										
											2020-01-05 13:44:19 +01:00
										 |  |  |                 dawn_sec=_to_sec(dawn), | 
					
						
							| 
									
										
										
										
											2020-01-02 11:32:47 +01:00
										 |  |  |                 dusk=dusk, | 
					
						
							| 
									
										
										
										
											2020-01-05 13:44:19 +01:00
										 |  |  |                 dusk_sec=_to_sec(dusk), | 
					
						
							| 
									
										
										
										
											2020-01-02 11:32:47 +01:00
										 |  |  |                 local_time=now, | 
					
						
							| 
									
										
										
										
											2020-01-05 13:44:19 +01:00
										 |  |  |                 day_sec=_to_sec(now), | 
					
						
							| 
									
										
										
										
											2020-01-02 11:32:47 +01:00
										 |  |  |                 posix_sec=int(epoch)) | 
					
						
							| 
									
										
										
										
											2018-11-30 16:38:29 +00:00
										 |  |  |     return flask.jsonify(resp) |