Changes in / [ae8cc50:988d75c]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
skype/skyped.py
rae8cc50 r988d75c 26 26 import locale 27 27 import time 28 import gobject 28 29 import socket 29 30 import getopt … … 33 34 from traceback import print_exception 34 35 import ssl 35 import select36 import threading37 36 38 37 __version__ = "0.1.1" … … 43 42 if type != KeyboardInterrupt: 44 43 print_exception(type, value, tb) 45 if options.conn: options.conn.close() 44 gobject.MainLoop().quit() 45 options.conn.close() 46 46 # shut down client if it's running 47 47 try: … … 53 53 sys.excepthook = eh 54 54 55 def wait_for_lock(lock, timeout_to_print, timeout, msg): 56 start = time.time() 57 locked = lock.acquire(0) 58 while not(locked): 59 time.sleep(0.5) 60 if timeout_to_print and (time.time() - timeout_to_print > start): 61 dprint("%s: Waited %f seconds" % \ 62 (msg, time.time() - start)) 63 timeout_to_print = False 64 if timeout and (time.time() - timeout > start): 65 dprint("%s: Waited %f seconds, giving up" % \ 66 (msg, time.time() - start)) 67 return False 68 locked = lock.acquire(0) 69 return True 70 71 def input_handler(fd): 72 global options 73 global skype 55 def input_handler(fd, io_condition): 56 global options 74 57 if options.buf: 75 58 for i in options.buf: 76 59 skype.send(i.strip()) 77 60 options.buf = None 61 else: 62 try: 63 input = fd.recv(1024) 64 except Exception, s: 65 dprint("Warning, receiving 1024 bytes failed (%s)." % s) 66 fd.close() 67 return False 68 for i in input.split("\n"): 69 skype.send(i.strip()) 78 70 return True 79 else:80 close_socket = False81 if wait_for_lock(options.lock, 3, 10, "input_handler"):82 try:83 input = fd.recv(1024)84 options.lock.release()85 except Exception, s:86 dprint("Warning, receiving 1024 bytes failed (%s)." % s)87 fd.close()88 options.conn = False89 options.lock.release()90 return False91 for i in input.split("\n"):92 if i.strip() == "SET USERSTATUS OFFLINE":93 close_socket = True94 skype.send(i.strip())95 return not(close_socket)96 71 97 72 def skype_idle_handler(skype): … … 99 74 c = skype.skype.Command("PING", Block=True) 100 75 skype.skype.SendCommand(c) 101 dprint("... skype pinged")102 76 except Skype4Py.SkypeAPIError, s: 103 77 dprint("Warning, pinging Skype failed (%s)." % (s)) … … 105 79 106 80 def send(sock, txt): 107 global options81 from time import sleep 108 82 count = 1 109 83 done = False 110 while (not done) and (count < 10) and options.conn: 111 if wait_for_lock(options.lock, 3, 10, "socket send"): 112 try: 113 if options.conn: sock.send(txt) 114 options.lock.release() 115 done = True 116 except Exception, s: 117 options.lock.release() 118 count += 1 119 dprint("Warning, sending '%s' failed (%s). count=%d" % (txt, s, count)) 120 time.sleep(1) 84 while (not done) and (count < 10): 85 try: 86 sock.send(txt) 87 done = True 88 except Exception, s: 89 count += 1 90 dprint("Warning, sending '%s' failed (%s). count=%d" % (txt, s, count)) 91 sleep(1) 121 92 if not done: 122 if options.conn: options.conn.close() 123 options.conn = False 124 return done 93 options.conn.close() 125 94 126 95 def bitlbee_idle_handler(skype): 127 global options128 done = False129 96 if options.conn: 130 97 try: 131 98 e = "PING" 132 done = send(options.conn, "%s\n" % e) 133 dprint("... pinged Bitlbee") 99 send(options.conn, "%s\n" % e) 134 100 except Exception, s: 135 101 dprint("Warning, sending '%s' failed (%s)." % (e, s)) 136 if options.conn: options.conn.close() 137 options.conn = False 138 done = False 139 return done 140 141 def server(host, port, skype): 102 options.conn.close() 103 return True 104 105 def server(host, port): 142 106 global options 143 107 sock = socket.socket() … … 145 109 sock.bind((host, port)) 146 110 sock.listen(1) 147 dprint("Waiting for connection...") 148 listener(sock, skype) 149 150 def listener(sock, skype): 151 global options 152 if not(wait_for_lock(options.lock, 3, 10, "listener")): return False 111 gobject.io_add_watch(sock, gobject.IO_IN, listener) 112 113 def listener(sock, *args): 114 global options 153 115 rawsock, addr = sock.accept() 154 116 options.conn = ssl.wrap_socket(rawsock, … … 161 123 options.conn.handshake() 162 124 except Exception: 163 options.lock.release()164 125 dprint("Warning, handshake failed, closing connection.") 165 126 return False … … 175 136 dprint("Warning, receiving 1024 bytes failed (%s)." % s) 176 137 options.conn.close() 177 options.conn = False178 options.lock.release()179 138 return False 180 139 if ret == 2: 181 140 dprint("Username and password OK.") 182 141 options.conn.send("PASSWORD OK\n") 183 options.lock.release() 184 serverloop(options, skype) 142 gobject.io_add_watch(options.conn, gobject.IO_IN, input_handler) 185 143 return True 186 144 else: 187 145 dprint("Username and/or password WRONG.") 188 146 options.conn.send("PASSWORD KO\n") 189 options.conn.close()190 options.conn = False191 options.lock.release()192 147 return False 193 148 … … 233 188 # everybody will be happy 234 189 e = i.encode('UTF-8') 190 dprint('<< ' + e) 235 191 if options.conn: 236 dprint('<< ' + e)237 192 try: 238 # I called the send function really_send239 193 send(options.conn, e + "\n") 240 194 except Exception, s: 241 195 dprint("Warning, sending '%s' failed (%s)." % (e, s)) 242 if options.conn: options.conn.close() 243 options.conn = False 244 else: 245 dprint('---' + e) 196 options.conn.close() 246 197 247 198 def send(self, msg_text): 248 199 if not len(msg_text) or msg_text == "PONG": 249 if msg_text == "PONG": options.last_bitlbee_pong = time.time()250 200 return 251 201 try: … … 302 252 -v --version display version information""" % (self.cfgpath, self.host, self.port) 303 253 sys.exit(ret) 304 305 def serverloop(options, skype):306 timeout = 1; # in seconds307 skype_ping_period = 5308 bitlbee_ping_period = 10309 bitlbee_pong_timeout = 30310 now = time.time()311 skype_ping_start_time = now312 bitlbee_ping_start_time = now313 options.last_bitlbee_pong = now314 in_error = []315 handler_ok = True316 while (len(in_error) == 0) and handler_ok and options.conn:317 ready_to_read, ready_to_write, in_error = \318 select.select([options.conn], [], [options.conn], \319 timeout)320 now = time.time()321 handler_ok = len(in_error) == 0322 if (len(ready_to_read) == 1) and handler_ok:323 handler_ok = input_handler(ready_to_read.pop())324 # don't ping bitlbee/skype if they already received data325 now = time.time() # allow for the input_handler to take some time326 bitlbee_ping_start_time = now327 skype_ping_start_time = now328 options.last_bitlbee_pong = now329 if (now - skype_ping_period > skype_ping_start_time) and handler_ok:330 handler_ok = skype_idle_handler(skype)331 skype_ping_start_time = now332 if now - bitlbee_ping_period > bitlbee_ping_start_time:333 handler_ok = bitlbee_idle_handler(skype)334 bitlbee_ping_start_time = now335 if options.last_bitlbee_pong:336 if (now - options.last_bitlbee_pong) > bitlbee_pong_timeout:337 dprint("Bitlbee pong timeout")338 # TODO is following line necessary? Should there be a options.conn.unwrap() somewhere?339 # options.conn.shutdown()340 if options.conn: options.conn.close()341 options.conn = False342 else:343 dprint("%f seconds since last PONG" % (now - options.last_bitlbee_pong))344 else:345 options.last_bitlbee_pong = now346 dprint("Serverloop done")347 254 348 255 if __name__=='__main__': … … 410 317 else: 411 318 dprint('skyped is started on port %s' % options.port) 319 server(options.host, options.port) 412 320 try: 413 321 skype = SkypeApi() 414 322 except Skype4Py.SkypeAPIError, s: 415 323 sys.exit("%s. Are you sure you have started Skype?" % s) 416 while 1: 417 options.conn = False 418 options.lock = threading.Lock() 419 server(options.host, options.port, skype) 324 gobject.timeout_add(2000, skype_idle_handler, skype) 325 gobject.timeout_add(60000, bitlbee_idle_handler, skype) 326 gobject.MainLoop().run()
Note: See TracChangeset
for help on using the changeset viewer.