import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:path_provider/path_provider.dart'; import 'package:rxdart/rxdart.dart'; import 'package:uuid/uuid.dart'; class FileService { const FileService._(); static Future saveToFile( Uint8List bytes, String filename, ) async { final dir = await documentsDirectory; if (dir == null) { throw const PaperlessApiException.unknown(); //TODO: better handling } File file = File("${dir.path}/$filename"); return file..writeAsBytes(bytes); } static Future getDirectory(PaperlessDirectoryType type) { return switch (type) { PaperlessDirectoryType.documents => documentsDirectory, PaperlessDirectoryType.temporary => temporaryDirectory, PaperlessDirectoryType.scans => temporaryScansDirectory, PaperlessDirectoryType.download => downloadsDirectory, PaperlessDirectoryType.upload => uploadDirectory, }; } static Future allocateTemporaryFile( PaperlessDirectoryType type, { required String extension, String? fileName, }) async { final dir = await getDirectory(type); final _fileName = (fileName ?? const Uuid().v1()) + '.$extension'; return File('${dir?.path}/$_fileName'); } static Future get temporaryDirectory => getTemporaryDirectory(); static Future get documentsDirectory async { if (Platform.isAndroid) { return (await getExternalStorageDirectories( type: StorageDirectory.documents, ))! .first; } else if (Platform.isIOS) { final dir = await getApplicationDocumentsDirectory() .then((dir) => Directory('${dir.path}/documents')); return dir.create(recursive: true); } else { throw UnsupportedError("Platform not supported."); } } static Future get downloadsDirectory async { if (Platform.isAndroid) { Directory directory = Directory('/storage/emulated/0/Download'); if (!directory.existsSync()) { final downloadsDir = await getExternalStorageDirectories( type: StorageDirectory.downloads, ); directory = downloadsDir!.first; } return directory; } else if (Platform.isIOS) { final appDir = await getApplicationDocumentsDirectory(); final dir = Directory('${appDir.path}/downloads'); return dir.create(recursive: true); } else { throw UnsupportedError("Platform not supported."); } } static Future get uploadDirectory async { final dir = await getApplicationDocumentsDirectory() .then((dir) => Directory('${dir.path}/upload')); return dir.create(recursive: true); } static Future getConsumptionDirectory( {required String userId}) async { final uploadDir = await uploadDirectory.then((dir) => Directory('${dir.path}/$userId')); return uploadDir.create(recursive: true); } static Future get temporaryScansDirectory async { final tempDir = await temporaryDirectory; final scansDir = Directory('${tempDir.path}/scans'); return scansDir.create(recursive: true); } static Future clearUserData({required String userId}) async { final scanDir = await temporaryScansDirectory; final tempDir = await temporaryDirectory; final consumptionDir = await getConsumptionDirectory(userId: userId); await scanDir.delete(recursive: true); await tempDir.delete(recursive: true); await consumptionDir.delete(recursive: true); } static Future clearDirectoryContent(PaperlessDirectoryType type) async { final dir = await getDirectory(type); if (dir == null || !(await dir.exists())) { return; } await Future.wait( dir.listSync().map((item) => item.delete(recursive: true)), ); } static Future> getAllFiles(Directory directory) { return directory.list().whereType().toList(); } static Future> getAllSubdirectories(Directory directory) { return directory.list().whereType().toList(); } } enum PaperlessDirectoryType { documents, temporary, scans, download, upload; }