2020-03-04 18:07:56 +01:00
|
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
# PYTHON_ARGCOMPLETE_OK
|
|
|
|
|
import argcomplete, argparse
|
2020-03-05 14:05:12 +01:00
|
|
|
|
import json as JSON
|
2020-03-04 18:07:56 +01:00
|
|
|
|
import requests
|
|
|
|
|
import sys
|
|
|
|
|
|
2020-07-10 14:14:19 +02:00
|
|
|
|
from datetime import datetime, timedelta, timezone
|
|
|
|
|
from dateutil import parser as dtparser
|
2020-03-04 18:07:56 +01:00
|
|
|
|
|
2020-03-09 18:12:26 +01:00
|
|
|
|
from pyEDSM.edsm.exception import ServerError, NotFoundError
|
|
|
|
|
|
|
|
|
|
# ===========================================================================
|
|
|
|
|
|
|
|
|
|
def querystations(url, params):
|
|
|
|
|
response = requests.post(url, params)
|
|
|
|
|
if response.status_code != 200:
|
|
|
|
|
raise ServerError(url, params)
|
|
|
|
|
json = response.json()
|
|
|
|
|
if json["count"] == 0:
|
|
|
|
|
raise NotFoundError()
|
|
|
|
|
return json
|
|
|
|
|
|
2020-03-05 14:05:12 +01:00
|
|
|
|
# ===========================================================================
|
2020-03-04 18:07:56 +01:00
|
|
|
|
|
2021-03-14 14:39:57 +01:00
|
|
|
|
def getNearestSystem(coords, raw=False):
|
2020-03-09 17:39:44 +01:00
|
|
|
|
params = {
|
|
|
|
|
"x": coords[0],
|
|
|
|
|
"y": coords[1],
|
|
|
|
|
"z": coords[2]
|
|
|
|
|
}
|
2020-03-09 18:12:26 +01:00
|
|
|
|
response = requests.post(APIURLS["nearest"], params)
|
|
|
|
|
if response.status_code != 200:
|
|
|
|
|
raise ServerError(url, params)
|
|
|
|
|
|
|
|
|
|
json = response.json()
|
2020-03-09 17:39:44 +01:00
|
|
|
|
|
2021-03-14 14:39:57 +01:00
|
|
|
|
if raw: return json
|
|
|
|
|
|
2020-03-09 17:51:36 +01:00
|
|
|
|
ret = None
|
|
|
|
|
system = json["system"]
|
2020-03-09 17:39:44 +01:00
|
|
|
|
if args.short:
|
2020-03-09 17:51:36 +01:00
|
|
|
|
ret = system["name"]
|
|
|
|
|
elif args.parsable:
|
|
|
|
|
ret = "{}|{},{},{}|{}".format(system["name"], system["x"],
|
|
|
|
|
system["y"], system["z"], round(system["distance"], 2))
|
2020-03-09 17:39:44 +01:00
|
|
|
|
else:
|
|
|
|
|
system = json["system"]
|
|
|
|
|
ret = "{} ({}, {}, {}), {} ly".format(system["name"], system["x"],
|
|
|
|
|
system["y"], system["z"], round(system["distance"], 2))
|
|
|
|
|
|
|
|
|
|
return ret
|
|
|
|
|
|
2021-03-14 14:39:57 +01:00
|
|
|
|
def getOldStations(raw=False):
|
2020-03-09 17:39:44 +01:00
|
|
|
|
params = {
|
|
|
|
|
"json": JSON.dumps({
|
|
|
|
|
"filters": FILTERS,
|
|
|
|
|
"sort": SORT,
|
|
|
|
|
"size": args.count
|
|
|
|
|
})
|
|
|
|
|
}
|
2020-03-09 18:12:26 +01:00
|
|
|
|
json = querystations(APIURLS["stations"], params)
|
2020-03-04 18:07:56 +01:00
|
|
|
|
|
2021-03-14 14:39:57 +01:00
|
|
|
|
if raw: return json
|
|
|
|
|
|
2020-03-09 17:59:35 +01:00
|
|
|
|
ret = ""
|
2020-03-08 00:59:55 +01:00
|
|
|
|
for station in json["results"]:
|
|
|
|
|
if args.short:
|
2020-03-04 18:07:56 +01:00
|
|
|
|
ret += "{}\n".format(station["system_name"])
|
2020-03-08 00:59:55 +01:00
|
|
|
|
else:
|
2020-07-10 14:14:19 +02:00
|
|
|
|
ret += "{}: {} ({} days ago)\n".format(station["system_name"], station["name"],
|
|
|
|
|
(datetime.now(timezone.utc) - dtparser.parse(station["updated_at"])).days)
|
2020-03-04 18:07:56 +01:00
|
|
|
|
|
|
|
|
|
return ret[:-1]
|
|
|
|
|
|
2021-03-14 14:39:57 +01:00
|
|
|
|
def getOldStationsInSystem(system, raw=False):
|
2020-03-05 14:05:12 +01:00
|
|
|
|
FILTERS.update(system_name={"value": system})
|
2020-03-09 17:39:44 +01:00
|
|
|
|
params = {
|
|
|
|
|
"json": JSON.dumps({
|
|
|
|
|
"filters": FILTERS,
|
|
|
|
|
"sort": SORT
|
|
|
|
|
})
|
|
|
|
|
}
|
2020-03-09 18:12:26 +01:00
|
|
|
|
json = querystations(APIURLS["stations"], params)
|
2020-03-04 18:07:56 +01:00
|
|
|
|
|
2021-03-14 14:39:57 +01:00
|
|
|
|
if raw: return json
|
|
|
|
|
|
2020-03-09 17:59:35 +01:00
|
|
|
|
ret = ""
|
2022-09-05 16:17:08 +02:00
|
|
|
|
if len(json["results"]) == 0:
|
2020-12-09 17:39:46 +01:00
|
|
|
|
raise NotFoundError()
|
2022-09-05 16:17:08 +02:00
|
|
|
|
for station in json["results"]:
|
2020-06-29 09:25:16 +02:00
|
|
|
|
# systems including the given name as a word will also trigger;
|
|
|
|
|
# looking for e.g. “Mari” will also give you stuff in “Mac Mari”!
|
|
|
|
|
if station["system_name"] == system:
|
|
|
|
|
if args.short:
|
|
|
|
|
ret += "{}\n".format(station["name"])
|
|
|
|
|
else:
|
2020-07-10 14:14:19 +02:00
|
|
|
|
ret += "{} ({} days ago)\n".format(station["name"],
|
|
|
|
|
(datetime.now(timezone.utc) - dtparser.parse(station["updated_at"])).days)
|
2020-03-04 18:07:56 +01:00
|
|
|
|
|
2020-03-08 00:59:55 +01:00
|
|
|
|
return ret[:-1]
|
2020-03-04 18:07:56 +01:00
|
|
|
|
|
2021-03-14 14:39:57 +01:00
|
|
|
|
def systemExists(system, raw=False):
|
2020-03-09 19:53:49 +01:00
|
|
|
|
params = {
|
|
|
|
|
"json": JSON.dumps({
|
|
|
|
|
"filters": {
|
|
|
|
|
"name": {
|
|
|
|
|
"value": system
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
response = requests.post(APIURLS["systems"], params)
|
|
|
|
|
if response.status_code != 200:
|
|
|
|
|
raise ServerError(url, params)
|
|
|
|
|
|
|
|
|
|
json = response.json()
|
2021-03-14 14:39:57 +01:00
|
|
|
|
|
|
|
|
|
if raw: return json
|
|
|
|
|
|
2020-03-09 19:53:49 +01:00
|
|
|
|
if json["count"] == 0:
|
|
|
|
|
raise NotFoundError()
|
|
|
|
|
|
|
|
|
|
ret = ""
|
|
|
|
|
for system in json["results"]:
|
|
|
|
|
ret += "{} ({}, {}, {})\n".format(system["name"], system["x"], system["y"],
|
|
|
|
|
system["z"])
|
|
|
|
|
|
|
|
|
|
return ret[:-1]
|
|
|
|
|
|
2020-03-04 18:07:56 +01:00
|
|
|
|
# ===========================================================================
|
|
|
|
|
|
|
|
|
|
parser = argparse.ArgumentParser(description="Script for interfacing with "
|
|
|
|
|
+ "Spansh’s API.")
|
2021-03-14 14:39:57 +01:00
|
|
|
|
parser.add_argument("--raw", action='store_true',
|
|
|
|
|
help="output raw json (mostly for debugging)")
|
2020-03-04 18:07:56 +01:00
|
|
|
|
subparsers = parser.add_subparsers(title="subcommands", help="sub-command help",
|
|
|
|
|
dest="subcommand", required=True)
|
|
|
|
|
|
2020-03-09 17:39:44 +01:00
|
|
|
|
parser_nearestsystem = subparsers.add_parser("nearestsystem",
|
|
|
|
|
help="Searches for the nearest system in the database to given coordinates.")
|
|
|
|
|
parser_nearestsystem.add_argument("coordinate", nargs=3, type=int,
|
|
|
|
|
help="the coordinates to search for (order: x, y, z)")
|
2020-03-09 17:51:36 +01:00
|
|
|
|
group = parser_nearestsystem.add_mutually_exclusive_group(required=False)
|
|
|
|
|
group.add_argument("--short", action='store_true',
|
2020-03-09 17:39:44 +01:00
|
|
|
|
help="short output format (system name only)")
|
2020-03-09 17:51:36 +01:00
|
|
|
|
group.add_argument("--parsable", action='store_true',
|
|
|
|
|
help="parsable output format (<name>|<x>,<y>,<z>|<distance>)")
|
2020-03-09 17:39:44 +01:00
|
|
|
|
|
2020-03-04 18:07:56 +01:00
|
|
|
|
parser_oldstations = subparsers.add_parser("oldstations",
|
|
|
|
|
help="Searches for stations with old data (>1 year without an update.")
|
|
|
|
|
parser_oldstations.add_argument("--system", nargs="?",
|
|
|
|
|
help="a single system to query. If not present, get the oldest stations "
|
2020-03-09 17:39:44 +01:00
|
|
|
|
+ "overall.")
|
2020-03-04 18:07:56 +01:00
|
|
|
|
parser_oldstations.add_argument("--count", nargs="?", type=int, default=50,
|
|
|
|
|
help="how many stations to output. Defaults to 50.")
|
2020-07-10 14:19:37 +02:00
|
|
|
|
parser_oldstations.add_argument("--minage", nargs="?", type=int, default=365,
|
|
|
|
|
help="minimum age of data (in days) to be considered “outdated”. Defaults to "
|
|
|
|
|
+ "365 (= 1 year).")
|
2020-03-08 00:59:55 +01:00
|
|
|
|
parser_oldstations.add_argument("--short", action='store_true',
|
|
|
|
|
help="short output format (system/station names only)")
|
2022-09-05 16:17:08 +02:00
|
|
|
|
parser_oldstations.add_argument("--nofeet", action='store_true',
|
|
|
|
|
help="omit Odyssey settlements")
|
2020-03-04 18:07:56 +01:00
|
|
|
|
|
2020-03-09 19:53:49 +01:00
|
|
|
|
parser_systemexists = subparsers.add_parser("systemexists",
|
|
|
|
|
help="Checks if a given system exists in the search database.")
|
|
|
|
|
parser_systemexists.add_argument("system", nargs=1,
|
|
|
|
|
help="the system to search for")
|
|
|
|
|
|
2020-03-04 18:07:56 +01:00
|
|
|
|
argcomplete.autocomplete(parser)
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
|
|
# ===========================================================================
|
|
|
|
|
|
2020-03-09 17:39:44 +01:00
|
|
|
|
APIURLS = {
|
2022-09-05 15:27:40 +02:00
|
|
|
|
"nearest": "https://spansh.uk/api/nearest",
|
|
|
|
|
"stations": "https://spansh.uk/api/stations/search",
|
|
|
|
|
"systems": "https://spansh.uk/api/systems/search",
|
2020-03-09 17:39:44 +01:00
|
|
|
|
}
|
2020-03-05 14:05:12 +01:00
|
|
|
|
|
2020-03-09 18:12:26 +01:00
|
|
|
|
try:
|
|
|
|
|
if args.subcommand == "nearestsystem":
|
|
|
|
|
out = getNearestSystem(args.coordinate)
|
|
|
|
|
elif args.subcommand == "oldstations":
|
2020-07-12 03:20:19 +02:00
|
|
|
|
FILTERS = {
|
|
|
|
|
"updated_at":
|
|
|
|
|
{
|
|
|
|
|
"value": [
|
|
|
|
|
"2017-11-06",
|
|
|
|
|
(datetime.now() - timedelta(days=args.minage)).strftime("%Y-%m-%d")
|
2022-09-05 16:17:08 +02:00
|
|
|
|
],
|
2020-07-12 03:20:19 +02:00
|
|
|
|
"comparison": "<=>"
|
2022-09-05 16:17:08 +02:00
|
|
|
|
},
|
|
|
|
|
"type":
|
|
|
|
|
{
|
|
|
|
|
"value": [
|
|
|
|
|
"Asteroid base",
|
|
|
|
|
"Coriolis Starport",
|
|
|
|
|
"Mega ship",
|
|
|
|
|
"Ocellus Starport",
|
|
|
|
|
"Orbis Starport",
|
|
|
|
|
"Outpost",
|
|
|
|
|
"Planetary Outpost",
|
|
|
|
|
"Planetary Port",
|
|
|
|
|
"Settlement" if not args.nofeet else ""
|
|
|
|
|
]
|
2020-07-12 03:20:19 +02:00
|
|
|
|
}
|
2022-09-05 16:17:08 +02:00
|
|
|
|
}
|
2020-07-12 03:20:19 +02:00
|
|
|
|
SORT = {
|
|
|
|
|
"updated_at": {
|
|
|
|
|
"direction": "asc"
|
|
|
|
|
}
|
2022-09-05 16:17:08 +02:00
|
|
|
|
}
|
2020-03-09 18:12:26 +01:00
|
|
|
|
if args.system:
|
2021-03-14 14:39:57 +01:00
|
|
|
|
out = getOldStationsInSystem(args.system, args.raw)
|
2020-03-09 18:12:26 +01:00
|
|
|
|
else:
|
2021-03-14 14:39:57 +01:00
|
|
|
|
out = getOldStations(args.raw)
|
2022-09-05 15:49:01 +02:00
|
|
|
|
if args.raw:
|
|
|
|
|
out = JSON.dumps(out, indent=2)
|
2020-03-09 19:53:49 +01:00
|
|
|
|
elif args.subcommand == "systemexists":
|
2021-03-14 14:39:57 +01:00
|
|
|
|
out = systemExists(args.system, args.raw)
|
2020-03-09 18:12:26 +01:00
|
|
|
|
except ServerError as e:
|
|
|
|
|
print(e)
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
except NotFoundError as e:
|
|
|
|
|
print("No results found.")
|
2020-03-09 18:15:25 +01:00
|
|
|
|
sys.exit(3)
|
2020-03-09 18:12:26 +01:00
|
|
|
|
else:
|
|
|
|
|
print(out)
|
|
|
|
|
sys.exit(0)
|