blue-assistant 4.97.1__py3-none-any.whl → 4.121.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.
@@ -17,7 +17,8 @@ function test_blue_assistant_script_run() {
17
17
  script=$script_name \
18
18
  test_blue_assistant_script_run-$(abcli_string_timestamp_short) \
19
19
  "${@:2}" \
20
- --test_mode 1
20
+ --test_mode 1 \
21
+ --verbose 1
21
22
 
22
23
  [[ $? -ne 0 ]] && return 1
23
24
 
blue_assistant/README.py CHANGED
@@ -6,13 +6,21 @@ from blue_assistant import NAME, VERSION, ICON, REPO_NAME
6
6
 
7
7
 
8
8
  items = [
9
- "{}[`{}`](#) [![image]({})](#) {}".format(
10
- ICON,
11
- f"feature {index}",
12
- "https://github.com/kamangir/assets/raw/main/blue-assistant/marquee.png?raw=true",
13
- f"description of feature {index} ...",
9
+ "[`{}`]({}) [![image]({})]({}) {}".format(
10
+ item["title"],
11
+ item["url"],
12
+ item["marquee"],
13
+ item["url"],
14
+ item["description"],
14
15
  )
15
- for index in range(1, 4)
16
+ for item in [
17
+ {
18
+ "title": "blue-amo",
19
+ "url": "./blue_assistant/script/repository/blue_amo/README.md",
20
+ "marquee": "https://github.com/kamangir/assets/raw/main/blue-amo-2025-02-03-nswnx6/stitching_the_frames-2.png?raw=true",
21
+ "description": "story-telling with AI",
22
+ }
23
+ ]
16
24
  ]
17
25
 
18
26
 
@@ -28,6 +36,6 @@ def build():
28
36
  )
29
37
  for readme in [
30
38
  {"items": items, "path": ".."},
31
- {"path": "docs/blue-amo-01.md"},
39
+ {"path": "script/repository/blue_amo/README.md"},
32
40
  ]
33
41
  )
@@ -4,7 +4,7 @@ ICON = "🧠"
4
4
 
5
5
  DESCRIPTION = f"{ICON} An AI Assistant."
6
6
 
7
- VERSION = "4.97.1"
7
+ VERSION = "4.121.1"
8
8
 
9
9
  REPO_NAME = "blue-assistant"
10
10
 
@@ -1,14 +1,16 @@
1
- from typing import List
1
+ from typing import Dict, Callable, Tuple
2
2
 
3
- from blue_assistant.script.actions.generic import GenericAction
4
- from blue_assistant.script.actions.generate_image import GenerateImageAction
5
- from blue_assistant.script.actions.generate_text import GenerateTextAction
6
- from blue_assistant.script.actions.wip import WorkInProgressAction
3
+ from blue_assistant.script.repository.base.classes import BaseScript
4
+ from blue_assistant.script.actions.generic import generic_action
5
+ from blue_assistant.script.actions.generate_image import generate_image
6
+ from blue_assistant.script.actions.generate_text import generate_text
7
+ from blue_assistant.script.actions.skip import skip_action
7
8
  from blue_assistant.logger import logger
8
9
 
9
- list_of_actions: List[GenericAction] = [
10
- GenericAction,
11
- GenerateImageAction,
12
- GenerateTextAction,
13
- WorkInProgressAction,
14
- ]
10
+
11
+ dict_of_actions: Dict[str, Callable[[BaseScript, str], bool]] = {
12
+ "generic_action": generic_action,
13
+ "generate_image": generate_image,
14
+ "generate_text": generate_text,
15
+ "skip": skip_action,
16
+ }
@@ -1,58 +1,52 @@
1
- from blue_objects import file, objects
1
+ from blueness import module
2
+ from blue_objects import objects
2
3
  from openai_commands.image_generation.api import OpenAIImageGenerator
3
4
 
5
+ from blue_assistant import NAME
4
6
  from blue_assistant.env import (
5
7
  BLUE_ASSISTANT_IMAGE_DEFAULT_MODEL,
6
8
  BLUE_ASSISTANT_IMAGE_DEFAULT_SIZE,
7
9
  BLUE_ASSISTANT_IMAGE_DEFAULT_QUALITY,
8
10
  )
9
- from blue_assistant.script.actions.generic import GenericAction
10
11
  from blue_assistant.script.repository.base.classes import BaseScript
11
12
  from blue_assistant.logger import logger
12
13
 
