ciocore 7.0.2b5__py2.py3-none-any.whl → 8.0.0__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.

Potentially problematic release.


This version of ciocore might be problematic. Click here for more details.

Files changed (111) hide show
  1. ciocore/VERSION +1 -1
  2. ciocore/__init__.py +23 -1
  3. ciocore/api_client.py +422 -156
  4. ciocore/cli.py +503 -0
  5. ciocore/common.py +10 -1
  6. ciocore/config.py +86 -53
  7. ciocore/data.py +20 -73
  8. ciocore/docsite/404.html +723 -0
  9. ciocore/docsite/apidoc/api_client/index.html +3203 -0
  10. ciocore/docsite/apidoc/apidoc/index.html +868 -0
  11. ciocore/docsite/apidoc/config/index.html +1591 -0
  12. ciocore/docsite/apidoc/data/index.html +1480 -0
  13. ciocore/docsite/apidoc/hardware_set/index.html +2367 -0
  14. ciocore/docsite/apidoc/package_environment/index.html +1450 -0
  15. ciocore/docsite/apidoc/package_tree/index.html +2310 -0
  16. ciocore/docsite/assets/_mkdocstrings.css +16 -0
  17. ciocore/docsite/assets/images/favicon.png +0 -0
  18. ciocore/docsite/assets/javascripts/bundle.4e31edb1.min.js +29 -0
  19. ciocore/docsite/assets/javascripts/bundle.4e31edb1.min.js.map +8 -0
  20. ciocore/docsite/assets/javascripts/lunr/min/lunr.ar.min.js +1 -0
  21. ciocore/docsite/assets/javascripts/lunr/min/lunr.da.min.js +18 -0
  22. ciocore/docsite/assets/javascripts/lunr/min/lunr.de.min.js +18 -0
  23. ciocore/docsite/assets/javascripts/lunr/min/lunr.du.min.js +18 -0
  24. ciocore/docsite/assets/javascripts/lunr/min/lunr.es.min.js +18 -0
  25. ciocore/docsite/assets/javascripts/lunr/min/lunr.fi.min.js +18 -0
  26. ciocore/docsite/assets/javascripts/lunr/min/lunr.fr.min.js +18 -0
  27. ciocore/docsite/assets/javascripts/lunr/min/lunr.hi.min.js +1 -0
  28. ciocore/docsite/assets/javascripts/lunr/min/lunr.hu.min.js +18 -0
  29. ciocore/docsite/assets/javascripts/lunr/min/lunr.hy.min.js +1 -0
  30. ciocore/docsite/assets/javascripts/lunr/min/lunr.it.min.js +18 -0
  31. ciocore/docsite/assets/javascripts/lunr/min/lunr.ja.min.js +1 -0
  32. ciocore/docsite/assets/javascripts/lunr/min/lunr.jp.min.js +1 -0
  33. ciocore/docsite/assets/javascripts/lunr/min/lunr.kn.min.js +1 -0
  34. ciocore/docsite/assets/javascripts/lunr/min/lunr.ko.min.js +1 -0
  35. ciocore/docsite/assets/javascripts/lunr/min/lunr.multi.min.js +1 -0
  36. ciocore/docsite/assets/javascripts/lunr/min/lunr.nl.min.js +18 -0
  37. ciocore/docsite/assets/javascripts/lunr/min/lunr.no.min.js +18 -0
  38. ciocore/docsite/assets/javascripts/lunr/min/lunr.pt.min.js +18 -0
  39. ciocore/docsite/assets/javascripts/lunr/min/lunr.ro.min.js +18 -0
  40. ciocore/docsite/assets/javascripts/lunr/min/lunr.ru.min.js +18 -0
  41. ciocore/docsite/assets/javascripts/lunr/min/lunr.sa.min.js +1 -0
  42. ciocore/docsite/assets/javascripts/lunr/min/lunr.stemmer.support.min.js +1 -0
  43. ciocore/docsite/assets/javascripts/lunr/min/lunr.sv.min.js +18 -0
  44. ciocore/docsite/assets/javascripts/lunr/min/lunr.ta.min.js +1 -0
  45. ciocore/docsite/assets/javascripts/lunr/min/lunr.te.min.js +1 -0
  46. ciocore/docsite/assets/javascripts/lunr/min/lunr.th.min.js +1 -0
  47. ciocore/docsite/assets/javascripts/lunr/min/lunr.tr.min.js +18 -0
  48. ciocore/docsite/assets/javascripts/lunr/min/lunr.vi.min.js +1 -0
  49. ciocore/docsite/assets/javascripts/lunr/min/lunr.zh.min.js +1 -0
  50. ciocore/docsite/assets/javascripts/lunr/tinyseg.js +206 -0
  51. ciocore/docsite/assets/javascripts/lunr/wordcut.js +6708 -0
  52. ciocore/docsite/assets/javascripts/workers/search.dfff1995.min.js +42 -0
  53. ciocore/docsite/assets/javascripts/workers/search.dfff1995.min.js.map +8 -0
  54. ciocore/docsite/assets/stylesheets/main.83068744.min.css +1 -0
  55. ciocore/docsite/assets/stylesheets/main.83068744.min.css.map +1 -0
  56. ciocore/docsite/assets/stylesheets/palette.ecc896b0.min.css +1 -0
  57. ciocore/docsite/assets/stylesheets/palette.ecc896b0.min.css.map +1 -0
  58. ciocore/docsite/cmdline/docs/index.html +834 -0
  59. ciocore/docsite/cmdline/downloader/index.html +897 -0
  60. ciocore/docsite/cmdline/packages/index.html +841 -0
  61. ciocore/docsite/cmdline/uploader/index.html +950 -0
  62. ciocore/docsite/how-to-guides/index.html +831 -0
  63. ciocore/docsite/index.html +853 -0
  64. ciocore/docsite/logo.png +0 -0
  65. ciocore/docsite/objects.inv +0 -0
  66. ciocore/docsite/search/search_index.json +1 -0
  67. ciocore/docsite/sitemap.xml +3 -0
  68. ciocore/docsite/sitemap.xml.gz +0 -0
  69. ciocore/docsite/stylesheets/extra.css +26 -0
  70. ciocore/docsite/stylesheets/tables.css +167 -0
  71. ciocore/downloader/__init__.py +0 -0
  72. ciocore/downloader/base_downloader.py +644 -0
  73. ciocore/downloader/download_runner_base.py +47 -0
  74. ciocore/downloader/job_downloader.py +119 -0
  75. ciocore/{downloader.py → downloader/legacy_downloader.py} +0 -1
  76. ciocore/downloader/log.py +73 -0
  77. ciocore/downloader/logging_download_runner.py +87 -0
  78. ciocore/downloader/perpetual_downloader.py +63 -0
  79. ciocore/downloader/registry.py +97 -0
  80. ciocore/downloader/reporter.py +135 -0
  81. ciocore/file_utils.py +3 -3
  82. ciocore/hardware_set.py +0 -4
  83. ciocore/package_environment.py +67 -75
  84. ciocore/package_query.py +171 -0
  85. ciocore/package_tree.py +300 -377
  86. ciocore/retry.py +0 -0
  87. ciocore/uploader/_uploader.py +205 -152
  88. {ciocore-7.0.2b5.dist-info → ciocore-8.0.0.dist-info}/METADATA +34 -16
  89. ciocore-8.0.0.dist-info/RECORD +127 -0
  90. {ciocore-7.0.2b5.dist-info → ciocore-8.0.0.dist-info}/WHEEL +1 -1
  91. ciocore-8.0.0.dist-info/entry_points.txt +2 -0
  92. tests/extra_env_fixtures.py +57 -0
  93. tests/instance_type_fixtures.py +42 -8
  94. tests/project_fixtures.py +8 -0
  95. tests/test_api_client.py +121 -2
  96. tests/test_base_downloader.py +104 -0
  97. tests/test_cli.py +163 -0
  98. tests/test_common.py +8 -8
  99. tests/test_config.py +23 -9
  100. tests/test_data.py +144 -160
  101. tests/test_downloader.py +118 -0
  102. tests/test_hardware_set.py +69 -20
  103. tests/test_job_downloader.py +213 -0
  104. ciocore/__about__.py +0 -10
  105. ciocore/cli/__init__.py +0 -3
  106. ciocore/cli/conductor.py +0 -210
  107. ciocore-7.0.2b5.data/scripts/conductor +0 -19
  108. ciocore-7.0.2b5.data/scripts/conductor.bat +0 -13
  109. ciocore-7.0.2b5.dist-info/RECORD +0 -51
  110. tests/mocks/api_client_mock.py +0 -31
  111. {ciocore-7.0.2b5.dist-info → ciocore-8.0.0.dist-info}/top_level.txt +0 -0
