Skip to content

Commit

Permalink
Merge pull request #13 from dave-shawley/link-formatting
Browse files Browse the repository at this point in the history
Add formatting for Link headers
  • Loading branch information
dave-shawley committed Jul 4, 2017
2 parents 3d28d7d + c5c6335 commit e84f5de
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 0 deletions.
7 changes: 7 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ Changelog

.. py:currentmodule:: ietfparse
* `Next Release`_

- Add formatting of HTTP `Link`_ header using ``str(header)``.

* `1.4.1`_ (03-Apr-2017)

- Add some documentation about exceptions raised during header parsing.
Expand Down Expand Up @@ -75,6 +79,7 @@ Changelog
.. _Accept-Encoding: https://tools.ietf.org/html/rfc7231#section-5.3.4
.. _Accept-Language: https://tools.ietf.org/html/rfc7231#section-5.3.5
.. _Cache-Control: https://tools.ietf.org/html/rfc7231#section-5.2
.. _Link: https://tools.ietf.org/html/rfc5988

.. _1.1.0: https://github.com/dave-shawley/ietfparse/compare/1.0.0...1.1.0
.. _1.1.1: https://github.com/dave-shawley/ietfparse/compare/1.1.0...1.1.1
Expand All @@ -83,3 +88,5 @@ Changelog
.. _1.2.2: https://github.com/dave-shawley/ietfparse/compare/1.2.1...1.2.2
.. _1.3.0: https://github.com/dave-shawley/ietfparse/compare/1.2.2...1.3.0
.. _1.4.0: https://github.com/dave-shawley/ietfparse/compare/1.3.0...1.4.0
.. _1.4.1: https://github.com/dave-shawley/ietfparse/compare/1.4.0...1.4.1
.. _Next Release: https://github.com/dave-shawley/ietfparse/compare/1.4.1...head
5 changes: 5 additions & 0 deletions docs/header-parsing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ described in :rfc:`5988` into a sequence of
'http://example.com/TheBook/chapter2'
>>> parsed[0].parameters
[('rel', 'previous'), ('title', 'previous chapter')]
>>> str(parsed[0])
'<http://example.com/TheBook/chapter2>; rel="previous"; title="previous chapter"'

Notice that the parameter values are returned as a list of name and value
tuples. This is by design and required by the RFC to support the
Expand All @@ -186,3 +188,6 @@ tuples. This is by design and required by the RFC to support the
following the link. Multiple "hreflang" parameters on a single link-
value indicate that multiple languages are available from the
indicated resource.

Also note that you can cast a :class:`ietfparse.datastructures.LinkHeader`
instance to a string to get a correctly formatted representation of it.
14 changes: 14 additions & 0 deletions ietfparse/datastructures.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,17 @@ class LinkHeader(object):
def __init__(self, target, parameters=None):
self.target = target
self.parameters = parameters or []

def __str__(self):
formatted = '<{0}>'.format(self.target)
if self.parameters:
params = ['{0}="{1}"'.format(*pair)
for pair in self.parameters if pair[0] != 'rel']
params = '; '.join(sorted(params))
rel = ['{0}="{1}"'.format(*pair)
for pair in self.parameters if pair[0] == 'rel']
if rel:
formatted += '; ' + rel[0]
if params:
formatted += '; ' + params
return formatted
23 changes: 23 additions & 0 deletions tests/headers_link_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,26 @@ def test_that_semantic_tests_can_be_turned_off(self):
strict=False,
)
self.assertEqual(len(parsed), 3)


class WhenFormattingLinkHeader(unittest.TestCase):

def test_that_parameters_are_sorted_after_rel(self):
parsed = headers.parse_link('<http://example.com>; title="foo";'
' rel="next"; hreflang="en"')
self.assertEqual(str(parsed[0]),
'<http://example.com>; rel="next"; hreflang="en";'
' title="foo"')

def test_that_rel_is_not_required(self):
parsed = headers.parse_link('<>')
self.assertEqual(str(parsed[0]), '<>')

def test_that_only_first_rel_is_used(self):
parsed = headers.parse_link('<>; rel=used; rel=first; rel=one')
self.assertEqual(str(parsed[0]), '<>; rel="used"')

def test_that_parameters_are_sorted_without_rel(self):
parsed = headers.parse_link('<>; title=foo; hreflang="en"')
self.assertEqual(str(parsed[0]),
'<>; hreflang="en"; title="foo"')

0 comments on commit e84f5de

Please sign in to comment.