abstract-utilities 0.2.2.593__py3-none-any.whl → 0.2.2.667__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of abstract-utilities might be problematic. Click here for more details.

Files changed (47) hide show
  1. abstract_utilities/__init__.py +13 -4
  2. abstract_utilities/class_utils/abstract_classes.py +104 -34
  3. abstract_utilities/class_utils/caller_utils.py +39 -0
  4. abstract_utilities/class_utils/global_utils.py +35 -21
  5. abstract_utilities/class_utils/imports/imports.py +1 -1
  6. abstract_utilities/directory_utils/src/directory_utils.py +2 -0
  7. abstract_utilities/file_utils/imports/classes.py +59 -55
  8. abstract_utilities/file_utils/src/file_filters/__init__.py +0 -3
  9. abstract_utilities/file_utils/src/file_filters/ensure_utils.py +382 -10
  10. abstract_utilities/file_utils/src/file_filters/filter_params.py +64 -0
  11. abstract_utilities/file_utils/src/file_filters/predicate_utils.py +21 -91
  12. abstract_utilities/file_utils/src/initFunctionsGen.py +36 -23
  13. abstract_utilities/file_utils/src/initFunctionsGens.py +280 -0
  14. abstract_utilities/import_utils/imports/__init__.py +1 -1
  15. abstract_utilities/import_utils/imports/init_imports.py +3 -0
  16. abstract_utilities/import_utils/imports/module_imports.py +2 -1
  17. abstract_utilities/import_utils/imports/utils.py +1 -1
  18. abstract_utilities/import_utils/src/__init__.py +1 -0
  19. abstract_utilities/import_utils/src/extract_utils.py +2 -2
  20. abstract_utilities/import_utils/src/import_functions.py +30 -10
  21. abstract_utilities/import_utils/src/import_utils.py +39 -0
  22. abstract_utilities/import_utils/src/layze_import_utils/__init__.py +2 -0
  23. abstract_utilities/import_utils/src/layze_import_utils/lazy_utils.py +41 -0
  24. abstract_utilities/import_utils/src/layze_import_utils/nullProxy.py +32 -0
  25. abstract_utilities/import_utils/src/nullProxy.py +30 -0
  26. abstract_utilities/import_utils/src/sysroot_utils.py +1 -1
  27. abstract_utilities/imports.py +3 -2
  28. abstract_utilities/json_utils/json_utils.py +11 -3
  29. abstract_utilities/log_utils/log_file.py +73 -25
  30. abstract_utilities/parse_utils/parse_utils.py +23 -0
  31. abstract_utilities/path_utils/imports/module_imports.py +1 -1
  32. abstract_utilities/path_utils/path_utils.py +7 -12
  33. abstract_utilities/read_write_utils/imports/imports.py +1 -1
  34. abstract_utilities/read_write_utils/read_write_utils.py +102 -32
  35. abstract_utilities/type_utils/__init__.py +5 -1
  36. abstract_utilities/type_utils/get_type.py +116 -0
  37. abstract_utilities/type_utils/imports/__init__.py +1 -0
  38. abstract_utilities/type_utils/imports/constants.py +134 -0
  39. abstract_utilities/type_utils/imports/module_imports.py +25 -1
  40. abstract_utilities/type_utils/is_type.py +455 -0
  41. abstract_utilities/type_utils/make_type.py +126 -0
  42. abstract_utilities/type_utils/mime_types.py +68 -0
  43. abstract_utilities/type_utils/type_utils.py +0 -877
  44. {abstract_utilities-0.2.2.593.dist-info → abstract_utilities-0.2.2.667.dist-info}/METADATA +1 -1
  45. {abstract_utilities-0.2.2.593.dist-info → abstract_utilities-0.2.2.667.dist-info}/RECORD +47 -36
  46. {abstract_utilities-0.2.2.593.dist-info → abstract_utilities-0.2.2.667.dist-info}/WHEEL +0 -0
  47. {abstract_utilities-0.2.2.593.dist-info → abstract_utilities-0.2.2.667.dist-info}/top_level.txt +0 -0
