Skip to content

Conversation

m-entrup
Copy link

We iterate over all shapes find_shapes() returns.
Raises a FileNotFoundError if filename does not point to a file.
The picture is created as a new shape.
The last step is to delete the old shape.

We iterate over all shapes find_shapes() return.
Raises a FileNotFoundError if `filename`does not point to a file.
The picture is created as a new shape
The last step is to delete the old shape.
The code uses data/example01.pptx to test adding an image shape.
The placeholder with the text #logo gets replaced by the image.
We iterate over all shapes find_shapes() return.
Raises a FileNotFoundError if `filename`does not point to a file.
The picture is created as a new shape
The last step is to delete the old shape.
Comment on lines 47 to 57
img_file = open(filename, "rb")
old_shape: BaseShape
for old_shape in shapes_to_replace:
slide_shapes = old_shape._parent
slide_shapes.add_picture(
image_file=img_file,
left=old_shape.left,
top=old_shape.top,
width=old_shape.width,
height=old_shape.height
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be a with open() …?
Or is that not required when only read access is performed?

filename = pathlib.Path(filename)
if not filename.is_file():
raise FileNotFoundError(f"The file does not exist: {filename}")
img_file = open(filename, "rb")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
img_file = open(filename, "rb")
with open(filename, "rb") as img_file:

if not filename.is_file():
raise FileNotFoundError(f"The file does not exist: {filename}")
img_file = open(filename, "rb")
old_shape: BaseShape
Copy link
Collaborator

@lysnikolaou lysnikolaou Oct 12, 2019

Choose a reason for hiding this comment

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

I would maybe type shapes_to_replace, instead of old_shape.

Copy link
Author

Choose a reason for hiding this comment

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

I already use shapes_to_replace for the iterator that is returned by _find_shapes(). In my opinion the singular version shape_to_replace is to close to shapes_to_replace and therefor old_shape makes it easier to distinguish between the iterator and the single shape.

m-entrup and others added 8 commits October 12, 2019 16:13
We use requirements.txt and dev_requirements.txt.
Therefore, Pipfile and Pipfile.lock are not needed.
Ignoring all PyCharm related files in .idea/.
We use requirements.txt and dev_requirements.txt.
Therefore, Pipfile and Pipfile.lock are not needed.
Ignoring all PyCharm related files in .idea/.
Running replace_by_image() a second time.
verifying the second run does not create new shapes.
# install all needed dependencies.
#Pipfile.lock
Pipfile
Pipfile.lock
Copy link

Choose a reason for hiding this comment

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

What's the reason for not committing the dependency lock file? I would only not do this if there is a problem...

Copy link
Author

Choose a reason for hiding this comment

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

As we use requirements.txt and dev_requirements.txt for listing dependencies a Pipfile would duplicate the requirements.

"""
pass
shapes_to_replace = self._find_shapes(label)
if not shapes_to_replace:
Copy link

Choose a reason for hiding this comment

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

This should be an Exception. Don't let errors pass silently!

Copy link
Author

Choose a reason for hiding this comment

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

It is a good idea to handle the problem on a higher level. I will replace return by

raise ValueError(f"The label '{label}' can't be found in the template.")

img_file = open(filename, "rb")
old_shape: BaseShape
for old_shape in shapes_to_replace:
slide_shapes = old_shape._parent
Copy link

@cmahr cmahr Oct 12, 2019

Choose a reason for hiding this comment

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

Not a big fan of using the internals of the pptx library. But if there is really no better way...

Copy link
Owner

Choose a reason for hiding this comment

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

It seems there is currently no other solution:
scanny/python-pptx#246

Could be mentionend in a code comment.

Copy link

Choose a reason for hiding this comment

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

Thx for linking the resource.

)
# Removing shapes is performed at the lxml level.
# The `element` attribute contains an instance of `lxml.etree._Element`.
slide_shapes.element.remove(old_shape.element)
Copy link

Choose a reason for hiding this comment

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

Yikes! We should really not deal with xml ourselves. We should open a RP in pptx to get this feature implemented. For the time being, we should either 1) isolate this in a private method marked deprecated to prevent excessive use, or 2) decorate the pptx presentation object.

Large images are always scaled.
The aspect ratio is kept.
The new kwarg `do_not_scale_up`can disable upscaling.
Centering is always active.
m-entrup added a commit to m-entrup/pptx-blueprint that referenced this pull request Oct 13, 2019
Raising an error if `shapes_to_replace` is empty.
Wrapping `open()`into a `with` statement.
@m-entrup
Copy link
Author

This PR is messed up a bit by myself. It should be best to use PR #9 instead. All changes to replace_image() are included into PR #9.

@m-entrup m-entrup closed this Oct 13, 2019
@m-entrup m-entrup deleted the master branch October 13, 2019 08:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants