Merge branch 'pricing'

This commit is contained in:
blitzmann
2015-07-03 02:38:23 -04:00
7 changed files with 46 additions and 63 deletions

View File

@@ -26,6 +26,7 @@ class Price(object):
def __init__(self, typeID): def __init__(self, typeID):
self.typeID = typeID self.typeID = typeID
self.time = 0 self.time = 0
self.price = 0
self.failed = None self.failed = None
self.__item = None self.__item = None

View File

@@ -30,37 +30,13 @@ class PriceViewFull(StatsView):
def __init__(self, parent): def __init__(self, parent):
StatsView.__init__(self) StatsView.__init__(self)
self.parent = parent self.parent = parent
self._timerId = wx.NewId()
self._timer = None
self.parent.Bind(wx.EVT_TIMER, self.OnTimer)
self._timerRunsBeforeUpdate = 60
self._timerRuns = 0
self._timerIdUpdate = wx.NewId()
self._timerUpdate = None
self._cachedShip = 0 self._cachedShip = 0
self._cachedFittings = 0 self._cachedFittings = 0
self._cachedTotal = 0 self._cachedTotal = 0
def OnTimer(self, event):
if self._timerId == event.GetId():
if self._timerRuns >= self._timerRunsBeforeUpdate:
self._timerRuns = 0
self._timer.Stop()
self.refreshPanel(self.fit)
else:
self.labelEMStatus.SetLabel("Prices update retry in: %d seconds" %(self._timerRunsBeforeUpdate - self._timerRuns))
self._timerRuns += 1
if self._timerIdUpdate == event.GetId():
self._timerUpdate.Stop()
self.labelEMStatus.SetLabel("")
def getHeaderText(self, fit): def getHeaderText(self, fit):
return "Price" return "Price"
def getTextExtentW(self, text):
width, height = self.parent.GetTextExtent(text)
return width
def populatePanel(self, contentPanel, headerPanel): def populatePanel(self, contentPanel, headerPanel):
contentSizer = contentPanel.GetSizer() contentSizer = contentPanel.GetSizer()
self.panel = contentPanel self.panel = contentPanel
@@ -111,22 +87,11 @@ class PriceViewFull(StatsView):
for cargo in fit.cargo: for cargo in fit.cargo:
for _ in xrange(cargo.amount): for _ in xrange(cargo.amount):
typeIDs.append(cargo.itemID) typeIDs.append(cargo.itemID)
if self._timer:
if self._timer.IsRunning():
self._timer.Stop()
sMkt = service.Market.getInstance() sMkt = service.Market.getInstance()
sMkt.getPrices(typeIDs, self.processPrices) sMkt.getPrices(typeIDs, self.processPrices)
self.labelEMStatus.SetLabel("Updating prices...") self.labelEMStatus.SetLabel("Updating prices...")
if not self._timerUpdate:
self._timerUpdate = wx.Timer(self.parent, self._timerIdUpdate)
if self._timerUpdate:
if not self._timerUpdate.IsRunning():
self._timerUpdate.Start(1000)
else: else:
if self._timer:
if self._timer.IsRunning():
self._timer.Stop()
self.labelEMStatus.SetLabel("") self.labelEMStatus.SetLabel("")
self.labelPriceShip.SetLabel("0.0 ISK") self.labelPriceShip.SetLabel("0.0 ISK")
self.labelPriceFittings.SetLabel("0.0 ISK") self.labelPriceFittings.SetLabel("0.0 ISK")
@@ -136,20 +101,10 @@ class PriceViewFull(StatsView):
def processPrices(self, prices): def processPrices(self, prices):
shipPrice = prices[0].price shipPrice = prices[0].price
if shipPrice == None:
if not self._timer:
self._timer = wx.Timer(self.parent, self._timerId)
self._timer.Start(1000)
self._timerRuns = 0
else:
if self._timer:
self._timer.Stop()
self.labelEMStatus.SetLabel("")
if shipPrice == None:
shipPrice = 0
modPrice = sum(map(lambda p: p.price or 0, prices[1:])) modPrice = sum(map(lambda p: p.price or 0, prices[1:]))
self.labelEMStatus.SetLabel("")
if self._cachedShip != shipPrice: if self._cachedShip != shipPrice:
self.labelPriceShip.SetLabel("%s ISK" % formatAmount(shipPrice, 3, 3, 9, currency=True)) self.labelPriceShip.SetLabel("%s ISK" % formatAmount(shipPrice, 3, 3, 9, currency=True))
self.labelPriceShip.SetToolTip(wx.ToolTip(locale.format('%.2f', shipPrice, 1))) self.labelPriceShip.SetToolTip(wx.ToolTip(locale.format('%.2f', shipPrice, 1)))

View File

