GeneralManager 0.5.2__py3-none-any.whl → 0.6.0__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.
@@ -0,0 +1,107 @@
1
+ from __future__ import annotations
2
+ import json
3
+
4
+ from typing import Type, Any, Callable, TYPE_CHECKING
5
+ from django.db import models, transaction
6
+ from general_manager.interface.databaseBasedInterface import (
7
+ DBBasedInterface,
8
+ GeneralManagerModel,
9
+ classPreCreationMethod,
10
+ classPostCreationMethod,
11
+ )
12
+
13
+ if TYPE_CHECKING:
14
+ from general_manager.manager.generalManager import GeneralManager
15
+ from general_manager.manager.meta import GeneralManagerMeta
16
+
17
+
18
+ class ReadOnlyInterface(DBBasedInterface):
19
+ _interface_type = "readonly"
20
+
21
+ @classmethod
22
+ def sync_data(cls) -> None:
23
+ """
24
+ Synchronizes the database model with JSON data, ensuring exact correspondence.
25
+
26
+ This method parses JSON data from the parent class and updates the associated Django model so that its records exactly match the JSON content. It creates or updates instances based on unique fields and deletes any database entries not present in the JSON data. Raises a ValueError if required attributes are missing or if the JSON data is invalid.
27
+ """
28
+ model: Type[models.Model] | None = getattr(cls, "_model", None)
29
+ parent_class = getattr(cls, "_parent_class", None)
30
+ if model is None or parent_class is None:
31
+ raise ValueError("Attribute '_model' and '_parent_class' must be set.")
32
+ json_data = getattr(parent_class, "_json_data", None)
33
+ if not json_data:
34
+ raise ValueError(
35
+ f"For ReadOnlyInterface '{parent_class.__name__}' must be set '_json_data'"
36
+ )
37
+
38
+ # JSON-Daten parsen
39
+ if isinstance(json_data, str):
40
+ data_list = json.loads(json_data)
41
+ elif isinstance(json_data, list):
42
+ data_list: list[Any] = json_data
43
+ else:
44
+ raise ValueError(
45
+ "_json_data must be a JSON string or a list of dictionaries"
46
+ )
47
+
48
+ unique_fields = getattr(parent_class, "_unique_fields", [])
49
+ if not unique_fields:
50
+ raise ValueError(
51
+ f"For ReadOnlyInterface '{parent_class.__name__}' must be defined '_unique_fields'"
52
+ )
53
+
54
+ with transaction.atomic():
55
+ json_unique_values: set[Any] = set()
56
+
57
+ # Daten synchronisieren
58
+ for data in data_list:
59
+ lookup = {field: data[field] for field in unique_fields}
60
+ unique_identifier = tuple(lookup[field] for field in unique_fields)
61
+ json_unique_values.add(unique_identifier)
62
+
63
+ instance, _ = model.objects.get_or_create(**lookup)
64
+ updated = False
65
+ for field_name, value in data.items():
66
+ if getattr(instance, field_name, None) != value:
67
+ setattr(instance, field_name, value)
68
+ updated = True
69
+ if updated:
70
+ instance.save()
71
+
72
+ # Existierende Einträge abrufen und löschen, wenn nicht im JSON vorhanden
73
+ existing_instances = model.objects.all()
74
+ for instance in existing_instances:
75
+ lookup = {field: getattr(instance, field) for field in unique_fields}
76
+ unique_identifier = tuple(lookup[field] for field in unique_fields)
77
+ if unique_identifier not in json_unique_values:
78
+ instance.delete()
79
+
80
+ @staticmethod
81
+ def readOnlyPostCreate(func: Callable[..., Any]) -> Callable[..., Any]:
82
+ """
83
+ Decorator for post-creation hooks that registers the interface class as read-only.
84
+
85
+ Wraps a function to be called after a class creation event, then appends the interface
86
+ class to the meta-class's `read_only_classes` list.
87
+ """
88
+
89
+ def wrapper(
90
+ mcs: Type[GeneralManagerMeta],
91
+ new_class: Type[GeneralManager],
92
+ interface_cls: Type[ReadOnlyInterface],
93
+ model: Type[GeneralManagerModel],
94
+ ):
95
+ func(mcs, new_class, interface_cls, model)
96
+ mcs.read_only_classes.append(interface_cls)
97
+
98
+ return wrapper
99
+
100
+ @classmethod
101
+ def handleInterface(cls) -> tuple[classPreCreationMethod, classPostCreationMethod]:
102
+ """
103
+ Returns pre- and post-creation methods for integrating the interface with a GeneralManager.
104
+
105
+ The pre-creation method modifies keyword arguments before a GeneralManager instance is created. The post-creation method, wrapped with a decorator, modifies the instance after creation to add additional data. These methods are intended for use by the GeneralManagerMeta class during the manager's lifecycle.
106
+ """
107
+ return cls._preCreate, cls.readOnlyPostCreate(cls._postCreate)
@@ -1,17 +1,18 @@
1
1
  from __future__ import annotations
