more simple patch in post view

This commit is contained in:
Cayo Puigdefabregas 2020-10-08 14:47:11 +02:00
parent 0e89af1215
commit 258c3b4efd
1 changed files with 62 additions and 61 deletions

View File

@ -1,6 +1,5 @@
import os import os
import json import json
import copy
from time import time from time import time
from distutils.version import StrictVersion from distutils.version import StrictVersion
from typing import List from typing import List
@ -8,6 +7,7 @@ from uuid import UUID
from flask import current_app as app, request, g from flask import current_app as app, request, g
from sqlalchemy.util import OrderedSet from sqlalchemy.util import OrderedSet
from marshmallow.exceptions import ValidationError as mValidationError
from teal.marshmallow import ValidationError from teal.marshmallow import ValidationError
from teal.resource import View from teal.resource import View
@ -24,26 +24,28 @@ SUPPORTED_WORKBENCH = StrictVersion('11.0')
TMP_SNAPSHOTS = 'tmp/snapshots' TMP_SNAPSHOTS = 'tmp/snapshots'
def save_snapshot_in_file(snapshot_json): def save_json(req_json):
""" """
This function allow save a snapshot in json format un a TMP_SNAPSHOTS directory This function allow save a snapshot in json format un a TMP_SNAPSHOTS directory
The file need to be saved with one name format with the stamptime and uuid joins The file need to be saved with one name format with the stamptime and uuid joins
""" """
name_file = "{uuid}_{time}.json".format(uuid=snapshot_json['uuid'], time=int(time())) name_file = "{uuid}_{time}.json".format(uuid=req_json.get('uuid', ''), time=int(time()))
path_name = "{tmp}/{file}".format(tmp=TMP_SNAPSHOTS, file=name_file) path_name = "{tmp}/{file}".format(tmp=TMP_SNAPSHOTS, file=name_file)
if not os.path.isdir(TMP_SNAPSHOTS): if not os.path.isdir(TMP_SNAPSHOTS):
os.system('mkdir -p {}'.format(TMP_SNAPSHOTS)) os.system('mkdir -p {}'.format(TMP_SNAPSHOTS))
snapshot_file = open(path_name, 'w') snapshot_file = open(path_name, 'w')
snapshot_file.write(json.dumps(snapshot_json)) snapshot_file.write(json.dumps(req_json))
snapshot_file.close() snapshot_file.close()
return path_name
class ActionView(View): class ActionView(View):
def post(self): def post(self):
"""Posts an action.""" """Posts an action."""
json = request.get_json(validate=False) json = request.get_json(validate=False)
path_snapshot = save_json(json)
if not json or 'type' not in json: if not json or 'type' not in json:
raise ValidationError('Resource needs a type.') raise ValidationError('Resource needs a type.')
# todo there should be a way to better get subclassess resource # todo there should be a way to better get subclassess resource
@ -51,11 +53,14 @@ class ActionView(View):
resource_def = app.resources[json['type']] resource_def = app.resources[json['type']]
a = resource_def.schema.load(json) a = resource_def.schema.load(json)
if json['type'] == Snapshot.t: if json['type'] == Snapshot.t:
return self.snapshot(a, resource_def) response = self.snapshot(a, resource_def)
os.remove(path_snapshot)
return response
if json['type'] == VisualTest.t: if json['type'] == VisualTest.t:
pass pass
# TODO JN add compute rate with new visual test and old components device # TODO JN add compute rate with new visual test and old components device
if json['type'] == InitTransfer.t: if json['type'] == InitTransfer.t:
os.remove(path_snapshot)
return self.transfer_ownership() return self.transfer_ownership()
Model = db.Model._decl_class_registry.data[json['type']]() Model = db.Model._decl_class_registry.data[json['type']]()
action = Model(**a) action = Model(**a)
@ -64,6 +69,7 @@ class ActionView(View):
ret = self.schema.jsonify(action) ret = self.schema.jsonify(action)
ret.status_code = 201 ret.status_code = 201
db.session.commit() db.session.commit()
os.remove(path_snapshot)
return ret return ret
def one(self, id: UUID): def one(self, id: UUID):
@ -80,67 +86,62 @@ class ActionView(View):
# model object, when we flush them to the db we will flush # model object, when we flush them to the db we will flush
# snapshot, and we want to wait to flush snapshot at the end # snapshot, and we want to wait to flush snapshot at the end
snapshot_json_bakup = copy.copy(snapshot_json) device = snapshot_json.pop('device') # type: Computer
try: components = None
device = snapshot_json.pop('device') # type: Computer if snapshot_json['software'] == (SnapshotSoftware.Workbench or SnapshotSoftware.WorkbenchAndroid):
components = None components = snapshot_json.pop('components', None) # type: List[Component]
if snapshot_json['software'] == (SnapshotSoftware.Workbench or SnapshotSoftware.WorkbenchAndroid): snapshot = Snapshot(**snapshot_json)
components = snapshot_json.pop('components', None) # type: List[Component]
snapshot = Snapshot(**snapshot_json)
# Remove new actions from devices so they don't interfere with sync # Remove new actions from devices so they don't interfere with sync
actions_device = set(e for e in device.actions_one) actions_device = set(e for e in device.actions_one)
device.actions_one.clear() device.actions_one.clear()
if components: if components:
actions_components = tuple(set(e for e in c.actions_one) for c in components) actions_components = tuple(set(e for e in c.actions_one) for c in components)
for component in components: for component in components:
component.actions_one.clear() component.actions_one.clear()
assert not device.actions_one assert not device.actions_one
assert all(not c.actions_one for c in components) if components else True assert all(not c.actions_one for c in components) if components else True
db_device, remove_actions = resource_def.sync.run(device, components) db_device, remove_actions = resource_def.sync.run(device, components)
del device # Do not use device anymore del device # Do not use device anymore
snapshot.device = db_device snapshot.device = db_device
snapshot.actions |= remove_actions | actions_device # Set actions to snapshot snapshot.actions |= remove_actions | actions_device # Set actions to snapshot
# commit will change the order of the components by what # commit will change the order of the components by what
# the DB wants. Let's get a copy of the list so we preserve order # the DB wants. Let's get a copy of the list so we preserve order
ordered_components = OrderedSet(x for x in snapshot.components) ordered_components = OrderedSet(x for x in snapshot.components)
# Add the new actions to the db-existing devices and components # Add the new actions to the db-existing devices and components
db_device.actions_one |= actions_device db_device.actions_one |= actions_device
if components: if components:
for component, actions in zip(ordered_components, actions_components): for component, actions in zip(ordered_components, actions_components):
component.actions_one |= actions component.actions_one |= actions
snapshot.actions |= actions snapshot.actions |= actions
if snapshot.software == SnapshotSoftware.Workbench: if snapshot.software == SnapshotSoftware.Workbench:
# Check ownership of (non-component) device to from current.user # Check ownership of (non-component) device to from current.user
if db_device.owner_id != g.user.id: if db_device.owner_id != g.user.id:
raise InsufficientPermission() raise InsufficientPermission()
# Compute ratings # Compute ratings
try: try:
rate_computer, price = RateComputer.compute(db_device) rate_computer, price = RateComputer.compute(db_device)
except CannotRate: except CannotRate:
pass pass
else: else:
snapshot.actions.add(rate_computer) snapshot.actions.add(rate_computer)
if price: if price:
snapshot.actions.add(price) snapshot.actions.add(price)
elif snapshot.software == SnapshotSoftware.WorkbenchAndroid: elif snapshot.software == SnapshotSoftware.WorkbenchAndroid:
pass # TODO try except to compute RateMobile pass # TODO try except to compute RateMobile
# Check if HID is null and add Severity:Warning to Snapshot # Check if HID is null and add Severity:Warning to Snapshot
if snapshot.device.hid is None: if snapshot.device.hid is None:
snapshot.severity = Severity.Warning snapshot.severity = Severity.Warning
db.session.add(snapshot) db.session.add(snapshot)
db.session().final_flush() db.session().final_flush()
ret = self.schema.jsonify(snapshot) # transform it back ret = self.schema.jsonify(snapshot) # transform it back
ret.status_code = 201 ret.status_code = 201
db.session.commit() db.session.commit()
return ret return ret
except Exception as err:
save_snapshot_in_file(snapshot_json_bakup)
raise err
def transfer_ownership(self): def transfer_ownership(self):
"""Perform a InitTransfer action to change author_id of device""" """Perform a InitTransfer action to change author_id of device"""