Last active
September 11, 2018 13:35
-
-
Save lena/43a8bd5b6acca810de337509cdd0c5b6 to your computer and use it in GitHub Desktop.
Solution to Onboarding Project #2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Location to Datetime CLI | |
Usage: | |
python location_to_datetime.py --coordinates='39.6034810,-119.6822510' | |
python location_to_datetime.py --address='278 Bay Ridge Avenue, Brooklyn, NY, 11209' | |
python location_to_datetime.py --address='New York' --from-time='2017-08-08' --from-address='Egypt' | |
python location_to_datetime.py --address='New York' --from-time='2017-08-08T10:20:23' --from-address='Egypt' | |
python location_to_datetime.py --address='New York' --to-json | |
python location_to_datetime.py --address='New York' --format-str='YYYY-MM-DD HH:mm:ss ZZ' | |
Note: | |
Because there is no API key configured, the Google API sometimes returns an error instead of the correct result. | |
So just retry. This can be fixed by adding a `&key=<API_KEY>` to the API requests. | |
""" | |
import sys | |
import json | |
import argparse | |
import datetime | |
import requests | |
import arrow | |
GOOGLE_TIMEZONE_API_URL = 'https://maps.googleapis.com/maps/api/timezone/json' | |
GOOGLE_ADDRESS_API_URL = 'https://maps.googleapis.com/maps/api/geocode/json' | |
def run(coordinates=None, address=None, from_address=None, from_time=None): | |
assert (coordinates or address), 'Must provide an address or coordinates value to get a result.' | |
assert (from_address and from_time) or (not from_address and not from_time), 'Must provide a from_address and from_time value if you want to convert a datetime.' | |
if coordinates: | |
try: | |
tz = _get_timezone_for_coordinates(coordinates) | |
except Exception: | |
raise Exception('Could not find timezone for provided coordinates') | |
else: | |
try: | |
tz = _get_timezone_for_address(address) | |
except Exception: | |
raise Exception('Could not find timezone for provided address') | |
if not from_address and not from_time: | |
result = arrow.now(tz) | |
else: | |
try: | |
result = _convert_timezone(tz, from_address, from_time) | |
except Exception: | |
raise Exception('Could not find timezone for provided from_address') | |
return result | |
def _convert_timezone(tz, from_address, from_time): | |
from_tz = _get_timezone_for_address(from_address) | |
from_datetime = datetime.datetime.fromisoformat(from_time) | |
return arrow.get(from_datetime, from_tz).to(tz) | |
def _datetime_to_json(dt): | |
obj = { | |
'year': dt.year, | |
'month': dt.month, | |
'day': dt.day, | |
'hour': dt.hour, | |
'minute': dt.minute, | |
'timezone': dt.strftime('%Z') | |
} | |
return json.dumps(obj) | |
def _get_timezone_for_coordinates(coordinates): | |
response = requests.get('{}?location={}×tamp=100'.format(GOOGLE_TIMEZONE_API_URL, coordinates)) | |
return response.json()['timeZoneId'] | |
def _get_timezone_for_address(address): | |
response = requests.get('{}?address={}'.format(GOOGLE_ADDRESS_API_URL, address)) | |
location = response.json()['results'][0]['geometry']['location'] | |
coordinates = ('{lat},{lng}'.format(**location)) | |
return _get_timezone_for_coordinates(coordinates) | |
def _format_result(result, to_json, format_str): | |
if to_json: | |
return _datetime_to_json(result) | |
if format_str: | |
return result.format(format_str) | |
return result.isoformat() | |
if __name__ == '__main__': | |
parser = argparse.ArgumentParser(description='Returns the requested location\'s current time or converts timezones.') | |
parser.add_argument('--from-address', type=str, help='Address that you want to convert from, e.g., \'Egypt\'') | |
parser.add_argument('--from-time', type=str, help='Date/datetime (in ISO8601 format) that you want to convert.') | |
location_group = parser.add_mutually_exclusive_group() | |
location_group.add_argument('--coordinates', help='Coordinates string you want to look up the time for, e.g., \'39.6034810,-119.6822510\'') | |
location_group.add_argument('--address', type=str, help='Address you want to look up the time for, e.g., \'New York\'.') | |
result_format_group = parser.add_mutually_exclusive_group() | |
result_format_group.add_argument('--to-json', help='True if you want the result to be a json date object', action='store_true') | |
result_format_group.add_argument('--format-str', type=str, help='Specify a format of the result string.') | |
args = parser.parse_args() | |
print(args) | |
try: | |
result = run( | |
coordinates=args.coordinates, | |
address=args.address, | |
from_address=args.from_address, | |
from_time=args.from_time, | |
) | |
formatted_result = _format_result(result, args.to_json, args.format_str) | |
print(formatted_result) | |
except Exception as e: | |
print(e, file=sys.stderr) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment