diff --git a/download/__pycache__/models.cpython-38.pyc b/download/__pycache__/models.cpython-38.pyc index 982061c..d6aebfa 100644 Binary files a/download/__pycache__/models.cpython-38.pyc and b/download/__pycache__/models.cpython-38.pyc differ diff --git a/download/__pycache__/views.cpython-38.pyc b/download/__pycache__/views.cpython-38.pyc index 3cbfebd..1183e72 100644 Binary files a/download/__pycache__/views.cpython-38.pyc and b/download/__pycache__/views.cpython-38.pyc differ diff --git a/request/migrations/0001_initial.py b/download/migrations/0010_downloadattempt.py similarity index 58% rename from request/migrations/0001_initial.py rename to download/migrations/0010_downloadattempt.py index 9cf5783..92bbb03 100644 --- a/request/migrations/0001_initial.py +++ b/download/migrations/0010_downloadattempt.py @@ -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 import django.db.models.deletion @@ -6,21 +6,21 @@ import django.db.models.deletion class Migration(migrations.Migration): - initial = True - dependencies = [ - ('download', '0009_auto_20201106_1718'), ('core', '0002_quoteuser'), + ('download', '0009_auto_20201106_1718'), ] operations = [ migrations.CreateModel( - name='QuoteRequest', + name='DownloadAttempt', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('timestamp', models.DateTimeField(auto_now_add=True)), - ('address', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='quote_requests', to='download.address')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='quote_requests', to='core.quoteuser')), + ('successful', models.BooleanField(default=False)), + ('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')), ], ), ] diff --git a/download/migrations/0011_downloadattempt_geolocation.py b/download/migrations/0011_downloadattempt_geolocation.py new file mode 100644 index 0000000..6ace948 --- /dev/null +++ b/download/migrations/0011_downloadattempt_geolocation.py @@ -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, + ), + ] diff --git a/download/migrations/__pycache__/0010_downloadattempt.cpython-38.pyc b/download/migrations/__pycache__/0010_downloadattempt.cpython-38.pyc new file mode 100644 index 0000000..2aacade Binary files /dev/null and b/download/migrations/__pycache__/0010_downloadattempt.cpython-38.pyc differ diff --git a/download/migrations/__pycache__/0011_downloadattempt_geolocation.cpython-38.pyc b/download/migrations/__pycache__/0011_downloadattempt_geolocation.cpython-38.pyc new file mode 100644 index 0000000..99b12f7 Binary files /dev/null and b/download/migrations/__pycache__/0011_downloadattempt_geolocation.cpython-38.pyc differ diff --git a/download/models.py b/download/models.py index 421d598..b1625c3 100644 --- a/download/models.py +++ b/download/models.py @@ -26,3 +26,11 @@ class EmailSent(models.Model): user = models.ForeignKey(QuoteUser, on_delete=models.CASCADE) pdf = models.ForeignKey(PDF, on_delete=models.CASCADE) 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) \ No newline at end of file diff --git a/download/views.py b/download/views.py index e8ceb9a..f5d5093 100644 --- a/download/views.py +++ b/download/views.py @@ -1,7 +1,7 @@ from django.shortcuts import render, HttpResponse from django.http import FileResponse from django.core.mail import EmailMultiAlternatives -from .models import Address, PDF, EmailSent +from .models import Address, PDF, EmailSent, DownloadAttempt from .forms import CodeForm from core.models import QuoteUser from django.template.loader import render_to_string @@ -19,16 +19,10 @@ def search(request, addr): if len(addr) <= 3: 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): - # 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 email = EmailMultiAlternatives() 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.send() -def save_email(to, addr, pdf, dt): +def save_email(user, addr, pdf, dt): EmailSent.objects.create( - user=QuoteUser.objects.get(email=to), + user=user, pdf=pdf, 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: return render(request, 'common/password-incorrect.html') 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 dt_date = datetime.datetime.now() try: @@ -74,7 +85,10 @@ def download(request, pdfid): 'code': form.cleaned_data['code'] }) # 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') else: form = CodeForm() diff --git a/request/__pycache__/__init__.cpython-38.pyc b/request/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index e1e6230..0000000 Binary files a/request/__pycache__/__init__.cpython-38.pyc and /dev/null differ diff --git a/request/__pycache__/admin.cpython-38.pyc b/request/__pycache__/admin.cpython-38.pyc deleted file mode 100644 index 6dff48c..0000000 Binary files a/request/__pycache__/admin.cpython-38.pyc and /dev/null differ diff --git a/request/__pycache__/forms.cpython-38.pyc b/request/__pycache__/forms.cpython-38.pyc deleted file mode 100644 index 22ea7eb..0000000 Binary files a/request/__pycache__/forms.cpython-38.pyc and /dev/null differ diff --git a/request/__pycache__/models.cpython-38.pyc b/request/__pycache__/models.cpython-38.pyc deleted file mode 100644 index d6113f4..0000000 Binary files a/request/__pycache__/models.cpython-38.pyc and /dev/null differ diff --git a/request/__pycache__/urls.cpython-38.pyc b/request/__pycache__/urls.cpython-38.pyc deleted file mode 100644 index dda39cb..0000000 Binary files a/request/__pycache__/urls.cpython-38.pyc and /dev/null differ diff --git a/request/__pycache__/views.cpython-38.pyc b/request/__pycache__/views.cpython-38.pyc deleted file mode 100644 index 0c0424e..0000000 Binary files a/request/__pycache__/views.cpython-38.pyc and /dev/null differ diff --git a/request/apps.py b/request/apps.py deleted file mode 100644 index 3e130f9..0000000 --- a/request/apps.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.apps import AppConfig - - -class RequestConfig(AppConfig): - name = 'request' diff --git a/request/forms.py b/request/forms.py deleted file mode 100644 index fb32b75..0000000 --- a/request/forms.py +++ /dev/null @@ -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) diff --git a/request/migrations/__pycache__/0001_initial.cpython-38.pyc b/request/migrations/__pycache__/0001_initial.cpython-38.pyc deleted file mode 100644 index 20e96ac..0000000 Binary files a/request/migrations/__pycache__/0001_initial.cpython-38.pyc and /dev/null differ diff --git a/request/migrations/__pycache__/__init__.cpython-38.pyc b/request/migrations/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 579cab6..0000000 Binary files a/request/migrations/__pycache__/__init__.cpython-38.pyc and /dev/null differ diff --git a/request/models.py b/request/models.py deleted file mode 100644 index 644cbd6..0000000 --- a/request/models.py +++ /dev/null @@ -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') \ No newline at end of file diff --git a/request/templates/request/request.html b/request/templates/request/request.html deleted file mode 100644 index d055353..0000000 --- a/request/templates/request/request.html +++ /dev/null @@ -1,10 +0,0 @@ -{% extends 'common/master.html' %} -{% block body %} -

