refactoring and fixing some problems of manual merge

This commit is contained in:
Cayo Puigdefabregas 2020-10-28 13:30:22 +01:00
parent 0106728e4f
commit fe3f038218
1 changed files with 44 additions and 29 deletions

View File

@ -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):