class SkillManifestReconciler(object): def __init__(self, db, device_manifest, db_manifest): self.db = db self.skill_manifest_repo = DeviceSkillRepository(db) self.skill_repo = SkillRepository(self.db) self.device_manifest = {sm.skill_gid: sm for sm in device_manifest} self.db_manifest = {ds.skill_gid: ds for ds in db_manifest} self.device_manifest_global_ids = { gid for gid in self.device_manifest.keys() } self.db_manifest_global_ids = {gid for gid in self.db_manifest} def reconcile(self): """Compare the manifest sent by the device to that on the database.""" self._update_skills() self._remove_skills() self._add_skills() def _update_skills(self): common_global_ids = self.device_manifest_global_ids.intersection( self.db_manifest_global_ids) for gid in common_global_ids: if self.device_manifest[gid] == self.db_manifest[gid]: self.skill_manifest_repo.update_manifest_skill( self.device_manifest[gid]) def _remove_skills(self): skills_to_remove = self.db_manifest_global_ids.difference( self.device_manifest_global_ids) for gid in skills_to_remove: manifest_skill = self.db_manifest[gid] self.skill_manifest_repo.remove_manifest_skill(manifest_skill) if manifest_skill.device_id in gid: self.skill_repo.remove_by_gid(gid) def _add_skills(self): skills_to_add = self.device_manifest_global_ids.difference( self.db_manifest_global_ids) for gid in skills_to_add: skill_id = self.skill_repo.ensure_skill_exists(gid) self.device_manifest[gid].skill_id = skill_id self.skill_manifest_repo.add_manifest_skill( self.device_manifest[gid])
def add_device_skill(db, device_id, skill): manifest_skill = ManifestSkill(device_id=device_id, install_method='test_install_method', install_status='test_install_status', skill_id=skill.id, skill_gid=skill.skill_gid, install_ts=datetime.utcnow(), update_ts=datetime.utcnow()) device_skill_repo = DeviceSkillRepository(db) manifest_skill.id = device_skill_repo.add_manifest_skill(manifest_skill) return manifest_skill