materials-commons-cli 2.1.8__tar.gz → 2.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/PKG-INFO +1 -1
- materials_commons_cli-2.2.0/materials_commons/cli/__init__.py +1 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/functions.py +14 -6
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/parser.py +9 -3
- materials_commons_cli-2.2.0/materials_commons/cli/subcommands/server.py +75 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/subcommands/up.py +93 -12
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/user_config.py +8 -5
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons_cli.egg-info/PKG-INFO +1 -1
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons_cli.egg-info/SOURCES.txt +1 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons_cli.egg-info/requires.txt +1 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/setup.py +1 -0
- materials_commons_cli-2.1.8/materials_commons/cli/__init__.py +0 -1
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/LICENSE +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/README.md +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/LICENSE.txt +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/cloned_project.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/exceptions.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/file_functions.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/globus.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/list_objects.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/print_formatter.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/sqltable.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/subcommands/__init__.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/subcommands/clone.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/subcommands/config.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/subcommands/dataset.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/subcommands/down.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/subcommands/expt.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/subcommands/fetch.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/subcommands/globus.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/subcommands/init.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/subcommands/ls.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/subcommands/mkdir.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/subcommands/mv.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/subcommands/proj.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/subcommands/remote.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/subcommands/rm.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/subcommands/versions.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/tmp_functions.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/tree_functions.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/treedb.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons_cli.egg-info/dependency_links.txt +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons_cli.egg-info/entry_points.txt +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons_cli.egg-info/not-zip-safe +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons_cli.egg-info/top_level.txt +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/setup.cfg +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/test/test_api.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/test/test_functions.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/test/test_mc_dataset.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/test/test_mc_down.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/test/test_mc_mkdir.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/test/test_mc_mv.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/test/test_mc_proj.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/test/test_mc_rm.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/test/test_mc_up.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/test/test_treecompare_no_cache.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/test/test_treecompare_with_cache.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/test/test_treedb.py +0 -0
- {materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/test/test_user_config.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '2.2.0'
|
{materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/functions.py
RENAMED
|
@@ -134,15 +134,23 @@ def format_time(time_value, fmt="%Y %b %d %H:%M:%S"):
|
|
|
134
134
|
else:
|
|
135
135
|
return str(type(time_value))
|
|
136
136
|
|
|
137
|
-
def checksum(path, chunk_size=
|
|
138
|
-
"""Generate MD5 checksum for the file at "path"
|
|
137
|
+
def checksum(path, chunk_size=8192):
|
|
138
|
+
"""Generate MD5 checksum for the file at "path"
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
path (str): Path to file
|
|
142
|
+
chunk_size (int): Size of chunks to read (default 8192 bytes)
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
str: MD5 checksum hexdigest
|
|
146
|
+
"""
|
|
139
147
|
md5 = hashlib.md5()
|
|
140
148
|
with open(path, 'rb') as f:
|
|
141
149
|
while True:
|
|
142
|
-
|
|
143
|
-
if not
|
|
150
|
+
chunk = f.read(chunk_size)
|
|
151
|
+
if not chunk:
|
|
144
152
|
break
|
|
145
|
-
md5.update(
|
|
153
|
+
md5.update(chunk)
|
|
146
154
|
return md5.hexdigest()
|
|
147
155
|
|
|
148
156
|
def random_name(n=3, max_letters=6, sep='-'):
|
|
@@ -449,7 +457,7 @@ def make_local_project(path, data=None):
|
|
|
449
457
|
else:
|
|
450
458
|
proj = models.Project(data=data)
|
|
451
459
|
except requests.exceptions.ConnectionError as e:
|
|
452
|
-
raise MCCLIException("Could not connect to " + remote.
|
|
460
|
+
raise MCCLIException("Could not connect to " + project_config.remote.mcurl)
|
|
453
461
|
except requests.exceptions.HTTPError as e:
|
|
454
462
|
raise MCCLIException("HTTPError: " + str(e))
|
|
455
463
|
|
|
@@ -31,6 +31,7 @@ from materials_commons.cli.subcommands.rm import rm_subcommand
|
|
|
31
31
|
from materials_commons.cli.subcommands.up import up_subcommand
|
|
32
32
|
from materials_commons.cli.subcommands.versions import versions_subcommand
|
|
33
33
|
from materials_commons.cli.user_config import Config
|
|
34
|
+
from materials_commons.cli.subcommands.server import server_subcommand
|
|
34
35
|
|
|
35
36
|
standard_usage = [
|
|
36
37
|
{'name': 'remote', 'desc': 'List servers', 'subcommand': remote_subcommand},
|
|
@@ -50,7 +51,8 @@ standard_usage = [
|
|
|
50
51
|
{'name': 'versions', 'desc': 'List file versions', 'subcommand': versions_subcommand},
|
|
51
52
|
# {'name': 'proc', 'desc': 'List processes', 'subcommand': ProcSubcommand()},
|
|
52
53
|
# {'name': 'samp', 'desc': 'List samples', 'subcommand': SampSubcommand()},
|
|
53
|
-
{'name': 'config', 'desc': 'Configure `mc`', 'subcommand': config_subcommand}
|
|
54
|
+
{'name': 'config', 'desc': 'Configure `mc`', 'subcommand': config_subcommand},
|
|
55
|
+
{'name': 'server', 'desc': 'Run MC Server', 'subcommand': server_subcommand}
|
|
54
56
|
]
|
|
55
57
|
standard_interfaces = {d['name']: d for d in standard_usage}
|
|
56
58
|
|
|
@@ -60,8 +62,13 @@ def make_parser():
|
|
|
60
62
|
usage_help.write("mc <command> [<args>]\n\n")
|
|
61
63
|
usage_help.write("The standard mc commands are:\n")
|
|
62
64
|
|
|
65
|
+
beta = os.getenv('MC_BETA')
|
|
63
66
|
for name, interface in standard_interfaces.items():
|
|
64
|
-
|
|
67
|
+
if name == 'server':
|
|
68
|
+
if beta:
|
|
69
|
+
usage_help.write(" {:10} {:40}\n".format(name, interface['desc']))
|
|
70
|
+
else:
|
|
71
|
+
usage_help.write(" {:10} {:40}\n".format(name, interface['desc']))
|
|
65
72
|
|
|
66
73
|
parser = argparse.ArgumentParser(
|
|
67
74
|
description='Materials Commons command line interface',
|
|
@@ -130,7 +137,6 @@ def main(argv=None, working_dir=None):
|
|
|
130
137
|
if working_dir is None:
|
|
131
138
|
working_dir = os.getcwd()
|
|
132
139
|
try:
|
|
133
|
-
|
|
134
140
|
config = Config()
|
|
135
141
|
if config.REST_logging:
|
|
136
142
|
mcapi.Client.set_debug_on()
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import asyncio
|
|
3
|
+
import signal
|
|
4
|
+
import uuid
|
|
5
|
+
from typing import Awaitable, Callable, Dict, Any
|
|
6
|
+
|
|
7
|
+
from materials_commons.cli.desktop.command_handlers import register_handlers
|
|
8
|
+
from materials_commons.cli.desktop.websocket_server import WebSocketCommandListener
|
|
9
|
+
from materials_commons.cli.user_config import Config
|
|
10
|
+
from materials_commons.cli.desktop.local_rest_server import LocalRestServer
|
|
11
|
+
|
|
12
|
+
CommandHandler = Callable[[Dict[str, Any]], Awaitable[None]]
|
|
13
|
+
|
|
14
|
+
DEFAULT_WS_URL = "wss://materialscommons.org/ws"
|
|
15
|
+
DEFAULT_RECONNECT_MIN_SEC = 1
|
|
16
|
+
DEFAULT_RECONNECT_MAX_SEC = 30
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _install_signal_handlers(loop: asyncio.AbstractEventLoop):
|
|
20
|
+
# Installs signal handlers for graceful shutdown
|
|
21
|
+
for sig in (signal.SIGINT, signal.SIGTERM):
|
|
22
|
+
try:
|
|
23
|
+
loop.add_signal_handler(sig, lambda s=sig: asyncio.create_task(_graceful_stop(loop)), None)
|
|
24
|
+
except NotImplementedError:
|
|
25
|
+
signal.signal(sig, lambda *_: asyncio.create_task(_graceful_stop(loop)))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
async def _graceful_stop(loop: asyncio.AbstractEventLoop):
|
|
29
|
+
"""Cancels pending tasks then stops the event loop"""
|
|
30
|
+
tasks = [t for t in asyncio.all_tasks(loop) if t is not asyncio.current_task(loop)]
|
|
31
|
+
for t in tasks:
|
|
32
|
+
t.cancel()
|
|
33
|
+
await asyncio.gather(*tasks, return_exceptions=True)
|
|
34
|
+
loop.stop()
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def server_subcommand(argv, working_dir=None):
|
|
38
|
+
parser = argparse.ArgumentParser(description='Start the Materials Commons server')
|
|
39
|
+
parser.add_argument('--ws-url', type=str, default=DEFAULT_WS_URL, help='WebSocket URL for commands')
|
|
40
|
+
args = parser.parse_args(argv)
|
|
41
|
+
|
|
42
|
+
config = Config()
|
|
43
|
+
if config.client_uuid is None:
|
|
44
|
+
config.client_uuid = str(uuid.uuid4())
|
|
45
|
+
config.save()
|
|
46
|
+
|
|
47
|
+
# Runs local REST server and remote command listener
|
|
48
|
+
async def main():
|
|
49
|
+
queue = asyncio.Queue()
|
|
50
|
+
running_loop = asyncio.get_running_loop()
|
|
51
|
+
local_rest_server = LocalRestServer(loop=running_loop, queue=queue)
|
|
52
|
+
local_rest_server.start()
|
|
53
|
+
|
|
54
|
+
listener = WebSocketCommandListener(args.ws_url, config.default_remote.mcapikey, config.client_uuid,
|
|
55
|
+
register_handlers(), queue)
|
|
56
|
+
try:
|
|
57
|
+
await listener.run()
|
|
58
|
+
finally:
|
|
59
|
+
await listener.shutdown()
|
|
60
|
+
local_rest_server.stop()
|
|
61
|
+
|
|
62
|
+
# Creates event loop; runs main; handles interrupts
|
|
63
|
+
try:
|
|
64
|
+
loop = asyncio.new_event_loop()
|
|
65
|
+
asyncio.set_event_loop(loop)
|
|
66
|
+
_install_signal_handlers(loop)
|
|
67
|
+
loop.run_until_complete(main())
|
|
68
|
+
except KeyboardInterrupt:
|
|
69
|
+
pass
|
|
70
|
+
finally:
|
|
71
|
+
try:
|
|
72
|
+
loop.run_until_complete(_graceful_stop(loop))
|
|
73
|
+
except Exception:
|
|
74
|
+
pass
|
|
75
|
+
loop.close()
|
{materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/subcommands/up.py
RENAMED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import argparse
|
|
2
|
+
import logging
|
|
3
|
+
import sys
|
|
2
4
|
|
|
3
5
|
import materials_commons.cli.exceptions as cliexcept
|
|
4
6
|
import materials_commons.cli.functions as clifuncs
|
|
5
7
|
import materials_commons.cli.globus as cliglobus
|
|
6
8
|
import materials_commons.cli.tree_functions as treefuncs
|
|
7
9
|
from materials_commons.cli.treedb import LocalTree, RemoteTree
|
|
10
|
+
from materials_commons.cli.subcommands.server import DEFAULT_WS_URL
|
|
11
|
+
from materials_commons.cli.desktop.uploader.api import ws_upload_synchronous
|
|
12
|
+
import os
|
|
13
|
+
from pathlib import Path
|
|
8
14
|
|
|
9
15
|
|
|
10
16
|
def make_parser():
|
|
@@ -14,11 +20,14 @@ def make_parser():
|
|
|
14
20
|
|
|
15
21
|
mc_up_usage = """
|
|
16
22
|
mc up [-r] [--no-compare] [--limit] <pathspec> [<pathspec> ...]
|
|
17
|
-
mc up -g [-r] [--no-compare] [--label] <pathspec> [<pathspec> ...]
|
|
23
|
+
mc up -g [-r] [--no-compare] [--label] <pathspec> [<pathspec> ...]
|
|
24
|
+
mc up --websocket [-r] <pathspec> [<pathspec> ...]"""
|
|
18
25
|
|
|
19
26
|
globus_help = """Use globus to upload files. Uses the current active upload or creates a new upload.
|
|
20
27
|
Use `globus task list` to monitor transfer tasks. Use `mc globus upload` to manage uploads."""
|
|
21
28
|
|
|
29
|
+
websocket_help = """Use websockets to upload files. Files are uploaded in parallel and progress is reported."""
|
|
30
|
+
|
|
22
31
|
parser = argparse.ArgumentParser(
|
|
23
32
|
description=mc_up_description,
|
|
24
33
|
usage=mc_up_usage,
|
|
@@ -30,24 +39,40 @@ def make_parser():
|
|
|
30
39
|
help='File size upload limit (MB). Default=750MB. Max size is also 750MB. Does not apply to Globus uploads.')
|
|
31
40
|
parser.add_argument('-g', '--globus', action="store_true", default=False,
|
|
32
41
|
help=globus_help)
|
|
42
|
+
parser.add_argument('--websocket', '--ws', action="store_true", default=False, help=websocket_help)
|
|
43
|
+
parser.add_argument('--ws-url', type=str, default=DEFAULT_WS_URL, help='WebSocket URL for commands')
|
|
33
44
|
parser.add_argument('--label', nargs=1, type=str,
|
|
34
45
|
help='Globus transfer label to make finding tasks simpler. Default is `<project name>-<upload name>.')
|
|
35
46
|
parser.add_argument('--no-compare', action="store_true", default=False,
|
|
36
47
|
help='Upload without checking if remote is equivalent.')
|
|
37
|
-
parser.add_argument('--upload-as', nargs=1, default=None,
|
|
48
|
+
parser.add_argument('--upload-as', nargs=1, default=None,
|
|
49
|
+
help='Upload to a different location than standard upload. Specified as if it were a local path.')
|
|
50
|
+
parser.add_argument('--chunk-size', type=int, default=1024 * 1024,
|
|
51
|
+
help='Chunk size for websocket uploads (default: 1MB)')
|
|
52
|
+
parser.add_argument('--max-concurrent', type=int, default=3,
|
|
53
|
+
help='Maximum concurrent uploads for websocket mode (default: 3)')
|
|
38
54
|
return parser
|
|
39
55
|
|
|
56
|
+
|
|
40
57
|
def up_subcommand(argv, working_dir):
|
|
41
58
|
"""
|
|
42
59
|
upload files to Materials Commons
|
|
43
60
|
|
|
44
61
|
mc up [-r] [--no-compare] [--limit] <pathspec> [<pathspec> ...]
|
|
45
62
|
mc up -g [-r] [--no-compare] [--label] <pathspec> [<pathspec> ...]
|
|
46
|
-
|
|
63
|
+
mc up --ws [-r] <pathspec> [<pathspec> ...]
|
|
47
64
|
"""
|
|
48
65
|
parser = make_parser()
|
|
49
66
|
args = parser.parse_args(argv)
|
|
50
67
|
|
|
68
|
+
showLogs = os.getenv("MC_SHOW_LOGS")
|
|
69
|
+
if showLogs == "true":
|
|
70
|
+
logging.basicConfig(
|
|
71
|
+
level=logging.INFO,
|
|
72
|
+
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
|
73
|
+
handlers=[logging.StreamHandler(sys.stdout)]
|
|
74
|
+
)
|
|
75
|
+
|
|
51
76
|
proj = clifuncs.make_local_project(working_dir)
|
|
52
77
|
|
|
53
78
|
pconfig = clifuncs.read_project_config(proj.local_path)
|
|
@@ -62,6 +87,12 @@ def up_subcommand(argv, working_dir):
|
|
|
62
87
|
if args.upload_as and args.globus:
|
|
63
88
|
print("--upload-as option is not supported with --globus")
|
|
64
89
|
raise cliexcept.MCCLIException("Invalid upload request")
|
|
90
|
+
if args.upload_as and args.websocket:
|
|
91
|
+
print("--upload-as option is not supported with --websocket")
|
|
92
|
+
raise cliexcept.MCCLIException("Invalid upload request")
|
|
93
|
+
if args.globus and args.websocket:
|
|
94
|
+
print("--globus option is not supported with --websocket")
|
|
95
|
+
raise cliexcept.MCCLIException("Invalid upload request")
|
|
65
96
|
|
|
66
97
|
upload_as = None
|
|
67
98
|
if args.upload_as:
|
|
@@ -69,7 +100,56 @@ def up_subcommand(argv, working_dir):
|
|
|
69
100
|
args.upload_as,
|
|
70
101
|
working_dir)[0]
|
|
71
102
|
|
|
72
|
-
if args.
|
|
103
|
+
if args.websocket:
|
|
104
|
+
# convert input paths (absolute or relative to working_dir) to local_abspath
|
|
105
|
+
local_abspaths = treefuncs.clipaths_to_local_abspaths(
|
|
106
|
+
proj.local_path, args.paths, working_dir)
|
|
107
|
+
|
|
108
|
+
# filter, skipping .mc, those specified by .mcignore
|
|
109
|
+
local_abspaths = treefuncs.filter_local_abspaths(
|
|
110
|
+
proj.local_path, local_abspaths, working_dir)
|
|
111
|
+
|
|
112
|
+
mcpaths = treefuncs.clipaths_to_mcpaths(proj.local_path, local_abspaths, working_dir)
|
|
113
|
+
|
|
114
|
+
file_paths = []
|
|
115
|
+
project_paths = []
|
|
116
|
+
|
|
117
|
+
for local_path, mc_path in zip(local_abspaths, mcpaths):
|
|
118
|
+
if treefuncs.os.path.isdir(local_path):
|
|
119
|
+
if args.recursive:
|
|
120
|
+
for root, dirs, files in os.walk(local_path):
|
|
121
|
+
for filename in files:
|
|
122
|
+
file_path = os.path.join(root, filename)
|
|
123
|
+
|
|
124
|
+
# Calculate relative path and construct mc_path
|
|
125
|
+
relative = Path(file_path).relative_to(local_path)
|
|
126
|
+
file_mc_path = str(Path(mc_path) / relative)
|
|
127
|
+
file_paths.append(file_path)
|
|
128
|
+
project_paths.append(file_mc_path)
|
|
129
|
+
else:
|
|
130
|
+
print("Skipping directory because --recursive option not specified: " + local_path)
|
|
131
|
+
else:
|
|
132
|
+
file_paths.append(local_path)
|
|
133
|
+
project_paths.append(mc_path)
|
|
134
|
+
if not file_paths:
|
|
135
|
+
print("No files to upload.")
|
|
136
|
+
return
|
|
137
|
+
|
|
138
|
+
status = ws_upload_synchronous(
|
|
139
|
+
file_paths=file_paths,
|
|
140
|
+
project_paths=project_paths,
|
|
141
|
+
project_id=proj.id,
|
|
142
|
+
chunk_size=args.chunk_size,
|
|
143
|
+
max_concurrent=args.max_concurrent,
|
|
144
|
+
ws_url=args.ws_url
|
|
145
|
+
)
|
|
146
|
+
if not status:
|
|
147
|
+
print("\nSome uploads failed.")
|
|
148
|
+
raise cliexcept.MCCLIException(
|
|
149
|
+
"Upload failed. Check server logs for details.")
|
|
150
|
+
|
|
151
|
+
print("\nAll uploads completed successfully!")
|
|
152
|
+
elif args.globus:
|
|
73
153
|
|
|
74
154
|
# convert input paths (absolute or relative to working_dir) to local_abspath
|
|
75
155
|
local_abspaths = treefuncs.clipaths_to_local_abspaths(
|
|
@@ -81,7 +161,7 @@ def up_subcommand(argv, working_dir):
|
|
|
81
161
|
|
|
82
162
|
mcpaths = treefuncs.clipaths_to_mcpaths(proj.local_path, local_abspaths, working_dir)
|
|
83
163
|
|
|
84
|
-
all_uploads = {upload.id:upload for upload in proj.remote.get_all_globus_upload_requests(proj.id)}
|
|
164
|
+
all_uploads = {upload.id: upload for upload in proj.remote.get_all_globus_upload_requests(proj.id)}
|
|
85
165
|
|
|
86
166
|
globus_upload_id = None
|
|
87
167
|
if pconfig.globus_upload_id:
|
|
@@ -99,8 +179,9 @@ def up_subcommand(argv, working_dir):
|
|
|
99
179
|
upload = all_uploads[globus_upload_id]
|
|
100
180
|
print("Using current globus upload (name=" + upload.name + ", id=" + str(upload.id) + ").")
|
|
101
181
|
|
|
102
|
-
if upload.status != 2:
|
|
103
|
-
raise cliexcept.MCCLIException(
|
|
182
|
+
if upload.status != 2: # TODO clean up status code / message
|
|
183
|
+
raise cliexcept.MCCLIException(
|
|
184
|
+
"Current Globus upload (id=" + str(globus_upload_id) + ") not ready for uploading.")
|
|
104
185
|
|
|
105
186
|
label = proj.name + "-" + upload.name
|
|
106
187
|
if args.label:
|
|
@@ -117,7 +198,7 @@ def up_subcommand(argv, working_dir):
|
|
|
117
198
|
print("Use `mc globus upload` to manage Globus uploads.")
|
|
118
199
|
print("Multiple transfer tasks may be initiated.")
|
|
119
200
|
print("When all tasks finish uploading, use `mc globus upload --id " + str(upload.id) +
|
|
120
|
-
|
|
201
|
+
" --finish` " + "to import all uploaded files into the Materials Commons project.")
|
|
121
202
|
|
|
122
203
|
else:
|
|
123
204
|
localtree = None
|
|
@@ -125,9 +206,9 @@ def up_subcommand(argv, working_dir):
|
|
|
125
206
|
localtree = LocalTree(proj.local_path)
|
|
126
207
|
|
|
127
208
|
treefuncs.standard_upload_v2(proj, args.paths, working_dir,
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
209
|
+
recursive=args.recursive, limit=args.limit[0],
|
|
210
|
+
no_compare=args.no_compare,
|
|
211
|
+
upload_as=upload_as, localtree=localtree,
|
|
212
|
+
remotetree=remotetree)
|
|
132
213
|
|
|
133
214
|
return
|
{materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/user_config.py
RENAMED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import getpass
|
|
2
|
+
import json
|
|
2
3
|
import os
|
|
3
|
-
import
|
|
4
|
-
import warnings
|
|
4
|
+
import re
|
|
5
5
|
from os.path import join
|
|
6
|
-
import json
|
|
7
6
|
|
|
7
|
+
import requests
|
|
8
8
|
from materials_commons.api.client import Client
|
|
9
9
|
|
|
10
10
|
|
|
@@ -94,7 +94,8 @@ class Config(object):
|
|
|
94
94
|
'mcurl': None,
|
|
95
95
|
'email': None,
|
|
96
96
|
'remotes': {},
|
|
97
|
-
'globus': {}
|
|
97
|
+
'globus': {},
|
|
98
|
+
'client_uuid': None,
|
|
98
99
|
}
|
|
99
100
|
|
|
100
101
|
# check for recognized environment variables
|
|
@@ -137,6 +138,7 @@ class Config(object):
|
|
|
137
138
|
|
|
138
139
|
self.developer_mode = config.get('developer_mode', False)
|
|
139
140
|
self.REST_logging = config.get('REST_logging', False)
|
|
141
|
+
self.client_uuid = config.get('client_uuid', None)
|
|
140
142
|
|
|
141
143
|
def save(self):
|
|
142
144
|
config = {
|
|
@@ -144,7 +146,8 @@ class Config(object):
|
|
|
144
146
|
'remotes': [vars(value) for value in self.remotes],
|
|
145
147
|
'globus': vars(self.globus),
|
|
146
148
|
'developer_mode': self.developer_mode,
|
|
147
|
-
'REST_logging': self.REST_logging
|
|
149
|
+
'REST_logging': self.REST_logging,
|
|
150
|
+
'client_uuid': self.client_uuid or '',
|
|
148
151
|
}
|
|
149
152
|
if not os.path.exists(self.config_file):
|
|
150
153
|
user = getpass.getuser()
|
|
@@ -32,6 +32,7 @@ materials_commons/cli/subcommands/mv.py
|
|
|
32
32
|
materials_commons/cli/subcommands/proj.py
|
|
33
33
|
materials_commons/cli/subcommands/remote.py
|
|
34
34
|
materials_commons/cli/subcommands/rm.py
|
|
35
|
+
materials_commons/cli/subcommands/server.py
|
|
35
36
|
materials_commons/cli/subcommands/up.py
|
|
36
37
|
materials_commons/cli/subcommands/versions.py
|
|
37
38
|
materials_commons_cli.egg-info/PKG-INFO
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '2.1.8'
|
|
File without changes
|
|
File without changes
|
{materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/LICENSE.txt
RENAMED
|
File without changes
|
{materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/cloned_project.py
RENAMED
|
File without changes
|
{materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/exceptions.py
RENAMED
|
File without changes
|
{materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/file_functions.py
RENAMED
|
File without changes
|
|
File without changes
|
{materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/list_objects.py
RENAMED
|
File without changes
|
{materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/print_formatter.py
RENAMED
|
File without changes
|
{materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/sqltable.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/subcommands/ls.py
RENAMED
|
File without changes
|
|
File without changes
|
{materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/subcommands/mv.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/subcommands/rm.py
RENAMED
|
File without changes
|
|
File without changes
|
{materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/tmp_functions.py
RENAMED
|
File without changes
|
{materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/materials_commons/cli/tree_functions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/test/test_treecompare_no_cache.py
RENAMED
|
File without changes
|
{materials_commons_cli-2.1.8 → materials_commons_cli-2.2.0}/test/test_treecompare_with_cache.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|