Add install button

This commit is contained in:
Mauricio Baeza 2020-11-12 19:35:29 -06:00
parent 233a7c1fbf
commit 41681330d3
10 changed files with 3993 additions and 4703 deletions

View File

@ -1 +1 @@
0.5.0 0.6.0

View File

@ -26,7 +26,7 @@ import logging
TYPE_EXTENSION = 1 TYPE_EXTENSION = 1
# ~ https://semver.org/ # ~ https://semver.org/
VERSION = '0.5.0' VERSION = '0.6.0'
# ~ Your great extension name, not used spaces # ~ Your great extension name, not used spaces
NAME = 'ZAZPip' NAME = 'ZAZPip'
@ -112,7 +112,7 @@ MENU_MAIN = {}
MENUS = ( MENUS = (
{ {
'title': {'en': 'Open Pip', 'es': 'Abrir Pip'}, 'title': {'en': 'Open Pip', 'es': 'Abrir Pip'},
'argument': 'open', 'argument': 'open_dialog_pip',
'context': '', 'context': '',
'icon': 'icon', 'icon': 'icon',
'toolbar': False, 'toolbar': False,

View File

@ -67,6 +67,7 @@ import unohelper
from com.sun.star.awt import MessageBoxButtons as MSG_BUTTONS from com.sun.star.awt import MessageBoxButtons as MSG_BUTTONS
from com.sun.star.awt.MessageBoxResults import YES from com.sun.star.awt.MessageBoxResults import YES
from com.sun.star.awt import Rectangle, Size, Point from com.sun.star.awt import Rectangle, Size, Point
from com.sun.star.awt.PosSize import POSSIZE
from com.sun.star.awt import Key, KeyModifier, KeyEvent from com.sun.star.awt import Key, KeyModifier, KeyEvent
from com.sun.star.container import NoSuchElementException from com.sun.star.container import NoSuchElementException
from com.sun.star.datatransfer import XTransferable, DataFlavor from com.sun.star.datatransfer import XTransferable, DataFlavor
@ -399,19 +400,6 @@ def _get_class_doc(obj: Any) -> Any:
return classes[type_doc](obj) return classes[type_doc](obj)
# ~ def _get_class_uno(obj: Any) -> Any:
# ~ classes = dict(
# ~ SwXTextGraphicObject = LOImage,
# ~ SvxShapeText = LOImage,
# ~ )
# ~ name = obj.ImplementationName
# ~ print(f'ImplementationName = {name}')
# ~ instance = obj
# ~ if name in classes:
# ~ instance = classes[name](obj)
# ~ return instance
def dict_to_property(values: dict, uno_any: bool=False): def dict_to_property(values: dict, uno_any: bool=False):
ps = tuple([PropertyValue(Name=n, Value=v) for n, v in values.items()]) ps = tuple([PropertyValue(Name=n, Value=v) for n, v in values.items()])
if uno_any: if uno_any:
@ -429,6 +417,14 @@ def _property_to_dict(values):
return d return d
def json_dumps(data):
return json.dumps(data, indent=4, sort_keys=True)
def json_loads(data):
return json.loads(data)
def data_to_dict(data): def data_to_dict(data):
if isinstance(data, tuple) and isinstance(data[0], tuple): if isinstance(data, tuple) and isinstance(data[0], tuple):
return _array_to_dict(data) return _array_to_dict(data)
@ -438,12 +434,6 @@ def data_to_dict(data):
return {} return {}
def _path_url(path: str) -> str:
if path.startswith('file://'):
return path
return uno.systemPathToFileUrl(path)
def _get_dispatch() -> Any: def _get_dispatch() -> Any:
return create_instance('com.sun.star.frame.DispatchHelper') return create_instance('com.sun.star.frame.DispatchHelper')
@ -1145,7 +1135,7 @@ class LODocument(object):
opt = dict_to_property(args) opt = dict_to_property(args)
if path: if path:
try: try:
self.obj.storeAsURL(_path_url(path), opt) self.obj.storeAsURL(_P.to_url(path), opt)
except Exception as e: except Exception as e:
error(e) error(e)
result = False result = False
@ -2828,7 +2818,7 @@ class LODocs(object):
http://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1frame_1_1XComponentLoader.html http://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1frame_1_1XComponentLoader.html
http://api.libreoffice.org/docs/idl/ref/servicecom_1_1sun_1_1star_1_1document_1_1MediaDescriptor.html http://api.libreoffice.org/docs/idl/ref/servicecom_1_1sun_1_1star_1_1document_1_1MediaDescriptor.html
""" """
path = _path_url(path) path = _P.to_url(path)
opt = dict_to_property(args) opt = dict_to_property(args)
doc = cls._desktop.loadComponentFromURL(path, '_default', 0, opt) doc = cls._desktop.loadComponentFromURL(path, '_default', 0, opt)
if doc is None: if doc is None:
@ -2994,9 +2984,10 @@ class EventsFocus(EventsListenerBase, XFocusListener):
# ~ HelpURL = ? # ~ HelpURL = ?
class UnoBaseObject(object): class UnoBaseObject(object):
def __init__(self, obj): def __init__(self, obj, path=''):
self._obj = obj self._obj = obj
self._model = obj.Model self._model = obj.Model
# ~ self._path = path
def __setattr__(self, name, value): def __setattr__(self, name, value):
exists = hasattr(self, name) exists = hasattr(self, name)
@ -3199,6 +3190,22 @@ class UnoBaseObject(object):
def tab_stop(self, value): def tab_stop(self, value):
self.model.Tabstop = value self.model.Tabstop = value
@property
def ps(self):
ps = self.obj.getPosSize()
return ps
@ps.setter
def ps(self, ps):
self.obj.setPosSize(ps.X, ps.Y, ps.Width, ps.Height, POSSIZE)
def set_focus(self):
self.obj.setFocus()
return
def ps_from(self, source):
self.ps = source.ps
return
def center(self, horizontal=True, vertical=False): def center(self, horizontal=True, vertical=False):
p = self.parent.Model p = self.parent.Model
w = p.Width w = p.Width
@ -3361,6 +3368,78 @@ class UnoImage(UnoBaseObject):
self.m.ImageURL = _P.to_url(value) self.m.ImageURL = _P.to_url(value)
class UnoListBox(UnoBaseObject):
def __init__(self, obj):
super().__init__(obj)
self._path = ''
def __setattr__(self, name, value):
if name in ('_path',):
self.__dict__[name] = value
else:
super().__setattr__(name, value)
@property
def type(self):
return 'listbox'
@property
def value(self):
return self.obj.getSelectedItem()
@property
def count(self):
return len(self.data)
@property
def data(self):
return self.model.StringItemList
@data.setter
def data(self, values):
self.model.StringItemList = list(sorted(values))
@property
def path(self):
return self._path
@path.setter
def path(self, value):
self._path = value
def unselect(self):
self.obj.selectItem(self.value, False)
return
def select(self, pos=0):
if isinstance(pos, str):
self.obj.selectItem(pos, True)
else:
self.obj.selectItemPos(pos, True)
return
def clear(self):
self.model.removeAllItems()
return
def _set_image_url(self, image):
if _P.exists(image):
return _P.to_url(image)
path = _P.join(self._path, DIR['images'], image)
return _P.to_url(path)
def insert(self, value, path='', pos=-1, show=True):
if pos < 0:
pos = self.count
if path:
self.model.insertItem(pos, value, self._set_image_url(path))
else:
self.model.insertItemText(pos, value)
if show:
self.select(pos)
return
UNO_CLASSES = { UNO_CLASSES = {
'label': UnoLabel, 'label': UnoLabel,
'link': UnoLabelLink, 'link': UnoLabelLink,
@ -3369,6 +3448,7 @@ UNO_CLASSES = {
'check': UnoCheck, 'check': UnoCheck,
'text': UnoText, 'text': UnoText,
'image': UnoImage, 'image': UnoImage,
'listbox': UnoListBox,
} }
@ -3382,9 +3462,9 @@ class LODialog(object):
'check': 'com.sun.star.awt.UnoControlCheckBoxModel', 'check': 'com.sun.star.awt.UnoControlCheckBoxModel',
'text': 'com.sun.star.awt.UnoControlEditModel', 'text': 'com.sun.star.awt.UnoControlEditModel',
'image': 'com.sun.star.awt.UnoControlImageControlModel', 'image': 'com.sun.star.awt.UnoControlImageControlModel',
'listbox': 'com.sun.star.awt.UnoControlListBoxModel',
# ~ 'grid': 'com.sun.star.awt.grid.UnoControlGridModel', # ~ 'grid': 'com.sun.star.awt.grid.UnoControlGridModel',
# ~ 'groupbox': 'com.sun.star.awt.UnoControlGroupBoxModel', # ~ 'groupbox': 'com.sun.star.awt.UnoControlGroupBoxModel',
# ~ 'listbox': 'com.sun.star.awt.UnoControlListBoxModel',
# ~ 'roadmap': 'com.sun.star.awt.UnoControlRoadmapModel', # ~ 'roadmap': 'com.sun.star.awt.UnoControlRoadmapModel',
# ~ 'tree': 'com.sun.star.awt.tree.TreeControlModel', # ~ 'tree': 'com.sun.star.awt.tree.TreeControlModel',
# ~ 'pages': 'com.sun.star.awt.UnoMultiPageModel', # ~ 'pages': 'com.sun.star.awt.UnoMultiPageModel',
@ -3405,7 +3485,7 @@ class LODialog(object):
path = args.pop('Path', '') path = args.pop('Path', '')
if path: if path:
dp = create_instance(service, True) dp = create_instance(service, True)
dlg = dp.createDialog(_path_url(path)) dlg = dp.createDialog(_P.to_url(path))
return dlg return dlg
if 'Location' in args: if 'Location' in args:
@ -3446,6 +3526,9 @@ class LODialog(object):
return self._controls return self._controls
@property @property
def path(self):
return self._path
@property
def id(self): def id(self):
return self._id return self._id
@id.setter @id.setter
@ -3474,6 +3557,13 @@ class LODialog(object):
def visible(self, value): def visible(self, value):
self.obj.Visible = value self.obj.Visible = value
@property
def step(self):
return self.model.Step
@step.setter
def step(self, value):
self.model.Step = value
@property @property
def events(self): def events(self):
return self._events return self._events
@ -3539,6 +3629,8 @@ class LODialog(object):
control = self.obj.getControl(name) control = self.obj.getControl(name)
_add_listeners(self.events, control, name) _add_listeners(self.events, control, name)
control = UNO_CLASSES[tipo](control) control = UNO_CLASSES[tipo](control)
if tipo in ('listbox',):
control.path = self.path
if tipo == 'tree' and root: if tipo == 'tree' and root:
control.root = root control.root = root

View File

@ -11,7 +11,7 @@
<value/> <value/>
</prop> </prop>
<prop oor:name="URL" oor:type="xs:string"> <prop oor:name="URL" oor:type="xs:string">
<value>service:net.elmau.zaz.pip?open</value> <value>service:net.elmau.zaz.pip?open_dialog_pip</value>
</prop> </prop>
<prop oor:name="Target" oor:type="xs:string"> <prop oor:name="Target" oor:type="xs:string">
<value>_self</value> <value>_self</value>

View File

@ -4,7 +4,7 @@
<node oor:name="Global"> <node oor:name="Global">
<node oor:name="P_SHIFT_MOD1_MOD2" oor:op="fuse"> <node oor:name="P_SHIFT_MOD1_MOD2" oor:op="fuse">
<prop oor:name="Command"> <prop oor:name="Command">
<value xml:lang="en-US">service:net.elmau.zaz.pip?open</value> <value xml:lang="en-US">service:net.elmau.zaz.pip?open_dialog_pip</value>
</prop> </prop>
</node> </node>
</node> </node>

View File

@ -1,507 +1,23 @@
import uno import uno
import unohelper import unohelper
from com.sun.star.task import XJobExecutor from com.sun.star.task import XJobExecutor
import easymacro as app import main
ID_EXTENSION = 'net.elmau.zaz.pip' ID_EXTENSION = 'net.elmau.zaz.pip'
SERVICE = ('com.sun.star.task.Job',) SERVICE = ('com.sun.star.task.Job',)
TITLE = 'ZAZ-PIP'
URL_PIP = 'https://bootstrap.pypa.io/get-pip.py'
PIP = 'pip'
PACKAGES = {
'cffi': 'ok.png',
'cryptography': 'ok.png',
'httpx': 'ok.png',
'lxml': 'ok.png',
'numpy': 'ok.png',
'pandas': 'ok.png',
'psycopg2-binary': 'ok.png',
'peewee': 'ok.png',
'pillow': 'ok.png',
'pytesseract': 'ok.png',
'sounddevice': 'ok.png',
}
_ = app.install_locales(__file__)
class Controllers(object):
OK1 = 'Successfully installed'
OK2 = 'Requirement already'
OK3 = 'Successfully uninstalled'
def __init__(self, dialog):
self.d = dialog
self.path_python = app.get_path_python()
self._states = {
'list': False,
'install': False,
'search': False,
'versions': False,
}
def _set_state(self, state):
for k in self._states.keys():
self._states[k] = False
self._states[state] = True
return
def cmd_install_pip_action(self, event):
msg = _('Do you want install PIP?')
if not app.question(msg, 'ZAZ-Pip'):
return
self._install_pip()
return
@app.run_in_thread
def _install_pip(self):
self.d.link_proyect.visible = False
self.d.lst_log.visible = True
path_pip = app.get_temp_file(True)
self.d.lst_log.insert('Download PIP...')
data, err = app.url_open(URL_PIP, verify=False)
if err:
msg = _('Do you have internet connection?')
app.errorbox('{}\n\n{}'.format(msg, err))
return
app.save_file(path_pip, 'wb', data)
if not app.is_created(path_pip):
msg = _('File PIP not save')
app.errorbox(msg)
return
self.d.lst_log.insert(_('PIP save correctly...'))
try:
self.d.lst_log.insert(_('Start installing PIP...'))
cmd = '"{}" "{}" --user'.format(self.path_python, path_pip)
for line in app.popen(cmd):
if isinstance(line, tuple):
app.errorbox(line)
break
self.d.lst_log.insert(line)
cmd = self._cmd_pip('-V')
label = app.run(cmd, True)
if label:
self.d.lbl_pip.value = label
self.d.cmd_install_pip.visible = False
self.d.cmd_admin_pip.visible = True
msg = _('PIP installed sucesfully')
app.msgbox(msg)
else:
msg = _('PIP not installed, see log')
app.warning(msg)
except Exception as e:
app.errorbox(e)
return
def _cmd_pip(self, args):
cmd = '"{}" -m pip {}'.format(self.path_python, args)
return cmd
def cmd_admin_pip_action(self, event):
self.d.lst_log.possize(self.d.lst_package)
self.d.lst_log.step = 1
self.d.step = 1
self.cmd_home_action(None)
return
def cmd_close_action(self, event):
self.d.close()
return
def cmd_home_action(self, event):
self.d.txt_search.value = ''
self._list()
return
def txt_search_key_released(self, event):
if event.KeyCode == app.KEY['enter']:
self.cmd_search_action(None)
return
if not self.d.txt_search.value.strip():
self.cmd_home_action(None)
return
@app.run_in_thread
def _list(self):
self._set_state('list')
self.d.lst_log.visible = False
self.d.lst_package.visible = True
cmd = self._cmd_pip(' list --format=json')
self.d.lst_package.clear()
result = app.run(cmd, True)
packages = app.json_loads(result)
for p in packages:
t = '{} - ({})'.format(p['name'], p['version'])
self.d.lst_package.insert(t, 'ok.png')
self.d.lst_package.select()
self.d.txt_search.set_focus()
return
@app.run_in_thread
def _search(self, value):
self._set_state('search')
line = ''
cmd = self._cmd_pip(' search {}'.format(value))
self.d.lst_package.clear()
for line in app.popen(cmd):
parts = line.split(')')
name = parts[0].strip() + ')'
description = parts[-1].strip()
parts = name.split('(')
name_verify = parts[0].strip()
package = '{} {}'.format(name, description)
image = PACKAGES.get(name_verify, 'question.png')
self.d.lst_package.insert(package, image)
if line:
self.d.lst_package.select()
else:
self.d.lst_package.insert(_('Not found...'), 'error.png', show=False)
return
def cmd_search_action(self, event):
search = self.d.txt_search.value.strip()
if not search:
self.d.txt_search.set_focus()
return
self._search(search)
return
@app.run_in_thread
def _install(self, value):
self._set_state('install')
self.d.lst_package.visible = False
self.d.lst_log.visible = True
line = ''
name = value.split(' ')[0].strip()
cmd = self._cmd_pip(' install --upgrade --user {}'.format(name))
self.d.lst_log.clear()
for line in app.popen(cmd):
if self.OK1 in line or self.OK2 in line:
self.d.lst_log.insert(line, 'ok.png')
else:
self.d.lst_log.insert(line)
return
@app.catch_exception
def lst_package_double_click(self, event):
opt = 'install'
if self._states['list']:
opt = 'upgrade'
name = self.d.lst_package.value
msg = _('Do you want {}:\n\n{} ?').format(opt, name)
if not app.question(msg, TITLE):
return
self._install(name)
return
@app.run_in_thread
def _uninstall(self, value):
self._set_state('install')
self.d.lst_package.visible = False
self.d.lst_log.visible = True
line = ''
name = value.split(' ')[0].strip()
cmd = self._cmd_pip(' uninstall -y {}'.format(name))
self.d.lst_log.clear()
for line in app.popen(cmd):
if self.OK3 in line:
self.d.lst_log.insert(line, 'ok.png')
else:
self.d.lst_log.insert(line)
return
def cmd_uninstall_action(self, event):
if not self._states['list']:
msg = _('Select installed package')
app.warning(msg)
return
name = self.d.lst_package.value
msg = _('Do you want uninstall:\n\n{} ?').format(name)
if not app.question(msg):
return
self._uninstall(name)
return
@app.catch_exception
def cmd_shell_action(self, name):
if app.IS_WIN:
cmd = '"{}"'.format(self.path_python)
app.open_file(cmd)
else:
cmd = 'exec "{}"'
if app.IS_MAC:
cmd = 'open "{}"'
elif app.DESKTOP == 'gnome':
cmd = 'gnome-terminal -- {}'
cmd = cmd.format(self.path_python)
app.run(cmd)
return
class ZAZPip(unohelper.Base, XJobExecutor): class ZAZPip(unohelper.Base, XJobExecutor):
def __init__(self, ctx): def __init__(self, ctx):
self.ctx = ctx self.ctx = ctx
def trigger(self, args): def trigger(self, args):
dialog = self._create_dialog() main.ID_EXTENSION = ID_EXTENSION
dialog.open() main.run(args, __file__)
return return
def _create_dialog(self):
args= {
'Name': 'dialog',
'Title': 'Zaz-Pip',
'Width': 200,
'Height': 220,
}
dialog = app.create_dialog(args)
dialog.id_extension = ID_EXTENSION
dialog.events = Controllers(dialog)
lbl_title = '{} {} - {}'.format(app.NAME, app.VERSION, app.OS)
args = {
'Type': 'Label',
'Name': 'lbl_title',
'Label': lbl_title,
'Width': 100,
'Height': 15,
'Border': 1,
'Align': 1,
'VerticalAlign': 1,
'Step': 10,
'FontHeight': 12,
}
dialog.add_control(args)
dialog.center(dialog.lbl_title, y=5)
path_python = app.get_path_python()
cmd = '"{}" -V'.format(path_python)
label = app.run(cmd, True)
args = {
'Type': 'Label',
'Name': 'lbl_python',
'Label': str(label),
'Width': 100,
'Height': 15,
'Border': 1,
'Align': 1,
'VerticalAlign': 1,
'Step': 10,
'FontHeight': 11,
}
dialog.add_control(args)
dialog.center(dialog.lbl_python, y=25)
cmd = '"{}" -m pip -V'.format(path_python)
label = app.run(cmd, True)
exists_pip = True
if not label:
exists_pip = False
label = _('PIP not installed')
args = {
'Type': 'Label',
'Name': 'lbl_pip',
'Label': label,
'Width': 160,
'Height': 30,
'Border': 1,
'Align': 1,
'VerticalAlign': 1,
'Step': 10,
'MultiLine': True,
}
dialog.add_control(args)
dialog.center(dialog.lbl_pip, y=45)
args = {
'Type': 'Button',
'Name': 'cmd_admin_pip',
'Label': _('Admin PIP'),
'Width': 60,
'Height': 18,
'Step': 10,
'ImageURL': 'python.png',
'ImagePosition': 1,
}
dialog.add_control(args)
dialog.center(dialog.cmd_admin_pip, y=80)
args = {
'Type': 'Button',
'Name': 'cmd_install_pip',
'Label': _('Install PIP'),
'Width': 60,
'Height': 18,
'Step': 10,
'ImageURL': 'install.png',
'ImagePosition': 1,
}
dialog.add_control(args)
dialog.center(dialog.cmd_install_pip, y=80)
args = {
'Type': 'Link',
'Name': 'link_proyect',
'URL': 'https://gitlab.com/mauriciobaeza/',
'Label': 'https://gitlab.com/mauriciobaeza/',
'Border': 1,
'Width': 130,
'Height': 15,
'Align': 1,
'VerticalAlign': 1,
'Step': 10,
}
dialog.add_control(args)
dialog.center(dialog.link_proyect, y=-5)
args = {
'Type': 'Listbox',
'Name': 'lst_log',
'Width': 160,
'Height': 105,
'Step': 10,
}
dialog.add_control(args)
dialog.center(dialog.lst_log, y=105)
args = {
'Type': 'Label',
'Name': 'lbl_package',
'Label': _('Packages'),
'Width': 100,
'Height': 15,
'Border': 1,
'Align': 1,
'VerticalAlign': 1,
'Step': 1,
}
dialog.add_control(args)
args = {
'Type': 'Text',
'Name': 'txt_search',
'Width': 180,
'Height': 12,
'Step': 1,
'Border': 0,
}
dialog.add_control(args)
args = {
'Type': 'Listbox',
'Name': 'lst_package',
'Width': 180,
'Height': 128,
'Step': 1,
}
dialog.add_control(args)
args = {
'Type': 'Button',
'Name': 'cmd_close',
'Label': _('~Close'),
'Width': 60,
'Height': 18,
'Step': 1,
'ImageURL': 'close.png',
'ImagePosition': 1,
# ~ 'PushButtonType': 2,
}
dialog.add_control(args)
dialog.center(dialog.cmd_close, y=-5)
args = {
'Type': 'Button',
'Name': 'cmd_home',
'Width': 18,
'Height': 18,
'Step': 1,
'ImageURL': 'home.png',
'FocusOnClick': False,
'Y': 2,
}
dialog.add_control(args)
args = {
'Type': 'Button',
'Name': 'cmd_search',
'Width': 18,
'Height': 18,
'Step': 1,
'ImageURL': 'search.png',
'FocusOnClick': False,
'Y': 2,
}
dialog.add_control(args)
args = {
'Type': 'Button',
'Name': 'cmd_uninstall',
'Width': 18,
'Height': 18,
'Step': 1,
'ImageURL': 'uninstall.png',
'FocusOnClick': False,
'Y': 2,
}
dialog.add_control(args)
args = {
'Type': 'Button',
'Name': 'cmd_shell',
'Width': 18,
'Height': 18,
'Step': 1,
'ImageURL': 'shell.png',
'FocusOnClick': False,
'Y': 2,
}
dialog.add_control(args)
controls = (dialog.cmd_home, dialog.cmd_search,
dialog.cmd_uninstall, dialog.cmd_shell)
dialog.lbl_package.move(dialog.cmd_home)
dialog.txt_search.move(dialog.lbl_package)
dialog.lst_package.move(dialog.txt_search)
dialog.lbl_package.center()
dialog.lst_package.center()
dialog.txt_search.center()
dialog.center(controls)
dialog.step = 10
dialog.cmd_install_pip.visible = not exists_pip
dialog.cmd_admin_pip.visible = exists_pip
dialog.lst_log.visible = False
return dialog
g_ImplementationHelper = unohelper.ImplementationHelper() g_ImplementationHelper = unohelper.ImplementationHelper()
g_ImplementationHelper.addImplementation(ZAZPip, ID_EXTENSION, SERVICE) g_ImplementationHelper.addImplementation(ZAZPip, ID_EXTENSION, SERVICE)

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<description xmlns="http://openoffice.org/extensions/description/2006" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:d="http://openoffice.org/extensions/description/2006"> <description xmlns="http://openoffice.org/extensions/description/2006" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:d="http://openoffice.org/extensions/description/2006">
<identifier value="net.elmau.zaz.pip"/> <identifier value="net.elmau.zaz.pip"/>
<version value="0.5.0"/> <version value="0.6.0"/>
<display-name> <display-name>
<name lang="en">ZAZ Pip</name> <name lang="en">ZAZ Pip</name>
<name lang="es">ZAZ Pip</name> <name lang="es">ZAZ Pip</name>

File diff suppressed because it is too large Load Diff

517
source/pythonpath/main.py Normal file
View File

@ -0,0 +1,517 @@
#!/usr/bin/env python3
import easymacro as app
ID_EXTENSION = ''
TITLE = 'ZAZ-PIP'
URL_PIP = 'https://bootstrap.pypa.io/get-pip.py'
PIP = 'pip'
URL_GIT = 'https://git.elmau.net/elmau'
PACKAGES = {
'cffi': 'ok.png',
'cryptography': 'ok.png',
'httpx': 'ok.png',
'lxml': 'ok.png',
'numpy': 'ok.png',
'pandas': 'ok.png',
'psycopg2-binary': 'ok.png',
'peewee': 'ok.png',
'pillow': 'ok.png',
'pytesseract': 'ok.png',
'sounddevice': 'ok.png',
}
def open_dialog_pip():
dialog = _create_dialog()
dialog.open()
return
def run(args, path_locales):
app.install_locales(path_locales)
globals()[args]()
return
@app.catch_exception
class Controllers(object):
OK1 = 'Successfully installed'
OK2 = 'Requirement already'
OK3 = 'Successfully uninstalled'
def __init__(self, dialog):
self.d = dialog
self.path_python = app.paths.python
self._states = {
'list': False,
'install': False,
'search': False,
'versions': False,
}
def _set_state(self, state):
for k in self._states.keys():
self._states[k] = False
self._states[state] = True
return
def cmd_install_pip_action(self, event):
msg = _('Do you want install PIP?')
if not app.question(msg, 'ZAZ-Pip'):
return
self._install_pip()
return
@app.run_in_thread
def _install_pip(self):
self.d.link_proyect.visible = False
self.d.lst_log.visible = True
path_pip = app.get_temp_file(True)
self.d.lst_log.insert('Download PIP...')
data, err = app.url_open(URL_PIP, verify=False)
if err:
msg = _('Do you have internet connection?')
app.errorbox('{}\n\n{}'.format(msg, err))
return
app.save_file(path_pip, 'wb', data)
if not app.is_created(path_pip):
msg = _('File PIP not save')
app.errorbox(msg)
return
self.d.lst_log.insert(_('PIP save correctly...'))
try:
self.d.lst_log.insert(_('Start installing PIP...'))
cmd = '"{}" "{}" --user'.format(self.path_python, path_pip)
for line in app.popen(cmd):
if isinstance(line, tuple):
app.errorbox(line)
break
self.d.lst_log.insert(line)
cmd = self._cmd_pip('-V')
label = app.run(cmd, True)
if label:
self.d.lbl_pip.value = label
self.d.cmd_install_pip.visible = False
self.d.cmd_admin_pip.visible = True
msg = _('PIP installed sucesfully')
app.msgbox(msg)
else:
msg = _('PIP not installed, see log')
app.warning(msg)
except Exception as e:
app.errorbox(e)
return
def _cmd_pip(self, args):
cmd = '"{}" -m pip {}'.format(self.path_python, args)
return cmd
@app.catch_exception
def cmd_admin_pip_action(self, event):
self.d.lst_log.ps_from(self.d.lst_package)
self.d.lst_log.step = 1
self.d.step = 1
self.cmd_home_action(None)
return
def cmd_close_action(self, event):
self.d.close()
return
def cmd_home_action(self, event):
self.d.txt_search.value = ''
self._list()
return
def txt_search_key_released(self, event):
if event.KeyCode == app.KEY['enter']:
self.cmd_search_action(None)
return
if not self.d.txt_search.value.strip():
self.cmd_home_action(None)
return
@app.run_in_thread
def _list(self):
self._set_state('list')
self.d.lst_log.visible = False
self.d.lst_package.visible = True
cmd = self._cmd_pip(' list --format=json')
self.d.lst_package.clear()
result = app.run(cmd, True)
packages = app.json_loads(result)
for p in packages:
t = '{} - ({})'.format(p['name'], p['version'])
self.d.lst_package.insert(t, 'ok.png')
self.d.lst_package.select()
self.d.txt_search.set_focus()
return
@app.run_in_thread
def _search(self, value):
self._set_state('search')
line = ''
cmd = self._cmd_pip(' search {}'.format(value))
self.d.lst_package.clear()
for line in app.popen(cmd):
parts = line.split(')')
name = parts[0].strip() + ')'
description = parts[-1].strip()
parts = name.split('(')
name_verify = parts[0].strip()
package = '{} {}'.format(name, description)
image = PACKAGES.get(name_verify, 'question.png')
self.d.lst_package.insert(package, image)
if line:
self.d.lst_package.select()
else:
self.d.lst_package.insert(_('Not found...'), 'error.png', show=False)
return
def cmd_search_action(self, event):
search = self.d.txt_search.value.strip()
if not search:
self.d.txt_search.set_focus()
return
self._search(search)
return
@app.run_in_thread
def _install(self, value):
self._set_state('install')
self.d.lst_package.visible = False
self.d.lst_log.visible = True
line = ''
name = value.split(' ')[0].strip()
cmd = self._cmd_pip(' install --upgrade --user {}'.format(name))
self.d.lst_log.clear()
for line in app.popen(cmd):
if self.OK1 in line or self.OK2 in line:
self.d.lst_log.insert(line, 'ok.png')
else:
self.d.lst_log.insert(line)
return
@app.catch_exception
def lst_package_double_click(self, event):
opt = 'install'
if self._states['list']:
opt = 'upgrade'
name = self.d.lst_package.value
msg = _('Do you want {}:\n\n{} ?').format(opt, name)
if not app.question(msg, TITLE):
return
self._install(name)
return
@app.run_in_thread
def _uninstall(self, value):
self._set_state('install')
self.d.lst_package.visible = False
self.d.lst_log.visible = True
line = ''
name = value.split(' ')[0].strip()
cmd = self._cmd_pip(' uninstall -y {}'.format(name))
self.d.lst_log.clear()
for line in app.popen(cmd):
if self.OK3 in line:
self.d.lst_log.insert(line, 'ok.png')
else:
self.d.lst_log.insert(line)
return
def cmd_uninstall_action(self, event):
if not self._states['list']:
msg = _('Select installed package')
app.warning(msg)
return
name = self.d.lst_package.value
msg = _('Do you want uninstall:\n\n{} ?').format(name)
if not app.question(msg):
return
self._uninstall(name)
return
@app.catch_exception
def cmd_shell_action(self, name):
if app.IS_WIN:
cmd = '"{}"'.format(self.path_python)
app.open_file(cmd)
else:
cmd = 'exec "{}"'
if app.IS_MAC:
cmd = 'open "{}"'
elif app.DESKTOP == 'gnome':
cmd = 'gnome-terminal -- {}'
cmd = cmd.format(self.path_python)
app.run(cmd)
return
@app.catch_exception
def _create_dialog():
args= {
'Name': 'dialog',
'Title': 'Zaz-Pip',
'Width': 200,
'Height': 220,
}
dialog = app.create_dialog(args)
dialog.id = ID_EXTENSION
dialog.events = Controllers
lbl_title = '{} {} - {}'.format(app.NAME, app.VERSION, app.OS)
args = {
'Type': 'Label',
'Name': 'lbl_title',
'Label': lbl_title,
'Width': 100,
'Height': 15,
'Border': 1,
'Align': 1,
'VerticalAlign': 1,
'Step': 10,
'FontHeight': 12,
}
dialog.add_control(args)
dialog.center(dialog.lbl_title, y=5)
path_python = app.paths.python
cmd = '"{}" -V'.format(path_python)
label = app.run(cmd, True)
args = {
'Type': 'Label',
'Name': 'lbl_python',
'Label': str(label),
'Width': 100,
'Height': 15,
'Border': 1,
'Align': 1,
'VerticalAlign': 1,
'Step': 10,
'FontHeight': 11,
}
dialog.add_control(args)
dialog.center(dialog.lbl_python, y=25)
cmd = '"{}" -m pip -V'.format(path_python)
label = app.run(cmd, True)
exists_pip = True
if not label:
exists_pip = False
label = _('PIP not installed')
args = {
'Type': 'Label',
'Name': 'lbl_pip',
'Label': label,
'Width': 160,
'Height': 30,
'Border': 1,
'Align': 1,
'VerticalAlign': 1,
'Step': 10,
'MultiLine': True,
}
dialog.add_control(args)
dialog.center(dialog.lbl_pip, y=45)
args = {
'Type': 'Button',
'Name': 'cmd_admin_pip',
'Label': _('Admin PIP'),
'Width': 60,
'Height': 18,
'Step': 10,
'ImageURL': 'python.png',
'ImagePosition': 1,
}
dialog.add_control(args)
dialog.center(dialog.cmd_admin_pip, y=80)
args = {
'Type': 'Button',
'Name': 'cmd_install_pip',
'Label': _('Install PIP'),
'Width': 60,
'Height': 18,
'Step': 10,
'ImageURL': 'install.png',
'ImagePosition': 1,
}
dialog.add_control(args)
dialog.center(dialog.cmd_install_pip, y=80)
args = {
'Type': 'Link',
'Name': 'link_proyect',
'URL': URL_GIT,
'Label': URL_GIT,
'Border': 1,
'Width': 130,
'Height': 15,
'Align': 1,
'VerticalAlign': 1,
'Step': 10,
}
dialog.add_control(args)
dialog.center(dialog.link_proyect, y=-5)
args = {
'Type': 'Listbox',
'Name': 'lst_log',
'Width': 160,
'Height': 105,
'Step': 10,
}
dialog.add_control(args)
dialog.center(dialog.lst_log, y=105)
args = {
'Type': 'Label',
'Name': 'lbl_package',
'Label': _('Packages'),
'Width': 100,
'Height': 15,
'Border': 1,
'Align': 1,
'VerticalAlign': 1,
'Step': 1,
}
lbl = dialog.add_control(args)
args = {
'Type': 'Text',
'Name': 'txt_search',
'Width': 180,
'Height': 12,
'Step': 1,
'Border': 0,
}
dialog.add_control(args)
args = {
'Type': 'Listbox',
'Name': 'lst_package',
'Width': 180,
'Height': 128,
'Step': 1,
}
dialog.add_control(args)
args = {
'Type': 'Button',
'Name': 'cmd_close',
'Label': _('~Close'),
'Width': 60,
'Height': 18,
'Step': 1,
'ImageURL': 'close.png',
'ImagePosition': 1,
# ~ 'PushButtonType': 2,
}
dialog.add_control(args)
dialog.center(dialog.cmd_close, y=-5)
args = {
'Type': 'Button',
'Name': 'cmd_home',
'Width': 18,
'Height': 18,
'Step': 1,
'ImageURL': 'home.png',
'FocusOnClick': False,
'Y': 2,
}
dialog.add_control(args)
args = {
'Type': 'Button',
'Name': 'cmd_search',
'Width': 18,
'Height': 18,
'Step': 1,
'ImageURL': 'search.png',
'FocusOnClick': False,
'Y': 2,
}
dialog.add_control(args)
args = {
'Type': 'Button',
'Name': 'cmd_uninstall',
'Width': 18,
'Height': 18,
'Step': 1,
'ImageURL': 'uninstall.png',
'FocusOnClick': False,
'Y': 2,
}
dialog.add_control(args)
args = {
'Type': 'Button',
'Name': 'cmd_install',
'Width': 18,
'Height': 18,
'Step': 1,
'ImageURL': 'install.png',
'FocusOnClick': False,
'Y': 2,
}
dialog.add_control(args)
args = {
'Type': 'Button',
'Name': 'cmd_shell',
'Width': 18,
'Height': 18,
'Step': 1,
'ImageURL': 'shell.png',
'FocusOnClick': False,
'Y': 2,
}
dialog.add_control(args)
controls = (dialog.cmd_home, dialog.cmd_search,
dialog.cmd_install, dialog.cmd_uninstall, dialog.cmd_shell)
dialog.lbl_package.move(dialog.cmd_home)
dialog.txt_search.move(dialog.lbl_package)
dialog.lst_package.move(dialog.txt_search)
dialog.lbl_package.center()
dialog.lst_package.center()
dialog.txt_search.center()
dialog.center(controls)
dialog.step = 10
dialog.cmd_install_pip.visible = not exists_pip
dialog.cmd_admin_pip.visible = exists_pip
dialog.lst_log.visible = False
return dialog