StrictDoc Documentation
strictdoc/features/project_index/view_object.py
Source file coverage
Path:
strictdoc/features/project_index/view_object.py
Lines:
126
Non-empty lines:
105
Non-empty lines covered with requirements:
105 / 105 (100.0%)
Functions:
14
Functions covered by requirements:
14 / 14 (100.0%)
1
"""
2
@relation(SDOC-SRS-53, scope=file)
3
"""
4
 
5
import os
6
from dataclasses import dataclass
7
from typing import Tuple, Union
8
 
9
from markupsafe import Markup
10
 
11
from strictdoc import __version__
12
from strictdoc.backend.sdoc.models.anchor import Anchor
13
from strictdoc.backend.sdoc.models.document import SDocDocument
14
from strictdoc.backend.sdoc.models.node import SDocNode
15
from strictdoc.core.document_tree import DocumentTree
16
from strictdoc.core.document_tree_iterator import DocumentTreeIterator
17
from strictdoc.core.file_system.file_tree import File, Folder
18
from strictdoc.core.project_config import ProjectConfig
19
from strictdoc.core.traceability_index import TraceabilityIndex
20
from strictdoc.export.html.generators.view_objects.helpers import (
21
    screen_should_display_file,
22
    screen_should_display_folder,
23
)
24
from strictdoc.export.html.html_templates import JinjaEnvironment
25
from strictdoc.export.html.renderers.link_renderer import LinkRenderer
26
from strictdoc.helpers.cast import assert_cast
27
 
28
 
29
@dataclass
30
class ProjectTreeViewObject:
31
    def __init__(
32
        self,
33
        *,
34
        traceability_index: TraceabilityIndex,
35
        project_config: ProjectConfig,
36
    ):
37
        self.traceability_index: TraceabilityIndex = traceability_index
38
        self.project_config: ProjectConfig = project_config
39
 
40
        link_renderer = LinkRenderer(
41
            root_path="", static_path=project_config.dir_for_sdoc_assets
42
        )
43
        self.link_renderer: LinkRenderer = link_renderer
44
 
45
        self.document_tree_iterator: DocumentTreeIterator = (
46
            DocumentTreeIterator(
47
                assert_cast(traceability_index.document_tree, DocumentTree)
48
            )
49
        )
50
        self.is_running_on_server: bool = project_config.is_running_on_server
51
        self.strictdoc_version = __version__
52
        self.contains_included_documents = (
53
            traceability_index.contains_included_documents
54
        )
55
 
56
    def render_local_anchor(
57
        self, node: Union[Anchor, SDocNode, SDocDocument]
58
    ) -> str:
59
        return self.link_renderer.render_local_anchor(node)
60
 
61
    def render_screen(self, jinja_environment: JinjaEnvironment) -> Markup:
62
        return jinja_environment.render_template_as_markup(
63
            "features/project_index/index.jinja", view_object=self
64
        )
65
 
66
    def render_map(self, jinja_environment: JinjaEnvironment) -> Markup:
67
        return jinja_environment.render_template_as_markup(
68
            "features/project_index/project_map.jinja.js", view_object=self
69
        )
70
 
71
    def render_static_url(self, url: str) -> str:
72
        return self.link_renderer.render_static_url(url)
73
 
74
    def render_url(self, url: str) -> str:
75
        return self.link_renderer.render_url(url)
76
 
77
    def render_static_url_with_prefix(self, url: str) -> str:
78
        return self.link_renderer.render_static_url_with_prefix(url)
79
 
80
    def is_empty_tree(self) -> bool:
81
        return self.document_tree_iterator.is_empty_tree()
82
 
83
    def get_document_level(self) -> int:
84
        return 0
85
 
86
    def split_path_for_display(self, path: str) -> Tuple[str, str]:
87
        """
88
        Split an absolute path into an (external_prefix, remainder) pair,
89
        so that the UI can hide the external_prefix (e.g. behind a
90
        click-to-reveal "…") from screen recordings/screenshots.
91
 
92
        If the path is inside the project root's parent directory, the
93
        remainder keeps everything from the project root directory name
94
        onward (e.g. "/strictdoc/some/src"). Otherwise the path lies
95
        outside the project entirely, and only its last path segment is
96
        kept in the remainder (e.g. remainder="/src" for
97
        path="/opt/external-libs/src").
98
        """
99
        project_root_path = self.project_config.get_project_root_path()
100
        external_prefix = os.path.dirname(project_root_path)
101
        if external_prefix and path.startswith(external_prefix):
102
            return external_prefix, path[len(external_prefix) :]
103
 
104
        fallback_prefix = os.path.dirname(path)
105
        if fallback_prefix and fallback_prefix != path:
106
            return fallback_prefix, path[len(fallback_prefix) :]
107
        return "", path
108
 
109
    def should_display_fragments_toggle(self) -> bool:
110
        return self.project_config.export_included_documents
111
 
112
    def should_display_folder(self, folder: Folder) -> bool:
113
        return screen_should_display_folder(
114
            folder,
115
            self.traceability_index,
116
            self.project_config,
117
            must_only_include_non_included_sdoc=False,
118
        )
119
 
120
    def should_display_file(self, file: File) -> bool:
121
        return screen_should_display_file(
122
            file,
123
            self.traceability_index,
124
            self.project_config,
125
            must_only_include_non_included_sdoc=False,
126
        )