Skip to content

Commit 294b3c5

Browse files
author
Steve Canny
committedNov 13, 2014
pkg: add Package.next_image_partname()
1 parent b3e5fbe commit 294b3c5

File tree

2 files changed

+48
-6
lines changed

2 files changed

+48
-6
lines changed
 

‎pptx/package.py

+19-6
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99

1010
import os
1111

12-
from pptx.opc.constants import RELATIONSHIP_TYPE as RT
13-
from pptx.opc.package import OpcPackage
14-
from pptx.parts.coreprops import CoreProperties
15-
from pptx.parts.image import Image, ImagePart
16-
from pptx.util import lazyproperty
12+
from .opc.constants import RELATIONSHIP_TYPE as RT
13+
from .opc.package import OpcPackage
14+
from .opc.packuri import PackURI
15+
from .parts.coreprops import CoreProperties
16+
from .parts.image import Image, ImagePart
17+
from .util import lazyproperty
1718

1819

1920
class Package(OpcPackage):
@@ -70,7 +71,19 @@ def next_image_partname(self, ext):
7071
partname, by sequence number. *ext* is used as the extention on the
7172
returned partname.
7273
"""
73-
raise NotImplementedError
74+
def first_available_image_idx():
75+
image_idxs = sorted([
76+
part.partname.idx for part in self.iter_parts()
77+
if part.partname.startswith('/ppt/media/image')
78+
])
79+
for i, image_idx in enumerate(image_idxs):
80+
idx = i + 1
81+
if idx < image_idx:
82+
return idx
83+
return len(image_idxs)+1
84+
85+
idx = first_available_image_idx()
86+
return PackURI('/ppt/media/image%d.%s' % (idx, ext))
7487

7588
@property
7689
def presentation(self):

‎tests/test_package.py

+29
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
from pptx.opc.constants import RELATIONSHIP_TYPE as RT
1212
from pptx.opc.package import Part, _Relationship
13+
from pptx.opc.packuri import PackURI
1314
from pptx.package import _ImageParts, Package
1415
from pptx.parts.coreprops import CoreProperties
1516
from pptx.parts.image import Image, ImagePart
@@ -71,6 +72,11 @@ def it_can_save_itself_to_a_pptx_file(self, temp_pptx_path):
7172
assert slide_layouts is not None
7273
assert len(slide_layouts) == 11
7374

75+
def it_knows_the_next_available_image_partname(self, next_fixture):
76+
package, ext, expected_value = next_fixture
77+
partname = package.next_image_partname(ext)
78+
assert partname == expected_value
79+
7480
# fixtures ---------------------------------------------
7581

7682
@pytest.fixture
@@ -80,6 +86,19 @@ def image_part_fixture(self, _image_parts_, image_part_):
8086
package._image_parts.get_or_add_image_part.return_value = image_part_
8187
return package, image_file, image_part_
8288

89+
@pytest.fixture(params=[
90+
((3, 4, 2), 1),
91+
((4, 2, 1), 3),
92+
((2, 3, 1), 4),
93+
])
94+
def next_fixture(self, request, iter_parts_):
95+
idxs, idx = request.param
96+
package = Package()
97+
package.iter_parts.return_value = self.i_image_parts(request, idxs)
98+
ext = 'foo'
99+
expected_value = '/ppt/media/image%d.%s' % (idx, ext)
100+
return package, ext, expected_value
101+
83102
@pytest.fixture
84103
def temp_pptx_path(self, tmpdir):
85104
return absjoin(str(tmpdir), 'test-pptx.pptx')
@@ -94,6 +113,16 @@ def image_part_(self, request):
94113
def _image_parts_(self, request):
95114
return property_mock(request, Package, '_image_parts')
96115

116+
def i_image_parts(self, request, idxs):
117+
def part(idx):
118+
partname = PackURI('/ppt/media/image%d.png' % idx)
119+
return instance_mock(request, Part, partname=partname)
120+
return iter([part(idx) for idx in idxs])
121+
122+
@pytest.fixture
123+
def iter_parts_(self, request):
124+
return property_mock(request, Package, 'iter_parts')
125+
97126

98127
class Describe_ImageParts(object):
99128

0 commit comments

Comments
 (0)
Please sign in to comment.