calorimeter/lib/food_scan/food_fact_lookup.dart
Marco a7a7f44050 Make scanned widgets appear in the list instead of putting the info into
the EnterFoodWidget.

1. Make scanned foods appear in the list of foods
2. Remove Controller for entering food

This commit removes the EnterFoodController that was used to put a
scanned food into the EnterFoodWidget.
This is now unnecessary because scanning a product will be distributed
via the FoodBLoC.
2024-09-24 14:41:42 +02:00

85 lines
2.0 KiB
Dart

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<FoodFactResponse> 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 mass;
FoodFactModel({
required this.name,
required this.mass,
required this.kcalPer100g,
});
factory FoodFactModel.fromJson(Map<String, dynamic> 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});
}