mirror of
https://git.linux-kernel.at/oliver/ivatar.git
synced 2025-11-20 15:08:02 +00:00
Add extra page after libravatar export upload, where user can choose what to import
This commit is contained in:
@@ -209,43 +209,3 @@ class UploadLibravatarExportForm(forms.Form):
|
|||||||
_('This field must be checked since we need to be able to\
|
_('This field must be checked since we need to be able to\
|
||||||
distribute photos to third parties.')
|
distribute photos to third parties.')
|
||||||
})
|
})
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def save(request, data):
|
|
||||||
'''
|
|
||||||
Save the models and assign it to the current user
|
|
||||||
'''
|
|
||||||
items = libravatar_read_gzdata(data.read())
|
|
||||||
for email in items['emails']:
|
|
||||||
if not ConfirmedEmail.objects.filter(email=email) and \
|
|
||||||
not UnconfirmedEmail.objects.filter(email=email): # pylint: disable=no-member
|
|
||||||
try:
|
|
||||||
unconfirmed = UnconfirmedEmail.objects.create( # pylint: disable=no-member
|
|
||||||
user=request.user,
|
|
||||||
email=email
|
|
||||||
)
|
|
||||||
unconfirmed.save()
|
|
||||||
unconfirmed.send_confirmation_mail(url=request.build_absolute_uri('/')[:-1])
|
|
||||||
except Exception as e: # pylint: disable=broad-except,invalid-name
|
|
||||||
# Debugging only
|
|
||||||
print('Exception while trying to import mail addresses: %s' % e)
|
|
||||||
if 'openids' in items:
|
|
||||||
messages.warning(
|
|
||||||
request,
|
|
||||||
_('You have OpenIDs in your export file, but we cannot\
|
|
||||||
import those at the moment'))
|
|
||||||
|
|
||||||
for pilobj in items['photos']:
|
|
||||||
# Is there a reasonable way to check if that photo already exists!?
|
|
||||||
try:
|
|
||||||
data = BytesIO()
|
|
||||||
pilobj.save(data, pilobj.format, quality=JPEG_QUALITY)
|
|
||||||
data.seek(0)
|
|
||||||
photo = Photo()
|
|
||||||
photo.user = request.user
|
|
||||||
photo.ip_address = get_client_ip(request)[0]
|
|
||||||
photo.format = file_format(pilobj.format)
|
|
||||||
photo.data = data.read()
|
|
||||||
photo.save()
|
|
||||||
except Exception: # pylint: disable=broad-except
|
|
||||||
pass
|
|
||||||
|
|||||||
@@ -49,14 +49,18 @@ def read_gzdata(gzdata=None):
|
|||||||
photo.attrib['encoding'], photo.attrib['format'], e))
|
photo.attrib['encoding'], photo.attrib['format'], e))
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
img = Image.open(BytesIO(data))
|
Image.open(BytesIO(data))
|
||||||
|
# If it is a working image, we can use it
|
||||||
|
photo.text.replace('\n', '')
|
||||||
|
photos.append({
|
||||||
|
'data': photo.text,
|
||||||
|
'format': photo.attrib['format'],
|
||||||
|
})
|
||||||
except Exception as e: # pylint: disable=broad-except,invalid-name
|
except Exception as e: # pylint: disable=broad-except,invalid-name
|
||||||
print('Cannot decode photo; Encoding: %s, Format: %s: %s' % (
|
print('Cannot decode photo; Encoding: %s, Format: %s: %s' % (
|
||||||
photo.attrib['encoding'], photo.attrib['format'], e))
|
photo.attrib['encoding'], photo.attrib['format'], e))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
photos.append(img)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'emails': emails,
|
'emails': emails,
|
||||||
'openids': openids,
|
'openids': openids,
|
||||||
|
|||||||
40
ivatar/ivataraccount/templates/choose_libravatar_export.html
Normal file
40
ivatar/ivataraccount/templates/choose_libravatar_export.html
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load static %}
|
||||||
|
{% load bootstrap4 %}
|
||||||
|
|
||||||
|
{% block title %}{% trans 'Choose items to be uploaded' %}{% endblock title %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>{% trans 'Choose items to be imported' %}</h1>
|
||||||
|
|
||||||
|
<div style="max-width:600px;">
|
||||||
|
<form method="post" action="{% url 'upload_export' 'save' %}">{% csrf_token %}
|
||||||
|
{% if emails %}
|
||||||
|
<p>
|
||||||
|
{% trans 'Email addresses we found in the export - existing ones will not be re-added' %}:
|
||||||
|
</p>
|
||||||
|
{% for email in emails %}
|
||||||
|
<input type="checkbox" checked name="email_{{ forloop.counter }}" value="{{ email }}"> {{ email }}</input><br/>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
<p/>
|
||||||
|
{% if photos %}
|
||||||
|
<p>
|
||||||
|
{% trans 'Photos we found in the export' %}:
|
||||||
|
</p>
|
||||||
|
{% for photo in photos %}
|
||||||
|
<input type="checkbox" checked name="photo_{{ forloop.counter }}" value="{{ photo.data }}">
|
||||||
|
<img style="max-width: 80px; max-height: 80px;" src="data:image/{{ photo.format }};base64,{{ photo.data }}"/>
|
||||||
|
</input>
|
||||||
|
<br/>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
<br/>
|
||||||
|
{% buttons %}
|
||||||
|
<button type="submit" class="btn btn-primary">{% trans 'Upload' %}</button>
|
||||||
|
<button type="cancel" class="btn btn-danger">{% trans 'Cancel' %}</button>
|
||||||
|
{% endbuttons %}
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endblock content %}
|
||||||
@@ -85,4 +85,6 @@ urlpatterns = [ # pylint: disable=invalid-name
|
|||||||
url(r'crop_photo/(?P<pk>\d+)', CropPhotoView.as_view(), name='crop_photo'),
|
url(r'crop_photo/(?P<pk>\d+)', CropPhotoView.as_view(), name='crop_photo'),
|
||||||
url(r'pref/$', UserPreferenceView.as_view(), name='user_preference'),
|
url(r'pref/$', UserPreferenceView.as_view(), name='user_preference'),
|
||||||
url(r'upload_export/$', UploadLibravatarExportView.as_view(), name='upload_export'),
|
url(r'upload_export/$', UploadLibravatarExportView.as_view(), name='upload_export'),
|
||||||
|
url(r'upload_export/(?P<save>save)$',
|
||||||
|
UploadLibravatarExportView.as_view(), name='upload_export'),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
'''
|
'''
|
||||||
View classes for ivatar/ivataraccount/
|
View classes for ivatar/ivataraccount/
|
||||||
'''
|
'''
|
||||||
import io
|
from io import BytesIO
|
||||||
from urllib.request import urlopen
|
from urllib.request import urlopen
|
||||||
|
import base64
|
||||||
|
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
@@ -20,22 +23,22 @@ 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 django_openid_auth.models import UserOpenID
|
||||||
|
|
||||||
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 ipware import get_client_ip
|
||||||
|
|
||||||
from libravatar import libravatar_url
|
from libravatar import libravatar_url
|
||||||
|
from ivatar.settings import MAX_NUM_PHOTOS, MAX_PHOTO_SIZE, JPEG_QUALITY
|
||||||
from .gravatar import get_photo as get_gravatar_photo
|
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
|
from .forms import AddEmailForm, UploadPhotoForm, AddOpenIDForm
|
||||||
from .forms import UpdatePreferenceForm, UploadLibravatarExportForm
|
from .forms import UpdatePreferenceForm, UploadLibravatarExportForm
|
||||||
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 .models import file_format
|
||||||
|
from . read_libravatar_export import read_gzdata as libravatar_read_gzdata
|
||||||
|
|
||||||
|
|
||||||
def openid_logging(message, level=0):
|
def openid_logging(message, level=0):
|
||||||
@@ -295,7 +298,7 @@ class ImportPhotoView(SuccessMessageMixin, TemplateView):
|
|||||||
if 'email_id' in kwargs:
|
if 'email_id' in kwargs:
|
||||||
try:
|
try:
|
||||||
addr = ConfirmedEmail.objects.get(pk=kwargs['email_id']).email
|
addr = ConfirmedEmail.objects.get(pk=kwargs['email_id']).email
|
||||||
except:
|
except Exception: # pylint: disable=broad-except
|
||||||
messages.error(
|
messages.error(
|
||||||
self.request,
|
self.request,
|
||||||
_('Address does not exist'))
|
_('Address does not exist'))
|
||||||
@@ -315,7 +318,8 @@ class ImportPhotoView(SuccessMessageMixin, TemplateView):
|
|||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
if libravatar_service_url:
|
if libravatar_service_url:
|
||||||
response = urlopen(libravatar_service_url)
|
# if it doesn't work, it will be catched by except
|
||||||
|
urlopen(libravatar_service_url)
|
||||||
context['photos'].append({
|
context['photos'].append({
|
||||||
'service_url': libravatar_service_url,
|
'service_url': libravatar_service_url,
|
||||||
'thumbnail_url': libravatar_service_url + '?s=80',
|
'thumbnail_url': libravatar_service_url + '?s=80',
|
||||||
@@ -324,12 +328,13 @@ class ImportPhotoView(SuccessMessageMixin, TemplateView):
|
|||||||
'height': 80,
|
'height': 80,
|
||||||
'service_name': 'Libravatar',
|
'service_name': 'Libravatar',
|
||||||
})
|
})
|
||||||
except Exception:
|
except Exception as e: # pylint: disable=broad-except,invalid-name
|
||||||
|
print('Exception caught during photo import: %s' % e)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs): # pylint: disable=no-self-use,unused-argument
|
def post(self, request, *args, **kwargs): # pylint: disable=no-self-use,unused-argument,too-many-branches
|
||||||
'''
|
'''
|
||||||
Handle post to photo import
|
Handle post to photo import
|
||||||
'''
|
'''
|
||||||
@@ -400,7 +405,7 @@ class RawImageView(DetailView):
|
|||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
photo = self.model.objects.get(pk=kwargs['pk']) # pylint: disable=no-member
|
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)
|
BytesIO(photo.data), content_type='image/%s' % photo.format)
|
||||||
|
|
||||||
|
|
||||||
@method_decorator(login_required, name='dispatch')
|
@method_decorator(login_required, name='dispatch')
|
||||||
@@ -717,8 +722,64 @@ class UploadLibravatarExportView(SuccessMessageMixin, FormView):
|
|||||||
success_url = reverse_lazy('profile')
|
success_url = reverse_lazy('profile')
|
||||||
model = User
|
model = User
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs): # pylint: disable=unused-argument
|
||||||
|
'''
|
||||||
|
Handle post request - choose items to import
|
||||||
|
'''
|
||||||
|
if 'save' in kwargs: # pylint: disable=too-many-nested-blocks
|
||||||
|
if kwargs['save'] == 'save':
|
||||||
|
for arg in request.POST:
|
||||||
|
if arg.startswith('email_'):
|
||||||
|
email = request.POST[arg]
|
||||||
|
if not ConfirmedEmail.objects.filter(email=email) and \
|
||||||
|
not UnconfirmedEmail.objects.filter(email=email): # pylint: disable=no-member
|
||||||
|
try:
|
||||||
|
unconfirmed = UnconfirmedEmail.objects.create( # pylint: disable=no-member
|
||||||
|
user=request.user,
|
||||||
|
email=email
|
||||||
|
)
|
||||||
|
unconfirmed.save()
|
||||||
|
unconfirmed.send_confirmation_mail(
|
||||||
|
url=request.build_absolute_uri('/')[:-1])
|
||||||
|
messages.info(
|
||||||
|
request,
|
||||||
|
'%s: %s' %(
|
||||||
|
email,
|
||||||
|
_('address added successfully,\
|
||||||
|
confirmation mail sent')))
|
||||||
|
except Exception as e: # pylint: disable=broad-except,invalid-name
|
||||||
|
# DEBUG
|
||||||
|
print('Exception during adding mail address (%s): %s' % (email, e))
|
||||||
|
|
||||||
|
if arg.startswith('photo'):
|
||||||
|
try:
|
||||||
|
data = base64.decodebytes(bytes(request.POST[arg], 'utf-8'))
|
||||||
|
except Exception as e: # pylint: disable=broad-except,invalid-name
|
||||||
|
print('Cannot decode photo: %s' % e)
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
pilobj = Image.open(BytesIO(data))
|
||||||
|
out = BytesIO()
|
||||||
|
pilobj.save(out, pilobj.format, quality=JPEG_QUALITY)
|
||||||
|
out.seek(0)
|
||||||
|
photo = Photo()
|
||||||
|
photo.user = request.user
|
||||||
|
photo.ip_address = get_client_ip(request)[0]
|
||||||
|
photo.format = file_format(pilobj.format)
|
||||||
|
photo.data = out.read()
|
||||||
|
photo.save()
|
||||||
|
except Exception as e: # pylint: disable=broad-except,invalid-name
|
||||||
|
print('Exception during save: %s' % e)
|
||||||
|
continue
|
||||||
|
|
||||||
|
return HttpResponseRedirect(reverse_lazy('profile'))
|
||||||
|
return super().post(request, args, kwargs)
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
data = self.request.FILES['export_file']
|
data = self.request.FILES['export_file']
|
||||||
|
items = libravatar_read_gzdata(data.read())
|
||||||
form.save(self.request, data)
|
# DEBUG print(items)
|
||||||
return super().form_valid(form)
|
return render(self.request, 'choose_libravatar_export.html', {
|
||||||
|
'emails': items['emails'],
|
||||||
|
'photos': items['photos'],
|
||||||
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user