osbot-utils 1.26.0__tar.gz → 1.28.0__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.
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/PKG-INFO +2 -2
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/README.md +1 -1
- osbot_utils-1.28.0/osbot_utils/helpers/Zip_Bytes.py +79 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Temp_Folder.py +5 -1
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Temp_Zip.py +8 -4
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Temp_Zip_In_Memory.py +4 -4
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Files.py +47 -11
- osbot_utils-1.28.0/osbot_utils/utils/Zip.py +235 -0
- osbot_utils-1.28.0/osbot_utils/version +1 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/pyproject.toml +1 -1
- osbot_utils-1.26.0/osbot_utils/utils/Zip.py +0 -140
- osbot_utils-1.26.0/osbot_utils/version +0 -1
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/LICENSE +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/base_classes/Cache_Pickle.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/base_classes/Kwargs_To_Disk.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/base_classes/Kwargs_To_Self.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/base_classes/Type_Safe.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/base_classes/Type_Safe__List.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/base_classes/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/context_managers/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/context_managers/capture_duration.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/context_managers/disable_root_loggers.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/classes/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/classes/singleton.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/lists/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/lists/filter_list.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/lists/group_by.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/lists/index_by.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/cache.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/cache_on_function.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/cache_on_self.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/cache_on_tmp.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/capture_exception.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/capture_status.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/catch.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/context.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/depreciated.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/function_type_check.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/obj_as_context.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/remove_return_value.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/required_fields.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/fluent/Fluent_Dict.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/fluent/Fluent_List.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/fluent/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/Mermaid.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/Mermaid__Edge.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/Mermaid__Graph.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/Mermaid__Node.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/Mermaid__Renderer.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/configs/Mermaid__Edge__Config.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/configs/Mermaid__Node__Config.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/configs/Mermaid__Render__Config.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/examples/Mermaid_Examples__FlowChart.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/models/Mermaid__Diagram_Direction.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/models/Mermaid__Diagram__Type.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/models/Mermaid__Node__Shape.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mgraph/MGraph.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mgraph/MGraph__Config.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mgraph/MGraph__Data.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mgraph/MGraph__Edge.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mgraph/MGraph__Node.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mgraph/MGraph__Random_Graphs.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mgraph/MGraph__Serializer.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mgraph/MGraphs.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mgraph/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/CFormat.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/CPrint.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/Dict_To_Attr.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/Local_Cache.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/Local_Caches.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/Print_Table.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/Python_Audit.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/Random_Seed.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/Type_Registry.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/Ast.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/Ast_Base.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/Ast_Data.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/Ast_Load.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/Ast_Merge.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/Ast_Node.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/Ast_Visit.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/Call_Tree.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Add.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Alias.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_And.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Argument.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Arguments.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Assert.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Assign.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Attribute.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Aug_Assign.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Bin_Op.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Bool_Op.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Break.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Call.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Class_Def.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Compare.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Comprehension.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Constant.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Continue.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Dict.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Eq.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Except_Handler.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Expr.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_For.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Function_Def.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Generator_Exp.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Gt.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_GtE.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_If.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_If_Exp.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Import.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Import_From.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_In.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Is.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Is_Not.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Keyword.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Lambda.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_List.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_List_Comp.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Load.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Lt.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_LtE.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Mod.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Module.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Mult.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Name.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Not.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Not_Eq.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Not_In.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Or.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Pass.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Pow.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Raise.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Return.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Set.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Slice.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Starred.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Store.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Sub.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Subscript.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Try.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Tuple.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Unary_Op.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_While.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_With.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_With_Item.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Yield.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Actions.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Config.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Data.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Invoke.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Row.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Table.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/cache_requests/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/cache_requests/flows/flow__Cache__Requests.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/flows/Flow.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/flows/Task.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/flows/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Dict_To_Css.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Dict_To_Html.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Dict_To_Tags.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Html_To_Dict.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Html_To_Tag.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Tag__Base.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Tag__Body.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Tag__Div.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Tag__H.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Tag__HR.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Tag__Head.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Tag__Html.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Tag__Link.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Tag__Style.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/Event__Queue.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/PubSub__Client.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/PubSub__Room.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/PubSub__Server.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/PubSub__Sqlite.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Connect.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Disconnect.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Join_Room.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Leave_Room.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Message.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/schemas/Schema__PubSub__Client.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/schemas/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/Capture_Sqlite_Error.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/Sqlite__Cursor.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/Sqlite__Database.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/Sqlite__Field.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/Sqlite__Globals.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/Sqlite__Table.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/Sqlite__Table__Create.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/Temp_Sqlite__Database__Disk.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/Temp_Sqlite__Table.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/cache/Schema__Table__Requests.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Patch.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Sqlite.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Table.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/cache/Sqlite__DB__Requests.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/cache/TestCase__Sqlite__Cache__Requests.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/cache/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Files.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Graph.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Json.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Local.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/domains/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/domains/schemas/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/models/Sqlite__Field__Type.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/models/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/sample_data/Sqlite__Sample_Data__Chinook.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/sample_data/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/sql_builder/SQL_Builder.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/sql_builder/SQL_Builder__Select.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/sql_builder/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Config.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Edges.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Files.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Nodes.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/tables/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ssh/SCP.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ssh/SSH.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ssh/SSH__Cache__Requests.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ssh/SSH__Execute.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ssh/SSH__Health_Check.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ssh/SSH__Linux.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ssh/SSH__Linux__Amazon.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ssh/SSH__Python.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ssh/TestCase__SSH.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ssh/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Call.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Call__Config.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Call__Graph.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Call__Handler.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Call__Print_Lines.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Call__Print_Traces.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Call__Stack.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Call__Stack_Node.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Call__Stats.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Call__View_Model.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Files.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Catch.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Duration.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Hook_Method.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Log_To_Queue.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Log_To_String.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Logging.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Patch_Print.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Profiler.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Pytest.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Stderr.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Stdout.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Temp_Env_Vars.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Temp_File.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Temp_Sys_Path.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Temp_Web_Server.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Unit_Test.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Unzip_File.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/__init__.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Assert.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Call_Stack.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Csv.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Dev.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Env.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Exceptions.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Functions.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Http.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Int.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Json.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Json_Cache.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Lists.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Misc.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Objects.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Png.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Process.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Python_Logger.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Status.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Str.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Toml.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Version.py +0 -0
- {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/__init__.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: osbot_utils
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.28.0
|
4
4
|
Summary: OWASP Security Bot - Utils
|
5
5
|
Home-page: https://github.com/owasp-sbot/OSBot-Utils
|
6
6
|
License: MIT
|
@@ -22,7 +22,7 @@ Description-Content-Type: text/markdown
|
|
22
22
|
|
23
23
|
Powerful Python util methods and classes that simplify common apis and tasks.
|
24
24
|
|
25
|
-

|
26
26
|
[](https://codecov.io/gh/owasp-sbot/OSBot-Utils)
|
27
27
|
|
28
28
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Powerful Python util methods and classes that simplify common apis and tasks.
|
4
4
|
|
5
|
-

|
6
6
|
[](https://codecov.io/gh/owasp-sbot/OSBot-Utils)
|
7
7
|
|
8
8
|
|
@@ -0,0 +1,79 @@
|
|
1
|
+
from osbot_utils.base_classes.Type_Safe import Type_Safe
|
2
|
+
from osbot_utils.utils.Dev import pprint
|
3
|
+
from osbot_utils.utils.Files import files_list, file_create_from_bytes, temp_file, parent_folder, parent_folder_create
|
4
|
+
from osbot_utils.utils.Zip import zip_bytes_empty, zip_bytes__files, zip_bytes__add_file, zip_bytes__add_files, \
|
5
|
+
zip_bytes__replace_files, zip_bytes__replace_file, zip_bytes__file_list, zip_bytes__file, \
|
6
|
+
zip_bytes__add_file__from_disk, zip_bytes__add_files__from_disk, zip_files, zip_file__files
|
7
|
+
|
8
|
+
|
9
|
+
class Zip_Bytes(Type_Safe):
|
10
|
+
zip_bytes : bytes
|
11
|
+
|
12
|
+
def __enter__(self):
|
13
|
+
self.zip_bytes = zip_bytes_empty()
|
14
|
+
return self
|
15
|
+
|
16
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
17
|
+
pass
|
18
|
+
|
19
|
+
def add_file(self, file_path, file_contents):
|
20
|
+
self.zip_bytes = zip_bytes__add_file(self.zip_bytes, file_path, file_contents)
|
21
|
+
return self
|
22
|
+
|
23
|
+
def add_file__from_disk(self, base_path, file_to_add):
|
24
|
+
self.zip_bytes = zip_bytes__add_file__from_disk(self.zip_bytes, base_path, file_to_add)
|
25
|
+
return self
|
26
|
+
|
27
|
+
def add_files(self, files_to_add):
|
28
|
+
self.zip_bytes = zip_bytes__add_files(self.zip_bytes, files_to_add)
|
29
|
+
return self
|
30
|
+
|
31
|
+
def add_files__from_disk(self, base_path, files_to_add):
|
32
|
+
self.zip_bytes = zip_bytes__add_files__from_disk(self.zip_bytes, base_path, files_to_add)
|
33
|
+
return self
|
34
|
+
|
35
|
+
def add_folder__from_disk(self, base_path, folder_to_add, pattern="*"):
|
36
|
+
files_to_add = files_list(folder_to_add, pattern=pattern)
|
37
|
+
return self.add_files__from_disk(base_path, files_to_add)
|
38
|
+
|
39
|
+
def add_from_zip_file(self, path_zip_file):
|
40
|
+
files_to_add = zip_file__files(path_zip_file)
|
41
|
+
self.add_files(files_to_add)
|
42
|
+
return self
|
43
|
+
|
44
|
+
def empty(self):
|
45
|
+
return self.size() == 0
|
46
|
+
|
47
|
+
def file(self, file_path):
|
48
|
+
return zip_bytes__file(self.zip_bytes, file_path)
|
49
|
+
|
50
|
+
def files(self):
|
51
|
+
return zip_bytes__files(self.zip_bytes)
|
52
|
+
|
53
|
+
def files_list(self):
|
54
|
+
return zip_bytes__file_list(self.zip_bytes)
|
55
|
+
|
56
|
+
def print_files_list(self):
|
57
|
+
pprint(self.files_list())
|
58
|
+
return self
|
59
|
+
def replace_files(self, files_to_replace):
|
60
|
+
self.zip_bytes = zip_bytes__replace_files(self.zip_bytes, files_to_replace)
|
61
|
+
return self
|
62
|
+
|
63
|
+
def replace_file(self, file_path, file_contents):
|
64
|
+
self.zip_bytes = zip_bytes__replace_file(self.zip_bytes, file_path, file_contents)
|
65
|
+
return self
|
66
|
+
|
67
|
+
def save(self, path=None):
|
68
|
+
if path is None:
|
69
|
+
path = temp_file(extension='.zip')
|
70
|
+
zip_file = file_create_from_bytes(bytes=self.zip_bytes, path=path)
|
71
|
+
return zip_file
|
72
|
+
|
73
|
+
def save_to(self, path):
|
74
|
+
parent_folder_create(path) # make sure the parent folder exists
|
75
|
+
return self.save(path)
|
76
|
+
|
77
|
+
|
78
|
+
def size(self):
|
79
|
+
return len(self.files_list())
|
@@ -4,7 +4,7 @@ from osbot_utils.utils.Misc import random_string
|
|
4
4
|
|
5
5
|
from osbot_utils.utils.Files import path_combine, temp_folder_current, safe_file_name, folder_exists, folder_create, \
|
6
6
|
folder_delete_recursively, files_list, file_create, folder_files, folders_recursive, files_find, files_recursive, \
|
7
|
-
temp_file_in_folder, create_folder, filter_parent_folder
|
7
|
+
temp_file_in_folder, create_folder, filter_parent_folder, file_contents
|
8
8
|
from osbot_utils.utils.Zip import zip_folder
|
9
9
|
|
10
10
|
|
@@ -92,6 +92,10 @@ class Temp_Folder:
|
|
92
92
|
def path(self):
|
93
93
|
return self.full_path
|
94
94
|
|
95
|
+
def file_contents(self, target_file):
|
96
|
+
file_path = path_combine(self.full_path, target_file)
|
97
|
+
return file_contents(file_path)
|
98
|
+
|
95
99
|
def files(self, show_parent_folder=False, include_folders=False):
|
96
100
|
all_files = files_recursive(self.path(), include_folders=include_folders)
|
97
101
|
if show_parent_folder:
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from osbot_utils.testing.Temp_Folder import Temp_Folder
|
2
|
-
from osbot_utils.utils.Files import Files, is_folder, file_exists, file_name
|
3
|
-
|
2
|
+
from osbot_utils.utils.Files import Files, is_folder, file_exists, file_name, file_move_to_folder, file_move, \
|
3
|
+
file_move_to
|
4
|
+
from osbot_utils.utils.Zip import zip_folder, zip_file__list
|
4
5
|
|
5
6
|
|
6
7
|
class Temp_Zip():
|
@@ -34,7 +35,7 @@ class Temp_Zip():
|
|
34
35
|
return self.zip_file
|
35
36
|
|
36
37
|
def files(self):
|
37
|
-
return
|
38
|
+
return zip_file__list(self.zip_file)
|
38
39
|
|
39
40
|
def print_path(self):
|
40
41
|
print()
|
@@ -42,4 +43,7 @@ class Temp_Zip():
|
|
42
43
|
return self
|
43
44
|
|
44
45
|
def zip_file_exists(self):
|
45
|
-
return file_exists(self.zip_file)
|
46
|
+
return file_exists(self.zip_file)
|
47
|
+
|
48
|
+
def move_to(self, target_file):
|
49
|
+
file_move_to(self.zip_file, target_file)
|
@@ -3,7 +3,7 @@ import io
|
|
3
3
|
from osbot_utils.testing.Temp_File import Temp_File
|
4
4
|
from osbot_utils.testing.Temp_Folder import Temp_Folder
|
5
5
|
from osbot_utils.utils.Files import is_file, is_folder, files_recursive, filter_parent_folder, temp_file
|
6
|
-
from osbot_utils.utils.Zip import zip_files_to_bytes,
|
6
|
+
from osbot_utils.utils.Zip import zip_files_to_bytes, zip_bytes__file_list, zip_bytes__add_file, zip_bytes__get_file
|
7
7
|
|
8
8
|
|
9
9
|
class Temp_Zip_In_Memory:
|
@@ -76,14 +76,14 @@ class Temp_Zip_In_Memory:
|
|
76
76
|
for items in self.targets_as_content:
|
77
77
|
file_path = items.get('file_path')
|
78
78
|
file_contents = items.get('file_contents')
|
79
|
-
zip_bytes =
|
79
|
+
zip_bytes = zip_bytes__add_file(zip_bytes, file_path, file_contents)
|
80
80
|
return zip_bytes
|
81
81
|
|
82
82
|
def zip_bytes_file_content(self, file_path):
|
83
|
-
return
|
83
|
+
return zip_bytes__get_file(self.zip_bytes(), file_path)
|
84
84
|
|
85
85
|
def zip_bytes_files(self):
|
86
|
-
return
|
86
|
+
return zip_bytes__file_list(self.zip_bytes())
|
87
87
|
|
88
88
|
def zip_buffer(self):
|
89
89
|
targets = self.target_files_with_root_folder()
|
@@ -8,6 +8,8 @@ import shutil
|
|
8
8
|
import tempfile
|
9
9
|
from os.path import abspath, join
|
10
10
|
from pathlib import Path, PosixPath
|
11
|
+
from typing import Union
|
12
|
+
|
11
13
|
from osbot_utils.utils.Misc import bytes_to_base64, base64_to_bytes, random_string
|
12
14
|
|
13
15
|
|
@@ -79,10 +81,12 @@ class Files:
|
|
79
81
|
return glob.glob(path_pattern, recursive=recursive)
|
80
82
|
|
81
83
|
@staticmethod
|
82
|
-
def files(path, pattern= '*.*'):
|
84
|
+
def files(path, pattern= '*.*', only_files=True):
|
83
85
|
result = []
|
84
86
|
for file in Path(path).rglob(pattern):
|
85
|
-
|
87
|
+
if only_files and is_not_file(file):
|
88
|
+
continue
|
89
|
+
result.append(str(file)) # todo: see if there is a better way to do this conversion to string
|
86
90
|
return sorted(result)
|
87
91
|
|
88
92
|
@staticmethod
|
@@ -194,7 +198,7 @@ class Files:
|
|
194
198
|
return path
|
195
199
|
|
196
200
|
@staticmethod
|
197
|
-
def folder_create_in_parent(path, name):
|
201
|
+
def folder_create_in_parent(path, name): # todo: revise the naming of this method, since it really doesn't have to do with 'parent' (it will depend on value of name)
|
198
202
|
folder_path = path_combine(path, name)
|
199
203
|
return folder_create(folder_path)
|
200
204
|
|
@@ -306,13 +310,24 @@ class Files:
|
|
306
310
|
return Files.open(path, mode='rb')
|
307
311
|
|
308
312
|
@staticmethod
|
309
|
-
def path_combine(path1, path2):
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
313
|
+
# def path_combine(path1, path2):
|
314
|
+
# if type(path1) in [str, Path] and type(path2) in [str, Path]:
|
315
|
+
# parent_path = str(path1)
|
316
|
+
# sub_path = str(path2)
|
317
|
+
# if sub_path.startswith('/'):
|
318
|
+
# sub_path = sub_path[1:]
|
319
|
+
# return abspath(join(parent_path,sub_path))
|
320
|
+
|
321
|
+
def path_combine(path1: Union[str, os.PathLike], path2: Union[str, os.PathLike]) -> str:
|
322
|
+
if path1 is None or path2 is None:
|
323
|
+
raise ValueError("Both paths must be provided")
|
324
|
+
|
325
|
+
parent_path = str(path1)
|
326
|
+
sub_path = str(path2)
|
327
|
+
|
328
|
+
sub_path = sub_path.lstrip('/') # Remove leading slashes from sub_path
|
329
|
+
|
330
|
+
return abspath(join(parent_path, sub_path))
|
316
331
|
|
317
332
|
@staticmethod
|
318
333
|
def parent_folder(path, use_full_path=False):
|
@@ -451,8 +466,11 @@ def all_parent_folders(path=None, include_path=False):
|
|
451
466
|
if path and path not in parent_directories: # to handle the root path case
|
452
467
|
parent_directories.append(path)
|
453
468
|
break
|
454
|
-
|
455
469
|
return parent_directories
|
470
|
+
|
471
|
+
def is_not_file(target):
|
472
|
+
return is_file(target) is False
|
473
|
+
|
456
474
|
def file_move(source_file, target_file):
|
457
475
|
if file_exists(source_file):
|
458
476
|
file_copy(source_file, target_file)
|
@@ -461,10 +479,27 @@ def file_move(source_file, target_file):
|
|
461
479
|
return True
|
462
480
|
return False
|
463
481
|
|
482
|
+
def file_move_to_folder(source_file, target_folder):
|
483
|
+
if file_exists(source_file):
|
484
|
+
if folder_exists(target_folder):
|
485
|
+
target_file = path_combine(target_folder, file_name(source_file))
|
486
|
+
if file_move(source_file, target_file):
|
487
|
+
return target_file
|
488
|
+
|
489
|
+
|
464
490
|
def folders_names_in_folder(target):
|
465
491
|
folders = folders_in_folder(target)
|
466
492
|
return folders_names(folders)
|
467
493
|
|
494
|
+
def parent_folder_create(target):
|
495
|
+
return folder_create(parent_folder(target))
|
496
|
+
|
497
|
+
def parent_folder_exists(target):
|
498
|
+
return folder_exists(parent_folder(target))
|
499
|
+
|
500
|
+
def parent_folder_not_exists(target):
|
501
|
+
return parent_folder_exists(target) is False
|
502
|
+
|
468
503
|
def stream_to_bytes(stream):
|
469
504
|
return stream.read()
|
470
505
|
|
@@ -506,6 +541,7 @@ file_full_path = absolute_path
|
|
506
541
|
file_lines = Files.lines
|
507
542
|
file_lines_gz = Files.lines_gz
|
508
543
|
file_md5 = Files.contents_md5
|
544
|
+
file_move_to = file_move
|
509
545
|
file_name = Files.file_name
|
510
546
|
file_name_without_extension = Files.file_name_without_extension
|
511
547
|
file_not_exists = Files.not_exists
|
@@ -0,0 +1,235 @@
|
|
1
|
+
import gzip
|
2
|
+
import io
|
3
|
+
import os
|
4
|
+
import shutil
|
5
|
+
import tarfile
|
6
|
+
import zipfile
|
7
|
+
from os.path import abspath
|
8
|
+
|
9
|
+
from osbot_utils.utils.Files import temp_folder, folder_files, temp_file, is_file, file_copy, file_move, file_exists, \
|
10
|
+
file_contents_as_bytes
|
11
|
+
|
12
|
+
#########################
|
13
|
+
# actions on gz_tar_bytes
|
14
|
+
|
15
|
+
def gz_tar_bytes__file_list(gz_bytes):
|
16
|
+
gz_buffer_from_bytes = io.BytesIO(gz_bytes)
|
17
|
+
with gzip.GzipFile(fileobj=gz_buffer_from_bytes, mode='rb') as gz:
|
18
|
+
decompressed_data = gz.read()
|
19
|
+
tar_buffer_from_bytes = io.BytesIO(decompressed_data) # Assuming the decompressed data is a tag file, process it
|
20
|
+
with tarfile.open(fileobj=tar_buffer_from_bytes, mode='r:') as tar:
|
21
|
+
return sorted(tar.getnames())
|
22
|
+
|
23
|
+
def gz_tar_bytes__get_file(gz_bytes, tar_file_path):
|
24
|
+
gz_buffer_from_bytes = io.BytesIO(gz_bytes)
|
25
|
+
with gzip.GzipFile(fileobj=gz_buffer_from_bytes, mode='rb') as gz:
|
26
|
+
decompressed_data = gz.read()
|
27
|
+
tar_buffer_from_bytes = io.BytesIO(decompressed_data)
|
28
|
+
with tarfile.open(fileobj=tar_buffer_from_bytes, mode='r:') as tar:
|
29
|
+
extracted_file = tar.extractfile(tar_file_path)
|
30
|
+
if extracted_file:
|
31
|
+
return extracted_file.read()
|
32
|
+
else:
|
33
|
+
raise FileNotFoundError(f"The file {tar_file_path} was not found in the tar archive.")
|
34
|
+
|
35
|
+
#########################
|
36
|
+
# actions on gz_zip_bytes
|
37
|
+
|
38
|
+
def gz_zip_bytes__file_list(gz_bytes):
|
39
|
+
gz_buffer_from_bytes = io.BytesIO(gz_bytes)
|
40
|
+
with gzip.GzipFile(fileobj=gz_buffer_from_bytes, mode='rb') as gz:
|
41
|
+
decompressed_data = gz.read()
|
42
|
+
zip_buffer_from_bytes = io.BytesIO(decompressed_data) # Assuming the decompressed data is a zip file, process it
|
43
|
+
with zipfile.ZipFile(zip_buffer_from_bytes, 'r') as zf:
|
44
|
+
return sorted(zf.namelist())
|
45
|
+
|
46
|
+
#########################
|
47
|
+
# actions on zipped bytes
|
48
|
+
|
49
|
+
def zip_bytes__add_file(zip_bytes, zip_file_path, file_contents): # todo: see if this is actually a valid use case (or if we should be using replace in all scenarios)
|
50
|
+
return zip_bytes__add_files(zip_bytes, {zip_file_path: file_contents})
|
51
|
+
|
52
|
+
def zip_bytes__add_file__from_disk(zip_bytes, base_path, file_to_add):
|
53
|
+
return zip_bytes__add_files__from_disk(zip_bytes, base_path, files_to_add=[file_to_add])
|
54
|
+
|
55
|
+
def zip_bytes__add_files__from_disk(zip_bytes, base_path, files_to_add, replace_files=True):
|
56
|
+
zip_files_to_add = {}
|
57
|
+
if base_path[:-1] != '/':
|
58
|
+
base_path += "/"
|
59
|
+
for file_to_add in files_to_add:
|
60
|
+
if file_exists(file_to_add):
|
61
|
+
file_contents = file_contents_as_bytes(file_to_add)
|
62
|
+
zip_file_path = file_to_add.replace(base_path, '')
|
63
|
+
zip_files_to_add[zip_file_path] = file_contents
|
64
|
+
|
65
|
+
if replace_files:
|
66
|
+
return zip_bytes__replace_files(zip_bytes, zip_files_to_add)
|
67
|
+
else:
|
68
|
+
return zip_bytes__add_files(zip_bytes, zip_files_to_add) # todo: see if this is actually a valid use case (or if we should be using replace in all scenarios)
|
69
|
+
|
70
|
+
def zip_bytes__add_files(zip_bytes, files_to_add): # todo: see if this is actually a valid use case (or if we should be using replace in all scenarios)
|
71
|
+
zip_buffer = io.BytesIO(zip_bytes) # Create a BytesIO buffer from the input zip bytes
|
72
|
+
|
73
|
+
with zipfile.ZipFile(zip_buffer, 'a', zipfile.ZIP_DEFLATED) as zf:
|
74
|
+
for file_path, file_contents in files_to_add.items():
|
75
|
+
if isinstance(file_contents, str):
|
76
|
+
file_contents = file_contents.encode('utf-8')
|
77
|
+
elif not isinstance(file_contents, bytes):
|
78
|
+
continue
|
79
|
+
zf.writestr(file_path, file_contents)
|
80
|
+
|
81
|
+
return zip_buffer.getvalue()
|
82
|
+
|
83
|
+
def zip_bytes__file(zip_bytes, zip_file_path):
|
84
|
+
zip_buffer = io.BytesIO(zip_bytes)
|
85
|
+
with zipfile.ZipFile(zip_buffer, 'r') as zf:
|
86
|
+
if zip_file_path in zf.namelist():
|
87
|
+
return zf.read(zip_file_path)
|
88
|
+
|
89
|
+
def zip_bytes__files(zip_bytes):
|
90
|
+
zip_buffer = io.BytesIO(zip_bytes) # Create a BytesIO buffer from the input zip bytes
|
91
|
+
files_dict = {} # Create a dictionary to store file contents
|
92
|
+
|
93
|
+
with zipfile.ZipFile(zip_buffer, 'r') as zf: # Open the zip file in read mode
|
94
|
+
for file_name in zf.namelist(): # Iterate over each file in the zip archive
|
95
|
+
files_dict[file_name] = zf.read(file_name) # Read the content of the file
|
96
|
+
|
97
|
+
return files_dict # Return the dictionary with file contents
|
98
|
+
|
99
|
+
def zip_bytes__file_list(zip_bytes):
|
100
|
+
zip_buffer_from_bytes = io.BytesIO(zip_bytes)
|
101
|
+
with zipfile.ZipFile(zip_buffer_from_bytes, 'r') as zf:
|
102
|
+
return sorted(zf.namelist())
|
103
|
+
|
104
|
+
def zip_bytes__remove_file(zip_bytes, file_to_remove):
|
105
|
+
return zip_bytes__remove_files(zip_bytes, [file_to_remove])
|
106
|
+
|
107
|
+
def zip_bytes__remove_files(zip_bytes, files_to_remove):
|
108
|
+
files_to_remove = set(files_to_remove) # Convert files_to_remove to a set for faster lookup
|
109
|
+
zip_buffer = io.BytesIO(zip_bytes) # Create a BytesIO buffer from the input zip bytes
|
110
|
+
new_zip_buffer = io.BytesIO() # Create a new BytesIO buffer for the updated zip
|
111
|
+
|
112
|
+
with zipfile.ZipFile(zip_buffer, 'r') as original_zip:
|
113
|
+
with zipfile.ZipFile(new_zip_buffer, 'w') as new_zip:
|
114
|
+
for item in original_zip.infolist(): # Iterate over each item in the original zip file
|
115
|
+
if item.filename not in files_to_remove: # Read the original content and write it to the new zip file
|
116
|
+
new_zip.writestr(item, original_zip.read(item.filename))
|
117
|
+
return new_zip_buffer.getvalue() # Get the updated zip content as bytes
|
118
|
+
|
119
|
+
def zip_bytes__replace_file(zip_bytes, zip_file_path, file_contents):
|
120
|
+
files_to_replace = {zip_file_path: file_contents }
|
121
|
+
return zip_bytes__replace_files(zip_bytes, files_to_replace)
|
122
|
+
|
123
|
+
def zip_bytes__replace_files(zip_bytes, files_to_replace):
|
124
|
+
zip_bytes__without_files = zip_bytes__remove_files(zip_bytes , set(files_to_replace))
|
125
|
+
zip_bytes__with_replaced_files = zip_bytes__add_files (zip_bytes__without_files, files_to_replace )
|
126
|
+
return zip_bytes__with_replaced_files
|
127
|
+
|
128
|
+
|
129
|
+
def zip_bytes__unzip(zip_bytes, target_folder=None):
|
130
|
+
target_folder = target_folder or temp_folder() # Use the provided target folder or create a temporary one
|
131
|
+
zip_buffer = io.BytesIO(zip_bytes) # Create a BytesIO buffer from the zip bytes
|
132
|
+
with zipfile.ZipFile(zip_buffer, 'r') as zf: # Open the zip file from the buffer
|
133
|
+
zf.extractall(target_folder) # Extract all files to the target folder
|
134
|
+
return target_folder # Return the path of the target folder
|
135
|
+
|
136
|
+
|
137
|
+
########################
|
138
|
+
# actions on zipped file
|
139
|
+
|
140
|
+
def zip_file__list(path_zip_file):
|
141
|
+
if is_file(path_zip_file):
|
142
|
+
with zipfile.ZipFile(path_zip_file) as zip_file:
|
143
|
+
return sorted(zip_file.namelist())
|
144
|
+
return []
|
145
|
+
|
146
|
+
def zip_file__files(path_zip_file):
|
147
|
+
if is_file(path_zip_file):
|
148
|
+
zip_bytes = file_contents_as_bytes(path_zip_file)
|
149
|
+
return zip_bytes__files(zip_bytes)
|
150
|
+
return []
|
151
|
+
|
152
|
+
def zip_file__unzip(path_zip_file, target_folder=None, format='zip'):
|
153
|
+
target_folder = target_folder or temp_folder()
|
154
|
+
shutil.unpack_archive(path_zip_file, extract_dir=target_folder, format=format)
|
155
|
+
return target_folder
|
156
|
+
|
157
|
+
# zip creation actions
|
158
|
+
def zip_bytes_empty():
|
159
|
+
|
160
|
+
zip_buffer = io.BytesIO() # Create a BytesIO buffer to hold the zip file
|
161
|
+
with zipfile.ZipFile(zip_buffer, mode='w') as _: # Use the zipfile.ZipFile class to create an empty zip file
|
162
|
+
pass # No files to add, so we just create the zip structure
|
163
|
+
return zip_buffer.getvalue() # Get the zip file content as bytes
|
164
|
+
|
165
|
+
def zip_bytes_to_file(zip_bytes, target_file=None):
|
166
|
+
if target_file is None:
|
167
|
+
target_file = temp_file(extension='.zip')
|
168
|
+
with open(target_file, 'wb') as f:
|
169
|
+
f.write(zip_bytes)
|
170
|
+
return target_file
|
171
|
+
|
172
|
+
def zip_files_to_bytes(target_files, root_folder=None):
|
173
|
+
zip_buffer = io.BytesIO() # Create a BytesIO buffer to hold the zipped file
|
174
|
+
with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zf: # Create a ZipFile object with the buffer as the target
|
175
|
+
for entry in target_files:
|
176
|
+
if type(entry) is str: # if entry is a string, assume it's a file path
|
177
|
+
file_path = entry
|
178
|
+
file_root_folder = root_folder
|
179
|
+
else:
|
180
|
+
file_path = entry.get('file')
|
181
|
+
file_root_folder = entry.get('root_folder') or root_folder
|
182
|
+
if file_root_folder:
|
183
|
+
arcname = file_path.replace(file_root_folder,'') # Define the arcname, which is the name inside the zip file
|
184
|
+
else:
|
185
|
+
arcname = file_path # if root_path is not provided, use the full file path
|
186
|
+
zf.write(file_path, arcname) # Add the file to the zip file
|
187
|
+
zip_buffer.seek(0)
|
188
|
+
return zip_buffer
|
189
|
+
|
190
|
+
def zip_folder(root_dir, format='zip'):
|
191
|
+
return shutil.make_archive(base_name=root_dir, format=format, root_dir=root_dir)
|
192
|
+
|
193
|
+
def zip_folder_to_file (root_dir, target_file):
|
194
|
+
zip_file = zip_folder(root_dir)
|
195
|
+
return file_move(zip_file, target_file)
|
196
|
+
|
197
|
+
def zip_folder_to_bytes(root_dir): # todo add unit test
|
198
|
+
zip_buffer = io.BytesIO() # Create a BytesIO buffer to hold the zipped file
|
199
|
+
with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zf: # Create a ZipFile object with the buffer as the target
|
200
|
+
for foldername, subfolders, filenames in os.walk(root_dir): # Walk the root_dir and add all files and folders to the zip file
|
201
|
+
for filename in filenames:
|
202
|
+
absolute_path = os.path.join(foldername, filename) # Create the complete filepath
|
203
|
+
arcname = os.path.relpath(absolute_path, root_dir) # Define the arcname, which is the name inside the zip file
|
204
|
+
zf.write(absolute_path, arcname) # Add the file to the zip file
|
205
|
+
zip_buffer.seek(0) # Reset buffer position
|
206
|
+
return zip_buffer
|
207
|
+
|
208
|
+
def zip_files(base_folder, file_pattern="*.*", target_file=None):
|
209
|
+
base_folder = abspath(base_folder)
|
210
|
+
file_list = folder_files(base_folder, file_pattern)
|
211
|
+
|
212
|
+
if len(file_list): # if there were files found
|
213
|
+
target_file = target_file or temp_file(extension='zip')
|
214
|
+
with zipfile.ZipFile(target_file,'w') as zip:
|
215
|
+
for file_name in file_list:
|
216
|
+
zip_file_path = file_name.replace(base_folder,'')
|
217
|
+
zip.write(file_name, zip_file_path)
|
218
|
+
|
219
|
+
return target_file
|
220
|
+
|
221
|
+
###########################
|
222
|
+
# extra function's mappings
|
223
|
+
|
224
|
+
file_unzip = zip_file__unzip
|
225
|
+
folder_zip = zip_folder
|
226
|
+
|
227
|
+
unzip_file = zip_file__unzip
|
228
|
+
|
229
|
+
zip_bytes__extract_to_folder = zip_bytes__unzip
|
230
|
+
zip_bytes__file_contents = zip_bytes__file
|
231
|
+
zip_bytes__get_file = zip_bytes__file
|
232
|
+
zip_bytes__unzip_to_folder = zip_bytes__unzip
|
233
|
+
|
234
|
+
zip_list_files = zip_file__list
|
235
|
+
zip_file__file_list = zip_file__list
|
@@ -0,0 +1 @@
|
|
1
|
+
v1.28.0
|