Commit c50950a3 authored by Yusei Tahara's avatar Yusei Tahara

2008-03-31 yusei

* Add a type based method for rewriting mail message.

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@20239 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent daef053e
##############################################################################
#
# Copyright (c) 2008 Nexedi SA and Contributors. All Rights Reserved.
# Yusei TAHARA <yusei@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program 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.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
"""External method for erp5_crm"""
import email
from cStringIO import StringIO
class MessageData:
def __init__(self, data):
self.message = email.message_from_string(data)
def getHeader(self, name):
return self.message.get(name)
def replaceHeader(self, name, value):
self.message.replace_header(name, value)
def getBodyMessage(self):
text_message = None
html_message = None
for part in self.message.walk():
if part.get_content_type() == 'text/plain' and not text_message and not part.is_multipart():
text_message = part
elif part.get_content_type() == 'text/html' and not html_message and not part.is_multipart():
return part
return text_message
def getTextContent(self):
message = self.getBodyMessage()
if message is not None:
return message.get_payload(decode=1)
def setTextContent(self, value):
message = self.getBodyMessage()
if message is not None:
message.set_payload(value)
def getValue(self, name):
if name=='body':
return self.getTextContent()
else:
return self.getHeader(name)
def replaceValue(self, name, value):
if name=='body':
self.setTextContent(value)
else:
self.replaceHeader(name, value)
def __str__(self):
return self.message.as_string()
def Base_rewriteMessageFileForCRMIngestion(context, ingestion_file):
ingestion_file.seek(0)
data = ingestion_file.read()
message = MessageData(data)
Base_findPortalTypeNameAndMatchedValueForEvent = context.Base_findPortalTypeNameAndMatchedValueForEvent
for name in ('subject', 'body'):
value = message.getValue(name)
portal_type, matched_value = Base_findPortalTypeNameAndMatchedValueForEvent(value)
if portal_type is not None:
new_value = value[len(matched_value)+1:]
message.replaceValue(name, new_value)
ingestion_file.seek(0)
ingestion_file.truncate(0)
ingestion_file.write(str(message))
ingestion_file.seek(0)
return ingestion_file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ContributionPredicate" module="Products.ERP5Type.Document.ContributionPredicate"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_identity_criterion</string> </key>
<value>
<dictionary>
<item>
<key> <string>file_extension</string> </key>
<value>
<list>
<string>eml</string>
</list>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>_range_criterion</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>criterion_property</string> </key>
<value>
<tuple>
<string>file_extension</string>
</tuple>
</value>
</item>
<item>
<key> <string>destination_portal_type</string> </key>
<value> <string>Mail Message</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>crm_ingestion</string> </value>
</item>
<item>
<key> <string>int_index</string> </key>
<value> <int>100</int> </value>
</item>
<item>
<key> <string>membership_criterion_base_category</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>membership_criterion_category</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Contribution Predicate</string> </value>
</item>
<item>
<key> <string>test_method_id</string> </key>
<value>
<tuple>
<string>IngestionFile_findTypeNameForEvent</string>
</tuple>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>CRM Ingestion</string> </value>
</item>
<item>
<key> <string>uid</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Python_magic</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>miss = (None, None)\n
\n
# length of portal type name must be less than 100.\n
value_first_lowered = value[:100].lower()\n
\n
if not \':\' in value_first_lowered:\n
return miss\n
\n
Base_translateString = context.Base_translateString\n
language_list = context.Localizer.get_supported_languages()\n
translated_portal_type_list = []\n
\n
def addCandidateTypeName(name, portal_type):\n
translated_portal_type_list.append((name, portal_type))\n
if \' \' in name:\n
alternative = name.split(\' \')[0]\n
translated_portal_type_list.append((alternative, portal_type))\n
\n
for type_name in context.getPortalEventTypeList():\n
addCandidateTypeName(type_name, type_name)\n
for language in language_list:\n
translated = Base_translateString(type_name, lang=language)\n
if translated != type_name:\n
addCandidateTypeName(translated, type_name)\n
\n
for translated, type_name in translated_portal_type_list:\n
prefix = \'%s:\' % translated.lower()\n
if value_first_lowered.startswith(prefix):\n
return type_name, translated\n
\n
return miss\n
</string> </value>
</item>
<item>
<key> <string>_code</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_filepath</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>value</string> </value>
</item>
<item>
<key> <string>errors</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>func_code</string> </key>
<value>
<object>
<klass>
<global name="FuncCode" module="Shared.DC.Scripts.Signature"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>co_argcount</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>co_varnames</string> </key>
<value>
<tuple>
<string>value</string>
<string>None</string>
<string>miss</string>
<string>_getattr_</string>
<string>_getitem_</string>
<string>value_first_lowered</string>
<string>context</string>
<string>Base_translateString</string>
<string>language_list</string>
<string>translated_portal_type_list</string>
<string>addCandidateTypeName</string>
<string>_getiter_</string>
<string>type_name</string>
<string>language</string>
<string>translated</string>
<string>prefix</string>
</tuple>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>func_defaults</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_findPortalTypeNameAndMatchedValueForEvent</string> </value>
</item>
<item>
<key> <string>warnings</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ExternalMethod" module="Products.ExternalMethod.ExternalMethod"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_function</string> </key>
<value> <string>Base_rewriteMessageFileForCRMIngestion</string> </value>
</item>
<item>
<key> <string>_module</string> </key>
<value> <string>CustomerRelationshipManagement</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_rewriteMessageFileForCRMIngestion</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -117,6 +117,15 @@ if reference_search_list:\n
if follow_up is None and text_search_list:\n
follow_up = getResultValue(reference=text_search_list, portal_type=follow_up_type_list)\n
\n
# Find portal type\n
subject = content_information.get(\'Subject\', \'\')\n
body = context.asText()\n
portal_type = None\n
for text in (subject, body):\n
portal_type, matched_value = context.Base_findPortalTypeNameAndMatchedValueForEvent(text)\n
if portal_type is not None:\n
break\n
\n
# Build dict.\n
result = {}\n
if sender_list:\n
......@@ -125,6 +134,8 @@ if to_list or cc_list:\n
result[\'destination_list\'] = to_list + cc_list\n
if follow_up is not None:\n
result[\'follow_up\'] = follow_up.getRelativeUrl()\n
if portal_type is not None:\n
result[\'portal_type\'] = portal_type\n
\n
return result\n
......@@ -194,6 +205,10 @@ return result\n
<string>follow_up_type_list</string>
<string>None</string>
<string>follow_up</string>
<string>subject</string>
<string>body</string>
<string>portal_type</string>
<string>matched_value</string>
<string>result</string>
<string>_write_</string>
</tuple>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Python_magic</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>if \'file\' in kw:\n
context.Base_rewriteMessageFileForCRMIngestion(context, kw[\'file\'])\n
return kw\n
</string> </value>
</item>
<item>
<key> <string>_code</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_filepath</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
</item>
<item>
<key> <string>errors</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>func_code</string> </key>
<value>
<object>
<klass>
<global name="FuncCode" module="Shared.DC.Scripts.Signature"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>co_argcount</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>co_varnames</string> </key>
<value>
<tuple>
<string>kw</string>
<string>_getattr_</string>
<string>context</string>
<string>_getitem_</string>
</tuple>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>func_defaults</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Event_rewriteIngestionData</string> </value>
</item>
<item>
<key> <string>warnings</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Python_magic</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from Products.ERP5Type.Document import newTempEvent\n
\n
new_id = newTempEvent(context, \'subobject\', data=context.getData())\n
event = context[new_id]\n
\n
# First, try to find portal type from content.\n
portal_type = event.getPropertyDictFromContent().get(\'portal_type\', None)\n
\n
if portal_type is not None:\n
return portal_type\n
\n
# If we cannot find portal type from content, return default one defined in\n
# predicate\n
return predicate.getDestinationPortalType()\n
</string> </value>
</item>
<item>
<key> <string>_code</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_filepath</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>predicate</string> </value>
</item>
<item>
<key> <string>errors</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>func_code</string> </key>
<value>
<object>
<klass>
<global name="FuncCode" module="Shared.DC.Scripts.Signature"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>co_argcount</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>co_varnames</string> </key>
<value>
<tuple>
<string>predicate</string>
<string>Products.ERP5Type.Document</string>
<string>newTempEvent</string>
<string>context</string>
<string>_getattr_</string>
<string>new_id</string>
<string>_getitem_</string>
<string>event</string>
<string>None</string>
<string>portal_type</string>
</tuple>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>func_defaults</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>IngestionFile_findTypeNameForEvent</string> </value>
</item>
<item>
<key> <string>warnings</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
2008-03-31 yusei
* Add a type based method for rewriting mail message.
2008-03-17 yusei
* Add source_project and destination_project fields for Ticket_view.
......
206
\ No newline at end of file
212
\ No newline at end of file
CustomerRelationshipManagement
\ No newline at end of file
portal_contribution_registry/crm_ingestion
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment