openfoodfacts / openfoodfacts-server

Open Food Facts database, API server and web interface - 🐪🦋 Perl, CSS and JS coders welcome 😊 For helping in Python, see Robotoff or taxonomy-editor
http://openfoodfacts.github.io/openfoodfacts-server/
GNU Affero General Public License v3.0
645 stars 374 forks source link

Uploaded images via the API does not appear on the site #4174

Open rursache opened 4 years ago

rursache commented 4 years ago

Describe the bug I'm working on a food inventory app on iOS and users can scan products and autofill items using OpenFoodFacts. I thought that uploading the items not found in the database back to you would be helpful and i've read the documentation and took a look at your iOS app and build a upload system for images and product names.

Expected behavior However, after uploading a new product (code, name and image) i cannot see the image on the site. example This doesn't happen on the OFF iOS app. example

Additional details Here is how i'm calling the api when uploading images:

var headers = generalHeaders
headers["Content-Disposition"] = "form-data; name=\"imgupload_front\"; filename=\"\(barcode)\""

return Promise() { resolver in
    AF.upload(multipartFormData: { multipartFormData in
        multipartFormData.append(barcode.data(using: .utf8)!, withName: "code")
        multipartFormData.append(image.asData()!, withName: "product_image_upload.pl/imgupload_front")
        multipartFormData.append(("front").data(using: .utf8)!, withName: "imagefield")
        multipartFormData.append(Config.Keys.offUsername.data(using: .utf8)!, withName: "userId")
        multipartFormData.append(Config.Keys.offPassword.data(using: .utf8)!, withName: "password")
    }, to: getURL(.uploadProduct), headers: headers)
    .responseJSON(completionHandler: { (response) in
        guard let jsonValue = response.value as? [String: Any] else {
        resolver.reject(self.createGenericError(response.error))
        return
    }

    if let statusCode = jsonValue["status"] as? Int, statusCode == 1 {
        resolver.fulfill(true)
    } else {
        resolver.fulfill(false)
    }
        })
}

Here is the response: ["status_verbose": fields saved, "status": 1]

Full endpoint (getURL(.uploadProduct)) - https://world.openfoodfacts.org/cgi/product_image_upload.pl

Question Is there some kind of manual check for the images or there is an issue with my code?

aleene commented 4 years ago

There is no manual check, so it must be the code. There used to be a check for image size. They should not be to small. That was to prevent images picked from the web.

aleene commented 4 years ago

Does this happen on existing products as well?

rursache commented 4 years ago

@aleene thanks for the fast response

There is no manual check, so it must be the code. There used to be a check for image size. They should not be to small. That was to prevent images picked from the web.

i'm uploading big-enough images (all are took with iPhone 11 Pro) and the call returns success. When testing i used small images and saw the error you talk about but that would be a status = 0 error response

