[IMP]: mail_gateway: Improvement in mailgate objects and refactoring of mailgate script to be used for any OpenERP model (Removed dependency with crm)
bzr revid: rpa@tinyerp.com-20100601123058-9j3ef3yi1z36vqlz
This commit is contained in:
@@ -50,9 +50,11 @@ class mailgate_thread(osv.osv):
|
||||
_rec_name = 'thread'
|
||||
|
||||
_columns = {
|
||||
'thread': fields.char('Thread', size=32, required=False),
|
||||
'thread': fields.char('Thread', size=124, required=False),
|
||||
'message_ids': one2many_domain('mailgate.message', 'thread_id', 'Messages', domain=[('history', '=', True)], required=False),
|
||||
'log_ids': one2many_domain('mailgate.message', 'thread_id', 'Logs', domain=[('history', '=', False)], required=False),
|
||||
'log_ids': one2many_domain('mailgate.message', 'thread_id', 'Logs', domain=[('history', '=', False)], required=False),
|
||||
'model': fields.char('Model Name', size=64, required=False),
|
||||
'res_id': fields.integer('Resource ID'),
|
||||
}
|
||||
|
||||
def __history(self, cr, uid, cases, keyword, history=False, subject=None, email=False, details=None, email_from=False, message_id=False, attach=[], context={}):
|
||||
@@ -130,8 +132,6 @@ class mailgate_message(osv.osv):
|
||||
|
||||
_columns = {
|
||||
'name':fields.char('Message', size=64),
|
||||
'model_id': fields.many2one('ir.model', 'Model'),
|
||||
'res_id': fields.integer('Resource ID'),
|
||||
'thread_id':fields.many2one('mailgate.thread', 'Thread'),
|
||||
'date': fields.datetime('Date'),
|
||||
'history': fields.boolean('Is History?', required=False),
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<field name="name" required="1" select="1"/>
|
||||
<field name="date" required="1" select="1"/>
|
||||
<field name="user_id" string="Responsible" select="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Details">
|
||||
<group col="4" colspan="4">
|
||||
@@ -33,7 +33,7 @@
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="view_mailgate_message_tree">
|
||||
<field name="name">mailgate.message.tree</field>
|
||||
<field name="model">mailgate.message</field>
|
||||
@@ -41,12 +41,12 @@
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Mailgateway Message">
|
||||
<field name="date" />
|
||||
<field name="email_from" />
|
||||
<field name="user_id" />
|
||||
<field name="email_from" />
|
||||
<field name="user_id" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="view_mailgate_message_search">
|
||||
<field name="name">mailgate.message.search</field>
|
||||
<field name="model">mailgate.message</field>
|
||||
@@ -56,11 +56,11 @@
|
||||
<field name="name" />
|
||||
<field name="date" />
|
||||
<field name="user_id" />
|
||||
<field name="message_id" />
|
||||
<field name="message_id" />
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="view_mailgate_thread_form">
|
||||
<field name="name">mailgate.thread.form</field>
|
||||
@@ -68,7 +68,12 @@
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Mailgateway Thread">
|
||||
<field name="thread" select="1"/>
|
||||
<group col="6" colspan="4">
|
||||
<field name="thread" select="1" colspan="3"/>
|
||||
<newline/>
|
||||
<field name="model" />
|
||||
<field name="res_id" />
|
||||
</group>
|
||||
<separator string="Logs" colspan="4"/>
|
||||
<field name="log_ids" nolabel="1" colspan="4" domain="[('history', '=', True)]">
|
||||
<tree string="Mailgateway Logs">
|
||||
@@ -79,7 +84,7 @@
|
||||
<field name="name" />
|
||||
<field name="date" />
|
||||
<field name="user_id" />
|
||||
<field name="message_id" />
|
||||
<field name="message_id" />
|
||||
<notebook colspan="4">
|
||||
<page string="Email Details">
|
||||
<group col="4" colspan="4">
|
||||
@@ -131,7 +136,7 @@
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="view_mailgate_thread_tree">
|
||||
<field name="name">mailgate.thread.tree</field>
|
||||
<field name="model">mailgate.thread</field>
|
||||
@@ -143,7 +148,7 @@
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.actions.act_window" id="action_view_mailgate_thread">
|
||||
<field name="name">Mailgateway Threads</field>
|
||||
<field name="res_model">mailgate.thread</field>
|
||||
@@ -151,7 +156,7 @@
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_mailgate_thread_tree"/>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.actions.act_window.view" id="action_view_mailgate_thread_view1">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view_mode">tree</field>
|
||||
@@ -164,19 +169,16 @@
|
||||
<field name="view_id" ref="view_mailgate_thread_form"/>
|
||||
<field name="act_window_id" ref="action_view_mailgate_thread"/>
|
||||
</record>
|
||||
|
||||
|
||||
<!-- <menuitem id="base.menu_crm_configuration" name="Cases"
|
||||
parent="base.menu_base_config" sequence="0"/>
|
||||
|
||||
|
||||
<menuitem id="menu_mailgate_thread" name="Mailgateway Threads" action="action_view_mailgate_thread"
|
||||
parent="base.menu_crm_configuration" sequence="20"/>
|
||||
-->
|
||||
parent="base.menu_base_config" sequence="20"/>
|
||||
|
||||
<act_window domain="[('partner_id', '=', active_id), ('history', '=', True)]"
|
||||
id="act_res_partner_emails" name="Emails"
|
||||
res_model="mailgate.message"
|
||||
src_model="res.partner"
|
||||
view_id="view_mailgate_message_tree"
|
||||
view_id="view_mailgate_message_tree"
|
||||
/>
|
||||
|
||||
</data>
|
||||
|
||||
@@ -130,7 +130,7 @@ class rpc_proxy(object):
|
||||
return self.rpc.execute(self.dbname, self.user_id, self.passwd, *request, **kwargs)
|
||||
|
||||
class email_parser(object):
|
||||
def __init__(self, uid, password, model, email, email_default, dbname, host, port):
|
||||
def __init__(self, uid, password, model, email, email_default, dbname, host, port, smtp_server=None, smtp_port=None, smtp_ssl=None, smtp_user=None, smtp_password=None):
|
||||
self.rpc = rpc_proxy(uid, password, host=host, port=port, dbname=dbname)
|
||||
try:
|
||||
self.model_id = int(model)
|
||||
@@ -141,7 +141,13 @@ class email_parser(object):
|
||||
self.email = email
|
||||
self.email_default = email_default
|
||||
self.canal_id = False
|
||||
|
||||
self.smtp_server = smtp_server
|
||||
self.smtp_port = smtp_port
|
||||
self.smtp_ssl = smtp_ssl
|
||||
self.smtp_user = smtp_user
|
||||
self.smtp_password = smtp_password
|
||||
|
||||
|
||||
def email_get(self, email_from):
|
||||
res = email_re.search(email_from)
|
||||
return res and res.group(1)
|
||||
@@ -170,7 +176,28 @@ class email_parser(object):
|
||||
from email.Header import decode_header
|
||||
s = decode_header(s.replace('\r', ''))
|
||||
return ''.join(map(lambda x:self._to_decode(x[0], [x[1]]), s or []))
|
||||
|
||||
|
||||
def history(self, model, new_id, subject, msg_to, msg_from, body, attach):
|
||||
thread_data = {
|
||||
'model': model,
|
||||
'res_id': new_id,
|
||||
'thread': subject,
|
||||
}
|
||||
thread_id = self.rpc('mailgate.thread', 'create', thread_data)
|
||||
msg_data = {
|
||||
'name': subject,
|
||||
'history': True,
|
||||
'thread_id': thread_id,
|
||||
'user_id': self.rpc.user_id,
|
||||
'date': time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'email_from': msg_from,
|
||||
'email_to': msg_to,
|
||||
'description': body,
|
||||
'attachment_ids': [(6, 0, attach)]
|
||||
}
|
||||
msg_id = self.rpc('mailgate.message', 'create', msg_data)
|
||||
return True
|
||||
|
||||
def msg_new(self, msg):
|
||||
message = self.msg_body_get(msg)
|
||||
msg_subject = self._decode_header(msg['Subject'])
|
||||
@@ -189,26 +216,30 @@ class email_parser(object):
|
||||
data.update(self.partner_get(msg_from))
|
||||
|
||||
try:
|
||||
id = self.rpc(self.model, 'create', data)
|
||||
self.rpc(self.model, '_history', [id], 'Receive', True, msg_to, message['body'], msg_from, False, {'model' : self.model})
|
||||
#self.rpc(self.model, 'case_open', [id])
|
||||
att_ids = []
|
||||
new_id = self.rpc(self.model, 'create', data)
|
||||
attachments = message['attachment']
|
||||
for attach in attachments or []:
|
||||
data_attach = {
|
||||
'name': str(attach),
|
||||
'datas': binascii.b2a_base64(str(attachments[attach])),
|
||||
'datas_fname': str(attach),
|
||||
'description': 'Mail attachment',
|
||||
'res_model': self.model,
|
||||
'res_id': new_id
|
||||
}
|
||||
att_ids.append(self.rpc('ir.attachment', 'create', data_attach))
|
||||
try:
|
||||
self.rpc(self.model, 'history', [new_id], 'Receive', True, msg_to, message['body'], msg_from, False, {'model' : self.model})
|
||||
except Exception, e:
|
||||
self.history(self.model, new_id, msg_subject, msg_to, msg_from, message['body'], att_ids)
|
||||
except Exception, e:
|
||||
if getattr(e, 'faultCode', '') and 'AccessError' in e.faultCode:
|
||||
e = '\n\nThe Specified user does not have an access to the CRM case.'
|
||||
e = '\n\nThe Specified user does not have an access to the Model.'
|
||||
print e
|
||||
attachments = message['attachment']
|
||||
for attach in attachments or []:
|
||||
data_attach = {
|
||||
'name': str(attach),
|
||||
'datas': binascii.b2a_base64(str(attachments[attach])),
|
||||
'datas_fname': str(attach),
|
||||
'description': 'Mail attachment',
|
||||
'res_model': self.model,
|
||||
'res_id': id
|
||||
}
|
||||
self.rpc('ir.attachment', 'create', data_attach)
|
||||
|
||||
|
||||
return id
|
||||
return new_id
|
||||
|
||||
# #change the return type format to dictionary
|
||||
# {
|
||||
@@ -262,63 +293,6 @@ class email_parser(object):
|
||||
#end for
|
||||
return message
|
||||
|
||||
def msg_user(self, msg, id):
|
||||
body = self.msg_body_get(msg)
|
||||
|
||||
# handle email body commands (ex: Set-State: Draft)
|
||||
actions = {}
|
||||
body_data=''
|
||||
for line in body['body'].split('\n'):
|
||||
res = command_re.match(line)
|
||||
if res:
|
||||
actions[res.group(1).lower()] = res.group(2).lower()
|
||||
else:
|
||||
body_data += line+'\n'
|
||||
body['body'] = body_data
|
||||
|
||||
data = {
|
||||
# 'description': body['body'],
|
||||
}
|
||||
act = 'case_open'
|
||||
if 'state' in actions:
|
||||
if actions['state'] in ['draft', 'close', 'cancel', 'open', 'pending']:
|
||||
act = 'case_' + actions['state']
|
||||
|
||||
for k1, k2 in [('cost', 'planned_cost'), ('revenue', 'planned_revenue'), ('probability', 'probability')]:
|
||||
try:
|
||||
data[k2] = float(actions[k1])
|
||||
except:
|
||||
pass
|
||||
|
||||
if 'priority' in actions:
|
||||
if actions['priority'] in ('1', '2', '3', '4', '5'):
|
||||
data['priority'] = actions['priority']
|
||||
|
||||
if 'partner' in actions:
|
||||
data['email_from'] = actions['partner'][:128]
|
||||
|
||||
if 'user' in actions:
|
||||
uids = self.rpc('res.users', 'name_search', actions['user'])
|
||||
if uids:
|
||||
data['user_id'] = uids[0][0]
|
||||
|
||||
self.rpc(self.model, act, [id])
|
||||
self.rpc(self.model, 'write', [id], data)
|
||||
attachments = body['attachment']
|
||||
for attach in attachments or []:
|
||||
data_attach = {
|
||||
'name': str(attach),
|
||||
'datas': binascii.b2a_base64(str(attachments[attach])),
|
||||
'datas_fname': str(attach),
|
||||
'description': 'Mail attachment',
|
||||
'res_model': self.model,
|
||||
'res_id': id
|
||||
}
|
||||
self.rpc('ir.attachment', 'create', data_attach)
|
||||
|
||||
self.rpc(self.model, '_history', [id], 'Send', True, self._decode_header(msg['To']), body['body'], self._decode_header(msg['From']), False, {'model' : self.model})
|
||||
return id
|
||||
|
||||
def msg_send(self, msg, emails, priority=None):
|
||||
if not len(emails):
|
||||
return False
|
||||
@@ -330,85 +304,38 @@ class email_parser(object):
|
||||
msg['Cc'] = ','.join(emails[1:])
|
||||
del msg['Reply-To']
|
||||
msg['Reply-To'] = self.email
|
||||
if priority:
|
||||
msg['X-Priority'] = priorities.get(priority, '3 (Normal)')
|
||||
s = smtplib.SMTP()
|
||||
s.connect()
|
||||
s.sendmail(self.email, emails, msg.as_string())
|
||||
s = smtplib.SMTP(self.smtp_server, self.smtp_port)
|
||||
s.ehlo()
|
||||
s.starttls()
|
||||
s.ehlo()
|
||||
|
||||
if self.smtp_user and self.smtp_password:
|
||||
s.login(self.smtp_user, self.smtp_password)
|
||||
s.sendmail(self.email, emails, msg.as_string())
|
||||
s.close()
|
||||
return True
|
||||
|
||||
def msg_partner(self, msg, id):
|
||||
message = self.msg_body_get(msg)
|
||||
body = message['body']
|
||||
act = 'case_open'
|
||||
self.rpc(self.model, act, [id])
|
||||
#body2 = '\n'.join(map(lambda l: '> '+l, (body or '').split('\n')))
|
||||
#data = {
|
||||
# 'description':body,
|
||||
#}
|
||||
#self.rpc(self.model, 'write', [id], data)
|
||||
attachments = message['attachment']
|
||||
for attach in attachments or []:
|
||||
data_attach = {
|
||||
'name': str(attach),
|
||||
'datas': binascii.b2a_base64(str(attachments[attach])),
|
||||
'datas_fname': str(attach),
|
||||
'description': 'Mail attachment',
|
||||
'res_model': self.model,
|
||||
'res_id': id
|
||||
}
|
||||
self.rpc('ir.attachment', 'create', data_attach)
|
||||
|
||||
self.rpc(self.model, '_history', [id], 'Send', True, self._decode_header(msg['To']), message['body'], self._decode_header(msg['From']), False, {'model' : self.model})
|
||||
return id
|
||||
|
||||
def msg_test(self, msg, case_str):
|
||||
if not case_str:
|
||||
return (False, False)
|
||||
emails = self.rpc(self.model, 'emails_get', int(case_str))
|
||||
return (int(case_str), emails)
|
||||
|
||||
def parse(self, msg):
|
||||
case_str = reference_re.search(msg.get('References', ''))
|
||||
if case_str:
|
||||
case_str = case_str.group(1)
|
||||
else:
|
||||
case_str = case_re.search(msg.get('Subject', ''))
|
||||
if case_str:
|
||||
case_str = case_str.group(1)
|
||||
(case_id, emails) = self.msg_test(msg, case_str)
|
||||
if case_id:
|
||||
if emails[0] and self.email_get(emails[0])==self.email_get(self._decode_header(msg['From'])):
|
||||
self.msg_user(msg, case_id)
|
||||
else:
|
||||
self.msg_partner(msg, case_id)
|
||||
else:
|
||||
case_id = self.msg_new(msg)
|
||||
subject = self._decode_header(msg['subject'])
|
||||
if msg.get('Subject', ''):
|
||||
del msg['Subject']
|
||||
msg['Subject'] = '['+str(case_id)+'] '+subject
|
||||
msg['Message-Id'] = '<'+str(time.time())+'-openerpcrm-'+str(case_id)+'@'+socket.gethostname()+'>'
|
||||
|
||||
emails = self.rpc(self.model, 'emails_get', case_id)
|
||||
priority = emails[3]
|
||||
em = [emails[0], emails[1]] + (emails[2] or '').split(',')
|
||||
emails = map(self.email_get, filter(None, em))
|
||||
#TODO: Something with Message hierarchy
|
||||
res_id = self.msg_new(msg)
|
||||
subject = self._decode_header(msg['subject'])
|
||||
if msg.get('Subject', ''):
|
||||
del msg['Subject']
|
||||
msg['Subject'] = '['+str(res_id)+'] '+subject
|
||||
msg['Message-Id'] = '<'+str(time.time())+'-openerpcrm-'+str(res_id)+'@'+socket.gethostname()+'>'
|
||||
|
||||
mm = [self._decode_header(msg['From']), self._decode_header(msg['To'])]+self._decode_header(msg.get('Cc', '')).split(',')
|
||||
msg_mails = map(self.email_get, filter(None, mm))
|
||||
|
||||
emails = filter(lambda m: m and m not in msg_mails, emails)
|
||||
try:
|
||||
self.msg_send(msg, emails, priority)
|
||||
except:
|
||||
self.msg_send(msg, msg_mails)
|
||||
except Exception, e:
|
||||
if self.email_default:
|
||||
a = self._decode_header(msg['Subject'])
|
||||
del msg['Subject']
|
||||
msg['Subject'] = '[OpenERP-CaseError] ' + a
|
||||
msg['Subject'] = '[OpenERP-FetchError] ' + a
|
||||
self.msg_send(msg, self.email_default.split(','))
|
||||
return case_id, emails
|
||||
return res_id, msg_mails
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys, optparse
|
||||
@@ -425,10 +352,14 @@ if __name__ == '__main__':
|
||||
parser.add_option("-d", "--dbname", dest="dbname", help="Database name (default: terp)", default='terp')
|
||||
parser.add_option("--host", dest="host", help="Hostname of the Open ERP Server", default="localhost")
|
||||
parser.add_option("--port", dest="port", help="Port of the Open ERP Server", default="8069")
|
||||
|
||||
parser.add_option('--smtp', dest='smtp_server', default='', help='specify the SMTP server for sending email')
|
||||
parser.add_option('--smtp-port', dest='smtp_port', default='25', help='specify the SMTP port', type="int")
|
||||
parser.add_option('--smtp-ssl', dest='smtp_ssl', default='', help='specify the SMTP server support SSL or not')
|
||||
parser.add_option('--smtp-user', dest='smtp_user', default='', help='specify the SMTP username for sending email')
|
||||
parser.add_option('--smtp-password', dest='smtp_password', default='', help='specify the SMTP password for sending email')
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
parser = email_parser(options.userid, options.password, options.model, options.email, options.default, dbname=options.dbname, host=options.host, port=options.port)
|
||||
parser = email_parser(options.userid, options.password, options.model, options.email, options.default, dbname=options.dbname, host=options.host, port=options.port, smtp_server=options.smtp_server, smtp_port=options.smtp_port, smtp_ssl=options.smtp_ssl, smtp_user=options.smtp_user, smtp_password=options.smtp_password)
|
||||
|
||||
msg_txt = email.message_from_file(sys.stdin)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user