hlsv 1.0.0
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE +676 -0
- data/README.md +356 -0
- data/bin/hlsv +4 -0
- data/config.default.yaml +19 -0
- data/lib/hlsv/cli.rb +85 -0
- data/lib/hlsv/find_keys.rb +979 -0
- data/lib/hlsv/html2word.rb +602 -0
- data/lib/hlsv/mon_script.rb +169 -0
- data/lib/hlsv/version.rb +5 -0
- data/lib/hlsv/web_app.rb +569 -0
- data/lib/hlsv/xpt/dataset.rb +38 -0
- data/lib/hlsv/xpt/library.rb +28 -0
- data/lib/hlsv/xpt/reader.rb +367 -0
- data/lib/hlsv/xpt/variable.rb +130 -0
- data/lib/hlsv/xpt.rb +11 -0
- data/lib/hlsv.rb +49 -0
- data/public/Contact-LOGO.png +0 -0
- data/public/app.js +569 -0
- data/public/styles.css +586 -0
- data/public/styles_csv.css +448 -0
- data/views/csv_view.erb +85 -0
- data/views/index.erb +233 -0
- data/views/report_template.erb +1144 -0
- metadata +176 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Copyright (c) 2026 AdClin
|
|
2
|
+
# Licensed under the GNU Affero General Public License v3.0 or later.
|
|
3
|
+
# See the LICENSE file for details.
|
|
4
|
+
|
|
5
|
+
# mon_script.rb
|
|
6
|
+
# Orchestration layer between the web interface (app.rb) and the analysis engine (find_keys.rb)
|
|
7
|
+
require_relative 'find_keys'
|
|
8
|
+
|
|
9
|
+
module Hlsv
|
|
10
|
+
module MonScript
|
|
11
|
+
# Execute the complete analysis workflow
|
|
12
|
+
# @param config [Hash] Configuration parameters from the web interface
|
|
13
|
+
# @return [Hash] Detailed execution results including steps, files, and statistics
|
|
14
|
+
def self.executer(config)
|
|
15
|
+
steps = []
|
|
16
|
+
temp_config = 'temp_config.yaml'
|
|
17
|
+
|
|
18
|
+
begin
|
|
19
|
+
# ========================================
|
|
20
|
+
# STEP 1: Configuration Validation
|
|
21
|
+
# ========================================
|
|
22
|
+
steps << {
|
|
23
|
+
etape: 1,
|
|
24
|
+
nom: "Configuration validation",
|
|
25
|
+
statut: "en_cours"
|
|
26
|
+
}
|
|
27
|
+
puts "=" * 60
|
|
28
|
+
puts "Step 1/3: Configuration validation"
|
|
29
|
+
|
|
30
|
+
# Prepare configuration for FindKeys
|
|
31
|
+
# Prefix study_name with "hlsv_results/" to create folders in hlsv_results/ directory
|
|
32
|
+
config_with_results = config.dup
|
|
33
|
+
original_study_name = config['study_name']
|
|
34
|
+
config_with_results['study_name'] = "hlsv_results/#{original_study_name}"
|
|
35
|
+
|
|
36
|
+
# Create temporary config file for FindKeys
|
|
37
|
+
File.write(temp_config, config_with_results.to_yaml)
|
|
38
|
+
|
|
39
|
+
# Initialize FindKeys with the configuration
|
|
40
|
+
fk = FindKeys.new(temp_config, verbose: false)
|
|
41
|
+
|
|
42
|
+
# Enable web mode for report generation
|
|
43
|
+
fk.report.instance_variable_set(:@web_mode, true)
|
|
44
|
+
|
|
45
|
+
steps[0][:statut] = "termine"
|
|
46
|
+
steps[0][:message] = "Configuration validated successfully"
|
|
47
|
+
|
|
48
|
+
# ========================================
|
|
49
|
+
# STEP 2: Analysis Execution
|
|
50
|
+
# ========================================
|
|
51
|
+
steps << {
|
|
52
|
+
etape: 2,
|
|
53
|
+
nom: "Analysis execution",
|
|
54
|
+
statut: "en_cours"
|
|
55
|
+
}
|
|
56
|
+
puts "Step 2/3: Analysis execution"
|
|
57
|
+
|
|
58
|
+
# Execute high-level check on all datasets
|
|
59
|
+
fk.high_level_check
|
|
60
|
+
|
|
61
|
+
steps[1][:statut] = "termine"
|
|
62
|
+
steps[1][:message] = "Analysis completed successfully"
|
|
63
|
+
|
|
64
|
+
# ========================================
|
|
65
|
+
# STEP 3: Report Generation
|
|
66
|
+
# ========================================
|
|
67
|
+
steps << {
|
|
68
|
+
etape: 3,
|
|
69
|
+
nom: "Report generation",
|
|
70
|
+
statut: "en_cours"
|
|
71
|
+
}
|
|
72
|
+
puts "Step 3/3: Report generation"
|
|
73
|
+
|
|
74
|
+
# Generate HTML report
|
|
75
|
+
fk.write_html_report
|
|
76
|
+
|
|
77
|
+
steps[2][:statut] = "termine"
|
|
78
|
+
steps[2][:message] = "Report generated successfully"
|
|
79
|
+
|
|
80
|
+
# ========================================
|
|
81
|
+
# Post-Processing: Move Config File
|
|
82
|
+
# ========================================
|
|
83
|
+
# Move the temp config file to the study directory for reference
|
|
84
|
+
config_destination = "hlsv_results/#{config['study_name']}/config.yaml"
|
|
85
|
+
if File.exist?(temp_config)
|
|
86
|
+
FileUtils.mv(temp_config, config_destination)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
puts "All steps completed successfully"
|
|
90
|
+
puts "=" * 60
|
|
91
|
+
|
|
92
|
+
# ========================================
|
|
93
|
+
# Return Detailed Results
|
|
94
|
+
# ========================================
|
|
95
|
+
build_result_summary(
|
|
96
|
+
fk: fk,
|
|
97
|
+
steps: steps,
|
|
98
|
+
original_study_name: original_study_name
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
rescue => e
|
|
102
|
+
# ========================================
|
|
103
|
+
# Error Handling
|
|
104
|
+
# ========================================
|
|
105
|
+
handle_execution_error(
|
|
106
|
+
error: e,
|
|
107
|
+
steps: steps,
|
|
108
|
+
temp_config: temp_config
|
|
109
|
+
)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
private
|
|
114
|
+
|
|
115
|
+
# Build a comprehensive result summary
|
|
116
|
+
# @param fk [FindKeys] FindKeys instance with analysis results
|
|
117
|
+
# @param steps [Array<Hash>] Execution steps with their status
|
|
118
|
+
# @param original_study_name [String] Original study name without 'hlsv_results/' prefix
|
|
119
|
+
# @return [Hash] Complete result summary
|
|
120
|
+
def self.build_result_summary(fk:, steps:, original_study_name:)
|
|
121
|
+
{
|
|
122
|
+
message: "Analysis completed successfully",
|
|
123
|
+
etapes: steps,
|
|
124
|
+
|
|
125
|
+
# Report information
|
|
126
|
+
rapport_path: "/telecharger/#{original_study_name}/#{File.basename(fk.report.report_name)}",
|
|
127
|
+
rapport_name: File.basename(fk.report.report_name),
|
|
128
|
+
|
|
129
|
+
# Output directory (without 'hlsv_results/' prefix for display)
|
|
130
|
+
output_directory: fk.dir_out.split('/')[1..].join('/'),
|
|
131
|
+
|
|
132
|
+
# Dataset statistics
|
|
133
|
+
nombre_datasets_analyses: fk.ds_list.size,
|
|
134
|
+
|
|
135
|
+
# Invalid datasets breakdown
|
|
136
|
+
nombre_datasets_invalid: {
|
|
137
|
+
invalid_dataset: fk.dslist_invalid.size,
|
|
138
|
+
invalid_ascii: fk.ds_with_issue[:ascii].empty? ? nil : fk.ds_with_issue[:ascii].join(', '),
|
|
139
|
+
invalid_define: fk.ds_with_issue[:define].empty? ? nil : fk.ds_with_issue[:define].join(', '),
|
|
140
|
+
invalid_data: fk.ds_with_issue[:data].empty? ? nil : fk.ds_with_issue[:data].join(', ')
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Handle execution errors gracefully
|
|
146
|
+
# @param error [Exception] The raised exception
|
|
147
|
+
# @param steps [Array<Hash>] Execution steps
|
|
148
|
+
# @param temp_config [String] Path to temporary config file
|
|
149
|
+
def self.handle_execution_error(error:, steps:, temp_config:)
|
|
150
|
+
# Mark the current step as failed
|
|
151
|
+
current_step = steps.find { |st| st[:statut] == "en_cours" }
|
|
152
|
+
if current_step
|
|
153
|
+
current_step[:statut] = "erreur"
|
|
154
|
+
current_step[:message] = error.message
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Clean up temporary config file
|
|
158
|
+
File.delete(temp_config) if File.exist?(temp_config)
|
|
159
|
+
|
|
160
|
+
# Build detailed error message
|
|
161
|
+
error_details = steps.map { |st|
|
|
162
|
+
"#{st[:nom]}: #{st[:statut]}"
|
|
163
|
+
}.join("\n")
|
|
164
|
+
|
|
165
|
+
# Re-raise with enhanced context
|
|
166
|
+
raise "#{error.message}\n\nExecution steps:\n#{error_details}"
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|