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: 891 - new "uploaded timestamp" field for raw images #892

Merged
merged 3 commits into from
Mar 30, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 6 additions & 0 deletions lib/src/model/product_image.dart
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ class ProductImage {
required String this.imgid,
this.width,
this.height,
this.uploaded,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can have a better variable name, maybe something like uploaded_on or created_at. Or is it the same var name in other places?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @AshAman999!

In this PR we have an 'uploaded_t' JSON tag and an int? uploaded field.

If we compare to similar fields:

  • we also have a 'created_t' JSON tag and a created field (cf. in Product)
  • but instead of int? in this PR, we do have a much more explicit DateTime?

Would you be OK with DateTime? uploaded? That would be consistent with the rest of the timestamp fields in the package, and wouldn't be confusing with a DateTime? type.

}) : language = null,
field = null;

Expand All @@ -138,6 +139,9 @@ class ProductImage {
final OpenFoodFactsLanguage? language;
String? url;

/// Upload timestamp, for uploaded images only, in seconds since Unix Epoch.
int? uploaded;

/// Revision number
int? rev;

Expand Down Expand Up @@ -232,6 +236,7 @@ class ProductImage {
'${language == null ? '' : ',language=${language.code}'}'
'${angle == null ? '' : ',angle=${angle!.degreesClockwise}'}'
'${url == null ? '' : ',url=$url'}'
'${uploaded == null ? '' : ',uploaded=$uploaded'}'
'${imgid == null ? '' : ',imgid=$imgid'}'
'${rev == null ? '' : ',rev=$rev'}'
'${coordinatesImageSize == null ? '' : ',coordinatesImageSize=$coordinatesImageSize'}'
Expand Down Expand Up @@ -262,6 +267,7 @@ class ProductImage {
other.size == size &&
other.language == language &&
other.url == url &&
other.uploaded == uploaded &&
other.rev == rev &&
other.imgid == imgid &&
other.angle == angle &&
Expand Down
88 changes: 59 additions & 29 deletions lib/src/utils/json_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,25 @@ class JsonHelper {
onlyMain: true,
);

// only for main images
static const String _ALL_IMAGES_TAG_REVISION = 'rev';
static const String _ALL_IMAGES_TAG_ANGLE = 'angle';
static const String _ALL_IMAGES_TAG_COORDINATES = 'coordinates_image_size';
static const String _ALL_IMAGES_TAG_X1 = 'x1';
static const String _ALL_IMAGES_TAG_Y1 = 'y1';
static const String _ALL_IMAGES_TAG_X2 = 'x2';
static const String _ALL_IMAGES_TAG_Y2 = 'y2';

// only for raw images
static const String _ALL_IMAGES_TAG_UPLOADED = 'uploaded_t';

// common to main and raw images
static const String _ALL_IMAGES_TAG_IMAGE_ID = 'imgid';
static const String _ALL_IMAGES_TAG_WIDTH = 'w';
static const String _ALL_IMAGES_TAG_HEIGHT = 'h';
static const String _ALL_IMAGES_TAG_SIZES = 'sizes';
static const String _ALL_IMAGES_TAG_URL = 'url';

/// Returns [ProductImage]s from a JSON map for "Images".
static List<ProductImage>? allImagesFromJson(
Map? json, {
Expand Down Expand Up @@ -126,12 +145,14 @@ class JsonHelper {
final Map<String, dynamic> fieldObject = json[key];

// get the sizes object
var sizesObject = fieldObject['sizes'] as Map<String, dynamic>?;
final Map<String, dynamic>? sizesObject =
fieldObject[_ALL_IMAGES_TAG_SIZES] as Map<String, dynamic>?;
if (sizesObject == null) {
continue;
}

if (imageId != null) {
final int? uploaded = fieldObject[_ALL_IMAGES_TAG_UPLOADED] as int?;
// get each number object (e.g. 200)
for (var size in ImageSize.values) {
var number = size.number;
Expand All @@ -143,26 +164,28 @@ class JsonHelper {
ProductImage.raw(
size: size,
imgid: imageId.toString(),
width: JsonObject.parseInt(numberObject['w']),
height: JsonObject.parseInt(numberObject['h']),
url: numberObject['url'],
width: JsonObject.parseInt(numberObject[_ALL_IMAGES_TAG_WIDTH]),
height: JsonObject.parseInt(numberObject[_ALL_IMAGES_TAG_HEIGHT]),
url: numberObject[_ALL_IMAGES_TAG_URL],
uploaded: uploaded,
),
);
}
continue;
}

final rev = JsonObject.parseInt(fieldObject['rev']);
final String imgid = fieldObject['imgid'].toString();
final int? rev =
JsonObject.parseInt(fieldObject[_ALL_IMAGES_TAG_REVISION]);
final String imgid = fieldObject[_ALL_IMAGES_TAG_IMAGE_ID].toString();
final ImageAngle? angle = ImageAngleExtension.fromInt(
JsonObject.parseInt(fieldObject['angle']),
JsonObject.parseInt(fieldObject[_ALL_IMAGES_TAG_ANGLE]),
);
final String? coordinatesImageSize =
fieldObject['coordinates_image_size']?.toString();
final int? x1 = JsonObject.parseInt(fieldObject['x1']);
final int? y1 = JsonObject.parseInt(fieldObject['y1']);
final int? x2 = JsonObject.parseInt(fieldObject['x2']);
final int? y2 = JsonObject.parseInt(fieldObject['y2']);
fieldObject[_ALL_IMAGES_TAG_COORDINATES]?.toString();
final int? x1 = JsonObject.parseInt(fieldObject[_ALL_IMAGES_TAG_X1]);
final int? y1 = JsonObject.parseInt(fieldObject[_ALL_IMAGES_TAG_Y1]);
final int? x2 = JsonObject.parseInt(fieldObject[_ALL_IMAGES_TAG_X2]);
final int? y2 = JsonObject.parseInt(fieldObject[_ALL_IMAGES_TAG_Y2]);

// get each number object (e.g. 200)
for (var size in ImageSize.values) {
Expand All @@ -171,9 +194,11 @@ class JsonHelper {
if (numberObject == null) {
continue;
}
final int? width = JsonObject.parseInt(numberObject['w']);
final int? height = JsonObject.parseInt(numberObject['h']);
final String? url = numberObject['url'];
final int? width =
JsonObject.parseInt(numberObject[_ALL_IMAGES_TAG_WIDTH]);
final int? height =
JsonObject.parseInt(numberObject[_ALL_IMAGES_TAG_HEIGHT]);
final String? url = numberObject[_ALL_IMAGES_TAG_URL];

var image = ProductImage(
field: field!,
Expand Down Expand Up @@ -244,50 +269,55 @@ class JsonHelper {
continue;
}
final Map<String, dynamic> item = <String, dynamic>{};
item['sizes'] = <String, Map<String, Object>>{};
item[_ALL_IMAGES_TAG_SIZES] = <String, Map<String, Object>>{};
bool first = true;
for (final ProductImage productImage in list) {
if (productImage.size == null) {
continue;
}
final Map<String, Object> size = <String, Object>{};
if (productImage.width != null) {
size['w'] = productImage.width!;
size[_ALL_IMAGES_TAG_WIDTH] = productImage.width!;
}
if (productImage.height != null) {
size['h'] = productImage.height!;
size[_ALL_IMAGES_TAG_HEIGHT] = productImage.height!;
}
if (productImage.url != null) {
size['url'] = productImage.url!;
size[_ALL_IMAGES_TAG_URL] = productImage.url!;
}
item['sizes']![productImage.size!.number] = size;
item[_ALL_IMAGES_TAG_SIZES]![productImage.size!.number] = size;
if (first) {
first = false;
if (productImage.isMain) {
if (!productImage.isMain) {
if (productImage.uploaded != null) {
item[_ALL_IMAGES_TAG_UPLOADED] = productImage.uploaded;
}
} else {
if (productImage.rev != null) {
item['rev'] = productImage.rev.toString();
item[_ALL_IMAGES_TAG_REVISION] = productImage.rev.toString();
}
if (productImage.imgid != null) {
item['imgid'] = productImage.imgid!;
item[_ALL_IMAGES_TAG_IMAGE_ID] = productImage.imgid!;
}
if (productImage.angle != null) {
item['angle'] = productImage.angle!.degree.toString();
item[_ALL_IMAGES_TAG_ANGLE] =
productImage.angle!.degree.toString();
}
if (productImage.coordinatesImageSize != null) {
item['coordinates_image_size'] =
item[_ALL_IMAGES_TAG_COORDINATES] =
productImage.coordinatesImageSize!;
}
if (productImage.x1 != null) {
item['x1'] = productImage.x1!;
item[_ALL_IMAGES_TAG_X1] = productImage.x1!;
}
if (productImage.y1 != null) {
item['y1'] = productImage.y1!;
item[_ALL_IMAGES_TAG_Y1] = productImage.y1!;
}
if (productImage.x2 != null) {
item['x2'] = productImage.x2!;
item[_ALL_IMAGES_TAG_X2] = productImage.x2!;
}
if (productImage.y2 != null) {
item['y2'] = productImage.y2!;
item[_ALL_IMAGES_TAG_Y2] = productImage.y2!;
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions test/api_json_to_from_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ void main() {
for (final ProductImage productImage2 in imagesBackAndForth) {
if (productImage1 == productImage2) {
count++;
expect(productImage1.toString(), productImage2.toString());
}
}
expect(count, 1);
Expand All @@ -61,6 +62,7 @@ void main() {
for (final ProductImage productImage
in productResult.product!.getMainImages()!) {
expect(productImage.isMain, true);
expect(productImage.uploaded, isNull);
count++;
}
expect(count, countMain);
Expand All @@ -69,6 +71,7 @@ void main() {
for (final ProductImage productImage
in productResult.product!.getRawImages()!) {
expect(productImage.isMain, false);
expect(productImage.uploaded, isNotNull);
count++;
}
expect(count, countRaw);
Expand Down
Loading