2
- from typing import Generic, Type, Any, TYPE_CHECKING
2
+ from typing import Generic, Type, Any, TYPE_CHECKING, TypeVar
3
3
  from general_manager.manager.meta import GeneralManagerMeta
4
- from general_manager.interface.baseInterface import (
5
- InterfaceBase,
6
- Bucket,
7
- GeneralManagerType,
8
- )
4
+
9
5
  from general_manager.api.property import GraphQLProperty
10
6
  from general_manager.cache.cacheTracker import DependencyTracker
11
7
  from general_manager.cache.signals import dataChange
8
+ from general_manager.bucket.baseBucket import Bucket
12
9
 
13
10
  if TYPE_CHECKING:
14
11
  from general_manager.permission.basePermission import BasePermission
12
+ from general_manager.interface.baseInterface import (
13
+ InterfaceBase,
14
+ )
15
+ GeneralManagerType = TypeVar("GeneralManagerType", bound="GeneralManager")
15
16
 
16
17
 
17
18
  class GeneralManager(Generic[GeneralManagerType], metaclass=GeneralManagerMeta):
@@ -129,15 +130,15 @@ class GeneralManager(Generic[GeneralManagerType], metaclass=GeneralManagerMeta):
129
130
  @staticmethod
130
131
  def __parse_identification(kwargs: dict[str, Any]) -> dict[str, Any] | None:
131
132
  """
132
- Converts a dictionary of keyword arguments by replacing any GeneralManager instances with their identifications.
133
+ Processes a dictionary by replacing GeneralManager instances with their identifications.
133
134
 
134
- For each key-value pair, if the value is a GeneralManager, it is replaced with its identification. Lists and tuples are processed recursively, replacing contained GeneralManager instances with their identifications. Returns a new dictionary with the processed values, or None if the result is empty.
135
+ For each key-value pair, replaces any GeneralManager instance with its identification. Lists and tuples are processed recursively, substituting contained GeneralManager instances with their identifications. Returns None if the resulting dictionary is empty.
135
136
 
136
137
  Args:
137
- kwargs: Dictionary of keyword arguments to process.
138
+ kwargs: Dictionary to process.
138
139
 
139
140
  Returns:
140
- A new dictionary with GeneralManager instances replaced by their identifications, or None if the dictionary is empty.
141
+ A new dictionary with GeneralManager instances replaced by their identifications, or None if empty.
141
142
  """
142
143
  output = {}
143
144
  for key, value in kwargs.items():
@@ -1,207 +1,21 @@
1
1
  from __future__ import annotations
2
2
  from typing import (
3
3
  Type,
4
- Generator,
5
4
  Any,
6
5
  Generic,
7
6
  get_args,
8
7
  cast,
9
8
  )
