diff --git a/gui/builtinPreferenceViews/pyfaGeneralPreferences.py b/gui/builtinPreferenceViews/pyfaGeneralPreferences.py
index acdfb398b..6cb611797 100644
--- a/gui/builtinPreferenceViews/pyfaGeneralPreferences.py
+++ b/gui/builtinPreferenceViews/pyfaGeneralPreferences.py
@@ -90,7 +90,9 @@ class PFGeneralPref(PreferenceView):
self.stDefaultSystem.Wrap(-1)
priceSizer.Add(self.stDefaultSystem, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
+ self.chPriceSource = wx.Choice(panel, choices=sorted(Price.sources.keys()))
self.chPriceSystem = wx.Choice(panel, choices=Price.systemsList.keys())
+ priceSizer.Add(self.chPriceSource, 1, wx.ALL | wx.EXPAND, 5)
priceSizer.Add(self.chPriceSystem, 1, wx.ALL | wx.EXPAND, 5)
mainSizer.Add(priceSizer, 0, wx.ALL | wx.EXPAND, 0)
@@ -124,6 +126,7 @@ class PFGeneralPref(PreferenceView):
self.cbGaugeAnimation.SetValue(self.sFit.serviceFittingOptions["enableGaugeAnimation"])
self.cbExportCharges.SetValue(self.sFit.serviceFittingOptions["exportCharges"])
self.cbOpenFitInNew.SetValue(self.sFit.serviceFittingOptions["openFitInNew"])
+ self.chPriceSource.SetStringSelection(self.sFit.serviceFittingOptions["priceSource"])
self.chPriceSystem.SetStringSelection(self.sFit.serviceFittingOptions["priceSystem"])
self.cbShowShipBrowserTooltip.SetValue(self.sFit.serviceFittingOptions["showShipBrowserTooltip"])
self.intDelay.SetValue(self.sFit.serviceFittingOptions["marketSearchDelay"])
@@ -140,6 +143,7 @@ class PFGeneralPref(PreferenceView):
self.cbGaugeAnimation.Bind(wx.EVT_CHECKBOX, self.onCBGaugeAnimation)
self.cbExportCharges.Bind(wx.EVT_CHECKBOX, self.onCBExportCharges)
self.cbOpenFitInNew.Bind(wx.EVT_CHECKBOX, self.onCBOpenFitInNew)
+ self.chPriceSource.Bind(wx.EVT_CHOICE, self.onPricesSourceSelection)
self.chPriceSystem.Bind(wx.EVT_CHOICE, self.onPriceSelection)
self.cbShowShipBrowserTooltip.Bind(wx.EVT_CHECKBOX, self.onCBShowShipBrowserTooltip)
self.intDelay.Bind(wx.lib.intctrl.EVT_INT, self.onMarketDelayChange)
@@ -224,5 +228,9 @@ class PFGeneralPref(PreferenceView):
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
event.Skip()
+ def onPricesSourceSelection(self, event):
+ source = self.chPriceSource.GetString(self.chPriceSource.GetSelection())
+ self.sFit.serviceFittingOptions["priceSource"] = source
+
PFGeneralPref.register()
diff --git a/service/fit.py b/service/fit.py
index 8fa36b4d4..c6898384f 100644
--- a/service/fit.py
+++ b/service/fit.py
@@ -74,6 +74,7 @@ class Fit(object):
"exportCharges": True,
"openFitInNew": False,
"priceSystem": "Jita",
+ "priceSource": "eve-central.com",
"showShipBrowserTooltip": True,
"marketSearchDelay": 250
}
diff --git a/service/marketSources/__init__.py b/service/marketSources/__init__.py
new file mode 100644
index 000000000..b093a0010
--- /dev/null
+++ b/service/marketSources/__init__.py
@@ -0,0 +1 @@
+__all__ = ['evecentral', 'evemarketdata']
\ No newline at end of file
diff --git a/service/marketSources/evecentral.py b/service/marketSources/evecentral.py
new file mode 100644
index 000000000..3a17ac957
--- /dev/null
+++ b/service/marketSources/evecentral.py
@@ -0,0 +1,87 @@
+# =============================================================================
+# Copyright (C) 2010 Diego Duclos
+#
+# This file is part of pyfa.
+#
+# pyfa is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# pyfa is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with pyfa. If not, see .
+# =============================================================================
+
+import time
+from logbook import Logger
+from xml.dom import minidom
+
+from service.network import Network
+from service.price import Price, VALIDITY, TIMEOUT, TimeoutError
+
+
+pyfalog = Logger(__name__)
+
+
+class EveCentral(object):
+
+ name = "eve-central.com"
+
+ def __init__(self, types, system, priceMap):
+ data = []
+ baseurl = "https://eve-central.com/api/marketstat"
+ data.append(("usesystem", system)) # Use Jita for market
+
+ 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
+
+ # 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
+
+
+Price.register(EveCentral)
diff --git a/service/marketSources/evemarketdata.py b/service/marketSources/evemarketdata.py
new file mode 100644
index 000000000..0b3c63dac
--- /dev/null
+++ b/service/marketSources/evemarketdata.py
@@ -0,0 +1,85 @@
+# =============================================================================
+# Copyright (C) 2010 Diego Duclos
+#
+# This file is part of pyfa.
+#
+# pyfa is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# pyfa is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with pyfa. If not, see .
+# =============================================================================
+
+import time
+from logbook import Logger
+from xml.dom import minidom
+
+from service.network import Network
+from service.price import Price, VALIDITY, TIMEOUT, TimeoutError
+
+
+pyfalog = Logger(__name__)
+
+
+class EveMarketData(object):
+
+ name = "eve-marketdata.com"
+
+ def __init__(self, types, system, priceMap):
+ data = []
+ baseurl = "https://eve-marketdata.com/api/item_prices.xml"
+ 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
+
+ try:
+ price = float(type_.firstChild.data)
+ except (TypeError, ValueError):
+ pyfalog.warning("Failed to get price for: {0}", type_)
+
+ # Fill price data
+ priceobj = priceMap[typeID]
+ 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]
+ 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
+
+
+Price.register(EveMarketData)
diff --git a/service/price.py b/service/price.py
index 9c6da235a..4df9aaa31 100644
--- a/service/price.py
+++ b/service/price.py
@@ -50,12 +50,18 @@ class Price(object):
"Hek": 30002053
}
+ sources = {}
+
def __init__(self):
# Start price fetcher
self.priceWorkerThread = PriceWorkerThread()
self.priceWorkerThread.daemon = True
self.priceWorkerThread.start()
+ @classmethod
+ def register(cls, source):
+ cls.sources[source.name] = source
+
@classmethod
def getInstance(cls):
if cls.instance is None:
@@ -92,58 +98,15 @@ class Price(object):
if len(toRequest) == 0:
return
- # This will store POST data for eve-central
- data = []
-
sFit = Fit.getInstance()
- # Base request URL
- baseurl = "https://eve-central.com/api/marketstat"
- data.append(("usesystem", cls.systemsList[sFit.serviceFittingOptions["priceSystem"]])) # Use Jita for market
- for typeID in toRequest: # Add all typeID arguments
- data.append(("typeid", typeID))
+ if len(cls.sources.keys()) == 0:
+ pyfalog.warn('No price source can be found')
+ return
- # 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
-
- # 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
+ # 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)
# if we get to this point, then we've got an error. Set to REREQUEST delay
for typeID in priceMap.keys():
@@ -246,3 +209,6 @@ class PriceWorkerThread(threading.Thread):
if itemID not in self.wait:
self.wait[itemID] = []
self.wait[itemID].append(callback)
+
+
+from service.marketSources import evecentral, evemarketdata # noqa: E402