You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
5.8 KiB

from django.shortcuts import render, HttpResponse
4 years ago
from django.http import FileResponse
from django.core.mail import EmailMultiAlternatives
from django.conf import settings
from .models import Address, PDF, EmailSent, DownloadAttempt, CCEmail, BCCEmail
4 years ago
from .forms import CodeForm
from core.models import QuoteUser
from django.template.loader import render_to_string
from django.conf import settings
import ipinfo
import json
from datetime import date
import datetime
import hashlib
import os
4 years ago
IPINFO_HANDLER = ipinfo.getHandler()
def get_cc_emails():
return [x.email for x in CCEmail.objects.filter(active=True)]
def get_bcc_emails():
return [x.email for x in BCCEmail.objects.filter(active=True)]
# https://stackoverflow.com/a/4581997
def get_client_ip(request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = request.META.get('REMOTE_ADDR')
return ip
def get_client_ip_info(request):
realip = get_client_ip(request)
handler = ipinfo.getHandler()
details = handler.getDetails(realip)
# needed for testing
if settings.DEBUG and (details.ip == '127.0.0.1' or details.ip == '::1'):
details.city = 'Local'
details.region = 'Local'
details.country = 'Local'
return details
4 years ago
# Create your views here.
def starter(request):
return render(request, 'download/download-page.html', {
'things': list(Address.objects.all())
})
4 years ago
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__icontains=addr)[:10]]
))
def send_email(to, addr, pdf, dt_date):
# send email
email = EmailMultiAlternatives()
# TODO: redefining template
3 years ago
email.subject = "Your quote for " + addr.address + " is attached"
email.to = [to]
context = {
'address': addr.address,
'subject': settings.QUOTE_SUBJECT
}
# Remove CC/BCC to stop spam catchers.
#email.bcc = get_bcc_emails()
#email.cc = get_cc_emails()
email.body = render_to_string('download/email/quote.txt', context)
email.attach_alternative(render_to_string('download/email/quote.html', context), 'text/html')
with open(str(pdf.upload_file), 'rb') as f:
content = f.read()
email.attach(pdf.address.address + '.pdf', content, 'application/octate-stream')
email.send()
def save_email(user, addr, pdf, dt):
EmailSent.objects.create(
user=user,
pdf=pdf,
ref_code=hashlib.sha256(dt.strftime("%Y%m%d%H%M%S").encode()).hexdigest()
)
def download(request):
4 years ago
if request.method == 'POST':
form = CodeForm(request.POST)
if form.is_valid():
# get addr by id
addr = Address.objects.filter(address=form.cleaned_data['address'])
if len(addr) == 0:
return HttpResponse('{ "status": "ERR", "message": "Address not found."}', content_type='application/json')
# only get first addr
addr = addr[0]
user, created = QuoteUser.objects.get_or_create(username=form.cleaned_data['email'], email=form.cleaned_data['email'])
# disallow login for new users
if created:
user.set_unusable_password()
user.save()
# TODO: fail gracefully
ip = get_client_ip_info(request)
# create download attempt
dla = DownloadAttempt.objects.create(
user=user,
pdf=PDF.objects.filter(address=addr).order_by('-upload_date')[0],
ip=ip.ip,
geolocation="{0}, {1}, {2}".format(
ip.city,
ip.region,
ip.country
)
)
pdf_quotes = PDF.objects.filter(address=addr, code=form.cleaned_data['code']).order_by('upload_date').reverse()
if len(pdf_quotes) == 0:
return HttpResponse('{ "status": "ERR", "message": "Incorrect code"}', content_type='application/json')
pdf_quote = pdf_quotes[0]
dla.code_correct = True
dla.save()
# stop spam; only allow 3 sends in one day
today = date.today()
today_good_attempts = DownloadAttempt.objects.filter(timestamp__day=today.day, timestamp__month=today.month, timestamp__year=today.year, email_sent=True, pdf__address=addr)
if len(today_good_attempts) >= settings.MAX_EMAILS_PER_DAY:
return HttpResponse('{ "status": "ERR", "message": "An email has been sent out for this address ' + str(settings.MAX_EMAILS_PER_DAY) + ' times today. Try again tomorrow." }', content_type='application/json');
# create timestamps
dt_date = datetime.datetime.now()
try:
send_email(form.cleaned_data['email'], addr, pdf_quote, dt_date)
except Exception as e:
print(e)
return HttpResponse('{ "status": "ERR", "message": "Email failed to send."}', content_type='application/json')
# only saves email if it sent
save_email(user, addr, pdf_quote, dt_date)
# only makes successful if email is sent
dla.email_sent = True
dla.save()
return HttpResponse('{ "status": "OK" }', content_type="application/json")
4 years ago
else:
form = CodeForm()
return render(request, 'download/code-form.html', {
'form': form
4 years ago
})
def download_preload(request, addid):
if request.method == 'POST':
code = request.POST.get('code')
email = request.POST.get('email')
form = CodeForm(initial={'code': code, 'email': email})
return render(request, 'download/code-form.html', {
'form': form,
'id': addrid,
})