parent
43b8b03dbc
commit
89d2147ea9
@ -0,0 +1,151 @@ |
||||
#!/usr/bin/python |
||||
# -*- coding: utf-8 -*- |
||||
# |
||||
# credit: http://sheep.art.pl/Wiki%20Engine%20in%20Python%20from%20Scratch |
||||
|
||||
|
||||
import BaseHTTPServer |
||||
import SimpleHTTPServer |
||||
import itertools |
||||
import logging |
||||
import platform |
||||
import os |
||||
import re |
||||
import subprocess |
||||
import tempfile |
||||
import urllib |
||||
from optparse import OptionParser |
||||
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG) |
||||
|
||||
|
||||
arduino_cmd = None |
||||
def get_arduino_command(): |
||||
"""Attempt to find or guess the path to the Arduino binary.""" |
||||
global arduino_cmd |
||||
if not arduino_cmd: |
||||
if platform.system() == "Darwin": |
||||
arduino_cmd_guesses = ["/Applications/Arduino.app/Contents/MacOS/Arduino"] |
||||
elif platform.system() == "Windows": |
||||
arduino_cmd_guesses = [ |
||||
"c:\Program Files\Arduino\Arduino.exe", |
||||
"c:\Program Files (x86)\Arduino\Arduino.exe" |
||||
] |
||||
else: |
||||
arduino_cmd_guesses = [] |
||||
|
||||
for guess in arduino_cmd_guesses: |
||||
if os.path.exists(guess): |
||||
logging.info("Found Arduino command at %s", guess) |
||||
arduino_cmd = guess |
||||
break |
||||
else: |
||||
logging.info("Couldn't find Arduino command; hoping it's on the path!") |
||||
arduino_cmd = "arduino" |
||||
return arduino_cmd |
||||
|
||||
|
||||
def guess_port_name(): |
||||
"""Attempt to guess a port name that we might find an Arduino on.""" |
||||
portname = None |
||||
if platform.system() == "Windows": |
||||
import _winreg as winreg |
||||
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM") |
||||
# We'll guess it's the last COM port. |
||||
for i in itertools.count(): |
||||
try: |
||||
portname = winreg.EnumValue(key, i)[1] |
||||
except WindowsError: |
||||
break |
||||
else: |
||||
# We'll guess it's the first non-bluetooth tty. or cu. prefixed device |
||||
ttys = [filename for filename in os.listdir("/dev") |
||||
if (filename.startswith("tty.") or filename.startswith("cu.")) |
||||
and not "luetooth" in filename] |
||||
ttys.sort(key=lambda k:(k.startswith("cu."), k)) |
||||
if ttys: |
||||
portname = "/dev/" + ttys[0] |
||||
logging.info("Guessing port name as %s", portname) |
||||
return portname |
||||
|
||||
|
||||
parser = OptionParser() |
||||
parser.add_option("--port", dest="port", help="Upload to serial port named PORT", metavar="PORT") |
||||
parser.add_option("--board", dest="board", help="Board definition to use", metavar="BOARD") |
||||
parser.add_option("--command", dest="cmd", help="Arduino command name", metavar="CMD") |
||||
|
||||
|
||||
class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler): |
||||
def do_HEAD(self): |
||||
"""Send response headers""" |
||||
if self.path != "/": |
||||
return SimpleHTTPServer.SimpleHTTPRequestHandler.do_HEAD(self) |
||||
self.send_response(200) |
||||
self.send_header("content-type", "text/html;charset=utf-8") |
||||
self.send_header('Access-Control-Allow-Origin', '*') |
||||
self.end_headers() |
||||
|
||||
def do_GET(self): |
||||
"""Send page text""" |
||||
if self.path != "/": |
||||
return SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self) |
||||
else: |
||||
self.send_response(302) |
||||
self.send_header("Location", "/blockly/apps/blocklyduino/index.html") |
||||
self.end_headers() |
||||
|
||||
def do_POST(self): |
||||
"""Save new page text and display it""" |
||||
if self.path != "/": |
||||
return SimpleHTTPServer.SimpleHTTPRequestHandler.do_POST(self) |
||||
|
||||
options, args = parser.parse_args() |
||||
|
||||
length = int(self.headers.getheader('content-length')) |
||||
if length: |
||||
text = self.rfile.read(length) |
||||
|
||||
print "sketch to upload: " + text |
||||
|
||||
dirname = tempfile.mkdtemp() |
||||
sketchname = os.path.join(dirname, os.path.basename(dirname)) + ".ino" |
||||
f = open(sketchname, "wb") |
||||
f.write(text + "\n") |
||||
f.close() |
||||
|
||||
print "created sketch at %s" % (sketchname,) |
||||
|
||||
# invoke arduino to build/upload |
||||
compile_args = [ |
||||
options.cmd or get_arduino_command(), |
||||
"--upload", |
||||
"--port", |
||||
options.port or guess_port_name(), |
||||
] |
||||
if options.board: |
||||
compile_args.extend([ |
||||
"--board", |
||||
options.board |
||||
]) |
||||
compile_args.append(sketchname) |
||||
|
||||
print "Uploading with %s" % (" ".join(compile_args)) |
||||
rc = subprocess.call(compile_args) |
||||
|
||||
if not rc == 0: |
||||
print "arduino --upload returned " + `rc` |
||||
self.send_response(400) |
||||
else: |
||||
self.send_response(200) |
||||
self.send_header('Access-Control-Allow-Origin', '*') |
||||
self.end_headers() |
||||
else: |
||||
self.send_response(400) |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
print "Blocklyduino can now be accessed at http://127.0.0.1:8080/" |
||||
server = BaseHTTPServer.HTTPServer(("127.0.0.1", 8080), Handler) |
||||
server.pages = {} |
||||
server.serve_forever() |
@ -1,79 +0,0 @@ |
||||
#!/usr/bin/python |
||||
# -*- coding: utf-8 -*- |
||||
# |
||||
# credit: http://sheep.art.pl/Wiki%20Engine%20in%20Python%20from%20Scratch |
||||
|
||||
import BaseHTTPServer, urllib, re, os |
||||
|
||||
class Handler(BaseHTTPServer.BaseHTTPRequestHandler): |
||||
template = u"""<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" |
||||
"http://www.w3.org/TR/html4/strict.dtd"><html><body><h1>Arduino INO web server</h1>To upload to an Arduino board connected to this computer, POST to /.</body></html>""" |
||||
|
||||
def escape_html(self, text): |
||||
"""Replace special HTML characters with HTML entities""" |
||||
return text.replace( |
||||
"&", "&").replace(">", ">").replace("<", "<") |
||||
|
||||
def do_HEAD(self): |
||||
"""Send response headers""" |
||||
self.send_response(200) |
||||
self.send_header("content-type", "text/html;charset=utf-8") |
||||
self.send_header('Access-Control-Allow-Origin', '*') |
||||
self.end_headers() |
||||
|
||||
def do_GET(self): |
||||
"""Send page text""" |
||||
self.do_HEAD() |
||||
self.wfile.write(self.template) |
||||
|
||||
def do_POST(self): |
||||
"""Save new page text and display it""" |
||||
length = int(self.headers.getheader('content-length')) |
||||
if length: |
||||
text = self.rfile.read(length) |
||||
|
||||
print "sketch to upload: " + text |
||||
|
||||
# create ino project (if it doesn't exist already) |
||||
os.system("mkdir ino_project") |
||||
os.chdir("ino_project") |
||||
rc = os.system("ino init") |
||||
|
||||
# 32512 probably means ino is not installed |
||||
if rc == 32512: |
||||
print "ino init returned " + `rc` |
||||
self.send_response(501) |
||||
else: |
||||
# write to file |
||||
fo = open("src/sketch.ino", "wb") |
||||
fo.write(text + "\n"); |
||||
fo.close() |
||||
|
||||
print "created src/sketch.ino" |
||||
|
||||
# invoke ino to build/upload |
||||
# skip_lib_includes is used to avoid "line too long" errors with IDE 1.5.8+ |
||||
rc = os.system("ino build --skip_lib_includes") |
||||
|
||||
# 512 probably means invalid option (skip_lib_includes) |
||||
if rc == 512: |
||||
print "ino build returned " + `rc` + " - trying again without skip_lib_includes" |
||||
rc = os.system("ino build") |
||||
|
||||
if not rc == 0: |
||||
print "ino build returned " + `rc` |
||||
self.send_response(400) |
||||
else: |
||||
rc = os.system("ino upload") |
||||
if not rc == 0: |
||||
print "ino upload returned " + `rc` |
||||
self.send_response(500) |
||||
else: |
||||
self.send_response(200) |
||||
os.chdir("..") |
||||
|
||||
if __name__ == '__main__': |
||||
print "running local web server at 127.0.0.1:8080..." |
||||
server = BaseHTTPServer.HTTPServer(("127.0.0.1", 8080), Handler) |
||||
server.pages = {} |
||||
server.serve_forever() |
Loading…
Reference in new issue