diff --git a/.gitignore b/.gitignore index fc2abb4..9450068 100644 --- a/.gitignore +++ b/.gitignore @@ -80,3 +80,13 @@ test/foo test/IMG_2252.JPG *.pdf + +foo/bar/foo1 + +foo/bar/foo2 + +foo/bar2 + +foo/bar1 + +test diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9b7eca4 --- /dev/null +++ b/Makefile @@ -0,0 +1,41 @@ +## warp +NAME = warp +VERSION = 0.1 +TARFILE = $(NAME)-$(VERSION).tar.gz +PYSOURCES = client_transfer_controller.py progress.py \ + client_udt_manager.py server.py \ + common_tools.py server_transfer_controller.py \ + config.py server_udt_manager.py \ + connection.py transfer_manager.py \ + file_transfer_agent.py warp.py \ + forward.py +SCRIPTS = warp.sh server.sh + +## Generic +RPMDIRS = SOURCES BUILD SRPMS RPMS BUILDROOT + +## Help +HELPTEXT = "\ + make help -- This message \n\ + make rpm -- makes warp rpm \n\ + make clean -- cleans everything \n\ + " + +help: + @ echo -e $(HELPTEXT) + +$(RPMDIRS): + mkdir $@ + +SOURCES/$(TARFILE): $(RPMDIRS) + - /bin/rm -rf $(NAME)-$(VERSION) + mkdir $(NAME)-$(VERSION) + cp $(PYSOURCES) $(SCRIPTS) $(NAME)-$(VERSION) + tar czf $@ $(NAME)-$(VERSION) + +rpm: SOURCES/$(TARFILE) + rpmbuild -ba --buildroot=$(PWD)/BUILDROOT $(NAME).spec + + +clean: + /bin/rm -rf $(NAME)-$(VERSION) $(RPMDIRS) diff --git a/client_transfer_controller.py b/client_transfer_controller.py index 166bebc..59a48bf 100644 --- a/client_transfer_controller.py +++ b/client_transfer_controller.py @@ -43,6 +43,10 @@ def _start(self): transfer_manager = self.server_channel.root.get_transfer_manager() if not self.recursive: try: + if transfer_manager.isdir(self.file_dest): + file_name = os.path.split(self.file_src)[1] + self.file_dest = os.path.join(self.file_dest, file_name) + transfer_agent = FileTransferAgent(ClientUDTManager(self.server_channel, self.hostname, self.tcp_mode), transfer_manager, self.file_src, self.file_dest, self.verify, False, self.stat) self.files_processed += 1 except EOFError: @@ -118,4 +122,5 @@ def is_transfer_success(self): return reduce(lambda y, x: 0 + y if x.transfer_success is True else 1 + y, self.transfer_agents, 0) == 0 def close(self): - self.server_channel.root.get_transfer_manager().finish() + # self.server_channel.root.get_transfer_manager().finish() + pass diff --git a/config.py b/config.py index e709ac4..a978bb1 100644 --- a/config.py +++ b/config.py @@ -6,6 +6,7 @@ import logging import __main__ as main +import os, pwd LOG_LEVEL = logging.INFO @@ -20,7 +21,10 @@ NONCE_SIZE = 32 PORT = 29977 -def get_file_logger(logger_name, filepath="/var/tmp/warp.log"): +# Creates user specific log files. +DEFAULT_LOG_FILE_NAME = "/var/tmp/" + "warp-" + pwd.getpwuid(os.getuid())[0] + ".log" + +def get_file_logger(logger_name, filepath=DEFAULT_LOG_FILE_NAME): """ Returns a formatted logger that logs to a file and the console. Takes the logger name as a parameters and optional filepath. diff --git a/connection.py b/connection.py index df08d11..37b2490 100644 --- a/connection.py +++ b/connection.py @@ -55,8 +55,8 @@ def connect(self): return self.channel def close(self): - pass - # self.forward_thread.exit() + logger.debug("Closing Channel.") + self.channel.close() @staticmethod def unpack_remote_host(remote_host): diff --git a/forward.py b/forward.py index 3cd2d80..effad18 100644 --- a/forward.py +++ b/forward.py @@ -79,11 +79,13 @@ def handle(self): break self.request.send(data) - peername = self.request.getpeername() - chan.close() - self.request.close() - verbose('Tunnel closed from %r' % (peername,)) - + try: + peername = self.request.getpeername() + chan.close() + self.request.close() + verbose('Tunnel closed from %r' % (peername,)) + except: + pass def forward_tunnel(local_port, remote_host, remote_port, transport): # this is a little convoluted, but lets me configure things for the Handler diff --git a/progress.py b/progress.py index 17305a0..c30991c 100644 --- a/progress.py +++ b/progress.py @@ -30,6 +30,9 @@ def redraw(self): def exit(self): self.screen.exit() + def fullscreen(self): + self.screen.fullscreen() + class Screen(object): def __init__(self): @@ -39,6 +42,7 @@ def __init__(self): self.next_line_top = 0 self.next_line_bottom = 1 + def fullscreen(self): print self.term.enter_fullscreen() def redraw(self): @@ -73,6 +77,12 @@ def add_component(self, component, to_bottom=False): self.next_line_bottom += 1 def exit(self): + for line in self.bottom_lines.itervalues(): + line.exit() + + for line in self.top_lines.itervalues(): + line.exit() + print self.term.clear() print self.term.exit_fullscreen() @@ -87,6 +97,10 @@ def __init__(self, comp=None): def add_component(self, component): self.components.append(component) + def exit(self): + for componenet in self.components: + componenet.active = False + def __iter__(self): for each in self.components: yield each @@ -157,10 +171,10 @@ def updateCallback(self): self.timeDiff = time.time() - self.lastUpdated self.lastUpdated = time.time() - def printableUnits(self, value): + def printableUnits(self, value, base=1000): i = 0 for i in range(1, len(self.units)+1): - if value // pow(1000, i) == 0: + if value // pow(base, i) == 0: break i-=1 return i @@ -172,10 +186,11 @@ def __str__(self): if self.value[2] and self.progress == self.expected_size: self.fill_char = "V" - i = self.printableUnits(self.expected_size) - j = self.printableUnits(self.progress) + baseDiskSize = pow(2, 10) + i = self.printableUnits(self.expected_size, baseDiskSize) + j = self.printableUnits(self.progress, baseDiskSize) - progress = "{0:.3f}".format(self.progress/pow(1000, j)) + self.units[j] + "/" + "{0:.3f}".format(self.expected_size/pow(1000, i)) + self.units[i] + progress = "{0:.3f}".format(self.progress/pow(baseDiskSize, j)) + self.units[j] + "/" + "{0:.3f}".format(self.expected_size/pow(baseDiskSize, i)) + self.units[i] speed = 0 if self.timeDiff != 0: speed = (self.lastProgress[1] - self.lastProgress[0])/self.timeDiff diff --git a/server.py b/server.py index 61f66fb..6189920 100755 --- a/server.py +++ b/server.py @@ -7,7 +7,7 @@ """ from config import * -from rpyc.utils.server import ThreadedServer +from rpyc.utils.server import OneShotServer from common_tools import * import plac from server_transfer_controller import ServerTransferController @@ -19,7 +19,7 @@ def main(): os.chdir(expanduser("~")) - server = ThreadedServer(ServerTransferController, hostname='localhost', port=0, protocol_config={"allow_public_attrs": True}) + server = OneShotServer(ServerTransferController, hostname='localhost', port=0, protocol_config={"allow_public_attrs": True}) sys.stderr.write(str(server.port)) sys.stderr.write(' ') server.start() diff --git a/server.sh b/server.sh new file mode 100755 index 0000000..dcfb7a9 --- /dev/null +++ b/server.sh @@ -0,0 +1,8 @@ +#!/bin/bash +WARPHOME=/opt/warp +MODNAME=opt-python +PRELOADED=$(echo ${LOADEDMODULES} | grep $MODNAME) +if [ -z $PRELOADED ]; then module load $MODNAME; fi +PYTHONPATH=${WARPHOME}:${PYTHONPATH} ${WARPHOME}/server.py $* +if [ -z $PRELOADED ]; then module unload $MODNAME; fi + diff --git a/transfer_manager.py b/transfer_manager.py index dadd625..6c9d785 100644 --- a/transfer_manager.py +++ b/transfer_manager.py @@ -2,7 +2,6 @@ from config import * from common_tools import * - class TransferManager: def __init__(self): pass @@ -10,9 +9,12 @@ def __init__(self): def __del__(self): pass - def is_file(self, filepath): + def isfile(self, filepath): return os.path.isfile(filepath) + def isdir(self, filepath): + return os.path.isdir(filepath) + def get_file_hash(self, filepath, block_count=0): return getHash(filepath, block_count) diff --git a/warp.py b/warp.py index 723171b..202170a 100755 --- a/warp.py +++ b/warp.py @@ -32,6 +32,8 @@ def main(remote_host, recursive, file_src, file_dest, tcp_mode, disable_verify, logger.setLevel(logging.DEBUG) global gui gui = mock.Mock() + else: + gui.fullscreen() startTime = time.time() @@ -74,10 +76,12 @@ def main(remote_host, recursive, file_src, file_dest, tcp_mode, disable_verify, else: logger.warn("Failed to send file.") + logger.debug("Redrawing GUI.") gui.redraw() + logger.debug("Closing Controller.") controller.close() + logger.debug("Closing Connection.") connection.close() - channel.close() logger.debug("Closed connections.") gui.exit() diff --git a/warp.sh b/warp.sh new file mode 100755 index 0000000..f439e88 --- /dev/null +++ b/warp.sh @@ -0,0 +1,8 @@ +#!/bin/bash +WARPHOME=/opt/warp +MODNAME=opt-python +PRELOADED=$(echo ${LOADEDMODULES} | grep $MODNAME) +if [ -z $PRELOADED ]; then module load $MODNAME; fi +PYTHONPATH=${WARPHOME}:${PYTHONPATH} ${WARPHOME}/warp.py $* +if [ -z $PRELOADED ]; then module unload $MODNAME; fi + diff --git a/warp.spec b/warp.spec new file mode 100644 index 0000000..17e78f0 --- /dev/null +++ b/warp.spec @@ -0,0 +1,36 @@ +Summary: warp UDT-based file transfer +Name: warp +Version: 0.1 +Release: 2 +License: GPL +Vendor: University of California +Group: System Environment/Base +Source: %{name}-%{version}.tar.gz +%define _topdir %(echo $PWD)/ +%define pkgroot /opt/%{name} + +%description +UDT is a reliable UDP based application level data transport protocol for +distributed data intensive applications over wide area high-speed networks. +Warp is a nice command-line client, written in Python, around UDT +%prep +%setup +%build +printf "\n\n\n### build ###\n\n\n" +%install +printf "\n\n\n### install ###\n\n\n" + +ROOT=$RPM_BUILD_ROOT +INSTALL=/usr/bin/install + +mkdir -p $ROOT/%{pkgroot} +mkdir -p $ROOT/usr/bin + +$INSTALL *.py $ROOT/%{pkgroot} +$INSTALL -m 755 warp.sh $ROOT/usr/bin/warp +$INSTALL -m 755 server.sh $ROOT/usr/bin/warp-server + +%files +%{pkgroot} +/usr/bin/* +