Skip to content
This repository has been archived by the owner on Mar 6, 2024. It is now read-only.

Commit

Permalink
Add ui extensions commands
Browse files Browse the repository at this point in the history
Following commads are added: generate, list, deploy, delete.
They will help the user to manage his ui extensions.

CLI Spinner class is implemented to indicate the action of the user.

Extension generator is class which inherits
generator abstract class and
give the ability to copy existing template from
the file system, of the user, and populate it
with the data, given by the user.

Prompt and PromptLauncher classes are
build on top of python click lib to give
the ability to validate and collect
the data from the user.
Signed-off-by: Nikola Vladimirov Iliev <[email protected]>
  • Loading branch information
Nikola Vladimirov Iliev committed Sep 19, 2018
1 parent bbef5ad commit 6f55d31
Show file tree
Hide file tree
Showing 25 changed files with 1,242 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ docs/_build/
target/

.idea/
.vscode/

docs/.bundle
docs/_site
Expand Down
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ python:
install:
- pip install git+https://github.com/vmware/pyvcloud.git
- pip install -r requirements.txt
- pip install -e .
- python setup.py install
- pip install tox

Expand Down
1 change: 1 addition & 0 deletions tests/run-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ D=`dirname $0`
$D/tenant-onboard.sh
$D/tenant-operations.sh
$D/cleanup.sh
$D/ui-ext-test.sh
23 changes: 23 additions & 0 deletions tests/ui-ext-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env bash

set -e

VCD="C:\Users\nvladimirovi\AppData\Roaming\Python\Python36\Scripts\vcd.exe"
VCD_UI_EXT_ABS_PATH=D:/test-py-cli/ui_plugin
VCD_HOST=bos1-vcd-sp-static-198-58.eng.vmware.com
VCD_ORG=System
VCD_USER=administrator
VCD_PASSWORD='********'

# $VCD login $VCD_HOST $VCD_ORG $VCD_USER --password $VCD_PASSWORD

$VCD version

echo 'This should deploy ui extension'
$VCD uiext deploy --path $VCD_UI_EXT_ABS_PATH -p -pr
echo 'This should list all ui extensions'
$VCD uiext list
echo 'This should delete all ui extensions'
$VCD uiext delete -a
echo 'This list command should print "There are no UI Extensions..." in the command line'
$VCD uiext list
Empty file added utilities/__init__.py
Empty file.
12 changes: 12 additions & 0 deletions utilities/colors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from enum import Enum

Colors = Enum('Colors', {
'HEADER': '\033[95m',
'OKBLUE': '\033[94m',
'OKGREEN': '\033[92m',
'WARNING': '\033[93m',
'FAIL': '\033[91m',
'ENDC': '\033[0m',
'BOLD': '\033[1m',
'UNDERLINE': '\033[4m'
})
Empty file added utilities/ui_ext/__init__.py
Empty file.
Empty file.
153 changes: 153 additions & 0 deletions utilities/ui_ext/cli_spinners/cli_spinner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import threading, time, sys
from enum import Enum

Spinners = Enum('Spinners', {
"line": {
"interval": 130,
"frames": [
"-",
"\\",
"|",
"/"
]
},
"dots": {
"interval": 500,
"frames": [
".",
"..",
"..."
]
}
})

def backspace(n):
# print((b'\x08').decode(), end='') # use \x08 char to go back
print('\r', end='')

class CliSpinner:
"""CliSpinner library.
Attributes
----------
CLEAR_LINE : str
Code to clear the line
"""
CLEAR_LINE = '\033[K'

def __init__(self, text=None, spinner='dots', placement='left', stream=sys.stdout):
"""Constructs the CliSpinner object.
Parameters
----------
text : str, optional
Text to display while spinning.
spinner : str|dict, optional
String or dictionary representing spinner. String can be one of 2 spinners
supported.
placement: str, optional
Side of the text to place the spinner on. Can be `left` or `right`.
Defaults to `left`.
stream : io, optional
Output.
"""
self._spinner = Spinners[spinner].value
self.text = text
self._stop_spinner = None
self._interval = self._spinner['interval']
self._stream = stream
self._frame_index = 0
self._placement = placement

def clear(self):
"""Clears the line and returns cursor to the start.
of line
Returns
-------
self
"""
self._stream.write('\r')
self._stream.write(self.CLEAR_LINE)

return self

def _frame(self):
"""Builds and returns the frame to be rendered
Returns
-------
frame
"""
frame = self._spinner['frames'][self._frame_index]
self._frame_index += 1

if self._frame_index == len(self._spinner['frames']):
self._frame_index = 0

return frame

def _render_frame(self):
"""Renders the frame on the line after clearing it.
"""
frame = self._frame()

if self.text is not None:
output = u'{0} {1}'.format(*[
(self.text, frame)
if self._placement == 'right' else
(frame, self.text)
][0])
else:
output = '{0}'.format(frame)
self._stream.write(output)
backspace(len(output))

def _render(self):
"""Runs the render until thread flag is set.
Returns
-------
self
"""
while not self._stop_spinner.is_set():
self._render_frame()
time.sleep(0.001 * self._interval)

return self

def start(self, text=None):
"""Starts the spinner on a separate thread.
Parameters
----------
text : None, optional
Text to be used alongside spinner
Returns
-------
self
"""
if text is not None:
self.text = text

self._stop_spinner = threading.Event()
self._spinner_thread = threading.Thread(target=self._render)
self._spinner_thread.setDaemon(True)
self._render_frame()
self._spinner_id = self._spinner_thread.name
self._spinner_thread.start()

return self

def stop(self, message=None):
"""Stops the spinner and clears the line.
Returns
-------
self
"""
if self._spinner_thread:
self._stop_spinner.set()
self._spinner_thread.join()

self._frame_index = 0
self._spinner_id = None
self.clear()

if message is not None:
print(message)

return self
Empty file.
Loading

0 comments on commit 6f55d31

Please sign in to comment.