Merge branch 'feature/recent' into dev
Conflicts: eos/db/saveddata/character.py eos/db/saveddata/fit.py Implements #983 but utilizing sqlalchemy events to update the fit modified date whenever something is added/changed.
This commit is contained in:
@@ -27,12 +27,11 @@ from eos.db.gamedata.group import groups_table
|
||||
from eos.db.util import processEager, processWhere
|
||||
from eos.gamedata import AlphaClone, Attribute, Category, Group, Item, MarketGroup, MetaGroup, AttributeInfo, MetaData
|
||||
|
||||
cache = {}
|
||||
configVal = getattr(eos.config, "gamedataCache", None)
|
||||
if configVal is True:
|
||||
def cachedQuery(amount, *keywords):
|
||||
def deco(function):
|
||||
cache = {}
|
||||
|
||||
def checkAndReturn(*args, **kwargs):
|
||||
useCache = kwargs.pop("useCache", True)
|
||||
cacheKey = []
|
||||
@@ -98,6 +97,34 @@ def getItem(lookfor, eager=None):
|
||||
return item
|
||||
|
||||
|
||||
@cachedQuery(1, "lookfor")
|
||||
def getItems(lookfor, eager=None):
|
||||
"""
|
||||
Gets a list of items. Does a bit of cache hackery to get working properly -- cache
|
||||
is usually based on function calls with the parameters, needed to extract data directly.
|
||||
Works well enough. Not currently used, but it's here for possible future inclusion
|
||||
"""
|
||||
|
||||
toGet = []
|
||||
results = []
|
||||
|
||||
for id in lookfor:
|
||||
if (id, None) in cache:
|
||||
results.append(cache.get((id, None)))
|
||||
else:
|
||||
toGet.append(id)
|
||||
|
||||
if len(toGet) > 0:
|
||||
# Get items that aren't currently cached, and store them in the cache
|
||||
items = gamedata_session.query(Item).filter(Item.ID.in_(toGet)).all()
|
||||
for item in items:
|
||||
cache[(item.ID, None)] = item
|
||||
results += items
|
||||
|
||||
# sort the results based on the original indexing
|
||||
results.sort(key=lambda x: lookfor.index(x.ID))
|
||||
return results
|
||||
|
||||
@cachedQuery(1, "lookfor")
|
||||
def getAlphaClone(lookfor, eager=None):
|
||||
if isinstance(lookfor, int):
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
from sqlalchemy import Table, Column, ForeignKey, Integer, Boolean, DateTime
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from sqlalchemy.orm import mapper, relation
|
||||
import sqlalchemy.sql.functions as func
|
||||
import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.saveddata.booster import Booster
|
||||
@@ -30,8 +30,8 @@ boosters_table = Table("boosters", saveddata_meta,
|
||||
Column("itemID", Integer),
|
||||
Column("fitID", Integer, ForeignKey("fits.ID"), nullable=False),
|
||||
Column("active", Boolean),
|
||||
Column("created", DateTime, nullable=True, default=func.now()),
|
||||
Column("modified", DateTime, nullable=True, onupdate=func.now()),
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now),
|
||||
)
|
||||
|
||||
# Legacy booster side effect code, should disable but a mapper relies on it.
|
||||
|
||||
@@ -18,19 +18,24 @@
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, DateTime
|
||||
from sqlalchemy.orm import mapper
|
||||
import sqlalchemy.sql.functions as func
|
||||
from sqlalchemy.orm import mapper, relation
|
||||
import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.saveddata.cargo import Cargo
|
||||
from eos.saveddata.fit import Fit
|
||||
|
||||
cargo_table = Table("cargo", saveddata_meta,
|
||||
Column("ID", Integer, primary_key=True),
|
||||
Column("fitID", Integer, ForeignKey("fits.ID"), nullable=False, index=True),
|
||||
Column("itemID", Integer, nullable=False),
|
||||
Column("amount", Integer, nullable=False),
|
||||
Column("created", DateTime, nullable=True, default=func.now()),
|
||||
Column("modified", DateTime, nullable=True, onupdate=func.now()),
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now),
|
||||
)
|
||||
|
||||
mapper(Cargo, cargo_table)
|
||||
mapper(Cargo, cargo_table,
|
||||
properties={
|
||||
"owner": relation(Fit)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, String, DateTime, Float
|
||||
from sqlalchemy.orm import relation, mapper
|
||||
import sqlalchemy.sql.functions as func
|
||||
import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.db.saveddata.implant import charImplants_table
|
||||
@@ -39,8 +39,8 @@ characters_table = Table("characters", saveddata_meta,
|
||||
Column("alphaCloneID", Integer, nullable=True),
|
||||
Column("ownerID", ForeignKey("users.ID"), nullable=True),
|
||||
Column("secStatus", Float, nullable=True, default=0.0),
|
||||
Column("created", DateTime, nullable=True, default=func.now()),
|
||||
Column("modified", DateTime, nullable=True, onupdate=func.now()))
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now))
|
||||
|
||||
mapper(Character, characters_table,
|
||||
properties={
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, String, DateTime
|
||||
from sqlalchemy.orm import mapper
|
||||
import sqlalchemy.sql.functions as func
|
||||
import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.saveddata.crestchar import CrestChar
|
||||
@@ -29,6 +29,6 @@ crest_table = Table("crest", saveddata_meta,
|
||||
Column("name", String, nullable=False, unique=True),
|
||||
Column("refresh_token", String, nullable=False),
|
||||
# These records aren't updated. Instead, they are dropped and created, hence we don't have a modified field
|
||||
Column("created", DateTime, nullable=True, default=func.now()))
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now))
|
||||
|
||||
mapper(CrestChar, crest_table)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, String, DateTime
|
||||
from sqlalchemy.orm import mapper
|
||||
import sqlalchemy.sql.functions as func
|
||||
import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.saveddata.damagePattern import DamagePattern
|
||||
@@ -32,8 +32,8 @@ damagePatterns_table = Table("damagePatterns", saveddata_meta,
|
||||
Column("kineticAmount", Integer),
|
||||
Column("explosiveAmount", Integer),
|
||||
Column("ownerID", ForeignKey("users.ID"), nullable=True),
|
||||
Column("created", DateTime, nullable=True, default=func.now()),
|
||||
Column("modified", DateTime, nullable=True, onupdate=func.now())
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||
)
|
||||
|
||||
mapper(DamagePattern, damagePatterns_table)
|
||||
|
||||
@@ -18,11 +18,12 @@
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, Boolean, DateTime
|
||||
from sqlalchemy.orm import mapper
|
||||
import sqlalchemy.sql.functions as func
|
||||
from sqlalchemy.orm import mapper, relation
|
||||
import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.saveddata.drone import Drone
|
||||
from eos.saveddata.fit import Fit
|
||||
|
||||
drones_table = Table("drones", saveddata_meta,
|
||||
Column("groupID", Integer, primary_key=True),
|
||||
@@ -31,8 +32,12 @@ drones_table = Table("drones", saveddata_meta,
|
||||
Column("amount", Integer, nullable=False),
|
||||
Column("amountActive", Integer, nullable=False),
|
||||
Column("projected", Boolean, default=False),
|
||||
Column("created", DateTime, nullable=True, default=func.now()),
|
||||
Column("modified", DateTime, nullable=True, onupdate=func.now())
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||
)
|
||||
|
||||
mapper(Drone, drones_table)
|
||||
mapper(Drone, drones_table,
|
||||
properties={
|
||||
"owner": relation(Fit)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, Boolean, DateTime
|
||||
from sqlalchemy.orm import mapper, relation
|
||||
import sqlalchemy.sql.functions as func
|
||||
import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.saveddata.fighterAbility import FighterAbility
|
||||
@@ -33,8 +33,8 @@ fighters_table = Table("fighters", saveddata_meta,
|
||||
Column("active", Boolean, nullable=True),
|
||||
Column("amount", Integer, nullable=False),
|
||||
Column("projected", Boolean, default=False),
|
||||
Column("created", DateTime, nullable=True, default=func.now()),
|
||||
Column("modified", DateTime, nullable=True, onupdate=func.now())
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||
)
|
||||
|
||||
fighter_abilities_table = Table("fightersAbilities", saveddata_meta,
|
||||
|
||||
@@ -22,7 +22,7 @@ from sqlalchemy.orm.collections import attribute_mapped_collection
|
||||
from sqlalchemy.sql import and_
|
||||
from sqlalchemy.orm import relation, reconstructor, mapper, relationship
|
||||
from sqlalchemy import ForeignKey, Column, Integer, String, Table, Boolean, DateTime
|
||||
import sqlalchemy.sql.functions as func
|
||||
import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.db import saveddata_session
|
||||
@@ -59,8 +59,8 @@ fits_table = Table("fits", saveddata_meta,
|
||||
Column("implantLocation", Integer, nullable=False, default=ImplantLocation.FIT),
|
||||
Column("notes", String, nullable=True),
|
||||
Column("ignoreRestrictions", Boolean, default=0),
|
||||
Column("created", DateTime, nullable=True, default=func.now()),
|
||||
Column("modified", DateTime, nullable=True, onupdate=func.now())
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, default=datetime.datetime.now, onupdate=datetime.datetime.now)
|
||||
)
|
||||
|
||||
projectedFits_table = Table("projectedFits", saveddata_meta,
|
||||
@@ -68,16 +68,16 @@ projectedFits_table = Table("projectedFits", saveddata_meta,
|
||||
Column("victimID", ForeignKey("fits.ID"), primary_key=True),
|
||||
Column("amount", Integer, nullable=False, default=1),
|
||||
Column("active", Boolean, nullable=False, default=1),
|
||||
Column("created", DateTime, nullable=True, default=func.now()),
|
||||
Column("modified", DateTime, nullable=True, onupdate=func.now())
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||
)
|
||||
|
||||
commandFits_table = Table("commandFits", saveddata_meta,
|
||||
Column("boosterID", ForeignKey("fits.ID"), primary_key=True),
|
||||
Column("boostedID", ForeignKey("fits.ID"), primary_key=True),
|
||||
Column("active", Boolean, nullable=False, default=1),
|
||||
Column("created", DateTime, nullable=True, default=func.now()),
|
||||
Column("modified", DateTime, nullable=True, onupdate=func.now())
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||
)
|
||||
|
||||
|
||||
@@ -143,49 +143,70 @@ es_Fit._Fit__commandFits = association_proxy(
|
||||
"booster_fit", # .. and return the booster fit
|
||||
creator=lambda boosterID, booster_fit: CommandFit(boosterID, booster_fit)
|
||||
)
|
||||
|
||||
|
||||
# These relationships are broken out so that we can easily access it in the events stuff
|
||||
# We sometimes don't want particular relationships to cause a fit modified update (eg: projecting
|
||||
# a fit onto another would 'modify' both fits unless the following relationship is ignored)
|
||||
projectedFitSourceRel = relationship(
|
||||
ProjectedFit,
|
||||
primaryjoin=projectedFits_table.c.sourceID == fits_table.c.ID,
|
||||
backref='source_fit',
|
||||
collection_class=attribute_mapped_collection('victimID'),
|
||||
cascade='all, delete, delete-orphan')
|
||||
|
||||
|
||||
boostedOntoRel = relationship(
|
||||
CommandFit,
|
||||
primaryjoin=commandFits_table.c.boosterID == fits_table.c.ID,
|
||||
backref='booster_fit',
|
||||
collection_class=attribute_mapped_collection('boostedID'),
|
||||
cascade='all, delete, delete-orphan')
|
||||
|
||||
mapper(es_Fit, fits_table,
|
||||
properties={
|
||||
"_Fit__modules" : relation(
|
||||
"_Fit__modules": relation(
|
||||
Module,
|
||||
collection_class=HandledModuleList,
|
||||
primaryjoin=and_(modules_table.c.fitID == fits_table.c.ID, modules_table.c.projected == False), # noqa
|
||||
order_by=modules_table.c.position,
|
||||
cascade='all, delete, delete-orphan'),
|
||||
"_Fit__projectedModules" : relation(
|
||||
"_Fit__projectedModules": relation(
|
||||
Module,
|
||||
collection_class=HandledProjectedModList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(modules_table.c.fitID == fits_table.c.ID, modules_table.c.projected == True)), # noqa
|
||||
"owner" : relation(
|
||||
"owner": relation(
|
||||
User,
|
||||
backref="fits"),
|
||||
"itemID" : fits_table.c.shipID,
|
||||
"shipID" : fits_table.c.shipID,
|
||||
"_Fit__boosters" : relation(
|
||||
"itemID": fits_table.c.shipID,
|
||||
"shipID": fits_table.c.shipID,
|
||||
"_Fit__boosters": relation(
|
||||
Booster,
|
||||
collection_class=HandledImplantBoosterList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
backref='owner',
|
||||
single_parent=True),
|
||||
"_Fit__drones" : relation(
|
||||
"_Fit__drones": relation(
|
||||
Drone,
|
||||
collection_class=HandledDroneCargoList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(drones_table.c.fitID == fits_table.c.ID, drones_table.c.projected == False)), # noqa
|
||||
"_Fit__fighters" : relation(
|
||||
"_Fit__fighters": relation(
|
||||
Fighter,
|
||||
collection_class=HandledDroneCargoList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(fighters_table.c.fitID == fits_table.c.ID, fighters_table.c.projected == False)), # noqa
|
||||
"_Fit__cargo" : relation(
|
||||
"_Fit__cargo": relation(
|
||||
Cargo,
|
||||
collection_class=HandledDroneCargoList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(cargo_table.c.fitID == fits_table.c.ID)),
|
||||
"_Fit__projectedDrones" : relation(
|
||||
"_Fit__projectedDrones": relation(
|
||||
Drone,
|
||||
collection_class=HandledProjectedDroneList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
@@ -197,51 +218,41 @@ mapper(es_Fit, fits_table,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(fighters_table.c.fitID == fits_table.c.ID, fighters_table.c.projected == True)), # noqa
|
||||
"_Fit__implants" : relation(
|
||||
"_Fit__implants": relation(
|
||||
Implant,
|
||||
collection_class=HandledImplantBoosterList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
backref='fit',
|
||||
backref='owner',
|
||||
single_parent=True,
|
||||
primaryjoin=fitImplants_table.c.fitID == fits_table.c.ID,
|
||||
secondaryjoin=fitImplants_table.c.implantID == Implant.ID,
|
||||
secondary=fitImplants_table),
|
||||
"_Fit__character" : relation(
|
||||
"_Fit__character": relation(
|
||||
Character,
|
||||
backref="fits"),
|
||||
"_Fit__damagePattern" : relation(DamagePattern),
|
||||
"_Fit__targetResists" : relation(TargetResists),
|
||||
"projectedOnto" : relationship(
|
||||
ProjectedFit,
|
||||
primaryjoin=projectedFits_table.c.sourceID == fits_table.c.ID,
|
||||
backref='source_fit',
|
||||
collection_class=attribute_mapped_collection('victimID'),
|
||||
cascade='all, delete, delete-orphan'),
|
||||
"victimOf" : relationship(
|
||||
"_Fit__damagePattern": relation(DamagePattern),
|
||||
"_Fit__targetResists": relation(TargetResists),
|
||||
"projectedOnto": projectedFitSourceRel,
|
||||
"victimOf": relationship(
|
||||
ProjectedFit,
|
||||
primaryjoin=fits_table.c.ID == projectedFits_table.c.victimID,
|
||||
backref='victim_fit',
|
||||
collection_class=attribute_mapped_collection('sourceID'),
|
||||
cascade='all, delete, delete-orphan'),
|
||||
"boostedOnto" : relationship(
|
||||
CommandFit,
|
||||
primaryjoin=commandFits_table.c.boosterID == fits_table.c.ID,
|
||||
backref='booster_fit',
|
||||
collection_class=attribute_mapped_collection('boostedID'),
|
||||
cascade='all, delete, delete-orphan'),
|
||||
"boostedOf" : relationship(
|
||||
"boostedOnto": boostedOntoRel,
|
||||
"boostedOf": relationship(
|
||||
CommandFit,
|
||||
primaryjoin=fits_table.c.ID == commandFits_table.c.boostedID,
|
||||
backref='boosted_fit',
|
||||
collection_class=attribute_mapped_collection('boosterID'),
|
||||
cascade='all, delete, delete-orphan'),
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
mapper(ProjectedFit, projectedFits_table,
|
||||
properties={
|
||||
"_ProjectedFit__amount": projectedFits_table.c.amount,
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
mapper(CommandFit, commandFits_table)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, Boolean, DateTime
|
||||
from sqlalchemy.orm import mapper
|
||||
import sqlalchemy.sql.functions as func
|
||||
import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.saveddata.implant import Implant
|
||||
@@ -28,8 +28,8 @@ implants_table = Table("implants", saveddata_meta,
|
||||
Column("ID", Integer, primary_key=True),
|
||||
Column("itemID", Integer),
|
||||
Column("active", Boolean),
|
||||
Column("created", DateTime, nullable=True, default=func.now()),
|
||||
Column("modified", DateTime, nullable=True, onupdate=func.now())
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||
)
|
||||
|
||||
fitImplants_table = Table("fitImplants", saveddata_meta,
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, String, DateTime
|
||||
from sqlalchemy.orm import relation, mapper
|
||||
import sqlalchemy.sql.functions as func
|
||||
import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.db.saveddata.implant import implantsSetMap_table
|
||||
@@ -30,8 +30,8 @@ from eos.saveddata.implantSet import ImplantSet
|
||||
implant_set_table = Table("implantSets", saveddata_meta,
|
||||
Column("ID", Integer, primary_key=True),
|
||||
Column("name", String, nullable=False),
|
||||
Column("created", DateTime, nullable=True, default=func.now()),
|
||||
Column("modified", DateTime, nullable=True, onupdate=func.now())
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||
)
|
||||
|
||||
mapper(ImplantSet, implant_set_table,
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, CheckConstraint, Boolean, DateTime
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, CheckConstraint, Boolean, DateTime, select
|
||||
from sqlalchemy.orm import relation, mapper
|
||||
import sqlalchemy.sql.functions as func
|
||||
import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.saveddata.module import Module
|
||||
@@ -34,9 +34,12 @@ modules_table = Table("modules", saveddata_meta,
|
||||
Column("state", Integer, CheckConstraint("state >= -1"), CheckConstraint("state <= 2")),
|
||||
Column("projected", Boolean, default=False, nullable=False),
|
||||
Column("position", Integer),
|
||||
Column("created", DateTime, nullable=True, default=func.now()),
|
||||
Column("modified", DateTime, nullable=True, onupdate=func.now()),
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now),
|
||||
CheckConstraint('("dummySlot" = NULL OR "itemID" = NULL) AND "dummySlot" != "itemID"'))
|
||||
|
||||
mapper(Module, modules_table,
|
||||
properties={"owner": relation(Fit)})
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, Float, DateTime
|
||||
from sqlalchemy.orm import mapper
|
||||
import sqlalchemy.sql.functions as func
|
||||
import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.saveddata.override import Override
|
||||
@@ -28,8 +28,8 @@ overrides_table = Table("overrides", saveddata_meta,
|
||||
Column("itemID", Integer, primary_key=True, index=True),
|
||||
Column("attrID", Integer, primary_key=True, index=True),
|
||||
Column("value", Float, nullable=False),
|
||||
Column("created", DateTime, nullable=True, default=func.now()),
|
||||
Column("modified", DateTime, nullable=True, onupdate=func.now())
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||
)
|
||||
|
||||
mapper(Override, overrides_table)
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy.sql import and_
|
||||
from sqlalchemy import desc, select
|
||||
|
||||
from eos.db import saveddata_session, sd_lock
|
||||
from eos.db.saveddata.fit import projectedFits_table
|
||||
@@ -242,6 +243,22 @@ def getFitsWithShip(shipID, ownerID=None, where=None, eager=None):
|
||||
return fits
|
||||
|
||||
|
||||
def getRecentFits(ownerID=None, where=None, eager=None):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
q = select((
|
||||
Fit.ID,
|
||||
Fit.shipID,
|
||||
Fit.name,
|
||||
Fit.modified,
|
||||
Fit.created,
|
||||
Fit.timestamp
|
||||
)).order_by(desc(Fit.modified), desc(Fit.timestamp)).limit(50)
|
||||
fits = eos.db.saveddata_session.execute(q).fetchall()
|
||||
|
||||
return fits
|
||||
|
||||
|
||||
def getFitsWithModules(typeIDs, eager=None):
|
||||
"""
|
||||
Get all the fits that have typeIDs fitted to them
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, DateTime
|
||||
from sqlalchemy.orm import mapper
|
||||
import sqlalchemy.sql.functions as func
|
||||
import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.saveddata.character import Skill
|
||||
@@ -29,8 +29,8 @@ skills_table = Table("characterSkills", saveddata_meta,
|
||||
Column("characterID", ForeignKey("characters.ID"), primary_key=True, index=True),
|
||||
Column("itemID", Integer, primary_key=True),
|
||||
Column("_Skill__level", Integer, nullable=True),
|
||||
Column("created", DateTime, nullable=True, default=func.now()),
|
||||
Column("modified", DateTime, nullable=True, onupdate=func.now())
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||
)
|
||||
|
||||
mapper(Skill, skills_table)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, Float, ForeignKey, String, DateTime
|
||||
from sqlalchemy.orm import mapper
|
||||
import sqlalchemy.sql.functions as func
|
||||
import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.saveddata.targetResists import TargetResists
|
||||
@@ -32,8 +32,8 @@ targetResists_table = Table("targetResists", saveddata_meta,
|
||||
Column("kineticAmount", Float),
|
||||
Column("explosiveAmount", Float),
|
||||
Column("ownerID", ForeignKey("users.ID"), nullable=True),
|
||||
Column("created", DateTime, nullable=True, default=func.now()),
|
||||
Column("modified", DateTime, nullable=True, onupdate=func.now())
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||
)
|
||||
|
||||
mapper(TargetResists, targetResists_table)
|
||||
|
||||
86
eos/events.py
Normal file
86
eos/events.py
Normal file
@@ -0,0 +1,86 @@
|
||||
# Decided to put this in it's own file so that we can easily choose not to import it (thanks to mac-deprecated builds =/)
|
||||
|
||||
import datetime
|
||||
from sqlalchemy.event import listen
|
||||
from sqlalchemy.orm.collections import InstrumentedList
|
||||
|
||||
from eos.db.saveddata.fit import projectedFitSourceRel, boostedOntoRel
|
||||
|
||||
from eos.saveddata.fit import Fit
|
||||
from eos.saveddata.module import Module
|
||||
from eos.saveddata.drone import Drone
|
||||
from eos.saveddata.fighter import Fighter
|
||||
from eos.saveddata.cargo import Cargo
|
||||
from eos.saveddata.implant import Implant
|
||||
from eos.saveddata.booster import Booster
|
||||
|
||||
ignored_rels = [
|
||||
projectedFitSourceRel,
|
||||
boostedOntoRel
|
||||
]
|
||||
|
||||
|
||||
def update_fit_modified(target, value, oldvalue, initiator):
|
||||
if not target.owner:
|
||||
return
|
||||
|
||||
if value != oldvalue:
|
||||
# some things (like Implants) have a backref to the fit, which actually produces a list.
|
||||
# In this situation, simply take the 0 index to get to the fit.
|
||||
# There may be cases in the future in which there are multiple fits, so this should be
|
||||
# looked at more indepth later
|
||||
if isinstance(target.owner, InstrumentedList):
|
||||
parent = target.owner[0]
|
||||
else:
|
||||
parent = target.owner
|
||||
|
||||
# ensure this is a fit we're dealing with
|
||||
if isinstance(parent, Fit):
|
||||
parent.modified = datetime.datetime.now()
|
||||
|
||||
|
||||
def apply_col_listeners(target, context):
|
||||
# We only want to set these events when the module is first loaded (otherwise events will fire during the initial
|
||||
# population of data). This runs through all columns and sets up "set" events on each column. We do it with each
|
||||
# column because the alternative would be to do a before/after_update for the Mapper itself, however we're only
|
||||
# allowed to change the local attributes during those events as that's inter-flush.
|
||||
# See http://docs.sqlalchemy.org/en/rel_1_0/orm/session_events.html#mapper-level-events
|
||||
|
||||
# @todo replace with `inspect(Module).column_attrs` when mac binaries are updated
|
||||
|
||||
manager = getattr(target.__class__, "_sa_class_manager", None)
|
||||
if manager:
|
||||
for col in manager.mapper.column_attrs:
|
||||
listen(col, 'set', update_fit_modified)
|
||||
|
||||
|
||||
def rel_listener(target, value, initiator):
|
||||
if not target or (isinstance(value, Module) and value.isEmpty):
|
||||
return
|
||||
|
||||
print "{} has had a relationship change :D".format(target)
|
||||
target.modified = datetime.datetime.now()
|
||||
|
||||
|
||||
def apply_rel_listeners(target, context):
|
||||
# We only want to see these events when the fit is first loaded (otherwise events will fire during the initial
|
||||
# population of data). This sets listeners for all the relationships on fits. This allows us to update the fit's
|
||||
# modified date whenever something is added/removed from fit
|
||||
# See http://docs.sqlalchemy.org/en/rel_1_0/orm/events.html#sqlalchemy.orm.events.InstanceEvents.load
|
||||
|
||||
# todo: when we can, move over to `inspect(es_Fit).relationships` (when mac binaries are updated)
|
||||
manager = getattr(target.__class__, "_sa_class_manager", None)
|
||||
if manager:
|
||||
for rel in manager.mapper.relationships:
|
||||
if rel in ignored_rels:
|
||||
continue
|
||||
listen(rel, 'append', rel_listener)
|
||||
listen(rel, 'remove', rel_listener)
|
||||
|
||||
listen(Fit, 'load', apply_rel_listeners)
|
||||
listen(Module, 'load', apply_col_listeners)
|
||||
listen(Drone, 'load', apply_col_listeners)
|
||||
listen(Fighter, 'load', apply_col_listeners)
|
||||
listen(Cargo, 'load', apply_col_listeners)
|
||||
listen(Implant, 'load', apply_col_listeners)
|
||||
listen(Booster, 'load', apply_col_listeners)
|
||||
@@ -21,6 +21,7 @@ import time
|
||||
from copy import deepcopy
|
||||
from itertools import chain
|
||||
from math import sqrt, log, asinh
|
||||
import datetime
|
||||
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
|
||||
@@ -77,6 +78,8 @@ class Fit(object):
|
||||
self.projected = False
|
||||
self.name = name
|
||||
self.timestamp = time.time()
|
||||
self.created = None
|
||||
self.modified = None
|
||||
self.modeID = None
|
||||
|
||||
self.build()
|
||||
@@ -180,6 +183,14 @@ class Fit(object):
|
||||
self.__mode = mode
|
||||
self.modeID = mode.item.ID if mode is not None else None
|
||||
|
||||
@property
|
||||
def modifiedCoalesce(self):
|
||||
"""
|
||||
This is a property that should get whichever date is available for the fit. @todo: migrate old timestamp data
|
||||
and ensure created / modified are set in database to get rid of this
|
||||
"""
|
||||
return self.modified or self.created or datetime.datetime.fromtimestamp(self.timestamp)
|
||||
|
||||
@property
|
||||
def character(self):
|
||||
return self.__character if self.__character is not None else Character.getAll0()
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
import sys
|
||||
import os.path
|
||||
from logbook import Logger
|
||||
import datetime
|
||||
|
||||
import sqlalchemy
|
||||
# noinspection PyPackageRequirements
|
||||
@@ -940,7 +941,16 @@ class MainFrame(wx.Frame):
|
||||
wx.PostEvent(self, FitSelected(fitID=fit.ID))
|
||||
wx.PostEvent(self.shipBrowser, Stage3Selected(shipID=fit.shipID, back=True))
|
||||
else:
|
||||
wx.PostEvent(self.shipBrowser, ImportSelected(fits=fits, back=True))
|
||||
fits.sort(key=lambda _fit: (_fit.ship.item.name, _fit.name))
|
||||
results = []
|
||||
for fit in fits:
|
||||
results.append((
|
||||
fit.ID,
|
||||
fit.name,
|
||||
fit.modifiedCoalesce,
|
||||
fit.ship.item
|
||||
))
|
||||
wx.PostEvent(self.shipBrowser, ImportSelected(fits=results, back=True))
|
||||
|
||||
def closeProgressDialog(self):
|
||||
# Windows apparently handles ProgressDialogs differently. We can
|
||||
|
||||
@@ -337,15 +337,21 @@ class NavigationPanel(SFItem.SFBrowserItem):
|
||||
self.newBmpH = BitmapLoader.getBitmap("fit_add_small", "gui")
|
||||
self.resetBmpH = BitmapLoader.getBitmap("freset_small", "gui")
|
||||
self.switchBmpH = BitmapLoader.getBitmap("fit_switch_view_mode_small", "gui")
|
||||
self.recentBmpH = BitmapLoader.getBitmap("frecent_small", "gui")
|
||||
|
||||
switchImg = BitmapLoader.getImage("fit_switch_view_mode_small", "gui")
|
||||
switchImg = switchImg.AdjustChannels(1, 1, 1, 0.4)
|
||||
self.switchBmpD = wx.BitmapFromImage(switchImg)
|
||||
|
||||
recentImg = BitmapLoader.getImage("frecent_small", "gui")
|
||||
recentImg = recentImg.AdjustChannels(1, 1, 1, 0.4)
|
||||
self.recentBmpD = wx.BitmapFromImage(recentImg)
|
||||
|
||||
self.resetBmp = self.AdjustChannels(self.resetBmpH)
|
||||
self.rewBmp = self.AdjustChannels(self.rewBmpH)
|
||||
self.searchBmp = self.AdjustChannels(self.searchBmpH)
|
||||
self.switchBmp = self.AdjustChannels(self.switchBmpH)
|
||||
self.recentBmp = self.AdjustChannels(self.recentBmpH)
|
||||
self.newBmp = self.AdjustChannels(self.newBmpH)
|
||||
|
||||
self.toolbar.AddButton(self.resetBmp, "Ship groups", clickCallback=self.OnHistoryReset,
|
||||
@@ -356,6 +362,9 @@ class NavigationPanel(SFItem.SFBrowserItem):
|
||||
self.btnSwitch = self.toolbar.AddButton(self.switchBmpD, "Hide empty ship groups",
|
||||
clickCallback=self.ToggleEmptyGroupsView, hoverBitmap=self.switchBmpH,
|
||||
show=False)
|
||||
self.btnRecent = self.toolbar.AddButton(self.recentBmpD, "Recent Fits",
|
||||
clickCallback=self.ToggleRecentShips, hoverBitmap=self.recentBmpH,
|
||||
show=True)
|
||||
|
||||
modifier = "CTRL" if 'wxMac' not in wx.PlatformInfo else "CMD"
|
||||
self.toolbar.AddButton(self.searchBmp, "Search fittings ({}+F)".format(modifier), clickCallback=self.ToggleSearchBox,
|
||||
@@ -415,6 +424,27 @@ class NavigationPanel(SFItem.SFBrowserItem):
|
||||
def OnResize(self, event):
|
||||
self.Refresh()
|
||||
|
||||
def ToggleRecentShips(self, bool = None, emitEvent = True):
|
||||
# this is so janky. Need to revaluate pretty much entire ship browser. >.<
|
||||
toggle = bool if bool is not None else not self.shipBrowser.recentFits
|
||||
|
||||
if not toggle:
|
||||
self.shipBrowser.recentFits = False
|
||||
self.btnRecent.label = "Recent Fits"
|
||||
self.btnRecent.normalBmp = self.recentBmpD
|
||||
|
||||
if emitEvent:
|
||||
wx.PostEvent(self.shipBrowser, Stage1Selected())
|
||||
else:
|
||||
self.shipBrowser.recentFits = True
|
||||
self.btnRecent.label = "Hide Recent Fits"
|
||||
self.btnRecent.normalBmp = self.recentBmp
|
||||
|
||||
if emitEvent:
|
||||
sFit = Fit.getInstance()
|
||||
fits = sFit.getRecentFits()
|
||||
wx.PostEvent(self.shipBrowser, ImportSelected(fits=fits, back=True, recent=True))
|
||||
|
||||
def ToggleEmptyGroupsView(self):
|
||||
if self.shipBrowser.filterShipsWithNoFits:
|
||||
self.shipBrowser.filterShipsWithNoFits = False
|
||||
@@ -453,11 +483,13 @@ class NavigationPanel(SFItem.SFBrowserItem):
|
||||
wx.PostEvent(self.mainFrame, FitSelected(fitID=fitID))
|
||||
|
||||
def OnHistoryReset(self):
|
||||
self.ToggleRecentShips(False, False)
|
||||
if self.shipBrowser.browseHist:
|
||||
self.shipBrowser.browseHist = []
|
||||
self.gotoStage(1, 0)
|
||||
|
||||
def OnHistoryBack(self):
|
||||
self.ToggleRecentShips(False, False)
|
||||
if len(self.shipBrowser.browseHist) > 0:
|
||||
stage, data = self.shipBrowser.browseHist.pop()
|
||||
self.gotoStage(stage, data)
|
||||
@@ -537,6 +569,7 @@ class NavigationPanel(SFItem.SFBrowserItem):
|
||||
self.bkBitmap.mFactor = mFactor
|
||||
|
||||
def gotoStage(self, stage, data=None):
|
||||
self.shipBrowser.recentFits = False
|
||||
if stage == 1:
|
||||
wx.PostEvent(self.Parent, Stage1Selected())
|
||||
elif stage == 2:
|
||||
@@ -572,6 +605,7 @@ class ShipBrowser(wx.Panel):
|
||||
self._stage3ShipName = ""
|
||||
self.fitIDMustEditName = -1
|
||||
self.filterShipsWithNoFits = False
|
||||
self.recentFits = False
|
||||
|
||||
self.racesFilter = {}
|
||||
|
||||
@@ -628,7 +662,8 @@ class ShipBrowser(wx.Panel):
|
||||
|
||||
def RefreshList(self, event):
|
||||
stage = self.GetActiveStage()
|
||||
if stage == 3 or stage == 4:
|
||||
|
||||
if stage in (3, 4, 5):
|
||||
self.lpane.RefreshList(True)
|
||||
event.Skip()
|
||||
|
||||
@@ -671,6 +706,7 @@ class ShipBrowser(wx.Panel):
|
||||
return self.racesFilter[race]
|
||||
|
||||
def stage1(self, event):
|
||||
self.navpanel.ToggleRecentShips(False, False)
|
||||
self._lastStage = self._activeStage
|
||||
self._activeStage = 1
|
||||
self.lastdata = 0
|
||||
@@ -726,6 +762,7 @@ class ShipBrowser(wx.Panel):
|
||||
def stage2Callback(self, data):
|
||||
if self.GetActiveStage() != 2:
|
||||
return
|
||||
self.navpanel.ToggleRecentShips(False, False)
|
||||
|
||||
categoryID = self._stage2Data
|
||||
ships = list(data[1])
|
||||
@@ -811,7 +848,7 @@ class ShipBrowser(wx.Panel):
|
||||
return info[1]
|
||||
|
||||
def stage3(self, event):
|
||||
|
||||
self.navpanel.ToggleRecentShips(False, False)
|
||||
self.lpane.ShowLoading(False)
|
||||
|
||||
# If back is False, do not append to history. This could be us calling
|
||||
@@ -920,6 +957,10 @@ class ShipBrowser(wx.Panel):
|
||||
self.Layout()
|
||||
|
||||
def importStage(self, event):
|
||||
"""
|
||||
The import stage handles both displaying fits after importing as well as displaying recent fits. todo: need to
|
||||
reconcile these two better into a more uniform function, right now hacked together to get working
|
||||
"""
|
||||
self.lpane.ShowLoading(False)
|
||||
|
||||
self.navpanel.ShowNewFitButton(False)
|
||||
@@ -933,29 +974,26 @@ class ShipBrowser(wx.Panel):
|
||||
|
||||
fits = event.fits
|
||||
|
||||
# sort by ship name, then fit name
|
||||
fits.sort(key=lambda _fit: (_fit.ship.item.name, _fit.name))
|
||||
|
||||
self.lastdata = fits
|
||||
self.lpane.Freeze()
|
||||
self.lpane.RemoveAllChildren()
|
||||
|
||||
if fits:
|
||||
for fit in fits:
|
||||
shipTrait = fit.ship.item.traits.traitText if (fit.ship.item.traits is not None) else ""
|
||||
# empty string if no traits
|
||||
shipItem = fit[3]
|
||||
shipTrait = shipItem.traits.traitText if (shipItem.traits is not None) else ""
|
||||
|
||||
self.lpane.AddWidget(FitItem(
|
||||
self.lpane,
|
||||
fit.ID,
|
||||
fit[0],
|
||||
(
|
||||
fit.ship.item.name,
|
||||
shipItem.name,
|
||||
shipTrait,
|
||||
fit.name,
|
||||
fit.booster,
|
||||
fit.timestamp,
|
||||
fit[1],
|
||||
False,
|
||||
fit[2]
|
||||
),
|
||||
fit.ship.item.ID,
|
||||
shipItem.ID,
|
||||
))
|
||||
self.lpane.RefreshList(doFocus=False)
|
||||
self.lpane.Thaw()
|
||||
@@ -1473,6 +1511,7 @@ class FitItem(SFItem.SFBrowserItem):
|
||||
|
||||
self.shipFittingInfo = shipFittingInfo
|
||||
self.shipName, self.shipTrait, self.fitName, self.fitBooster, self.timestamp = shipFittingInfo
|
||||
|
||||
self.shipTrait = re.sub("<.*?>", " ", self.shipTrait)
|
||||
# see GH issue #62
|
||||
|
||||
@@ -1553,10 +1592,13 @@ class FitItem(SFItem.SFBrowserItem):
|
||||
# self.animCount = 0
|
||||
# =====================================================================
|
||||
|
||||
"""
|
||||
# Remove this bit as the time stuff is non-functional (works... but not exactly sure what it's meant to do)
|
||||
self.selTimerID = wx.NewId()
|
||||
|
||||
self.selTimer = wx.Timer(self, self.selTimerID)
|
||||
self.selTimer.Start(100)
|
||||
"""
|
||||
|
||||
self.Bind(wx.EVT_RIGHT_UP, self.OnContextMenu)
|
||||
self.Bind(wx.EVT_MIDDLE_UP, self.OpenNewTab)
|
||||
@@ -1645,6 +1687,7 @@ class FitItem(SFItem.SFBrowserItem):
|
||||
|
||||
def OnTimer(self, event):
|
||||
|
||||
# @todo: figure out what exactly this is supposed to accomplish
|
||||
if self.selTimerID == event.GetId():
|
||||
ctimestamp = time.time()
|
||||
interval = 5
|
||||
@@ -1726,7 +1769,6 @@ class FitItem(SFItem.SFBrowserItem):
|
||||
self.fitName = fitName
|
||||
sFit.renameFit(self.fitID, self.fitName)
|
||||
wx.PostEvent(self.mainFrame, FitRenamed(fitID=self.fitID))
|
||||
self.Refresh()
|
||||
else:
|
||||
self.tcFitName.SetValue(self.fitName)
|
||||
|
||||
@@ -1893,8 +1935,8 @@ class FitItem(SFItem.SFBrowserItem):
|
||||
|
||||
mdc.SetFont(self.fontNormal)
|
||||
|
||||
fitDate = time.localtime(self.timestamp)
|
||||
fitLocalDate = "%d/%02d/%02d %02d:%02d" % (fitDate[0], fitDate[1], fitDate[2], fitDate[3], fitDate[4])
|
||||
fitDate = self.timestamp.strftime("%m/%d/%Y %H:%M")
|
||||
fitLocalDate = fitDate #"%d/%02d/%02d %02d:%02d" % (fitDate[0], fitDate[1], fitDate[2], fitDate[3], fitDate[4])
|
||||
pfdate = drawUtils.GetPartialText(mdc, fitLocalDate,
|
||||
self.toolbarx - self.textStartx - self.padding * 2 - self.thoverw)
|
||||
|
||||
@@ -1947,6 +1989,15 @@ class FitItem(SFItem.SFBrowserItem):
|
||||
state = SFItem.SB_ITEM_NORMAL
|
||||
return state
|
||||
|
||||
def Refresh(self):
|
||||
activeFit = self.mainFrame.getActiveFit()
|
||||
if activeFit == self.fitID:
|
||||
sFit = Fit.getInstance()
|
||||
fit = sFit.getFit(activeFit)
|
||||
self.timestamp = fit.modifiedCoalesce
|
||||
|
||||
SFItem.SFBrowserItem.Refresh(self)
|
||||
|
||||
def RenderBackground(self):
|
||||
rect = self.GetRect()
|
||||
|
||||
|
||||
BIN
imgs/gui/frecent_small.png
Normal file
BIN
imgs/gui/frecent_small.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 793 B |
7
pyfa.py
7
pyfa.py
@@ -337,6 +337,7 @@ if __name__ == "__main__":
|
||||
else:
|
||||
saVersion = sqlalchemy.__version__
|
||||
saMatch = re.match("([0-9]+).([0-9]+)([b\.])([0-9]+)", saVersion)
|
||||
config.saVersion = (int(saMatch.group(1)), int(saMatch.group(2)), int(saMatch.group(4)))
|
||||
if saMatch:
|
||||
saMajor = int(saMatch.group(1))
|
||||
saMinor = int(saMatch.group(2))
|
||||
@@ -362,6 +363,12 @@ if __name__ == "__main__":
|
||||
raise PreCheckException("Cannot import requests. You can download requests from https://pypi.python.org/pypi/requests.")
|
||||
|
||||
import eos.db
|
||||
|
||||
if config.saVersion[0] > 0 or config.saVersion[1] >= 7:
|
||||
# <0.7 doesn't have support for events ;_; (mac-deprecated)
|
||||
config.sa_events = True
|
||||
import eos.events
|
||||
|
||||
# noinspection PyUnresolvedReferences
|
||||
import service.prefetch # noqa: F401
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
import copy
|
||||
from logbook import Logger
|
||||
from time import time
|
||||
import datetime
|
||||
|
||||
import eos.db
|
||||
from eos.saveddata.booster import Booster as es_Booster
|
||||
@@ -93,10 +94,24 @@ class Fit(object):
|
||||
fits = eos.db.getFitsWithShip(shipID)
|
||||
names = []
|
||||
for fit in fits:
|
||||
names.append((fit.ID, fit.name, fit.booster, fit.timestamp))
|
||||
names.append((fit.ID, fit.name, fit.booster, fit.modified or fit.created or datetime.datetime.fromtimestamp(fit.timestamp)))
|
||||
|
||||
return names
|
||||
|
||||
@staticmethod
|
||||
def getRecentFits():
|
||||
""" Fetches recently modified fits, used with shipBrowser """
|
||||
pyfalog.debug("Fetching recent fits")
|
||||
fits = eos.db.getRecentFits()
|
||||
returnInfo = []
|
||||
|
||||
for fit in fits:
|
||||
item = eos.db.getItem(fit[1])
|
||||
returnInfo.append((fit[0], fit[2], fit[3] or fit[4] or datetime.datetime.fromtimestamp(fit[5]), item))
|
||||
# ID name timestamps
|
||||
|
||||
return returnInfo
|
||||
|
||||
@staticmethod
|
||||
def getFitsWithModules(typeIDs):
|
||||
""" Lists fits flagged as booster """
|
||||
@@ -258,10 +273,15 @@ class Fit(object):
|
||||
pyfalog.debug("Searching for fit: {0}", name)
|
||||
results = eos.db.searchFits(name)
|
||||
fits = []
|
||||
|
||||
for fit in results:
|
||||
fits.append((
|
||||
fit.ID, fit.name, fit.ship.item.ID, fit.ship.item.name, fit.booster,
|
||||
fit.timestamp))
|
||||
fit.ID,
|
||||
fit.name,
|
||||
fit.ship.item.ID,
|
||||
fit.ship.item.name,
|
||||
fit.booster,
|
||||
fit.modifiedCoalesce))
|
||||
return fits
|
||||
|
||||
def addImplant(self, fitID, itemID, recalc=True):
|
||||
|
||||
Reference in New Issue
Block a user