Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 5586 - added explicit product type to all relevant background tasks #5721

Merged
merged 4 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading