87 lines
3.4 KiB
Python
87 lines
3.4 KiB
Python
# 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
|
|
|
|
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)
|