py10x-universe 0.1.3__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.
- core_10x/__init__.py +42 -0
- core_10x/backbone/__init__.py +0 -0
- core_10x/backbone/backbone_store.py +59 -0
- core_10x/backbone/backbone_traitable.py +30 -0
- core_10x/backbone/backbone_user.py +66 -0
- core_10x/backbone/bound_data_domain.py +49 -0
- core_10x/backbone/namespace.py +101 -0
- core_10x/backbone/vault.py +38 -0
- core_10x/code_samples/__init__.py +0 -0
- core_10x/code_samples/_package_manifest.py +3 -0
- core_10x/code_samples/directories.py +181 -0
- core_10x/code_samples/person.py +76 -0
- core_10x/concrete_traits.py +356 -0
- core_10x/conftest.py +12 -0
- core_10x/curve.py +321 -0
- core_10x/data_domain.py +48 -0
- core_10x/data_domain_binder.py +45 -0
- core_10x/directory.py +250 -0
- core_10x/entity.py +8 -0
- core_10x/entity_filter.py +5 -0
- core_10x/environment_variables.py +147 -0
- core_10x/exec_control.py +84 -0
- core_10x/experimental/__init__.py +0 -0
- core_10x/experimental/data_protocol_ex.py +34 -0
- core_10x/global_cache.py +121 -0
- core_10x/manual_tests/__init__.py +0 -0
- core_10x/manual_tests/calendar_test.py +35 -0
- core_10x/manual_tests/ctor_update_bug.py +58 -0
- core_10x/manual_tests/debug_graph_on.py +17 -0
- core_10x/manual_tests/debug_graphoff_inside_graph_on.py +28 -0
- core_10x/manual_tests/enum_bits_test.py +17 -0
- core_10x/manual_tests/env_vars_trivial_test.py +12 -0
- core_10x/manual_tests/existing_traitable.py +33 -0
- core_10x/manual_tests/k10x_test1.py +13 -0
- core_10x/manual_tests/named_constant_test.py +121 -0
- core_10x/manual_tests/nucleus_trivial_test.py +42 -0
- core_10x/manual_tests/polars_test.py +14 -0
- core_10x/manual_tests/py_class_test.py +4 -0
- core_10x/manual_tests/rc_test.py +42 -0
- core_10x/manual_tests/rdate_test.py +12 -0
- core_10x/manual_tests/reference_serialization_bug.py +19 -0
- core_10x/manual_tests/resource_trivial_test.py +10 -0
- core_10x/manual_tests/store_uri_test.py +6 -0
- core_10x/manual_tests/trait_definition_test.py +19 -0
- core_10x/manual_tests/trait_filter_test.py +15 -0
- core_10x/manual_tests/trait_flag_modification_test.py +42 -0
- core_10x/manual_tests/trait_modification_bug.py +26 -0
- core_10x/manual_tests/traitable_as_of_test.py +82 -0
- core_10x/manual_tests/traitable_heir_test.py +39 -0
- core_10x/manual_tests/traitable_history_test.py +41 -0
- core_10x/manual_tests/traitable_serialization_test.py +54 -0
- core_10x/manual_tests/traitable_trivial_test.py +71 -0
- core_10x/manual_tests/trivial_graph_test.py +16 -0
- core_10x/manual_tests/ts_class_association_test.py +64 -0
- core_10x/manual_tests/ts_trivial_test.py +35 -0
- core_10x/named_constant.py +425 -0
- core_10x/nucleus.py +81 -0
- core_10x/package_manifest.py +85 -0
- core_10x/package_refactoring.py +153 -0
- core_10x/py_class.py +431 -0
- core_10x/rc.py +155 -0
- core_10x/rdate.py +339 -0
- core_10x/resource.py +189 -0
- core_10x/roman_number.py +67 -0
- core_10x/testlib/__init__.py +0 -0
- core_10x/testlib/test_store.py +240 -0
- core_10x/testlib/traitable_history_tests.py +787 -0
- core_10x/testlib/ts_tests.py +280 -0
- core_10x/trait.py +377 -0
- core_10x/trait_definition.py +176 -0
- core_10x/trait_filter.py +205 -0
- core_10x/trait_method_error.py +36 -0
- core_10x/traitable.py +1082 -0
- core_10x/traitable_cli.py +153 -0
- core_10x/traitable_heir.py +33 -0
- core_10x/traitable_id.py +31 -0
- core_10x/ts_store.py +172 -0
- core_10x/ts_store_type.py +26 -0
- core_10x/ts_union.py +147 -0
- core_10x/ui_hint.py +153 -0
- core_10x/unit_tests/test_concrete_traits.py +156 -0
- core_10x/unit_tests/test_converters.py +51 -0
- core_10x/unit_tests/test_curve.py +157 -0
- core_10x/unit_tests/test_directory.py +54 -0
- core_10x/unit_tests/test_documentation.py +172 -0
- core_10x/unit_tests/test_environment_variables.py +15 -0
- core_10x/unit_tests/test_filters.py +239 -0
- core_10x/unit_tests/test_graph.py +348 -0
- core_10x/unit_tests/test_named_constant.py +98 -0
- core_10x/unit_tests/test_rc.py +11 -0
- core_10x/unit_tests/test_rdate.py +484 -0
- core_10x/unit_tests/test_trait_method_error.py +80 -0
- core_10x/unit_tests/test_trait_modification.py +19 -0
- core_10x/unit_tests/test_traitable.py +959 -0
- core_10x/unit_tests/test_traitable_history.py +1 -0
- core_10x/unit_tests/test_ts_store.py +1 -0
- core_10x/unit_tests/test_ts_union.py +369 -0
- core_10x/unit_tests/test_ui_nodes.py +81 -0
- core_10x/unit_tests/test_xxcalendar.py +471 -0
- core_10x/vault/__init__.py +0 -0
- core_10x/vault/sec_keys.py +133 -0
- core_10x/vault/security_keys_old.py +168 -0
- core_10x/vault/vault.py +56 -0
- core_10x/vault/vault_traitable.py +56 -0
- core_10x/vault/vault_user.py +70 -0
- core_10x/xdate_time.py +136 -0
- core_10x/xnone.py +71 -0
- core_10x/xxcalendar.py +228 -0
- infra_10x/__init__.py +0 -0
- infra_10x/manual_tests/__init__.py +0 -0
- infra_10x/manual_tests/test_misc.py +16 -0
- infra_10x/manual_tests/test_prepare_filter_and_pipeline.py +25 -0
- infra_10x/mongodb_admin.py +111 -0
- infra_10x/mongodb_store.py +346 -0
- infra_10x/mongodb_utils.py +129 -0
- infra_10x/unit_tests/conftest.py +13 -0
- infra_10x/unit_tests/test_mongo_db.py +36 -0
- infra_10x/unit_tests/test_mongo_history.py +1 -0
- py10x_universe-0.1.3.dist-info/METADATA +406 -0
- py10x_universe-0.1.3.dist-info/RECORD +214 -0
- py10x_universe-0.1.3.dist-info/WHEEL +4 -0
- py10x_universe-0.1.3.dist-info/licenses/LICENSE +21 -0
- ui_10x/__init__.py +0 -0
- ui_10x/apps/__init__.py +0 -0
- ui_10x/apps/collection_editor_app.py +100 -0
- ui_10x/choice.py +212 -0
- ui_10x/collection_editor.py +135 -0
- ui_10x/concrete_trait_widgets.py +220 -0
- ui_10x/conftest.py +8 -0
- ui_10x/entity_stocker.py +173 -0
- ui_10x/examples/__init__.py +0 -0
- ui_10x/examples/_guess_word_data.py +14076 -0
- ui_10x/examples/collection_editor.py +17 -0
- ui_10x/examples/date_selector.py +14 -0
- ui_10x/examples/entity_stocker.py +18 -0
- ui_10x/examples/guess_word.py +392 -0
- ui_10x/examples/message_box.py +20 -0
- ui_10x/examples/multi_choice.py +17 -0
- ui_10x/examples/py_data_browser.py +66 -0
- ui_10x/examples/radiobox.py +29 -0
- ui_10x/examples/single_choice.py +31 -0
- ui_10x/examples/style_sheet.py +47 -0
- ui_10x/examples/trivial_entity_editor.py +18 -0
- ui_10x/platform.py +20 -0
- ui_10x/platform_interface.py +517 -0
- ui_10x/py_data_browser.py +249 -0
- ui_10x/qt6/__init__.py +0 -0
- ui_10x/qt6/conftest.py +8 -0
- ui_10x/qt6/manual_tests/__init__.py +0 -0
- ui_10x/qt6/manual_tests/basic_test.py +35 -0
- ui_10x/qt6/platform_implementation.py +275 -0
- ui_10x/qt6/utils.py +665 -0
- ui_10x/rio/__init__.py +0 -0
- ui_10x/rio/apps/examples/examples/__init__.py +22 -0
- ui_10x/rio/apps/examples/examples/components/__init__.py +3 -0
- ui_10x/rio/apps/examples/examples/components/collection_editor.py +15 -0
- ui_10x/rio/apps/examples/examples/pages/collection_editor.py +21 -0
- ui_10x/rio/apps/examples/examples/pages/login_page.py +88 -0
- ui_10x/rio/apps/examples/examples/pages/style_sheet.py +21 -0
- ui_10x/rio/apps/examples/rio.toml +14 -0
- ui_10x/rio/component_builder.py +497 -0
- ui_10x/rio/components/__init__.py +9 -0
- ui_10x/rio/components/group_box.py +31 -0
- ui_10x/rio/components/labeled_checkbox.py +18 -0
- ui_10x/rio/components/line_edit.py +37 -0
- ui_10x/rio/components/radio_button.py +32 -0
- ui_10x/rio/components/separator.py +24 -0
- ui_10x/rio/components/splitter.py +121 -0
- ui_10x/rio/components/tree_view.py +75 -0
- ui_10x/rio/conftest.py +35 -0
- ui_10x/rio/internals/__init__.py +0 -0
- ui_10x/rio/internals/app.py +192 -0
- ui_10x/rio/manual_tests/__init__.py +0 -0
- ui_10x/rio/manual_tests/basic_test.py +24 -0
- ui_10x/rio/manual_tests/splitter.py +27 -0
- ui_10x/rio/platform_implementation.py +91 -0
- ui_10x/rio/style_sheet.py +53 -0
- ui_10x/rio/unit_tests/test_collection_editor.py +68 -0
- ui_10x/rio/unit_tests/test_internals.py +630 -0
- ui_10x/rio/unit_tests/test_style_sheet.py +37 -0
- ui_10x/rio/widgets/__init__.py +46 -0
- ui_10x/rio/widgets/application.py +109 -0
- ui_10x/rio/widgets/button.py +48 -0
- ui_10x/rio/widgets/button_group.py +60 -0
- ui_10x/rio/widgets/calendar.py +23 -0
- ui_10x/rio/widgets/checkbox.py +24 -0
- ui_10x/rio/widgets/dialog.py +137 -0
- ui_10x/rio/widgets/group_box.py +27 -0
- ui_10x/rio/widgets/layout.py +34 -0
- ui_10x/rio/widgets/line_edit.py +37 -0
- ui_10x/rio/widgets/list.py +105 -0
- ui_10x/rio/widgets/message_box.py +70 -0
- ui_10x/rio/widgets/scroll_area.py +31 -0
- ui_10x/rio/widgets/spacer.py +6 -0
- ui_10x/rio/widgets/splitter.py +45 -0
- ui_10x/rio/widgets/text_edit.py +28 -0
- ui_10x/rio/widgets/tree.py +89 -0
- ui_10x/rio/widgets/unit_tests/test_button.py +101 -0
- ui_10x/rio/widgets/unit_tests/test_button_group.py +33 -0
- ui_10x/rio/widgets/unit_tests/test_calendar.py +114 -0
- ui_10x/rio/widgets/unit_tests/test_checkbox.py +109 -0
- ui_10x/rio/widgets/unit_tests/test_group_box.py +158 -0
- ui_10x/rio/widgets/unit_tests/test_label.py +43 -0
- ui_10x/rio/widgets/unit_tests/test_line_edit.py +140 -0
- ui_10x/rio/widgets/unit_tests/test_list.py +146 -0
- ui_10x/table_header_view.py +305 -0
- ui_10x/table_view.py +174 -0
- ui_10x/trait_editor.py +189 -0
- ui_10x/trait_widget.py +131 -0
- ui_10x/traitable_editor.py +200 -0
- ui_10x/traitable_view.py +131 -0
- ui_10x/unit_tests/conftest.py +8 -0
- ui_10x/unit_tests/test_platform.py +9 -0
- ui_10x/utils.py +661 -0
core_10x/__init__.py
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# from os import path
|
|
2
|
+
#
|
|
3
|
+
# pp = path.dirname(path.abspath(__file__))
|
|
4
|
+
# path_to_core_10x = path.dirname(pp)
|
|
5
|
+
import atexit
|
|
6
|
+
|
|
7
|
+
from py10x_core import CORE_10X, PyLinkage, XCache
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# fmt: off
|
|
11
|
+
def cleanup():
|
|
12
|
+
XCache.clear()
|
|
13
|
+
PyLinkage.clear()
|
|
14
|
+
|
|
15
|
+
atexit.register(cleanup)
|
|
16
|
+
|
|
17
|
+
PyLinkage.init({
|
|
18
|
+
CORE_10X.PACKAGE_NAME: __name__,
|
|
19
|
+
|
|
20
|
+
CORE_10X.XNONE_MODULE_NAME: 'xnone',
|
|
21
|
+
CORE_10X.XNONE_CLASS_NAME: 'XNone',
|
|
22
|
+
|
|
23
|
+
CORE_10X.RC_MODULE_NAME: 'rc',
|
|
24
|
+
CORE_10X.RC_TRUE_NAME: 'RC_TRUE',
|
|
25
|
+
|
|
26
|
+
CORE_10X.NUCLEUS_MODULE_NAME: 'nucleus',
|
|
27
|
+
CORE_10X.NUCLEUS_CLASS_NAME: 'Nucleus',
|
|
28
|
+
|
|
29
|
+
CORE_10X.ANONYMOUS_MODULE_NAME: 'traitable',
|
|
30
|
+
CORE_10X.ANONYMOUS_CLASS_NAME: 'AnonymousTraitable',
|
|
31
|
+
|
|
32
|
+
CORE_10X.TRAITABLE_ID_MODULE_NAME: 'traitable_id',
|
|
33
|
+
CORE_10X.TRAITABLE_ID_CLASS_NAME: 'ID',
|
|
34
|
+
|
|
35
|
+
CORE_10X.TRAIT_METHOD_ERROR_MODULE_NAME: 'trait_method_error',
|
|
36
|
+
CORE_10X.TRAIT_METHOD_ERROR_CLASS_NAME: 'TraitMethodError',
|
|
37
|
+
|
|
38
|
+
CORE_10X.PACKAGE_REFACTORING_MODULE_NAME: 'package_refactoring',
|
|
39
|
+
CORE_10X.PACKAGE_REFACTORING_CLASS_NAME: 'PackageRefactoring',
|
|
40
|
+
CORE_10X.PACKAGE_REFACTORING_FIND_CLASS: 'find_class',
|
|
41
|
+
CORE_10X.PACKAGE_REFACTORING_FIND_CLASS_ID: 'find_class_id',
|
|
42
|
+
})
|
|
File without changes
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from core_10x.environment_variables import EnvVars
|
|
2
|
+
from core_10x.global_cache import cache
|
|
3
|
+
from core_10x.ts_store import TsStore
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class BackboneStore:
|
|
7
|
+
"""
|
|
8
|
+
Backbone Store instance should exist for every build area. It may be run with or without authentication required.
|
|
9
|
+
If authentication is required, it must have a special-purpose user SIDEKICK with read-only permissions and must have the following databases:
|
|
10
|
+
- admin
|
|
11
|
+
- _backbone_ - collections:
|
|
12
|
+
- bound data domains;
|
|
13
|
+
- users;
|
|
14
|
+
- user groups;
|
|
15
|
+
- ...
|
|
16
|
+
- _vault_ - collections of Resource Accessors (per username)
|
|
17
|
+
- _shadow_ - collections of 'Shadow' (user-password-encrypted private key) for each user (for exporting sec keys for a new user's computer)
|
|
18
|
+
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
# fmt: off
|
|
22
|
+
SIDEKICK_USER = 'sidekick'
|
|
23
|
+
BACKBONE_DB_NAME = '_backbone_'
|
|
24
|
+
VAULT_DB_NAME = '_vault_'
|
|
25
|
+
SHADOW_DB_NAME = '_shadow_'
|
|
26
|
+
# fmt: on
|
|
27
|
+
|
|
28
|
+
@classmethod
|
|
29
|
+
@cache
|
|
30
|
+
def bb_store(cls) -> TsStore: # -- BB Store
|
|
31
|
+
cls_name = EnvVars.backbone_store_class_name
|
|
32
|
+
cls.hostname = hostname = EnvVars.backbone_store_host_name
|
|
33
|
+
if not cls_name or not hostname:
|
|
34
|
+
return None
|
|
35
|
+
|
|
36
|
+
cls.store_cls = store_cls = TsStore.store_class(cls_name)
|
|
37
|
+
|
|
38
|
+
is_running, with_auth = store_cls.is_running_with_auth(hostname)
|
|
39
|
+
if not is_running:
|
|
40
|
+
raise OSError(f'{store_cls.s_driver_name}({hostname}) is not running')
|
|
41
|
+
|
|
42
|
+
cls.with_auth = with_auth
|
|
43
|
+
if with_auth:
|
|
44
|
+
cls.username = cls.SIDEKICK_USER
|
|
45
|
+
cls.password = cls.SIDEKICK_USER
|
|
46
|
+
else:
|
|
47
|
+
cls.username = ''
|
|
48
|
+
cls.password = ''
|
|
49
|
+
|
|
50
|
+
return store_cls.instance(hostname=hostname, dbname=cls.BACKBONE_DB_NAME, username=cls.username, password=cls.password)
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
@cache
|
|
54
|
+
def store(cls, db_name: str) -> TsStore:
|
|
55
|
+
bb_store = cls.bb_store()
|
|
56
|
+
if db_name == cls.BACKBONE_DB_NAME:
|
|
57
|
+
return bb_store
|
|
58
|
+
|
|
59
|
+
return cls.store_cls.instance(hostname=cls.hostname, dbname=db_name, username=cls.username, password=cls.password)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from core_10x.backbone.backbone_store import BackboneStore
|
|
6
|
+
from core_10x.traitable import RT, T, Traitable, TraitDefinition
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from core_10x.traitable import RC
|
|
10
|
+
from core_10x.ts_store import TsStore
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class BackboneTraitable(Traitable):
|
|
14
|
+
@classmethod
|
|
15
|
+
def build_trait_dir(cls) -> RC:
|
|
16
|
+
for trait_def in cls.__dict__.values():
|
|
17
|
+
if isinstance(trait_def, TraitDefinition):
|
|
18
|
+
trait_def.flags_change(T.EVAL_ONCE)
|
|
19
|
+
|
|
20
|
+
return Traitable.build_trait_dir()
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
def store(cls) -> TsStore:
|
|
24
|
+
return BackboneStore.bb_store()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class VaultTraitable(BackboneTraitable):
|
|
28
|
+
@classmethod
|
|
29
|
+
def store(cls) -> TsStore:
|
|
30
|
+
return BackboneStore.store(BackboneStore.VAULT_DB_NAME)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from py10x_core import OsUser
|
|
4
|
+
|
|
5
|
+
from core_10x.backbone.backbone_traitable import RT, BackboneTraitable, T
|
|
6
|
+
from core_10x.backbone.namespace import FUNCTIONAL_ACCOUNT_PREFIX, USER_ADMIN_SUFFIX
|
|
7
|
+
from core_10x.global_cache import cache
|
|
8
|
+
from core_10x.trait_filter import f
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class BackboneUserGroup(BackboneTraitable):
|
|
12
|
+
# fmt: off
|
|
13
|
+
name: str = T(T.ID)
|
|
14
|
+
description: str = T()
|
|
15
|
+
everyone: bool = T(False)
|
|
16
|
+
is_admin: bool = T(False)
|
|
17
|
+
is_reserved: bool = T(False)
|
|
18
|
+
builtin_roles: list = T()
|
|
19
|
+
user_ids: list = T()
|
|
20
|
+
|
|
21
|
+
users: set = RT()
|
|
22
|
+
# fmt: on
|
|
23
|
+
|
|
24
|
+
def users_get(self) -> set:
|
|
25
|
+
return set(self.user_ids)
|
|
26
|
+
|
|
27
|
+
def is_member(self, user_id: str) -> bool:
|
|
28
|
+
return user_id in self.users if not self.everyone else False
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class BackboneUser(BackboneTraitable):
|
|
32
|
+
# fmt: off
|
|
33
|
+
user_id: str = T(T.ID) // 'OS login'
|
|
34
|
+
suspended: bool = T(False)
|
|
35
|
+
public_key: bytes = T()
|
|
36
|
+
|
|
37
|
+
is_admin: bool = RT()
|
|
38
|
+
downloaded: bool = RT(False)
|
|
39
|
+
builtin_roles: list = RT()
|
|
40
|
+
# fmt: on
|
|
41
|
+
|
|
42
|
+
def user_id_get(self) -> str:
|
|
43
|
+
return OsUser.me.name()
|
|
44
|
+
|
|
45
|
+
def is_admin_get(self) -> bool:
|
|
46
|
+
for group in BackboneUserGroup.collection().find(f(is_admin=True)):
|
|
47
|
+
if group.is_member(self.user_id):
|
|
48
|
+
return True
|
|
49
|
+
|
|
50
|
+
return False
|
|
51
|
+
|
|
52
|
+
def admin_id(self) -> str:
|
|
53
|
+
return f'{self.user_id}_{USER_ADMIN_SUFFIX}' if self.is_admin else ''
|
|
54
|
+
|
|
55
|
+
@classmethod
|
|
56
|
+
def regular_id(cls, admin_id: str) -> str:
|
|
57
|
+
return admin_id.split(f'_{USER_ADMIN_SUFFIX}')[0]
|
|
58
|
+
|
|
59
|
+
@classmethod
|
|
60
|
+
def is_functional_account(cls, user_id: str) -> bool:
|
|
61
|
+
return user_id.split('-', 1) == FUNCTIONAL_ACCOUNT_PREFIX
|
|
62
|
+
|
|
63
|
+
@classmethod
|
|
64
|
+
@cache
|
|
65
|
+
def me(cls) -> BackboneUser:
|
|
66
|
+
return cls.existing_instance(user_id=OsUser.me.name())
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from core_10x.backbone.backbone_traitable import RT, BackboneTraitable, T
|
|
2
|
+
from core_10x.data_domain import DataDomain
|
|
3
|
+
from core_10x.environment_variables import EnvVars
|
|
4
|
+
from core_10x.resource import Resource
|
|
5
|
+
from core_10x.xnone import XNone
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ResourceSpec(BackboneTraitable):
|
|
9
|
+
# fmt: off
|
|
10
|
+
build_area: str = T(T.ID)
|
|
11
|
+
name: str = T(T.ID)
|
|
12
|
+
resource_class: type = T()
|
|
13
|
+
resource_kwargs: dict = T()
|
|
14
|
+
|
|
15
|
+
resource: Resource = RT()
|
|
16
|
+
# fmt: on
|
|
17
|
+
|
|
18
|
+
def build_area_get(self) -> str:
|
|
19
|
+
return EnvVars.sdlc_area
|
|
20
|
+
|
|
21
|
+
def name_get(self) -> str:
|
|
22
|
+
kwargs = self.resource_kwargs
|
|
23
|
+
return kwargs.get(Resource.HOSTNAME_TAG, XNone)
|
|
24
|
+
|
|
25
|
+
def resource_get(self) -> Resource:
|
|
26
|
+
cls = self.resource_class
|
|
27
|
+
assert issubclass(cls, Resource), f'{cls} is not a subclass of Resource'
|
|
28
|
+
return cls.instance(**self.resource_kwargs)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class BoundDataDomain(BackboneTraitable):
|
|
32
|
+
# fmt: off
|
|
33
|
+
domain: DataDomain.__class__ = T(T.ID)
|
|
34
|
+
build_area: str = T(T.ID)
|
|
35
|
+
bound_categories: dict = T()
|
|
36
|
+
# fmt: on
|
|
37
|
+
|
|
38
|
+
def build_area_get(self) -> str:
|
|
39
|
+
return EnvVars.sdlc_area
|
|
40
|
+
|
|
41
|
+
def resource(self, category: str, throw: bool = True) -> Resource:
|
|
42
|
+
r_spec_id: str = self.bound_categories.get(category)
|
|
43
|
+
if not r_spec_id:
|
|
44
|
+
if throw:
|
|
45
|
+
raise ValueError(f'{self.domain} - unknown category {category}')
|
|
46
|
+
return None
|
|
47
|
+
|
|
48
|
+
r_spec = ResourceSpec(_id=r_spec_id)
|
|
49
|
+
return r_spec.resource
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from core_10x.named_constant import NamedConstant
|
|
2
|
+
|
|
3
|
+
# fmt: off
|
|
4
|
+
BACKBONE_STORE_CLASS_NAME = 'infra_10x.mongo_db.Mongo'
|
|
5
|
+
#BACKBONE_USER_NAME = 'core_10x.backbone.backbone_admin.BACKBONE_USER'
|
|
6
|
+
|
|
7
|
+
AUTO_PASSWORD_LENGTH = 32
|
|
8
|
+
|
|
9
|
+
class DB_NAME:
|
|
10
|
+
ANY = ''
|
|
11
|
+
NONE = '_none'
|
|
12
|
+
ADMIN = 'admin'
|
|
13
|
+
BACKBONE = '_backbone_'
|
|
14
|
+
VAULT = '_vault_'
|
|
15
|
+
SHADOW = '_shadow_'
|
|
16
|
+
|
|
17
|
+
class STANDARD_ROLE:
|
|
18
|
+
READ = 'read'
|
|
19
|
+
READ_ANY = 'readAnyDatabase'
|
|
20
|
+
READ_WRITE = 'readWrite'
|
|
21
|
+
READ_WRITE_ANY = 'readWriteAnyDatabase'
|
|
22
|
+
DB_ADMIN = 'dbAdmin'
|
|
23
|
+
DB_ADMIN_ANY = 'dbAdminAnyDatabase'
|
|
24
|
+
OWNER = 'dbOwner'
|
|
25
|
+
USER_ADMIN = 'userAdmin'
|
|
26
|
+
USER_ADMIN_ANY = 'userAdminAnyDatabase'
|
|
27
|
+
CLUSTER_ADMIN = 'clusterAdmin'
|
|
28
|
+
CLUSTER_MAN = 'clusterManager'
|
|
29
|
+
BACKUP = 'backup'
|
|
30
|
+
RESTORE = 'restore'
|
|
31
|
+
ROOT = 'root'
|
|
32
|
+
|
|
33
|
+
class ACTION:
|
|
34
|
+
FIND = 'find'
|
|
35
|
+
INSERT = 'insert'
|
|
36
|
+
UPDATE = 'update'
|
|
37
|
+
REMOVE = 'remove'
|
|
38
|
+
INDEX_LIST = 'listIndexes'
|
|
39
|
+
INDEX_CREATE = 'createIndex'
|
|
40
|
+
COLL_LIST = 'listCollections'
|
|
41
|
+
COLL_STATS = 'collStats'
|
|
42
|
+
COLL_RENAME = 'renameCollectionSameDB'
|
|
43
|
+
COLL_CREATE = 'createCollection'
|
|
44
|
+
COLL_DROP = 'dropCollection'
|
|
45
|
+
DB_LIST = 'listDatabases'
|
|
46
|
+
DB_STATS = 'dbStats'
|
|
47
|
+
CHANGE_STREAME = 'changeStream'
|
|
48
|
+
|
|
49
|
+
CHANGE_OWN_PASSWORD = 'changeOwnPassword'
|
|
50
|
+
|
|
51
|
+
class PERMISSION:
|
|
52
|
+
NONE = []
|
|
53
|
+
NEW_PWD = [ ACTION.CHANGE_OWN_PASSWORD ]
|
|
54
|
+
READ_ONLY = [ ACTION.FIND ]
|
|
55
|
+
READ_EX = [ ACTION.FIND, ACTION.COLL_LIST ]
|
|
56
|
+
WRITE = [ ACTION.INSERT, ACTION.UPDATE, ACTION.REMOVE ]
|
|
57
|
+
INDEX = [ ACTION.INDEX_LIST, ACTION.INDEX_CREATE ]
|
|
58
|
+
COLL = [ ACTION.COLL_LIST, ACTION.COLL_RENAME, ACTION.COLL_STATS, ACTION.COLL_CREATE, ACTION.COLL_DROP ]
|
|
59
|
+
|
|
60
|
+
UPDATE = [ *READ_ONLY, ACTION.UPDATE ]
|
|
61
|
+
READ_WRITE = [ *READ_ONLY, *WRITE, *INDEX, *COLL ]
|
|
62
|
+
|
|
63
|
+
USER_ADMIN_SUFFIX = 'admin'
|
|
64
|
+
FUNCTIONAL_ACCOUNT_PREFIX = 'xx'
|
|
65
|
+
FUNCTIONAL_ACCOUNT_DEPARTMENT = 'XX Functional Accounts'
|
|
66
|
+
|
|
67
|
+
class USER_ROLE(NamedConstant):
|
|
68
|
+
NONE = []
|
|
69
|
+
VISITOR = PERMISSION.READ_EX
|
|
70
|
+
WORKER = PERMISSION.READ_WRITE
|
|
71
|
+
|
|
72
|
+
class COLL_PLACEHOLDER:
|
|
73
|
+
TAG = '__coll_placeholder'
|
|
74
|
+
USERNAME = 'username'
|
|
75
|
+
# fmt: on
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class CUSTOM_ROLE(NamedConstant):
|
|
79
|
+
"""
|
|
80
|
+
role_name: e.g., 'VISITOR'
|
|
81
|
+
permissions_per_db_name: a dict: each key is either a db_name or db_name/collection_name, value is PERMISSION, e.g.,
|
|
82
|
+
{ 'catalog': PERMISSION.READ_ONLY, 'logs/errors': PERMISSION.READ_WRITE }
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
@classmethod
|
|
86
|
+
def coll_placeholder(cls, value) -> tuple: # -- (coll_placeholder, stripped_value)
|
|
87
|
+
cvalue = dict(value)
|
|
88
|
+
return (cvalue.pop(COLL_PLACEHOLDER.TAG, None), value)
|
|
89
|
+
|
|
90
|
+
@classmethod
|
|
91
|
+
def user_role_name(cls, username: str) -> str:
|
|
92
|
+
return f'{username.upper()}_USR'
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
# fmt: off
|
|
96
|
+
SECURITY_KEYS_MISSING = 'Sec keys are missing. If you are using a new computer, please run "xx user new machine" from your shell'
|
|
97
|
+
SECURITY_KEYS_INCOMPATIBLE = 'Sec keys are incompatible with an encrypted password'
|
|
98
|
+
|
|
99
|
+
SECRETS_CLIENT_ARGS = dict(service_name = 'secretmanager', region_name = 'me-south-1')
|
|
100
|
+
SECRETS_PATH_PREFIX = '/external-secrets/xx'
|
|
101
|
+
# fmt: on
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
|
|
3
|
+
from core_10x.backbone.backbone_traitable import RC, T, VaultTraitable
|
|
4
|
+
from core_10x.vault.security_keys import SecKeys
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ResourceAccessor(VaultTraitable):
|
|
8
|
+
# fmt: off
|
|
9
|
+
resource_name: str = T(T.ID)
|
|
10
|
+
#username: str = T(T.ID)
|
|
11
|
+
|
|
12
|
+
login: str = T()
|
|
13
|
+
password: bytes = T()
|
|
14
|
+
last_updated: datetime = T()
|
|
15
|
+
# fmt: on
|
|
16
|
+
|
|
17
|
+
def last_updated_get(self) -> datetime:
|
|
18
|
+
return datetime.utcnow()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Vault:
|
|
22
|
+
ANY_HOST = '.'
|
|
23
|
+
|
|
24
|
+
@staticmethod
|
|
25
|
+
def save_resource_accessor(username: str, hostname: str, login: str, password: str, public_key: bytes = None) -> RC:
|
|
26
|
+
assert login and password, 'login and password must not be empty'
|
|
27
|
+
|
|
28
|
+
pwd = SecKeys.encrypt(password, public_key=public_key)
|
|
29
|
+
if pwd is None:
|
|
30
|
+
return RC(False, 'Security Keys are missing. If you are using a new computer, please run "xx user new machine" from your shell')
|
|
31
|
+
|
|
32
|
+
ra = ResourceAccessor(hostname=hostname)
|
|
33
|
+
ra.reload()
|
|
34
|
+
rc = ra.set_values(login=login, password=pwd)
|
|
35
|
+
if not rc:
|
|
36
|
+
return rc
|
|
37
|
+
|
|
38
|
+
ra.save()
|
|
File without changes
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
from core_10x.directory import Directory
|
|
2
|
+
|
|
3
|
+
ANIMALS = Directory.define(
|
|
4
|
+
'Animals',
|
|
5
|
+
[
|
|
6
|
+
'Microorganisms',
|
|
7
|
+
[
|
|
8
|
+
'Single Cell',
|
|
9
|
+
'Multi Cell',
|
|
10
|
+
],
|
|
11
|
+
'Mollusks',
|
|
12
|
+
'Fishes',
|
|
13
|
+
[
|
|
14
|
+
'Salt Water',
|
|
15
|
+
[
|
|
16
|
+
'Beluga'
|
|
17
|
+
],
|
|
18
|
+
'Fresh Water',
|
|
19
|
+
],
|
|
20
|
+
'Amphibia',
|
|
21
|
+
'Reptiles',
|
|
22
|
+
'Birds',
|
|
23
|
+
'Mammals',
|
|
24
|
+
[
|
|
25
|
+
'Cats',
|
|
26
|
+
'Dogs',
|
|
27
|
+
'Bears',
|
|
28
|
+
'Whales',
|
|
29
|
+
[
|
|
30
|
+
'Bluewhale',
|
|
31
|
+
'Orca',
|
|
32
|
+
'Spermwhale',
|
|
33
|
+
'Beluga'
|
|
34
|
+
],
|
|
35
|
+
],
|
|
36
|
+
],
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
FISH = Directory.define(
|
|
40
|
+
( 'FWF', 'Fresh Water Fish' ),
|
|
41
|
+
[
|
|
42
|
+
( 'PkF', 'Pike Family' ),
|
|
43
|
+
[
|
|
44
|
+
( 'NPK', 'Northern Pike' ),
|
|
45
|
+
( 'MSK', 'Muskie' ),
|
|
46
|
+
( 'PKL', 'Pickerel' ),
|
|
47
|
+
],
|
|
48
|
+
( 'PeF', 'Perch Family' ),
|
|
49
|
+
[
|
|
50
|
+
( 'PCH', 'Common Perch' ),
|
|
51
|
+
( 'YPH', 'Yellow Perch' ),
|
|
52
|
+
( 'WLY', 'Walleye' ),
|
|
53
|
+
( 'SGR', 'Sagger' ),
|
|
54
|
+
],
|
|
55
|
+
( 'CrF', 'Carp Family' ),
|
|
56
|
+
[
|
|
57
|
+
( 'CRP', 'Common Carp' ),
|
|
58
|
+
( 'WCP', 'Wild Carp' ),
|
|
59
|
+
( 'IDE', 'Ide' ),
|
|
60
|
+
( 'BRM', 'Bream' ),
|
|
61
|
+
( 'RCH', 'Roach' ),
|
|
62
|
+
],
|
|
63
|
+
],
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
STANDARD_PIXMAPS = Directory.define(
|
|
67
|
+
'Standard Pixmaps',
|
|
68
|
+
[
|
|
69
|
+
'Title Bar',
|
|
70
|
+
[
|
|
71
|
+
'TitleBarMaxButton',
|
|
72
|
+
'TitleBarCloseButton',
|
|
73
|
+
'TitleBarNormalButton',
|
|
74
|
+
'TitleBarShadeButton',
|
|
75
|
+
'TitleBarUnshadeButton',
|
|
76
|
+
'TitleBarContextHelpButton',
|
|
77
|
+
],
|
|
78
|
+
'Message Box',
|
|
79
|
+
[
|
|
80
|
+
'MessageBoxInformation',
|
|
81
|
+
'MessageBoxWarning',
|
|
82
|
+
'MessageBoxCritical',
|
|
83
|
+
'MessageBoxQuestion',
|
|
84
|
+
],
|
|
85
|
+
'Drive',
|
|
86
|
+
[
|
|
87
|
+
'DriveFDIcon',
|
|
88
|
+
'DriveHDIcon',
|
|
89
|
+
'DriveCDIcon',
|
|
90
|
+
'DriveDVDIcon',
|
|
91
|
+
'DriveNetIcon',
|
|
92
|
+
],
|
|
93
|
+
'Dir',
|
|
94
|
+
[
|
|
95
|
+
'DirHomeIcon',
|
|
96
|
+
'DirOpenIcon',
|
|
97
|
+
'DirClosedIcon',
|
|
98
|
+
'DirIcon',
|
|
99
|
+
'DirLinkIcon',
|
|
100
|
+
'DirLinkOpenIcon',
|
|
101
|
+
],
|
|
102
|
+
'File',
|
|
103
|
+
[
|
|
104
|
+
'FileIcon',
|
|
105
|
+
'FileLinkIcon',
|
|
106
|
+
'FileDialogStart',
|
|
107
|
+
'FileDialogEnd',
|
|
108
|
+
'FileDialogToParent',
|
|
109
|
+
'FileDialogNewFolder',
|
|
110
|
+
'FileDialogDetailedView',
|
|
111
|
+
'FileDialogInfoView',
|
|
112
|
+
'FileDialogContentsView',
|
|
113
|
+
'FileDialogListView',
|
|
114
|
+
'FileDialogBack',
|
|
115
|
+
],
|
|
116
|
+
'Dialog',
|
|
117
|
+
[
|
|
118
|
+
'DialogOkButton',
|
|
119
|
+
'DialogCancelButton',
|
|
120
|
+
'DialogHelpButton',
|
|
121
|
+
'DialogOpenButton',
|
|
122
|
+
'DialogSaveButton',
|
|
123
|
+
'DialogCloseButton',
|
|
124
|
+
'DialogApplyButton',
|
|
125
|
+
'DialogResetButton',
|
|
126
|
+
'DialogDiscardButton',
|
|
127
|
+
'DialogYesButton',
|
|
128
|
+
'DialogNoButton',
|
|
129
|
+
'DialogYesToAllButton',
|
|
130
|
+
'DialogNoToAllButton',
|
|
131
|
+
'DialogSaveAllButton',
|
|
132
|
+
'DialogAbortButton',
|
|
133
|
+
'DialogRetryButton',
|
|
134
|
+
'DialogIgnoreButton',
|
|
135
|
+
],
|
|
136
|
+
'Arrow',
|
|
137
|
+
[
|
|
138
|
+
'ArrowUp',
|
|
139
|
+
'ArrowDown',
|
|
140
|
+
'ArrowLeft',
|
|
141
|
+
'ArrowRight',
|
|
142
|
+
'ArrowBack',
|
|
143
|
+
'ArrowRight',
|
|
144
|
+
'ArrowForward',
|
|
145
|
+
],
|
|
146
|
+
'Media',
|
|
147
|
+
[
|
|
148
|
+
'MediaPlay',
|
|
149
|
+
'MediaStop',
|
|
150
|
+
'MediaPause',
|
|
151
|
+
'MediaSkipForward',
|
|
152
|
+
'MediaSkipBackward',
|
|
153
|
+
'MediaSeekForward',
|
|
154
|
+
'MediaSeekBackward',
|
|
155
|
+
'MediaVolume',
|
|
156
|
+
'MediaVolumeMuted',
|
|
157
|
+
],
|
|
158
|
+
'Other',
|
|
159
|
+
[
|
|
160
|
+
'DesktopIcon',
|
|
161
|
+
'TrashIcon',
|
|
162
|
+
'ComputerIcon',
|
|
163
|
+
'DockWidgetCloseButton',
|
|
164
|
+
'ToolBarHorizontalExtensionButton',
|
|
165
|
+
'ToolBarVerticalExtensionButton',
|
|
166
|
+
'CommandLink',
|
|
167
|
+
'VistaShield',
|
|
168
|
+
'BrowserReload',
|
|
169
|
+
'BrowserStop',
|
|
170
|
+
'LineEditClearButton',
|
|
171
|
+
'RestoreDefaultsButton',
|
|
172
|
+
],
|
|
173
|
+
],
|
|
174
|
+
#'CustomBase',
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
if __name__ == '__main__':
|
|
178
|
+
h1 = FISH.choices()
|
|
179
|
+
|
|
180
|
+
f = ANIMALS.flatten()
|
|
181
|
+
h2 = ANIMALS.choices()
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
from datetime import date
|
|
2
|
+
|
|
3
|
+
from core_10x.named_constant import NamedConstant
|
|
4
|
+
from core_10x.traitable import RC, RC_TRUE, RT, T, Traitable, Ui
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class WEIGHT_QU( NamedConstant ):
|
|
8
|
+
LB = ( 'lb', 1. )
|
|
9
|
+
KG = ( 'kg', 2.205 )
|
|
10
|
+
G = ( 'g', 0.002205 )
|
|
11
|
+
CT = ( 'ct', 0.0004409 )
|
|
12
|
+
|
|
13
|
+
class Person(Traitable):
|
|
14
|
+
first_name: str = T(T.ID)
|
|
15
|
+
last_name: str = T(T.ID)
|
|
16
|
+
dob: date = T()
|
|
17
|
+
weight_lbs: float = T(fmt = ',.4f')
|
|
18
|
+
|
|
19
|
+
age: int
|
|
20
|
+
full_name: str = RT(T.EXPENSIVE)
|
|
21
|
+
weight: float
|
|
22
|
+
weight_qu: WEIGHT_QU = RT(default = WEIGHT_QU.LB)
|
|
23
|
+
|
|
24
|
+
older_than: bool
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def dob_set(self, trait, value: date) -> RC:
|
|
28
|
+
today = date.today()
|
|
29
|
+
if value and value > today:
|
|
30
|
+
return RC(False, f'{value} may not be after {today}')
|
|
31
|
+
return self.raw_set_value(trait, value)
|
|
32
|
+
|
|
33
|
+
def full_name_get(self) -> str:
|
|
34
|
+
return f'{self.first_name} {self.last_name}'
|
|
35
|
+
|
|
36
|
+
def full_name_style_sheet(self) -> dict:
|
|
37
|
+
age = self.age
|
|
38
|
+
return {Ui.FG_COLOR: 'red' if age < 20 or age > 70 else 'green'}
|
|
39
|
+
|
|
40
|
+
def full_name_set(self, trait, value: str) -> RC:
|
|
41
|
+
parts = value.split(' ')
|
|
42
|
+
if(len(parts) != 2):
|
|
43
|
+
return RC(False, f'"{value}" - must be "first_name last_name"')
|
|
44
|
+
|
|
45
|
+
self.first_name = parts[0]
|
|
46
|
+
self.last_name = parts[1]
|
|
47
|
+
return RC_TRUE
|
|
48
|
+
|
|
49
|
+
def age_get(self) -> int:
|
|
50
|
+
dob = self.dob
|
|
51
|
+
if not dob:
|
|
52
|
+
return 0
|
|
53
|
+
|
|
54
|
+
today = date.today()
|
|
55
|
+
years = today.year - dob.year
|
|
56
|
+
dm = today.month - dob.month
|
|
57
|
+
if dm < 0:
|
|
58
|
+
return years - 1
|
|
59
|
+
|
|
60
|
+
if dm > 0:
|
|
61
|
+
return years
|
|
62
|
+
|
|
63
|
+
return years - 1 if today.day < dob.day else years
|
|
64
|
+
|
|
65
|
+
def older_than_get(self, age: int) -> bool:
|
|
66
|
+
return self.age > age
|
|
67
|
+
|
|
68
|
+
#-- getter and setter for weight trait
|
|
69
|
+
def weight_get(self) -> float:
|
|
70
|
+
return self.weight_lbs / self.weight_qu.value
|
|
71
|
+
|
|
72
|
+
def weight_set(self, trait, value) -> RC: #-- trait setter gets its trait and the value and must return RC
|
|
73
|
+
return self.set_values( weight_lbs = value * self.weight_qu.value)
|
|
74
|
+
|
|
75
|
+
def weight_to_str(self, trait, value) -> str:
|
|
76
|
+
return f'{trait.to_str(value)} {self.weight_qu.label}'
|