Skip to content

Commit

Permalink
feat: 5586 - added explicit product type to all relevant background t…
Browse files Browse the repository at this point in the history
…asks

New file:
* `work_type.dart`: Type of long download work for some background tasks.

Impacted files:
* `background_task.dart`: removed the default `uriProductHelper` getter
* `background_task_barcode.dart`: added a `uriProductHelper` getter that depends on the `productType`
* `background_task_download_products.dart`: refactored the access to product type
* `background_task_full_refresh.dart`: split by product type
* `background_task_language_refresh.dart`: split by product type
* `background_task_offline.dart`: refactored the access to product type
* `background_task_progressing.dart`: added the `productType` parameter; moved code to new `WorkType` class
* `background_task_top_barcodes.dart`: refactored the access to product type
* `dao_product.dart`: new methods `getProductTypes` and `splitAllProducts`; refactored with product type
* `lazy_counter.dart`: explicitly counting the "food" products
* `newsfeed_provider.dart`: explicitly getting the news from "food"
* `offline_data_page.dart`: now displaying "download top N products" buttons for each product type; stats for each product type
* `offline_tasks_page.dart`: enhanced "work text" algo, now depending on product type
* `operation_type.dart`: enhanced "key" algo, now depending on product type
* `ordered_nutrients_cache.dart`: explicitly using the "food" nutrients
* `product_list_page.dart`: now reloading products from their server
* `product_list_popup_items.dart`: now linking to the first server with products
* `product_query.dart`: made product type a mandatory parameter
* `product_refresher.dart`: added mandatory parameter product type
* `random_questions_query.dart`: explicitly ask for "food" robotoff products
* `temp_product_list_share_helper.dart`: added mandatory parameter product type
* `user_preferences_dev_debug_info.dart`: added explicit use of "food" data
  • Loading branch information
