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

Fix #19110: Copy translation's target exploration images regardless if submitter uploaded new images or not #20188

Merged
merged 23 commits into from
May 1, 2024

Conversation

StephenYu2018
Copy link
Member

@StephenYu2018 StephenYu2018 commented Apr 20, 2024

Overview

This PR fixes #19110.

This PR does the following:

  • Instructs SuggestionHandler to copy of translation's target exploration images within GCS file system from /exploration/... to /exploration_suggestions/...
    • This makes images created using the copy tool able to load when reviewing the translation suggestion
  • Refactors relevant code flow starting from SuggestionHandler.post()
  • cloud_storage_services.py and dev_mode_storage_services.py throw a ValueError if source asset does not exist at given filepath
  • Introduces backend tests:
    • cloud_storage_services_test: Throws value error when source asset does not exist at filepath
    • suggestion_test:
      • test_saves_new_images_in_translation_that_were_copied_from_target_exploration
      • test_raises_exception_if_target_exploration_image_is_not_in_target_exploration_assets

The original bug occurred because images in the translation's target exploration were copied in GCS File System from /exploration/... to /exploration_suggestions/... only when the translation submitter uploaded new images to the translation text. If a translation reviewer were to review that submitted translation, the images would not load since they must be fetched from /exploration_suggestions/....

The PR that introduced this bug is #16532, in particular this commit. Prior to these changes, suggestion images were uploaded as long as it wasn't a question suggestion (in other words, a translation suggestion). Those changes introduced a check to only upload suggestion images if the list of new images introduced by the translation submitter was not empty. It's also possible that it was trying to check that the list of new images wasn't None.

Essential Checklist

