Skip to content

Commit

Permalink
feat: display author name on details (pypi#12018)
Browse files Browse the repository at this point in the history
* feat: display author name on details

When using a valid RFC-822 identifier in `author-email` metadata,
display the name value and link to the email address.

Does not yet support multiple values in `author-email`.

Resolves pypi#11990

Signed-off-by: Mike Fiedler <miketheman@gmail.com>

* lint: add space

I think isort might be mis-identifying `email.utils` as non-stdlib.

Signed-off-by: Mike Fiedler <miketheman@gmail.com>

Co-authored-by: Dustin Ingram <di@users.noreply.github.com>
  • Loading branch information
miketheman and di committed Aug 8, 2022
1 parent c95be4a commit 637435d
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 1 deletion.
14 changes: 14 additions & 0 deletions tests/unit/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,17 @@ def test_is_recent(delta, expected):

def test_is_recent_none():
assert filters.is_recent(None) is False


@pytest.mark.parametrize(
("meta_email", "expected_name", "expected_email"),
[
("not-an-email-address", "", ""),
("foo@bar.com", "", "foo@bar.com"),
('"Foo Bar" <foo@bar.com>', "Foo Bar", "foo@bar.com"),
],
)
def test_format_author_email(meta_email, expected_name, expected_email):
author_name, author_email = filters.format_author_email(meta_email)
assert author_name == expected_name
assert author_email == expected_email
1 change: 1 addition & 0 deletions warehouse/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ def configure(settings=None):
filters.setdefault("localize_datetime", "warehouse.filters:localize_datetime")
filters.setdefault("is_recent", "warehouse.filters:is_recent")
filters.setdefault("canonicalize_name", "packaging.utils:canonicalize_name")
filters.setdefault("format_author_email", "warehouse.filters:format_author_email")

# We also want to register some global functions for Jinja
jglobals = config.get_settings().setdefault("jinja2.globals", {})
Expand Down
16 changes: 16 additions & 0 deletions warehouse/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import re
import urllib.parse

from email.utils import getaddresses

import html5lib
import html5lib.serializer
import html5lib.treewalkers
Expand Down Expand Up @@ -163,5 +165,19 @@ def is_recent(timestamp):
return False


def format_author_email(metadata_email: str) -> tuple[str, str]:
"""
Return the name and email address from a metadata RFC-822 string.
Use Jinja's `first` and `last` to access each part in a template.
TODO: Support more than one email address, per RFC-822.
"""
author_emails = []
for author_name, author_email in getaddresses([metadata_email]):
if "@" not in author_email:
return author_name, ""
author_emails.append((author_name, author_email))
return author_emails[0][0], author_emails[0][1]


def includeme(config):
config.add_request_method(_camo_url, name="camo_url")
2 changes: 1 addition & 1 deletion warehouse/templates/includes/packaging/project-data.html
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ <h3 class="sidebar-section__title">{% trans %}Meta{% endtrans %}</h3>
<p><strong>{% trans %}License:{% endtrans %}</strong> {{ license }}</p>
{% endif %}
{% if release.author_email %}
<p><strong>{% trans %}Author:{% endtrans %}</strong> <a href="mailto:{{ release.author_email }}">{{ release.author or release.author_email }}</a></p>
<p><strong>{% trans %}Author:{% endtrans %}</strong> <a href="mailto:{{ release.author_email|format_author_email|last }}">{{ release.author or release.author_email|format_author_email|first }}</a></p>
{% elif release.author %}
<p><strong>{% trans %}Author:{% endtrans %}</strong> {{ release.author }}</p>
{% endif %}
Expand Down

0 comments on commit 637435d

Please sign in to comment.