ciocore/package_tree.py CHANGED
@@ -1,54 +1,328 @@
1
1
  """
2
- A class to provide available packages as DAG structure.
2
+ A class to provide available packages as DAG structure. In reality however, the structure is just two levels deep: **hosts** and **plugins**.
3
3
 
4
- In reality, the structure is just two levels deep: **hosts** and **plugins**. DCCs such as **Maya** and
5
- **Cinema4D** are top-level host packages. Renderers and other plugins are children of those hosts.
6
- Methods are provided to traverse the tree to find packages by name, version, platform and so on.
4
+ * DCCs such as **Maya** and **Cinema4D** are top-level host packages.
5
+ * Renderers and other plugins are children of those hosts.
7
6
 
8
- If you are writing submission tools there's no need to create a Package tree directly.
9
- It is recommended to use the singleton module: [ciocore.data](/developer/ciocore/data/). The only
10
- functions you should need from this module are: [supported_host_names()](#supported_host_names) and [supported_plugins()](#supported_plugins)
7
+ Methods are provided to traverse the tree to find packages by name, version, platform and so on. If you are writing submission tools there's no need to create a Package tree directly. It is recommended to use the singleton module: [ciocore.data](/data/).
8
+
9
+ The only functions you should need from this module are:
10
+
11
+ * [supported_host_names()](/package_tree/#ciocore.package_tree.PackageTree.supported_host_names)
12
+ * [supported_plugins()](/package_tree/#ciocore.package_tree.PackageTree.supported_plugins)
11
13
  """
