/* SPDX-License-Identifier: GPL-3.0-or-later */ /* Copyright (C) 2024 Marco Groß */ 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))); 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 kcalPer100gPrepared; final int mass; FoodFactModel({ required this.name, required this.mass, required this.kcalPer100g, required this.kcalPer100gPrepared, }); factory FoodFactModel.fromJson(Map json) { int kcalPer100g = json['product']['nutriments']['energy-kcal_100g'] ?? 0; int kcalPer100gPrepared = json['product']['nutriments']['energy-kcal_prepared_100g'] ?? 0; 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: kcalPer100g, kcalPer100gPrepared: kcalPer100gPrepared, mass: quantity); } } enum FoodFactResponseStatus { foodFactServerNotReachable, barcodeNotFound, ok, } class FoodFactResponse { final FoodFactModel? food; final FoodFactResponseStatus status; FoodFactResponse({required this.food, required this.status}); }