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/package_environment.py
CHANGED
|
@@ -1,26 +1,111 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Manage environment variables for both Windows and Linux render nodes.
|
|
3
|
+
"""
|
|
4
|
+
|
|
1
5
|
class PackageEnvironment(object):
|
|
2
|
-
"""Encapsulate the submission environment vars.
|
|
3
6
|
|
|
4
|
-
Handle building up the env with a single call to extend()
|
|
5
|
-
"""
|
|
6
7
|
|
|
7
8
|
def __init__(self, env_list=None, platform=None):
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
On the first add, if the package contains a platform field (which it will) or in the case of a list, it is
|
|
11
|
-
accompanied by a platform, then we use it, otherwise we default to linux. It is an error to
|
|
12
|
-
try to change platform after the first add.
|
|
9
|
+
"""
|
|
10
|
+
Encapsulate a list of environment variables.
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
subsequent amendments. Policy is implied by the storage data type. String=exclusive,
|
|
16
|
-
List=append. User cannot change the policy once a variable has been declared.
|
|
12
|
+
Typically, one would initialize a PackageEnvironment with a package, and then modify by adding more packages or lists of variables. Extra variables can be added by the customer, or programmatically such as during asset scraping.
|
|
17
13
|
|
|
14
|
+
Args:
|
|
15
|
+
env_list (object|list): An object that provides a list of dictionaries with properties: `name`, `value`, and `merge_policy`.
|
|
16
|
+
platform (str): If the env_list is a regular list, then this is required.
|
|
17
|
+
|
|
18
|
+
Args are delegated to [extend()](/package_environment/#ciocore.package_environment.PackageEnvironment.extend).
|
|
18
19
|
"""
|
|
19
20
|
self.platform = None
|
|
20
21
|
self._env = {}
|
|
21
|
-
|
|
22
|
+
|
|
22
23
|
self.extend(env_list, platform)
|
|
23
24
|
|
|
25
|
+
|
|
26
|
+
def extend(self, env_list, platform=None):
|
|
27
|
+
"""
|
|
28
|
+
Extend the Package environment with the given variable specifications.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
env_list (object|list): Either:
|
|
32
|
+
* A list of dictionaries with properties: `name`, `value`, and `merge_policy`.
|
|
33
|
+
* An object with an `environment` key that contains a list of the dictionaries described above. The latter is the structure of a package. Therefore we can initialize or extend a PackageEnvironment with a package.
|
|
34
|
+
platform (str): Defaults to `None`. If env_list is a package, then the platform is taken from the package and the `platform` keyword is ignored. If env_list is a list, then if this is the first add, a platform should be specified, otherwise it will default to linux.
|
|
35
|
+
|
|
36
|
+
The first time data is added to a PackageEnvironment, the platform is set in stone. Subsequent `adds` that try to change the platform are considered an error.
|
|
37
|
+
|
|
38
|
+
Each variable to be added specifies a merge_policy: `append`, `prepend`, or `exclusive` `append` and `prepend` can be thought of as lists= types. Once an individual variable has been initialized as a list, it can't be changed to `exclusive`. This means:
|
|
39
|
+
|
|
40
|
+
1. It's not possible to overwrite variables that have been added as `append` or `prepend`.
|
|
41
|
+
2. Exclusive variables are always overwritten by subsequent adds.
|
|
42
|
+
|
|
43
|
+
Raises:
|
|
44
|
+
ValueError: Either an attempt to change the platform once initialized, or an invalid merge policy.
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
Example:
|
|
48
|
+
>>> from ciocore import api_client, package_tree, package_environment
|
|
49
|
+
>>> packages = api_client.request_software_packages()
|
|
50
|
+
>>> pt = package_tree.PackageTree(packages, product="cinema4d")
|
|
51
|
+
>>> one_dcc_name = pt.supported_host_names()[0]
|
|
52
|
+
cinema4d 21.209.RB305619 linux
|
|
53
|
+
|
|
54
|
+
>>> pkg = pt.find_by_name(one_dcc_name)
|
|
55
|
+
>>> pe = package_environment.PackageEnvironment(pkg)
|
|
56
|
+
>>> print(dict(pe))
|
|
57
|
+
{
|
|
58
|
+
"PATH": "/opt/maxon/cinema4d/21/cinema4d21.209vRB305619/bin",
|
|
59
|
+
"g_licenseServerRLM": "conductor-rlm:6112",
|
|
60
|
+
"LD_LIBRARY_PATH": "/opt/maxon/cinema4d/21/cinema4d21.209vRB305619/lib64:/opt/maxon/cinema4d/21/cinema4d21.209vRB305619/bin/resource/modules/python/libs/linux64/python.linux64.framework/lib64:/opt/maxon/cinema4d/21/cinema4d21.209vRB305619/bin/resource/modules/embree.module/libs/linux64",
|
|
61
|
+
"PYTHONPATH": "/opt/maxon/cinema4d/21/cinema4d21.209vRB305619/bin/resource/modules/python/libs/linux64/python.linux64.framework/lib64/python2.7/lib-dynload",
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
>>> extra_env = [
|
|
65
|
+
{"name":"PATH", "value": "/my/custom/scripts", "merge_policy":"append"},
|
|
66
|
+
{"name":"DEBUG_MODE", "value": "1", "merge_policy":"exclusive"}
|
|
67
|
+
]
|
|
68
|
+
>>> pe.extend(extra_env)
|
|
69
|
+
>>> print(dict(pe))
|
|
70
|
+
{
|
|
71
|
+
"PATH": "/opt/maxon/cinema4d/21/cinema4d21.209vRB305619/bin:/my/custom/scripts",
|
|
72
|
+
"g_licenseServerRLM": "conductor-rlm:6112",
|
|
73
|
+
"LD_LIBRARY_PATH": "/opt/maxon/cinema4d/21/cinema4d21.209vRB305619/lib64:/opt/maxon/cinema4d/21/cinema4d21.209vRB305619/bin/resource/modules/python/libs/linux64/python.linux64.framework/lib64:/opt/maxon/cinema4d/21/cinema4d21.209vRB305619/bin/resource/modules/embree.module/libs/linux64",
|
|
74
|
+
"PYTHONPATH": "/opt/maxon/cinema4d/21/cinema4d21.209vRB305619/bin/resource/modules/python/libs/linux64/python.linux64.framework/lib64/python2.7/lib-dynload",
|
|
75
|
+
"DEBUG_MODE": "1",
|
|
76
|
+
}
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
if not env_list:
|
|
80
|
+
return
|
|
81
|
+
|
|
82
|
+
try:
|
|
83
|
+
others = env_list["environment"]
|
|
84
|
+
requested_platform = env_list.get("platform")
|
|
85
|
+
except TypeError:
|
|
86
|
+
others = env_list
|
|
87
|
+
requested_platform = platform
|
|
88
|
+
|
|
89
|
+
if not self.platform:
|
|
90
|
+
self.platform = requested_platform or "linux"
|
|
91
|
+
elif requested_platform and requested_platform != self.platform:
|
|
92
|
+
raise ValueError("Can't change platform once initialized.")
|
|
93
|
+
|
|
94
|
+
for var in others:
|
|
95
|
+
name = var["name"]
|
|
96
|
+
value = var["value"]
|
|
97
|
+
policy = var["merge_policy"]
|
|
98
|
+
if policy not in ["append", "prepend", "exclusive"]:
|
|
99
|
+
raise ValueError("Unexpected merge policy: %s" % policy)
|
|
100
|
+
|
|
101
|
+
if policy == "append":
|
|
102
|
+
self._append(name, value)
|
|
103
|
+
elif policy == "prepend":
|
|
104
|
+
self._prepend(name, value)
|
|
105
|
+
else:
|
|
106
|
+
self._set(name, value)
|
|
107
|
+
|
|
108
|
+
|
|
24
109
|
def _set(self, name, value):
|
|
25
110
|
"""Set the value of an exclusive variable.
|
|
26
111
|
|
|
@@ -50,45 +135,22 @@ class PackageEnvironment(object):
|
|
|
50
135
|
self._env[name] = []
|
|
51
136
|
self._env[name].append(value)
|
|
52
137
|
|
|
53
|
-
def
|
|
54
|
-
"""
|
|
138
|
+
def _prepend(self, name, value):
|
|
139
|
+
"""Set the value of an append/prepend variable.
|
|
55
140
|
|
|
56
|
-
|
|
57
|
-
A list of objects OR an object with an "environment" key that contains a
|
|
58
|
-
list of objects. The latter is the structure of a package. Therefore we can initialize or extend
|
|
59
|
-
a PackageEnvironment with a package.
|
|
141
|
+
Can be appended to with subsequent adds.
|
|
60
142
|
|
|
61
|
-
|
|
62
|
-
they are added according to their merge policy. See _set and _append above.
|
|
143
|
+
It is an error if the variable has already been declared with policy=exclusive.
|
|
63
144
|
"""
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
requested_platform = platform
|
|
74
|
-
|
|
75
|
-
if not self.platform:
|
|
76
|
-
self.platform = requested_platform or "linux"
|
|
77
|
-
elif requested_platform and requested_platform != self.platform:
|
|
78
|
-
raise ValueError("Can't change platform once initialized.")
|
|
79
|
-
|
|
80
|
-
for var in others:
|
|
81
|
-
name = var["name"]
|
|
82
|
-
value = var["value"]
|
|
83
|
-
policy = var["merge_policy"]
|
|
84
|
-
if policy not in ["append", "exclusive"]:
|
|
85
|
-
raise ValueError("Unexpected merge policy: %s" % policy)
|
|
86
|
-
|
|
87
|
-
if policy == "append":
|
|
88
|
-
self._append(name, value)
|
|
89
|
-
else:
|
|
90
|
-
self._set(name, value)
|
|
91
|
-
|
|
145
|
+
if self._env.get(name):
|
|
146
|
+
if not isinstance(self._env[name], list):
|
|
147
|
+
raise ValueError(
|
|
148
|
+
"Can't change merge policy for '{}' from 'exclusive' to 'prepend'.".format(name)
|
|
149
|
+
)
|
|
150
|
+
else:
|
|
151
|
+
self._env[name] = []
|
|
152
|
+
self._env[name].insert(0, value)
|
|
153
|
+
|
|
92
154
|
def __iter__(self):
|
|
93
155
|
"""Cast the object as a dict."""
|
|
94
156
|
sep = ";" if self.platform == "windows" else ":"
|
ciocore/package_query.py
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Generate markdown from the software packages list.
|
|
3
|
+
"""
|
|
4
|
+
import os
|
|
5
|
+
import sys
|
|
6
|
+
import json
|
|
7
|
+
from ciocore.package_tree import PackageTree
|
|
8
|
+
from ciocore import api_client
|
|
9
|
+
import markdown
|
|
10
|
+
import io
|
|
11
|
+
import tempfile
|
|
12
|
+
import webbrowser
|
|
13
|
+
|
|
14
|
+
PURE = """
|
|
15
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/purecss@3.0.0/build/pure-min.css" integrity="sha384-X38yfunGUhNzHpBaEBsWLO+A0HDYOQi8ufWDkZ0k9e0eXz/tH3II7uKZ9msv++Ls" crossorigin="anonymous">
|
|
16
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def green(rhs):
|
|
20
|
+
return "\033[92m{}\033[0m".format(rhs)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def red(rhs):
|
|
24
|
+
return "\033[91m{}\033[0m".format(rhs)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def blue(rhs):
|
|
28
|
+
return "\033[94m{}\033[0m".format(rhs)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def magenta(rhs):
|
|
32
|
+
return "\033[95m{}\033[0m".format(rhs)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def raw(rhs, stream):
|
|
36
|
+
stream.write("{}\n\n".format(rhs))
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def d(n, rhs, stream):
|
|
40
|
+
"""Indent with dashes"""
|
|
41
|
+
stream.write("{} {}\n".format("-" * n, rhs))
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def hr(stream):
|
|
45
|
+
stream.write("---\n\n")
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def h(n, rhs, stream):
|
|
49
|
+
stream.write("{} {}\n\n".format("#" * n, rhs))
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def plugin_table_header(stream):
|
|
53
|
+
stream.write(
|
|
54
|
+
'|<div style="width:150px">Plugin</div> |<div style="min-width:400px">Versions</div>|\n|:------------|:-------------|\n'
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def plugin_table_row(plugin, versions, stream):
|
|
59
|
+
stream.write("|{}|{}|\n".format(plugin, versions))
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def write_markdown(hostnames, tree_data, platform, stream):
|
|
63
|
+
"""
|
|
64
|
+
Write the tree of packages in Markdown.
|
|
65
|
+
|
|
66
|
+
Use this to generate docs for the Conductor mkdocs site.
|
|
67
|
+
"""
|
|
68
|
+
if not hostnames:
|
|
69
|
+
return
|
|
70
|
+
h(2, "{} Software".format(platform.capitalize()), stream)
|
|
71
|
+
last_hostgroup = None
|
|
72
|
+
for hostname in hostnames:
|
|
73
|
+
display_hostname = " ".join(hostname.split()[:2])
|
|
74
|
+
hostgroup = hostname.split(" ")[0]
|
|
75
|
+
stream.write("\n")
|
|
76
|
+
if not hostgroup == last_hostgroup:
|
|
77
|
+
hr(stream)
|
|
78
|
+
h(3, hostgroup, stream)
|
|
79
|
+
h(4, display_hostname, stream)
|
|
80
|
+
last_hostgroup = hostgroup
|
|
81
|
+
plugins = tree_data.supported_plugins(hostname)
|
|
82
|
+
if plugins:
|
|
83
|
+
plugin_table_header(stream)
|
|
84
|
+
for plugin in plugins:
|
|
85
|
+
plugin_table_row(
|
|
86
|
+
plugin["plugin"], ", ".join(plugin["versions"]), stream
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def write_text(hostnames, tree_data, platform, color_func, stream):
|
|
91
|
+
"""
|
|
92
|
+
Write the tree of packages as text.
|
|
93
|
+
|
|
94
|
+
Products are indented with one dash.
|
|
95
|
+
Host packages are indented with two dashes.
|
|
96
|
+
Plugin packages are indented with three dashes.
|
|
97
|
+
"""
|
|
98
|
+
if not hostnames:
|
|
99
|
+
d(0, red("There are no '{}' host packages".format(platform)), stream)
|
|
100
|
+
return
|
|
101
|
+
d(0, "{} Software".format(platform).upper(), stream)
|
|
102
|
+
last_hostgroup = None
|
|
103
|
+
for hostname in hostnames:
|
|
104
|
+
display_hostname = " ".join(hostname.split()[:2])
|
|
105
|
+
hostgroup = hostname.split(" ")[0]
|
|
106
|
+
if not hostgroup == last_hostgroup:
|
|
107
|
+
d(0, green("-" * 30), stream)
|
|
108
|
+
d(1, color_func(hostgroup), stream)
|
|
109
|
+
d(2, color_func(display_hostname), stream)
|
|
110
|
+
last_hostgroup = hostgroup
|
|
111
|
+
plugins = tree_data.supported_plugins(hostname)
|
|
112
|
+
if plugins:
|
|
113
|
+
for plugin in plugins:
|
|
114
|
+
d(
|
|
115
|
+
3,
|
|
116
|
+
color_func(
|
|
117
|
+
"{} [{}]".format(
|
|
118
|
+
plugin["plugin"], ", ".join(plugin["versions"])
|
|
119
|
+
)
|
|
120
|
+
),
|
|
121
|
+
stream,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
def sort_hostnames_by_version(hostnames):
|
|
125
|
+
def sort_version(pkg):
|
|
126
|
+
hostname, product, version, platform = pkg
|
|
127
|
+
return f"{version} {product} {platform}"
|
|
128
|
+
def sort_product(pkg):
|
|
129
|
+
hostname, product, version, platform = pkg
|
|
130
|
+
return f"{product} {platform}"
|
|
131
|
+
pkg_sortable = [(hostname, hostname.split()[0], hostname.split()[1], hostname.split()[2]) for hostname in hostnames]
|
|
132
|
+
_psorted = sorted(pkg_sortable, key=sort_version, reverse=True)
|
|
133
|
+
_sorted = sorted(_psorted, key=sort_product)
|
|
134
|
+
return [pkg[0] for pkg in _sorted]
|
|
135
|
+
|
|
136
|
+
def pq(format="text"):
|
|
137
|
+
packages = api_client.request_software_packages()
|
|
138
|
+
|
|
139
|
+
tree_data = PackageTree(packages)
|
|
140
|
+
|
|
141
|
+
hostnames = sort_hostnames_by_version(tree_data.supported_host_names())
|
|
142
|
+
linux_hostnames = [h for h in hostnames if h.endswith("linux")]
|
|
143
|
+
windows_hostnames = [h for h in hostnames if h.endswith("windows")]
|
|
144
|
+
|
|
145
|
+
if format == "markdown":
|
|
146
|
+
stream = sys.stdout
|
|
147
|
+
raw(
|
|
148
|
+
"This page contains the complete list of software available at Conductor. If you require applications or plugins that are not in the list, please [create a support ticket](https://support.conductortech.com/hc/en-us/requests/new) and let us know.",
|
|
149
|
+
stream,
|
|
150
|
+
)
|
|
151
|
+
write_markdown(linux_hostnames, tree_data, "linux", stream)
|
|
152
|
+
write_markdown(windows_hostnames, tree_data, "windows", stream)
|
|
153
|
+
elif format == "text":
|
|
154
|
+
stream = sys.stdout
|
|
155
|
+
write_text(linux_hostnames, tree_data, "linux", magenta, stream)
|
|
156
|
+
d(0, "", stream)
|
|
157
|
+
write_text(windows_hostnames, tree_data, "windows", blue, stream)
|
|
158
|
+
elif format == "html":
|
|
159
|
+
stream = io.StringIO()
|
|
160
|
+
raw(
|
|
161
|
+
"This page contains the complete list of software available at Conductor. If you require applications or plugins that are not in the list, please [create a support ticket](https://support.conductortech.com/hc/en-us/requests/new) and let us know.",
|
|
162
|
+
stream,
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
write_markdown(linux_hostnames, tree_data, "linux", stream)
|
|
166
|
+
write_markdown(windows_hostnames, tree_data, "windows", stream)
|
|
167
|
+
|
|
168
|
+
html = markdown.markdown(
|
|
169
|
+
stream.getvalue(), extensions=["markdown.extensions.tables"]
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
html = decorate(html)
|
|
173
|
+
|
|
174
|
+
stream.close()
|
|
175
|
+
with tempfile.NamedTemporaryFile(mode="w", suffix=".html", delete=False) as f:
|
|
176
|
+
f.write(html)
|
|
177
|
+
webbrowser.open("file://" + f.name, new=2)
|
|
178
|
+
|
|
179
|
+
def decorate(html):
|
|
180
|
+
html = html.replace("<table>", '<table class="pure-table pure-table-bordered">')
|
|
181
|
+
html = '<html><head>{}</head><body style="margin: 2em;">{}</body></html>'.format(PURE, html)
|
|
182
|
+
return html
|