Add support for ipv4 prefixes under 16
This commit is contained in:
parent
4f10a22ad8
commit
5eee66d071
34
ipapi.py
34
ipapi.py
|
@ -23,7 +23,8 @@ parser.add_argument("--log-level", default = "INFO", help = "the log level use f
|
||||||
parser.add_argument("-l", "--limit", default = 3600, type = int, help = "the number of requests per hour to limit usage of the api to (default: %(default)s)")
|
parser.add_argument("-l", "--limit", default = 3600, type = int, help = "the number of requests per hour to limit usage of the api to (default: %(default)s)")
|
||||||
parser.add_argument("-r", "--raws", help = "the path containing raw tile data (default: %(default)s)")
|
parser.add_argument("-r", "--raws", help = "the path containing raw tile data (default: %(default)s)")
|
||||||
parser.add_argument("-t", "--tile-size", default = 256, type = int, help = "the tile size to use (default: %(default)s)")
|
parser.add_argument("-t", "--tile-size", default = 256, type = int, help = "the tile size to use (default: %(default)s)")
|
||||||
parser.add_argument("-c", "--cache-size", default = 4096, type = int, help = "the number of tiles to keep in the cache (default: %(default)s)")
|
parser.add_argument("-c", "--cache-size", default = 4096, type = int, help = "the number of compressed tiles to keep in the cache (default: %(default)s)")
|
||||||
|
parser.add_argument("-d", "--decomp-cache-size", default = 1024, type = int, help = "the number of decompressed tiles to keep in the cache (default: %(default)s)")
|
||||||
parser.add_argument("-v", "--variants", default = "density,rtt", help = "the variants to return data for (default: %(default)s)")
|
parser.add_argument("-v", "--variants", default = "density,rtt", help = "the variants to return data for (default: %(default)s)")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
@ -94,9 +95,15 @@ if args.raws:
|
||||||
data_bytes = 4
|
data_bytes = 4
|
||||||
|
|
||||||
@lru_cache(args.cache_size)
|
@lru_cache(args.cache_size)
|
||||||
def get_raw_data(path: Path):
|
def get_raw_data_compressed(path: Path):
|
||||||
print(f"reading file '{path}'...")
|
print(f"reading file '{path}'...")
|
||||||
return decompress(path.read_bytes())
|
return path.read_bytes()
|
||||||
|
|
||||||
|
@lru_cache(args.decomp_cache_size)
|
||||||
|
def get_raw_data(path: Path):
|
||||||
|
compressed_data = get_raw_data_compressed(path)
|
||||||
|
print(f"decompressing file '{path}'...")
|
||||||
|
return decompress(compressed_data)
|
||||||
|
|
||||||
@app.get("/api/scandata/:date/:variant/tile/:z/:y/:x")
|
@app.get("/api/scandata/:date/:variant/tile/:z/:y/:x")
|
||||||
def get_info_tile(request: Request):
|
def get_info_tile(request: Request):
|
||||||
|
@ -106,19 +113,27 @@ if args.raws:
|
||||||
variant = unquote(request.path_params["variant"])
|
variant = unquote(request.path_params["variant"])
|
||||||
if variant not in variants_set:
|
if variant not in variants_set:
|
||||||
return error_response("Invalid variant provided", 400)
|
return error_response("Invalid variant provided", 400)
|
||||||
|
try:
|
||||||
z = int(unquote(request.path_params["z"]))
|
z = int(unquote(request.path_params["z"]))
|
||||||
if z < 0:
|
except ValueError:
|
||||||
return error_response("Invalid z value provided", 400)
|
return error_response("Invalid z value provided", 400)
|
||||||
|
try:
|
||||||
y = int(unquote(request.path_params["y"]))
|
y = int(unquote(request.path_params["y"]))
|
||||||
if y < 0:
|
if y < 0:
|
||||||
|
raise ValueError()
|
||||||
|
except ValueError:
|
||||||
return error_response("Invalid y value provided", 400)
|
return error_response("Invalid y value provided", 400)
|
||||||
|
try:
|
||||||
x = int(unquote(request.path_params["x"]))
|
x = int(unquote(request.path_params["x"]))
|
||||||
if x < 0:
|
if x < 0:
|
||||||
|
raise ValueError()
|
||||||
|
except ValueError:
|
||||||
return error_response("Invalid x value provided", 400)
|
return error_response("Invalid x value provided", 400)
|
||||||
y_tile, y_off = divmod(y, tile_size)
|
y_tile, y_off = divmod(y, tile_size)
|
||||||
x_tile, x_off = divmod(x, tile_size)
|
x_tile, x_off = divmod(x, tile_size)
|
||||||
off = y_off * tile_size * data_bytes + x_off * data_bytes
|
|
||||||
path = raws_path / date / variant / f"{z}" / f"{y_tile}" / f"{x_tile}.bin"
|
path = raws_path / date / variant / f"{z}" / f"{y_tile}" / f"{x_tile}.bin"
|
||||||
|
img_size = (tile_size >> -z) if z < 0 else tile_size
|
||||||
|
off = y_off * img_size * data_bytes + x_off * data_bytes
|
||||||
try:
|
try:
|
||||||
value = int.from_bytes(get_raw_data(path)[off : off + data_bytes], "little")
|
value = int.from_bytes(get_raw_data(path)[off : off + data_bytes], "little")
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
|
@ -132,10 +147,13 @@ if args.raws:
|
||||||
def get_info_range(request: Request):
|
def get_info_range(request: Request):
|
||||||
try:
|
try:
|
||||||
range = IPv4Network(unquote(request.path_params["range"]), strict = False)
|
range = IPv4Network(unquote(request.path_params["range"]), strict = False)
|
||||||
except:
|
except ValueError:
|
||||||
return error_response("Invalid IPv4 range", 400)
|
return error_response("Invalid IPv4 range", 400)
|
||||||
if range.prefixlen < 16:
|
if range.prefixlen % 2 != 0:
|
||||||
return error_response("Prefix length of IPv4 range must be 16 or above", 400)
|
return error_response("Prefix length of IPv4 range must be even", 400)
|
||||||
|
if range.prefixlen == 0:
|
||||||
|
x, y = 0, 0
|
||||||
|
else:
|
||||||
x, y = HilbertCurve(range.prefixlen // 2, 2).point_from_distance(int(range.network_address) // (1 << (32 - range.prefixlen)))
|
x, y = HilbertCurve(range.prefixlen // 2, 2).point_from_distance(int(range.network_address) // (1 << (32 - range.prefixlen)))
|
||||||
z = (range.prefixlen - 16) // 2
|
z = (range.prefixlen - 16) // 2
|
||||||
request.path_params["x"] = str(x)
|
request.path_params["x"] = str(x)
|
||||||
|
|
Loading…
Reference in New Issue