diff --git a/ereuse_devicehub/resources/device/sync.py b/ereuse_devicehub/resources/device/sync.py index 650d8036..8b27a85f 100644 --- a/ereuse_devicehub/resources/device/sync.py +++ b/ereuse_devicehub/resources/device/sync.py @@ -30,13 +30,6 @@ DEVICES_ALLOW_DUPLICITY = [ 'GraphicCard', ] -err_motherboard = "Error: We have detected that a there is a device" -err_motherboard += " in your inventory with this system UUID. " -err_motherboard += "We proceed to block this snapshot to prevent its" -err_motherboard += " information from being updated incorrectly." -err_motherboard += " The solution we offer you to inventory this device " -err_motherboard += "is to do it by creating a placeholder." - class Sync: """Synchronizes the device and components with the database.""" @@ -74,18 +67,10 @@ class Sync: of the passed-in components. 2. A list of Add / Remove (not yet added to session). """ + device.components = OrderedSet(components) + device.set_hid() + device.components = OrderedSet() db_device = self.execute_register(device) - motherboard = None - if components: - for c in components: - if c.type == "Motherboard": - motherboard = c - - if motherboard: - for c in db_device.components: - if c.type == "Motherboard" and motherboard.hid != c.hid: - # import pdb; pdb.set_trace() - raise ValidationError(err_motherboard) db_components, actions = OrderedSet(), OrderedSet() if components is not None: # We have component info (see above) @@ -93,12 +78,9 @@ class Sync: # Until a good reason is given, we synthetically forbid # non-computers with components raise ValidationError('Only computers can have components.') - blacklist = set() # type: Set[int] not_new_components = set() for component in components: - db_component, is_new = self.execute_register_component( - component, blacklist, parent=db_device - ) + db_component, is_new = self.execute_register_component(component) db_components.add(db_component) if not is_new: not_new_components.add(db_component) @@ -109,9 +91,7 @@ class Sync: self.create_placeholder(db_device) return db_device, actions - def execute_register_component( - self, component: Component, blacklist: Set[int], parent: Computer - ): + def execute_register_component(self, component: Component): """Synchronizes one component to the DB. This method is a specialization of :meth:`.execute_register` @@ -141,30 +121,18 @@ class Sync: is_new = True return component, is_new - # if not, then continue with the traditional behaviour - try: - if component.hid: - db_component = Device.query.filter_by( - hid=component.hid, owner_id=g.user.id, placeholder=None - ).one() - assert isinstance( - db_component, Device - ), '{} must be a component'.format(db_component) - else: - # Is there a component similar to ours? - db_component = component.similar_one(parent, blacklist) - # We blacklist this component so we - # ensure we don't get it again for another component - # with the same physical properties - blacklist.add(db_component.id) - except ResourceNotFound: + if component.hid: + db_component = Device.query.filter_by( + hid=component.hid, owner_id=g.user.id, placeholder=None + ).first() + assert isinstance(db_component, Device), '{} must be a component'.format( + db_component + ) + is_new = False + else: db.session.add(component) - # db.session.flush() db_component = component is_new = True - else: - self.merge(component, db_component) - is_new = False return db_component, is_new def execute_register(self, device: Device) -> Device: @@ -194,53 +162,15 @@ class Sync: :raise DatabaseError: Any other error from the DB. :return: The synced device from the db with the tags linked. """ - assert inspect(device).transient, 'Device cannot be already synced from DB' - assert all( - inspect(tag).transient for tag in device.tags - ), 'Tags cannot be synced from DB' db_device = device.get_from_db() if db_device and db_device.allocated: raise ResourceNotFound('device is actually allocated {}'.format(device)) - try: - tags = { - Tag.from_an_id(tag.id).one() for tag in device.tags - } # type: Set[Tag] - except ResourceNotFound: - raise ResourceNotFound('tag you are linking to device {}'.format(device)) - linked_tags = {tag for tag in tags if tag.device_id} # type: Set[Tag] - if linked_tags: - sample_tag = next(iter(linked_tags)) - for tag in linked_tags: - if tag.device_id != sample_tag.device_id: - raise MismatchBetweenTags( - tag, sample_tag - ) # Tags linked to different devices - if db_device: # Device from hid - if ( - sample_tag.device_id != db_device.id - ): # Device from hid != device from tags - raise MismatchBetweenTagsAndHid(db_device.id, db_device.hid) - else: # There was no device from hid - if sample_tag.device.physical_properties != device.physical_properties: - # Incoming physical props of device != props from tag's device - # which means that the devices are not the same - raise MismatchBetweenProperties( - sample_tag.device.physical_properties, - device.physical_properties, - ) - db_device = sample_tag.device - - if db_device: # Device from hid or tags - self.merge(device, db_device) - else: # Device is new and tags are not linked to a device + if not db_device: device.tags.clear() # We don't want to add the transient dummy tags db.session.add(device) db_device = device - db_device.tags |= ( - tags # Union of tags the device had plus the (potentially) new ones - ) try: db.session.flush() except IntegrityError as e: @@ -258,29 +188,6 @@ class Sync: assert db_device is not None return db_device - @staticmethod - def merge(device: Device, db_device: Device): - """Copies the physical properties of the device to the db_device. - - This method mutates db_device. - """ - if db_device.owner_id != g.user.id: - return - - if device.placeholder and not db_device.placeholder: - return - - for field_name, value in device.physical_properties.items(): - if value is not None: - setattr(db_device, field_name, value) - - # if device.system_uuid and db_device.system_uuid and device.system_uuid != db_device.system_uuid: - # TODO @cayop send error to sentry.io - # there are 2 computers duplicate get db_device for hid - - if hasattr(device, 'system_uuid') and device.system_uuid: - db_device.system_uuid = device.system_uuid - @staticmethod def create_placeholder(device: Device): """If the device is new, we need create automaticaly a new placeholder"""