1 | #!/usr/bin/env python
|
---|
2 | """ Simple python server to allow Remote phonebook of ST2030 to work with
|
---|
3 | Asterisk server, using the phone and fullname settings of the config file
|
---|
4 | as input values, like
|
---|
5 | [20012]
|
---|
6 | fullname=Rick van der Zwet
|
---|
7 |
|
---|
8 |
|
---|
9 | In order to get it working alter HOST and PORT to the location of your webserver
|
---|
10 |
|
---|
11 | Next specify remote phone book URL to be http://HOST:PORT/search?q=#SEARCH
|
---|
12 | at Advanced -> Phone Lists -> Remote Phone Book in the webinterface
|
---|
13 |
|
---|
14 | OR
|
---|
15 |
|
---|
16 | In your autoprovising files the entries under the section [sys]
|
---|
17 | Phonebook1_url=http://HOST:PORT/search?q=#SEARCH
|
---|
18 | Phonebook1_name=example.com phone book
|
---|
19 |
|
---|
20 |
|
---|
21 |
|
---|
22 |
|
---|
23 | Original webserver template - Copyright Jon Berg , turtlemeat.com
|
---|
24 | """
|
---|
25 | from __future__ import with_statement
|
---|
26 | import string,cgi,time,os
|
---|
27 | from os import curdir, sep
|
---|
28 | from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
|
---|
29 | import urlparse, urllib
|
---|
30 | import ConfigParser
|
---|
31 |
|
---|
32 | __author__ = "Rick van der Zwet"
|
---|
33 | __copyright = "Copyright 2008, Rick van der Zwet"
|
---|
34 | __licence__ = "BSD"
|
---|
35 | __version__ = "0.0.2"
|
---|
36 | __maitainer__ = "Rick van der Zwet"
|
---|
37 | __email__ = "rick@wzoeterwoude.net"
|
---|
38 | __status__ = "Production"
|
---|
39 | __credits__ = [" Jon Berg , turtlemeat.com"]
|
---|
40 | __website__ = "http://rickvanderzwet.nl/svn/data/develop/pythonplaza/asterisk-remote-phonebook.py"
|
---|
41 |
|
---|
42 | #
|
---|
43 | # Specify your asterisk config file and the IP/host you like the mini-server to
|
---|
44 | # be running on
|
---|
45 | USERFILE='/etc/asterisk/users.conf'
|
---|
46 | LOGFILE='/var/log/phonebook.log'
|
---|
47 | HOST='192.168.50.10'
|
---|
48 | PORT=8000
|
---|
49 |
|
---|
50 | class MyHandler(BaseHTTPRequestHandler):
|
---|
51 | __base = BaseHTTPRequestHandler
|
---|
52 |
|
---|
53 | protocol_version = "HTTP/1.0"
|
---|
54 |
|
---|
55 | def log_message(self, format, *args):
|
---|
56 | """Log an arbitrary message., custom function, log to file, instead of stdout
|
---|
57 | """
|
---|
58 |
|
---|
59 | with open(LOGFILE,"a") as f:
|
---|
60 | f.write("%s - - [%s] %s\n" %
|
---|
61 | (self.address_string(),
|
---|
62 | self.log_date_time_string(),
|
---|
63 | format%args))
|
---|
64 |
|
---|
65 |
|
---|
66 | def do_GET(self):
|
---|
67 | parsed_path = urlparse.urlparse(self.path)
|
---|
68 | rpath = parsed_path.path
|
---|
69 | qdict = cgi.parse_qs(parsed_path.query,True)
|
---|
70 |
|
---|
71 | if rpath == '/search':
|
---|
72 | if qdict.has_key('q'):
|
---|
73 | searchkey = qdict['q'][0].lower()
|
---|
74 | else:
|
---|
75 | qdict['q'] = ' '
|
---|
76 | searchkey = ' '
|
---|
77 |
|
---|
78 | #Parse astrisk file, fetch phone number and Name
|
---|
79 | config = ConfigParser.ConfigParser()
|
---|
80 | try:
|
---|
81 | config.readfp(open(USERFILE))
|
---|
82 | except IOError:
|
---|
83 | self.send_error(404,'Config file not found/readable: %s' % USERFILE)
|
---|
84 | return
|
---|
85 |
|
---|
86 | #Do matching
|
---|
87 | results = []
|
---|
88 | for section in config.sections():
|
---|
89 | try:
|
---|
90 | if config.get(section, 'fullname').lower().find(searchkey) != -1:
|
---|
91 | results.append(([config.get(section, 'fullname')][0], section));
|
---|
92 | except ConfigParser.NoOptionError:
|
---|
93 | pass
|
---|
94 | results.sort()
|
---|
95 |
|
---|
96 | #Get right output part
|
---|
97 | if qdict.has_key('from'):
|
---|
98 | f = int(qdict['from'][0])
|
---|
99 | t = f + 31
|
---|
100 | if t > len(results):
|
---|
101 | t = len(results)
|
---|
102 | results = results[f:t]
|
---|
103 |
|
---|
104 |
|
---|
105 | output = ''
|
---|
106 | if (len(results) < 32):
|
---|
107 | output += '<ThomsonPhoneBook>\n'
|
---|
108 | #result smaller 32 hits
|
---|
109 | for name, phone in results:
|
---|
110 | output += '<DirectoryEntry>\n'
|
---|
111 | output += '\t<Name>%s</Name>\n' % name
|
---|
112 | output += '\t<Telephone>%s</Telephone>\n' % phone
|
---|
113 | output += '</DirectoryEntry>\n'
|
---|
114 | output += '</ThomsonPhoneBook>\n'
|
---|
115 | else:
|
---|
116 | output += '<ThomsonPhoneMenu>\n'
|
---|
117 | p = 0
|
---|
118 | while (p < len(results)):
|
---|
119 | # Damm phone, no & but & only
|
---|
120 | url = 'http://%s:%s/search?q=%s&from=%s' % (HOST, PORT, urllib.quote_plus(qdict['q'][0]), p)
|
---|
121 | #url = 'http://%s:%s/search' % (HOST, PORT)
|
---|
122 | name_start = results[p][0]
|
---|
123 | if (p + 31 < len(results)):
|
---|
124 | name_end = results[p+31][0]
|
---|
125 | else:
|
---|
126 | name_end = results[len(results) - 1][0]
|
---|
127 | output += '<MenuItem>\n'
|
---|
128 | output += '\t<Name>%s -> %s</Name>\n' % (name_start, name_end)
|
---|
129 | output += '\t<URL>%s</URL>\n' % url
|
---|
130 | output += '</MenuItem>\n'
|
---|
131 | p = p + 32
|
---|
132 | output += '</ThomsonPhoneMenu>\n'
|
---|
133 |
|
---|
134 | # Output file
|
---|
135 | # Broken Phone ST2030, requires \r on all headers
|
---|
136 | # Broken Phone ST2030 does not properly support HTTP/1.1 as keep-alive
|
---|
137 | # is not running properly , could _not_ be seperated into properly
|
---|
138 | # self.send_response(200), self.send_header('Connnection: close')
|
---|
139 |
|
---|
140 | # Allow easy XML debugging in Mozilla Firefox 3
|
---|
141 | # * Content-Type is don't care value, might as well text/plain
|
---|
142 | # * Connection: close is don't care value
|
---|
143 |
|
---|
144 | head = 'HTTP/1.0 200 OK\r\n'
|
---|
145 | head += 'Content-Length: %s\r\n' % len(output)
|
---|
146 | head += 'Content-Type: application/xml\r\n'
|
---|
147 | head += 'Connection: close\r\n'
|
---|
148 | head += '\r\n'
|
---|
149 | self.wfile.write(head + output + '\r\n');
|
---|
150 |
|
---|
151 | # Force connection closing
|
---|
152 | self.close_connection = 1
|
---|
153 | # Log succesfull request
|
---|
154 | self.log_request(200,len(output))
|
---|
155 |
|
---|
156 | def main():
|
---|
157 | server = HTTPServer((HOST, PORT), MyHandler)
|
---|
158 | try:
|
---|
159 | pid = os.fork()
|
---|
160 | except OSError, e:
|
---|
161 | raise Exception, "%s [%d]" % (e.strerror, e.errno)
|
---|
162 | if (pid==0):
|
---|
163 | os.setsid()
|
---|
164 | print 'started httpserver on %s:%s... (pid=%s)' % (HOST, PORT, os.getpid())
|
---|
165 | print 'Logfile at: %s' % LOGFILE
|
---|
166 | server.serve_forever()
|
---|
167 | # On any signal close socket
|
---|
168 | # server.socket.close()
|
---|
169 | else:
|
---|
170 | os._exit(0)
|
---|
171 |
|
---|
172 | if __name__ == '__main__':
|
---|
173 | main()
|
---|
174 |
|
---|