13
-
14
- class GenerateImageAction(GenericAction):
15
- name = file.name(__file__)
16
-
17
- def __init__(
18
- self,
19
- script: BaseScript,
20
- ):
21
- super().__init__(script=script)
22
-
23
- self.generator = OpenAIImageGenerator(
24
- model=BLUE_ASSISTANT_IMAGE_DEFAULT_MODEL,
25
- verbose=self.script.verbose,
26
- )
27
-
28
- # https://platform.openai.com/docs/guides/images
29
- def perform(
30
- self,
31
- node_name: str,
32
- ) -> bool:
33
- if not super().perform(node_name=node_name):
34
- return False
35
-
36
- filename = f"{node_name}.png"
37
-
38
- success = self.generator.generate(
39
- prompt=self.script.nodes[node_name]["prompt"],
40
- filename=objects.path_of(
41
- filename=filename,
42
- object_name=self.script.object_name,
43
- create=True,
44
- ),
45
- quality=(
46
- BLUE_ASSISTANT_IMAGE_DEFAULT_QUALITY if self.script.test_mode else "hd"
47
- ),
48
- size=(
49
- BLUE_ASSISTANT_IMAGE_DEFAULT_SIZE
50
- if self.script.test_mode
51
- else "1792x1024"
52
- ),
53
- )[0]
54
-
55
- if success:
56
- self.script.nodes[node_name]["filename"] = filename
57
-
58
- return success
14
+ NAME = module.name(__file__, NAME)
15
+
16
+
17
+ # https://platform.openai.com/docs/guides/images
18
+ def generate_image(
19
+ script: BaseScript,
20
+ node_name: str,
21
+ ) -> bool:
22
+ logger.info(f"{NAME}: {script} @ {node_name} ...")
23
+
24
+ generator = OpenAIImageGenerator(
25
+ model=BLUE_ASSISTANT_IMAGE_DEFAULT_MODEL,
26
+ verbose=script.verbose,
27
+ )
28
+
29
+ filename = f"{node_name}.png"
30
+
31
+ success = generator.generate(
32
+ prompt=script.nodes[node_name]["prompt"],
33
+ filename=objects.path_of(
34
+ filename=filename,
35
+ object_name=script.object_name,
36
+ create=True,
37
+ ),
38
+ quality=(BLUE_ASSISTANT_IMAGE_DEFAULT_QUALITY if script.test_mode else "hd"),
39
+ size=(BLUE_ASSISTANT_IMAGE_DEFAULT_SIZE if script.test_mode else "1792x1024"),
40
+ sign_with_prompt=False,
41
+ footer=[
42
+ script.nodes[node_name].get(
43
+ "summary_prompt",
44
+ script.nodes[node_name]["prompt"],
45
+ )
46
+ ],
47
+ )[0]
48
+
49
+ if success:
50
+ script.nodes[node_name]["filename"] = filename
51
+
52
+ return success
@@ -1,97 +1,85 @@
1
- from typing import Dict, Tuple, List
1
+ from typing import List
2
2
  from openai import OpenAI
3
3
  import pprint
4
4
 
5
5
  from blueness import module
6
- from blue_objects import file
7
6
  from openai_commands.env import OPENAI_API_KEY
8
7
 
9
8
  from blue_assistant import NAME
9
+ from blue_assistant.script.repository.base.classes import BaseScript
10
10
  from blue_assistant.env import (
11
11
  BLUE_ASSISTANT_TEXT_DEFAULT_MODEL,
12
12
  BLUE_ASSISTANT_TEXT_MAX_TOKEN,
13
13
  )
14
- from blue_assistant.script.actions.generic import GenericAction
15
14
  from blue_assistant.logger import logger
16
15
 
17
16
  NAME = module.name(__file__, NAME)
18
17
 
19
18
 
20
- class GenerateTextAction(GenericAction):
21
- name = file.name(__file__)
22
-
23
- # https://platform.openai.com/docs/guides/text-generation
24
- def perform(
25
- self,
26
- node_name: str,
27
- ) -> bool:
28
- if not OPENAI_API_KEY:
29
- logger.error("OPENAI_API_KEY is not set.")
30
- return False
31
-
32
- if not super().perform(node_name=node_name):
33
- return False
19
+ # https://platform.openai.com/docs/guides/text-generation
20
+ def generate_text(
21
+ script: BaseScript,
22
+ node_name: str,
23
+ ) -> bool:
24
+ if not OPENAI_API_KEY:
25
+ logger.error("OPENAI_API_KEY is not set.")
26
+ return False
27
+
28
+ logger.info(f"{NAME}: {script} @ {node_name} ...")
29
+
30
+ messages: List = []
31
+ list_of_context_nodes = script.get_history(node_name)
32
+ logger.info("node context: {}".format(" <- ".join(list_of_context_nodes)))
33
+ for context_node in reversed(list_of_context_nodes):
34
+ messages += [
35
+ {
36
+ "role": "user",
37
+ "content": [
38
+ {
39
+ "type": "text",
40
+ "text": script.apply_vars(script.nodes[context_node]["prompt"]),
41
+ }
42
+ ],
43
+ }
44
+ ]
34
45
 