monsieurtanuki committed Oct 21, 2024
1 parent a8cfcd0 commit dcd7dab
Show file tree
Hide file tree
Showing 23 changed files with 389 additions and 135 deletions.
5 changes: 1 addition & 4 deletions packages/smooth_app/lib/background/background_task.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ abstract class BackgroundTask {
required this.stamp,
final OpenFoodFactsLanguage? language,
}) // TODO(monsieurtanuki): don't store the password in a clear format...
// TODO(monsieurtanuki): store the uriProductHelper as well
: user = jsonEncode(ProductQuery.getWriteUser().toJson()),
country = ProductQuery.getCountry().offTag,
languageCode = (language ?? ProductQuery.getLanguage()).offTag;
Expand Down Expand Up @@ -181,10 +182,6 @@ abstract class BackgroundTask {
/// subtasks that call the next one at the end.
bool get hasImmediateNextTask => false;

// TODO(monsieurtanuki): store the uriProductHelper as well
@protected
UriProductHelper get uriProductHelper => ProductQuery.getUriProductHelper();

/// Returns true if tasks with the same stamp would overwrite each-other.
bool isDeduplicable() => true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ abstract class BackgroundTaskBarcode extends BackgroundTask {
localDatabase: localDatabase,
);

@override
@protected
UriProductHelper get uriProductHelper => ProductQuery.getUriProductHelper(
productType: productType,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class BackgroundTaskDownloadProducts extends BackgroundTaskProgressing {
required super.work,
required super.pageSize,
required super.totalSize,
required super.productType,
required this.downloadFlag,
});

Expand Down Expand Up @@ -49,19 +50,22 @@ class BackgroundTaskDownloadProducts extends BackgroundTaskProgressing {
required final int totalSize,
required final int soFarSize,
required final int downloadFlag,
required final ProductType productType,
}) async {
final String uniqueId = await _operationType.getNewKey(
localDatabase,
soFarSize: soFarSize,
totalSize: totalSize,
work: work,
productType: productType,
);
final BackgroundTask task = _getNewTask(
uniqueId,
work,
pageSize,
totalSize,
downloadFlag,
productType,
);
await task.addToManager(localDatabase);
}
Expand All @@ -77,6 +81,7 @@ class BackgroundTaskDownloadProducts extends BackgroundTaskProgressing {
final int pageSize,
final int totalSize,
final int downloadFlag,
final ProductType productType,
) =>
BackgroundTaskDownloadProducts._(
processName: _operationType.processName,
Expand All @@ -86,6 +91,7 @@ class BackgroundTaskDownloadProducts extends BackgroundTaskProgressing {
pageSize: pageSize,
totalSize: totalSize,
downloadFlag: downloadFlag,
productType: productType,
);

@override
Expand Down Expand Up @@ -133,8 +139,6 @@ class BackgroundTaskDownloadProducts extends BackgroundTaskProgressing {
throw Exception('Something bad happened downloading products');
}
final DaoProduct daoProduct = DaoProduct(localDatabase);
final ProductType? productType =
ProductQuery.extractProductType(uriProductHelper);
for (final Product product in downloadedProducts) {
if (await _shouldBeUpdated(daoProduct, product.barcode!)) {
await daoProduct.put(
Expand All @@ -159,6 +163,7 @@ class BackgroundTaskDownloadProducts extends BackgroundTaskProgressing {
totalSize: totalSize,
soFarSize: totalSize - remaining,
downloadFlag: downloadFlag,
productType: productType,
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import 'package:provider/provider.dart';
import 'package:smooth_app/background/background_task.dart';
import 'package:smooth_app/background/background_task_download_products.dart';
import 'package:smooth_app/background/background_task_paged.dart';
import 'package:smooth_app/background/background_task_progressing.dart';
import 'package:smooth_app/background/operation_type.dart';
import 'package:smooth_app/background/work_type.dart';
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';
Expand Down Expand Up @@ -66,34 +66,44 @@ class BackgroundTaskFullRefresh extends BackgroundTaskPaged {
final DaoProduct daoProduct = DaoProduct(localDatabase);
final DaoWorkBarcode daoWorkBarcode = DaoWorkBarcode(localDatabase);

await daoWorkBarcode
.deleteWork(BackgroundTaskProgressing.workFreshWithoutKP);
await daoWorkBarcode.deleteWork(BackgroundTaskProgressing.workFreshWithKP);
for (final ProductType productType in ProductType.values) {
await daoWorkBarcode.deleteWork(
WorkType.freshKP.getWorkTag(productType),
);
await daoWorkBarcode.deleteWork(
WorkType.freshNoKP.getWorkTag(productType),
);
}

// We separate the products into two lists, products with or without
// knowledge panels
final List<String> barcodes = await daoProduct.getAllKeys();
final List<String> productsWithoutKP = <String>[];
final List<String> productsWithKP = <String>[];
for (final String barcode in barcodes) {
if (await _shouldBeDownloadedWithoutKP(daoProduct, barcode)) {
productsWithoutKP.add(barcode);
} else {
productsWithKP.add(barcode);
// We separate the products into lists, products with or without
// knowledge panels, and split by product types.
final Map<String, List<String>> split = await daoProduct.splitAllProducts(
(Product product) {
final bool noKP = product.knowledgePanels == null;
final WorkType workType = noKP ? WorkType.freshNoKP : WorkType.freshKP;
final ProductType productType = product.productType ?? ProductType.food;
return workType.getWorkTag(productType);
},
);
for (int i = 0; i <= 1; i++) {
final bool noKP = i == 0;
final WorkType workType = noKP ? WorkType.freshNoKP : WorkType.freshKP;
for (final ProductType productType in ProductType.values) {
final String tag = workType.getWorkTag(productType);
final List<String>? barcodes = split[tag];
if (barcodes == null) {
continue;
}
await _startDownloadTask(
barcodes: barcodes,
work: tag,
localDatabase: localDatabase,
downloadFlag:
noKP ? BackgroundTaskDownloadProducts.flagMaskExcludeKP : 0,
productType: productType,
);
}
}
await _startDownloadTask(
barcodes: productsWithoutKP,
work: BackgroundTaskProgressing.workFreshWithoutKP,
localDatabase: localDatabase,
downloadFlag: BackgroundTaskDownloadProducts.flagMaskExcludeKP,
);
await _startDownloadTask(
barcodes: productsWithKP,
work: BackgroundTaskProgressing.workFreshWithKP,
localDatabase: localDatabase,
downloadFlag: 0,
);
}

@override
Expand All @@ -102,24 +112,12 @@ class BackgroundTaskFullRefresh extends BackgroundTaskPaged {
@override
bool hasImmediateNextTask = false;

/// Returns true if we should download data without KP.
///
/// That happens in one case:
/// * we already have a corresponding local product that does not have
/// populated knowledge panel fields.
static Future<bool> _shouldBeDownloadedWithoutKP(
final DaoProduct daoProduct,
final String barcode,
) async {
final Product? product = await daoProduct.get(barcode);
return product != null && product.knowledgePanels == null;
}

Future<void> _startDownloadTask({
required final List<String> barcodes,
required final String work,
required final LocalDatabase localDatabase,
required final int downloadFlag,
required final ProductType productType,
}) async {
if (barcodes.isEmpty) {
return;
Expand All @@ -134,6 +132,7 @@ class BackgroundTaskFullRefresh extends BackgroundTaskPaged {
totalSize: barcodes.length,
soFarSize: 0,
downloadFlag: downloadFlag,
productType: productType,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,15 @@ class BackgroundTaskLanguageRefresh extends BackgroundTask {
required super.uniqueId,
required super.stamp,
required this.excludeBarcodes,
required this.productType,
});

BackgroundTaskLanguageRefresh.fromJson(super.json)
: excludeBarcodes = _getStringList(json, _jsonTagExcludeBarcodes),
productType =
ProductType.fromOffTag(json[_jsonTagProductType] as String?) ??
// for legacy reason (not refreshed products = no product type)
ProductType.food,
super.fromJson();

static List<String> _getStringList(
Expand All @@ -32,28 +37,48 @@ class BackgroundTaskLanguageRefresh extends BackgroundTask {
}

final List<String> excludeBarcodes;
final ProductType productType;

static const String _jsonTagExcludeBarcodes = 'excludeBarcodes';
static const String _jsonTagProductType = 'productType';

@override
Map<String, dynamic> toJson() {
final Map<String, dynamic> result = super.toJson();
result[_jsonTagExcludeBarcodes] = excludeBarcodes;
result[_jsonTagProductType] = productType.offTag;
return result;
}

static const OperationType _operationType = OperationType.languageRefresh;

UriProductHelper get _uriProductHelper => ProductQuery.getUriProductHelper(
productType: productType,
);

static Future<void> addTask(
final LocalDatabase localDatabase, {
final List<String> excludeBarcodes = const <String>[],
final ProductType? productType,
}) async {
if (productType == null) {
for (final ProductType item in ProductType.values) {
await addTask(
localDatabase,
excludeBarcodes: excludeBarcodes,
productType: item,
);
}
return;
}
final String uniqueId = await _operationType.getNewKey(
localDatabase,
productType: productType,
);
final BackgroundTask task = _getNewTask(
uniqueId,
excludeBarcodes,
productType,
);
await task.addToManager(localDatabase);
}
Expand All @@ -66,12 +91,14 @@ class BackgroundTaskLanguageRefresh extends BackgroundTask {
static BackgroundTask _getNewTask(
final String uniqueId,
final List<String> excludeBarcodes,
final ProductType productType,
) =>
BackgroundTaskLanguageRefresh._(
processName: _operationType.processName,
uniqueId: uniqueId,
stamp: ';languageRefresh',
stamp: ';languageRefresh;${productType.offTag}',
excludeBarcodes: excludeBarcodes,
productType: productType,
);

@override
Expand All @@ -91,6 +118,7 @@ class BackgroundTaskLanguageRefresh extends BackgroundTask {
language,
limit: _pageSize,
excludeBarcodes: excludeBarcodes,
productType: productType,
);
if (barcodes.isEmpty) {
return;
Expand All @@ -108,7 +136,7 @@ class BackgroundTaskLanguageRefresh extends BackgroundTask {
country: ProductQuery.getCountry(),
version: ProductQuery.productQueryVersion,
),
uriHelper: uriProductHelper,
uriHelper: _uriProductHelper,
);
if (searchResult.products == null || searchResult.count == null) {
throw Exception('Cannot refresh language');
Expand Down
10 changes: 9 additions & 1 deletion packages/smooth_app/lib/background/background_task_offline.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:openfoodfacts/openfoodfacts.dart';
import 'package:provider/provider.dart';
import 'package:smooth_app/background/background_task.dart';
import 'package:smooth_app/background/background_task_progressing.dart';
import 'package:smooth_app/background/background_task_top_barcodes.dart';
import 'package:smooth_app/background/operation_type.dart';
import 'package:smooth_app/background/work_type.dart';
import 'package:smooth_app/database/dao_work_barcode.dart';
import 'package:smooth_app/database/local_database.dart';

Expand All @@ -17,6 +19,7 @@ class BackgroundTaskOffline extends BackgroundTaskProgressing {
required super.work,
required super.pageSize,
required super.totalSize,
required super.productType,
});

BackgroundTaskOffline.fromJson(super.json) : super.fromJson();
Expand All @@ -27,6 +30,7 @@ class BackgroundTaskOffline extends BackgroundTaskProgressing {
required final BuildContext context,
required final int pageSize,
required final int totalSize,
required final ProductType productType,
}) async {
final LocalDatabase localDatabase = context.read<LocalDatabase>();
final String uniqueId = await _operationType.getNewKey(
Expand All @@ -36,9 +40,10 @@ class BackgroundTaskOffline extends BackgroundTaskProgressing {
);
final BackgroundTask task = _getNewTask(
uniqueId,
BackgroundTaskProgressing.workOffline,
WorkType.offline.getWorkTag(productType),
pageSize,
totalSize,
productType,
);
if (!context.mounted) {
return;
Expand All @@ -59,6 +64,7 @@ class BackgroundTaskOffline extends BackgroundTaskProgressing {
final String work,
final int pageSize,
final int totalSize,
final ProductType productType,
) =>
BackgroundTaskOffline._(
processName: _operationType.processName,
Expand All @@ -67,6 +73,7 @@ class BackgroundTaskOffline extends BackgroundTaskProgressing {
work: work,
pageSize: pageSize,
totalSize: totalSize,
productType: productType,
);

@override
Expand All @@ -85,6 +92,7 @@ class BackgroundTaskOffline extends BackgroundTaskProgressing {
pageSize: pageSize,
totalSize: totalSize,
soFarSize: 0,
productType: productType,
);
}
}
Loading

0 comments on commit dcd7dab

Please sign in to comment.