mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-03-22 15:09:22 +01:00
Simplify metadata loader
No reason for the metadata loader to handle the downloading
This commit is contained in:
parent
76bc61c155
commit
1f49c2d3ea
6 changed files with 19 additions and 145 deletions
|
@ -1,79 +0,0 @@
|
||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:exifdart/exifdart_io.dart';
|
|
||||||
import 'package:exifdart/exifdart_memory.dart';
|
|
||||||
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
|
||||||
import 'package:logging/logging.dart';
|
|
||||||
import 'package:nc_photos/account.dart';
|
|
||||||
import 'package:nc_photos/api/api.dart';
|
|
||||||
import 'package:nc_photos/api/api_util.dart' as api_util;
|
|
||||||
import 'package:nc_photos/cache_manager_util.dart';
|
|
||||||
import 'package:nc_photos/entity/file.dart';
|
|
||||||
import 'package:nc_photos/exception.dart';
|
|
||||||
import 'package:nc_photos/image_size_getter_util.dart';
|
|
||||||
import 'package:nc_photos/platform/metadata_loader.dart' as itf;
|
|
||||||
|
|
||||||
class MetadataLoader implements itf.MetadataLoader {
|
|
||||||
@override
|
|
||||||
loadCacheFile(Account account, File file) async {
|
|
||||||
final getFileFuture =
|
|
||||||
_getFileTask.getFileUntil(api_util.getFileUrl(account, file));
|
|
||||||
final result = await Future.any([
|
|
||||||
getFileFuture,
|
|
||||||
Future.delayed(Duration(seconds: 10)),
|
|
||||||
]);
|
|
||||||
if (_getFileTask.isGood && result is FileInfo) {
|
|
||||||
return _onGetFile(file, result);
|
|
||||||
} else {
|
|
||||||
// timeout
|
|
||||||
_getFileTask.cancel();
|
|
||||||
throw TimeoutException("Timeout loading file: ${file.strippedPath}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
loadNewFile(Account account, File file) async {
|
|
||||||
final response =
|
|
||||||
await Api(account).files().get(path: api_util.getFileUrlRelative(file));
|
|
||||||
if (!response.isGood) {
|
|
||||||
_log.severe("[loadNewFile] Failed requesting server: $response");
|
|
||||||
throw ApiException(
|
|
||||||
response: response,
|
|
||||||
message: "Failed communicating with server: ${response.statusCode}");
|
|
||||||
}
|
|
||||||
return itf.MetadataLoader.loadMetadata(
|
|
||||||
file: file,
|
|
||||||
exifdartReaderBuilder: () => MemoryBlobReader(response.body),
|
|
||||||
imageSizeGetterInputBuilder: () => AsyncMemoryInput(response.body),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
loadFile(Account account, File file) async {
|
|
||||||
final store = DefaultCacheManager().store;
|
|
||||||
final info = await store.getFile(api_util.getFileUrl(account, file));
|
|
||||||
if (info == null) {
|
|
||||||
// no cache
|
|
||||||
return loadNewFile(account, file);
|
|
||||||
} else {
|
|
||||||
return _onGetFile(file, info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
cancel() {
|
|
||||||
_getFileTask.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Map<String, dynamic>> _onGetFile(File file, FileInfo info) {
|
|
||||||
return itf.MetadataLoader.loadMetadata(
|
|
||||||
file: file,
|
|
||||||
exifdartReaderBuilder: () => FileReader(info.file),
|
|
||||||
imageSizeGetterInputBuilder: () => AsyncFileInput(info.file),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
final _getFileTask = CancelableGetFile(DefaultCacheManager().store);
|
|
||||||
|
|
||||||
static final _log = Logger("mobile.metadata_loader.MetadataLoader");
|
|
||||||
}
|
|
|
@ -1,5 +1,4 @@
|
||||||
export 'db_util.dart';
|
export 'db_util.dart';
|
||||||
export 'downloader.dart';
|
export 'downloader.dart';
|
||||||
export 'map_widget.dart';
|
export 'map_widget.dart';
|
||||||
export 'metadata_loader.dart';
|
|
||||||
export 'universal_storage.dart';
|
export 'universal_storage.dart';
|
||||||
|
|
|
@ -1,30 +1,26 @@
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:exifdart/exifdart.dart' as exifdart;
|
import 'package:exifdart/exifdart.dart' as exifdart;
|
||||||
|
import 'package:exifdart/exifdart_memory.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:image_size_getter/image_size_getter.dart';
|
import 'package:image_size_getter/image_size_getter.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
||||||
|
import 'package:nc_photos/image_size_getter_util.dart';
|
||||||
|
|
||||||
abstract class MetadataLoader {
|
class LoadMetadata {
|
||||||
/// Load metadata for [file] from cache
|
/// Load metadata of [binary], which is the content of [file]
|
||||||
///
|
Future<Map<String, dynamic>> call(
|
||||||
/// If the file is not found in cache after a certain amount of time, an
|
Account account, File file, Uint8List binary) {
|
||||||
/// exception will be thrown
|
return _loadMetadata(
|
||||||
Future<Map<String, dynamic>> loadCacheFile(Account account, File file);
|
file: file,
|
||||||
|
exifdartReaderBuilder: () => MemoryBlobReader(binary),
|
||||||
|
imageSizeGetterInputBuilder: () => AsyncMemoryInput(binary),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// Download and load metadata for [file]
|
Future<Map<String, dynamic>> _loadMetadata({
|
||||||
///
|
|
||||||
/// This function will always try to download the file, no matter it's cached
|
|
||||||
/// or not
|
|
||||||
Future<Map<String, dynamic>> loadNewFile(Account account, File file);
|
|
||||||
|
|
||||||
/// Load metadata for [file], either from cache or a new download
|
|
||||||
Future<Map<String, dynamic>> loadFile(Account account, File file);
|
|
||||||
|
|
||||||
void cancel();
|
|
||||||
|
|
||||||
@protected
|
|
||||||
static Future<Map<String, dynamic>> loadMetadata({
|
|
||||||
@required File file,
|
@required File file,
|
||||||
exifdart.AbstractBlobReader Function() exifdartReaderBuilder,
|
exifdart.AbstractBlobReader Function() exifdartReaderBuilder,
|
||||||
AsyncImageInput Function() imageSizeGetterInputBuilder,
|
AsyncImageInput Function() imageSizeGetterInputBuilder,
|
|
@ -4,9 +4,9 @@ import 'package:nc_photos/connectivity_util.dart' as connectivity_util;
|
||||||
import 'package:nc_photos/entity/exif.dart';
|
import 'package:nc_photos/entity/exif.dart';
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/entity/file/data_source.dart';
|
import 'package:nc_photos/entity/file/data_source.dart';
|
||||||
import 'package:nc_photos/mobile/platform.dart'
|
|
||||||
if (dart.library.html) 'package:nc_photos/web/platform.dart' as platform;
|
|
||||||
import 'package:nc_photos/or_null.dart';
|
import 'package:nc_photos/or_null.dart';
|
||||||
|
import 'package:nc_photos/use_case/get_file_binary.dart';
|
||||||
|
import 'package:nc_photos/use_case/load_metadata.dart';
|
||||||
import 'package:nc_photos/use_case/scan_missing_metadata.dart';
|
import 'package:nc_photos/use_case/scan_missing_metadata.dart';
|
||||||
import 'package:nc_photos/use_case/update_property.dart';
|
import 'package:nc_photos/use_case/update_property.dart';
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@ class UpdateMissingMetadata {
|
||||||
/// would emit either File data (for each updated files) or an exception
|
/// would emit either File data (for each updated files) or an exception
|
||||||
Stream<dynamic> call(Account account, File root) async* {
|
Stream<dynamic> call(Account account, File root) async* {
|
||||||
final dataStream = ScanMissingMetadata(fileRepo)(account, root);
|
final dataStream = ScanMissingMetadata(fileRepo)(account, root);
|
||||||
final metadataLoader = platform.MetadataLoader();
|
|
||||||
await for (final d in dataStream) {
|
await for (final d in dataStream) {
|
||||||
if (d is Exception || d is Error) {
|
if (d is Exception || d is Error) {
|
||||||
yield d;
|
yield d;
|
||||||
|
@ -34,7 +33,8 @@ class UpdateMissingMetadata {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_log.fine("[call] Updating metadata for ${file.path}");
|
_log.fine("[call] Updating metadata for ${file.path}");
|
||||||
final metadata = await metadataLoader.loadFile(account, file);
|
final binary = await GetFileBinary(fileRepo)(account, file);
|
||||||
|
final metadata = await LoadMetadata()(account, file, binary);
|
||||||
int imageWidth, imageHeight;
|
int imageWidth, imageHeight;
|
||||||
Exif exif;
|
Exif exif;
|
||||||
if (metadata.containsKey("resolution")) {
|
if (metadata.containsKey("resolution")) {
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
import 'package:exifdart/exifdart_memory.dart';
|
|
||||||
import 'package:logging/logging.dart';
|
|
||||||
import 'package:nc_photos/account.dart';
|
|
||||||
import 'package:nc_photos/api/api.dart';
|
|
||||||
import 'package:nc_photos/api/api_util.dart' as api_util;
|
|
||||||
import 'package:nc_photos/entity/file.dart';
|
|
||||||
import 'package:nc_photos/exception.dart';
|
|
||||||
import 'package:nc_photos/image_size_getter_util.dart';
|
|
||||||
import 'package:nc_photos/platform/metadata_loader.dart' as itf;
|
|
||||||
|
|
||||||
class MetadataLoader implements itf.MetadataLoader {
|
|
||||||
// on web we just download the image again, hopefully the browser would
|
|
||||||
// cache it for us (which is sadly not the case :|
|
|
||||||
@override
|
|
||||||
loadCacheFile(Account account, File file) => loadNewFile(account, file);
|
|
||||||
|
|
||||||
@override
|
|
||||||
loadNewFile(Account account, File file) async {
|
|
||||||
final response =
|
|
||||||
await Api(account).files().get(path: api_util.getFileUrlRelative(file));
|
|
||||||
if (!response.isGood) {
|
|
||||||
_log.severe("[loadFile] Failed requesting server: $response");
|
|
||||||
throw ApiException(
|
|
||||||
response: response,
|
|
||||||
message: "Failed communicating with server: ${response.statusCode}");
|
|
||||||
}
|
|
||||||
return itf.MetadataLoader.loadMetadata(
|
|
||||||
file: file,
|
|
||||||
exifdartReaderBuilder: () => MemoryBlobReader(response.body),
|
|
||||||
imageSizeGetterInputBuilder: () => AsyncMemoryInput(response.body),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
loadFile(Account account, File file) => loadNewFile(account, file);
|
|
||||||
|
|
||||||
@override
|
|
||||||
cancel() {}
|
|
||||||
|
|
||||||
static final _log = Logger("web.metadata_loader.MetadataLoader");
|
|
||||||
}
|
|
|
@ -1,5 +1,4 @@
|
||||||
export 'db_util.dart';
|
export 'db_util.dart';
|
||||||
export 'downloader.dart';
|
export 'downloader.dart';
|
||||||
export 'map_widget.dart';
|
export 'map_widget.dart';
|
||||||
export 'metadata_loader.dart';
|
|
||||||
export 'universal_storage.dart';
|
export 'universal_storage.dart';
|
||||||
|
|
Loading…
Reference in a new issue