@@ -39,7 +39,7 @@ class Price(ViewColumn):
sMkt = service.Market.getInstance() sMkt = service.Market.getInstance()
price = sMkt.getPriceNow(stuff.item.ID) price = sMkt.getPriceNow(stuff.item.ID)
if not price or not price.price: if not price or not price.price or not price.isValid:
return False return False
price = price.price # Set new price variable with what we need price = price.price # Set new price variable with what we need
@@ -50,12 +50,17 @@ class Price(ViewColumn):
return formatAmount(price, 3, 3, 9, currency=True) return formatAmount(price, 3, 3, 9, currency=True)
def delayedText(self, mod, display, colItem): def delayedText(self, mod, display, colItem):
def callback(requests): sMkt = service.Market.getInstance()
price = requests[0].price def callback(item):
colItem.SetText(formatAmount(price, 3, 3, 9, currency=True) if price else "") price = sMkt.getPriceNow(item.ID)
text = formatAmount(price.price, 3, 3, 9, currency=True) if price.price else ""
if price.failed: text += " (!)"
colItem.SetText(text)
display.SetItem(colItem) display.SetItem(colItem)
service.Market.getInstance().getPrices([mod.item.ID], callback)
sMkt.waitForPrice(mod.item, callback)
def getImageId(self, mod): def getImageId(self, mod):
return -1 return -1

View File

@@ -250,7 +250,7 @@ class Display(wx.ListCtrl):
newText = col.getText(st) newText = col.getText(st)
if newText is False: if newText is False:
col.delayedText(st, self, colItem) col.delayedText(st, self, colItem)
newText = "" newText = u"\u21bb"
newImageId = col.getImageId(st) newImageId = col.getImageId(st)

BIN
icons/refresh_small.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 B

View File

@@ -71,6 +71,7 @@ class ShipBrowserWorkerThread(threading.Thread):
class PriceWorkerThread(threading.Thread): class PriceWorkerThread(threading.Thread):
def run(self): def run(self):
self.queue = Queue.Queue() self.queue = Queue.Queue()
self.wait = {}
self.processUpdates() self.processUpdates()
def processUpdates(self): def processUpdates(self):
@@ -86,9 +87,21 @@ class PriceWorkerThread(threading.Thread):
wx.CallAfter(callback) wx.CallAfter(callback)
queue.task_done() queue.task_done()
# After we fetch prices, go through the list of waiting items and call their callbacks
for price in requests:
callbacks = self.wait.pop(price.typeID, None)
if callbacks:
for callback in callbacks:
wx.CallAfter(callback)
def trigger(self, prices, callbacks): def trigger(self, prices, callbacks):
self.queue.put((callbacks, prices)) self.queue.put((callbacks, prices))
def setToWait(self, itemID, callback):
if itemID not in self.wait:
self.wait[itemID] = []
self.wait[itemID].append(callback)
class SearchWorkerThread(threading.Thread): class SearchWorkerThread(threading.Thread):
def run(self): def run(self):
self.cv = threading.Condition() self.cv = threading.Condition()
@@ -693,10 +706,6 @@ class Market():
self.priceCache[typeID] = price self.priceCache[typeID] = price
if not price.isValid:
# if the price has expired
price.price = None
return price return price
def getPricesNow(self, typeIDs): def getPricesNow(self, typeIDs):
@@ -719,6 +728,21 @@ class Market():
self.priceWorkerThread.trigger(requests, cb) self.priceWorkerThread.trigger(requests, cb)
def waitForPrice(self, item, callback):
"""
Wait for prices to be fetched and callback when finished. This is used with the column prices for modules.
Instead of calling them individually, we set them to wait until the entire fit price is called and calculated
(see GH #290)
"""
def cb():
try:
callback(item)
except:
pass
self.priceWorkerThread.setToWait(item.ID, cb)
def clearPriceCache(self): def clearPriceCache(self):
self.priceCache.clear() self.priceCache.clear()
deleted_rows = eos.db.clearPrices() deleted_rows = eos.db.clearPrices()

View File

@@ -71,7 +71,6 @@ class Price():
# Attempt to send request and process it # Attempt to send request and process it
try: try:
len(priceMap)
network = service.Network.getInstance() network = service.Network.getInstance()
data = network.request(baseurl, network.PRICES, data) data = network.request(baseurl, network.PRICES, data)
xml = minidom.parse(data) xml = minidom.parse(data)
@@ -102,7 +101,7 @@ class Price():
for typeID in priceMap.keys(): for typeID in priceMap.keys():
priceobj = priceMap[typeID] priceobj = priceMap[typeID]
priceobj.time = time.time() + TIMEOUT priceobj.time = time.time() + TIMEOUT
priceobj.failed = None priceobj.failed = True
del priceMap[typeID] del priceMap[typeID]
except: except:
# all other errors will pass and continue onward to the REREQUEST delay # all other errors will pass and continue onward to the REREQUEST delay
@@ -111,6 +110,5 @@ class Price():
# if we get to this point, then we've got an error. Set to REREQUEST delay # if we get to this point, then we've got an error. Set to REREQUEST delay
for typeID in priceMap.keys(): for typeID in priceMap.keys():
priceobj = priceMap[typeID] priceobj = priceMap[typeID]
priceobj.price = 0
priceobj.time = time.time() + REREQUEST priceobj.time = time.time() + REREQUEST
priceobj.failed = None priceobj.failed = True