medicafe 0.240809.0__py3-none-any.whl → 0.240925.9__py3-none-any.whl
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.
Potentially problematic release.
This version of medicafe might be problematic. Click here for more details.
- MediBot/MediBot.bat +56 -16
- MediBot/MediBot.py +90 -79
- MediBot/MediBot_Crosswalk_Library.py +496 -194
- MediBot/MediBot_Preprocessor.py +22 -14
- MediBot/MediBot_Preprocessor_lib.py +299 -153
- MediBot/MediBot_UI.py +25 -24
- MediBot/MediBot_dataformat_library.py +17 -25
- MediBot/MediBot_docx_decoder.py +267 -110
- MediBot/update_json.py +26 -1
- MediBot/update_medicafe.py +134 -44
- MediLink/MediLink.py +93 -51
- MediLink/MediLink_837p_encoder.py +23 -23
- MediLink/MediLink_837p_encoder_library.py +141 -96
- MediLink/MediLink_API_Generator.py +1 -7
- MediLink/MediLink_API_v3.py +240 -59
- MediLink/MediLink_APIs.py +1 -2
- MediLink/MediLink_ClaimStatus.py +21 -6
- MediLink/MediLink_ConfigLoader.py +8 -8
- MediLink/MediLink_DataMgmt.py +321 -100
- MediLink/MediLink_Decoder.py +249 -87
- MediLink/MediLink_Deductible.py +7 -8
- MediLink/MediLink_Down.py +115 -120
- MediLink/MediLink_Gmail.py +2 -11
- MediLink/MediLink_Parser.py +63 -36
- MediLink/MediLink_UI.py +29 -24
- MediLink/MediLink_Up.py +12 -8
- {medicafe-0.240809.0.dist-info → medicafe-0.240925.9.dist-info}/METADATA +1 -1
- medicafe-0.240925.9.dist-info/RECORD +47 -0
- {medicafe-0.240809.0.dist-info → medicafe-0.240925.9.dist-info}/WHEEL +1 -1
- medicafe-0.240809.0.dist-info/RECORD +0 -47
- {medicafe-0.240809.0.dist-info → medicafe-0.240925.9.dist-info}/LICENSE +0 -0
- {medicafe-0.240809.0.dist-info → medicafe-0.240925.9.dist-info}/top_level.txt +0 -0
MediLink/MediLink_DataMgmt.py
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
import csv
|
|
3
|
-
import os
|
|
1
|
+
|
|
2
|
+
import csv, os, re, subprocess, time
|
|
4
3
|
from datetime import datetime, timedelta
|
|
5
|
-
import re
|
|
6
|
-
import subprocess
|
|
7
4
|
|
|
8
5
|
# Need this for running Medibot and MediLink
|
|
9
6
|
try:
|
|
@@ -167,64 +164,170 @@ def consolidate_csvs(source_directory, file_prefix="Consolidated", interactive=F
|
|
|
167
164
|
def operate_winscp(operation_type, files, endpoint_config, local_storage_path, config):
|
|
168
165
|
"""
|
|
169
166
|
General function to operate WinSCP for uploading or downloading files.
|
|
167
|
+
"""
|
|
168
|
+
MediLink_ConfigLoader.log("Starting operate_winscp with operation_type: {}".format(operation_type))
|
|
169
|
+
|
|
170
|
+
config = ensure_config_loaded(config)
|
|
171
|
+
winscp_path = get_winscp_path(config)
|
|
172
|
+
|
|
173
|
+
if not os.path.isfile(winscp_path):
|
|
174
|
+
MediLink_ConfigLoader.log("WinSCP.com not found at {}".format(winscp_path), level="ERROR")
|
|
175
|
+
return []
|
|
170
176
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
:param endpoint_config: Dictionary containing endpoint configuration.
|
|
174
|
-
:param local_storage_path: Base local storage path for logs and files.
|
|
177
|
+
validate_endpoint_config(endpoint_config)
|
|
178
|
+
winscp_log_path = setup_logging(operation_type, local_storage_path)
|
|
175
179
|
|
|
176
|
-
#
|
|
177
|
-
|
|
178
|
-
upload_config = {
|
|
179
|
-
'session_name': 'MySession',
|
|
180
|
-
'remote_directory_up': '/remote/upload/path'
|
|
181
|
-
}
|
|
180
|
+
# Validate the local_storage_path and replace it if necessary
|
|
181
|
+
local_storage_path = validate_local_storage_path(local_storage_path, config)
|
|
182
182
|
|
|
183
|
-
|
|
183
|
+
remote_directory = get_remote_directory(endpoint_config, operation_type)
|
|
184
|
+
command = build_command(winscp_path, winscp_log_path, endpoint_config, remote_directory, operation_type, files, local_storage_path)
|
|
184
185
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
186
|
+
if config.get("TestMode", True):
|
|
187
|
+
MediLink_ConfigLoader.log("Test mode is enabled. Simulating operation.")
|
|
188
|
+
return simulate_operation(operation_type, files, config)
|
|
189
|
+
|
|
190
|
+
result = execute_winscp_command(command, operation_type, files, local_storage_path)
|
|
191
|
+
MediLink_ConfigLoader.log("[Execute WinSCP Command] Result: {}".format(result), level="DEBUG")
|
|
192
|
+
return result
|
|
190
193
|
|
|
191
|
-
|
|
194
|
+
def validate_local_storage_path(local_storage_path, config):
|
|
192
195
|
"""
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
196
|
+
Validates the local storage path and replaces it with outputFilePath from config if it contains spaces.
|
|
197
|
+
"""
|
|
198
|
+
if ' ' in local_storage_path:
|
|
199
|
+
MediLink_ConfigLoader.log("Local storage path contains spaces, using outputFilePath from config.", level="WARN")
|
|
200
|
+
output_file_path = config.get('outputFilePath', None)
|
|
201
|
+
if not output_file_path:
|
|
202
|
+
raise ValueError("outputFilePath not found in config.")
|
|
203
|
+
return os.path.normpath(output_file_path)
|
|
204
|
+
return os.path.normpath(local_storage_path)
|
|
205
|
+
|
|
206
|
+
def ensure_config_loaded(config):
|
|
207
|
+
MediLink_ConfigLoader.log("Ensuring configuration is loaded.")
|
|
208
|
+
if not config:
|
|
209
|
+
MediLink_ConfigLoader.log("Warning: No config passed to ensure_config_loaded. Re-loading config...")
|
|
210
|
+
config, _ = MediLink_ConfigLoader.load_configuration()
|
|
211
|
+
|
|
212
|
+
# Check if config was successfully loaded
|
|
213
|
+
if not config or 'MediLink_Config' not in config:
|
|
214
|
+
MediLink_ConfigLoader.log("Failed to load the MediLink configuration. Config is None or missing 'MediLink_Config'.")
|
|
215
|
+
raise RuntimeError("Failed to load the MediLink configuration. Config is None or missing 'MediLink_Config'.")
|
|
216
|
+
|
|
217
|
+
# Check that 'endpoints' key exists within 'MediLink_Config'
|
|
218
|
+
if 'endpoints' not in config['MediLink_Config']:
|
|
219
|
+
MediLink_ConfigLoader.log("The loaded configuration is missing the 'endpoints' section.")
|
|
220
|
+
raise ValueError("The loaded configuration is missing the 'endpoints' section.")
|
|
221
|
+
|
|
222
|
+
# Additional checks can be added here to ensure all expected keys and structures are present
|
|
223
|
+
if 'local_storage_path' not in config['MediLink_Config']:
|
|
224
|
+
MediLink_ConfigLoader.log("The loaded configuration is missing the 'local_storage_path' setting.")
|
|
225
|
+
raise ValueError("The loaded configuration is missing the 'local_storage_path' setting.")
|
|
226
|
+
|
|
227
|
+
MediLink_ConfigLoader.log("Configuration loaded successfully.")
|
|
228
|
+
return config['MediLink_Config'] # Return the relevant part of the config for simplicity
|
|
229
|
+
|
|
230
|
+
def get_winscp_path(config):
|
|
231
|
+
MediLink_ConfigLoader.log("Retrieving WinSCP path from provided config.")
|
|
232
|
+
|
|
233
|
+
def find_winscp_path(cfg):
|
|
234
|
+
if 'winscp_path' in cfg:
|
|
235
|
+
# cfg is already 'MediLink_Config'
|
|
236
|
+
MediLink_ConfigLoader.log("Config provided directly as 'MediLink_Config'.")
|
|
237
|
+
return cfg.get('winscp_path')
|
|
238
|
+
else:
|
|
239
|
+
# cfg is the full configuration, retrieve 'MediLink_Config'
|
|
240
|
+
MediLink_ConfigLoader.log("Config provided as full configuration; accessing 'MediLink_Config'.")
|
|
241
|
+
medi_link_config = cfg.get('MediLink_Config', {})
|
|
242
|
+
return medi_link_config.get('winscp_path')
|
|
243
|
+
|
|
244
|
+
# Attempt to find the WinSCP path using the provided config
|
|
245
|
+
winscp_path = find_winscp_path(config)
|
|
246
|
+
|
|
247
|
+
# If the path is not found, attempt to use default paths
|
|
248
|
+
if not winscp_path:
|
|
249
|
+
error_message = "WinSCP path not found in config. Attempting to use default paths."
|
|
250
|
+
# print(error_message)
|
|
251
|
+
MediLink_ConfigLoader.log(error_message)
|
|
203
252
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
253
|
+
# Try the default paths
|
|
254
|
+
default_paths = [
|
|
255
|
+
os.path.join(os.getcwd(), "Installers", "WinSCP-Portable", "WinSCP.com"),
|
|
256
|
+
os.path.join(os.getcwd(), "Necessary Programs", "WinSCP-Portable", "WinSCP.com")
|
|
257
|
+
]
|
|
258
|
+
|
|
259
|
+
for path in default_paths:
|
|
260
|
+
if os.path.exists(path):
|
|
261
|
+
found_message = "WinSCP found at {}. Using this path.".format(path)
|
|
262
|
+
# print(found_message)
|
|
263
|
+
MediLink_ConfigLoader.log(found_message)
|
|
264
|
+
return path
|
|
265
|
+
|
|
266
|
+
# If no valid path is found, attempt to reload the configuration
|
|
267
|
+
reload_message = "WinSCP not found in config or default paths. Reloading the entire configuration."
|
|
268
|
+
# print(reload_message)
|
|
269
|
+
MediLink_ConfigLoader.log(reload_message)
|
|
270
|
+
|
|
271
|
+
try:
|
|
272
|
+
config, _ = MediLink_ConfigLoader.load_configuration()
|
|
273
|
+
winscp_path = find_winscp_path(config)
|
|
274
|
+
|
|
275
|
+
if winscp_path:
|
|
276
|
+
success_message = "WinSCP path found after reloading configuration. Using this path."
|
|
277
|
+
# print(success_message)
|
|
278
|
+
MediLink_ConfigLoader.log(success_message)
|
|
279
|
+
return winscp_path
|
|
280
|
+
else:
|
|
281
|
+
raise FileNotFoundError("WinSCP path not found even after reloading configuration.")
|
|
282
|
+
|
|
283
|
+
except Exception as e:
|
|
284
|
+
error_message = "Failed to reload configuration or find WinSCP path: {}. Exiting script.".format(e)
|
|
285
|
+
print(error_message)
|
|
286
|
+
MediLink_ConfigLoader.log(error_message)
|
|
287
|
+
raise FileNotFoundError(error_message)
|
|
288
|
+
|
|
289
|
+
return winscp_path
|
|
207
290
|
|
|
208
|
-
|
|
291
|
+
def validate_endpoint_config(endpoint_config):
|
|
292
|
+
MediLink_ConfigLoader.log("Validating endpoint configuration.")
|
|
293
|
+
if not isinstance(endpoint_config, dict):
|
|
294
|
+
MediLink_ConfigLoader.log("Endpoint configuration object is invalid. Expected a dictionary, got: {}".format(type(endpoint_config)))
|
|
295
|
+
raise ValueError("Endpoint configuration object is invalid. Expected a dictionary, got: {}".format(type(endpoint_config)))
|
|
296
|
+
|
|
297
|
+
def setup_logging(operation_type, local_storage_path):
|
|
298
|
+
MediLink_ConfigLoader.log("Setting up logging for operation type: {}".format(operation_type))
|
|
209
299
|
log_filename = "winscp_upload.log" if operation_type == "upload" else "winscp_download.log"
|
|
210
|
-
|
|
300
|
+
return os.path.join(local_storage_path, log_filename)
|
|
301
|
+
|
|
302
|
+
def get_remote_directory(endpoint_config, operation_type):
|
|
303
|
+
MediLink_ConfigLoader.log("Getting remote directory for operation type: {}".format(operation_type))
|
|
304
|
+
if endpoint_config is None:
|
|
305
|
+
MediLink_ConfigLoader.log("Error: Endpoint configuration is None.")
|
|
306
|
+
raise ValueError("Endpoint configuration is None. Expected a dictionary with configuration details.")
|
|
307
|
+
|
|
308
|
+
if not isinstance(endpoint_config, dict):
|
|
309
|
+
MediLink_ConfigLoader.log("Error: Endpoint configuration is invalid. Expected a dictionary, got: {}".format(type(endpoint_config)))
|
|
310
|
+
raise TypeError("Endpoint configuration is invalid. Expected a dictionary, got: {}".format(type(endpoint_config)))
|
|
211
311
|
|
|
212
|
-
# Session and directory setup
|
|
213
312
|
try:
|
|
214
|
-
session_name = endpoint_config.get('session_name', '')
|
|
215
313
|
if operation_type == "upload":
|
|
216
|
-
|
|
314
|
+
return endpoint_config['remote_directory_up']
|
|
315
|
+
elif operation_type == "download":
|
|
316
|
+
return endpoint_config['remote_directory_down']
|
|
217
317
|
else:
|
|
218
|
-
|
|
318
|
+
MediLink_ConfigLoader.log("Invalid operation type: {}. Expected 'upload' or 'download'.".format(operation_type))
|
|
319
|
+
raise ValueError("Invalid operation type: {}. Expected 'upload' or 'download'.".format(operation_type))
|
|
219
320
|
except KeyError as e:
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
321
|
+
MediLink_ConfigLoader.log("Critical Error: Endpoint config is missing key: {}".format(e))
|
|
322
|
+
raise RuntimeError("Configuration error: Missing required remote directory in endpoint configuration.")
|
|
323
|
+
|
|
324
|
+
def build_command(winscp_path, winscp_log_path, endpoint_config, remote_directory, operation_type, files, local_storage_path, newer_than=None, filemask=None):
|
|
325
|
+
# Log the operation type
|
|
326
|
+
MediLink_ConfigLoader.log("[Build Command] Building WinSCP command for operation type: {}".format(operation_type))
|
|
327
|
+
|
|
328
|
+
session_name = endpoint_config.get('session_name', '')
|
|
329
|
+
|
|
330
|
+
# Initial command structure
|
|
228
331
|
command = [
|
|
229
332
|
winscp_path,
|
|
230
333
|
'/log=' + winscp_log_path,
|
|
@@ -235,66 +338,184 @@ def operate_winscp(operation_type, files, endpoint_config, local_storage_path, c
|
|
|
235
338
|
'cd {}'.format(remote_directory)
|
|
236
339
|
]
|
|
237
340
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
341
|
+
try:
|
|
342
|
+
# Handle upload operation
|
|
343
|
+
if operation_type == "upload":
|
|
344
|
+
if not files:
|
|
345
|
+
MediLink_ConfigLoader.log("Error: No files provided for upload operation.", level="ERROR")
|
|
346
|
+
raise ValueError("No files provided for upload operation.")
|
|
347
|
+
|
|
348
|
+
put_commands = []
|
|
349
|
+
for f in files:
|
|
350
|
+
# Normalize the path
|
|
351
|
+
normalized_path = os.path.normpath(f)
|
|
352
|
+
original_path = normalized_path # Keep for logging
|
|
353
|
+
|
|
354
|
+
# Remove leading slash if present
|
|
355
|
+
if normalized_path.startswith('\\') or normalized_path.startswith('/'):
|
|
356
|
+
normalized_path = normalized_path.lstrip('\\/')
|
|
357
|
+
MediLink_ConfigLoader.log("Removed leading slash from path: {}".format(original_path), level="DEBUG")
|
|
358
|
+
|
|
359
|
+
# Remove trailing slash if present
|
|
360
|
+
if normalized_path.endswith('\\') or normalized_path.endswith('/'):
|
|
361
|
+
normalized_path = normalized_path.rstrip('\\/')
|
|
362
|
+
MediLink_ConfigLoader.log("Removed trailing slash from path: {}".format(original_path), level="DEBUG")
|
|
363
|
+
|
|
364
|
+
# Determine if quotes are necessary (e.g., if path contains spaces)
|
|
365
|
+
if ' ' in normalized_path:
|
|
366
|
+
put_command = 'put "{}"'.format(normalized_path)
|
|
367
|
+
MediLink_ConfigLoader.log("Constructed put command with quotes: {}".format(put_command), level="DEBUG")
|
|
368
|
+
else:
|
|
369
|
+
put_command = 'put {}'.format(normalized_path)
|
|
370
|
+
MediLink_ConfigLoader.log("Constructed put command without quotes: {}".format(put_command), level="DEBUG")
|
|
371
|
+
|
|
372
|
+
put_commands.append(put_command)
|
|
373
|
+
command += put_commands
|
|
374
|
+
|
|
375
|
+
# Handle download operation
|
|
376
|
+
elif operation_type == "download":
|
|
377
|
+
lcd_path = os.path.normpath(local_storage_path)
|
|
378
|
+
original_lcd_path = lcd_path # Keep for logging
|
|
379
|
+
|
|
380
|
+
# Remove leading slash if present
|
|
381
|
+
if lcd_path.startswith('\\') or lcd_path.startswith('/'):
|
|
382
|
+
lcd_path = lcd_path.lstrip('\\/')
|
|
383
|
+
MediLink_ConfigLoader.log("Removed leading slash from local storage path: {}".format(original_lcd_path), level="DEBUG")
|
|
384
|
+
|
|
385
|
+
# Remove trailing slash if present
|
|
386
|
+
if lcd_path.endswith('\\') or lcd_path.endswith('/'):
|
|
387
|
+
lcd_path = lcd_path.rstrip('\\/')
|
|
388
|
+
MediLink_ConfigLoader.log("Removed trailing slash from local storage path: {}".format(original_lcd_path), level="DEBUG")
|
|
389
|
+
|
|
390
|
+
# Determine if quotes are necessary (e.g., if path contains spaces)
|
|
391
|
+
if ' ' in lcd_path:
|
|
392
|
+
lcd_command = 'lcd "{}"'.format(lcd_path)
|
|
393
|
+
MediLink_ConfigLoader.log("Constructed lcd command with quotes: {}".format(lcd_command), level="DEBUG")
|
|
394
|
+
else:
|
|
395
|
+
lcd_command = 'lcd {}'.format(lcd_path)
|
|
396
|
+
MediLink_ConfigLoader.log("Constructed lcd command without quotes: {}".format(lcd_command), level="DEBUG")
|
|
397
|
+
|
|
398
|
+
command.append(lcd_command)
|
|
399
|
+
|
|
400
|
+
# Handle filemask input
|
|
401
|
+
if filemask:
|
|
402
|
+
# TODO: Implement logic to translate filemask into WinSCP syntax
|
|
403
|
+
# This should handle cases where filemask is a list, JSON, dictionary, or None.
|
|
404
|
+
# Example: Convert to a string like "*.{ext1}|*.{ext2}|*.{ext3}".
|
|
405
|
+
if isinstance(filemask, list):
|
|
406
|
+
filemask_str = '|'.join(['*.' + ext for ext in filemask])
|
|
407
|
+
elif isinstance(filemask, dict):
|
|
408
|
+
filemask_str = '|'.join(['*.' + ext for ext in filemask.keys()])
|
|
409
|
+
elif isinstance(filemask, str):
|
|
410
|
+
filemask_str = filemask # Assume it's already in the correct format
|
|
265
411
|
else:
|
|
266
|
-
|
|
412
|
+
filemask_str = '*' # Default to all files if filemask is None or unsupported type
|
|
413
|
+
else:
|
|
414
|
+
filemask_str = '*' # Default to all files if filemask is None
|
|
415
|
+
|
|
416
|
+
# Use synchronize command for efficient downloading
|
|
417
|
+
if newer_than:
|
|
418
|
+
command.append('synchronize local -filemask="{}" -newerthan={}'.format(filemask_str, newer_than))
|
|
419
|
+
else:
|
|
420
|
+
command.append('synchronize local -filemask="{}"'.format(filemask_str))
|
|
421
|
+
|
|
422
|
+
# Close and exit commands
|
|
423
|
+
command += ['close', 'exit']
|
|
424
|
+
MediLink_ConfigLoader.log("[Build Command] WinSCP command: {}".format(command))
|
|
425
|
+
return command
|
|
426
|
+
|
|
427
|
+
except Exception as e:
|
|
428
|
+
MediLink_ConfigLoader.log("Error in build_command: {}. Reverting to original implementation.".format(e), level="ERROR")
|
|
429
|
+
|
|
430
|
+
# Fallback to original implementation
|
|
431
|
+
# Handle upload operation
|
|
432
|
+
if operation_type == "upload":
|
|
433
|
+
if not files:
|
|
434
|
+
MediLink_ConfigLoader.log("Error: No files provided for upload operation.", level="ERROR")
|
|
435
|
+
raise ValueError("No files provided for upload operation.")
|
|
436
|
+
command.extend(["put {}".format(os.path.normpath(file_path)) for file_path in files])
|
|
437
|
+
|
|
438
|
+
# Handle download operation
|
|
267
439
|
else:
|
|
268
|
-
|
|
269
|
-
|
|
440
|
+
command.append('get *')
|
|
441
|
+
|
|
442
|
+
# Close and exit commands
|
|
443
|
+
command.extend(['close', 'exit'])
|
|
444
|
+
MediLink_ConfigLoader.log("[Build Command] Original WinSCP command: {}".format(command))
|
|
445
|
+
return command
|
|
446
|
+
|
|
447
|
+
def simulate_operation(operation_type, files, config):
|
|
448
|
+
MediLink_ConfigLoader.log("Test Mode is enabled! Simulating WinSCP {} operation.".format(operation_type))
|
|
449
|
+
|
|
450
|
+
if operation_type == 'upload' and files:
|
|
451
|
+
MediLink_ConfigLoader.log("Simulating 3 second delay for upload operation for files: {}".format(files))
|
|
452
|
+
time.sleep(3)
|
|
453
|
+
return [os.path.normpath(file) for file in files if os.path.exists(file)]
|
|
454
|
+
elif operation_type == 'download':
|
|
455
|
+
MediLink_ConfigLoader.log("Simulating 3 second delay for download operation. No files to download in test mode.")
|
|
456
|
+
time.sleep(3)
|
|
457
|
+
return []
|
|
270
458
|
else:
|
|
271
|
-
|
|
459
|
+
MediLink_ConfigLoader.log("Invalid operation type during simulation: {}".format(operation_type))
|
|
460
|
+
return []
|
|
461
|
+
|
|
462
|
+
def execute_winscp_command(command, operation_type, files, local_storage_path):
|
|
463
|
+
"""
|
|
464
|
+
Execute the WinSCP command for the specified operation type.
|
|
465
|
+
"""
|
|
466
|
+
MediLink_ConfigLoader.log("Executing WinSCP command for operation type: {}".format(operation_type))
|
|
467
|
+
|
|
468
|
+
try:
|
|
272
469
|
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
|
|
273
470
|
stdout, stderr = process.communicate()
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
471
|
+
except Exception as e:
|
|
472
|
+
MediLink_ConfigLoader.log("Error occurred while executing WinSCP command: {}".format(e), level="ERROR")
|
|
473
|
+
return [] # Return an empty list instead of None
|
|
474
|
+
|
|
475
|
+
if process.returncode == 0:
|
|
476
|
+
MediLink_ConfigLoader.log("WinSCP {} operation completed successfully.".format(operation_type))
|
|
477
|
+
|
|
278
478
|
if operation_type == 'download':
|
|
279
|
-
downloaded_files =
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
479
|
+
downloaded_files = list_downloaded_files(local_storage_path) # BUG This isn't behaving correctly because the local_storage_path isn't where winscp is dumping the files
|
|
480
|
+
MediLink_ConfigLoader.log("Files currently located in local_storage_path: {}".format(downloaded_files), level="DEBUG")
|
|
481
|
+
|
|
482
|
+
if not downloaded_files:
|
|
483
|
+
MediLink_ConfigLoader.log("No files were downloaded or an error occurred during the listing process.", level="WARNING")
|
|
283
484
|
return downloaded_files
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
uploaded_files =
|
|
288
|
-
for file_path in files:
|
|
289
|
-
normalized_path = os.path.normpath(file_path)
|
|
290
|
-
if os.path.exists(normalized_path): # Check if the file exists before appending
|
|
291
|
-
uploaded_files.append(normalized_path)
|
|
292
|
-
else:
|
|
293
|
-
MediLink_ConfigLoader.log("Failed to upload file: {} does not exist.".format(normalized_path))
|
|
485
|
+
|
|
486
|
+
elif operation_type == 'upload':
|
|
487
|
+
uploaded_files = [os.path.normpath(file) for file in files if os.path.exists(file)]
|
|
488
|
+
MediLink_ConfigLoader.log("Uploaded files: {}".format(uploaded_files), level="DEBUG")
|
|
294
489
|
return uploaded_files
|
|
295
490
|
else:
|
|
296
|
-
|
|
297
|
-
|
|
491
|
+
error_message = stderr.decode('utf-8').strip()
|
|
492
|
+
MediLink_ConfigLoader.log("Failed to {} files. Exit code: {}. Details: {}".format(
|
|
493
|
+
operation_type, process.returncode, error_message), level="ERROR")
|
|
494
|
+
return [] # Return an empty list instead of None
|
|
495
|
+
|
|
496
|
+
def list_downloaded_files(local_storage_path):
|
|
497
|
+
|
|
498
|
+
MediLink_ConfigLoader.log("Listing downloaded files in local storage path: {}".format(local_storage_path))
|
|
499
|
+
|
|
500
|
+
# Initialize an empty list to hold file paths
|
|
501
|
+
downloaded_files = []
|
|
502
|
+
|
|
503
|
+
try:
|
|
504
|
+
# Walk through the directory and collect all file paths
|
|
505
|
+
for root, _, files in os.walk(local_storage_path):
|
|
506
|
+
for file in files:
|
|
507
|
+
file_path = os.path.join(root, file)
|
|
508
|
+
downloaded_files.append(file_path)
|
|
509
|
+
MediLink_ConfigLoader.log("File found: {}".format(file_path), level="DEBUG")
|
|
510
|
+
|
|
511
|
+
if not downloaded_files:
|
|
512
|
+
MediLink_ConfigLoader.log("No files found in the directory: {}".format(local_storage_path), level="WARNING")
|
|
513
|
+
|
|
514
|
+
except Exception as e:
|
|
515
|
+
MediLink_ConfigLoader.log("Error occurred while listing files in {}: {}".format(local_storage_path, e), level="ERROR")
|
|
516
|
+
|
|
517
|
+
# Ensure that the function always returns a list
|
|
518
|
+
return downloaded_files
|
|
298
519
|
|
|
299
520
|
def detect_new_files(directory_path, file_extension='.DAT'):
|
|
300
521
|
"""
|