add "wormhole" entrypoint script. requires twisted.
I'm using Twisted for the subcommand argument parsing. It might be nice to use something smaller.
This commit is contained in:
parent
5682ddff8e
commit
7a99c04d64
|
@ -1,73 +0,0 @@
|
||||||
from __future__ import print_function
|
|
||||||
import sys, os, json
|
|
||||||
from nacl.secret import SecretBox
|
|
||||||
from wormhole.blocking.transcribe import Receiver, WrongPasswordError
|
|
||||||
from wormhole.blocking.transit import TransitReceiver
|
|
||||||
|
|
||||||
APPID = "lothar.com/wormhole/file-xfer"
|
|
||||||
|
|
||||||
# we're receiving
|
|
||||||
transit_receiver = TransitReceiver()
|
|
||||||
|
|
||||||
mydata = json.dumps({
|
|
||||||
"transit": {
|
|
||||||
"direct_connection_hints": transit_receiver.get_direct_hints(),
|
|
||||||
"relay_connection_hints": transit_receiver.get_relay_hints(),
|
|
||||||
},
|
|
||||||
}).encode("utf-8")
|
|
||||||
r = Receiver(APPID, mydata)
|
|
||||||
r.set_code(r.input_code("Enter receive-file wormhole code: "))
|
|
||||||
|
|
||||||
try:
|
|
||||||
data = json.loads(r.get_data().decode("utf-8"))
|
|
||||||
except WrongPasswordError as e:
|
|
||||||
print("ERROR: " + e.explain(), file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
#print("their data: %r" % (data,))
|
|
||||||
|
|
||||||
file_data = data["file"]
|
|
||||||
xfer_key = r.derive_key(APPID+"/xfer-key", SecretBox.KEY_SIZE)
|
|
||||||
filename = os.path.basename(file_data["filename"]) # unicode
|
|
||||||
filesize = file_data["filesize"]
|
|
||||||
encrypted_filesize = filesize + SecretBox.NONCE_SIZE+16
|
|
||||||
|
|
||||||
# now receive the rest of the owl
|
|
||||||
tdata = data["transit"]
|
|
||||||
transit_key = r.derive_key(APPID+"/transit-key")
|
|
||||||
transit_receiver.set_transit_key(transit_key)
|
|
||||||
transit_receiver.add_their_direct_hints(tdata["direct_connection_hints"])
|
|
||||||
transit_receiver.add_their_relay_hints(tdata["relay_connection_hints"])
|
|
||||||
skt = transit_receiver.establish_connection()
|
|
||||||
print("Receiving %d bytes.." % filesize)
|
|
||||||
encrypted = b""
|
|
||||||
while len(encrypted) < encrypted_filesize:
|
|
||||||
more = skt.recv(encrypted_filesize - len(encrypted))
|
|
||||||
if not more:
|
|
||||||
print("Connection dropped before full file received")
|
|
||||||
print("got %d bytes, wanted %d" % (len(encrypted), encrypted_filesize))
|
|
||||||
sys.exit(1)
|
|
||||||
encrypted += more
|
|
||||||
assert len(encrypted) == encrypted_filesize
|
|
||||||
|
|
||||||
decrypted = SecretBox(xfer_key).decrypt(encrypted)
|
|
||||||
|
|
||||||
# only write to the current directory, and never overwrite anything
|
|
||||||
here = os.path.abspath(os.getcwd())
|
|
||||||
target = os.path.abspath(os.path.join(here, filename))
|
|
||||||
if os.path.dirname(target) != here:
|
|
||||||
print("Error: suggested filename (%s) would be outside current directory"
|
|
||||||
% (filename,))
|
|
||||||
skt.send("bad filename\n")
|
|
||||||
skt.close()
|
|
||||||
sys.exit(1)
|
|
||||||
if os.path.exists(target):
|
|
||||||
print("Error: refusing to overwrite existing file %s" % (filename,))
|
|
||||||
skt.send("file already exists\n")
|
|
||||||
skt.close()
|
|
||||||
sys.exit(1)
|
|
||||||
with open(target, "wb") as f:
|
|
||||||
f.write(decrypted)
|
|
||||||
print("Received file written to %s" % filename)
|
|
||||||
skt.send("ok\n")
|
|
||||||
skt.close()
|
|
||||||
sys.exit(0)
|
|
|
@ -1,19 +0,0 @@
|
||||||
from __future__ import print_function
|
|
||||||
import sys, time, json
|
|
||||||
from wormhole.blocking.transcribe import Receiver, WrongPasswordError
|
|
||||||
|
|
||||||
APPID = "lothar.com/wormhole/text-xfer"
|
|
||||||
|
|
||||||
# we're receiving
|
|
||||||
data = json.dumps({"message": "ok"}).encode("utf-8")
|
|
||||||
r = Receiver(APPID, data)
|
|
||||||
r.set_code(r.input_code("Enter receive-text wormhole code: "))
|
|
||||||
start = time.time()
|
|
||||||
try:
|
|
||||||
them_bytes = r.get_data()
|
|
||||||
except WrongPasswordError as e:
|
|
||||||
print("ERROR: " + e.explain(), file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
them_d = json.loads(them_bytes.decode("utf-8"))
|
|
||||||
print(them_d["message"])
|
|
||||||
print("elapsed time: %.2f" % (time.time() - start))
|
|
|
@ -1,68 +0,0 @@
|
||||||
from __future__ import print_function
|
|
||||||
import os, sys, json
|
|
||||||
from nacl.secret import SecretBox
|
|
||||||
from wormhole.blocking.transcribe import Initiator, WrongPasswordError
|
|
||||||
from wormhole.blocking.transit import TransitSender
|
|
||||||
|
|
||||||
APPID = "lothar.com/wormhole/file-xfer"
|
|
||||||
|
|
||||||
# we're sending
|
|
||||||
filename = sys.argv[1]
|
|
||||||
assert os.path.isfile(filename)
|
|
||||||
transit_sender = TransitSender()
|
|
||||||
|
|
||||||
filesize = os.stat(filename).st_size
|
|
||||||
data = json.dumps({
|
|
||||||
"file": {
|
|
||||||
"filename": os.path.basename(filename),
|
|
||||||
"filesize": filesize,
|
|
||||||
},
|
|
||||||
"transit": {
|
|
||||||
"direct_connection_hints": transit_sender.get_direct_hints(),
|
|
||||||
"relay_connection_hints": transit_sender.get_relay_hints(),
|
|
||||||
},
|
|
||||||
}).encode("utf-8")
|
|
||||||
|
|
||||||
i = Initiator(APPID, data)
|
|
||||||
code = i.get_code()
|
|
||||||
print("On the other computer, please run: receive_file")
|
|
||||||
print("Wormhole code is '%s'" % code)
|
|
||||||
print("")
|
|
||||||
try:
|
|
||||||
them_bytes = i.get_data()
|
|
||||||
except WrongPasswordError as e:
|
|
||||||
print("ERROR: " + e.explain(), file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
them_d = json.loads(them_bytes.decode("utf-8"))
|
|
||||||
#print("them: %r" % (them_d,))
|
|
||||||
xfer_key = i.derive_key(APPID+"/xfer-key", SecretBox.KEY_SIZE)
|
|
||||||
|
|
||||||
box = SecretBox(xfer_key)
|
|
||||||
with open(filename, "rb") as f:
|
|
||||||
plaintext = f.read()
|
|
||||||
nonce = os.urandom(SecretBox.NONCE_SIZE)
|
|
||||||
encrypted = box.encrypt(plaintext, nonce)
|
|
||||||
|
|
||||||
tdata = them_d["transit"]
|
|
||||||
transit_key = i.derive_key(APPID+"/transit-key")
|
|
||||||
transit_sender.set_transit_key(transit_key)
|
|
||||||
transit_sender.add_their_direct_hints(tdata["direct_connection_hints"])
|
|
||||||
transit_sender.add_their_relay_hints(tdata["relay_connection_hints"])
|
|
||||||
skt = transit_sender.establish_connection()
|
|
||||||
|
|
||||||
print("Sending %d bytes.." % filesize)
|
|
||||||
sent = 0
|
|
||||||
while sent < len(encrypted):
|
|
||||||
more = skt.send(encrypted[sent:])
|
|
||||||
sent += more
|
|
||||||
|
|
||||||
print("File sent.. waiting for confirmation")
|
|
||||||
# ack is a short newline-terminated string, followed by socket close. A long
|
|
||||||
# read is probably good enough.
|
|
||||||
ack = skt.recv(300)
|
|
||||||
if ack == "ok\n":
|
|
||||||
print("Confirmation received. Transfer complete.")
|
|
||||||
sys.exit(0)
|
|
||||||
else:
|
|
||||||
print("Transfer failed (remote says: %r)" % ack)
|
|
||||||
sys.exit(1)
|
|
|
@ -1,22 +0,0 @@
|
||||||
from __future__ import print_function
|
|
||||||
import sys, json
|
|
||||||
from wormhole.blocking.transcribe import Initiator, WrongPasswordError
|
|
||||||
|
|
||||||
APPID = "lothar.com/wormhole/text-xfer"
|
|
||||||
|
|
||||||
# we're sending
|
|
||||||
message = sys.argv[1]
|
|
||||||
data = json.dumps({"message": message,
|
|
||||||
}).encode("utf-8")
|
|
||||||
i = Initiator(APPID, data)
|
|
||||||
code = i.get_code()
|
|
||||||
print("On the other computer, please run: receive_text")
|
|
||||||
print("Wormhole code is: %s" % code)
|
|
||||||
print("")
|
|
||||||
try:
|
|
||||||
them_bytes = i.get_data()
|
|
||||||
except WrongPasswordError as e:
|
|
||||||
print("ERROR: " + e.explain(), file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
them_d = json.loads(them_bytes.decode("utf-8"))
|
|
||||||
print("them: %r" % (them_d,))
|
|
4
setup.py
4
setup.py
|
@ -19,7 +19,9 @@ setup(name="wormhole-sync",
|
||||||
url="https://github.com/warner/wormhole-sync",
|
url="https://github.com/warner/wormhole-sync",
|
||||||
package_dir={"": "src"},
|
package_dir={"": "src"},
|
||||||
packages=["wormhole"],
|
packages=["wormhole"],
|
||||||
install_requires=["spake2", "pynacl", "requests"],
|
entry_points={"console_scripts":
|
||||||
|
["wormhole = wormhole.scripts.runner:entry"]},
|
||||||
|
install_requires=["spake2", "pynacl", "requests", "twisted"],
|
||||||
test_suite="wormhole.test",
|
test_suite="wormhole.test",
|
||||||
cmdclass=commands,
|
cmdclass=commands,
|
||||||
)
|
)
|
||||||
|
|
0
src/wormhole/scripts/__init__.py
Normal file
0
src/wormhole/scripts/__init__.py
Normal file
74
src/wormhole/scripts/cmd_receive_file.py
Normal file
74
src/wormhole/scripts/cmd_receive_file.py
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
from __future__ import print_function
|
||||||
|
import sys, os, json
|
||||||
|
from nacl.secret import SecretBox
|
||||||
|
from wormhole.blocking.transcribe import Receiver, WrongPasswordError
|
||||||
|
from wormhole.blocking.transit import TransitReceiver
|
||||||
|
|
||||||
|
APPID = "lothar.com/wormhole/file-xfer"
|
||||||
|
|
||||||
|
def receive_file(so):
|
||||||
|
# we're receiving
|
||||||
|
transit_receiver = TransitReceiver()
|
||||||
|
|
||||||
|
mydata = json.dumps({
|
||||||
|
"transit": {
|
||||||
|
"direct_connection_hints": transit_receiver.get_direct_hints(),
|
||||||
|
"relay_connection_hints": transit_receiver.get_relay_hints(),
|
||||||
|
},
|
||||||
|
}).encode("utf-8")
|
||||||
|
r = Receiver(APPID, mydata)
|
||||||
|
r.set_code(r.input_code("Enter receive-file wormhole code: "))
|
||||||
|
|
||||||
|
try:
|
||||||
|
data = json.loads(r.get_data().decode("utf-8"))
|
||||||
|
except WrongPasswordError as e:
|
||||||
|
print("ERROR: " + e.explain(), file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
#print("their data: %r" % (data,))
|
||||||
|
|
||||||
|
file_data = data["file"]
|
||||||
|
xfer_key = r.derive_key(APPID+"/xfer-key", SecretBox.KEY_SIZE)
|
||||||
|
filename = os.path.basename(file_data["filename"]) # unicode
|
||||||
|
filesize = file_data["filesize"]
|
||||||
|
encrypted_filesize = filesize + SecretBox.NONCE_SIZE+16
|
||||||
|
|
||||||
|
# now receive the rest of the owl
|
||||||
|
tdata = data["transit"]
|
||||||
|
transit_key = r.derive_key(APPID+"/transit-key")
|
||||||
|
transit_receiver.set_transit_key(transit_key)
|
||||||
|
transit_receiver.add_their_direct_hints(tdata["direct_connection_hints"])
|
||||||
|
transit_receiver.add_their_relay_hints(tdata["relay_connection_hints"])
|
||||||
|
skt = transit_receiver.establish_connection()
|
||||||
|
print("Receiving %d bytes.." % filesize)
|
||||||
|
encrypted = b""
|
||||||
|
while len(encrypted) < encrypted_filesize:
|
||||||
|
more = skt.recv(encrypted_filesize - len(encrypted))
|
||||||
|
if not more:
|
||||||
|
print("Connection dropped before full file received")
|
||||||
|
print("got %d bytes, wanted %d" % (len(encrypted), encrypted_filesize))
|
||||||
|
return 1
|
||||||
|
encrypted += more
|
||||||
|
assert len(encrypted) == encrypted_filesize
|
||||||
|
|
||||||
|
decrypted = SecretBox(xfer_key).decrypt(encrypted)
|
||||||
|
|
||||||
|
# only write to the current directory, and never overwrite anything
|
||||||
|
here = os.path.abspath(os.getcwd())
|
||||||
|
target = os.path.abspath(os.path.join(here, filename))
|
||||||
|
if os.path.dirname(target) != here:
|
||||||
|
print("Error: suggested filename (%s) would be outside current directory"
|
||||||
|
% (filename,))
|
||||||
|
skt.send("bad filename\n")
|
||||||
|
skt.close()
|
||||||
|
return 1
|
||||||
|
if os.path.exists(target):
|
||||||
|
print("Error: refusing to overwrite existing file %s" % (filename,))
|
||||||
|
skt.send("file already exists\n")
|
||||||
|
skt.close()
|
||||||
|
return 1
|
||||||
|
with open(target, "wb") as f:
|
||||||
|
f.write(decrypted)
|
||||||
|
print("Received file written to %s" % filename)
|
||||||
|
skt.send("ok\n")
|
||||||
|
skt.close()
|
||||||
|
return 0
|
20
src/wormhole/scripts/cmd_receive_text.py
Normal file
20
src/wormhole/scripts/cmd_receive_text.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
from __future__ import print_function
|
||||||
|
import sys, time, json
|
||||||
|
from wormhole.blocking.transcribe import Receiver, WrongPasswordError
|
||||||
|
|
||||||
|
APPID = "lothar.com/wormhole/text-xfer"
|
||||||
|
|
||||||
|
def receive_text(so):
|
||||||
|
# we're receiving
|
||||||
|
data = json.dumps({"message": "ok"}).encode("utf-8")
|
||||||
|
r = Receiver(APPID, data)
|
||||||
|
r.set_code(r.input_code("Enter receive-text wormhole code: "))
|
||||||
|
start = time.time()
|
||||||
|
try:
|
||||||
|
them_bytes = r.get_data()
|
||||||
|
except WrongPasswordError as e:
|
||||||
|
print("ERROR: " + e.explain(), file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
them_d = json.loads(them_bytes.decode("utf-8"))
|
||||||
|
print(them_d["message"])
|
||||||
|
print("elapsed time: %.2f" % (time.time() - start))
|
69
src/wormhole/scripts/cmd_send_file.py
Normal file
69
src/wormhole/scripts/cmd_send_file.py
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
from __future__ import print_function
|
||||||
|
import os, sys, json
|
||||||
|
from nacl.secret import SecretBox
|
||||||
|
from wormhole.blocking.transcribe import Initiator, WrongPasswordError
|
||||||
|
from wormhole.blocking.transit import TransitSender
|
||||||
|
|
||||||
|
APPID = "lothar.com/wormhole/file-xfer"
|
||||||
|
|
||||||
|
def send_file(so):
|
||||||
|
# we're sending
|
||||||
|
filename = so["filename"]
|
||||||
|
assert os.path.isfile(filename)
|
||||||
|
transit_sender = TransitSender()
|
||||||
|
|
||||||
|
filesize = os.stat(filename).st_size
|
||||||
|
data = json.dumps({
|
||||||
|
"file": {
|
||||||
|
"filename": os.path.basename(filename),
|
||||||
|
"filesize": filesize,
|
||||||
|
},
|
||||||
|
"transit": {
|
||||||
|
"direct_connection_hints": transit_sender.get_direct_hints(),
|
||||||
|
"relay_connection_hints": transit_sender.get_relay_hints(),
|
||||||
|
},
|
||||||
|
}).encode("utf-8")
|
||||||
|
|
||||||
|
i = Initiator(APPID, data)
|
||||||
|
code = i.get_code()
|
||||||
|
print("On the other computer, please run: receive_file")
|
||||||
|
print("Wormhole code is '%s'" % code)
|
||||||
|
print("")
|
||||||
|
try:
|
||||||
|
them_bytes = i.get_data()
|
||||||
|
except WrongPasswordError as e:
|
||||||
|
print("ERROR: " + e.explain(), file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
them_d = json.loads(them_bytes.decode("utf-8"))
|
||||||
|
#print("them: %r" % (them_d,))
|
||||||
|
xfer_key = i.derive_key(APPID+"/xfer-key", SecretBox.KEY_SIZE)
|
||||||
|
|
||||||
|
box = SecretBox(xfer_key)
|
||||||
|
with open(filename, "rb") as f:
|
||||||
|
plaintext = f.read()
|
||||||
|
nonce = os.urandom(SecretBox.NONCE_SIZE)
|
||||||
|
encrypted = box.encrypt(plaintext, nonce)
|
||||||
|
|
||||||
|
tdata = them_d["transit"]
|
||||||
|
transit_key = i.derive_key(APPID+"/transit-key")
|
||||||
|
transit_sender.set_transit_key(transit_key)
|
||||||
|
transit_sender.add_their_direct_hints(tdata["direct_connection_hints"])
|
||||||
|
transit_sender.add_their_relay_hints(tdata["relay_connection_hints"])
|
||||||
|
skt = transit_sender.establish_connection()
|
||||||
|
|
||||||
|
print("Sending %d bytes.." % filesize)
|
||||||
|
sent = 0
|
||||||
|
while sent < len(encrypted):
|
||||||
|
more = skt.send(encrypted[sent:])
|
||||||
|
sent += more
|
||||||
|
|
||||||
|
print("File sent.. waiting for confirmation")
|
||||||
|
# ack is a short newline-terminated string, followed by socket close. A long
|
||||||
|
# read is probably good enough.
|
||||||
|
ack = skt.recv(300)
|
||||||
|
if ack == "ok\n":
|
||||||
|
print("Confirmation received. Transfer complete.")
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
print("Transfer failed (remote says: %r)" % ack)
|
||||||
|
return 1
|
23
src/wormhole/scripts/cmd_send_text.py
Normal file
23
src/wormhole/scripts/cmd_send_text.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
from __future__ import print_function
|
||||||
|
import sys, json
|
||||||
|
from wormhole.blocking.transcribe import Initiator, WrongPasswordError
|
||||||
|
|
||||||
|
APPID = "lothar.com/wormhole/text-xfer"
|
||||||
|
|
||||||
|
def send_text(so):
|
||||||
|
# we're sending
|
||||||
|
message = so["text"]
|
||||||
|
data = json.dumps({"message": message,
|
||||||
|
}).encode("utf-8")
|
||||||
|
i = Initiator(APPID, data)
|
||||||
|
code = i.get_code()
|
||||||
|
print("On the other computer, please run: receive_text")
|
||||||
|
print("Wormhole code is: %s" % code)
|
||||||
|
print("")
|
||||||
|
try:
|
||||||
|
them_bytes = i.get_data()
|
||||||
|
except WrongPasswordError as e:
|
||||||
|
print("ERROR: " + e.explain(), file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
them_d = json.loads(them_bytes.decode("utf-8"))
|
||||||
|
print("them: %r" % (them_d,))
|
88
src/wormhole/scripts/runner.py
Normal file
88
src/wormhole/scripts/runner.py
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
import sys
|
||||||
|
from twisted.python import usage
|
||||||
|
|
||||||
|
class SendTextOptions(usage.Options):
|
||||||
|
def parseArgs(self, text):
|
||||||
|
self["text"] = text
|
||||||
|
synopsis = "TEXT"
|
||||||
|
|
||||||
|
class ReceiveTextOptions(usage.Options):
|
||||||
|
synopsis = ""
|
||||||
|
|
||||||
|
class SendFileOptions(usage.Options):
|
||||||
|
def parseArgs(self, filename):
|
||||||
|
self["filename"] = filename
|
||||||
|
synopsis = "FILENAME"
|
||||||
|
|
||||||
|
class ReceiveFileOptions(usage.Options):
|
||||||
|
synopsis = ""
|
||||||
|
|
||||||
|
class Options(usage.Options):
|
||||||
|
synopsis = "\nUsage: wormhole <command>"
|
||||||
|
subCommands = [("send-text", None, SendTextOptions, "Send a text message"),
|
||||||
|
("send-file", None, SendFileOptions, "Send a file"),
|
||||||
|
("receive-text", None, ReceiveTextOptions, "Receive a text message"),
|
||||||
|
("receive-file", None, ReceiveFileOptions, "Receive a file"),
|
||||||
|
]
|
||||||
|
|
||||||
|
def getUsage(self, **kwargs):
|
||||||
|
t = usage.Options.getUsage(self, **kwargs)
|
||||||
|
return t + "\nPlease run 'wormhole <command> --help' for more details on each command.\n"
|
||||||
|
|
||||||
|
def postOptions(self):
|
||||||
|
if not hasattr(self, 'subOptions'):
|
||||||
|
raise usage.UsageError("must specify a command")
|
||||||
|
|
||||||
|
def send_text(*args):
|
||||||
|
from . import cmd_send_text
|
||||||
|
return cmd_send_text.send_text(*args)
|
||||||
|
|
||||||
|
def receive_text(*args):
|
||||||
|
from . import cmd_receive_text
|
||||||
|
return cmd_receive_text.receive_text(*args)
|
||||||
|
|
||||||
|
def send_file(*args):
|
||||||
|
from . import cmd_send_file
|
||||||
|
return cmd_send_file.send_file(*args)
|
||||||
|
|
||||||
|
def receive_file(*args):
|
||||||
|
from . import cmd_receive_file
|
||||||
|
return cmd_receive_file.receive_file(*args)
|
||||||
|
|
||||||
|
DISPATCH = {"send-text": send_text,
|
||||||
|
"receive-text": receive_text,
|
||||||
|
"send-file": send_file,
|
||||||
|
"receive-file": receive_file,
|
||||||
|
}
|
||||||
|
|
||||||
|
def run(args, stdout, stderr, executable=None):
|
||||||
|
"""This is invoked directly by the 'wormhole' entry-point script. It can
|
||||||
|
also invoked by entry() below."""
|
||||||
|
config = Options()
|
||||||
|
try:
|
||||||
|
config.parseOptions(args)
|
||||||
|
except usage.error, e:
|
||||||
|
c = config
|
||||||
|
while hasattr(c, 'subOptions'):
|
||||||
|
c = c.subOptions
|
||||||
|
print >>stderr, str(c)
|
||||||
|
print >>stderr, e.args[0]
|
||||||
|
return 1
|
||||||
|
command = config.subCommand
|
||||||
|
so = config.subOptions
|
||||||
|
so["executable"] = executable
|
||||||
|
try:
|
||||||
|
#rc = DISPATCH[command](so, stdout, stderr)
|
||||||
|
rc = DISPATCH[command](so)
|
||||||
|
return rc
|
||||||
|
except ImportError, e:
|
||||||
|
print >>stderr, "--- ImportError ---"
|
||||||
|
print >>stderr, e
|
||||||
|
print >>stderr, "Please run 'python setup.py build'"
|
||||||
|
raise
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def entry():
|
||||||
|
"""This is used by a setuptools entry_point. When invoked this way,
|
||||||
|
setuptools has already put the installed package on sys.path ."""
|
||||||
|
return run(sys.argv[1:], sys.stdout, sys.stderr, executable=sys.argv[0])
|
Loading…
Reference in New Issue
Block a user