#! /usr/bin/python # -*- encoding: utf-8 -*- import xmlrpclib import sys from optparse import OptionParser # CID Name that will be displayed if there is no match in res.partner.address default_cid_name = "Not in OpenERP" # Define command line options option_server = {'names': ('-s', '--server'), 'dest': 'server', 'type': 'string', 'help': 'DNS or IP address of the OpenERP server. Default = localhost', 'action': 'store', 'default':'localhost'} option_port = {'names': ('-p', '--port'), 'dest': 'port', 'type': 'int', 'help': "Port of OpenERP's XML-RPC interface. Default = 8069", 'action': 'store', 'default': 8069} option_database = {'names': ('-d', '--database'), 'dest': 'database', 'type': 'string', 'help': "OpenERP database name. Default = openerp", 'action': 'store', 'default': 'openerp'} option_user = {'names': ('-u', '--user-id'), 'dest': 'user', 'type': 'int', 'help': "OpenERP user ID to use when connecting to OpenERP. Default = 2", 'action': 'store', 'default': 2} option_password = {'names': ('-w', '--password'), 'dest': 'password', 'type': 'string', 'help': "Password of the OpenERP user. Default = demo", 'action': 'store', 'default': 'demo'} option_ascii = {'names': ('-a', '--ascii'), 'dest': 'ascii', 'help': "Convert name from UTF-8 to ASCII. Default = no, keep UTF-8", 'action': 'store_true', 'default': False} options = [option_server, option_port, option_database, option_user, option_password, option_ascii] def stdout_write(string): '''Wrapper on sys.stdout.write''' sys.stdout.write(string.encode(sys.stdout.encoding, 'replace')) sys.stdout.flush() def stderr_write(string): '''Wrapper on sys.stderr.write''' sys.stderr.write(string.encode(sys.stdout.encoding, 'replace')) sys.stdout.flush() def reformat_phone_number_before_query_openerp(number): '''We match only on the end of the phone number''' if len(number) >= 9: return number[-9:len(number)] # Take 9 last numbers else: return number def convert_to_ascii(my_unicode): '''Convert to ascii, with clever management of accents (é -> e, è -> e)''' import unicodedata if isinstance(my_unicode, unicode): my_unicode_with_ascii_chars_only = ''.join((char for char in unicodedata.normalize('NFD', my_unicode) if unicodedata.category(char) != 'Mn')) return str(my_unicode_with_ascii_chars_only) # If the argument is already of string type, we return it with the same value elif isinstance(my_unicode, str): return my_unicode else: return False def main(options, arguments): #print 'options = %s' % options #print 'arguments = %s' % arguments # AGI passes parameters to the script on standard input stdinput = {} while 1: input_line = sys.stdin.readline().strip() if input_line == '': break variable, value = input_line.split(':') # TODO à protéger ! if variable[:4] != 'agi_': # All AGI parameters start with 'agi_' stderr_write("bad stdin variable : %s\n" % variable) continue variable = variable.strip() value = value.strip() if variable != '': stdinput[variable] = value stderr_write("full AGI environnement :\n") for variable in stdinput.keys(): stderr_write("%s = %s\n" % (variable, stdinput[variable])) input_cid_number = stdinput.get('agi_callerid', False) stderr_write('stdout encoding = %s\n' % sys.stdout.encoding) if not isinstance(input_cid_number, str): exit(0) # Match for particular cases and anonymous phone calls # To test anonymous call in France, dial 3651 + number if not input_cid_number.isdigit(): stdout_write('VERBOSE "CallerID number (%s) is not a digit"\n' % input_cid_number) exit(0) stdout_write('VERBOSE "CallerID number = %s"\n' % input_cid_number) query_number = reformat_phone_number_before_query_openerp(input_cid_number) stderr_write("phone number sent to OpenERP = %s\n" % query_number) stdout_write('VERBOSE "Starting XML-RPC request on OpenERP %s:%s"\n' % (options.server, str(options.port))) sock = xmlrpclib.ServerProxy('http://%s:%s/xmlrpc/object' % (options.server, str(options.port))) res = sock.execute(options.database, options.user, options.password, 'res.partner.address', 'get_name_from_phone_number', query_number) # To simulate a long execution of the XML-RPC request #import time #time.sleep(5) stdout_write('VERBOSE "End of XML-RPC request on OpenERP"\n') # Function to limit the size of the CID name to 40 chars if res: if len(res) > 40: res = res[0:40] else: # if the number is not found in OpenERP, we put 'default_cid_name' as CID Name res = default_cid_name # All SIP phones should support UTF-8... but in case you have analog phones over TDM # or buggy phones, you should use the command line option --ascii if options.ascii: res = convert_to_ascii(res) stdout_write('VERBOSE "CallerID Name = %s"\n' % res) stdout_write('SET CALLERID "%s"<%s>\n' % (res, input_cid_number)) if __name__ == '__main__': #! /usr/bin/python # -*- encoding: utf-8 -*- import xmlrpclib import sys from optparse import OptionParser # CID Name that will be displayed if there is no match in res.partner.address default_cid_name = "Not in OpenERP" # Define command line options option_server = {'names': ('-s', '--server'), 'dest': 'server', 'type': 'string', 'help': 'DNS or IP address of the OpenERP server. Default = localhost', 'action': 'store', 'default':'localhost'} option_port = {'names': ('-p', '--port'), 'dest': 'port', 'type': 'int', 'help': "Port of OpenERP's XML-RPC interface. Default = 8069", 'action': 'store', 'default': 8069} option_database = {'names': ('-d', '--database'), 'dest': 'database', 'type': 'string', 'help': "OpenERP database name. Default = openerp", 'action': 'store', 'default': 'openerp'} option_user = {'names': ('-u', '--user-id'), 'dest': 'user', 'type': 'int', 'help': "OpenERP user ID to use when connecting to OpenERP. Default = 2", 'action': 'store', 'default': 2} option_password = {'names': ('-w', '--password'), 'dest': 'password', 'type': 'string', 'help': "Password of the OpenERP user. Default = demo", 'action': 'store', 'default': 'demo'} option_ascii = {'names': ('-a', '--ascii'), 'dest': 'ascii', 'help': "Convert name from UTF-8 to ASCII. Default = no, keep UTF-8", 'action': 'store_true', 'default': False} options = [option_server, option_port, option_database, option_user, option_password, option_ascii] def stdout_write(string): '''Wrapper on sys.stdout.write''' sys.stdout.write(string.encode(sys.stdout.encoding, 'replace')) sys.stdout.flush() def stderr_write(string): '''Wrapper on sys.stderr.write''' sys.stderr.write(string.encode(sys.stdout.encoding, 'replace')) sys.stdout.flush() def reformat_phone_number_before_query_openerp(number): '''We match only on the end of the phone number''' if len(number) >= 9: return number[-9:len(number)] # Take 9 last numbers else: return number def convert_to_ascii(my_unicode): '''Convert to ascii, with clever management of accents (é -> e, è -> e)''' import unicodedata if isinstance(my_unicode, unicode): my_unicode_with_ascii_chars_only = ''.join((char for char in unicodedata.normalize('NFD', my_unicode) if unicodedata.category(char) != 'Mn')) return str(my_unicode_with_ascii_chars_only) # If the argument is already of string type, we return it with the same value elif isinstance(my_unicode, str): return my_unicode else: return False def main(options, arguments): #print 'options = %s' % options #print 'arguments = %s' % arguments # AGI passes parameters to the script on standard input stdinput = {} while 1: input_line = sys.stdin.readline().strip() if input_line == '': break variable, value = input_line.split(':') # TODO à protéger ! if variable[:4] != 'agi_': # All AGI parameters start with 'agi_' stderr_write("bad stdin variable : %s\n" % variable) continue variable = variable.strip() value = value.strip() if variable != '': stdinput[variable] = value stderr_write("full AGI environnement :\n") for variable in stdinput.keys(): stderr_write("%s = %s\n" % (variable, stdinput[variable])) input_cid_number = stdinput.get('agi_callerid', False) stderr_write('stdout encoding = %s\n' % sys.stdout.encoding) if not isinstance(input_cid_number, str): exit(0) # Match for particular cases and anonymous phone calls # To test anonymous call in France, dial 3651 + number if not input_cid_number.isdigit(): stdout_write('VERBOSE "CallerID number (%s) is not a digit"\n' % input_cid_number) exit(0) stdout_write('VERBOSE "CallerID number = %s"\n' % input_cid_number) query_number = reformat_phone_number_before_query_openerp(input_cid_number) stderr_write("phone number sent to OpenERP = %s\n" % query_number) stdout_write('VERBOSE "Starting XML-RPC request on OpenERP %s:%s"\n' % (options.server, str(options.port))) sock = xmlrpclib.ServerProxy('http://%s:%s/xmlrpc/object' % (options.server, str(options.port))) res = sock.execute(options.database, options.user, options.password, 'res.partner.address', 'get_name_from_phone_number', query_number) # To simulate a long execution of the XML-RPC request #import time #time.sleep(5) stdout_write('VERBOSE "End of XML-RPC request on OpenERP"\n') # Function to limit the size of the CID name to 40 chars if res: if len(res) > 40: res = res[0:40] else: # if the number is not found in OpenERP, we put 'default_cid_name' as CID Name res = default_cid_name # All SIP phones should support UTF-8... but in case you have analog phones over TDM # or buggy phones, you should use the command line option --ascii if options.ascii: res = convert_to_ascii(res) stdout_write('VERBOSE "CallerID Name = %s"\n' % res) stdout_write('SET CALLERID "%s"<%s>\n' % (res, input_cid_number)) if __name__ == '__main__': try: parser = OptionParser() for option in options: param = option['names'] del option['names'] parser.add_option(*param, **option) options, arguments = parser.parse_args() sys.argv[:] = arguments main(options, arguments) except Exception as e: f = open('/tmp/my-custom-log', 'w') f.write('ERROR: %s\n' %str(e)) f.close()