exonware-xwsystem 0.1.0.1__py3-none-any.whl → 0.1.0.4__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.
- exonware/__init__.py +2 -1
- exonware/conf.py +2 -2
- exonware/xwsystem/__init__.py +115 -43
- exonware/xwsystem/base.py +30 -0
- exonware/xwsystem/caching/__init__.py +39 -13
- exonware/xwsystem/caching/base.py +24 -6
- exonware/xwsystem/caching/bloom_cache.py +2 -2
- exonware/xwsystem/caching/cache_manager.py +2 -1
- exonware/xwsystem/caching/conditional.py +2 -2
- exonware/xwsystem/caching/contracts.py +85 -139
- exonware/xwsystem/caching/decorators.py +6 -19
- exonware/xwsystem/caching/defs.py +2 -1
- exonware/xwsystem/caching/disk_cache.py +2 -1
- exonware/xwsystem/caching/distributed.py +2 -1
- exonware/xwsystem/caching/errors.py +2 -1
- exonware/xwsystem/caching/events.py +110 -27
- exonware/xwsystem/caching/eviction_strategies.py +2 -2
- exonware/xwsystem/caching/external_caching_python.py +701 -0
- exonware/xwsystem/caching/facade.py +253 -0
- exonware/xwsystem/caching/factory.py +300 -0
- exonware/xwsystem/caching/fluent.py +14 -12
- exonware/xwsystem/caching/integrity.py +21 -6
- exonware/xwsystem/caching/lfu_cache.py +2 -1
- exonware/xwsystem/caching/lfu_optimized.py +18 -6
- exonware/xwsystem/caching/lru_cache.py +7 -4
- exonware/xwsystem/caching/memory_bounded.py +2 -2
- exonware/xwsystem/caching/metrics_exporter.py +2 -2
- exonware/xwsystem/caching/observable_cache.py +2 -2
- exonware/xwsystem/caching/pluggable_cache.py +2 -2
- exonware/xwsystem/caching/rate_limiter.py +2 -2
- exonware/xwsystem/caching/read_through.py +2 -2
- exonware/xwsystem/caching/secure_cache.py +81 -28
- exonware/xwsystem/caching/serializable.py +9 -7
- exonware/xwsystem/caching/stats.py +2 -2
- exonware/xwsystem/caching/tagging.py +2 -2
- exonware/xwsystem/caching/ttl_cache.py +4 -3
- exonware/xwsystem/caching/two_tier_cache.py +6 -3
- exonware/xwsystem/caching/utils.py +30 -12
- exonware/xwsystem/caching/validation.py +2 -2
- exonware/xwsystem/caching/warming.py +6 -3
- exonware/xwsystem/caching/write_behind.py +15 -6
- exonware/xwsystem/config/__init__.py +11 -17
- exonware/xwsystem/config/base.py +5 -5
- exonware/xwsystem/config/contracts.py +93 -153
- exonware/xwsystem/config/defaults.py +3 -2
- exonware/xwsystem/config/defs.py +3 -2
- exonware/xwsystem/config/errors.py +2 -5
- exonware/xwsystem/config/logging.py +12 -8
- exonware/xwsystem/config/logging_setup.py +3 -2
- exonware/xwsystem/config/performance.py +1 -46
- exonware/xwsystem/config/performance_modes.py +9 -8
- exonware/xwsystem/config/version_manager.py +1 -0
- exonware/xwsystem/config.py +27 -0
- exonware/xwsystem/console/__init__.py +53 -0
- exonware/xwsystem/console/base.py +133 -0
- exonware/xwsystem/console/cli/__init__.py +61 -0
- exonware/xwsystem/{cli → console/cli}/args.py +27 -24
- exonware/xwsystem/{cli → console/cli}/base.py +18 -87
- exonware/xwsystem/{cli → console/cli}/colors.py +15 -13
- exonware/xwsystem/console/cli/console.py +98 -0
- exonware/xwsystem/{cli → console/cli}/contracts.py +51 -69
- exonware/xwsystem/console/cli/defs.py +87 -0
- exonware/xwsystem/console/cli/encoding.py +69 -0
- exonware/xwsystem/{cli → console/cli}/errors.py +8 -3
- exonware/xwsystem/console/cli/event_logger.py +166 -0
- exonware/xwsystem/{cli → console/cli}/progress.py +25 -21
- exonware/xwsystem/{cli → console/cli}/prompts.py +3 -2
- exonware/xwsystem/{cli → console/cli}/tables.py +27 -24
- exonware/xwsystem/console/contracts.py +113 -0
- exonware/xwsystem/console/defs.py +154 -0
- exonware/xwsystem/console/errors.py +34 -0
- exonware/xwsystem/console/event_logger.py +385 -0
- exonware/xwsystem/console/writer.py +132 -0
- exonware/xwsystem/contracts.py +28 -0
- exonware/xwsystem/data_structures/__init__.py +23 -0
- exonware/xwsystem/data_structures/trie.py +34 -0
- exonware/xwsystem/data_structures/union_find.py +144 -0
- exonware/xwsystem/defs.py +17 -0
- exonware/xwsystem/errors.py +23 -0
- exonware/xwsystem/facade.py +62 -0
- exonware/xwsystem/http_client/__init__.py +22 -1
- exonware/xwsystem/http_client/advanced_client.py +8 -5
- exonware/xwsystem/http_client/base.py +3 -2
- exonware/xwsystem/http_client/client.py +7 -4
- exonware/xwsystem/http_client/contracts.py +42 -56
- exonware/xwsystem/http_client/defs.py +2 -1
- exonware/xwsystem/http_client/errors.py +2 -1
- exonware/xwsystem/http_client/facade.py +156 -0
- exonware/xwsystem/io/__init__.py +22 -3
- exonware/xwsystem/io/archive/__init__.py +8 -2
- exonware/xwsystem/io/archive/archive.py +1 -1
- exonware/xwsystem/io/archive/archive_files.py +4 -7
- exonware/xwsystem/io/archive/archivers.py +120 -10
- exonware/xwsystem/io/archive/base.py +4 -5
- exonware/xwsystem/io/archive/codec_integration.py +1 -2
- exonware/xwsystem/io/archive/compression.py +1 -2
- exonware/xwsystem/io/archive/facade.py +263 -0
- exonware/xwsystem/io/archive/formats/__init__.py +2 -3
- exonware/xwsystem/io/archive/formats/brotli_format.py +20 -7
- exonware/xwsystem/io/archive/formats/lz4_format.py +20 -7
- exonware/xwsystem/io/archive/formats/rar.py +11 -5
- exonware/xwsystem/io/archive/formats/sevenzip.py +12 -6
- exonware/xwsystem/io/archive/formats/squashfs_format.py +1 -2
- exonware/xwsystem/io/archive/formats/tar.py +52 -7
- exonware/xwsystem/io/archive/formats/wim_format.py +11 -5
- exonware/xwsystem/io/archive/formats/zip.py +1 -2
- exonware/xwsystem/io/archive/formats/zpaq_format.py +1 -2
- exonware/xwsystem/io/archive/formats/zstandard.py +20 -7
- exonware/xwsystem/io/base.py +119 -115
- exonware/xwsystem/io/codec/__init__.py +4 -2
- exonware/xwsystem/io/codec/base.py +19 -13
- exonware/xwsystem/io/codec/contracts.py +59 -2
- exonware/xwsystem/io/codec/registry.py +67 -21
- exonware/xwsystem/io/common/__init__.py +1 -1
- exonware/xwsystem/io/common/atomic.py +29 -16
- exonware/xwsystem/io/common/base.py +11 -10
- exonware/xwsystem/io/common/lock.py +6 -5
- exonware/xwsystem/io/common/path_manager.py +2 -1
- exonware/xwsystem/io/common/watcher.py +1 -2
- exonware/xwsystem/io/contracts.py +301 -433
- exonware/xwsystem/io/contracts_1.py +1180 -0
- exonware/xwsystem/io/data_operations.py +19 -20
- exonware/xwsystem/io/defs.py +4 -3
- exonware/xwsystem/io/errors.py +3 -2
- exonware/xwsystem/io/facade.py +87 -61
- exonware/xwsystem/io/file/__init__.py +1 -1
- exonware/xwsystem/io/file/base.py +8 -9
- exonware/xwsystem/io/file/conversion.py +2 -3
- exonware/xwsystem/io/file/file.py +61 -18
- exonware/xwsystem/io/file/paged_source.py +8 -8
- exonware/xwsystem/io/file/paging/__init__.py +1 -2
- exonware/xwsystem/io/file/paging/byte_paging.py +4 -5
- exonware/xwsystem/io/file/paging/line_paging.py +2 -3
- exonware/xwsystem/io/file/paging/record_paging.py +2 -3
- exonware/xwsystem/io/file/paging/registry.py +1 -2
- exonware/xwsystem/io/file/source.py +13 -17
- exonware/xwsystem/io/filesystem/__init__.py +1 -1
- exonware/xwsystem/io/filesystem/base.py +1 -2
- exonware/xwsystem/io/filesystem/local.py +3 -4
- exonware/xwsystem/io/folder/__init__.py +1 -1
- exonware/xwsystem/io/folder/base.py +1 -2
- exonware/xwsystem/io/folder/folder.py +16 -7
- exonware/xwsystem/io/indexing/__init__.py +14 -0
- exonware/xwsystem/io/indexing/facade.py +443 -0
- exonware/xwsystem/io/path_parser.py +98 -0
- exonware/xwsystem/io/serialization/__init__.py +21 -3
- exonware/xwsystem/io/serialization/auto_serializer.py +146 -20
- exonware/xwsystem/io/serialization/base.py +84 -34
- exonware/xwsystem/io/serialization/contracts.py +50 -73
- exonware/xwsystem/io/serialization/defs.py +2 -1
- exonware/xwsystem/io/serialization/errors.py +2 -1
- exonware/xwsystem/io/serialization/flyweight.py +154 -7
- exonware/xwsystem/io/serialization/format_detector.py +15 -14
- exonware/xwsystem/io/serialization/formats/__init__.py +8 -5
- exonware/xwsystem/io/serialization/formats/binary/bson.py +15 -6
- exonware/xwsystem/io/serialization/formats/binary/cbor.py +5 -5
- exonware/xwsystem/io/serialization/formats/binary/marshal.py +5 -5
- exonware/xwsystem/io/serialization/formats/binary/msgpack.py +5 -5
- exonware/xwsystem/io/serialization/formats/binary/pickle.py +5 -5
- exonware/xwsystem/io/serialization/formats/binary/plistlib.py +5 -5
- exonware/xwsystem/io/serialization/formats/database/dbm.py +7 -7
- exonware/xwsystem/io/serialization/formats/database/shelve.py +7 -7
- exonware/xwsystem/io/serialization/formats/database/sqlite3.py +7 -7
- exonware/xwsystem/io/serialization/formats/tabular/__init__.py +27 -0
- exonware/xwsystem/io/serialization/formats/tabular/base.py +89 -0
- exonware/xwsystem/io/serialization/formats/tabular/csv.py +319 -0
- exonware/xwsystem/io/serialization/formats/tabular/df.py +249 -0
- exonware/xwsystem/io/serialization/formats/tabular/excel.py +291 -0
- exonware/xwsystem/io/serialization/formats/tabular/googlesheets.py +374 -0
- exonware/xwsystem/io/serialization/formats/text/__init__.py +1 -1
- exonware/xwsystem/io/serialization/formats/text/append_only_log.py +5 -7
- exonware/xwsystem/io/serialization/formats/text/configparser.py +5 -5
- exonware/xwsystem/io/serialization/formats/text/csv.py +7 -5
- exonware/xwsystem/io/serialization/formats/text/formdata.py +5 -5
- exonware/xwsystem/io/serialization/formats/text/json.py +27 -18
- exonware/xwsystem/io/serialization/formats/text/json5.py +8 -4
- exonware/xwsystem/io/serialization/formats/text/jsonlines.py +18 -14
- exonware/xwsystem/io/serialization/formats/text/multipart.py +5 -5
- exonware/xwsystem/io/serialization/formats/text/toml.py +8 -6
- exonware/xwsystem/io/serialization/formats/text/xml.py +25 -20
- exonware/xwsystem/io/serialization/formats/text/yaml.py +8 -6
- exonware/xwsystem/io/serialization/parsers/__init__.py +3 -2
- exonware/xwsystem/io/serialization/parsers/base.py +6 -5
- exonware/xwsystem/io/serialization/parsers/hybrid_parser.py +7 -6
- exonware/xwsystem/io/serialization/parsers/msgspec_parser.py +10 -7
- exonware/xwsystem/io/serialization/parsers/orjson_direct_parser.py +7 -6
- exonware/xwsystem/io/serialization/parsers/orjson_parser.py +11 -8
- exonware/xwsystem/io/serialization/parsers/pysimdjson_parser.py +13 -9
- exonware/xwsystem/io/serialization/parsers/rapidjson_parser.py +10 -7
- exonware/xwsystem/io/serialization/parsers/registry.py +11 -10
- exonware/xwsystem/io/serialization/parsers/standard.py +7 -6
- exonware/xwsystem/io/serialization/parsers/ujson_parser.py +10 -7
- exonware/xwsystem/io/serialization/registry.py +4 -4
- exonware/xwsystem/io/serialization/serializer.py +168 -79
- exonware/xwsystem/io/serialization/universal_options.py +367 -0
- exonware/xwsystem/io/serialization/utils/__init__.py +1 -2
- exonware/xwsystem/io/serialization/utils/path_ops.py +5 -6
- exonware/xwsystem/io/source_reader.py +223 -0
- exonware/xwsystem/io/stream/__init__.py +1 -1
- exonware/xwsystem/io/stream/async_operations.py +61 -14
- exonware/xwsystem/io/stream/base.py +1 -2
- exonware/xwsystem/io/stream/codec_io.py +6 -7
- exonware/xwsystem/ipc/__init__.py +1 -0
- exonware/xwsystem/ipc/async_fabric.py +4 -4
- exonware/xwsystem/ipc/base.py +6 -5
- exonware/xwsystem/ipc/contracts.py +41 -66
- exonware/xwsystem/ipc/defs.py +2 -1
- exonware/xwsystem/ipc/errors.py +2 -1
- exonware/xwsystem/ipc/message_queue.py +5 -2
- exonware/xwsystem/ipc/pipes.py +70 -34
- exonware/xwsystem/ipc/process_manager.py +7 -5
- exonware/xwsystem/ipc/process_pool.py +6 -5
- exonware/xwsystem/ipc/shared_memory.py +64 -11
- exonware/xwsystem/monitoring/__init__.py +7 -0
- exonware/xwsystem/monitoring/base.py +11 -8
- exonware/xwsystem/monitoring/contracts.py +86 -144
- exonware/xwsystem/monitoring/defs.py +2 -1
- exonware/xwsystem/monitoring/error_recovery.py +16 -3
- exonware/xwsystem/monitoring/errors.py +2 -1
- exonware/xwsystem/monitoring/facade.py +183 -0
- exonware/xwsystem/monitoring/memory_monitor.py +1 -0
- exonware/xwsystem/monitoring/metrics.py +1 -0
- exonware/xwsystem/monitoring/performance_manager_generic.py +7 -7
- exonware/xwsystem/monitoring/performance_monitor.py +1 -0
- exonware/xwsystem/monitoring/performance_validator.py +1 -0
- exonware/xwsystem/monitoring/system_monitor.py +6 -5
- exonware/xwsystem/monitoring/tracing.py +18 -16
- exonware/xwsystem/monitoring/tracker.py +2 -1
- exonware/xwsystem/operations/__init__.py +5 -50
- exonware/xwsystem/operations/base.py +3 -44
- exonware/xwsystem/operations/contracts.py +25 -15
- exonware/xwsystem/operations/defs.py +1 -1
- exonware/xwsystem/operations/diff.py +5 -4
- exonware/xwsystem/operations/errors.py +1 -1
- exonware/xwsystem/operations/merge.py +6 -4
- exonware/xwsystem/operations/patch.py +5 -4
- exonware/xwsystem/patterns/__init__.py +1 -0
- exonware/xwsystem/patterns/base.py +2 -1
- exonware/xwsystem/patterns/context_manager.py +2 -1
- exonware/xwsystem/patterns/contracts.py +215 -256
- exonware/xwsystem/patterns/defs.py +2 -1
- exonware/xwsystem/patterns/dynamic_facade.py +1 -0
- exonware/xwsystem/patterns/errors.py +2 -4
- exonware/xwsystem/patterns/handler_factory.py +2 -3
- exonware/xwsystem/patterns/import_registry.py +1 -0
- exonware/xwsystem/patterns/object_pool.py +1 -0
- exonware/xwsystem/patterns/registry.py +4 -43
- exonware/xwsystem/plugins/__init__.py +2 -1
- exonware/xwsystem/plugins/base.py +6 -5
- exonware/xwsystem/plugins/contracts.py +94 -158
- exonware/xwsystem/plugins/defs.py +2 -1
- exonware/xwsystem/plugins/errors.py +2 -1
- exonware/xwsystem/py.typed +3 -0
- exonware/xwsystem/query/__init__.py +36 -0
- exonware/xwsystem/query/contracts.py +56 -0
- exonware/xwsystem/query/errors.py +22 -0
- exonware/xwsystem/query/registry.py +128 -0
- exonware/xwsystem/runtime/__init__.py +2 -1
- exonware/xwsystem/runtime/base.py +4 -3
- exonware/xwsystem/runtime/contracts.py +39 -60
- exonware/xwsystem/runtime/defs.py +2 -1
- exonware/xwsystem/runtime/env.py +11 -9
- exonware/xwsystem/runtime/errors.py +2 -1
- exonware/xwsystem/runtime/reflection.py +3 -2
- exonware/xwsystem/security/__init__.py +68 -11
- exonware/xwsystem/security/audit.py +167 -0
- exonware/xwsystem/security/base.py +121 -24
- exonware/xwsystem/security/contracts.py +91 -146
- exonware/xwsystem/security/crypto.py +17 -16
- exonware/xwsystem/security/defs.py +2 -1
- exonware/xwsystem/security/errors.py +2 -1
- exonware/xwsystem/security/facade.py +321 -0
- exonware/xwsystem/security/file_security.py +330 -0
- exonware/xwsystem/security/hazmat.py +11 -8
- exonware/xwsystem/security/monitor.py +372 -0
- exonware/xwsystem/security/path_validator.py +140 -18
- exonware/xwsystem/security/policy.py +357 -0
- exonware/xwsystem/security/resource_limits.py +1 -0
- exonware/xwsystem/security/validator.py +455 -0
- exonware/xwsystem/shared/__init__.py +14 -1
- exonware/xwsystem/shared/base.py +285 -2
- exonware/xwsystem/shared/contracts.py +415 -126
- exonware/xwsystem/shared/defs.py +2 -1
- exonware/xwsystem/shared/errors.py +2 -2
- exonware/xwsystem/shared/xwobject.py +316 -0
- exonware/xwsystem/structures/__init__.py +1 -0
- exonware/xwsystem/structures/base.py +3 -2
- exonware/xwsystem/structures/circular_detector.py +15 -14
- exonware/xwsystem/structures/contracts.py +53 -76
- exonware/xwsystem/structures/defs.py +2 -1
- exonware/xwsystem/structures/errors.py +2 -1
- exonware/xwsystem/structures/tree_walker.py +2 -1
- exonware/xwsystem/threading/__init__.py +21 -4
- exonware/xwsystem/threading/async_primitives.py +6 -5
- exonware/xwsystem/threading/base.py +3 -2
- exonware/xwsystem/threading/contracts.py +87 -143
- exonware/xwsystem/threading/defs.py +2 -1
- exonware/xwsystem/threading/errors.py +2 -1
- exonware/xwsystem/threading/facade.py +175 -0
- exonware/xwsystem/threading/locks.py +1 -0
- exonware/xwsystem/threading/safe_factory.py +1 -0
- exonware/xwsystem/utils/__init__.py +40 -0
- exonware/xwsystem/utils/base.py +22 -21
- exonware/xwsystem/utils/contracts.py +50 -73
- exonware/xwsystem/utils/dt/__init__.py +19 -3
- exonware/xwsystem/utils/dt/base.py +5 -4
- exonware/xwsystem/utils/dt/contracts.py +22 -29
- exonware/xwsystem/utils/dt/defs.py +2 -1
- exonware/xwsystem/utils/dt/errors.py +2 -5
- exonware/xwsystem/utils/dt/formatting.py +88 -2
- exonware/xwsystem/utils/dt/humanize.py +10 -9
- exonware/xwsystem/utils/dt/parsing.py +56 -5
- exonware/xwsystem/utils/dt/timezone_utils.py +2 -24
- exonware/xwsystem/utils/errors.py +2 -4
- exonware/xwsystem/utils/paths.py +1 -0
- exonware/xwsystem/utils/string.py +49 -0
- exonware/xwsystem/utils/test_runner.py +185 -0
- exonware/xwsystem/utils/utils_contracts.py +2 -1
- exonware/xwsystem/utils/web.py +110 -0
- exonware/xwsystem/validation/__init__.py +25 -1
- exonware/xwsystem/validation/base.py +6 -5
- exonware/xwsystem/validation/contracts.py +29 -41
- exonware/xwsystem/validation/data_validator.py +1 -0
- exonware/xwsystem/validation/declarative.py +11 -8
- exonware/xwsystem/validation/defs.py +2 -1
- exonware/xwsystem/validation/errors.py +2 -1
- exonware/xwsystem/validation/facade.py +198 -0
- exonware/xwsystem/validation/fluent_validator.py +22 -19
- exonware/xwsystem/validation/schema_discovery.py +210 -0
- exonware/xwsystem/validation/type_safety.py +2 -1
- exonware/xwsystem/version.py +2 -2
- {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.4.dist-info}/METADATA +71 -4
- exonware_xwsystem-0.1.0.4.dist-info/RECORD +337 -0
- exonware/xwsystem/cli/__init__.py +0 -43
- exonware/xwsystem/cli/console.py +0 -113
- exonware/xwsystem/cli/defs.py +0 -134
- exonware/xwsystem/conf.py +0 -44
- exonware/xwsystem/security/auth.py +0 -484
- exonware_xwsystem-0.1.0.1.dist-info/RECORD +0 -284
- {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.4.dist-info}/WHEEL +0 -0
- {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.4.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,20 +1,29 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/io/file/file.py
|
|
1
2
|
"""
|
|
2
3
|
Company: eXonware.com
|
|
3
4
|
Author: Eng. Muhammad AlShehri
|
|
4
5
|
Email: connect@exonware.com
|
|
5
|
-
Version: 0.1.0.
|
|
6
|
+
Version: 0.1.0.4
|
|
6
7
|
Generation Date: September 04, 2025
|
|
7
8
|
|
|
8
9
|
XWFile - Concrete implementation of file operations.
|
|
10
|
+
|
|
11
|
+
Handles reading from local paths and URIs (file, http, https, ftp, etc.)
|
|
12
|
+
when source_config is provided. Security and allowed schemes are configured
|
|
13
|
+
via SourceLoadConfig (from xwdata); xwsystem enforces it.
|
|
9
14
|
"""
|
|
10
15
|
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import asyncio
|
|
11
19
|
import os
|
|
12
20
|
from pathlib import Path
|
|
13
|
-
from typing import Any, Optional,
|
|
21
|
+
from typing import Any, Optional, BinaryIO, TextIO
|
|
14
22
|
|
|
15
23
|
from ..base import AFile
|
|
16
24
|
from ..contracts import FileMode, OperationResult, IFile
|
|
17
25
|
from ..common.atomic import AtomicFileWriter
|
|
26
|
+
from ..source_reader import get_scheme, read_source_text, SourceLoadConfig
|
|
18
27
|
from ...config.logging_setup import get_logger
|
|
19
28
|
from ...security.path_validator import PathValidator
|
|
20
29
|
from ...validation.data_validator import DataValidator
|
|
@@ -30,23 +39,29 @@ class XWFile(AFile):
|
|
|
30
39
|
"""
|
|
31
40
|
Concrete implementation of file operations with both static and instance methods.
|
|
32
41
|
|
|
33
|
-
|
|
34
|
-
|
|
42
|
+
Handles local paths and URIs (http, https, ftp, etc.) when source_config is set.
|
|
43
|
+
All read-from-URI logic and security checks live in xwsystem (source_reader);
|
|
44
|
+
config is supplied by callers (e.g. xwdata).
|
|
35
45
|
|
|
36
46
|
Features:
|
|
37
47
|
- File I/O operations (read, write, save, load)
|
|
48
|
+
- URI loading (file, http, https, ftp) with SourceLoadConfig
|
|
38
49
|
- File metadata operations (size, permissions, timestamps)
|
|
39
|
-
- File validation and safety checks
|
|
40
|
-
- Static utility methods for file operations
|
|
41
50
|
- xwsystem integration (security, validation, monitoring)
|
|
42
51
|
"""
|
|
43
52
|
|
|
44
|
-
def __init__(
|
|
53
|
+
def __init__(
|
|
54
|
+
self,
|
|
55
|
+
file_path: str | Path,
|
|
56
|
+
source_config: Optional[SourceLoadConfig] = None,
|
|
57
|
+
**config
|
|
58
|
+
):
|
|
45
59
|
"""
|
|
46
60
|
Initialize XWFile with xwsystem integration.
|
|
47
61
|
|
|
48
62
|
Args:
|
|
49
|
-
file_path: Path to file
|
|
63
|
+
file_path: Path to file or URI (http://..., ftp://..., etc.)
|
|
64
|
+
source_config: If set, load() can read from URIs; security from this config.
|
|
50
65
|
**config: Configuration options for file operations
|
|
51
66
|
"""
|
|
52
67
|
super().__init__(file_path)
|
|
@@ -54,6 +69,7 @@ class XWFile(AFile):
|
|
|
54
69
|
# Initialize xwsystem utilities
|
|
55
70
|
self._path_validator = PathValidator()
|
|
56
71
|
self._data_validator = DataValidator()
|
|
72
|
+
self._source_config = source_config
|
|
57
73
|
|
|
58
74
|
# Configuration
|
|
59
75
|
self.validate_paths = config.get('validate_paths', True)
|
|
@@ -84,7 +100,7 @@ class XWFile(AFile):
|
|
|
84
100
|
self._handle = open(self.file_path, mode.value)
|
|
85
101
|
logger.debug(f"File opened: {self.file_path} in mode {mode.value}")
|
|
86
102
|
|
|
87
|
-
def read(self, size: Optional[int] = None) ->
|
|
103
|
+
def read(self, size: Optional[int] = None) -> str | bytes:
|
|
88
104
|
"""Read from file with validation."""
|
|
89
105
|
if not self._handle:
|
|
90
106
|
raise ValueError("File not open")
|
|
@@ -97,7 +113,7 @@ class XWFile(AFile):
|
|
|
97
113
|
|
|
98
114
|
return data
|
|
99
115
|
|
|
100
|
-
def write(self, data:
|
|
116
|
+
def write(self, data: str | bytes) -> int:
|
|
101
117
|
"""Write to file with validation."""
|
|
102
118
|
if not self._handle:
|
|
103
119
|
raise ValueError("File not open")
|
|
@@ -138,7 +154,27 @@ class XWFile(AFile):
|
|
|
138
154
|
return False
|
|
139
155
|
|
|
140
156
|
def load(self, **kwargs) -> Any:
|
|
141
|
-
"""Load data from file
|
|
157
|
+
"""Load data from file or URI. For URIs uses source_reader (config-driven)."""
|
|
158
|
+
uri_or_path = str(self.file_path)
|
|
159
|
+
scheme = get_scheme(uri_or_path)
|
|
160
|
+
|
|
161
|
+
# URI (http, https, ftp): use source_reader with config (sync wrapper)
|
|
162
|
+
if scheme != 'file' and self._source_config is not None:
|
|
163
|
+
with performance_monitor("file_load"):
|
|
164
|
+
loop = asyncio.new_event_loop()
|
|
165
|
+
try:
|
|
166
|
+
asyncio.set_event_loop(loop)
|
|
167
|
+
content, _ = loop.run_until_complete(
|
|
168
|
+
read_source_text(uri_or_path, config=self._source_config)
|
|
169
|
+
)
|
|
170
|
+
if self.validate_data:
|
|
171
|
+
self._data_validator.validate_data(content)
|
|
172
|
+
return content
|
|
173
|
+
finally:
|
|
174
|
+
loop.close()
|
|
175
|
+
asyncio.set_event_loop(None)
|
|
176
|
+
|
|
177
|
+
# Local file path
|
|
142
178
|
if not self.file_path.exists():
|
|
143
179
|
raise FileNotFoundError(f"File not found: {self.file_path}")
|
|
144
180
|
|
|
@@ -147,7 +183,6 @@ class XWFile(AFile):
|
|
|
147
183
|
|
|
148
184
|
with performance_monitor("file_load"):
|
|
149
185
|
try:
|
|
150
|
-
# Try to read as text first, then binary
|
|
151
186
|
try:
|
|
152
187
|
with open(self.file_path, 'r', encoding='utf-8') as f:
|
|
153
188
|
data = f.read()
|
|
@@ -163,7 +198,7 @@ class XWFile(AFile):
|
|
|
163
198
|
logger.error(f"Load failed for {self.file_path}: {e}")
|
|
164
199
|
raise
|
|
165
200
|
|
|
166
|
-
def save_as(self, path:
|
|
201
|
+
def save_as(self, path: str | Path, data: Any, **kwargs) -> bool:
|
|
167
202
|
"""Save data to specific path."""
|
|
168
203
|
target_path = Path(path)
|
|
169
204
|
|
|
@@ -193,13 +228,13 @@ class XWFile(AFile):
|
|
|
193
228
|
logger.error(f"Save as failed for {target_path}: {e}")
|
|
194
229
|
return False
|
|
195
230
|
|
|
196
|
-
def to_file(self, path:
|
|
231
|
+
def to_file(self, path: str | Path, **kwargs) -> bool:
|
|
197
232
|
"""Write current object to file."""
|
|
198
233
|
# This would depend on the specific object being saved
|
|
199
234
|
# For now, we'll use the file path as the data
|
|
200
235
|
return self.save_as(path, str(self.file_path), **kwargs)
|
|
201
236
|
|
|
202
|
-
def from_file(self, path:
|
|
237
|
+
def from_file(self, path: str | Path, **kwargs) -> File:
|
|
203
238
|
"""Load object from file."""
|
|
204
239
|
# Create new XWFile instance for the given path
|
|
205
240
|
new_file = XWFile(path, **kwargs)
|
|
@@ -210,6 +245,14 @@ class XWFile(AFile):
|
|
|
210
245
|
# UTILITY METHODS
|
|
211
246
|
# ============================================================================
|
|
212
247
|
|
|
248
|
+
def exists(self) -> bool:
|
|
249
|
+
"""Check if file exists (instance method)."""
|
|
250
|
+
return AFile.exists(self.file_path)
|
|
251
|
+
|
|
252
|
+
def get_size(self) -> int:
|
|
253
|
+
"""Get file size (instance method)."""
|
|
254
|
+
return AFile.size(self.file_path)
|
|
255
|
+
|
|
213
256
|
def get_info(self) -> dict[str, Any]:
|
|
214
257
|
"""Get comprehensive file information."""
|
|
215
258
|
return {
|
|
@@ -244,8 +287,8 @@ class XWFile(AFile):
|
|
|
244
287
|
|
|
245
288
|
@staticmethod
|
|
246
289
|
def convert(
|
|
247
|
-
source_path:
|
|
248
|
-
target_path:
|
|
290
|
+
source_path: str | Path,
|
|
291
|
+
target_path: str | Path,
|
|
249
292
|
source_format: Optional[str] = None,
|
|
250
293
|
target_format: Optional[str] = None,
|
|
251
294
|
**options
|
|
@@ -288,7 +331,7 @@ class XWFile(AFile):
|
|
|
288
331
|
|
|
289
332
|
def save_as(
|
|
290
333
|
self,
|
|
291
|
-
target_path:
|
|
334
|
+
target_path: str | Path,
|
|
292
335
|
target_format: Optional[str] = None,
|
|
293
336
|
**options
|
|
294
337
|
) -> None:
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Company: eXonware.com
|
|
5
5
|
Author: Eng. Muhammad AlShehri
|
|
6
6
|
Email: connect@exonware.com
|
|
7
|
-
Version: 0.1.0.
|
|
7
|
+
Version: 0.1.0.4
|
|
8
8
|
Generation Date: 30-Oct-2025
|
|
9
9
|
|
|
10
10
|
Paged file source with MODULAR paging system.
|
|
@@ -19,7 +19,7 @@ Priority 5 (Extensibility): Add new strategies without changing this class!
|
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
21
|
from pathlib import Path
|
|
22
|
-
from typing import
|
|
22
|
+
from typing import Optional, Iterator
|
|
23
23
|
|
|
24
24
|
from ..contracts import IPagedDataSource
|
|
25
25
|
from .source import FileDataSource
|
|
@@ -29,7 +29,7 @@ from ..contracts import IPagingStrategy
|
|
|
29
29
|
from .paging import auto_detect_paging_strategy
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
class PagedFileSource(FileDataSource, IPagedDataSource[
|
|
32
|
+
class PagedFileSource(FileDataSource, IPagedDataSource[bytes | str]):
|
|
33
33
|
"""
|
|
34
34
|
Paged file source with PLUGGABLE paging strategies!
|
|
35
35
|
|
|
@@ -50,7 +50,7 @@ class PagedFileSource(FileDataSource, IPagedDataSource[Union[bytes, str]]):
|
|
|
50
50
|
|
|
51
51
|
def __init__(
|
|
52
52
|
self,
|
|
53
|
-
path:
|
|
53
|
+
path: str | Path,
|
|
54
54
|
mode: str = 'rb',
|
|
55
55
|
encoding: Optional[str] = None,
|
|
56
56
|
validate_path: bool = True,
|
|
@@ -84,7 +84,7 @@ class PagedFileSource(FileDataSource, IPagedDataSource[Union[bytes, str]]):
|
|
|
84
84
|
return -1
|
|
85
85
|
return self._path.stat().st_size
|
|
86
86
|
|
|
87
|
-
def read_page(self, page: int, page_size: int, **options) ->
|
|
87
|
+
def read_page(self, page: int, page_size: int, **options) -> bytes | str:
|
|
88
88
|
"""
|
|
89
89
|
Read specific page using the paging strategy.
|
|
90
90
|
|
|
@@ -99,7 +99,7 @@ class PagedFileSource(FileDataSource, IPagedDataSource[Union[bytes, str]]):
|
|
|
99
99
|
**options
|
|
100
100
|
)
|
|
101
101
|
|
|
102
|
-
def iter_pages(self, page_size: int, **options) -> Iterator[
|
|
102
|
+
def iter_pages(self, page_size: int, **options) -> Iterator[bytes | str]:
|
|
103
103
|
"""
|
|
104
104
|
Iterate over pages using the paging strategy.
|
|
105
105
|
"""
|
|
@@ -111,7 +111,7 @@ class PagedFileSource(FileDataSource, IPagedDataSource[Union[bytes, str]]):
|
|
|
111
111
|
**options
|
|
112
112
|
)
|
|
113
113
|
|
|
114
|
-
def read_chunk(self, offset: int, size: int, **options) ->
|
|
114
|
+
def read_chunk(self, offset: int, size: int, **options) -> bytes | str:
|
|
115
115
|
"""
|
|
116
116
|
Read chunk by byte offset (always byte-based).
|
|
117
117
|
|
|
@@ -136,7 +136,7 @@ class PagedFileSource(FileDataSource, IPagedDataSource[Union[bytes, str]]):
|
|
|
136
136
|
except Exception as e:
|
|
137
137
|
raise IOError(f"Failed to read chunk from {self._path}: {e}")
|
|
138
138
|
|
|
139
|
-
def iter_chunks(self, chunk_size: int, **options) -> Iterator[
|
|
139
|
+
def iter_chunks(self, chunk_size: int, **options) -> Iterator[bytes | str]:
|
|
140
140
|
"""
|
|
141
141
|
Iterate over chunks by byte size.
|
|
142
142
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Company: eXonware.com
|
|
5
5
|
Author: Eng. Muhammad AlShehri
|
|
6
6
|
Email: connect@exonware.com
|
|
7
|
-
Version: 0.1.0.
|
|
7
|
+
Version: 0.1.0.4
|
|
8
8
|
Generation Date: 30-Oct-2025
|
|
9
9
|
|
|
10
10
|
Modular paging system with strategy pattern.
|
|
@@ -42,4 +42,3 @@ __all__ = [
|
|
|
42
42
|
"get_paging_strategy",
|
|
43
43
|
"auto_detect_paging_strategy",
|
|
44
44
|
]
|
|
45
|
-
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Company: eXonware.com
|
|
5
5
|
Author: Eng. Muhammad AlShehri
|
|
6
6
|
Email: connect@exonware.com
|
|
7
|
-
Version: 0.1.0.
|
|
7
|
+
Version: 0.1.0.4
|
|
8
8
|
Generation Date: 30-Oct-2025
|
|
9
9
|
|
|
10
10
|
Byte-based paging strategy.
|
|
@@ -17,7 +17,7 @@ Priority 5 (Extensibility): Pluggable via registry
|
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
19
|
from pathlib import Path
|
|
20
|
-
from typing import
|
|
20
|
+
from typing import Optional, Iterator
|
|
21
21
|
|
|
22
22
|
from ...contracts import IPagingStrategy
|
|
23
23
|
|
|
@@ -47,7 +47,7 @@ class BytePagingStrategy:
|
|
|
47
47
|
mode: str = 'rb',
|
|
48
48
|
encoding: Optional[str] = None,
|
|
49
49
|
**options
|
|
50
|
-
) ->
|
|
50
|
+
) -> bytes | str:
|
|
51
51
|
"""Read page by byte offset."""
|
|
52
52
|
offset = page * page_size
|
|
53
53
|
|
|
@@ -62,7 +62,7 @@ class BytePagingStrategy:
|
|
|
62
62
|
mode: str = 'rb',
|
|
63
63
|
encoding: Optional[str] = None,
|
|
64
64
|
**options
|
|
65
|
-
) -> Iterator[
|
|
65
|
+
) -> Iterator[bytes | str]:
|
|
66
66
|
"""Iterate over pages by byte chunks."""
|
|
67
67
|
page = 0
|
|
68
68
|
while True:
|
|
@@ -71,4 +71,3 @@ class BytePagingStrategy:
|
|
|
71
71
|
break
|
|
72
72
|
yield content
|
|
73
73
|
page += 1
|
|
74
|
-
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Company: eXonware.com
|
|
5
5
|
Author: Eng. Muhammad AlShehri
|
|
6
6
|
Email: connect@exonware.com
|
|
7
|
-
Version: 0.1.0.
|
|
7
|
+
Version: 0.1.0.4
|
|
8
8
|
Generation Date: 30-Oct-2025
|
|
9
9
|
|
|
10
10
|
Line-based paging strategy.
|
|
@@ -17,7 +17,7 @@ Priority 5 (Extensibility): Pluggable via registry
|
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
19
|
from pathlib import Path
|
|
20
|
-
from typing import
|
|
20
|
+
from typing import Optional, Iterator
|
|
21
21
|
|
|
22
22
|
from ...contracts import IPagingStrategy
|
|
23
23
|
|
|
@@ -84,4 +84,3 @@ class LinePagingStrategy:
|
|
|
84
84
|
break
|
|
85
85
|
yield content
|
|
86
86
|
page += 1
|
|
87
|
-
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Company: eXonware.com
|
|
5
5
|
Author: Eng. Muhammad AlShehri
|
|
6
6
|
Email: connect@exonware.com
|
|
7
|
-
Version: 0.1.0.
|
|
7
|
+
Version: 0.1.0.4
|
|
8
8
|
Generation Date: 30-Oct-2025
|
|
9
9
|
|
|
10
10
|
Record-based paging strategy for structured formats.
|
|
@@ -17,7 +17,7 @@ Priority 5 (Extensibility): Pluggable via registry
|
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
19
|
from pathlib import Path
|
|
20
|
-
from typing import
|
|
20
|
+
from typing import Optional, Iterator
|
|
21
21
|
|
|
22
22
|
from ...contracts import IPagingStrategy
|
|
23
23
|
|
|
@@ -98,4 +98,3 @@ class RecordPagingStrategy:
|
|
|
98
98
|
break
|
|
99
99
|
yield content
|
|
100
100
|
page += 1
|
|
101
|
-
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Company: eXonware.com
|
|
5
5
|
Author: Eng. Muhammad AlShehri
|
|
6
6
|
Email: connect@exonware.com
|
|
7
|
-
Version: 0.1.0.
|
|
7
|
+
Version: 0.1.0.4
|
|
8
8
|
Generation Date: 30-Oct-2025
|
|
9
9
|
|
|
10
10
|
Paging strategy registry - LIKE CodecRegistry!
|
|
@@ -177,4 +177,3 @@ def auto_detect_paging_strategy(mode: str = 'rb', **hints) -> IPagingStrategy:
|
|
|
177
177
|
>>> strategy = auto_detect_paging_strategy(mode='r')
|
|
178
178
|
"""
|
|
179
179
|
return get_global_paging_registry().auto_detect(mode, **hints)
|
|
180
|
-
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Company: eXonware.com
|
|
5
5
|
Author: Eng. Muhammad AlShehri
|
|
6
6
|
Email: connect@exonware.com
|
|
7
|
-
Version: 0.1.0.
|
|
7
|
+
Version: 0.1.0.4
|
|
8
8
|
Generation Date: 30-Oct-2025
|
|
9
9
|
|
|
10
10
|
File-based data source implementation.
|
|
@@ -17,12 +17,12 @@ Priority 5 (Extensibility): Foundation for other data sources (HTTP, S3, etc.)
|
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
19
|
from pathlib import Path
|
|
20
|
-
from typing import
|
|
20
|
+
from typing import Optional, Any
|
|
21
21
|
|
|
22
22
|
from ..contracts import IDataSource
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
class FileDataSource(IDataSource[
|
|
25
|
+
class FileDataSource(IDataSource[bytes | str]):
|
|
26
26
|
"""
|
|
27
27
|
File-based data source implementation.
|
|
28
28
|
|
|
@@ -46,7 +46,7 @@ class FileDataSource(IDataSource[Union[bytes, str]]):
|
|
|
46
46
|
|
|
47
47
|
def __init__(
|
|
48
48
|
self,
|
|
49
|
-
path:
|
|
49
|
+
path: str | Path,
|
|
50
50
|
mode: str = 'rb',
|
|
51
51
|
encoding: Optional[str] = None,
|
|
52
52
|
validate_path: bool = True
|
|
@@ -66,16 +66,13 @@ class FileDataSource(IDataSource[Union[bytes, str]]):
|
|
|
66
66
|
self._validate_path = validate_path
|
|
67
67
|
|
|
68
68
|
if validate_path:
|
|
69
|
-
# Use PathValidator for validation
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
pv.validate_path(str(self._path), for_writing=for_writing, create_dirs=True)
|
|
77
|
-
except ImportError:
|
|
78
|
-
pass
|
|
69
|
+
# Use PathValidator for validation (always available in xwsystem)
|
|
70
|
+
from ...security.path_validator import PathValidator
|
|
71
|
+
# Don't check existence during initialization - file may be created later
|
|
72
|
+
pv = PathValidator(check_existence=False)
|
|
73
|
+
# For write modes, allow creating the file (path doesn't exist yet)
|
|
74
|
+
for_writing = mode and ('w' in mode or 'a' in mode or '+' in mode)
|
|
75
|
+
pv.validate_path(str(self._path), for_writing=for_writing, create_dirs=True)
|
|
79
76
|
|
|
80
77
|
@property
|
|
81
78
|
def uri(self) -> str:
|
|
@@ -87,7 +84,7 @@ class FileDataSource(IDataSource[Union[bytes, str]]):
|
|
|
87
84
|
"""Return scheme identifier."""
|
|
88
85
|
return "file"
|
|
89
86
|
|
|
90
|
-
def read(self, **options) ->
|
|
87
|
+
def read(self, **options) -> bytes | str:
|
|
91
88
|
"""
|
|
92
89
|
Read entire file content.
|
|
93
90
|
|
|
@@ -109,7 +106,7 @@ class FileDataSource(IDataSource[Union[bytes, str]]):
|
|
|
109
106
|
except Exception as e:
|
|
110
107
|
raise IOError(f"Failed to read {self._path}: {e}")
|
|
111
108
|
|
|
112
|
-
def write(self, data:
|
|
109
|
+
def write(self, data: bytes | str, **options) -> None:
|
|
113
110
|
"""
|
|
114
111
|
Write entire content to file.
|
|
115
112
|
|
|
@@ -211,4 +208,3 @@ class FileDataSource(IDataSource[Union[bytes, str]]):
|
|
|
211
208
|
'uri': self.uri,
|
|
212
209
|
'error': str(e)
|
|
213
210
|
}
|
|
214
|
-
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Company: eXonware.com
|
|
5
5
|
Author: Eng. Muhammad AlShehri
|
|
6
6
|
Email: connect@exonware.com
|
|
7
|
-
Version: 0.1.0.
|
|
7
|
+
Version: 0.1.0.4
|
|
8
8
|
Generation Date: 30-Oct-2025
|
|
9
9
|
|
|
10
10
|
Base classes for virtual filesystem.
|
|
@@ -24,4 +24,3 @@ class AFileSystem(IVirtualFS, ABC):
|
|
|
24
24
|
def scheme(self) -> str:
|
|
25
25
|
"""URI scheme."""
|
|
26
26
|
pass
|
|
27
|
-
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Company: eXonware.com
|
|
5
5
|
Author: Eng. Muhammad AlShehri
|
|
6
6
|
Email: connect@exonware.com
|
|
7
|
-
Version: 0.1.0.
|
|
7
|
+
Version: 0.1.0.4
|
|
8
8
|
Generation Date: 30-Oct-2025
|
|
9
9
|
|
|
10
10
|
Local filesystem implementation.
|
|
@@ -17,7 +17,7 @@ Priority 5 (Extensibility): Foundation for other FS (S3, FTP, etc.)
|
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
19
|
from pathlib import Path
|
|
20
|
-
from typing import
|
|
20
|
+
from typing import Optional, Any
|
|
21
21
|
|
|
22
22
|
from ..contracts import IFileSystem
|
|
23
23
|
|
|
@@ -39,7 +39,7 @@ class LocalFileSystem(IFileSystem):
|
|
|
39
39
|
>>> fs.write_text("file.txt", "content") # Saves to S3!
|
|
40
40
|
"""
|
|
41
41
|
|
|
42
|
-
def __init__(self, base_path: Optional[
|
|
42
|
+
def __init__(self, base_path: Optional[str | Path] = None):
|
|
43
43
|
"""
|
|
44
44
|
Initialize local filesystem.
|
|
45
45
|
|
|
@@ -152,4 +152,3 @@ class LocalFileSystem(IFileSystem):
|
|
|
152
152
|
def write(self, path: str, content: bytes) -> None:
|
|
153
153
|
"""Write file contents."""
|
|
154
154
|
self.write_bytes(path, content)
|
|
155
|
-
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Company: eXonware.com
|
|
5
5
|
Author: Eng. Muhammad AlShehri
|
|
6
6
|
Email: connect@exonware.com
|
|
7
|
-
Version: 0.1.0.
|
|
7
|
+
Version: 0.1.0.4
|
|
8
8
|
Generation Date: 30-Oct-2025
|
|
9
9
|
|
|
10
10
|
Base classes for folder operations.
|
|
@@ -35,4 +35,3 @@ class AFolderSource(IFolderSource, ABC):
|
|
|
35
35
|
def delete(self, recursive: bool = False) -> bool:
|
|
36
36
|
"""Delete directory."""
|
|
37
37
|
pass
|
|
38
|
-
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/io/folder/folder.py
|
|
1
2
|
"""
|
|
2
3
|
Company: eXonware.com
|
|
3
4
|
Author: Eng. Muhammad AlShehri
|
|
4
5
|
Email: connect@exonware.com
|
|
5
|
-
Version: 0.1.0.
|
|
6
|
+
Version: 0.1.0.4
|
|
6
7
|
Generation Date: September 04, 2025
|
|
7
8
|
|
|
8
9
|
XWFolder - Concrete implementation of folder operations.
|
|
@@ -11,7 +12,7 @@ XWFolder - Concrete implementation of folder operations.
|
|
|
11
12
|
import os
|
|
12
13
|
import shutil
|
|
13
14
|
from pathlib import Path
|
|
14
|
-
from typing import Any, Optional
|
|
15
|
+
from typing import Any, Optional
|
|
15
16
|
|
|
16
17
|
from ..base import AFolder
|
|
17
18
|
from ..contracts import OperationResult, IFolder
|
|
@@ -37,7 +38,7 @@ class XWFolder(AFolder):
|
|
|
37
38
|
- xwsystem integration (security, validation, monitoring)
|
|
38
39
|
"""
|
|
39
40
|
|
|
40
|
-
def __init__(self, dir_path:
|
|
41
|
+
def __init__(self, dir_path: str | Path, **config):
|
|
41
42
|
"""
|
|
42
43
|
Initialize XWFolder with xwsystem integration.
|
|
43
44
|
|
|
@@ -93,13 +94,17 @@ class XWFolder(AFolder):
|
|
|
93
94
|
logger.error(f"Failed to delete directory {self.dir_path}: {e}")
|
|
94
95
|
return False
|
|
95
96
|
|
|
96
|
-
def copy_to(self, destination:
|
|
97
|
+
def copy_to(self, destination: str | Path) -> bool:
|
|
97
98
|
"""Copy directory to destination."""
|
|
98
99
|
dest_path = Path(destination)
|
|
99
100
|
|
|
100
101
|
if self.validate_paths:
|
|
101
102
|
self._path_validator.validate_path(self.dir_path)
|
|
102
|
-
|
|
103
|
+
# Destination doesn't need to exist yet - it will be created by copytree
|
|
104
|
+
# Use check_existence=False to allow destination to not exist
|
|
105
|
+
dest_parent = dest_path.parent
|
|
106
|
+
if dest_parent:
|
|
107
|
+
self._path_validator.validate_path(dest_parent, create_dirs=True)
|
|
103
108
|
|
|
104
109
|
with performance_monitor("directory_copy"):
|
|
105
110
|
try:
|
|
@@ -110,13 +115,17 @@ class XWFolder(AFolder):
|
|
|
110
115
|
logger.error(f"Failed to copy directory from {self.dir_path} to {dest_path}: {e}")
|
|
111
116
|
return False
|
|
112
117
|
|
|
113
|
-
def move_to(self, destination:
|
|
118
|
+
def move_to(self, destination: str | Path) -> bool:
|
|
114
119
|
"""Move directory to destination."""
|
|
115
120
|
dest_path = Path(destination)
|
|
116
121
|
|
|
117
122
|
if self.validate_paths:
|
|
118
123
|
self._path_validator.validate_path(self.dir_path)
|
|
119
|
-
|
|
124
|
+
# Destination doesn't need to exist yet - it will be created by move
|
|
125
|
+
# Use check_existence=False to allow destination to not exist
|
|
126
|
+
dest_parent = dest_path.parent
|
|
127
|
+
if dest_parent:
|
|
128
|
+
self._path_validator.validate_path(dest_parent, create_dirs=True)
|
|
120
129
|
|
|
121
130
|
with performance_monitor("directory_move"):
|
|
122
131
|
try:
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/io/indexing/__init__.py
|
|
2
|
+
"""
|
|
3
|
+
Company: eXonware.com
|
|
4
|
+
Author: Eng. Muhammad AlShehri
|
|
5
|
+
Email: connect@exonware.com
|
|
6
|
+
Version: 0.1.0.4
|
|
7
|
+
Generation Date: January 2026
|
|
8
|
+
|
|
9
|
+
Indexing module - Unified indexing facade for line-oriented files.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from .facade import XWIndex
|
|
13
|
+
|
|
14
|
+
__all__ = ["XWIndex"]
|