here is the cURL for my request (excluding the user_id/pass, i'm using those but not sharing here)

curl --location --request POST 'https://world.openfoodfacts.org/cgi/product_jqm2.pl' \
--form 'product_image_upload.pl/imgupload_front=@/Users/radu/Downloads/IMG_9535.jpg' \
--form 'code=59474203' \
--form 'imagefield=front' \

and the image is here. this is the product with barcode 9001414441350 (notice that the photo uploaded with OFF is on the site but the one uploaded with the cURL is not while getting ["status_verbose": fields saved, "status": 1]

Does this happen on existing products as well?

here is a barcode of a product already existing but with a new front image uploaded by me - 9001414041116. still can't see my own photo

what could be wrong? i would like the api call to fail and let me know if it's something i do wrong

aleene commented 4 years ago

Is the result json you show, not the one for the fields save. I have/use another result json for an image upload.

rursache commented 4 years ago

Is the result json you show, not the one for the fields save. I have/use another result json for an image upload.

the above is an example of the image upload, the fields update works. i don't see a connection

Ban3 commented 4 years ago

The docs do show the image upload like your cURL, but is the documentation actually correct? The cURL equivalent what the official apps are doing is more like:

curl --location --request POST 'https://world.openfoodfacts.org/cgi/product_image_upload.pl' \
--form 'imgupload_front=@/Users/radu/Downloads/IMG_9535.jpg' \
--form 'code=59474203' \
--form 'imagefield=front' 

It's like this in the old documentation

aleene commented 4 years ago

In the changes history there is a user openfoodfacts-contributors. That will be your attempt to upload an image. (A username and pw is not needed for images). So I guess the upload did not finish.

In the code of the ios-app, there is a part that lets you see the upload progress. It might help you to see if the upload is really happening.

aleene commented 4 years ago

Is the result json you show, not the one for the fields save. I have/use another result json for an image upload.

the above is an example of the image upload, the fields update works. i don't see a connection

The image upload results json is different, so you need to check that one out.

rursache commented 4 years ago

The docs do show the image upload like your cURL, but is the documentation actually correct? The cURL equivalent what the official apps are doing is more like:

curl --location --request POST 'https://world.openfoodfacts.org/cgi/product_image_upload.pl' \
--form 'imgupload_front=@/Users/radu/Downloads/IMG_9535.jpg' \
--form 'code=59474203' \
--form 'imagefield=front' 

It's like this in the old documentation

i changed product_image_upload.pl/imgupload_front to imgupload_front and there are still no changes, still success on the api call but no image on product page

In the code of the ios-app, there is a part that lets you see the upload progress. It might help you to see if the upload is really happening.

as stated in my initial post, i built the uploader around that code, yet it's not working the same.

is there any way to activate a debug mode?

Ban3 commented 4 years ago

i changed product_image_upload.pl/imgupload_front to imgupload_front and there are still no changes, still success on the api call but no image on product page

Did you notice the different endpoint product_image_upload.pl replaces product_jqm2.pl.

https://world.openfoodfacts.org/cgi/product_image_upload.pl

rursache commented 4 years ago

i changed product_image_upload.pl/imgupload_front to imgupload_front and there are still no changes, still success on the api call but no image on product page

Did you notice the different endpoint product_image_upload.pl replaces product_jqm2.pl.

https://world.openfoodfacts.org/cgi/product_image_upload.pl

thank you, i did miss that, sorry

i'm now getting

["error": The picture is too small. Please do not upload pictures found on the Internet and only send photos you have taken yourself., "status": status not ok, "imgid": -4, "files": <__NSSingleObjectArrayI 0x280c386d0>(
{
    code = 0094393698890;
}
)
, "debug": product_id: 0094393698890 - userid:  - imagefield: front_en - size of image file received: 0 - saved jpg:  - could not read image: Exception 410: no images defined `Image::Magick::Q16' @ error/Q16.xs/XS_Image__Magick__Q16_Write/15081 - image too small - width:  - height: ]

even tho the image is huge

i'll keep digging, i'm doing something wrong with the image data, i don't think it's related to OFF anymore.

thanks @Ban3 and @aleene

Ban3 commented 4 years ago

i'll keep digging, i'm doing something wrong with the image data, i don't think it's related to OFF anymore.

Yeah, my guess is that receives 0 bytes, hence 'too small'

The question about the documentation still stands. @teolemon @stephanegigandet or whoever known, is the way in the new documentation supposed to work?

rursache commented 4 years ago

i'll keep digging, i'm doing something wrong with the image data, i don't think it's related to OFF anymore.

i've found the 'issue' on my part. currently OFF is using the obsolete Alamofire v4 for networking, i'm using v5.2.2. instead of providing the image in Data format, if i provide a URL (to that image), the upload will be fine. example

so, in Swift:

multipartFormData.append(imgUrl, withName: "imgupload_front")

instead of

multipartFormData.append(image.asData()!, withName: "imgupload_front", mimeType: "image/jpeg")

i'm not happy with this, i've done this countless times using Data format and never had an issue, ~Alamofire is doing something underhood~. in the way my app works, i don't always have URLs for local paths to provide an image.

EDIT: seems like the API don't accept base64 strings for images but a constant stream of that data. why is that? EDIT 2: saving the UIImage first (in documents directory for ex.) then streaming it to the API did the trick. i'm still 🤯 that base64 strings are not accepted

stephanegigandet commented 4 years ago

The new documentation is incorrect indeed.

teolemon commented 3 years ago

@rursache just curious, is your app live ?

rursache commented 3 years ago

@rursache just curious, is your app live ?

yes, it is

github-actions[bot] commented 7 months ago

This issue has been open 90 days with no activity. Can you give it a little love by linking it to a parent issue, adding relevant labels and projets, creating a mockup if applicable, adding code pointers from https://github.com/openfoodfacts/openfoodfacts-server/blob/main/.github/labeler.yml, giving it a priority, editing the original issue to have a more comprehensive description… Thank you very much for your contribution to 🍊 Open Food Facts