environment_monitoring_app/lib/services/zipping_service.dart

97 lines
3.3 KiB
Dart

import 'dart:io';
import 'dart:convert'; // Added to ensure correct UTF-8 encoding
import 'package:flutter/foundation.dart';
import 'package:archive/archive_io.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
/// A dedicated service to handle the creation of ZIP archives for FTP submission.
class ZippingService {
/// Creates multiple JSON files from a map of data and zips them into a single archive.
/// The map keys will be the filenames (e.g., 'db.json', 'form_data.json').
/// The map values should be the JSON string content for each file.
Future<File?> createDataZip({
required Map<String, String> jsonDataMap,
required String baseFileName,
Directory? destinationDir,
}) async {
try {
final targetDir = destinationDir ?? await getTemporaryDirectory();
// Ensure the target directory exists before creating the file
if (!await targetDir.exists()) {
await targetDir.create(recursive: true);
}
final zipFilePath = p.join(targetDir.path, '$baseFileName.zip');
final encoder = ZipFileEncoder();
encoder.create(zipFilePath);
debugPrint("Creating data ZIP at: $zipFilePath");
for (var entry in jsonDataMap.entries) {
final fileName = entry.key;
final jsonContent = entry.value;
// --- MODIFIED: Ensure UTF-8 encoding ---
// 1. Encode the string content into UTF-8 bytes
final utf8Bytes = utf8.encode(jsonContent);
// 2. Use the UTF-8 bytes and their correct length for the archive
// (This replaces the original: jsonContent.length, jsonContent.codeUnits)
final archiveFile = ArchiveFile(fileName, utf8Bytes.length, utf8Bytes);
// --- END MODIFICATION ---
encoder.addArchiveFile(archiveFile);
debugPrint("Added $fileName to data ZIP.");
}
encoder.close();
debugPrint("Data ZIP creation complete.");
return File(zipFilePath);
} catch (e) {
debugPrint("Error creating data ZIP file: $e");
return null;
}
}
/// Creates a ZIP file from a list of image files.
Future<File?> createImageZip({
required List<File> imageFiles,
required String baseFileName,
Directory? destinationDir, // ADDED: New optional parameter
}) async {
if (imageFiles.isEmpty) {
debugPrint("No images provided to create an image ZIP.");
return null;
}
try {
final targetDir = destinationDir ?? await getTemporaryDirectory();
// Ensure the target directory exists before creating the file
if (!await targetDir.exists()) {
await targetDir.create(recursive: true);
}
final zipFilePath = p.join(targetDir.path, '${baseFileName}_img.zip');
final encoder = ZipFileEncoder();
encoder.create(zipFilePath);
debugPrint("Creating image ZIP at: $zipFilePath");
for (var imageFile in imageFiles) {
if (await imageFile.exists()) {
await encoder.addFile(imageFile);
debugPrint("Added ${p.basename(imageFile.path)} to image ZIP.");
} else {
debugPrint("Skipping non-existent file: ${imageFile.path}");
}
}
encoder.close();
debugPrint("Image ZIP creation complete.");
return File(zipFilePath);
} catch (e) {
debugPrint("Error creating image ZIP file: $e");
return null;
}
}
}