From d4785b1f74bfe0a5dfb5e739486e92395a49ce75 Mon Sep 17 00:00:00 2001 From: Ming Ming Date: Thu, 24 Jun 2021 22:54:41 +0800 Subject: [PATCH] Improve album compatibility handling --- lib/app_db.dart | 6 ++- lib/entity/album.dart | 44 +++++++----------- lib/entity/album/upgrader.dart | 25 +++++++++++ test/entity/album_test.dart | 82 +++++++++++----------------------- 4 files changed, 72 insertions(+), 85 deletions(-) create mode 100644 lib/entity/album/upgrader.dart diff --git a/lib/app_db.dart b/lib/app_db.dart index 53de8ecf..5c34a26b 100644 --- a/lib/app_db.dart +++ b/lib/app_db.dart @@ -4,6 +4,7 @@ import 'package:idb_shim/idb.dart'; import 'package:logging/logging.dart'; import 'package:nc_photos/account.dart'; import 'package:nc_photos/entity/album.dart'; +import 'package:nc_photos/entity/album/upgrader.dart'; import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/mobile/platform.dart' if (dart.library.html) 'package:nc_photos/web/platform.dart' as platform; @@ -134,7 +135,10 @@ class AppDbAlbumEntry { return AppDbAlbumEntry( json["path"], json["index"], - Album.fromJson(json["album"].cast()), + Album.fromJson( + json["album"].cast(), + upgraderV1: AlbumUpgraderV1(), + ), ); } diff --git a/lib/entity/album.dart b/lib/entity/album.dart index 10ff1579..6fcd511e 100644 --- a/lib/entity/album.dart +++ b/lib/entity/album.dart @@ -8,6 +8,7 @@ import 'package:idb_sqflite/idb_sqflite.dart'; import 'package:logging/logging.dart'; import 'package:nc_photos/account.dart'; import 'package:nc_photos/app_db.dart'; +import 'package:nc_photos/entity/album/upgrader.dart'; import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/entity/file/data_source.dart'; import 'package:nc_photos/exception.dart'; @@ -131,34 +132,19 @@ class Album with EquatableMixin { this.name = name ?? "", this.items = UnmodifiableListView(items); - factory Album.versioned({ - int version, - DateTime lastUpdated, - @required String name, - @required List items, - File albumFile, + factory Album.fromJson( + Map json, { + AlbumUpgraderV1 upgraderV1, }) { - // there's only one version right now - if (version < 2) { - return Album( - lastUpdated: lastUpdated, - name: name, - items: [], - albumFile: albumFile, - ); - } else { - return Album( - lastUpdated: lastUpdated, - name: name, - items: items, - albumFile: albumFile, - ); + final jsonVersion = json["version"]; + if (jsonVersion < 2) { + json = upgraderV1?.call(json); + if (json == null) { + _log.info("[fromJson] Version $jsonVersion not compatible"); + return null; + } } - } - - factory Album.fromJson(Map json) { - return Album.versioned( - version: json["version"], + return Album( lastUpdated: json["lastUpdated"] == null ? null : DateTime.parse(json["lastUpdated"]), @@ -292,8 +278,10 @@ class AlbumRemoteDataSource implements AlbumDataSource { final fileRepo = FileRepo(FileWebdavDataSource()); final data = await GetFileBinary(fileRepo)(account, albumFile); try { - return Album.fromJson(jsonDecode(utf8.decode(data))) - .copyWith(albumFile: albumFile); + return Album.fromJson( + jsonDecode(utf8.decode(data)), + upgraderV1: AlbumUpgraderV1(), + ).copyWith(albumFile: albumFile); } catch (e, stacktrace) { dynamic d = data; try { diff --git a/lib/entity/album/upgrader.dart b/lib/entity/album/upgrader.dart new file mode 100644 index 00000000..7fcb456c --- /dev/null +++ b/lib/entity/album/upgrader.dart @@ -0,0 +1,25 @@ +import 'package:logging/logging.dart'; + +abstract class AlbumUpgrader { + Map call(Map json); +} + +/// Upgrade v1 Album to v2 +class AlbumUpgraderV1 implements AlbumUpgrader { + AlbumUpgraderV1({ + this.logFilePath, + }); + + Map call(Map json) { + // v1 album items are corrupted in one of the updates, drop it + _log.fine("[call] Upgrade v1 Album for file: $logFilePath"); + final result = Map.from(json); + result["items"] = []; + return result; + } + + /// File path for logging only + final String logFilePath; + + static final _log = Logger("entity.album.upgrader.AlbumUpgraderV1"); +} diff --git a/test/entity/album_test.dart b/test/entity/album_test.dart index 0558c111..21b67e17 100644 --- a/test/entity/album_test.dart +++ b/test/entity/album_test.dart @@ -1,4 +1,5 @@ import 'package:nc_photos/entity/album.dart'; +import 'package:nc_photos/entity/album/upgrader.dart'; import 'package:nc_photos/entity/file.dart'; import 'package:test/test.dart'; @@ -250,62 +251,31 @@ void main() { }); }); - group("versioned", () { - test("v1", () { - final album = Album.versioned( - version: 1, - lastUpdated: DateTime.utc(2020, 1, 2, 3, 4, 5, 678, 901), - name: "album", - items: [ - AlbumFileItem( - file: File(path: "remote.php/dav/files/admin/test1.jpg"), - ), - AlbumFileItem( - file: File(path: "remote.php/dav/files/admin/test2.jpg"), - ), - ], - albumFile: File(path: "remote.php/dav/files/admin/test1.jpg"), - ); - expect( - album, - Album( - lastUpdated: DateTime.utc(2020, 1, 2, 3, 4, 5, 678, 901), - name: "album", - items: [], - albumFile: File(path: "remote.php/dav/files/admin/test1.jpg"), - )); - }); - - test("v2", () { - final album = Album.versioned( - version: 2, - lastUpdated: DateTime.utc(2020, 1, 2, 3, 4, 5, 678, 901), - name: "album", - items: [ - AlbumFileItem( - file: File(path: "remote.php/dav/files/admin/test1.jpg"), - ), - AlbumFileItem( - file: File(path: "remote.php/dav/files/admin/test2.jpg"), - ), - ], - albumFile: File(path: "remote.php/dav/files/admin/test1.jpg"), - ); - expect( - album, - Album( - lastUpdated: DateTime.utc(2020, 1, 2, 3, 4, 5, 678, 901), - name: "album", - items: [ - AlbumFileItem( - file: File(path: "remote.php/dav/files/admin/test1.jpg"), - ), - AlbumFileItem( - file: File(path: "remote.php/dav/files/admin/test2.jpg"), - ), - ], - albumFile: File(path: "remote.php/dav/files/admin/test1.jpg"), - )); + test("AlbumUpgraderV1", () { + final json = { + "version": 1, + "lastUpdated": "2020-01-02T03:04:05.678901Z", + "items": [ + { + "type": "file", + "content": { + "file": { + "path": "remote.php/dav/files/admin/test1.jpg", + }, + }, + }, + ], + "albumFile": { + "path": "remote.php/dav/files/admin/test1.json", + }, + }; + expect(AlbumUpgraderV1()(json), { + "version": 1, + "lastUpdated": "2020-01-02T03:04:05.678901Z", + "items": [], + "albumFile": { + "path": "remote.php/dav/files/admin/test1.json", + }, }); }); });