Skip to content

Commit da3afb4

Browse files
author
Steve Canny
committed
add PackURI value type
1 parent 1d6cf3f commit da3afb4

2 files changed

Lines changed: 134 additions & 0 deletions

File tree

opc/packuri.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# packuri.py
4+
#
5+
# Copyright (C) 2012, 2013 Steve Canny scanny@cisco.com
6+
#
7+
# This module is part of python-opc and is released under the MIT License:
8+
# http://www.opensource.org/licenses/mit-license.php
9+
10+
"""
11+
Provides the PackURI value type along with some useful known values such as
12+
PACKAGE_URI.
13+
"""
14+
15+
import posixpath
16+
17+
18+
class PackURI(str):
19+
"""
20+
Provides access to pack URI components such as the baseURI and the
21+
filename slice. Behaves as |str| otherwise.
22+
"""
23+
def __new__(cls, pack_uri_str):
24+
if not pack_uri_str[0] == '/':
25+
tmpl = "PackURI must begin with slash, got '%s'"
26+
raise ValueError(tmpl % pack_uri_str)
27+
return str.__new__(cls, pack_uri_str)
28+
29+
@property
30+
def baseURI(self):
31+
"""
32+
The base URI of this pack URI, the directory portion, roughly
33+
speaking. E.g. ``'/ppt/slides'`` for ``'/ppt/slides/slide1.xml'``.
34+
For the package pseudo-partname '/', baseURI is '/'.
35+
"""
36+
return posixpath.split(self)[0]
37+
38+
@property
39+
def filename(self):
40+
"""
41+
The "filename" portion of this pack URI, e.g. ``'slide1.xml'`` for
42+
``'/ppt/slides/slide1.xml'``. For the package pseudo-partname '/',
43+
filename is ''.
44+
"""
45+
return posixpath.split(self)[1]
46+
47+
@property
48+
def membername(self):
49+
"""
50+
The pack URI with the leading slash stripped off, the form used as
51+
the Zip file membername for the package item. Returns '' for the
52+
package pseudo-partname '/'.
53+
"""
54+
return self[1:]
55+
56+
@property
57+
def rels_uri(self):
58+
"""
59+
The pack URI of the .rels part corresponding to the current pack URI.
60+
Only produces sensible output if the pack URI is a partname or the
61+
package pseudo-partname '/'.
62+
"""
63+
rels_filename = '%s.rels' % self.filename
64+
rels_uri_str = posixpath.join(self.baseURI, '_rels', rels_filename)
65+
return PackURI(rels_uri_str)
66+
67+
68+
PACKAGE_URI = PackURI('/')
69+
CONTENT_TYPES_URI = PackURI('/[Content_Types].xml')

tests/test_packuri.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# test_packuri.py
4+
#
5+
# Copyright (C) 2013 Steve Canny scanny@cisco.com
6+
#
7+
# This module is part of python-pptx and is released under the MIT License:
8+
# http://www.opensource.org/licenses/mit-license.php
9+
10+
"""Test suite for opc.packuri module."""
11+
12+
import pytest
13+
14+
from opc.packuri import PackURI
15+
16+
17+
class DescribePackURI(object):
18+
19+
def cases(self, expected_values):
20+
"""
21+
Return list of tuples zipped from uri_str cases and
22+
*expected_values*. Raise if lengths don't match.
23+
"""
24+
uri_str_cases = [
25+
'/',
26+
'/ppt/presentation.xml',
27+
'/ppt/slides/slide1.xml',
28+
]
29+
if len(expected_values) != len(uri_str_cases):
30+
msg = "len(expected_values) differs from len(uri_str_cases)"
31+
raise AssertionError(msg)
32+
pack_uris = [PackURI(uri_str) for uri_str in uri_str_cases]
33+
return zip(pack_uris, expected_values)
34+
35+
def it_should_raise_on_construct_with_bad_pack_uri_str(self):
36+
with pytest.raises(ValueError):
37+
PackURI('foobar')
38+
39+
def it_can_calculate_baseURI(self):
40+
expected_values = ('/', '/ppt', '/ppt/slides')
41+
for pack_uri, expected_baseURI in self.cases(expected_values):
42+
assert pack_uri.baseURI == expected_baseURI
43+
44+
def it_can_calculate_filename(self):
45+
expected_values = ('', 'presentation.xml', 'slide1.xml')
46+
for pack_uri, expected_filename in self.cases(expected_values):
47+
assert pack_uri.filename == expected_filename
48+
49+
def it_can_calculate_membername(self):
50+
expected_values = (
51+
'',
52+
'ppt/presentation.xml',
53+
'ppt/slides/slide1.xml',
54+
)
55+
for pack_uri, expected_membername in self.cases(expected_values):
56+
assert pack_uri.membername == expected_membername
57+
58+
def it_can_calculate_rels_uri(self):
59+
expected_values = (
60+
'/_rels/.rels',
61+
'/ppt/_rels/presentation.xml.rels',
62+
'/ppt/slides/_rels/slide1.xml.rels',
63+
)
64+
for pack_uri, expected_rels_uri in self.cases(expected_values):
65+
assert pack_uri.rels_uri == expected_rels_uri

0 commit comments

Comments
 (0)