|
9 | 9 |
|
10 | 10 | from .compat import cls_method_fn |
11 | 11 | from .constants import RELATIONSHIP_TYPE as RT |
12 | | -from .oxml import CT_Relationships, serialize_part_xml |
| 12 | +from .oxml import serialize_part_xml |
13 | 13 | from ..oxml import parse_xml |
14 | 14 | from .packuri import PACKAGE_URI, PackURI |
15 | 15 | from .pkgreader import PackageReader |
16 | 16 | from .pkgwriter import PackageWriter |
| 17 | +from .rel import Relationships |
17 | 18 | from .shared import lazyproperty |
18 | 19 |
|
19 | 20 |
|
@@ -386,126 +387,6 @@ def _part_cls_for(cls, content_type): |
386 | 387 | return cls.default_part_type |
387 | 388 |
|
388 | 389 |
|
389 | | -class Relationships(dict): |
390 | | - """ |
391 | | - Collection object for |_Relationship| instances, having list semantics. |
392 | | - """ |
393 | | - def __init__(self, baseURI): |
394 | | - super(Relationships, self).__init__() |
395 | | - self._baseURI = baseURI |
396 | | - self._target_parts_by_rId = {} |
397 | | - |
398 | | - def add_relationship(self, reltype, target, rId, is_external=False): |
399 | | - """ |
400 | | - Return a newly added |_Relationship| instance. |
401 | | - """ |
402 | | - rel = _Relationship(rId, reltype, target, self._baseURI, is_external) |
403 | | - self[rId] = rel |
404 | | - if not is_external: |
405 | | - self._target_parts_by_rId[rId] = target |
406 | | - return rel |
407 | | - |
408 | | - def get_or_add(self, reltype, target_part): |
409 | | - """ |
410 | | - Return relationship of *reltype* to *target_part*, newly added if not |
411 | | - already present in collection. |
412 | | - """ |
413 | | - rel = self._get_matching(reltype, target_part) |
414 | | - if rel is None: |
415 | | - rId = self._next_rId |
416 | | - rel = self.add_relationship(reltype, target_part, rId) |
417 | | - return rel |
418 | | - |
419 | | - def get_or_add_ext_rel(self, reltype, target_ref): |
420 | | - """ |
421 | | - Return rId of external relationship of *reltype* to *target_ref*, |
422 | | - newly added if not already present in collection. |
423 | | - """ |
424 | | - rel = self._get_matching(reltype, target_ref, is_external=True) |
425 | | - if rel is None: |
426 | | - rId = self._next_rId |
427 | | - rel = self.add_relationship( |
428 | | - reltype, target_ref, rId, is_external=True |
429 | | - ) |
430 | | - return rel.rId |
431 | | - |
432 | | - def part_with_reltype(self, reltype): |
433 | | - """ |
434 | | - Return target part of rel with matching *reltype*, raising |KeyError| |
435 | | - if not found and |ValueError| if more than one matching relationship |
436 | | - is found. |
437 | | - """ |
438 | | - rel = self._get_rel_of_type(reltype) |
439 | | - return rel.target_part |
440 | | - |
441 | | - @property |
442 | | - def related_parts(self): |
443 | | - """ |
444 | | - dict mapping rIds to target parts for all the internal relationships |
445 | | - in the collection. |
446 | | - """ |
447 | | - return self._target_parts_by_rId |
448 | | - |
449 | | - @property |
450 | | - def xml(self): |
451 | | - """ |
452 | | - Serialize this relationship collection into XML suitable for storage |
453 | | - as a .rels file in an OPC package. |
454 | | - """ |
455 | | - rels_elm = CT_Relationships.new() |
456 | | - for rel in self.values(): |
457 | | - rels_elm.add_rel( |
458 | | - rel.rId, rel.reltype, rel.target_ref, rel.is_external |
459 | | - ) |
460 | | - return rels_elm.xml |
461 | | - |
462 | | - def _get_matching(self, reltype, target, is_external=False): |
463 | | - """ |
464 | | - Return relationship of matching *reltype*, *target*, and |
465 | | - *is_external* from collection, or None if not found. |
466 | | - """ |
467 | | - def matches(rel, reltype, target, is_external): |
468 | | - if rel.reltype != reltype: |
469 | | - return False |
470 | | - if rel.is_external != is_external: |
471 | | - return False |
472 | | - rel_target = rel.target_ref if rel.is_external else rel.target_part |
473 | | - if rel_target != target: |
474 | | - return False |
475 | | - return True |
476 | | - |
477 | | - for rel in self.values(): |
478 | | - if matches(rel, reltype, target, is_external): |
479 | | - return rel |
480 | | - return None |
481 | | - |
482 | | - def _get_rel_of_type(self, reltype): |
483 | | - """ |
484 | | - Return single relationship of type *reltype* from the collection. |
485 | | - Raises |KeyError| if no matching relationship is found. Raises |
486 | | - |ValueError| if more than one matching relationship is found. |
487 | | - """ |
488 | | - matching = [rel for rel in self.values() if rel.reltype == reltype] |
489 | | - if len(matching) == 0: |
490 | | - tmpl = "no relationship of type '%s' in collection" |
491 | | - raise KeyError(tmpl % reltype) |
492 | | - if len(matching) > 1: |
493 | | - tmpl = "multiple relationships of type '%s' in collection" |
494 | | - raise ValueError(tmpl % reltype) |
495 | | - return matching[0] |
496 | | - |
497 | | - @property |
498 | | - def _next_rId(self): |
499 | | - """ |
500 | | - Next available rId in collection, starting from 'rId1' and making use |
501 | | - of any gaps in numbering, e.g. 'rId2' for rIds ['rId1', 'rId3']. |
502 | | - """ |
503 | | - for n in range(1, len(self)+2): |
504 | | - rId_candidate = 'rId%d' % n # like 'rId19' |
505 | | - if rId_candidate not in self: |
506 | | - return rId_candidate |
507 | | - |
508 | | - |
509 | 390 | class Unmarshaller(object): |
510 | 391 | """ |
511 | 392 | Hosts static methods for unmarshalling a package from a |PackageReader| |
@@ -552,42 +433,3 @@ def _unmarshal_relationships(pkg_reader, package, parts): |
552 | 433 | target = (srel.target_ref if srel.is_external |
553 | 434 | else parts[srel.target_partname]) |
554 | 435 | source.load_rel(srel.reltype, target, srel.rId, srel.is_external) |
555 | | - |
556 | | - |
557 | | -class _Relationship(object): |
558 | | - """ |
559 | | - Value object for relationship to part. |
560 | | - """ |
561 | | - def __init__(self, rId, reltype, target, baseURI, external=False): |
562 | | - super(_Relationship, self).__init__() |
563 | | - self._rId = rId |
564 | | - self._reltype = reltype |
565 | | - self._target = target |
566 | | - self._baseURI = baseURI |
567 | | - self._is_external = bool(external) |
568 | | - |
569 | | - @property |
570 | | - def is_external(self): |
571 | | - return self._is_external |
572 | | - |
573 | | - @property |
574 | | - def reltype(self): |
575 | | - return self._reltype |
576 | | - |
577 | | - @property |
578 | | - def rId(self): |
579 | | - return self._rId |
580 | | - |
581 | | - @property |
582 | | - def target_part(self): |
583 | | - if self._is_external: |
584 | | - raise ValueError("target_part property on _Relationship is undef" |
585 | | - "ined when target mode is External") |
586 | | - return self._target |
587 | | - |
588 | | - @property |
589 | | - def target_ref(self): |
590 | | - if self._is_external: |
591 | | - return self._target |
592 | | - else: |
593 | | - return self._target.partname.relative_ref(self._baseURI) |
0 commit comments