Skip to content

Commit

Permalink
fix: jans-cli-tui (#3287)
Browse files Browse the repository at this point in the history
* fix(jans-cli-tui) fix Empty spaces in multi tab properties ref:(#3286)

* fix: jans-cli-tui save script location

* fix: jans-linux-tui remove updatedAt from user edit

* fix: jans-cli-tui user-edit None value

* fix:jans-cli-tui rename jans_date_picker

* fix:jans-cli-tui refactor test files for renaming jans_date_picker

* fix:jans-cli-tui fix import error

* feat:jans-cli-tui add mouse menu for cut, paste, copy (ref: #2712)

* fix:jans-cli-tui remove unused imports

* fix:jans-cli-tui change user password (ref: #3360)

* fix: jans-cli-tui imports

* Revert "fix: jans-cli-tui imports"

This reverts commit 9978479.

* fix: jans-cli-tui imports

* feat: jans-cli-tui option --no-tui

* fix:jans-cli-tui unable to search user in search box (ref: #3353)

* fix: jans-cli-tui searches should call <get>if no search string entered (ref: #3379)

* fix:jans-cli-tui reverting changes for worng user password implementation (ref: #3360)

* fix: jans-cli-tui user patch operation

* fix: rename 010_oxauth as 010_auth_server

* fix: rename oxauth to_oauth

* fix: jans-cli-tui parse escaped colon for patch (ref: #3448)

* fix: jans-cli-tui fix typo (ref: #3475)

* fix:jans-cli-tui fix script search (ref #3468)

* fix:jans-cli-tui fix script search (ref #3468)

* fix: jan-cli-tui add none option to tokenEndpointAuthMethod (ref: #3463)

* fix: jans-cli-tui code smells

* fix: jans-cli-tui code smells

* fix: jans-cli-tui code smells

* fix: jans-cli-tui code smells

* fix: jans-cli-tui typo

Co-authored-by: AbdelwahabAdam <abdelwahabosama.1@gmail.com>
  • Loading branch information
devrimyatar and AbdelwahabAdam committed Jan 2, 2023
1 parent 458a8e3 commit 27e7518
Show file tree
Hide file tree
Showing 19 changed files with 509 additions and 347 deletions.
31 changes: 19 additions & 12 deletions jans-cli-tui/cli_tui/cli/config_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -1126,7 +1126,11 @@ def patch_requests(self, endpoint, url_param_dict, data):
security = self.get_scope_for_endpoint(endpoint)
self.get_access_token(security)

headers = self.get_request_header({'Accept': 'application/json', 'Content-Type': 'application/json-patch+json'})
content_key = 'application/json-patch+json'
for content_key in endpoint.info.get('requestBody', {}).get('content', {}):
break

headers = self.get_request_header({'Accept': 'application/json', 'Content-Type': content_key})
data = data
response = requests.patch(
url=url,
Expand Down Expand Up @@ -1361,17 +1365,18 @@ def process_command_patch(self, path, suffix_param, endpoint_params, data_fn, da
except ValueError as ve:
self.exit_with_error(str(ve))

if not isinstance(data, list):
if ('configuser' not in endpoint.path) and (not isinstance(data, list)):
self.exit_with_error("{} must be array of /components/schemas/PatchRequest".format(data_fn))

op_modes = ('add', 'remove', 'replace', 'move', 'copy', 'test')
if 'configuser' not in endpoint.path:
op_modes = ('add', 'remove', 'replace', 'move', 'copy', 'test')

for item in data:
if not item['op'] in op_modes:
print("op must be one of {}".format(', '.join(op_modes)))
sys.exit()
if not item['path'].startswith('/'):
item['path'] = '/' + item['path']
for item in data:
if not item['op'] in op_modes:
print("op must be one of {}".format(', '.join(op_modes)))
sys.exit()
if not item['path'].startswith('/'):
item['path'] = '/' + item['path']

response = self.patch_requests(endpoint, suffix_param, data)

Expand Down Expand Up @@ -1419,11 +1424,13 @@ def process_command_by_id(self, operation_id, url_suffix, endpoint_args, data_fn
pdata = args.patch_replace

if pop:
if pop != 'remove' and pdata.count(':') != 1:
self.exit_with_error("Please provide --patch-data as colon delimited key:value pair")
if pop != 'remove':
try:
ppath, pval = self.unescaped_split(pdata, ':')
except Exception:
self.exit_with_error("Please provide --patch-data as colon delimited key:value pair.\nUse escape if you need colon in value or key, i.e. mtlsUserInfoEndpoint:https\\:example.jans.io/userinfo")

if pop != 'remove':
ppath, pval = pdata.split(':')
data = [{'op': pop, 'path': '/'+ ppath.lstrip('/'), 'value': pval}]
else:
data = [{'op': pop, 'path': '/'+ pdata.lstrip('/')}]
Expand Down
18 changes: 18 additions & 0 deletions jans-cli-tui/cli_tui/cli_style.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,24 @@

"outh-titledtext":"green",
"outh-label":"blue",

# PLUGINS
"plugin-navbar":"#2600ff",
"plugin-navbar-headcolor":"green",
"plugin-navbar-entriescolor":"blue",
"plugin-tabs":"",
"plugin-text":"green",
"plugin-textsearch":"",
"plugin-label":"bold",
"plugin-textrequired":"#8b000a",
"plugin-checkbox":"green",
"plugin-checkboxlist":"green",
"plugin-radiobutton":"green",
"plugin-dropdown":"green",
"plugin-widget":"green",
"plugin-container":"",
"plugin-container.text":"green",

## edit_client_dialog
"outh-client-navbar":"#2600ff",
"outh-client-navbar-headcolor":"green",
Expand Down
191 changes: 181 additions & 10 deletions jans-cli-tui/cli_tui/jans_cli_tui.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@
if os.path.exists(pylib_dir):
sys.path.insert(0, pylib_dir)

no_tui = False
if '--no-tui' in sys.argv:
sys.argv.remove('--no-tui')
no_tui = True

from cli import config_cli

if no_tui:
config_cli.main()
sys.exit()

import prompt_toolkit
from prompt_toolkit.application import Application
from prompt_toolkit.application.current import get_app
Expand Down Expand Up @@ -63,19 +74,16 @@
from typing import TypeVar, Callable
from prompt_toolkit.widgets import Button, Dialog, Label

# -------------------------------------------------------------------------- #
from cli import config_cli
from utils.validators import IntegerValidator
from wui_components.jans_cli_dialog import JansGDialog
from wui_components.jans_nav_bar import JansNavBar
from wui_components.jans_message_dialog import JansMessageDialog

from cli_style import style

import cli_style

from utils.multi_lang import _
# -------------------------------------------------------------------------- #
from prompt_toolkit.mouse_events import MouseEvent, MouseEventType
from prompt_toolkit.keys import Keys


home_dir = Path.home()
config_dir = home_dir.joinpath('.config')
Expand Down Expand Up @@ -109,6 +117,7 @@ def __init__(self):
self.cli_object_ok = False
self.pbar_text = ""
self.progressing_text = ""
self.mouse_float=True

self.not_implemented = Frame(
body=HSplit([Label(text=_("Not imlemented yet")), Button(text=_("MyButton"))], width=D()),
Expand Down Expand Up @@ -290,7 +299,7 @@ async def coroutine():
await self.show_dialog_as_float(dialog)
try:
app.layout.focus(focused_before)
except:
except Exception:
app.layout.focus(self.center_frame)

self.start_progressing()
Expand Down Expand Up @@ -364,7 +373,7 @@ async def coroutine():
result = await self.show_dialog_as_float(dialog)
try:
app.layout.focus(focused_before)
except:
except Exception:
app.layout.focus(self.center_frame)

self.create_cli()
Expand All @@ -380,6 +389,167 @@ def set_keybindings(self) -> None:
self.bindings.add('f1')(self.help)
self.bindings.add('escape')(self.escape)
self.bindings.add('s-up')(self.up)
self.bindings.add(Keys.Vt100MouseEvent)(self.mouse)



def mouse(self,event): ### mouse: [<35;108;20M

pieces = event.data.split(";") ##['LEFT', 'MOUSE_DOWN', '146', '10']
mouse_click=int(pieces[0][3:])
mouse_state=str(pieces[2][-1:])
x = int(pieces[1])
y = int(pieces[2][:-1])

mouse_event, x, y = map(int, [mouse_click,x,y])
m = mouse_state

mouse_event = {
(0, 'M'): MouseEventType.MOUSE_DOWN,
(0, 'm'): MouseEventType.MOUSE_UP,
(2, 'M'): MouseEventType.MOUSE_DOWN,
(2, 'm'): MouseEventType.MOUSE_UP,
(64, 'M'): MouseEventType.SCROLL_UP,
(65, 'M'): MouseEventType.SCROLL_DOWN,
}.get((mouse_event, m))

mouse_click = {
0: "LEFT",
2: "RIGHT"
}.get(mouse_click)


# ------------------------------------------------------------------------------------ #
# ------------------------------------------------------------------------------------ #
# ------------------------------------------------------------------------------------ #
style_tmp = '<style >{}</style>'
style_tmp_red = '<style fg="ansired" bg="#00FF00">{}</style>'

res=[]
res.append(HTML(style_tmp.format("Copy")))
res.append("\n")
res.append(HTML(style_tmp.format("Cut")))
res.append("\n")
res.append(HTML(style_tmp.format("Paste")))
res.append("\n")

content= Window(
content=FormattedTextControl(
text=merge_formatted_text(res),
focusable=True,
), height=D())
floa=Float(content=content, left=x,top=y)
floa.name='mouse'

# ------------------------------------------------------------------------------------ #
# ------------------------------------------------------------------------------------ #
# ------------------------------------------------------------------------------------ #

if mouse_click == "RIGHT" and mouse_event == MouseEventType.MOUSE_DOWN :
if self.mouse_float == True :
self.root_layout.floats.append(floa)
self.mouse_cord=(x,y)
self.mouse_float = False
else:
try:
if get_app().layout.container.floats:
if get_app().layout.container.floats[-1].name =='mouse':
get_app().layout.container.floats.remove(get_app().layout.container.floats[-1])
self.root_layout.floats.append(floa)
self.mouse_cord=(x,y)
self.mouse_float = False
else:
self.root_layout.floats.append(floa)
self.mouse_cord=(x,y)
self.mouse_float = False
else:
self.root_layout.floats.append(floa)
self.mouse_cord=(x,y)
self.mouse_float = False
except Exception:
pass

elif mouse_click == "LEFT" and mouse_event == MouseEventType.MOUSE_DOWN and self.mouse_float == False:
try:
if get_app().layout.container.floats:
if get_app().layout.container.floats[-1].name =='mouse':

if self.mouse_select =='Copy':
data = get_app().current_buffer.copy_selection(False)
get_app().clipboard.set_data(data)
get_app().layout.container.floats.remove(get_app().layout.container.floats[-1])
self.mouse_float = True

elif self.mouse_select =='Paste':
data = get_app().clipboard.get_data()
get_app().current_buffer.paste_clipboard_data(data)
get_app().layout.container.floats.remove(get_app().layout.container.floats[-1])
self.mouse_float = True

elif self.mouse_select =='Cut':
data = get_app().current_buffer.copy_selection(True)
get_app().clipboard.set_data(data)
get_app().layout.container.floats.remove(get_app().layout.container.floats[-1])
self.mouse_float = True

else:
get_app().layout.container.floats.remove(get_app().layout.container.floats[-1])
self.mouse_float = True

except Exception:
pass


if get_app().layout.container.floats:
try :
get_float_name = get_app().layout.container.floats[-1].name
except Exception:
get_float_name = ''

if get_float_name =='mouse':
if self.mouse_cord[0] <= x and self.mouse_cord[0] >= x-5:
if self.mouse_cord[1] == y-1:
res = []
res.append(HTML(style_tmp_red.format("Copy ")))
res.append("\n")
res.append(HTML(style_tmp.format("Cut")))
res.append("\n")
res.append(HTML(style_tmp.format("Paste")))
res.append("\n")
get_app().layout.container.floats[-1].content.content.text=merge_formatted_text(res)
self.mouse_select = 'Copy'
elif self.mouse_cord[1] == y-2:
res = []
res.append(HTML(style_tmp.format("Copy")))
res.append("\n")
res.append(HTML(style_tmp_red.format("Cut ")))
res.append("\n")
res.append(HTML(style_tmp.format("Paste")))
res.append("\n")
get_app().layout.container.floats[-1].content.content.text=merge_formatted_text(res)
self.mouse_select = 'Cut'
elif self.mouse_cord[1] == y-3:
res = []
res.append(HTML(style_tmp.format("Copy")))
res.append("\n")
res.append(HTML(style_tmp.format("Cut")))
res.append("\n")
res.append(HTML(style_tmp_red.format("Paste")))
res.append("\n")
get_app().layout.container.floats[-1].content.content.text=merge_formatted_text(res)
self.mouse_select = 'Paste'
else:
self.mouse_select = 'None'
else:
res = []
res.append(HTML(style_tmp.format("Copy")))
res.append("\n")
res.append(HTML(style_tmp.format("Cut")))
res.append("\n")
res.append(HTML(style_tmp.format("Paste")))
res.append("\n")
get_app().layout.container.floats[-1].content.content.text=merge_formatted_text(res)
self.mouse_select = 'None'

def up(self, ev: KeyPressEvent) -> None:
get_app().layout.focus(Frame(self.nav_bar.nav_window))
Expand Down Expand Up @@ -548,7 +718,8 @@ def custom_handler():
if on_selection_changed:
rl._handle_enter = custom_handler

v = VSplit([Label(text=title, width=len(title), style=style), rl])
v = VSplit([Window(FormattedTextControl(title), width=len(title)+1, style=style,), rl], padding=1)

v.me = rl

return v
Expand Down Expand Up @@ -633,7 +804,7 @@ async def coroutine():
result = await self.show_dialog_as_float(dialog)
try:
self.layout.focus(focused_before)
except:
except Exception:
self.layout.focus(self.center_frame)

return result
Expand Down
Loading

0 comments on commit 27e7518

Please sign in to comment.