35
- messages: List = []
36
- list_of_context_nodes = self.script.get_history(node_name)
37
- logger.info("node context: {}".format(" <- ".join(list_of_context_nodes)))
38
- for context_node in reversed(list_of_context_nodes):
46
+ if script.nodes[context_node].get("completed", False):
39
47
  messages += [
40
48
  {
41
- "role": "user",
49
+ "role": "assistant",
42
50
  "content": [
43
51
  {
44
52
  "type": "text",
45
- "text": self.script.apply_vars(
46
- self.script.nodes[context_node]["prompt"]
47
- ),
53
+ "text": script.nodes[context_node]["output"],
48
54
  }
49
55
  ],
50
56
  }
51
57
  ]
52
58
 
53
- if self.script.nodes[context_node].get("completed", False):
54
- messages += [
55
- {
56
- "role": "assistant",
57
- "content": [
58
- {
59
- "type": "text",
60
- "text": self.script.nodes[context_node]["output"],
61
- }
62
- ],
63
- }
64
- ]
65
-
66
- if self.script.verbose:
67
- logger.info(f"messages: {pprint.pformat(messages)}")
68
-
69
- client = OpenAI(api_key=OPENAI_API_KEY)
70
-
71
- try:
72
- response = client.chat.completions.create(
73
- messages=messages,
74
- model=BLUE_ASSISTANT_TEXT_DEFAULT_MODEL,
75
- max_tokens=BLUE_ASSISTANT_TEXT_MAX_TOKEN,
76
- )
77
- except Exception as e:
78
- logger.error(str(e))
79
- return False
59
+ if script.verbose:
60
+ logger.info(f"messages: {pprint.pformat(messages)}")
80
61
 
81
- if self.script.verbose:
82
- logger.info("response: {}".format(response))
62
+ client = OpenAI(api_key=OPENAI_API_KEY)
83
63
 
84
- if not response.choices:
85
- logger.error("no choice.")
86
- return False
64
+ try:
65
+ response = client.chat.completions.create(
66
+ messages=messages,
67
+ model=BLUE_ASSISTANT_TEXT_DEFAULT_MODEL,
68
+ max_tokens=BLUE_ASSISTANT_TEXT_MAX_TOKEN,
69
+ )
70
+ except Exception as e:
71
+ logger.error(str(e))
72
+ return False
87
73
 
88
- output = response.choices[0].message.content
89
- logger.info(f"🗣️ output: {output}")
74
+ if script.verbose:
75
+ logger.info("response: {}".format(response))
90
76
 
91
- self.script.nodes[node_name]["output"] = output
77
+ if not response.choices:
78
+ logger.error("no choice.")
79
+ return False
92
80
 
93
- var_name = self.script.nodes[node_name].get("output", "")
94
- if var_name:
95
- self.script.vars[var_name] = output
81
+ output = response.choices[0].message.content
82
+ logger.info(f"🗣️ output: {output}")
83
+ script.nodes[node_name]["output"] = output
96
84
 
97
- return True
85
+ return True
@@ -1,27 +1,15 @@
1
- from blue_objects import file
1
+ from blueness import module
2
2
 
3
+ from blue_assistant import NAME
3
4
  from blue_assistant.script.repository.base.classes import BaseScript
4
5
  from blue_assistant.logger import logger
5
6
 
7
+ NAME = module.name(__file__, NAME)
6
8
 
7
- class GenericAction:
8
- name = file.name(__file__)
9
9
 
10
- def __init__(
11
- self,
12
- script: BaseScript,
13
- ):
14
- self.script = script
15
-
16
- def perform(
17
- self,
18
- node_name: str,
19
- ) -> bool:
20
- logger.info(
21
- "{}.perform on {}.{} ...".format(
22
- self.__class__.__name__,
23
- self.script.name,
24
- node_name,
25
- ),
26
- )
27
- return True
10
+ def generic_action(
11
+ script: BaseScript,
12
+ node_name: str,
13
+ ) -> bool:
14
+ logger.info(f"{NAME}: {script} @ {node_name} ...")
15
+ return True
@@ -0,0 +1,15 @@
1
+ from blueness import module
2
+
3
+ from blue_assistant import NAME
4
+ from blue_assistant.script.repository.base.classes import BaseScript
5
+ from blue_assistant.logger import logger
6
+
7
+ NAME = module.name(__file__, NAME)
8
+
9
+
10
+ def skip_action(
11
+ script: BaseScript,
12
+ node_name: str,
13
+ ) -> bool:
14
+ logger.info(f"{NAME}: {script} @ {node_name} ...")
15
+ return True
@@ -0,0 +1,13 @@
1
+ from typing import Dict, Callable
2
+
3
+ from blue_assistant.script.repository.base.classes import BaseScript
4
+ from blue_assistant.script.repository.blue_amo.actions import (
5
+ slicing_into_frames,
6
+ stitching_the_frames,
7
+ )
8
+
9
+
10
+ dict_of_actions: Dict[str, Callable[[BaseScript, str], bool]] = {
11
+ "slicing_into_frames": slicing_into_frames.slicing_into_frames,
12
+ "stitching_the_frames": stitching_the_frames.stitching_the_frames,
13
+ }
@@ -7,7 +7,7 @@ from blue_assistant.logger import logger
7
7
  NAME = module.name(__file__, NAME)