@@ -26,6 +26,13 @@ from .imports import *
26
26
 
27
27
  logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
28
28
  logger = logging.getLogger(__name__)
29
+ def get_keys(mapping,typ=None):
30
+ typ = typ or set
31
+ if isinstance(mapping,dict):
32
+ mapping = mapping.keys()
33
+ return typ(mapping)
34
+ def make_key_map(dict_obj):
35
+ return {k:get_keys(v) for k,v in dict_obj.items()}
29
36
  def convert_and_normalize_values(values):
30
37
  for value in values:
31
38
  if isinstance(value, str):
@@ -116,10 +123,11 @@ def safe_dump_to_file(data, file_path=None, ensure_ascii=False, indent=4, *args,
116
123
  else:
117
124
  logger.error("file_path and data must be provided to safe_dump_to_file")
118
125
 
119
- def safe_read_from_json(*args,**kwargs):
126
+ def safe_read_from_json(file_path,*args,**kwargs):
120
127
  is_read=True
121
- file_path = args[0]
122
- valid_file_path = get_file_path(*args,is_read=is_read,**kwargs)
128
+
129
+
130
+ valid_file_path = get_file_path(file_path,*args,is_read=is_read,**kwargs)
123
131
  if valid_file_path:
124
132
  file_path = valid_file_path
125
133
  try:
@@ -1,42 +1,90 @@
1
1
  from .imports import *
2
- def get_logFile(bpName: str = None, maxBytes: int = 100_000, backupCount: int = 3) -> logging.Logger:
2
+ import os, sys, inspect, logging
3
+ from logging.handlers import RotatingFileHandler
4
+
5
+ PACKAGE_NAME = "abstract_utilities" # ← update if needed
6
+
7
+
8
+ def _resolve_log_root():
3
9
  """
4
- If bpName is None, use the “caller module’s basename” as the logger name.
5
- Otherwise, use the explicitly provided bpName.
10
+ Returns a safe writable logging directory depending on environment:
11
+ - If running in a virtualenv → <venv>/.logs/<package>
12
+ - Else if user writable → ~/.cache/<package>/logs
13
+ - Else → /var/log/<package>
14
+ """
15
+ # 1) Virtualenv or Conda environment
16
+ venv = os.getenv("VIRTUAL_ENV") or os.getenv("CONDA_PREFIX")
17
+ if venv:
18
+ root = os.path.join(venv, ".logs", PACKAGE_NAME)
19
+ os.makedirs(root, exist_ok=True)
20
+ return root
21
+
22
+ # 2) User home cache folder
23
+ home = os.path.expanduser("~")
24
+ user_cache_root = os.path.join(home, ".cache", PACKAGE_NAME, "logs")
25
+ try:
26
+ os.makedirs(user_cache_root, exist_ok=True)
27
+ return user_cache_root
28
+ except PermissionError:
29
+ pass
30
+
31
+ # 3) Last resort: system log dir (requires correct service user permissions)
32
+ system_root = f"/var/log/{PACKAGE_NAME}"
33
+ try:
34
+ os.makedirs(system_root, exist_ok=True)
35
+ return system_root
36
+ except PermissionError:
37
+ # Fail-safe fallback to /tmp
38
+ fallback = f"/tmp/{PACKAGE_NAME}/logs"
39
+ os.makedirs(fallback, exist_ok=True)
40
+ return fallback
41
+
42
+
43
+ LOG_ROOT = _resolve_log_root()
44
+
45
+
46
+ def get_logFile(bpName=None, maxBytes=100_000, backupCount=3):
47
+ """
48
+ A logger that always writes to a safe OS-appropriate path.
49
+ Works even when installed through pip.
6
50
  """
7
51
  if bpName is None:
8
- # Find the first frame outside logging_utils.py
9
52
  frame_idx = _find_caller_frame_index()
10
53
  frame_info = inspect.stack()[frame_idx]
11
- caller_path = frame_info.filename # e.g. "/home/joe/project/app/routes.py"
54
+ caller_path = frame_info.filename
12
55
  bpName = os.path.splitext(os.path.basename(caller_path))[0]
13
56
  del frame_info
14
57
 
15
-
16
-
17
- logger = logging.getLogger(bpName)
58
+ logger = logging.getLogger(f"{PACKAGE_NAME}.{bpName}")
18
59
  logger.setLevel(logging.INFO)
19
60
 
20
61
  if not logger.handlers:
21
- try:
22
- log_dir = mkdirs("logs")
23
- log_path = os.path.join(log_dir, f"{bpName}.log")
24
- handler = RotatingFileHandler(log_path, maxBytes=maxBytes, backupCount=backupCount)
25
- handler.setLevel(logging.INFO)
26
-
27
- fmt = "%(asctime)s - %(levelname)s - %(pathname)s - %(message)s"
28
- formatter = logging.Formatter(fmt)
29
- handler.setFormatter(formatter)
30
- logger.addHandler(handler)
31
-
32
- console = logging.StreamHandler()
33
- console.setLevel(logging.INFO)
34
- console.setFormatter(formatter)
35
- logger.addHandler(console)
36
- except Exception as e:
37
- print(f"{e}")
62
+ log_file = os.path.join(LOG_ROOT, f"{bpName}.log")
63
+ handler = RotatingFileHandler(log_file, maxBytes=maxBytes, backupCount=backupCount)
64
+
65
+ fmt = "%(asctime)s - %(levelname)s - %(pathname)s:%(lineno)d - %(message)s"
66
+ formatter = logging.Formatter(fmt)
67
+ handler.setFormatter(formatter)
68
+
69
+ logger.addHandler(handler)
70
+
71
+ # Console handler (optional; can disable for gunicorn)
72
+ console = logging.StreamHandler(sys.stdout)
73
+ console.setFormatter(formatter)
74
+ logger.addHandler(console)
75
+
38
76
  return logger
39
77
 
78
+
79
+ def _find_caller_frame_index():
80
+ """Find the correct caller module outside this logger."""
81
+ for idx, frame_info in enumerate(inspect.stack()):
82
+ if idx == 0:
83
+ continue
84
+ module = inspect.getmodule(frame_info.frame)
85
+ if module and module.__name__ not in (__name__, "logging"):
86
+ return idx
87
+ return 1
40
88
  def _find_caller_frame_index():
41
89
  """
42
90
  Scan up the call stack until we find a frame whose module is NOT logging_utils.
@@ -64,6 +64,29 @@ def detect_language_from_text(text: str):
64
64
 
65
65
  likely = [lang for lang, score in scores.items() if score == max_score]
66
66
  return likely[0] if len(likely) == 1 else 'uncertain'
67
+ def get_tripple_string(string):
68
+ nustring = ''
69
+ for i in range(3):
70
+ nustring +=string
71
+ return nustring
72
+ def get_within_quotes(text,quotes=None):
73
+ quotes_strings = quotes or ["'",'"']
74
+ in_quotes = []
75
+ for quotes_string in quotes_strings:
76
+ if not isinstance(quotes_string,list):
77
+ tripple= get_tripple_string(quotes_string)
78
+ texts = [text]
79
+ if tripple in text:
80
+ texts= text.split(tripple)
81
+ for text_part in texts:
82
+ quote_count = len(text_part) - len(text_part.replace(quotes_string,''))
83
+ quote_spl = text_part.split(quotes_string)
84
+ in_quotes+=[quote_spl[i] for i in range(quote_count) if ((i == 1 or i%2 != float(0)) and len(quote_spl) > i)]
85
+ else:
86
+ texts= text.split(quotes_string[0])
87
+ for text in texts:
88
+ in_quotes.append(text.split(quotes_string[1])[0])
89
+ return in_quotes
67
90
 
68
91
  def search_code(code_languages, parts):
69
92
  return [data for datas in parts for data in make_list(datas)
@@ -2,7 +2,7 @@ from ...string_utils import eatAll
2
2
  from ...list_utils import make_list
3
3
  from ...type_utils import get_media_exts, is_media_type,MIME_TYPES
4
4
  from ...safe_utils import safe_join,get_slash
5
- from ...class_utils import get_caller_path,get_caller_dir
5
+ from ...class_utils import get_caller_path,get_caller_dir,get_initial_caller,get_initial_caller_dir
6
6
  from ...file_utils import is_file,is_dir,is_exists
7
7
  from ...ssh_utils import is_file,is_dir,is_exists
8
8
  from ...directory_utils import *
@@ -107,17 +107,6 @@ def path_join(*paths, isfile=False):
107
107
  os.makedirs(final_path, exist_ok=True)
108
108
  return final_path
109
109
 
110
- def is_file(*paths):
111
- item_path = os.path.join(*paths)
112
- return os.path.isfile(item_path)
113
-
114
- def is_dir(*paths):
115
- item_path = os.path.join(*paths)
116
- return os.path.isdir(item_path)
117
-
118
- def is_path(*paths):
119
- item_path = os.path.join(*paths)
120
- return item_path if os.path.exists(item_path) else None
121
110
 
122
111
  def get_all_directories(directory):
123
112
  dir_list = os.listdir(directory)
@@ -132,7 +121,7 @@ def get_all_files(directory=None):
132
121
 
133
122
  def get_all_items(directory):
134
123
  dir_list = os.listdir(directory)
135
- file_list = [item for item in dir_list if is_path(directory,item)]
124
+ file_list = [item for item in dir_list if is_exists(directory,item)]
136
125
  return file_list
137
126
 
138
127
 
@@ -176,6 +165,7 @@ def get_safe_splitext(path=None,basename=None):
176
165
  basename_str = str(basename)
177
166
  filename,ext = os.path.splitext(basename_str)
178
167
  return filename,ext
168
+ return None,None
179
169
  def get_safe_filename(path=None,basename=None):
180
170
  filename,_ = get_safe_splitext(path=path,basename=basename)
181
171
  return filename
@@ -223,6 +213,11 @@ def create_base_dir(directory=None, child=None):
223
213
 
224
214
 
225
215
 
216
+ def get_abs_path(path,i=None):
217
+ abs_dir = get_initial_caller_dir()
218
+ return os.path.join(abs_dir,path)
219
+
220
+
226
221
 
227
222
  def get_file_parts(path):
228
223
  if path:
@@ -1,2 +1,2 @@
1
1
  from ...imports import os,shlex
2
-
2
+ import base64
@@ -194,45 +194,115 @@ def write_to_path(
194
194
  ## f.write(str(contents))
195
195
  ## return file_path
196
196
  # --- Core functionality -------------------------------------------------------
197
- def write_to_file(*args, **kwargs):
197
+ ##def write_to_file(*args, **kwargs):
198
+ ## """
199
+ ## Write contents to a file (create if missing).
200
+ ##
201
+ ## Returns the file_path written.
202
+ ## """
203
+ ## file_path, contents = check_read_write_params(*args, **kwargs)
204
+ ## values,kwargs = get_from_kwargs(['file_path','contents'],del_kwarg=True,**kwargs)
205
+ ## dirname = os.path.dirname(file_path)
206
+ ##
207
+ ## if contents is None:
208
+ ## raise ValueError("Missing contents to write.")
209
+ ## user_at_host = kwargs.get("user_at_host")
210
+ ## if get_user_pass_host_key(**kwargs):
211
+ ## make_dirs(dirname, exist_ok=True,**kwargs)
212
+ ## kwargs["cwd"] = kwargs.get('cwd') or os.path.dirname(file_path)
213
+ ## # sanitize for shell safety
214
+ ## quoted_path = shlex.quote(file_path)
215
+ ## quoted_data = shlex.quote(str(contents))
216
+ ## # shell command that fully overwrites
217
+ ## # (no append, replaces contents entirely)
218
+ ## kwargs["cmd"] = f'sh -c "echo {quoted_data} > {quoted_path}"'
219
+ ## if not kwargs.get('password') and not kwargs.get('key'):
220
+ ## kwargs["cmd"]=f'sudo {kwargs["cmd"]}'
221
+ ## result = run_pruned_func(run_cmd,**kwargs)
222
+ ## if 'file_path' in kwargs:
223
+ ## del kwargs['file_path']
224
+ ## if not is_file(file_path,**kwargs) or str(contents) != read_from_file(file_path,**kwargs):
225
+ ## kwargs["cmd"]=f'sudo {kwargs["cmd"]}'
226
+ ## result = run_pruned_func(run_cmd,**kwargs)
227
+ ## return result
228
+ ##
229
+ ## make_dirs(dirname or ".", exist_ok=True)
230
+ ## with open(file_path, "w", encoding="utf-8") as f:
231
+ ## f.write(str(contents))
232
+ ## return file_path
233
+
234
+ def _should_use_remote(**kwargs) -> bool:
235
+ """
236
+ Only use remote mode IF:
237
+ - user_at_host is provided
238
+ - AND password/key is provided
239
+ Otherwise: local write.
198
240
  """
199
- Write contents to a file (create if missing).
241
+ user = kwargs.get("user_at_host")
242
+ if not user:
243
+ return False # not remote
244
+
245
+ # If user_at_host is provided, then password or key MUST be present
246
+ if kwargs.get("password") or kwargs.get("key"):
247
+ return True
200
248
 
201
- Returns the file_path written.
249
+ return False # user provided but no auth → treat as local
250
+
251
+
252
+ def _write_to_file(contents: str, file_path: str, **kwargs) -> str:
202
253
  """
203
- file_path, contents = check_read_write_params(*args, **kwargs)
204
- values,kwargs = get_from_kwargs(['file_path','contents'],del_kwarg=True,**kwargs)
254
+ Safe writer that handles arbitrarily large files.
255
+ Uses native I/O for local writes and streams for remote.
256
+ """
257
+
258
+ remote = _should_use_remote(**kwargs)
205
259
  dirname = os.path.dirname(file_path)
206
-
207
- if contents is None:
208
- raise ValueError("Missing contents to write.")
209
- user_at_host = kwargs.get("user_at_host")
210
- if get_user_pass_host_key(**kwargs):
211
- make_dirs(dirname, exist_ok=True,**kwargs)
212
- kwargs["cwd"] = kwargs.get('cwd') or os.path.dirname(file_path)
213
- # sanitize for shell safety
214
- quoted_path = shlex.quote(file_path)
215
- quoted_data = shlex.quote(str(contents))
216
- # shell command that fully overwrites
217
- # (no append, replaces contents entirely)
218
- kwargs["cmd"] = f'sh -c "echo {quoted_data} > {quoted_path}"'
219
- if not kwargs.get('password') and not kwargs.get('key'):
220
- kwargs["cmd"]=f'sudo {kwargs["cmd"]}'
221
- result = run_pruned_func(run_cmd,**kwargs)
222
- if 'file_path' in kwargs:
223
- del kwargs['file_path']
224
- if not is_file(file_path,**kwargs) or str(contents) != read_from_file(file_path,**kwargs):
225
- kwargs["cmd"]=f'sudo {kwargs["cmd"]}'
226
- result = run_pruned_func(run_cmd,**kwargs)
227
- return result
260
+ make_dirs(dirname, exist_ok=True, **kwargs)
261
+
262
+ # --- Local write (always robust) ---
263
+ if not remote:
264
+ with open(file_path, "w", encoding="utf-8") as f:
265
+ f.write(contents)
266
+ return file_path
267
+
268
+ # --- Remote write ---
269
+ # Stream data through SSH using base64 chunks instead of huge one-liner
270
+ import io
271
+ import base64
272
+
273
+ # Write to a temporary file locally first
274
+ tmp_path = "/tmp/_abstract_write.tmp"
275
+ with open(tmp_path, "w", encoding="utf-8") as tmpf:
276
+ tmpf.write(contents)
277
+
278
+ user_at_host = kwargs["user_at_host"]
279
+ password = kwargs.get("password")
280
+ key = kwargs.get("key")
281
+
282
+ # Use scp for remote write — no shell arg limits
283
+ scp_cmd = f"scp {shlex.quote(tmp_path)} {user_at_host}:{shlex.quote(file_path)}"
284
+ return run_pruned_func(
285
+ run_local_cmd,
286
+ cmd=scp_cmd,
287
+ password=password,
288
+ key=key,
289
+ **kwargs
290
+ )
228
291
 
229
- make_dirs(dirname or ".", exist_ok=True)
230
- with open(file_path, "w", encoding="utf-8") as f:
231
- f.write(str(contents))
232
- return file_path
233
292
 
293
+ def write_to_file(*, contents: str, file_path: str, **kwargs):
294
+ """
295
+ Error-handled wrapper.
296
+ """
297
+
298
+ try:
299
+ result = _write_to_file(contents=contents, file_path=file_path, **kwargs)
300
+ return result
234
301
 
235
- def read_from_file(file_path,**kwargs):
302
+ except Exception as e:
303
+ print("WRITE ERROR:", e)
304
+ raise RuntimeError(f"Failed writing: {file_path}")
305
+ def read_from_file(file_path=None,**kwargs):
236
306
  if get_user_pass_host_key(**kwargs):
237
307
  kwargs["cwd"] = kwargs.get('cwd') or os.path.dirname(file_path)
238
308
  basename = os.path.basename(file_path)
@@ -1,3 +1,7 @@
1
+ from .imports import *
1
2
  from .alpha_utils import *
2
3
  from .num_utils import *
3
- from .type_utils import *
4
+ from .is_type import *
5
+ from .make_type import *
6
+ from .get_type import *
7
+ from .mime_types import *
@@ -0,0 +1,116 @@
1
+ from .imports import *
2
+ from .alpha_utils import *
3
+ from .num_utils import *
4
+ from .is_type import *
5
+ from .make_type import *
6
+ def get_obj_obj(obj_type: str, obj: any) -> any:
7
+ """
8
+ Returns the object converted according to the given type string.
9
+
10
+ Args:
11
+ obj_type: The string representing the type to convert to.
12
+ obj: The object to convert.
13
+
14
+ Returns:
15
+ any: The object converted to the specified type.
16
+ """
17
+ if obj_type == 'str':
18
+ return make_str(obj)
19
+ elif obj_type == 'bool':
20
+ return make_bool(obj)
21
+ elif obj_type == 'float':
22
+ return make_float(obj)
23
+ elif obj_type == 'int':
24
+ try:
25
+ return int(obj)
26
+ except (TypeError, ValueError):
27
+ return obj
28
+ else:
29
+ return obj
30
+ def get_len_or_num(obj: any) -> int:
31
+ """
32
+ Returns the length of the object if it can be converted to a string, else the integer representation of the object.
33
+
34
+ Args:
35
+ obj: The object to process.
36
+
37
+ Returns:
38
+ int: The length of the object as a string or the integer representation of the object.
39
+ """
40
+ if is_int(obj) or is_float(obj):
41
+ return int(obj)
42
+ else:
43
+ try:
44
+ return len(str(obj))
45
+ except (TypeError, ValueError):
46
+ return 0
47
+ def get_types_list()->list:
48
+ return ['list', 'bool', 'str', 'int', 'float', 'set', 'dict', 'frozenset', 'bytearray', 'bytes', 'memoryview', 'range', 'enumerate', 'zip', 'filter', 'map', 'property', 'slice', 'super', 'type', 'Exception', 'NoneType']
49
+
50
+
51
+ def str_lower(obj):
52
+ try:
53
+ obj=str(obj).lower()
54
+ except Exception as e:
55
+ print(f"{e}")
56
+ return obj
57
+
58
+ def get_bool_response(bool_response,json_data):
59
+ if not is_instance(bool_response,bool):
60
+ try:
61
+ bool_response = json_data.get(bool_response) in [None,'',[],"",{}]
62
+ except:
63
+ pass
64
+ return bool_response
65
+ def get_alphabet_str():
66
+ return 'abcdefghijklmnopqrstuvwxyz'
67
+ def get_alphabet_upper_str():
68
+ alphabet_str = get_alphabet_str()
69
+ return alphabet_str.upper()
70
+ def get_alphabet_comp_str():
71
+ return get_alphabet_str() + get_alphabet_upper_str()
72
+
73
+ def get_alphabet():
74
+ alphabet_str = get_alphabet_str()
75
+ return break_string(alphabet_str)
76
+ def get_alphabet_upper():
77
+ alphabet_upper_str = get_alphabet_upper_str()
78
+ return break_string(alphabet_upper_str)
79
+ def get_alphabet_comp():
80
+ alphabet_comp_str = get_alphabet_comp_str()
81
+ return break_string(alphabet_comp_str)
82
+ def get_numbers_str():
83
+ return '0123457890'
84
+ def get_numbers_int():
85
+ numbers_str = get_numbers_str()
86
+ return [int(number) for number in numbers_str]
87
+ def get_numbers():
88
+ numbers_str = get_numbers_str()
89
+ return break_string(numbers_str)
90
+ def get_numbers_comp():
91
+ numbers_str = get_numbers()
92
+ numbers_int = get_numbers_int()
93
+ return numbers_str + numbers_int
94
+ def break_string(string):
95
+ string_str = str(string)
96
+ return list(string_str)
97
+ def get_alpha_ints(ints=True,alpha=True,lower=True,capitalize=True,string=True,listObj=True):
98
+ objs = [] if listObj else ""
99
+ if ints:
100
+ objs+=getInts(string=string,listObj=listObj)
101
+ if alpha:
102
+ objs+=getAlphas(lower=lower,capitalize=capitalize,listObj=listObj)
103
+ return objs
104
+ def if_true_get_string(data, key):
105
+ return key if data.get(key) else None
106
+ def find_for_string(string, parts):
107
+ return [part for part in parts if string.lower() in str(part).lower()]
108
+
109
+
110
+ def is_strings_in_string(strings, parts):
111
+ strings = make_list(strings)
112
+ for string in strings:
113
+ parts = find_for_string(string, parts)
114
+ if not parts:
115
+ return []
116
+ return parts
@@ -1,2 +1,3 @@
1
1
  from .imports import *
2
2
  from .module_imports import *
3
+ from .constants import *
@@ -0,0 +1,134 @@
1
+ from .module_imports import *
2
+ MIME_TYPES = {
3
+ 'image': {
4
+ '.jpg': 'image/jpeg',
5
+ '.jpeg': 'image/jpeg',
6
+ '.png': 'image/png',
7
+ '.gif': 'image/gif',
8
+ '.bmp': 'image/bmp',
9
+ '.tiff': 'image/tiff',
10
+ '.webp': 'image/webp',
11
+ '.svg': 'image/svg+xml',
12
+ '.ico': 'image/vnd.microsoft.icon',
13
+ '.heic': 'image/heic',
14
+ '.psd': 'image/vnd.adobe.photoshop',
15
+ '.raw': 'image/x-raw',
16
+ },
17
+ 'video': {
18
+ '.mp4': 'video/mp4',
19
+ '.webm': 'video/webm',
20
+ '.ogg': 'video/ogg',
21
+ '.mov': 'video/quicktime',
22
+ '.avi': 'video/x-msvideo',
23
+ '.mkv': 'video/x-matroska',
24
+ '.flv': 'video/x-flv',
25
+ '.wmv': 'video/x-ms-wmv',
26
+ '.3gp': 'video/3gpp',
27
+ '.ts': 'video/mp2t',
28
+ '.mpeg': 'video/mpeg',
29
+ '.mpg': 'video/mpg'
30
+ },
31
+ 'audio': {
32
+ '.mp3': 'audio/mpeg',
33
+ '.wav': 'audio/wav',
34
+ '.flac': 'audio/flac',
35
+ '.aac': 'audio/aac',
36
+ '.ogg': 'audio/ogg',
37
+ '.m4a': 'audio/mp4',
38
+ '.opus': 'audio/opus',
39
+ },
40
+ 'document': {
41
+ '.pdf': 'application/pdf',
42
+ '.doc': 'application/msword',
43
+ '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
44
+ '.odt': 'application/vnd.oasis.opendocument.text',
45
+ '.txt': 'text/plain',
46
+ '.rtf': 'application/rtf',
47
+ '.md': 'text/markdown',
48
+ '.markdown': 'text/markdown',
49
+ '.tex': 'application/x-tex',
50
+ '.log': 'text/plain',
51
+ '.json': 'application/json',
52
+ '.xml': 'application/xml',
53
+ '.yaml': 'application/x-yaml',
54
+ '.yml': 'application/x-yaml',
55
+ '.ini': 'text/plain',
56
+ '.cfg': 'text/plain',
57
+ '.toml': 'application/toml',
58
+ '.csv': 'text/csv',
59
+ '.tsv': 'text/tab-separated-values'
60
+ },
61
+ 'presentation': {
62
+ '.ppt': 'application/vnd.ms-powerpoint',
63
+ '.pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
64
+ '.odp': 'application/vnd.oasis.opendocument.presentation',
65
+ },
66
+ 'spreadsheet': {
67
+ '.xls': 'application/vnd.ms-excel',
68
+ '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
69
+ '.ods': 'application/vnd.oasis.opendocument.spreadsheet',
70
+ '.csv': 'text/csv',
71
+ '.tsv': 'text/tab-separated-values'
72
+ },
73
+ 'code': {
74
+ '.py': 'text/x-python',
75
+ '.java': 'text/x-java-source',
76
+ '.c': 'text/x-c',
77
+ '.cpp': 'text/x-c++',
78
+ '.h': 'text/x-c',
79
+ '.hpp': 'text/x-c++',
80
+ '.js': 'application/javascript',
81
+ '.cjs': 'application/javascript',
82
+ '.mjs': 'application/javascript',
83
+ '.jsx': 'application/javascript',
84
+ '.ts': 'application/typescript',
85
+ '.tsx': 'application/typescript',
86
+ '.rb': 'text/x-ruby',
87
+ '.php': 'application/x-php',
88
+ '.go': 'text/x-go',
89
+ '.rs': 'text/rust',
90
+ '.swift': 'text/x-swift',
91
+ '.kt': 'text/x-kotlin',
92
+ '.sh': 'application/x-shellscript',
93
+ '.bash': 'application/x-shellscript',
94
+ '.ps1': 'application/x-powershell',
95
+ '.sql': 'application/sql',
96
+ '.yml': 'application/x-yaml',
97
+ '.coffee':'text/coffeescript',
98
+ '.lua': 'text/x-lua',
99
+ },
100
+ 'archive': {
101
+ '.zip': 'application/zip',
102
+ '.tar': 'application/x-tar',
103
+ '.gz': 'application/gzip',
104
+ '.tgz': 'application/gzip',
105
+ '.bz2': 'application/x-bzip2',
106
+ '.xz': 'application/x-xz',
107
+ '.rar': 'application/vnd.rar',
108
+ '.7z': 'application/x-7z-compressed',
109
+ '.iso': 'application/x-iso9660-image',
110
+ '.dmg': 'application/x-apple-diskimage',
111
+ '.jar': 'application/java-archive',
112
+ '.war': 'application/java-archive',
113
+ '.whl': 'application/python-wheel',
114
+ '.egg': 'application/python-egg',
115
+ },
116
+ 'font': {
117
+ '.ttf': 'font/ttf',
118
+ '.otf': 'font/otf',
119
+ '.woff': 'font/woff',
120
+ '.woff2': 'font/woff2',
121
+ '.eot': 'application/vnd.ms-fontobject'
122
+ },
123
+ 'executable': {
124
+ '.exe': 'application/vnd.microsoft.portable-executable',
125
+ '.dll': 'application/vnd.microsoft.portable-executable',
126
+ '.bin': 'application/octet-stream',
127
+ '.deb': 'application/vnd.debian.binary-package',
128
+ '.rpm': 'application/x-rpm'
129
+ }
130
+ }
131
+
132
+ # And just the sets, if you only need to test ext‐membership:
133
+ MEDIA_TYPES = make_key_map(MIME_TYPES)
134
+