Skip to content

Commit

Permalink
Merge branch 'master' into devel
Browse files Browse the repository at this point in the history
  • Loading branch information
bgol committed Oct 25, 2014
2 parents 6215b64 + facfcfb commit 04ab156
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 125 deletions.
56 changes: 36 additions & 20 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ files from other commanders to fill out your database.
== CHANGE LOG
==============================================================================

v4.6.1 Oct 25/2014
. (kfsone) Added "--supply" (-S) which shows supply (demand and stock) fields when editing,
. (kfsone) Added "--timestamps" (-T) which shows timestamp field when editing,
. (kfsone) Added "--force-na" (-0) which replaces 'unk' values with 'n/a' (use with care),
. (kfsone) Deprecated "--all" and "--zero",
. (kfsone) Minor fixes to new .prices format

v4.6.0 Oct 24/2014
. (kfsone) New extended .prices format:
<item name> <sell> <buy> <demand> <stock> [<time>]
Expand Down Expand Up @@ -59,16 +66,6 @@ v4.4.0 Oct 19/2014
data. Thanks to Gazelle, Smacker, RedWizzard, Haringer, Wolverine.
It's only data but it's a big update and a lot of work went into it :)

v4.3.0 Oct 17/2014
. (gazelle) Added "--zero" option to "update --all" which makes the default
value for demand/stock levels "0" instead of "-1". (-1 means 'unknown'.
Use this option if you are editing timestamps and stock levels and all
those '-'s get in your way)
. (gazelle) Moved Star, System, etc data out of ".sql" file and into
per-table ".csv" files. This should make it much easier for people to
share and synchronize data and make it less daunting for people to
maintain their data files. Great work, Gazelle!

(See end of file for older changes)


Expand Down Expand Up @@ -354,21 +351,26 @@ UPDATE sub-command:
the prices for a given station into a text file and let you edit it
with your favorite editor.

trade.py update [--editor <executable> | --sublime | --notepad | --npp | --vim] station
trade.py update

--editor <executable name or path>
e.g. --editor "C:\Program Files\WibbleEdit\WibbleEdit.exe"
Saves the prices in a human-readable format and loads that into
an editor. Make changes and save to update the database.

--all
Exposes timestamp, demand and stock value columns.
--supply
-S
Exposes the "demand" and "stock" columns.

--timestamps
-T
Exposes the "timestamp" column.

--zero
Requires --all
Causes unknown demand/stock levels to show as 0 instead of -1.
Use this when you are actively editing those fields and the -1s
get in your way.
--force-na
-0
Changes the default demand/stock to be "n/a".
CAUTION: "n/a" indicates that the item is either not bought
or not sold at this station, and TD will ignore it accordingly.

--sublime
--subl
Expand All @@ -391,9 +393,13 @@ UPDATE sub-command:

Examples:
trade.py update "aulin enterprise" --notepad
trade.py update chango --subl
trade.py update chango --subl --supply
trade.py update anderson --editor "C:\Program Files\Microsoft Office\WordPad.exe"
trade.py update wcm
trade.py update wcm --timestamps
trade.py update --sub --sup --time --zero aulin
aka:
trade.py update --sub -ST0 aulin


NAV sub-command:

Expand Down Expand Up @@ -600,6 +606,16 @@ See "cli.py" for examples.
== Change Log Archive
==============================================================================

v4.3.0 Oct 17/2014
. (gazelle) Added "--zero" option to "update --all" which makes the default
value for demand/stock levels "0" instead of "-1". (-1 means 'unknown'.
Use this option if you are editing timestamps and stock levels and all
those '-'s get in your way)
. (gazelle) Moved Star, System, etc data out of ".sql" file and into
per-table ".csv" files. This should make it much easier for people to
share and synchronize data and make it less daunting for people to
maintain their data files. Great work, Gazelle!

