mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 04:50:36 +03:00
Refactoring: enable formatting with autopep8
This commit is contained in:
parent
9e4f7ca2f2
commit
18c09ecd93
11
.vscode/settings.json
vendored
11
.vscode/settings.json
vendored
|
@ -4,6 +4,7 @@
|
|||
".pytest_cache/": true
|
||||
},
|
||||
"typescript.tsdk": "rsconcept/frontend/node_modules/typescript/lib",
|
||||
"eslint.workingDirectories": ["rsconcept/frontend"],
|
||||
"isort.args": [
|
||||
"--line-length",
|
||||
"100",
|
||||
|
@ -12,10 +13,16 @@
|
|||
"--project",
|
||||
"apps"
|
||||
],
|
||||
"eslint.workingDirectories": ["rsconcept/frontend"],
|
||||
"autopep8.args": [
|
||||
"--max-line-length",
|
||||
"120",
|
||||
"--aggressive",
|
||||
"--ignore",
|
||||
"E303"
|
||||
],
|
||||
"[python]": {
|
||||
"editor.formatOnSave": false,
|
||||
"editor.defaultFormatter": "ms-python.autopep8",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.tabSize": 4,
|
||||
"editor.insertSpaces": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
|
|
|
@ -7,13 +7,14 @@ ItemType = TypeVar("ItemType")
|
|||
|
||||
class Graph(Generic[ItemType]):
|
||||
''' Directed graph. '''
|
||||
def __init__(self, graph: Optional[dict[ItemType, list[ItemType]]]=None):
|
||||
|
||||
def __init__(self, graph: Optional[dict[ItemType, list[ItemType]]] = None):
|
||||
if graph is None:
|
||||
self.outputs: dict[ItemType, list[ItemType]] = {}
|
||||
self.inputs: dict[ItemType, list[ItemType]] = {}
|
||||
else:
|
||||
self.outputs = graph
|
||||
self.inputs: dict[ItemType, list[ItemType]] = {id : [] for id in graph.keys()} #type: ignore[no-redef]
|
||||
self.inputs: dict[ItemType, list[ItemType]] = {id: [] for id in graph.keys()} # type: ignore[no-redef]
|
||||
for parent in graph.keys():
|
||||
for child in graph[parent]:
|
||||
self.inputs[child].append(parent)
|
||||
|
|
|
@ -1,41 +1,54 @@
|
|||
''' Utility: Text messages. '''
|
||||
# pylint: skip-file
|
||||
|
||||
|
||||
def constituentaNotOwned(title: str):
|
||||
return f'Конституента не принадлежит схеме: {title}'
|
||||
|
||||
|
||||
def substitutionNotInList():
|
||||
return 'Отождествляемая конституента отсутствует в списке'
|
||||
|
||||
|
||||
def schemaNotOwned():
|
||||
return 'Нет доступа к схеме'
|
||||
|
||||
|
||||
def renameTrivial(name: str):
|
||||
return f'Имя должно отличаться от текущего: {name}'
|
||||
|
||||
|
||||
def substituteTrivial(name: str):
|
||||
return f'Отождествление конституенты с собой не корректно: {name}'
|
||||
|
||||
|
||||
def substituteDouble(name: str):
|
||||
return f'Повторное отождествление: {name}'
|
||||
|
||||
|
||||
def aliasTaken(name: str):
|
||||
return f'Имя уже используется: {name}'
|
||||
|
||||
|
||||
def pyconceptFailure():
|
||||
return 'Invalid data response from pyconcept'
|
||||
|
||||
|
||||
def typificationInvalidStr():
|
||||
return 'Invalid typification string'
|
||||
|
||||
|
||||
def libraryTypeUnexpected():
|
||||
return 'Attempting to use invalid adaptor for non-RSForm item'
|
||||
|
||||
|
||||
def exteorFileVersionNotSupported():
|
||||
return 'Некорректный формат файла Экстеор. Сохраните файл в новой версии'
|
||||
|
||||
|
||||
def invalidPosition():
|
||||
return 'Invalid position: should be positive integer'
|
||||
|
||||
|
||||
def constituentaNoStructure():
|
||||
return 'Указанная конституента не обладает теоретико-множественной типизацией'
|
||||
|
|
|
@ -29,6 +29,7 @@ _INSERT_LAST: int = -1
|
|||
|
||||
class RSForm:
|
||||
''' RSForm is math form of conceptual schema. '''
|
||||
|
||||
def __init__(self, item: LibraryItem):
|
||||
if item.item_type != LibraryItemType.RSFORM:
|
||||
raise ValueError(msg.libraryTypeUnexpected())
|
||||
|
@ -195,7 +196,7 @@ class RSForm:
|
|||
self.item.save()
|
||||
|
||||
@transaction.atomic
|
||||
def create_cst(self, data: dict, insert_after: Optional[str]=None) -> Constituenta:
|
||||
def create_cst(self, data: dict, insert_after: Optional[str] = None) -> Constituenta:
|
||||
''' Create new cst from data. '''
|
||||
resolver = self.resolver()
|
||||
cst = self._insert_new(data, insert_after)
|
||||
|
@ -224,7 +225,7 @@ class RSForm:
|
|||
):
|
||||
''' Execute constituenta substitution. '''
|
||||
assert original.pk != substitution.pk
|
||||
mapping = { original.alias: substitution.alias }
|
||||
mapping = {original.alias: substitution.alias}
|
||||
self.apply_mapping(mapping)
|
||||
if transfer_term:
|
||||
substitution.term_raw = original.term_raw
|
||||
|
@ -362,7 +363,7 @@ class RSForm:
|
|||
cst.save()
|
||||
order += 1
|
||||
|
||||
def _insert_new(self, data: dict, insert_after: Optional[str]=None) -> Constituenta:
|
||||
def _insert_new(self, data: dict, insert_after: Optional[str] = None) -> Constituenta:
|
||||
if insert_after is not None:
|
||||
cst_after = Constituenta.objects.get(pk=insert_after)
|
||||
return self.insert_new(data['alias'], data['cst_type'], cst_after.order + 1)
|
||||
|
@ -426,21 +427,22 @@ class RSForm:
|
|||
|
||||
class SemanticInfo:
|
||||
''' Semantic information derived from constituents. '''
|
||||
|
||||
def __init__(self, schema: RSForm):
|
||||
self._graph = schema._graph_formal()
|
||||
self._items = list(
|
||||
schema.constituents() \
|
||||
.only('id', 'alias', 'cst_type', 'definition_formal') \
|
||||
schema.constituents()
|
||||
.only('id', 'alias', 'cst_type', 'definition_formal')
|
||||
.order_by('order')
|
||||
)
|
||||
self._cst_by_alias = { cst.alias : cst for cst in self._items }
|
||||
self._cst_by_ID = { cst.id : cst for cst in self._items }
|
||||
self._cst_by_alias = {cst.alias: cst for cst in self._items}
|
||||
self._cst_by_ID = {cst.id: cst for cst in self._items}
|
||||
self.info = {
|
||||
cst.id: {
|
||||
'is_simple' : False, \
|
||||
'is_template' : False, \
|
||||
'parent' : cst.id, \
|
||||
'children' : []
|
||||
'is_simple': False,
|
||||
'is_template': False,
|
||||
'parent': cst.id,
|
||||
'children': []
|
||||
}
|
||||
for cst in self._items
|
||||
}
|
||||
|
@ -483,7 +485,7 @@ class SemanticInfo:
|
|||
|
||||
dependencies = self._graph.inputs[target.id]
|
||||
has_complex_dependency = any(
|
||||
self.is_template(cst_id) and \
|
||||
self.is_template(cst_id) and
|
||||
not self.is_simple_expression(cst_id) for cst_id in dependencies
|
||||
)
|
||||
if has_complex_dependency:
|
||||
|
@ -538,7 +540,7 @@ class SemanticInfo:
|
|||
sources.add(parent_info['parent'])
|
||||
return sources
|
||||
|
||||
def _need_check_head(self, sources: set[int], head: str)-> bool:
|
||||
def _need_check_head(self, sources: set[int], head: str) -> bool:
|
||||
if len(sources) == 0:
|
||||
return True
|
||||
elif len(sources) != 1:
|
||||
|
@ -551,15 +553,16 @@ class SemanticInfo:
|
|||
|
||||
class _OrderManager:
|
||||
''' Ordering helper class '''
|
||||
|
||||
def __init__(self, schema: RSForm):
|
||||
self._semantic = schema.semantic()
|
||||
self._graph = schema._graph_formal()
|
||||
self._items = list(
|
||||
schema.constituents() \
|
||||
.only('id', 'order', 'alias', 'cst_type', 'definition_formal') \
|
||||
schema.constituents()
|
||||
.only('id', 'order', 'alias', 'cst_type', 'definition_formal')
|
||||
.order_by('order')
|
||||
)
|
||||
self._cst_by_ID = { cst.id : cst for cst in self._items }
|
||||
self._cst_by_ID = {cst.id: cst for cst in self._items}
|
||||
|
||||
def restore_order(self) -> None:
|
||||
''' Implement order restoration process. '''
|
||||
|
@ -579,8 +582,8 @@ class _OrderManager:
|
|||
result = [cst for cst in self._items if cst.cst_type == CstType.BASE]
|
||||
result = result + [cst for cst in self._items if cst.cst_type == CstType.CONSTANT]
|
||||
kernel = [
|
||||
cst.id for cst in self._items if \
|
||||
cst.cst_type in [CstType.STRUCTURED, CstType.AXIOM] or \
|
||||
cst.id for cst in self._items if
|
||||
cst.cst_type in [CstType.STRUCTURED, CstType.AXIOM] or
|
||||
self._cst_by_ID[self._semantic.parent(cst.id)].cst_type == CstType.STRUCTURED
|
||||
]
|
||||
kernel = kernel + self._graph.expand_inputs(kernel)
|
||||
|
@ -604,7 +607,6 @@ class _OrderManager:
|
|||
result.append(child)
|
||||
self._items = result
|
||||
|
||||
|
||||
@transaction.atomic
|
||||
def _save_order(self) -> None:
|
||||
order = 1
|
||||
|
|
|
@ -150,7 +150,7 @@ def generate_structure(alias: str, expression: str, parse: dict) -> list:
|
|||
parent_type = ast[parent_index]['typeID']
|
||||
parent_text = generated[parent_index]['text']
|
||||
parent_is_boolean = generated[parent_index]['is_boolean']
|
||||
assert(parent_type in [TokenType.BOOLEAN, TokenType.DECART])
|
||||
assert parent_type in [TokenType.BOOLEAN, TokenType.DECART]
|
||||
|
||||
if parent_is_boolean:
|
||||
if parent_type == TokenType.BOOLEAN:
|
||||
|
|
|
@ -65,6 +65,7 @@ class ErrorDescriptionSerializer(serializers.Serializer):
|
|||
child=serializers.CharField()
|
||||
)
|
||||
|
||||
|
||||
class NodeDataSerializer(serializers.Serializer):
|
||||
''' Serializer: Node data. '''
|
||||
dataType = serializers.CharField()
|
||||
|
|
|
@ -93,7 +93,7 @@ class CstSerializer(serializers.ModelSerializer):
|
|||
definition: Optional[str] = data['definition_raw'] if 'definition_raw' in data else None
|
||||
term: Optional[str] = data['term_raw'] if 'term_raw' in data else None
|
||||
term_changed = 'term_forms' in data
|
||||
if definition is not None and definition != instance.definition_raw :
|
||||
if definition is not None and definition != instance.definition_raw:
|
||||
data['definition_resolved'] = schema.resolver().resolve(definition)
|
||||
if term is not None and term != instance.term_raw:
|
||||
data['term_resolved'] = schema.resolver().resolve(term)
|
||||
|
|
|
@ -12,6 +12,7 @@ _TRS_VERSION_MIN = 16
|
|||
_TRS_VERSION = 16
|
||||
_TRS_HEADER = 'Exteor 4.8.13.1000 - 30/05/2022'
|
||||
|
||||
|
||||
class FileSerializer(serializers.Serializer):
|
||||
''' Serializer: File input. '''
|
||||
file = serializers.FileField(allow_empty_file=False)
|
||||
|
@ -25,6 +26,7 @@ class RSFormUploadSerializer(serializers.Serializer):
|
|||
|
||||
class RSFormTRSSerializer(serializers.Serializer):
|
||||
''' Serializer: TRS file production and loading for RSForm. '''
|
||||
|
||||
def to_representation(self, instance: RSForm) -> dict:
|
||||
result = self._prepare_json_rsform(instance)
|
||||
items = instance.constituents().order_by('order')
|
||||
|
@ -115,7 +117,7 @@ class RSFormTRSSerializer(serializers.Serializer):
|
|||
if self.context['load_meta']:
|
||||
result['title'] = data.get('title', 'Без названия')
|
||||
result['alias'] = data.get('alias', '')
|
||||
result['comment']= data.get('comment', '')
|
||||
result['comment'] = data.get('comment', '')
|
||||
if 'id' in data:
|
||||
result['id'] = data['id']
|
||||
self.instance = RSForm(LibraryItem.objects.get(pk=result['id']))
|
||||
|
|
|
@ -10,6 +10,7 @@ from ..models import RSForm
|
|||
|
||||
class PyConceptAdapter:
|
||||
''' RSForm adapter for interacting with pyconcept module. '''
|
||||
|
||||
def __init__(self, data: Union[RSForm, dict]):
|
||||
try:
|
||||
if 'items' in cast(dict, data):
|
||||
|
|
|
@ -14,6 +14,7 @@ class NewCstResponse(serializers.Serializer):
|
|||
new_cst = serializers.IntegerField()
|
||||
schema = RSFormParseSerializer()
|
||||
|
||||
|
||||
class NewMultiCstResponse(serializers.Serializer):
|
||||
''' Serializer: Create multiple cst response. '''
|
||||
cst_list = serializers.ListField(
|
||||
|
@ -21,6 +22,7 @@ class NewMultiCstResponse(serializers.Serializer):
|
|||
)
|
||||
schema = RSFormParseSerializer()
|
||||
|
||||
|
||||
class NewVersionResponse(serializers.Serializer):
|
||||
''' Serializer: Create cst response. '''
|
||||
version = serializers.IntegerField()
|
||||
|
|
|
@ -8,6 +8,7 @@ from apps.rsform.models import Constituenta, CstType, LibraryItem, LibraryItemTy
|
|||
|
||||
class TestConstituenta(TestCase):
|
||||
''' Testing Constituenta model. '''
|
||||
|
||||
def setUp(self):
|
||||
self.schema1 = LibraryItem.objects.create(item_type=LibraryItemType.RSFORM, title='Test1')
|
||||
self.schema2 = LibraryItem.objects.create(item_type=LibraryItemType.RSFORM, title='Test2')
|
||||
|
|
|
@ -6,6 +6,7 @@ from apps.rsform.models import LibraryItem, LibraryItemType, Subscription, User
|
|||
|
||||
class TestLibraryItem(TestCase):
|
||||
''' Testing LibraryItem model. '''
|
||||
|
||||
def setUp(self):
|
||||
self.user1 = User.objects.create(username='User1')
|
||||
self.user2 = User.objects.create(username='User2')
|
||||
|
|
|
@ -7,6 +7,7 @@ from apps.rsform.models import Constituenta, CstType, RSForm, User
|
|||
|
||||
class TestRSForm(TestCase):
|
||||
''' Testing RSForm wrapper. '''
|
||||
|
||||
def setUp(self):
|
||||
self.user1 = User.objects.create(username='User1')
|
||||
self.user2 = User.objects.create(username='User2')
|
||||
|
@ -81,7 +82,7 @@ class TestRSForm(TestCase):
|
|||
def test_insert_at_reorder(self):
|
||||
self.schema.insert_new('X1')
|
||||
d1 = self.schema.insert_new('D1')
|
||||
d2 = self.schema.insert_new('D2',position=1)
|
||||
d2 = self.schema.insert_new('D2', position=1)
|
||||
d1.refresh_from_db()
|
||||
self.assertEqual(d1.order, 3)
|
||||
self.assertEqual(d2.order, 1)
|
||||
|
@ -345,8 +346,8 @@ class TestRSForm(TestCase):
|
|||
definition_resolved='очень сильный человек'
|
||||
)
|
||||
|
||||
x1.term_raw='слон'
|
||||
x1.term_resolved='слон'
|
||||
x1.term_raw = 'слон'
|
||||
x1.term_resolved = 'слон'
|
||||
x1.save()
|
||||
|
||||
self.schema.on_term_change([x1.id])
|
||||
|
|
|
@ -8,7 +8,6 @@ from apps.rsform.utils import apply_pattern, fix_old_references
|
|||
class TestUtils(unittest.TestCase):
|
||||
''' Test various utility functions. '''
|
||||
|
||||
|
||||
def test_apply_mapping_patter(self):
|
||||
mapping = {'X101': 'X20'}
|
||||
pattern = re.compile(r'(X[0-9]+)')
|
||||
|
|
|
@ -15,6 +15,7 @@ _REF_OLD_PATTERN = re.compile(r'@{([^0-9\-][^\}\|\{]*?)\|([^\}\|\{]*?)\|([^\}\|\
|
|||
|
||||
class ObjectOwnerOrAdmin(BasePermission):
|
||||
''' Permission for object ownership restriction '''
|
||||
|
||||
def has_object_permission(self, request, view, obj):
|
||||
if request.user == obj.owner:
|
||||
return True
|
||||
|
@ -25,6 +26,7 @@ class ObjectOwnerOrAdmin(BasePermission):
|
|||
|
||||
class IsClaimable(IsAuthenticated):
|
||||
''' Permission for object ownership restriction '''
|
||||
|
||||
def has_object_permission(self, request, view, obj):
|
||||
if not super().has_permission(request, view):
|
||||
return False
|
||||
|
@ -33,6 +35,7 @@ class IsClaimable(IsAuthenticated):
|
|||
|
||||
class SchemaOwnerOrAdmin(BasePermission):
|
||||
''' Permission for object ownership restriction '''
|
||||
|
||||
def has_object_permission(self, request, view, obj):
|
||||
if request.user == obj.schema.owner:
|
||||
return True
|
||||
|
@ -43,6 +46,7 @@ class SchemaOwnerOrAdmin(BasePermission):
|
|||
|
||||
class ItemOwnerOrAdmin(BasePermission):
|
||||
''' Permission for object ownership restriction '''
|
||||
|
||||
def has_object_permission(self, request, view, obj):
|
||||
if request.user == obj.item.owner:
|
||||
return True
|
||||
|
@ -77,11 +81,11 @@ def apply_pattern(text: str, mapping: dict[str, str], pattern: re.Pattern[str])
|
|||
for segment in re.finditer(pattern, text):
|
||||
entity = segment.group(1)
|
||||
if entity in mapping:
|
||||
output += text[pos_input : segment.start(1)]
|
||||
output += text[pos_input: segment.start(1)]
|
||||
output += mapping[entity]
|
||||
output += text[segment.end(1) : segment.end(0)]
|
||||
output += text[segment.end(1): segment.end(0)]
|
||||
pos_input = segment.end(0)
|
||||
output += text[pos_input : len(text)]
|
||||
output += text[pos_input: len(text)]
|
||||
return output
|
||||
|
||||
|
||||
|
@ -92,10 +96,10 @@ def fix_old_references(text: str) -> str:
|
|||
pos_input: int = 0
|
||||
output: str = ''
|
||||
for segment in re.finditer(_REF_OLD_PATTERN, text):
|
||||
output += text[pos_input : segment.start(0)]
|
||||
output += text[pos_input: segment.start(0)]
|
||||
output += f'@{{{segment.group(1)}|{segment.group(2)},{segment.group(3)}}}'
|
||||
pos_input = segment.end(0)
|
||||
output += text[pos_input : len(text)]
|
||||
output += text[pos_input: len(text)]
|
||||
return output
|
||||
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
|
|||
cst = cast(m.Constituenta, serializer.validated_data['target'])
|
||||
|
||||
schema_details = s.RSFormParseSerializer(schema.item).data['items']
|
||||
cst_parse = next(item for item in schema_details if item['id']==cst.id)['parse']
|
||||
cst_parse = next(item for item in schema_details if item['id'] == cst.id)['parse']
|
||||
if not cst_parse['typification']:
|
||||
return Response(
|
||||
status=c.HTTP_400_BAD_REQUEST,
|
||||
|
@ -131,7 +131,7 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
|
|||
cst.cst_type = serializer.validated_data['cst_type']
|
||||
cst.save()
|
||||
|
||||
mapping = { old_alias: cst.alias }
|
||||
mapping = {old_alias: cst.alias}
|
||||
schema.apply_mapping(mapping, change_aliases=False)
|
||||
schema.item.refresh_from_db()
|
||||
cst.refresh_from_db()
|
||||
|
|
|
@ -128,7 +128,7 @@ def retrieve_version(request: Request, pk_item: int, pk_version: int):
|
|||
(c.HTTP_200_OK, 'application/zip'): bytes,
|
||||
c.HTTP_404_NOT_FOUND: None
|
||||
}
|
||||
)
|
||||
)
|
||||
@api_view(['GET'])
|
||||
def export_file(request: Request, pk: int):
|
||||
''' Endpoint: Download Exteor compatible file for versioned data. '''
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
''' Utility: Text messages. '''
|
||||
# pylint: skip-file
|
||||
|
||||
|
||||
def passwordAuthFailed():
|
||||
return 'Неизвестное сочетание имени пользователя и пароля'
|
||||
|
||||
|
||||
def passwordsNotMatch():
|
||||
return 'Введенные пароли не совпадают'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
''' Models: User profile and Authentification. '''
|
||||
''' Models: User profile and Authorization. '''
|
||||
|
||||
# Note: using User import to isolate original
|
||||
# pylint: disable=unused-import,ungrouped-imports
|
||||
|
|
|
@ -23,6 +23,7 @@ def _get_secret(key: str, default):
|
|||
return f.read()
|
||||
return value
|
||||
|
||||
|
||||
_TRUE_VARIANTS = [True, 'True', '1']
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
|
|
Loading…
Reference in New Issue
Block a user