s3dgraphy 1.6.0.dev52__tar.gz → 1.6.0.dev54__tar.gz
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.
- {s3dgraphy-1.6.0.dev52/src/s3dgraphy.egg-info → s3dgraphy-1.6.0.dev54}/PKG-INFO +2 -2
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/pyproject.toml +2 -2
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/__init__.py +1 -1
- s3dgraphy-1.6.0.dev54/src/s3dgraphy/__main__.py +121 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/api.py +19 -0
- s3dgraphy-1.6.0.dev54/src/s3dgraphy/room_import/__init__.py +64 -0
- s3dgraphy-1.6.0.dev54/src/s3dgraphy/room_import/access.py +368 -0
- s3dgraphy-1.6.0.dev54/src/s3dgraphy/room_import/engine.py +877 -0
- s3dgraphy-1.6.0.dev54/src/s3dgraphy/room_import/errors.py +27 -0
- s3dgraphy-1.6.0.dev54/src/s3dgraphy/room_import/inventory.py +745 -0
- s3dgraphy-1.6.0.dev54/src/s3dgraphy/room_import/node.py +595 -0
- s3dgraphy-1.6.0.dev54/src/s3dgraphy/room_import/pack.py +178 -0
- s3dgraphy-1.6.0.dev54/src/s3dgraphy/room_import/trust.py +142 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54/src/s3dgraphy.egg-info}/PKG-INFO +2 -2
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy.egg-info/SOURCES.txt +13 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy.egg-info/requires.txt +1 -1
- s3dgraphy-1.6.0.dev54/tests/test_room_import.py +527 -0
- s3dgraphy-1.6.0.dev54/tests/test_room_import_access.py +225 -0
- s3dgraphy-1.6.0.dev54/tests/test_room_import_inventory.py +489 -0
- s3dgraphy-1.6.0.dev54/tests/test_room_import_trust.py +57 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_semantic_purity.py +7 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/LICENSE +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/MANIFEST.in +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/README.md +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/setup.cfg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/acquisition_descriptor.schema.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/acquisition_mappings/ercolano.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/acquisition_mappings/fs.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/acquisition_mappings/uri.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/datamodel_translations.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/em.ttl +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/em_document_types.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/em_extractor_types.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/em_palette_icons.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/em_qualia_types.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/em_qualia_types_additions.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/em_state_symbols.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/em_visual_rules.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/hdto_extension.ttl +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/new_qualia_template.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/node_registry.generated.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/outdated_s3dgraphy.ttl +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/outdated_s3dgraphy_nomapping.ttl +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/s3Dgraphy_connections_datamodel.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/s3Dgraphy_connections_datamodel.json.v155.bak +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/s3Dgraphy_node_datamodel.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/ActivityNodeGroup.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/EMNarrative.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/EMNarrative.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/EpochNode.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/ParadataNodeGroup.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/RSF.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/RSF.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/SE.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/SE_old.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/SE_old.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/SF.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/SF.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/TSU.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/US.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/US.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/USD.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/USD.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/USVn.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/USVn.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/USVs.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/USVs.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/UTR.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/VSF.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/VSF.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/author.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/author.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/author_ai.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/author_ai.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/combiner.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/combiner.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/container.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/continuity.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/continuity.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/document.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/document.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/00_transformation.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/01_topographicnetwork.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/02_pointcloud.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/03_mesh.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/04_points.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/05_lines.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/06_polygons.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/07_DEM.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/08_ortophoto.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/09_photos.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/10_laserscanner.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/11_device.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/11_device_computer.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/11_device_drone.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/11_device_gnss.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/11_device_optical.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/11_device_scanner.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/11_device_sensor.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/11_device_station.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/12_gnss_survey.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/13_field_drawing.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/14_recording_sheet.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/15_decimation.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/16_georeferencing.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/17_format_conversion.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/18_classification.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/dtc/19_vectorization.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/embargo.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/embargo.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/extractor.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/extractor.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/gcp_set.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/generic_node.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/geo_position.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/graph.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/license.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/license.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/link.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/narrative.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/narrative.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/play.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/property.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/property.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/proxy.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/registration_transform.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/representation_model.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/representation_model_doc.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/representation_model_sf.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/resource_file.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/semantic_shape.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/serSU.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/serSU.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/serUSD.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/serUSV.png +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/serUSVn.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/serUSVs.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/tileset.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/version_gltf.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/version_mesh.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/version_scene.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/2D/version_tiles.svg +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/3D/RSF.glb +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/3D/SF.glb +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/3D/TSU.glb +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/3D/US.glb +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/3D/USD.glb +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/3D/USVn.glb +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/3D/USVs.glb +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/3D/VSF.glb +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/3D/combiner.glb +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/3D/continuity.glb +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/3D/document.glb +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/3D/extractor.glb +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/3D/property.glb +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/3D/serSU.glb +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/3D/serUSD.glb +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/src/3D/serUSV.glb +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/JSON_config/version_for_cases.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/acquisition/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/acquisition/acquire.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/acquisition/descriptor.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/acquisition/mapping.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/ai_validation.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/annotation/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/annotation/migrate_reading.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/annotation/paradata.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/annotation/reading.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/authorities/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/authorities/resolver.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/authorities/snapshots/LICENSE +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/authorities/snapshots/chronontology.jsonld +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/authorities/snapshots/getty_aat.jsonld +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/authorities/snapshots/getty_tgn.jsonld +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/authorities/snapshots/periodo.jsonld +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/authorities/snapshots/provenance.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/classification.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/container.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/contract/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/contract/connector.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/contract/consumer.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/contract/core.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/contract/reference.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/crdt.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/data/StratiMiner_Extraction_Prompt.md +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/datamodel.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/diagnostics.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/dissemination.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/dtc/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/dtc/capture.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/dtc/corpus.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/dtc/devices.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/dtc/ingest.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/dtc/neighbourhood.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/dtc/residency.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/edges/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/edges/connection_resolver.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/edges/connections_loader.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/edges/edge.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/editorial.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/docx_exporter.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/emjson_exporter.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/graphml/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/graphml/canvas_generator.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/graphml/edge_generator.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/graphml/epoch_generator.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/graphml/graphml_exporter.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/graphml/graphml_patcher.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/graphml/group_node_generator.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/graphml/node_generator.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/graphml/node_registry.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/graphml/palette_resources.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/graphml/paradata_generator.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/graphml/paradata_image_generator.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/graphml/paradata_node_generators.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/graphml/table_node_generator.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/graphml/utils.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/html_exporter.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/ipynb_exporter.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/json_exporter.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/latex_exporter.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/rdf_exporter.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/exporter/unified_xlsx_exporter.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/geometry/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/geometry/aton.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/geometry/gltf.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/geometry/migrate.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/geometry/proxy.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/geometry/reading_glb.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/geometry/store_backed.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/geometry/wkt.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/graph.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/hdto.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/iiif.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/importer/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/importer/base_importer.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/importer/csv_importer.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/importer/emjson_importer.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/importer/fmpxml_importer.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/importer/import_graphml.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/importer/mapped_xlsx_importer.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/importer/metashape_project.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/importer/pyarchinit_importer.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/importer/qualia_importer.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/importer/rdf_importer.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/importer/sheet_header.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/importer/source_text.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/importer/unified_xlsx_importer.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/importer/xlsx_importer.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/importer/xml_importer.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/indices.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/labels.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/language.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/links.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/mappings/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/mappings/authoring.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/mappings/emdb/generic_specialfind_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/mappings/emdb/site_properties_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/mappings/emdb/usm_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/mappings/generic/excel_to_graphml_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/mappings/pyarchinit/pyarchinit_us_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/mappings/registry.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/mappings/source_list/em_sourcelist_it.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/mappings/source_list/source_list_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/mappings/template_emdb_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/mappings/template_pyarchinit_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/merge/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/merge/graph_merger.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/multigraph/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/multigraph/multigraph.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/narrative/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/narrative/bake.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/narrative/generation.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/narrative/query.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/narrative/registry.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/narrative/site_story.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/annotation_region_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/author_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/base_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/combiner_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/document_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/dtc_acquisition_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/dtc_device_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/dtc_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/dtc_process_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/embargo_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/epoch_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/extractor_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/geo_position_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/georeferencing_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/graph_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/group_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/hdt_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/heritage_entity_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/license_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/narrative_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/paradata_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/project_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/property_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/representation_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/resource_file_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/resource_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/semantic_shape_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/stratigraphic_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/study_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/nodes/translation_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/ownership.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/paradata_view.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/photogrammetry/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/photogrammetry/delta.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/project_tree.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/property_source.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/publication.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/rapporti.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/resolvers/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/resolvers/builtin_rules.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/resolvers/property_resolver.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/resources/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/resources/addresses.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/resources/alignment.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/resources/files.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/resources/fs_backend.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/resources/locate.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/resources/minio_backend.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/resources/moved.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/resources/object_store.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/resources/resolver.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/resources/storage_rows.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/resources/tiles3tz.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/resources/versions.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/rights.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/shelf/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/shelf/core.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/spatiotemporal.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/stamp/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/stamp/absorb.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/stamp/emit.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/stamp/hints.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/stamp/identity.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/study.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/_db_handle.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/_legacy_paradata_svgs.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/_workspace.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/conflict_resolver.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/edge_registry.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/graph_ingestor.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/graph_projector.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/graphml_writer.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/group_projector.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/group_store.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/ingest_result.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/paradata_store.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/pyarchinit_pg_importer.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/rapporti.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/uuid7.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/vocab_provider_core.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/vocab_types.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/yed_classifier.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/yed_detector.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/yed_group_walker.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/yed_import_pipeline.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/yed_rapporti_policy.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/sync/yed_table_parser.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/templates/em_data_template.xlsx +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/templates/em_palette_template.graphml +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/temporal/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/temporal/inference_engine.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/tools/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/tools/consumer_drift.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/tools/datamodel_i18n.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/tools/deliverable_report.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/tools/glyph_sheet.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/tools/glyphs_from_svg.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/tools/node_finder.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/tools/sync_node_datamodel.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/tools/wheel_drift.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/transforms/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/transforms/aux_tracking.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/transforms/compact.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/transforms/materialize_continuity.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/translation.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/utils/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/utils/utils.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/utils/visual_layout.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy/zero_hour.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy.egg-info/dependency_links.txt +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/src/s3dgraphy.egg-info/top_level.txt +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_acquisition.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_acquisition_fs.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_add_resource.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_ai_validation_nodes.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_alternative_labels.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_api_surface.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_asset_dtc_protocol.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_asset_versions.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_aton_shapes.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_attach_only.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_authority_projection.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_authority_resolver.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_blend_locator.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_bucket_alignment.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_canonical_document_rename.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_canvas_metadata_import.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_capture_acquisition.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_capture_rdf_class.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_chronology_on_request.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_coating_unit.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_composite_node_name.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_connection_resolver.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_consumer_drift.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_container.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_container_layouts.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_containment_tpq.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_contract.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_contract_consumer.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_convert_command.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_crdt.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_cycle_message_is_cheap.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_datamodel_fingerprint.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_datamodel_i18n.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_deterministic_ids.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_dev29_em_sourcelist.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_dev29_file_set_stamp.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_dev29_graphml_without_a_database.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_dev29_image_set_texturing.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_dev29_not_georeferenced.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_dev29_one_act_n_outputs.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_dev29_ttl_round_trip.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_dev30_decisions.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_devices.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_dissemination_tombstones.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_dove_sta_il_testo.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_dtc_corpus.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_dtc_ingest.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_dtc_neighbourhood.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_dtc_projection.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_dtc_residency.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_edge_outside_graph.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_edge_ui_phrases.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_editorial.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_em_ttl_matches_the_datamodels.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_emjson_no_drawing_keys.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_emjson_roundtrip.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_emjson_schema_version.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_epoch_properties_and_sub_epochs.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_epoch_undated_import.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_explicit_node_type_marker.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_extracted_from_unit.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_filtered_import.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_fmpxml_importer.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_fs_backend.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_functional_units.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_georeference_scene.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_gltf_stitch.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_glyph_paths.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_graph_header_code.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_graph_helpers_indexed.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_graph_indices_alive.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_graph_indices_edges.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_graph_scope_migration.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_hdto_projection.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_hdto_study.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_header_key_aliases.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_i_generi_dei_passi.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_iiif.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_il_modo_d_accesso.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_il_modo_dal_relay.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_il_proprietario_si_legge.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_il_riallineamento.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_importer_edge_hygiene.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_ipynb_exporter.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_issue27_small_points.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_la_lingua_alla_nascita.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_la_lingua_dei_dati.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_la_lingua_nell_op.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_la_riga_d_intestazione.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_latex_exporter.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_le_traduzioni.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_lod_levels.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_lossless_roundtrip.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_mapping_authoring.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_mapping_csv_and_relations.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_masonry_unit.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_material_color.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_merge_conflicts.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_metashape_project.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_migrate_legacy_proxy.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_minio_backend.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_narrative_authorship.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_narrative_bake_docx.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_narrative_figures.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_narrative_generation.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_narrative_mentions.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_narrative_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_narrative_query.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_narrative_scaffolder.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_narrative_site_place.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_narrative_unvalidated_export.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_node_datamodel_registry.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_node_finder.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_node_type_map_integrity.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_one_resolver.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_one_spelling_writers.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_op_vocabulary.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_pg_importer.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_photogrammetry_delta.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_physical_relation_spellings.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_piu_indirizzi.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_promote_keeps_proxy_type.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_promotion.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_property_as_source.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_property_owners.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_proxy_resource.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_proxy_retype.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_psx_locator.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_pyarchinit_tier2.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_qualia_dai_d7_d8.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_rdf_embedding.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_rdf_reverse_edges.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_rdf_roundtrip.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_reading_coords.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_reading_glb.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_reading_migration.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_reading_place.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_reading_rdf.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_recompute_warnings.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_release.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_reproject.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_resource_file_node.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_resource_files_implicit.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_resource_layer.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_resource_representations.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_resource_revision.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_resource_tier.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_reverse_edges.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_rm_container_node_group.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_shelf.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_shelf_facets.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_shelf_hatting.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_shelf_role_uri_table.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_shipped_mappings.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_source_list_mapping.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_source_text.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_spatiotemporal_entities.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_stable_study_code.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_stamp.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_stamp_hints.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_stamp_title_description.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_storage_rows.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_store_backed_geometry.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_stratiminer_api.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_study_metadata.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_tileset_resource.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_ttl_roundtrip.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_unit_definition.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_verifica_provenance.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_version_for.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_visual_assets.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_wheel_drift.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_xlsx_containment_and_unknown_bounds.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_xlsx_importer_graph_init.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_xlsx_source_column.py +0 -0
- {s3dgraphy-1.6.0.dev52 → s3dgraphy-1.6.0.dev54}/tests/test_zero_hour.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: s3dgraphy
|
|
3
|
-
Version: 1.6.0.
|
|
3
|
+
Version: 1.6.0.dev54
|
|
4
4
|
Summary: 3D Stratigraphic Graph Management Library for archaeological and heritage applications
|
|
5
5
|
Author-email: Emanuel Demetrescu <emanuel.demetrescu@cnr.it>
|
|
6
6
|
Maintainer-email: Emanuel Demetrescu <emanuel.demetrescu@cnr.it>
|
|
@@ -35,7 +35,7 @@ Requires-Dist: pandas>=2.0.0
|
|
|
35
35
|
Requires-Dist: lxml>=4.9.0
|
|
36
36
|
Requires-Dist: openpyxl>=3.0.0
|
|
37
37
|
Requires-Dist: networkx>=3.0
|
|
38
|
-
Requires-Dist: dtcstamp>=0.1.
|
|
38
|
+
Requires-Dist: dtcstamp>=0.1.5
|
|
39
39
|
Provides-Extra: rdf
|
|
40
40
|
Requires-Dist: rdflib>=7.0; extra == "rdf"
|
|
41
41
|
Provides-Extra: rdf-embedded
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "s3dgraphy"
|
|
7
|
-
version = "1.6.0.
|
|
7
|
+
version = "1.6.0.dev54"
|
|
8
8
|
description = "3D Stratigraphic Graph Management Library for archaeological and heritage applications"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -56,7 +56,7 @@ dependencies = [
|
|
|
56
56
|
# the four above. It has zero dependencies of its own and is one module, so
|
|
57
57
|
# it can also simply be copied; s3dgraphy depends on it rather than
|
|
58
58
|
# vendoring it, because two copies of a format rule drift.
|
|
59
|
-
"dtcstamp>=0.1.
|
|
59
|
+
"dtcstamp>=0.1.5", # 0.1.1 lacks stamp_description: import s3dgraphy.stamp fails (MICRO-DTCSTAMP-012)
|
|
60
60
|
]
|
|
61
61
|
|
|
62
62
|
[project.urls]
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"""`python -m s3dgraphy <command>` — the library's own commands.
|
|
2
|
+
|
|
3
|
+
python -m s3dgraphy room-import <em.json> --node <url> --room <id>
|
|
4
|
+
[--dry-run] [--pack-tilesets 3tz] …
|
|
5
|
+
|
|
6
|
+
One command for now: the first door of the room importer
|
|
7
|
+
(:mod:`s3dgraphy.room_import`). `--help` on it says the rest.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import argparse
|
|
13
|
+
import json
|
|
14
|
+
import os
|
|
15
|
+
import shlex
|
|
16
|
+
import subprocess
|
|
17
|
+
import sys
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _token(args) -> str:
|
|
21
|
+
if args.token_cmd:
|
|
22
|
+
out = subprocess.run(shlex.split(args.token_cmd), capture_output=True,
|
|
23
|
+
text=True, check=True).stdout
|
|
24
|
+
lines = [l.strip() for l in out.splitlines() if l.strip()]
|
|
25
|
+
return lines[-1] if lines else ""
|
|
26
|
+
if args.token_file:
|
|
27
|
+
with open(os.path.expanduser(args.token_file), encoding="utf-8") as fh:
|
|
28
|
+
return fh.read().strip()
|
|
29
|
+
return (args.token or os.environ.get("EM_TOKEN") or "").strip()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def room_import_main(argv) -> int:
|
|
33
|
+
p = argparse.ArgumentParser(
|
|
34
|
+
prog="python -m s3dgraphy room-import",
|
|
35
|
+
description="Bring an EM study (an em.json and its folder) into a room "
|
|
36
|
+
"of a StratiGraph node: the files go up once, what is outside "
|
|
37
|
+
"the folder stays a reference, the graph is seated last.")
|
|
38
|
+
p.add_argument("em_json", help="the study's em.json")
|
|
39
|
+
p.add_argument("--node", required=True, help="the node's base, e.g. https://em.localhost:8443/em")
|
|
40
|
+
p.add_argument("--room", required=True, help="the room's id")
|
|
41
|
+
p.add_argument("--title", default=None, help="the room's title (default: the study's name)")
|
|
42
|
+
p.add_argument("--base", default=None,
|
|
43
|
+
help="the folder the em.json's relative paths start from "
|
|
44
|
+
"(default: the em.json's folder)")
|
|
45
|
+
p.add_argument("--visibility", default="restricted", choices=("restricted", "public"))
|
|
46
|
+
p.add_argument("--token", default=None, help="an access token (or EM_TOKEN)")
|
|
47
|
+
p.add_argument("--token-file", default=None, help="a file holding the token")
|
|
48
|
+
p.add_argument("--token-cmd", default=None,
|
|
49
|
+
help="a command printing a token (run again when it runs out), "
|
|
50
|
+
"e.g. stratigraph-server/dev-stack/token.sh")
|
|
51
|
+
p.add_argument("--dry-run", action="store_true",
|
|
52
|
+
help="the plan only: what goes up, what the node has, "
|
|
53
|
+
"references, missing. Writes nothing")
|
|
54
|
+
p.add_argument("--pack-tilesets", default=None, choices=("3tz",),
|
|
55
|
+
help="a tileset folder goes up as one canonical .3tz")
|
|
56
|
+
p.add_argument("--journal", default=None, help="the journal (default: beside the em.json)")
|
|
57
|
+
p.add_argument("--work-dir", default=None, help="where packed archives are written")
|
|
58
|
+
p.add_argument("--report-dir", default=None, help="where the report goes (default: beside the journal)")
|
|
59
|
+
p.add_argument("--by-reference", action="store_true",
|
|
60
|
+
help="a personal node: register files by reference (asset-reference) "
|
|
61
|
+
"instead of sending their bytes")
|
|
62
|
+
p.add_argument("--elsewhere", default="host", choices=("host", "reference", "move"),
|
|
63
|
+
help="a file the node keeps at home in ANOTHER room: host it here "
|
|
64
|
+
"without moving it (default), leave it a reference to that "
|
|
65
|
+
"room, or move its home here")
|
|
66
|
+
p.add_argument("--workers", type=int, default=4)
|
|
67
|
+
p.add_argument("--reseed", action="store_true", help="send every operation again")
|
|
68
|
+
p.add_argument("--json", action="store_true", help="print the whole report as JSON")
|
|
69
|
+
args = p.parse_args(argv)
|
|
70
|
+
|
|
71
|
+
from .room_import import room_import
|
|
72
|
+
from .room_import import access
|
|
73
|
+
token = _token(args) or None
|
|
74
|
+
if token and args.token_cmd:
|
|
75
|
+
access.set_renewer(args.node.rstrip("/"), token, lambda: _token(args))
|
|
76
|
+
elif token:
|
|
77
|
+
access.adopt(args.node.rstrip("/"), token)
|
|
78
|
+
report = room_import(args.em_json, node=args.node, room=args.room, title=args.title,
|
|
79
|
+
base_dir=args.base, visibility=args.visibility, token=token,
|
|
80
|
+
dry_run=args.dry_run, pack_tilesets=args.pack_tilesets,
|
|
81
|
+
journal_path=args.journal, work_dir=args.work_dir,
|
|
82
|
+
report_dir=args.report_dir, by_reference=args.by_reference,
|
|
83
|
+
workers=args.workers, reseed=args.reseed,
|
|
84
|
+
elsewhere=args.elsewhere)
|
|
85
|
+
if args.json:
|
|
86
|
+
print(json.dumps(report, ensure_ascii=False, indent=1, default=str))
|
|
87
|
+
elif args.dry_run:
|
|
88
|
+
plan = report["plan"]
|
|
89
|
+
from .room_import.inventory import human_size
|
|
90
|
+
print(f"plan for {args.room} on {args.node}:")
|
|
91
|
+
print(f" {plan['resources']} resources · " + ", ".join(
|
|
92
|
+
f"{g} {n}" for g, n in plan["groups"].items()))
|
|
93
|
+
print(f" to upload: {plan['upload']['files']} file(s), {human_size(plan['upload']['bytes'])}")
|
|
94
|
+
print(f" already on the node: {plan['already']['files']} file(s), "
|
|
95
|
+
f"{human_size(plan['already']['bytes'])}")
|
|
96
|
+
print(f" references: {plan['references']} · missing: {plan['missing']}")
|
|
97
|
+
for t in plan["trees"]:
|
|
98
|
+
print(f" tree {t['name']}: {t['files']} file(s)")
|
|
99
|
+
for pk in report.get("packs") or []:
|
|
100
|
+
print(f" pack: {pk}")
|
|
101
|
+
print(f" {sum(report['requests'].values())} request(s), {report['seconds']} s")
|
|
102
|
+
else:
|
|
103
|
+
print(report["sentence"])
|
|
104
|
+
for f in report.get("report_files") or []:
|
|
105
|
+
print(f" report: {f}")
|
|
106
|
+
return 1 if report.get("failed") else 0
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
COMMANDS = {"room-import": room_import_main}
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def main(argv=None) -> int:
|
|
113
|
+
argv = list(sys.argv[1:] if argv is None else argv)
|
|
114
|
+
if not argv or argv[0] in ("-h", "--help") or argv[0] not in COMMANDS:
|
|
115
|
+
print(__doc__.strip())
|
|
116
|
+
return 0 if (not argv or argv[0] in ("-h", "--help")) else 2
|
|
117
|
+
return COMMANDS[argv[0]](argv[1:])
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
if __name__ == "__main__":
|
|
121
|
+
raise SystemExit(main())
|
|
@@ -3068,6 +3068,25 @@ def resolve_file(entry: Dict[str, Any], **kwargs) -> Dict[str, Any]:
|
|
|
3068
3068
|
return resolve(entry, **kwargs)
|
|
3069
3069
|
|
|
3070
3070
|
|
|
3071
|
+
# ── a study into a room, from a folder (MICRO-ROOM-IMPORT, 15 Oct 2026) ──────
|
|
3072
|
+
def room_import(em_json: str, *, node: str, room: str, title: Optional[str] = None,
|
|
3073
|
+
base_dir: Optional[str] = None, visibility: str = "restricted",
|
|
3074
|
+
token: Optional[str] = None, dry_run: bool = False,
|
|
3075
|
+
pack_tilesets: Optional[str] = None, **kwargs) -> Dict[str, Any]:
|
|
3076
|
+
"""Bring the study of ``em_json`` and every file of its folder into
|
|
3077
|
+
``room`` on ``node``: what is in the folder goes up once (HEAD by sha256
|
|
3078
|
+
first), what is outside stays a reference by digest, the resources become
|
|
3079
|
+
hosted keeping their path, the graph is seated last as operations, then
|
|
3080
|
+
``study-access``. ``dry_run``: the plan only, nothing written.
|
|
3081
|
+
``pack_tilesets="3tz"``: a tileset folder goes up as one canonical
|
|
3082
|
+
``.3tz``. → the report. The one engine of the three doors (the command,
|
|
3083
|
+
EMStudio, EM Tools); see :mod:`s3dgraphy.room_import`."""
|
|
3084
|
+
from .room_import import room_import as _run
|
|
3085
|
+
return _run(em_json, node=node, room=room, title=title, base_dir=base_dir,
|
|
3086
|
+
visibility=visibility, token=token, dry_run=dry_run,
|
|
3087
|
+
pack_tilesets=pack_tilesets, **kwargs)
|
|
3088
|
+
|
|
3089
|
+
|
|
3071
3090
|
# ── S1 · the Storage list and «find moved» (E.D., 11 Oct 2026) ────────────────
|
|
3072
3091
|
def storage_rows(graph: Graph, results: Sequence[Dict[str, Any]],
|
|
3073
3092
|
graph_name: str = "") -> List[Dict[str, Any]]:
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""A study into a room, from a folder: ONE engine, three doors.
|
|
2
|
+
|
|
3
|
+
E.D., 15 Oct 2026: «mi manca un importer secco per i dataset di Extended
|
|
4
|
+
Matrix, con tutti i suoi dati locali». Until today the gesture existed twice —
|
|
5
|
+
«Bring into a room…» in EM Tools (`sync_manager/bring.py`, Python inside
|
|
6
|
+
Blender) and in EMStudio (`seedOpsForContainer` and the inventory, in
|
|
7
|
+
TypeScript) — and the two diverged: different resources seen, different
|
|
8
|
+
resolving, the graph seated first in one and last in the other (the table is
|
|
9
|
+
in the report of MICRO-ROOM-IMPORT). Two implementations of one gesture are two
|
|
10
|
+
behaviours to correct.
|
|
11
|
+
|
|
12
|
+
So: **one engine, here**, pure Python, no Blender, testable with a fake node;
|
|
13
|
+
**three doors** that call it — the command (`python -m s3dgraphy room-import`,
|
|
14
|
+
:func:`s3dgraphy.api.room_import`), EMStudio through its bridge, EM Tools'
|
|
15
|
+
Files and «Bring into a room» (where only the SCENE stays: exporting a model
|
|
16
|
+
from the scene before it goes up, materialising what comes down). It also
|
|
17
|
+
works on a folder nobody ever opened in Blender — a dataset from Zenodo.
|
|
18
|
+
|
|
19
|
+
The parts of EM Tools without `bpy` were MOVED here, not copied
|
|
20
|
+
(`inventory`, `node` ← `asset_upload` + `rooms_list` + `room_access` +
|
|
21
|
+
`handoff`, `access`, `trust`): EM Tools imports them from s3Dgraphy.
|
|
22
|
+
|
|
23
|
+
THE RULES
|
|
24
|
+
|
|
25
|
+
1. **What is in the folder goes up.** What the graph cites outside it
|
|
26
|
+
(`onedrive://`, `smb://`, the NAS, http, `blend://`) becomes a reference by
|
|
27
|
+
digest: its locator and checksum stay, `residency: reference`. **A file
|
|
28
|
+
goes up once**: if the node has it (HEAD by sha256) it is not sent again,
|
|
29
|
+
and a file the study names twice is one upload.
|
|
30
|
+
2. **Restart.** A second run uploads nothing and duplicates nothing: files are
|
|
31
|
+
asked for by digest, the operations are idempotent, and the journal
|
|
32
|
+
(`.em_room_import.json` beside the em.json) remembers what was hashed and
|
|
33
|
+
what was seeded. A cut run starts again where it was.
|
|
34
|
+
3. **The graph is seated last**, as in `bring.py`: the room receives the
|
|
35
|
+
resources already hosted, in one seeding, through `POST …/ops` in parts —
|
|
36
|
+
the same operations `dev-stack/seed_rooms.py` and EMStudio send.
|
|
37
|
+
4. **Stamps travel with their files**: a `<file>.stamp.json` beside a file
|
|
38
|
+
goes up with it (`data.stamp_asset` on the resource).
|
|
39
|
+
5. **The report says everything**: uploaded N (size), already on the node,
|
|
40
|
+
references M, missing K, the room's link — json and md.
|
|
41
|
+
|
|
42
|
+
A hosted resource keeps its path: `data.url` becomes the room's address and
|
|
43
|
+
the old locator stays as a second address of the same bytes (`addresses`); a
|
|
44
|
+
`resource_file` keeps it in `data.path`, as EMStudio writes it. A file at home
|
|
45
|
+
in ANOTHER room of the node (F1, `X-EM-Home-Room`) is not moved without a
|
|
46
|
+
person's yes: it becomes a reference to the room it lives in.
|
|
47
|
+
|
|
48
|
+
A TILESET in a folder (`packaging: directory`, thousands of files) goes up
|
|
49
|
+
file by file, with a list of its members (`members_manifest`, dtcstamp's
|
|
50
|
+
canonical form) — or, with `--pack-tilesets 3tz`, as ONE canonical `.3tz`
|
|
51
|
+
written by dtcstamp (s3Dgraphy stays a reader), a sibling representation
|
|
52
|
+
(`dtc_derived_from` the folder, a DTC step `packing` with its stamp); the
|
|
53
|
+
folder stays as a reference. See :mod:`.pack`.
|
|
54
|
+
|
|
55
|
+
Defaults to confirm (E.D.): the name `room_import` / `room-import`, a new
|
|
56
|
+
room's visibility `restricted`.
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
from .engine import (JOURNAL_NAME, Interrupted, Journal, make_plan, markdown,
|
|
60
|
+
room_import, summarise_plan)
|
|
61
|
+
from .errors import RoomError
|
|
62
|
+
|
|
63
|
+
__all__ = ["JOURNAL_NAME", "Interrupted", "Journal", "RoomError", "make_plan",
|
|
64
|
+
"markdown", "room_import", "summarise_plan"]
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
"""The access to a node, renewed before it runs out — and said when it cannot be.
|
|
2
|
+
|
|
3
|
+
Moved here from EM Tools (`sync_manager/access.py`, 3bfdb93) on 15 Oct 2026
|
|
4
|
+
(MICRO-ROOM-IMPORT). One change: what used to reach into EM Tools' own modules
|
|
5
|
+
after a renewal (`_follow`: the REST session and the per-graph rooms carry the
|
|
6
|
+
new token) is now a hook, `ON_RENEWED`, that EM Tools fills. And a token that
|
|
7
|
+
came from a COMMAND (`set_renewer`: `dev-stack/token.sh`, for the room
|
|
8
|
+
importer run from a shell) is renewed by running it again.
|
|
9
|
+
|
|
10
|
+
Measured on 4 Oct 2026: «Archive this .blend» failed about fifteen minutes after
|
|
11
|
+
entering the room with «could not reach the room: [Errno 32] Broken pipe». The
|
|
12
|
+
node had answered **401** (em-dev-server's log, four times between 13:49:09 and
|
|
13
|
+
13:49:34) while Blender was still sending the file, and the realm says why: the
|
|
14
|
+
`em-tools` client issues access tokens that live **900 s**
|
|
15
|
+
(`access.token.lifespan`, read from Keycloak's admin API). Blender kept only the
|
|
16
|
+
access token, so after fifteen minutes every call was refused — and a refusal
|
|
17
|
+
that arrives before a large body is sent reads, on this side, as a cut pipe.
|
|
18
|
+
|
|
19
|
+
Now the sign-in keeps what the realm gives beside the access token — the refresh
|
|
20
|
+
token, the token endpoint, the client — in memory, like the token itself
|
|
21
|
+
(`room.py`'s rule: never on disk). Every call to a node goes through `urlopen`
|
|
22
|
+
here, which:
|
|
23
|
+
|
|
24
|
+
* **before** the call, renews an access that expires within `SKEW` seconds (more
|
|
25
|
+
for a call that carries a body: the node reads the header first, and a large
|
|
26
|
+
body must not set off on a token about to die);
|
|
27
|
+
* **after** a 401 — or a cut pipe on an access that has expired — renews once and
|
|
28
|
+
sends again, when the body can be sent again;
|
|
29
|
+
* when the realm will not renew (the sign-in session idled out: 30 minutes on
|
|
30
|
+
the dev realm), raises `AccessExpired`, whose sentence says what happened:
|
|
31
|
+
«the access to <node> has expired: sign in again», never «Broken pipe».
|
|
32
|
+
|
|
33
|
+
A token that came from somewhere else (pasted) has no refresh token: it is used
|
|
34
|
+
until it expires, and then the same sentence.
|
|
35
|
+
|
|
36
|
+
Calls carry the token they were given, often a copy taken minutes ago (a
|
|
37
|
+
per-graph room keeps one in `room_session._where`). The header is therefore
|
|
38
|
+
matched by LINEAGE: any token this session ever received for a node is replaced
|
|
39
|
+
by that node's newest one. Stale copies heal at the one place every call
|
|
40
|
+
crosses.
|
|
41
|
+
|
|
42
|
+
Standard library only (it runs inside Blender's Python too).
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
from __future__ import annotations
|
|
46
|
+
|
|
47
|
+
import base64
|
|
48
|
+
import errno
|
|
49
|
+
import json
|
|
50
|
+
import threading
|
|
51
|
+
import time
|
|
52
|
+
import urllib.error
|
|
53
|
+
import urllib.parse
|
|
54
|
+
import urllib.request
|
|
55
|
+
from typing import Any, Callable, Dict, List, Optional
|
|
56
|
+
|
|
57
|
+
from .errors import RoomError
|
|
58
|
+
|
|
59
|
+
#: renew when the access has less than this left (seconds)
|
|
60
|
+
SKEW = 60
|
|
61
|
+
#: …and this much for a call that carries a body
|
|
62
|
+
SKEW_BODY = 180
|
|
63
|
+
|
|
64
|
+
#: base → {token, refresh_token, expires_at, token_endpoint, client_id}
|
|
65
|
+
_creds: Dict[str, Dict[str, Any]] = {}
|
|
66
|
+
#: every token this session received → the base it belongs to
|
|
67
|
+
_lineage: Dict[str, str] = {}
|
|
68
|
+
_lock = threading.RLock()
|
|
69
|
+
|
|
70
|
+
#: the last access that ran out, for the panel's «Sign in again» (base or "")
|
|
71
|
+
EXPIRED = {"base": "", "line": ""}
|
|
72
|
+
|
|
73
|
+
#: what the sentence of an expiry tells the person to do; EM Tools sets its
|
|
74
|
+
#: own (EM ▸ Where you work ▸ Sign in again)
|
|
75
|
+
SIGN_IN_HINT = "sign in again"
|
|
76
|
+
|
|
77
|
+
#: called as `hook(base, new_token)` after every renewal: whoever keeps a copy
|
|
78
|
+
#: of the token (EM Tools' REST session, its per-graph rooms) follows it here
|
|
79
|
+
ON_RENEWED: List[Callable[[str, str], None]] = []
|
|
80
|
+
|
|
81
|
+
#: base → a callable that returns a NEW access token (a command run again)
|
|
82
|
+
_renewers: Dict[str, Callable[[], str]] = {}
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class AccessExpired(RoomError):
|
|
86
|
+
"""The access to a node ran out and could not be renewed: sign in again."""
|
|
87
|
+
|
|
88
|
+
def __init__(self, base: str, why: str = ""):
|
|
89
|
+
self.base = base
|
|
90
|
+
sentence = (f"the access to {base or 'the node'} has expired: "
|
|
91
|
+
f"{SIGN_IN_HINT}")
|
|
92
|
+
if why:
|
|
93
|
+
sentence += f" — {why}"
|
|
94
|
+
super().__init__(sentence, status=401)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _norm(base: str) -> str:
|
|
98
|
+
return (base or "").strip().rstrip("/")
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def expiry_of(token: str) -> Optional[float]:
|
|
102
|
+
"""The `exp` claim of a JWT, read and not verified (the node verifies)."""
|
|
103
|
+
try:
|
|
104
|
+
part = str(token).split(".")[1]
|
|
105
|
+
claims = json.loads(base64.urlsafe_b64decode(part + "=" * (-len(part) % 4)))
|
|
106
|
+
exp = claims.get("exp")
|
|
107
|
+
return float(exp) if exp is not None else None
|
|
108
|
+
except Exception: # noqa: BLE001 — an opaque token: no expiry to read
|
|
109
|
+
return None
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def subject_of(token: str) -> str:
|
|
113
|
+
"""Who a JWT is about (`sub`, else the name), read and not verified."""
|
|
114
|
+
try:
|
|
115
|
+
part = str(token).split(".")[1]
|
|
116
|
+
claims = json.loads(base64.urlsafe_b64decode(part + "=" * (-len(part) % 4)))
|
|
117
|
+
return str(claims.get("sub") or claims.get("preferred_username") or "")
|
|
118
|
+
except Exception: # noqa: BLE001 — an opaque token: no subject to read
|
|
119
|
+
return ""
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def _life_of(token: str) -> Optional[float]:
|
|
123
|
+
"""How long the realm let this access live (`exp - iat`), when it says."""
|
|
124
|
+
try:
|
|
125
|
+
part = str(token).split(".")[1]
|
|
126
|
+
claims = json.loads(base64.urlsafe_b64decode(part + "=" * (-len(part) % 4)))
|
|
127
|
+
return float(claims["exp"]) - float(claims["iat"])
|
|
128
|
+
except Exception: # noqa: BLE001
|
|
129
|
+
return None
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def remember(base: str, token: str, *, refresh_token: str = "",
|
|
133
|
+
expires_in: Optional[float] = None, token_endpoint: str = "",
|
|
134
|
+
client_id: str = "") -> None:
|
|
135
|
+
"""Keep what a sign-in returned, in memory, for `base`."""
|
|
136
|
+
if not token:
|
|
137
|
+
return
|
|
138
|
+
base = _norm(base)
|
|
139
|
+
expires_at = (time.time() + float(expires_in)) if expires_in else expiry_of(token)
|
|
140
|
+
life = float(expires_in) if expires_in else _life_of(token)
|
|
141
|
+
with _lock:
|
|
142
|
+
old = _creds.get(base) or {}
|
|
143
|
+
_creds[base] = {
|
|
144
|
+
"token": token,
|
|
145
|
+
"refresh_token": refresh_token or "",
|
|
146
|
+
"expires_at": expires_at,
|
|
147
|
+
"life": life,
|
|
148
|
+
"token_endpoint": token_endpoint or old.get("token_endpoint") or "",
|
|
149
|
+
"client_id": client_id or old.get("client_id") or "",
|
|
150
|
+
}
|
|
151
|
+
_lineage[token] = base
|
|
152
|
+
if EXPIRED["base"] == base:
|
|
153
|
+
EXPIRED.update({"base": "", "line": ""})
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def adopt(base: str, token: Optional[str]) -> None:
|
|
157
|
+
"""A token that reached the session another way (pasted, a link): known by
|
|
158
|
+
its base, so a refusal can be said as an expiry. No refresh token."""
|
|
159
|
+
if not token:
|
|
160
|
+
return
|
|
161
|
+
base = _norm(base)
|
|
162
|
+
with _lock:
|
|
163
|
+
if token in _lineage:
|
|
164
|
+
return
|
|
165
|
+
held = (_creds.get(base) or {}).get("token")
|
|
166
|
+
if held and subject_of(held) != subject_of(token):
|
|
167
|
+
# ANOTHER PERSON on the same node: a lineage of its own. Measured
|
|
168
|
+
# (5 Oct 2026, the room list smoke): the viewer's pasted token
|
|
169
|
+
# joined dev's lineage, and `fresh` handed every call dev's token
|
|
170
|
+
# — the node answered as dev to a viewer
|
|
171
|
+
for t in [t for t, bb in _lineage.items() if bb == base]:
|
|
172
|
+
_lineage.pop(t, None)
|
|
173
|
+
_creds.pop(base, None)
|
|
174
|
+
_lineage[token] = base
|
|
175
|
+
if base not in _creds:
|
|
176
|
+
_creds[base] = {"token": token, "refresh_token": "",
|
|
177
|
+
"expires_at": expiry_of(token), "life": _life_of(token),
|
|
178
|
+
"token_endpoint": "", "client_id": ""}
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def set_renewer(base: str, token: str, renewer: Callable[[], str]) -> None:
|
|
182
|
+
"""`token` for `base`, renewed by calling `renewer()` — a token that came
|
|
183
|
+
from a command (`dev-stack/token.sh`) is renewed by running it again. The
|
|
184
|
+
expiry is read from the token itself."""
|
|
185
|
+
adopt(base, token)
|
|
186
|
+
with _lock:
|
|
187
|
+
_renewers[_norm(base)] = renewer
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def forget(base: Optional[str] = None) -> None:
|
|
191
|
+
"""Drop what is kept for `base` (every base when None)."""
|
|
192
|
+
with _lock:
|
|
193
|
+
for b in ([_norm(base)] if base else list(_creds)):
|
|
194
|
+
_creds.pop(b, None)
|
|
195
|
+
_renewers.pop(b, None)
|
|
196
|
+
for t in [t for t, bb in _lineage.items() if bb == b]:
|
|
197
|
+
_lineage.pop(t, None)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def base_of(token: Optional[str]) -> Optional[str]:
|
|
201
|
+
return _lineage.get(token or "")
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def _left(cred: Dict[str, Any]) -> Optional[float]:
|
|
205
|
+
exp = cred.get("expires_at")
|
|
206
|
+
return None if exp is None else exp - time.time()
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def _post_form(url: str, fields: Dict[str, str], timeout: float = 30.0) -> Dict[str, Any]:
|
|
210
|
+
from .trust import urlopen as _open
|
|
211
|
+
request = urllib.request.Request(
|
|
212
|
+
url, data=urllib.parse.urlencode(fields).encode(), method="POST",
|
|
213
|
+
headers={"Content-Type": "application/x-www-form-urlencoded"})
|
|
214
|
+
with _open(request, timeout=timeout) as answer:
|
|
215
|
+
return json.loads(answer.read() or b"{}")
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def renew(base: str) -> str:
|
|
219
|
+
"""A new access for `base` through its refresh token → the new token.
|
|
220
|
+
|
|
221
|
+
Raises `AccessExpired` with the reason when there is nothing to renew with,
|
|
222
|
+
or the realm refuses (the sign-in session idled out)."""
|
|
223
|
+
base = _norm(base)
|
|
224
|
+
with _lock:
|
|
225
|
+
cred = dict(_creds.get(base) or {})
|
|
226
|
+
renewer = _renewers.get(base)
|
|
227
|
+
if renewer is not None and not cred.get("refresh_token"):
|
|
228
|
+
try:
|
|
229
|
+
token = str(renewer() or "").strip()
|
|
230
|
+
except Exception as exc: # noqa: BLE001 — the command's own failure
|
|
231
|
+
raise _expired(base, f"the command that gives the access failed: {exc}") from exc
|
|
232
|
+
if not token:
|
|
233
|
+
raise _expired(base, "the command that gives the access printed nothing")
|
|
234
|
+
with _lock:
|
|
235
|
+
_creds[base] = {"token": token, "refresh_token": "",
|
|
236
|
+
"expires_at": expiry_of(token), "life": _life_of(token),
|
|
237
|
+
"token_endpoint": "", "client_id": ""}
|
|
238
|
+
_lineage[token] = base
|
|
239
|
+
_follow(base, token)
|
|
240
|
+
return token
|
|
241
|
+
if not cred.get("refresh_token") or not cred.get("token_endpoint"):
|
|
242
|
+
raise _expired(base, "this access cannot be renewed from here")
|
|
243
|
+
try:
|
|
244
|
+
payload = _post_form(cred["token_endpoint"], {
|
|
245
|
+
"grant_type": "refresh_token",
|
|
246
|
+
"refresh_token": cred["refresh_token"],
|
|
247
|
+
"client_id": cred.get("client_id") or "",
|
|
248
|
+
# NO client_secret: a public client
|
|
249
|
+
})
|
|
250
|
+
except urllib.error.HTTPError as exc:
|
|
251
|
+
detail = ""
|
|
252
|
+
try:
|
|
253
|
+
detail = json.loads(exc.read() or b"{}").get("error_description") or ""
|
|
254
|
+
except Exception: # noqa: BLE001
|
|
255
|
+
pass
|
|
256
|
+
raise _expired(base, f"the realm would not renew it ({exc.code}"
|
|
257
|
+
+ (f": {detail}" if detail else "") + ")") from exc
|
|
258
|
+
except (urllib.error.URLError, OSError, ValueError) as exc:
|
|
259
|
+
raise RoomError(f"could not reach the sign-in of {base} to renew the "
|
|
260
|
+
f"access: {getattr(exc, 'reason', exc)}") from exc
|
|
261
|
+
token = str(payload.get("access_token") or "")
|
|
262
|
+
if not token:
|
|
263
|
+
raise _expired(base, "the realm returned no access token")
|
|
264
|
+
remember(base, token,
|
|
265
|
+
refresh_token=str(payload.get("refresh_token") or cred["refresh_token"]),
|
|
266
|
+
expires_in=payload.get("expires_in"),
|
|
267
|
+
token_endpoint=cred["token_endpoint"], client_id=cred.get("client_id", ""))
|
|
268
|
+
_follow(base, token)
|
|
269
|
+
print(f"[EM access] renewed the access to {base}")
|
|
270
|
+
return token
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def _expired(base: str, why: str) -> AccessExpired:
|
|
274
|
+
exc = AccessExpired(base, why)
|
|
275
|
+
EXPIRED.update({"base": base, "line": str(exc)})
|
|
276
|
+
return exc
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
def _follow(base: str, token: str) -> None:
|
|
280
|
+
"""Whoever keeps a copy of the token follows it (`ON_RENEWED`)."""
|
|
281
|
+
for hook in list(ON_RENEWED):
|
|
282
|
+
try:
|
|
283
|
+
hook(base, token)
|
|
284
|
+
except Exception: # noqa: BLE001 — one follower's trouble is its own
|
|
285
|
+
pass
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def fresh(token: Optional[str], *, margin: float = SKEW) -> Optional[str]:
|
|
289
|
+
"""The newest token of `token`'s lineage, renewed when it has less than
|
|
290
|
+
`margin` seconds left. A token this session does not know is returned as is."""
|
|
291
|
+
base = base_of(token)
|
|
292
|
+
if not token or base is None:
|
|
293
|
+
return token
|
|
294
|
+
with _lock:
|
|
295
|
+
cred = dict(_creds.get(base) or {})
|
|
296
|
+
current = cred.get("token") or token
|
|
297
|
+
left = _left(cred)
|
|
298
|
+
life = cred.get("life")
|
|
299
|
+
if life:
|
|
300
|
+
# an access that lives less than the margin would be renewed at every
|
|
301
|
+
# call (measured with a 60 s access: 195 renewals in one bring)
|
|
302
|
+
margin = min(margin, life / 4)
|
|
303
|
+
if left is not None and left < margin:
|
|
304
|
+
if cred.get("refresh_token") or base in _renewers:
|
|
305
|
+
return renew(base)
|
|
306
|
+
if left <= 0:
|
|
307
|
+
raise _expired(base, "")
|
|
308
|
+
return current
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
def _bearer(request) -> Optional[str]:
|
|
312
|
+
value = request.get_header("Authorization") or ""
|
|
313
|
+
return value[7:].strip() if value.lower().startswith("bearer ") else None
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def _resendable(request) -> bool:
|
|
317
|
+
data = request.data
|
|
318
|
+
return data is None or isinstance(data, (bytes, bytearray))
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def _cut(exc: BaseException) -> bool:
|
|
322
|
+
"""A pipe cut or a connection reset — what a 401 before a body looks like."""
|
|
323
|
+
reason = getattr(exc, "reason", exc)
|
|
324
|
+
code = getattr(reason, "errno", None)
|
|
325
|
+
return code in (errno.EPIPE, errno.ECONNRESET) or isinstance(
|
|
326
|
+
reason, (BrokenPipeError, ConnectionResetError))
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
def urlopen(request, timeout: Optional[float] = None):
|
|
330
|
+
"""`urllib.request.urlopen` for a call to a node — TLS through `trust`, the
|
|
331
|
+
access renewed before it runs out and once more after a refusal."""
|
|
332
|
+
from .trust import urlopen as _open
|
|
333
|
+
if isinstance(request, str):
|
|
334
|
+
request = urllib.request.Request(request)
|
|
335
|
+
token = _bearer(request)
|
|
336
|
+
base = base_of(token)
|
|
337
|
+
if token and base is not None:
|
|
338
|
+
margin = SKEW_BODY if request.data is not None else SKEW
|
|
339
|
+
current = fresh(token, margin=margin)
|
|
340
|
+
if current and current != token:
|
|
341
|
+
request.add_header("Authorization", f"Bearer {current}")
|
|
342
|
+
token = current
|
|
343
|
+
try:
|
|
344
|
+
return _open(request, timeout=timeout)
|
|
345
|
+
except urllib.error.HTTPError as exc:
|
|
346
|
+
if exc.code != 401 or base is None:
|
|
347
|
+
raise
|
|
348
|
+
except (urllib.error.URLError, OSError) as exc:
|
|
349
|
+
if base is None or not _cut(exc):
|
|
350
|
+
raise
|
|
351
|
+
with _lock:
|
|
352
|
+
left = _left(_creds.get(base) or {})
|
|
353
|
+
if left is None or left > 0:
|
|
354
|
+
raise # a cut, not an expiry: the caller says it
|
|
355
|
+
# 401, or a cut on an access that ran out: renew once and send again
|
|
356
|
+
token = renew(base)
|
|
357
|
+
if not _resendable(request):
|
|
358
|
+
# a streamed body cannot be read twice: the access is renewed, the
|
|
359
|
+
# gesture is the person's to repeat
|
|
360
|
+
raise RoomError(f"the access to {base} ran out during the call and has "
|
|
361
|
+
f"been renewed: press the button again", status=401)
|
|
362
|
+
request.add_header("Authorization", f"Bearer {token}")
|
|
363
|
+
try:
|
|
364
|
+
return _open(request, timeout=timeout)
|
|
365
|
+
except urllib.error.HTTPError as exc:
|
|
366
|
+
if exc.code == 401:
|
|
367
|
+
raise _expired(base, "the node refused the renewed access too") from exc
|
|
368
|
+
raise
|