From 83fbdab53ebbd0e149c1c83a90b1f5dcd70e844b Mon Sep 17 00:00:00 2001 From: Michael Bemmerl Date: Fri, 29 Jul 2011 03:15:14 +0200 Subject: [PATCH 01/21] Added parser to retrieve the latitude & longitude from the command line. --- geohash.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/geohash.py b/geohash.py index 96bcd4b..9023318 100644 --- a/geohash.py +++ b/geohash.py @@ -1,6 +1,8 @@ #!/usr/bin/python -# Copyright 2011 Mark Holmquist +# Copyright (C) 2011 Mark Holmquist +# Copyright (C) 2011 Michael Bemmerl + # This script is free software, licensed under the GPLv3, of which you should have received a copy with this software. # If you didn't, I apologize, but you'll be able to find it at /usr/share/common-licences/GPL-3 or http://www.gnu.org/licenses/gpl-3.0.txt @@ -14,9 +16,16 @@ import hashlib import json import urllib +import argparse + +parser = argparse.ArgumentParser(description="Calculate a geohash location based on the opening price for BTC/USD trades at Mt. Gox.") +parser.add_argument('lat', help="Latitude (integer part)", type=int) +parser.add_argument('lon', help="Longitude (integer part)", type=int) + +args = parser.parse_args() -latitude = 33 -longitude = -116 +latitude = args.lat +longitude = args.lon btcinfo = urllib.urlopen("http://bitcoincharts.com/t/markets.json") jsoninfo = btcinfo.read() From 79bb5cddca0bdfe45d42940ffb10a345593d97e3 Mon Sep 17 00:00:00 2001 From: Michael Bemmerl Date: Fri, 29 Jul 2011 04:00:52 +0200 Subject: [PATCH 02/21] Added ability to use other markets than Mt. Gox. --- geohash.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/geohash.py b/geohash.py index 9023318..dd26475 100644 --- a/geohash.py +++ b/geohash.py @@ -6,7 +6,7 @@ # This script is free software, licensed under the GPLv3, of which you should have received a copy with this software. # If you didn't, I apologize, but you'll be able to find it at /usr/share/common-licences/GPL-3 or http://www.gnu.org/licenses/gpl-3.0.txt -# This script will calculate a geohash location for you based on the opening price at Mt. Gox for BTC/USD trades. +# This script will calculate a geohash location for you based on the opening price at a market for BTC trades. # Usually, people use the DJIA for this algorithm, but I didn't think that was nerdy enough :) # It will also automagically give you a link to a google map to the location. # If you'd like any help with it, don't hesitate to open up an issue at github. @@ -18,29 +18,37 @@ import urllib import argparse -parser = argparse.ArgumentParser(description="Calculate a geohash location based on the opening price for BTC/USD trades at Mt. Gox.") +parser = argparse.ArgumentParser(description="Calculate a geohash location based on the opening price for BTC trades.") parser.add_argument('lat', help="Latitude (integer part)", type=int) parser.add_argument('lon', help="Longitude (integer part)", type=int) +parser.add_argument('-s', '--symbol', help="Symbol of the market (default: mtgoxUSD)", default="mtgoxUSD") args = parser.parse_args() latitude = args.lat longitude = args.lon +symbol = args.symbol.lower() +jsoninfo = "" -btcinfo = urllib.urlopen("http://bitcoincharts.com/t/markets.json") -jsoninfo = btcinfo.read() +try: + btcinfo = urllib.urlopen("http://bitcoincharts.com/t/markets.json") + jsoninfo = btcinfo.read() +except IOError as (errno, strerror): + print "Could not retrieve data from bitcoincharts: " + str(strerror) + raise SystemExit dictinfo = json.loads(jsoninfo) todayopen = -1 for sym in dictinfo: - if sym["symbol"] == "mtgoxUSD": + if sym["symbol"].lower() == symbol: todayopen = sym["open"] + break else: continue if todayopen < 0: - raise ValueError("No data from bitcoincharts, is it down?") + raise ValueError("Symbol \"{0}\" not found. Try another one.".format(symbol)) thestring = str(datetime.date.today()) + "-" + str(todayopen) From c68359045e3175355b40ec543d3b741988d5a479 Mon Sep 17 00:00:00 2001 From: Michael Bemmerl Date: Fri, 29 Jul 2011 04:04:26 +0200 Subject: [PATCH 03/21] Consistent capitalization of help message. --- geohash.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/geohash.py b/geohash.py index dd26475..d490b1a 100644 --- a/geohash.py +++ b/geohash.py @@ -19,9 +19,9 @@ import argparse parser = argparse.ArgumentParser(description="Calculate a geohash location based on the opening price for BTC trades.") -parser.add_argument('lat', help="Latitude (integer part)", type=int) -parser.add_argument('lon', help="Longitude (integer part)", type=int) -parser.add_argument('-s', '--symbol', help="Symbol of the market (default: mtgoxUSD)", default="mtgoxUSD") +parser.add_argument('lat', help="latitude (integer part)", type=int) +parser.add_argument('lon', help="longitude (integer part)", type=int) +parser.add_argument('-s', '--symbol', help="symbol of the market (default: mtgoxUSD)", default="mtgoxUSD") args = parser.parse_args() From 47f22d1ecf76c094fed54f27e6a7a33f532ce403 Mon Sep 17 00:00:00 2001 From: Michael Bemmerl Date: Sat, 30 Jul 2011 01:07:19 +0200 Subject: [PATCH 04/21] Use different mapping services for the map URL --- geohash.py | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/geohash.py b/geohash.py index d490b1a..803acce 100644 --- a/geohash.py +++ b/geohash.py @@ -22,20 +22,22 @@ parser.add_argument('lat', help="latitude (integer part)", type=int) parser.add_argument('lon', help="longitude (integer part)", type=int) parser.add_argument('-s', '--symbol', help="symbol of the market (default: mtgoxUSD)", default="mtgoxUSD") +parser.add_argument('-m', '--map', help="print URL to a mapping service instead of displaying the raw latitude & longitude.", default="") args = parser.parse_args() latitude = args.lat longitude = args.lon symbol = args.symbol.lower() +map = args.map.lower() jsoninfo = "" try: - btcinfo = urllib.urlopen("http://bitcoincharts.com/t/markets.json") - jsoninfo = btcinfo.read() + btcinfo = urllib.urlopen("http://bitcoincharts.com/t/markets.json") + jsoninfo = btcinfo.read() except IOError as (errno, strerror): - print "Could not retrieve data from bitcoincharts: " + str(strerror) - raise SystemExit + print "Could not retrieve data from bitcoincharts: " + str(strerror) + raise SystemExit dictinfo = json.loads(jsoninfo) @@ -76,4 +78,19 @@ decnum[1] -= longitude decnum[1] *= -1 -print "http://maps.google.com/maps?q=" + str(decnum[0]) + "," + str(decnum[1]) + "(Geohash+for+" + str(datetime.date.today()) + ")&iwloc=A" +url = "" + +if map == "google": + url = "http://maps.google.com/maps?q={0},{1}({2})&iwloc=A" +elif map == "osm": + url = "http://osm.org/?mlat={0}&mlon={1}&zoom=12" +elif map == "yahoo": + url = "http://maps.yahoo.com/maps_result?ard=1&mag=9&lat={0}&lon={1}" +elif map == "bing": + url = "http://www.bing.com/maps/?q={0}+{1}&lvl=11" + +if map != "": + print url.format(decnum[0], decnum[1], "Geohash+for+" + str(datetime.date.today())) +else: + print "latitude: " + str(decnum[0]) + print "longitude: " + str(decnum[1]) From 4ebc5a27020252e827655f52b355cf381fc557d4 Mon Sep 17 00:00:00 2001 From: Michael Bemmerl Date: Sat, 30 Jul 2011 01:16:07 +0200 Subject: [PATCH 05/21] Fill latitude / longitude variables with geohash position --- geohash.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/geohash.py b/geohash.py index 803acce..fbb2b86 100644 --- a/geohash.py +++ b/geohash.py @@ -67,16 +67,14 @@ curpow += 1 if latitude >= 0: - decnum[0] += latitude + latitude += decnum[0] else: - decnum[0] -= latitude - decnum[0] *= -1 + latitude += decnum[0] * -1 if longitude >= 0: - decnum[1] += longitude + longitude += decnum[1] else: - decnum[1] -= longitude - decnum[1] *= -1 + longitude += decnum[1] * -1 url = "" @@ -90,7 +88,7 @@ url = "http://www.bing.com/maps/?q={0}+{1}&lvl=11" if map != "": - print url.format(decnum[0], decnum[1], "Geohash+for+" + str(datetime.date.today())) + print url.format(latitude, longitude, "Geohash+for+" + str(datetime.date.today())) else: - print "latitude: " + str(decnum[0]) - print "longitude: " + str(decnum[1]) + print "latitude: " + str(latitude) + print "longitude: " + str(longitude) From c679beb861121e60dfec1172a45fbe4629e4abf4 Mon Sep 17 00:00:00 2001 From: Michael Bemmerl Date: Sat, 30 Jul 2011 01:26:37 +0200 Subject: [PATCH 06/21] Display map service provider in help message. --- geohash.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geohash.py b/geohash.py index fbb2b86..b9f1fd6 100644 --- a/geohash.py +++ b/geohash.py @@ -22,7 +22,7 @@ parser.add_argument('lat', help="latitude (integer part)", type=int) parser.add_argument('lon', help="longitude (integer part)", type=int) parser.add_argument('-s', '--symbol', help="symbol of the market (default: mtgoxUSD)", default="mtgoxUSD") -parser.add_argument('-m', '--map', help="print URL to a mapping service instead of displaying the raw latitude & longitude.", default="") +parser.add_argument('-m', '--map', help="print URL to a mapping service instead of displaying the raw latitude & longitude.", default="", choices=["google", "osm", "yahoo", "bing"]) args = parser.parse_args() From d6c0613721ac0d9b12fe747d431d710bb83f202e Mon Sep 17 00:00:00 2001 From: Michael Bemmerl Date: Sat, 30 Jul 2011 02:18:12 +0200 Subject: [PATCH 07/21] List available symbols at bitcoincharts --- geohash.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/geohash.py b/geohash.py index b9f1fd6..0089ab1 100644 --- a/geohash.py +++ b/geohash.py @@ -19,10 +19,11 @@ import argparse parser = argparse.ArgumentParser(description="Calculate a geohash location based on the opening price for BTC trades.") -parser.add_argument('lat', help="latitude (integer part)", type=int) -parser.add_argument('lon', help="longitude (integer part)", type=int) +parser.add_argument('lat', help="latitude (integer part)", type=int, default=0) +parser.add_argument('lon', help="longitude (integer part)", type=int, default=0) parser.add_argument('-s', '--symbol', help="symbol of the market (default: mtgoxUSD)", default="mtgoxUSD") parser.add_argument('-m', '--map', help="print URL to a mapping service instead of displaying the raw latitude & longitude.", default="", choices=["google", "osm", "yahoo", "bing"]) +parser.add_argument('--list-symbols', help="list all available market symbols.", action="store_true") args = parser.parse_args() @@ -41,6 +42,11 @@ dictinfo = json.loads(jsoninfo) +if args.list_symbols: + for sym in dictinfo: + print sym["symbol"] + raise SystemExit + todayopen = -1 for sym in dictinfo: if sym["symbol"].lower() == symbol: From 33b6650641885819953c0ca139b7940e46f501b3 Mon Sep 17 00:00:00 2001 From: Michael Bemmerl Date: Sun, 20 May 2012 03:29:46 +0200 Subject: [PATCH 08/21] Bitcoin Charts switched to rolling intervals, so there is no opening price anymore. This change is using the first price after midnight for calculation of the geohash. --- geohash.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/geohash.py b/geohash.py index 96bcd4b..c637d8b 100644 --- a/geohash.py +++ b/geohash.py @@ -1,10 +1,12 @@ #!/usr/bin/python -# Copyright 2011 Mark Holmquist +# Copyright (C) 2011 Mark Holmquist +# Copyright (C) 2012 Michael Bemmerl + # This script is free software, licensed under the GPLv3, of which you should have received a copy with this software. # If you didn't, I apologize, but you'll be able to find it at /usr/share/common-licences/GPL-3 or http://www.gnu.org/licenses/gpl-3.0.txt -# This script will calculate a geohash location for you based on the opening price at Mt. Gox for BTC/USD trades. +# This script will calculate a geohash location for you based on the first price at Mt. Gox for BTC/USD trades after UTC midnight. # Usually, people use the DJIA for this algorithm, but I didn't think that was nerdy enough :) # It will also automagically give you a link to a google map to the location. # If you'd like any help with it, don't hesitate to open up an issue at github. @@ -12,23 +14,22 @@ import datetime import hashlib -import json import urllib +import time +import csv latitude = 33 longitude = -116 +todayopen = -1 -btcinfo = urllib.urlopen("http://bitcoincharts.com/t/markets.json") -jsoninfo = btcinfo.read() +utc_unix = time.time() +midnight = utc_unix - utc_unix % 86400 +csvinfo = urllib.urlopen("http://bitcoincharts.com/t/trades.csv?symbol=mtgoxUSD&start={0}".format(int(midnight))) -dictinfo = json.loads(jsoninfo) +reader = csv.reader(csvinfo, delimiter=',') -todayopen = -1 -for sym in dictinfo: - if sym["symbol"] == "mtgoxUSD": - todayopen = sym["open"] - else: - continue +# Price is in the second column +todayopen = reader.next()[1] if todayopen < 0: raise ValueError("No data from bitcoincharts, is it down?") From 0f4d4779e5d6754ec5408100af940604b7cb2e29 Mon Sep 17 00:00:00 2001 From: Michael Bemmerl Date: Sun, 20 May 2012 04:55:01 +0200 Subject: [PATCH 09/21] Display error message if BCC has no price data for a given market --- geohash.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/geohash.py b/geohash.py index 5fc8c6e..ab518d3 100644 --- a/geohash.py +++ b/geohash.py @@ -6,13 +6,13 @@ # This script is free software, licensed under the GPLv3, of which you should have received a copy with this software. # If you didn't, I apologize, but you'll be able to find it at /usr/share/common-licences/GPL-3 or http://www.gnu.org/licenses/gpl-3.0.txt -# This script will calculate a geohash location for you based on the first price at Mt. Gox for BTC/USD trades after UTC midnight. +# This script will calculate a geohash location for you based on the first price at a market for BTC trades after midnight (UTC). # Usually, people use the DJIA for this algorithm, but I didn't think that was nerdy enough :) # It will also automagically give you a link to a google map to the location. # If you'd like any help with it, don't hesitate to open up an issue at github. # Have fun! -import datetime +from datetime import date import hashlib import urllib import argparse @@ -26,9 +26,10 @@ parser.add_argument('-m', '--map', help="print URL to a mapping service instead of displaying the raw latitude & longitude.", default="", choices=["google", "osm", "yahoo", "bing"]) args = parser.parse_args() + latitude = args.lat longitude = args.lon -symbol = args.symbol.lower() +symbol = args.symbol map = args.map.lower() # Calculate unix timestamp of last midnight (UTC) @@ -43,15 +44,17 @@ reader = csv.reader(csvinfo, delimiter=',') -# Price is in the second column firstprice = -1 try: + # Price is in the second column firstprice = reader.next()[1] +except StopIteration: + raise ValueError("No price data for symbol \"{0}\".".format(symbol)) except IndexError: raise ValueError("Symbol \"{0}\" not found. Try another one.".format(symbol)) -thestring = str(datetime.date.today()) + "-" + str(firstprice) +thestring = str(date.today()) + "-" + str(firstprice) thehash = hashlib.md5(thestring).hexdigest() @@ -87,7 +90,7 @@ url = "http://www.bing.com/maps/?q={0}+{1}&lvl=11" if map != "": - print url.format(latitude, longitude, "Geohash+for+" + str(datetime.date.today())) + print url.format(latitude, longitude, "Geohash+for+" + str(date.today())) else: print "latitude: " + str(latitude) print "longitude: " + str(longitude) From fce810a6f023a7f07aee0727a2313cc8f73687a4 Mon Sep 17 00:00:00 2001 From: Michael Bemmerl Date: Sun, 20 May 2012 04:55:48 +0200 Subject: [PATCH 10/21] Implemented 30W Time Zone Rule --- geohash.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/geohash.py b/geohash.py index ab518d3..0f04517 100644 --- a/geohash.py +++ b/geohash.py @@ -36,6 +36,10 @@ utc_unix = time.time() midnight = utc_unix - utc_unix % 86400 +# 30W Time Zone Rule (see http://wiki.xkcd.com/geohashing/30W) +if latitude > -30: + midnight -= 86400 + try: csvinfo = urllib.urlopen("http://bitcoincharts.com/t/trades.csv?symbol={0}&start={1}".format(symbol, int(midnight))) except IOError as (errno, strerror): From 715bfcb29bfa375cf64a8f3f97cf9d5a52d51ef0 Mon Sep 17 00:00:00 2001 From: Michael Bemmerl Date: Sun, 27 May 2012 02:04:19 +0200 Subject: [PATCH 11/21] Defined functions for every code part. --- geohash.py | 166 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 95 insertions(+), 71 deletions(-) diff --git a/geohash.py b/geohash.py index db1818b..1d14a32 100644 --- a/geohash.py +++ b/geohash.py @@ -25,76 +25,100 @@ graticule_parser.add_argument('-s', '--symbol', help="symbol of the market (default: mtgoxUSD)", default="mtgoxUSD") graticule_parser.add_argument('-m', '--map', help="print URL to a mapping service instead of displaying the raw latitude & longitude.", default="", choices=["google", "osm", "yahoo", "bing"]) +def get_midnight(thirtyw_rule): + """Calculate unix timestamp of last midnight (UTC)""" + utc_unix = time.time() + midnight = utc_unix - utc_unix % 86400 + + if thirtyw_rule: + midnight -= 86400 + + return midnight + +def get_price(timestamp, symbol): + """Returns the first price after the unix date in timestamp""" + try: + csvinfo = urllib.urlopen("http://bitcoincharts.com/t/trades.csv?symbol={0}&start={1}".format(symbol, int(timestamp))) + except IOError as (errno, strerror): + print "Could not retrieve data from bitcoincharts: " + str(strerror) + raise SystemExit + + reader = csv.reader(csvinfo, delimiter=',') + + firstprice = -1 + + try: + firstprice = reader.next()[1] # Price is in the second column + except StopIteration: + raise ValueError("No price data for symbol \"{0}\".".format(symbol)) + except IndexError: + raise ValueError("Symbol \"{0}\" not found. Try another one.".format(symbol)) + + return firstprice + +def algorithm(date, price): + """Calculate the geohash algorithm and return a tupel with the results for latitude & longitude""" + thestring = str(date) + "-" + str(price) + + thehash = hashlib.md5(thestring).hexdigest() + + hexnum = (thehash[0:16], thehash[16:32]) + + curpow = 1 + decnum = [0.0, 0.0] + + while curpow <= len(hexnum[0]): + decnum[0] += int(hexnum[0][curpow-1], 16) * (1.0 / (16.0 ** curpow)) + decnum[1] += int(hexnum[1][curpow-1], 16) * (1.0 / (16.0 ** curpow)) + curpow += 1 + + return decnum + +def graticule(decnum, latitude, longitude): + """Calculate the geohash coordinates for a graticule.""" + if latitude >= 0: + latitude += decnum[0] + else: + latitude += decnum[0] * -1 + + if longitude >= 0: + longitude += decnum[1] + else: + longitude += decnum[1] * -1 + + return (latitude, longitude) + +def print_coords(map, latitude, longitude): + """Print the coordinates on the console.""" + url = "" + + if map == "google": + url = "http://maps.google.com/maps?q={0},{1}({2})&iwloc=A" + elif map == "osm": + url = "http://osm.org/?mlat={0}&mlon={1}&zoom=12" + elif map == "yahoo": + url = "http://maps.yahoo.com/maps_result?ard=1&mag=9&lat={0}&lon={1}" + elif map == "bing": + url = "http://www.bing.com/maps/?q={0}+{1}&lvl=11" + + if map != "": + print url.format(latitude, longitude, "Geohash+for+" + str(date.today())) + else: + print "latitude: " + str(latitude) + print "longitude: " + str(longitude) + +# +# End of function definitions +# + args = parser.parse_args() -latitude = args.lat -longitude = args.lon -symbol = args.symbol -map = args.map.lower() - -# Calculate unix timestamp of last midnight (UTC) -utc_unix = time.time() -midnight = utc_unix - utc_unix % 86400 - -# 30W Time Zone Rule (see http://wiki.xkcd.com/geohashing/30W) -if latitude > -30: - midnight -= 86400 - -try: - csvinfo = urllib.urlopen("http://bitcoincharts.com/t/trades.csv?symbol={0}&start={1}".format(symbol, int(midnight))) -except IOError as (errno, strerror): - print "Could not retrieve data from bitcoincharts: " + str(strerror) - raise SystemExit - -reader = csv.reader(csvinfo, delimiter=',') - -firstprice = -1 - -try: - # Price is in the second column - firstprice = reader.next()[1] -except StopIteration: - raise ValueError("No price data for symbol \"{0}\".".format(symbol)) -except IndexError: - raise ValueError("Symbol \"{0}\" not found. Try another one.".format(symbol)) - -thestring = str(date.today()) + "-" + str(firstprice) - -thehash = hashlib.md5(thestring).hexdigest() - -hexnum = (thehash[0:16], thehash[16:32]) - -curpow = 1 -decnum = [0.0, 0.0] - -while curpow <= len(hexnum[0]): - decnum[0] += int(hexnum[0][curpow-1], 16) * (1.0 / (16.0 ** curpow)) - decnum[1] += int(hexnum[1][curpow-1], 16) * (1.0 / (16.0 ** curpow)) - curpow += 1 - -if latitude >= 0: - latitude += decnum[0] -else: - latitude += decnum[0] * -1 - -if longitude >= 0: - longitude += decnum[1] -else: - longitude += decnum[1] * -1 - -url = "" - -if map == "google": - url = "http://maps.google.com/maps?q={0},{1}({2})&iwloc=A" -elif map == "osm": - url = "http://osm.org/?mlat={0}&mlon={1}&zoom=12" -elif map == "yahoo": - url = "http://maps.yahoo.com/maps_result?ard=1&mag=9&lat={0}&lon={1}" -elif map == "bing": - url = "http://www.bing.com/maps/?q={0}+{1}&lvl=11" - -if map != "": - print url.format(latitude, longitude, "Geohash+for+" + str(date.today())) -else: - print "latitude: " + str(latitude) - print "longitude: " + str(longitude) +if args.parser == "graticule": + # 30W Time Zone Rule (see http://wiki.xkcd.com/geohashing/30W) + midnight = get_midnight(args.lat > -30) + + price = get_price(midnight, args.symbol) + decnum = algorithm(date.today(), price) + + coords = graticule(decnum, args.lat, args.lon) + print_coords(args.map.lower(), coords[0], coords[1]) From 4b2fa333801c6bc794419b960f9801080e128d15 Mon Sep 17 00:00:00 2001 From: Michael Bemmerl Date: Sun, 27 May 2012 02:06:20 +0200 Subject: [PATCH 12/21] Implemented support for calculation the globalhash. --- geohash.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/geohash.py b/geohash.py index 1d14a32..9a77428 100644 --- a/geohash.py +++ b/geohash.py @@ -19,6 +19,10 @@ subparsers = parser.add_subparsers(help="sub-commands", dest="parser") +globalhash_parser = subparsers.add_parser("globalhash", help="calculate the globalhash") +globalhash_parser.add_argument('-s', '--symbol', help="symbol of the market (default: mtgoxUSD)", default="mtgoxUSD") +globalhash_parser.add_argument('-m', '--map', help="print URL to a mapping service instead of displaying the raw latitude & longitude.", default="", choices=["google", "osm", "yahoo", "bing"]) + graticule_parser = subparsers.add_parser("graticule", help="calculate the geohash of a graticule") graticule_parser.add_argument('lat', help="latitude (integer part)", type=int) graticule_parser.add_argument('lon', help="longitude (integer part)", type=int) @@ -88,6 +92,13 @@ def graticule(decnum, latitude, longitude): return (latitude, longitude) +def globalhash(decnum): + """Calculate the globalhash coordinates.""" + latitude = decnum[0] * 180 - 90 + longitude = decnum[1] * 360 - 180 + + return (latitude, longitude) + def print_coords(map, latitude, longitude): """Print the coordinates on the console.""" url = "" @@ -122,3 +133,11 @@ def print_coords(map, latitude, longitude): coords = graticule(decnum, args.lat, args.lon) print_coords(args.map.lower(), coords[0], coords[1]) +elif args.parser == "globalhash": + midnight = get_midnight(True) # Globalhash is always with 30W rule. + + price = get_price(midnight, args.symbol) + decnum = algorithm(date.today(), price) + + coords = globalhash(decnum) + print_coords(args.map.lower(), coords[0], coords[1]) From 10140a1d8a44dbf7075763357081a34fa56ab8b1 Mon Sep 17 00:00:00 2001 From: Michael Bemmerl Date: Sun, 27 May 2012 02:11:36 +0200 Subject: [PATCH 13/21] Error checking on latitude & longitude input. --- geohash.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/geohash.py b/geohash.py index 9a77428..9bcb237 100644 --- a/geohash.py +++ b/geohash.py @@ -125,6 +125,9 @@ def print_coords(map, latitude, longitude): args = parser.parse_args() if args.parser == "graticule": + if abs(args.lat) > 90 or abs(args.lon) > 180: + raise ValueError("Graticule coordinates out of range.") + # 30W Time Zone Rule (see http://wiki.xkcd.com/geohashing/30W) midnight = get_midnight(args.lat > -30) From 3721e73d86d27d4544cad89c2badcdcc018ca47c Mon Sep 17 00:00:00 2001 From: Michael Bemmerl Date: Sun, 27 May 2012 02:28:25 +0200 Subject: [PATCH 14/21] List available symbols at bitcoincharts. The code got somehow lost while merging the list-symbols branch in 8e776de1cdcd4ee53ec3abef57652a31173bba3e. --- geohash.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/geohash.py b/geohash.py index 9bcb237..3964520 100644 --- a/geohash.py +++ b/geohash.py @@ -13,7 +13,7 @@ # Have fun! from datetime import date -import hashlib, urllib, argparse, time, csv +import hashlib, urllib, argparse, time, csv, json parser = argparse.ArgumentParser(description="Calculate a geohash location based on the midnight price for BTC trades.") @@ -29,6 +29,8 @@ graticule_parser.add_argument('-s', '--symbol', help="symbol of the market (default: mtgoxUSD)", default="mtgoxUSD") graticule_parser.add_argument('-m', '--map', help="print URL to a mapping service instead of displaying the raw latitude & longitude.", default="", choices=["google", "osm", "yahoo", "bing"]) +list_symbols_parser = subparsers.add_parser("list-symbols", help="list all available symbols") + def get_midnight(thirtyw_rule): """Calculate unix timestamp of last midnight (UTC)""" utc_unix = time.time() @@ -118,6 +120,18 @@ def print_coords(map, latitude, longitude): print "latitude: " + str(latitude) print "longitude: " + str(longitude) +def list_symbols(): + try: + btcinfo = urllib.urlopen("http://bitcoincharts.com/t/markets.json") + jsoninfo = btcinfo.read() + jsoninfo = json.loads(jsoninfo) + + for sym in jsoninfo: + print sym["symbol"] + except IOError as (errno, strerror): + print "Could not retrieve data from bitcoincharts: " + str(strerror) + raise SystemExit + # # End of function definitions # @@ -144,3 +158,5 @@ def print_coords(map, latitude, longitude): coords = globalhash(decnum) print_coords(args.map.lower(), coords[0], coords[1]) +elif args.parser == "list-symbols": + list_symbols() From 5b27910e2f1cf258a51d4e1a7f605e1d1e0c06ac Mon Sep 17 00:00:00 2001 From: Michael Bemmerl Date: Sun, 27 May 2012 02:37:21 +0200 Subject: [PATCH 15/21] Print latest market trade time also. --- geohash.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/geohash.py b/geohash.py index 3964520..e2889b8 100644 --- a/geohash.py +++ b/geohash.py @@ -12,7 +12,7 @@ # If you'd like any help with it, don't hesitate to open up an issue at github. # Have fun! -from datetime import date +from datetime import date, datetime import hashlib, urllib, argparse, time, csv, json parser = argparse.ArgumentParser(description="Calculate a geohash location based on the midnight price for BTC trades.") @@ -121,17 +121,20 @@ def print_coords(map, latitude, longitude): print "longitude: " + str(longitude) def list_symbols(): + jsoninfo = "" + try: btcinfo = urllib.urlopen("http://bitcoincharts.com/t/markets.json") jsoninfo = btcinfo.read() jsoninfo = json.loads(jsoninfo) - - for sym in jsoninfo: - print sym["symbol"] except IOError as (errno, strerror): print "Could not retrieve data from bitcoincharts: " + str(strerror) raise SystemExit + print "symbol name".ljust(20) + "last trade" + for sym in jsoninfo: + print sym["symbol"].ljust(20) + str(datetime.fromtimestamp(int(sym["latest_trade"]))) + # # End of function definitions # From cc72e08d372cc863dd66f3982d717db8353c43ff Mon Sep 17 00:00:00 2001 From: Michael Bemmerl Date: Sat, 28 Feb 2015 01:34:24 +0100 Subject: [PATCH 16/21] URL of Bitcoincharts.com API updated --- geohash.py | 330 ++++++++++++++++++++++++++--------------------------- 1 file changed, 165 insertions(+), 165 deletions(-) diff --git a/geohash.py b/geohash.py index e2889b8..46276a5 100644 --- a/geohash.py +++ b/geohash.py @@ -1,165 +1,165 @@ -#!/usr/bin/python - -# Copyright (C) 2011 Mark Holmquist -# Copyright (C) 2011, 2012 Michael Bemmerl - -# This script is free software, licensed under the GPLv3, of which you should have received a copy with this software. -# If you didn't, I apologize, but you'll be able to find it at /usr/share/common-licences/GPL-3 or http://www.gnu.org/licenses/gpl-3.0.txt - -# This script will calculate a geohash location for you based on the first price at a market for BTC trades after midnight (UTC). -# Usually, people use the DJIA for this algorithm, but I didn't think that was nerdy enough :) -# It will also automagically give you a link to a google map to the location. -# If you'd like any help with it, don't hesitate to open up an issue at github. -# Have fun! - -from datetime import date, datetime -import hashlib, urllib, argparse, time, csv, json - -parser = argparse.ArgumentParser(description="Calculate a geohash location based on the midnight price for BTC trades.") - -subparsers = parser.add_subparsers(help="sub-commands", dest="parser") - -globalhash_parser = subparsers.add_parser("globalhash", help="calculate the globalhash") -globalhash_parser.add_argument('-s', '--symbol', help="symbol of the market (default: mtgoxUSD)", default="mtgoxUSD") -globalhash_parser.add_argument('-m', '--map', help="print URL to a mapping service instead of displaying the raw latitude & longitude.", default="", choices=["google", "osm", "yahoo", "bing"]) - -graticule_parser = subparsers.add_parser("graticule", help="calculate the geohash of a graticule") -graticule_parser.add_argument('lat', help="latitude (integer part)", type=int) -graticule_parser.add_argument('lon', help="longitude (integer part)", type=int) -graticule_parser.add_argument('-s', '--symbol', help="symbol of the market (default: mtgoxUSD)", default="mtgoxUSD") -graticule_parser.add_argument('-m', '--map', help="print URL to a mapping service instead of displaying the raw latitude & longitude.", default="", choices=["google", "osm", "yahoo", "bing"]) - -list_symbols_parser = subparsers.add_parser("list-symbols", help="list all available symbols") - -def get_midnight(thirtyw_rule): - """Calculate unix timestamp of last midnight (UTC)""" - utc_unix = time.time() - midnight = utc_unix - utc_unix % 86400 - - if thirtyw_rule: - midnight -= 86400 - - return midnight - -def get_price(timestamp, symbol): - """Returns the first price after the unix date in timestamp""" - try: - csvinfo = urllib.urlopen("http://bitcoincharts.com/t/trades.csv?symbol={0}&start={1}".format(symbol, int(timestamp))) - except IOError as (errno, strerror): - print "Could not retrieve data from bitcoincharts: " + str(strerror) - raise SystemExit - - reader = csv.reader(csvinfo, delimiter=',') - - firstprice = -1 - - try: - firstprice = reader.next()[1] # Price is in the second column - except StopIteration: - raise ValueError("No price data for symbol \"{0}\".".format(symbol)) - except IndexError: - raise ValueError("Symbol \"{0}\" not found. Try another one.".format(symbol)) - - return firstprice - -def algorithm(date, price): - """Calculate the geohash algorithm and return a tupel with the results for latitude & longitude""" - thestring = str(date) + "-" + str(price) - - thehash = hashlib.md5(thestring).hexdigest() - - hexnum = (thehash[0:16], thehash[16:32]) - - curpow = 1 - decnum = [0.0, 0.0] - - while curpow <= len(hexnum[0]): - decnum[0] += int(hexnum[0][curpow-1], 16) * (1.0 / (16.0 ** curpow)) - decnum[1] += int(hexnum[1][curpow-1], 16) * (1.0 / (16.0 ** curpow)) - curpow += 1 - - return decnum - -def graticule(decnum, latitude, longitude): - """Calculate the geohash coordinates for a graticule.""" - if latitude >= 0: - latitude += decnum[0] - else: - latitude += decnum[0] * -1 - - if longitude >= 0: - longitude += decnum[1] - else: - longitude += decnum[1] * -1 - - return (latitude, longitude) - -def globalhash(decnum): - """Calculate the globalhash coordinates.""" - latitude = decnum[0] * 180 - 90 - longitude = decnum[1] * 360 - 180 - - return (latitude, longitude) - -def print_coords(map, latitude, longitude): - """Print the coordinates on the console.""" - url = "" - - if map == "google": - url = "http://maps.google.com/maps?q={0},{1}({2})&iwloc=A" - elif map == "osm": - url = "http://osm.org/?mlat={0}&mlon={1}&zoom=12" - elif map == "yahoo": - url = "http://maps.yahoo.com/maps_result?ard=1&mag=9&lat={0}&lon={1}" - elif map == "bing": - url = "http://www.bing.com/maps/?q={0}+{1}&lvl=11" - - if map != "": - print url.format(latitude, longitude, "Geohash+for+" + str(date.today())) - else: - print "latitude: " + str(latitude) - print "longitude: " + str(longitude) - -def list_symbols(): - jsoninfo = "" - - try: - btcinfo = urllib.urlopen("http://bitcoincharts.com/t/markets.json") - jsoninfo = btcinfo.read() - jsoninfo = json.loads(jsoninfo) - except IOError as (errno, strerror): - print "Could not retrieve data from bitcoincharts: " + str(strerror) - raise SystemExit - - print "symbol name".ljust(20) + "last trade" - for sym in jsoninfo: - print sym["symbol"].ljust(20) + str(datetime.fromtimestamp(int(sym["latest_trade"]))) - -# -# End of function definitions -# - -args = parser.parse_args() - -if args.parser == "graticule": - if abs(args.lat) > 90 or abs(args.lon) > 180: - raise ValueError("Graticule coordinates out of range.") - - # 30W Time Zone Rule (see http://wiki.xkcd.com/geohashing/30W) - midnight = get_midnight(args.lat > -30) - - price = get_price(midnight, args.symbol) - decnum = algorithm(date.today(), price) - - coords = graticule(decnum, args.lat, args.lon) - print_coords(args.map.lower(), coords[0], coords[1]) -elif args.parser == "globalhash": - midnight = get_midnight(True) # Globalhash is always with 30W rule. - - price = get_price(midnight, args.symbol) - decnum = algorithm(date.today(), price) - - coords = globalhash(decnum) - print_coords(args.map.lower(), coords[0], coords[1]) -elif args.parser == "list-symbols": - list_symbols() +#!/usr/bin/python + +# Copyright (C) 2011 Mark Holmquist +# Copyright (C) 2011, 2012, 2015 Michael Bemmerl + +# This script is free software, licensed under the GPLv3, of which you should have received a copy with this software. +# If you didn't, I apologize, but you'll be able to find it at /usr/share/common-licences/GPL-3 or http://www.gnu.org/licenses/gpl-3.0.txt + +# This script will calculate a geohash location for you based on the first price at a market for BTC trades after midnight (UTC). +# Usually, people use the DJIA for this algorithm, but I didn't think that was nerdy enough :) +# It will also automagically give you a link to a google map to the location. +# If you'd like any help with it, don't hesitate to open up an issue at github. +# Have fun! + +from datetime import date, datetime +import hashlib, urllib, argparse, time, csv, json + +parser = argparse.ArgumentParser(description="Calculate a geohash location based on the midnight price for BTC trades.") + +subparsers = parser.add_subparsers(help="sub-commands", dest="parser") + +globalhash_parser = subparsers.add_parser("globalhash", help="calculate the globalhash") +globalhash_parser.add_argument('-s', '--symbol', help="symbol of the market (default: bitfinexUSD)", default="bitfinexUSD") +globalhash_parser.add_argument('-m', '--map', help="print URL to a mapping service instead of displaying the raw latitude & longitude.", default="", choices=["google", "osm", "yahoo", "bing"]) + +graticule_parser = subparsers.add_parser("graticule", help="calculate the geohash of a graticule") +graticule_parser.add_argument('lat', help="latitude (integer part)", type=int) +graticule_parser.add_argument('lon', help="longitude (integer part)", type=int) +graticule_parser.add_argument('-s', '--symbol', help="symbol of the market (default: bitfinexUSD)", default="bitfinexUSD") +graticule_parser.add_argument('-m', '--map', help="print URL to a mapping service instead of displaying the raw latitude & longitude.", default="", choices=["google", "osm", "yahoo", "bing"]) + +list_symbols_parser = subparsers.add_parser("list-symbols", help="list all available symbols") + +def get_midnight(thirtyw_rule): + """Calculate unix timestamp of last midnight (UTC)""" + utc_unix = time.time() + midnight = utc_unix - utc_unix % 86400 + + if thirtyw_rule: + midnight -= 86400 + + return midnight + +def get_price(timestamp, symbol): + """Returns the first price after the unix date in timestamp""" + try: + csvinfo = urllib.urlopen("http://api.bitcoincharts.com/v1/trades.csv?symbol={0}&start={1}".format(symbol, int(timestamp))) + except IOError as (errno, strerror): + print "Could not retrieve data from bitcoincharts: " + str(strerror) + raise SystemExit + + reader = csv.reader(csvinfo, delimiter=',') + + firstprice = -1 + + try: + firstprice = reader.next()[1] # Price is in the second column + except StopIteration: + raise ValueError("No price data for symbol \"{0}\".".format(symbol)) + except IndexError: + raise ValueError("Symbol \"{0}\" not found. Try another one.".format(symbol)) + + return firstprice + +def algorithm(date, price): + """Calculate the geohash algorithm and return a tupel with the results for latitude & longitude""" + thestring = str(date) + "-" + str(price) + + thehash = hashlib.md5(thestring).hexdigest() + + hexnum = (thehash[0:16], thehash[16:32]) + + curpow = 1 + decnum = [0.0, 0.0] + + while curpow <= len(hexnum[0]): + decnum[0] += int(hexnum[0][curpow-1], 16) * (1.0 / (16.0 ** curpow)) + decnum[1] += int(hexnum[1][curpow-1], 16) * (1.0 / (16.0 ** curpow)) + curpow += 1 + + return decnum + +def graticule(decnum, latitude, longitude): + """Calculate the geohash coordinates for a graticule.""" + if latitude >= 0: + latitude += decnum[0] + else: + latitude += decnum[0] * -1 + + if longitude >= 0: + longitude += decnum[1] + else: + longitude += decnum[1] * -1 + + return (latitude, longitude) + +def globalhash(decnum): + """Calculate the globalhash coordinates.""" + latitude = decnum[0] * 180 - 90 + longitude = decnum[1] * 360 - 180 + + return (latitude, longitude) + +def print_coords(map, latitude, longitude): + """Print the coordinates on the console.""" + url = "" + + if map == "google": + url = "http://maps.google.com/maps?q={0},{1}({2})&iwloc=A" + elif map == "osm": + url = "http://osm.org/?mlat={0}&mlon={1}&zoom=12" + elif map == "yahoo": + url = "http://maps.yahoo.com/maps_result?ard=1&mag=9&lat={0}&lon={1}" + elif map == "bing": + url = "http://www.bing.com/maps/?q={0}+{1}&lvl=11" + + if map != "": + print url.format(latitude, longitude, "Geohash+for+" + str(date.today())) + else: + print "latitude: " + str(latitude) + print "longitude: " + str(longitude) + +def list_symbols(): + jsoninfo = "" + + try: + btcinfo = urllib.urlopen("http://api.bitcoincharts.com/v1/markets.json") + jsoninfo = btcinfo.read() + jsoninfo = json.loads(jsoninfo) + except IOError as (errno, strerror): + print "Could not retrieve data from bitcoincharts: " + str(strerror) + raise SystemExit + + print "symbol name".ljust(20) + "last trade" + for sym in jsoninfo: + print sym["symbol"].ljust(20) + str(datetime.fromtimestamp(int(sym["latest_trade"]))) + +# +# End of function definitions +# + +args = parser.parse_args() + +if args.parser == "graticule": + if abs(args.lat) > 90 or abs(args.lon) > 180: + raise ValueError("Graticule coordinates out of range.") + + # 30W Time Zone Rule (see http://wiki.xkcd.com/geohashing/30W) + midnight = get_midnight(args.lat > -30) + + price = get_price(midnight, args.symbol) + decnum = algorithm(date.today(), price) + + coords = graticule(decnum, args.lat, args.lon) + print_coords(args.map.lower(), coords[0], coords[1]) +elif args.parser == "globalhash": + midnight = get_midnight(True) # Globalhash is always with 30W rule. + + price = get_price(midnight, args.symbol) + decnum = algorithm(date.today(), price) + + coords = globalhash(decnum) + print_coords(args.map.lower(), coords[0], coords[1]) +elif args.parser == "list-symbols": + list_symbols() From 6a53c22c04775f602d253e94dfb685f2f3219537 Mon Sep 17 00:00:00 2001 From: Michael Bemmerl Date: Sat, 28 Feb 2015 02:20:26 +0100 Subject: [PATCH 17/21] Fixed mapping service URLs. --- geohash.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/geohash.py b/geohash.py index 46276a5..e0a4b77 100644 --- a/geohash.py +++ b/geohash.py @@ -108,14 +108,17 @@ def print_coords(map, latitude, longitude): if map == "google": url = "http://maps.google.com/maps?q={0},{1}({2})&iwloc=A" elif map == "osm": - url = "http://osm.org/?mlat={0}&mlon={1}&zoom=12" + url = "http://osm.org/?mlat={0}&mlon={1}#map=14/{0}/{1}" elif map == "yahoo": - url = "http://maps.yahoo.com/maps_result?ard=1&mag=9&lat={0}&lon={1}" + url = "https://maps.yahoo.com/map/?lat={0}&lon={1}&bb={2},{3},{4},{5}" elif map == "bing": - url = "http://www.bing.com/maps/?q={0}+{1}&lvl=11" + url = "https://www.bing.com/maps/?v=2&cp={0}~{1}&lvl=14&dir=0&sp=point.{0}_{1}_{2}" if map != "": - print url.format(latitude, longitude, "Geohash+for+" + str(date.today())) + if map == "yahoo": + print url.format(latitude, longitude, latitude + 0.01, longitude + 0.01, latitude - 0.01, longitude - 0.01) + else: + print url.format(latitude, longitude, "Geohash+for+" + str(date.today())) else: print "latitude: " + str(latitude) print "longitude: " + str(longitude) From a028b784d8d917e46a2fa261f0bd8bc92656d6ee Mon Sep 17 00:00:00 2001 From: Michael Bemmerl Date: Sat, 28 Feb 2015 02:21:01 +0100 Subject: [PATCH 18/21] Using SSL on all URLs, except for OSM. --- geohash.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/geohash.py b/geohash.py index e0a4b77..7da49dd 100644 --- a/geohash.py +++ b/geohash.py @@ -44,7 +44,7 @@ def get_midnight(thirtyw_rule): def get_price(timestamp, symbol): """Returns the first price after the unix date in timestamp""" try: - csvinfo = urllib.urlopen("http://api.bitcoincharts.com/v1/trades.csv?symbol={0}&start={1}".format(symbol, int(timestamp))) + csvinfo = urllib.urlopen("https://api.bitcoincharts.com/v1/trades.csv?symbol={0}&start={1}".format(symbol, int(timestamp))) except IOError as (errno, strerror): print "Could not retrieve data from bitcoincharts: " + str(strerror) raise SystemExit @@ -106,7 +106,7 @@ def print_coords(map, latitude, longitude): url = "" if map == "google": - url = "http://maps.google.com/maps?q={0},{1}({2})&iwloc=A" + url = "https://maps.google.com/maps?q={0},{1}({2})&iwloc=A" elif map == "osm": url = "http://osm.org/?mlat={0}&mlon={1}#map=14/{0}/{1}" elif map == "yahoo": @@ -127,7 +127,7 @@ def list_symbols(): jsoninfo = "" try: - btcinfo = urllib.urlopen("http://api.bitcoincharts.com/v1/markets.json") + btcinfo = urllib.urlopen("https://api.bitcoincharts.com/v1/markets.json") jsoninfo = btcinfo.read() jsoninfo = json.loads(jsoninfo) except IOError as (errno, strerror): From 0d57766c7f926f1b7d370b91a32ca4289fc9628e Mon Sep 17 00:00:00 2001 From: Michael Bemmerl Date: Sat, 5 Nov 2016 21:54:18 +0100 Subject: [PATCH 19/21] Using coinbaseUSD as default symbol. --- geohash.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/geohash.py b/geohash.py index 7da49dd..71655fa 100644 --- a/geohash.py +++ b/geohash.py @@ -1,7 +1,7 @@ #!/usr/bin/python # Copyright (C) 2011 Mark Holmquist -# Copyright (C) 2011, 2012, 2015 Michael Bemmerl +# Copyright (C) 2011, 2012, 2015, 2016 Michael Bemmerl # This script is free software, licensed under the GPLv3, of which you should have received a copy with this software. # If you didn't, I apologize, but you'll be able to find it at /usr/share/common-licences/GPL-3 or http://www.gnu.org/licenses/gpl-3.0.txt @@ -20,13 +20,13 @@ subparsers = parser.add_subparsers(help="sub-commands", dest="parser") globalhash_parser = subparsers.add_parser("globalhash", help="calculate the globalhash") -globalhash_parser.add_argument('-s', '--symbol', help="symbol of the market (default: bitfinexUSD)", default="bitfinexUSD") +globalhash_parser.add_argument('-s', '--symbol', help="symbol of the market (default: coinbaseUSD)", default="coinbaseUSD") globalhash_parser.add_argument('-m', '--map', help="print URL to a mapping service instead of displaying the raw latitude & longitude.", default="", choices=["google", "osm", "yahoo", "bing"]) graticule_parser = subparsers.add_parser("graticule", help="calculate the geohash of a graticule") graticule_parser.add_argument('lat', help="latitude (integer part)", type=int) graticule_parser.add_argument('lon', help="longitude (integer part)", type=int) -graticule_parser.add_argument('-s', '--symbol', help="symbol of the market (default: bitfinexUSD)", default="bitfinexUSD") +graticule_parser.add_argument('-s', '--symbol', help="symbol of the market (default: coinbaseUSD)", default="coinbaseUSD") graticule_parser.add_argument('-m', '--map', help="print URL to a mapping service instead of displaying the raw latitude & longitude.", default="", choices=["google", "osm", "yahoo", "bing"]) list_symbols_parser = subparsers.add_parser("list-symbols", help="list all available symbols") From 40498416afd2cc4d129cc547b4fc5bcbefb7dff9 Mon Sep 17 00:00:00 2001 From: Michael Bemmerl Date: Sun, 12 Apr 2020 00:04:57 +0200 Subject: [PATCH 20/21] Update for Python 3 compatibility (tested with Python 3.8.2). --- geohash.py | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/geohash.py b/geohash.py index 71655fa..3f717b2 100644 --- a/geohash.py +++ b/geohash.py @@ -1,7 +1,7 @@ #!/usr/bin/python # Copyright (C) 2011 Mark Holmquist -# Copyright (C) 2011, 2012, 2015, 2016 Michael Bemmerl +# Copyright (C) 2011, 2012, 2015, 2016, 2020 Michael Bemmerl # This script is free software, licensed under the GPLv3, of which you should have received a copy with this software. # If you didn't, I apologize, but you'll be able to find it at /usr/share/common-licences/GPL-3 or http://www.gnu.org/licenses/gpl-3.0.txt @@ -13,7 +13,7 @@ # Have fun! from datetime import date, datetime -import hashlib, urllib, argparse, time, csv, json +import hashlib, urllib.request, urllib.parse, urllib.error, argparse, time, csv, json parser = argparse.ArgumentParser(description="Calculate a geohash location based on the midnight price for BTC trades.") @@ -44,17 +44,19 @@ def get_midnight(thirtyw_rule): def get_price(timestamp, symbol): """Returns the first price after the unix date in timestamp""" try: - csvinfo = urllib.urlopen("https://api.bitcoincharts.com/v1/trades.csv?symbol={0}&start={1}".format(symbol, int(timestamp))) - except IOError as (errno, strerror): - print "Could not retrieve data from bitcoincharts: " + str(strerror) + csvinfo = urllib.request.urlopen("https://api.bitcoincharts.com/v1/trades.csv?symbol={0}&start={1}".format(symbol, int(timestamp))) + except IOError as e: + (errno, strerror) = e.args + print("Could not retrieve data from bitcoincharts: " + str(strerror)) raise SystemExit - reader = csv.reader(csvinfo, delimiter=',') + firstline = csvinfo.read().decode().splitlines()[0] + reader = csv.reader([firstline], delimiter=',') firstprice = -1 try: - firstprice = reader.next()[1] # Price is in the second column + firstprice = next(reader)[1] # Price is in the second column except StopIteration: raise ValueError("No price data for symbol \"{0}\".".format(symbol)) except IndexError: @@ -66,7 +68,7 @@ def algorithm(date, price): """Calculate the geohash algorithm and return a tupel with the results for latitude & longitude""" thestring = str(date) + "-" + str(price) - thehash = hashlib.md5(thestring).hexdigest() + thehash = hashlib.md5(thestring.encode('utf-8')).hexdigest() hexnum = (thehash[0:16], thehash[16:32]) @@ -116,27 +118,28 @@ def print_coords(map, latitude, longitude): if map != "": if map == "yahoo": - print url.format(latitude, longitude, latitude + 0.01, longitude + 0.01, latitude - 0.01, longitude - 0.01) + print(url.format(latitude, longitude, latitude + 0.01, longitude + 0.01, latitude - 0.01, longitude - 0.01)) else: - print url.format(latitude, longitude, "Geohash+for+" + str(date.today())) + print(url.format(latitude, longitude, "Geohash+for+" + str(date.today()))) else: - print "latitude: " + str(latitude) - print "longitude: " + str(longitude) + print("latitude: " + str(latitude)) + print("longitude: " + str(longitude)) def list_symbols(): jsoninfo = "" try: - btcinfo = urllib.urlopen("https://api.bitcoincharts.com/v1/markets.json") + btcinfo = urllib.request.urlopen("https://api.bitcoincharts.com/v1/markets.json") jsoninfo = btcinfo.read() jsoninfo = json.loads(jsoninfo) - except IOError as (errno, strerror): - print "Could not retrieve data from bitcoincharts: " + str(strerror) + except IOError as e: + (errno, strerror) = e.args + print("Could not retrieve data from bitcoincharts: " + str(strerror)) raise SystemExit - print "symbol name".ljust(20) + "last trade" + print("symbol name".ljust(20) + "last trade") for sym in jsoninfo: - print sym["symbol"].ljust(20) + str(datetime.fromtimestamp(int(sym["latest_trade"]))) + print(sym["symbol"].ljust(20) + str(datetime.fromtimestamp(int(sym["latest_trade"])))) # # End of function definitions From 343ac96eb0fa45851a7243bd4ac5b15af449b627 Mon Sep 17 00:00:00 2001 From: Michael Bemmerl Date: Sun, 12 Apr 2020 00:06:15 +0200 Subject: [PATCH 21/21] Using different symbol, since the old one returned old data only. --- geohash.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/geohash.py b/geohash.py index 3f717b2..32624da 100644 --- a/geohash.py +++ b/geohash.py @@ -20,13 +20,13 @@ subparsers = parser.add_subparsers(help="sub-commands", dest="parser") globalhash_parser = subparsers.add_parser("globalhash", help="calculate the globalhash") -globalhash_parser.add_argument('-s', '--symbol', help="symbol of the market (default: coinbaseUSD)", default="coinbaseUSD") +globalhash_parser.add_argument('-s', '--symbol', help="symbol of the market (default: krakenUSD)", default="krakenUSD") globalhash_parser.add_argument('-m', '--map', help="print URL to a mapping service instead of displaying the raw latitude & longitude.", default="", choices=["google", "osm", "yahoo", "bing"]) graticule_parser = subparsers.add_parser("graticule", help="calculate the geohash of a graticule") graticule_parser.add_argument('lat', help="latitude (integer part)", type=int) graticule_parser.add_argument('lon', help="longitude (integer part)", type=int) -graticule_parser.add_argument('-s', '--symbol', help="symbol of the market (default: coinbaseUSD)", default="coinbaseUSD") +graticule_parser.add_argument('-s', '--symbol', help="symbol of the market (default: krakenUSD)", default="krakenUSD") graticule_parser.add_argument('-m', '--map', help="print URL to a mapping service instead of displaying the raw latitude & longitude.", default="", choices=["google", "osm", "yahoo", "bing"]) list_symbols_parser = subparsers.add_parser("list-symbols", help="list all available symbols")