Please follow the instructions for making a code change.

  • I have linked the issue that this PR fixes in the "Development" section of the sidebar.
  • I have checked the "Files Changed" tab and confirmed that the changes are what I want to make.
  • I have written tests for my code.
  • The PR title starts with "Fix #bugnum: " or "Fix part of #bugnum: ...", followed by a short, clear summary of the changes.
  • I have assigned the correct reviewers to this PR (or will leave a comment with the phrase "@{{reviewer_username}} PTAL" if I can't assign them directly).

Proof that changes are correct

Before:
issue-19110-proof-before

After:
issue-19110-proof-after

Proof of changes on desktop with slow/throttled network

issue-19110-slow-proof.mp4

Proof of changes on mobile phone

issue-19110-mobile-proof.mp4

Proof of changes in Arabic language

issue-19110-arabic-proof.mp4

PR Pointers

@StephenYu2018 StephenYu2018 requested review from a team as code owners April 20, 2024 02:57
Copy link

oppiabot bot commented Apr 20, 2024

Hi @vojtechjelinek, @DubeySandeep, @kevintab95, PTAL at this PR, it modifies files in jobs or platform folders.
Also @StephenYu2018, please make sure to fill in the server jobs form for the new job or feature to be tested on the backup server. This PR can be merged only after the test run is successful. Please refer to this guide for details.
Thanks!

@oppiabot oppiabot bot added the PR: Affects datastore layer Labels to indicate a PR that changes the datastore layer. label Apr 20, 2024
Copy link

oppiabot bot commented Apr 20, 2024

Assigning @chris7716 for the first pass review of this PR. Thanks!

@StephenYu2018
Copy link
Member Author

StephenYu2018 commented Apr 20, 2024

@chris7716 @kevintab95 If the only datastore change is to raise an error when copying files in the case of the given source asset not existing, do I still have to do server testing for this behavior? If so, then I think I'll just revert this behavior back to what it originally was, since I'm aiming to get this PR merged by April 30th latest.

filenames: list(str). The image filenames.
"""
suggestion_image_context = suggestion.image_context
# TODO(#10513): Find a way to save the images before the suggestion is
Copy link
Member

Choose a reason for hiding this comment

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

Just to check, is this still relevant here? From reading this it's a bit unclear when the suggestion is created exactly, and what we actually want to do here.

Copy link
Member Author

Choose a reason for hiding this comment

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

@seanlip Issue #10513 is still open as of now. Although I personally don't see why we should save the images before the suggestion is saved, with the exception that images for question suggestions are saved before saving the question suggestion. I think that images should be saved as the suggestion is saved, since those images are a part of the suggestion and it doesn't make sense for images uploaded by the translation submitter to exist without the suggestion existing first. What do you think?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, I think that sounds reasonable to me too. I think we can close that issue since it doesn't provide justification and we can't understand why it makes conceptual sense to do it ... I'll leave a note there.

Copy link
Member

Choose a reason for hiding this comment

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

(Btw the comments in #10475 have some interesting context on the existing implementation, e.g. https://docs.google.com/document/d/1kGvPjYnW9ArYKtzxYOmFbp7MA-A45B3znRWFIlaEGVo/edit#heading=h.xyfn6zlrzj3e and #10475 (comment)

Copy link
Member Author

Choose a reason for hiding this comment

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

@seanlip I removed the TODO comment.

)
except ValueError as error:
raise Exception(
'There are images in the target exploration that are '
Copy link
Member

Choose a reason for hiding this comment

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

This is somewhat unclear and I wouldn't know what to do if I saw this error. Could you please explain it more simply?

Copy link
Member Author

Choose a reason for hiding this comment

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

An image in the submitted translation's original content named "{filename}" cannot be found. Please save it to the backend file system at /exploration/{exp_id}/assets/image/ before submitting this translation again.

For example, if an image with filename img.png was part of submitted translation's target exploration with id s5Fr3Zd, then the error message will read: An image in the submitted translation's original content named "img.png" cannot be found. Please save it to the backend file system at /exploration/s5Fr3Zd/assets/image/ before submitting this translation again.

Also, I think I should move the copy operation of old images before the save operation of new images. That way if the images aren't copied successfully, then we don't save the new images either.

@seanlip What do you think?

Copy link
Member

Choose a reason for hiding this comment

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

Yup, that's much clearer, thanks!

I don't have a strong opinion on which order we should do the copy/save in -- I'm not sure why we'd want to test copying first in particular. One suggestion to keep things clean might be to fetch all the necessary images first (from both the original content and the new suggestion), and then save all of them to the correct paths in one for loop.

Copy link
Member Author

Choose a reason for hiding this comment

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

@seanlip I restructured the error message.

files, suggestion, new_image_filenames
)

self._copy_images_from_target_exploration_to_translation(suggestion)
Copy link
Member

Choose a reason for hiding this comment

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

I'm a bit confused ... why do we upload and then copy? I.e. why isn't adding the images that were part of the translation suggestion into the suggestion's directory sufficient?

I would have thought that we would:

(a) add the images that were sent as image data into the suggestion's directory
(b) copy the images that were part of the translation suggestion's text, but that were not sent as image data, into the suggestion's directory

Copy link
Member Author

@StephenYu2018 StephenYu2018 Apr 20, 2024

Choose a reason for hiding this comment

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

@seanlip For context, the copy tool creates an image in the HTML string, whose filepath points to the original image's filepath. The original image is an image in a card's content belonging to the target exploration. The intent of this algorithm isn't to upload images created using the copy tool. Instead, we are trying to copy the original images for the translation suggestion to use as assets. Since the images created using the copy tool have the same filename as the original image, this will also allow the images created using the copy tool to load when reviewing the translation. In short, we save images uploaded directly from the translation submitter, and then we copy the original images within the target exploration's card's content for the suggestion to use later on.

I think the highlighted method name is not clear about this. I think the name _copy_images_in_target_exploration_content_to_translation(suggestion) would be better since it better explains what images I'm referring to.

Copy link
Member

@seanlip seanlip Apr 22, 2024

Choose a reason for hiding this comment

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

Ah yup, as long as we just use the images in the translation suggestion's card, then that seems fine. I just want to ensure we aren't copying "extra" images that aren't part of the card. Thanks!

Copy link
Member Author

@StephenYu2018 StephenYu2018 Apr 23, 2024

Choose a reason for hiding this comment

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

@seanlip I renamed the method responsible for copying the images in the target exploration content.

Copy link
Member

@kevintab95 kevintab95 left a comment

Choose a reason for hiding this comment

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

LGTM for 4 codeowner files. Thanks @StephenYu2018!

@kevintab95 kevintab95 removed their assignment Apr 22, 2024
Copy link

oppiabot bot commented Apr 22, 2024

Assigning @lkbhitesh07 for code owner reviews. Thanks!

@seanlip seanlip removed their assignment Apr 22, 2024
@lkbhitesh07 lkbhitesh07 removed their assignment Apr 27, 2024
Copy link
Member

@seanlip seanlip left a comment

Choose a reason for hiding this comment

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

Thanks @StephenYu2018, replied to both comments (including here).

response_dict['error'])
self.logout()

def test_saves_new_images_in_translation_that_were_copied_from_target_exploration( # pylint: disable=line-too-long
Copy link
Member

Choose a reason for hiding this comment

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

@StephenYu2018 Sorry, I can't find that test ... which line of code are you referring to?

Copy link
Member

@seanlip seanlip left a comment

Choose a reason for hiding this comment

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

Thanks @StephenYu2018! LGTM, we can defer future work to #20232 as discussed.

@seanlip seanlip removed their assignment Apr 28, 2024
Copy link
Contributor

@chris7716 chris7716 left a comment

Choose a reason for hiding this comment

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

LGTM for codeowner files.

Copy link

oppiabot bot commented Apr 29, 2024

Unassigning @chris7716 since they have already approved the PR.

@oppiabot oppiabot bot added the PR: LGTM label Apr 29, 2024
Copy link

oppiabot bot commented Apr 29, 2024

Hi @StephenYu2018, this PR is ready to be merged. Please address any remaining comments prior to merging, and feel free to merge this PR once the CI checks pass and you're happy with it. Thanks!

@StephenYu2018
Copy link
Member Author

@seanlip @chris7716 @kevintab95 Can you merge this PR now? The CI checks have passed.

@seanlip seanlip added this pull request to the merge queue May 1, 2024
Merged via the queue into oppia:develop with commit bcb13ff May 1, 2024
81 checks passed
@StephenYu2018 StephenYu2018 deleted the issue-19110 branch May 1, 2024 18:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR: Affects datastore layer Labels to indicate a PR that changes the datastore layer. PR: LGTM
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG]: Problems with image when translating lessons into Portugese
8 participants