Merge branch 'master' into fit_export_options
This commit is contained in:
17
eos/db/migrations/upgrade30.py
Normal file
17
eos/db/migrations/upgrade30.py
Normal file
@@ -0,0 +1,17 @@
|
||||
"""
|
||||
Migration 30
|
||||
|
||||
- changes to prices table
|
||||
"""
|
||||
|
||||
|
||||
import sqlalchemy
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
try:
|
||||
saveddata_engine.execute("SELECT status FROM prices LIMIT 1")
|
||||
except sqlalchemy.exc.DatabaseError:
|
||||
# Just drop table, table will be re-created by sqlalchemy and
|
||||
# data will be re-fetched
|
||||
saveddata_engine.execute("DROP TABLE prices;")
|
||||
@@ -17,17 +17,20 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
|
||||
from sqlalchemy import Table, Column, Float, Integer
|
||||
from sqlalchemy.orm import mapper
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.saveddata.price import Price
|
||||
|
||||
|
||||
prices_table = Table("prices", saveddata_meta,
|
||||
Column("typeID", Integer, primary_key=True),
|
||||
Column("price", Float, default=0.0),
|
||||
Column("time", Integer, nullable=False),
|
||||
Column("failed", Integer))
|
||||
Column("status", Integer, nullable=False))
|
||||
|
||||
|
||||
mapper(Price, prices_table, properties={
|
||||
"_Price__price": prices_table.c.price,
|
||||
|
||||
@@ -446,17 +446,6 @@ class Item(EqBase):
|
||||
|
||||
@property
|
||||
def price(self):
|
||||
priceObj = self.priceObj
|
||||
if not priceObj:
|
||||
return 0
|
||||
else:
|
||||
return priceObj.price
|
||||
|
||||
@property
|
||||
def priceObj(self):
|
||||
if not self.marketGroupID:
|
||||
return None
|
||||
|
||||
# todo: use `from sqlalchemy import inspect` instead (mac-deprecated doesn't have inspect(), was imp[lemented in 0.8)
|
||||
if self.__priceObj is not None and getattr(self.__priceObj, '_sa_instance_state', None) and self.__priceObj._sa_instance_state.deleted:
|
||||
pyfalog.debug("Price data for {} was deleted (probably from a cache reset), resetting object".format(self.ID))
|
||||
@@ -469,10 +458,7 @@ class Item(EqBase):
|
||||
pyfalog.debug("Creating a price for {}".format(self.ID))
|
||||
self.__priceObj = types_Price(self.ID)
|
||||
eos.db.add(self.__priceObj)
|
||||
# Commented out by DarkPhoenix: it caused issues when opening stats for item with many
|
||||
# variations, as each commit takes ~50 ms, for items with 30 variations time to open stats
|
||||
# window could reach 2 seconds. Hopefully just adding it is sufficient.
|
||||
# eos.db.commit()
|
||||
eos.db.commit()
|
||||
else:
|
||||
self.__priceObj = db_price
|
||||
|
||||
|
||||
@@ -215,6 +215,8 @@ class ModifiedAttributeDict(collections.MutableMapping):
|
||||
if force is not None:
|
||||
if cappingValue is not None:
|
||||
force = min(force, cappingValue)
|
||||
if key in (50, 30, 48, 11):
|
||||
force = round(force, 2)
|
||||
return force
|
||||
# Grab our values if they're there, otherwise we'll take default values
|
||||
preIncrease = self.__preIncreases.get(key, 0)
|
||||
@@ -268,7 +270,8 @@ class ModifiedAttributeDict(collections.MutableMapping):
|
||||
# Cap value if we have cap defined
|
||||
if cappingValue is not None:
|
||||
val = min(val, cappingValue)
|
||||
|
||||
if key in (50, 30, 48, 11):
|
||||
val = round(val, 2)
|
||||
return val
|
||||
|
||||
def __handleSkill(self, skillName):
|
||||
|
||||
@@ -1016,11 +1016,11 @@ class Fit(object):
|
||||
|
||||
@property
|
||||
def pgUsed(self):
|
||||
return self.getItemAttrOnlineSum(self.modules, "power")
|
||||
return round(self.getItemAttrOnlineSum(self.modules, "power"), 2)
|
||||
|
||||
@property
|
||||
def cpuUsed(self):
|
||||
return self.getItemAttrOnlineSum(self.modules, "cpu")
|
||||
return round(self.getItemAttrOnlineSum(self.modules, "cpu"), 2)
|
||||
|
||||
@property
|
||||
def droneBandwidthUsed(self):
|
||||
|
||||
@@ -18,24 +18,30 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
import time
|
||||
|
||||
from sqlalchemy.orm import reconstructor
|
||||
import time
|
||||
from enum import IntEnum, unique
|
||||
|
||||
from logbook import Logger
|
||||
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
@unique
|
||||
class PriceStatus(IntEnum):
|
||||
notFetched = 0
|
||||
success = 1
|
||||
fail = 2
|
||||
notSupported = 3
|
||||
|
||||
|
||||
class Price(object):
|
||||
def __init__(self, typeID):
|
||||
self.typeID = typeID
|
||||
self.time = 0
|
||||
self.__price = 0
|
||||
self.failed = None
|
||||
|
||||
@reconstructor
|
||||
def init(self):
|
||||
self.__item = None
|
||||
self.status = PriceStatus.notFetched
|
||||
|
||||
@property
|
||||
def isValid(self):
|
||||
@@ -43,7 +49,10 @@ class Price(object):
|
||||
|
||||
@property
|
||||
def price(self):
|
||||
return self.__price or 0.0
|
||||
if self.status in (PriceStatus.fail, PriceStatus.notSupported):
|
||||
return 0
|
||||
else:
|
||||
return self.__price or 0
|
||||
|
||||
@price.setter
|
||||
def price(self, price):
|
||||
|
||||
@@ -133,7 +133,7 @@ class ItemCompare(wx.Panel):
|
||||
except IndexError:
|
||||
# Price
|
||||
if sort == len(self.attrs) + 1:
|
||||
func = lambda i: i.price if i.price != 0 else float("Inf")
|
||||
func = lambda i: i.price.price if i.price.price != 0 else float("Inf")
|
||||
# Something else
|
||||
else:
|
||||
self.sortReverse = False
|
||||
@@ -168,7 +168,7 @@ class ItemCompare(wx.Panel):
|
||||
self.paramList.SetItem(i, x + 1, valueUnit)
|
||||
|
||||
# Add prices
|
||||
self.paramList.SetItem(i, len(self.attrs) + 1, formatAmount(item.price, 3, 3, 9, currency=True) if item.price else "")
|
||||
self.paramList.SetItem(i, len(self.attrs) + 1, formatAmount(item.price.price, 3, 3, 9, currency=True) if item.price.price else "")
|
||||
|
||||
self.paramList.RefreshRows()
|
||||
self.Layout()
|
||||
|
||||
@@ -100,32 +100,32 @@ class PriceViewFull(StatsView):
|
||||
implant_price = 0
|
||||
|
||||
if fit:
|
||||
ship_price = fit.ship.item.price
|
||||
ship_price = fit.ship.item.price.price
|
||||
|
||||
if fit.modules:
|
||||
for module in fit.modules:
|
||||
if not module.isEmpty:
|
||||
module_price += module.item.price
|
||||
module_price += module.item.price.price
|
||||
|
||||
if fit.drones:
|
||||
for drone in fit.drones:
|
||||
drone_price += drone.item.price * drone.amount
|
||||
drone_price += drone.item.price.price * drone.amount
|
||||
|
||||
if fit.fighters:
|
||||
for fighter in fit.fighters:
|
||||
fighter_price += fighter.item.price * fighter.amountActive
|
||||
fighter_price += fighter.item.price.price * fighter.amountActive
|
||||
|
||||
if fit.cargo:
|
||||
for cargo in fit.cargo:
|
||||
cargo_price += cargo.item.price * cargo.amount
|
||||
cargo_price += cargo.item.price.price * cargo.amount
|
||||
|
||||
if fit.boosters:
|
||||
for booster in fit.boosters:
|
||||
booster_price += booster.item.price
|
||||
booster_price += booster.item.price.price
|
||||
|
||||
if fit.implants:
|
||||
for implant in fit.implants:
|
||||
implant_price += implant.item.price
|
||||
implant_price += implant.item.price.price
|
||||
|
||||
total_price = 0
|
||||
|
||||
|
||||
@@ -94,32 +94,32 @@ class PriceViewMinimal(StatsView):
|
||||
implant_price = 0
|
||||
|
||||
if fit:
|
||||
ship_price = fit.ship.item.price
|
||||
ship_price = fit.ship.item.price.price
|
||||
|
||||
if fit.modules:
|
||||
for module in fit.modules:
|
||||
if not module.isEmpty:
|
||||
module_price += module.item.price
|
||||
module_price += module.item.price.price
|
||||
|
||||
if fit.drones:
|
||||
for drone in fit.drones:
|
||||
drone_price += drone.item.price * drone.amount
|
||||
drone_price += drone.item.price.price * drone.amount
|
||||
|
||||
if fit.fighters:
|
||||
for fighter in fit.fighters:
|
||||
fighter_price += fighter.item.price * fighter.amountActive
|
||||
fighter_price += fighter.item.price.price * fighter.amountActive
|
||||
|
||||
if fit.cargo:
|
||||
for cargo in fit.cargo:
|
||||
cargo_price += cargo.item.price * cargo.amount
|
||||
cargo_price += cargo.item.price.price * cargo.amount
|
||||
|
||||
if fit.boosters:
|
||||
for booster in fit.boosters:
|
||||
booster_price += booster.item.price
|
||||
booster_price += booster.item.price.price
|
||||
|
||||
if fit.implants:
|
||||
for implant in fit.implants:
|
||||
implant_price += implant.item.price
|
||||
implant_price += implant.item.price.price
|
||||
|
||||
fitting_price = module_price
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import wx
|
||||
|
||||
from eos.saveddata.cargo import Cargo
|
||||
from eos.saveddata.drone import Drone
|
||||
from eos.saveddata.price import PriceStatus
|
||||
from service.price import Price as ServicePrice
|
||||
from gui.viewColumn import ViewColumn
|
||||
from gui.bitmap_loader import BitmapLoader
|
||||
@@ -45,10 +46,7 @@ class Price(ViewColumn):
|
||||
if stuff.isEmpty:
|
||||
return ""
|
||||
|
||||
priceObj = stuff.item.priceObj
|
||||
|
||||
if not priceObj:
|
||||
return ""
|
||||
priceObj = stuff.item.price
|
||||
|
||||
if not priceObj.isValid:
|
||||
return False
|
||||
@@ -69,10 +67,12 @@ class Price(ViewColumn):
|
||||
|
||||
def callback(item):
|
||||
price = item[0]
|
||||
text = formatAmount(price.price, 3, 3, 9, currency=True) if price.price else ""
|
||||
if price.failed:
|
||||
text += " (!)"
|
||||
colItem.SetText(text)
|
||||
textItems = []
|
||||
if price.price:
|
||||
textItems.append(formatAmount(price.price, 3, 3, 9, currency=True))
|
||||
if price.status == PriceStatus.fail:
|
||||
textItems.append("(!)")
|
||||
colItem.SetText(" ".join(textItems))
|
||||
|
||||
display.SetItem(colItem)
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import wx
|
||||
from logbook import Logger
|
||||
|
||||
from eos import db
|
||||
from eos.saveddata.price import PriceStatus
|
||||
from service.fit import Fit
|
||||
from service.market import Market
|
||||
from service.network import TimeoutError
|
||||
@@ -85,13 +86,18 @@ class Price(object):
|
||||
toRequest = set()
|
||||
|
||||
# Compose list of items we're going to request
|
||||
for typeID in priceMap:
|
||||
for typeID in tuple(priceMap):
|
||||
# Get item object
|
||||
item = db.getItem(typeID)
|
||||
# We're not going to request items only with market group, as eve-central
|
||||
# doesn't provide any data for items not on the market
|
||||
if item is not None and item.marketGroupID:
|
||||
toRequest.add(typeID)
|
||||
if item is None:
|
||||
continue
|
||||
if not item.marketGroupID:
|
||||
priceMap[typeID].status = PriceStatus.notSupported
|
||||
del priceMap[typeID]
|
||||
continue
|
||||
toRequest.add(typeID)
|
||||
|
||||
# Do not waste our time if all items are not on the market
|
||||
if len(toRequest) == 0:
|
||||
@@ -117,11 +123,10 @@ class Price(object):
|
||||
except TimeoutError:
|
||||
# Timeout error deserves special treatment
|
||||
pyfalog.warning("Price fetch timout")
|
||||
for typeID in priceMap.keys():
|
||||
for typeID in tuple(priceMap):
|
||||
priceobj = priceMap[typeID]
|
||||
priceobj.time = time.time() + TIMEOUT
|
||||
priceobj.failed = True
|
||||
|
||||
priceobj.status = PriceStatus.fail
|
||||
del priceMap[typeID]
|
||||
except Exception as ex:
|
||||
# something happened, try another source
|
||||
@@ -134,7 +139,7 @@ class Price(object):
|
||||
for typeID in priceMap.keys():
|
||||
priceobj = priceMap[typeID]
|
||||
priceobj.time = time.time() + REREQUEST
|
||||
priceobj.failed = True
|
||||
priceobj.status = PriceStatus.fail
|
||||
|
||||
@classmethod
|
||||
def fitItemsList(cls, fit):
|
||||
@@ -167,16 +172,15 @@ class Price(object):
|
||||
sMkt = Market.getInstance()
|
||||
item = sMkt.getItem(objitem)
|
||||
|
||||
return item.price
|
||||
return item.price.price
|
||||
|
||||
def getPrices(self, objitems, callback, waitforthread=False):
|
||||
"""Get prices for multiple typeIDs"""
|
||||
requests = []
|
||||
sMkt = Market.getInstance()
|
||||
for objitem in objitems:
|
||||
priceobj = sMkt.getItem(objitem).priceObj
|
||||
if priceobj:
|
||||
requests.append(priceobj)
|
||||
item = sMkt.getItem(objitem)
|
||||
requests.append(item.price)
|
||||
|
||||
def cb():
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user