import 'dart:convert'; import 'dart:developer'; import 'dart:io'; class FoodFactLookupClient { FoodFactLookupClient(); static const String url = "https://world.openfoodfacts.org/api/v3/product/"; String getProductUrl(String ean) { return "$url$ean.json"; } Future retrieveFoodInfo(String ean) async { HttpClient client = HttpClient(); String asString = ""; try { var request = await client.getUrl(Uri.parse(getProductUrl(ean))); await Future.delayed(const Duration(seconds: 10)); var response = await request.close(); if (response.statusCode != HttpStatus.ok) { return FoodFactResponse( food: null, status: FoodFactResponseStatus.barcodeNotFound); } asString = await response.transform(utf8.decoder).join(); } on SocketException { return FoodFactResponse( food: null, status: FoodFactResponseStatus.foodFactServerNotReachable); } catch (e) { log(e.toString()); } finally { client.close(); } return FoodFactResponse( food: FoodFactModel.fromJson(jsonDecode(asString)), status: FoodFactResponseStatus.ok); } } class FoodFactModel { final String name; final int kcalPer100g; final int mass; FoodFactModel({ required this.name, required this.mass, required this.kcalPer100g, }); factory FoodFactModel.fromJson(Map json) { String quantityString = json['product']['product_quantity'] ?? "0"; int quantity; try { quantity = int.parse(quantityString); } catch (e) { quantity = 0; } return FoodFactModel( name: json['product']['product_name'], kcalPer100g: json['product']['nutriments']['energy-kcal_100g'], mass: quantity); } } enum FoodFactResponseStatus { foodFactServerNotReachable, barcodeNotFound, ok, } class FoodFactResponse { final FoodFactModel? food; final FoodFactResponseStatus status; FoodFactResponse({required this.food, required this.status}); }