SHOW:
|
|
- or go back to the newest paste.
| 1 | #! /usr/bin/python | |
| 2 | # -*- encoding: utf-8 -*- | |
| 3 | ||
| 4 | import xmlrpclib | |
| 5 | import sys | |
| 6 | from optparse import OptionParser | |
| 7 | ||
| 8 | ||
| 9 | # CID Name that will be displayed if there is no match in res.partner.address | |
| 10 | default_cid_name = "Not in OpenERP" | |
| 11 | ||
| 12 | # Define command line options | |
| 13 | option_server = {'names': ('-s', '--server'), 'dest': 'server', 'type': 'string', 'help': 'DNS or IP address of the OpenERP server. Default = localhost', 'action': 'store', 'default':'localhost'}
| |
| 14 | option_port = {'names': ('-p', '--port'), 'dest': 'port', 'type': 'int', 'help': "Port of OpenERP's XML-RPC interface. Default = 8069", 'action': 'store', 'default': 8069}
| |
| 15 | option_database = {'names': ('-d', '--database'), 'dest': 'database', 'type': 'string', 'help': "OpenERP database name. Default = openerp", 'action': 'store', 'default': 'openerp'}
| |
| 16 | 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}
| |
| 17 | option_password = {'names': ('-w', '--password'), 'dest': 'password', 'type': 'string', 'help': "Password of the OpenERP user. Default = demo", 'action': 'store', 'default': 'demo'}
| |
| 18 | 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}
| |
| 19 | ||
| 20 | options = [option_server, option_port, option_database, option_user, option_password, option_ascii] | |
| 21 | ||
| 22 | def stdout_write(string): | |
| 23 | '''Wrapper on sys.stdout.write''' | |
| 24 | sys.stdout.write(string.encode(sys.stdout.encoding, 'replace')) | |
| 25 | sys.stdout.flush() | |
| 26 | ||
| 27 | def stderr_write(string): | |
| 28 | '''Wrapper on sys.stderr.write''' | |
| 29 | sys.stderr.write(string.encode(sys.stdout.encoding, 'replace')) | |
| 30 | sys.stdout.flush() | |
| 31 | ||
| 32 | ||
| 33 | def reformat_phone_number_before_query_openerp(number): | |
| 34 | '''We match only on the end of the phone number''' | |
| 35 | if len(number) >= 9: | |
| 36 | return number[-9:len(number)] # Take 9 last numbers | |
| 37 | else: | |
| 38 | return number | |
| 39 | ||
| 40 | def convert_to_ascii(my_unicode): | |
| 41 | '''Convert to ascii, with clever management of accents (é -> e, è -> e)''' | |
| 42 | import unicodedata | |
| 43 | if isinstance(my_unicode, unicode): | |
| 44 | my_unicode_with_ascii_chars_only = ''.join((char for char in unicodedata.normalize('NFD', my_unicode) if unicodedata.category(char) != 'Mn'))
| |
| 45 | return str(my_unicode_with_ascii_chars_only) | |
| 46 | # If the argument is already of string type, we return it with the same value | |
| 47 | elif isinstance(my_unicode, str): | |
| 48 | return my_unicode | |
| 49 | else: | |
| 50 | return False | |
| 51 | ||
| 52 | def main(options, arguments): | |
| 53 | #print 'options = %s' % options | |
| 54 | #print 'arguments = %s' % arguments | |
| 55 | ||
| 56 | # AGI passes parameters to the script on standard input | |
| 57 | stdinput = {}
| |
| 58 | while 1: | |
| 59 | input_line = sys.stdin.readline().strip() | |
| 60 | if input_line == '': | |
| 61 | break | |
| 62 | variable, value = input_line.split(':') # TODO à protéger !
| |
| 63 | if variable[:4] != 'agi_': # All AGI parameters start with 'agi_' | |
| 64 | stderr_write("bad stdin variable : %s\n" % variable)
| |
| 65 | continue | |
| 66 | variable = variable.strip() | |
| 67 | value = value.strip() | |
| 68 | if variable != '': | |
| 69 | stdinput[variable] = value | |
| 70 | stderr_write("full AGI environnement :\n")
| |
| 71 | for variable in stdinput.keys(): | |
| 72 | stderr_write("%s = %s\n" % (variable, stdinput[variable]))
| |
| 73 | ||
| 74 | input_cid_number = stdinput.get('agi_callerid', False)
| |
| 75 | stderr_write('stdout encoding = %s\n' % sys.stdout.encoding)
| |
| 76 | ||
| 77 | if not isinstance(input_cid_number, str): | |
| 78 | exit(0) | |
| 79 | # Match for particular cases and anonymous phone calls | |
| 80 | # To test anonymous call in France, dial 3651 + number | |
| 81 | if not input_cid_number.isdigit(): | |
| 82 | stdout_write('VERBOSE "CallerID number (%s) is not a digit"\n' % input_cid_number)
| |
| 83 | exit(0) | |
| 84 | ||
| 85 | stdout_write('VERBOSE "CallerID number = %s"\n' % input_cid_number)
| |
| 86 | query_number = reformat_phone_number_before_query_openerp(input_cid_number) | |
| 87 | stderr_write("phone number sent to OpenERP = %s\n" % query_number)
| |
| 88 | ||
| 89 | stdout_write('VERBOSE "Starting XML-RPC request on OpenERP %s:%s"\n' % (options.server, str(options.port)))
| |
| 90 | ||
| 91 | sock = xmlrpclib.ServerProxy('http://%s:%s/xmlrpc/object' % (options.server, str(options.port)))
| |
| 92 | ||
| 93 | res = sock.execute(options.database, options.user, options.password, 'res.partner.address', 'get_name_from_phone_number', query_number) | |
| 94 | # To simulate a long execution of the XML-RPC request | |
| 95 | #import time | |
| 96 | #time.sleep(5) | |
| 97 | ||
| 98 | stdout_write('VERBOSE "End of XML-RPC request on OpenERP"\n')
| |
| 99 | ||
| 100 | # Function to limit the size of the CID name to 40 chars | |
| 101 | if res: | |
| 102 | if len(res) > 40: | |
| 103 | res = res[0:40] | |
| 104 | else: | |
| 105 | # if the number is not found in OpenERP, we put 'default_cid_name' as CID Name | |
| 106 | res = default_cid_name | |
| 107 | ||
| 108 | # All SIP phones should support UTF-8... but in case you have analog phones over TDM | |
| 109 | # or buggy phones, you should use the command line option --ascii | |
| 110 | if options.ascii: | |
| 111 | res = convert_to_ascii(res) | |
| 112 | ||
| 113 | stdout_write('VERBOSE "CallerID Name = %s"\n' % res)
| |
| 114 | stdout_write('SET CALLERID "%s"<%s>\n' % (res, input_cid_number))
| |
| 115 | ||
| 116 | if __name__ == '__main__': | |
| 117 | - | parser = OptionParser() |
| 117 | + | |
| 118 | - | for option in options: |
| 118 | + | |
| 119 | - | param = option['names'] |
| 119 | + | |
| 120 | - | del option['names'] |
| 120 | + | |
| 121 | - | parser.add_option(*param, **option) |
| 121 | + | |
| 122 | - | options, arguments = parser.parse_args() |
| 122 | + | |
| 123 | - | sys.argv[:] = arguments |
| 123 | + | |
| 124 | - | main(options, arguments) |
| 124 | + | |
| 125 | # CID Name that will be displayed if there is no match in res.partner.address | |
| 126 | default_cid_name = "Not in OpenERP" | |
| 127 | ||
| 128 | # Define command line options | |
| 129 | option_server = {'names': ('-s', '--server'), 'dest': 'server', 'type': 'string', 'help': 'DNS or IP address of the OpenERP server. Default = localhost', 'action': 'store', 'default':'localhost'}
| |
| 130 | option_port = {'names': ('-p', '--port'), 'dest': 'port', 'type': 'int', 'help': "Port of OpenERP's XML-RPC interface. Default = 8069", 'action': 'store', 'default': 8069}
| |
| 131 | option_database = {'names': ('-d', '--database'), 'dest': 'database', 'type': 'string', 'help': "OpenERP database name. Default = openerp", 'action': 'store', 'default': 'openerp'}
| |
| 132 | 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}
| |
| 133 | option_password = {'names': ('-w', '--password'), 'dest': 'password', 'type': 'string', 'help': "Password of the OpenERP user. Default = demo", 'action': 'store', 'default': 'demo'}
| |
| 134 | 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}
| |
| 135 | ||
| 136 | options = [option_server, option_port, option_database, option_user, option_password, option_ascii] | |
| 137 | ||
| 138 | def stdout_write(string): | |
| 139 | '''Wrapper on sys.stdout.write''' | |
| 140 | sys.stdout.write(string.encode(sys.stdout.encoding, 'replace')) | |
| 141 | sys.stdout.flush() | |
| 142 | ||
| 143 | def stderr_write(string): | |
| 144 | '''Wrapper on sys.stderr.write''' | |
| 145 | sys.stderr.write(string.encode(sys.stdout.encoding, 'replace')) | |
| 146 | sys.stdout.flush() | |
| 147 | ||
| 148 | ||
| 149 | def reformat_phone_number_before_query_openerp(number): | |
| 150 | '''We match only on the end of the phone number''' | |
| 151 | if len(number) >= 9: | |
| 152 | return number[-9:len(number)] # Take 9 last numbers | |
| 153 | else: | |
| 154 | return number | |
| 155 | ||
| 156 | def convert_to_ascii(my_unicode): | |
| 157 | '''Convert to ascii, with clever management of accents (é -> e, è -> e)''' | |
| 158 | import unicodedata | |
| 159 | if isinstance(my_unicode, unicode): | |
| 160 | my_unicode_with_ascii_chars_only = ''.join((char for char in unicodedata.normalize('NFD', my_unicode) if unicodedata.category(char) != 'Mn'))
| |
| 161 | return str(my_unicode_with_ascii_chars_only) | |
| 162 | # If the argument is already of string type, we return it with the same value | |
| 163 | elif isinstance(my_unicode, str): | |
| 164 | return my_unicode | |
| 165 | else: | |
| 166 | return False | |
| 167 | ||
| 168 | def main(options, arguments): | |
| 169 | #print 'options = %s' % options | |
| 170 | #print 'arguments = %s' % arguments | |
| 171 | ||
| 172 | # AGI passes parameters to the script on standard input | |
| 173 | stdinput = {}
| |
| 174 | while 1: | |
| 175 | input_line = sys.stdin.readline().strip() | |
| 176 | if input_line == '': | |
| 177 | break | |
| 178 | variable, value = input_line.split(':') # TODO à protéger !
| |
| 179 | if variable[:4] != 'agi_': # All AGI parameters start with 'agi_' | |
| 180 | stderr_write("bad stdin variable : %s\n" % variable)
| |
| 181 | continue | |
| 182 | variable = variable.strip() | |
| 183 | value = value.strip() | |
| 184 | if variable != '': | |
| 185 | stdinput[variable] = value | |
| 186 | stderr_write("full AGI environnement :\n")
| |
| 187 | for variable in stdinput.keys(): | |
| 188 | stderr_write("%s = %s\n" % (variable, stdinput[variable]))
| |
| 189 | ||
| 190 | input_cid_number = stdinput.get('agi_callerid', False)
| |
| 191 | stderr_write('stdout encoding = %s\n' % sys.stdout.encoding)
| |
| 192 | ||
| 193 | if not isinstance(input_cid_number, str): | |
| 194 | exit(0) | |
| 195 | # Match for particular cases and anonymous phone calls | |
| 196 | # To test anonymous call in France, dial 3651 + number | |
| 197 | if not input_cid_number.isdigit(): | |
| 198 | stdout_write('VERBOSE "CallerID number (%s) is not a digit"\n' % input_cid_number)
| |
| 199 | exit(0) | |
| 200 | ||
| 201 | stdout_write('VERBOSE "CallerID number = %s"\n' % input_cid_number)
| |
| 202 | query_number = reformat_phone_number_before_query_openerp(input_cid_number) | |
| 203 | stderr_write("phone number sent to OpenERP = %s\n" % query_number)
| |
| 204 | ||
| 205 | stdout_write('VERBOSE "Starting XML-RPC request on OpenERP %s:%s"\n' % (options.server, str(options.port)))
| |
| 206 | ||
| 207 | sock = xmlrpclib.ServerProxy('http://%s:%s/xmlrpc/object' % (options.server, str(options.port)))
| |
| 208 | ||
| 209 | res = sock.execute(options.database, options.user, options.password, 'res.partner.address', 'get_name_from_phone_number', query_number) | |
| 210 | # To simulate a long execution of the XML-RPC request | |
| 211 | #import time | |
| 212 | #time.sleep(5) | |
| 213 | ||
| 214 | stdout_write('VERBOSE "End of XML-RPC request on OpenERP"\n')
| |
| 215 | ||
| 216 | # Function to limit the size of the CID name to 40 chars | |
| 217 | if res: | |
| 218 | if len(res) > 40: | |
| 219 | res = res[0:40] | |
| 220 | else: | |
| 221 | # if the number is not found in OpenERP, we put 'default_cid_name' as CID Name | |
| 222 | res = default_cid_name | |
| 223 | ||
| 224 | # All SIP phones should support UTF-8... but in case you have analog phones over TDM | |
| 225 | # or buggy phones, you should use the command line option --ascii | |
| 226 | if options.ascii: | |
| 227 | res = convert_to_ascii(res) | |
| 228 | ||
| 229 | stdout_write('VERBOSE "CallerID Name = %s"\n' % res)
| |
| 230 | stdout_write('SET CALLERID "%s"<%s>\n' % (res, input_cid_number))
| |
| 231 | ||
| 232 | if __name__ == '__main__': | |
| 233 | try: | |
| 234 | parser = OptionParser() | |
| 235 | for option in options: | |
| 236 | param = option['names'] | |
| 237 | del option['names'] | |
| 238 | parser.add_option(*param, **option) | |
| 239 | options, arguments = parser.parse_args() | |
| 240 | sys.argv[:] = arguments | |
| 241 | main(options, arguments) | |
| 242 | except Exception as e: | |
| 243 | f = open('/tmp/my-custom-log', 'w')
| |
| 244 | f.write('ERROR: %s\n' %str(e))
| |
| 245 | f.close() |