bluer-objects 6.104.1__py3-none-any.whl → 6.464.1__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.
Files changed (170) hide show
  1. bluer_objects/.abcli/abcli.sh +6 -0
  2. bluer_objects/.abcli/alias.sh +13 -6
  3. bluer_objects/.abcli/assets/cd.sh +20 -0
  4. bluer_objects/.abcli/assets/mv.sh +34 -0
  5. bluer_objects/.abcli/assets/publish.sh +40 -0
  6. bluer_objects/.abcli/assets.sh +15 -0
  7. bluer_objects/.abcli/create_test_asset.sh +10 -0
  8. bluer_objects/.abcli/download.sh +3 -1
  9. bluer_objects/.abcli/file.sh +15 -4
  10. bluer_objects/.abcli/gif.sh +18 -0
  11. bluer_objects/.abcli/host.sh +23 -7
  12. bluer_objects/.abcli/ls.sh +19 -8
  13. bluer_objects/.abcli/metadata/download.sh +9 -0
  14. bluer_objects/.abcli/metadata/edit.sh +15 -0
  15. bluer_objects/.abcli/metadata/upload.sh +9 -0
  16. bluer_objects/.abcli/mlflow/browse.sh +2 -0
  17. bluer_objects/.abcli/mlflow/deploy.sh +21 -5
  18. bluer_objects/.abcli/mlflow/lock/lock.sh +11 -0
  19. bluer_objects/.abcli/mlflow/lock/unlock.sh +12 -0
  20. bluer_objects/.abcli/mlflow/lock.sh +15 -0
  21. bluer_objects/.abcli/mlflow/tags/search.sh +1 -5
  22. bluer_objects/.abcli/mlflow.sh +0 -2
  23. bluer_objects/.abcli/pdf/convert.sh +92 -0
  24. bluer_objects/.abcli/pdf.sh +15 -0
  25. bluer_objects/.abcli/storage/clear.sh +2 -0
  26. bluer_objects/.abcli/tests/clone.sh +2 -3
  27. bluer_objects/.abcli/tests/create_test_asset.sh +16 -0
  28. bluer_objects/.abcli/tests/file.sh +64 -0
  29. bluer_objects/.abcli/tests/gif.sh +3 -3
  30. bluer_objects/.abcli/tests/help.sh +23 -7
  31. bluer_objects/.abcli/tests/ls.sh +11 -4
  32. bluer_objects/.abcli/tests/metadata.sh +35 -0
  33. bluer_objects/.abcli/tests/mlflow_lock.sh +30 -0
  34. bluer_objects/.abcli/tests/mlflow_tags.sh +1 -1
  35. bluer_objects/.abcli/tests/open.sh +11 -0
  36. bluer_objects/.abcli/tests/open_gif_open.sh +14 -0
  37. bluer_objects/.abcli/tests/pdf.sh +39 -0
  38. bluer_objects/.abcli/tests/storage_clear.sh +11 -0
  39. bluer_objects/.abcli/tests/storage_public_upload.sh +25 -0
  40. bluer_objects/.abcli/tests/storage_status.sh +12 -0
  41. bluer_objects/.abcli/tests/{storage.sh → storage_upload_download.sh} +26 -8
  42. bluer_objects/.abcli/upload.sh +26 -2
  43. bluer_objects/README/__init__.py +7 -22
  44. bluer_objects/README/alias.py +67 -0
  45. bluer_objects/README/build/__init__.py +0 -0
  46. bluer_objects/README/build/aliases.py +23 -0
  47. bluer_objects/README/build/docs.py +23 -0
  48. bluer_objects/README/build/modules.py +9 -0
  49. bluer_objects/README/consts.py +44 -0
  50. bluer_objects/README/functions.py +154 -204
  51. bluer_objects/README/items.py +78 -6
  52. bluer_objects/README/process/__init__.py +0 -0
  53. bluer_objects/README/process/assets.py +36 -0
  54. bluer_objects/README/process/details.py +20 -0
  55. bluer_objects/README/process/envs.py +23 -0
  56. bluer_objects/README/process/help.py +27 -0
  57. bluer_objects/README/process/include.py +40 -0
  58. bluer_objects/README/process/legacy.py +21 -0
  59. bluer_objects/README/process/mermaid.py +20 -0
  60. bluer_objects/README/process/national_internet.py +55 -0
  61. bluer_objects/README/process/objects.py +32 -0
  62. bluer_objects/README/process/signature.py +35 -0
  63. bluer_objects/README/process/title.py +44 -0
  64. bluer_objects/README/process/variables.py +12 -0
  65. bluer_objects/__init__.py +1 -1
  66. bluer_objects/assets/__init__.py +0 -0
  67. bluer_objects/assets/__main__.py +57 -0
  68. bluer_objects/assets/functions.py +62 -0
  69. bluer_objects/config.env +13 -1
  70. bluer_objects/env.py +27 -1
  71. bluer_objects/file/__main__.py +52 -7
  72. bluer_objects/file/functions.py +21 -4
  73. bluer_objects/file/load.py +2 -9
  74. bluer_objects/file/save.py +17 -24
  75. bluer_objects/graphics/__main__.py +7 -0
  76. bluer_objects/graphics/gif.py +11 -7
  77. bluer_objects/graphics/screen.py +9 -8
  78. bluer_objects/help/assets.py +93 -0
  79. bluer_objects/help/create_test_asset.py +22 -0
  80. bluer_objects/help/download.py +17 -3
  81. bluer_objects/help/file.py +59 -0
  82. bluer_objects/help/functions.py +9 -1
  83. bluer_objects/help/gif.py +25 -0
  84. bluer_objects/help/host.py +6 -4
  85. bluer_objects/help/ls.py +26 -3
  86. bluer_objects/help/metadata.py +51 -0
  87. bluer_objects/help/mlflow/__init__.py +23 -2
  88. bluer_objects/help/mlflow/cache.py +2 -4
  89. bluer_objects/help/mlflow/lock.py +52 -0
  90. bluer_objects/help/mlflow/tags.py +34 -23
  91. bluer_objects/help/pdf.py +67 -0
  92. bluer_objects/help/upload.py +10 -3
  93. bluer_objects/host/functions.py +4 -1
  94. bluer_objects/logger/confusion_matrix.py +76 -0
  95. bluer_objects/logger/image.py +110 -0
  96. bluer_objects/logger/stitch.py +107 -0
  97. bluer_objects/markdown.py +8 -6
  98. bluer_objects/metadata/__init__.py +1 -0
  99. bluer_objects/metadata/flatten.py +27 -0
  100. bluer_objects/mlflow/__init__.py +1 -1
  101. bluer_objects/mlflow/__main__.py +49 -31
  102. bluer_objects/mlflow/lock/__init__.py +1 -0
  103. bluer_objects/mlflow/lock/__main__.py +58 -0
  104. bluer_objects/mlflow/lock/functions.py +121 -0
  105. bluer_objects/mlflow/logging.py +53 -41
  106. bluer_objects/mlflow/models.py +7 -0
  107. bluer_objects/mlflow/objects.py +7 -0
  108. bluer_objects/mlflow/runs.py +10 -1
  109. bluer_objects/mlflow/serverless/__init__.py +3 -0
  110. bluer_objects/mlflow/serverless/api.py +88 -0
  111. bluer_objects/mlflow/serverless/read.py +19 -0
  112. bluer_objects/mlflow/serverless/search.py +35 -0
  113. bluer_objects/mlflow/serverless/write.py +42 -0
  114. bluer_objects/mlflow/tags.py +59 -9
  115. bluer_objects/objects.py +3 -1
  116. bluer_objects/pdf/__init__.py +1 -0
  117. bluer_objects/pdf/__main__.py +78 -0
  118. bluer_objects/pdf/convert/__init__.py +0 -0
  119. bluer_objects/pdf/convert/batch.py +54 -0
  120. bluer_objects/pdf/convert/combination.py +32 -0
  121. bluer_objects/pdf/convert/convert.py +110 -0
  122. bluer_objects/pdf/convert/image.py +53 -0
  123. bluer_objects/pdf/convert/md.py +97 -0
  124. bluer_objects/pdf/convert/missing.py +96 -0
  125. bluer_objects/pdf/convert/pdf.py +37 -0
  126. bluer_objects/sample.env +6 -0
  127. bluer_objects/storage/WebDAV.py +11 -7
  128. bluer_objects/storage/WebDAVrequest.py +360 -0
  129. bluer_objects/storage/WebDAVzip.py +26 -29
  130. bluer_objects/storage/__init__.py +28 -1
  131. bluer_objects/storage/__main__.py +40 -6
  132. bluer_objects/storage/base.py +84 -5
  133. bluer_objects/storage/policies.py +7 -0
  134. bluer_objects/storage/s3.py +367 -0
  135. bluer_objects/testing/__main__.py +6 -0
  136. bluer_objects/tests/test_README_consts.py +71 -0
  137. bluer_objects/tests/test_README_items.py +128 -0
  138. bluer_objects/tests/test_alias.py +33 -0
  139. bluer_objects/tests/test_env.py +42 -7
  140. bluer_objects/tests/test_file_download.py +30 -0
  141. bluer_objects/tests/test_file_load_save.py +1 -2
  142. bluer_objects/tests/test_file_load_save_text.py +46 -0
  143. bluer_objects/tests/test_graphics_gif.py +2 -0
  144. bluer_objects/tests/test_log_image_grid.py +29 -0
  145. bluer_objects/tests/test_logger_confusion_matrix.py +18 -0
  146. bluer_objects/tests/test_logger_matrix.py +2 -2
  147. bluer_objects/tests/test_logger_stitch_images.py +47 -0
  148. bluer_objects/tests/test_metadata.py +12 -6
  149. bluer_objects/tests/test_metadata_flatten.py +109 -0
  150. bluer_objects/tests/test_mlflow.py +114 -5
  151. bluer_objects/tests/test_mlflow_lock.py +26 -0
  152. bluer_objects/tests/test_objects.py +2 -0
  153. bluer_objects/tests/test_shell.py +34 -0
  154. bluer_objects/tests/test_storage.py +8 -21
  155. bluer_objects/tests/test_storage_base.py +39 -0
  156. bluer_objects/tests/test_storage_s3.py +67 -0
  157. bluer_objects/tests/test_storage_webdav_request.py +75 -0
  158. bluer_objects/tests/test_storage_webdav_zip.py +42 -0
  159. bluer_objects/tests/test_web_is_accessible.py +11 -0
  160. {bluer_objects-6.104.1.dist-info → bluer_objects-6.464.1.dist-info}/METADATA +20 -11
  161. bluer_objects-6.464.1.dist-info/RECORD +228 -0
  162. {bluer_objects-6.104.1.dist-info → bluer_objects-6.464.1.dist-info}/WHEEL +1 -1
  163. bluer_objects/.abcli/storage/download_file.sh +0 -9
  164. bluer_objects/.abcli/storage/exists.sh +0 -8
  165. bluer_objects/.abcli/storage/list.sh +0 -8
  166. bluer_objects/.abcli/storage/rm.sh +0 -11
  167. bluer_objects/.abcli/tests/mlflow_test.sh +0 -7
  168. bluer_objects-6.104.1.dist-info/RECORD +0 -143
  169. {bluer_objects-6.104.1.dist-info → bluer_objects-6.464.1.dist-info}/licenses/LICENSE +0 -0
  170. {bluer_objects-6.104.1.dist-info → bluer_objects-6.464.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,44 @@
1
+ import os
2
+ from typing import Union
3
+
4
+ from bluer_objects.env import abcli_path_git
5
+
6
+ github_kamangir = "https://github.com/kamangir"
7
+ designs_repo = f"{github_kamangir}/bluer-designs"
8
+
9
+
10
+ def designs_url(suffix: str) -> str:
11
+ return "{}/blob/main{}".format(
12
+ designs_repo,
13
+ f"/{suffix}" if suffix else "",
14
+ )
15
+
16
+
17
+ def assets_url(
18
+ suffix: str = "",
19
+ volume: Union[str, int] = "",
20
+ blob: bool = False,
21
+ ) -> str:
22
+ return "{}/assets{}/{}/main{}".format(
23
+ github_kamangir,
24
+ str(volume),
25
+ "blob" if blob else "raw",
26
+ f"/{suffix}" if suffix else "",
27
+ )
28
+
29
+
30
+ assets = assets_url(volume="")
31
+ assets2 = assets_url(volume="2")
32
+
33
+
34
+ def assets_path(
35
+ suffix: str = "",
36
+ volume: Union[str, int] = "",
37
+ ) -> str:
38
+ return os.path.join(
39
+ abcli_path_git,
40
+ "assets{}{}".format(
41
+ str(volume),
42
+ f"/{suffix}" if suffix else "",
43
+ ),
44
+ )
@@ -3,11 +3,24 @@ import os
3
3
  import yaml
4
4
 
5
5
  from blueness import module
6
-
7
- from bluer_objects import NAME as MY_NAME, ICON as MY_ICON
8
- from bluer_objects.metadata import get_from_object
6
+ from bluer_options import env
7
+ from bluer_options.logger import shorten_text
8
+ from bluer_objects import NAME as MY_NAME
9
9
  from bluer_objects import file
10
10
  from bluer_objects import markdown
11
+ from bluer_objects.metadata import get_from_object
12
+ from bluer_objects.README.process.assets import process_assets
13
+ from bluer_objects.README.process.details import process_details
14
+ from bluer_objects.README.process.envs import process_envs
15
+ from bluer_objects.README.process.help import process_help
16
+ from bluer_objects.README.process.include import process_include
17
+ from bluer_objects.README.process.legacy import apply_legacy
18
+ from bluer_objects.README.process.mermaid import process_mermaid
19
+ from bluer_objects.README.process.national_internet import process_national_internet
20
+ from bluer_objects.README.process.objects import process_objects
21
+ from bluer_objects.README.process.title import process_title
22
+ from bluer_objects.README.process.variables import process_variable, variables
23
+ from bluer_objects.README.process.signature import signature
11
24
  from bluer_objects.logger import logger
12
25
 
13
26
  MY_NAME = module.name(__file__, MY_NAME)
@@ -28,6 +41,8 @@ def build(
28
41
  help_function: Union[Callable[[List[str]], str], None] = None,
29
42
  legacy_mode: bool = True,
30
43
  assets_repo: str = "kamangir/assets",
44
+ download: bool = env.BLUER_AI_WEB_STATUS != "offline",
45
+ verbose: bool = False,
31
46
  ) -> bool:
32
47
  if path:
33
48
  if path.endswith(".md"):
@@ -41,7 +56,7 @@ def build(
41
56
  MODULE_NAME = REPO_NAME
42
57
 
43
58
  logger.info(
44
- "{}.build: {}-{}: {}[{}]: {} -{}> {}".format(
59
+ "{}.build: {}-{}: {}[{}]: {} -{}{}> {}".format(
45
60
  MY_NAME,
46
61
  NAME,
47
62
  VERSION,
@@ -49,148 +64,58 @@ def build(
49
64
  MODULE_NAME,
50
65
  template_filename,
51
66
  "+legacy-" if legacy_mode else "",
67
+ "download-" if download else "",
52
68
  filename,
53
69
  )
54
70
  )
55
71
 
56
- table_of_items = markdown.generate_table(items, cols=cols) if cols > 0 else items
72
+ if verbose:
73
+ logger.info(f"filename: {filename}")
74
+ logger.info(f"items: {items}")
57
75
 
58
- signature = [
59
- "",
60
- " ".join(
61
- [
62
- f"[![pylint](https://github.com/kamangir/{REPO_NAME}/actions/workflows/pylint.yml/badge.svg)](https://github.com/kamangir/{REPO_NAME}/actions/workflows/pylint.yml)",
63
- f"[![pytest](https://github.com/kamangir/{REPO_NAME}/actions/workflows/pytest.yml/badge.svg)](https://github.com/kamangir/{REPO_NAME}/actions/workflows/pytest.yml)",
64
- f"[![bashtest](https://github.com/kamangir/{REPO_NAME}/actions/workflows/bashtest.yml/badge.svg)](https://github.com/kamangir/{REPO_NAME}/actions/workflows/bashtest.yml)",
65
- f"[![PyPI version](https://img.shields.io/pypi/v/{MODULE_NAME}.svg)](https://pypi.org/project/{MODULE_NAME}/)",
66
- f"[![PyPI - Downloads](https://img.shields.io/pypi/dd/{MODULE_NAME})](https://pypistats.org/packages/{MODULE_NAME})",
67
- ]
68
- ),
69
- "",
70
- "built by {} [`{}`]({}), based on {}[`{}-{}`]({}).".format(
71
- MY_ICON,
72
- "bluer README",
73
- "https://github.com/kamangir/bluer-objects/tree/main/bluer_objects/README",
74
- f"{ICON} " if ICON else "",
75
- NAME,
76
- VERSION,
77
- f"https://github.com/kamangir/{REPO_NAME}",
78
- ),
79
- ]
76
+ table_of_items = markdown.generate_table(items, cols=cols) if cols > 0 else items
80
77
 
81
78
  success, template = file.load_text(template_filename)
82
79
  if not success:
83
80
  return success
84
81
 
85
- def apply_legacy(line: str) -> str:
86
- for before, after in {
87
- "yaml:::": "metadata:::",
88
- "--help--": "help:::",
89
- "--include": "include:::",
90
- "--table--": "items:::",
91
- "--signature--": "signature:::",
92
- }.items():
93
- line = line.replace(before, after)
94
- return line
95
-
96
82
  if legacy_mode:
97
- logger.info("applying legacy conversions...")
98
- template = [apply_legacy(line) for line in template]
83
+ template = apply_legacy(template)
99
84
 
100
85
  content: List[str] = []
101
86
  mermaid_started: bool = False
102
- variables: Dict[str, str] = {}
103
87
  for template_line in template:
104
88
  if template_line.startswith("ignore:::"):
105
- content_section = [template_line.split(":::", 1)[1].strip()]
106
- else:
107
- if template_line.startswith("set:::"):
108
- key, value = template_line.split("set:::", 1)[1].split(" ", 1)
109
- variables[key] = value
110
- logger.info(f":::{key} = {value}")
111
- continue
112
-
113
- for key, value in variables.items():
114
- template_line = template_line.replace(
115
- f"get:::{key}",
116
- value,
117
- )
118
-
119
- if "assets:::" in template_line:
120
- template_line = " ".join(
121
- [
122
- (
123
- (
124
- "![image](https://github.com/{}/blob/main/{}?raw=true)".format(
125
- assets_repo,
126
- token.split(":::")[1].strip(),
127
- )
128
- if any(
129
- token.endswith(extension)
130
- for extension in ["png", "jpg", "jpeg", "gif"]
131
- )
132
- else "[{}](https://github.com/{}/blob/main/{})".format(
133
- file.name_and_extension(
134
- token.split(":::")[1].strip()
135
- ),
136
- assets_repo,
137
- token.split(":::")[1].strip(),
138
- )
139
- )
140
- if token.startswith("assets:::")
141
- else token
142
- )
143
- for token in template_line.split(" ")
144
- ]
145
- )
146
-
147
- if "object:::" in template_line:
148
- template_line = " ".join(
149
- [
150
- (
151
- "[{}]({}/{}.tar.gz)".format(
152
- token.split(":::")[1].strip(),
153
- "TBA",
154
- token.split(":::")[1].strip(),
155
- )
156
- if token.startswith("object:::")
157
- else token
158
- )
159
- for token in template_line.split(" ")
160
- ]
161
- )
162
-
163
- content_section: List[str] = [template_line]
164
-
165
- if template_line.startswith("details:::"):
166
- suffix = template_line.split(":::", 1)[1]
167
- if suffix:
168
- content_section = [
169
- "",
170
- "<details>",
171
- f"<summary>{suffix}</summary>",
172
- "",
173
- ]
174
- else:
175
- content_section = [
176
- "",
177
- "</details>",
178
- "",
179
- ]
180
- elif template_line.startswith("metadata:::"):
181
- object_name_and_key = template_line.split(":::", 1)[1]
182
- if ":::" not in object_name_and_key:
183
- object_name_and_key += ":::"
184
- object_name, key = object_name_and_key.split(":::", 1)
185
-
186
- value = get_from_object(
187
- object_name,
188
- key,
189
- {},
190
- download=True,
191
- )
192
-
193
- content_section = (
89
+ content += [template_line.split(":::", 1)[1].strip()]
90
+ continue
91
+
92
+ template_line = process_envs(template_line)
93
+
94
+ for key, value in variables.items():
95
+ template_line = template_line.replace(
96
+ f"get:::{key}",
97
+ value,
98
+ )
99
+
100
+ if "metadata:::" in template_line:
101
+ object_name_and_key = template_line.split("metadata:::", 1)[1]
102
+ if " " in object_name_and_key:
103
+ object_name_and_key = object_name_and_key.split(" ", 1)[0]
104
+ if ":::" not in object_name_and_key:
105
+ object_name_and_key += ":::"
106
+ object_name, key = object_name_and_key.split(":::", 1)
107
+
108
+ value = get_from_object(
109
+ object_name,
110
+ key,
111
+ {},
112
+ download=download,
113
+ )
114
+
115
+ logger.info(shorten_text(f"metadata[{object_name_and_key}] = {value}"))
116
+
117
+ if template_line.startswith("metadata:::"):
118
+ content += (
194
119
  ["```yaml"]
195
120
  + yaml.dump(
196
121
  value,
@@ -198,85 +123,110 @@ def build(
198
123
  ).split("\n")
199
124
  + ["```"]
200
125
  )
201
- elif template_line.startswith("```mermaid"):
202
- mermaid_started = True
203
- logger.info("🧜🏽‍♀️ detected ...")
204
- elif mermaid_started and template_line.startswith("```"):
205
- mermaid_started = False
206
- elif mermaid_started:
207
- if '"' in template_line and ":::folder" not in template_line:
208
- template_line_pieces = template_line.split('"')
209
- if len(template_line_pieces) != 3:
210
- logger.error(
211
- f"🧜🏽‍♀️ mermaid line not in expected format: {template_line}."
212
- )
213
- return False
214
-
215
- template_line_pieces[1] = (
216
- template_line_pieces[1]
217
- .replace("<", "&lt;")
218
- .replace(">", "&gt;")
219
- .replace(" ", "<br>")
220
- .replace("~~", " ")
221
- )
222
-
223
- content_section = ['"'.join(template_line_pieces)]
224
- elif "items:::" in template_line:
225
- content_section = table_of_items
226
- elif "signature:::" in template_line:
227
- content_section = signature
228
- elif "include:::" in template_line:
229
- include_filename_relative = template_line.split(" ")[1].strip()
230
- include_filename = file.absolute(
231
- include_filename_relative,
232
- file.path(template_filename),
233
- )
234
-
235
- success, content_section = file.load_text(include_filename)
236
- if not success:
237
- return success
238
-
239
- content_section = [
240
- line for line in content_section if not line.startswith("used by:")
241
- ]
242
-
243
- include_title = (template_line.split(" ", 2) + ["", "", ""])[2]
244
- if include_title:
245
- content_section = [f"## {include_title}"] + content_section[1:]
246
-
247
- if "include:::noref" not in template_line:
248
- content_section += [
249
- "using [{}]({}).".format(
250
- file.name(include_filename),
251
- include_filename_relative,
252
- )
253
- ]
254
-
255
- logger.info(f"{MY_NAME}.build: including {include_filename} ...")
256
- elif "help:::" in template_line:
257
- if help_function is not None:
258
- help_command = template_line.split("help:::")[1].strip()
259
-
260
- tokens = help_command.strip().split(" ")[1:]
126
+ continue
261
127
 
262
- help_content = help_function(tokens)
263
- if not help_content:
264
- logger.warning(f"help not found: {help_command}: {tokens}")
265
- return False
128
+ template_line = template_line.replace(
129
+ f"metadata:::{object_name}:::{key}",
130
+ str(value),
131
+ )
132
+
133
+ if template_line.startswith("set:::"):
134
+ process_variable(template_line)
135
+ continue
136
+
137
+ template_line = process_assets(template_line, assets_repo)
138
+
139
+ template_line = process_objects(template_line)
140
+
141
+ if template_line.startswith("details:::"):
142
+ content += process_details(template_line)
143
+ continue
144
+
145
+ if "items:::" in template_line:
146
+ content += table_of_items
147
+ continue
148
+
149
+ if "include:::" in template_line:
150
+ content += process_include(
151
+ template_line,
152
+ file.path(template_filename),
153
+ )
154
+ continue
155
+
156
+ if "signature:::" in template_line:
157
+ content += signature(
158
+ REPO_NAME,
159
+ NAME,
160
+ ICON,
161
+ MODULE_NAME,
162
+ VERSION,
163
+ )
164
+ continue
165
+
166
+ if template_line.startswith("title:::"):
167
+ success, updated_content = process_title(
168
+ template_line,
169
+ filename,
170
+ )
171
+ if not success:
172
+ return success
173
+
174
+ content += updated_content
175
+ continue
176
+
177
+ if "help:::" in template_line:
178
+ if help_function is None:
179
+ logger.error("help_function not found.")
180
+ return False
181
+
182
+ success, updated_content = process_help(
183
+ template_line,
184
+ help_function,
185
+ )
186
+ if not success:
187
+ return success
188
+
189
+ content += updated_content
190
+ continue
191
+
192
+ content_section = [template_line]
193
+ if template_line.startswith("```mermaid"):
194
+ mermaid_started = True
195
+ logger.info("🧜🏽‍♀️ detected ...")
196
+ elif mermaid_started and template_line.startswith("```"):
197
+ mermaid_started = False
198
+ elif mermaid_started:
199
+ if '"' in template_line and ":::folder" not in template_line:
200
+ content_section = process_mermaid(template_line)
201
+ else:
202
+ for macro, macro_value in macros.items():
203
+ if macro not in template_line:
204
+ continue
266
205
 
267
- logger.info(f"+= help: {help_command}")
268
- print(help_content)
206
+ if template_line.replace(macro, "").strip():
207
+ # this and that macro::: is going to be ...
269
208
  content_section = [
270
- "```bash",
271
- help_content,
272
- "```",
209
+ template_line.replace(
210
+ macro,
211
+ (
212
+ " ".join(macro_value)
213
+ if isinstance(macro_value, list)
214
+ else macro_value
215
+ ),
216
+ )
273
217
  ]
274
- else:
275
- for macro, macro_value in macros.items():
276
- if macro in template_line:
277
- content_section = macro_value
278
- break
218
+ else:
219
+ # macro:::
220
+ content_section = (
221
+ macro_value if isinstance(macro_value, list) else [macro_value]
222
+ )
223
+ break
279
224
 
280
225
  content += content_section
281
226
 
227
+ content = process_national_internet(
228
+ filename,
229
+ content,
230
+ )
231
+
282
232
  return file.save_text(filename, content)
@@ -1,17 +1,43 @@
1
1
  from typing import List, Dict
2
2
 
3
3
 
4
+ # {image,jpg : url}
5
+ def ImageItems(items: Dict[str, str]) -> List[str]:
6
+ def add_raw(url: str) -> str:
7
+ return (
8
+ f"{url}?raw=true" if "github.com" in url and "raw=true" not in url else url
9
+ )
10
+
11
+ return [
12
+ (
13
+ ""
14
+ if not image
15
+ else "[![image]({})]({})".format(
16
+ add_raw(image), url if url else add_raw(image)
17
+ )
18
+ )
19
+ for image, url in items.items()
20
+ ]
21
+
22
+
4
23
  # name, url, marquee, description
5
24
  def Items(
6
25
  items: List[Dict[str, str]],
26
+ sort: bool = False,
7
27
  ) -> List[str]:
8
- return [
28
+ output = [
9
29
  (
10
- "[`{}`]({}) [![image]({})]({}) {}".format(
11
- item["name"],
12
- item.get(
13
- "url",
14
- "#",
30
+ "{}[![image]({})]({}) {}".format(
31
+ (
32
+ "[`{}`]({}) ".format(
33
+ item["name"],
34
+ item.get(
35
+ "url",
36
+ "#",
37
+ ),
38
+ )
39
+ if item["name"]
40
+ else ""
15
41
  ),
16
42
  item.get(
17
43
  "marquee",
@@ -28,3 +54,49 @@ def Items(
28
54
  )
29
55
  for item in items
30
56
  ]
57
+
58
+ if sort:
59
+ output = sorted(output)
60
+
61
+ return output
62
+
63
+
64
+ # dict of {name, url, marquee, description}
65
+ def Items_of_dict(
66
+ dict_of_things: Dict[str, Dict],
67
+ ) -> List[str]:
68
+ return Items(
69
+ sorted(
70
+ [
71
+ {
72
+ "order": info.get("order", thing_name),
73
+ "name": thing_name,
74
+ "marquee": info.get("marquee", ""),
75
+ "url": f"./{thing_name}.md",
76
+ }
77
+ for thing_name, info in dict_of_things.items()
78
+ if thing_name != "template"
79
+ ],
80
+ key=lambda x: x["order"],
81
+ )
82
+ )
83
+
84
+
85
+ # dict of {name, url, marquee, description}
86
+ def list_of_dict(
87
+ dict_of_things: Dict[str, Dict],
88
+ ) -> List[str]:
89
+ return [
90
+ item["text"]
91
+ for item in sorted(
92
+ [
93
+ {
94
+ "text": f"- [{thing_name}](./{thing_name}.md)",
95
+ "order": info.get("order", thing_name),
96
+ }
97
+ for thing_name, info in dict_of_things.items()
98
+ if thing_name != "template"
99
+ ],
100
+ key=lambda x: x["order"],
101
+ )
102
+ ]
File without changes
@@ -0,0 +1,36 @@
1
+ from bluer_objects import file
2
+
3
+
4
+ def process_assets(
5
+ template_line: str,
6
+ assets_repo: str,
7
+ ) -> str:
8
+ prefix = f"https://github.com/{assets_repo}/blob/main"
9
+
10
+ if "assets:::" in template_line:
11
+ template_line = " ".join(
12
+ [
13
+ (
14
+ (
15
+ "![image]({}/{}?raw=true)".format(
16
+ prefix,
17
+ token.split(":::")[1].strip(),
18
+ )
19
+ if any(
20
+ token.endswith(extension)
21
+ for extension in ["png", "jpg", "jpeg", "gif"]
22
+ )
23
+ else "[{}]({}/{})".format(
24
+ file.name_and_extension(token.split(":::")[1].strip()),
25
+ prefix,
26
+ token.split(":::")[1].strip(),
27
+ )
28
+ )
29
+ if token.startswith("assets:::")
30
+ else token
31
+ )
32
+ for token in template_line.split(" ")
33
+ ]
34
+ )
35
+
36
+ return template_line
@@ -0,0 +1,20 @@
1
+ from typing import List
2
+
3
+
4
+ def process_details(template_line: str) -> List[str]:
5
+ suffix = template_line.split(":::", 1)[1]
6
+ if suffix:
7
+ content_section = [
8
+ "",
9
+ "<details>",
10
+ f"<summary>{suffix}</summary>",
11
+ "",
12
+ ]
13
+ else:
14
+ content_section = [
15
+ "",
16
+ "</details>",
17
+ "",
18
+ ]
19
+
20
+ return content_section
@@ -0,0 +1,23 @@
1
+ from bluer_options.env import get_env
2
+
3
+ from bluer_objects.logger import logger
4
+
5
+
6
+ def process_envs(template_line: str) -> str:
7
+ while "env:::" in template_line:
8
+ env_name = template_line.split("env:::", 1)[1]
9
+ if " " in env_name:
10
+ env_name = env_name.split(" ", 1)[0]
11
+ else:
12
+ if ":::" in env_name:
13
+ env_name = env_name.split(":::", 1)[0]
14
+
15
+ env_value = get_env(env_name)
16
+
17
+ template_line = template_line.replace(
18
+ f"env:::{env_name}",
19
+ env_value,
20
+ )
21
+ logger.info(f"{env_name} -> {env_value}")
22
+
23
+ return template_line
@@ -0,0 +1,27 @@
1
+ from typing import List, Union, Callable, Tuple
2
+
3
+ from bluer_objects.logger import logger
4
+
5
+
6
+ def process_help(
7
+ template_line: str,
8
+ help_function: Union[Callable[[List[str]], str], None] = None,
9
+ ) -> Tuple[bool, List[str]]:
10
+ help_command = template_line.split("help:::")[1].strip()
11
+
12
+ tokens = help_command.strip().split(" ")[1:]
13
+
14
+ help_content = help_function(tokens)
15
+ if not help_content:
16
+ logger.error(f"help not found: {help_command}: {tokens}")
17
+ return False, []
18
+
19
+ logger.info(f"+= help: {help_command}")
20
+ print(help_content)
21
+ content_section = [
22
+ "```bash",
23
+ help_content,
24
+ "```",
25
+ ]
26
+
27
+ return True, content_section