diff --git a/ivatar/ivataraccount/models.py b/ivatar/ivataraccount/models.py
index 12d365e..5563551 100644
--- a/ivatar/ivataraccount/models.py
+++ b/ivatar/ivataraccount/models.py
@@ -24,6 +24,8 @@ from openid.association import Association as OIDAssociation
from openid.store import nonce as oidnonce
from openid.store.interface import OpenIDStore
+from libravatar import libravatar_url
+
from ivatar.settings import MAX_LENGTH_EMAIL, logger
from ivatar.settings import MAX_PIXELS, AVATAR_MAX_SIZE, JPEG_QUALITY
from ivatar.settings import MAX_LENGTH_URL
@@ -128,6 +130,9 @@ class Photo(BaseAccountModel):
if gravatar:
image_url = gravatar['image_url']
+ if service_name == 'Libravatar':
+ image_url = libravatar_url(email_address)
+
if not image_url:
return False # pragma: no cover
try:
diff --git a/ivatar/ivataraccount/templates/_import_photo_form.html b/ivatar/ivataraccount/templates/_import_photo_form.html
new file mode 100644
index 0000000..d5fcf56
--- /dev/null
+++ b/ivatar/ivataraccount/templates/_import_photo_form.html
@@ -0,0 +1,37 @@
+{% load i18n %}
+{% load bootstrap4 %}
+
+{% if not user.is_anonymous %}
+ {% if photos %}
+
{% trans 'Would you like to import some of these externally hosted photos?' %}
+ {% if email_id %}
+
+ {% endif %}
+{% endif %}
diff --git a/ivatar/ivataraccount/templates/assign_photo_email.html b/ivatar/ivataraccount/templates/assign_photo_email.html
index d5961e7..472adbb 100644
--- a/ivatar/ivataraccount/templates/assign_photo_email.html
+++ b/ivatar/ivataraccount/templates/assign_photo_email.html
@@ -37,7 +37,12 @@
-{% blocktrans %}upload a new one{% endblocktrans %}
+
+
+ {% blocktrans %}Upload a new one{% endblocktrans %}
+
+ {% blocktrans %}Import from other services{% endblocktrans %}
+
{% endif %}
diff --git a/ivatar/ivataraccount/templates/email_confirmed.html b/ivatar/ivataraccount/templates/email_confirmed.html
index 2d54ec5..8f7aec7 100644
--- a/ivatar/ivataraccount/templates/email_confirmed.html
+++ b/ivatar/ivataraccount/templates/email_confirmed.html
@@ -9,31 +9,8 @@
{% trans 'Your email address was successfully confirmed!' %}
-{% if not user.is_anonymous %}
-{% if photos %}
-
-{% trans 'Would you like to import some of these externally hosted photos?' %}
-
-{% endif %}
+{% include '_import_photo_form.html' %}
{% trans 'Back to your profile' %}
-{% endif %}
{% endblock content %}
diff --git a/ivatar/ivataraccount/templates/import_photo.html b/ivatar/ivataraccount/templates/import_photo.html
new file mode 100644
index 0000000..104c985
--- /dev/null
+++ b/ivatar/ivataraccount/templates/import_photo.html
@@ -0,0 +1,33 @@
+{% extends 'base.html' %}
+{% load i18n %}
+{% load bootstrap4 %}
+
+{% block title %}{% trans 'Import photo' %} - Libravatar{% endblock title %}
+
+{% block content %}
+
+{% trans 'Import photo' %}
+
+{% include '_import_photo_form.html' %}
+
+{% if not email_id %}
+
+
+
+{% endif %}
+
+{% trans 'Back to your profile' %}
+
+{% endblock content %}
diff --git a/ivatar/ivataraccount/templates/profile.html b/ivatar/ivataraccount/templates/profile.html
index ad2d4f5..8e0488a 100644
--- a/ivatar/ivataraccount/templates/profile.html
+++ b/ivatar/ivataraccount/templates/profile.html
@@ -79,7 +79,11 @@
{% endif %}
{% if not max_photos %}
-{% trans 'Upload a new photo' %}
+
+
+ {% trans 'Upload a new photo' %}
+ {% trans 'Import photo from other services' %}
+
{% endif %}
{% trans 'Account settings' %}
diff --git a/ivatar/ivataraccount/test_views.py b/ivatar/ivataraccount/test_views.py
index aaf1994..150bf95 100644
--- a/ivatar/ivataraccount/test_views.py
+++ b/ivatar/ivataraccount/test_views.py
@@ -333,7 +333,7 @@ class Tester(TestCase): # pylint: disable=too-many-public-methods
'unable to import photo from Gravatar?')
self.assertEqual(
str(list(response.context[0]['messages'])[0]),
- 'Image successfully imported',
+ 'Gravatar image successfully imported',
'Importing gravatar photo did not work?')
self.assertIsInstance(
self.user.photo_set.first(),
@@ -1162,8 +1162,6 @@ class Tester(TestCase): # pylint: disable=too-many-public-methods
)
url = '%s?%s' % (urlobj.path, urlobj.query)
response = self.client.get(url, follow=False)
- print(response)
- print(response.content)
self.assertRedirects(
response=response,
expected_url=default,
diff --git a/ivatar/ivataraccount/urls.py b/ivatar/ivataraccount/urls.py
index 5ffb225..9c14baa 100644
--- a/ivatar/ivataraccount/urls.py
+++ b/ivatar/ivataraccount/urls.py
@@ -69,6 +69,12 @@ urlpatterns = [ # pylint: disable=invalid-name
url(
r'assign_photo_openid/(?P\d+)',
AssignPhotoOpenIDView.as_view(), name='assign_photo_openid'),
+ url(
+ r'import_photo/$',
+ ImportPhotoView.as_view(), name='import_photo'),
+ url(
+ r'import_photo/(?P[\w.]+@[\w.]+.[\w.]+)',
+ ImportPhotoView.as_view(), name='import_photo'),
url(
r'import_photo/(?P\d+)',
ImportPhotoView.as_view(), name='import_photo'),
diff --git a/ivatar/ivataraccount/views.py b/ivatar/ivataraccount/views.py
index f96eca9..8e968eb 100644
--- a/ivatar/ivataraccount/views.py
+++ b/ivatar/ivataraccount/views.py
@@ -2,6 +2,7 @@
View classes for ivatar/ivataraccount/
'''
import io
+from urllib.request import urlopen
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
@@ -16,6 +17,7 @@ from django.utils.translation import ugettext_lazy as _
from django.http import HttpResponseRedirect, HttpResponse
from django.urls import reverse_lazy, reverse
from django.shortcuts import render
+from django_openid_auth.models import UserOpenID
from django_openid_auth.models import UserOpenID
from openid import oidutil
@@ -23,6 +25,9 @@ from openid.consumer import consumer
from ipware import get_client_ip
+from libravatar import libravatar_url
+from .gravatar import get_photo as get_gravatar_photo
+
from ivatar.settings import MAX_NUM_PHOTOS, MAX_PHOTO_SIZE
from .forms import AddEmailForm, UploadPhotoForm, AddOpenIDForm
@@ -272,39 +277,111 @@ class AssignPhotoOpenIDView(SuccessMessageMixin, TemplateView):
@method_decorator(login_required, name='dispatch')
-class ImportPhotoView(SuccessMessageMixin, View):
+class ImportPhotoView(SuccessMessageMixin, TemplateView):
'''
View class to import a photo from another service
Currently only Gravatar is supported
'''
+ template_name = 'import_photo.html'
- @staticmethod
- def post(request, *args, **kwargs): # pylint: disable=unused-argument
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['photos'] = []
+ addr = None
+ if 'email_id' in kwargs:
+ try:
+ addr = ConfirmedEmail.objects.get(pk=kwargs['email_id']).email
+ except:
+ messages.error(
+ self.request,
+ _('Address does not exist'))
+ return context
+
+ if 'email_addr' in kwargs:
+ addr = kwargs['email_addr']
+
+ if addr:
+ gravatar = get_gravatar_photo(addr)
+ if gravatar:
+ context['photos'].append(gravatar)
+
+ libravatar_service_url = libravatar_url(
+ email=addr,
+ default=404,
+ )
+ try:
+ if libravatar_service_url:
+ response = urlopen(libravatar_service_url)
+ context['photos'].append({
+ 'service_url': libravatar_service_url,
+ 'thumbnail_url': libravatar_service_url + '?s=80',
+ 'image_url': libravatar_service_url + '?s=512',
+ 'width': 80,
+ 'height': 80,
+ 'service_name': 'Libravatar',
+ })
+ except Exception:
+ pass
+
+ return context
+
+ def post(self, request, *args, **kwargs): # pylint: disable=no-self-use,unused-argument
'''
- Handle post - import photo
+ Handle post to photo import
'''
- try:
- email = ConfirmedEmail.objects.get(
- id=kwargs['email_id'], user=request.user)
- except Exception: # pylint: disable=broad-except
- messages.error(
- request,
- _('Address does not exist'))
- return HttpResponseRedirect(reverse_lazy('profile'))
+
+ addr = None
+ email_id = None
+ imported = None
+
+ if 'email_id' in kwargs:
+ email_id = kwargs['email_id']
+ if 'email_id' in request.POST:
+ email_id = request.POST['email_id']
+ if 'email_addr' in kwargs:
+ addr = kwargs['email_addr']
+ if 'email_addr' in request.POST:
+ addr = request.POST['email_addr']
+
+ if email_id:
+ email = ConfirmedEmail.objects.filter(
+ id=email_id, user=request.user)
+ if email.count() > 0:
+ addr = email.first().email
+ else:
+ messages.error(
+ request,
+ _('Address does not exist'))
+ return HttpResponseRedirect(reverse_lazy('profile'))
if 'photo_Gravatar' in request.POST:
photo = Photo()
photo.user = request.user
- photo.ip_address = get_client_ip(request)[0]
- if photo.import_image('Gravatar', email.email):
+ photo.ip_address = get_client_ip(request)
+ if photo.import_image('Gravatar', addr):
messages.success(request,
- _('Image successfully imported'))
+ _('Gravatar image successfully imported'))
else:
# Honestly, I'm not sure how to test this...
messages.error(
request,
- _('Image import not successful')) # pragma: no cover
- else:
+ _('Gravatar image import not successful')) # pragma: no cover
+ imported = True
+
+ if 'photo_Libravatar' in request.POST:
+ photo = Photo()
+ photo.user = request.user
+ photo.ip_address = get_client_ip(request)
+ if photo.import_image('Libravatar', addr):
+ messages.success(request,
+ _('Libravatar image successfully imported'))
+ else:
+ # Honestly, I'm not sure how to test this...
+ messages.error(
+ request,
+ _('Libravatar image import not successful')) # pragma: no cover
+ imported = True
+ if not imported:
messages.warning(request, _('Nothing importable'))
return HttpResponseRedirect(reverse_lazy('profile'))
diff --git a/ivatar/views.py b/ivatar/views.py
index 1568048..35753d5 100644
--- a/ivatar/views.py
+++ b/ivatar/views.py
@@ -5,8 +5,10 @@ from io import BytesIO
from os import path
from PIL import Image
from django.views.generic.base import TemplateView
-from django.http import HttpResponse, HttpResponseRedirect
+from django.http import HttpResponse, HttpResponseRedirect, HttpResponseNotFound
from django.core.exceptions import ObjectDoesNotExist
+from django.utils.translation import ugettext_lazy as _
+
from ivatar.settings import AVATAR_MAX_SIZE, JPEG_QUALITY
from . ivataraccount.models import ConfirmedEmail, ConfirmedOpenId
from . ivataraccount.models import pil_format
@@ -58,10 +60,12 @@ class AvatarImageView(TemplateView):
# If that mail/openid doesn't exist, or has no photo linked to it
if not obj or not obj.photo:
- # Return the default URL, as specified
+ # Return the default URL, as specified, or 404 Not Found, if default=404
if default:
+ if str(default) == str(404):
+ return HttpResponseNotFound(_('Image not found
'))
return HttpResponseRedirect(default)
- # Return our default URl
+ # Return our default URL
else:
static_img = path.join('static', 'img', 'mm', '%s%s' % (str(size), '.png'))
if not path.isfile(static_img):