10
- import json
11
9
  from datetime import datetime, date, time
12
10
  from general_manager.api.graphql import GraphQLProperty
13
11
  from general_manager.measurement import Measurement
14
12
  from general_manager.manager.generalManager import GeneralManager
15
- from general_manager.interface.baseInterface import (
13
+ from general_manager.bucket.baseBucket import (
16
14
  Bucket,
17
15
  GeneralManagerType,
18
16
  )
19
17
 
20
18
 
21
- class GroupBucket(Bucket[GeneralManagerType]):
22
-
23
- def __init__(
24
- self,
25
- manager_class: Type[GeneralManagerType],
26
- group_by_keys: tuple[str, ...],
27
- data: Bucket[GeneralManagerType],
28
- ):
29
- super().__init__(manager_class)
30
- self.__checkGroupByArguments(group_by_keys)
31
- self._group_by_keys = group_by_keys
32
- self._data = self.__buildGroupedManager(data)
33
- self._basis_data = data
34
-
35
- def __eq__(self, other: object) -> bool:
36
- if not isinstance(other, self.__class__):
37
- return False
38
- return (
39
- self._data == other._data
40
- and self._manager_class == other._manager_class
41
- and self._group_by_keys == other._group_by_keys
42
- )
43
-
44
- def __checkGroupByArguments(self, group_by_keys: tuple[str, ...]) -> None:
45
- """
46
- Validates that all group-by keys are strings and valid attributes of the manager class.
47
-
48
- Raises:
49
- TypeError: If any group-by key is not a string.
50
- ValueError: If any group-by key is not a valid attribute of the manager class.
51
- """
52
- if not all(isinstance(arg, str) for arg in group_by_keys):
53
- raise TypeError("groupBy() argument must be a string")
54
- if not all(
55
- arg in self._manager_class.Interface.getAttributes()
56
- for arg in group_by_keys
57
- ):
58
- raise ValueError(
59
- f"groupBy() argument must be a valid attribute of {self._manager_class.__name__}"
60
- )
61
-
62
- def __buildGroupedManager(
63
- self,
64
- data: Bucket[GeneralManagerType],
65
- ) -> list[GroupManager[GeneralManagerType]]:
66
- """
67
- This method builds the grouped manager.
68
- It returns a GroupBucket with the grouped data.
69
- """
70
- group_by_values = set()
71
- for entry in data:
72
- group_by_value = {}
73
- for arg in self._group_by_keys:
74
- group_by_value[arg] = getattr(entry, arg)
75
- group_by_values.add(json.dumps(group_by_value))
76
-
77
- groups = []
78
- for group_by_value in sorted(group_by_values):
79
- group_by_value = json.loads(group_by_value)
80
- grouped_manager_objects = data.filter(**group_by_value)
81
- groups.append(
82
- GroupManager(
83
- self._manager_class, group_by_value, grouped_manager_objects
84
- )
85
- )
86
- return groups
87
-
88
- def __or__(self, other: object) -> GroupBucket[GeneralManagerType]:
89
- if not isinstance(other, self.__class__):
90
- raise ValueError("Cannot combine different bucket types")
91
- if self._manager_class != other._manager_class:
92
- raise ValueError("Cannot combine different manager classes")
93
- return GroupBucket(
94
- self._manager_class,
95
- self._group_by_keys,
96
- self._basis_data | other._basis_data,
97
- )
98
-
99
- def __iter__(self) -> Generator[GroupManager[GeneralManagerType]]:
100
- for grouped_manager in self._data:
101
- yield grouped_manager
102
-
103
- def filter(self, **kwargs: Any) -> GroupBucket[GeneralManagerType]:
104
- new_basis_data = self._basis_data.filter(**kwargs)
105
- return GroupBucket(
106
- self._manager_class,
107
- self._group_by_keys,
108
- new_basis_data,
109
- )
110
-
111
- def exclude(self, **kwargs: Any) -> GroupBucket[GeneralManagerType]:
112
- new_basis_data = self._basis_data.exclude(**kwargs)
113
- return GroupBucket(
114
- self._manager_class,
115
- self._group_by_keys,
116
- new_basis_data,
117
- )
118
-
119
- def first(self) -> GroupManager[GeneralManagerType] | None:
120
- try:
121
- return next(iter(self))
122
- except StopIteration:
123
- return None
124
-
125
- def last(self) -> GroupManager[GeneralManagerType] | None:
126
- items = list(self)
127
- if items:
128
- return items[-1]
129
- return None
130
-
131
- def count(self) -> int:
132
- return sum(1 for _ in self)
133
-
134
- def all(self) -> Bucket[GeneralManagerType]:
135
- return self
136
-
137
- def get(self, **kwargs: Any) -> GroupManager[GeneralManagerType]:
138
- first_value = self.filter(**kwargs).first()
139
- if first_value is None:
140
- raise ValueError(
141
- f"Cannot find {self._manager_class.__name__} with {kwargs}"
142
- )
143
- return first_value
144
-
145
- def __getitem__(
146
- self, item: int | slice
147
- ) -> GroupManager[GeneralManagerType] | GroupBucket[GeneralManagerType]:
148
- if isinstance(item, int):
149
- return self._data[item]
150
- elif isinstance(item, slice):
151
- new_data = self._data[item]
152
- new_base_data = None
153
- for manager in new_data:
154
- if new_base_data is None:
155
- new_base_data = manager._data
156
- else:
157
- new_base_data = new_base_data | manager._data
158
- if new_base_data is None:
159
- raise ValueError("Cannot slice an empty GroupBucket")
160
- return GroupBucket(self._manager_class, self._group_by_keys, new_base_data)
161
- raise TypeError(f"Invalid argument type: {type(item)}. Expected int or slice.")
162
-
163
- def __len__(self) -> int:
164
- return self.count()
165
-
166
- def __contains__(self, item: GeneralManagerType) -> bool:
167
- return item in self._basis_data
168
-
169
- def sort(
170
- self,
171
- key: tuple[str] | str,
172
- reverse: bool = False,
173
- ) -> Bucket[GeneralManagerType]:
174
- if isinstance(key, str):
175
- key = (key,)
176
- if reverse:
177
- sorted_data = sorted(
178
- self._data,
179
- key=lambda x: tuple(getattr(x, k) for k in key),
180
- reverse=True,
181
- )
182
- else:
183
- sorted_data = sorted(
184
- self._data, key=lambda x: tuple(getattr(x, k) for k in key)
185
- )
186
-
187
- new_bucket = GroupBucket(
188
- self._manager_class, self._group_by_keys, self._basis_data
189
- )
190
- new_bucket._data = sorted_data
191
- return new_bucket
192
-
193
- def group_by(self, *group_by_keys: str) -> GroupBucket[GeneralManagerType]:
194
- """
195
- This method groups the data by the given arguments.
196
- It returns a GroupBucket with the grouped data.
197
- """
198
- return GroupBucket(
199
- self._manager_class,
200
- tuple([*self._group_by_keys, *group_by_keys]),
201
- self._basis_data,
202
- )
203
-
204
-
205
19
  class GroupManager(Generic[GeneralManagerType]):
206
20
  """
207
21
  This class is used to group the data of a GeneralManager.
@@ -219,13 +33,21 @@ class GroupManager(Generic[GeneralManagerType]):
219
33
  self._data = data
220
34
  self._grouped_data: dict[str, Any] = {}
221
35
 
36
+ def __hash__(self) -> int:
37
+ return hash(
38
+ (
39
+ self._manager_class,
40
+ tuple(self._group_by_value.items()),
41
+ frozenset(self._data),
42
+ )
43
+ )
44
+
222
45
  def __eq__(self, other: object) -> bool:
223
- if not isinstance(other, self.__class__):
224
- return False
225
46
  return (
226
- self._data == other._data
47
+ isinstance(other, self.__class__)
227
48
  and self._manager_class == other._manager_class
228
49
  and self._group_by_value == other._group_by_value
50
+ and frozenset(self._data) == frozenset(other._data)
229
51
  )
230
52
 
231
53
  def __repr__(self) -> str:
@@ -1,14 +1,14 @@
1
1
  from __future__ import annotations
2
- from general_manager.interface.baseInterface import (
3
- InterfaceBase,
4
- )
2
+
5
3
  from django.conf import settings
6
4
  from typing import Any, Type, TYPE_CHECKING, Generic, TypeVar, Iterable
5
+ from general_manager.interface.baseInterface import InterfaceBase
7
6
 
8
7
  if TYPE_CHECKING:
9
- from general_manager.interface.databaseInterface import ReadOnlyInterface
8
+ from general_manager.interface.readOnlyInterface import ReadOnlyInterface
10
9
  from general_manager.manager.generalManager import GeneralManager
11
10
 
11
+
12
12
  GeneralManagerType = TypeVar("GeneralManagerType", bound="GeneralManager")
13
13
 
14
14
 
@@ -24,6 +24,20 @@ class GeneralManagerMeta(type):
24
24
  Interface: type[InterfaceBase]
25
25
 
26
26
  def __new__(mcs, name: str, bases: tuple[type, ...], attrs: dict[str, Any]) -> type:
27
+
28
+ """
29
+ Creates a new class, handling interface integration and registration for the general manager framework.
30
+
31
+ If an 'Interface' attribute is present in the class definition, validates and processes it using the interface's pre- and post-creation hooks, then registers the resulting class for attribute initialization and tracking. If the 'AUTOCREATE_GRAPHQL' setting is enabled, also registers the class for pending GraphQL interface creation.
32
+
33
+ Args:
34
+ name: The name of the class being created.
35
+ bases: Base classes for the new class.
36
+ attrs: Attribute dictionary for the new class.
37
+
38
+ Returns:
39
+ The newly created class, possibly augmented with interface and registration logic.
40
+ """
27
41
  def createNewGeneralManagerClass(
28
42
  mcs, name: str, bases: tuple[type, ...], attrs: dict[str, Any]
29
43
  ) -> Type[GeneralManager]:
@@ -33,7 +47,7 @@ class GeneralManagerMeta(type):
33
47
  interface = attrs.pop("Interface")
34
48
  if not issubclass(interface, InterfaceBase):
35
49
  raise TypeError(
36
- f"Interface must be a subclass of {InterfaceBase.__name__}"
50
+ f"{interface.__name__} must be a subclass of InterfaceBase"
37
51
  )
38
52
  preCreation, postCreation = interface.handleInterface()
39
53
  attrs, interface_cls, model = preCreation(name, attrs, interface)
@@ -6,12 +6,10 @@ from general_manager.permission.permissionChecks import (
6
6
  permission_filter,
7
7
  )
8
8
 
9
+ from django.contrib.auth.models import AnonymousUser, AbstractUser
10
+ from general_manager.permission.permissionDataManager import PermissionDataManager
9
11
 
10
12
  if TYPE_CHECKING:
11
- from django.contrib.auth.models import AbstractUser, AnonymousUser
12
- from general_manager.permission.permissionDataManager import (
13
- PermissionDataManager,
14
- )
15
13
  from general_manager.manager.generalManager import GeneralManager
16
14
  from general_manager.manager.meta import GeneralManagerMeta
17
15
 
@@ -66,7 +64,7 @@ class BasePermission(ABC):
66
64
  request_user = cls.getUserWithId(request_user)
67
65
 
68
66
  errors = []
69
- permission_data = PermissionDataManager[GeneralManager].forUpdate(
67
+ permission_data = PermissionDataManager.forUpdate(
70
68
  base_data=old_manager_instance, update_data=data
71
69
  )
72
70
  Permission = cls(permission_data, request_user)
@@ -90,7 +88,7 @@ class BasePermission(ABC):
90
88
  request_user = cls.getUserWithId(request_user)
91
89
 
92
90
  errors = []
93
- permission_data = PermissionDataManager[GeneralManager](manager_instance)
91
+ permission_data = PermissionDataManager(manager_instance)
94
92
  Permission = cls(permission_data, request_user)
95
93
  for key in manager_instance.__dict__.keys():
96
94
  is_allowed = Permission.checkPermission("delete", key)
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GeneralManager
3
- Version: 0.5.2
4
- Summary: Kurzbeschreibung deines Pakets
3
+ Version: 0.6.0
4
+ Summary: Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching.
5
5
  Author-email: Tim Kleindick <tkleindick@yahoo.de>
6
6
  License-Expression: MIT
7
7
  Requires-Python: >=3.12
@@ -1,6 +1,6 @@
1
1
  general_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  general_manager/apps.py,sha256=0QwuIAnhHm5u0wTlCiDVsl8k0RU0BEgfFjmBMl9zvsw,3320
3
- general_manager/api/graphql.py,sha256=L-UUiDDOe1s5mhXs9nBNf0f7PXz9JLloUfyrXbjIfIs,27408
3
+ general_manager/api/graphql.py,sha256=a_mH5dvM3yXC1WyQKFCYpzSE00DQFLNKhRsZrwvLrNM,27453
4
4
  general_manager/api/mutation.py,sha256=uu5RVxc9wbb-Zrbtt4azegvyKymMqEsxk_CkerKCd9Q,5178
5
5
  general_manager/api/property.py,sha256=oc93p1P8dcIvrNorRuqD1EJVsd6eYttYhZuAS0s28gs,696
6
6
  general_manager/auxiliary/__init__.py,sha256=4IwKJzsNxGduF-Ej0u1BNHVaMhkql8PjHbVtx9DOTSY,76
@@ -10,29 +10,35 @@ general_manager/auxiliary/jsonEncoder.py,sha256=TDsgFQvheITHZgdmn-m8tk1_QCzpT0Xw
10
10
  general_manager/auxiliary/makeCacheKey.py,sha256=lczutqxlofLSUnheKRi8nazhOyPa04TZOFNxNn5vDu4,1126
11
11
  general_manager/auxiliary/noneToZero.py,sha256=KfQtMQnrT6vsYST0K7lv6pVujkDcK3XL8czHYOhgqKQ,539
12
12
  general_manager/auxiliary/pathMapping.py,sha256=nrz5owQg2a69Yig1eCXorR9U0NSw7NmBAk5OkeoHTdA,6842
13
+ general_manager/bucket/baseBucket.py,sha256=65oQbSE6C8TE0yVPP_Aoi_Fwq0Uo2TLVPWMG6l2qxyQ,7836
14
+ general_manager/bucket/calculationBucket.py,sha256=M2z7H7mvs56BIlr0NKQYqxcbWO92cFsgXSeKgM4oAko,18056
15
+ general_manager/bucket/databaseBucket.py,sha256=V_xiPa8ErnPHVh_-i-oaH8qCa818UJxm5CVl80SVc1U,9060
16
+ general_manager/bucket/groupBucket.py,sha256=55QdUaH_qO1JFJ2Jc1f2WcxniiLE5LB3vNwbnksKk8A,10939
13
17
  general_manager/cache/cacheDecorator.py,sha256=DK2ANIJgPpMxazfMSiFrI9OuVE_7K9zlIZQRrgaC2Lw,3268
14
18
  general_manager/cache/cacheTracker.py,sha256=rRw3OhBDf86hTC2Xbt1ocRgZqwu8_kXk4lczamcADFg,2955
15
19
  general_manager/cache/dependencyIndex.py,sha256=kEbIAzzMzKlQgplKfcMYBPZ562zCBkOBKvJusxO_iC4,10537
16
- general_manager/cache/modelDependencyCollector.py,sha256=wS2edbZsQ1aTfRlHj02lhuasZHCc2ucRGob-E7ejuoY,2433
20
+ general_manager/cache/modelDependencyCollector.py,sha256=lIqBvo0QygoxxZPJ32_vMs_-eJaVJDznGyrEmxPV41E,2436
17
21
  general_manager/cache/signals.py,sha256=ZHeXKFMN7tj9t0J-vSqf_05_NhGqEF2sZtbZO3vaRqI,1234
18
22
  general_manager/factory/__init__.py,sha256=wbPIGyBlWBHa7aGWUd-1IUMPWUS-M6YqtPUL1iKXW8U,93
19
23
  general_manager/factory/autoFactory.py,sha256=WBhSuMVsxkPAPLhlZhYXwHVIqiomUveS7vMxw1ON_8Q,9376
20
24
  general_manager/factory/factories.py,sha256=F6_nYFyJRYYc3LQApfoVFdctfLzsWUDHKafn6xjckB8,7224
21
25
  general_manager/factory/factoryMethods.py,sha256=9Bag891j0XHe3dUBAFi7gUKcKeUwcBZN3cDLBobyBiI,3225
22
- general_manager/interface/__init__.py,sha256=6x5adQLefTugvrJeyPcAxstyqgLAYeaJ1EPdAbac9pE,213
23
- general_manager/interface/baseInterface.py,sha256=V8AzZ9CwswZAqc2aODmE_7DtqokOkOxzpXFVQ6qznMo,11271
24
- general_manager/interface/calculationInterface.py,sha256=GzSNXjU6Z7bFz60gHyMKkI5xNUDIPuniV8wbyVtQT50,14250
25
- general_manager/interface/databaseInterface.py,sha256=khzqoOcKrBSaYnZAdPmm9cdseNx4YdPRqx5B-81KGf4,28431
26
+ general_manager/interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
+ general_manager/interface/baseInterface.py,sha256=b7MH-jVADcpGluvJMogPn2O3Yiy37uCnWOM9j0Ec0o0,8692
28
+ general_manager/interface/calculationInterface.py,sha256=ZMYQcJZdfnEimsKOGFVfg-8r6Syjo_D9_HPVJkd59ak,4018
29
+ general_manager/interface/databaseBasedInterface.py,sha256=K2PYxANuLQU8wzrajcl922tuWwko642KJAS3f3PnAmg,21566
30
+ general_manager/interface/databaseInterface.py,sha256=rQWeL5u_WCvDtikXLracFkECVM9vZHjs7UXTJlDDCmY,4146
31
+ general_manager/interface/readOnlyInterface.py,sha256=d2CM2gj5XZNEaVFZeNCgqZf46rwUAetVS3SyePCKNsY,4691
26
32
  general_manager/manager/__init__.py,sha256=l3RYp62aEhj3Y975_XUTIzo35LUnkTJHkb_hgChnXXI,111
27
- general_manager/manager/generalManager.py,sha256=L470Jevvh87doI5leUbTa9P6weIdekRZ6OTorqN-WpY,6091
28
- general_manager/manager/groupManager.py,sha256=gT7cLq3d6PhsLfVGaIG5-fC7xnwN-4nT46N2WpnSesY,10588
33
+ general_manager/manager/generalManager.py,sha256=HX69KhrnSGVkuJwHY_jzff5gS0VD-6fRxKnd59A5Ct4,6100
34
+ general_manager/manager/groupManager.py,sha256=8dpZUfm7aFL4lraUWv4qbbDRClQZaYxw4prclhBZYZs,4367
29
35
  general_manager/manager/input.py,sha256=iKawV3P1QICz-0AQUF00OvH7LZYxussg3svpvCUl8hE,2977
30
- general_manager/manager/meta.py,sha256=Km4axFpDKI_Wx000dOok5jUwjJVqq5QJG9XhrWRw5mo,3624
36
+ general_manager/manager/meta.py,sha256=g94L92hDy5gdGhgaTu3pjgZtt_fLC8LruNj9T34ApdA,4414
31
37
  general_manager/measurement/__init__.py,sha256=X97meFujBldE5v0WMF7SmKeGpC5R0JTczfLo_Lq1Xek,84
32
38
  general_manager/measurement/measurement.py,sha256=e_FjHieeJbBtjXGCO9J7vRPw6KCkMrOxwWjaD0m8ee4,11777
33
39
  general_manager/measurement/measurementField.py,sha256=iq9Hqe6ZGX8CxXm4nIqTAWTRkQVptzpqE9ExX-jFyNs,5928
34
40
  general_manager/permission/__init__.py,sha256=5UlDERN60Vn8obGVkT-cOM8kHjzmoxgK5w5FgTCDhGE,59
35
- general_manager/permission/basePermission.py,sha256=PsJiX-UNeSh6xUlcUwuQNCLYvHZipWUJ0kAoMkdxXJc,6113
41
+ general_manager/permission/basePermission.py,sha256=14iKo6qVmaUdg1sAz-gSZyNtpVKAAapIhutVAMDf93c,6056
36
42
  general_manager/permission/fileBasedPermission.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
43
  general_manager/permission/managerBasedPermission.py,sha256=VgZJVgkXWdaLk6K7c0kYxTbELnTYK6UY9mMuKH5u64w,5728
38
44
  general_manager/permission/permissionChecks.py,sha256=T-9khBqiwM4ASBdey9p07sC_xgzceIU9EAE0reukguM,1655
@@ -40,8 +46,8 @@ general_manager/permission/permissionDataManager.py,sha256=Ji7fsnuaKTa6M8yzCGyzr
40
46
  general_manager/rule/__init__.py,sha256=4Har5cfPD1fmOsilTDod-ZUz3Com-tkl58jz7yY4fD0,23
41
47
  general_manager/rule/handler.py,sha256=z8SFHTIZ0LbLh3fV56Mud0V4_OvWkqJjlHvFqau7Qfk,7334
42
48
  general_manager/rule/rule.py,sha256=3FVCKGL7BTVoStdgOTdWQwuoVRIxAIAilV4VOzouDpc,10759
43
- generalmanager-0.5.2.dist-info/licenses/LICENSE,sha256=YGFm0ieb4KpkMRRt2qnWue6uFh0cUMtobwEBkHwajhc,1450
44
- generalmanager-0.5.2.dist-info/METADATA,sha256=7fumKNtzVKr86HwflW_Sesa93yWWHXTJAyumR-TWDEU,6101
45
- generalmanager-0.5.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
46
- generalmanager-0.5.2.dist-info/top_level.txt,sha256=sTDtExP9ga-YP3h3h42yivUY-A2Q23C2nw6LNKOho4I,16
47
- generalmanager-0.5.2.dist-info/RECORD,,
49
+ generalmanager-0.6.0.dist-info/licenses/LICENSE,sha256=YGFm0ieb4KpkMRRt2qnWue6uFh0cUMtobwEBkHwajhc,1450
50
+ generalmanager-0.6.0.dist-info/METADATA,sha256=Z3Eh9kL1htCX6HfL5DVmlU6FGIfvu_1k777eTxiNMjU,6205
51
+ generalmanager-0.6.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
52
+ generalmanager-0.6.0.dist-info/top_level.txt,sha256=sTDtExP9ga-YP3h3h42yivUY-A2Q23C2nw6LNKOho4I,16
53
+ generalmanager-0.6.0.dist-info/RECORD,,