opencue-pycue 1.11.66__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.
- opencue_pycue-1.11.66/.gitignore +3 -0
- opencue_pycue-1.11.66/Dockerfile +23 -0
- opencue_pycue-1.11.66/FileSequence/FileSequence.py +136 -0
- opencue_pycue-1.11.66/FileSequence/FrameRange.py +188 -0
- opencue_pycue-1.11.66/FileSequence/FrameSet.py +88 -0
- opencue_pycue-1.11.66/FileSequence/__init__.py +26 -0
- opencue_pycue-1.11.66/PKG-INFO +11 -0
- opencue_pycue-1.11.66/README.md +6 -0
- opencue_pycue-1.11.66/opencue/__init__.py +45 -0
- opencue_pycue-1.11.66/opencue/api.py +809 -0
- opencue_pycue-1.11.66/opencue/config.py +96 -0
- opencue_pycue-1.11.66/opencue/cuebot.py +391 -0
- opencue_pycue-1.11.66/opencue/default.yaml +24 -0
- opencue_pycue-1.11.66/opencue/exception.py +77 -0
- opencue_pycue-1.11.66/opencue/search.py +404 -0
- opencue_pycue-1.11.66/opencue/util.py +134 -0
- opencue_pycue-1.11.66/opencue/version.py +20 -0
- opencue_pycue-1.11.66/opencue/wrappers/__init__.py +13 -0
- opencue_pycue-1.11.66/opencue/wrappers/allocation.py +232 -0
- opencue_pycue-1.11.66/opencue/wrappers/comment.py +83 -0
- opencue_pycue-1.11.66/opencue/wrappers/deed.py +85 -0
- opencue_pycue-1.11.66/opencue/wrappers/depend.py +164 -0
- opencue_pycue-1.11.66/opencue/wrappers/filter.py +550 -0
- opencue_pycue-1.11.66/opencue/wrappers/frame.py +394 -0
- opencue_pycue-1.11.66/opencue/wrappers/group.py +373 -0
- opencue_pycue-1.11.66/opencue/wrappers/host.py +648 -0
- opencue_pycue-1.11.66/opencue/wrappers/job.py +1111 -0
- opencue_pycue-1.11.66/opencue/wrappers/layer.py +600 -0
- opencue_pycue-1.11.66/opencue/wrappers/limit.py +125 -0
- opencue_pycue-1.11.66/opencue/wrappers/owner.py +110 -0
- opencue_pycue-1.11.66/opencue/wrappers/proc.py +225 -0
- opencue_pycue-1.11.66/opencue/wrappers/render_partition.py +42 -0
- opencue_pycue-1.11.66/opencue/wrappers/service.py +286 -0
- opencue_pycue-1.11.66/opencue/wrappers/show.py +372 -0
- opencue_pycue-1.11.66/opencue/wrappers/subscription.py +146 -0
- opencue_pycue-1.11.66/opencue/wrappers/task.py +48 -0
- opencue_pycue-1.11.66/opencue/wrappers/util.py +122 -0
- opencue_pycue-1.11.66/pyproject.toml +38 -0
- opencue_pycue-1.11.66/tests/__init__.py +13 -0
- opencue_pycue-1.11.66/tests/api_test.py +874 -0
- opencue_pycue-1.11.66/tests/config_test.py +145 -0
- opencue_pycue-1.11.66/tests/cuebot_test.py +76 -0
- opencue_pycue-1.11.66/tests/file_sequence_test.py +303 -0
- opencue_pycue-1.11.66/tests/search_test.py +88 -0
- opencue_pycue-1.11.66/tests/test_suite.py +27 -0
- opencue_pycue-1.11.66/tests/util_test.py +173 -0
- opencue_pycue-1.11.66/tests/wrappers/__init__.py +13 -0
- opencue_pycue-1.11.66/tests/wrappers/allocation_test.py +144 -0
- opencue_pycue-1.11.66/tests/wrappers/comment_test.py +62 -0
- opencue_pycue-1.11.66/tests/wrappers/deed_test.py +77 -0
- opencue_pycue-1.11.66/tests/wrappers/depend_test.py +98 -0
- opencue_pycue-1.11.66/tests/wrappers/filter_test.py +524 -0
- opencue_pycue-1.11.66/tests/wrappers/frame_test.py +291 -0
- opencue_pycue-1.11.66/tests/wrappers/group_test.py +281 -0
- opencue_pycue-1.11.66/tests/wrappers/host_test.py +301 -0
- opencue_pycue-1.11.66/tests/wrappers/job_test.py +564 -0
- opencue_pycue-1.11.66/tests/wrappers/layer_test.py +426 -0
- opencue_pycue-1.11.66/tests/wrappers/limit_test.py +121 -0
- opencue_pycue-1.11.66/tests/wrappers/owner_test.py +124 -0
- opencue_pycue-1.11.66/tests/wrappers/proc_test.py +146 -0
- opencue_pycue-1.11.66/tests/wrappers/service_test.py +153 -0
- opencue_pycue-1.11.66/tests/wrappers/show_test.py +335 -0
- opencue_pycue-1.11.66/tests/wrappers/subscription_test.py +110 -0
- opencue_pycue-1.11.66/tests/wrappers/task_test.py +62 -0
- opencue_pycue-1.11.66/tests/wrappers/util_test.py +139 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
FROM python:3.9
|
|
2
|
+
|
|
3
|
+
WORKDIR /opt/opencue
|
|
4
|
+
|
|
5
|
+
# Paths to the pre-built python packages.
|
|
6
|
+
# They are all defined her but no necessary used to make it simpler between the images
|
|
7
|
+
ARG OPENCUE_PROTO_PACKAGE_PATH=/tmp/invalidpath
|
|
8
|
+
ARG OPENCUE_RQD_PACKAGE_PATH=/tmp/invalidpath
|
|
9
|
+
ARG OPENCUE_PYCUE_PACKAGE_PATH=/tmp/invalidpath
|
|
10
|
+
ARG OPENCUE_PYOUTLINE_PACKAGE_PATH=/tmp/invalidpath
|
|
11
|
+
ARG OPENCUE_CUESUBMIT_PACKAGE_PATH=/tmp/invalidpath
|
|
12
|
+
ARG OPENCUE_CUEGUI_PACKAGE_PATH=/tmp/invalidpath
|
|
13
|
+
ARG OPENCUE_CUEADMIN_PACKAGE_PATH=/tmp/invalidpath
|
|
14
|
+
|
|
15
|
+
RUN python3 -m pip install --upgrade pip
|
|
16
|
+
|
|
17
|
+
COPY LICENSE ./
|
|
18
|
+
|
|
19
|
+
RUN mkdir /tmp/packages
|
|
20
|
+
COPY ${OPENCUE_PROTO_PACKAGE_PATH} /tmp/packages/
|
|
21
|
+
COPY ${OPENCUE_PYCUE_PACKAGE_PATH} /tmp/packages/
|
|
22
|
+
|
|
23
|
+
RUN python3 -m pip install /tmp/packages/*.whl
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Copyright Contributors to the OpenCue Project
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
Helper class for representing a frame seqeunce path.
|
|
17
|
+
|
|
18
|
+
It supports a complex syntax implementing features such as comma-separated frame ranges,
|
|
19
|
+
stepped frame ranges and more. See the FileSequence class for more detail.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
import re
|
|
23
|
+
from .FrameSet import FrameSet
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class FileSequence:
|
|
27
|
+
"""Represents a file path to a frame sequence"""
|
|
28
|
+
__filepath = None
|
|
29
|
+
frameSet = None
|
|
30
|
+
__basename = None
|
|
31
|
+
__prefix = None
|
|
32
|
+
__suffix = None
|
|
33
|
+
__dirname = ""
|
|
34
|
+
__padSize = 1
|
|
35
|
+
__iter_index = 0
|
|
36
|
+
|
|
37
|
+
def __init__(self, filepath):
|
|
38
|
+
"""
|
|
39
|
+
Construct a FileSequence object by parsing a filepath.
|
|
40
|
+
Details on how to specify a frame range can be seen in the FrameRange class
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
filePathMatch = re.match(r"^(?P<pf>.*\.)(?P<fspec>[\d#,\-@x]+)(?P<sf>\.[.\w]+)$", filepath)
|
|
44
|
+
if filePathMatch is not None:
|
|
45
|
+
self.__filepath = filepath
|
|
46
|
+
self.__prefix = filePathMatch.group('pf')
|
|
47
|
+
self.__suffix = filePathMatch.group('sf')
|
|
48
|
+
dirmatch = re.match(r"^(?P<dirname>.*/)(?P<basename>.*)$", self.__prefix)
|
|
49
|
+
if dirmatch is not None:
|
|
50
|
+
self.__dirname = dirmatch.group("dirname")
|
|
51
|
+
self.__basename = dirmatch.group("basename")
|
|
52
|
+
else:
|
|
53
|
+
self.__basename = self.__prefix
|
|
54
|
+
framerangematch = re.match(r"^([\d\-x,]+)", filePathMatch.group("fspec"))
|
|
55
|
+
if framerangematch is not None:
|
|
56
|
+
self.frameSet = FrameSet(framerangematch.group(1))
|
|
57
|
+
if self.frameSet.get(0) > self.frameSet.get(-1):
|
|
58
|
+
raise ValueError('invalid filesequence range : ' + framerangematch.group(1))
|
|
59
|
+
firstFrameMatch = re.findall(r"^[-0]\d+", framerangematch.group(1))
|
|
60
|
+
if len(firstFrameMatch) > 0:
|
|
61
|
+
self.__padSize = len(firstFrameMatch[0])
|
|
62
|
+
|
|
63
|
+
padmatch = re.findall(r"#+$", filePathMatch.group("fspec"))
|
|
64
|
+
if len(padmatch) > 0:
|
|
65
|
+
self.__padSize = len(padmatch[0])
|
|
66
|
+
else:
|
|
67
|
+
raise ValueError('invalid filesequence path : ' + filepath)
|
|
68
|
+
|
|
69
|
+
def getPrefix(self):
|
|
70
|
+
"""Returns the prefix of the file sequence"""
|
|
71
|
+
return self.__prefix
|
|
72
|
+
|
|
73
|
+
def getSuffix(self):
|
|
74
|
+
"""Returns the suffix of the file sequence"""
|
|
75
|
+
return self.__suffix
|
|
76
|
+
|
|
77
|
+
def getDirname(self):
|
|
78
|
+
"""Returns the dirname of the file sequence, if given otherwise returns empty an string"""
|
|
79
|
+
return self.__dirname
|
|
80
|
+
|
|
81
|
+
def getBasename(self):
|
|
82
|
+
"""Returns the base name of the file sequence"""
|
|
83
|
+
return self.__basename.rstrip(".")
|
|
84
|
+
|
|
85
|
+
def getPadSize(self):
|
|
86
|
+
"""Returns the size of the frame padding. It defaults to 1 if none is detected"""
|
|
87
|
+
return self.__padSize
|
|
88
|
+
|
|
89
|
+
def getFileList(self, frameSet=None):
|
|
90
|
+
""" Returns the file list of the sequence """
|
|
91
|
+
filelist = []
|
|
92
|
+
paddingString = "%%0%dd" % self.getPadSize()
|
|
93
|
+
if self.frameSet:
|
|
94
|
+
for frame in self.frameSet.getAll():
|
|
95
|
+
if (frameSet is None or
|
|
96
|
+
(isinstance(frameSet, FrameSet) and frame in frameSet.getAll())):
|
|
97
|
+
framepath = self.getPrefix() + paddingString % frame + self.getSuffix()
|
|
98
|
+
filelist.append(framepath)
|
|
99
|
+
else:
|
|
100
|
+
for frame in frameSet.getAll():
|
|
101
|
+
framepath = self.getPrefix() + paddingString % frame + self.getSuffix()
|
|
102
|
+
filelist.append(framepath)
|
|
103
|
+
return filelist
|
|
104
|
+
|
|
105
|
+
def getOpenRVPath(self, frameSet=None):
|
|
106
|
+
""" Returns a string specific for the OpenRV player"""
|
|
107
|
+
frameRange = ""
|
|
108
|
+
curFrameSet = frameSet or self.frameSet
|
|
109
|
+
if isinstance(curFrameSet, FrameSet):
|
|
110
|
+
frameRange = "%d-%d" % (curFrameSet.get(0), curFrameSet.get(-1))
|
|
111
|
+
framepath = self.getPrefix() + frameRange + "@"*self.__padSize + self.getSuffix()
|
|
112
|
+
return framepath
|
|
113
|
+
|
|
114
|
+
def __getitem__(self, index):
|
|
115
|
+
return self.getFileList()[index]
|
|
116
|
+
|
|
117
|
+
def __next__(self):
|
|
118
|
+
self.__iter_index += 1
|
|
119
|
+
if self.__iter_index <= len(self):
|
|
120
|
+
return self.getFileList()[self.__iter_index - 1]
|
|
121
|
+
raise StopIteration
|
|
122
|
+
|
|
123
|
+
def __iter__(self):
|
|
124
|
+
self.__iter_index = 0
|
|
125
|
+
return self
|
|
126
|
+
|
|
127
|
+
def __len__(self):
|
|
128
|
+
return len(self.getFileList())
|
|
129
|
+
|
|
130
|
+
def __call__(self, frame):
|
|
131
|
+
paddingString = "%%0%dd" % self.getPadSize()
|
|
132
|
+
framepath = self.getPrefix() + paddingString % frame + self.getSuffix()
|
|
133
|
+
return framepath
|
|
134
|
+
|
|
135
|
+
def __str__(self):
|
|
136
|
+
return self.__filepath
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# Copyright Contributors to the OpenCue Project
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
Helper class for representing a frame range.
|
|
17
|
+
|
|
18
|
+
It supports a complex syntax implementing features such as comma-separated frame ranges,
|
|
19
|
+
stepped frame ranges and more. See the FrameRange class for more detail.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from __future__ import division
|
|
23
|
+
from __future__ import print_function
|
|
24
|
+
from __future__ import absolute_import
|
|
25
|
+
|
|
26
|
+
from builtins import str
|
|
27
|
+
from builtins import range
|
|
28
|
+
from builtins import object
|
|
29
|
+
import re
|
|
30
|
+
from collections import OrderedDict
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class FrameRange(object):
|
|
34
|
+
"""Represents a sequence of frame numbers."""
|
|
35
|
+
|
|
36
|
+
SINGLE_FRAME_PATTERN = re.compile(r'^(-?)\d+$')
|
|
37
|
+
SIMPLE_FRAME_RANGE_PATTERN = re.compile(r'^(?P<sf>(-?)\d+)-(?P<ef>(-?)\d+)$')
|
|
38
|
+
STEP_PATTERN = re.compile(
|
|
39
|
+
r'^(?P<sf>(-?)\d+)-(?P<ef>(-?)\d+)(?P<stepSep>[xy])(?P<step>(-?)\d+)$')
|
|
40
|
+
INTERLEAVE_PATTERN = re.compile(r'^(?P<sf>(-?)\d+)-(?P<ef>(-?)\d+):(?P<step>(-?)\d+)$')
|
|
41
|
+
|
|
42
|
+
def __init__(self, frameRange):
|
|
43
|
+
"""
|
|
44
|
+
Construct a FrameRange object by parsing a spec.
|
|
45
|
+
|
|
46
|
+
FrameSet("1-10x3");
|
|
47
|
+
FrameSet("1-10y3"); // inverted step
|
|
48
|
+
FrameSet("10-1x-1");
|
|
49
|
+
FrameSet("1"); // same as "1-1x1"
|
|
50
|
+
FrameSet("1-10:5"); // interleave of 5
|
|
51
|
+
|
|
52
|
+
A valid spec consists of:
|
|
53
|
+
|
|
54
|
+
An inTime.
|
|
55
|
+
An optional hyphen and outTime.
|
|
56
|
+
An optional x or y and stepSize.
|
|
57
|
+
Or an optional : and interleaveSize.
|
|
58
|
+
If outTime is less than inTime, stepSize must be negative.
|
|
59
|
+
|
|
60
|
+
A stepSize of 0 produces an empty FrameRange.
|
|
61
|
+
|
|
62
|
+
A stepSize cannot be combined with a interleaveSize.
|
|
63
|
+
|
|
64
|
+
A stepSize designated with y creates an inverted step. Frames that would be included
|
|
65
|
+
with an x step are excluded.
|
|
66
|
+
|
|
67
|
+
Example: 1-10y3 == 2, 3, 5, 6, 8, 9.
|
|
68
|
+
|
|
69
|
+
An interleaveSize alters the order of frames when iterating over the FrameRange. The
|
|
70
|
+
iterator will first produce the list of frames from inTime to outTime with a stepSize
|
|
71
|
+
equal to interleaveSize. The interleaveSize is then divided in half, producing another
|
|
72
|
+
set of frames unique from the first set. This process is repeated until interleaveSize
|
|
73
|
+
reaches 1.
|
|
74
|
+
|
|
75
|
+
Example: 1-10:5 == 1, 6, 2, 4, 8, 10, 3, 5, 7, 9.
|
|
76
|
+
"""
|
|
77
|
+
self.frameList = self.parseFrameRange(frameRange)
|
|
78
|
+
|
|
79
|
+
def __str__(self):
|
|
80
|
+
# TODO(bcipriano) Make this smarter, group frame ranges and by step. (Issue #83)
|
|
81
|
+
return ','.join([str(frame) for frame in self.frameList])
|
|
82
|
+
|
|
83
|
+
def __getitem__(self, key):
|
|
84
|
+
return self.frameList[key]
|
|
85
|
+
|
|
86
|
+
def __len__(self):
|
|
87
|
+
return self.size()
|
|
88
|
+
|
|
89
|
+
def size(self):
|
|
90
|
+
"""Gets the number of frames contained in this sequence."""
|
|
91
|
+
return len(self.frameList)
|
|
92
|
+
|
|
93
|
+
def get(self, idx):
|
|
94
|
+
"""Gets an individual entry in the sequence, by numerical position."""
|
|
95
|
+
return self.frameList[idx]
|
|
96
|
+
|
|
97
|
+
def index(self, idx):
|
|
98
|
+
"""Query index of frame number in frame set.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
int, index of frame. -1 if frame set does not contain frame.
|
|
102
|
+
"""
|
|
103
|
+
try:
|
|
104
|
+
return self.frameList.index(idx)
|
|
105
|
+
except ValueError:
|
|
106
|
+
return -1
|
|
107
|
+
|
|
108
|
+
def getAll(self):
|
|
109
|
+
"""Gets the full numerical sequence."""
|
|
110
|
+
return self.frameList
|
|
111
|
+
|
|
112
|
+
def normalize(self):
|
|
113
|
+
"""Sorts and deduplicates the sequence."""
|
|
114
|
+
self.frameList = list(set(self.frameList))
|
|
115
|
+
self.frameList.sort()
|
|
116
|
+
|
|
117
|
+
@classmethod
|
|
118
|
+
def parseFrameRange(cls, frameRange):
|
|
119
|
+
"""
|
|
120
|
+
Parse a string representation into a numerical sequence.
|
|
121
|
+
|
|
122
|
+
:type frameRange: str
|
|
123
|
+
:param frameRange: String representation of the frame range.
|
|
124
|
+
:rtype: FrameRange
|
|
125
|
+
:return: FrameRange representing the numerical sequence.
|
|
126
|
+
"""
|
|
127
|
+
singleFrameMatcher = re.match(cls.SINGLE_FRAME_PATTERN, frameRange)
|
|
128
|
+
if singleFrameMatcher:
|
|
129
|
+
return [int(frameRange)]
|
|
130
|
+
|
|
131
|
+
simpleRangeMatcher = re.match(cls.SIMPLE_FRAME_RANGE_PATTERN, frameRange)
|
|
132
|
+
if simpleRangeMatcher:
|
|
133
|
+
startFrame = int(simpleRangeMatcher.group('sf'))
|
|
134
|
+
endFrame = int(simpleRangeMatcher.group('ef'))
|
|
135
|
+
return cls.__getIntRange(startFrame, endFrame, (1 if endFrame >= startFrame else -1))
|
|
136
|
+
|
|
137
|
+
rangeWithStepMatcher = re.match(cls.STEP_PATTERN, frameRange)
|
|
138
|
+
if rangeWithStepMatcher:
|
|
139
|
+
startFrame = int(rangeWithStepMatcher.group('sf'))
|
|
140
|
+
endFrame = int(rangeWithStepMatcher.group('ef'))
|
|
141
|
+
step = int(rangeWithStepMatcher.group('step'))
|
|
142
|
+
stepSep = rangeWithStepMatcher.group('stepSep')
|
|
143
|
+
return cls.__getSteppedRange(startFrame, endFrame, step, stepSep == 'y')
|
|
144
|
+
|
|
145
|
+
rangeWithInterleaveMatcher = re.match(cls.INTERLEAVE_PATTERN, frameRange)
|
|
146
|
+
if rangeWithInterleaveMatcher:
|
|
147
|
+
startFrame = int(rangeWithInterleaveMatcher.group('sf'))
|
|
148
|
+
endFrame = int(rangeWithInterleaveMatcher.group('ef'))
|
|
149
|
+
step = int(rangeWithInterleaveMatcher.group('step'))
|
|
150
|
+
return cls.__getInterleavedRange(startFrame, endFrame, step)
|
|
151
|
+
|
|
152
|
+
raise ValueError('unrecognized frame range syntax ' + frameRange)
|
|
153
|
+
|
|
154
|
+
@staticmethod
|
|
155
|
+
def __getIntRange(start, end, step):
|
|
156
|
+
return list(range(start, end+(step // abs(step)), step))
|
|
157
|
+
|
|
158
|
+
@classmethod
|
|
159
|
+
def __getSteppedRange(cls, start, end, step, inverseStep):
|
|
160
|
+
cls.__validateStepSign(start, end, step)
|
|
161
|
+
steppedRange = cls.__getIntRange(start, end, step)
|
|
162
|
+
if inverseStep:
|
|
163
|
+
fullRange = cls.__getIntRange(start, end, (-1 if step < 0 else 1))
|
|
164
|
+
return [frame for frame in fullRange if frame not in steppedRange]
|
|
165
|
+
return steppedRange
|
|
166
|
+
|
|
167
|
+
@classmethod
|
|
168
|
+
def __getInterleavedRange(cls, start, end, step):
|
|
169
|
+
cls.__validateStepSign(start, end, step)
|
|
170
|
+
interleavedFrames = OrderedDict()
|
|
171
|
+
incrValue = step // abs(step)
|
|
172
|
+
while abs(step) > 0:
|
|
173
|
+
interleavedFrames.update(
|
|
174
|
+
[(frame, None) for frame in cls.__getIntRange(start, end, step)])
|
|
175
|
+
start += incrValue
|
|
176
|
+
step = int(step / 2.0)
|
|
177
|
+
return list(interleavedFrames.keys())
|
|
178
|
+
|
|
179
|
+
@staticmethod
|
|
180
|
+
def __validateStepSign(start, end, step):
|
|
181
|
+
if step > 1 and end < start:
|
|
182
|
+
raise ValueError(
|
|
183
|
+
'end frame may not be less than start frame when using a positive step')
|
|
184
|
+
if step == 0:
|
|
185
|
+
raise ValueError('step cannot be zero')
|
|
186
|
+
if step < 0 and end >= start:
|
|
187
|
+
raise ValueError(
|
|
188
|
+
'end frame may not be greater than start frame when using a negative step')
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Copyright Contributors to the OpenCue Project
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""Module for `FileSequence.FrameSet`."""
|
|
16
|
+
|
|
17
|
+
from __future__ import absolute_import
|
|
18
|
+
from __future__ import print_function
|
|
19
|
+
from __future__ import division
|
|
20
|
+
|
|
21
|
+
from builtins import str
|
|
22
|
+
from builtins import object
|
|
23
|
+
from .FrameRange import FrameRange
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class FrameSet(object):
|
|
27
|
+
"""Represents a sequence of `FileSequence.FrameRange`."""
|
|
28
|
+
|
|
29
|
+
def __init__(self, frameRange):
|
|
30
|
+
"""Construct a FrameSet object by parsing a spec.
|
|
31
|
+
|
|
32
|
+
See FrameRange for the supported syntax. A FrameSet follows the same syntax,
|
|
33
|
+
with the addition that it may be a comma-separated list of different FrameRanges.
|
|
34
|
+
"""
|
|
35
|
+
self.frameList = self.parseFrameRange(frameRange)
|
|
36
|
+
|
|
37
|
+
def __str__(self):
|
|
38
|
+
# TODO(bcipriano) Make this smarter, group frame ranges and by step. (Issue #83)
|
|
39
|
+
return ','.join([str(frame) for frame in self.frameList])
|
|
40
|
+
|
|
41
|
+
def __getitem__(self, key):
|
|
42
|
+
return self.frameList[key]
|
|
43
|
+
|
|
44
|
+
def __len__(self):
|
|
45
|
+
return self.size()
|
|
46
|
+
|
|
47
|
+
def size(self):
|
|
48
|
+
"""Gets the number of frames contained in this sequence."""
|
|
49
|
+
return len(self.frameList)
|
|
50
|
+
|
|
51
|
+
def get(self, idx):
|
|
52
|
+
"""Gets an individual entry in the sequence, by numerical position."""
|
|
53
|
+
return self.frameList[idx]
|
|
54
|
+
|
|
55
|
+
def index(self, idx):
|
|
56
|
+
"""Query index of frame number in frame set.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
int, index of frame. -1 if frame set does not contain frame.
|
|
60
|
+
"""
|
|
61
|
+
try:
|
|
62
|
+
return self.frameList.index(idx)
|
|
63
|
+
except ValueError:
|
|
64
|
+
return -1
|
|
65
|
+
|
|
66
|
+
def getAll(self):
|
|
67
|
+
"""Gets the full numerical sequence."""
|
|
68
|
+
return self.frameList
|
|
69
|
+
|
|
70
|
+
def normalize(self):
|
|
71
|
+
"""Sorts and dedeuplicates the sequence."""
|
|
72
|
+
self.frameList = list(set(self.frameList))
|
|
73
|
+
self.frameList.sort()
|
|
74
|
+
|
|
75
|
+
@staticmethod
|
|
76
|
+
def parseFrameRange(frameRange):
|
|
77
|
+
"""
|
|
78
|
+
Parses a string representation of a frame range into a FrameSet.
|
|
79
|
+
|
|
80
|
+
:type frameRange: str
|
|
81
|
+
:param frameRange: String representation of the frame range.
|
|
82
|
+
:rtype: FrameSet
|
|
83
|
+
:return: The FrameSet representing the same sequence.
|
|
84
|
+
"""
|
|
85
|
+
frameList = []
|
|
86
|
+
for frameRangeSection in frameRange.split(','):
|
|
87
|
+
frameList.extend(FrameRange.parseFrameRange(frameRangeSection))
|
|
88
|
+
return frameList
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Copyright Contributors to the OpenCue Project
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
Top-level module of FileSequence.
|
|
17
|
+
|
|
18
|
+
FileSequence contains helper classes for representing a job's frame range.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import absolute_import
|
|
22
|
+
from __future__ import print_function
|
|
23
|
+
from __future__ import division
|
|
24
|
+
from .FrameRange import FrameRange
|
|
25
|
+
from .FrameSet import FrameSet
|
|
26
|
+
from .FileSequence import FileSequence
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: opencue_pycue
|
|
3
|
+
Version: 1.11.66
|
|
4
|
+
Requires-Dist: future==1.0.0
|
|
5
|
+
Requires-Dist: opencue-proto
|
|
6
|
+
Requires-Dist: pyyaml==6.0.1
|
|
7
|
+
Requires-Dist: six==1.16.0
|
|
8
|
+
Provides-Extra: test
|
|
9
|
+
Requires-Dist: mock==2.0.0; extra == 'test'
|
|
10
|
+
Requires-Dist: pyfakefs==5.2.3; extra == 'test'
|
|
11
|
+
Requires-Dist: pytest; extra == 'test'
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Copyright Contributors to the OpenCue Project
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""Top level of the opencue module."""
|
|
16
|
+
|
|
17
|
+
from __future__ import absolute_import
|
|
18
|
+
from __future__ import print_function
|
|
19
|
+
from __future__ import division
|
|
20
|
+
|
|
21
|
+
import logging
|
|
22
|
+
|
|
23
|
+
# pylint: disable=cyclic-import
|
|
24
|
+
from .cuebot import Cuebot
|
|
25
|
+
from . import api
|
|
26
|
+
from . import wrappers
|
|
27
|
+
from . import search
|
|
28
|
+
|
|
29
|
+
from .exception import CueException
|
|
30
|
+
from .exception import EntityNotFoundException
|
|
31
|
+
# pylint: disable=redefined-builtin
|
|
32
|
+
from .util import id
|
|
33
|
+
# pylint: enable=redefined-builtin
|
|
34
|
+
from .util import logPath
|
|
35
|
+
from .util import proxy
|
|
36
|
+
from .util import rep
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class __NullHandler(logging.Handler):
|
|
40
|
+
def emit(self, record):
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
__logger = logging.getLogger("opencue")
|
|
45
|
+
__logger.addHandler(__NullHandler())
|