220 lines
6.9 KiB
Python
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'))
|