Skip to content

Commit

Permalink
feat: 5741 - respecting the "search products" access limitations
Browse files Browse the repository at this point in the history
New file:
* `search_products_manager.dart`: Management of "search products" access limitations.

Impacted files:
* `background_task_download_products.dart`: refactored using `SearchProductsManager`
* `background_task_language_refresh.dart`: refactored using `SearchProductsManager`
* `background_task_top_barcodes.dart`: refactored using `SearchProductsManager`
* `lazy_counter.dart`: refactored using `SearchProductsManager`
* `paged_product_query.dart`: refactored using `SearchProductsManager`
* `product_list_page.dart`: refactored using `SearchProductsManager`
* `product_refresher.dart`: refactored using `SearchProductsManager`
* `pubspec.lock`: wtf
  • Loading branch information
monsieurtanuki committed Nov 7, 2024
1 parent e3fa4f4 commit 3ba9a48
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:smooth_app/database/dao_product.dart';
import 'package:smooth_app/database/dao_work_barcode.dart';
import 'package:smooth_app/database/local_database.dart';
import 'package:smooth_app/query/product_query.dart';
import 'package:smooth_app/query/search_products_manager.dart';

/// Background progressing task about downloading products.
class BackgroundTaskDownloadProducts extends BackgroundTaskProgressing {
Expand Down Expand Up @@ -123,7 +124,8 @@ class BackgroundTaskDownloadProducts extends BackgroundTaskProgressing {
fields.remove(ProductField.KNOWLEDGE_PANELS);
}
final OpenFoodFactsLanguage language = ProductQuery.getLanguage();
final SearchResult searchResult = await OpenFoodAPIClient.searchProducts(
final SearchResult searchResult =
await SearchProductsManager.searchProducts(
ProductQuery.getReadUser(),
ProductSearchQueryConfiguration(
fields: fields,
Expand All @@ -137,6 +139,7 @@ class BackgroundTaskDownloadProducts extends BackgroundTaskProgressing {
version: ProductQuery.productQueryVersion,
),
uriHelper: uriProductHelper,
type: SearchProductsType.background,
);
final List<Product>? downloadedProducts = searchResult.products;
if (downloadedProducts == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:smooth_app/background/operation_type.dart';
import 'package:smooth_app/database/dao_product.dart';
import 'package:smooth_app/database/local_database.dart';
import 'package:smooth_app/query/product_query.dart';
import 'package:smooth_app/query/search_products_manager.dart';

/// Background task about downloading products to translate.
class BackgroundTaskLanguageRefresh extends BackgroundTask {
Expand Down Expand Up @@ -127,7 +128,8 @@ class BackgroundTaskLanguageRefresh extends BackgroundTask {
if (barcodes.isEmpty) {
return;
}
final SearchResult searchResult = await OpenFoodAPIClient.searchProducts(
final SearchResult searchResult =
await SearchProductsManager.searchProducts(
getUser(),
ProductSearchQueryConfiguration(
fields: ProductQuery.fields,
Expand All @@ -141,6 +143,7 @@ class BackgroundTaskLanguageRefresh extends BackgroundTask {
version: ProductQuery.productQueryVersion,
),
uriHelper: _uriProductHelper,
type: SearchProductsType.background,
);
if (searchResult.products == null || searchResult.count == null) {
throw Exception('Cannot refresh language');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:smooth_app/background/operation_type.dart';
import 'package:smooth_app/database/dao_work_barcode.dart';
import 'package:smooth_app/database/local_database.dart';
import 'package:smooth_app/query/product_query.dart';
import 'package:smooth_app/query/search_products_manager.dart';

/// Background progressing task about downloading top n barcodes.
class BackgroundTaskTopBarcodes extends BackgroundTaskProgressing {
Expand Down Expand Up @@ -101,7 +102,8 @@ class BackgroundTaskTopBarcodes extends BackgroundTaskProgressing {

@override
Future<void> execute(final LocalDatabase localDatabase) async {
final SearchResult searchResult = await OpenFoodAPIClient.searchProducts(
final SearchResult searchResult =
await SearchProductsManager.searchProducts(
ProductQuery.getReadUser(),
ProductSearchQueryConfiguration(
fields: <ProductField>[ProductField.BARCODE],
Expand All @@ -115,6 +117,7 @@ class BackgroundTaskTopBarcodes extends BackgroundTaskProgressing {
version: ProductQuery.productQueryVersion,
),
uriHelper: uriProductHelper,
type: SearchProductsType.background,
);
if (searchResult.products == null || searchResult.count == null) {
throw Exception('Cannot download top barcodes');
Expand Down
4 changes: 3 additions & 1 deletion packages/smooth_app/lib/pages/preferences/lazy_counter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:openfoodfacts/openfoodfacts.dart';
import 'package:smooth_app/data_models/preferences/user_preferences.dart';
import 'package:smooth_app/query/paged_user_product_query.dart';
import 'package:smooth_app/query/product_query.dart';
import 'package:smooth_app/query/search_products_manager.dart';
import 'package:smooth_app/services/smooth_services.dart';

/// Lazy Counter, with a cached value stored locally, and a call to the server.
Expand Down Expand Up @@ -81,12 +82,13 @@ class LazyCounterUserSearch extends LazyCounter {
);

try {
final SearchResult result = await OpenFoodAPIClient.searchProducts(
final SearchResult result = await SearchProductsManager.searchProducts(
user,
configuration,
uriHelper: ProductQuery.getUriProductHelper(
productType: ProductType.food,
),
type: SearchProductsType.count,
);
return result.count;
} catch (e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import 'package:smooth_app/pages/product/common/product_refresher.dart';
import 'package:smooth_app/pages/product_list_user_dialog_helper.dart';
import 'package:smooth_app/pages/scan/carousel/scan_carousel_manager.dart';
import 'package:smooth_app/query/product_query.dart';
import 'package:smooth_app/query/search_products_manager.dart';
import 'package:smooth_app/resources/app_icons.dart' as icons;
import 'package:smooth_app/themes/theme_provider.dart';
import 'package:smooth_app/widgets/smooth_app_bar.dart';
Expand Down Expand Up @@ -455,13 +456,14 @@ class _ProductListPageState extends State<ProductListPage>
for (final MapEntry<ProductType, List<String>> entry
in productTypes.entries) {
final SearchResult searchResult =
await OpenFoodAPIClient.searchProducts(
await SearchProductsManager.searchProducts(
ProductQuery.getReadUser(),
ProductRefresher().getBarcodeListQueryConfiguration(
entry.value,
language,
),
uriHelper: ProductQuery.getUriProductHelper(productType: entry.key),
type: SearchProductsType.live,
);
final List<Product>? freshProducts = searchResult.products;
if (freshProducts == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import 'package:smooth_app/generic_lib/loading_dialog.dart';
import 'package:smooth_app/generic_lib/widgets/smooth_snackbar.dart';
import 'package:smooth_app/pages/user_management/login_page.dart';
import 'package:smooth_app/query/product_query.dart';
import 'package:smooth_app/query/search_products_manager.dart';
import 'package:smooth_app/services/smooth_services.dart';
import 'package:smooth_app/themes/smooth_theme_colors.dart';

Expand Down Expand Up @@ -263,10 +264,12 @@ class ProductRefresher {
) async {
try {
final OpenFoodFactsLanguage language = ProductQuery.getLanguage();
final SearchResult searchResult = await OpenFoodAPIClient.searchProducts(
final SearchResult searchResult =
await SearchProductsManager.searchProducts(
ProductQuery.getReadUser(),
getBarcodeListQueryConfiguration(barcodes, language),
uriHelper: ProductQuery.getUriProductHelper(productType: productType),
type: SearchProductsType.live,
);
if (searchResult.products == null) {
return null;
Expand Down
4 changes: 3 additions & 1 deletion packages/smooth_app/lib/query/paged_product_query.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:openfoodfacts/openfoodfacts.dart';
import 'package:smooth_app/data_models/product_list.dart';
import 'package:smooth_app/query/product_query.dart';
import 'package:smooth_app/query/search_products_manager.dart';

/// Paged product query (with [pageSize] and [pageNumber]).
abstract class PagedProductQuery {
Expand Down Expand Up @@ -39,10 +40,11 @@ abstract class PagedProductQuery {
void toTopPage() => _pageNumber = _startPageNumber;

Future<SearchResult> getSearchResult() async =>
OpenFoodAPIClient.searchProducts(
SearchProductsManager.searchProducts(
ProductQuery.getReadUser(),
getQueryConfiguration(),
uriHelper: ProductQuery.getUriProductHelper(productType: productType),
type: SearchProductsType.live,
);

AbstractQueryConfiguration getQueryConfiguration();
Expand Down
67 changes: 67 additions & 0 deletions packages/smooth_app/lib/query/search_products_manager.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import 'package:openfoodfacts/openfoodfacts.dart';

/// Type of "search products" action.
enum SearchProductsType {
/// For heavy background tasks like offline downloads.
background,

/// For live user interactions in the app.
live,

/// For counts like "number of products I edited".
count;

/// General threshold: 10 requests per minute.
static final TooManyRequestsManager _generalRequestManager =
TooManyRequestsManager(
maxCount: 10,
duration: const Duration(minutes: 1),
);

/// Specific threshold for background tasks.
static final TooManyRequestsManager _backgroundRequestManager =
TooManyRequestsManager(
maxCount: 3,
duration: const Duration(minutes: 1),
);

/// Specific threshold for count tasks.
///
/// For the record there are currently 4 counts displayed.
static final TooManyRequestsManager _countRequestManager =
TooManyRequestsManager(
maxCount: 4,
duration: const Duration(minutes: 1),
);

Future<void> _specificWaitIfNeeded() async => switch (this) {
SearchProductsType.background =>
_backgroundRequestManager.waitIfNeeded(),
SearchProductsType.count => _countRequestManager.waitIfNeeded(),
SearchProductsType.live => null,
};

Future<void> waitIfNeeded() async {
await _specificWaitIfNeeded();
await _generalRequestManager.waitIfNeeded();
}
}

/// Management of "search products" access limitations.
class SearchProductsManager {
SearchProductsManager._();

static Future<SearchResult> searchProducts(
final User? user,
final AbstractQueryConfiguration configuration, {
required final UriProductHelper uriHelper,
required final SearchProductsType type,
}) async {
await type.waitIfNeeded();
return OpenFoodAPIClient.searchProducts(
user,
configuration,
uriHelper: uriHelper,
);
}
}
4 changes: 2 additions & 2 deletions packages/smooth_app/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -696,10 +696,10 @@ packages:
dependency: "direct main"
description:
name: flutter_svg
sha256: "1b7723a814d84fb65869ea7115cdb3ee7c3be5a27a755c1ec60e049f6b9fcbb2"
sha256: de82e6bf958cec7190fbc1c5298282c851228e35ae2b14e2b103e7f777818c64
url: "https://pub.dev"
source: hosted
version: "2.0.11"
version: "2.0.13"
flutter_test:
dependency: "direct dev"
description: flutter
Expand Down

0 comments on commit 3ba9a48

Please sign in to comment.