Add helper class for downloading and resizing MET image and json files
This commit is contained in:
parent
a38f564411
commit
31ec04dea9
137
lib/_tools/artifact_download_helper.dart
Normal file
137
lib/_tools/artifact_download_helper.dart
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:http/http.dart';
|
||||||
|
import 'package:image/image.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
import 'package:wonders/logic/data/wonders_data/chichen_itza_data.dart';
|
||||||
|
import 'package:wonders/logic/data/wonders_data/christ_redeemer_data.dart';
|
||||||
|
import 'package:wonders/logic/data/wonders_data/great_wall_data.dart';
|
||||||
|
import 'package:wonders/logic/data/wonders_data/machu_picchu_data.dart';
|
||||||
|
import 'package:wonders/logic/data/wonders_data/petra_data.dart';
|
||||||
|
import 'package:wonders/logic/data/wonders_data/pyramids_giza_data.dart';
|
||||||
|
import 'package:wonders/logic/data/wonders_data/taj_mahal_data.dart';
|
||||||
|
|
||||||
|
import '../common_libs.dart';
|
||||||
|
import '../logic/data/collectible_data.dart';
|
||||||
|
import '../logic/data/wonders_data/colosseum_data.dart';
|
||||||
|
|
||||||
|
class ArtifactDownloadHelper extends StatefulWidget {
|
||||||
|
const ArtifactDownloadHelper({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ArtifactDownloadHelper> createState() => _ArtifactDownloadHelperState();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Using collectiblesData fetch the data for each artifact and download the image.
|
||||||
|
/// Resize all images to have multiple sizes (small, medium, large)
|
||||||
|
/// Save images using format [ID].jpg and [ID].json
|
||||||
|
/// OR modify CollectibleData_helper.html to include all data in the collectiblesData list so no JSON is required.
|
||||||
|
class _ArtifactDownloadHelperState extends State<ArtifactDownloadHelper> {
|
||||||
|
late String imagesDir;
|
||||||
|
final http = Client();
|
||||||
|
final List<String> missingIds = [];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
createDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> createDirectory() async {
|
||||||
|
final rootDir = await getApplicationDocumentsDirectory();
|
||||||
|
imagesDir = '${rootDir.path}/met_collectibles';
|
||||||
|
await Directory(imagesDir).create(recursive: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Center(
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: downloadArtifacts,
|
||||||
|
child: Text('Download Artifacts'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> downloadImage(String id, String url) async {
|
||||||
|
//final sizes = [400, 800, 1600, 3000];
|
||||||
|
debugPrint('Downloading $url to $imagesDir');
|
||||||
|
final imgResponse = await get(Uri.parse(url));
|
||||||
|
// If the image is less than a KB, it's probably a 404 image.
|
||||||
|
if (imgResponse.bodyBytes.lengthInBytes < 2000) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
File file = File('$imagesDir/$id.jpg');
|
||||||
|
file.writeAsBytesSync(imgResponse.bodyBytes);
|
||||||
|
print('img saved @ ${file.path}');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> downloadImageAndJson(String id) async {
|
||||||
|
File imgFile = File('$imagesDir/$id.jpg');
|
||||||
|
if (imgFile.existsSync()) {
|
||||||
|
print('Skipping $id');
|
||||||
|
await resizeImage(id, 600);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Uri uri = Uri.parse('https://collectionapi.metmuseum.org/public/collection/v1/objects/$id');
|
||||||
|
print('Downloading $id');
|
||||||
|
final response = await http.get(uri);
|
||||||
|
Map json = jsonDecode(response.body) as Map;
|
||||||
|
if (!json.containsKey('primaryImage') || json['primaryImage'].isEmpty) {
|
||||||
|
print('Missing $id');
|
||||||
|
missingIds.add(id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final url = json['primaryImage'] as String;
|
||||||
|
//bool isPublicDomain = json['isPublicDomain'] as bool;
|
||||||
|
final downloadSuccess = await downloadImage(id, url);
|
||||||
|
if (downloadSuccess) {
|
||||||
|
File file = File('$imagesDir/$id.json');
|
||||||
|
file.writeAsStringSync(response.body);
|
||||||
|
print('json saved @ ${file.path}');
|
||||||
|
} else {
|
||||||
|
print('Missing $id');
|
||||||
|
missingIds.add(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void downloadArtifacts() async {
|
||||||
|
/// Download collectibles
|
||||||
|
// for (var c in collectiblesData) {
|
||||||
|
// downloadImageAndJson(c.artifactId);
|
||||||
|
// }
|
||||||
|
missingIds.clear();
|
||||||
|
|
||||||
|
/// Download search artifacts
|
||||||
|
final searchData = ChichenItzaData().searchData +
|
||||||
|
ChristRedeemerData().searchData +
|
||||||
|
ColosseumData().searchData +
|
||||||
|
GreatWallData().searchData +
|
||||||
|
MachuPicchuData().searchData +
|
||||||
|
PetraData().searchData +
|
||||||
|
PyramidsGizaData().searchData +
|
||||||
|
TajMahalData().searchData;
|
||||||
|
for (var a in searchData) {
|
||||||
|
await downloadImageAndJson(a.id.toString());
|
||||||
|
print('${searchData.indexOf(a) + 1}/${searchData.length}');
|
||||||
|
}
|
||||||
|
print('Missing IDs: $missingIds');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> resizeImage(String id, int size) async {
|
||||||
|
final resizedFile = File('$imagesDir/${id}_$size.jpg');
|
||||||
|
final srcFile = File('$imagesDir/$id.jpg');
|
||||||
|
print('Resizing $id...');
|
||||||
|
if (resizedFile.existsSync() || !srcFile.existsSync()) return;
|
||||||
|
final img = decodeJpg(srcFile.readAsBytesSync());
|
||||||
|
if (img != null) {
|
||||||
|
final resizedImg = copyResize(img, width: size);
|
||||||
|
resizedFile.writeAsBytesSync(encodeJpg(resizedImg));
|
||||||
|
print('Resized $id');
|
||||||
|
} else {
|
||||||
|
print('Failed to resize $id');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
class SearchData {
|
class SearchData {
|
||||||
static const String baseImagePath = 'https://images.metmuseum.org/CRDImages/';
|
static const String baseImagePath = 'https://images.metmuseum.org/CRDImages/';
|
||||||
|
static const missingIds = [313256, 327544, 327596, 545776, 38549, 38578, 38473, 38598, 38153, 38203, 64486, 64487];
|
||||||
const SearchData(this.year, this.id, this.title, this.keywords, this.imagePath, [this.aspectRatio = 0]);
|
const SearchData(this.year, this.id, this.title, this.keywords, this.imagePath, [this.aspectRatio = 0]);
|
||||||
final int year;
|
final int year;
|
||||||
final int id;
|
final int id;
|
||||||
|
@ -11,6 +11,8 @@ import 'package:wonders/logic/unsplash_logic.dart';
|
|||||||
import 'package:wonders/logic/wallpaper_logic.dart';
|
import 'package:wonders/logic/wallpaper_logic.dart';
|
||||||
import 'package:wonders/logic/wonders_logic.dart';
|
import 'package:wonders/logic/wonders_logic.dart';
|
||||||
|
|
||||||
|
import '_tools/artifact_download_helper.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
|
WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
|
||||||
// Keep native splash screen up until app is finished bootstrapping
|
// Keep native splash screen up until app is finished bootstrapping
|
||||||
@ -30,6 +32,7 @@ class WondersApp extends StatelessWidget with GetItMixin {
|
|||||||
WondersApp({Key? key}) : super(key: key);
|
WondersApp({Key? key}) : super(key: key);
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
return MaterialApp(home: ArtifactDownloadHelper());
|
||||||
final locale = watchX((SettingsLogic s) => s.currentLocale);
|
final locale = watchX((SettingsLogic s) => s.currentLocale);
|
||||||
return MaterialApp.router(
|
return MaterialApp.router(
|
||||||
routeInformationProvider: appRouter.routeInformationProvider,
|
routeInformationProvider: appRouter.routeInformationProvider,
|
||||||
|
14
pubspec.lock
14
pubspec.lock
@ -5,10 +5,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: archive
|
name: archive
|
||||||
sha256: "0c8368c9b3f0abbc193b9d6133649a614204b528982bebc7026372d61677ce3a"
|
sha256: "20071638cbe4e5964a427cfa0e86dce55d060bc7d82d56f3554095d7239a8765"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.3.7"
|
version: "3.4.2"
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -61,10 +61,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: collection
|
name: collection
|
||||||
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
|
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.17.2"
|
version: "1.18.0"
|
||||||
convert:
|
convert:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -377,13 +377,13 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.3"
|
version: "2.1.3"
|
||||||
image:
|
image:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: image
|
name: image
|
||||||
sha256: a72242c9a0ffb65d03de1b7113bc4e189686fc07c7147b8b41811d0dd0e0d9bf
|
sha256: "028f61960d56f26414eb616b48b04eb37d700cbe477b7fb09bf1d7ce57fd9271"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.17"
|
version: "4.1.3"
|
||||||
image_fade:
|
image_fade:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -33,6 +33,7 @@ dependencies:
|
|||||||
google_maps_flutter_web: ^0.5.4+2
|
google_maps_flutter_web: ^0.5.4+2
|
||||||
go_router: ^6.5.5
|
go_router: ^6.5.5
|
||||||
http: ^0.13.5
|
http: ^0.13.5
|
||||||
|
image: ^4.1.3
|
||||||
image_fade: ^0.6.2
|
image_fade: ^0.6.2
|
||||||
image_gallery_saver: ^2.0.3
|
image_gallery_saver: ^2.0.3
|
||||||
intl: ^0.18.1
|
intl: ^0.18.1
|
||||||
|
@ -10,6 +10,11 @@ include(${EPHEMERAL_DIR}/generated_config.cmake)
|
|||||||
# https://github.com/flutter/flutter/issues/57146.
|
# https://github.com/flutter/flutter/issues/57146.
|
||||||
set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper")
|
set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper")
|
||||||
|
|
||||||
|
# Set fallback configurations for older versions of the flutter tool.
|
||||||
|
if (NOT DEFINED FLUTTER_TARGET_PLATFORM)
|
||||||
|
set(FLUTTER_TARGET_PLATFORM "windows-x64")
|
||||||
|
endif()
|
||||||
|
|
||||||
# === Flutter Library ===
|
# === Flutter Library ===
|
||||||
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")
|
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")
|
||||||
|
|
||||||
@ -92,7 +97,7 @@ add_custom_command(
|
|||||||
COMMAND ${CMAKE_COMMAND} -E env
|
COMMAND ${CMAKE_COMMAND} -E env
|
||||||
${FLUTTER_TOOL_ENVIRONMENT}
|
${FLUTTER_TOOL_ENVIRONMENT}
|
||||||
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
|
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
|
||||||
windows-x64 $<CONFIG>
|
${FLUTTER_TARGET_PLATFORM} $<CONFIG>
|
||||||
VERBATIM
|
VERBATIM
|
||||||
)
|
)
|
||||||
add_custom_target(flutter_assemble DEPENDS
|
add_custom_target(flutter_assemble DEPENDS
|
||||||
|
Loading…
x
Reference in New Issue
Block a user