Skip to content

Commit

Permalink
Experimental json generator
Browse files Browse the repository at this point in the history
  • Loading branch information
Oliver Smith committed Dec 11, 2014
1 parent 02dc9be commit bd73e5e
Showing 1 changed file with 186 additions and 0 deletions.
186 changes: 186 additions & 0 deletions misc/prices-json-exp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
#! /usr/bin/env python

# Experimental module to generate a JSON version of the .prices file.

# Set to True to allow export of systems that don't have any station data
emptySystems = True
# Set to True to allow export of stations that don't have prices
emptyStations = True
# Positions should be xferred as whole multiples of this
posMultiplier = 32

import sqlite3
import json
import time
import collections
import os

conn = sqlite3.connect("data/TradeDangerous.db")

def collectItemData(db):
"""
Builds a flat, array of item names that serves as a table of items.
Station Price Data refers to this table by position in the array.
As a result, we also need a mapping for itemID -> tableID
"""

items = [] # table of items
itemIdx = {} # mapping from itemID -> position in items
for ID, name in db.execute("SELECT i.item_id, i.name FROM Item AS i"):
itemIdx[ID] = len(items)
items.append(name)

return items, itemIdx


def collectSystems(
db,
itemIdx,
posMult=None,
withEmptySystems=False,
withStations=True,
withEmptyStations=False,
withPrices=True
):
"""
Build the System -> Station -> Price data from the supplied DB.
withEmptySystems:
True: include systems with no station data.
withStations:
False: (implies withEmptySystems=True) don't include station data.
withEmptyStations:
True: include stations with no price data.
withPrices:
False: (implies withEmptyStations=True) don't include price data.
"""

systems = collections.defaultdict(dict)
if not withStations:
withEmptySystems = True

for sysID, sys, posX, posY, posZ in db.execute("""
SELECT sys.system_id, sys.name,
sys.pos_x, sys.pos_y, sys.pos_z
FROM System AS sys
LEFT OUTER JOIN Station
USING (system_id)
GROUP BY 1
"""):
if posMult:
posX = int(posX * posMult)
posY = int(posY * posMult)
posZ = int(posZ * posMult)
systemData = {
'pos': [ posX, posY, posZ ],
}
if withStations:
stations = collectStations(
db, itemIdx,
sysID,
withEmptyStations=withEmptyStations,
withPrices=withPrices,
)
if not stations and not withEmptySystems:
continue
if stations:
systemData['stn'] = stations
systems[sys] = systemData

return systems


def collectStations(
db,
itemIdx,
sysID,
withEmptyStations=False,
withPrices=True
):
"""
Populate a station list for a given system, including price data.
"""
stations = {}
if not withPrices:
withEmptyStations = True
for stnID, name, lsFromStar, lastMod in db.execute("""
SELECT stn.station_id, stn.name, stn.ls_from_star,
MAX(si.modified)
FROM Station AS stn
LEFT OUTER JOIN StationItem si
USING (station_id)
WHERE stn.system_id = ?
GROUP BY 1
""", [sysID]):
if not lastMod and not withEmptyStations:
continue
stationData = {
'ls': int(lsFromStar),
}
if lastMod:
stationData['ts'] = lastMod
if withPrices:
buy, sell = collectPriceData(
db, itemIdx,
stnID,
)
stationData['buy'] = buy
stationData['sell'] = sell

stations[name] = stationData

return stations


def collectPriceData(db, itemIdx, stnID):
"""
Collect buying and selling data for a given station. Items reference the
position in the itemData array.
"""

buying, selling = [], []

for itmID, cr in db.execute("""
SELECT sb.item_id, sb.price
FROM StationBuying AS sb
WHERE station_id = ?
""", [stnID]):
buying.append([ itemIdx[itmID], cr ])

for itmID, cr, units, level in db.execute("""
SELECT ss.item_id, ss.price, ss.units, ss.level
FROM StationSelling AS ss
WHERE station_id = ?
""", [stnID]):
selling.append([ itemIdx[itmID], cr, units, level ])

return buying, selling


itemData, itemIdx = collectItemData(conn)
sysData = collectSystems(
conn, itemIdx,
posMult=posMultiplier,
withEmptySystems=emptySystems, withEmptyStations=emptyStations
)
jsonData = {
'src': 'td/json-exp',
'posMult': posMultiplier,
'time': int(time.time()),
'items': itemData,
'emptySys': emptySystems,
'emptyStn': emptyStations,
'sys': sysData,
}

try:
cmdrName = os.environ['CMDR']
jsonData['cmdr'] = cmdrName
except KeyError:
pass

print(json.dumps(jsonData, separators=(',',':')))

0 comments on commit bd73e5e

Please sign in to comment.