| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 13e928f commit aa84f3b
9 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -33,6 +33,28 @@ def after_unmarshal(self): | |||
| 33 | 33 | # subclass | |
| 34 | 34 | pass | |
| 35 | 35 | ||
| 36 | + def iter_rels(self): | ||
| 37 | + """ | ||
| 38 | + Generate exactly one reference to each relationship in the package by | ||
| 39 | + performing a depth-first traversal of the rels graph. | ||
| 40 | + """ | ||
| 41 | + def walk_rels(source, visited=None): | ||
| 42 | + visited = [] if visited is None else visited | ||
| 43 | + for rel in source.rels.values(): | ||
| 44 | + yield rel | ||
| 45 | + if rel.is_external: | ||
| 46 | + continue | ||
| 47 | + part = rel.target_part | ||
| 48 | + if part in visited: | ||
| 49 | + continue | ||
| 50 | + visited.append(part) | ||
| 51 | + new_source = part | ||
| 52 | + for rel in walk_rels(new_source, visited): | ||
| 53 | + yield rel | ||
| 54 | + | ||
| 55 | + for rel in walk_rels(self): | ||
| 56 | + yield rel | ||
| 57 | + | ||
| 36 | 58 | def iter_parts(self): | |
| 37 | 59 | """ | |
| 38 | 60 | Generate exactly one reference to each of the parts in the package by | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -6,25 +6,61 @@ | |||
| 6 | 6 | ||
| 7 | 7 | from __future__ import absolute_import, print_function, unicode_literals | |
| 8 | 8 | ||
| 9 | + from docx.opc.constants import RELATIONSHIP_TYPE as RT | ||
| 9 | 10 | from docx.opc.package import OpcPackage | |
| 11 | + from docx.shared import lazyproperty | ||
| 10 | 12 | ||
| 11 | 13 | ||
| 12 | 14 | class Package(OpcPackage): | |
| 13 | 15 | """ | |
| 14 | 16 | Customizations specific to a WordprocessingML package. | |
| 15 | 17 | """ | |
| 16 | - @property | ||
| 18 | + def after_unmarshal(self): | ||
| 19 | + """ | ||
| 20 | + Called by loading code after all parts and relationships have been | ||
| 21 | + loaded, to afford the opportunity for any required post-processing. | ||
| 22 | + """ | ||
| 23 | + self._gather_image_parts() | ||
| 24 | + | ||
| 25 | + @lazyproperty | ||
| 17 | 26 | def image_parts(self): | |
| 18 | 27 | """ | |
| 19 | 28 | Collection of all image parts in this package. | |
| 20 | 29 | """ | |
| 30 | + return ImageParts() | ||
| 31 | + | ||
| 32 | + def _gather_image_parts(self): | ||
| 33 | + """ | ||
| 34 | + Load the image part collection with all the image parts in package. | ||
| 35 | + """ | ||
| 36 | + for rel in self.iter_rels(): | ||
| 37 | + if rel.is_external: | ||
| 38 | + continue | ||
| 39 | + if rel.reltype != RT.IMAGE: | ||
| 40 | + continue | ||
| 41 | + if rel.target_part in self.image_parts: | ||
| 42 | + continue | ||
| 43 | + self.image_parts.append(rel.target_part) | ||
| 21 | 44 | ||
| 22 | 45 | ||
| 23 | 46 | class ImageParts(object): | |
| 24 | 47 | """ | |
| 25 | 48 | Collection of |ImagePart| instances containing all the image parts in the | |
| 26 | 49 | package. | |
| 27 | 50 | """ | |
| 51 | + def __init__(self): | ||
| 52 | + super(ImageParts, self).__init__() | ||
| 53 | + self._image_parts = [] | ||
| 54 | + | ||
| 55 | + def __contains__(self, item): | ||
| 56 | + return self._image_parts.__contains__(item) | ||
| 57 | + | ||
| 58 | + def __len__(self): | ||
| 59 | + return self._image_parts.__len__() | ||
| 60 | + | ||
| 61 | + def append(self, item): | ||
| 62 | + self._image_parts.append(item) | ||
| 63 | + | ||
| 28 | 64 | def get_or_add_image_part(self, image_descriptor): | |
| 29 | 65 | """ | |
| 30 | 66 | Return an |ImagePart| instance containing the image identified by | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,18 @@ | |||
| 1 | + # encoding: utf-8 | ||
| 2 | + | ||
| 3 | + """ | ||
| 4 | + Test suite for docx.package module | ||
| 5 | + """ | ||
| 6 | + | ||
| 7 | + from __future__ import absolute_import, print_function, unicode_literals | ||
| 8 | + | ||
| 9 | + from docx.package import Package | ||
| 10 | + | ||
| 11 | + from .unitutil import docx_path | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + class DescribePackage(object): | ||
| 15 | + | ||
| 16 | + def it_gathers_package_image_parts_after_unmarshalling(self): | ||
| 17 | + package = Package.open(docx_path('having-images')) | ||
| 18 | + assert len(package.image_parts) == 3 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -28,6 +28,18 @@ def absjoin(*paths): | |||
| 28 | 28 | return os.path.abspath(os.path.join(*paths)) | |
| 29 | 29 | ||
| 30 | 30 | ||
| 31 | + def docx_path(name): | ||
| 32 | + """ | ||
| 33 | + Return the absolute path to test .docx file with root name *name*. | ||
| 34 | + """ | ||
| 35 | + return absjoin(_thisdir, 'test_files', '%s.docx' % name) | ||
| 36 | + | ||
| 37 | + | ||
| 38 | + # =========================================================================== | ||
| 39 | + # pytest mocking helpers | ||
| 40 | + # =========================================================================== | ||
| 41 | + | ||
| 42 | + | ||
| 31 | 43 | def class_mock(request, q_class_name, autospec=True, **kwargs): | |
| 32 | 44 | """ | |
| 33 | 45 | Return a mock patching the class with qualified name *q_class_name*. | |
| Back | FazBrowse Home | New Git URL |
0 commit comments