files_service.dart 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import 'package:dio/dio.dart';
  2. import 'package:logging/logging.dart';
  3. import 'package:path/path.dart';
  4. import 'package:photos/core/configuration.dart';
  5. import 'package:photos/core/network.dart';
  6. import 'package:photos/db/files_db.dart';
  7. import 'package:photos/extensions/list.dart';
  8. import 'package:photos/models/file.dart';
  9. import 'package:photos/models/magic_metadata.dart';
  10. import 'package:photos/services/file_magic_service.dart';
  11. import 'package:photos/utils/date_time_util.dart';
  12. class FilesService {
  13. late Dio _enteDio;
  14. late Logger _logger;
  15. late FilesDB _filesDB;
  16. late Configuration _config;
  17. FilesService._privateConstructor() {
  18. _enteDio = Network.instance.enteDio;
  19. _logger = Logger("FilesService");
  20. _filesDB = FilesDB.instance;
  21. _config = Configuration.instance;
  22. }
  23. static final FilesService instance = FilesService._privateConstructor();
  24. Future<int> getFileSize(int uploadedFileID) async {
  25. try {
  26. final response = await _enteDio.post(
  27. "/files/size",
  28. data: {
  29. "fileIDs": [uploadedFileID]
  30. },
  31. );
  32. return response.data["size"];
  33. } catch (e) {
  34. _logger.severe(e);
  35. rethrow;
  36. }
  37. }
  38. Future<void> bulkEditTime(
  39. List<File> files,
  40. EditTimeSource source,
  41. ) async {
  42. assert(
  43. source == EditTimeSource.fileName,
  44. "edit source ${source.name} is not supported yet",
  45. );
  46. final ListMatch<File> result = files.splitMatch(
  47. (element) => element.isUploaded,
  48. );
  49. final List<File> uploadedFiles = result.matched;
  50. // editTime For LocalFiles
  51. final List<File> localOnlyFiles = result.unmatched;
  52. for (File localFile in localOnlyFiles) {
  53. final timeResult = parseDateTimeFromFileNameV2(
  54. basenameWithoutExtension(localFile.title ?? ""),
  55. );
  56. if (timeResult != null) {
  57. localFile.creationTime = timeResult.microsecondsSinceEpoch;
  58. }
  59. }
  60. await _filesDB.insertMultiple(localOnlyFiles);
  61. final List<File> remoteFilesToUpdate = [];
  62. final Map<int, Map<String, int>> fileIDToUpdateMetadata = {};
  63. for (File remoteFile in uploadedFiles) {
  64. // discard files not owned by user and also dedupe already processed
  65. // files
  66. if (remoteFile.ownerID != _config.getUserID()! ||
  67. fileIDToUpdateMetadata.containsKey(remoteFile.uploadedFileID)) {
  68. continue;
  69. }
  70. final timeResult = parseDateTimeFromFileNameV2(
  71. basenameWithoutExtension(remoteFile.title ?? ""),
  72. );
  73. if (timeResult != null) {
  74. remoteFilesToUpdate.add(remoteFile);
  75. fileIDToUpdateMetadata[remoteFile.uploadedFileID!] = {
  76. pubMagicKeyEditedTime: timeResult.microsecondsSinceEpoch,
  77. };
  78. }
  79. }
  80. if (remoteFilesToUpdate.isNotEmpty) {
  81. await FileMagicService.instance.updatePublicMagicMetadata(
  82. remoteFilesToUpdate,
  83. null,
  84. metadataUpdateMap: fileIDToUpdateMetadata,
  85. );
  86. }
  87. }
  88. }
  89. enum EditTimeSource {
  90. // parse the time from fileName
  91. fileName,
  92. // parse the time from exif data of file.
  93. exif,
  94. // use the which user provided as input
  95. manualFix,
  96. // adjust the time of selected photos by +/- time.
  97. // required for cases when the original device in which photos were taken
  98. // had incorrect time (quite common with physical cameras)
  99. manualAdjusted,
  100. }