* Try other price sources if user's preferred fails (#1342)

* Handle cached prices better when eve-marketdata returns 0 for lack of price data (#1334)
This commit is contained in:
blitzmann
2017-11-25 02:50:46 -05:00
parent 5fa43138b3
commit dea775058d
5 changed files with 76 additions and 79 deletions

View File

@@ -89,6 +89,9 @@ class PFGeneralPref(PreferenceView):
self.stDefaultSystem = wx.StaticText(panel, wx.ID_ANY, u"Default Market Prices:", wx.DefaultPosition, wx.DefaultSize, 0)
self.stDefaultSystem.Wrap(-1)
priceSizer.Add(self.stDefaultSystem, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.stDefaultSystem.SetCursor(helpCursor)
self.stDefaultSystem.SetToolTip(
wx.ToolTip('The source you choose will be tried first, but subsequent sources will be used if the preferred source fails. The system you choose is absolute and requests will not be made against other systems.'))
self.chPriceSource = wx.Choice(panel, choices=sorted(Price.sources.keys()))
self.chPriceSystem = wx.Choice(panel, choices=Price.systemsList.keys())

View File

@@ -40,48 +40,30 @@ class EveCentral(object):
for typeID in types: # Add all typeID arguments
data.append(("typeid", typeID))
# Attempt to send request and process it
try:
network = Network.getInstance()
data = network.request(baseurl, network.PRICES, data)
xml = minidom.parse(data)
types = xml.getElementsByTagName("marketstat").item(0).getElementsByTagName("type")
# Cycle through all types we've got from request
for type_ in types:
# Get data out of each typeID details tree
typeID = int(type_.getAttribute("id"))
sell = type_.getElementsByTagName("sell").item(0)
# If price data wasn't there, set price to zero
try:
percprice = float(sell.getElementsByTagName("percentile").item(0).firstChild.data)
except (TypeError, ValueError):
pyfalog.warning("Failed to get price for: {0}", type_)
percprice = 0
network = Network.getInstance()
data = network.request(baseurl, network.PRICES, data)
xml = minidom.parse(data)
types = xml.getElementsByTagName("marketstat").item(0).getElementsByTagName("type")
# Cycle through all types we've got from request
for type_ in types:
# Get data out of each typeID details tree
typeID = int(type_.getAttribute("id"))
sell = type_.getElementsByTagName("sell").item(0)
# If price data wasn't there, set price to zero
try:
percprice = float(sell.getElementsByTagName("percentile").item(0).firstChild.data)
except (TypeError, ValueError):
pyfalog.warning("Failed to get price for: {0}", type_)
percprice = 0
# Fill price data
priceobj = priceMap[typeID]
priceobj.price = percprice
priceobj.time = time.time() + VALIDITY
priceobj.failed = None
# Fill price data
priceobj = priceMap[typeID]
priceobj.price = percprice
priceobj.time = time.time() + VALIDITY
priceobj.failed = None
# delete price from working dict
del priceMap[typeID]
# If getting or processing data returned any errors
except TimeoutError:
# Timeout error deserves special treatment
pyfalog.warning("Price fetch timout")
for typeID in priceMap.keys():
priceobj = priceMap[typeID]
priceobj.time = time.time() + TIMEOUT
priceobj.failed = True
del priceMap[typeID]
except:
# all other errors will pass and continue onward to the REREQUEST delay
pyfalog.warning("Caught exception in fetchPrices")
pass
pass
# delete price from working dict
del priceMap[typeID]
Price.register(EveCentral)

View File

@@ -38,48 +38,36 @@ class EveMarketData(object):
data.append(("system_id", system)) # Use Jita for market
data.append(("type_ids", ','.join(str(x) for x in types)))
# Attempt to send request and process it
try:
network = Network.getInstance()
data = network.request(baseurl, network.PRICES, data)
xml = minidom.parse(data)
print (xml.getElementsByTagName("eve").item(0))
types = xml.getElementsByTagName("eve").item(0).getElementsByTagName("price")
# Cycle through all types we've got from request
for type_ in types:
# Get data out of each typeID details tree
typeID = int(type_.getAttribute("id"))
price = 0
network = Network.getInstance()
data = network.request(baseurl, network.PRICES, data)
xml = minidom.parse(data)
types = xml.getElementsByTagName("eve").item(0).getElementsByTagName("price")
try:
price = float(type_.firstChild.data)
except (TypeError, ValueError):
pyfalog.warning("Failed to get price for: {0}", type_)
# Cycle through all types we've got from request
for type_ in types:
# Get data out of each typeID details tree
typeID = int(type_.getAttribute("id"))
# Fill price data
priceobj = priceMap[typeID]
try:
price = float(type_.firstChild.data)
except (TypeError, ValueError):
pyfalog.warning("Failed to get price for: {0}", type_)
# Fill price data
priceobj = priceMap[typeID]
# eve-marketdata returns 0 if price data doesn't even exist for the item. In this case, don't reset the
# cached price, and set the price timeout to TIMEOUT (every 15 minutes currently). Se GH issue #1334
if price != 0:
priceobj.price = price
priceobj.time = time.time() + VALIDITY
priceobj.failed = None
# delete price from working dict
del priceMap[typeID]
# If getting or processing data returned any errors
except TimeoutError:
# Timeout error deserves special treatment
pyfalog.warning("Price fetch timout")
for typeID in priceMap.keys():
priceobj = priceMap[typeID]
else:
priceobj.time = time.time() + TIMEOUT
priceobj.failed = True
del priceMap[typeID]
except:
# all other errors will pass and continue onward to the REREQUEST delay
pyfalog.warning("Caught exception in fetchPrices")
pass
pass
priceobj.failed = None
# delete price from working dict
del priceMap[typeID]
Price.register(EveMarketData)

View File

@@ -125,6 +125,7 @@ class Network(object):
raise AuthenticationError()
elif error.code >= 500:
raise ServerError()
raise Error(error)
except urllib2.URLError as error:
pyfalog.warning("Timed out or other URL error:")
pyfalog.warning(error)

View File

@@ -105,10 +105,33 @@ class Price(object):
return
# attempt to find user's selected price source, otherwise get first one
sourceCls = cls.sources.get(sFit.serviceFittingOptions["priceSource"], cls.sources[cls.sources.keys()[0]])
sourceCls(toRequest, cls.systemsList[sFit.serviceFittingOptions["priceSystem"]], priceMap)
sourcesToTry = list(cls.sources.keys())
curr = sFit.serviceFittingOptions["priceSource"] if sFit.serviceFittingOptions["priceSource"] in sourcesToTry else sourcesToTry[0]
# if we get to this point, then we've got an error. Set to REREQUEST delay
while len(sourcesToTry) > 0:
sourcesToTry.remove(curr)
try:
sourceCls = cls.sources.get(curr)
sourceCls(toRequest, cls.systemsList[sFit.serviceFittingOptions["priceSystem"]], priceMap)
break
# If getting or processing data returned any errors
except TimeoutError:
# Timeout error deserves special treatment
pyfalog.warning("Price fetch timout")
for typeID in priceMap.keys():
priceobj = priceMap[typeID]
priceobj.time = time.time() + TIMEOUT
priceobj.failed = True
del priceMap[typeID]
except Exception as ex:
# something happened, try another source
pyfalog.warn('Failed to fetch prices from price source {}: {}'.format(curr, ex, sourcesToTry[0]))
if len(sourcesToTry) > 0:
pyfalog.warn('Trying {}'.format(sourcesToTry[0]))
curr = sourcesToTry[0]
# if we get to this point, then we've got an error in all of our sources. Set to REREQUEST delay
for typeID in priceMap.keys():
priceobj = priceMap[typeID]
priceobj.time = time.time() + REREQUEST