v4.2.3 Oct 17/2014
. (ShadowGar, Smacker65) Imported Harbinger and RedWizzard system data,
also added tracking of where data has come from. Thanks also to Wolverine
Expand Down
38 changes: 23 additions & 15 deletions buildcache.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,19 +113,20 @@ class UnitsAndLevel(object):
'H': 3, '3': 3,
}
# Split a <units>L<level> reading
splitLRe = re.compile(r'^(?P<units>\d+)L(?P<level>-\d+)$')
splitLRe = re.compile(r'^(?P<units>\d+)L(?P<level>-?\d+)$')
# Split a <units><level> reading
splitAtRe = re.compile(r'^(?P<units>\d+)(?P<level>[\?LMH])$', re.IGNORECASE)

def __init__(self, category, reading):
if reading in (None, "unk", "-1L-1", "-1L0", "0L-1"):
ucReading = reading.upper()
if ucReading in ("UNK", "-1L-1", "-1L0", "0L-1"):
self.units, self.level = -1, -1
elif reading in ("-", "-L-", "n/a", "0"):
elif ucReading in ("-", "-L-", "N/A", "0"):
self.units, self.level = 0, 0
else:
matches = self.splitLRe.match(reading) or self.splitAtRe.match(reading)
matches = self.splitLRe.match(ucReading) or self.splitAtRe.match(ucReading)
if not matches:
raise ValueError("Invalid {} units/level value. Expected 'unk', <units>L<level> or <units>[\?LMH], got '{}'".format(category, reading))
raise ValueError("Invalid {} units/level value. Expected 'unk', <units>L<level> or <units>[?LMH], got '{}'".format(category, reading))
units, level = matches.group('units', 'level')
try:
self.units, self.level = int(units), UnitsAndLevel.levels[level]
Expand Down Expand Up @@ -153,7 +154,7 @@ class PriceEntry(namedtuple('PriceEntry', [ 'stationID', 'itemID', 'asking', 'pa
pass


def priceLineNegotiator(priceFile, db, debug=0):
def genSQLFromPriceLines(priceFile, db, defaultZero, debug=0):
"""
Yields SQL for populating the database with prices
by reading the file handle for price lines.
Expand All @@ -178,7 +179,11 @@ def priceLineNegotiator(priceFile, db, debug=0):
else:
itemsByName = { name: itemID for (itemID, name) in cur.execute("SELECT item_id, name FROM item") }

defaultUnits = -1 if not defaultZero else 0
defaultLevel = -1 if not defaultZero else 0

lineNo = 0

for line in priceFile:
lineNo += 1
try:
Expand Down Expand Up @@ -219,8 +224,13 @@ def priceLineNegotiator(priceFile, db, debug=0):
raise ValueError("Unrecognized line/syntax: {}".format(line))

itemName, stationPaying, stationAsking, modified = matches.group('item'), int(matches.group('paying')), int(matches.group('asking')), matches.group('time')
demand = UnitsAndLevel('demand', matches.group('demand'))
stock = UnitsAndLevel('stock', matches.group('stock'))
demandString, stockString = matches.group('demand'), matches.group('stock')
if demandString and stockString:
demand = UnitsAndLevel('demand', demandString)
stock = UnitsAndLevel('stock', stockString)
demandUnits, demandLevel, stockUnits, stockLevel = demand.units, demand.level, stock.units, stock.level
else:
demandUnits, demandLevel, stockUnits, stockLevel = defaultUnits, defaultLevel, defaultUnits, defaultLevel
if modified and modified.lower() in ('now', '"now"', "'now'"):
modified = None # Use CURRENT_FILESTAMP

Expand All @@ -230,14 +240,12 @@ def priceLineNegotiator(priceFile, db, debug=0):
raise UnknownItemError(priceFile, lineNo, key)

uiOrder += 1
yield PriceEntry(stationID, itemID, stationPaying, stationAsking, uiOrder, modified, demand.units, demand.level, stock.units, stock.level)
yield PriceEntry(stationID, itemID, stationPaying, stationAsking, uiOrder, modified, demandUnits, demandLevel, stockUnits, stockLevel)
except UnknownItemError:
continue


def processPricesFile(db, pricesPath, stationID=None, debug=0):
global currentTimestamp

def processPricesFile(db, pricesPath, stationID=None, defaultZero=False, debug=0):
if debug: print("* Processing Prices file '{}'".format(str(pricesPath)))

if stationID:
Expand All @@ -247,7 +255,7 @@ def processPricesFile(db, pricesPath, stationID=None, debug=0):
try:
with pricesPath.open() as pricesFile:
bindValues = []
for price in priceLineNegotiator(pricesFile, db, debug):
for price in genSQLFromPriceLines(pricesFile, db, defaultZero, debug):
if debug > 2: print(price)
bindValues += [ price ]
stmt = """
Expand Down Expand Up @@ -308,7 +316,7 @@ def processImportFile(db, importPath, tableName, debug=0):
print("WARNING: processImportFile found no {} file".format(importPath))


def buildCache(dbPath, sqlPath, pricesPath, importTables, debug=0):
def buildCache(dbPath, sqlPath, pricesPath, importTables, defaultZero=False, debug=0):
"""
Rebuilds the SQlite database from source files.
Expand Down Expand Up @@ -338,7 +346,7 @@ def buildCache(dbPath, sqlPath, pricesPath, importTables, debug=0):
processImportFile(tempDB, Path(importName), importTable, debug=debug)

# Parse the prices file
processPricesFile(tempDB, pricesPath, debug=debug)
processPricesFile(tempDB, pricesPath, defaultZero=defaultZero, debug=debug)

# Database is ready; copy it to a persistent store.
if debug: print("* Populating SQLite database file '%s'" % dbPath)
Expand Down
26 changes: 19 additions & 7 deletions prices.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,23 @@
import re
import sqlite3


class Element(object):
basic = (1 << 0)
supply = (1 << 1)
timestamp = (1 << 2)
full = (basic | supply | timestamp)


######################################################################
# Main

def dumpPrices(dbFilename, withModified=False, withLevels=False, stationID=None, file=None, defaultZero=False, debug=0):
def dumpPrices(dbFilename, elementMask, stationID=None, file=None, defaultZero=False, debug=0):
""" Generate a 'prices' list for the given list of stations using data from the DB. """

withSupply = (elementMask & Element.supply)
withTimes = (elementMask & Element.timestamp)

conn = sqlite3.connect(str(dbFilename)) # so we can handle a Path object too
cur = conn.cursor()

Expand Down Expand Up @@ -124,10 +136,10 @@ def itemQtyAndLevel(quantity, level):
levelWidth = 8

file.write("# {:<{width}} {:>{crwidth}} {:>{crwidth}}".format("Item Name", "Sell Cr", "Buy Cr", width=longestNameLen, crwidth=maxCrWidth))
if withLevels:
if withSupply:
file.write(" {:>{lvlwidth}} {:>{lvlwidth}}".format("Demand", "Stock", lvlwidth=levelWidth))
if withModified:
file.write(" {}".format("Modified"))
if withTimes:
file.write(" {}".format("Timestamp"))
file.write("\n\n")

for (sysID, stnID, catID, itemID, fromStn, toStn, modified, demand, demandLevel, stock, stockLevel) in cur:
Expand All @@ -150,17 +162,17 @@ def itemQtyAndLevel(quantity, level):
lastCat = category

file.write(" {:<{width}} {:{crwidth}d} {:{crwidth}d}".format(items[itemID], fromStn, toStn, width=longestNameLen, crwidth=maxCrWidth))
if withLevels:
if withSupply:
file.write(" {:>{lvlwidth}} {:>{lvlwidth}}".format(
itemQtyAndLevel(demand, demandLevel),
itemQtyAndLevel(stock, stockLevel),
lvlwidth=levelWidth,
))
if withModified:
if withTimes:
file.write(" {}".format(modified or 'now'))
file.write("\n")


if __name__ == "__main__":
from tradedb import TradeDB
dumpPrices(TradeDB.defaultDB, withModified=True, withLevels=True)
dumpPrices(TradeDB.defaultDB, elementMask=Element.full)
Loading

0 comments on commit 04ab156

Please sign in to comment.