environment_monitoring_app/lib/services/ftp_service.dart

79 lines
3.3 KiB
Dart

// lib/services/ftp_service.dart
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:ftpconnect/ftpconnect.dart';
import 'package:environment_monitoring_app/services/server_config_service.dart';
// --- ADDED: Import for the new service that manages the retry queue ---
import 'package:environment_monitoring_app/services/retry_service.dart';
class FtpService {
final ServerConfigService _serverConfigService = ServerConfigService();
// --- REMOVED: This creates an infinite loop with RetryService ---
// final RetryService _retryService = RetryService();
/// Uploads a single file to the active server's FTP.
///
/// [fileToUpload] The local file to be uploaded.
/// [remotePath] The destination path on the FTP server (e.g., '/uploads/images/').
/// Returns a map with 'success' and 'message' keys.
Future<Map<String, dynamic>> uploadFile(File fileToUpload, String remotePath) async {
final config = await _serverConfigService.getActiveFtpConfig();
if (config == null || config['ftp_host'] == null || config['ftp_user'] == null || config['ftp_pass'] == null) {
return {'success': false, 'message': 'FTP credentials are not configured or selected.'};
}
final ftpHost = config['ftp_host'] as String;
final ftpUser = config['ftp_user'] as String;
final ftpPass = config['ftp_pass'] as String;
final ftpPort = config['ftp_port'] as int? ?? 21; // Default to port 21
final ftpConnect = FTPConnect(
ftpHost,
user: ftpUser,
pass: ftpPass,
port: ftpPort,
showLog: kDebugMode, // Show logs only in debug mode
timeout: 60, // --- MODIFIED: Set the timeout to 60 seconds ---
);
try {
debugPrint('FTP: Connecting to $ftpHost...');
await ftpConnect.connect();
debugPrint('FTP: Uploading file ${fileToUpload.path} to $remotePath...');
bool res = await ftpConnect.uploadFileWithRetry(
fileToUpload,
pRemoteName: remotePath,
pRetryCount: 3, // --- MODIFIED: Retry three times on failure ---
);
if (res) {
return {'success': true, 'message': 'File uploaded successfully via FTP.'};
} else {
// --- MODIFIED: Create a local instance of RetryService to break the circular dependency ---
final retryService = RetryService();
debugPrint('FTP upload for ${fileToUpload.path} failed after retries, queueing.');
await retryService.addFtpToQueue(
localFilePath: fileToUpload.path,
remotePath: remotePath
);
return {'success': false, 'message': 'FTP upload failed and has been queued for manual retry.'};
}
} catch (e) {
// --- MODIFIED: Create a local instance of RetryService to break the circular dependency ---
final retryService = RetryService();
debugPrint('FTP upload for ${fileToUpload.path} failed with an exception, queueing. Error: $e');
await retryService.addFtpToQueue(
localFilePath: fileToUpload.path,
remotePath: remotePath
);
return {'success': false, 'message': 'FTP upload failed and has been queued for manual retry.'};
} finally {
// Always ensure disconnection, even if an error occurs.
debugPrint('FTP: Disconnecting...');
await ftpConnect.disconnect();
}
}
}