View difference between Paste ID: X8iq1zJw and dcgjeLCB
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()