-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
247 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,247 @@ | ||
#! /usr/bin/env python | ||
|
||
import tradedb | ||
from tradeexcept import TradeException | ||
import json | ||
|
||
class UnknownSystemError(TradeException): | ||
def __str__(self): | ||
return "Unknown System: " + ' '.join(self.args) | ||
|
||
|
||
class UnknownStationError(TradeException): | ||
def __str__(self): | ||
return "Unknown Station: " + ' '.join(self.args) | ||
|
||
|
||
def lookup_system(tdb, tdenv, name, x, y, z): | ||
try: | ||
system = tdb.systemByName[name] | ||
except KeyError: | ||
system = None | ||
if not system: | ||
try: | ||
system = tdb.lookupSystem(name) | ||
except LookupError: | ||
pass | ||
|
||
if system: | ||
if (system.posX != x or system.posY != y or system.posZ != z): | ||
raise Exception("System {} position mismatch: " | ||
"Got {},{},{} expected {},{},{}".format( | ||
name, | ||
x, y, z, | ||
system.posX, system.posY, system.posZ | ||
)) | ||
return system | ||
|
||
newSystem = "@{} [{}, {}, {}]".format( | ||
name, x, y, z | ||
) | ||
|
||
candidates = [] | ||
for candidate in tdb.systemByID.values(): | ||
if (candidate.posX == x and | ||
candidate.posY == y and | ||
candidate.posZ == z | ||
): | ||
candidates.append(candidate) | ||
|
||
if len(candidates) == 1: | ||
candidate = candidates[0] | ||
if candidate.casefold() != name.casefold(): | ||
if not tdenv.quiet: | ||
print("System name mismatch: " | ||
"Local: {}, " | ||
"Remote: {}, " | ||
"Coords: {}, {}, {}".format( | ||
name, | ||
candidate.dbname, | ||
candidate.posX, | ||
candidate.posY, | ||
candidate.posZ, | ||
)) | ||
return candidates[0] | ||
|
||
if len(candidates): | ||
raise Exception("System {} matches co-ordinates for systems: {}" + | ||
','.join([system.name for system in candidates]) | ||
) | ||
|
||
if tdenv.addUnknown: | ||
return tdb.addLocalSystem(name, x, y, z) | ||
|
||
return None | ||
|
||
|
||
def lookup_station(tdb, tdenv, system, name, lsFromStar): | ||
normalizedName = tradedb.TradeDB.normalizedStr(name) | ||
for stn in system.stations: | ||
stnNormalizedName = tradedb.TradeDB.normalizedStr(stn.dbname) | ||
if stnNormalizedName == normalizedName: | ||
if lsFromStar and not stn.lsFromStar: | ||
tdenv.DEBUG0( | ||
"- Updating station {}: " | ||
" dist from star = {}", | ||
stn.name(), | ||
lsFromStar | ||
) | ||
db = tdb.getDB() | ||
db.execute( | ||
"UPDATE Station " | ||
"SET dist_from_star = ? " | ||
"WHERE station_id = ?", | ||
[lsFromStar, stn.ID] | ||
) | ||
db.commit() | ||
return stn | ||
|
||
if tdenv.addUnknown: | ||
return tdb.addLocalStation(system, name, lsFromStar) | ||
|
||
return None | ||
|
||
def load_prices_json( | ||
tdb, | ||
tdenv, | ||
jsonText | ||
): | ||
""" | ||
Take data from a prices file and load it into the database. | ||
""" | ||
|
||
data = json.loads(jsonText) | ||
|
||
sysData = data['sys'] | ||
sysName = sysData['name'] | ||
pos = sysData['pos'] | ||
|
||
stnData = data['stn'] | ||
stnName = stnData['name'] | ||
lsFromStar = stnData['ls'] | ||
|
||
system = lookup_system( | ||
tdb, tdenv, | ||
sysName, | ||
pos[0], pos[1], pos[2], | ||
) | ||
if not system: | ||
if not tdenv.ignoreUnknown: | ||
raise UnknownSystemError(sysName) | ||
if not tdenv.quiet: | ||
print("NOTE: Ignoring unknown system: {} [{},{},{}]".format( | ||
sysName, | ||
pos[0], pos[1], pos[2], | ||
)) | ||
return | ||
if system.dbname != sysName and tdenv.detail: | ||
print("NOTE: Treating '{}' as '{}'".format( | ||
name, system.dbname | ||
)) | ||
tdenv.DEBUG1("- System: {}", system.dbname) | ||
|
||
station = lookup_station( | ||
tdb, tdenv, | ||
system, | ||
stnName, | ||
lsFromStar, | ||
) | ||
if not station: | ||
if tdenv.ignoreUnknown: | ||
raise UnknownStationError(stnName) | ||
if not tdenv.quiet: | ||
print("NOTE: Ignoring unknown station: {}/{}".format( | ||
sysName.upper(), stnName | ||
)) | ||
return | ||
tdenv.DEBUG1("- Station: {}", station.dbname) | ||
|
||
|
||
def generate_prices_json( | ||
tdb, | ||
tdenv, | ||
station, | ||
): | ||
""" | ||
Generate a JSON dump of the specified station along | ||
with everything we know about the station and the system | ||
it is in. | ||
tdb: | ||
The TradeDB object to use | ||
tdenv: | ||
Settings | ||
station: | ||
Station to dump | ||
""" | ||
|
||
system = station.system | ||
|
||
stationData = { | ||
'cmdr': tdenv.commander or "unknown", | ||
'src': 'td/price-json', | ||
'sys': { | ||
'name': system.dbname, | ||
'pos': [ system.posX, system.posY, system.posZ ], | ||
}, | ||
'stn': { | ||
'name': station.dbname, | ||
'ls': station.lsFromStar, | ||
}, | ||
'items': {} | ||
} | ||
|
||
conn = tdb.getDB() | ||
cur = conn.cursor() | ||
cur.execute(""" | ||
SELECT si.item_id, | ||
si.modified, | ||
sb.price, sb.units, sb.level, | ||
ss.price, ss.units, ss.level | ||
FROM StationItem AS si | ||
LEFT OUTER JOIN StationBuying AS sb | ||
ON ( | ||
sb.station_id = si.station_id | ||
AND sb.item_id = si.item_id | ||
) | ||
LEFT OUTER JOIN StationSelling AS ss | ||
ON ( | ||
ss.station_id = si.station_id | ||
AND ss.item_id = si.item_id | ||
) | ||
WHERE si.station_id = ? | ||
""", [station.ID]) | ||
|
||
items = {} | ||
|
||
lastModified = "0" | ||
for ( | ||
itemID, modified, | ||
sbPrice, sbUnits, sbLevel, | ||
ssPrice, ssUnits, ssLevel | ||
) in cur: | ||
lastModified = max(lastModified, modified) | ||
item = tdb.itemByID[itemID] | ||
itemData = items[item.dbname] = { | ||
'm': modified, | ||
} | ||
if sbPrice and (sbUnits >= 0 or sbLevel >= 0): | ||
itemData['b'] = [ sbPrice, sbUnits, sbLevel ] | ||
elif sbPrice: | ||
itemData['b'] = sbPrice | ||
if ssPrice and (ssUnits >= 0 or sbLevel >= 0): | ||
itemData['s'] = [ | ||
ssPrice, ssUnits, ssLevel | ||
] | ||
elif ssPrice: | ||
itemData['s'] = ssPrice | ||
|
||
# dedupe timestamps. | ||
for itemData in items.values(): | ||
if itemData['m'] == lastModified: | ||
del itemData['m'] | ||
|
||
stationData['m'] = lastModified | ||
stationData['items'] = items | ||
|
||
return json.dumps(stationData, separators=(',',':')) |