From b99f1193748b2c0ebcd3fbee931822414bc88c85 Mon Sep 17 00:00:00 2001 From: monsieurtanuki Date: Mon, 21 Oct 2024 11:21:45 +0200 Subject: [PATCH] feat: new web folder structure for images (#984) Deleted file: * `suggestion_manager.dart`: unrelated removal of deprecated code Impacted files: * `image_helper.dart`: unrelated removal of deprecated code * `json_helper.dart`: unrelated removal of deprecated code * `open_food_api_client.dart`: unrelated removal of deprecated code * `openfoodfacts.dart`: unrelated removal of deprecated code * `pnns_groups.dart`: unrelated removal of deprecated code * `status.dart`: unrelated removal of deprecated code * `uri_helper.dart`: new web folder structure for images --- lib/openfoodfacts.dart | 1 - lib/src/model/status.dart | 5 --- lib/src/open_food_api_client.dart | 42 ------------------- lib/src/utils/image_helper.dart | 60 --------------------------- lib/src/utils/json_helper.dart | 19 --------- lib/src/utils/pnns_groups.dart | 5 --- lib/src/utils/suggestion_manager.dart | 53 ----------------------- lib/src/utils/uri_helper.dart | 26 ++++++------ 8 files changed, 14 insertions(+), 197 deletions(-) delete mode 100644 lib/src/utils/suggestion_manager.dart diff --git a/lib/openfoodfacts.dart b/lib/openfoodfacts.dart index 6961707a9e..83b5e46a51 100644 --- a/lib/openfoodfacts.dart +++ b/lib/openfoodfacts.dart @@ -145,7 +145,6 @@ export 'src/utils/product_helper.dart'; export 'src/utils/product_query_configurations.dart'; export 'src/utils/product_search_query_configuration.dart'; export 'src/utils/server_type.dart'; -export 'src/utils/suggestion_manager.dart'; export 'src/utils/tag_type.dart'; export 'src/utils/tag_type_autocompleter.dart'; export 'src/utils/too_many_requests_exception.dart'; diff --git a/lib/src/model/status.dart b/lib/src/model/status.dart index 63e1ac5ca7..9ee665da36 100644 --- a/lib/src/model/status.dart +++ b/lib/src/model/status.dart @@ -7,11 +7,6 @@ part 'status.g.dart'; @JsonSerializable() class Status extends JsonObject { - // TODO: deprecated from 2023-11-24; remove when old enough - @Deprecated('Use wrongUserOrPasswordErrorMessage instead') - static const WRONG_USER_OR_PASSWORD_ERROR_MESSAGE = - wrongUserOrPasswordErrorMessage; - static const wrongUserOrPasswordErrorMessage = 'Incorrect user name or password'; diff --git a/lib/src/open_food_api_client.dart b/lib/src/open_food_api_client.dart index 49c1cc78e5..067d33b92d 100644 --- a/lib/src/open_food_api_client.dart +++ b/lib/src/open_food_api_client.dart @@ -37,7 +37,6 @@ import 'model/user.dart'; import 'utils/abstract_query_configuration.dart'; import 'utils/country_helper.dart'; import 'utils/http_helper.dart'; -import 'utils/image_helper.dart'; import 'utils/language_helper.dart'; import 'utils/ocr_field.dart'; import 'utils/open_food_api_configuration.dart'; @@ -309,47 +308,6 @@ class OpenFoodAPIClient { return result; } - /// Returns the ids of all uploaded images for that product. - /// - /// To be used in combination with [ImageHelper.getUploadedImageUrl]. - /// Does not depend on language or country. - // TODO: deprecated from 2023-11-25; remove when old enough - @Deprecated('Use product field "images" instead') - static Future> getProductImageIds( - final String barcode, { - final User? user, - final UriProductHelper uriHelper = uriHelperFoodProd, - }) async { - final ProductQueryConfiguration configuration = ProductQueryConfiguration( - barcode, - version: ProductQueryVersion.v3, - fields: [ProductField.IMAGES], - ); - final String productString = await getProductString( - configuration, - user: user, - uriHelper: uriHelper, - ); - final String jsonStr = _replaceQuotes(productString); - final json = HttpHelper().jsonDecode(jsonStr); - if (json['status'] != 'success') { - throw Exception('Error: ${json['status']}'); - } else if (json['product']['images'] == null) { - return []; - } - - final Map images = json['product']['images']; - final List result = []; - for (final String key in images.keys) { - final int? value = int.tryParse(key); - if (value != null) { - result.add(value); - } - } - result.sort(); - return result; - } - /// Returns the response body of "get product" API for the given barcode. static Future getProductString( final ProductQueryConfiguration configuration, { diff --git a/lib/src/utils/image_helper.dart b/lib/src/utils/image_helper.dart index 455fa3ea6a..6e4eded188 100644 --- a/lib/src/utils/image_helper.dart +++ b/lib/src/utils/image_helper.dart @@ -1,7 +1,3 @@ -import 'open_food_api_configuration.dart'; -import 'uri_helper.dart'; -import '../model/product_image.dart'; - /// Helper class related to product pictures class ImageHelper { /// Minimum accepted width for an uploaded image. @@ -9,60 +5,4 @@ class ImageHelper { /// Minimum accepted height for an uploaded image. static const int minimumHeight = 160; - - /// Returns the [image] full url - for a specific [imageSize] if needed. - /// - /// E.g. "https://images.openfoodfacts.org/images/products/359/671/046/2858/front_fr.4.100.jpg" - // TODO: deprecated from 2023-11-25; remove when old enough - @Deprecated('Use ProductImage.getUrl instead') - static String getLocalizedProductImageUrl( - final String barcode, - final ProductImage image, { - final ImageSize? imageSize, - final UriProductHelper uriHelper = uriHelperFoodProd, - }) => - image.getUrl(barcode, uriHelper: uriHelper, imageSize: imageSize); - - /// Returns the [image] full url for an uploaded ("raw") image. - /// - /// E.g. "https://images.openfoodfacts.org/images/products/359/671/046/2858/1.400.jpg" - // TODO: deprecated from 2023-11-25; remove when old enough - @Deprecated('Use ProductImage.getUrl instead') - static String getUploadedImageUrl( - final String barcode, - final int imageId, - final ImageSize imageSize, { - final UriProductHelper uriHelper = uriHelperFoodProd, - }) => - ProductImage.raw(imgid: imageId.toString(), size: imageSize).getUrl( - barcode, - uriHelper: uriHelper, - ); - - /// Returns the [image] filename - for a specific [imageSize] if needed. - /// - /// By default uses the own [image]'s size field. - /// E.g. "front_fr.4.100.jpg" - /// cf. https://github.com/openfoodfacts/smooth-app/issues/3065 - // TODO: deprecated from 2023-11-25; remove when old enough - @Deprecated('Use ProductImage.getUrlFilename instead') - static String getProductImageFilename( - final ProductImage image, { - final ImageSize? imageSize, - }) => - image.getUrlFilename(imageSize: imageSize); - - /// Returns the filename of an uploaded image. - /// - /// cf. https://github.com/openfoodfacts/smooth-app/issues/3065 - // TODO: deprecated from 2023-11-25; remove when old enough - @Deprecated('Use ProductImage.getUrlFilename instead') - static String getUploadedImageFilename( - final int imageId, - final ImageSize imageSize, - ) => - ProductImage.raw( - imgid: imageId.toString(), - size: imageSize, - ).getUrlFilename(); } diff --git a/lib/src/utils/json_helper.dart b/lib/src/utils/json_helper.dart index 32d76d2b1d..996aa3452a 100644 --- a/lib/src/utils/json_helper.dart +++ b/lib/src/utils/json_helper.dart @@ -76,17 +76,6 @@ class JsonHelper { return result; } - /// Returns [ProductImage]s from a JSON map for "Images". - /// - /// For historical reasons we keep only the 4 main images here, on all sizes - /// and languages. - // TODO: deprecated from 2023-11-25; remove when old enough - @Deprecated('Use allImagesFromJson instead') - static List? imagesFromJson(Map? json) => allImagesFromJson( - json, - onlyMain: true, - ); - // only for main images static const String _ALL_IMAGES_TAG_REVISION = 'rev'; static const String _ALL_IMAGES_TAG_ANGLE = 'angle'; @@ -226,14 +215,6 @@ class JsonHelper { return imageList; } - // TODO: deprecated from 2023-11-25; remove when old enough - @Deprecated('Use allImagesToJson instead') - static Map imagesToJson(List? images) => - allImagesToJson( - images, - onlyMain: true, - ); - static Map allImagesToJson( final List? images, { final bool onlyMain = false, diff --git a/lib/src/utils/pnns_groups.dart b/lib/src/utils/pnns_groups.dart index 7ebb8f021c..e5aabf7ecd 100644 --- a/lib/src/utils/pnns_groups.dart +++ b/lib/src/utils/pnns_groups.dart @@ -268,9 +268,4 @@ enum PnnsGroup2 implements OffTagged { /// Name in English final String name; - - /// Returns the id of the subgroup - // TODO: deprecated from 2023-11-15; remove when old enough - @Deprecated('Use offTag instead') - String get id => offTag; } diff --git a/lib/src/utils/suggestion_manager.dart b/lib/src/utils/suggestion_manager.dart deleted file mode 100644 index a3f667964b..0000000000 --- a/lib/src/utils/suggestion_manager.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'dart:async'; - -import '../model/user.dart'; -import 'autocomplete_manager.dart'; -import 'autocompleter.dart'; -import 'country_helper.dart'; -import 'language_helper.dart'; -import 'open_food_api_configuration.dart'; -import 'uri_helper.dart'; -import 'tag_type.dart'; -import 'tag_type_autocompleter.dart'; - -/// Manager that returns the suggestions for the latest input. -/// -/// Typical use case: the user types one character (which triggers a call to -/// suggestions), then another character (which triggers another call). -/// What if the second call is much faster than the first one, for server or -/// connection reasons? The autocomplete widget will get the second suggestions, -/// then the first suggestions will override them. -/// And the user should get the suggestions that match the latest input. -// TODO: deprecated from 2023-12-06; remove when old enough -@Deprecated('Use TagTypeAutocompleter and AutocompleteManager instead') -class SuggestionManager implements Autocompleter { - SuggestionManager( - final TagType taxonomyType, { - required final OpenFoodFactsLanguage language, - final OpenFoodFactsCountry? country, - final String? categories, - final String? shape, - final int limit = 25, - final UriProductHelper uriHelper = uriHelperFoodProd, - final User? user, - }) : manager = AutocompleteManager( - TagTypeAutocompleter( - tagType: taxonomyType, - language: language, - country: country, - categories: categories, - shape: shape, - limit: limit, - uriHelper: uriHelper, - user: user, - ), - ); - - final AutocompleteManager manager; - - @override - Future> getSuggestions( - final String input, - ) async => - manager.getSuggestions(input); -} diff --git a/lib/src/utils/uri_helper.dart b/lib/src/utils/uri_helper.dart index 7cd7289c3b..c75da636d8 100644 --- a/lib/src/utils/uri_helper.dart +++ b/lib/src/utils/uri_helper.dart @@ -135,21 +135,23 @@ class UriProductHelper extends UriHelper { /// Returns the barcode sub-folder (without trailing '/'). /// /// For instance: - /// * `12345678` for barcode `12345678` - /// * `123/456/789` for barcode `123456789` - /// * `123/456/789/0` for barcode `1234567890` + /// * `000/001/234/5678` for barcode `12345678` + /// * `000/012/345/6789` for barcode `123456789` + /// * `000/123/456/7890` for barcode `1234567890` /// * `123/456/789/0123` for barcode `1234567890123` static String getBarcodeSubPath(final String barcode) { - if (barcode.length < 9) { - return barcode; - } - final String p1 = barcode.substring(0, 3); - final String p2 = barcode.substring(3, 6); - final String p3 = barcode.substring(6, 9); - if (barcode.length == 9) { - return '$p1/$p2/$p3'; + const int typicalLength = 13; + final int length = barcode.length; + final String workBarcode; + if (length >= typicalLength) { + workBarcode = barcode; + } else { + workBarcode = '${'0' * (typicalLength - length)}$barcode'; } - final String p4 = barcode.substring(9); + final String p1 = workBarcode.substring(0, 3); + final String p2 = workBarcode.substring(3, 6); + final String p3 = workBarcode.substring(6, 9); + final String p4 = workBarcode.substring(9); return '$p1/$p2/$p3/$p4'; } }