Started migrating to python3

This commit is contained in:
Sebastian 2023-07-12 19:44:08 +02:00
parent 6439a0d974
commit 58e4dbc484
12 changed files with 428 additions and 415 deletions

3
.style.yapf Normal file
View File

@ -0,0 +1,3 @@
[style]
based_on_style = pep8
column_limit=100

View File

@ -1,7 +1,8 @@
# Django settings for past3d project.
from django.core.urlresolvers import reverse_lazy
from django.urls import reverse_lazy
import os
BASE_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../')
DEBUG = True
@ -15,13 +16,15 @@ MANAGERS = ADMINS
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'ENGINE':
'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'NAME': os.path.join(BASE_DIR, "data.sqlite"), # Or path to database file if using sqlite3.
# The following settings are not used with sqlite3:
'USER': '',
'PASSWORD': '',
'HOST': '', # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
'PORT': '', # Set to empty string for default.
'HOST':
'', # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
'PORT': '', # Set to empty string for default.
}
}
@ -54,7 +57,7 @@ USE_TZ = True
# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/var/www/example.com/media/"
MEDIA_ROOT = os.path.join(BASE_DIR,"media")
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
@ -65,7 +68,7 @@ MEDIA_URL = '/media/'
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/var/www/example.com/static/"
STATIC_ROOT = os.path.join(BASE_DIR,"static")
STATIC_ROOT = os.path.join(BASE_DIR, "static")
# URL prefix for static files.
# Example: "http://example.com/static/", "http://static.example.com/"
@ -73,7 +76,7 @@ STATIC_URL = '/static/'
# Additional locations of static files
STATICFILES_DIRS = (
os.path.join(BASE_DIR,"static_common"),
os.path.join(BASE_DIR, "static_common"),
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
@ -84,7 +87,7 @@ STATICFILES_DIRS = (
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
# Make this unique, and don't share it with anybody.
@ -94,7 +97,7 @@ SECRET_KEY = 'InsertSomethingSecretHereBeforeDoingProduktion'
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
# 'django.template.loaders.eggs.Loader',
# 'django.template.loaders.eggs.Loader',
)
MIDDLEWARE_CLASSES = (
@ -113,7 +116,7 @@ ROOT_URLCONF = 'past3d.urls'
WSGI_APPLICATION = 'past3d.wsgi.application'
TEMPLATE_DIRS = (
os.path.join(BASE_DIR,'templates'),
os.path.join(BASE_DIR, 'templates'),
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
@ -140,7 +143,7 @@ SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer'
LOGIN_REDIRECT_URL = reverse_lazy('geometry_create')
EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
EMAIL_FILE_PATH = '/tmp/django'
EMAIL_FILE_PATH = '/tmp/django'
# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to

View File

@ -1,31 +1,19 @@
from django.conf.urls import patterns, include, url
from django.urls import include, re_path, path
from django.conf import settings
from django.conf.urls.static import static
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
from views import HomeView
from past3d.views import HomeView
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'past3d.views.home', name='home'),
# url(r'^past3d/', include('past3d.foo.urls')),
url(r'^$', HomeView.as_view(), name='home'),
url(r'^users/', include('users.urls')),
url(r'^3d/', include('pastebin.urls')),
# Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
)
urlpatterns = [
re_path(r'^$', HomeView.as_view(), name='home'),
path('users/', include('users.urls')),
path('3d/', include('pastebin.urls')),
path('admin/', admin.site.urls),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

View File

@ -2,9 +2,11 @@
# -*- coding: utf-8 -*-
from django.contrib import admin
from models import Geometry
from pastebin.models import Geometry
class GeometryAdmin(admin.ModelAdmin):
list_display = ['name', 'description', 'date', 'file', 'sourcefile']
admin.site.register(Geometry, GeometryAdmin)

View File

@ -5,7 +5,7 @@ import struct
from django.forms import ModelForm
from django import forms
from models import Geometry
from pastebin.models import Geometry
facet_pattern = re.compile(r'facet normal\s+[0-9.e+-]+\s+[0-9.e+-]+\s+[0-9.e+-]+')
loop_pattern = re.compile(r'outer\s+loop')
@ -14,74 +14,77 @@ endloop_pattern = re.compile(r'endloop')
endfacet_pattern = re.compile(r'endfacet')
endsolid_pattern = re.compile(r'endsolid .*')
class STLUploadForm(ModelForm):
def clean_file(self):
stlfile = self.cleaned_data.get("file")
stlfile.open()
def clean_file(self):
if stlfile.read(5) != "solid":
#print "binary"
#Skip header
stlfile.seek(80)
count = struct.unpack("i",stlfile.read(4))[0]
if stlfile.size - 84 != count * 50:
raise forms.ValidationError("Not a valid binary STL file.")
stlfile = self.cleaned_data.get("file")
stlfile.open()
else:
#print "ascii"
next_patterns = [facet_pattern]
stlfile.readline()
line = stlfile.readline().strip()
matched_pattern = None
vertex_count = 0
if stlfile.read(5) != "solid":
#print "binary"
#Skip header
stlfile.seek(80)
count = struct.unpack("i", stlfile.read(4))[0]
if stlfile.size - 84 != count * 50:
raise forms.ValidationError("Not a valid binary STL file.")
while line != "":
else:
#print "ascii"
next_patterns = [facet_pattern]
stlfile.readline()
line = stlfile.readline().strip()
corret = False
for pattern in next_patterns:
if pattern.match(line) != None:
corret = True
matched_pattern = pattern
if not corret:
raise forms.ValidationError("Not a valid ascii STL file.")
matched_pattern = None
vertex_count = 0
if matched_pattern == facet_pattern:
next_patterns = [loop_pattern]
if matched_pattern == loop_pattern:
vertex_count = 0
next_patterns = [vertex_pattern]
if matched_pattern == vertex_pattern:
vertex_count += 1
if vertex_count < 3:
next_patterns = [vertex_pattern, endloop_pattern]
else :
next_patterns = [endloop_pattern]
if matched_pattern == endloop_pattern:
next_patterns = [endfacet_pattern]
if matched_pattern == endfacet_pattern:
next_patterns = [facet_pattern, endsolid_pattern]
while line != "":
line = stlfile.readline().strip()
corret = False
for pattern in next_patterns:
if pattern.match(line) != None:
corret = True
matched_pattern = pattern
if not corret:
raise forms.ValidationError("Not a valid ascii STL file.")
if matched_pattern != endsolid_pattern:
raise forms.ValidationError("Not a valid ascii STL file.")
if matched_pattern == facet_pattern:
next_patterns = [loop_pattern]
if matched_pattern == loop_pattern:
vertex_count = 0
next_patterns = [vertex_pattern]
if matched_pattern == vertex_pattern:
vertex_count += 1
if vertex_count < 3:
next_patterns = [vertex_pattern, endloop_pattern]
else:
next_patterns = [endloop_pattern]
if matched_pattern == endloop_pattern:
next_patterns = [endfacet_pattern]
if matched_pattern == endfacet_pattern:
next_patterns = [facet_pattern, endsolid_pattern]
# see https://code.djangoproject.com/ticket/20020
# stlfile.close()
return stlfile
line = stlfile.readline().strip()
if matched_pattern != endsolid_pattern:
raise forms.ValidationError("Not a valid ascii STL file.")
# see https://code.djangoproject.com/ticket/20020
# stlfile.close()
return stlfile
class GeometryForm(STLUploadForm):
class Meta:
model = Geometry
fields = ['name', 'description', 'public', 'expiration', 'file', 'sourcefile']
class Meta:
model = Geometry
fields = ['name', 'description', 'public', 'expiration', 'file', 'sourcefile']
class AnonymousGeometryForm(STLUploadForm):
expiration = forms.ChoiceField(choices=Geometry.EXPIRATION_CHOICES[:-1])
class Meta:
model = Geometry
fields = ['name', 'description', 'public', 'expiration', 'file']
expiration = forms.ChoiceField(choices=Geometry.EXPIRATION_CHOICES[:-1])
class Meta:
model = Geometry
fields = ['name', 'description', 'public', 'expiration', 'file']

View File

@ -5,164 +5,160 @@ import re
from hashlib import md5
from datetime import datetime, timedelta
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.contrib.auth.models import User
from django.db import models
vertex_pattern = re.compile(r'vertex\s+([0-9.e+-]+)\s+([0-9.e+-]+)\s+([0-9.e+-]+)')
def safe_upload_path(base_dir):
def generate_path(instance, filename):
def generate_path(instance, filename):
ext = os.path.splitext(filename)[1]
ext = os.path.splitext(filename)[1]
md5sum = md5()
md5sum.update(instance.name
+ str(datetime.now())
+ filename)
randomname = md5sum.hexdigest()
md5sum = md5()
md5sum.update(instance.name + str(datetime.now()) + filename)
randomname = md5sum.hexdigest()
return os.path.join(base_dir,'%s%s' % (randomname, ext))
return generate_path
return os.path.join(base_dir, '%s%s' % (randomname, ext))
return generate_path
class Geometry(models.Model):
HOUR = 0
DAY = 1
WEEK = 2
MONTH = 3
FORERVER = 4
HOUR = 0
DAY = 1
WEEK = 2
MONTH = 3
FORERVER = 4
EXPIRATION_CHOICES = ((HOUR, 'one hour'),
(DAY, 'one day'),
(WEEK, 'one week'),
(MONTH, 'one month'),
(FORERVER, 'forever'))
EXPIRATION_CHOICES = ((HOUR, 'one hour'), (DAY, 'one day'), (WEEK, 'one week'),
(MONTH, 'one month'), (FORERVER, 'forever'))
DELTAS = { HOUR : timedelta(hours = 1),
DAY : timedelta(days = 1),
WEEK : timedelta(weeks = 1),
MONTH : timedelta(weeks = 4)}
DELTAS = {
HOUR: timedelta(hours=1),
DAY: timedelta(days=1),
WEEK: timedelta(weeks=1),
MONTH: timedelta(weeks=4)
}
name = models.CharField(max_length = 128)
description = models.TextField(blank=True)
user = models.ForeignKey(User, blank=True, null=True)
date = models.DateTimeField(auto_now_add=True)
expiration = models.IntegerField(default = 0, choices = EXPIRATION_CHOICES)
public = models.BooleanField(default=True)
polycount = models.IntegerField(blank=True, default=0)
width = models.FloatField(blank=True, default=0)
depth = models.FloatField(blank=True, default=0)
height = models.FloatField(blank=True, default=0)
file = models.FileField(upload_to=safe_upload_path('models'))
sourcefile = models.FileField(upload_to=safe_upload_path('sources'), blank=True)
name = models.CharField(max_length=128)
description = models.TextField(blank=True)
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True)
expiration = models.IntegerField(default=0, choices=EXPIRATION_CHOICES)
public = models.BooleanField(default=True)
polycount = models.IntegerField(blank=True, default=0)
width = models.FloatField(blank=True, default=0)
depth = models.FloatField(blank=True, default=0)
height = models.FloatField(blank=True, default=0)
file = models.FileField(upload_to=safe_upload_path('models'))
sourcefile = models.FileField(upload_to=safe_upload_path('sources'), blank=True)
def get_absolute_url(self):
return reverse('geometry_details', kwargs={'id' : self.pk})
def get_absolute_url(self):
return reverse('geometry_details', kwargs={'id': self.pk})
@classmethod
def get_latest(cls):
return cls.objects.all().filter(public = True).order_by('-date')[:10]
@classmethod
def get_latest(cls):
return cls.objects.all().filter(public=True).order_by('-date')[:10]
def get_expiration_date(self):
for expiration in [self.HOUR, self.DAY, self.WEEK, self.MONTH]:
if self.expiration == expiration:
return self.date + self.DELTAS[expiration]
def get_expiration_date(self):
for expiration in [self.HOUR, self.DAY, self.WEEK, self.MONTH]:
if self.expiration == expiration:
return self.date + self.DELTAS[expiration]
return None
return None
def _generate_meta_infos(self):
print("Generating metainfos %s" % self.name)
def _generate_meta_infos(self):
print "Generating metainfos %s" % self.name
self.file.open()
self.file.open()
count = 0
min_coord = [None, None, None]
max_coord = [None, None, None]
count = 0
min_coord = [None,None,None]
max_coord = [None,None,None]
if self.file.read(5) != "solid":
print("binary")
# Skip header
self.file.seek(80)
count = struct.unpack("i", self.file.read(4))[0]
if self.file.read(5) != "solid":
print "binary"
#Skip header
self.file.seek(80)
count = struct.unpack("i",self.file.read(4))[0]
done = False
for pos in range(0, count):
# Skip normal (3 * 32bit)
self.file.seek(self.file.tell() + 3 * 4)
# Loop over each coordinate
for vert in range(0, 3):
# Loop over each coordinate
for i in range(0, 3):
x = struct.unpack("<f", self.file.read(4))[0]
done = False
for pos in range(0,count):
#Skip normal (3 * 32bit)
self.file.seek(self.file.tell()+3*4)
#Loop over each coordinate
for vert in range(0,3):
# Loop over each coordinate
for i in range(0,3):
x = struct.unpack("<f",self.file.read(4))[0]
if min_coord[i] is not None:
min_coord[i] = min(min_coord[i], x)
else:
min_coord[i] = x
if min_coord[i] != None :
min_coord[i] = min(min_coord[i], x)
else:
min_coord[i] = x
if max_coord[i] is not None:
max_coord[i] = max(max_coord[i], x)
else:
max_coord[i] = x
# Skip attributes (16bit)
self.file.seek(self.file.tell() + 2)
if max_coord[i] != None :
max_coord[i] = max(max_coord[i], x)
else:
max_coord[i] = x
#Skip attributes (16bit)
self.file.seek(self.file.tell()+2)
else:
print("ascii")
else:
print "ascii"
line = self.file.readline()
while line != "":
line = line.strip()
if line.startswith("facet"):
count = count + 1
if line.startswith("vertex"):
coords = vertex_pattern.match(line).groups()
for i in range(0, 3):
x = float(coords[i])
line = self.file.readline()
while line != "":
line = line.strip()
if line.startswith("facet"):
count = count + 1
if line.startswith("vertex"):
coords = vertex_pattern.match(line).groups();
for i in range(0,3):
x = float(coords[i])
if min_coord[i] is not None:
min_coord[i] = min(min_coord[i], x)
else:
min_coord[i] = x
if min_coord[i] != None :
min_coord[i] = min(min_coord[i], x)
else:
min_coord[i] = x
if max_coord[i] is not None:
max_coord[i] = max(max_coord[i], x)
else:
max_coord[i] = x
if max_coord[i] != None :
max_coord[i] = max(max_coord[i], x)
else:
max_coord[i] = x
line = self.file.readline()
line = self.file.readline()
self.file.close()
self.file.close()
self.width = max_coord[0] - min_coord[0]
self.depth = max_coord[1] - min_coord[1]
self.height = max_coord[2] - min_coord[2]
self.polycount = count
self.width = max_coord[0] - min_coord[0]
self.depth = max_coord[1] - min_coord[1]
self.height = max_coord[2] - min_coord[2]
self.polycount = count
self.save()
self.save()
def get_polycount(self):
if self.polycount == 0:
self._generate_meta_infos()
return self.polycount
def get_polycount(self):
if self.polycount == 0:
self._generate_meta_infos()
return self.polycount
def get_width(self):
if self.polycount == 0:
self._generate_meta_infos()
return self.width
def get_width(self):
if self.polycount == 0:
self._generate_meta_infos()
return self.width
def get_depth(self):
if self.polycount == 0:
self._generate_meta_infos()
return self.depth
def get_depth(self):
if self.polycount == 0:
self._generate_meta_infos()
return self.depth
def get_height(self):
if self.polycount == 0:
self._generate_meta_infos()
return self.height
def get_height(self):
if self.polycount == 0:
self._generate_meta_infos()
return self.height

View File

@ -1,11 +1,11 @@
from django.conf.urls import patterns, include, url
from django.urls import re_path
from views import GeometryView, GeometryListView, GeometryCreate, GeometryDelete
from pastebin.views import GeometryView, GeometryListView, GeometryCreate, GeometryDelete
urlpatterns = patterns('',
url(r'^new/$', GeometryCreate.as_view(), name='geometry_create'),
url(r'^list/$', GeometryListView.as_view(), name='geometry_list'),
url(r'^list/page/(?P<page>[0-9]+)/$', GeometryListView.as_view(), name='geometry_list'),
url(r'^delete/(?P<id>\d+)/$', GeometryDelete.as_view(), name='geometry_delete'),
url(r'^(?P<id>\d+)/$', GeometryView.as_view(), name='geometry_details'))
urlpatterns = [
re_path(r'^new/$', GeometryCreate.as_view(), name='geometry_create'),
re_path(r'^list/$', GeometryListView.as_view(), name='geometry_list'),
re_path(r'^list/page/(?P<page>[0-9]+)/$', GeometryListView.as_view(), name='geometry_list'),
re_path(r'^delete/(?P<id>\d+)/$', GeometryDelete.as_view(), name='geometry_delete'),
re_path(r'^(?P<id>\d+)/$', GeometryView.as_view(), name='geometry_details')
]

View File

@ -1,23 +1,25 @@
from django.views.generic.edit import CreateView, DeleteView
from django.views.generic.detail import DetailView
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.views.generic.base import ContextMixin
from django.core.exceptions import PermissionDenied
from django.views.generic.base import TemplateView
from django.views.generic.list import ListView
from forms import GeometryForm, AnonymousGeometryForm
from models import Geometry
from pastebin.forms import GeometryForm, AnonymousGeometryForm
from pastebin.models import Geometry
class LastesGeometriesMixin(ContextMixin):
def get_context_data(self, **kwargs):
context = super(LastesGeometriesMixin, self).get_context_data(**kwargs)
context['latest_geometries'] = Geometry.get_latest()
return context
def get_context_data(self, **kwargs):
context = super(LastesGeometriesMixin, self).get_context_data(**kwargs)
context['latest_geometries'] = Geometry.get_latest()
return context
class GeometryListView(ListView, LastesGeometriesMixin):
queryset = Geometry.objects.all().filter(public = True).order_by('date')
queryset = Geometry.objects.all().filter(public=True).order_by('date')
paginate_by = 50
paginate_orphans = 25
page_kwarg = 'page'
@ -26,10 +28,10 @@ class GeometryListView(ListView, LastesGeometriesMixin):
class GeometryView(DetailView):
model = Geometry
pk_url_kwarg = 'id'
context_object_name = 'geometry'
template_name = 'pastebin/geometry.html'
model = Geometry
pk_url_kwarg = 'id'
context_object_name = 'geometry'
template_name = 'pastebin/geometry.html'
class GeometryCreate(CreateView, LastesGeometriesMixin):
@ -37,28 +39,29 @@ class GeometryCreate(CreateView, LastesGeometriesMixin):
template_name = 'pastebin/geometry_create.html'
def get_success_url(self):
return reverse('geometry_details', kwargs={'id' :self.object.id})
return reverse('geometry_details', kwargs={'id': self.object.id})
def get_form_class(self):
if self.request.user.is_authenticated() :
return GeometryForm
else:
return AnonymousGeometryForm
if self.request.user.is_authenticated():
return GeometryForm
else:
return AnonymousGeometryForm
def form_valid(self, form):
res = super(GeometryCreate, self).form_valid(form)
if self.request.user.is_authenticated() :
self.object.user = self.request.user
self.object.save()
res = super(GeometryCreate, self).form_valid(form)
if self.request.user.is_authenticated():
self.object.user = self.request.user
self.object.save()
return res
return res
class GeometryDelete(DeleteView, LastesGeometriesMixin):
model = Geometry
pk_url_kwarg = 'id'
template_name = 'pastebin/geometry_delete.html'
success_url ='/'
success_url = '/'
def check_user(self, request):
obj = self.get_object()
@ -67,8 +70,8 @@ class GeometryDelete(DeleteView, LastesGeometriesMixin):
def get(self, request, *args, **kwargs):
self.check_user(request)
return super(GeometryDelete,self).get(self, request, *args, **kwargs)
return super(GeometryDelete, self).get(self, request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
self.check_user(request)
return super(GeometryDelete,self).delete(self, request, *args, **kwargs)
return super(GeometryDelete, self).delete(self, request, *args, **kwargs)

View File

@ -1,5 +1,6 @@
Django==1.5.4
Werkzeug==0.9.4
django-extensions==1.2.2
six==1.4.1
wsgiref==0.1.2
asgiref==3.7.2
Django==4.2.3
django-extensions==3.2.3
MarkupSafe==2.1.3
sqlparse==0.4.4
Werkzeug==2.3.6

View File

@ -2,93 +2,86 @@ from django import forms
from django.forms import ModelForm
from django.contrib.auth.models import User
class UserCreateForm(ModelForm):
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
class Meta:
model = User
fields = ['username', 'email']
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
class Meta:
model = User
fields = ['username', 'email']
def clean_password2(self):
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return password1
def clean_password2(self):
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
def clean_email(self):
#Make sure Email is unique
email = self.cleaned_data.get("email")
if User.objects.filter(email = email):
raise forms.ValidationError("Email already in use.")
return password1
return email
def clean_email(self):
# Make sure Email is unique
email = self.cleaned_data.get("email")
if User.objects.filter(email=email):
raise forms.ValidationError("Email already in use.")
return email
def save(self, commit=True):
user = super(UserCreateForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
user.is_active = False
if commit:
user.save()
return user
def save(self, commit=True):
user = super(UserCreateForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
user.is_active = False
if commit:
user.save()
return user
class UserUpdateForm(ModelForm):
new_password1 = forms.CharField(label='New Password',
widget=forms.PasswordInput,
required=False)
new_password2 = forms.CharField(label='New Password confirmation',
widget=forms.PasswordInput,
required=False)
current_password = forms.CharField(label='Current Password', widget=forms.PasswordInput)
new_password1 = forms.CharField(label='New Password',
widget=forms.PasswordInput,
required=False)
new_password2 = forms.CharField(label='New Password confirmation',
widget=forms.PasswordInput,
required=False)
current_password = forms.CharField(label='Current Password', widget=forms.PasswordInput)
class Meta:
model = User
fields = ['email']
class Meta:
model = User
fields = ['email']
def clean_current_password(self):
current_password = self.cleaned_data.get("current_password")
def clean_current_password(self):
current_password = self.cleaned_data.get("current_password")
if not self.instance.check_password(current_password):
raise forms.ValidationError("Password incorrect")
if not self.instance.check_password(current_password):
raise forms.ValidationError("Password incorrect")
return current_password
return current_password
def clean_new_password2(self):
password1 = self.cleaned_data.get("new_password1")
password2 = self.cleaned_data.get("new_password2")
def clean_new_password2(self):
password1 = self.cleaned_data.get("new_password1")
password2 = self.cleaned_data.get("new_password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return password1
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return password1
def clean_email(self):
#Make sure Email is still unique
email = self.cleaned_data.get("email")
if User.objects.filter(email = email).exclude(id=self.instance.id):
raise forms.ValidationError("Email already in use.")
def clean_email(self):
# Make sure Email is still unique
email = self.cleaned_data.get("email")
if User.objects.filter(email=email).exclude(id=self.instance.id):
raise forms.ValidationError("Email already in use.")
return email
return email
def save(self, commit=True):
user = super(UserUpdateForm, self).save(commit=False)
def save(self, commit=True):
user = super(UserUpdateForm, self).save(commit=False)
password = self.cleaned_data.get("new_password1")
if password:
user.set_password(password)
if commit:
user.save()
return user
password = self.cleaned_data.get("new_password1")
if password:
user.set_password(password)
if commit:
user.save()
return user

View File

@ -1,37 +1,57 @@
from django.conf.urls import patterns, include, url
from django.core.urlresolvers import reverse_lazy
from django.urls import re_path, path, reverse_lazy
from django.contrib.auth import views as auth_views
from pastebin.models import Geometry
from views import *
from users.views import *
urlpatterns = patterns('',
url(r'^signup/$', UserCreateView.as_view(), name='signup'),
url(r'^confirm/(?P<user_id>\d+)/$', SendConfirmationView.as_view(), name='send_confirmation'),
url(r'^confirm/(?P<user_id>\d+)/(?P<token>.+)/$', CheckConfirmationView.as_view(), name='check_confirmation'),
url(r'^update/(?P<user_id>\d+)/$', UserUpdateView.as_view(), name='user_update'),
url(r'^password/reset/$', 'django.contrib.auth.views.password_reset', {'extra_context' : {'latest_geometries' : Geometry.get_latest()},
'template_name' : 'users/password_reset.html',
'post_reset_redirect' : reverse_lazy('password_reset_sent')},
name='password_reset'),
url(r'^password/reset/(?P<uidb36>[0-9A-Za-z]+)/(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm', {'extra_context' : {'latest_geometries' : Geometry.get_latest()},
'template_name' : 'users/password_reset_confirm.html',
'post_reset_redirect' : reverse_lazy('login')},
name='password_reset_confirm'),
url(r'^password/reset/sent/$', 'django.contrib.auth.views.password_reset_done', {'extra_context' : {'latest_geometries' : Geometry.get_latest()},
'template_name' : 'users/password_reset_sent.html',},
name='password_reset_sent'),
url(r'^login/$', 'django.contrib.auth.views.login', {'extra_context' : {'latest_geometries' : Geometry.get_latest()},
'template_name' : 'users/login.html'},
name='login'),
url(r'^logout/$', 'django.contrib.auth.views.logout',{'extra_context' : {'latest_geometries' : Geometry.get_latest()},
'next_page' : reverse_lazy('login')},
name='logout'),
)
urlpatterns = [
re_path(r'^signup/$', UserCreateView.as_view(), name='signup'),
re_path(r'^confirm/(?P<user_id>\d+)/$', SendConfirmationView.as_view(), name='send_confirmation'),
re_path(r'^confirm/(?P<user_id>\d+)/(?P<token>.+)/$',
CheckConfirmationView.as_view(),
name='check_confirmation'),
re_path(r'^update/(?P<user_id>\d+)/$', UserUpdateView.as_view(), name='user_update'),
path('password/reset/',
auth_views.PasswordResetView.as_view(), {
'extra_context': {
'latest_geometries': Geometry.get_latest()
},
'template_name': 'users/password_reset.html',
'post_reset_redirect': reverse_lazy('password_reset_sent')
},
name='password_reset'),
path('password/reset/confirm/',
auth_views.PasswordResetConfirmView.as_view(), {
'extra_context': {
'latest_geometries': Geometry.get_latest()
},
'template_name': 'users/password_reset_confirm.html',
'post_reset_redirect': reverse_lazy('login')
},
name='password_reset_confirm'),
path('password/reset/sent/',
auth_views.PasswordResetDoneView.as_view(), {
'extra_context': {
'latest_geometries': Geometry.get_latest()
},
'template_name': 'users/password_reset_sent.html',
},
name='password_reset_sent'),
path('login/',
auth_views.LoginView.as_view(), {
'extra_context': {
'latest_geometries': Geometry.get_latest()
},
'template_name': 'users/login.html'
},
name='login'),
path('logout/',
auth_views.LogoutView.as_view(), {
'extra_context': {
'latest_geometries': Geometry.get_latest()
},
'next_page': reverse_lazy('login')
},
name='logout'),
]

View File

@ -1,104 +1,105 @@
from django.views.generic.edit import CreateView, UpdateView
from django.views.generic.base import TemplateView
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.contrib.sites.models import get_current_site
from django.urls import reverse
from django.contrib.sites.shortcuts import get_current_site
from django.contrib.auth.tokens import default_token_generator
from django.template import loader
from django.utils.http import int_to_base36
from django.http import Http404
from django.http import Http404
from django.core.exceptions import PermissionDenied
from pastebin.views import LastesGeometriesMixin
from forms import UserCreateForm, UserUpdateForm
from users.forms import UserCreateForm, UserUpdateForm
class UserCreateView(CreateView, LastesGeometriesMixin):
model = User
form_class = UserCreateForm
template_name = 'users/signup.html'
model = User
form_class = UserCreateForm
template_name = 'users/signup.html'
def get_success_url(self):
return reverse('send_confirmation', kwargs={'user_id' : self.object.pk})
def get_success_url(self):
return reverse('send_confirmation', kwargs={'user_id': self.object.pk})
class UserUpdateView(UpdateView, LastesGeometriesMixin):
model = User
form_class = UserUpdateForm
template_name = 'users/user_update.html'
pk_url_kwarg = 'user_id'
model = User
form_class = UserUpdateForm
template_name = 'users/user_update.html'
pk_url_kwarg = 'user_id'
def get_queryset(self):
return self.model.objects.filter(id=self.request.user.id)
def get_success_url(self):
return reverse('geometry_create')
def get_queryset(self):
return self.model.objects.filter(id=self.request.user.id)
def get_success_url(self):
return reverse('geometry_create')
class SendConfirmationView(TemplateView, LastesGeometriesMixin):
template_name = 'users/send_confirmation.html'
email_template_name = 'users/confirmation_email.txt'
template_name = 'users/send_confirmation.html'
email_template_name = 'users/confirmation_email.txt'
def get_context_data(self, **kwargs):
context = super(SendConfirmationView, self).get_context_data(**kwargs)
context['confirm_user'] = User.objects.get(id=kwargs['user_id'])
return context
def get_context_data(self, **kwargs):
context = super(SendConfirmationView, self).get_context_data(**kwargs)
context['confirm_user'] = User.objects.get(id=kwargs['user_id'])
return context
def get(self, request, *args, **kwargs):
try:
user = User.objects.get(id=kwargs['user_id'])
except User.DoesNotExist:
raise Http404
def get(self, request, *args, **kwargs):
try:
user = User.objects.get(id=kwargs['user_id'])
except User.DoesNotExist:
raise Http404
if user.is_active:
raise Http404
site_name = get_current_site(self.request).name
uid = int_to_base36(user.pk)
token = default_token_generator.make_token(user)
link = request.build_absolute_uri(reverse('check_confirmation', kwargs={'user_id' : user.pk, 'token' : token}))
if user.is_active:
raise Http404
context = {
'email': user.email,
'site_name': site_name,
'validation_link': link,
'user': user
}
site_name = get_current_site(self.request).name
uid = int_to_base36(user.pk)
token = default_token_generator.make_token(user)
link = request.build_absolute_uri(
reverse('check_confirmation', kwargs={
'user_id': user.pk,
'token': token
}))
subject = "Validate your registration at %s" % site_name
email = loader.render_to_string(self.email_template_name, context)
user.email_user(subject,email)
context = {
'email': user.email,
'site_name': site_name,
'validation_link': link,
'user': user
}
subject = "Validate your registration at %s" % site_name
email = loader.render_to_string(self.email_template_name, context)
user.email_user(subject, email)
return super(SendConfirmationView,self).get(self, request, *args, **kwargs)
return super(SendConfirmationView, self).get(self, request, *args, **kwargs)
class CheckConfirmationView(TemplateView, LastesGeometriesMixin):
template_name = 'users/check_confirmation.html'
template_name = 'users/check_confirmation.html'
def get_context_data(self, **kwargs):
context = super(CheckConfirmationView, self).get_context_data(**kwargs)
context['confirm_user'] = User.objects.get(id=kwargs['user_id'])
return context
def get_context_data(self, **kwargs):
context = super(CheckConfirmationView, self).get_context_data(**kwargs)
context['confirm_user'] = User.objects.get(id=kwargs['user_id'])
return context
def get(self, request, *args, **kwargs):
try:
user = User.objects.get(id=kwargs['user_id'])
except User.DoesNotExist:
raise Http404
def get(self, request, *args, **kwargs):
try:
user = User.objects.get(id=kwargs['user_id'])
except User.DoesNotExist:
raise Http404
if user.is_active:
raise Http404
if user.is_active:
raise Http404
if not default_token_generator.check_token(user,kwargs['token']):
raise Http404
if not default_token_generator.check_token(user, kwargs['token']):
raise Http404
user.is_active = True
user.save()
user.is_active = True
user.save()
print "Acitvating %s" % user.username
print("Acitvating %s" % user.username)
return super(CheckConfirmationView,self).get(self, request, *args, **kwargs)
return super(CheckConfirmationView, self).get(self, request, *args, **kwargs)