Private
Public Access
1
0
Files
rowsandall/rowers/management/commands/processemail.py
2017-12-03 20:18:24 +01:00

220 lines
6.9 KiB
Python

#!/srv/venv/bin/python
""" Process emails """
import sys
import os
import zipfile
import re
import time
from time import strftime
from django.core.management.base import BaseCommand
from django_mailbox.models import Message, MessageAttachment,Mailbox
from django.core.urlresolvers import reverse
from django.conf import settings
from rowers.models import Workout, Rower
from rowingdata import rower as rrower
from rowingdata import rowingdata as rrdata
import rowers.uploads as uploads
from rowers.mailprocessing import make_new_workout_from_email, send_confirm
workoutmailbox = Mailbox.objects.get(name='workouts')
failedmailbox = Mailbox.objects.get(name='Failed')
# If you find a solution that does not need the two paths, please comment!
sys.path.append('$path_to_root_of_project$')
sys.path.append('$path_to_root_of_project$/$project_name$')
os.environ['DJANGO_SETTINGS_MODULE'] = '$project_name$.settings'
if not getattr(__builtins__, "WindowsError", None):
class WindowsError(OSError): pass
def rdata(file_obj, rower=rrower()):
""" Read rowing data file and return 0 if file doesn't exist"""
try:
result = rrdata(file_obj, rower=rower)
except IOError:
result = 0
return result
def processattachment(rower, fileobj, title, uploadoptions,testing=False):
try:
filename = fileobj.name
except AttributeError:
filename = fileobj[6:]
# test if file exists and is not empty
try:
with open('media/'+filename,'r') as fop:
line = fop.readline()
except IOError:
return 0
workoutid = [
make_new_workout_from_email(rower, filename, title,testing=testing)
]
if workoutid[0]:
link = settings.SITE_URL+reverse(
rower.defaultlandingpage,
kwargs = {
'id':workoutid[0],
}
)
if uploadoptions and not 'error' in uploadoptions:
workout = Workout.objects.get(id=workoutid[0])
uploads.do_sync(workout, uploadoptions)
uploads.make_private(workout, uploadoptions)
if 'make_plot' in uploadoptions:
plottype = uploadoptions['plottype']
workoutcsvfilename = workout.csvfilename[6:-4]
timestr = strftime("%Y%m%d-%H%M%S")
imagename = workoutcsvfilename + timestr + '.png'
result,jobid = uploads.make_plot(
workout.user, workout, workoutcsvfilename,
workout.csvfilename,
plottype, title,
imagename=imagename
)
try:
if workoutid and not testing:
email_sent = send_confirm(
rower.user, title, link,
uploadoptions
)
time.sleep(10)
except:
try:
if not testing:
time.sleep(10)
if workoutid:
email_sent = send_confirm(
rower.user, title, link,
uploadoptions
)
except:
pass
return workoutid
def get_from_address(message):
from_address = message.from_address[0].lower()
if message.encoded:
body = message.text.splitlines()
else:
body = message.get_body().splitlines()
try:
first_line = body[0].lower()
except IndexError:
first_line = ''
if "quiske" in first_line:
match = re.search(r'[\w\.-]+@[\w\.-]+', first_line)
return match.group(0)
return from_address
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument(
'--testing',
action='store_true',
dest='testing',
default=False,
help="Run in testing mode, don't send emails",
)
"""Run the Email processing command """
def handle(self, *args, **options):
messages = Message.objects.filter(mailbox_id = workoutmailbox.id)
message_ids = [m.id for m in messages]
attachments = MessageAttachment.objects.filter(
message_id__in=message_ids
)
if 'testing' in options:
testing = options['testing']
else:
testing = False
cntr = 0
for attachment in attachments:
extension = attachment.document.name[-3:].lower()
try:
message = Message.objects.get(id=attachment.message_id)
if message.encoded:
# if message.text:
body = "\n".join(message.text.splitlines())
else:
body = message.get_body()
uploadoptions = uploads.upload_options(body)
from_address = get_from_address(message)
name = message.subject
# get a list of users
# theusers = User.objects.filter(email=from_address)
rowers = [
r for r in Rower.objects.all() if r.user.email.lower() == from_address
]
except IOError:
rowers = []
for rower in rowers:
if extension == 'zip':
zip_file = zipfile.ZipFile(attachment.document)
for id,filename in enumerate(zip_file.namelist()):
datafile = zip_file.extract(filename, path='media/')
if id>0:
title = name+' ('+str(id+1)+')'
else:
title = name
workoutid = processattachment(
rower, datafile, title, uploadoptions,
testing=testing
)
else:
# move attachment and make workout
workoutid = processattachment(
rower, attachment.document, name, uploadoptions,
testing=testing
)
# We're done with the attachment. It can be deleted
try:
attachment.delete()
except IOError:
pass
except WindowsError:
if not testing:
time.sleep(2)
try:
attachment.delete()
except WindowsError:
pass
except:
message.mailbox = failedmailbox
message.save()
if message.attachments.exists() is False:
# no attachments, so can be deleted
message.delete()
messages = Message.objects.all()
for message in messages:
if message.attachments.exists() is False:
message.delete()
self.stdout.write(self.style.SUCCESS(
'Successfully processed email attachments'))