8
8
 
9
9
 
10
- def slice_into_frames(
10
+ def slicing_into_frames(
11
11
  script: BaseScript,
12
12
  node_name: str,
13
13
  ) -> bool:
@@ -25,11 +25,14 @@ def slice_into_frames(
25
25
  list_of_frame_prompts += script.vars["frame_count"] * [""]
26
26
 
27
27
  for index in range(script.vars["frame_count"]):
28
- node_name = f"generating-frame-{index+1:03d}"
28
+ node_name = f"generating_frame_{index+1:03d}"
29
29
 
30
- script.nodes[node_name]["prompt"] = script.nodes[node_name]["prompt"].replace(
31
- ":::input",
32
- list_of_frame_prompts[index],
30
+ script.nodes[node_name]["summary_prompt"] = list_of_frame_prompts[index]
31
+
32
+ script.nodes[node_name]["prompt"] = (
33
+ script.nodes[node_name]["prompt"]
34
+ .replace(":::story", " ".join(list_of_frame_prompts[:index]))
35
+ .replace(":::input", list_of_frame_prompts[index])
33
36
  )
34
37
 
35
38
  return True
@@ -0,0 +1,128 @@
1
+ from typing import List
2
+ import numpy as np
3
+ import cv2
4
+ from tqdm import trange
5
+ import math
6
+
7
+ from blueness import module
8
+ from blue_objects import file, objects
9
+ from blue_options import string
10
+
11
+ from blue_assistant import NAME
12
+ from blue_assistant.script.repository.base.classes import BaseScript
13
+ from blue_assistant.logger import logger
14
+
15
+ NAME = module.name(__file__, NAME)
16
+
17
+
18
+ def stitching_the_frames(
19
+ script: BaseScript,
20
+ node_name: str,
21
+ ) -> bool:
22
+ list_of_frames_filenames: List[str] = [
23
+ filename
24
+ for filename in [
25
+ script.nodes[node_name_].get("filename", "")
26
+ for node_name_ in [
27
+ f"generating_frame_{index+1:03d}"
28
+ for index in range(script.vars["frame_count"])
29
+ ]
30
+ ]
31
+ if filename
32
+ ]
33
+ if not list_of_frames_filenames:
34
+ return True
35
+
36
+ logger.info(
37
+ "{} frames to stitch: {}".format(
38
+ len(list_of_frames_filenames),
39
+ ", ".join(list_of_frames_filenames),
40
+ )
41
+ )
42
+
43
+ list_of_frames: List[np.ndarray] = []
44
+ for filename in list_of_frames_filenames:
45
+ success, frame = file.load_image(
46
+ objects.path_of(
47
+ filename=filename,
48
+ object_name=script.object_name,
49
+ )
50
+ )
51
+
52
+ if success:
53
+ list_of_frames += [frame]
54
+
55
+ if not list_of_frames:
56
+ return True
57
+
58
+ common_height = list_of_frames[0].shape[0]
59
+ common_width = list_of_frames[0].shape[1]
60
+ for index in trange(1, len(list_of_frames)):
61
+ frame_height = list_of_frames[index].shape[0]
62
+ frame_width = list_of_frames[index].shape[1]
63
+
64
+ if frame_height != common_height or frame_width != common_width:
65
+ list_of_frames[index] = cv2.resize(
66
+ list_of_frames[index],
67
+ (common_width, common_height),
68
+ interpolation=cv2.INTER_AREA,
69
+ )
70
+
71
+ width_count = int(math.ceil(math.sqrt(len(list_of_frames))))
72
+ height_count = int(math.ceil(len(list_of_frames) / width_count))
73
+ logger.info(
74
+ "{} x {} -> {} x {}".format(
75
+ len(list_of_frames),
76
+ string.pretty_shape_of_matrix(list_of_frames[0]),
77
+ height_count,
78
+ width_count,
79
+ )
80
+ )
81
+
82
+ list_of_frames += (height_count * width_count - len(list_of_frames)) * [
83
+ np.zeros_like(list_of_frames[0])
84
+ ]
85
+
86
+ full_frame: np.ndarray = None
87
+ for height_index in trange(height_count):
88
+ row = np.concatenate(
89
+ list_of_frames[
90
+ height_index * width_count : (height_index + 1) * width_count
91
+ ],
92
+ axis=1,
93
+ )
94
+
95
+ if not height_index:
96
+ full_frame = row
97
+ else:
98
+ full_frame = np.concatenate([full_frame, row], axis=0)
99
+ logger.info(f"full frame: {string.pretty_shape_of_matrix(full_frame)}")
100
+
101
+ for scale in [1, 2, 4]:
102
+ scaled_full_frame = (
103
+ full_frame
104
+ if scale == 1
105
+ else cv2.resize(
106
+ full_frame,
107
+ (
108
+ int(full_frame.shape[1] / scale),
109
+ int(full_frame.shape[0] / scale),
110
+ ),
111
+ interpolation=cv2.INTER_AREA,
112
+ )
113
+ )
114
+
115
+ if not file.save_image(
116
+ objects.path_of(
117
+ filename="{}{}.png".format(
118
+ node_name,
119
+ "" if scale == 1 else f"-{scale}",
120
+ ),
121
+ object_name=script.object_name,
122
+ ),
123
+ scaled_full_frame,
124
+ log=True,
125
+ ):
126
+ return False
127
+
128
+ return True
@@ -5,12 +5,7 @@ from blue_objects import file, path
5
5
 
6
6
  from blue_assistant import NAME
7
7
  from blue_assistant.script.repository.generic.classes import GenericScript
8
- from blue_assistant.script.repository.blue_amo.actions.slice_into_frames import (
9
- slice_into_frames,
10
- )
11
- from blue_assistant.script.repository.blue_amo.actions.stitch_the_frames import (
12
- stitch_the_frames,
13
- )
8
+ from blue_assistant.script.repository.blue_amo.actions import dict_of_actions
14
9
  from blue_assistant.logger import logger
15
10
 
16
11
  NAME = module.name(__file__, NAME)
@@ -34,7 +29,7 @@ class BlueAmoScript(GenericScript):
34
29
  if self.test_mode:
35
30
  self.vars["frame_count"] = 1
36
31
 
37
- holder_node_name = "generating-the-frames"
32
+ holder_node_name = "generating_the_frames"
38
33
  logger.info(
39
34
  "{}: expanding {} X {}...".format(
40
35
  NAME,
@@ -47,19 +42,19 @@ class BlueAmoScript(GenericScript):
47
42
  del self.nodes[holder_node_name]
48
43
  self.G.remove_node(holder_node_name)
49
44
 
50
- reduce_node = "stitching-the-frames"
45
+ reduce_node = "stitching_the_frames"
51
46
  self.G.add_node(reduce_node)
52
47
  self.nodes[reduce_node] = {"action": "skip"}
53
48
 
54
49
  for index in range(self.vars["frame_count"]):
55
- node_name = f"generating-frame-{index+1:03d}"
50
+ node_name = f"generating_frame_{index+1:03d}"
56
51
 
57
52
  self.nodes[node_name] = copy.deepcopy(holder_node)
58
53
 
59
54
  self.G.add_node(node_name)
60
55
  self.G.add_edge(
61
56
  node_name,
62
- "slicing-into-frames",
57
+ "slicing_into_frames",
63
58
  )
64
59
  self.G.add_edge(
65
60
  reduce_node,
@@ -75,14 +70,8 @@ class BlueAmoScript(GenericScript):
75
70
  if not super().perform_action(node_name=node_name):
76
71
  return False
77
72
 
78
- if node_name == "slicing-into-frames":
79
- return slice_into_frames(
80
- script=self,
81
- node_name=node_name,
82
- )
83
-
84
- if node_name == "stitching-the-frames":
85
- return stitch_the_frames(
73
+ if node_name in dict_of_actions:
74
+ return dict_of_actions[node_name](
86
75
  script=self,
87
76
  node_name=node_name,
88
77
  )
@@ -9,7 +9,7 @@ from blue_objects.metadata import post_to_object
9
9
 
10
10
  from blue_assistant import NAME
11
11
  from blue_assistant.script.repository.base.classes import BaseScript
12
- from blue_assistant.script.actions.functions import get_action_class
12
+ from blue_assistant.script.actions import dict_of_actions
13
13
  from blue_assistant.logger import logger
14
14
 
15
15
 
@@ -24,25 +24,15 @@ class GenericScript(BaseScript):
24
24
  node_name: str,
25
25
  ) -> bool:
26
26
  action_name = self.nodes[node_name].get("action", "unknown")
27
- if action_name == "skip":
28
- return True
29
-
30
- success, action_class = get_action_class(action_name=action_name)
31
- if not success:
32
- return success
33
-
34
- logger.info(
35
- "{}.perform_action: {} == {} on {}".format(
36
- NAME,
37
- action_name,
38
- action_class.__name__,
39
- node_name,
40
- )
41
- )
42
27
 
43
- action_object = action_class(script=self)
28
+ if action_name not in dict_of_actions:
29
+ logger.error(f"{action_name}: action not found.")
30
+ return False
44
31
 
45
- return action_object.perform(node_name=node_name)
32
+ return dict_of_actions[action_name](
33
+ script=self,
34
+ node_name=node_name,
35
+ )
46
36
 
47
37
  def run(
48
38
  self,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: blue_assistant
3
- Version: 4.97.1
3
+ Version: 4.121.1
4
4
  Summary: 🧠 An AI Assistant.
5
5
  Home-page: https://github.com/kamangir/blue-assistant
6
6
  Author: Arash Abadpour (Kamangir)
@@ -67,9 +67,13 @@ graph LR
67
67
  classDef folder fill:#999,stroke:#333,stroke-width:2px;
68
68
  ```
69
69
 
70
+ | |
71
+ | --- |
72
+ | [`blue-amo`](https://raw.githubusercontent.com/kamangir/blue-assistant/main/blue_assistant/script/repository/blue_amo/README.md) [![image](https://github.com/kamangir/assets/raw/main/blue-amo-2025-02-03-nswnx6/stitching_the_frames-2.png?raw=true)](https://raw.githubusercontent.com/kamangir/blue-assistant/main/blue_assistant/script/repository/blue_amo/README.md) story-telling with AI |
73
+
70
74
  ---
71
75
 
72
76
 
73
77
  [![pylint](https://github.com/kamangir/blue-assistant/actions/workflows/pylint.yml/badge.svg)](https://github.com/kamangir/blue-assistant/actions/workflows/pylint.yml) [![pytest](https://github.com/kamangir/blue-assistant/actions/workflows/pytest.yml/badge.svg)](https://github.com/kamangir/blue-assistant/actions/workflows/pytest.yml) [![bashtest](https://github.com/kamangir/blue-assistant/actions/workflows/bashtest.yml/badge.svg)](https://github.com/kamangir/blue-assistant/actions/workflows/bashtest.yml) [![PyPI version](https://img.shields.io/pypi/v/blue-assistant.svg)](https://pypi.org/project/blue-assistant/) [![PyPI - Downloads](https://img.shields.io/pypi/dd/blue-assistant)](https://pypistats.org/packages/blue-assistant)
74
78
 
75
- built by 🌀 [`blue_options-4.207.1`](https://github.com/kamangir/awesome-bash-cli), based on 🧠 [`blue_assistant-4.97.1`](https://github.com/kamangir/blue-assistant).
79
+ built by 🌀 [`blue_options-4.207.1`](https://github.com/kamangir/awesome-bash-cli), based on 🧠 [`blue_assistant-4.121.1`](https://github.com/kamangir/blue-assistant).
@@ -1,5 +1,5 @@
1
- blue_assistant/README.py,sha256=Nzr3v-VSa8CISkqkLHd8ILyY_WiJ7x2igYPH-lYpzEY,795
2
- blue_assistant/__init__.py,sha256=PSvVOR6YHG3cJIrNq6NGYQS9Zk8RctcrOYRMi-GaQiI,310
1
+ blue_assistant/README.py,sha256=Z_T2b3tcugn2-oCcb0uqEBbva1ydY_kZ7u-ipH5Nt3g,1060
2
+ blue_assistant/__init__.py,sha256=gBWYfpEKu8JsBKhR0TdNZ2DsfpC8fPQJx3oltGBoSk8,311
3
3
  blue_assistant/__main__.py,sha256=URtal70XZc0--3FDTYWcLtnGOqBYjMX9gt-L1k8hDXI,361
4
4
  blue_assistant/config.env,sha256=gjGYkDkmzpwgy7_J-i9RclTKZsKtaAibn7mavD9l4u8,210
5
5
  blue_assistant/env.py,sha256=h2goHjsspOLjZ44yFHqHLB7wPl_GCodg3D6yfSE5FfM,732
@@ -19,7 +19,7 @@ blue_assistant/.abcli/script/run.sh,sha256=kSXmyM9NUj2X2orSGyu5t_P5frG-gyumbRq-x
19
19
  blue_assistant/.abcli/tests/README.sh,sha256=Qs0YUxVB1OZZ70Nqw2kT1LKXeUnC5-XfQRMfqb8Cbwg,152
20
20
  blue_assistant/.abcli/tests/help.sh,sha256=mENB9ZNBEEPmIs9tp8WkQW3dq75_US7EI7_-d4IJQpo,724
21
21
  blue_assistant/.abcli/tests/script_list.sh,sha256=OVOwWO9wR0eeDZTM6uub-eTKbz3eswU3vEUPWXcK-gQ,178
22
- blue_assistant/.abcli/tests/script_run.sh,sha256=ai6ZIepiDkEufPdVjnPEly2FPQdaHobWKBA5wlyqA8g,743
22
+ blue_assistant/.abcli/tests/script_run.sh,sha256=vfmK8sjkMfSQPwCacQppiL6inMbvQP7nci7qLppFSL0,769
23
23
  blue_assistant/.abcli/tests/version.sh,sha256=oR2rvYR8zi-0VDPIdPJsmsmWwYaamT8dmNTqUh3-8Gw,154
24
24
  blue_assistant/help/__init__.py,sha256=ajz1GSNU9xYVrFEDSz6Xwg7amWQ_yvW75tQa1ZvRIWc,3
25
25
  blue_assistant/help/__main__.py,sha256=cVejR7OpoWPg0qLbm-PZf5TuJS27x49jzfiyCLyzEns,241
@@ -28,24 +28,23 @@ blue_assistant/help/script.py,sha256=tofv49tIBqoH8ed9hDCFHqzWaXmyyPofvqElk2n976w
28
28
  blue_assistant/script/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
29
  blue_assistant/script/__main__.py,sha256=eOSOo5yYTPMwIXZ0GkuWkmOcsDWrZtHvClyJizXSk2w,1657
30
30
  blue_assistant/script/load.py,sha256=JsDY9T3HTM9vXngvKsA0Mt_erxAnRR_jI62-JhrOBMU,831
31
- blue_assistant/script/actions/__init__.py,sha256=8Sp6avoJGDXVORvx5mvkxTNaxjz_KevKN4Wb8qLZHsQ,487
32
- blue_assistant/script/actions/functions.py,sha256=nazOu20plxxxUIcr1YCpNiWn4zmcGCCWcojWxLnZtl8,669
33
- blue_assistant/script/actions/generate_image.py,sha256=wvj3V10gWe_rcxh5xIT3JZ2I-Uwgh_Rl_E73JLsenUc,1695
34
- blue_assistant/script/actions/generate_text.py,sha256=EeE57DAbAj3n7VDUzFn1kT8LJCwHIQvg-Ds8unxicEQ,2971
35
- blue_assistant/script/actions/generic.py,sha256=9VCnJ9u1eT3H63Ihg6SRpKrWNw5MPa6MLP16QYl6HaE,577
36
- blue_assistant/script/actions/wip.py,sha256=K4kJE4bn3u6o-QWTESPydO_eD54zOwZbU9WLAO94z1Q,171
31
+ blue_assistant/script/actions/__init__.py,sha256=W0PisTP1H0RRqivzwiaXlN-kvE3m1xlJtn5WGZ-PFtg,625
32
+ blue_assistant/script/actions/generate_image.py,sha256=1OtDAXcFijTXUwZqfpw0375pCTQ3ooFvD2dYJxwFJSg,1513
33
+ blue_assistant/script/actions/generate_text.py,sha256=xenvUISPKoq3rkzrBZIlRhQh7s7PTkchTTMdcyybe24,2394
34
+ blue_assistant/script/actions/generic.py,sha256=ET1RaKcUABM8HdIv8JecSpUFasYqmwHacL-5LjF-8NM,355
35
+ blue_assistant/script/actions/skip.py,sha256=G9gbGBbOLiCqcsmEUobdoxkB6wohFYmyi1arQGorZSg,352
37
36
  blue_assistant/script/repository/__init__.py,sha256=WFkbe-6yyljpmeVpXgLhOPt-YRc7BwkRNzPO-7Wz0Dg,573
38
37
  blue_assistant/script/repository/blue_amo/__init__.py,sha256=WjL9GIlN-DBnbUMJ8O_FxTp0rcVGlsIS3H9YtXEefTk,76
39
- blue_assistant/script/repository/blue_amo/classes.py,sha256=SK3kNk14cZ8M7-aU3tQtbrTQLcw-ev_KtNR8J0U7QZY,2382
40
- blue_assistant/script/repository/blue_amo/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
- blue_assistant/script/repository/blue_amo/actions/slice_into_frames.py,sha256=AId4m8K64RHNS_RF_TvifOZPQqyS84ejKqz3KNxRsOA,1041
42
- blue_assistant/script/repository/blue_amo/actions/stitch_the_frames.py,sha256=Q9kqawnTxHTM-Mff8Ok0kdvhV-FIAGaKizy7JwdSrPU,2229
38
+ blue_assistant/script/repository/blue_amo/classes.py,sha256=vWQ_qMdJ2LmpEjDGFnSxOMZPd34yj-DX4UUTnx5aMtY,2082
39
+ blue_assistant/script/repository/blue_amo/actions/__init__.py,sha256=je2S21KvYB3QkbABs71parwUh8MCh2mdlNZfLx_QuDg,430
40
+ blue_assistant/script/repository/blue_amo/actions/slicing_into_frames.py,sha256=79SI7_69FKKLeX_jHlfXnUWGtG4Sj7sBJOfeFwK8I9U,1201
41
+ blue_assistant/script/repository/blue_amo/actions/stitching_the_frames.py,sha256=mbXriat6deEAmuo5Y1ValySnUXDENR7TZS_3nVPlQ6M,3622
43
42
  blue_assistant/script/repository/generic/__init__.py,sha256=kLffGsQMQAFJTw6IZBE5eBxvshP1x9wwHHR4hsDJblo,75
44
- blue_assistant/script/repository/generic/classes.py,sha256=7XIbzwMFFLr79NcVHi53uRPznw2wkQIF8UQ1-KAdNAY,2540
43
+ blue_assistant/script/repository/generic/classes.py,sha256=XuUhtBdY85ZGdMR9IcZ7nScJmQ2IDhJBbhyMv3amDHc,2265
45
44
  blue_assistant/script/repository/moon_datasets/__init__.py,sha256=aCtmP2avh3yKAJ668S3GsLR9vbBOm5zt9FSFCqy_tAs,86
46
45
  blue_assistant/script/repository/moon_datasets/classes.py,sha256=68zThDhjF9gGRnsw8EKNLGOMBFbCSljt0jGovuOzCAc,197
47
- blue_assistant-4.97.1.dist-info/LICENSE,sha256=ogEPNDSH0_dhiv_lT3ifVIdgIzHAqNA_SemnxUfPBJk,7048
48
- blue_assistant-4.97.1.dist-info/METADATA,sha256=ObxR2e-zVw0o4-sBebHfSFzZ-D_WcEChr1OnU69oOMw,2625
49
- blue_assistant-4.97.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
50
- blue_assistant-4.97.1.dist-info/top_level.txt,sha256=ud0BkBbdOVze13bNqHuhZj1rwCztaBtDf5ChEYzASOs,15
51
- blue_assistant-4.97.1.dist-info/RECORD,,
46
+ blue_assistant-4.121.1.dist-info/LICENSE,sha256=ogEPNDSH0_dhiv_lT3ifVIdgIzHAqNA_SemnxUfPBJk,7048
47
+ blue_assistant-4.121.1.dist-info/METADATA,sha256=WEP68rkZElk6gmoZ7G27BUdyM3KjBo_n1pdHFWDv91A,3032
48
+ blue_assistant-4.121.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
49
+ blue_assistant-4.121.1.dist-info/top_level.txt,sha256=ud0BkBbdOVze13bNqHuhZj1rwCztaBtDf5ChEYzASOs,15
50
+ blue_assistant-4.121.1.dist-info/RECORD,,
@@ -1,22 +0,0 @@
1
- from typing import List, Dict, Tuple, Type
2
-
3
- from blueness import module
4
- from blue_assistant.script.actions.generic import GenericAction
5
- from blue_assistant.script.repository.base.classes import BaseScript
6
- from blue_assistant.script.actions import list_of_actions
7
-
8
- from blue_assistant import NAME
9
- from blue_assistant.logger import logger
10
-
11
- NAME = module.name(__file__, NAME)
12
-
13
-
14
- def get_action_class(
15
- action_name: str,
16
- ) -> Tuple[bool, Type[GenericAction]]:
17
- for action_class in list_of_actions:
18
- if action_class.name == action_name:
19
- return True, action_class
20
-
21
- logger.error(f"{action_name}: action not found.")
22
- return False, GenericAction
@@ -1,7 +0,0 @@
1
- from blue_objects import file
2
-
3
- from blue_assistant.script.actions.generic import GenericAction
4
-
5
-
6
- class WorkInProgressAction(GenericAction):
7
- name = file.name(__file__)
@@ -1,81 +0,0 @@
1
- from typing import List
2
- import numpy as np
3
- import cv2
4
- from tqdm import trange
5
-
6
- from blueness import module
7
- from blue_objects import file, objects
8
- from blue_options import string
9
-
10
- from blue_assistant import NAME
11
- from blue_assistant.script.repository.base.classes import BaseScript
12
- from blue_assistant.logger import logger
13
-
14
- NAME = module.name(__file__, NAME)
15
-
16
-
17
- def stitch_the_frames(
18
- script: BaseScript,
19
- node_name: str,
20
- ) -> bool:
21
- list_of_frames_filenames: List[str] = [
22
- filename
23
- for filename in [
24
- script.nodes[node_name_].get("filename", "")
25
- for node_name_ in [
26
- f"generating-frame-{index+1:03d}"
27
- for index in range(script.vars["frame_count"])
28
- ]
29
- ]
30
- if filename
31
- ]
32
- if not list_of_frames_filenames:
33
- return True
34
-
35
- logger.info(
36
- "{} frames to stitch: {}".format(
37
- len(list_of_frames_filenames),
38
- ", ".join(list_of_frames_filenames),
39
- )
40
- )
41
-
42
- list_of_frames: List[np.ndarray] = []
43
- for filename in list_of_frames_filenames:
44
- success, frame = file.load_image(
45
- objects.path_of(
46
- filename=filename,
47
- object_name=script.object_name,
48
- )
49
- )
50
-
51
- if success:
52
- list_of_frames += [frame]
53
-
54
- if not list_of_frames:
55
- return True
56
-
57
- common_height = list_of_frames[0].shape[0]
58
- for index in trange(len(list_of_frames)):
59
- if list_of_frames[index].shape[0] != common_height:
60
- aspect_ratio = (
61
- list_of_frames[index].shape[1] / list_of_frames[index].shape[0]
62
- )
63
- new_width = int(common_height * aspect_ratio)
64
-
65
- list_of_frames[index] = cv2.resize(
66
- list_of_frames[index],
67
- (new_width, common_height),
68
- interpolation=cv2.INTER_AREA,
69
- )
70
-
71
- full_frame = np.concatenate(list_of_frames, axis=1)
72
- logger.info(f"full_frame: {string.pretty_shape_of_matrix(full_frame)}")
73
-
74
- return file.save_image(
75
- objects.path_of(
76
- filename=f"{node_name}.png",
77
- object_name=script.object_name,
78
- ),
79
- full_frame,
80
- log=True,
81
- )