* 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

@@ -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