confirm Revoke, confirm and revoke documents actions
This commit is contained in:
parent
8a797f079b
commit
c8b0c56bbb
|
@ -280,7 +280,9 @@ class RevokeDocumentDef(ActionDef):
|
||||||
SCHEMA = schemas.RevokeDocument
|
SCHEMA = schemas.RevokeDocument
|
||||||
|
|
||||||
|
|
||||||
|
class ConfirmRevokeDocumentDef(ActionDef):
|
||||||
|
VIEW = None
|
||||||
|
SCHEMA = schemas.ConfirmRevokeDocument
|
||||||
|
|
||||||
|
|
||||||
class CancelTradeDef(ActionDef):
|
class CancelTradeDef(ActionDef):
|
||||||
|
|
|
@ -1447,6 +1447,7 @@ class Reserve(Organize):
|
||||||
class CancelReservation(Organize):
|
class CancelReservation(Organize):
|
||||||
"""The act of cancelling a reservation."""
|
"""The act of cancelling a reservation."""
|
||||||
|
|
||||||
|
|
||||||
class ConfirmDocument(JoinedTableMixin, ActionWithMultipleTradeDocuments):
|
class ConfirmDocument(JoinedTableMixin, ActionWithMultipleTradeDocuments):
|
||||||
"""Users confirm the one action trade this confirmation it's link to trade
|
"""Users confirm the one action trade this confirmation it's link to trade
|
||||||
and the document that confirm
|
and the document that confirm
|
||||||
|
@ -1480,6 +1481,10 @@ class RevokeDocument(ConfirmDocument):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ConfirmRevokeDocument(ConfirmDocument):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Confirm(JoinedTableMixin, ActionWithMultipleDevices):
|
class Confirm(JoinedTableMixin, ActionWithMultipleDevices):
|
||||||
"""Users confirm the one action trade this confirmation it's link to trade
|
"""Users confirm the one action trade this confirmation it's link to trade
|
||||||
and the devices that confirm
|
and the devices that confirm
|
||||||
|
|
|
@ -480,60 +480,6 @@ class Confirm(ActionWithMultipleDevices):
|
||||||
raise ValidationError(txt)
|
raise ValidationError(txt)
|
||||||
|
|
||||||
|
|
||||||
class ConfirmDocument(ActionWithMultipleDocuments):
|
|
||||||
__doc__ = m.Confirm.__doc__
|
|
||||||
action = NestedOn('Action', only_query='id')
|
|
||||||
|
|
||||||
@validates_schema
|
|
||||||
def validate_revoke(self, data: dict):
|
|
||||||
for doc in data.get('documents', []):
|
|
||||||
# if document not exist in the Trade, then this query is wrong
|
|
||||||
if not doc in data['action'].documents:
|
|
||||||
txt = "Document {} not exist in the trade".format(doc.file_name)
|
|
||||||
raise ValidationError(txt)
|
|
||||||
|
|
||||||
@validates_schema
|
|
||||||
def validate_docs(self, data):
|
|
||||||
"""If there are one device than have one confirmation,
|
|
||||||
then remove the list this device of the list of devices of this action
|
|
||||||
"""
|
|
||||||
if not data['devices'] == OrderedSet():
|
|
||||||
return
|
|
||||||
|
|
||||||
documents = []
|
|
||||||
for doc in data['documents']:
|
|
||||||
actions = copy.copy(doc.actions)
|
|
||||||
actions.reverse()
|
|
||||||
for ac in actions:
|
|
||||||
if ac == data['action']:
|
|
||||||
# If document have the last action the action Trade
|
|
||||||
documents.append(doc)
|
|
||||||
break
|
|
||||||
|
|
||||||
if ac.t == Confirm.t and not ac.user == g.user:
|
|
||||||
# If document is confirmed but is not for g.user, then need confirm
|
|
||||||
documents.append(doc)
|
|
||||||
break
|
|
||||||
|
|
||||||
if ac.t == 'Revoke' and not ac.user == g.user:
|
|
||||||
# If document is revoke before from other user
|
|
||||||
# it's not possible confirm now
|
|
||||||
break
|
|
||||||
|
|
||||||
if ac.t == 'ConfirmRevoke' and ac.user == g.user:
|
|
||||||
# if the last action is a ConfirmRevoke this mean than not there are
|
|
||||||
# other confirmation from the real owner of the trade
|
|
||||||
break
|
|
||||||
|
|
||||||
if ac.t == Confirm.t and ac.user == g.user:
|
|
||||||
# If dodument is confirmed we don't need confirmed again
|
|
||||||
break
|
|
||||||
|
|
||||||
if not documents:
|
|
||||||
txt = 'No there are documents to confirm'
|
|
||||||
raise ValidationError(txt)
|
|
||||||
|
|
||||||
|
|
||||||
class Revoke(ActionWithMultipleDevices):
|
class Revoke(ActionWithMultipleDevices):
|
||||||
__doc__ = m.Revoke.__doc__
|
__doc__ = m.Revoke.__doc__
|
||||||
action = NestedOn('Action', only_query='id')
|
action = NestedOn('Action', only_query='id')
|
||||||
|
@ -584,51 +530,107 @@ class Revoke(ActionWithMultipleDevices):
|
||||||
raise ValidationError(txt)
|
raise ValidationError(txt)
|
||||||
|
|
||||||
|
|
||||||
class RevokeDocument(ActionWithMultipleDocuments):
|
class ConfirmDocument(ActionWithMultipleDocuments):
|
||||||
__doc__ = m.RevokeDocument.__doc__
|
__doc__ = m.Confirm.__doc__
|
||||||
action = NestedOn('Action', only_query='id')
|
action = NestedOn('Action', only_query='id')
|
||||||
|
|
||||||
@validates_schema
|
@validates_schema
|
||||||
def validate_revoke(self, data: dict):
|
def validate_documents(self, data):
|
||||||
for doc in data.get('documents', []):
|
"""If there are one device than have one confirmation,
|
||||||
# if document not exist in the Trade, then this query is wrong
|
then remove the list this device of the list of devices of this action
|
||||||
if not doc in data['action'].documents:
|
"""
|
||||||
txt = "Document {} not exist in the trade".format(doc.file_name)
|
# import pdb; pdb.set_trace()
|
||||||
|
if data['documents'] == OrderedSet():
|
||||||
|
return
|
||||||
|
|
||||||
|
documents = []
|
||||||
|
for doc in data['documents']:
|
||||||
|
if not doc.lot.trade:
|
||||||
|
return
|
||||||
|
|
||||||
|
data['action'] = doc.lot.trade
|
||||||
|
|
||||||
|
if not doc.actions:
|
||||||
|
continue
|
||||||
|
|
||||||
|
ac = doc.actions[-1]
|
||||||
|
|
||||||
|
if ac.t == 'ConfirmDocument' and not ac.user == g.user:
|
||||||
|
# If document is confirmed but is not for g.user, then need confirm
|
||||||
|
documents.append(doc)
|
||||||
|
|
||||||
|
if not documents:
|
||||||
|
txt = 'No there are documents to confirm'
|
||||||
raise ValidationError(txt)
|
raise ValidationError(txt)
|
||||||
|
|
||||||
|
|
||||||
|
class RevokeDocument(ActionWithMultipleDocuments):
|
||||||
|
__doc__ = m.RevokeDocument.__doc__
|
||||||
|
action = NestedOn('Action', only_query='id')
|
||||||
|
|
||||||
@validates_schema
|
@validates_schema
|
||||||
def validate_documents(self, data):
|
def validate_documents(self, data):
|
||||||
"""Check if there are or no one before confirmation,
|
"""Check if there are or no one before confirmation,
|
||||||
This is not checked in the view becouse the list of documents is inmutable
|
This is not checked in the view becouse the list of documents is inmutable
|
||||||
|
|
||||||
"""
|
"""
|
||||||
import pdb; pdb.set_trace()
|
if data['documents'] == OrderedSet():
|
||||||
if not data['documents'] == OrderedSet():
|
|
||||||
return
|
return
|
||||||
|
|
||||||
documents = []
|
documents = []
|
||||||
for doc in data['documents']:
|
for doc in data['documents']:
|
||||||
actions = copy.copy(doc.actions)
|
if not doc.lot.trade:
|
||||||
actions.reverse()
|
return
|
||||||
for ac in actions:
|
|
||||||
if ac == data['action']:
|
|
||||||
# data['action'] is a Trade action, if this is the first action
|
|
||||||
# to find mean that this document don't have a confirmation
|
|
||||||
break
|
|
||||||
|
|
||||||
if ac.t == 'Revoke' and ac.user == g.user:
|
data['action'] = doc.lot.trade
|
||||||
# this doc is confirmation jet
|
|
||||||
break
|
|
||||||
|
|
||||||
if ac.t == Confirm.t and ac.user == g.user:
|
if not doc.actions:
|
||||||
|
continue
|
||||||
|
|
||||||
|
ac = doc.actions[-1]
|
||||||
|
|
||||||
|
if ac.t == 'ConfirmDocument' and ac.user == g.user:
|
||||||
documents.append(doc)
|
documents.append(doc)
|
||||||
break
|
|
||||||
|
|
||||||
if not documents:
|
if not documents:
|
||||||
txt = 'No there are documents to revoke'
|
txt = 'No there are documents to revoke'
|
||||||
raise ValidationError(txt)
|
raise ValidationError(txt)
|
||||||
|
|
||||||
|
|
||||||
|
class ConfirmRevokeDocument(ActionWithMultipleDocuments):
|
||||||
|
__doc__ = m.ConfirmRevoke.__doc__
|
||||||
|
action = NestedOn('Action', only_query='id')
|
||||||
|
|
||||||
|
@validates_schema
|
||||||
|
def validate_documents(self, data):
|
||||||
|
"""Check if there are or no one before confirmation,
|
||||||
|
This is not checked in the view becouse the list of documents is inmutable
|
||||||
|
|
||||||
|
"""
|
||||||
|
if data['documents'] == OrderedSet():
|
||||||
|
return
|
||||||
|
|
||||||
|
documents = []
|
||||||
|
for doc in data['documents']:
|
||||||
|
if not doc.lot.trade:
|
||||||
|
return
|
||||||
|
|
||||||
|
if not doc.actions:
|
||||||
|
continue
|
||||||
|
|
||||||
|
ac = doc.actions[-1]
|
||||||
|
|
||||||
|
if ac.t == 'RevokeDocument' and not ac.user == g.user:
|
||||||
|
# If document is revoke before you can Confirm now
|
||||||
|
# and revoke is an action of one other user
|
||||||
|
data['action'] = ac
|
||||||
|
documents.append(doc)
|
||||||
|
|
||||||
|
if not documents:
|
||||||
|
txt = 'No there are documents with revoke for confirm'
|
||||||
|
raise ValidationError(txt)
|
||||||
|
|
||||||
|
|
||||||
class ConfirmRevoke(ActionWithMultipleDevices):
|
class ConfirmRevoke(ActionWithMultipleDevices):
|
||||||
__doc__ = m.ConfirmRevoke.__doc__
|
__doc__ = m.ConfirmRevoke.__doc__
|
||||||
action = NestedOn('Action', only_query='id')
|
action = NestedOn('Action', only_query='id')
|
||||||
|
@ -689,60 +691,6 @@ class ConfirmRevoke(ActionWithMultipleDevices):
|
||||||
raise ValidationError(txt)
|
raise ValidationError(txt)
|
||||||
|
|
||||||
|
|
||||||
class ConfirmRevokeDocument(ActionWithMultipleDocuments):
|
|
||||||
__doc__ = m.ConfirmRevoke.__doc__
|
|
||||||
action = NestedOn('Action', only_query='id')
|
|
||||||
|
|
||||||
@validates_schema
|
|
||||||
def validate_revoke(self, data: dict):
|
|
||||||
for doc in data.get('documents', []):
|
|
||||||
# if document not exist in the Trade, then this query is wrong
|
|
||||||
if not doc in data['action'].documents:
|
|
||||||
txt = "Document {} not exist in the trade".format(doc.file_name)
|
|
||||||
raise ValidationError(txt)
|
|
||||||
|
|
||||||
@validates_schema
|
|
||||||
def validate_docs(self, data):
|
|
||||||
"""Check if there are or no one before confirmation,
|
|
||||||
This is not checked in the view becouse the list of documents is inmutable
|
|
||||||
|
|
||||||
"""
|
|
||||||
if not data['devices'] == OrderedSet():
|
|
||||||
return
|
|
||||||
|
|
||||||
documents = []
|
|
||||||
for doc in data['documents']:
|
|
||||||
actions = copy.copy(doc.actions)
|
|
||||||
actions.reverse()
|
|
||||||
for ac in actions:
|
|
||||||
if ac == data['action']:
|
|
||||||
# If document have the last action the action for confirm
|
|
||||||
documents.append(doc)
|
|
||||||
break
|
|
||||||
|
|
||||||
if ac.t == 'Revoke' and not ac.user == g.user:
|
|
||||||
# If document is revoke before you can Confirm now
|
|
||||||
# and revoke is an action of one other user
|
|
||||||
documents.append(doc)
|
|
||||||
break
|
|
||||||
|
|
||||||
if ac.t == ConfirmRevoke.t and ac.user == g.user:
|
|
||||||
# If document is confirmed we don't need confirmed again
|
|
||||||
break
|
|
||||||
|
|
||||||
if ac.t == Confirm.t:
|
|
||||||
# if onwer of trade confirm again before than this user Confirm the
|
|
||||||
# revoke, then is not possible confirm the revoke
|
|
||||||
#
|
|
||||||
# If g.user confirm the trade before do a ConfirmRevoke
|
|
||||||
# then g.user can not to do the ConfirmRevoke more
|
|
||||||
break
|
|
||||||
|
|
||||||
if not documents:
|
|
||||||
txt = 'No there are documents with revoke for confirm'
|
|
||||||
raise ValidationError(txt)
|
|
||||||
|
|
||||||
|
|
||||||
class Trade(ActionWithMultipleDevices):
|
class Trade(ActionWithMultipleDevices):
|
||||||
__doc__ = m.Trade.__doc__
|
__doc__ = m.Trade.__doc__
|
||||||
date = DateTime(data_key='date', required=False)
|
date = DateTime(data_key='date', required=False)
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import copy
|
|
||||||
|
|
||||||
from flask import g
|
from flask import g
|
||||||
from sqlalchemy.util import OrderedSet
|
from sqlalchemy.util import OrderedSet
|
||||||
from teal.marshmallow import ValidationError
|
from teal.marshmallow import ValidationError
|
||||||
|
|
||||||
from ereuse_devicehub.db import db
|
from ereuse_devicehub.db import db
|
||||||
from ereuse_devicehub.resources.action.models import (Trade, Confirm, ConfirmRevoke,
|
from ereuse_devicehub.resources.action.models import (Trade, Confirm, ConfirmRevoke,
|
||||||
Revoke, RevokeDocument, ConfirmDocument)
|
Revoke, RevokeDocument, ConfirmDocument,
|
||||||
|
ConfirmRevokeDocument)
|
||||||
from ereuse_devicehub.resources.user.models import User
|
from ereuse_devicehub.resources.user.models import User
|
||||||
from ereuse_devicehub.resources.lot.views import delete_from_trade
|
from ereuse_devicehub.resources.lot.views import delete_from_trade
|
||||||
|
|
||||||
|
@ -307,28 +306,22 @@ class ConfirmDocumentView(ConfirmDocumentMixin):
|
||||||
request_confirm = {
|
request_confirm = {
|
||||||
'type': 'Confirm',
|
'type': 'Confirm',
|
||||||
'action': trade.id,
|
'action': trade.id,
|
||||||
'devices': [device_id]
|
'documents': [document_id],
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Model = Confirm
|
Model = ConfirmDocument
|
||||||
|
|
||||||
def validate(self, data):
|
def validate(self, data):
|
||||||
"""If there are one device than have one confirmation,
|
"""If there are one device than have one confirmation,
|
||||||
then remove the list this device of the list of devices of this action
|
then remove the list this device of the list of devices of this action
|
||||||
"""
|
"""
|
||||||
real_devices = []
|
for doc in data['documents']:
|
||||||
for dev in data['devices']:
|
ac = doc.trading
|
||||||
ac = dev.last_action_trading
|
if not doc.trading in ['Confirm', 'Need Confirmation']:
|
||||||
if ac.type == Confirm.t and not ac.user == g.user:
|
txt = 'Some of documents do not have enough to confirm for to do a Doble Confirmation'
|
||||||
real_devices.append(dev)
|
ValidationError(txt)
|
||||||
|
### End check ###
|
||||||
data['devices'] = OrderedSet(real_devices)
|
|
||||||
|
|
||||||
# Change the owner for every devices
|
|
||||||
for dev in data['devices']:
|
|
||||||
user_to = data['action'].user_to
|
|
||||||
dev.change_owner(user_to)
|
|
||||||
|
|
||||||
|
|
||||||
class RevokeDocumentView(ConfirmDocumentMixin):
|
class RevokeDocumentView(ConfirmDocumentMixin):
|
||||||
|
@ -337,18 +330,13 @@ class RevokeDocumentView(ConfirmDocumentMixin):
|
||||||
request_revoke = {
|
request_revoke = {
|
||||||
'type': 'Revoke',
|
'type': 'Revoke',
|
||||||
'action': trade.id,
|
'action': trade.id,
|
||||||
'devices': [device_id],
|
'documents': [document_id],
|
||||||
}
|
}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Model = RevokeDocument
|
Model = RevokeDocument
|
||||||
|
|
||||||
def __init__(self, data, resource_def, schema):
|
|
||||||
self.schema = schema
|
|
||||||
a = resource_def.schema.load(data)
|
|
||||||
self.validate(a)
|
|
||||||
|
|
||||||
def validate(self, data):
|
def validate(self, data):
|
||||||
"""All devices need to have the status of DoubleConfirmation."""
|
"""All devices need to have the status of DoubleConfirmation."""
|
||||||
|
|
||||||
|
@ -357,7 +345,7 @@ class RevokeDocumentView(ConfirmDocumentMixin):
|
||||||
raise ValidationError('Documents not exist.')
|
raise ValidationError('Documents not exist.')
|
||||||
|
|
||||||
for doc in data['documents']:
|
for doc in data['documents']:
|
||||||
if not doc.trading == 'Confirmed':
|
if not doc.trading in ['Document Confirmed', 'Confirm']:
|
||||||
txt = 'Some of documents do not have enough to confirm for to do a revoke'
|
txt = 'Some of documents do not have enough to confirm for to do a revoke'
|
||||||
ValidationError(txt)
|
ValidationError(txt)
|
||||||
### End check ###
|
### End check ###
|
||||||
|
@ -369,33 +357,21 @@ class ConfirmRevokeDocumentView(ConfirmDocumentMixin):
|
||||||
request_confirm_revoke = {
|
request_confirm_revoke = {
|
||||||
'type': 'ConfirmRevoke',
|
'type': 'ConfirmRevoke',
|
||||||
'action': action_revoke.id,
|
'action': action_revoke.id,
|
||||||
'devices': [device_id]
|
'documents': [document_id],
|
||||||
}
|
}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Model = ConfirmRevoke
|
Model = ConfirmRevokeDocument
|
||||||
|
|
||||||
def validate(self, data):
|
def validate(self, data):
|
||||||
"""All devices need to have the status of revoke."""
|
"""All devices need to have the status of revoke."""
|
||||||
|
|
||||||
if not data['action'].type == 'Revoke':
|
if not data['action'].type == 'RevokeDocument':
|
||||||
txt = 'Error: this action is not a revoke action'
|
txt = 'Error: this action is not a revoke action'
|
||||||
ValidationError(txt)
|
ValidationError(txt)
|
||||||
|
|
||||||
for dev in data['devices']:
|
for doc in data['documents']:
|
||||||
if not dev.trading == 'Revoke':
|
if not doc.trading == 'Revoke':
|
||||||
txt = 'Some of devices do not have revoke to confirm'
|
txt = 'Some of documents do not have revoke to confirm'
|
||||||
ValidationError(txt)
|
ValidationError(txt)
|
||||||
|
|
||||||
devices = OrderedSet(data['devices'])
|
|
||||||
data['devices'] = devices
|
|
||||||
|
|
||||||
# Change the owner for every devices
|
|
||||||
# data['action'] == 'Revoke'
|
|
||||||
|
|
||||||
trade = data['action'].action
|
|
||||||
for dev in devices:
|
|
||||||
dev.reset_owner()
|
|
||||||
|
|
||||||
trade.lot.devices.difference_update(devices)
|
|
||||||
|
|
|
@ -202,6 +202,19 @@ class ActionView(View):
|
||||||
confirm_revoke = trade_view.ConfirmRevokeView(json, resource_def, self.schema)
|
confirm_revoke = trade_view.ConfirmRevokeView(json, resource_def, self.schema)
|
||||||
return confirm_revoke.post()
|
return confirm_revoke.post()
|
||||||
|
|
||||||
|
if json['type'] == 'RevokeDocument':
|
||||||
|
revoke = trade_view.RevokeDocumentView(json, resource_def, self.schema)
|
||||||
|
return revoke.post()
|
||||||
|
|
||||||
|
if json['type'] == 'ConfirmDocument':
|
||||||
|
confirm = trade_view.ConfirmDocumentView(json, resource_def, self.schema)
|
||||||
|
return confirm.post()
|
||||||
|
|
||||||
|
if json['type'] == 'ConfirmRevokeDocument':
|
||||||
|
confirm_revoke = trade_view.ConfirmRevokeDocumentView(json, resource_def, self.schema)
|
||||||
|
return confirm_revoke.post()
|
||||||
|
|
||||||
|
# import pdb; pdb.set_trace()
|
||||||
a = resource_def.schema.load(json)
|
a = resource_def.schema.load(json)
|
||||||
Model = db.Model._decl_class_registry.data[json['type']]()
|
Model = db.Model._decl_class_registry.data[json['type']]()
|
||||||
action = Model(**a)
|
action = Model(**a)
|
||||||
|
|
|
@ -94,38 +94,41 @@ class TradeDocument(Thing):
|
||||||
"""The trading state, or None if no Trade action has
|
"""The trading state, or None if no Trade action has
|
||||||
ever been performed to this device. This extract the posibilities for to do"""
|
ever been performed to this device. This extract the posibilities for to do"""
|
||||||
|
|
||||||
# import pdb; pdb.set_trace()
|
confirm = 'Confirm'
|
||||||
confirm = 'ConfirmDocument'
|
need_confirm = 'Need Confirmation'
|
||||||
to_confirm = 'To Confirm'
|
double_confirm = 'Document Confirmed'
|
||||||
revoke = 'Revoke'
|
revoke = 'Revoke'
|
||||||
|
revoke_pending = 'Revoke Pending'
|
||||||
|
confirm_revoke = 'Document Revoked'
|
||||||
|
|
||||||
if not self.actions:
|
if not self.actions:
|
||||||
return
|
return
|
||||||
|
|
||||||
actions = copy.copy(self.actions)
|
ac = self.actions[-1]
|
||||||
actions = list(reversed(actions))
|
|
||||||
ac = actions[0]
|
|
||||||
|
|
||||||
if ac.type == revoke:
|
if ac.type == 'ConfirmRevokeDocument':
|
||||||
|
# can to do revoke_confirmed
|
||||||
|
return confirm_revoke
|
||||||
|
|
||||||
|
if ac.type == 'RevokeDocument':
|
||||||
|
if ac.user == g.user:
|
||||||
|
# can todo revoke_pending
|
||||||
|
return revoke_pending
|
||||||
|
else:
|
||||||
|
# can to do confirm_revoke
|
||||||
return revoke
|
return revoke
|
||||||
|
|
||||||
if ac.type == confirm:
|
if ac.type == 'ConfirmDocument':
|
||||||
if ac.user == self.owner:
|
if ac.user == self.owner:
|
||||||
return to_confirm
|
if self.owner == g.user:
|
||||||
return 'Confirmed'
|
# can to do revoke
|
||||||
|
return confirm
|
||||||
def last_action_of(self, *types):
|
else:
|
||||||
"""Gets the last action of the given types.
|
# can to do confirm
|
||||||
|
return need_confirm
|
||||||
:raise LookupError: Device has not an action of the given type.
|
else:
|
||||||
"""
|
# can to do revoke
|
||||||
try:
|
return double_confirm
|
||||||
# noinspection PyTypeHints
|
|
||||||
actions = self.actions
|
|
||||||
actions.sort(key=lambda x: x.created)
|
|
||||||
return next(e for e in reversed(actions) if isinstance(e, types))
|
|
||||||
except StopIteration:
|
|
||||||
raise LookupError('{!r} does not contain actions of types {}.'.format(self, types))
|
|
||||||
|
|
||||||
def _warning_actions(self, actions):
|
def _warning_actions(self, actions):
|
||||||
return sorted(ev for ev in actions if ev.severity >= Severity.Warning)
|
return sorted(ev for ev in actions if ev.severity >= Severity.Warning)
|
||||||
|
|
Reference in New Issue