|
#!/home/achin/devel/envs/smoshs/bin/python |
|
|
|
import BaseHTTPServer |
|
from pprint import pprint |
|
from twilio import twiml |
|
from urlparse import parse_qs |
|
import subprocess |
|
import re |
|
import os |
|
import signal |
|
|
|
class SmoshsHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
|
mosh_map = {} |
|
def do_GET(self): |
|
self.send_response(200) |
|
self.send_header("Content-Type","text/plain") |
|
self.end_headers() |
|
|
|
self.wfile.write("Hello!") |
|
self.wfile.close() |
|
|
|
|
|
def _send_reply(self, msg, data): |
|
r = twiml.Response() |
|
r.sms(msg, to=data['From'][0], sender=data['To'][0]) |
|
s = str(r) |
|
self.send_response(200) |
|
self.send_header("Content-Type","text/xml") |
|
self.send_header("Content-Length",len(s)) |
|
self.end_headers() |
|
self.wfile.write(s) |
|
|
|
|
|
def do_POST(self): |
|
pprint(self.path) |
|
if not self.path.startswith("/smoshs"): |
|
self.send_response(404) |
|
self.send_header("Content-Type","text/plain") |
|
self.end_headers() |
|
self.wfile.write("404") |
|
return |
|
|
|
pprint(self.headers) |
|
length = int(self.headers.get("Content-Length")) |
|
data = parse_qs(self.rfile.read(length)) |
|
fromnumber = data['From'][0] |
|
pprint(data) |
|
body = data['Body'][0].lower().split() |
|
if body[0] != "mosh": |
|
return self._send_reply("bad command", data=data) |
|
|
|
if len(body) < 2: |
|
return self._send_reply("sub commands: start, kill, status", data=data) |
|
|
|
if body[1] == "status": |
|
if fromnumber in self.mosh_map: |
|
pid = self.mosh_map[fromnumber]['pid'] |
|
try: |
|
exe = os.readlink("/proc/%d/exe" % pid) |
|
print "Mosh exe process looks like", exe |
|
except: |
|
exe="" |
|
if not exe.endswith("mosh-server"): |
|
print "Mosh seems to have died, cleaning up" |
|
del self.mosh_map[fromnumber] |
|
return self._send_reply("Your mosh process has died", data=data) |
|
|
|
return self._send_reply("Mosh is still running", data=data) |
|
else: |
|
return self._send_reply("No mosh processes running for you", data=data) |
|
|
|
elif body[1] == "kill": |
|
msg = "" |
|
if fromnumber in self.mosh_map: |
|
pid = self.mosh_map[fromnumber]['pid'] |
|
os.kill(pid, signal.SIGINT) |
|
del self.mosh_map[fromnumber] |
|
return self._send_reply("Mosh-server processed killed", data=data) |
|
else: |
|
return self._send_reply("No mosh processes running for you", data=data) |
|
|
|
elif body[1] == "start": |
|
msg = "" |
|
if fromnumber in self.mosh_map: |
|
pid = self.mosh_map[fromnumber]['pid'] |
|
try: |
|
exe = os.readlink("/proc/%d/exe" % pid) |
|
print "Mosh exe process looks like", exe |
|
except: |
|
exe="" |
|
if not exe.endswith("mosh-server"): |
|
print "Mosh seems to have died, cleaning up" |
|
del self.mosh_map[fromnumber] |
|
msg = "You had a mosh-server process, but it died. I'll start a new one. " |
|
else: |
|
return self._send_reply("You already have a mosh-server running. Send \"mosh kill\" to kill it", data=data) |
|
|
|
|
|
p = subprocess.Popen(["mosh-server", "new"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
|
p.wait() |
|
moshout = p.stdout.read() |
|
# get PID |
|
moshpid = moshport = moshkey = None |
|
for line in moshout.split("\n"): |
|
m = re.search(r"\[mosh-server detached, pid = (\d+)\]", line) |
|
if m: |
|
moshpid = int(m.group(1)) |
|
m = re.search(r"MOSH CONNECT (\d+) (\S+)", line) |
|
if m: |
|
moshport = int(m.group(1)) |
|
moshkey = m.group(2) |
|
print "mosh is running as pid %d on port %d with key %s" % (moshpid, moshport, moshkey) |
|
|
|
self.mosh_map[fromnumber] = dict(pid=moshpid, port=moshport, key=moshkey) |
|
|
|
return self._send_reply(msg + "Mosh started on port %d with key %s" % (moshport, moshkey), data=data) |
|
|
|
|
|
|
|
|
|
def run(server_class=BaseHTTPServer.HTTPServer, |
|
handler_class=BaseHTTPServer.BaseHTTPRequestHandler): |
|
server_address = ('', 8080) |
|
httpd = server_class(server_address, handler_class) |
|
httpd.serve_forever() |
|
|
|
if __name__ == "__main__": |
|
run(handler_class=SmoshsHandler) |