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

|
23
22
|
[](https://codecov.io/gh/owasp-sbot/OSBot-Utils)
|
24
23
|
|
25
24
|
|
26
25
|
|
27
26
|
## Install - Release 1.x
|
28
27
|
|
29
|
-
**for main branch**:
|
28
|
+
**for main branch**: just get it from pypi
|
30
29
|
|
31
30
|
```
|
32
31
|
pip install osbot-utils
|
@@ -2,14 +2,14 @@
|
|
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
|
|
9
9
|
|
10
10
|
## Install - Release 1.x
|
11
11
|
|
12
|
-
**for main branch**:
|
12
|
+
**for main branch**: just get it from pypi
|
13
13
|
|
14
14
|
```
|
15
15
|
pip install osbot-utils
|
@@ -130,8 +130,11 @@ class Sqlite__Database(Kwargs_To_Self):
|
|
130
130
|
table_names.append('sqlite_master')
|
131
131
|
return table_names
|
132
132
|
|
133
|
+
def purge_database(self): # this fells like a better name than vacuum :)
|
134
|
+
return self.vacuum()
|
133
135
|
|
134
|
-
|
136
|
+
def vacuum(self):
|
137
|
+
return self.cursor().vacuum()
|
135
138
|
|
136
139
|
|
137
140
|
|
@@ -130,6 +130,7 @@ class Sqlite__Table(Kwargs_To_Self):
|
|
130
130
|
rows = table_sqlite_master.cursor().execute__fetch_all(sql_query, params)
|
131
131
|
return table_sqlite_master.list_of_field_name_from_rows(rows, field_name)
|
132
132
|
|
133
|
+
|
133
134
|
def new_row_obj(self, row_data=None):
|
134
135
|
if self.row_schema:
|
135
136
|
new_obj = self.row_schema()
|
@@ -154,6 +155,7 @@ class Sqlite__Table(Kwargs_To_Self):
|
|
154
155
|
picked_row_data[field_name] = field_value
|
155
156
|
return picked_row_data
|
156
157
|
return row_data
|
158
|
+
|
157
159
|
def parse_row(self, row):
|
158
160
|
if row and self.auto_pickle_blob:
|
159
161
|
fields = self.fields__cached()
|
@@ -169,6 +171,14 @@ class Sqlite__Table(Kwargs_To_Self):
|
|
169
171
|
def print(self, **kwargs):
|
170
172
|
return Print_Table(**kwargs).print(self.rows())
|
171
173
|
|
174
|
+
def row(self, where, fields=None):
|
175
|
+
if fields is None:
|
176
|
+
return self.select_row_where(**where)
|
177
|
+
|
178
|
+
sql_query, params = self.sql_builder(limit=1).query_select_fields_with_conditions(fields, where)
|
179
|
+
row = self.cursor().execute__fetch_one(sql_query, params)
|
180
|
+
return self.parse_row(row)
|
181
|
+
|
172
182
|
def row_add(self, row_obj=None):
|
173
183
|
invalid_reason = self.sql_builder().validate_row_obj(row_obj)
|
174
184
|
if invalid_reason:
|
@@ -0,0 +1,45 @@
|
|
1
|
+
from osbot_utils.decorators.lists.index_by import index_by
|
2
|
+
from osbot_utils.decorators.methods.cache_on_self import cache_on_self
|
3
|
+
from osbot_utils.helpers.sqlite.domains.Sqlite__DB__Local import Sqlite__DB__Local
|
4
|
+
from osbot_utils.helpers.sqlite.tables.Sqlite__Table__Files import Sqlite__Table__Files
|
5
|
+
|
6
|
+
|
7
|
+
class Sqlite__DB__Files(Sqlite__DB__Local):
|
8
|
+
|
9
|
+
def __init__(self, db_path=None, db_name=None):
|
10
|
+
super().__init__(db_path=db_path, db_name=db_name)
|
11
|
+
|
12
|
+
def add_file(self, path, contents=None, metadata=None):
|
13
|
+
return self.table_files().add_file(path, contents, metadata)
|
14
|
+
|
15
|
+
def clear_table(self):
|
16
|
+
self.table_files().clear()
|
17
|
+
|
18
|
+
def delete_file(self, path):
|
19
|
+
return self.table_files().delete_file(path)
|
20
|
+
|
21
|
+
def file(self, path, include_contents=False):
|
22
|
+
return self.table_files().file(path, include_contents=include_contents)
|
23
|
+
|
24
|
+
def file_exists(self, path):
|
25
|
+
return self.table_files().file_exists(path)
|
26
|
+
|
27
|
+
def file_names(self):
|
28
|
+
return self.table_files().select_field_values('path')
|
29
|
+
@cache_on_self
|
30
|
+
def table_files(self):
|
31
|
+
return Sqlite__Table__Files(database=self).setup()
|
32
|
+
|
33
|
+
@index_by
|
34
|
+
def files(self,include_contents=False):
|
35
|
+
return self.table_files().files(include_contents=include_contents)
|
36
|
+
|
37
|
+
def files__with_content(self):
|
38
|
+
return self.files(include_contents=True)
|
39
|
+
|
40
|
+
def files__by_path(self):
|
41
|
+
return self.files(index_by='path')
|
42
|
+
|
43
|
+
def setup(self):
|
44
|
+
self.table_files()
|
45
|
+
return self
|
{osbot_utils-1.10.0 → osbot_utils-1.13.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Local.py
RENAMED
@@ -10,7 +10,8 @@ class Sqlite__DB__Local(Sqlite__Database):
|
|
10
10
|
db_name: str
|
11
11
|
|
12
12
|
def __init__(self, db_path=None, db_name=None):
|
13
|
-
self
|
13
|
+
if hasattr(self, 'db_name') is False:
|
14
|
+
self.db_name = db_name or random_text('db_local') + '.sqlite'
|
14
15
|
super().__init__(db_path=db_path or self.path_local_db())
|
15
16
|
|
16
17
|
def path_db_folder(self):
|
@@ -0,0 +1,86 @@
|
|
1
|
+
from osbot_utils.base_classes.Kwargs_To_Self import Kwargs_To_Self
|
2
|
+
from osbot_utils.helpers.sqlite.Sqlite__Table import Sqlite__Table
|
3
|
+
from osbot_utils.utils.Misc import timestamp_utc_now, bytes_sha256, str_sha256
|
4
|
+
from osbot_utils.utils.Status import status_warning, status_ok
|
5
|
+
|
6
|
+
SQLITE__TABLE_NAME__FILES = 'files'
|
7
|
+
|
8
|
+
class Schema__Table__Files(Kwargs_To_Self):
|
9
|
+
path : str
|
10
|
+
contents : bytes
|
11
|
+
metadata : bytes
|
12
|
+
timestamp: int
|
13
|
+
|
14
|
+
|
15
|
+
class Sqlite__Table__Files(Sqlite__Table):
|
16
|
+
auto_pickle_blob : bool = True
|
17
|
+
set_timestamp : bool = True
|
18
|
+
|
19
|
+
def __init__(self, **kwargs):
|
20
|
+
self.table_name = SQLITE__TABLE_NAME__FILES
|
21
|
+
self.row_schema = Schema__Table__Files
|
22
|
+
super().__init__(**kwargs)
|
23
|
+
|
24
|
+
def add_file(self, path, contents=None, metadata= None):
|
25
|
+
if self.contains(path=path): # don't allow multiple entries for the same file path (until we add versioning support)
|
26
|
+
return status_warning(f"File not added, since file with path '{path}' already exists in the database")
|
27
|
+
if metadata is None:
|
28
|
+
metadata = {}
|
29
|
+
metadata.update(self.create_contents_metadata(contents))
|
30
|
+
row_data = self.create_node_data(path, contents, metadata)
|
31
|
+
new_row_obj = self.add_row_and_commit(**row_data)
|
32
|
+
return status_ok(message='file added', data= new_row_obj)
|
33
|
+
|
34
|
+
def create_contents_metadata(self, contents):
|
35
|
+
file_size = len(contents)
|
36
|
+
file_is_binary = type(contents) is bytes
|
37
|
+
if file_is_binary:
|
38
|
+
file_hash = bytes_sha256(contents)
|
39
|
+
else:
|
40
|
+
file_hash = str_sha256(str(contents))
|
41
|
+
return dict(file_contents=dict(hash = file_hash ,
|
42
|
+
is_binary = file_is_binary ,
|
43
|
+
size = file_size ))
|
44
|
+
|
45
|
+
def delete_file(self, path):
|
46
|
+
if self.not_contains(path=path): # don't allow multiple entries for the same file path (until we add versioning support)
|
47
|
+
return status_warning(f"File not deleted, since file with path '{path}' did not exist in the database")
|
48
|
+
|
49
|
+
self.rows_delete_where(path=path)
|
50
|
+
return status_ok(message='file deleted')
|
51
|
+
|
52
|
+
def create_node_data(self, path, contents=None, metadata= None):
|
53
|
+
node_data = {'path' : path ,
|
54
|
+
'contents': contents ,
|
55
|
+
'metadata': metadata }
|
56
|
+
if self.set_timestamp:
|
57
|
+
node_data['timestamp'] = timestamp_utc_now()
|
58
|
+
return node_data
|
59
|
+
|
60
|
+
def field_names_without_content(self): # todo: refactor to get this directly from the schema
|
61
|
+
return ['id', 'path', 'metadata', 'timestamp'] # and so that these values are not hard-coded here
|
62
|
+
|
63
|
+
def file(self, path, include_contents=True):
|
64
|
+
if include_contents:
|
65
|
+
fields = ['*']
|
66
|
+
else:
|
67
|
+
fields = self.field_names_without_content()
|
68
|
+
return self.row(where=dict(path=path), fields = fields)
|
69
|
+
|
70
|
+
def file_without_contents(self, path):
|
71
|
+
return self.file(path, include_contents=False)
|
72
|
+
|
73
|
+
def file_exists(self, path):
|
74
|
+
return self.contains(path=path)
|
75
|
+
|
76
|
+
def files(self, include_contents=False):
|
77
|
+
if include_contents:
|
78
|
+
return self.rows()
|
79
|
+
fields_names = self.field_names_without_content()
|
80
|
+
return self.rows(fields_names)
|
81
|
+
|
82
|
+
def setup(self):
|
83
|
+
if self.exists() is False:
|
84
|
+
self.create()
|
85
|
+
self.index_create('path')
|
86
|
+
return self
|
@@ -1,11 +1,11 @@
|
|
1
|
-
from osbot_utils.utils.Files import Files, file_delete, folder_delete_all, files_list, file_create,
|
1
|
+
from osbot_utils.utils.Files import Files, file_delete, folder_delete_all, files_list, file_create, \
|
2
2
|
parent_folder, file_exists, file_contents
|
3
3
|
from osbot_utils.utils.Misc import random_filename
|
4
4
|
|
5
5
|
|
6
6
|
class Temp_File:
|
7
|
-
def __init__(self, contents='...', extension='tmp'):
|
8
|
-
self.tmp_file = random_filename(extension)
|
7
|
+
def __init__(self, contents='...', extension='tmp',file_name=None, ):
|
8
|
+
self.tmp_file = file_name or random_filename(extension)
|
9
9
|
self.tmp_folder = None
|
10
10
|
self.file_path = None
|
11
11
|
self.original_contents = contents
|
@@ -30,7 +30,7 @@ class Temp_File:
|
|
30
30
|
return file_exists(self.file_path)
|
31
31
|
|
32
32
|
def file_name(self):
|
33
|
-
return file_name(self.path())
|
33
|
+
return Files.file_name(self.path())
|
34
34
|
|
35
35
|
def files_in_folder(self):
|
36
36
|
return files_list(self.tmp_folder)
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# In Misc.py
|
2
|
+
import os
|
3
|
+
|
4
|
+
from osbot_utils.utils.Files import all_parent_folders
|
5
|
+
from osbot_utils.utils.Misc import list_set
|
6
|
+
from osbot_utils.utils.Str import strip_quotes
|
7
|
+
|
8
|
+
|
9
|
+
def env_value(var_name):
|
10
|
+
return env_vars().get(var_name, None)
|
11
|
+
|
12
|
+
def env_vars_list():
|
13
|
+
return list_set(env_vars())
|
14
|
+
|
15
|
+
def env_vars(reload_vars=False):
|
16
|
+
"""
|
17
|
+
if reload_vars reload data from .env file
|
18
|
+
then return dictionary with current environment variables
|
19
|
+
"""
|
20
|
+
if reload_vars:
|
21
|
+
load_dotenv()
|
22
|
+
vars = os.environ
|
23
|
+
data = {}
|
24
|
+
for key in vars:
|
25
|
+
data[key] = vars[key]
|
26
|
+
return data
|
27
|
+
|
28
|
+
def env_load_from_file(path, override=False):
|
29
|
+
if os.path.exists(path):
|
30
|
+
with open(path) as f:
|
31
|
+
for line in f:
|
32
|
+
line = line.strip()
|
33
|
+
if not line or line.startswith('#'): # Strip whitespace and ignore comments
|
34
|
+
continue
|
35
|
+
key, value = line.split(sep='=', maxsplit=1) # Split the line into key and value
|
36
|
+
value = strip_quotes(value.strip()) # Handle case when the value is in quotes
|
37
|
+
if override or key.strip() not in os.environ: # Set the environment variable
|
38
|
+
os.environ[key.strip()] = value.strip()
|
39
|
+
|
40
|
+
def env_unload_from_file(path):
|
41
|
+
if os.path.exists(path):
|
42
|
+
with open(path) as f:
|
43
|
+
for line in f:
|
44
|
+
line = line.strip()
|
45
|
+
if not line or line.startswith('#'): # Strip whitespace and ignore comments
|
46
|
+
continue
|
47
|
+
key, _ = line.split(sep='=', maxsplit=1) # Split the line into key and value
|
48
|
+
key = key.strip()
|
49
|
+
if key in os.environ: # Remove the environment variable if it exists
|
50
|
+
del os.environ[key]
|
51
|
+
|
52
|
+
def load_dotenv(dotenv_path=None, override=False):
|
53
|
+
if dotenv_path: # If a specific dotenv path is provided, load from it
|
54
|
+
env_load_from_file(dotenv_path, override)
|
55
|
+
else:
|
56
|
+
directories = all_parent_folders(include_path=True) # Define the possible directories to search for the .env file (which is this and all parent folders)
|
57
|
+
for directory in directories: # Iterate through the directories and load the .env file if found
|
58
|
+
env_path = os.path.join(directory, '.env') # Define the path to the .env file
|
59
|
+
if os.path.exists(env_path): # If we found one
|
60
|
+
env_load_from_file(env_path, override) # Process it
|
61
|
+
break # Stop after loading the first .env file # Stop after loading the first .env file
|
62
|
+
|
63
|
+
|
64
|
+
def unload_dotenv(dotenv_path=None):
|
65
|
+
if dotenv_path: # If a specific dotenv path is provided, unload from it
|
66
|
+
env_unload_from_file(dotenv_path)
|
67
|
+
else:
|
68
|
+
directories = all_parent_folders(include_path=True) # Define the possible directories to search for the .env file (which is this and all parent folders)
|
69
|
+
for directory in directories: # Iterate through the directories and unload the .env file if found
|
70
|
+
env_path = os.path.join(directory, '.env') # Define the path to the .env file
|
71
|
+
if os.path.exists(env_path): # If we found one
|
72
|
+
env_unload_from_file(env_path) # Process it
|
73
|
+
break # Stop after unloading the first .env file
|
74
|
+
|
75
|
+
|
76
|
+
env_load = load_dotenv
|
@@ -21,7 +21,7 @@ class Files:
|
|
21
21
|
def copy(source:str, destination:str) -> str:
|
22
22
|
if file_exists(source): # make sure source file exists
|
23
23
|
destination_parent_folder = parent_folder(destination) # get target parent folder
|
24
|
-
folder_create(destination_parent_folder) # ensure
|
24
|
+
folder_create(destination_parent_folder) # ensure target folder exists # todo: check if this is still needed (we should be using a copy method that creates the required fodlers)
|
25
25
|
return shutil.copy(source, destination) # copy file and returns file destination
|
26
26
|
|
27
27
|
@staticmethod
|
@@ -308,7 +308,11 @@ class Files:
|
|
308
308
|
@staticmethod
|
309
309
|
def path_combine(path1, path2):
|
310
310
|
if type(path1) in [str, Path] and type(path2) in [str, Path]:
|
311
|
-
|
311
|
+
parent_path = str(path1)
|
312
|
+
sub_path = str(path2)
|
313
|
+
if sub_path.startswith('/'):
|
314
|
+
sub_path = sub_path[1:]
|
315
|
+
return abspath(join(parent_path,sub_path))
|
312
316
|
|
313
317
|
@staticmethod
|
314
318
|
def parent_folder(path):
|
@@ -424,13 +428,53 @@ class Files:
|
|
424
428
|
file.write(contents)
|
425
429
|
return path
|
426
430
|
|
427
|
-
# todo: refactor the methods above into static methods
|
431
|
+
# todo: refactor the methods above into static methods (as bellow)
|
428
432
|
|
433
|
+
def all_parent_folders(path=None, include_path=False):
|
434
|
+
if path is None:
|
435
|
+
path = os.getcwd()
|
436
|
+
parent_directories = []
|
429
437
|
|
438
|
+
# Optionally include the starting path
|
439
|
+
if include_path:
|
440
|
+
parent_directories.append(path)
|
441
|
+
|
442
|
+
while True: # Split the path into parts
|
443
|
+
path, tail = os.path.split(path)
|
444
|
+
if tail:
|
445
|
+
parent_directories.append(path)
|
446
|
+
else:
|
447
|
+
if path and path not in parent_directories: # to handle the root path case
|
448
|
+
parent_directories.append(path)
|
449
|
+
break
|
450
|
+
|
451
|
+
return parent_directories
|
452
|
+
def file_move(source_file, target_file):
|
453
|
+
if file_exists(source_file):
|
454
|
+
file_copy(source_file, target_file)
|
455
|
+
if file_exists(target_file):
|
456
|
+
if file_delete(source_file):
|
457
|
+
return True
|
458
|
+
return False
|
459
|
+
|
460
|
+
def folders_names_in_folder(target):
|
461
|
+
folders = folders_in_folder(target)
|
462
|
+
return folders_names(folders)
|
463
|
+
|
464
|
+
def stream_to_bytes(stream):
|
465
|
+
return stream.read()
|
466
|
+
|
467
|
+
def stream_to_file(stream, path=None):
|
468
|
+
if path is None: # if path is not defined
|
469
|
+
path = Files.temp_file() # save it to a temp file
|
470
|
+
with open(path, 'wb') as file: # Write the content to the file
|
471
|
+
file.write(stream.read())
|
472
|
+
return path
|
430
473
|
|
431
474
|
# helper methods
|
432
475
|
# todo: all all methods above (including the duplicated mappings at the top)
|
433
476
|
|
477
|
+
bytes_to_file = Files.write_bytes
|
434
478
|
create_folder = Files.folder_create
|
435
479
|
create_folder_in_parent = Files.folder_create_in_parent
|
436
480
|
create_temp_file = Files.write
|
@@ -465,6 +509,7 @@ file_open_gz = Files.open_gz
|
|
465
509
|
file_open_bytes = Files.open_bytes
|
466
510
|
file_to_base64 = Files.file_to_base64
|
467
511
|
file_from_base64 = Files.file_from_base64
|
512
|
+
file_from_bytes = Files.write_bytes
|
468
513
|
file_save = Files.save
|
469
514
|
file_sha256 = Files.contents_sha256
|
470
515
|
file_size = Files.file_size
|
@@ -7,8 +7,6 @@ import pickle
|
|
7
7
|
import types
|
8
8
|
from typing import get_origin, Union, get_args
|
9
9
|
|
10
|
-
from dotenv import load_dotenv
|
11
|
-
|
12
10
|
from osbot_utils.utils.Misc import list_set
|
13
11
|
from osbot_utils.utils.Str import str_unicode_escape, str_max_width
|
14
12
|
|
@@ -88,24 +86,6 @@ def enum_from_value(enum_type, value):
|
|
88
86
|
except KeyError:
|
89
87
|
raise ValueError(f"Value '{value}' is not a valid member of {enum_type.__name__}.") # Handle the case where the value does not match any Enum member
|
90
88
|
|
91
|
-
def env_value(var_name):
|
92
|
-
return env_vars().get(var_name, None)
|
93
|
-
|
94
|
-
def env_vars_list():
|
95
|
-
return list_set(env_vars())
|
96
|
-
|
97
|
-
def env_vars(reload_vars=False):
|
98
|
-
"""
|
99
|
-
if reload_vars reload data from .env file
|
100
|
-
then return dictionary with current environment variables
|
101
|
-
"""
|
102
|
-
if reload_vars:
|
103
|
-
load_dotenv()
|
104
|
-
vars = os.environ
|
105
|
-
data = {}
|
106
|
-
for key in vars:
|
107
|
-
data[key] = vars[key]
|
108
|
-
return data
|
109
89
|
|
110
90
|
def get_field(target, field, default=None):
|
111
91
|
if target is not None:
|
@@ -3,13 +3,19 @@ from html import escape, unescape
|
|
3
3
|
|
4
4
|
from osbot_utils.utils.Files import safe_file_name
|
5
5
|
|
6
|
+
# todo: refactor this this class all str related methods (mainly from the Misc class)
|
6
7
|
|
7
|
-
def html_escape(value):
|
8
|
+
def html_escape(value: str):
|
8
9
|
return escape(value)
|
9
10
|
|
10
|
-
def html_unescape(value):
|
11
|
+
def html_unescape(value: str):
|
11
12
|
return unescape(value)
|
12
13
|
|
14
|
+
def strip_quotes(value: str): # Remove surrounding quotes (single or double)
|
15
|
+
if (value.startswith("'") and value.endswith("'")) or (value.startswith('"') and value.endswith('"')):
|
16
|
+
return value[1:-1]
|
17
|
+
return value
|
18
|
+
|
13
19
|
def str_dedent(value, strip=True):
|
14
20
|
result = textwrap.dedent(value)
|
15
21
|
if strip:
|
@@ -1,11 +1,41 @@
|
|
1
|
+
import gzip
|
1
2
|
import io
|
2
3
|
import os
|
3
4
|
import shutil
|
5
|
+
import tarfile
|
4
6
|
import zipfile
|
5
7
|
from os.path import abspath
|
6
8
|
|
7
|
-
from osbot_utils.utils.Files import temp_folder, folder_files, temp_file, is_file
|
9
|
+
from osbot_utils.utils.Files import temp_folder, folder_files, temp_file, is_file, file_copy, file_move
|
10
|
+
|
11
|
+
|
12
|
+
def gz_tar_bytes_file_list(gz_bytes):
|
13
|
+
gz_buffer_from_bytes = io.BytesIO(gz_bytes)
|
14
|
+
with gzip.GzipFile(fileobj=gz_buffer_from_bytes, mode='rb') as gz:
|
15
|
+
decompressed_data = gz.read()
|
16
|
+
tar_buffer_from_bytes = io.BytesIO(decompressed_data) # Assuming the decompressed data is a tag file, process it
|
17
|
+
with tarfile.open(fileobj=tar_buffer_from_bytes, mode='r:') as tar:
|
18
|
+
return sorted(tar.getnames())
|
19
|
+
|
20
|
+
def gz_tar_bytes_get_file(gz_bytes, tar_file_path):
|
21
|
+
gz_buffer_from_bytes = io.BytesIO(gz_bytes)
|
22
|
+
with gzip.GzipFile(fileobj=gz_buffer_from_bytes, mode='rb') as gz:
|
23
|
+
decompressed_data = gz.read()
|
24
|
+
tar_buffer_from_bytes = io.BytesIO(decompressed_data)
|
25
|
+
with tarfile.open(fileobj=tar_buffer_from_bytes, mode='r:') as tar:
|
26
|
+
extracted_file = tar.extractfile(tar_file_path)
|
27
|
+
if extracted_file:
|
28
|
+
return extracted_file.read()
|
29
|
+
else:
|
30
|
+
raise FileNotFoundError(f"The file {tar_file_path} was not found in the tar archive.")
|
8
31
|
|
32
|
+
def gz_zip_bytes_file_list(gz_bytes):
|
33
|
+
gz_buffer_from_bytes = io.BytesIO(gz_bytes)
|
34
|
+
with gzip.GzipFile(fileobj=gz_buffer_from_bytes, mode='rb') as gz:
|
35
|
+
decompressed_data = gz.read()
|
36
|
+
zip_buffer_from_bytes = io.BytesIO(decompressed_data) # Assuming the decompressed data is a zip file, process it
|
37
|
+
with zipfile.ZipFile(zip_buffer_from_bytes, 'r') as zf:
|
38
|
+
return sorted(zf.namelist())
|
9
39
|
|
10
40
|
def unzip_file(zip_file, target_folder=None, format='zip'):
|
11
41
|
target_folder = target_folder or temp_folder()
|
@@ -28,6 +58,14 @@ def zip_bytes_get_file(zip_bytes, zip_file_path):
|
|
28
58
|
with zipfile.ZipFile(zip_buffer, 'r') as zf:
|
29
59
|
return zf.read(zip_file_path)
|
30
60
|
|
61
|
+
def zip_bytes_extract_to_folder(zip_bytes, target_folder=None):
|
62
|
+
target_folder = target_folder or temp_folder() # Use the provided target folder or create a temporary one
|
63
|
+
zip_buffer = io.BytesIO(zip_bytes) # Create a BytesIO buffer from the zip bytes
|
64
|
+
with zipfile.ZipFile(zip_buffer, 'r') as zf: # Open the zip file from the buffer
|
65
|
+
zf.extractall(target_folder) # Extract all files to the target folder
|
66
|
+
return target_folder # Return the path of the target folder
|
67
|
+
|
68
|
+
|
31
69
|
def zip_bytes_file_list(zip_bytes):
|
32
70
|
zip_buffer_from_bytes = io.BytesIO(zip_bytes)
|
33
71
|
with zipfile.ZipFile(zip_buffer_from_bytes, 'r') as zf:
|
@@ -61,6 +99,11 @@ def zip_files_to_bytes(target_files, root_folder=None):
|
|
61
99
|
def zip_folder(root_dir, format='zip'):
|
62
100
|
return shutil.make_archive(base_name=root_dir, format=format, root_dir=root_dir)
|
63
101
|
|
102
|
+
def zip_folder_to_file (root_dir, target_file):
|
103
|
+
zip_file = zip_folder(root_dir)
|
104
|
+
return file_move(zip_file, target_file)
|
105
|
+
|
106
|
+
|
64
107
|
def zip_folder_to_bytes(root_dir): # todo add unit test
|
65
108
|
zip_buffer = io.BytesIO() # Create a BytesIO buffer to hold the zipped file
|
66
109
|
with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zf: # Create a ZipFile object with the buffer as the target
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
v1.13.0
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "osbot_utils"
|
3
|
-
version = "v1.
|
3
|
+
version = "v1.13.0"
|
4
4
|
description = "OWASP Security Bot - Utils"
|
5
5
|
authors = ["Dinis Cruz <dinis.cruz@owasp.org>"]
|
6
6
|
license = "MIT"
|
@@ -10,12 +10,6 @@ repository = "https://github.com/owasp-sbot/OSBot-Utils"
|
|
10
10
|
|
11
11
|
[tool.poetry.dependencies]
|
12
12
|
python = "^3.11"
|
13
|
-
python-dotenv = "*"
|
14
|
-
|
15
|
-
#[tool.poetry.group.test.dependencies]
|
16
|
-
#pytest = "*"
|
17
|
-
#pytest-cov = "*"
|
18
|
-
#coveralls = "*"
|
19
13
|
|
20
14
|
|
21
15
|
[build-system]
|
@@ -1,23 +0,0 @@
|
|
1
|
-
from osbot_utils.decorators.methods.cache_on_self import cache_on_self
|
2
|
-
from osbot_utils.helpers.sqlite.domains.Sqlite__DB__Local import Sqlite__DB__Local
|
3
|
-
from osbot_utils.helpers.sqlite.tables.Sqlite__Table__Files import Sqlite__Table__Files
|
4
|
-
|
5
|
-
|
6
|
-
class Sqlite__DB__Files(Sqlite__DB__Local):
|
7
|
-
|
8
|
-
def __init__(self, db_path=None, db_name=None):
|
9
|
-
super().__init__(db_path=db_path, db_name=db_name)
|
10
|
-
|
11
|
-
def add_file(self, path, contents=None, metadata=None):
|
12
|
-
return self.table_files().add_file(path, contents, metadata)
|
13
|
-
|
14
|
-
@cache_on_self
|
15
|
-
def table_files(self):
|
16
|
-
return Sqlite__Table__Files(database=self).setup()
|
17
|
-
|
18
|
-
def files(self):
|
19
|
-
return self.table_files().files()
|
20
|
-
|
21
|
-
def setup(self):
|
22
|
-
self.table_files()
|
23
|
-
return self
|
@@ -1,45 +0,0 @@
|
|
1
|
-
from osbot_utils.base_classes.Kwargs_To_Self import Kwargs_To_Self
|
2
|
-
from osbot_utils.helpers.sqlite.Sqlite__Table import Sqlite__Table
|
3
|
-
from osbot_utils.utils.Misc import timestamp_utc_now
|
4
|
-
|
5
|
-
SQLITE__TABLE_NAME__FILES = 'files'
|
6
|
-
|
7
|
-
class Schema__Table__Files(Kwargs_To_Self):
|
8
|
-
path : str
|
9
|
-
contents : bytes
|
10
|
-
metadata : bytes
|
11
|
-
timestamp: int
|
12
|
-
|
13
|
-
|
14
|
-
class Sqlite__Table__Files(Sqlite__Table):
|
15
|
-
auto_pickle_blob : bool = True
|
16
|
-
set_timestamp : bool = True
|
17
|
-
|
18
|
-
def __init__(self, **kwargs):
|
19
|
-
self.table_name = SQLITE__TABLE_NAME__FILES
|
20
|
-
self.row_schema = Schema__Table__Files
|
21
|
-
super().__init__(**kwargs)
|
22
|
-
|
23
|
-
def add_file(self, path, contents=None, metadata= None):
|
24
|
-
if self.contains(path=path): # don't allow multiple entries for the same file path (until we add versioning support)
|
25
|
-
return None
|
26
|
-
row_data = self.create_node_data(path, contents, metadata)
|
27
|
-
return self.add_row_and_commit(**row_data)
|
28
|
-
|
29
|
-
def create_node_data(self, path, contents=None, metadata= None):
|
30
|
-
node_data = {'path' : path ,
|
31
|
-
'contents': contents ,
|
32
|
-
'metadata': metadata }
|
33
|
-
if self.set_timestamp:
|
34
|
-
node_data['timestamp'] = timestamp_utc_now()
|
35
|
-
return node_data
|
36
|
-
|
37
|
-
|
38
|
-
def files(self):
|
39
|
-
return self.rows()
|
40
|
-
|
41
|
-
def setup(self):
|
42
|
-
if self.exists() is False:
|
43
|
-
self.create()
|
44
|
-
self.index_create('path')
|
45
|
-
return self
|