init_logging() makes more sense in the config module.
[pyTivo/wgw.git] / beacon.py
blobb69bb7421a4b6cd512d381bf4d4c90f27518db79
1 import re
2 import struct
3 from socket import *
4 from threading import Timer
5 import config
7 class Beacon:
9 UDPSock = socket(AF_INET, SOCK_DGRAM)
10 UDPSock.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
11 services = []
13 def add_service(self, service):
14 self.services.append(service)
15 self.send_beacon()
17 def format_services(self):
18 return ';'.join(self.services)
20 def format_beacon(self, conntype, services=True):
21 beacon = ['tivoconnect=1',
22 'swversion=1',
23 'method=%s' % conntype,
24 'identity=%s' % config.getGUID(),
25 'machine=%s' % gethostname(),
26 'platform=pc']
28 if services:
29 beacon.append('services=' + self.format_services())
30 else:
31 beacon.append('services=TiVoMediaServer:0/http')
33 return '\n'.join(beacon)
35 def send_beacon(self):
36 beacon_ips = config.getBeaconAddresses()
37 for beacon_ip in beacon_ips.split():
38 if beacon_ip != 'listen':
39 try:
40 self.UDPSock.sendto(self.format_beacon('broadcast'),
41 (beacon_ip, 2190))
42 except error, e:
43 print e
45 def start(self):
46 self.send_beacon()
47 self.timer = Timer(60, self.start)
48 self.timer.start()
50 def stop(self):
51 self.timer.cancel()
53 def listen(self):
54 """ For the direct-connect, TCP-style beacon """
55 import thread
57 def server():
58 TCPSock = socket(AF_INET, SOCK_STREAM)
59 TCPSock.bind(('', 2190))
60 TCPSock.listen(5)
62 while True:
63 # Wait for a connection
64 client, address = TCPSock.accept()
66 # Accept the client's beacon
67 client_length = struct.unpack('!I', client.recv(4))[0]
68 client_message = client.recv(client_length)
70 # Send ours
71 message = self.format_beacon('connected')
72 client.send(struct.pack('!I', len(message)))
73 client.send(message)
74 client.close()
76 thread.start_new_thread(server, ())
78 def get_name(self, address):
79 """ Exchange beacons, and extract the machine name. """
80 our_beacon = self.format_beacon('connected', False)
81 machine_name = re.compile('machine=(.*)\n').search
83 try:
84 tsock = socket()
85 tsock.connect((address, 2190))
87 tsock.send(struct.pack('!I', len(our_beacon)))
88 tsock.send(our_beacon)
90 length = struct.unpack('!I', tsock.recv(4))[0]
91 tivo_beacon = tsock.recv(length)
93 tsock.close()
95 name = machine_name(tivo_beacon).groups()[0]
96 except:
97 name = address
99 return name
101 if __name__ == '__main__':
102 b = Beacon()
104 b.add_service('TiVoMediaServer:9032/http')
105 b.send_beacon()