blue-assistant 4.307.1__tar.gz → 4.325.1__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 (85) hide show
  1. {blue_assistant-4.307.1/blue_assistant.egg-info → blue_assistant-4.325.1}/PKG-INFO +2 -2
  2. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/README.md +1 -1
  3. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/script/run.sh +3 -1
  4. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/__init__.py +1 -1
  5. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/help/script.py +27 -3
  6. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/script/__main__.py +16 -1
  7. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/script/actions/web_crawl.py +4 -3
  8. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/script/load.py +9 -1
  9. blue_assistant-4.325.1/blue_assistant/script/repository/base/classes.py +21 -0
  10. blue_assistant-4.307.1/blue_assistant/script/repository/base/classes.py → blue_assistant-4.325.1/blue_assistant/script/repository/base/root.py +156 -47
  11. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/script/repository/blue_amo/classes.py +17 -19
  12. blue_assistant-4.325.1/blue_assistant/script/repository/functions.py +18 -0
  13. blue_assistant-4.325.1/blue_assistant/script/repository/orbital_data_explorer/actions/__init__.py +11 -0
  14. blue_assistant-4.325.1/blue_assistant/script/repository/orbital_data_explorer/actions/expanding_the_extractions.py +109 -0
  15. blue_assistant-4.325.1/blue_assistant/script/repository/orbital_data_explorer/classes.py +15 -0
  16. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/web/crawl.py +5 -5
  17. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/web/fetch.py +2 -2
  18. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/web/functions.py +11 -0
  19. {blue_assistant-4.307.1 → blue_assistant-4.325.1/blue_assistant.egg-info}/PKG-INFO +2 -2
  20. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant.egg-info/SOURCES.txt +3 -0
  21. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/setup.py +1 -0
  22. blue_assistant-4.307.1/blue_assistant/script/repository/base/root.py +0 -5
  23. blue_assistant-4.307.1/blue_assistant/script/repository/orbital_data_explorer/classes.py +0 -7
  24. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/LICENSE +0 -0
  25. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/MANIFEST.in +0 -0
  26. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/abcli.sh +0 -0
  27. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/actions.sh +0 -0
  28. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/alias.sh +0 -0
  29. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/blue_assistant.sh +0 -0
  30. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/browse.sh +0 -0
  31. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/hue/create_user.sh +0 -0
  32. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/hue/list.sh +0 -0
  33. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/hue/set.sh +0 -0
  34. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/hue.sh +0 -0
  35. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/script/list.sh +0 -0
  36. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/script.sh +0 -0
  37. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/tests/README.sh +0 -0
  38. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/tests/help.sh +0 -0
  39. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/tests/script_list.sh +0 -0
  40. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/tests/script_run.sh +0 -0
  41. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/tests/version.sh +0 -0
  42. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/tests/web_crawl.sh +0 -0
  43. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/tests/web_fetch.sh +0 -0
  44. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/web/crawl.sh +0 -0
  45. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/web/fetch.sh +0 -0
  46. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/.abcli/web.sh +0 -0
  47. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/README.py +0 -0
  48. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/__main__.py +0 -0
  49. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/config.env +0 -0
  50. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/env.py +0 -0
  51. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/functions.py +0 -0
  52. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/help/__init__.py +0 -0
  53. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/help/__main__.py +0 -0
  54. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/help/functions.py +0 -0
  55. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/help/hue.py +0 -0
  56. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/help/web.py +0 -0
  57. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/host.py +0 -0
  58. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/logger.py +0 -0
  59. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/sample.env +0 -0
  60. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/script/__init__.py +0 -0
  61. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/script/actions/__init__.py +0 -0
  62. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/script/actions/generate_image.py +0 -0
  63. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/script/actions/generate_text.py +0 -0
  64. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/script/actions/generic.py +0 -0
  65. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/script/repository/__init__.py +0 -0
  66. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/script/repository/base/__init__.py +0 -0
  67. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/script/repository/blue_amo/__init__.py +0 -0
  68. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/script/repository/blue_amo/actions/__init__.py +0 -0
  69. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/script/repository/blue_amo/actions/setting_frame_prompts.py +0 -0
  70. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/script/repository/blue_amo/actions/stitching_the_frames.py +0 -0
  71. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/script/repository/hue/__init__.py +0 -0
  72. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/script/repository/hue/__main__.py +0 -0
  73. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/script/repository/hue/api.py +0 -0
  74. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/script/repository/hue/classes.py +0 -0
  75. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/script/repository/hue/colors.py +0 -0
  76. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/script/repository/orbital_data_explorer/__init__.py +0 -0
  77. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/urls.py +0 -0
  78. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/web/__init__.py +0 -0
  79. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant/web/__main__.py +0 -0
  80. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant.egg-info/dependency_links.txt +0 -0
  81. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant.egg-info/requires.txt +0 -0
  82. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/blue_assistant.egg-info/top_level.txt +0 -0
  83. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/pyproject.toml +0 -0
  84. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/requirements.txt +0 -0
  85. {blue_assistant-4.307.1 → blue_assistant-4.325.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: blue_assistant
3
- Version: 4.307.1
3
+ Version: 4.325.1
4
4
  Summary: 🧠 An AI Assistant.
5
5
  Home-page: https://github.com/kamangir/blue-assistant
6
6
  Author: Arash Abadpour (Kamangir)
@@ -124,4 +124,4 @@ Also home to [`@web`](https://raw.githubusercontent.com/kamangir/blue-assistant/
124
124
 
125
125
  [![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)
126
126
 
127
- built by 🌀 [`blue_options-4.240.1`](https://github.com/kamangir/awesome-bash-cli), based on 🧠 [`blue_assistant-4.307.1`](https://github.com/kamangir/blue-assistant).
127
+ built by 🌀 [`blue_options-4.240.1`](https://github.com/kamangir/awesome-bash-cli), based on 🧠 [`blue_assistant-4.325.1`](https://github.com/kamangir/blue-assistant).
@@ -79,4 +79,4 @@ Also home to [`@web`](./blue_assistant/web/)
79
79
 
80
80
  [![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)
81
81
 
82
- built by 🌀 [`blue_options-4.240.1`](https://github.com/kamangir/awesome-bash-cli), based on 🧠 [`blue_assistant-4.307.1`](https://github.com/kamangir/blue-assistant).
82
+ built by 🌀 [`blue_options-4.240.1`](https://github.com/kamangir/awesome-bash-cli), based on 🧠 [`blue_assistant-4.325.1`](https://github.com/kamangir/blue-assistant).
@@ -8,8 +8,9 @@ function blue_assistant_script_run() {
8
8
 
9
9
  local script_options=$2
10
10
  local script_name=$(abcli_option "$script_options" script base)
11
+ local script_version=$(abcli_option "$script_options" version base)
11
12
 
12
- local object_name=$(abcli_clarify_object $3 $script_name-$(abcli_string_timestamp_short))
13
+ local object_name=$(abcli_clarify_object $3 $script_name-$script_version-$(abcli_string_timestamp_short))
13
14
  [[ "$do_download" == 1 ]] &&
14
15
  abcli_download - $object_name
15
16
 
@@ -19,6 +20,7 @@ function blue_assistant_script_run() {
19
20
  python3 -m blue_assistant.script \
20
21
  run \
21
22
  --script_name $script_name \
23
+ --script_version $script_version \
22
24
  --object_name $object_name \
23
25
  "${@:4}"
24
26
  [[ $? -ne 0 ]] && return 1
@@ -4,7 +4,7 @@ ICON = "🧠"
4
4
 
5
5
  DESCRIPTION = f"{ICON} An AI Assistant."
6
6
 
7
- VERSION = "4.307.1"
7
+ VERSION = "4.325.1"
8
8
 
9
9
  REPO_NAME = "blue-assistant"
10
10
 
@@ -1,8 +1,10 @@
1
1
  from typing import List
2
+ from functools import reduce
2
3
 
3
4
  from blue_options.terminal import show_usage, xtra
4
5
 
5
6
  from blue_assistant.script.repository import list_of_script_names
7
+ from blue_assistant.script.repository.functions import get_script_versions
6
8
 
7
9
 
8
10
  def help_list(
@@ -32,13 +34,28 @@ def help_run(
32
34
  ) -> str:
33
35
  options = xtra("~download,dryrun,~upload", mono=mono)
34
36
 
35
- script_options = "script=<script>"
37
+ script_options = "script=<name>,version=<version>"
36
38
 
37
39
  args = [
38
40
  "[--test_mode 1]",
39
41
  "[--verbose 1]",
42
+ "[--runnable <~node_1,~node_2>]",
40
43
  ]
41
44
 
45
+ def script_version_details(script_name: str) -> List[str]:
46
+ list_of_script_versions = get_script_versions(script_name)
47
+
48
+ return (
49
+ [
50
+ "{}: {}".format(
51
+ script_name,
52
+ " | ".join(list_of_script_versions),
53
+ )
54
+ ]
55
+ if list_of_script_versions
56
+ else []
57
+ )
58
+
42
59
  return show_usage(
43
60
  [
44
61
  "@assistant",
@@ -49,9 +66,16 @@ def help_run(
49
66
  "[-|<object-name>]",
50
67
  ]
51
68
  + args,
52
- "run <object-name>.",
69
+ "run <script-name>/<script-version> in <object-name>.",
53
70
  {
54
- "script: {}".format(" | ".join(list_of_script_names)): [],
71
+ "name: {}".format(" | ".join(list_of_script_names)): reduce(
72
+ lambda x, y: x + y,
73
+ [
74
+ script_version_details(script_name)
75
+ for script_name in list_of_script_names
76
+ ],
77
+ [],
78
+ )
55
79
  },
56
80
  mono=mono,
57
81
  )
@@ -21,6 +21,11 @@ parser.add_argument(
21
21
  type=str,
22
22
  help=" | ".join(list_of_script_names),
23
23
  )
24
+ parser.add_argument(
25
+ "--script_version",
26
+ type=str,
27
+ default="base",
28
+ )
24
29
  parser.add_argument(
25
30
  "--object_name",
26
31
  type=str,
@@ -48,6 +53,13 @@ parser.add_argument(
48
53
  default=1,
49
54
  help="0 | 1",
50
55
  )
56
+ parser.add_argument(
57
+ "--runnable",
58
+ type=str,
59
+ default="",
60
+ help="~node_1,~node_2",
61
+ )
62
+
51
63
  args = parser.parse_args()
52
64
 
53
65
  delim = " " if args.delim == "space" else args.delim
@@ -64,13 +76,16 @@ if args.task == "list":
64
76
  elif args.task == "run":
65
77
  success, script = load_script(
66
78
  script_name=args.script_name,
79
+ script_version=args.script_version,
67
80
  object_name=args.object_name,
68
81
  test_mode=args.test_mode == 1,
69
82
  verbose=args.verbose == 1,
70
83
  )
71
84
 
72
85
  if success:
73
- success = script.run()
86
+ success = script.run(
87
+ runnable=args.runnable,
88
+ )
74
89
  else:
75
90
  success = None
76
91
 
@@ -4,6 +4,7 @@ from blue_options.logger import log_list
4
4
 
5
5
  from blue_assistant import NAME
6
6
  from blue_assistant.web.crawl import crawl_list_of_urls
7
+ from blue_assistant.web.functions import normalize_url
7
8
  from blue_assistant.script.repository.base.root import RootScript
8
9
  from blue_assistant.logger import logger
9
10
 
@@ -32,16 +33,16 @@ def web_crawl(
32
33
  if seed_url_var_name not in script.vars:
33
34
  logger.error(f"{node_name}: {seed_url_var_name}: seed_urls not found in vars.")
34
35
  return False
35
- seed_urls = script.vars[seed_url_var_name]
36
+ seed_urls = list({normalize_url(url) for url in script.vars[seed_url_var_name]})
36
37
  log_list(logger, "using", seed_urls, "seed url(s)")
37
38
 
38
- success, _ = crawl_list_of_urls(
39
+ success, crawl_cache = crawl_list_of_urls(
39
40
  seed_urls=seed_urls,
40
41
  object_name=script.object_name,
41
42
  max_iterations=script.nodes[node_name]["max_iterations"],
42
43
  cache_prefix=node_name,
43
44
  )
44
45
 
45
- script.nodes[node_name]["output"] = success
46
+ script.nodes[node_name]["output"] = crawl_cache
46
47
 
47
48
  return success
@@ -8,8 +8,11 @@ from blue_assistant.logger import logger
8
8
  def load_script(
9
9
  script_name: str,
10
10
  object_name: str,
11
+ script_version: str = "base",
11
12
  test_mode: bool = False,
13
+ log: bool = True,
12
14
  verbose: bool = False,
15
+ save_graph: bool = True,
13
16
  ) -> Tuple[bool, BaseScript]:
14
17
  found: bool = False
15
18
  script_class: Type[BaseScript] = BaseScript
@@ -22,8 +25,13 @@ def load_script(
22
25
  if not found:
23
26
  logger.error(f"{script_name}: script not found.")
24
27
 
25
- return found, script_class(
28
+ script = script_class(
29
+ script_version=script_version,
26
30
  object_name=object_name,
27
31
  test_mode=test_mode,
32
+ log=log,
28
33
  verbose=verbose,
34
+ save_graph=save_graph,
29
35
  )
36
+
37
+ return found and script.valid, script
@@ -0,0 +1,21 @@
1
+ import copy
2
+
3
+ from blueness import module
4
+ from blue_objects import file, path
5
+
6
+ from blue_assistant import NAME
7
+ from blue_assistant.script.repository.base.root import RootScript
8
+ from blue_assistant.script.actions import dict_of_actions
9
+ from blue_assistant.logger import logger
10
+
11
+
12
+ NAME = module.name(__file__, NAME)
13
+
14
+
15
+ class BaseScript(RootScript):
16
+ name = path.name(file.path(__file__))
17
+
18
+ def __init__(self, **kwargs):
19
+ super().__init__(**kwargs)
20
+
21
+ self.dict_of_actions = copy.deepcopy(dict_of_actions)
@@ -1,40 +1,40 @@
1
- from typing import Dict, List, Callable
2
1
  import os
3
- import networkx as nx
2
+ from typing import Dict, List
4
3
  from functools import reduce
4
+ import networkx as nx
5
5
  from tqdm import tqdm
6
- import copy
7
6
 
8
- from blueness import module
9
- from blue_objects import file, objects, path
10
- from blue_objects.metadata import post_to_object
7
+ from blue_options.options import Options
8
+ from blue_objects import file, path, objects
9
+ from blue_objects.metadata import post_to_object, get_from_object
11
10
  from blueflow.workflow import dot_file
12
11
 
13
- from blue_assistant import NAME
14
- from blue_assistant.script.repository.base.root import RootScript
15
- from blue_assistant.script.actions import dict_of_actions
16
12
  from blue_assistant.logger import logger
17
13
 
18
14
 
19
- NAME = module.name(__file__, NAME)
20
-
21
-
22
- class BaseScript(RootScript):
15
+ class RootScript:
23
16
  name = path.name(file.path(__file__))
24
17
 
25
18
  def __init__(
26
19
  self,
27
20
  object_name: str,
21
+ script_version: str = "base",
28
22
  test_mode: bool = False,
23
+ log: bool = True,
29
24
  verbose: bool = False,
25
+ save_graph: bool = True,
30
26
  ):
27
+ self.valid = False
28
+
29
+ self.nodes_changed = False
30
+
31
31
  self.object_name = object_name
32
32
 
33
33
  self.test_mode = test_mode
34
34
 
35
35
  self.verbose = verbose
36
36
 
37
- self.dict_of_actions = copy.deepcopy(dict_of_actions)
37
+ self.dict_of_actions = {}
38
38
 
39
39
  metadata_filename = os.path.join(
40
40
  file.path(__file__),
@@ -43,64 +43,133 @@ class BaseScript(RootScript):
43
43
  )
44
44
  self.metadata: Dict
45
45
  success, self.metadata = file.load_yaml(metadata_filename)
46
- assert success, f"cannot load {self.name}/metadata.yaml"
46
+ if not success:
47
+ logger.error(f"cannot load {self.name}/metadata.yaml")
48
+ return
49
+
50
+ # validate and set
51
+ last_script_version = get_from_object(
52
+ object_name,
53
+ "script_version",
54
+ script_version,
55
+ )
56
+ if script_version != last_script_version:
57
+ logger.error(
58
+ "script version in {} is {} != {}".format(
59
+ object_name,
60
+ last_script_version,
61
+ script_version,
62
+ )
63
+ )
64
+ return
65
+ if not post_to_object(
66
+ object_name,
67
+ "script_version",
68
+ script_version,
69
+ ):
70
+ return
71
+ if log:
72
+ logger.info(f"script version: {script_version}")
47
73
 
48
74
  self.metadata.setdefault("script", {})
49
- assert isinstance(
50
- self.script,
51
- dict,
52
- ), "script: expected dict, received {}.".format(
53
- self.script.__class__.__name__,
54
- )
75
+ if not isinstance(self.script, dict):
76
+ logger.error(
77
+ "script: expected dict, received {}.".format(
78
+ self.script.__class__.__name__,
79
+ )
80
+ )
81
+ return
55
82
 
56
83
  self.script.setdefault("nodes", {})
57
- assert isinstance(
84
+ if not isinstance(
58
85
  self.nodes,
59
86
  dict,
60
- ), "nodes: expected dict, received {}.".format(
61
- self.nodes.__class__.__name__,
62
- )
87
+ ):
88
+ logger.error(
89
+ "nodes: expected dict, received {}.".format(
90
+ self.nodes.__class__.__name__,
91
+ )
92
+ )
93
+ return
63
94
 
64
95
  self.script.setdefault("vars", {})
65
- assert isinstance(
96
+ if not isinstance(
66
97
  self.vars,
67
98
  dict,
68
- ), "vars: expected dict, received {}.".format(
69
- self.vars.__class__.__name__,
70
- )
99
+ ):
100
+ logger.error(
101
+ "vars: expected dict, received {}.".format(
102
+ self.vars.__class__.__name__,
103
+ )
104
+ )
105
+ return
106
+
107
+ self.script.setdefault("versions", {})
108
+ if not isinstance(
109
+ self.versions,
110
+ dict,
111
+ ):
112
+ logger.error(
113
+ "versions: expected dict, received {}.".format(
114
+ self.versions.__class__.__name__,
115
+ )
116
+ )
117
+ return
118
+
119
+ if script_version != "base":
120
+ if script_version not in self.versions:
121
+ logger.error(f"{script_version}: script version not found.")
122
+ return
123
+
124
+ for thing in ["vars", "nodes"]:
125
+ updates = self.versions[script_version].get(thing, {})
126
+ if len(updates) and log:
127
+ logger.info(f"{thing}.update({updates})")
128
+ self.metadata["script"][thing].update(updates)
71
129
 
72
130
  if self.test_mode:
73
- logger.info("🧪 test mode is on.")
131
+ if log:
132
+ logger.info("🧪 test mode is on.")
74
133
 
75
134
  if "test_mode" in self.script:
76
135
  updates = self.script["test_mode"]
77
- logger.info(f"🧪 vars.update({updates})")
136
+ if log:
137
+ logger.info(f"🧪 vars.update({updates})")
78
138
  self.vars.update(updates)
79
139
 
80
140
  for node_name, node in self.nodes.items():
81
141
  if "test_mode" in node:
82
142
  updates = node["test_mode"]
83
- logger.info(f"🧪 {node_name}.update({updates})")
143
+ if log:
144
+ logger.info(f"🧪 {node_name}.update({updates})")
84
145
  node.update(updates)
85
146
 
86
- logger.info(
87
- "loaded {} node(s): {}".format(
88
- len(self.nodes),
89
- ", ".join(self.nodes.keys()),
147
+ if log:
148
+ logger.info(
149
+ "loaded {} node(s): {}".format(
150
+ len(self.nodes),
151
+ ", ".join(self.nodes.keys()),
152
+ )
90
153
  )
91
- )
92
154
 
93
- logger.info(
94
- "loaded {} var(s): {}".format(
95
- len(self.vars),
96
- ", ".join(self.vars.keys()),
155
+ logger.info(
156
+ "loaded {} var(s): {}".format(
157
+ len(self.vars),
158
+ ", ".join(self.vars.keys()),
159
+ )
97
160
  )
98
- )
99
161
  if verbose:
100
162
  for var_name, var_value in self.vars.items():
101
163
  logger.info("{}: {}".format(var_name, var_value))
102
164
 
103
- assert self.generate_graph(), "cannot generate graph."
165
+ if not self.generate_graph(
166
+ log=log,
167
+ verbose=verbose,
168
+ save_graph=save_graph,
169
+ ):
170
+ return
171
+
172
+ self.valid = True
104
173
 
105
174
  def __str__(self) -> str:
106
175
  return "{}[{} var(s), {} node(s) -> {}]".format(
@@ -115,13 +184,17 @@ class BaseScript(RootScript):
115
184
  text = text.replace(f":::{var_name}", str(var_value))
116
185
 
117
186
  for node_name, node in self.nodes.items():
118
- text = text.replace(f":::{node_name}", node.get("output", ""))
187
+ node_output = node.get("output", "")
188
+ if isinstance(node_output, str):
189
+ text = text.replace(f":::{node_name}", node_output)
119
190
 
120
191
  return text
121
192
 
122
193
  def generate_graph(
123
194
  self,
195
+ log: bool = True,
124
196
  verbose: bool = False,
197
+ save_graph: bool = True,
125
198
  ) -> bool:
126
199
  self.G: nx.DiGraph = nx.DiGraph()
127
200
 
@@ -146,7 +219,7 @@ class BaseScript(RootScript):
146
219
  if dependency:
147
220
  self.G.add_edge(node_name, dependency)
148
221
 
149
- return self.save_graph()
222
+ return self.save_graph(log=log) if save_graph else True
150
223
 
151
224
  def get_context(
152
225
  self,
@@ -174,14 +247,26 @@ class BaseScript(RootScript):
174
247
  logger.error(f"{action_name}: action not found.")
175
248
  return False
176
249
 
177
- def run(self) -> bool:
250
+ def run(
251
+ self,
252
+ runnable: str = "",
253
+ ) -> bool:
178
254
  logger.info(f"{self.name}.run -> {self.object_name}")
179
255
 
256
+ if runnable:
257
+ logger.info(f"applying runnables: {runnable}")
258
+ runnable_options = Options(runnable)
259
+ for node_name, node_is_runnable in runnable_options.items():
260
+ logger.info(f"{node_name}.runnable={node_is_runnable}")
261
+ self.nodes[node_name]["runnable"] = node_is_runnable
262
+
180
263
  success: bool = True
181
264
  while (
182
265
  not all(self.nodes[node].get("completed", False) for node in self.nodes)
183
266
  and success
184
267
  ):
268
+ self.nodes_changed = False
269
+
185
270
  for node_name in tqdm(self.nodes):
186
271
  if self.nodes[node_name].get("completed", False):
187
272
  continue
@@ -212,6 +297,22 @@ class BaseScript(RootScript):
212
297
 
213
298
  self.nodes[node_name]["completed"] = True
214
299
 
300
+ cache_filename = self.nodes[node_name].get("cache", "")
301
+ if cache_filename:
302
+ if not file.save_text(
303
+ objects.path_of(
304
+ object_name=self.object_name,
305
+ filename=cache_filename,
306
+ ),
307
+ [self.nodes[node_name].get("output", "")],
308
+ ):
309
+ success = False
310
+ break
311
+
312
+ if self.nodes_changed:
313
+ logger.info("🪄 nodes changed.")
314
+ break
315
+
215
316
  if not post_to_object(
216
317
  self.object_name,
217
318
  "output",
@@ -221,7 +322,10 @@ class BaseScript(RootScript):
221
322
 
222
323
  return success
223
324
 
224
- def save_graph(self) -> bool:
325
+ def save_graph(
326
+ self,
327
+ log: bool = True,
328
+ ) -> bool:
225
329
  return dot_file.save_to_file(
226
330
  objects.path_of(
227
331
  filename="workflow.dot",
@@ -235,6 +339,7 @@ class BaseScript(RootScript):
235
339
  ]
236
340
  ),
237
341
  add_legend=False,
342
+ log=log,
238
343
  )
239
344
 
240
345
  # Aliases
@@ -249,3 +354,7 @@ class BaseScript(RootScript):
249
354
  @property
250
355
  def vars(self) -> Dict:
251
356
  return self.metadata["script"]["vars"]
357
+
358
+ @property
359
+ def versions(self) -> Dict:
360
+ return self.metadata["script"]["versions"]
@@ -14,35 +14,33 @@ NAME = module.name(__file__, NAME)
14
14
  class BlueAmoScript(BaseScript):
15
15
  name = path.name(file.path(__file__))
16
16
 
17
- def __init__(
18
- self,
19
- object_name: str,
20
- test_mode: bool = False,
21
- verbose: bool = False,
22
- ):
23
- super().__init__(
24
- object_name=object_name,
25
- test_mode=test_mode,
26
- verbose=verbose,
27
- )
17
+ def __init__(self, **kwargs):
18
+ super().__init__(**kwargs)
28
19
 
29
20
  self.dict_of_actions.update(dict_of_actions)
30
21
 
31
22
  def generate_graph(
32
23
  self,
24
+ log: bool = True,
33
25
  verbose: bool = False,
26
+ save_graph: bool = True,
34
27
  ) -> bool:
35
- if not super().generate_graph(verbose=verbose):
28
+ if not super().generate_graph(
29
+ log=log,
30
+ verbose=verbose,
31
+ save_graph=save_graph,
32
+ ):
36
33
  return False
37
34
 
38
35
  map_node_name = "generating_the_frames"
39
- logger.info(
40
- "{}: expanding {} X {}...".format(
41
- NAME,
42
- map_node_name,
43
- self.vars["frame_count"],
36
+ if log:
37
+ logger.info(
38
+ "{}: expanding {} X {}...".format(
39
+ NAME,
40
+ map_node_name,
41
+ self.vars["frame_count"],
42
+ )
44
43
  )
45
- )
46
44
 
47
45
  map_node = self.nodes[map_node_name]
48
46
  del self.nodes[map_node_name]
@@ -64,4 +62,4 @@ class BlueAmoScript(BaseScript):
64
62
  node_name,
65
63
  )
66
64
 
67
- return self.save_graph()
65
+ return self.save_graph(log=log) if save_graph else True
@@ -0,0 +1,18 @@
1
+ from typing import List, Tuple
2
+
3
+ from blue_options import string
4
+
5
+ from blue_assistant.script.load import load_script
6
+
7
+
8
+ def get_script_versions(
9
+ script_name: str,
10
+ ) -> List[str]:
11
+ success, script = load_script(
12
+ script_name=script_name,
13
+ object_name=string.timestamp(),
14
+ log=False,
15
+ save_graph=False,
16
+ )
17
+
18
+ return list(script.versions.keys()) if success else []
@@ -0,0 +1,11 @@
1
+ from typing import Dict, Callable
2
+
3
+ from blue_assistant.script.repository.base.classes import BaseScript
4
+ from blue_assistant.script.repository.orbital_data_explorer.actions import (
5
+ expanding_the_extractions,
6
+ )
7
+
8
+
9
+ dict_of_actions: Dict[str, Callable[[BaseScript, str], bool]] = {
10
+ "expanding_the_extractions": expanding_the_extractions.expanding_the_extractions,
11
+ }
@@ -0,0 +1,109 @@
1
+ import copy
2
+ from typing import Dict
3
+
4
+ from blueness import module
5
+ from blue_options.logger import log_dict, log_list
6
+ from blue_objects import file, objects
7
+ from blue_objects.metadata import get_from_object
8
+
9
+ from blue_assistant import NAME
10
+ from blue_assistant.script.repository.base.classes import BaseScript
11
+ from blue_assistant.web.functions import url_to_filename
12
+ from blue_assistant.logger import logger
13
+
14
+ NAME = module.name(__file__, NAME)
15
+
16
+
17
+ def expanding_the_extractions(
18
+ script: BaseScript,
19
+ node_name: str,
20
+ ) -> bool:
21
+ map_node_name = "extraction"
22
+
23
+ crawl_cache: Dict[str, str] = get_from_object(
24
+ script.object_name,
25
+ "web_crawl_cache",
26
+ {},
27
+ )
28
+ log_dict(logger, "using", crawl_cache, "crawled url(s)")
29
+
30
+ list_of_urls = [
31
+ url
32
+ for url, content_type in crawl_cache.items()
33
+ if "html" in content_type
34
+ and not file.exists(
35
+ objects.path_of(
36
+ object_name=script.object_name,
37
+ filename="{}_cache/{}.txt".format(
38
+ map_node_name,
39
+ url_to_filename(url),
40
+ ),
41
+ )
42
+ )
43
+ ]
44
+ log_list(logger, "using", list_of_urls, "crawled unextracted html(s).")
45
+
46
+ max_nodes = min(
47
+ len(list_of_urls),
48
+ script.nodes[node_name]["max_nodes"],
49
+ )
50
+ logger.info(
51
+ "{}: expanding {} X {}...".format(
52
+ NAME,
53
+ map_node_name,
54
+ max_nodes,
55
+ )
56
+ )
57
+
58
+ map_node = script.nodes[map_node_name]
59
+ del script.nodes[map_node_name]
60
+ script.G.remove_node(map_node_name)
61
+
62
+ reduce_node_name = "generating_summary"
63
+ for index in range(max_nodes):
64
+ url = list_of_urls[index]
65
+ index_node_name = f"{map_node_name}_{index+1:03d}"
66
+
67
+ success, url_content = file.load_yaml(
68
+ filename=objects.path_of(
69
+ object_name=script.object_name,
70
+ filename="web_crawl_cache/{}.yaml".format(
71
+ url_to_filename(url),
72
+ ),
73
+ ),
74
+ )
75
+ if not success:
76
+ logger.warning(f"{url}: failed to load url content.")
77
+ continue
78
+ if "text" not in url_content:
79
+ logger.warning(f"{url}: no text found in url content.")
80
+ continue
81
+
82
+ logger.info(f"{url} -{map_node_name}-> {index_node_name}")
83
+
84
+ script.nodes[index_node_name] = copy.deepcopy(map_node)
85
+
86
+ script.nodes[index_node_name]["prompt"] = map_node["prompt"].replace(
87
+ ":::url_content",
88
+ url_content["text"],
89
+ )
90
+
91
+ script.nodes[index_node_name]["url"] = url
92
+ script.nodes[index_node_name]["cache"] = "{}_cache/{}.txt".format(
93
+ map_node_name,
94
+ url_to_filename(url),
95
+ )
96
+
97
+ script.G.add_node(index_node_name)
98
+ script.G.add_edge(
99
+ index_node_name,
100
+ node_name,
101
+ )
102
+ script.G.add_edge(
103
+ reduce_node_name,
104
+ index_node_name,
105
+ )
106
+
107
+ script.nodes_changed = True
108
+
109
+ return script.save_graph()
@@ -0,0 +1,15 @@
1
+ from blue_objects import file, path
2
+
3
+ from blue_assistant.script.repository.base.classes import BaseScript
4
+ from blue_assistant.script.repository.orbital_data_explorer.actions import (
5
+ dict_of_actions,
6
+ )
7
+
8
+
9
+ class OrbitalDataExplorerScript(BaseScript):
10
+ name = path.name(file.path(__file__))
11
+
12
+ def __init__(self, **kwargs):
13
+ super().__init__(**kwargs)
14
+
15
+ self.dict_of_actions.update(dict_of_actions)
@@ -35,7 +35,7 @@ def crawl_list_of_urls(
35
35
  seed_urls
36
36
  + get_from_object(
37
37
  object_name,
38
- f"{cache_prefix}_crawl_queue",
38
+ f"{cache_prefix}_queue",
39
39
  [],
40
40
  )
41
41
  )
@@ -44,7 +44,7 @@ def crawl_list_of_urls(
44
44
 
45
45
  crawl_cache: Dict[str, str] = get_from_object(
46
46
  object_name,
47
- f"{cache_prefix}_crawl_cache",
47
+ f"{cache_prefix}_cache",
48
48
  {},
49
49
  )
50
50
  log_dict(logger, "loaded cache:", crawl_cache, "url(s)")
@@ -75,7 +75,7 @@ def crawl_list_of_urls(
75
75
  if not file.save_yaml(
76
76
  filename=objects.path_of(
77
77
  object_name=object_name,
78
- filename="{}_crawl_cache/{}.yaml".format(
78
+ filename="{}_cache/{}.yaml".format(
79
79
  cache_prefix,
80
80
  url_to_filename(url),
81
81
  ),
@@ -108,12 +108,12 @@ def crawl_list_of_urls(
108
108
  if not (
109
109
  post_to_object(
110
110
  object_name,
111
- f"{cache_prefix}_crawl_cache",
111
+ f"{cache_prefix}_cache",
112
112
  crawl_cache,
113
113
  )
114
114
  and post_to_object(
115
115
  object_name,
116
- f"{cache_prefix}_crawl_queue",
116
+ f"{cache_prefix}_queue",
117
117
  queue,
118
118
  )
119
119
  ):
@@ -9,6 +9,7 @@ from blueness import module
9
9
  from blue_options.logger import log_long_text, log_list
10
10
 
11
11
  from blue_assistant import NAME
12
+ from blue_assistant.web.functions import normalize_url
12
13
  from blue_assistant.logger import logger
13
14
 
14
15
  warnings.filterwarnings("ignore", category=XMLParsedAsHTMLWarning)
@@ -49,8 +50,7 @@ def fetch_links_and_text(
49
50
  for a_tag in soup.find_all("a", href=True):
50
51
  a_url = urljoin(url, a_tag["href"])
51
52
 
52
- if "#" in a_url:
53
- a_url = a_url.split("#", 1)[0]
53
+ a_url = normalize_url(a_url)
54
54
 
55
55
  if a_url.startswith(url):
56
56
  if url not in list_of_urls:
@@ -1,4 +1,15 @@
1
1
  import re
2
+ from urllib.parse import urlparse, urlunparse
3
+
4
+
5
+ # https://chatgpt.com/c/67d733a0-4be4-8005-bf52-fb9ba32487c2
6
+ def normalize_url(url: str) -> str:
7
+ return urlunparse(
8
+ urlparse(url)._replace(
9
+ query="",
10
+ fragment="",
11
+ ),
12
+ )
2
13
 
3
14
 
4
15
  def url_to_filename(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: blue_assistant
3
- Version: 4.307.1
3
+ Version: 4.325.1
4
4
  Summary: 🧠 An AI Assistant.
5
5
  Home-page: https://github.com/kamangir/blue-assistant
6
6
  Author: Arash Abadpour (Kamangir)
@@ -124,4 +124,4 @@ Also home to [`@web`](https://raw.githubusercontent.com/kamangir/blue-assistant/
124
124
 
125
125
  [![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)
126
126
 
127
- built by 🌀 [`blue_options-4.240.1`](https://github.com/kamangir/awesome-bash-cli), based on 🧠 [`blue_assistant-4.307.1`](https://github.com/kamangir/blue-assistant).
127
+ built by 🌀 [`blue_options-4.240.1`](https://github.com/kamangir/awesome-bash-cli), based on 🧠 [`blue_assistant-4.325.1`](https://github.com/kamangir/blue-assistant).
@@ -56,6 +56,7 @@ blue_assistant/script/actions/generate_text.py
56
56
  blue_assistant/script/actions/generic.py
57
57
  blue_assistant/script/actions/web_crawl.py
58
58
  blue_assistant/script/repository/__init__.py
59
+ blue_assistant/script/repository/functions.py
59
60
  blue_assistant/script/repository/base/__init__.py
60
61
  blue_assistant/script/repository/base/classes.py
61
62
  blue_assistant/script/repository/base/root.py
@@ -71,6 +72,8 @@ blue_assistant/script/repository/hue/classes.py
71
72
  blue_assistant/script/repository/hue/colors.py
72
73
  blue_assistant/script/repository/orbital_data_explorer/__init__.py
73
74
  blue_assistant/script/repository/orbital_data_explorer/classes.py
75
+ blue_assistant/script/repository/orbital_data_explorer/actions/__init__.py
76
+ blue_assistant/script/repository/orbital_data_explorer/actions/expanding_the_extractions.py
74
77
  blue_assistant/web/__init__.py
75
78
  blue_assistant/web/__main__.py
76
79
  blue_assistant/web/crawl.py
@@ -18,6 +18,7 @@ setup(
18
18
  f"{NAME}.script.repository.blue_amo.actions",
19
19
  f"{NAME}.script.repository.hue",
20
20
  f"{NAME}.script.repository.orbital_data_explorer",
21
+ f"{NAME}.script.repository.orbital_data_explorer.actions",
21
22
  f"{NAME}.web",
22
23
  ],
23
24
  include_package_data=True,
@@ -1,5 +0,0 @@
1
- from blue_objects import file, objects, path
2
-
3
-
4
- class RootScript:
5
- name = path.name(file.path(__file__))
@@ -1,7 +0,0 @@
1
- from blue_objects import file, path
2
-
3
- from blue_assistant.script.repository.base.classes import BaseScript
4
-
5
-
6
- class OrbitalDataExplorerScript(BaseScript):
7
- name = path.name(file.path(__file__))