Developer Area

root/apps/python/trunk/pytel.py @ 543

Revision 543, 10.5 kB (checked in by nadya, 4 years ago)

PyTel? - Python scripts for .tel

Line 
1#!/usr/bin/env python
2
3# PyTel command line utility for access .tel data
4
5# Copyright (c) 2009, Andrew McDonald
6# All rights reserved.
7#
8# Redistribution and use in source and binary forms, with or without
9# modification, are permitted provided that the following conditions
10# are met:
11#
12#    * Redistributions of source code must retain the above copyright
13#      notice, this list of conditions and the following disclaimer.
14#
15#    * Redistributions in binary form must reproduce the above
16#      copyright notice, this list of conditions and the following
17#      disclaimer in the documentation and/or other materials provided
18#      with the distribution.
19#
20#    * The name of the author may not be used to endorse or promote
21#      products derived from this software without specific prior
22#      written permission.
23#
24# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35# POSSIBILITY OF SUCH DAMAGE.
36
37import sys
38import os
39import getopt
40import csv
41import getpass
42import urllib2
43import base64
44import M2Crypto
45import telsoap
46import telquery
47
48rcdir = os.path.expanduser("~/.pytel")
49
50def printusage(argv):
51    print "Usage: %s [init|refresh|query|emailquery|snomurl] [options]" % \
52        os.path.basename(argv[0])
53
54def printusageinit(argv):
55    print "Usage: %s init [options]" % \
56        os.path.basename(argv[0])
57    print "Options:"
58    print "-u, --user=username"
59    print "-p, --pass=password"
60    print "-c, --challresp=challenge_response"
61
62def printusagerefresh(argv):
63    print "Usage: %s refresh" % \
64        os.path.basename(argv[0])
65    print "No options"
66
67def printusagequery(argv):
68    print "Usage: %s query domain [service]" % \
69        os.path.basename(argv[0])
70    print "domain is a .tel domain"
71
72def printusageemailquery(argv):
73    print "Usage: %s emailquery domain" % \
74        os.path.basename(argv[0])
75    print "domain is a .tel domain"
76
77def printusagesnomurl(argv):
78    print "Usage: %s snomurl [options] server" % \
79        os.path.basename(argv[0])
80    print "server is the web server hosting the telsnom.py cgi script"
81    print "Options:"
82    print "-u, --user=phone_admin_username"
83    print "-p, --pass=phone_admin_password"
84    print "-t, --phone=phone_hostname"
85    print "-f, --funckey=function_key"
86    print "-n, --nopriv"
87
88def doinit(username, password, challresp):
89    # initialise config
90
91    if username == None:
92        sys.stdout.write("Username: ")
93        username = sys.stdin.readline().rstrip()
94
95    if password == None:
96        #sys.stdout.write("Password: ")
97        #password = sys.stdin.readline().rstrip()
98        password = getpass.getpass("Password: ")
99
100    if challresp == None:
101        chall = telsoap.getChallenge(username, password)
102        if chall == None:
103            print "Incorrect username or password"
104            return None
105        print "Challenge: %s" % chall
106        #sys.stdout.write("Response: ")
107        #challresp = sys.stdin.readline().rstrip()
108        challresp = getpass.getpass("Response: ")
109
110   
111    cred = telsoap.getAPICredentials(username, password, challresp)
112    if cred == None:
113        print "Incorrect challenge response"
114        return None
115
116    (soid, api_pass, priv_key) = cred
117
118    if not os.path.isdir(rcdir):
119        os.mkdir(rcdir)
120        os.chmod(rcdir, 0700)
121
122    f = open(rcdir+'/soapuser', 'w+')
123    f.write(soid+'\n')
124    f.write(api_pass+'\n')
125    f.close()
126
127    priv_key.save_pem(rcdir+'/telkey.pem', None)
128
129    return (soid, api_pass, priv_key)
130
131def loadconf():
132    try:
133        f = open(rcdir+'/soapuser', 'r')
134        soid = f.readline().rstrip()
135        api_pass = f.readline().rstrip()
136        f.close()
137    except:
138        soid = None
139        api_pass = None
140
141    try:
142        priv_key = M2Crypto.RSA.load_key(rcdir+'/telkey.pem',
143                                         M2Crypto.util.no_passphrase_callback)
144    except:
145        priv_key = None
146
147    return (soid, api_pass, priv_key)
148
149def loadfriends():
150    friends = {}
151    try:
152        f = open(rcdir+'/friendlist.csv', 'r')
153        csv_reader = csv.reader(f)
154        for r in csv_reader:
155            friends[r[0]] = r[1]
156        f.close()
157    except:
158        friends = {}
159    return friends
160
161def dorefresh(soid, api_pass, priv_key):
162    pubs = telsoap.listPublishers(soid, api_pass)
163    if pubs == None:
164        print "Authentication data may be bad, try reinitializing"
165        return None
166    if len(pubs) == 1:
167        pl = "y"
168    else:
169        pl = "ies"
170    print "Refreshing list with %d entr%s" % (len(pubs), pl)
171    f = open(rcdir+'/friendlist.csv', 'w+')
172    for (p,l) in pubs:
173        f.write("%s,%s\n" % (p,l))
174    f.close()
175
176def main(argv):
177    if len(argv) < 2 or not argv[1] in ["init","refresh","query",
178                                        "emailquery","snomurl"]:
179        printusage(argv)
180        sys.exit(1)
181
182    if argv[1] == "init":
183        username = None
184        password = None
185        challresp = None
186        try:
187            (opts,args) = getopt.getopt(argv[2:], "u:p:c:",
188                                        ["user=","pass=","challresp="])
189        except getopt.GetoptError:
190            printusageinit(argv)
191            sys.exit(1)
192
193        if len(args) > 0:
194            printusage(argv)
195            sys.exit(1)
196
197        for (o,v) in opts:
198            if o == "-u" or o == "--user":
199                username = v
200            elif o == "-p" or o == "--pass":
201                password = v
202            elif o == "-c" or o == "--challresp":
203                challresp = v
204        cred = doinit(username, password, challresp)
205        if cred == None:
206            sys.exit(2)
207        (soid, api_pass, priv_key) = cred
208        dorefresh(soid, api_pass, priv_key)
209
210    elif argv[1] == "refresh":
211        if len(argv) > 2:
212            printusagerefresh(argv)
213            sys.exit(1)
214        (soid, api_pass, priv_key) = loadconf()
215        if soid == None or api_pass == None or priv_key == None:
216            print "Unable to load credentials, try reinitializing"
217            sys.exit(2)
218       
219        dorefresh(soid, api_pass, priv_key)
220
221    elif argv[1] == "query":
222        if not (len(argv) >= 3 and len(argv) <= 4) \
223                or argv[2][-4:] != ".tel":
224            printusagequery(argv)
225            sys.exit(1)
226        if len(argv) == 4:
227            service = argv[3]
228        else:
229            service = None
230        (soid, api_pass, priv_key) = loadconf()
231        if priv_key == None:
232            # credentials not available
233            friends = {}
234        else:
235            friends = loadfriends()
236        telquery.printlist(argv[2], service, priv_key, friends)
237
238    elif argv[1] == "emailquery":
239        if not len(argv) == 3 or argv[2][-4:] != ".tel":
240            printusageemailquery(argv)
241            sys.exit(1)
242        (soid, api_pass, priv_key) = loadconf()
243        if priv_key == None:
244            # credentials not available
245            friends = {}
246        else:
247            friends = loadfriends()
248        telquery.printemaillist(argv[2], priv_key, friends)
249
250    elif argv[1] == "snomurl":
251        username = None
252        password = None
253        phone = None
254        funckey = None
255        nopriv=False
256        try:
257            (opts,args) = getopt.getopt(argv[2:], "u:p:t:f:n",
258                                        ["user=","pass=",
259                                         "phone=","funckey=",
260                                         "nopriv"])
261        except getopt.GetoptError:
262            printusagesnomurl(argv)
263            sys.exit(1)
264
265        if len(args) != 1:
266            printusagesnomurl(argv)
267            sys.exit(1)
268
269        for (o,v) in opts:
270            if o == "-u" or o == "--user":
271                username = v
272            elif o == "-p" or o == "--pass":
273                password = v
274            elif o == "-t" or o == "--phone":
275                phone = v
276            elif o == "-f" or o == "--funckey":
277                funckey = v
278            elif o == "-n" or o == "--nopriv":
279                nopriv = True
280
281        if phone:
282            bad = False
283            if not (username and phone and funckey):
284                bad = True
285            else:
286                try:
287                    fval = int(funckey)
288                    if fval < 1 or fval > 12:
289                        bad = True
290                except ValueError:
291                    bad = True
292
293            if bad:
294                printusagesnomurl(argv)
295                sys.exit(1)
296
297            funckey = str(fval-1)
298
299        if nopriv:
300            (soid, api_pass, priv_key) = (None, None, None)
301        else:
302            (soid, api_pass, priv_key) = loadconf()
303
304        if priv_key == None:
305            # credentials not available
306            qstr = ""
307        else:
308            friends = loadfriends()
309            pemkey = priv_key.as_pem(None)
310            friendstr = ""
311            for d in friends:
312                if len(friendstr) > 0:
313                    friendstr += ";"
314                friendstr += "%s,%s" % (d,friends[d])
315
316            qstr = "?telkey=%s&friends=%s" % (urllib2.quote(pemkey),
317                                              urllib2.quote(friendstr))
318
319        cgiurl="http://%s/cgi-bin/telsnom.py%s" % (args[0], qstr)
320
321        print cgiurl
322
323        if phone:
324            authdata = base64.encodestring('%s:%s' % (username, password))[:-1]
325            authheader =  "Basic %s" % authdata
326
327            funcseturl = "http://%s/dummy.htm?settings=save&fkey%s=%s" % \
328                (phone, funckey, urllib2.quote("url "+cgiurl))
329            req = urllib2.Request(funcseturl)
330            req.add_header("User-Agent", "PyTel/1.0")
331            req.add_header("Authorization", authheader)
332
333            try:
334                response = urllib2.urlopen(req)
335            except urllib2.HTTPError, e:
336                if e.code == 401:
337                    print "Incorrect phone username or password"
338                    return
339                else:
340                    raise e
341            print "Settings pushed to phone"
342        else:
343            print "Settings must be manually set on phone"
344
345    return
346
347if __name__ == "__main__":
348    main(sys.argv)
Note: See TracBrowser for help on using the browser.
Telnic
Search This Site
Partners
Neustar
ICANN
Main site | WHOIS | Sell .tel | FAQ | Archived Site | About Telnic | Contact Us