• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SPF-OST / pytrnsys_gui / 11482354319

23 Oct 2024 02:43PM UTC coverage: 67.591% (+0.7%) from 66.906%
11482354319

push

github

web-flow
Merge pull request #554 from SPF-OST/548-open-recent-projects

expanded on open recent functionality

144 of 197 new or added lines in 8 files covered. (73.1%)

5 existing lines in 2 files now uncovered.

10413 of 15406 relevant lines covered (67.59%)

0.68 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

55.43
/trnsysGUI/project.py
1
__all__ = [
1✔
2
    "CreateProject",
3
    "LoadProject",
4
    "MigrateProject",
5
    "Project",
6
    "getProject",
7
    "getExistingEmptyDirectory",
8
    "getLoadOrMigrateProject",
9
]
10

11
import dataclasses as _dc
1✔
12
import pathlib as _pl
1✔
13
import typing as _tp
1✔
14

15
import PyQt5.QtWidgets as _qtw
1✔
16

17
import trnsysGUI.common.cancelled as _ccl
1✔
18
import trnsysGUI.messageBox as mb
1✔
19
from trnsysGUI import constants
1✔
20
from trnsysGUI.dialogs.startupDialog import StartupDialog
1✔
21
from trnsysGUI.recentProjectsHandler import RecentProjectsHandler
1✔
22

23

24
@_dc.dataclass
1✔
25
class CreateProject:
1✔
26
    jsonFilePath: _pl.Path
1✔
27

28

29
@_dc.dataclass
1✔
30
class LoadProject:
1✔
31
    jsonFilePath: _pl.Path
1✔
32

33

34
@_dc.dataclass
1✔
35
class MigrateProject:
1✔
36
    oldJsonFilePath: _pl.Path
1✔
37
    newProjectFolderPath: _pl.Path
1✔
38

39

40
Project = CreateProject | LoadProject | MigrateProject
1✔
41

42

43
def getProject() -> _ccl.MaybeCancelled[Project]:
1✔
44
    createOpenMaybeCancelled = StartupDialog.showDialogAndGetResult()
1✔
45

46
    while not _ccl.isCancelled(createOpenMaybeCancelled):
1✔
47
        createOpen = _ccl.value(createOpenMaybeCancelled)
1✔
48

49
        projectMaybeCancelled = (
1✔
50
            loadRecentProject(createOpen)
51
            if isinstance(createOpen, _pl.Path)
52
            else _getProjectInternal(constants.CreateNewOrOpenExisting(createOpen))
53
        )
54
        if not _ccl.isCancelled(projectMaybeCancelled):
1✔
55
            project = _ccl.value(projectMaybeCancelled)
1✔
56
            assert isinstance(project, (CreateProject, LoadProject))
1✔
57
            RecentProjectsHandler.addProject(project.jsonFilePath)
1✔
58
            return _tp.cast(Project, project)  # Don't know why mypy requires this cast
1✔
59

NEW
60
        createOpenMaybeCancelled = StartupDialog.showDialogAndGetResult()
×
61

62
    return _ccl.CANCELLED
×
63

64

65
def _getProjectInternal(createOrOpenExisting: "constants.CreateNewOrOpenExisting") -> _ccl.MaybeCancelled[Project]:
1✔
NEW
66
    if createOrOpenExisting == constants.CreateNewOrOpenExisting.OPEN_EXISTING:
×
UNCOV
67
        return getLoadOrMigrateProject()
×
68

NEW
69
    if createOrOpenExisting == constants.CreateNewOrOpenExisting.CREATE_NEW:
×
70
        return getCreateProject()
×
71

NEW
72
    raise AssertionError(f"Unknown value for enum {constants.CreateNewOrOpenExisting}: {createOrOpenExisting}")
×
73

74

75
def getCreateProject(startingDirectoryPath: _tp.Optional[_pl.Path] = None) -> _ccl.MaybeCancelled[CreateProject]:
1✔
76
    projectFolderPathMaybeCancelled = getExistingEmptyDirectory(startingDirectoryPath)
×
77
    if _ccl.isCancelled(projectFolderPathMaybeCancelled):
×
78
        return _ccl.CANCELLED
×
79
    projectFolderPath = _ccl.value(projectFolderPathMaybeCancelled)
×
80

81
    jsonFilePath = projectFolderPath / f"{projectFolderPath.name}.json"
