Merge lp:~sil/lolocopter/to-protect-and-serve into lp:lolocopter

Proposed by Stuart Langridge
Status: Merged
Approved by: Jono Bacon
Approved revision: not available
Merged at revision: not available
Proposed branch: lp:~sil/lolocopter/to-protect-and-serve
Merge into: lp:lolocopter
Diff against target: 98 lines (+94/-0)
1 file modified
lolocopter/lolocopter_server.py (+94/-0)
To merge this branch: bzr merge lp:~sil/lolocopter/to-protect-and-serve
Reviewer Review Type Date Requested Status
Jono Bacon Approve
Review via email: mp+14866@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Stuart Langridge (sil) wrote :

Here I have added the server. No integration work done yet.

Revision history for this message
Jono Bacon (jonobacon) wrote :

Looks good to me. Thanks.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'lolocopter/lolocopter_server.py'
2--- lolocopter/lolocopter_server.py 1970-01-01 00:00:00 +0000
3+++ lolocopter/lolocopter_server.py 2009-11-14 17:40:21 +0000
4@@ -0,0 +1,94 @@
5+import gtk, BaseHTTPServer, threading, gobject, json, shutil, avahi, dbus, os
6+
7+class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
8+ counts = 0
9+ def do_GET(self):
10+ if self.path == "/":
11+ self.send_summary()
12+ elif self.path == "/loldata":
13+ self.send_lolfile()
14+ else:
15+ self.send_error()
16+ def send_summary(self):
17+ self.send_response(200)
18+ self.send_header("Content-type", "text/plain")
19+ self.end_headers()
20+ self.wfile.write(json.dumps({
21+ "lol_data": "/loldata",
22+ "network_clock_udp_port": self.network_clock_udp_port
23+ }))
24+ def send_error(self):
25+ self.send_response(404)
26+ self.send_header("Content-type", "text/plain")
27+ self.end_headers()
28+ self.wfile.write("fail.")
29+ def send_lolfile(self):
30+ self.send_response(200)
31+ self.send_header("Content-type", "application/octet-stream")
32+ self.end_headers()
33+ fp = open(self.lol_to_advertise)
34+ shutil.copyfileobj(fp, self.wfile)
35+ fp.close()
36+ # tell lolocopter that someone's downloaded the file
37+ if self.joiner_callback:
38+ # call it in idle so it's on the main thread
39+ gobject.idle_add(self.joiner_callback)
40+
41+class LolocopterServer(object):
42+ def __init__(self, network_clock_udp_port,
43+ lol_to_advertise, public_name, joiner_callback=None):
44+ self.network_clock_udp_port = network_clock_udp_port
45+ self.lol_to_advertise = lol_to_advertise
46+ self.public_name = public_name
47+ self.joiner_callback = joiner_callback
48+
49+ def __advertise_service(self):
50+ bus = dbus.SystemBus()
51+ server = dbus.Interface(bus.get_object(avahi.DBUS_NAME,
52+ avahi.DBUS_PATH_SERVER), avahi.DBUS_INTERFACE_SERVER)
53+
54+ g = dbus.Interface(bus.get_object(avahi.DBUS_NAME,
55+ server.EntryGroupNew()), avahi.DBUS_INTERFACE_ENTRY_GROUP)
56+ shortlol = os.path.splitext(
57+ os.path.split(self.lol_to_advertise)[1])[0]
58+ advertise_name = "%s on %s's lolocopter" % (shortlol,
59+ self.public_name)
60+ g.AddService(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC,dbus.UInt32(0),
61+ advertise_name,
62+ "_http._tcp", "", "",
63+ dbus.UInt16(self.httpd_port), "")
64+ g.Commit()
65+ self.group = g
66+
67+ print "serving on ", self.httpd_port
68+
69+ def __starthttp(self, network_clock_udp_port,
70+ lol_to_advertise, public_name, joiner_callback=None):
71+ MyHandler.protocol_version = "HTTP/1.0"
72+ MyHandler.network_clock_udp_port = network_clock_udp_port
73+ MyHandler.joiner_callback = joiner_callback
74+ MyHandler.lol_to_advertise = lol_to_advertise
75+ httpd = BaseHTTPServer.HTTPServer(('', 0), MyHandler)
76+ sa = httpd.socket.getsockname()
77+ self.httpd_port = sa[1]
78+ self.__advertise_service()
79+ httpd.serve_forever()
80+
81+ # start http server in a thread
82+ def start_server(self):
83+ self.thr = threading.Thread(target=self.__starthttp, args=(
84+ self.network_clock_udp_port,
85+ self.lol_to_advertise,
86+ self.public_name,
87+ self.joiner_callback))
88+ self.thr.daemon = True
89+ self.thr.start()
90+
91+ def stop_server(self):
92+ # unpublish
93+ self.group.Reset()
94+ # kill thread
95+ # erm, not sure how to stop a serve_forever
96+ # so do nothing here. epic fail.
97+ # should kill the thread.
98+

Subscribers

People subscribed via source and target branches

to all changes: