refactoring and fixing some problems of manual merge
This commit is contained in:
parent
0106728e4f
commit
fe3f038218
|
@ -6,10 +6,13 @@ import marshmallow
|
||||||
from flask import g, current_app as app, render_template, request, Response
|
from flask import g, current_app as app, render_template, request, Response
|
||||||
from flask.json import jsonify
|
from flask.json import jsonify
|
||||||
from flask_sqlalchemy import Pagination
|
from flask_sqlalchemy import Pagination
|
||||||
|
from sqlalchemy.util import OrderedSet
|
||||||
from marshmallow import fields, fields as f, validate as v, Schema as MarshmallowSchema
|
from marshmallow import fields, fields as f, validate as v, Schema as MarshmallowSchema
|
||||||
from teal import query
|
from teal import query
|
||||||
|
from teal.db import ResourceNotFound
|
||||||
from teal.cache import cache
|
from teal.cache import cache
|
||||||
from teal.resource import View
|
from teal.resource import View
|
||||||
|
from teal.marshmallow import ValidationError
|
||||||
|
|
||||||
from ereuse_devicehub import auth
|
from ereuse_devicehub import auth
|
||||||
from ereuse_devicehub.db import db
|
from ereuse_devicehub.db import db
|
||||||
|
@ -183,7 +186,7 @@ class DeviceMergeView(View):
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@auth.Auth.requires_auth
|
@auth.Auth.requires_auth
|
||||||
def merge_devices(self, dev1_id, dev2_id):
|
def merge_devices(self, dev1_id: int, dev2_id: int) -> Device:
|
||||||
"""Merge the current device with `with_device` (dev2_id) by
|
"""Merge the current device with `with_device` (dev2_id) by
|
||||||
adding all `with_device` actions under the current device, (dev1_id).
|
adding all `with_device` actions under the current device, (dev1_id).
|
||||||
|
|
||||||
|
@ -191,45 +194,57 @@ class DeviceMergeView(View):
|
||||||
many models in session.
|
many models in session.
|
||||||
"""
|
"""
|
||||||
# base_device = Device.query.filter_by(id=dev1_id, owner_id=g.user.id).one()
|
# base_device = Device.query.filter_by(id=dev1_id, owner_id=g.user.id).one()
|
||||||
base_device = Device.query.filter_by(id=dev1_id).one()
|
self.base_device = Device.query.filter_by(id=dev1_id).one()
|
||||||
with_device = Device.query.filter_by(id=dev2_id).one()
|
self.with_device = Device.query.filter_by(id=dev2_id).one()
|
||||||
snapshots = sorted(
|
|
||||||
filterfalse(lambda x: not isinstance(x, actions.Snapshot), (base_device.actions + with_device.actions)))
|
|
||||||
workbench_snapshots = [s for s in snapshots if
|
|
||||||
s.software == (SnapshotSoftware.Workbench or SnapshotSoftware.WorkbenchAndroid)]
|
|
||||||
latest_snapshot_device = [d for d in (base_device, with_device) if d.id == snapshots[-1].device.id][0]
|
|
||||||
latest_snapshotworkbench_device = \
|
|
||||||
[d for d in (base_device, with_device) if d.id == workbench_snapshots[-1].device.id][0]
|
|
||||||
# Adding actions of with_device
|
|
||||||
with_actions_one = [a for a in with_device.actions if isinstance(a, actions.ActionWithOneDevice)]
|
|
||||||
with_actions_multiple = [a for a in with_device.actions if isinstance(a, actions.ActionWithMultipleDevices)]
|
|
||||||
|
|
||||||
|
if not self.base_device.type == self.with_device.type:
|
||||||
|
# Validation than we are speaking of the same kind of devices
|
||||||
|
raise ValidationError('The devices is not the same type.')
|
||||||
|
|
||||||
|
# Adding actions of self.with_device
|
||||||
|
with_actions_one = [a for a in self.with_device.actions
|
||||||
|
if isinstance(a, actions.ActionWithOneDevice)]
|
||||||
|
with_actions_multiple = [a for a in self.with_device.actions
|
||||||
|
if isinstance(a, actions.ActionWithMultipleDevices)]
|
||||||
|
|
||||||
|
# Moving the tags from `with_device` to `base_device`
|
||||||
|
# Union of tags the device had plus the (potentially) new ones
|
||||||
|
self.base_device.tags |= self.with_device.tags
|
||||||
|
self.with_device.tags.clear() # We don't want to add the transient dummy tags
|
||||||
|
# db.session.add(self.with_device)
|
||||||
|
|
||||||
|
# Moving the actions from `with_device` to `base_device`
|
||||||
for action in with_actions_one:
|
for action in with_actions_one:
|
||||||
if action.parent:
|
if action.parent:
|
||||||
action.parent = base_device
|
action.parent = self.base_device
|
||||||
else:
|
else:
|
||||||
base_device.actions_one.add(action)
|
self.base_device.actions_one.add(action)
|
||||||
for action in with_actions_multiple:
|
for action in with_actions_multiple:
|
||||||
if action.parent:
|
if action.parent:
|
||||||
action.parent = base_device
|
action.parent = self.base_device
|
||||||
else:
|
else:
|
||||||
base_device.actions_multiple.add(action)
|
self.base_device.actions_multiple.add(action)
|
||||||
|
|
||||||
# Keeping the components of latest SnapshotWorkbench
|
# Keeping the components of with_device
|
||||||
# base_device.components = latest_snapshotworkbench_device.components
|
components = OrderedSet(c for c in self.with_device.components)
|
||||||
base_device.components = with_device.components
|
self.base_device.components = components
|
||||||
|
|
||||||
# Properties from latest Snapshot
|
# Properties from with_device
|
||||||
|
self.merge()
|
||||||
|
|
||||||
base_device.type = with_device.type
|
db.session().add(self.base_device)
|
||||||
base_device.hid = with_device.hid
|
|
||||||
base_device.manufacturer = with_device.manufacturer
|
|
||||||
base_device.model = with_device.model
|
|
||||||
base_device.chassis = with_device.chassis
|
|
||||||
|
|
||||||
db.session().add(base_device)
|
|
||||||
db.session().final_flush()
|
db.session().final_flush()
|
||||||
return base_device
|
return self.base_device
|
||||||
|
|
||||||
|
def merge(self):
|
||||||
|
"""Copies the physical properties of the base_device to the with_device.
|
||||||
|
This method mutates base_device.
|
||||||
|
"""
|
||||||
|
for field_name, value in self.with_device.physical_properties.items():
|
||||||
|
if value is not None:
|
||||||
|
setattr(self.base_device, field_name, value)
|
||||||
|
|
||||||
|
self.base_device.hid = self.with_device.hid
|
||||||
|
|
||||||
|
|
||||||
class ManufacturerView(View):
|
class ManufacturerView(View):
|
||||||
|
|
Reference in New Issue