mirror of
https://github.com/jazzband/django-avatar.git
synced 2026-03-16 22:20:30 +00:00
* feat: add libravatar support (#114) and format * feat: add documentation for libravatar * fix(gh-actions): remove support for 3.6 and add 3.11 3.6 reached EOL: https://devguide.python.org/versions/ I also refactored the matrix by removing duplicated code * fix(deps): add missing dnspython * feat(deps): add requirements.txt * fix(gh-actions): install deps * chore(deps): add pyproject.toml See https://github.com/pypa/pip/issues/8559 * fix(gh-actions): add fail-fast so all checks run * fix(deps): bump coverage to 7.1.0 * fix(pre-commit): update versions * fix(pre-commit): config error * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * style: update code for passing flake * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: 0xMRTT <0xMRTT@evta.fr> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
675315b33c
commit
8034665e6b
12 changed files with 93 additions and 29 deletions
26
.github/workflows/test.yml
vendored
26
.github/workflows/test.yml
vendored
|
|
@ -5,29 +5,13 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
|
python-version: ['3.8', '3.9', '3.10', '3.11']
|
||||||
|
django-version: ['3.2', '4.0', '4.1']
|
||||||
include:
|
include:
|
||||||
- python-version: 3.6
|
|
||||||
django-version: 3.2
|
|
||||||
- python-version: 3.7
|
- python-version: 3.7
|
||||||
django-version: 3.2
|
django-version: 3.2
|
||||||
- python-version: 3.8
|
fail-fast: false
|
||||||
django-version: 3.2
|
|
||||||
- python-version: 3.9
|
|
||||||
django-version: 3.2
|
|
||||||
- python-version: '3.10'
|
|
||||||
django-version: 3.2
|
|
||||||
- python-version: 3.8
|
|
||||||
django-version: 4.0
|
|
||||||
- python-version: 3.9
|
|
||||||
django-version: 4.0
|
|
||||||
- python-version: '3.10'
|
|
||||||
django-version: 4.0
|
|
||||||
- python-version: 3.8
|
|
||||||
django-version: 4.1
|
|
||||||
- python-version: 3.9
|
|
||||||
django-version: 4.1
|
|
||||||
- python-version: '3.10'
|
|
||||||
django-version: 4.1
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: 'Set up Python ${{ matrix.python-version }}'
|
- name: 'Set up Python ${{ matrix.python-version }}'
|
||||||
|
|
@ -37,7 +21,7 @@ jobs:
|
||||||
cache: 'pip'
|
cache: 'pip'
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
pip install -e .
|
pip install -r requirements.txt
|
||||||
pip install -r tests/requirements.txt
|
pip install -r tests/requirements.txt
|
||||||
pip install "Django~=${{ matrix.django-version }}.0" .
|
pip install "Django~=${{ matrix.django-version }}.0" .
|
||||||
- name: Run Tests
|
- name: Run Tests
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,24 @@
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v4.3.0
|
rev: v4.4.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: end-of-file-fixer
|
- id: end-of-file-fixer
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
|
|
||||||
- repo: https://github.com/pycqa/isort
|
- repo: https://github.com/pycqa/isort
|
||||||
rev: "5.10.1"
|
rev: "5.12.0"
|
||||||
hooks:
|
hooks:
|
||||||
- id: isort
|
- id: isort
|
||||||
args: ["--profile", "black"]
|
args: ["--profile", "black"]
|
||||||
|
|
||||||
- repo: https://github.com/psf/black
|
- repo: https://github.com/psf/black
|
||||||
rev: 22.10.0
|
rev: 23.1.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
args: [--target-version=py310]
|
args: [--target-version=py310]
|
||||||
|
|
||||||
- repo: https://github.com/pycqa/flake8
|
- repo: https://github.com/pycqa/flake8
|
||||||
rev: '5.0.4'
|
rev: '6.0.0'
|
||||||
hooks:
|
hooks:
|
||||||
- id: flake8
|
- id: flake8
|
||||||
additional_dependencies:
|
additional_dependencies:
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ class AvatarConf(AppConf):
|
||||||
DELETE_TEMPLATE = ""
|
DELETE_TEMPLATE = ""
|
||||||
PROVIDERS = (
|
PROVIDERS = (
|
||||||
"avatar.providers.PrimaryAvatarProvider",
|
"avatar.providers.PrimaryAvatarProvider",
|
||||||
|
"avatar.providers.LibRAvatarProvider",
|
||||||
"avatar.providers.GravatarAvatarProvider",
|
"avatar.providers.GravatarAvatarProvider",
|
||||||
"avatar.providers.DefaultAvatarProvider",
|
"avatar.providers.DefaultAvatarProvider",
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import avatar.models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import avatar.models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("avatar", "0001_initial"),
|
("avatar", "0001_initial"),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import avatar.models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("avatar", "0002_add_verbose_names_to_avatar_fields"),
|
("avatar", "0002_add_verbose_names_to_avatar_fields"),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
import hashlib
|
import hashlib
|
||||||
|
import re
|
||||||
from urllib.parse import urlencode, urljoin
|
from urllib.parse import urlencode, urljoin
|
||||||
|
|
||||||
|
import dns.resolver
|
||||||
from django.utils.module_loading import import_string
|
from django.utils.module_loading import import_string
|
||||||
|
|
||||||
from avatar.conf import settings
|
from avatar.conf import settings
|
||||||
|
|
@ -64,6 +66,31 @@ class GravatarAvatarProvider(object):
|
||||||
return urljoin(settings.AVATAR_GRAVATAR_BASE_URL, path)
|
return urljoin(settings.AVATAR_GRAVATAR_BASE_URL, path)
|
||||||
|
|
||||||
|
|
||||||
|
class LibRAvatarProvider:
|
||||||
|
"""
|
||||||
|
Returns the url of an avatar by the Ravatar service.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_avatar_url(cls, user, width, _height=None):
|
||||||
|
email = getattr(user, settings.AVATAR_GRAVATAR_FIELD).encode("utf-8")
|
||||||
|
_, domain = email.split(b"@")
|
||||||
|
try:
|
||||||
|
answers = dns.resolver.query("_avatars._tcp." + domain, "SRV")
|
||||||
|
hostname = re.sub(r"\.$", "", str(answers[0].target))
|
||||||
|
# query returns "example.com." and while http requests are fine with this,
|
||||||
|
# https most certainly do not consider "example.com." and "example.com" to be the same.
|
||||||
|
port = str(answers[0].port)
|
||||||
|
if port == "443":
|
||||||
|
baseurl = "https://" + hostname + "/avatar/"
|
||||||
|
else:
|
||||||
|
baseurl = "http://" + hostname + ":" + port + "/avatar/"
|
||||||
|
except Exception:
|
||||||
|
baseurl = "https://seccdn.libravatar.org/avatar/"
|
||||||
|
hash = hashlib.md5(email.strip().lower()).hexdigest()
|
||||||
|
return baseurl + hash
|
||||||
|
|
||||||
|
|
||||||
class FacebookAvatarProvider(object):
|
class FacebookAvatarProvider(object):
|
||||||
"""
|
"""
|
||||||
Returns the url of a Facebook profile image.
|
Returns the url of a Facebook profile image.
|
||||||
|
|
|
||||||
|
|
@ -180,6 +180,7 @@ appear on the site. Listed below are those settings:
|
||||||
|
|
||||||
(
|
(
|
||||||
'avatar.providers.PrimaryAvatarProvider',
|
'avatar.providers.PrimaryAvatarProvider',
|
||||||
|
'avatar.providers.LibRAvatarProvider',
|
||||||
'avatar.providers.GravatarAvatarProvider',
|
'avatar.providers.GravatarAvatarProvider',
|
||||||
'avatar.providers.DefaultAvatarProvider',
|
'avatar.providers.DefaultAvatarProvider',
|
||||||
)
|
)
|
||||||
|
|
|
||||||
50
pyproject.toml
Normal file
50
pyproject.toml
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
[tool.poetry]
|
||||||
|
name = "django-avatar"
|
||||||
|
version = "7.0.1"
|
||||||
|
description = "A Django app for handling user avatars"
|
||||||
|
authors = ["Eric Florenzano <floguy@gmail.com>"]
|
||||||
|
maintainers = ["Johannes Wilm <johannes@fiduswriter.org>"]
|
||||||
|
license = "BSD-4-Clause"
|
||||||
|
readme = "README.rst"
|
||||||
|
packages = [
|
||||||
|
{ include = "avatar" },
|
||||||
|
]
|
||||||
|
exclude = [
|
||||||
|
{ path = "tests"},
|
||||||
|
]
|
||||||
|
homepage = "https://github.com/jazzband/django-avatar"
|
||||||
|
repository = "https://github.com/jazzband/django-avatar"
|
||||||
|
documentation = "https://django-avatar.readthedocs.io"
|
||||||
|
keywords=["avatar", "django"]
|
||||||
|
classifiers=[
|
||||||
|
"Development Status :: 5 - Production/Stable",
|
||||||
|
"Environment :: Web Environment",
|
||||||
|
"Framework :: Django",
|
||||||
|
"Intended Audience :: Developers",
|
||||||
|
"Framework :: Django",
|
||||||
|
"Framework :: Django :: 3.2",
|
||||||
|
"Framework :: Django :: 4.0",
|
||||||
|
"Framework :: Django :: 4.1",
|
||||||
|
"License :: OSI Approved :: BSD License",
|
||||||
|
"Operating System :: OS Independent",
|
||||||
|
"Programming Language :: Python",
|
||||||
|
"Programming Language :: Python :: 3.6",
|
||||||
|
"Programming Language :: Python :: 3.7",
|
||||||
|
"Programming Language :: Python :: 3.8",
|
||||||
|
"Programming Language :: Python :: 3.9",
|
||||||
|
"Programming Language :: Python :: 3.10",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.poetry.dependencies]
|
||||||
|
python = "^3.7"
|
||||||
|
Pillow = "^9.4.0"
|
||||||
|
django-appconf = "^1.0.5"
|
||||||
|
dnspython = "^2.3.0"
|
||||||
|
|
||||||
|
[tool.poetry.group.dev.dependencies]
|
||||||
|
coverage = "^7.1.0"
|
||||||
|
python-magic = "^0.4.27"
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["poetry-core"]
|
||||||
|
build-backend = "poetry.core.masonry.api"
|
||||||
3
requirements.txt
Normal file
3
requirements.txt
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
Pillow>=8.4.0
|
||||||
|
django-appconf>=1.0.5
|
||||||
|
dnspython>=2.3.0
|
||||||
1
setup.py
1
setup.py
|
|
@ -61,6 +61,7 @@ setup(
|
||||||
install_requires=[
|
install_requires=[
|
||||||
"Pillow>=8.4.0",
|
"Pillow>=8.4.0",
|
||||||
"django-appconf>=1.0.5",
|
"django-appconf>=1.0.5",
|
||||||
|
"dnspython>=2.3.0",
|
||||||
],
|
],
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
coverage==6.2
|
coverage==7.1.0
|
||||||
django
|
django
|
||||||
python-magic
|
python-magic
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue