Remove request asking system; track downloads instead of reuqests. Use IP address lookup

master
Tait Hoyem 4 years ago
parent 948997835e
commit 4072a1524c

@ -1,4 +1,4 @@
# Generated by Django 3.1.2 on 2020-11-06 18:06 # Generated by Django 3.1.2 on 2020-11-06 22:28
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
@ -6,21 +6,21 @@ import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
initial = True
dependencies = [ dependencies = [
('download', '0009_auto_20201106_1718'),
('core', '0002_quoteuser'), ('core', '0002_quoteuser'),
('download', '0009_auto_20201106_1718'),
] ]
operations = [ operations = [
migrations.CreateModel( migrations.CreateModel(
name='QuoteRequest', name='DownloadAttempt',
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('timestamp', models.DateTimeField(auto_now_add=True)), ('timestamp', models.DateTimeField(auto_now_add=True)),
('address', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='quote_requests', to='download.address')), ('successful', models.BooleanField(default=False)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='quote_requests', to='core.quoteuser')), ('ip', models.GenericIPAddressField()),
('pdf', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='attempts', to='download.pdf')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='attempts', to='core.quoteuser')),
], ],
), ),
] ]

@ -0,0 +1,19 @@
# Generated by Django 3.1.2 on 2020-11-07 00:51
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('download', '0010_downloadattempt'),
]
operations = [
migrations.AddField(
model_name='downloadattempt',
name='geolocation',
field=models.CharField(default='', max_length=64),
preserve_default=False,
),
]

@ -26,3 +26,11 @@ class EmailSent(models.Model):
user = models.ForeignKey(QuoteUser, on_delete=models.CASCADE) user = models.ForeignKey(QuoteUser, on_delete=models.CASCADE)
pdf = models.ForeignKey(PDF, on_delete=models.CASCADE) pdf = models.ForeignKey(PDF, on_delete=models.CASCADE)
ref_code = models.CharField(max_length=256) ref_code = models.CharField(max_length=256)
class DownloadAttempt(models.Model):
timestamp = models.DateTimeField(auto_now_add=True, editable=False, null=False, blank=False)
user = models.ForeignKey(QuoteUser, on_delete=models.CASCADE, related_name='attempts')
successful = models.BooleanField(default=False)
pdf = models.ForeignKey(PDF, on_delete=models.CASCADE, related_name='attempts')
ip = models.GenericIPAddressField()
geolocation = models.CharField(max_length=64)

@ -1,7 +1,7 @@
from django.shortcuts import render, HttpResponse from django.shortcuts import render, HttpResponse
from django.http import FileResponse from django.http import FileResponse
from django.core.mail import EmailMultiAlternatives from django.core.mail import EmailMultiAlternatives
from .models import Address, PDF, EmailSent from .models import Address, PDF, EmailSent, DownloadAttempt
from .forms import CodeForm from .forms import CodeForm
from core.models import QuoteUser from core.models import QuoteUser
from django.template.loader import render_to_string from django.template.loader import render_to_string
@ -19,16 +19,10 @@ def search(request, addr):
if len(addr) <= 3: if len(addr) <= 3:
return HttpResponse(json.dumps([])) return HttpResponse(json.dumps([]))
return HttpResponse(json.dumps( return HttpResponse(json.dumps(
[x.toDict() for x in Address.objects.filter(address__startswith=addr)] [x.toDict() for x in Address.objects.filter(address__contains=addr)[:10]]
)) ))
def send_email(to, addr, pdf, dt_date): def send_email(to, addr, pdf, dt_date):
# save email in user database; do nothing if exception
user, created = QuoteUser.objects.get_or_create(username=to, email=to)
# disallow login for new user
if created:
user.set_unusable_password()
user.save()
# send email # send email
email = EmailMultiAlternatives() email = EmailMultiAlternatives()
email.subject = 'Your free quote!' email.subject = 'Your free quote!'
@ -44,9 +38,9 @@ def send_email(to, addr, pdf, dt_date):
email.attach(str(pdf.upload_file), content, 'application/octate-stream') email.attach(str(pdf.upload_file), content, 'application/octate-stream')
email.send() email.send()
def save_email(to, addr, pdf, dt): def save_email(user, addr, pdf, dt):
EmailSent.objects.create( EmailSent.objects.create(
user=QuoteUser.objects.get(email=to), user=user,
pdf=pdf, pdf=pdf,
ref_code=hashlib.sha256(dt.strftime("%Y%m%d%H%M%S").encode()).hexdigest() ref_code=hashlib.sha256(dt.strftime("%Y%m%d%H%M%S").encode()).hexdigest()
) )
@ -64,6 +58,23 @@ def download(request, pdfid):
if len(pdf) == 0: if len(pdf) == 0:
return render(request, 'common/password-incorrect.html') return render(request, 'common/password-incorrect.html')
pdf = pdf[0] pdf = pdf[0]
# create user
user, created = QuoteUser.objects.get_or_create(username=form.cleaned_data['email'], email=form.cleaned_data['email'])
# disallow login for new user
if created:
user.set_unusable_password()
user.save()
# create download attempt
dla = DownloadAttempt.objects.create(
user=user,
pdf=pdf,
ip=request.META.get('REMOTE_ADDR'),
geolocation="{0}, {1}, {2}".format(
request.ipinfo.city,
request.ipinfo.region,
request.ipinfo.country
)
)
# create timestamps # create timestamps
dt_date = datetime.datetime.now() dt_date = datetime.datetime.now()
try: try:
@ -74,7 +85,10 @@ def download(request, pdfid):
'code': form.cleaned_data['code'] 'code': form.cleaned_data['code']
}) })
# only saves email if it sent # only saves email if it sent
save_email(form.cleaned_data['email'], addr, pdf, dt_date) save_email(user, addr, pdf, dt_date)
# only makes successful if email is sent
dla.successful = True
dla.save()
return render(request, 'download/email-confirm.html') return render(request, 'download/email-confirm.html')
else: else:
form = CodeForm() form = CodeForm()

@ -1,5 +0,0 @@
from django.apps import AppConfig
class RequestConfig(AppConfig):
name = 'request'

@ -1,5 +0,0 @@
from django import forms
class RequestForm(forms.Form):
email = forms.EmailField(label='Email', max_length=32, required=True)
address = forms.CharField(label='Address', max_length=64, required=True)

@ -1,9 +0,0 @@
from django.db import models
from core.models import QuoteUser
from download.models import Address
# Create your models here.
class QuoteRequest(models.Model):
timestamp = models.DateTimeField(auto_now_add=True, editable=False, null=False, blank=False)
address = models.ForeignKey(Address, on_delete=models.CASCADE, related_name='quote_requests')
user = models.ForeignKey(QuoteUser, on_delete=models.CASCADE, related_name='quote_requests')

@ -1,10 +0,0 @@
{% extends 'common/master.html' %}
{% block body %}
<h1>Request A Quote</h1>
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
</form>
<p>{{ message }}</p>
{% endblock %}

@ -1,6 +0,0 @@
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='request')
]

@ -1,38 +0,0 @@
from django.shortcuts import render, HttpResponse
from .forms import RequestForm
from django.conf import settings
from django.core.mail import EmailMultiAlternatives
from core.models import QuoteUser
from download.models import Address
from .models import QuoteRequest
# Create your views here.
def index(request):
if request.method == 'POST':
form = RequestForm(request.POST)
if form.is_valid():
to_addr = form.cleaned_data['email']
address = form.cleaned_data['address']
email = EmailMultiAlternatives()
email.to = [to_addr]
email.bcc = [settings.REQUEST_BBC]
email.body = 'Somebody has requested a quote'
try:
email.send()
except:
return HttpResponse('Error', code=500)
# if all went all, add user, address, and request to database
# TODO: add messages
user, user_created = QuoteUser.objects.get_or_create(username=to_addr, email=to_addr)
addr, addr_created = Address.objects.get_or_create(address=address)
qr, qr_created = QuoteRequest.objects.get_or_create(user=user, address=addr)
return render(request, 'request/request.html', {
'form': RequestForm(),
'message': 'Thank you for requesting a quote. We will get back to you soon.'
})
else:
return render(request, 'request/request.html', {
'form': RequestForm()
})

@ -0,0 +1,32 @@
{% extends 'common/master.html' %}
{% block body %}
<style>
table {
border-collapse: collapse;
}
td {
padding: 20px;
border: 1px solid black;
margin: 0px;
}
</style>
<h1>View Download Attempts</h1>
<table>
<tr>
<th>Email</th>
<th>Address</th>
<th>IP</th>
<th>Geolocation</th>
<th>Timestamp</th>
</tr>
{% for req in requests %}
<tr>
<td>{{ req.user.email }}</td>
<td>{{ req.pdf.address.address }}</td>
<td>{{ req.ip }}</td>
<td>{{ req.geolocation }}</td>
<td>{{ req.timestamp }}</td>
</tr>
{% endfor %}
</table>
{% endblock %}

@ -3,5 +3,4 @@ from . import views
urlpatterns = [ urlpatterns = [
path('', views.index, name='requests_view'), path('', views.index, name='requests_view'),
path('delete/', views.delete, name='requests_delete')
] ]

@ -1,12 +1,9 @@
from django.shortcuts import render, HttpResponse from django.shortcuts import render, HttpResponse
from request.models import QuoteRequest from download.models import DownloadAttempt
# Create your views here. # Create your views here.
def index(request): def index(request):
# TODO: Allow search
return render(request, 'viewrequests/requests.html', { return render(request, 'viewrequests/requests.html', {
'requests': QuoteRequest.objects.all() 'requests': DownloadAttempt.objects.all().order_by('-timestamp')[:100]
}) })
def delete(request):
print(request.POST)
pass

@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.

@ -1,31 +0,0 @@
{% extends 'common/master.html' %}
{% block body %}
<style>
table {
border-collapse: collapse;
}
td {
padding: 20px;
border: 1px solid black;
margin: 0px;
}
</style>
<form method="POST">
{% csrf_token %}
<table>
<tr>
<th>User</th>
<th>Address</th>
<th>Delete</th>
</tr>
{% for req in requests %}
<tr>
<td>{{ req.user.email }}</td>
<td>{{ req.address.address }}</td>
<td><input type="checkbox" value="{{ req.id }}" name="req_ids" id="req_ids_{{ req.id }}"></td>
</tr>
{% endfor %}
</table>
<input type="submit" value="Delete">
</form>
{% endblock %}

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.
Loading…
Cancel
Save