tradedangerous 12.7.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- py.typed +1 -0
- trade.py +49 -0
- tradedangerous/__init__.py +43 -0
- tradedangerous/cache.py +1381 -0
- tradedangerous/cli.py +136 -0
- tradedangerous/commands/TEMPLATE.py +74 -0
- tradedangerous/commands/__init__.py +244 -0
- tradedangerous/commands/buildcache_cmd.py +102 -0
- tradedangerous/commands/buy_cmd.py +427 -0
- tradedangerous/commands/commandenv.py +372 -0
- tradedangerous/commands/exceptions.py +94 -0
- tradedangerous/commands/export_cmd.py +150 -0
- tradedangerous/commands/import_cmd.py +222 -0
- tradedangerous/commands/local_cmd.py +243 -0
- tradedangerous/commands/market_cmd.py +207 -0
- tradedangerous/commands/nav_cmd.py +252 -0
- tradedangerous/commands/olddata_cmd.py +270 -0
- tradedangerous/commands/parsing.py +221 -0
- tradedangerous/commands/rares_cmd.py +298 -0
- tradedangerous/commands/run_cmd.py +1521 -0
- tradedangerous/commands/sell_cmd.py +262 -0
- tradedangerous/commands/shipvendor_cmd.py +60 -0
- tradedangerous/commands/station_cmd.py +68 -0
- tradedangerous/commands/trade_cmd.py +181 -0
- tradedangerous/commands/update_cmd.py +67 -0
- tradedangerous/corrections.py +55 -0
- tradedangerous/csvexport.py +234 -0
- tradedangerous/db/__init__.py +27 -0
- tradedangerous/db/adapter.py +192 -0
- tradedangerous/db/config.py +107 -0
- tradedangerous/db/engine.py +259 -0
- tradedangerous/db/lifecycle.py +332 -0
- tradedangerous/db/locks.py +208 -0
- tradedangerous/db/orm_models.py +500 -0
- tradedangerous/db/paths.py +113 -0
- tradedangerous/db/utils.py +661 -0
- tradedangerous/edscupdate.py +565 -0
- tradedangerous/edsmupdate.py +474 -0
- tradedangerous/formatting.py +210 -0
- tradedangerous/fs.py +156 -0
- tradedangerous/gui.py +1146 -0
- tradedangerous/mapping.py +133 -0
- tradedangerous/mfd/__init__.py +103 -0
- tradedangerous/mfd/saitek/__init__.py +3 -0
- tradedangerous/mfd/saitek/directoutput.py +678 -0
- tradedangerous/mfd/saitek/x52pro.py +195 -0
- tradedangerous/misc/checkpricebounds.py +287 -0
- tradedangerous/misc/clipboard.py +49 -0
- tradedangerous/misc/coord64.py +83 -0
- tradedangerous/misc/csvdialect.py +57 -0
- tradedangerous/misc/derp-sentinel.py +35 -0
- tradedangerous/misc/diff-system-csvs.py +159 -0
- tradedangerous/misc/eddb.py +81 -0
- tradedangerous/misc/eddn.py +349 -0
- tradedangerous/misc/edsc.py +437 -0
- tradedangerous/misc/edsm.py +121 -0
- tradedangerous/misc/importeddbstats.py +54 -0
- tradedangerous/misc/prices-json-exp.py +179 -0
- tradedangerous/misc/progress.py +194 -0
- tradedangerous/plugins/__init__.py +249 -0
- tradedangerous/plugins/edcd_plug.py +371 -0
- tradedangerous/plugins/eddblink_plug.py +861 -0
- tradedangerous/plugins/edmc_batch_plug.py +133 -0
- tradedangerous/plugins/spansh_plug.py +2647 -0
- tradedangerous/prices.py +211 -0
- tradedangerous/submit-distances.py +422 -0
- tradedangerous/templates/Added.csv +37 -0
- tradedangerous/templates/Category.csv +17 -0
- tradedangerous/templates/RareItem.csv +143 -0
- tradedangerous/templates/TradeDangerous.sql +338 -0
- tradedangerous/tools.py +40 -0
- tradedangerous/tradecalc.py +1302 -0
- tradedangerous/tradedb.py +2320 -0
- tradedangerous/tradeenv.py +313 -0
- tradedangerous/tradeenv.pyi +109 -0
- tradedangerous/tradeexcept.py +131 -0
- tradedangerous/tradeorm.py +183 -0
- tradedangerous/transfers.py +192 -0
- tradedangerous/utils.py +243 -0
- tradedangerous/version.py +16 -0
- tradedangerous-12.7.6.dist-info/METADATA +106 -0
- tradedangerous-12.7.6.dist-info/RECORD +87 -0
- tradedangerous-12.7.6.dist-info/WHEEL +5 -0
- tradedangerous-12.7.6.dist-info/entry_points.txt +3 -0
- tradedangerous-12.7.6.dist-info/licenses/LICENSE +373 -0
- tradedangerous-12.7.6.dist-info/top_level.txt +2 -0
- tradegui.py +24 -0
tradedangerous/prices.py
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# --------------------------------------------------------------------
|
|
2
|
+
# Copyright (C) Oliver 'kfsone' Smith 2014 <oliver@kfs.org>:
|
|
3
|
+
# Copyright (C) Bernd 'Gazelle' Gollesch 2016, 2017
|
|
4
|
+
# Copyright (C) Stefan 'Tromador' Morrell 2025
|
|
5
|
+
# Copyright (C) Jonathan 'eyeonus' Jones 2018-2025
|
|
6
|
+
#
|
|
7
|
+
# You are free to use, redistribute, or even print and eat a copy of
|
|
8
|
+
# this software so long as you include this copyright notice.
|
|
9
|
+
# I guarantee there is at least one bug neither of us knew about.
|
|
10
|
+
# --------------------------------------------------------------------
|
|
11
|
+
# TradeDangerous :: Modules :: Generate TradeDangerous.prices
|
|
12
|
+
|
|
13
|
+
import sys
|
|
14
|
+
from sqlalchemy.orm import Session
|
|
15
|
+
from .db import orm_models as SA
|
|
16
|
+
from .tradeexcept import TradeException
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Element: # TODO: enum?
|
|
20
|
+
basic = 1 << 0
|
|
21
|
+
supply = 1 << 1
|
|
22
|
+
timestamp = 1 << 2
|
|
23
|
+
full = basic | supply | timestamp
|
|
24
|
+
blanks = 1 << 31
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
######################################################################
|
|
28
|
+
# Main
|
|
29
|
+
|
|
30
|
+
def dumpPrices(
|
|
31
|
+
session: Session, # SQLAlchemy session
|
|
32
|
+
elementMask, # which columns to output
|
|
33
|
+
stationID=None, # limits to one station
|
|
34
|
+
file=None, # file handle to write to
|
|
35
|
+
defaultZero=False,
|
|
36
|
+
debug=0,
|
|
37
|
+
):
|
|
38
|
+
"""
|
|
39
|
+
Generate a prices list using data from the DB.
|
|
40
|
+
If stationID is not None, only the specified station is dumped.
|
|
41
|
+
If file is not None, outputs to the given file handle.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
withTimes = elementMask & Element.timestamp
|
|
45
|
+
|
|
46
|
+
# ORM queries to build lookup dicts
|
|
47
|
+
systems = dict(
|
|
48
|
+
session.query(SA.System.system_id, SA.System.name).all()
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
stations = {
|
|
52
|
+
ID: [name, systems.get(sysID)]
|
|
53
|
+
for ID, name, sysID in session.query(
|
|
54
|
+
SA.Station.station_id, SA.Station.name, SA.Station.system_id
|
|
55
|
+
).all()
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
categories = dict(
|
|
59
|
+
session.query(SA.Category.category_id, SA.Category.name).all()
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
items = {
|
|
63
|
+
ID: [name, catID, categories[catID]]
|
|
64
|
+
for ID, name, catID in session.query(
|
|
65
|
+
SA.Item.item_id, SA.Item.name, SA.Item.category_id
|
|
66
|
+
).all()
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# find longest item name (for formatting)
|
|
70
|
+
longestName = max(items.values(), key=lambda ent: len(ent[0]))
|
|
71
|
+
longestNameLen = len(longestName[0])
|
|
72
|
+
|
|
73
|
+
defaultDemandVal = 0 if defaultZero else -1
|
|
74
|
+
|
|
75
|
+
# Build the main query
|
|
76
|
+
q = (
|
|
77
|
+
session.query(
|
|
78
|
+
SA.StationItem.station_id,
|
|
79
|
+
SA.Item.item_id,
|
|
80
|
+
SA.StationItem.demand_price,
|
|
81
|
+
SA.StationItem.supply_price,
|
|
82
|
+
SA.StationItem.demand_units,
|
|
83
|
+
SA.StationItem.demand_level,
|
|
84
|
+
SA.StationItem.supply_units,
|
|
85
|
+
SA.StationItem.supply_level,
|
|
86
|
+
SA.StationItem.modified,
|
|
87
|
+
SA.Item.name,
|
|
88
|
+
SA.Item.category_id,
|
|
89
|
+
SA.Category.name.label("category_name"),
|
|
90
|
+
SA.Station.name.label("station_name"),
|
|
91
|
+
SA.System.name.label("system_name"),
|
|
92
|
+
)
|
|
93
|
+
.join(SA.Item, SA.Item.item_id == SA.StationItem.item_id)
|
|
94
|
+
.join(SA.Category, SA.Category.category_id == SA.Item.category_id)
|
|
95
|
+
.join(SA.Station, SA.Station.station_id == SA.StationItem.station_id)
|
|
96
|
+
.join(SA.System, SA.System.system_id == SA.Station.system_id)
|
|
97
|
+
.order_by(SA.Station.station_id, SA.Category.name, SA.Item.ui_order)
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
if stationID:
|
|
101
|
+
q = q.filter(SA.StationItem.station_id == stationID)
|
|
102
|
+
|
|
103
|
+
# Set up output
|
|
104
|
+
if not file:
|
|
105
|
+
file = sys.stdout
|
|
106
|
+
|
|
107
|
+
if stationID:
|
|
108
|
+
stationSet = str(stations[stationID])
|
|
109
|
+
else:
|
|
110
|
+
stationSet = "ALL Systems/Stations"
|
|
111
|
+
|
|
112
|
+
file.write(
|
|
113
|
+
"# TradeDangerous prices for {}\n"
|
|
114
|
+
"\n"
|
|
115
|
+
"# REMOVE ITEMS THAT DON'T APPEAR IN THE UI\n"
|
|
116
|
+
"# ORDER IS REMEMBERED: Move items around within categories "
|
|
117
|
+
"to match the game UI\n"
|
|
118
|
+
"\n"
|
|
119
|
+
"# File syntax:\n"
|
|
120
|
+
"# <item name> <sell> <buy> [<demand> <supply> [<timestamp>]]\n"
|
|
121
|
+
"# Use '?' for demand/supply when you don't know/care,\n"
|
|
122
|
+
"# Use '-' for demand/supply to indicate unavailable,\n"
|
|
123
|
+
"# Otherwise use a number followed by L, M or H, e.g.\n"
|
|
124
|
+
"# 1L, 23M or 30000H\n"
|
|
125
|
+
"# If you omit the timestamp, the current time will be used when "
|
|
126
|
+
"the file is loaded.\n"
|
|
127
|
+
"\n".format(stationSet)
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
levelDesc = "?0LMH"
|
|
131
|
+
maxCrWidth = 7
|
|
132
|
+
levelWidth = 9
|
|
133
|
+
|
|
134
|
+
outFmt = (
|
|
135
|
+
" {{:<{width}}}"
|
|
136
|
+
" {{:>{crwidth}}}"
|
|
137
|
+
" {{:>{crwidth}}}"
|
|
138
|
+
" {{:>{lvlwidth}}}"
|
|
139
|
+
" {{:>{lvlwidth}}}".format(
|
|
140
|
+
width=longestNameLen,
|
|
141
|
+
crwidth=maxCrWidth,
|
|
142
|
+
lvlwidth=levelWidth,
|
|
143
|
+
)
|
|
144
|
+
)
|
|
145
|
+
if withTimes:
|
|
146
|
+
outFmt += " {}"
|
|
147
|
+
outFmt += "\n"
|
|
148
|
+
header = outFmt.format(
|
|
149
|
+
"Item Name",
|
|
150
|
+
"SellCr", "BuyCr",
|
|
151
|
+
"Demand", "Supply",
|
|
152
|
+
"Timestamp",
|
|
153
|
+
)
|
|
154
|
+
file.write('#' + header[1:])
|
|
155
|
+
|
|
156
|
+
naIQL = "-"
|
|
157
|
+
unkIQL = "?"
|
|
158
|
+
defIQL = "?" if not defaultZero else "-"
|
|
159
|
+
|
|
160
|
+
# Main loop — stream results instead of preloading
|
|
161
|
+
output = ""
|
|
162
|
+
lastStn, lastCat = None, None
|
|
163
|
+
for row in q.yield_per(1000).execution_options(stream_results=True):
|
|
164
|
+
stnID = row.station_id
|
|
165
|
+
station = row.station_name
|
|
166
|
+
system = row.system_name
|
|
167
|
+
item = row.name
|
|
168
|
+
catID = row.category_id
|
|
169
|
+
category = row.category_name
|
|
170
|
+
|
|
171
|
+
# Guard against bad system names
|
|
172
|
+
if not system:
|
|
173
|
+
raise TradeException(
|
|
174
|
+
f"Station {station} (ID {stnID}) is linked to a system with no name."
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
if stnID != lastStn:
|
|
178
|
+
file.write(output)
|
|
179
|
+
output = f"\n\n@ {system.upper()}/{station}\n"
|
|
180
|
+
lastStn = stnID
|
|
181
|
+
lastCat = None
|
|
182
|
+
|
|
183
|
+
if catID != lastCat:
|
|
184
|
+
output += f" + {category}\n"
|
|
185
|
+
lastCat = catID
|
|
186
|
+
|
|
187
|
+
demandCr = row.demand_price or 0
|
|
188
|
+
supplyCr = row.supply_price or 0
|
|
189
|
+
demandUnits = row.demand_units or defaultDemandVal
|
|
190
|
+
demandLevel = row.demand_level or defaultDemandVal
|
|
191
|
+
supplyUnits = row.supply_units or defaultDemandVal
|
|
192
|
+
supplyLevel = row.supply_level or defaultDemandVal
|
|
193
|
+
|
|
194
|
+
# Demand/supply formatting
|
|
195
|
+
if supplyCr > 0:
|
|
196
|
+
demandStr = defIQL if demandCr <= 0 else unkIQL
|
|
197
|
+
supplyStr = (
|
|
198
|
+
naIQL if supplyLevel == 0
|
|
199
|
+
else (f"{supplyUnits if supplyUnits >= 0 else '?'}{levelDesc[supplyLevel+1]}")
|
|
200
|
+
)
|
|
201
|
+
else:
|
|
202
|
+
demandStr = (
|
|
203
|
+
naIQL if demandCr == 0 or demandLevel == 0
|
|
204
|
+
else (f"{demandUnits if demandUnits >= 0 else '?'}{levelDesc[demandLevel+1]}")
|
|
205
|
+
)
|
|
206
|
+
supplyStr = naIQL
|
|
207
|
+
|
|
208
|
+
modified = row.modified or ""
|
|
209
|
+
output += outFmt.format(item, demandCr, supplyCr, demandStr, supplyStr, modified)
|
|
210
|
+
|
|
211
|
+
file.write(output)
|
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
#!/usr/bin/env python3.6
|
|
2
|
+
# Deprecated
|
|
3
|
+
# Website no longer exists
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Small tool to submit new star data to EDStarCoordinator.
|
|
7
|
+
|
|
8
|
+
Use:
|
|
9
|
+
submit-distances.py "system name"
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
#
|
|
13
|
+
# NOTE: This tool is very hacky. If someone wants to clean it up,
|
|
14
|
+
# and submit a diff, that'd be greatly appreciated!
|
|
15
|
+
#
|
|
16
|
+
|
|
17
|
+
import argparse
|
|
18
|
+
import os
|
|
19
|
+
import random
|
|
20
|
+
import re
|
|
21
|
+
import requests
|
|
22
|
+
import sys
|
|
23
|
+
import tradedb
|
|
24
|
+
import tradeenv
|
|
25
|
+
|
|
26
|
+
from tradedangerous.misc.edsc import StarSubmission, StarSubmissionResult, SubmissionError
|
|
27
|
+
from tradedangerous.misc.clipboard import SystemNameClip
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
standardStars = [
|
|
31
|
+
"SOL",
|
|
32
|
+
"NEW YEMBO",
|
|
33
|
+
"VESUVIT",
|
|
34
|
+
"HIP 79884",
|
|
35
|
+
"ASELLUS AUSTRALIS",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
sys.stderr.write("*** WARNING: submit-distances.py is deprecated; if you rely on it, please post a github issue\n")
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
############################################################################
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class UsageError(Exception):
|
|
46
|
+
def __init__(self, argv, error):
|
|
47
|
+
self.argv, self.error = argv, error
|
|
48
|
+
|
|
49
|
+
def __str__(self):
|
|
50
|
+
return error + "\n" + argv.format_usage()
|
|
51
|
+
|
|
52
|
+
def parse_arguments():
|
|
53
|
+
parser = argparse.ArgumentParser(
|
|
54
|
+
description='Submit star distances to the EDSC project.',
|
|
55
|
+
)
|
|
56
|
+
parser.add_argument(
|
|
57
|
+
'origin',
|
|
58
|
+
help='System to submit distances for.',
|
|
59
|
+
type=str,
|
|
60
|
+
)
|
|
61
|
+
parser.add_argument(
|
|
62
|
+
'--pick',
|
|
63
|
+
help='Randomly select N existing systems from gamma or ealier',
|
|
64
|
+
required=False,
|
|
65
|
+
type=int,
|
|
66
|
+
)
|
|
67
|
+
parser.add_argument(
|
|
68
|
+
'--cmdr',
|
|
69
|
+
required=False,
|
|
70
|
+
help='Specify your commander name.',
|
|
71
|
+
type=str,
|
|
72
|
+
default=os.environ.get('CMDR', None)
|
|
73
|
+
)
|
|
74
|
+
parser.add_argument(
|
|
75
|
+
'--test',
|
|
76
|
+
help='Use the EDSC Test Database.',
|
|
77
|
+
required=False,
|
|
78
|
+
action='store_true',
|
|
79
|
+
)
|
|
80
|
+
parser.add_argument(
|
|
81
|
+
'--detail', '-v',
|
|
82
|
+
help='Output additional detail.',
|
|
83
|
+
action='count',
|
|
84
|
+
default=0,
|
|
85
|
+
)
|
|
86
|
+
parser.add_argument(
|
|
87
|
+
'--debug', '-w',
|
|
88
|
+
help='Enable debugging output,',
|
|
89
|
+
action='count',
|
|
90
|
+
default=0,
|
|
91
|
+
)
|
|
92
|
+
parser.add_argument(
|
|
93
|
+
'--no-update',
|
|
94
|
+
help='Disallow distances from an existing system.',
|
|
95
|
+
action='store_false',
|
|
96
|
+
default=True,
|
|
97
|
+
dest='allowUpdate',
|
|
98
|
+
)
|
|
99
|
+
parser.add_argument(
|
|
100
|
+
'--extra-file',
|
|
101
|
+
help='File to read/write extra stars to.',
|
|
102
|
+
type=str,
|
|
103
|
+
default='data/extra-stars.txt',
|
|
104
|
+
dest='extraFile',
|
|
105
|
+
)
|
|
106
|
+
parser.add_argument(
|
|
107
|
+
'destinations',
|
|
108
|
+
help='System or systems to measure distance to.',
|
|
109
|
+
default=[],
|
|
110
|
+
nargs='*',
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
argv = parser.parse_args(sys.argv[1:])
|
|
114
|
+
argv.origin = argv.origin.upper()
|
|
115
|
+
if argv.origin.startswith('@'):
|
|
116
|
+
argv.origin = argv.origin[1:]
|
|
117
|
+
|
|
118
|
+
if not argv.cmdr:
|
|
119
|
+
raise UsageError(argv, "No commander name specified")
|
|
120
|
+
|
|
121
|
+
return argv
|
|
122
|
+
|
|
123
|
+
def get_system(argv, tdb):
|
|
124
|
+
system = tdb.systemByName.get(argv.origin.upper(), None)
|
|
125
|
+
if not system:
|
|
126
|
+
return argv.origin, None
|
|
127
|
+
|
|
128
|
+
if not argv.allowUpdate:
|
|
129
|
+
raise UsageError(
|
|
130
|
+
argv,
|
|
131
|
+
"System '{}' already exists.\n"
|
|
132
|
+
.format(systemName)
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
if argv.detail:
|
|
136
|
+
print("EXISTING SYSTEM:", argv.origin)
|
|
137
|
+
|
|
138
|
+
return argv.origin, system
|
|
139
|
+
|
|
140
|
+
def pick_destinations(argv, tdb):
|
|
141
|
+
numSystems = len(tdb.systemByName)
|
|
142
|
+
if numSystems < 1:
|
|
143
|
+
raise UsageError(
|
|
144
|
+
argv,
|
|
145
|
+
"Can't --pick random systems: "
|
|
146
|
+
"Your TD database doesn't contain any systems."
|
|
147
|
+
)
|
|
148
|
+
num = min(argv.pick, numSystems)
|
|
149
|
+
systems = tdb.systemByName
|
|
150
|
+
try:
|
|
151
|
+
gamma = tdb.lookupAdded("Gamma")
|
|
152
|
+
except KeyError:
|
|
153
|
+
gamma = 20
|
|
154
|
+
destinations = random.sample([
|
|
155
|
+
sysName for sysName, system in systems.items()
|
|
156
|
+
if system.addedID <= gamma and \
|
|
157
|
+
not sysName in standardStars
|
|
158
|
+
], num)
|
|
159
|
+
|
|
160
|
+
return destinations
|
|
161
|
+
|
|
162
|
+
def get_outliers(argv):
|
|
163
|
+
outliers = set()
|
|
164
|
+
try:
|
|
165
|
+
with open(argv.extraFile, "r", encoding="utf-8") as input:
|
|
166
|
+
for line in input:
|
|
167
|
+
name = line.partition('#')[0].strip().upper()
|
|
168
|
+
if name and name != argv.origin:
|
|
169
|
+
outliers.add(name)
|
|
170
|
+
except FileNotFoundError:
|
|
171
|
+
pass
|
|
172
|
+
outliers = list(outliers)
|
|
173
|
+
random.shuffle(outliers)
|
|
174
|
+
return outliers
|
|
175
|
+
|
|
176
|
+
def get_distances(argv, clip, stars):
|
|
177
|
+
distances = []
|
|
178
|
+
for star in stars:
|
|
179
|
+
starNo = len(distances) + 1
|
|
180
|
+
# Check it's not already in the list
|
|
181
|
+
star = star.upper()
|
|
182
|
+
if star in distances:
|
|
183
|
+
continue
|
|
184
|
+
|
|
185
|
+
clip.copy_text(star)
|
|
186
|
+
|
|
187
|
+
if len(stars) > 1:
|
|
188
|
+
prefix = "{:>2}/{:2}: ".format(starNo, len(stars))
|
|
189
|
+
else:
|
|
190
|
+
prefix = ""
|
|
191
|
+
dist = input(prefix + "Distance to {}: ".format(star))
|
|
192
|
+
if dist == 'q':
|
|
193
|
+
return distances, 'q'
|
|
194
|
+
|
|
195
|
+
if dist:
|
|
196
|
+
distances.append({
|
|
197
|
+
'name': star.upper(),
|
|
198
|
+
'dist': float(dist),
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
return distances, 'end'
|
|
202
|
+
|
|
203
|
+
def check_system(argv, tdb, tdbSys, name):
|
|
204
|
+
system = tdb.systemByName.get(name.upper(), None)
|
|
205
|
+
if system and not tdbSys:
|
|
206
|
+
print("KNOWN SYSTEM")
|
|
207
|
+
return
|
|
208
|
+
if system:
|
|
209
|
+
print("KNOWN SYSTEM: {:.2f} ly".format(
|
|
210
|
+
tdbSys.distanceTo(system)
|
|
211
|
+
))
|
|
212
|
+
|
|
213
|
+
def add_extra_stars(argv, extraStars):
|
|
214
|
+
if not extraStars:
|
|
215
|
+
return
|
|
216
|
+
if argv.detail:
|
|
217
|
+
print("Saving {} to {}".format(
|
|
218
|
+
str(extraStars), argv.extraFile,
|
|
219
|
+
))
|
|
220
|
+
try:
|
|
221
|
+
with open(argv.extraFile, "a", encoding="utf-8") as output:
|
|
222
|
+
for star in extraStars:
|
|
223
|
+
print(star, file=output)
|
|
224
|
+
except FileNotFoundError:
|
|
225
|
+
pass
|
|
226
|
+
|
|
227
|
+
def submit_distances(argv, tdb, distances):
|
|
228
|
+
system = argv.origin
|
|
229
|
+
cmdr = argv.cmdr
|
|
230
|
+
mode = "TEST" if argv.test else "Live"
|
|
231
|
+
|
|
232
|
+
print()
|
|
233
|
+
print("System:", system)
|
|
234
|
+
print("Database:", mode)
|
|
235
|
+
print("Distances:")
|
|
236
|
+
for ref in distances:
|
|
237
|
+
print(" {}: {:.02f} ly".format(
|
|
238
|
+
ref['name'], ref['dist']
|
|
239
|
+
))
|
|
240
|
+
print()
|
|
241
|
+
|
|
242
|
+
ok = input("Does this look correct (y/n)? ")
|
|
243
|
+
if ok != 'y':
|
|
244
|
+
print("Stopped")
|
|
245
|
+
return
|
|
246
|
+
|
|
247
|
+
print()
|
|
248
|
+
print("Submitting {} {}".format(mode, system))
|
|
249
|
+
|
|
250
|
+
sub = StarSubmission(
|
|
251
|
+
star=system,
|
|
252
|
+
commander=cmdr,
|
|
253
|
+
refs=distances,
|
|
254
|
+
test=argv.test,
|
|
255
|
+
)
|
|
256
|
+
resp = sub.submit()
|
|
257
|
+
|
|
258
|
+
result = StarSubmissionResult(star=system, response=resp)
|
|
259
|
+
print(str(result))
|
|
260
|
+
if result.valid:
|
|
261
|
+
# Check for systems we can add
|
|
262
|
+
trilats = set()
|
|
263
|
+
for sysName in result.systems.keys():
|
|
264
|
+
code, coord = result.systems[sysName]
|
|
265
|
+
sysName = sysName.upper()
|
|
266
|
+
# Does it have a distance
|
|
267
|
+
if isinstance(coord, (list, tuple)):
|
|
268
|
+
x, y, z = coord
|
|
269
|
+
system = tdb.systemByName.get(sysName, None)
|
|
270
|
+
if system:
|
|
271
|
+
tdb.updateLocalSystem(system, sysName, x, y, z)
|
|
272
|
+
else:
|
|
273
|
+
tdb.addLocalSystem(sysName, x, y, z)
|
|
274
|
+
if result.recheck:
|
|
275
|
+
return list(result.recheck.keys())
|
|
276
|
+
return None
|
|
277
|
+
|
|
278
|
+
def do_rechecks(argv, clip, rechecks):
|
|
279
|
+
print("\aSome systems need their distances rechecked:")
|
|
280
|
+
|
|
281
|
+
distances, term = get_distances(argv, clip, rechecks)
|
|
282
|
+
return distances
|
|
283
|
+
|
|
284
|
+
def send_and_check_distances(argv, tdb, clip, distances):
|
|
285
|
+
if not distances:
|
|
286
|
+
if argv.detail:
|
|
287
|
+
print("No distances, no submission.")
|
|
288
|
+
return False
|
|
289
|
+
|
|
290
|
+
while distances:
|
|
291
|
+
rechecks = submit_distances(argv, tdb, distances)
|
|
292
|
+
if not rechecks:
|
|
293
|
+
break
|
|
294
|
+
|
|
295
|
+
distances = do_rechecks(argv, clip, rechecks)
|
|
296
|
+
|
|
297
|
+
return True
|
|
298
|
+
|
|
299
|
+
def process_destinations(argv, tdb):
|
|
300
|
+
clip = SystemNameClip()
|
|
301
|
+
|
|
302
|
+
print("Distances from {}:".format(argv.origin))
|
|
303
|
+
distances, _ = get_distances(argv, clip, argv.destinations)
|
|
304
|
+
send_and_check_distances(argv, tdb, clip, distances)
|
|
305
|
+
|
|
306
|
+
############################################################################
|
|
307
|
+
|
|
308
|
+
def main():
|
|
309
|
+
argv = parse_arguments()
|
|
310
|
+
|
|
311
|
+
tdenv = tradeenv.TradeEnv(properties=argv)
|
|
312
|
+
tdb = tradedb.TradeDB(tdenv)
|
|
313
|
+
|
|
314
|
+
system, tdbSys = get_system(argv, tdb)
|
|
315
|
+
|
|
316
|
+
if argv.pick:
|
|
317
|
+
argv.destinations.extend(pick_destinations(argv, tdb))
|
|
318
|
+
|
|
319
|
+
if argv.destinations:
|
|
320
|
+
process_destinations(argv, tdb)
|
|
321
|
+
return
|
|
322
|
+
|
|
323
|
+
print("Add EDSC Star Distances for \"{}\"".format(system))
|
|
324
|
+
print()
|
|
325
|
+
print("You will now be prompted for distances to various stars.")
|
|
326
|
+
print()
|
|
327
|
+
print(
|
|
328
|
+
"At each prompt, the star name will be copied into your paste buffer. "
|
|
329
|
+
"You should alt-tab into the game and paste the name into the Galaxy "
|
|
330
|
+
"Map's search box. Then alt-tab back and enter the distance value."
|
|
331
|
+
)
|
|
332
|
+
print()
|
|
333
|
+
print(
|
|
334
|
+
"At each prompt enter a ly distance (e.g. 123.45), q to stop, "
|
|
335
|
+
"or leave the line empty if you don't want to enter data for "
|
|
336
|
+
"this star."
|
|
337
|
+
)
|
|
338
|
+
print(
|
|
339
|
+
"5 distances are required for EDSC to make a first guess at a "
|
|
340
|
+
"star's location. You can submit more to increase the accuracy "
|
|
341
|
+
"but the only time you need to submit more than 10 is when you "
|
|
342
|
+
"are trying to submit corrections."
|
|
343
|
+
)
|
|
344
|
+
print()
|
|
345
|
+
|
|
346
|
+
clip = SystemNameClip()
|
|
347
|
+
|
|
348
|
+
print()
|
|
349
|
+
print("""
|
|
350
|
+
===================================================
|
|
351
|
+
STANDARD STARS: (q to skip to the next section)
|
|
352
|
+
|
|
353
|
+
These are stars with well-known positions.
|
|
354
|
+
===================================================
|
|
355
|
+
""")
|
|
356
|
+
distances, term = get_distances(argv, clip, standardStars)
|
|
357
|
+
if distances:
|
|
358
|
+
send_and_check_distances(argv, tdb, clip, distances)
|
|
359
|
+
|
|
360
|
+
outliers = get_outliers(argv)
|
|
361
|
+
if outliers:
|
|
362
|
+
print("""
|
|
363
|
+
===================================================
|
|
364
|
+
EXTRA STARS: (q to skip to the next section)
|
|
365
|
+
|
|
366
|
+
Stars from {}.
|
|
367
|
+
===================================================
|
|
368
|
+
""".format(argv.extraFile))
|
|
369
|
+
distances, term = get_distances(argv, clip, outliers)
|
|
370
|
+
if distances:
|
|
371
|
+
send_and_check_distances(argv, tdb, clip, distances)
|
|
372
|
+
|
|
373
|
+
print("""
|
|
374
|
+
===================================================
|
|
375
|
+
CHOOSE YOUR OWN: (q to stop)
|
|
376
|
+
|
|
377
|
+
Specify additional stars.
|
|
378
|
+
|
|
379
|
+
Prefix names with a '+' to add them to
|
|
380
|
+
{}.
|
|
381
|
+
===================================================
|
|
382
|
+
""".format(argv.extraFile))
|
|
383
|
+
distances = []
|
|
384
|
+
newOutliers = []
|
|
385
|
+
while True:
|
|
386
|
+
star = input("Enter star name: ")
|
|
387
|
+
star = star.strip().upper()
|
|
388
|
+
if not star or star == 'Q':
|
|
389
|
+
break
|
|
390
|
+
# Remove surrounding quotes
|
|
391
|
+
save = False
|
|
392
|
+
if star.startswith('+'):
|
|
393
|
+
save = True
|
|
394
|
+
star = star[1:].strip()
|
|
395
|
+
star = re.sub(r'\s+', ' ', star)
|
|
396
|
+
star = re.sub(r"''+", "'", star)
|
|
397
|
+
star = re.sub(r'^("|\')+\s*(.*)\s*\1+', r'\2', star)
|
|
398
|
+
if star.find('"') >= 0:
|
|
399
|
+
print("Invalid star name")
|
|
400
|
+
continue
|
|
401
|
+
if star.startswith('+'):
|
|
402
|
+
save = True
|
|
403
|
+
star = star[1:].strip()
|
|
404
|
+
for ref in distances:
|
|
405
|
+
if ref['name'] == star:
|
|
406
|
+
print("'{}' is already listed.")
|
|
407
|
+
continue
|
|
408
|
+
check_system(argv, tdb, tdbSys, star)
|
|
409
|
+
extras, term = get_distances(argv, clip, [star])
|
|
410
|
+
if term != 'q' and len(extras) > 0:
|
|
411
|
+
distances.extend(extras)
|
|
412
|
+
if save and star not in outliers and star not in newOutliers:
|
|
413
|
+
newOutliers.append(star)
|
|
414
|
+
|
|
415
|
+
if send_and_check_distances(argv, tdb, clip, distances):
|
|
416
|
+
add_extra_stars(argv, newOutliers)
|
|
417
|
+
|
|
418
|
+
if __name__ == "__main__":
|
|
419
|
+
try:
|
|
420
|
+
main()
|
|
421
|
+
except (SubmissionError, UsageError) as e:
|
|
422
|
+
print(str(e))
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
unq:name
|
|
2
|
+
'Alpha1'
|
|
3
|
+
'Alpha2'
|
|
4
|
+
'Alpha3'
|
|
5
|
+
'Alpha4'
|
|
6
|
+
'Beta1'
|
|
7
|
+
'Beta1 (unverified)'
|
|
8
|
+
'Beta1 (unverified)-Inferred'
|
|
9
|
+
'Beta1-Inferred'
|
|
10
|
+
'Beta2'
|
|
11
|
+
'Beta2 (outside Beta3)'
|
|
12
|
+
'Beta2 (outside Beta3)-Inferred'
|
|
13
|
+
'Beta2 (unverified)'
|
|
14
|
+
'Beta2 (unverified)-Inferred'
|
|
15
|
+
'Beta2-Inferred'
|
|
16
|
+
'Beta3'
|
|
17
|
+
'Beta3 (unverified)'
|
|
18
|
+
'Beta3 (unverified)-Inferred'
|
|
19
|
+
'Beta3-Inferred'
|
|
20
|
+
'Beyond The Pill (unverified)-Inferred'
|
|
21
|
+
'EDSM'
|
|
22
|
+
'Gamma'
|
|
23
|
+
'Gamma (unverified)'
|
|
24
|
+
'Gamma (unverified)-Inferred'
|
|
25
|
+
'Gamma-Inferred'
|
|
26
|
+
'Gamma1'
|
|
27
|
+
'Gamma1 (unverified)'
|
|
28
|
+
'Gamma1 (unverified)-Inferred'
|
|
29
|
+
'Gamma1-Inferred'
|
|
30
|
+
'Journal'
|
|
31
|
+
'Local'
|
|
32
|
+
'netLog'
|
|
33
|
+
'Not Present'
|
|
34
|
+
'Premium Beta1'
|
|
35
|
+
'Premium Beta2'
|
|
36
|
+
'Release 1.00-EDStar'
|
|
37
|
+
'undefined-Inferred'
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
unq:category_id,name
|
|
2
|
+
1,Metals
|
|
3
|
+
2,Minerals
|
|
4
|
+
3,Chemicals
|
|
5
|
+
4,Foods
|
|
6
|
+
5,Textiles
|
|
7
|
+
6,Industrial Materials
|
|
8
|
+
7,Medicines
|
|
9
|
+
8,Legal Drugs
|
|
10
|
+
9,Machinery
|
|
11
|
+
10,Technology
|
|
12
|
+
11,Weapons
|
|
13
|
+
12,Consumer Items
|
|
14
|
+
13,Slavery
|
|
15
|
+
14,Waste
|
|
16
|
+
15,NonMarketable
|
|
17
|
+
16,Salvage
|