file_util.dart 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import 'dart:io' as io;
  2. import 'dart:typed_data';
  3. import 'package:path/path.dart';
  4. import 'package:dio/dio.dart';
  5. import 'package:flutter_cache_manager/flutter_cache_manager.dart';
  6. import 'package:flutter_image_compress/flutter_image_compress.dart';
  7. import 'package:photo_manager/photo_manager.dart';
  8. import 'package:photos/core/cache/image_cache.dart';
  9. import 'package:photos/core/cache/thumbnail_cache.dart';
  10. import 'package:photos/core/cache/thumbnail_cache_manager.dart';
  11. import 'package:photos/core/cache/video_cache_manager.dart';
  12. import 'package:photos/core/configuration.dart';
  13. import 'package:photos/core/constants.dart';
  14. import 'package:photos/db/files_db.dart';
  15. import 'package:photos/models/file.dart';
  16. import 'package:photos/models/file_type.dart';
  17. import 'crypto_util.dart';
  18. Future<void> deleteFiles(List<File> files,
  19. {bool deleteEveryWhere = false}) async {
  20. await PhotoManager.editor
  21. .deleteWithIds(files.map((file) => file.localID).toList());
  22. for (File file in files) {
  23. deleteEveryWhere
  24. ? await FilesDB.instance.markForDeletion(file)
  25. : await FilesDB.instance.delete(file);
  26. }
  27. }
  28. void preloadFile(File file) {
  29. if (file.fileType == FileType.video) {
  30. return;
  31. }
  32. if (file.localID == null) {
  33. getFileFromServer(file);
  34. } else {
  35. if (FileLruCache.get(file) == null) {
  36. file.getAsset().then((asset) {
  37. asset.file.then((assetFile) {
  38. FileLruCache.put(file, assetFile);
  39. });
  40. });
  41. }
  42. }
  43. }
  44. void preloadLocalFileThumbnail(File file) {
  45. if (file.localID == null ||
  46. ThumbnailLruCache.get(file, THUMBNAIL_SMALL_SIZE) != null) {
  47. return;
  48. }
  49. file.getAsset().then((asset) {
  50. asset
  51. .thumbDataWithSize(THUMBNAIL_SMALL_SIZE, THUMBNAIL_SMALL_SIZE)
  52. .then((data) {
  53. ThumbnailLruCache.put(file, THUMBNAIL_SMALL_SIZE, data);
  54. });
  55. });
  56. }
  57. Future<Uint8List> getBytes(File file, {int quality = 100}) async {
  58. if (file.localID == null) {
  59. return getFileFromServer(file).then((file) => file.readAsBytesSync());
  60. } else {
  61. return await getBytesFromDisk(file, quality: quality);
  62. }
  63. }
  64. Future<Uint8List> getBytesFromDisk(File file, {int quality = 100}) async {
  65. final originalBytes = (await file.getAsset()).originBytes;
  66. if (extension(file.title) == ".HEIC" || quality != 100) {
  67. return originalBytes.then((bytes) {
  68. return FlutterImageCompress.compressWithList(bytes, quality: quality)
  69. .then((converted) {
  70. return Uint8List.fromList(converted);
  71. });
  72. });
  73. } else {
  74. return originalBytes;
  75. }
  76. }
  77. Future<io.File> getFileFromServer(File file) async {
  78. final cacheManager = file.fileType == FileType.video
  79. ? VideoCacheManager()
  80. : DefaultCacheManager();
  81. if (!file.isEncrypted) {
  82. return cacheManager.getSingleFile(file.getDownloadUrl());
  83. } else {
  84. return cacheManager.getFileFromCache(file.getDownloadUrl()).then((info) {
  85. if (info == null) {
  86. return _downloadAndDecrypt(file, cacheManager);
  87. } else {
  88. return info.file;
  89. }
  90. });
  91. }
  92. }
  93. Future<io.File> getThumbnailFromServer(File file) async {
  94. if (!file.isEncrypted) {
  95. return ThumbnailCacheManager()
  96. .getSingleFile(file.getThumbnailUrl())
  97. .then((data) {
  98. ThumbnailFileLruCache.put(file, data);
  99. return data;
  100. });
  101. } else {
  102. return ThumbnailCacheManager()
  103. .getFileFromCache(file.getThumbnailUrl())
  104. .then((info) {
  105. if (info == null) {
  106. return _downloadAndDecryptThumbnail(file).then((data) {
  107. ThumbnailFileLruCache.put(file, data);
  108. return data;
  109. });
  110. } else {
  111. ThumbnailFileLruCache.put(file, info.file);
  112. return info.file;
  113. }
  114. });
  115. }
  116. }
  117. Future<io.File> _downloadAndDecrypt(
  118. File file, BaseCacheManager cacheManager) async {
  119. final temporaryPath = Configuration.instance.getTempDirectory() +
  120. file.generatedID.toString() +
  121. ".aes";
  122. return Dio().download(file.getDownloadUrl(), temporaryPath).then((_) async {
  123. final data = await CryptoUtil.decryptFileToData(
  124. temporaryPath, Configuration.instance.getKey());
  125. io.File(temporaryPath).deleteSync();
  126. return cacheManager.putFile(file.getDownloadUrl(), data);
  127. });
  128. }
  129. Future<io.File> _downloadAndDecryptThumbnail(File file) async {
  130. final temporaryPath = Configuration.instance.getTempDirectory() +
  131. file.generatedID.toString() +
  132. "_thumbnail.aes";
  133. Dio dio = Dio();
  134. return dio.download(file.getThumbnailUrl(), temporaryPath).then((_) async {
  135. final data = await CryptoUtil.decryptFileToData(
  136. temporaryPath, Configuration.instance.getKey());
  137. io.File(temporaryPath).deleteSync();
  138. return ThumbnailCacheManager().putFile(file.getThumbnailUrl(), data);
  139. });
  140. }