Do allow importing photo from confirmed email

This commit is contained in:
Oliver Falk
2018-07-10 13:18:11 +02:00
parent 007021ce89
commit 4cf9e72c93
5 changed files with 92 additions and 54 deletions

View File

@@ -0,0 +1,29 @@
{% load i18n %}
{% load bootstrap4 %}
{% if not user.is_anonymous %}
{% if photos %}
<p>{% trans 'Would you like to import some of these externally hosted photos?' %}</p>
<form action="{% url 'import_photo' email_id %}" method="post">{% csrf_token %}
<input type="hidden" name="email_id" value="{{ email_id }}">
<ul class="horizontal-list imported-list centered">
{% for photo in photos %}
<li><input type="checkbox" name="photo_{{photo.service_name}}" id="photo_{{photo.service_name}}" checked="checked">
<br/><label for="photo_{{photo.service_name}}"><img src="{{ photo.thumbnail_url }}" class="thumbnail" alt="{{photo.service_name}} image"></label>
<br/>
{% if photo.service_url %}
<a href="{{ photo.service_url }}">{{ photo.service_name }}</a>
{% else %} {# pragma: no cover #}
{{ photo.service_name }} {# pragma: no cover #}
{% endif %} {# pragma: no cover #}
</li>
{% endfor %}
</ul>
<p>
{% buttons %}
<button type="submit" class="btn btn-primary">{% trans 'Import' %}</button>
{% endbuttons %}
</p>
</form>
{% endif %}
{% endif %}

View File

@@ -37,7 +37,12 @@
</form></li> </form></li>
</ul> </ul>
<p><a href="{% url 'upload_photo' %}">{% blocktrans %}upload a new one{% endblocktrans %}</a></p> <p>
<br/>
<a href="{% url 'upload_photo' %}">{% blocktrans %}Upload a new one{% endblocktrans %}</a>
<br/>
<a href="{% url 'import_photo' email.pk %}">{% blocktrans %}Import from other services{% endblocktrans %}</a>
</p>
{% endif %} {% endif %}

View File

@@ -9,31 +9,8 @@
<p><b>{% trans 'Your email address was successfully confirmed!' %}</b></p> <p><b>{% trans 'Your email address was successfully confirmed!' %}</b></p>
{% if not user.is_anonymous %} {% include '_import_photo_form.html' %}
{% if photos %}
<p>{% trans 'Would you like to import some of these externally hosted photos?' %}</p>
<form action="{% url 'import_photo' email_id %}" method="post">{% csrf_token %}
<input type="hidden" name="email_id" value="{{ email_id }}">
<ul class="horizontal-list imported-list centered">
{% for photo in photos %}
<li><input type="checkbox" name="photo_{{photo.service_name}}" id="photo_{{photo.service_name}}" checked="checked">
<br/><label for="photo_{{photo.service_name}}"><img src="{{ photo.thumbnail_url }}" class="thumbnail" alt="{{photo.service_name}} image"></label>
<br/>
{% if photo.service_url %}
<a href="{{ photo.service_url }}">{{ photo.service_name }}</a>
{% else %} {# pragma: no cover #}
{{ photo.service_name }} {# pragma: no cover #}
{% endif %} {# pragma: no cover #}
</li>
{% endfor %}
</ul>
<p><input type="submit" value="{% trans 'Import' %}"></p>
</form>
{% endif %}
<p><a href="{% url 'profile' %}">{% trans 'Back to your profile' %}</a></p> <p><a href="{% url 'profile' %}">{% trans 'Back to your profile' %}</a></p>
{% endif %}
{% endblock content %} {% endblock content %}

View File

@@ -0,0 +1,14 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans 'Import photo' %} - Libravatar{% endblock title %}
{% block content %}
<h1>{% trans 'Import photo' %}</h1>
{% include '_import_photo_form.html' %}
<p><a href="{% url 'profile' %}">{% trans 'Back to your profile' %}</a></p>
{% endblock content %}

View File

@@ -1,6 +1,9 @@
''' '''
View classes for ivatar/ivataraccount/ View classes for ivatar/ivataraccount/
''' '''
import io
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
@@ -14,23 +17,21 @@ from django.utils.translation import ugettext_lazy as _
from django.http import HttpResponseRedirect, HttpResponse from django.http import HttpResponseRedirect, HttpResponse
from django.urls import reverse_lazy, reverse from django.urls import reverse_lazy, reverse
from django.shortcuts import render from django.shortcuts import render
from django_openid_auth.models import UserOpenID
from openid import oidutil from openid import oidutil
from openid.consumer import consumer from openid.consumer import consumer
from ipware import get_client_ip
from ivatar.settings import MAX_NUM_PHOTOS, MAX_PHOTO_SIZE
from .forms import AddEmailForm, UploadPhotoForm, AddOpenIDForm from .forms import AddEmailForm, UploadPhotoForm, AddOpenIDForm
from .forms import UpdatePreferenceForm from .forms import UpdatePreferenceForm
from .models import UnconfirmedEmail, ConfirmedEmail, Photo from .models import UnconfirmedEmail, ConfirmedEmail, Photo
from .models import UnconfirmedOpenId, ConfirmedOpenId, DjangoOpenIDStore from .models import UnconfirmedOpenId, ConfirmedOpenId, DjangoOpenIDStore
from .models import UserPreference from .models import UserPreference
from .gravatar import get_photo as get_gravatar_photo
from ivatar.settings import MAX_NUM_PHOTOS, MAX_PHOTO_SIZE
import io
from ipware import get_client_ip
from django_openid_auth.models import UserOpenID
def openid_logging(message, level=0): def openid_logging(message, level=0):
@@ -57,12 +58,12 @@ class CreateView(SuccessMessageMixin, FormView):
password=form.cleaned_data['password1']) password=form.cleaned_data['password1'])
if user is not None: if user is not None:
login(self.request, user) login(self.request, user)
pref = UserPreference.objects.create(user_id=user.pk) pref = UserPreference.objects.create(user_id=user.pk) # pylint: disable=no-member
pref.save() pref.save()
return HttpResponseRedirect(reverse_lazy('profile')) return HttpResponseRedirect(reverse_lazy('profile'))
else:
return HttpResponseRedirect( return HttpResponseRedirect(
reverse_lazy('login')) # pragma: no cover reverse_lazy('login')) # pragma: no cover
@method_decorator(login_required, name='dispatch') @method_decorator(login_required, name='dispatch')
@@ -111,11 +112,11 @@ class RemoveUnconfirmedEmailView(SuccessMessageMixin, View):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
try: try:
email = UnconfirmedEmail.objects.get( email = UnconfirmedEmail.objects.get( # pylint: disable=no-member
user=request.user, id=kwargs['email_id']) user=request.user, id=kwargs['email_id'])
email.delete() email.delete()
messages.success(request, _('Address removed')) messages.success(request, _('Address removed'))
except UnconfirmedEmail.DoesNotExist: except UnconfirmedEmail.DoesNotExist: # pylint: disable=no-member
messages.error(request, _('Address does not exist')) messages.error(request, _('Address does not exist'))
return HttpResponseRedirect(reverse_lazy('profile')) return HttpResponseRedirect(reverse_lazy('profile'))
@@ -136,8 +137,8 @@ class ConfirmEmailView(SuccessMessageMixin, TemplateView):
return HttpResponseRedirect(reverse_lazy('profile')) return HttpResponseRedirect(reverse_lazy('profile'))
try: try:
unconfirmed = UnconfirmedEmail.objects.get(verification_key=key) unconfirmed = UnconfirmedEmail.objects.get(verification_key=key) # pylint: disable=no-member
except UnconfirmedEmail.DoesNotExist: except UnconfirmedEmail.DoesNotExist: # pylint: disable=no-member
messages.error(request, _('Verification key does not exist')) messages.error(request, _('Verification key does not exist'))
return HttpResponseRedirect(reverse_lazy('profile')) return HttpResponseRedirect(reverse_lazy('profile'))
@@ -172,7 +173,7 @@ class RemoveConfirmedEmailView(SuccessMessageMixin, View):
user=request.user, id=kwargs['email_id']) user=request.user, id=kwargs['email_id'])
email.delete() email.delete()
messages.success(request, _('Address removed')) messages.success(request, _('Address removed'))
except ConfirmedEmail.DoesNotExist: except ConfirmedEmail.DoesNotExist: # pylint: disable=no-member
messages.error(request, _('Address does not exist')) messages.error(request, _('Address does not exist'))
return HttpResponseRedirect(reverse_lazy('profile')) return HttpResponseRedirect(reverse_lazy('profile'))
@@ -193,16 +194,16 @@ class AssignPhotoEmailView(SuccessMessageMixin, TemplateView):
return HttpResponseRedirect(reverse_lazy('profile')) return HttpResponseRedirect(reverse_lazy('profile'))
try: try:
photo = self.model.objects.get( photo = self.model.objects.get( # pylint: disable=no-member
id=request.POST['photo_id'], user=request.user) id=request.POST['photo_id'], user=request.user)
except self.model.DoesNotExist: except self.model.DoesNotExist: # pylint: disable=no-member
messages.error(request, _('Photo does not exist')) messages.error(request, _('Photo does not exist'))
return HttpResponseRedirect(reverse_lazy('profile')) return HttpResponseRedirect(reverse_lazy('profile'))
try: try:
email = ConfirmedEmail.objects.get( email = ConfirmedEmail.objects.get(
user=request.user, id=kwargs['email_id']) user=request.user, id=kwargs['email_id'])
except ConfirmedEmail.DoesNotExist: except ConfirmedEmail.DoesNotExist: # pylint: disable=no-member
messages.error(request, _('Invalid request')) messages.error(request, _('Invalid request'))
return HttpResponseRedirect(reverse_lazy('profile')) return HttpResponseRedirect(reverse_lazy('profile'))
@@ -234,16 +235,16 @@ class AssignPhotoOpenIDView(SuccessMessageMixin, TemplateView):
return HttpResponseRedirect(reverse_lazy('profile')) return HttpResponseRedirect(reverse_lazy('profile'))
try: try:
photo = self.model.objects.get( photo = self.model.objects.get( # pylint: disable=no-member
id=request.POST['photo_id'], user=request.user) id=request.POST['photo_id'], user=request.user)
except self.model.DoesNotExist: except self.model.DoesNotExist: # pylint: disable=no-member
messages.error(request, _('Photo does not exist')) messages.error(request, _('Photo does not exist'))
return HttpResponseRedirect(reverse_lazy('profile')) return HttpResponseRedirect(reverse_lazy('profile'))
try: try:
openid = ConfirmedOpenId.objects.get( openid = ConfirmedOpenId.objects.get( # pylint: disable=no-member
user=request.user, id=kwargs['openid_id']) user=request.user, id=kwargs['openid_id'])
except ConfirmedOpenId.DoesNotExist: except ConfirmedOpenId.DoesNotExist: # pylint: disable=no-member
messages.error(request, _('Invalid request')) messages.error(request, _('Invalid request'))
return HttpResponseRedirect(reverse_lazy('profile')) return HttpResponseRedirect(reverse_lazy('profile'))
@@ -255,22 +256,34 @@ class AssignPhotoOpenIDView(SuccessMessageMixin, TemplateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs) data = super().get_context_data(**kwargs)
data['openid'] = ConfirmedOpenId.objects.get(pk=kwargs['openid_id']) data['openid'] = ConfirmedOpenId.objects.get(pk=kwargs['openid_id']) # pylint: disable=no-member
return data return data
@method_decorator(login_required, name='dispatch') @method_decorator(login_required, name='dispatch')
class ImportPhotoView(SuccessMessageMixin, View): class ImportPhotoView(SuccessMessageMixin, TemplateView):
''' '''
View class to import a photo from another service View class to import a photo from another service
Currently only Gravatar is supported Currently only Gravatar is supported
''' '''
template_name = 'import_photo.html'
def post(self, request, *args, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['photos'] = []
gravatar = get_gravatar_photo(ConfirmedEmail.objects.get(pk=kwargs['email_id']).email)
if gravatar:
context['photos'].append(gravatar)
return context
def post(self, request, *args, **kwargs): # pylint: disable=no-self-use,unused-argument
'''
Handle post to photo import
'''
try: try:
email = ConfirmedEmail.objects.get( email = ConfirmedEmail.objects.get(
id=kwargs['email_id'], user=request.user) id=kwargs['email_id'], user=request.user)
except Exception as e: except ConfirmedEmail.DoesNotExist as e: # pylint: disable=no-member
messages.error( messages.error(
request, request,
_('Address does not exist')) _('Address does not exist'))
@@ -301,7 +314,7 @@ class RawImageView(DetailView):
model = Photo model = Photo
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
photo = self.model.objects.get(pk=kwargs['pk']) photo = self.model.objects.get(pk=kwargs['pk']) # pylint: disable=no-member
return HttpResponse( return HttpResponse(
io.BytesIO(photo.data), content_type='image/%s' % photo.format) io.BytesIO(photo.data), content_type='image/%s' % photo.format)