Request A Quote

-
- {% csrf_token %} - {{ form.as_p }} - -
-

{{ message }}

-{% endblock %} \ No newline at end of file diff --git a/request/urls.py b/request/urls.py deleted file mode 100644 index 05dff9b..0000000 --- a/request/urls.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.urls import path -from . import views - -urlpatterns = [ - path('', views.index, name='request') -] \ No newline at end of file diff --git a/request/views.py b/request/views.py deleted file mode 100644 index 82f6dde..0000000 --- a/request/views.py +++ /dev/null @@ -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() - }) \ No newline at end of file diff --git a/request/__init__.py b/viewdownloads/__init__.py similarity index 100% rename from request/__init__.py rename to viewdownloads/__init__.py diff --git a/viewrequests/__pycache__/__init__.cpython-38.pyc b/viewdownloads/__pycache__/__init__.cpython-38.pyc similarity index 100% rename from viewrequests/__pycache__/__init__.cpython-38.pyc rename to viewdownloads/__pycache__/__init__.cpython-38.pyc diff --git a/viewrequests/__pycache__/admin.cpython-38.pyc b/viewdownloads/__pycache__/admin.cpython-38.pyc similarity index 100% rename from viewrequests/__pycache__/admin.cpython-38.pyc rename to viewdownloads/__pycache__/admin.cpython-38.pyc diff --git a/viewrequests/__pycache__/models.cpython-38.pyc b/viewdownloads/__pycache__/models.cpython-38.pyc similarity index 100% rename from viewrequests/__pycache__/models.cpython-38.pyc rename to viewdownloads/__pycache__/models.cpython-38.pyc diff --git a/viewdownloads/__pycache__/urls.cpython-38.pyc b/viewdownloads/__pycache__/urls.cpython-38.pyc new file mode 100644 index 0000000..bb2075c Binary files /dev/null and b/viewdownloads/__pycache__/urls.cpython-38.pyc differ diff --git a/viewdownloads/__pycache__/views.cpython-38.pyc b/viewdownloads/__pycache__/views.cpython-38.pyc new file mode 100644 index 0000000..6d0de35 Binary files /dev/null and b/viewdownloads/__pycache__/views.cpython-38.pyc differ diff --git a/request/admin.py b/viewdownloads/admin.py similarity index 100% rename from request/admin.py rename to viewdownloads/admin.py diff --git a/viewrequests/apps.py b/viewdownloads/apps.py similarity index 100% rename from viewrequests/apps.py rename to viewdownloads/apps.py diff --git a/request/migrations/__init__.py b/viewdownloads/migrations/__init__.py similarity index 100% rename from request/migrations/__init__.py rename to viewdownloads/migrations/__init__.py diff --git a/viewrequests/migrations/__pycache__/__init__.cpython-38.pyc b/viewdownloads/migrations/__pycache__/__init__.cpython-38.pyc similarity index 100% rename from viewrequests/migrations/__pycache__/__init__.cpython-38.pyc rename to viewdownloads/migrations/__pycache__/__init__.cpython-38.pyc diff --git a/viewrequests/models.py b/viewdownloads/models.py similarity index 100% rename from viewrequests/models.py rename to viewdownloads/models.py diff --git a/viewdownloads/templates/viewrequests/requests.html b/viewdownloads/templates/viewrequests/requests.html new file mode 100644 index 0000000..8757a6d --- /dev/null +++ b/viewdownloads/templates/viewrequests/requests.html @@ -0,0 +1,32 @@ +{% extends 'common/master.html' %} +{% block body %} + +