×
82

83
    return CreateProject(jsonFilePath)
×
84

85

86
def getExistingEmptyDirectory(
1✔
87
    startingDirectoryPath: _tp.Optional[_pl.Path] = None,
88
) -> _ccl.MaybeCancelled[_pl.Path]:
89
    while True:
×
90
        selectedDirectoryPathString = _qtw.QFileDialog.getExistingDirectory(
×
91
            caption="Select new project directory", directory=str(startingDirectoryPath)
92
        )
93
        if not selectedDirectoryPathString:
×
94
            return _ccl.CANCELLED
×
95

96
        selectedDirectoryPath = _pl.Path(selectedDirectoryPathString)
×
97

98
        if _isEmptyDirectory(selectedDirectoryPath):
×
99
            return selectedDirectoryPath
×
100

NEW
101
        mb.MessageBox.create(messageText=constants.DIRECTORY_MUST_BE_EMPTY, buttons=[_qtw.QMessageBox.Ok])
×
102

103

104
def _isEmptyDirectory(path: _pl.Path) -> bool:
1✔
105
    if not path.is_dir():
×
106
        return False
×
107
    containedFilesAndDirectories = list(path.iterdir())
×
108
    isDirectoryEmpty = len(containedFilesAndDirectories) == 0
×
109
    return isDirectoryEmpty
×
110

111

112
def getLoadOrMigrateProject() -> _ccl.MaybeCancelled[LoadProject | MigrateProject]:
1✔
113
    projectFolderPathString, _ = _qtw.QFileDialog.getOpenFileName(caption="Open diagram", filter="*.json")
×
114
    if not projectFolderPathString:
×
115
        return _ccl.CANCELLED
×
116
    jsonFilePath = _pl.Path(projectFolderPathString)
×
117
    projectFolderPath = jsonFilePath.parent
×
118
    return checkIfProjectEnviromentIsValid(projectFolderPath, jsonFilePath)
×
119

120

121
def loadRecentProject(projectPath: _pl.Path) -> _ccl.MaybeCancelled[LoadProject | MigrateProject]:
1✔
122
    try:
1✔
123
        if not projectPath.exists():
1✔
NEW
124
            if (
×
125
                mb.MessageBox.create(messageText=constants.RECENT_MOVED_OR_DELETED, buttons=[_qtw.QMessageBox.Ok])
126
                == _qtw.QMessageBox.Ok
127
            ):
NEW
128
                RecentProjectsHandler.removeProject(projectPath)
×
UNCOV
129
                return _ccl.CANCELLED
×
130
        else:
131
            return checkIfProjectEnviromentIsValid(projectPath.parent, projectPath)
1✔
132
    except TypeError:
×
NEW
133
        if (
×
134
            mb.MessageBox.create(messageText=constants.NO_RECENT_AVAILABLE, buttons=[_qtw.QMessageBox.Ok])
135
            == _qtw.QMessageBox.Ok
136
        ):
137
            return _ccl.CANCELLED
×
138
    return _ccl.CANCELLED
×
139

140

141
def checkIfProjectEnviromentIsValid(
1✔
142
    projectFolderPath, jsonFilePath
143
) -> _ccl.MaybeCancelled[LoadProject | MigrateProject]:
144
    containingFolderIsCalledSameAsJsonFile = projectFolderPath.name == jsonFilePath.stem
1✔
145
    ddckFolder = projectFolderPath / "ddck"
1✔
146
    if not containingFolderIsCalledSameAsJsonFile or not ddckFolder.is_dir():
1✔
147
        oldJsonFilePath = jsonFilePath
1✔
148
        if mb.MessageBox.create(messageText=constants.NO_PROPER_PROJECT_ENVIRONMENT) == _qtw.QMessageBox.Cancel:
1✔
149
            return _ccl.CANCELLED
×
150
        maybeCancelled = getExistingEmptyDirectory(startingDirectoryPath=projectFolderPath.parent)
1✔
151
        if _ccl.isCancelled(maybeCancelled):
1✔
152
            return _ccl.CANCELLED
×
153
        newProjectFolderPath = _ccl.value(maybeCancelled)
1✔
154
        return MigrateProject(oldJsonFilePath, newProjectFolderPath)
1✔
155
    return LoadProject(jsonFilePath)
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc