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.
Files changed (293) hide show
  1. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/PKG-INFO +2 -2
  2. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/README.md +1 -1
  3. osbot_utils-1.28.0/osbot_utils/helpers/Zip_Bytes.py +79 -0
  4. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Temp_Folder.py +5 -1
  5. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Temp_Zip.py +8 -4
  6. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Temp_Zip_In_Memory.py +4 -4
  7. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Files.py +47 -11
  8. osbot_utils-1.28.0/osbot_utils/utils/Zip.py +235 -0
  9. osbot_utils-1.28.0/osbot_utils/version +1 -0
  10. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/pyproject.toml +1 -1
  11. osbot_utils-1.26.0/osbot_utils/utils/Zip.py +0 -140
  12. osbot_utils-1.26.0/osbot_utils/version +0 -1
  13. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/LICENSE +0 -0
  14. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/__init__.py +0 -0
  15. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/base_classes/Cache_Pickle.py +0 -0
  16. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/base_classes/Kwargs_To_Disk.py +0 -0
  17. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/base_classes/Kwargs_To_Self.py +0 -0
  18. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/base_classes/Type_Safe.py +0 -0
  19. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/base_classes/Type_Safe__List.py +0 -0
  20. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/base_classes/__init__.py +0 -0
  21. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/context_managers/__init__.py +0 -0
  22. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/context_managers/capture_duration.py +0 -0
  23. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/context_managers/disable_root_loggers.py +0 -0
  24. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/__init__.py +0 -0
  25. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/classes/__init__.py +0 -0
  26. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/classes/singleton.py +0 -0
  27. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/lists/__init__.py +0 -0
  28. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/lists/filter_list.py +0 -0
  29. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/lists/group_by.py +0 -0
  30. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/lists/index_by.py +0 -0
  31. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/__init__.py +0 -0
  32. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/cache.py +0 -0
  33. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/cache_on_function.py +0 -0
  34. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/cache_on_self.py +0 -0
  35. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/cache_on_tmp.py +0 -0
  36. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/capture_exception.py +0 -0
  37. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/capture_status.py +0 -0
  38. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/catch.py +0 -0
  39. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/context.py +0 -0
  40. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/depreciated.py +0 -0
  41. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/function_type_check.py +0 -0
  42. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/obj_as_context.py +0 -0
  43. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/remove_return_value.py +0 -0
  44. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/decorators/methods/required_fields.py +0 -0
  45. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/fluent/Fluent_Dict.py +0 -0
  46. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/fluent/Fluent_List.py +0 -0
  47. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/fluent/__init__.py +0 -0
  48. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/__init__.py +0 -0
  49. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/Mermaid.py +0 -0
  50. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/Mermaid__Edge.py +0 -0
  51. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/Mermaid__Graph.py +0 -0
  52. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/Mermaid__Node.py +0 -0
  53. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/Mermaid__Renderer.py +0 -0
  54. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/configs/Mermaid__Edge__Config.py +0 -0
  55. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/configs/Mermaid__Node__Config.py +0 -0
  56. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/configs/Mermaid__Render__Config.py +0 -0
  57. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/examples/Mermaid_Examples__FlowChart.py +0 -0
  58. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/models/Mermaid__Diagram_Direction.py +0 -0
  59. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/models/Mermaid__Diagram__Type.py +0 -0
  60. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mermaid/models/Mermaid__Node__Shape.py +0 -0
  61. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mgraph/MGraph.py +0 -0
  62. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mgraph/MGraph__Config.py +0 -0
  63. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mgraph/MGraph__Data.py +0 -0
  64. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mgraph/MGraph__Edge.py +0 -0
  65. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mgraph/MGraph__Node.py +0 -0
  66. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mgraph/MGraph__Random_Graphs.py +0 -0
  67. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mgraph/MGraph__Serializer.py +0 -0
  68. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mgraph/MGraphs.py +0 -0
  69. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/graphs/mgraph/__init__.py +0 -0
  70. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/CFormat.py +0 -0
  71. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/CPrint.py +0 -0
  72. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/Dict_To_Attr.py +0 -0
  73. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/Local_Cache.py +0 -0
  74. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/Local_Caches.py +0 -0
  75. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/Print_Table.py +0 -0
  76. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/Python_Audit.py +0 -0
  77. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/Random_Seed.py +0 -0
  78. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/Type_Registry.py +0 -0
  79. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/__init__.py +0 -0
  80. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/Ast.py +0 -0
  81. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/Ast_Base.py +0 -0
  82. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/Ast_Data.py +0 -0
  83. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/Ast_Load.py +0 -0
  84. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/Ast_Merge.py +0 -0
  85. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/Ast_Node.py +0 -0
  86. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/Ast_Visit.py +0 -0
  87. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/Call_Tree.py +0 -0
  88. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/__init__.py +0 -0
  89. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Add.py +0 -0
  90. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Alias.py +0 -0
  91. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_And.py +0 -0
  92. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Argument.py +0 -0
  93. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Arguments.py +0 -0
  94. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Assert.py +0 -0
  95. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Assign.py +0 -0
  96. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Attribute.py +0 -0
  97. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Aug_Assign.py +0 -0
  98. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Bin_Op.py +0 -0
  99. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Bool_Op.py +0 -0
  100. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Break.py +0 -0
  101. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Call.py +0 -0
  102. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Class_Def.py +0 -0
  103. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Compare.py +0 -0
  104. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Comprehension.py +0 -0
  105. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Constant.py +0 -0
  106. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Continue.py +0 -0
  107. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Dict.py +0 -0
  108. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Eq.py +0 -0
  109. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Except_Handler.py +0 -0
  110. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Expr.py +0 -0
  111. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_For.py +0 -0
  112. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Function_Def.py +0 -0
  113. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Generator_Exp.py +0 -0
  114. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Gt.py +0 -0
  115. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_GtE.py +0 -0
  116. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_If.py +0 -0
  117. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_If_Exp.py +0 -0
  118. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Import.py +0 -0
  119. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Import_From.py +0 -0
  120. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_In.py +0 -0
  121. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Is.py +0 -0
  122. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Is_Not.py +0 -0
  123. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Keyword.py +0 -0
  124. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Lambda.py +0 -0
  125. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_List.py +0 -0
  126. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_List_Comp.py +0 -0
  127. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Load.py +0 -0
  128. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Lt.py +0 -0
  129. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_LtE.py +0 -0
  130. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Mod.py +0 -0
  131. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Module.py +0 -0
  132. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Mult.py +0 -0
  133. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Name.py +0 -0
  134. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Not.py +0 -0
  135. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Not_Eq.py +0 -0
  136. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Not_In.py +0 -0
  137. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Or.py +0 -0
  138. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Pass.py +0 -0
  139. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Pow.py +0 -0
  140. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Raise.py +0 -0
  141. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Return.py +0 -0
  142. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Set.py +0 -0
  143. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Slice.py +0 -0
  144. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Starred.py +0 -0
  145. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Store.py +0 -0
  146. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Sub.py +0 -0
  147. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Subscript.py +0 -0
  148. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Try.py +0 -0
  149. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Tuple.py +0 -0
  150. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Unary_Op.py +0 -0
  151. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_While.py +0 -0
  152. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_With.py +0 -0
  153. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_With_Item.py +0 -0
  154. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/Ast_Yield.py +0 -0
  155. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ast/nodes/__init__.py +0 -0
  156. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Actions.py +0 -0
  157. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Config.py +0 -0
  158. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Data.py +0 -0
  159. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Invoke.py +0 -0
  160. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Row.py +0 -0
  161. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Table.py +0 -0
  162. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/cache_requests/__init__.py +0 -0
  163. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/cache_requests/flows/flow__Cache__Requests.py +0 -0
  164. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/flows/Flow.py +0 -0
  165. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/flows/Task.py +0 -0
  166. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/flows/__init__.py +0 -0
  167. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Dict_To_Css.py +0 -0
  168. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Dict_To_Html.py +0 -0
  169. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Dict_To_Tags.py +0 -0
  170. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Html_To_Dict.py +0 -0
  171. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Html_To_Tag.py +0 -0
  172. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Tag__Base.py +0 -0
  173. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Tag__Body.py +0 -0
  174. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Tag__Div.py +0 -0
  175. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Tag__H.py +0 -0
  176. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Tag__HR.py +0 -0
  177. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Tag__Head.py +0 -0
  178. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Tag__Html.py +0 -0
  179. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Tag__Link.py +0 -0
  180. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/Tag__Style.py +0 -0
  181. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/html/__init__.py +0 -0
  182. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/Event__Queue.py +0 -0
  183. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/PubSub__Client.py +0 -0
  184. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/PubSub__Room.py +0 -0
  185. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/PubSub__Server.py +0 -0
  186. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/PubSub__Sqlite.py +0 -0
  187. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/__init__.py +0 -0
  188. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event.py +0 -0
  189. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Connect.py +0 -0
  190. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Disconnect.py +0 -0
  191. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Join_Room.py +0 -0
  192. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Leave_Room.py +0 -0
  193. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Message.py +0 -0
  194. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/schemas/Schema__PubSub__Client.py +0 -0
  195. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/pubsub/schemas/__init__.py +0 -0
  196. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/Capture_Sqlite_Error.py +0 -0
  197. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/Sqlite__Cursor.py +0 -0
  198. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/Sqlite__Database.py +0 -0
  199. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/Sqlite__Field.py +0 -0
  200. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/Sqlite__Globals.py +0 -0
  201. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/Sqlite__Table.py +0 -0
  202. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/Sqlite__Table__Create.py +0 -0
  203. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/Temp_Sqlite__Database__Disk.py +0 -0
  204. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/Temp_Sqlite__Table.py +0 -0
  205. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/__init__.py +0 -0
  206. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/cache/Schema__Table__Requests.py +0 -0
  207. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests.py +0 -0
  208. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Patch.py +0 -0
  209. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Sqlite.py +0 -0
  210. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Table.py +0 -0
  211. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/cache/Sqlite__DB__Requests.py +0 -0
  212. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/cache/TestCase__Sqlite__Cache__Requests.py +0 -0
  213. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/cache/__init__.py +0 -0
  214. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Files.py +0 -0
  215. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Graph.py +0 -0
  216. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Json.py +0 -0
  217. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Local.py +0 -0
  218. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/domains/__init__.py +0 -0
  219. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/domains/schemas/__init__.py +0 -0
  220. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/models/Sqlite__Field__Type.py +0 -0
  221. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/models/__init__.py +0 -0
  222. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/sample_data/Sqlite__Sample_Data__Chinook.py +0 -0
  223. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/sample_data/__init__.py +0 -0
  224. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/sql_builder/SQL_Builder.py +0 -0
  225. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/sql_builder/SQL_Builder__Select.py +0 -0
  226. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/sql_builder/__init__.py +0 -0
  227. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Config.py +0 -0
  228. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Edges.py +0 -0
  229. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Files.py +0 -0
  230. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Nodes.py +0 -0
  231. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/sqlite/tables/__init__.py +0 -0
  232. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ssh/SCP.py +0 -0
  233. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ssh/SSH.py +0 -0
  234. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ssh/SSH__Cache__Requests.py +0 -0
  235. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ssh/SSH__Execute.py +0 -0
  236. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ssh/SSH__Health_Check.py +0 -0
  237. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ssh/SSH__Linux.py +0 -0
  238. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ssh/SSH__Linux__Amazon.py +0 -0
  239. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ssh/SSH__Python.py +0 -0
  240. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ssh/TestCase__SSH.py +0 -0
  241. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/ssh/__init__.py +0 -0
  242. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Call.py +0 -0
  243. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Call__Config.py +0 -0
  244. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Call__Graph.py +0 -0
  245. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Call__Handler.py +0 -0
  246. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Call__Print_Lines.py +0 -0
  247. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Call__Print_Traces.py +0 -0
  248. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Call__Stack.py +0 -0
  249. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Call__Stack_Node.py +0 -0
  250. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Call__Stats.py +0 -0
  251. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Call__View_Model.py +0 -0
  252. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/Trace_Files.py +0 -0
  253. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/helpers/trace/__init__.py +0 -0
  254. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Catch.py +0 -0
  255. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Duration.py +0 -0
  256. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Hook_Method.py +0 -0
  257. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Log_To_Queue.py +0 -0
  258. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Log_To_String.py +0 -0
  259. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Logging.py +0 -0
  260. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Patch_Print.py +0 -0
  261. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Profiler.py +0 -0
  262. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Pytest.py +0 -0
  263. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Stderr.py +0 -0
  264. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Stdout.py +0 -0
  265. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Temp_Env_Vars.py +0 -0
  266. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Temp_File.py +0 -0
  267. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Temp_Sys_Path.py +0 -0
  268. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Temp_Web_Server.py +0 -0
  269. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Unit_Test.py +0 -0
  270. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/Unzip_File.py +0 -0
  271. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/testing/__init__.py +0 -0
  272. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Assert.py +0 -0
  273. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Call_Stack.py +0 -0
  274. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Csv.py +0 -0
  275. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Dev.py +0 -0
  276. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Env.py +0 -0
  277. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Exceptions.py +0 -0
  278. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Functions.py +0 -0
  279. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Http.py +0 -0
  280. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Int.py +0 -0
  281. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Json.py +0 -0
  282. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Json_Cache.py +0 -0
  283. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Lists.py +0 -0
  284. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Misc.py +0 -0
  285. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Objects.py +0 -0
  286. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Png.py +0 -0
  287. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Process.py +0 -0
  288. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Python_Logger.py +0 -0
  289. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Status.py +0 -0
  290. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Str.py +0 -0
  291. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Toml.py +0 -0
  292. {osbot_utils-1.26.0 → osbot_utils-1.28.0}/osbot_utils/utils/Version.py +0 -0
  293. {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.26.0
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
- ![Current Release](https://img.shields.io/badge/release-v1.26.0-blue)
25
+ ![Current Release](https://img.shields.io/badge/release-v1.28.0-blue)
26
26
  [![codecov](https://codecov.io/gh/owasp-sbot/OSBot-Utils/graph/badge.svg?token=GNVW0COX1N)](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
- ![Current Release](https://img.shields.io/badge/release-v1.26.0-blue)
5
+ ![Current Release](https://img.shields.io/badge/release-v1.28.0-blue)
6
6
  [![codecov](https://codecov.io/gh/owasp-sbot/OSBot-Utils/graph/badge.svg?token=GNVW0COX1N)](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
- from osbot_utils.utils.Zip import zip_folder, zip_file_list
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 zip_file_list(self.zip_file)
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, zip_bytes_file_list, zip_bytes_add_file, zip_bytes_get_file
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 = zip_bytes_add_file(zip_bytes, file_path, file_contents)
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 zip_bytes_get_file(self.zip_bytes(), file_path)
83
+ return zip_bytes__get_file(self.zip_bytes(), file_path)
84
84
 
85
85
  def zip_bytes_files(self):
86
- return zip_bytes_file_list(self.zip_bytes())
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= '*.*'): # todo: check behaviour and improve ability to detect file (vs folders)
84
+ def files(path, pattern= '*.*', only_files=True):
83
85
  result = []
84
86
  for file in Path(path).rglob(pattern):
85
- result.append(str(file)) # todo: see if there is a better way to do this conversion to string
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
- if type(path1) in [str, Path] and type(path2) in [str, Path]:
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))
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
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "osbot_utils"
3
- version = "v1.26.0"
3
+ version = "v1.28.0"
4
4
  description = "OWASP Security Bot - Utils"
5
5
  authors = ["Dinis Cruz <dinis.cruz@owasp.org>"]
6
6
  license = "MIT"