diff --git a/gui/builtinPreferenceViews/pyfaGeneralPreferences.py b/gui/builtinPreferenceViews/pyfaGeneralPreferences.py index 6cb611797..00b06202e 100644 --- a/gui/builtinPreferenceViews/pyfaGeneralPreferences.py +++ b/gui/builtinPreferenceViews/pyfaGeneralPreferences.py @@ -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()) diff --git a/service/marketSources/evecentral.py b/service/marketSources/evecentral.py index 3a17ac957..e323015c5 100644 --- a/service/marketSources/evecentral.py +++ b/service/marketSources/evecentral.py @@ -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) diff --git a/service/marketSources/evemarketdata.py b/service/marketSources/evemarketdata.py index 0b3c63dac..0a5861388 100644 --- a/service/marketSources/evemarketdata.py +++ b/service/marketSources/evemarketdata.py @@ -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) diff --git a/service/network.py b/service/network.py index a990fee23..893ccbb33 100644 --- a/service/network.py +++ b/service/network.py @@ -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) diff --git a/service/price.py b/service/price.py index 4df9aaa31..ee42e5f2e 100644 --- a/service/price.py +++ b/service/price.py @@ -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