View Download Attempts

+ + + + + + + + + {% for req in requests %} + + + + + + + + {% endfor %} +
EmailAddressIPGeolocationTimestamp
{{ req.user.email }}{{ req.pdf.address.address }}{{ req.ip }}{{ req.geolocation }}{{ req.timestamp }}
+{% endblock %} \ No newline at end of file diff --git a/request/tests.py b/viewdownloads/tests.py similarity index 100% rename from request/tests.py rename to viewdownloads/tests.py diff --git a/viewrequests/urls.py b/viewdownloads/urls.py similarity index 66% rename from viewrequests/urls.py rename to viewdownloads/urls.py index 6f3d181..bd6956d 100644 --- a/viewrequests/urls.py +++ b/viewdownloads/urls.py @@ -3,5 +3,4 @@ from . import views urlpatterns = [ path('', views.index, name='requests_view'), - path('delete/', views.delete, name='requests_delete') ] \ No newline at end of file diff --git a/viewrequests/views.py b/viewdownloads/views.py similarity index 52% rename from viewrequests/views.py rename to viewdownloads/views.py index d05357b..51dfb09 100644 --- a/viewrequests/views.py +++ b/viewdownloads/views.py @@ -1,12 +1,9 @@ from django.shortcuts import render, HttpResponse -from request.models import QuoteRequest +from download.models import DownloadAttempt # Create your views here. def index(request): + # TODO: Allow search 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 \ No newline at end of file diff --git a/viewrequests/__init__.py b/viewrequests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/viewrequests/__pycache__/urls.cpython-38.pyc b/viewrequests/__pycache__/urls.cpython-38.pyc deleted file mode 100644 index 1cc866d..0000000 Binary files a/viewrequests/__pycache__/urls.cpython-38.pyc and /dev/null differ diff --git a/viewrequests/__pycache__/views.cpython-38.pyc b/viewrequests/__pycache__/views.cpython-38.pyc deleted file mode 100644 index 8d9a639..0000000 Binary files a/viewrequests/__pycache__/views.cpython-38.pyc and /dev/null differ diff --git a/viewrequests/admin.py b/viewrequests/admin.py deleted file mode 100644 index 8c38f3f..0000000 --- a/viewrequests/admin.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.contrib import admin - -# Register your models here. diff --git a/viewrequests/migrations/__init__.py b/viewrequests/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/viewrequests/templates/viewrequests/requests.html b/viewrequests/templates/viewrequests/requests.html deleted file mode 100644 index c849567..0000000 --- a/viewrequests/templates/viewrequests/requests.html +++ /dev/null @@ -1,31 +0,0 @@ -{% extends 'common/master.html' %} -{% block body %} - -
- {% csrf_token %} - - - - - - - {% for req in requests %} - - - - - - {% endfor %} -
UserAddressDelete
{{ req.user.email }}{{ req.address.address }}
- -
-{% endblock %} \ No newline at end of file diff --git a/viewrequests/tests.py b/viewrequests/tests.py deleted file mode 100644 index 7ce503c..0000000 --- a/viewrequests/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here.