|
11 | 11 | from maelstro.common.types import GsLayer |
12 | 12 | from maelstro.common.models import CopyPreview, InfoRecord, SuccessRecord |
13 | 13 | from maelstro.common.exceptions import ParamError |
| 14 | +from requests import HTTPError |
14 | 15 | from .georchestra import GeorchestraHandler |
15 | 16 | from .operations import raise_for_status |
16 | | - |
| 17 | +from lxml import etree |
17 | 18 |
|
18 | 19 | logger = logging.getLogger() |
19 | 20 |
|
@@ -356,33 +357,56 @@ def copy_layer( |
356 | 357 | ) |
357 | 358 | resource = gs_src.rest_client.get(xml_resource_route) |
358 | 359 |
|
| 360 | + # Clean <attributes> element to avoid "Custom attributes" checkbox being set |
| 361 | + # See issue #94 |
| 362 | + cleaned_content = self.remove_attributes_element(resource.content) |
359 | 363 | if has_resource.status_code == 200: |
360 | 364 | if has_layer.status_code != 200: |
361 | 365 | resp = self.gs_dst.rest_client.delete(resource_route) |
362 | 366 | raise_for_status(resp) |
363 | 367 | resp = self.gs_dst.rest_client.post( |
364 | 368 | resource_post_route, |
365 | | - data=resource.content, |
| 369 | + data=cleaned_content, |
366 | 370 | headers={"content-type": "application/xml"}, |
367 | 371 | ) |
368 | 372 | else: |
369 | 373 | resp = self.gs_dst.rest_client.put( |
370 | 374 | xml_resource_route, |
371 | | - data=resource.content, |
| 375 | + data=cleaned_content, |
372 | 376 | headers={"content-type": "application/xml"}, |
373 | 377 | ) |
374 | 378 | else: |
375 | | - resp = self.gs_dst.rest_client.post( |
376 | | - resource_post_route, |
377 | | - data=resource.content, |
378 | | - headers={"content-type": "application/xml"}, |
379 | | - ) |
380 | | - if resp.status_code == 404: |
381 | | - raise ParamError( |
382 | | - context="dst", |
383 | | - key=resource_post_route, |
384 | | - err="Route not found. Check Workspace and datastore", |
| 379 | + # if featureType doesn't exist as XMl but exist in DB |
| 380 | + # this methode will work and won't check the "Custom attributes" checkbox |
| 381 | + try: |
| 382 | + resp = self.gs_dst.rest_client.post( |
| 383 | + resource_post_route, |
| 384 | + data=cleaned_content, |
| 385 | + headers={"content-type": "application/xml"}, |
385 | 386 | ) |
| 387 | + if resp.status_code == 404: |
| 388 | + raise ParamError( |
| 389 | + context="dst", |
| 390 | + key=resource_post_route, |
| 391 | + err="Route not found. Check Workspace and datastore", |
| 392 | + ) |
| 393 | + except HTTPError as err: |
| 394 | + if err.response.status_code == 400: |
| 395 | + # Insert with all attributes |
| 396 | + # if featureType doesn't exist as XMl AND in DB we need to use resource.content with attributes |
| 397 | + # "Custom attributes" checkbox won't be checked |
| 398 | + resp = self.gs_dst.rest_client.post( |
| 399 | + resource_post_route, |
| 400 | + data=resource.content, |
| 401 | + headers={"content-type": "application/xml"}, |
| 402 | + ) |
| 403 | + |
| 404 | + else: |
| 405 | + raise ParamError( |
| 406 | + context="dst", |
| 407 | + key=resource_post_route, |
| 408 | + err=err, |
| 409 | + ) from err |
386 | 410 | raise_for_status(resp) |
387 | 411 |
|
388 | 412 | resp = self.gs_dst.rest_client.put( |
@@ -425,3 +449,10 @@ def copy_style( |
425 | 449 | headers={"content-type": style_def.headers["content-type"]}, |
426 | 450 | ) |
427 | 451 | raise_for_status(dst_style_def) |
| 452 | + |
| 453 | + def remove_attributes_element(self, xml_bytes: bytes) -> bytes: |
| 454 | + root = etree.fromstring(xml_bytes) |
| 455 | + attributes = root.find("attributes") |
| 456 | + if attributes is not None: |
| 457 | + root.remove(attributes) |
| 458 | + return etree.tostring(root, encoding="utf-8") |
0 commit comments