/usr/lib/python2.7/dist-packages/openpyxl/packaging/relationship.py is in python-openpyxl 2.4.9-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | from __future__ import absolute_import
# Copyright (c) 2010-2017 openpyxl
import posixpath
from openpyxl.descriptors import (
String,
Set,
NoneSet,
Alias,
Sequence,
)
from openpyxl.descriptors.serialisable import Serialisable
from openpyxl.xml.constants import REL_NS, PKG_REL_NS
from openpyxl.xml.functions import (
Element,
fromstring,
tostring
)
class Relationship(Serialisable):
"""Represents many kinds of relationships."""
tagname = "Relationship"
Type = String()
Target = String()
target = Alias("Target")
TargetMode = String(allow_none=True)
Id = String(allow_none=True)
id = Alias("Id")
def __init__(self,
Id=None,
Type=None,
type=None,
Target=None,
TargetMode=None
):
"""
`type` can be used as a shorthand with the default relationships namespace
otherwise the `Type` must be a fully qualified URL
"""
if type is not None:
Type = "{0}/{1}".format(REL_NS, type)
self.Type = Type
self.Target = Target
self.TargetMode = TargetMode
self.Id = Id
class RelationshipList(Serialisable):
tagname = "Relationships"
Relationship = Sequence(expected_type=Relationship)
def __init__(self, Relationship=()):
self.Relationship = Relationship
def append(self, value):
values = self.Relationship[:]
values.append(value)
if not value.Id:
value.Id = "rId{0}".format((len(values)))
self.Relationship = values
def __len__(self):
return len(self.Relationship)
def __bool__(self):
return bool(self.Relationship)
def find(self, content_type):
"""
Find relationships by content-type
NB. these content-types namespaced objects and different to the MIME-types
in the package manifest :-(
"""
for r in self.Relationship:
if r.Type == content_type:
yield r
def __getitem__(self, key):
for r in self.Relationship:
if r.Id == key:
return r
raise KeyError("Unknown relationship: {0}".format(key))
def to_tree(self):
tree = Element("Relationships", xmlns=PKG_REL_NS)
for idx, rel in enumerate(self.Relationship, 1):
if not rel.Id:
rel.Id = "rId{0}".format(idx)
tree.append(rel.to_tree())
return tree
def get_rels_path(path):
"""
Convert relative path to absolutes that can be loaded from a zip
archive.
The path to be passed in is that of containing object (workbook,
worksheet, etc.)
"""
folder, obj = posixpath.split(path)
filename = posixpath.join(folder, '_rels', '{0}.rels'.format(obj))
return filename
def get_dependents(archive, filename):
"""
Normalise dependency file paths to absolute ones
Relative paths are relative to parent object
"""
src = archive.read(filename)
node = fromstring(src)
rels = RelationshipList.from_tree(node)
folder = posixpath.dirname(filename)
parent = posixpath.split(folder)[0]
for r in rels.Relationship:
if r.TargetMode == "External":
continue
elif r.target.startswith("/"):
r.target = r.target[1:]
else:
pth = posixpath.join(parent, r.target)
r.target = posixpath.normpath(pth)
return rels
|