ciocore 5.1.1__py2.py3-none-any.whl → 10.0.0b3__py2.py3-none-any.whl
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.
- ciocore/VERSION +1 -1
- ciocore/__init__.py +23 -1
- ciocore/api_client.py +655 -160
- ciocore/auth/__init__.py +5 -3
- ciocore/cli.py +501 -0
- ciocore/common.py +15 -13
- ciocore/conductor_submit.py +77 -60
- ciocore/config.py +127 -13
- ciocore/data.py +162 -77
- ciocore/docsite/404.html +746 -0
- ciocore/docsite/apidoc/api_client/index.html +3605 -0
- ciocore/docsite/apidoc/apidoc/index.html +909 -0
- ciocore/docsite/apidoc/config/index.html +1652 -0
- ciocore/docsite/apidoc/data/index.html +1553 -0
- ciocore/docsite/apidoc/hardware_set/index.html +2460 -0
- ciocore/docsite/apidoc/package_environment/index.html +1507 -0
- ciocore/docsite/apidoc/package_tree/index.html +2386 -0
- ciocore/docsite/assets/_mkdocstrings.css +16 -0
- ciocore/docsite/assets/images/favicon.png +0 -0
- ciocore/docsite/assets/javascripts/bundle.471ce7a9.min.js +29 -0
- ciocore/docsite/assets/javascripts/bundle.471ce7a9.min.js.map +7 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.ar.min.js +1 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.da.min.js +18 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.de.min.js +18 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.du.min.js +18 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.el.min.js +1 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.es.min.js +18 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.fi.min.js +18 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.fr.min.js +18 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.he.min.js +1 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.hi.min.js +1 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.hu.min.js +18 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.hy.min.js +1 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.it.min.js +18 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.ja.min.js +1 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.jp.min.js +1 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.kn.min.js +1 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.ko.min.js +1 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.multi.min.js +1 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.nl.min.js +18 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.no.min.js +18 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.pt.min.js +18 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.ro.min.js +18 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.ru.min.js +18 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.sa.min.js +1 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.stemmer.support.min.js +1 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.sv.min.js +18 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.ta.min.js +1 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.te.min.js +1 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.th.min.js +1 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.tr.min.js +18 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.vi.min.js +1 -0
- ciocore/docsite/assets/javascripts/lunr/min/lunr.zh.min.js +1 -0
- ciocore/docsite/assets/javascripts/lunr/tinyseg.js +206 -0
- ciocore/docsite/assets/javascripts/lunr/wordcut.js +6708 -0
- ciocore/docsite/assets/javascripts/workers/search.b8dbb3d2.min.js +42 -0
- ciocore/docsite/assets/javascripts/workers/search.b8dbb3d2.min.js.map +7 -0
- ciocore/docsite/assets/stylesheets/main.3cba04c6.min.css +1 -0
- ciocore/docsite/assets/stylesheets/main.3cba04c6.min.css.map +1 -0
- ciocore/docsite/assets/stylesheets/palette.06af60db.min.css +1 -0
- ciocore/docsite/assets/stylesheets/palette.06af60db.min.css.map +1 -0
- ciocore/docsite/cmdline/docs/index.html +871 -0
- ciocore/docsite/cmdline/downloader/index.html +934 -0
- ciocore/docsite/cmdline/packages/index.html +878 -0
- ciocore/docsite/cmdline/uploader/index.html +995 -0
- ciocore/docsite/how-to-guides/index.html +869 -0
- ciocore/docsite/index.html +895 -0
- ciocore/docsite/logo.png +0 -0
- ciocore/docsite/objects.inv +0 -0
- ciocore/docsite/search/search_index.json +1 -0
- ciocore/docsite/sitemap.xml +3 -0
- ciocore/docsite/sitemap.xml.gz +0 -0
- ciocore/docsite/stylesheets/extra.css +26 -0
- ciocore/docsite/stylesheets/tables.css +167 -0
- ciocore/downloader/base_downloader.py +644 -0
- ciocore/downloader/download_runner_base.py +47 -0
- ciocore/downloader/job_downloader.py +119 -0
- ciocore/{downloader.py → downloader/legacy_downloader.py} +12 -9
- ciocore/downloader/log.py +73 -0
- ciocore/downloader/logging_download_runner.py +87 -0
- ciocore/downloader/perpetual_downloader.py +63 -0
- ciocore/downloader/registry.py +97 -0
- ciocore/downloader/reporter.py +135 -0
- ciocore/exceptions.py +8 -2
- ciocore/file_utils.py +51 -50
- ciocore/hardware_set.py +449 -0
- ciocore/loggeria.py +89 -20
- ciocore/package_environment.py +110 -48
- ciocore/package_query.py +182 -0
- ciocore/package_tree.py +319 -258
- ciocore/retry.py +0 -0
- ciocore/uploader/_uploader.py +547 -364
- ciocore/uploader/thread_queue_job.py +176 -0
- ciocore/uploader/upload_stats/__init__.py +3 -4
- ciocore/uploader/upload_stats/stats_formats.py +10 -4
- ciocore/validator.py +34 -2
- ciocore/worker.py +174 -151
- ciocore-10.0.0b3.dist-info/METADATA +928 -0
- ciocore-10.0.0b3.dist-info/RECORD +128 -0
- {ciocore-5.1.1.dist-info → ciocore-10.0.0b3.dist-info}/WHEEL +1 -1
- ciocore-10.0.0b3.dist-info/entry_points.txt +2 -0
- tests/instance_type_fixtures.py +175 -0
- tests/package_fixtures.py +205 -0
- tests/test_api_client.py +297 -12
- tests/test_base_downloader.py +104 -0
- tests/test_cli.py +149 -0
- tests/test_common.py +1 -7
- tests/test_config.py +40 -18
- tests/test_data.py +162 -173
- tests/test_downloader.py +118 -0
- tests/test_hardware_set.py +139 -0
- tests/test_job_downloader.py +213 -0
- tests/test_package_query.py +38 -0
- tests/test_package_tree.py +91 -291
- tests/test_submit.py +44 -18
- tests/test_uploader.py +1 -4
- ciocore/__about__.py +0 -10
- ciocore/cli/conductor.py +0 -191
- ciocore/compat.py +0 -15
- ciocore-5.1.1.data/scripts/conductor +0 -19
- ciocore-5.1.1.data/scripts/conductor.bat +0 -13
- ciocore-5.1.1.dist-info/METADATA +0 -408
- ciocore-5.1.1.dist-info/RECORD +0 -47
- tests/mocks/api_client_mock.py +0 -51
- /ciocore/{cli → downloader}/__init__.py +0 -0
- {ciocore-5.1.1.dist-info → ciocore-10.0.0b3.dist-info}/top_level.txt +0 -0
ciocore/file_utils.py
CHANGED
|
@@ -6,6 +6,7 @@ import glob
|
|
|
6
6
|
|
|
7
7
|
from ciocore import exceptions
|
|
8
8
|
from ciocore.common import CONDUCTOR_LOGGER_NAME
|
|
9
|
+
|
|
9
10
|
# Regular expressions for different path expressions that are supported
|
|
10
11
|
RX_HASH = r"#+" # image.####.exr
|
|
11
12
|
RX_MAPID = r"_MAPID_" # image_MAPID_.exr
|
|
@@ -41,14 +42,14 @@ logger = logging.getLogger(CONDUCTOR_LOGGER_NAME)
|
|
|
41
42
|
|
|
42
43
|
|
|
43
44
|
def separate_path(path, no_extension=False):
|
|
44
|
-
|
|
45
|
+
"""
|
|
45
46
|
Seperate the given path into three pieces:
|
|
46
47
|
|
|
47
48
|
1. The directory (if any)
|
|
48
49
|
2. The base filename (mandatory)
|
|
49
50
|
3. The file extension (if any)
|
|
50
51
|
|
|
51
|
-
For example, given this path: "/animals/fuzzy_cat.jpg"
|
|
52
|
+
For example, given this path: "/animals/fuzzy_cat.jpg"
|
|
52
53
|
return "/animals", "fuzzy_cat", ".jpg"
|
|
53
54
|
|
|
54
55
|
The path argument may be a full filepath (including the directory) or just the name of the file.
|
|
@@ -64,7 +65,7 @@ def separate_path(path, no_extension=False):
|
|
|
64
65
|
represent a frame number or an extension. There is no way to know for sure. By default, the
|
|
65
66
|
function will assume that the "10312" is an extension. Override this behavior by setting the
|
|
66
67
|
no_extensio arg to True.
|
|
67
|
-
|
|
68
|
+
"""
|
|
68
69
|
dirpath, filename = os.path.split(path)
|
|
69
70
|
|
|
70
71
|
if no_extension:
|
|
@@ -76,12 +77,12 @@ def separate_path(path, no_extension=False):
|
|
|
76
77
|
|
|
77
78
|
|
|
78
79
|
def process_dependencies(paths):
|
|
79
|
-
|
|
80
|
+
"""
|
|
80
81
|
For the given lists of dependency paths, return a dictionary where the keys are the depenency
|
|
81
82
|
filepaths and the values are paths, and the values are a a string, describing what is wrong with
|
|
82
83
|
the path (if anything). If the path is valid, the value will be None
|
|
83
84
|
|
|
84
|
-
|
|
85
|
+
"""
|
|
85
86
|
dependencies = {}
|
|
86
87
|
for path in paths:
|
|
87
88
|
|
|
@@ -96,10 +97,10 @@ def process_dependencies(paths):
|
|
|
96
97
|
|
|
97
98
|
|
|
98
99
|
def process_upload_filepaths(paths):
|
|
99
|
-
|
|
100
|
+
"""
|
|
100
101
|
Given the list of paths, process each one, ultimately returning a flattened
|
|
101
102
|
list of all processed paths
|
|
102
|
-
|
|
103
|
+
"""
|
|
103
104
|
processed_paths = []
|
|
104
105
|
for path in paths:
|
|
105
106
|
processed_paths.extend(process_upload_filepath(path))
|
|
@@ -108,10 +109,10 @@ def process_upload_filepaths(paths):
|
|
|
108
109
|
|
|
109
110
|
|
|
110
111
|
def process_upload_filepath(path, strict=True):
|
|
111
|
-
|
|
112
|
+
"""
|
|
112
113
|
Process the given path to ensure that the path is valid (exists on disk), and return any/all
|
|
113
|
-
files which the path may represent.
|
|
114
|
-
|
|
114
|
+
files which the path may represent.
|
|
115
|
+
|
|
115
116
|
For example, if the path is a directory or an image
|
|
116
117
|
sequence, then explicitly list and return all files that that path represents/contains.
|
|
117
118
|
|
|
@@ -121,10 +122,10 @@ def process_upload_filepath(path, strict=True):
|
|
|
121
122
|
directory, the
|
|
122
123
|
|
|
123
124
|
|
|
124
|
-
This function should be able to handle various types of paths:
|
|
125
|
-
|
|
126
|
-
1. Directory path
|
|
127
|
-
2. File path
|
|
125
|
+
This function should be able to handle various types of paths:
|
|
126
|
+
|
|
127
|
+
1. Directory path
|
|
128
|
+
2. File path
|
|
128
129
|
3. Image sequence path
|
|
129
130
|
|
|
130
131
|
Process the path by doing the following:
|
|
@@ -139,7 +140,7 @@ def process_upload_filepath(path, strict=True):
|
|
|
139
140
|
|
|
140
141
|
3. If the path is a file then ensure that it exists on disk and that it conforms to Conductor's
|
|
141
142
|
expectations.
|
|
142
|
-
|
|
143
|
+
"""
|
|
143
144
|
|
|
144
145
|
paths = []
|
|
145
146
|
|
|
@@ -207,7 +208,7 @@ def process_upload_filepath(path, strict=True):
|
|
|
207
208
|
|
|
208
209
|
|
|
209
210
|
def get_common_dirpath(paths):
|
|
210
|
-
|
|
211
|
+
"""
|
|
211
212
|
Find the common directory between all of the filepaths (essentially find the lowest common
|
|
212
213
|
denominator of all of the given paths). If thers is no common directory shared between the
|
|
213
214
|
paths, return None
|
|
@@ -224,7 +225,7 @@ def get_common_dirpath(paths):
|
|
|
224
225
|
directory.
|
|
225
226
|
|
|
226
227
|
|
|
227
|
-
|
|
228
|
+
"""
|
|
228
229
|
# Using os.path.commonprefix only gets us so far, as it merely matches as
|
|
229
230
|
# many characters as possible, but doesn't ensure those characters clearly end
|
|
230
231
|
# on a directory. For example, given these two paths
|
|
@@ -255,13 +256,13 @@ def get_common_dirpath(paths):
|
|
|
255
256
|
|
|
256
257
|
|
|
257
258
|
def _is_valid_path(path_str):
|
|
258
|
-
|
|
259
|
+
r"""
|
|
259
260
|
This is dirty/inaccurate helper function to determine whether the given "path" is considered
|
|
260
261
|
valid. If so, return True.
|
|
261
262
|
|
|
262
263
|
If the given path_str is any of the following characters, then it's to be considered invalid:
|
|
263
264
|
|
|
264
|
-
On linux
|
|
265
|
+
On linux/mac:
|
|
265
266
|
/
|
|
266
267
|
//
|
|
267
268
|
lettered drive (e.g. x:\)
|
|
@@ -271,25 +272,25 @@ def _is_valid_path(path_str):
|
|
|
271
272
|
\\
|
|
272
273
|
lettered drive (e.g. x:\)
|
|
273
274
|
|
|
274
|
-
|
|
275
|
+
"""
|
|
275
276
|
# This will handle / or // on linux/mac and \ and \\ on windows
|
|
276
|
-
if path_str in [os.sep, os.sep + os.sep]:
|
|
277
|
+
if path_str in [os.sep, os.sep + os.sep]:
|
|
277
278
|
return
|
|
278
279
|
|
|
279
280
|
# handle's lettered drives on Windows (e.g. g:\ )
|
|
280
|
-
if re.match(r"^[a-zA-Z]:\\$", path_str):
|
|
281
|
+
if re.match(r"^[a-zA-Z]:\\$", path_str):
|
|
281
282
|
return
|
|
282
283
|
|
|
283
284
|
return True
|
|
284
285
|
|
|
285
286
|
|
|
286
287
|
def get_files(dirpath, recurse=True):
|
|
287
|
-
|
|
288
|
+
"""
|
|
288
289
|
Return all files found in the given directory.
|
|
289
290
|
|
|
290
291
|
Optionally recurse the directory to also include files that are located in subdirectories as
|
|
291
292
|
well
|
|
292
|
-
|
|
293
|
+
"""
|
|
293
294
|
files = []
|
|
294
295
|
|
|
295
296
|
if not os.path.isdir(dirpath):
|
|
@@ -311,39 +312,39 @@ def get_files(dirpath, recurse=True):
|
|
|
311
312
|
|
|
312
313
|
|
|
313
314
|
def conform_platform_filepath(filepath):
|
|
314
|
-
|
|
315
|
+
"""
|
|
315
316
|
For the given path, ensure that the path conforms to the standards that Conductor expects. Each
|
|
316
317
|
platform may potentially have different rules that it follows in order to achieve this.
|
|
317
|
-
|
|
318
|
+
"""
|
|
318
319
|
platform = sys.platform
|
|
319
320
|
|
|
320
321
|
# If the platform is windows, then run specific Windows rules
|
|
321
|
-
if platform.startswith(
|
|
322
|
+
if platform.startswith("win"):
|
|
322
323
|
filepath = conform_win_path(filepath)
|
|
323
324
|
|
|
324
325
|
return filepath
|
|
325
326
|
|
|
326
327
|
|
|
327
328
|
def conform_win_path(filepath):
|
|
328
|
-
|
|
329
|
+
"""
|
|
329
330
|
For the given filepath, resolve any environment variables in the path and convert all backlashes
|
|
330
331
|
to forward slashes
|
|
331
|
-
|
|
332
|
+
"""
|
|
332
333
|
exp_file = os.path.abspath(os.path.expandvars(filepath))
|
|
333
|
-
return os.path.normpath(exp_file).replace(
|
|
334
|
+
return os.path.normpath(exp_file).replace("\\", "/")
|
|
334
335
|
|
|
335
336
|
|
|
336
337
|
def validate_path(filepath):
|
|
337
|
-
|
|
338
|
-
Validate that the given filepath:
|
|
338
|
+
"""
|
|
339
|
+
Validate that the given filepath:
|
|
339
340
|
|
|
340
|
-
1. Does not contain colons. This is docker path limitation
|
|
341
|
+
1. Does not contain colons. This is docker path limitation
|
|
341
342
|
2. Starts with a "/". Otherwise the path cannot be mounted in a linux filesystem
|
|
342
343
|
|
|
343
344
|
If the filepath is valid, return None. Otherwise return a message that describes why the
|
|
344
345
|
filepath is invalid
|
|
345
346
|
|
|
346
|
-
|
|
347
|
+
"""
|
|
347
348
|
# Strip the lettered drive portion of the filepath (if there is one).
|
|
348
349
|
# This is only going to affect a path with a lettered drive on Windows filesystem
|
|
349
350
|
filepath = os.path.splitdrive(filepath)[-1]
|
|
@@ -360,14 +361,14 @@ def validate_path(filepath):
|
|
|
360
361
|
|
|
361
362
|
|
|
362
363
|
def quote_path(filepath):
|
|
363
|
-
|
|
364
|
+
"""
|
|
364
365
|
Wrap the given filepath in double quotes and escape its content.
|
|
365
|
-
|
|
366
|
+
"""
|
|
366
367
|
return '"%s"' % filepath.replace('"', '\\"')
|
|
367
368
|
|
|
368
369
|
|
|
369
370
|
def get_files_from_path_expression(path_expression):
|
|
370
|
-
|
|
371
|
+
"""
|
|
371
372
|
Given a path expression (such as an image sequence path), seek out all files that are part of
|
|
372
373
|
that path expression (e.g all of the files that are part of that image sequence) and return a
|
|
373
374
|
list of their explicit paths. This function relies on what is actually on disk, so only files
|
|
@@ -388,7 +389,7 @@ def get_files_from_path_expression(path_expression):
|
|
|
388
389
|
/data/shot-###/image.####.exr
|
|
389
390
|
/data/shot-###/image.%04d.exr
|
|
390
391
|
/data/shot-###/camera-$F/image.%04d.exr
|
|
391
|
-
|
|
392
|
+
"""
|
|
392
393
|
|
|
393
394
|
logger.debug("Evaluating path expression: %s", path_expression)
|
|
394
395
|
# Cycle through all regexes and replace each match with a * so that we can glob file system.
|
|
@@ -405,10 +406,10 @@ def get_files_from_path_expression(path_expression):
|
|
|
405
406
|
|
|
406
407
|
|
|
407
408
|
def get_rx_matches(path_expression, expressions, limit=0):
|
|
408
|
-
|
|
409
|
+
"""
|
|
409
410
|
Loop through the given list of expressions (regexes), and return those that match the given
|
|
410
411
|
path_expression. If a limit is provided, return the first n expressions that match.
|
|
411
|
-
|
|
412
|
+
"""
|
|
412
413
|
matches = []
|
|
413
414
|
for rx in expressions:
|
|
414
415
|
if re.findall(rx, path_expression, flags=re.I):
|
|
@@ -419,12 +420,12 @@ def get_rx_matches(path_expression, expressions, limit=0):
|
|
|
419
420
|
|
|
420
421
|
|
|
421
422
|
def create_file(filepath):
|
|
422
|
-
|
|
423
|
+
"""
|
|
423
424
|
Create an empty file with the given permissions (octal)
|
|
424
|
-
|
|
425
|
+
"""
|
|
425
426
|
umask_original = os.umask(0)
|
|
426
427
|
try:
|
|
427
|
-
handle = os.fdopen(os.open(filepath, os.O_WRONLY | os.O_CREAT, 0o666),
|
|
428
|
+
handle = os.fdopen(os.open(filepath, os.O_WRONLY | os.O_CREAT, 0o666), "w")
|
|
428
429
|
finally:
|
|
429
430
|
os.umask(umask_original)
|
|
430
431
|
handle.write("")
|
|
@@ -432,18 +433,18 @@ def create_file(filepath):
|
|
|
432
433
|
|
|
433
434
|
|
|
434
435
|
def get_tx_paths(filepaths, existing_only=False):
|
|
435
|
-
|
|
436
|
+
"""
|
|
436
437
|
Return the tx filepaths for the given filepaths
|
|
437
|
-
|
|
438
|
+
"""
|
|
438
439
|
return [get_tx_path(path, existing_only=existing_only) for path in filepaths]
|
|
439
440
|
|
|
440
441
|
|
|
441
442
|
def get_tx_path(filepath, existing_only=False):
|
|
442
|
-
|
|
443
|
+
"""
|
|
443
444
|
For the given filepath, construct a parallel *.tx filepath residing in the same directory (same
|
|
444
445
|
name, different extension). If existing_only is True, only return the tx filepath if it exists
|
|
445
446
|
on disk, otherwise return an empty string.
|
|
446
|
-
|
|
447
|
+
"""
|
|
447
448
|
filepath_base, _ = os.path.splitext(filepath)
|
|
448
449
|
tx_filepath = filepath_base + ".tx"
|
|
449
450
|
if existing_only and not os.path.isfile(tx_filepath):
|
|
@@ -452,7 +453,7 @@ def get_tx_path(filepath, existing_only=False):
|
|
|
452
453
|
|
|
453
454
|
|
|
454
455
|
def strip_drive_letter(filepath):
|
|
455
|
-
|
|
456
|
+
r"""
|
|
456
457
|
If the given filepath has a drive letter, remove it and return the rest of the path
|
|
457
458
|
|
|
458
459
|
C:\cat.txt --> \cat.txt
|
|
@@ -467,6 +468,6 @@ def strip_drive_letter(filepath):
|
|
|
467
468
|
|
|
468
469
|
Note that os.path.splitdrive should not be used (anymore), due to a change in behavior that was
|
|
469
470
|
implemented somewhere between python 2.7.6 vs 2.7.11
|
|
470
|
-
|
|
471
|
-
rx_drive = r
|
|
471
|
+
"""
|
|
472
|
+
rx_drive = r"^[a-z]:"
|
|
472
473
|
return re.sub(rx_drive, "", filepath, flags=re.I)
|