Initial working version with minor bugs
This commit is contained in:
parent
f946e4933a
commit
71b3993326
83 changed files with 34485 additions and 173 deletions
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.0.2 on 2024-02-19 12:10
|
||||
# Generated by Django 5.1.2 on 2025-02-26 08:04
|
||||
|
||||
import django.contrib.auth.models
|
||||
import django.contrib.auth.validators
|
||||
|
|
@ -18,92 +18,19 @@ class Migration(migrations.Migration):
|
|||
migrations.CreateModel(
|
||||
name='CustomUser',
|
||||
fields=[
|
||||
(
|
||||
'id',
|
||||
models.BigAutoField(
|
||||
auto_created=True, primary_key=True, serialize=False, verbose_name='ID'
|
||||
),
|
||||
),
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('password', models.CharField(max_length=128, verbose_name='password')),
|
||||
(
|
||||
'last_login',
|
||||
models.DateTimeField(blank=True, null=True, verbose_name='last login'),
|
||||
),
|
||||
(
|
||||
'is_superuser',
|
||||
models.BooleanField(
|
||||
default=False,
|
||||
help_text='Designates that this user has all permissions without explicitly assigning them.',
|
||||
verbose_name='superuser status',
|
||||
),
|
||||
),
|
||||
(
|
||||
'username',
|
||||
models.CharField(
|
||||
error_messages={'unique': 'A user with that username already exists.'},
|
||||
help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.',
|
||||
max_length=150,
|
||||
unique=True,
|
||||
validators=[django.contrib.auth.validators.UnicodeUsernameValidator()],
|
||||
verbose_name='username',
|
||||
),
|
||||
),
|
||||
(
|
||||
'first_name',
|
||||
models.CharField(blank=True, max_length=150, verbose_name='first name'),
|
||||
),
|
||||
(
|
||||
'last_name',
|
||||
models.CharField(blank=True, max_length=150, verbose_name='last name'),
|
||||
),
|
||||
(
|
||||
'email',
|
||||
models.EmailField(blank=True, max_length=254, verbose_name='email address'),
|
||||
),
|
||||
(
|
||||
'is_staff',
|
||||
models.BooleanField(
|
||||
default=False,
|
||||
help_text='Designates whether the user can log into this admin site.',
|
||||
verbose_name='staff status',
|
||||
),
|
||||
),
|
||||
(
|
||||
'is_active',
|
||||
models.BooleanField(
|
||||
default=True,
|
||||
help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.',
|
||||
verbose_name='active',
|
||||
),
|
||||
),
|
||||
(
|
||||
'date_joined',
|
||||
models.DateTimeField(
|
||||
default=django.utils.timezone.now, verbose_name='date joined'
|
||||
),
|
||||
),
|
||||
(
|
||||
'groups',
|
||||
models.ManyToManyField(
|
||||
blank=True,
|
||||
help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.',
|
||||
related_name='user_set',
|
||||
related_query_name='user',
|
||||
to='auth.group',
|
||||
verbose_name='groups',
|
||||
),
|
||||
),
|
||||
(
|
||||
'user_permissions',
|
||||
models.ManyToManyField(
|
||||
blank=True,
|
||||
help_text='Specific permissions for this user.',
|
||||
related_name='user_set',
|
||||
related_query_name='user',
|
||||
to='auth.permission',
|
||||
verbose_name='user permissions',
|
||||
),
|
||||
),
|
||||
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
|
||||
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
|
||||
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
|
||||
('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
|
||||
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
|
||||
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
|
||||
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
|
||||
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
|
||||
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
|
||||
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
|
||||
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'user',
|
||||
|
|
|
|||
70
accounts/templatetags/gravatar.py
Normal file
70
accounts/templatetags/gravatar.py
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
import hashlib
|
||||
from urllib.parse import urlencode
|
||||
import requests # Added to perform HTTP requests
|
||||
from django import template
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
register = template.Library()
|
||||
|
||||
@register.filter
|
||||
def gravatar_hash(email):
|
||||
"""
|
||||
Returns the hash of the email.
|
||||
"""
|
||||
email_encoded = email.strip().lower().encode('utf-8')
|
||||
email_hash = hashlib.sha256(email_encoded).hexdigest()
|
||||
return email_hash
|
||||
|
||||
@register.filter
|
||||
def gravatar_url(email, size=20):
|
||||
"""
|
||||
Returns the Gravatar URL for a given email. The URL includes parameters
|
||||
for the default image and the size.
|
||||
"""
|
||||
default = "wavatar"
|
||||
email_hash = gravatar_hash(email)
|
||||
params = urlencode({'d': default, 's': str(size)})
|
||||
return f"https://www.gravatar.com/avatar/{email_hash}?{params}"
|
||||
|
||||
def gravatar_profile_url(email=None):
|
||||
"""
|
||||
Returns the Gravatar Profile URL for a given email.
|
||||
"""
|
||||
if email is None:
|
||||
return f"https://www.gravatar.com/profile"
|
||||
email_hash = gravatar_hash(email)
|
||||
return f"https://secure.gravatar.com/{email_hash}"
|
||||
|
||||
@register.filter
|
||||
def gravatar(email, size=20):
|
||||
"""
|
||||
Returns an HTML image tag for the Gravatar of a given email,
|
||||
with the specified width and height.
|
||||
"""
|
||||
url = gravatar_url(email, size)
|
||||
# Return a safe HTML snippet with the image element
|
||||
html = f'<img src="{url}" width="{size}" height="{size}" alt="Gravatar">'
|
||||
return mark_safe(html)
|
||||
|
||||
@register.filter
|
||||
def gravatar_profile_data(email):
|
||||
"""
|
||||
Retrieves the Gravatar profile JSON for a given email.
|
||||
It fetches data from https://gravatar.com/<HASH>.json, extracts the first entry,
|
||||
and returns it as a standardized dictionary for use in templates.
|
||||
If the email is None or if any error occurs, returns an empty dictionary.
|
||||
"""
|
||||
if not email:
|
||||
return {}
|
||||
email_hash = gravatar_hash(email)
|
||||
url = f"https://gravatar.com/{email_hash}.json"
|
||||
try:
|
||||
response = requests.get(url, timeout=5)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
# Gravatar's JSON response typically contains an "entry" list; we take the first entry.
|
||||
if "entry" in data and data["entry"]:
|
||||
return data["entry"][0]
|
||||
return {}
|
||||
except (requests.RequestException, ValueError):
|
||||
return {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue