Coverage for middle_layer/closeout/application_layer/services/export_projects.py: 32.61%

46 statements  

« prev     ^ index     » next       coverage.py v7.10.5, created at 2026-03-09 06:13 +0000

1# Copyright 2024 Associated Universities, Inc. 

2# 

3# This file is part of Telescope Time Allocation Tools (TTAT). 

4# 

5# TTAT is free software: you can redistribute it and/or modify 

6# it under the terms of the GNU General Public License as published by 

7# the Free Software Foundation, either version 3 of the License, or 

8# any later version. 

9# 

10# TTAT is distributed in the hope that it will be useful, 

11# but WITHOUT ANY WARRANTY; without even the implied warranty of 

12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

13# GNU General Public License for more details. 

14# 

15# You should have received a copy of the GNU General Public License 

16# along with TTAT. If not, see <https://www.gnu.org/licenses/>. 

17 

18import logging 

19from collections import defaultdict 

20from datetime import datetime 

21from typing import Callable 

22 

23from closeout.domain_layer.entities.prototype_project import PrototypeProject 

24 

25ExportProjectFunction = Callable[[PrototypeProject], None] 

26 

27 

28def gbt_export(project: PrototypeProject) -> bool: 

29 """Export a project for the GBT facility""" 

30 logging.info(f"Running GBT export for project {project.prototype_project_id}") 

31 return True 

32 

33 

34def vla_export(project: PrototypeProject) -> bool: 

35 """Export a project for the VLA facility""" 

36 logging.info(f"Running VLA export for project {project.prototype_project_id}") 

37 return True 

38 

39 

40def vlba_export(project: PrototypeProject) -> bool: 

41 """Export a project for the VLBA facility""" 

42 logging.info(f"Running VLBA export for project {project.prototype_project_id}") 

43 return True 

44 

45 

46def unknown_facility_export(project: PrototypeProject) -> bool: 

47 """Default export handler for unknown facilities""" 

48 logging.info(f"Running export for unknown facility project {project.prototype_project_id}") 

49 return False 

50 

51 

52# Registry of facility-specific export functions 

53FACILITY_EXPORTS: defaultdict[str, ExportProjectFunction] = defaultdict( 

54 lambda: unknown_facility_export, GBT=gbt_export, VLA=vla_export, VLBA=vlba_export 

55) 

56 

57 

58def validate_source(project: PrototypeProject) -> bool: 

59 """Validate that all sources in the project are properly defined 

60 

61 :param project: The project containing sources to validate 

62 :return: True if all sources are valid, False otherwise 

63 """ 

64 logging.info(f"Validating sources for project {project.prototype_project_id}") 

65 return True 

66 

67 

68def validate_resource(project: PrototypeProject) -> bool: 

69 """Validate that all resources required by the project are available 

70 

71 :param project: The project with resources to validate 

72 :return: True if all resources are valid, False otherwise 

73 """ 

74 logging.info(f"Validating resources for project {project.prototype_project_id}") 

75 return True 

76 

77 

78def validate_project(project: PrototypeProject) -> bool: 

79 """Validate the overall project 

80 

81 :param project: The project to validate 

82 :return: True if the project is valid, False otherwise 

83 """ 

84 logging.info(f"Validating project {project.prototype_project_id}") 

85 return True 

86 

87 

88def export_project(project: PrototypeProject) -> tuple[bool, PrototypeProject]: 

89 """Export a project after validating sources, resources, and project structure 

90 

91 :param project: PrototypeProject to export 

92 :return: Tuple containing (success_flag, updated_project) 

93 where success_flag is True if export was successful 

94 """ 

95 

96 # Execute validation steps in sequence 

97 if not validate_source(project): 

98 logging.warning(f"Source validation failed for project {project.prototype_project_id}") 

99 return False, project 

100 

101 if not validate_resource(project): 

102 logging.warning(f"Resource validation failed for project {project.prototype_project_id}") 

103 return False, project 

104 

105 if not validate_project(project): 

106 logging.warning(f"Project validation failed for project {project.prototype_project_id}") 

107 return False, project 

108 

109 # Get facility name or use "UNKNOWN" if not available 

110 facility_name = project.facility.facility_name if project.facility else "UNKNOWN" 

111 

112 # Execute the appropriate facility-specific export function 

113 result = FACILITY_EXPORTS[facility_name](project) 

114 

115 if result: 

116 # Update exported timestamp on success 

117 project.exported_at = datetime.now() 

118 project.report = project.generate_report() # persist the report as it is now 

119 logging.info(f"Successfully exported project {project.prototype_project_id} for {facility_name}") 

120 else: 

121 logging.error(f"Failed to export project {project.prototype_project_id} for {facility_name}") 

122 

123 return result, project