pyxecm 1.5__py3-none-any.whl → 1.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyxecm might be problematic. Click here for more details.
- pyxecm/__init__.py +2 -0
- pyxecm/avts.py +1065 -0
- pyxecm/coreshare.py +467 -571
- pyxecm/customizer/customizer.py +160 -19
- pyxecm/customizer/k8s.py +139 -25
- pyxecm/customizer/m365.py +694 -1498
- pyxecm/customizer/payload.py +2306 -485
- pyxecm/customizer/pht.py +547 -124
- pyxecm/customizer/salesforce.py +378 -443
- pyxecm/customizer/servicenow.py +379 -133
- pyxecm/helper/assoc.py +20 -0
- pyxecm/helper/data.py +237 -33
- pyxecm/helper/xml.py +1 -1
- pyxecm/otawp.py +1810 -0
- pyxecm/otcs.py +3180 -2938
- pyxecm/otds.py +1591 -1875
- pyxecm/otmm.py +131 -11
- {pyxecm-1.5.dist-info → pyxecm-1.6.dist-info}/METADATA +3 -1
- pyxecm-1.6.dist-info/RECORD +32 -0
- {pyxecm-1.5.dist-info → pyxecm-1.6.dist-info}/WHEEL +1 -1
- pyxecm-1.5.dist-info/RECORD +0 -30
- {pyxecm-1.5.dist-info → pyxecm-1.6.dist-info}/LICENSE +0 -0
- {pyxecm-1.5.dist-info → pyxecm-1.6.dist-info}/top_level.txt +0 -0
pyxecm/otmm.py
CHANGED
|
@@ -107,7 +107,7 @@ class OTMM:
|
|
|
107
107
|
target(*args, **kwargs)
|
|
108
108
|
except Exception as e:
|
|
109
109
|
thread_name = threading.current_thread().name
|
|
110
|
-
logger.error("Thread %s: failed with exception %s", thread_name, e)
|
|
110
|
+
logger.error("Thread '%s': failed with exception -> %s", thread_name, e)
|
|
111
111
|
logger.error(traceback.format_exc())
|
|
112
112
|
|
|
113
113
|
# end method definition
|
|
@@ -261,6 +261,48 @@ class OTMM:
|
|
|
261
261
|
|
|
262
262
|
# end method definition
|
|
263
263
|
|
|
264
|
+
def get_asset(self, asset_id: str) -> dict:
|
|
265
|
+
"""Get an asset based on its ID
|
|
266
|
+
|
|
267
|
+
Args:
|
|
268
|
+
asset_id (str): Asset ID
|
|
269
|
+
|
|
270
|
+
Returns:
|
|
271
|
+
dict: dictionary with asset data
|
|
272
|
+
"""
|
|
273
|
+
|
|
274
|
+
request_url = self.config()["assetsUrl"] + "/" + asset_id
|
|
275
|
+
|
|
276
|
+
headers = {"Content-Type": "application/x-www-form-urlencoded"}
|
|
277
|
+
|
|
278
|
+
try:
|
|
279
|
+
response = self._session.get(
|
|
280
|
+
request_url,
|
|
281
|
+
headers=headers,
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
response.raise_for_status()
|
|
285
|
+
|
|
286
|
+
except requests.exceptions.HTTPError as http_err:
|
|
287
|
+
logger.error("HTTP error occurred: %s", http_err)
|
|
288
|
+
return None
|
|
289
|
+
except requests.exceptions.ConnectionError as conn_err:
|
|
290
|
+
logger.error("Connection error occurred: %s", conn_err)
|
|
291
|
+
return None
|
|
292
|
+
except requests.exceptions.Timeout as timeout_err:
|
|
293
|
+
logger.error("Timeout error occurred: %s", timeout_err)
|
|
294
|
+
return None
|
|
295
|
+
except requests.exceptions.RequestException as req_err:
|
|
296
|
+
logger.error("Request error occurred: %s", req_err)
|
|
297
|
+
return None
|
|
298
|
+
except Exception as e:
|
|
299
|
+
logger.error("An unexpected error occurred: %s", e)
|
|
300
|
+
return None
|
|
301
|
+
|
|
302
|
+
return response.json()
|
|
303
|
+
|
|
304
|
+
# end method definition
|
|
305
|
+
|
|
264
306
|
def get_business_unit_assets(
|
|
265
307
|
self, bu_id: int, offset: int = 0, limit: int = 200
|
|
266
308
|
) -> list | None:
|
|
@@ -418,7 +460,7 @@ class OTMM:
|
|
|
418
460
|
if download_url:
|
|
419
461
|
request_url = download_url
|
|
420
462
|
else:
|
|
421
|
-
request_url = self.config()["assetsUrl"] + "/" + asset_id + "/
|
|
463
|
+
request_url = self.config()["assetsUrl"] + "/" + asset_id + "/contents"
|
|
422
464
|
|
|
423
465
|
file_name = os.path.join(self._download_dir, asset_id)
|
|
424
466
|
|
|
@@ -623,8 +665,81 @@ class OTMM:
|
|
|
623
665
|
) -> bool:
|
|
624
666
|
"""Load all Media Assets for Products and Business Units
|
|
625
667
|
|
|
668
|
+
Args:
|
|
669
|
+
load_products (bool, optional): If true load assets on Business Unit level. Defaults to True.
|
|
670
|
+
load_business_units (bool, optional): If true load assets on Product level. Defaults to True.
|
|
671
|
+
download_assets (bool, optional): Should assets been downloaded. Defaults to True.
|
|
672
|
+
|
|
626
673
|
Returns:
|
|
627
674
|
bool: True = Success, False = Failure
|
|
675
|
+
|
|
676
|
+
Example Asset:
|
|
677
|
+
{
|
|
678
|
+
'access_control_descriptor': {
|
|
679
|
+
'permissions_map': {...}
|
|
680
|
+
},
|
|
681
|
+
'asset_content_info': {
|
|
682
|
+
'master_content': {...}
|
|
683
|
+
},
|
|
684
|
+
'asset_id': '68fe5a6423fd317fdf87e83bc8cde736d4df27bf',
|
|
685
|
+
'asset_lock_state_last_update_date': '2024-09-09T22:02:53Z',
|
|
686
|
+
'asset_lock_state_user_id': '202',
|
|
687
|
+
'asset_state': 'NORMAL',
|
|
688
|
+
'asset_state_last_update_date': '2024-09-09T22:02:53Z',
|
|
689
|
+
'asset_state_user_id': '202',
|
|
690
|
+
'checked_out': False,
|
|
691
|
+
'content_editable': True,
|
|
692
|
+
'content_lock_state_last_update_date': '2024-08-14T00:33:27Z',
|
|
693
|
+
'content_lock_state_user_id': '202',
|
|
694
|
+
'content_lock_state_user_name': 'ajohnson3',
|
|
695
|
+
'content_size': 18474085,
|
|
696
|
+
'content_state': 'NORMAL',
|
|
697
|
+
'content_state_last_update_date': '2024-08-14T00:33:27Z',
|
|
698
|
+
'content_state_user_id': '202',
|
|
699
|
+
'content_state_user_name': 'Amanda Johnson',
|
|
700
|
+
'content_type': 'ACROBAT',
|
|
701
|
+
'creator_id': '202',
|
|
702
|
+
'date_imported': '2024-08-14T00:33:26Z',
|
|
703
|
+
'date_last_updated': '2024-09-09T22:02:53Z',
|
|
704
|
+
'deleted': False,
|
|
705
|
+
'delivery_service_url': 'https://assets.opentext.com/adaptivemedia/rendition?id=68fe5a6423fd317fdf87e83bc8cde736d4df27bf',
|
|
706
|
+
'expired': False,
|
|
707
|
+
'import_job_id': 7764,
|
|
708
|
+
'import_user_name': 'ajohnson3',
|
|
709
|
+
'latest_version': True,
|
|
710
|
+
'legacy_model_id': 104,
|
|
711
|
+
'locked': False,
|
|
712
|
+
'master_content_info': {
|
|
713
|
+
'content_checksum': '45f42d19542af5b6146cbb3927a5490f',
|
|
714
|
+
'content_data': {...},
|
|
715
|
+
'content_kind': 'MASTER',
|
|
716
|
+
'content_manager_id': 'ARTESIA.CONTENT.GOOGLE.CLOUD',
|
|
717
|
+
'content_path': 'data/repository/original/generative-ai-governance-essentials-wp-en_56cbbfe270593ba1a5ab6551d2c8b373469cc1a9.pdf',
|
|
718
|
+
'content_size': 18474085,
|
|
719
|
+
'height': -1,
|
|
720
|
+
'id': '56cbbfe270593ba1a5ab6551d2c8b373469cc1a9',
|
|
721
|
+
'mime_type': 'application/pdf',
|
|
722
|
+
'name': 'generative-ai-governance-essentials-wp-en.pdf',
|
|
723
|
+
'unit_of_size': 'BYTES',
|
|
724
|
+
'url': '/otmmapi/v6/renditions/56cbbfe270593ba1a5ab6551d2c8b373469cc1a9',
|
|
725
|
+
'width': -1
|
|
726
|
+
},
|
|
727
|
+
'metadata_lock_state_user_name': 'ajohnson3',
|
|
728
|
+
'metadata_model_id': 'OTM.MARKETING.MODEL',
|
|
729
|
+
'metadata_state_user_name': 'Amanda Johnson',
|
|
730
|
+
'mime_type': 'application/pdf',
|
|
731
|
+
'name': 'generative-ai-governance-essentials-wp-en.pdf',
|
|
732
|
+
'original_asset_id': '68fe5a6423fd317fdf87e83bc8cde736d4df27bf',
|
|
733
|
+
'product_associations': False,
|
|
734
|
+
'rendition_content': {
|
|
735
|
+
'thumbnail_content': {...},
|
|
736
|
+
'preview_content': {...},
|
|
737
|
+
'pdf_preview_content': {...}
|
|
738
|
+
},
|
|
739
|
+
'subscribed_to': False,
|
|
740
|
+
'thumbnail_content_id': '70aef1a5b5e480337bc115e47443884432c355ff',
|
|
741
|
+
'version': 1
|
|
742
|
+
}
|
|
628
743
|
"""
|
|
629
744
|
|
|
630
745
|
asset_list = []
|
|
@@ -656,7 +771,7 @@ class OTMM:
|
|
|
656
771
|
asset["workspace_type"] = "Product"
|
|
657
772
|
asset["workspace_name"] = product_name
|
|
658
773
|
|
|
659
|
-
asset_list += assets
|
|
774
|
+
asset_list += [asset for asset in assets if "content_size" in asset]
|
|
660
775
|
|
|
661
776
|
if load_business_units:
|
|
662
777
|
|
|
@@ -684,15 +799,20 @@ class OTMM:
|
|
|
684
799
|
asset["workspace_type"] = "Business Unit"
|
|
685
800
|
asset["workspace_name"] = bu_name
|
|
686
801
|
|
|
687
|
-
asset_list += assets
|
|
802
|
+
asset_list += [asset for asset in assets if "content_size" in asset]
|
|
803
|
+
# end for bu_name...
|
|
804
|
+
# end if load_business_units
|
|
688
805
|
|
|
689
|
-
|
|
806
|
+
# WE DON'T WANT TO DO THIS HERE ANY MORE!
|
|
807
|
+
# This is now done in the bulk document processing
|
|
808
|
+
# using conditions_delete and conditions_create
|
|
809
|
+
# asset_list = [
|
|
810
|
+
# item
|
|
811
|
+
# for item in asset_list
|
|
812
|
+
# if not item.get("deleted", False) and not item.get("expired", False)
|
|
813
|
+
# ]
|
|
690
814
|
|
|
691
|
-
|
|
692
|
-
item
|
|
693
|
-
for item in asset_list
|
|
694
|
-
if not item.get("deleted", False) and not item.get("expired", False)
|
|
695
|
-
]
|
|
815
|
+
total_count = len(asset_list)
|
|
696
816
|
|
|
697
817
|
number = self._thread_number
|
|
698
818
|
|
|
@@ -779,7 +899,7 @@ class OTMM:
|
|
|
779
899
|
)
|
|
780
900
|
continue
|
|
781
901
|
|
|
782
|
-
if download_assets:
|
|
902
|
+
if download_assets and asset.get("content_size", 0) > 0:
|
|
783
903
|
success = self.download_asset(
|
|
784
904
|
asset_id=asset_id,
|
|
785
905
|
asset_name=asset_name,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyxecm
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.6
|
|
4
4
|
Summary: A Python library to interact with Opentext Extended ECM REST API
|
|
5
5
|
Author-email: Kai Gatzweiler <kgatzweiler@opentext.com>, "Dr. Marc Diefenbruch" <mdiefenb@opentext.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/opentext/pyxecm
|
|
@@ -25,6 +25,8 @@ Requires-Dist: xmltodict
|
|
|
25
25
|
Requires-Dist: lxml
|
|
26
26
|
Requires-Dist: openpyxl
|
|
27
27
|
Requires-Dist: pandas
|
|
28
|
+
Requires-Dist: python-magic
|
|
29
|
+
Requires-Dist: websockets
|
|
28
30
|
Provides-Extra: customizer
|
|
29
31
|
Requires-Dist: python-hcl2 ; extra == 'customizer'
|
|
30
32
|
Requires-Dist: lxml ; extra == 'customizer'
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
pyxecm/__init__.py,sha256=aakkoowQ0bMt8CyublWcAeUZhiQYN8EhODIHi_sMjj0,301
|
|
2
|
+
pyxecm/avts.py,sha256=pWXhyyIxqCSmJGokCzKcAsHy2u38kEV8lAEked-8ysw,39704
|
|
3
|
+
pyxecm/coreshare.py,sha256=uchINAkJoZfcCeiPRBoVE6soyZUtGreuQLfKiWCyVtU,91462
|
|
4
|
+
pyxecm/otac.py,sha256=i1-4nljJUedAsz842s4WXH_YjmEC-hZh66zEGhRS5Uw,21684
|
|
5
|
+
pyxecm/otawp.py,sha256=Yisdn4JmGDfUF-GIdgb4MRTu2EumX-MTVlQeZOhvd5I,66030
|
|
6
|
+
pyxecm/otcs.py,sha256=uE-5HlvQg19N186-Tc1NFnuEXjCFJvK28wBXwP_Ko6U,423656
|
|
7
|
+
pyxecm/otds.py,sha256=eW-cH2oeKFKlARRi-ltX-Ja_DrOSNzDEk6TFhGDt0tE,148019
|
|
8
|
+
pyxecm/otiv.py,sha256=nHEBQ9tddtKMiR1yPbGGP-jJiDaQpyoFmZcQFPgw22w,1720
|
|
9
|
+
pyxecm/otmm.py,sha256=Pp00htEs46grAChlb5UOsBecYO2GsVzeiQXeZP7b6MM,33780
|
|
10
|
+
pyxecm/otpd.py,sha256=zRus7UnYYrwG9tYDPPLxBbGzozATwS07ftYun4kaaV4,12503
|
|
11
|
+
pyxecm/customizer/__init__.py,sha256=g32OUKoJiBYY4q9IMQctKTKq6YhFtv-IAIHcRC0KJu4,330
|
|
12
|
+
pyxecm/customizer/browser_automation.py,sha256=cbUTGBLmyYO7617QfNJCZtFCK0i8-2hfA6QhKSfuKOY,16430
|
|
13
|
+
pyxecm/customizer/customizer.py,sha256=OFrw2u3-4es205H9lMeFN4B0WpQAWxL7i-CnClAvawY,91195
|
|
14
|
+
pyxecm/customizer/k8s.py,sha256=iVA4WQodfkHxxkb8j3g2cr-GIR1ll6BMjq1aIXxIUB4,41414
|
|
15
|
+
pyxecm/customizer/m365.py,sha256=FvxpcukOjneivAPPQorP34eO3q7QZAzx1RVksCbmy50,145276
|
|
16
|
+
pyxecm/customizer/payload.py,sha256=V1yFl6Xw9q05QZynff1hmVugfzjSSjEW0cfPnuim8iw,855135
|
|
17
|
+
pyxecm/customizer/pht.py,sha256=lpoV15uyha3lH8pElG8j6U40JuBQC4Op_ci7VO65_EU,31655
|
|
18
|
+
pyxecm/customizer/salesforce.py,sha256=k2pGPLDAHANvp_-0QdlU4sbXplBNP2NXsUpjhBHSNJk,61644
|
|
19
|
+
pyxecm/customizer/sap.py,sha256=RNrHH0KjBQ10dHXoMaZIEd3EVPC8--4AN7nzy_Iv9k4,5947
|
|
20
|
+
pyxecm/customizer/servicenow.py,sha256=JWvlvLxC9nv3fnXOWMCKiHNfqas72a_qUmX4kSltdVQ,57358
|
|
21
|
+
pyxecm/customizer/successfactors.py,sha256=6hww4tKF_Bm2aLzFMStPuJmKJ4uBqteXwjWDkW0yDHU,38847
|
|
22
|
+
pyxecm/customizer/translate.py,sha256=RxC7O4lxfGaG1nttCm5WI5X2wEM4eEqbVcUtnYns1TQ,3968
|
|
23
|
+
pyxecm/helper/__init__.py,sha256=sScoB5RQAEkzP2LLvR_cRYwC1ARSdvBiv-4JwnJA7Dw,140
|
|
24
|
+
pyxecm/helper/assoc.py,sha256=bieUr9lkJ0WYohMGsM51wt7OIX_ii4KHaE0cmhRr5TM,6931
|
|
25
|
+
pyxecm/helper/data.py,sha256=WnpTi15ChtMWCLsk0BcZ3ry9ZZDnD4ajrFWmavmNGew,68217
|
|
26
|
+
pyxecm/helper/web.py,sha256=CYhJW4TgyHc2w9nV75YgGJR3fDHeUjQEMkulNI9U3E8,9263
|
|
27
|
+
pyxecm/helper/xml.py,sha256=WNvHI41AKpJnB2h_4gvHg0l0w3WtHlZ3W9q6TV6htYU,31664
|
|
28
|
+
pyxecm-1.6.dist-info/LICENSE,sha256=z5DWWd5cHmQYJnq4BDt1bmVQjuXY1Qsp6y0v5ETCw-s,11360
|
|
29
|
+
pyxecm-1.6.dist-info/METADATA,sha256=dSw3C2KHkoVC_AJjGk-7Mhb9p3Isoa2av9CiLhGlDbI,2130
|
|
30
|
+
pyxecm-1.6.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
31
|
+
pyxecm-1.6.dist-info/top_level.txt,sha256=TGak3_dYN67ugKFbmRxRG1leDyOt0T7dypjdX4Ij1WE,7
|
|
32
|
+
pyxecm-1.6.dist-info/RECORD,,
|
pyxecm-1.5.dist-info/RECORD
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
pyxecm/__init__.py,sha256=f0oWCTOUQrX9JuJZaP4r-5d493lSwvrGksu8xPxg4bI,253
|
|
2
|
-
pyxecm/coreshare.py,sha256=P23gGqnHFFP4akeC5ISSZXNwcNbDTFssXpIIDQdWvfI,95691
|
|
3
|
-
pyxecm/otac.py,sha256=i1-4nljJUedAsz842s4WXH_YjmEC-hZh66zEGhRS5Uw,21684
|
|
4
|
-
pyxecm/otcs.py,sha256=ZJvYOWiRnD_GutI6hM2923gap-xhWWtSG9jVuebE5YI,418633
|
|
5
|
-
pyxecm/otds.py,sha256=Q9ZHs1vQiPz2ZbkubjKUxX2r_Gl5F0NcqrWNXxllk1E,160812
|
|
6
|
-
pyxecm/otiv.py,sha256=nHEBQ9tddtKMiR1yPbGGP-jJiDaQpyoFmZcQFPgw22w,1720
|
|
7
|
-
pyxecm/otmm.py,sha256=pNy5oIk70duAlOEG3e43JxpQMQbCldRL9iD0KBGyUjU,28566
|
|
8
|
-
pyxecm/otpd.py,sha256=zRus7UnYYrwG9tYDPPLxBbGzozATwS07ftYun4kaaV4,12503
|
|
9
|
-
pyxecm/customizer/__init__.py,sha256=g32OUKoJiBYY4q9IMQctKTKq6YhFtv-IAIHcRC0KJu4,330
|
|
10
|
-
pyxecm/customizer/browser_automation.py,sha256=cbUTGBLmyYO7617QfNJCZtFCK0i8-2hfA6QhKSfuKOY,16430
|
|
11
|
-
pyxecm/customizer/customizer.py,sha256=7GHsuq2njG29xL5bLqdYe5eDcw2TpBgZMJOs6X4xKrY,86293
|
|
12
|
-
pyxecm/customizer/k8s.py,sha256=XMoLVQXxJwq51aXaYANwaqniYi7lqNnmVOmEkaqSuQY,36455
|
|
13
|
-
pyxecm/customizer/m365.py,sha256=emZOJX503-i3FWOqVXe26geiz_apFZiI-jWtoWJxE40,184000
|
|
14
|
-
pyxecm/customizer/payload.py,sha256=74n_KpNZ3s6ftDkjMP3fmsSHcrPXDb5gZrPgkcQ4Tiw,765958
|
|
15
|
-
pyxecm/customizer/pht.py,sha256=AxP8v8SbzkBZaxYDJ3Dqr330l29RJwzpkuKNIW46VjM,17348
|
|
16
|
-
pyxecm/customizer/salesforce.py,sha256=j2oqI4uzQdsl52hMMK9OyzL6Z3EUZYnvqEGQ_OscMEY,63787
|
|
17
|
-
pyxecm/customizer/sap.py,sha256=RNrHH0KjBQ10dHXoMaZIEd3EVPC8--4AN7nzy_Iv9k4,5947
|
|
18
|
-
pyxecm/customizer/servicenow.py,sha256=3ytAjLVKbWDL9MmTPPgPe7-bMDN1JLBQSGtkcGil20k,46745
|
|
19
|
-
pyxecm/customizer/successfactors.py,sha256=6hww4tKF_Bm2aLzFMStPuJmKJ4uBqteXwjWDkW0yDHU,38847
|
|
20
|
-
pyxecm/customizer/translate.py,sha256=RxC7O4lxfGaG1nttCm5WI5X2wEM4eEqbVcUtnYns1TQ,3968
|
|
21
|
-
pyxecm/helper/__init__.py,sha256=sScoB5RQAEkzP2LLvR_cRYwC1ARSdvBiv-4JwnJA7Dw,140
|
|
22
|
-
pyxecm/helper/assoc.py,sha256=MKjDgPYnRcuHkDMIvFMtYXiyMWPXpNie6UQrVgV0s-0,6488
|
|
23
|
-
pyxecm/helper/data.py,sha256=__B9FVwXBPpByaRaJ-l348po3dcaBXw4J1jVzQRy608,60308
|
|
24
|
-
pyxecm/helper/web.py,sha256=CYhJW4TgyHc2w9nV75YgGJR3fDHeUjQEMkulNI9U3E8,9263
|
|
25
|
-
pyxecm/helper/xml.py,sha256=SjMzZcFF37p50ESewF83bh5vl1oDOIjbYRLRZNVEeOU,31664
|
|
26
|
-
pyxecm-1.5.dist-info/LICENSE,sha256=z5DWWd5cHmQYJnq4BDt1bmVQjuXY1Qsp6y0v5ETCw-s,11360
|
|
27
|
-
pyxecm-1.5.dist-info/METADATA,sha256=NumUPC4fUYuiZJyN39qnYX1BqOBjUPXxYFPaP3w8N08,2076
|
|
28
|
-
pyxecm-1.5.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
|
|
29
|
-
pyxecm-1.5.dist-info/top_level.txt,sha256=TGak3_dYN67ugKFbmRxRG1leDyOt0T7dypjdX4Ij1WE,7
|
|
30
|
-
pyxecm-1.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|