|
6 | 6 | import logging |
7 | 7 | import uuid |
8 | 8 |
|
| 9 | +from sqlalchemy.orm import Session |
| 10 | + |
| 11 | +from rescue_api.models import Asset, Rescue, Rescuer |
9 | 12 | from .payload import AssetModel |
10 | 13 |
|
11 | 14 | # Configuration du logging |
@@ -157,7 +160,95 @@ def allocate_assets(self, free_space_mb: float, node_id: str = None) -> Dict: |
157 | 160 | "allocation_id": str(uuid.uuid4()) |
158 | 161 | } |
159 | 162 |
|
160 | | - def upsert_rescues(self, rescuer_id: int, assets: List[AssetModel]) -> Dict: |
| 163 | + |
| 164 | + def upsert_rescues_to_db(self, rescuer_id: int, assets: List[AssetModel], db: Session) -> Dict: |
| 165 | + if not self._rescuer_exists(rescuer_id=rescuer_id, db=db): |
| 166 | + return {} |
| 167 | + |
| 168 | + if not self._are_assets_data_consistent(assets=assets, db=db): |
| 169 | + return {} |
| 170 | + |
| 171 | + updated_rescues = [] |
| 172 | + inserted_rescues = [] |
| 173 | + not_committed_rescues = [] |
| 174 | + |
| 175 | + for asset in assets: |
| 176 | + asset_id = int(asset.asset_id) |
| 177 | + rescue = db.query(Rescue).filter( |
| 178 | + (Rescue.rescuer_id == rescuer_id) & (Rescue.asset_id == asset_id) |
| 179 | + ).first() |
| 180 | + |
| 181 | + is_insertion_operation = False |
| 182 | + if not rescue: |
| 183 | + is_insertion_operation = True |
| 184 | + rescue = Rescue( |
| 185 | + asset_id=asset_id, |
| 186 | + rescuer_id=rescuer_id, |
| 187 | + magnet_link=asset.magnet_link, |
| 188 | + status=asset.status.value.lower(), |
| 189 | + ) |
| 190 | + db.add(rescue) |
| 191 | + else: |
| 192 | + rescue.magnet_link = asset.magnet_link |
| 193 | + rescue.status = asset.status.value.lower() |
| 194 | + |
| 195 | + try: |
| 196 | + db.commit() |
| 197 | + except Exception as e: |
| 198 | + print(e) |
| 199 | + print(f"Rescue with rescuer_id='{rescuer_id}' and asset_id='{asset_id}' has not been committed to DB.") |
| 200 | + not_committed_rescues.append( |
| 201 | + { |
| 202 | + "asset_id": asset_id, |
| 203 | + "rescuer_id": rescuer_id, |
| 204 | + "magnet_link": asset.magnet_link, |
| 205 | + "status": asset.status.value.lower(), |
| 206 | + } |
| 207 | + ) |
| 208 | + else: |
| 209 | + committed_rescue = { |
| 210 | + "asset_id": asset_id, |
| 211 | + "rescuer_id": rescuer_id, |
| 212 | + "magnet_link": asset.magnet_link, |
| 213 | + "status": asset.status.value.lower(), |
| 214 | + } |
| 215 | + if is_insertion_operation: |
| 216 | + inserted_rescues.append(committed_rescue) |
| 217 | + else: |
| 218 | + updated_rescues.append(committed_rescue) |
| 219 | + |
| 220 | + return { |
| 221 | + "updated_rescues": updated_rescues, |
| 222 | + "inserted_rescues": inserted_rescues, |
| 223 | + "not_committed_rescues": not_committed_rescues, |
| 224 | + } |
| 225 | + |
| 226 | + |
| 227 | + @staticmethod |
| 228 | + def _rescuer_exists(rescuer_id: int, db: Session) -> bool: |
| 229 | + rescuer = db.query(Rescuer).filter(Rescuer.id == rescuer_id).first() |
| 230 | + return True if rescuer else False |
| 231 | + |
| 232 | + |
| 233 | + @staticmethod |
| 234 | + def _are_assets_data_consistent(assets: List[AssetModel], db: Session) -> bool: |
| 235 | + missing_assets_count = 0 |
| 236 | + asset_inconsistencies_count = 0 |
| 237 | + |
| 238 | + for asset in assets: |
| 239 | + db_asset = db.query(Asset).filter(Asset.id == int(asset.asset_id)).first() |
| 240 | + if not db_asset: |
| 241 | + missing_assets_count += 1 |
| 242 | + elif db_asset.url != asset.url: |
| 243 | + asset_inconsistencies_count += 1 |
| 244 | + |
| 245 | + if missing_assets_count > 0 or asset_inconsistencies_count > 0: |
| 246 | + return False |
| 247 | + |
| 248 | + return True |
| 249 | + |
| 250 | + |
| 251 | + def upsert_rescues_to_json(self, rescuer_id: int, assets: List[AssetModel]) -> Dict: |
161 | 252 | rescues_to_upsert = self._prepare_rescues_to_upsert(rescuer_id=rescuer_id, assets=assets) |
162 | 253 | rescues_from_db = self._load_json(self.rescues_file) |
163 | 254 |
|
|
0 commit comments