12
14
 
13
15
  import copy
14
16
  import json
15
17
 
16
- from ciocore.package_environment import PackageEnvironment
17
-
18
18
  WINDOWS = "windows"
19
19
  LINUX = "linux"
20
20
 
21
21
  #: The set of supported platforms, currently windows and linux.
22
22
  PLATFORMS = {WINDOWS, LINUX}
23
23
 
24
+ class PackageTree(object):
25
+ def __init__(self, packages, *host_products, **kwargs):
26
+ """Build the tree with a list of packages.
24
27
 
25
- def to_name(pkg):
26
- """
27
- Generate Name like `houdini 16.5.323 linux` or `maya 2016.SP3 linux`.
28
+ Args:
29
+ packages (list): List of packages direct from the [Conductor packages endpoint](https://dashboard.conductortech.com/api/v1/ee/packages).
28
30
 
29
- This name is derived from the product and version fields in a package. Note: It is not
30
- necessarily possible to go the other way and extract version fields from the name..
31
+ *host_products: Filter the tree to contain only top-level host packages of products specified in this list and their plugins. If there are no host_products specified, and the product keyword is omitted, the tree contains all packages.
31
32
 
32
- Arguments:
33
+ Keyword Args:
34
+ product (str): Build the tree from versions of a single product and its compatible plugins. Defaults to `None`, in which case the tree is built from all packages. It is an error to specify both host_products and product. If a nonexistent product is given, the PackageTree is empty. By specifying `product`, you can build the object based on a single plugin product.
35
+ platforms (set): Build the tree from versions for a specific platform. Defaults to the set `{"linux", "windows"}`.
33
36
 
34
- * **`pkg`** -- An object with product, platform , and all version fields.
37
+ Raises:
38
+ KeyError: An invalid platform was provided.
39
+ ValueError: Cannot choose both product and host_products.
40
+
41
+ Example:
42
+ >>> from ciocore import api_client, package_tree
43
+ # Request packages as a flat list from Conductor.
44
+ >>> packages = api_client.request_software_packages()
45
+ # Build tree of dependencies from packages list
46
+ >>> pt = package_tree.PackageTree(packages, "cinema4d", "maya-io")
47
+ >>> for path in pt.to_path_list():
48
+ >>> print(path)
49
+ cinema4d 22.118.RB320081 linux
50
+ cinema4d 22.118.RB320081 linux/redshift-cinema4d 3.0.43 linux
51
+ cinema4d 22.118.RB320081 linux/redshift-cinema4d 3.0.45 linux
52
+ maya-io 2022.SP3 linux
53
+ """
35
54
 
36
- Returns:
37
55
 
38
- * The package name.
56
+ platforms = kwargs.get("platforms",PLATFORMS)
57
+ product=kwargs.get("product")
39
58
 
40
- ???+ example
41
- ``` python
59
+ unknown_platforms = set(platforms) - PLATFORMS
60
+ if unknown_platforms:
61
+ raise KeyError("Unrecognized platform {}".format(" ".join(unknown_platforms)))
62
+
63
+ if product and host_products:
64
+ raise ValueError("You cannot choose both product and host_products.")
65
+
66
+ packages = [_clean_package(p) for p in packages if p["platform"] in platforms]
67
+
68
+ root_ids = []
69
+ if product:
70
+ root_ids = [p["package_id"] for p in packages if p["product"] == product]
71
+ else:
72
+ for p in packages:
73
+ if not p["plugin_host_product"]:
74
+ if p["product"] in host_products or not host_products:
75
+ root_ids.append(p["package_id"])
76
+
77
+ self._tree = _build_tree(packages, {"children": [], "plugins": root_ids})
78
+
79
+ def supported_host_names(self):
80
+ """
81
+ All host names from the software tree.
82
+
83
+ These names can be used to populate a dropdown menu. Then a single selection from that menu
84
+ can be used to retrieve the complete package in order to generate an environment dictionary
85
+ and get package IDs.
42
86
 
43
- from ciocore import api_client, package_tree
44
- packages = api_client.request_software_packages()
45
- package_tree.to_name(packages[0])
87
+ Returns:
88
+ list(str): Fully qualified DCC hosts of the form: `product version platform`.
89
+
90
+ Example:
91
+ >>> from ciocore import api_client, package_tree
92
+ >>> packages = api_client.request_software_packages()
93
+ >>> pt = package_tree.PackageTree(packages, product="cinema4d")
94
+ >>> pt.supported_host_names()
95
+ cinema4d 21.209.RB305619 linux
96
+ cinema4d 22.116.RB316423 linux
97
+ cinema4d 22.118.RB320081 linux
98
+ cinema4d 23.110.RB330286 linux
99
+ cinema4d 24.111 linux
100
+ cinema4d 24.111 windows
101
+ """
102
+
103
+ paths = []
104
+ for pkg in self._tree["children"]:
105
+ paths.append(to_name(pkg))
106
+ return sorted(paths)
107
+
108
+ def supported_plugins(self, host):
109
+ """
110
+ Find the plugins that are children of the given DCC host.
111
+
112
+ The result does not contain platform information since we assume that plugins are compatible with the DCC host that was used to request them.
113
+
114
+ Args:
115
+ host (str): Name of the DCC host, typically one of the entries returned by [supported_host_names()](/package_tree/#ciocore.package_tree.PackageTree.supported_host_names).
116
+
117
+ Returns:
118
+ list(dict): Each entry contains a plugin product and a list of versions.
119
+
120
+ Example:
121
+ >>> from ciocore import api_client, package_tree
122
+ >>> packages = api_client.request_software_packages()
123
+ >>> pt = package_tree.PackageTree(packages, product="cinema4d")
124
+ >>> name = pt.supported_host_names()[0]
125
+ >>> pt.supported_plugins(name)
126
+ [
127
+ {
128
+ "plugin": "arnold-cinema4d",
129
+ "versions": [
130
+ "3.3.2.100",
131
+ "3.3.3.0"
132
+ ]
133
+ },
134
+ {
135
+ "plugin": "redshift-cinema4d",
136
+ "versions": [
137
+ "2.6.54",
138
+ "2.6.56",
139
+ "3.0.21",
140
+ "3.0.22",
141
+ ],
142
+ },
143
+ ]
144
+ """
145
+
146
+ try:
147
+ subtree = self.find_by_name(host)
148
+ plugin_versions = _to_path_list(subtree)
149
+ except TypeError:
150
+ return []
151
+
152
+ if not plugin_versions:
153
+ return []
154
+
155
+ plugin_dict = {}
156
+ for plugin, version, _ in [pv.split(" ") for pv in plugin_versions]:
157
+ if plugin not in plugin_dict:
158
+ plugin_dict[plugin] = []
159
+ plugin_dict[plugin].append(version)
160
+
161
+ # convert to list so it can be sorted
162
+ plugins = []
163
+ for key in plugin_dict:
164
+ plugins.append({"plugin": key, "versions": sorted(plugin_dict[key])})
165
+
166
+ return sorted(plugins, key=lambda k: k["plugin"])
167
+
168
+ def find_by_name(self, name, limit=None):
169
+ """
170
+ Search the tree for a product with the given name.
46
171
 
47
- # Result:
48
- # redshift-maya 3.0.64 linux
172
+ Args:
173
+ name (str): The name constructed from the package using to_name(). It must be an exact match with product, version, and platform. For example: `maya 2018.0 windows`
49
174
 
50
- ```
175
+ Keyword Args:
176
+ limit (int): Limit the search depth. Defaults to `None`.
177
+
178
+ Returns:
179
+ object: The package that matches.
180
+
181
+ Example:
182
+ >>> from ciocore import api_client, package_tree
183
+ >>> packages = api_client.request_software_packages()
184
+ >>> pt = package_tree.PackageTree(packages, product="cinema4d")
185
+ >>> pt.find_by_name("redshift-cinema4d 3.0.64 linux")
186
+ {
187
+ 'platform': 'linux',
188
+ 'plugin_host_product': 'cinema4d',
189
+ 'product': 'redshift-cinema4d',
190
+ 'major_version': '3',
191
+ 'release_version': '64',
192
+ 'vendor': 'maxon',
193
+ 'children': [],
194
+ ...
195
+ }
196
+ """
197
+
198
+ return _find_by_name(self._tree, name, limit, 0)
199
+
200
+ def find_by_path(self, path):
201
+ """
202
+ Find the package uniquely described by the given path.
203
+
204
+ The path is of the form returned by the to_path_list() method.
205
+
206
+ Args:
207
+ path (str): The path
208
+
209
+ Returns:
210
+ object: The package or None if no package exists with the given path.
211
+
212
+ Example:
213
+ >>> from ciocore import api_client, package_tree, package_environment
214
+ >>> packages = api_client.request_software_packages()
215
+ >>> pt = package_tree.PackageTree(packages, product="cinema4d")
216
+ >>> pt.find_by_path("cinema4d 24.111 linux/redshift-cinema4d 3.0.62 linux")
217
+ {
218
+ 'platform': 'linux',
219
+ 'plugin_host_product': 'cinema4d',
220
+ 'product': 'redshift-cinema4d',
221
+ 'major_version': '3',
222
+ 'release_version': '62',
223
+ 'vendor': 'maxon',
224
+ 'children': [],
225
+ 'plugin_host_version': "24",
226
+ ...
227
+ }
228
+ """
229
+ return _find_by_path(self._tree, path)
230
+
231
+
232
+ def to_path_list(self, name=None):
233
+ """
234
+ Get paths to all nodes.
235
+
236
+ This is useful for populating a chooser to choose packages fully qualified by path.
237
+ Houdini's tree widget, for example, takes the below format unchanged and generates the
238
+ appropriate UI.
239
+
240
+ Args:
241
+ name (str): Get paths below the tree represented by the name. Defaults to None (root node).
242
+
243
+ Returns:
244
+ list(str): Paths to all nodes in the tree.
245
+
246
+ Example:
247
+ >>> from ciocore import api_client, package_tree
248
+ >>> packages = api_client.request_software_packages()
249
+ >>> pt = package_tree.PackageTree(packages, product="cinema4d")
250
+ >>> pt.to_path_list()
251
+ cinema4d 22.118.RB320081 linux
252
+ cinema4d 22.118.RB320081 linux/redshift-cinema4d 3.0.43 linux
253
+ cinema4d 22.118.RB320081 linux/redshift-cinema4d 3.0.45 linux
254
+ cinema4d 22.118.RB320081 linux/redshift-cinema4d 3.0.22 linux
255
+ cinema4d 22.118.RB320081 linux/arnold-cinema4d 3.3.2.100 linux
256
+ ...
257
+
258
+ >>> pt.to_path_list(name="cinema4d 24.111 linux")
259
+ redshift-cinema4d 3.0.57 linux
260
+ redshift-cinema4d 3.0.62 linux
261
+ redshift-cinema4d 3.0.45 linux
262
+ redshift-cinema4d 3.0.64 linux
263
+ """
264
+ if name:
265
+ subtree = self.find_by_name(name)
266
+ return _to_path_list(subtree)
267
+ return _to_path_list(self._tree)
268
+
269
+ def platforms(self):
270
+ """
271
+ Get the platforms represented by packages in the tree.
272
+
273
+ Returns:
274
+ set: The set of platforms.
275
+ """
276
+
277
+ # No need to recurse. Plugins are assumed to be compatible with the host.
278
+ return set([host["platform"] for host in self._tree["children"]])
279
+
280
+ def json(self):
281
+ """
282
+ The whole tree of softwware as json.
283
+
284
+ Returns:
285
+ str: JSON.
286
+
287
+ """
288
+ return json.dumps(self._tree)
289
+
290
+ def __bool__(self):
291
+ return True if self._tree["children"] else False
292
+
293
+ def __nonzero__(self):
294
+ # Python 2.7
295
+ return self.__bool__()
296
+
297
+ def as_dict(self):
298
+ """
299
+ Returns:
300
+ dict: The underlying software dictionary.
301
+
302
+ """
303
+ return self._tree
304
+
305
+
306
+ def to_name(pkg):
51
307
  """
308
+ Generate a name like `houdini 16.5.323 linux` or `maya 2016.SP3 linux`.
309
+
310
+ This name is derived from the product and version fields in a package. Note: It is not
311
+ necessarily possible to go the other way and extract version fields from the name.
312
+
313
+ Args:
314
+ pkg (object): An object with product, platform, and all version fields.
315
+
316
+ Returns:
317
+ str: The package name.
318
+
319
+ Examples:
320
+ >>> from ciocore import api_client, package_tree
321
+ >>> packages = api_client.request_software_packages()
322
+ >>> package_tree.to_name(packages[0])
323
+ redshift-maya 3.0.64 linux
324
+
325
+ """
52
326
 
53
327
  version_parts = [
54
328
  pkg["major_version"],
@@ -162,354 +436,3 @@ def _clean_package(package):
162
436
  pkg["children"] = []
163
437
  return pkg
164
438
 
165
-
166
- class PackageTree(object):
167
- def __init__(self, packages, *host_products, **kwargs):
168
- """
169
- Build the tree with a list of packages.
170
-
171
- Arguments:
172
-
173
- * **`packages`** -- List of packages direct from the [Conductor packages
174
- endpoint](https://dashboard.conductortech.com/api/v1/ee/packages).
175
-
176
-
177
- * **`*host_products`** -- Filter the tree to contain only top-level host packages of
178
- products specified in this list and their plugins. If there are no host_products specified,
179
- and the product keyword is omitted, the tree contains all packages.
180
-
181
- Keyword Arguments:
182
-
183
- * **`product`** -- Build the tree from versions of a single product and its compatible
184
- plugins -- Defaults to `None`, in which case the tree is built from all packages. It is
185
- an error to specify both host_products and product. If a nonexistent product is given,
186
- the PackageTree is empty. By specifying `product`, you can build the object based on a
187
- single plugin product.
188
- * **`platforms`** -- Build the tree from versions for a specific platform -- Defaults to the
189
- set `{"linux", "windows"}`.
190
-
191
- Raises:
192
-
193
- * **`KeyError`** -- An invalid platform was provided.
194
- * **`ValueError`** -- Cannot choose both product and host_products.
195
-
196
-
197
- ???+ example
198
- ``` python
199
-
200
- from ciocore import api_client, package_tree
201
-
202
- # Request packages as a flat list from Conductor.
203
- packages = api_client.request_software_packages()
204
-
205
- # Build tree of dependencies from packages list
206
- pt = package_tree.PackageTree(packages, "cinema4d", "maya-io")
207
- for path in pt.to_path_list():
208
- print(path)
209
-
210
- # Result
211
- # cinema4d 22.118.RB320081 linux
212
- # cinema4d 22.118.RB320081 linux/redshift-cinema4d 3.0.43 linux
213
- # cinema4d 22.118.RB320081 linux/redshift-cinema4d 3.0.45 linux
214
- # maya-io 2022.SP3 linux
215
- # ...
216
- ```
217
- """
218
-
219
- platforms = kwargs.get("platforms",PLATFORMS)
220
- product=kwargs.get("product")
221
-
222
- unknown_platforms = set(platforms) - PLATFORMS
223
- if unknown_platforms:
224
- raise KeyError("Unrecognized platform {}".format(" ".join(unknown_platforms)))
225
-
226
- if product and host_products:
227
- raise ValueError("You cannot choose both product and host_products.")
228
-
229
- packages = [_clean_package(p) for p in packages if p["platform"] in platforms]
230
-
231
- root_ids = []
232
- if product:
233
- root_ids = [p["package_id"] for p in packages if p["product"] == product]
234
- else:
235
- for p in packages:
236
- if not p["plugin_host_product"]:
237
- if p["product"] in host_products or not host_products:
238
- root_ids.append(p["package_id"])
239
-
240
- self._tree = _build_tree(packages, {"children": [], "plugins": root_ids})
241
-
242
- def find_by_name(self, name, limit=None):
243
- """
244
- Search the tree for a product with the given name.
245
-
246
- Arguments:
247
-
248
- * **`name`** -- This name is the name originally constructed from the package using
249
- to_name(). It must be an exact match with product, version, platform.
250
- For example: `maya 2018.0 windows`
251
-
252
- Keyword Arguments:
253
-
254
- * **`limit`** -- Limit the search depth -- Defaults to `None`.
255
-
256
- Returns:
257
-
258
- * The package that matches.
259
-
260
- ???+ example
261
- ``` python
262
-
263
- from ciocore import api_client, package_tree
264
- packages = api_client.request_software_packages()
265
-
266
- pt = package_tree.PackageTree(packages, product="cinema4d")
267
- pt.find_by_name("redshift-cinema4d 3.0.64 linux")
268
-
269
- # Result:
270
- # {
271
- # 'platform': 'linux',
272
- # 'plugin_host_product': 'cinema4d',
273
- # 'product': 'redshift-cinema4d',
274
- # 'major_version': '3',
275
- # 'release_version': '64',
276
- # 'vendor': 'maxon',
277
- # 'children': [],
278
- # ...
279
- # }
280
- ```
281
- """
282
-
283
- return _find_by_name(self._tree, name, limit, 0)
284
-
285
- def find_by_path(self, path):
286
- """
287
- Find the package uniquely described by the given path.
288
-
289
- The path is of the form returned by the to_path_list() method.
290
-
291
- Arguments:
292
-
293
- * **`path`** -- The path
294
-
295
- Returns:
296
-
297
- * The package or None if no package exists with the given path.
298
-
299
- ???+ example
300
- ``` python
301
-
302
- from ciocore import api_client, package_tree, package_environment
303
- packages = api_client.request_software_packages()
304
- pt = package_tree.PackageTree(packages, product="cinema4d")
305
- pt.find_by_path("cinema4d 24.111 linux/redshift-cinema4d 3.0.62 linux")
306
-
307
- # Result:
308
- # {
309
- # 'platform': 'linux',
310
- # 'plugin_host_product': 'cinema4d',
311
- # 'product': 'redshift-cinema4d',
312
- # 'major_version': '3',
313
- # 'release_version': '62',
314
- # 'vendor': 'maxon',
315
- # 'children': [],
316
- # 'plugin_host_version': "24",
317
- # ...
318
- # }
319
- ```
320
- """
321
-
322
- return _find_by_path(self._tree, path)
323
-
324
-
325
- def to_path_list(self, name=None):
326
- """
327
- Get paths to all nodes.
328
-
329
- This is useful for populating a chooser to choose packages fully qualified by path.
330
- Houdini's tree widget for example, takes the below format unchanged and generates the
331
- appropriate UI.
332
-
333
- Keyword Arguments:
334
-
335
- * **`name`** -- Get paths below the tree represented by the name. -- Defaults to `None` (root node).
336
-
337
- Returns:
338
-
339
- * _description_.
340
-
341
- ???+ example
342
- ``` python
343
-
344
- from ciocore import api_client, package_tree
345
- packages = api_client.request_software_packages()
346
- pt = package_tree.PackageTree(packages, product="cinema4d")
347
-
348
- pt.to_path_list()
349
- # Result:
350
- # cinema4d 22.118.RB320081 linux
351
- # cinema4d 22.118.RB320081 linux/redshift-cinema4d 3.0.43 linux
352
- # cinema4d 22.118.RB320081 linux/redshift-cinema4d 3.0.45 linux
353
- # cinema4d 22.118.RB320081 linux/redshift-cinema4d 3.0.22 linux
354
- # cinema4d 22.118.RB320081 linux/arnold-cinema4d 3.3.2.100 linux
355
- ...
356
-
357
- pt.to_path_list(name="cinema4d 24.111 linux")
358
- # Result:
359
- # redshift-cinema4d 3.0.57 linux
360
- # redshift-cinema4d 3.0.62 linux
361
- # redshift-cinema4d 3.0.45 linux
362
- # redshift-cinema4d 3.0.64 linux
363
-
364
-
365
- ```
366
- """
367
- if name:
368
- subtree = self.find_by_name(name)
369
- return _to_path_list(subtree)
370
- return _to_path_list(self._tree)
371
-
372
- def platforms(self):
373
- """
374
- Get the set of platforms represented by packages in the tree.
375
-
376
- Returns a set.
377
- """
378
-
379
- # No need to recurse. Plugins are assumed to be compatible with the host.
380
- return set([host["platform"] for host in self._tree["children"]])
381
-
382
- def json(self):
383
- """
384
- The whole tree as json.
385
-
386
- Returns:
387
-
388
- * JSON object.
389
-
390
- """
391
- return json.dumps(self._tree)
392
-
393
- def __bool__(self):
394
- return True if self._tree["children"] else False
395
-
396
- def __nonzero__(self):
397
- # Python 2.7
398
- return self.__bool__()
399
-
400
- def as_dict(self):
401
- """
402
- Returns:
403
-
404
- * The underlying dictionary.
405
-
406
- """
407
- return self._tree
408
-
409
- def supported_host_names(self):
410
- """
411
- All host names from the software tree.
412
-
413
- These names can be used to populate a dropdown menu. Then a single selection from that menu
414
- can be used to retrieve the complete package in order to generate an environment dictionary
415
- and get package IDs.
416
-
417
- Returns:
418
-
419
- * A list of fully qualified DCC hosts of the form: `product`, `version`, `platform`.
420
-
421
- ???+ example
422
- ``` python
423
-
424
- from ciocore import api_client, package_tree
425
- packages = api_client.request_software_packages()
426
- pt = package_tree.PackageTree(packages,
427
- product="cinema4d")
428
-
429
- pt.supported_host_names()
430
-
431
- # Result:
432
- # cinema4d 21.209.RB305619 linux
433
- # cinema4d 22.116.RB316423 linux
434
- # cinema4d 22.118.RB320081 linux
435
- # cinema4d 23.110.RB330286 linux
436
- # cinema4d 24.111 linux
437
- # cinema4d 24.111 windows
438
-
439
- ```
440
- """
441
-
442
- paths = []
443
- for pkg in self._tree["children"]:
444
- paths.append(to_name(pkg))
445
- return sorted(paths)
446
-
447
- def supported_plugins(self, host):
448
- """
449
- Find the plugins that are children of the given DCC host.
450
-
451
- The result does not contain platform information since we assume that plugins are compatible with the DCC host that was used to
452
- request them.
453
-
454
- Arguments:
455
-
456
- * **`host`** -- Name of the DCC host, typically one of the entries returned by supported_host_names().
457
-
458
- Returns:
459
-
460
- * A list of dictionaries, where each entry contains a plugin product and a list of versions.
461
-
462
- ???+ example
463
- ``` python
464
-
465
- from ciocore import api_client, package_tree packages =
466
- api_client.request_software_packages() pt = package_tree.PackageTree(packages,
467
- product="cinema4d")
468
- name = pt.supported_host_names()[0]
469
-
470
- pt.supported_plugins(name)
471
- # Result:
472
- #
473
- # [
474
- # {
475
- # "plugin": "arnold-cinema4d",
476
- # "versions": [
477
- # "3.3.2.100",
478
- # "3.3.3.0"
479
- # ]
480
- # },
481
- # {
482
- # "plugin": "redshift-cinema4d",
483
- # "versions": [
484
- # "2.6.54",
485
- # "2.6.56",
486
- # "3.0.21",
487
- # "3.0.22",
488
- # ],
489
- # },
490
- # ]
491
-
492
- ```
493
- """
494
-
495
- try:
496
- subtree = self.find_by_name(host)
497
- plugin_versions = _to_path_list(subtree)
498
- except TypeError:
499
- return []
500
-
501
- if not plugin_versions:
502
- return []
503
-
504
- plugin_dict = {}
505
- for plugin, version, _ in [pv.split(" ") for pv in plugin_versions]:
506
- if plugin not in plugin_dict:
507
- plugin_dict[plugin] = []
508
- plugin_dict[plugin].append(version)
509
-
510
- # convert to list so it can be sorted
511
- plugins = []
512
- for key in plugin_dict:
513
- plugins.append({"plugin": key, "versions": sorted(plugin_dict[key])})
514
-
515
- return sorted(plugins, key=lambda k: k["plugin"])