Command Line Interface

This commit is contained in:
Davte 2020-04-09 19:46:52 +02:00
parent d4abc1f2a5
commit d2522b3e08
3 changed files with 163 additions and 23 deletions

4
.gitignore vendored
View File

@ -1,4 +1,8 @@
# ---> Python
# Configuration file
*config.py
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]

View File

@ -1,8 +1,9 @@
import argparse
import asyncio
import collections
import logging
# import signal
import sys
import os
class Client:
@ -94,6 +95,34 @@ class Client:
raise KeyboardInterrupt("Not working yet...")
def get_action(action):
"""Parse abbreviations for `action`."""
if not isinstance(action, str):
return
elif action.lower().startswith('r'):
return 'receive'
elif action.lower().startswith('s'):
return 'send'
def get_file_path(path, action='receive'):
"""Check that file `path` is correct and return it."""
if (
isinstance(path, str)
and action == 'send'
and os.path.isfile(path)
):
return path
elif (
isinstance(path, str)
and action == 'receive'
and os.access(os.path.dirname(os.path.abspath(path)), os.W_OK)
):
return path
elif path is not None:
logging.error(f"Invalid file: `{path}`")
if __name__ == '__main__':
log_formatter = logging.Formatter(
"%(asctime)s [%(module)-15s %(levelname)-8s] %(message)s",
@ -107,31 +136,101 @@ if __name__ == '__main__':
console_handler.setLevel(logging.DEBUG)
root_logger.addHandler(console_handler)
if len(sys.argv) > 1:
action = sys.argv[1]
else:
action = input("Do you want to (R)eceive or (S)end a file?\t\t")
# Parse command-line arguments
cli_parser = argparse.ArgumentParser(description='Run client',
allow_abbrev=False)
cli_parser.add_argument('--host', type=str,
default=None,
required=False,
help='server address')
cli_parser.add_argument('--port', type=int,
default=None,
required=False,
help='server _port')
cli_parser.add_argument('--action', type=str,
default=None,
required=False,
help='[S]end or [R]eceive')
cli_parser.add_argument('--path', type=str,
default=None,
required=False,
help='File path')
cli_parser.add_argument('others',
metavar='R or S',
nargs='*',
help='[S]end or [R]eceive (see `action`)')
args = vars(cli_parser.parse_args())
_host = args['host']
_port = args['port']
_action = get_action(args['action'])
_file_path = args['path']
action = (
'send'
if action.lower() == 's'
else 'receive'
)
if len(sys.argv) > 2:
_file_path = sys.argv[2]
else:
_file_path = input(f"Enter file to {action}:\t\t\t\t\t\t")
# If _host and _port are not provided from command-line, try to import them
if _host is None:
try:
from config import host as _host
except ImportError:
_host = None
if _port is None:
try:
from config import port as _port
except ImportError:
_port = None
# Take `s`, `r` etc. from command line as `_action`
if _action is None:
for arg in args['others']:
_action = get_action(arg)
if _action:
break
if _action is None:
try:
from config import action as _action
_action = get_action(_action)
except ImportError:
_action = None
if _file_path is None:
try:
from config import file_path as _file_path
_file_path = get_action(_file_path)
except ImportError:
_file_path = None
# If import fails, prompt user for _host or _port
while _host is None:
_host = input("Enter _host:\t\t\t\t\t\t")
while _port is None:
try:
_port = int(input("Enter _port:\t\t\t\t\t\t"))
except ValueError:
logging.info("Invalid _port. Enter a valid _port number!")
_port = None
while _action is None:
_action = get_action(
input("Do you want to (R)eceive or (S)end a file?\t\t")
)
while _file_path is None:
_file_path = get_file_path(
path=input(f"Enter file to {_action}:\t\t\t\t\t\t"),
action=_action
)
loop = asyncio.get_event_loop()
client = Client(
host='davte.it',
port=5000,
host=_host,
port=_port,
)
# loop.add_signal_handler(signal.SIGINT, client.stop, loop)
logging.info("Starting client...")
if action.lower() == 'send':
loop.run_until_complete(client.run_sending_client(file_path=_file_path))
if _action == 'send':
loop.run_until_complete(
client.run_sending_client(
file_path=_file_path
)
)
else:
loop.run_until_complete(client.run_receiving_client(file_path=_file_path))
loop.run_until_complete(
client.run_receiving_client(
file_path=_file_path
)
)
loop.close()
logging.info("Stopped client")

View File

@ -1,3 +1,4 @@
import argparse
import asyncio
import collections
import logging
@ -96,7 +97,6 @@ class Server:
logging.info("Receiver is connecting...")
await self.run_writer(writer=writer)
logging.info("Outgoing transmission ended")
self.stop()
return
async def run_server(self):
@ -131,10 +131,47 @@ if __name__ == '__main__':
console_handler.setLevel(logging.DEBUG)
root_logger.addHandler(console_handler)
# Parse command-line arguments
parser = argparse.ArgumentParser(description='Run server',
allow_abbrev=False)
parser.add_argument('--_host', type=str,
default=None,
required=False,
help='server address')
parser.add_argument('--_port', type=int,
default=None,
required=False,
help='server _port')
args = vars(parser.parse_args())
host = args['_host']
port = args['_port']
# If _host and _port are not provided from command-line, try to import them
if host is None:
try:
from config import host
except ImportError:
host = None
if port is None:
try:
from config import port
except ImportError:
port = None
# If import fails, prompt user for _host or _port
while host is None:
host = input("Enter _host:\t\t\t\t\t\t")
while port is None:
try:
port = int(input("Enter _port:\t\t\t\t\t\t"))
except ValueError:
logging.info("Invalid _port. Enter a valid _port number!")
port = None
loop = asyncio.get_event_loop()
server = Server(
host='davte.it',
port=5000,
host=host,
port=port,
)
logging.info("Starting file bridging server...")
try: