Page MenuHomec4science

elmsubmit.py
No OneTemporary

File Metadata

Created
Fri, Jul 5, 13:01

elmsubmit.py

<protect># -*- coding: utf-8 -*-</protect>
<protect>## $Id$</protect>
## This file is part of the CERN Document Server Software (CDSware).
## Copyright (C) 2002 CERN.
##
## The CDSware is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License as
## published by the Free Software Foundation; either version 2 of the
## License, or (at your option) any later version.
##
## The CDSware is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<protect>## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.</protect>
<protect>
# import sys
import os
import os.path
import cdsware.config2pyobj as config2pyobj
import re
import smtplib
import cdsware.elmsubmit_EZEmail as elmsubmit_EZEmail
import cdsware.elmsubmit_submission_parser as elmsubmit_submission_parser
import cdsware.elmsubmit_field_validation as elmsubmit_field_validation
from cdsware.elmsubmit_misc import random_alphanum_string as _random_alphanum_string
from cdsware.elmsubmit_misc import import_dots as _import_dots
# Import the config file:
from cdsware.config import etcdir
#_this_module = sys.modules[__name__]
#_this_module_dir = os.path.abspath(os.path.dirname(_this_module.__file__))
elmconf = config2pyobj.configobj([os.path.join(etcdir, 'elmsubmit', 'elmsubmit.cfg')])
def process_email(email_string):
# See if we can parse the email:
try:
e = elmsubmit_EZEmail.ParseMessage(email_string)
except elmsubmit_EZEmail.EZEmailParseError, err:
try:
if err.basic_email_info['from'] is None:
raise ValueError
response = elmsubmit_EZEmail.CreateMessage(to=err.basic_email_info['from'],
_from=elmconf.people.admin,
message=elmconf.nolangmsgs.bad_email,
subject="Re: " + (err.basic_email_info.get('Subject', '') or ''),
references=[err.basic_email_info.get('message-id', '') or ''],
wrap_message=False)
_send_smtp(_from=elmconf.people.admin, to=err.basic_email_info['from'], msg=response)
raise elmsubmitError("Email could not be parsed. Reported to sender.")
except ValueError:
raise elmsubmitError("From: field of submission email could not be parsed. Could not report to sender.")
# See if we can parse the submission fields in the email:
try:
# Note that this returns a dictionary loaded with utf8 byte strings:
(submission_dict, dummy_var) = elmsubmit_submission_parser.parse_submission(e.primary_message.encode('utf8'))
# Add the submitter's email:
submission_dict['SuE'] = e.from_email.encode('utf8')
except elmsubmit_submission_parser.SubmissionParserError:
_notify(msg=e, response=elmconf.nolangmsgs.bad_submission)
raise elmsubmitSubmissionError("Could not parse submission.")
# See if we can find a recognized document type specified by the TYPE field:
try:
doctype = submission_dict['type']
handler_module_name = elmconf.sub_handlers.__getattr__(doctype)
except KeyError:
_notify(msg=e, response=elmconf.nolangmsgs.missing_type)
raise elmsubmitSubmissionError("Submission does not specify document type.")
except config2pyobj.ConfigGetKeyError:
_notify(msg=e, response=elmconf.nolangmsgs.unsupported_type)
raise elmsubmitSubmissionError("Submission specifies unrecognized document type.")
# See if we can import the python module containing a handler for
# the document type:
handler_module = _import_dots('cdsware.' + handler_module_name)
handler_function = getattr(handler_module, 'handler')
required_fields = getattr(handler_module, 'required_fields')
# Check we have been given the required fields:
available_fields = submission_dict.keys()
if not len(filter(lambda x: x in available_fields, required_fields)) == len(required_fields):
response = elmconf.nolangmsgs.missing_fields_1 + (' %s ' % (doctype)) + elmconf.nolangmsgs.missing_fields_2 + "\n\n" + repr(required_fields)
_notify(msg=e, response=response)
raise elmsubmitSubmissionError("Submission does not contain the required fields for document type %s. Required fields: %s" % (doctype, required_fields))
# Check that the fields we have been given validate OK:
map(lambda field: validate_submission_field(e, submission_dict, field, submission_dict[field]), required_fields)
# Map the fields to their proper storage names:
def f((field, value)):
try:
field = elmconf.field_mappings.__getattr__(field)
except config2pyobj.ConfigGetKeyError:
# No mapping defined for field:
pass
return(field, value)
submission_dict = dict(map(f, submission_dict.items()))
# Let the handler function process the email:
(response_email, admin_response_email, error) = handler_function(msg=e, submission_dict=submission_dict, elmconf=elmconf)
# Reply to the sender if there was a problem:
if response_email is not None:
_notify(msg=e, response=response_email)
# Reply to the admin if there was a failure:
if admin_response_email is not None:
_notify_admin(response=admin_response_email)
if error is not None:
raise error
def validate_submission_field(msg, submission_dict, field, value):
try:
(field_documentation, fixed_value, ok) = getattr(elmsubmit_field_validation, field)(value.decode('utf8'))
submission_dict[field] = fixed_value.encode('utf8')
if not ok:
_notify(msg=msg, response=elmconf.nolangmsgs.bad_field + ' ' + field.upper() + '\n\n'
+ elmconf.nolangmsgs.correct_format + '\n\n' + field_documentation)
raise elmsubmitSubmissionError("Submission contains field %s which does not validate." % (field))
except AttributeError:
# No validation defined for this field:
pass
def get_storage_dir(msg, doctype):
path = os.path.join(elmconf.files.maildir, doctype, _random_alphanum_string(15))
while os.path.exists(path):
path = os.path.join(elmconf.files.maildir, doctype, _random_alphanum_string(15))
try:
os.mkdir(path)
except EnvironmentError:
_notify(msg=msg, response=elmconf.nolangmsgs.temp_problem)
_notify_admin(response="Could not create directory: %s" % (path))
raise elmsubmitError("Could not create directory: %s" % (path))
return path
def process_files(msg, submission_dict):
files = map(lambda filename: filename.decode('utf8'), submission_dict['files'].splitlines())
# Check for the special filename 'all': if we find it, add all of
# the files attached to the email to the list of files to submit:
if 'all' in files:
f = lambda attachment: attachment['filename'] is not None
g = lambda attachment: attachment['filename'].lower()
attached_filenames = map(g, filter(f, msg.attachments))
files.extend(attached_filenames)
files = filter(lambda name: name != 'all', files)
# Filter out duplicate filenames:
_temp = {}
map(lambda filename: _temp.update({ filename : 1}), files)
files = _temp.keys()
# Get the files out of the mail message:
file_list = {}
for filename in files:
# See if we have special keyword self (which uses the mail message itself as the file):
if filename == 'self':
file = msg.original_message
filename = _random_alphanum_string(8) + '_' + msg.date_sent_utc.replace(' ', '_').replace(':', '-') + '.msg'
else:
nominal_attachments = filter(lambda attachment: attachment['filename'].lower() == filename, msg.attachments)
try:
file = nominal_attachments[0]['file']
except IndexError:
_notify(msg=msg, response=elmconf.nolangmsgs.missing_attachment + ' ' + filename)
raise elmsubmitSubmissionError("Submission is missing attached file: %s" % (filename))
file_list[filename.encode('utf8')] = file
submission_dict['files'] = file_list
def _send_smtp(_from, to, msg):
s = smtplib.SMTP()
s.connect(host=elmconf.servers.smtp)
s.sendmail(_from, to, msg)
s.close()
def _notify(msg, response):
response = elmsubmit_EZEmail.CreateMessage(to=[(msg.from_name, msg.from_email)],
_from=elmconf.people.admin,
message=response,
subject="Re: " + msg.subject,
references=[msg.message_id],
wrap_message=False)
_send_smtp(_from=elmconf.people.admin, to=msg.from_email, msg=response)
def _notify_admin(response):
response = elmsubmit_EZEmail.CreateMessage(to=elmconf.people.admin,
_from=elmconf.people.admin,
message=response,
subject="CDSWare / elmsubmit problem.",
wrap_message=False)
_send_smtp(_from=elmconf.people.admin, to=elmconf.people.admin, msg=response)
class elmsubmitError(Exception):
pass
class elmsubmitSubmissionError(elmsubmitError):
pass
class _elmsubmitPrivateError(Exception):
"""
An emtpy parent class for all the private errors in this module.
"""
pass
</protect>

Event Timeline