Compare commits

...

34 Commits

Author SHA1 Message Date
El Mau c2470ddd9d Add support for Flatplak and AppImage versions 2023-11-05 21:35:58 -06:00
El Mau 4b66d38e32 Make new OXT 2023-11-05 21:32:36 -06:00
El Mau d2d60e7281 Update version 2023-11-05 21:30:39 -06:00
Mauricio 0e750c0af0 Merge pull request 'cpython' (#14) from AmourSpirit/zaz-pip:cpython into develop
Reviewed-on: #14
2023-11-03 11:23:41 -06:00
Barry-Thomas-Paul: Moss 8dadb7e62e fix for debug error on Windows 2023-11-02 22:45:55 -04:00
Barry-Thomas-Paul: Moss 9f2ac70cc8 link cpython 2023-11-02 22:05:56 -04:00
Mauricio c93c182953 Merge pull request 'flatpak' (#13) from AmourSpirit/zaz-pip:flatpak into develop
Reviewed-on: #13
2023-11-01 19:18:49 -06:00
Barry-Thomas-Paul: Moss db3466b716 minor correcton for site_packages.exists() 2023-10-31 20:13:43 -04:00
Barry-Thomas-Paul: Moss 0453092831 fix for white text on bright yellow edit box in dark theme 2023-10-31 19:39:45 -04:00
Barry-Thomas-Paul: Moss 7b9ac8eee0 working with flatpak 2023-10-31 19:28:22 -04:00
Barry-Thomas-Paul: Moss 4aa0ca68c8 added pip_runner that add site_packages to sys.path 2023-10-31 16:19:18 -04:00
Barry-Thomas-Paul: Moss 923b39c7f2 pip installing in flatpak 2023-10-31 15:57:41 -04:00
Mauricio 90aa12adf2 Merge pull request 'develop' (#11) from AmourSpirit/zaz-pip:develop into develop
Reviewed-on: #11
2023-10-29 16:51:44 -06:00
AmourSpirit d52472dad7 Merge pull request 'app_image' (#1) from app_image into develop
Reviewed-on: AmourSpirit/zaz-pip#1
2023-10-19 17:09:26 -06:00
Barry-Thomas-Paul: Moss 6ec45c1bb4 Update to work with AppImage
Linxu ppImage Works with this minor fix.
Linux FlatPak still not working yet.
2023-10-19 19:06:50 -04:00
Barry-Thomas-Paul: Moss 910e5f54b1 update for Linxu AppImage 2023-10-19 15:29:02 -04:00
El Mau c9b9bfdf0a Fix issue #10 2022-04-23 21:49:30 -05:00
El Mau 587148553e Fix - Issue #10 2022-04-23 21:48:50 -05:00
El Mau 4b7b0c359f Fix issue #9 2022-03-26 23:03:54 -06:00
El Mau 269f9adc75 Fix - Issue #9 2022-03-26 16:07:22 -06:00
El Mau 668e23353b Update README 2022-03-26 11:46:41 -06:00
El Mau d7d65bb8ba Fix - Issue #9 2022-03-26 11:45:03 -06:00
El Mau b3c783c1fe Add Proxy dialog title to translate 2022-03-25 09:29:59 -06:00
El Mau 2452480457 Add french translation. Issue #8 2022-03-17 12:39:49 -06:00
El Mau afd94fa5fe Add french translation 2022-03-17 12:38:07 -06:00
El Mau c940f6fcc6 Fix issue #6 2022-02-04 21:29:23 -06:00
El Mau 450daa630a Update changelog 2022-02-04 21:27:30 -06:00
El Mau 6ce81f91c6 Fix to open terminal in Gnome 2022-02-04 21:26:17 -06:00
El Mau b7e0d2a0fc Update extension 2022-01-28 13:49:49 -06:00
El Mau 4d518c781e Issue #6 2022-01-28 13:45:10 -06:00
El Mau 354b5e1421 Release v0.9.0 2022-01-27 12:02:38 -06:00
El Mau b1e24d4411 Add minimal version 2022-01-27 09:45:07 -06:00
LibreOfficiant cac0b4fb59 Corrections to the english labels
Note: x-terminal-emulator is a generic command for all *NIX Desktop Environment *terminal commands.

Signed-off-by: LibreOfficiant <libreofficiant@noreply.localhost>
2022-01-27 07:53:37 -06:00
LibreOfficiant 9910b5302b Corrections to english messages
Including minor typos
2022-01-21 09:36:21 -06:00
27 changed files with 1222 additions and 174 deletions

View File

@ -1,3 +1,26 @@
v 1.0.0 [05-nov-2023]
- Thanks to https://git.cuates.net/AmourSpirit zaz-pip now work in:
* Mac Os
* Windows
* Linux, sudo installed LibreOffice
* Linux, Snap installed LibreOffice
* Linux, Flatpak installed LibreOffice
* Linux, AppImage LibreOffice
v 0.10.2 [22-apr-2022]
- Fix - issue #10
v 0.10.1 [26-mar-2022]
- Fix - issue #9
v 0.10.0 [19-mar-2022]
- Add french translation
v 0.9.0 [04-feb-2022]
- Fix - Add minimal version required, issue #5
- Fix - Corrections to english messages, issue #6
- Fix - Update and complete Spanish translation, thanks to me, :)
v 0.8.0 [13-jun-2021]
- Update easymacro.py
- Add proxy config
@ -20,7 +43,7 @@ v 0.3.0 [12-nov-2019]
- Test install numpy
v 0.2.0 [18-oct-2019]
- Add spanish
- Add Spanish translation
v 0.1.0 [18-oct-2019]
- Initial version

View File

@ -8,22 +8,29 @@ Thanks!
https://git.cuates.net/elmau/zaz
### Software libre, no gratis
### Free Software, not gratis software
This extension have a cost of maintenance of 1 euro every year.
BCH: `qztd3l00xle5tffdqvh2snvadkuau2ml0uqm4n875d`
G1: `A5DdXxCKPw3QKWVdDVs7CzkNugNUW1sHu5zDJFWxCU2h`
BTC: `3FhiXcXmAesmQzrNEngjHFnvaJRhU1AGWV`
```
Euros
IBAN: BE60 9671 0556 5870
SWIFT / BIC: TRWIBEB1XXX
```
You have others cryptos, welcome too!
* [Look the wiki](https://git.cuates.net/elmau/zaz-pip/wiki/home)
* [Mira la wiki](https://git.cuates.net/elmau/zaz-pip/wiki/home_es)
* [Look the wiki](https://gitlab.com/mauriciobaeza/zaz-pip/wikis/home)
* [Mira la wiki](https://gitlab.com/mauriciobaeza/zaz-pip/wikis/home_es)
Thanks for code:
* @AmourSpirit
Thanks for translations:
* Help Us
* English - @LibreOfficiant
* French - @LibreOfficiant

View File

@ -1 +1 @@
0.8.0
1.0.0

21
conf.py
View File

@ -26,7 +26,7 @@ import logging
TYPE_EXTENSION = 1
# ~ https://semver.org/
VERSION = '0.8.0'
VERSION = '1.0.0'
# ~ Your great extension name, not used spaces
NAME = 'ZAZPip'
@ -41,7 +41,7 @@ ID = 'net.elmau.zaz.pip'
USE_LOCALES = True
DOMAIN = 'base'
PATH_LOCALES = 'locales'
PATH_PYGETTEXT = '/usr/lib/python3.8/Tools/i18n/pygettext.py'
PATH_PYGETTEXT = '/usr/lib/python3.10/Tools/i18n/pygettext.py'
PATH_MSGMERGE = 'msgmerge'
@ -50,6 +50,7 @@ URL_GIT = 'https://git.cuates.net/elmau/zaz-pip'
PUBLISHER = {
'en': {'text': 'El Mau', 'link': URL_GIT},
'es': {'text': 'El Mau', 'link': URL_GIT},
'fr': {'text': 'El Mau', 'link': URL_GIT},
}
# ~ Name in this folder for copy
@ -57,9 +58,7 @@ ICON = 'images/logo.png'
# ~ Name inside extensions
ICON_EXT = f'{NAME.lower()}.png'
# ~ For example
# ~ DEPENDENCIES_MINIMAL = '6.0'
DEPENDENCIES_MINIMAL = ''
DEPENDENCIES_MINIMAL = '7.0'
# ~ Change for you favorite license
LICENSE_EN = f"""This file is part of {NAME}.
@ -77,7 +76,7 @@ LICENSE_EN = f"""This file is part of {NAME}.
You should have received a copy of the GNU General Public License
along with {NAME}. If not, see <https://www.gnu.org/licenses/>.
"""
LICENSE_ES = LICENSE_EN
LICENSE_FR = LICENSE_ES = LICENSE_EN
INFO = {
'en': {
@ -90,6 +89,11 @@ INFO = {
'description': 'Pip para LibreOffice',
'license': LICENSE_ES,
},
'fr': {
'display_name': 'ZAZ Pip',
'description': 'Pip pour LibreOffice',
'license': LICENSE_FR,
},
}
@ -112,7 +116,7 @@ PARENT = 'AddonMenu'
MENU_MAIN = {}
MENUS = (
{
'title': {'en': 'Open Pip', 'es': 'Abrir Pip'},
'title': {'en': 'Open Zaz-Pip', 'es': 'Abrir Zaz-Pip', 'fr': 'Ouvert Zaz-Pip'},
'argument': 'open_dialog_pip',
'context': '',
'icon': 'icon',
@ -154,7 +158,7 @@ DIRS = {
'description': 'description',
'images': 'images',
'registration': 'registration',
'files': 'files',
'files': 'extension',
'office': 'Office',
'locales': PATH_LOCALES,
'pythonpath': True,
@ -398,6 +402,7 @@ DATA_DESCRIPTION = {
'icon': ICON_EXT,
'publisher': PUBLISHER,
'update': URL_XML_UPDATE,
'minimal': DEPENDENCIES_MINIMAL,
}
DATA_ADDONS = {

BIN
extension/ZAZPip_v1.0.0.oxt Normal file

Binary file not shown.

Binary file not shown.

View File

@ -4,8 +4,9 @@
<node oor:name="AddonMenu">
<node oor:name="net.elmau.zaz.pip" oor:op="fuse">
<prop oor:name="Title" oor:type="xs:string">
<value xml:lang="en">Open Pip</value>
<value xml:lang="es">Abrir Pip</value>
<value xml:lang="en">Open Zaz-Pip</value>
<value xml:lang="es">Abrir Zaz-Pip</value>
<value xml:lang="fr">Ouvert Zaz-Pip</value>
</prop>
<prop oor:name="Context" oor:type="xs:string">
<value/>

View File

@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" manifest:version="1.2">
<manifest:file-entry manifest:full-path="job.xcu" manifest:media-type="application/vnd.sun.star.configuration-data" />
<manifest:file-entry manifest:full-path="ZAZPip.py" manifest:media-type="application/vnd.sun.star.uno-component;type=Python"/>
<manifest:file-entry manifest:full-path="pip_runner.py" manifest:media-type="application/vnd.sun.star.uno-component;type=Python" />
<manifest:file-entry manifest:full-path="Office/Accelerators.xcu" manifest:media-type="application/vnd.sun.star.configuration-data"/>
<manifest:file-entry manifest:full-path="Addons.xcu" manifest:media-type="application/vnd.sun.star.configuration-data"/>
</manifest:manifest>

View File

@ -13,9 +13,9 @@ class ZAZPip(unohelper.Base, XJobExecutor):
def __init__(self, ctx):
self.ctx = ctx
def trigger(self, args):
def trigger(self, option):
main.ID_EXTENSION = ID_EXTENSION
main.run(args, __file__)
main.run(__file__)
return

View File

@ -1,14 +1,19 @@
<?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" xmlns:l="http://libreoffice.org/extensions/description/2011">
<identifier value="net.elmau.zaz.pip"/>
<version value="0.8.0"/>
<version value="1.0.0"/>
<dependencies>
<l:LibreOffice-minimal-version value="7.0"/>
</dependencies>
<display-name>
<name lang="en">ZAZ Pip</name>
<name lang="es">ZAZ Pip</name>
<name lang="fr">ZAZ Pip</name>
</display-name>
<extension-description>
<src lang="en" xlink:href="description/desc_en.txt"/>
<src lang="es" xlink:href="description/desc_es.txt"/>
<src lang="fr" xlink:href="description/desc_fr.txt"/>
</extension-description>
<icon>
<default xlink:href="images/zazpip.png"/>
@ -16,11 +21,13 @@
<publisher>
<name xlink:href="https://git.cuates.net/elmau/zaz-pip" lang="en">El Mau</name>
<name xlink:href="https://git.cuates.net/elmau/zaz-pip" lang="es">El Mau</name>
<name xlink:href="https://git.cuates.net/elmau/zaz-pip" lang="fr">El Mau</name>
</publisher>
<registration>
<simple-license accept-by="user" suppress-on-update="true">
<license-text xlink:href="registration/license_en.txt" lang="en"/>
<license-text xlink:href="registration/license_es.txt" lang="es"/>
<license-text xlink:href="registration/license_fr.txt" lang="fr"/>
</simple-license>
</registration>
</description>

View File

@ -0,0 +1 @@
Pip pour LibreOffice

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

20
source/job.xcu Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE oor:component-data SYSTEM "../../../../component-update.dtd">
<oor:component-data oor:name="Jobs" oor:package="org.openoffice.Office"
xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<node oor:name="Jobs">
<node oor:name="PipRunnerJob" oor:op="fuse">
<prop oor:name="Service">
<value>net.elmau.zaz.pip.PipRunner</value>
</prop>
</node>
</node>
<node oor:name="Events">
<node oor:name="OnStartApp" oor:op="fuse">
<node oor:name="JobList">
<node oor:name="PipRunnerJob" oor:op="fuse" />
</node>
</node>
</node>
</oor:component-data>

View File

@ -5,7 +5,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2019-10-19 15:19-0500\n"
"POT-Creation-Date: 2022-03-26 11:23-0600\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -15,73 +15,144 @@ msgstr ""
"Generated-By: pygettext.py 1.5\n"
#: source/ZAZPip.py:49
msgid "Do you want install PIP?"
#: source/pythonpath/main.py:81
msgid "Do you want to install 'Python installer package' (PIP)?"
msgstr ""
#: source/ZAZPip.py:67
msgid "Do you have internet connection?"
#: source/pythonpath/main.py:93
msgid "Downloading PIP…"
msgstr ""
#: source/ZAZPip.py:73
msgid "File PIP not save"
#: source/pythonpath/main.py:96
msgid "Unable to connect to internet"
msgstr ""
#: source/ZAZPip.py:76
msgid "PIP save correctly..."
#: source/pythonpath/main.py:102
msgid "Unable to copy PIP installation file"
msgstr ""
#: source/ZAZPip.py:80
msgid "Start installing PIP..."
#: source/pythonpath/main.py:105
msgid "PIP installation file has been saved"
msgstr ""
#: source/ZAZPip.py:94
msgid "PIP installed sucesfully"
#: source/pythonpath/main.py:108
msgid "Starting PIP installation…"
msgstr ""
#: source/ZAZPip.py:97
msgid "PIP not installed, see log"
#: source/pythonpath/main.py:122
msgid "PIP was installed sucessfully"
msgstr ""
#: source/ZAZPip.py:173
msgid "Not found..."
#: source/pythonpath/main.py:125
msgid "PIP installation has failed, see log"
msgstr ""
#: source/ZAZPip.py:209
#: source/pythonpath/main.py:198
msgid "Package not found…"
msgstr ""
#: source/pythonpath/main.py:213
msgid "Enter the package name to install"
msgstr ""
#: source/pythonpath/main.py:218
msgid "Do you really want to install package: {}?"
msgstr ""
#: source/pythonpath/main.py:247
msgid "install"
msgstr ""
#: source/pythonpath/main.py:249
msgid "upgrade"
msgstr ""
#: source/pythonpath/main.py:252
msgid ""
"Do you want {}:\n"
"Do you want to {}:\n"
"\n"
"{} ?"
"{}?"
msgstr ""
#: source/ZAZPip.py:235
#: source/pythonpath/main.py:278
msgid "Select installed package"
msgstr ""
#: source/ZAZPip.py:240
#: source/pythonpath/main.py:283
msgid ""
"Do you want uninstall:\n"
"Do you want to uninstall:\n"
"\n"
"{} ?"
"{}?"
msgstr ""
#: source/ZAZPip.py:327
msgid "PIP not installed"
#: source/pythonpath/main.py:310
msgid ""
"Do you want to install from:\n"
"\n"
"{}"
msgstr ""
#: source/ZAZPip.py:346
#: source/pythonpath/main.py:337
msgid "Do you want to save this Proxy settings?"
msgstr ""
#: source/pythonpath/main.py:343
msgid "Proxy settings saved sucessfully"
msgstr ""
#: source/pythonpath/main.py:349
msgid "Do you want to remove Proxy settings?"
msgstr ""
#: source/pythonpath/main.py:355
msgid "Proxy settings deleted sucessfully"
msgstr ""
#: source/pythonpath/main.py:413
msgid "'Python installer package' (PIP) is not installed"
msgstr ""
#: source/pythonpath/main.py:432
msgid "Admin PIP"
msgstr ""
#: source/ZAZPip.py:359
#: source/pythonpath/main.py:445
msgid "Install PIP"
msgstr ""
#: source/ZAZPip.py:397
#: source/pythonpath/main.py:494
msgid "Packages"
msgstr ""
#: source/ZAZPip.py:429
#: source/pythonpath/main.py:536
msgid "~Close"
msgstr ""
#: source/pythonpath/main.py:635
msgid "Zaz-Pip - Proxy settings"
msgstr ""
#: source/pythonpath/main.py:646
msgid "Host: "
msgstr ""
#: source/pythonpath/main.py:669
msgid "Port: "
msgstr ""
#: source/pythonpath/main.py:690
msgid "User: "
msgstr ""
#: source/pythonpath/main.py:711
msgid "Password: "
msgstr ""
#: source/pythonpath/main.py:733
msgid "Save"
msgstr ""
#: source/pythonpath/main.py:745
msgid "Delete"
msgstr ""

View File

@ -5,84 +5,155 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2019-10-19 15:19-0500\n"
"PO-Revision-Date: 2019-10-19 15:20-0500\n"
"POT-Creation-Date: 2022-03-26 11:23-0600\n"
"PO-Revision-Date: 2021-01-21 16:32-0500\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 2.2.4\n"
"Last-Translator: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Language: en\n"
#: source/ZAZPip.py:49
msgid "Do you want install PIP?"
#: source/pythonpath/main.py:81
msgid "Do you want to install 'Python installer package' (PIP)?"
msgstr ""
#: source/ZAZPip.py:67
msgid "Do you have internet connection?"
#: source/pythonpath/main.py:93
msgid "Downloading PIP…"
msgstr ""
#: source/ZAZPip.py:73
msgid "File PIP not save"
#: source/pythonpath/main.py:96
msgid "Unable to connect to internet"
msgstr ""
#: source/ZAZPip.py:76
msgid "PIP save correctly..."
#: source/pythonpath/main.py:102
msgid "Unable to copy PIP installation file"
msgstr ""
#: source/ZAZPip.py:80
msgid "Start installing PIP..."
#: source/pythonpath/main.py:105
msgid "PIP installation file has been saved"
msgstr ""
#: source/ZAZPip.py:94
msgid "PIP installed sucesfully"
#: source/pythonpath/main.py:108
msgid "Starting PIP installation…"
msgstr ""
#: source/ZAZPip.py:97
msgid "PIP not installed, see log"
#: source/pythonpath/main.py:122
msgid "PIP was installed sucessfully"
msgstr ""
#: source/ZAZPip.py:173
msgid "Not found..."
#: source/pythonpath/main.py:125
msgid "PIP installation has failed, see log"
msgstr ""
#: source/ZAZPip.py:209
#: source/pythonpath/main.py:198
msgid "Package not found…"
msgstr ""
#: source/pythonpath/main.py:213
msgid "Enter the package name to install"
msgstr ""
#: source/pythonpath/main.py:218
msgid "Do you really want to install package: {}?"
msgstr ""
#: source/pythonpath/main.py:247
msgid "install"
msgstr ""
#: source/pythonpath/main.py:249
msgid "upgrade"
msgstr ""
#: source/pythonpath/main.py:252
msgid ""
"Do you want {}:\n"
"Do you want to {}:\n"
"\n"
"{} ?"
"{}?"
msgstr ""
#: source/ZAZPip.py:235
#: source/pythonpath/main.py:278
msgid "Select installed package"
msgstr ""
#: source/ZAZPip.py:240
#: source/pythonpath/main.py:283
msgid ""
"Do you want uninstall:\n"
"Do you want to uninstall:\n"
"\n"
"{} ?"
"{}?"
msgstr ""
#: source/ZAZPip.py:327
msgid "PIP not installed"
#: source/pythonpath/main.py:310
msgid ""
"Do you want to install from:\n"
"\n"
"{}"
msgstr ""
#: source/ZAZPip.py:346
#: source/pythonpath/main.py:337
msgid "Do you want to save this Proxy settings?"
msgstr ""
#: source/pythonpath/main.py:343
msgid "Proxy settings saved sucessfully"
msgstr ""
#: source/pythonpath/main.py:349
msgid "Do you want to remove Proxy settings?"
msgstr ""
#: source/pythonpath/main.py:355
msgid "Proxy settings deleted sucessfully"
msgstr ""
#: source/pythonpath/main.py:413
msgid "'Python installer package' (PIP) is not installed"
msgstr ""
#: source/pythonpath/main.py:432
msgid "Admin PIP"
msgstr ""
#: source/ZAZPip.py:359
#: source/pythonpath/main.py:445
msgid "Install PIP"
msgstr ""
#: source/ZAZPip.py:397
#: source/pythonpath/main.py:494
msgid "Packages"
msgstr ""
#: source/ZAZPip.py:429
#: source/pythonpath/main.py:536
msgid "~Close"
msgstr ""
#: source/pythonpath/main.py:635
msgid "Zaz-Pip - Proxy settings"
msgstr ""
#: source/pythonpath/main.py:646
msgid "Host: "
msgstr ""
#: source/pythonpath/main.py:669
msgid "Port: "
msgstr ""
#: source/pythonpath/main.py:690
msgid "User: "
msgstr ""
#: source/pythonpath/main.py:711
msgid "Password: "
msgstr ""
#: source/pythonpath/main.py:733
msgid "Save"
msgstr ""
#: source/pythonpath/main.py:745
msgid "Delete"
msgstr ""

View File

@ -5,90 +5,182 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2019-10-19 15:19-0500\n"
"PO-Revision-Date: 2019-10-19 15:24-0500\n"
"POT-Creation-Date: 2022-03-26 11:23-0600\n"
"PO-Revision-Date: 2022-03-26 11:28-0600\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 2.2.4\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 3.0.1\n"
#: source/ZAZPip.py:49
msgid "Do you want install PIP?"
msgstr "¿Desea instalar PIP?"
#: source/pythonpath/main.py:81
msgid "Do you want to install 'Python installer package' (PIP)?"
msgstr "¿Desea instalar el instalador de paquetes Python (PIP)?"
#: source/ZAZPip.py:67
msgid "Do you have internet connection?"
msgstr "¿Tiene conexión a Internet?"
#: source/pythonpath/main.py:93
msgid "Downloading PIP…"
msgstr "Descargando PIP…"
#: source/ZAZPip.py:73
msgid "File PIP not save"
msgstr "No se guardo el archivo PIP"
#: source/pythonpath/main.py:96
msgid "Unable to connect to internet"
msgstr "No se puede conectar a Internet"
#: source/ZAZPip.py:76
msgid "PIP save correctly..."
msgstr "Archivo PIP guardado correctamente..."
#: source/pythonpath/main.py:102
msgid "Unable to copy PIP installation file"
msgstr "No se puede copiar el archivo de instalación de PIP"
#: source/ZAZPip.py:80
msgid "Start installing PIP..."
msgstr "Iniciando instalación de PIP..."
#: source/pythonpath/main.py:105
msgid "PIP installation file has been saved"
msgstr "Se ha guardado el archivo de instalación de PIP"
#: source/ZAZPip.py:94
msgid "PIP installed sucesfully"
#: source/pythonpath/main.py:108
msgid "Starting PIP installation…"
msgstr "Iniciando la instalación de PIP…"
#: source/pythonpath/main.py:122
msgid "PIP was installed sucessfully"
msgstr "PIP instalado correctamente"
#: source/ZAZPip.py:97
msgid "PIP not installed, see log"
msgstr "PIP no fue instalado, vea el registro"
#: source/pythonpath/main.py:125
msgid "PIP installation has failed, see log"
msgstr "Ha fallado la instalación de PIP, vea el registro"
#: source/ZAZPip.py:173
msgid "Not found..."
msgstr "No encontrado..."
#: source/pythonpath/main.py:198
msgid "Package not found…"
msgstr "Paquete no encontrado…"
#: source/ZAZPip.py:209
#: source/pythonpath/main.py:213
msgid "Enter the package name to install"
msgstr "Introduzca el nombre del paquete a instalar"
#: source/pythonpath/main.py:218
msgid "Do you really want to install package: {}?"
msgstr "¿Desea instalar el paquete: {}?"
#: source/pythonpath/main.py:247
msgid "install"
msgstr "instalar"
#: source/pythonpath/main.py:249
msgid "upgrade"
msgstr "actualizar"
#: source/pythonpath/main.py:252
msgid ""
"Do you want {}:\n"
"Do you want to {}:\n"
"\n"
"{} ?"
"{}?"
msgstr ""
"¿Desea {}:\n"
"\n"
"{} ?"
#: source/ZAZPip.py:235
#: source/pythonpath/main.py:278
msgid "Select installed package"
msgstr "Seleccione un paquete instalado"
#: source/ZAZPip.py:240
#: source/pythonpath/main.py:283
msgid ""
"Do you want uninstall:\n"
"Do you want to uninstall:\n"
"\n"
"{} ?"
"{}?"
msgstr ""
"¿Desea desinstalar:\n"
"\n"
"{} ?"
#: source/ZAZPip.py:327
msgid "PIP not installed"
msgstr "PIP no esta instalado"
#: source/pythonpath/main.py:310
msgid ""
"Do you want to install from:\n"
"\n"
"{}"
msgstr ""
"¿Desea desinstalar desde:\n"
"\n"
"{} ?"
#: source/ZAZPip.py:346
#: source/pythonpath/main.py:337
msgid "Do you want to save this Proxy settings?"
msgstr "¿Desea guardar la configuración del Proxy?"
#: source/pythonpath/main.py:343
msgid "Proxy settings saved sucessfully"
msgstr "PIP instalado correctamente"
#: source/pythonpath/main.py:349
msgid "Do you want to remove Proxy settings?"
msgstr "¿Desea eliminar la configuración del Proxy?"
#: source/pythonpath/main.py:355
msgid "Proxy settings deleted sucessfully"
msgstr "Configuración del Proxy borrada correctamente"
#: source/pythonpath/main.py:413
msgid "'Python installer package' (PIP) is not installed"
msgstr "El \"instalador de paquetes de Python\" (PIP) no está instalado"
#: source/pythonpath/main.py:432
msgid "Admin PIP"
msgstr "Administrar PIP"
#: source/ZAZPip.py:359
#: source/pythonpath/main.py:445
msgid "Install PIP"
msgstr "Instalar PIP"
#: source/ZAZPip.py:397
#: source/pythonpath/main.py:494
msgid "Packages"
msgstr "Paquetes"
#: source/ZAZPip.py:429
#: source/pythonpath/main.py:536
msgid "~Close"
msgstr "~Cerrar"
#: source/pythonpath/main.py:635
msgid "Zaz-Pip - Proxy settings"
msgstr "Zaz-Pip - Configuración del Proxy"
#: source/pythonpath/main.py:646
msgid "Host: "
msgstr "Host: "
#: source/pythonpath/main.py:669
msgid "Port: "
msgstr "Puerto: "
#: source/pythonpath/main.py:690
msgid "User: "
msgstr "Usuario: "
#: source/pythonpath/main.py:711
msgid "Password: "
msgstr "Contraseña: "
#: source/pythonpath/main.py:733
msgid "Save"
msgstr "Guardar"
#: source/pythonpath/main.py:745
msgid "Delete"
msgstr "Eliminar"
#~ msgid "Do you have internet connection?"
#~ msgstr "¿Tiene conexión a Internet?"
#~ msgid "File PIP not save"
#~ msgstr "No se guardo el archivo PIP"
#~ msgid "PIP save correctly..."
#~ msgstr "Archivo PIP guardado correctamente..."
#~ msgid "Start installing PIP..."
#~ msgstr "Iniciando instalación de PIP..."
#~ msgid "Not found..."
#~ msgstr "No encontrado..."
#~ msgid "PIP not installed"
#~ msgstr "PIP no esta instalado"

Binary file not shown.

View File

@ -0,0 +1,168 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2022-03-26 11:23-0600\n"
"PO-Revision-Date: 2022-03-26 11:41-0600\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: fr_FR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 3.0.1\n"
#: source/pythonpath/main.py:81
msgid "Do you want to install 'Python installer package' (PIP)?"
msgstr "Souhaitez-vous installer 'Python installer package' (PIP) ?"
#: source/pythonpath/main.py:93
msgid "Downloading PIP…"
msgstr "Téléchargement de PIP…"
#: source/pythonpath/main.py:96
msgid "Unable to connect to internet"
msgstr "Pas de connection à internet"
#: source/pythonpath/main.py:102
msgid "Unable to copy PIP installation file"
msgstr "La réception du fichier d'installation de PIP a échoué"
#: source/pythonpath/main.py:105
msgid "PIP installation file has been saved"
msgstr "Fichier d'installation de PIP reçu"
#: source/pythonpath/main.py:108
msgid "Starting PIP installation…"
msgstr "Démarrage de l'installation de PIP…"
#: source/pythonpath/main.py:122
msgid "PIP was installed sucessfully"
msgstr "PIP est maintenant installé"
#: source/pythonpath/main.py:125
msgid "PIP installation has failed, see log"
msgstr "Echec à l'installation de PIP, consultez le fichier Log'"
#: source/pythonpath/main.py:198
msgid "Package not found…"
msgstr "Paquet non trouvé…"
#: source/pythonpath/main.py:213
msgid "Enter the package name to install"
msgstr "Nom du paquet à installer"
#: source/pythonpath/main.py:218
msgid "Do you really want to install package: {}?"
msgstr "Souhaitez-vous désinstaller :{} ?"
#: source/pythonpath/main.py:247
msgid "install"
msgstr "installer"
#: source/pythonpath/main.py:249
msgid "upgrade"
msgstr "mise à niveau"
#: source/pythonpath/main.py:252
msgid ""
"Do you want to {}:\n"
"\n"
"{}?"
msgstr ""
"Souhaitez-vous {}\n"
"\n"
"\"{}"
#: source/pythonpath/main.py:278
msgid "Select installed package"
msgstr "Choisissez un paquet déjà installé"
#: source/pythonpath/main.py:283
msgid ""
"Do you want to uninstall:\n"
"\n"
"{}?"
msgstr ""
"Souhaitez-vous désinstaller :\n"
"\n"
"{} ?"
#: source/pythonpath/main.py:310
msgid ""
"Do you want to install from:\n"
"\n"
"{}"
msgstr ""
"Souhaitez-vous installer :\n"
"\n"
"{} ?"
#: source/pythonpath/main.py:337
msgid "Do you want to save this Proxy settings?"
msgstr "Enregistrer les données du mandataire (Proxy) ?"
#: source/pythonpath/main.py:343
msgid "Proxy settings saved sucessfully"
msgstr "Les données mandataire (Proxy) sont enregistrées"
#: source/pythonpath/main.py:349
msgid "Do you want to remove Proxy settings?"
msgstr "Supprimer les données du mandataire (Proxy)?"
#: source/pythonpath/main.py:355
msgid "Proxy settings deleted sucessfully"
msgstr "Les données mandataire (Proxy) sont supprimées"
#: source/pythonpath/main.py:413
msgid "'Python installer package' (PIP) is not installed"
msgstr "'Python installer package' (PIP) absent"
#: source/pythonpath/main.py:432
msgid "Admin PIP"
msgstr "Administrer PIP"
#: source/pythonpath/main.py:445
msgid "Install PIP"
msgstr "Installer PIP"
#: source/pythonpath/main.py:494
msgid "Packages"
msgstr "Paquets"
#: source/pythonpath/main.py:536
msgid "~Close"
msgstr "~Fermer"
#: source/pythonpath/main.py:635
msgid "Zaz-Pip - Proxy settings"
msgstr "Zaz-PIP Données mandataire (Proxy)"
#: source/pythonpath/main.py:646
msgid "Host: "
msgstr "Hôte: "
#: source/pythonpath/main.py:669
msgid "Port: "
msgstr "Port: "
#: source/pythonpath/main.py:690
msgid "User: "
msgstr "Utilisateur: "
#: source/pythonpath/main.py:711
msgid "Password: "
msgstr "Mot de passe: "
#: source/pythonpath/main.py:733
msgid "Save"
msgstr "Enregistrer"
#: source/pythonpath/main.py:745
msgid "Delete"
msgstr "Supprimer"

57
source/pip_runner.py Normal file
View File

@ -0,0 +1,57 @@
# region Imports
from __future__ import unicode_literals, annotations
import os
import sys
from typing import TYPE_CHECKING, Tuple
from pathlib import Path
import uno
import unohelper
from com.sun.star.task import XJob
if TYPE_CHECKING:
# just for design time
from com.sun.star.beans import NamedValue
# endregion Imports
# region Constants
implementation_name = "net.elmau.zaz.pip.PipRunner"
implementation_services = ("com.sun.star.task.Job",)
# endregion Constants
# region XJob
class PipRunner(unohelper.Base, XJob):
def __init__(self, ctx):
self._is_flatpak = bool(os.getenv("FLATPAK_ID", ""))
if self._is_flatpak:
site_packages = self.get_flatpak_site_packages_dir()
ss = str(site_packages)
if site_packages.exists() and ss not in sys.path:
sys.path.append(ss)
def execute(self, *args: Tuple[NamedValue, ...]) -> None:
pass
def get_flatpak_site_packages_dir(self) -> Path:
# should never be all users
sand_box = os.getenv("FLATPAK_SANDBOX_DIR", "") or str(
Path.home() / ".var/app/org.libreoffice.LibreOffice/sandbox"
)
major_minor = f"{sys.version_info.major}.{sys.version_info.minor}"
site_packages = Path(sand_box) / f"lib/python{major_minor}/site-packages"
site_packages.mkdir(parents=True, exist_ok=True)
return site_packages
# endregion XJob
# region Implementation
g_TypeTable = {}
g_ImplementationHelper = unohelper.ImplementationHelper()
g_ImplementationHelper.addImplementation(PipRunner, implementation_name, implementation_services)
# endregion Implementation

View File

@ -31,6 +31,7 @@ import logging
import os
import platform
import re
import site
import shlex
import shutil
import socket
@ -167,6 +168,9 @@ OBJ_GRAPHIC = 'SwXTextGraphicObject'
OBJ_TEXTS = 'SwXTextRanges'
OBJ_TEXT = 'SwXTextRange'
IS_FLATPAK = bool(os.getenv("FLATPAK_ID", ""))
IS_APP_IMAGE = bool(os.getenv("APPIMAGE", ""))
# ~ from com.sun.star.sheet.FilterOperator import EMPTY, NO_EMPTY, EQUAL, NOT_EQUAL
@ -595,13 +599,24 @@ def call_macro(args, in_thread=False):
result = _call_macro(args)
return result
def get_env():
"""
Gets Environment used for subprocess.
"""
my_env = os.environ.copy()
py_path = ""
p_sep = ";" if IS_WIN else ":"
for d in sys.path:
py_path = py_path + d + p_sep
my_env["PYTHONPATH"] = py_path
return my_env
def run(command, capture=False, split=True):
if not split:
return subprocess.check_output(command, shell=True).decode()
return subprocess.check_output(command, shell=True, env=get_env()).decode()
cmd = shlex.split(command)
result = subprocess.run(cmd, capture_output=capture, text=True, shell=IS_WIN)
result = subprocess.run(cmd, capture_output=capture, text=True, shell=IS_WIN, env=get_env())
if capture:
result = result.stdout
else:
@ -612,7 +627,7 @@ def run(command, capture=False, split=True):
def popen(command):
try:
proc = subprocess.Popen(shlex.split(command), shell=IS_WIN,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=get_env())
for line in proc.stdout:
yield line.decode().rstrip()
except Exception as e:
@ -625,6 +640,60 @@ def sleep(seconds):
return
def get_site_packages_dir() -> str:
"""Gets the site-packages folder for the current user."""
major_minor = f"{sys.version_info.major}.{sys.version_info.minor}"
def get_windows_site_packages_dir() -> str:
nonlocal major_minor
if site.USER_SITE:
site_packages = Path(site.USER_SITE).resolve()
else:
site_packages = (
Path.home() / f"'/AppData/Roaming/Python/Python{major_minor}/site-packages'"
)
site_packages.mkdir(parents=True, exist_ok=True)
return str(site_packages)
def get_flatpak_site_packages_dir() -> str:
# should never be all users
nonlocal major_minor
sand_box = os.getenv("FLATPAK_SANDBOX_DIR", "") or str(
Path.home() / ".var/app/org.libreoffice.LibreOffice/sandbox"
)
site_packages = Path(sand_box) / f"lib/python{major_minor}/site-packages"
site_packages.mkdir(parents=True, exist_ok=True)
return str(site_packages)
def get_mac_site_packages_dir() -> str:
nonlocal major_minor
if site.USER_SITE:
site_packages = Path(site.USER_SITE).resolve()
else:
site_packages = (
Path.home() / f"Library/LibreOfficePython/{major_minor}/lib/python/site-packages"
)
site_packages.mkdir(parents=True, exist_ok=True)
return str(site_packages)
def get_default_site_packages_dir() -> str:
nonlocal major_minor
if site.USER_SITE:
site_packages = Path(site.USER_SITE).resolve()
else:
site_packages = Path.home() / f".local/lib/python{major_minor}/site-packages"
site_packages.mkdir(parents=True, exist_ok=True)
return str(site_packages)
if IS_WIN:
return get_windows_site_packages_dir()
if IS_MAC:
return get_mac_site_packages_dir()
if IS_FLATPAK:
return get_flatpak_site_packages_dir()
return get_default_site_packages_dir()
class TimerThread(threading.Thread):
def __init__(self, event, seconds, macro):
@ -4146,6 +4215,7 @@ class EventsFocus(EventsListenerBase, XFocusListener):
if service in self.CONTROLS:
obj = event.Source.Model
obj.BackgroundColor = COLOR_ON_FOCUS
obj.TextColor = TEXT_COLOR_ON_FOCUS
return
def focusLost(self, event):
@ -6184,7 +6254,10 @@ class Paths(object):
elif IS_MAC:
path = self.join(self.config('Module'), '..', 'Resources', PYTHON)
else:
path = sys.executable
if IS_APP_IMAGE:
path = self.join(self.config("Module"), PYTHON)
else:
path = sys.executable
return path
@classmethod
@ -6306,7 +6379,7 @@ class Paths(object):
if IS_WIN:
os.startfile(path)
else:
pid = subprocess.Popen(['xdg-open', path]).pid
pid = subprocess.Popen(['xdg-open', path, ], env=get_env()).pid
return
@classmethod
@ -6839,6 +6912,7 @@ def get_color(value):
COLOR_ON_FOCUS = get_color('LightYellow')
TEXT_COLOR_ON_FOCUS = get_color('black')
class LOServer(object):
@ -6890,7 +6964,7 @@ class LOServer(object):
for i in range(3):
self._server = subprocess.Popen(self.CMD,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=get_env())
time.sleep(3)
if self.is_running:
break

View File

@ -0,0 +1,214 @@
from __future__ import annotations
from typing import cast
import os
import sys
import tempfile
import subprocess
from pathlib import Path
from typing import Any, List, Dict
import easymacro as app
from contextlib import contextmanager
import uno
@contextmanager
def change_dir(directory):
"""
A context manager that changes the current working directory to the specified directory
temporarily and then changes it back when the context is exited.
"""
current_dir = os.getcwd()
os.chdir(directory)
try:
yield
finally:
os.chdir(current_dir)
class InstallPipFromWheel:
"""Download and install PIP from wheel url"""
def __init__(self, pip_wheel_url: str, lo_identifier: str) -> None:
self._pip_url = pip_wheel_url
self._lo_identifier = lo_identifier
def install(self, dst: str | Path = "") -> None:
"""
Install pip from wheel file.
Downloads the pip wheel file from the url provided in the config file and unzips it to the destination directory.
Args:
dst (str | Path, Optional): The destination directory where the pip wheel file will be installed. If not provided, the ``pythonpath`` location will be used.
Returns:
None:
Raises:
None:
"""
if not self._pip_url:
app.error("PIP installation has failed - No wheel url")
return
if not dst:
root_pth = Path(app.Paths.from_id(self._lo_identifier))
dst = root_pth / "pythonpath"
with tempfile.TemporaryDirectory() as temp_dir:
# temp_dir = tempfile.gettempdir()
path_pip = Path(temp_dir)
filename = path_pip / "pip-wheel.whl"
data, _, err = app.url_open(self._pip_url, verify=False)
if err:
app.error("Unable to download PIP installation wheel file")
return
filename.write_bytes(data)
if filename.exists():
app.info("PIP wheel file has been saved")
else:
app.error("PIP wheel file has not been saved")
return
try:
self._unzip_wheel(filename=filename, dst=dst)
except Exception:
return
# now that pip has been installed from wheel force a reinstall to ensure it is the latest version
self._force_install_pip()
def _unzip_wheel(self, filename: Path, dst: str | Path) -> None:
"""Unzip the downloaded wheel file"""
if isinstance(dst, str):
dst = Path(dst)
try:
# app.zip.unzip(source=str(filename), target=str(dst))
self.unzip_file(zip_file=filename, dest_dir=dst)
if dst.exists():
app.debug(f"PIP wheel file has been unzipped to {dst}")
else:
app.error("PIP wheel file has not been unzipped")
raise Exception("PIP wheel file has not been unzipped")
except Exception as err:
app.error(f"Unable to unzip wheel file: {err}", exc_info=True)
raise
def _force_install_pip(self) -> None:
"""Now that pip has been installed, force reinstall it to ensure it is the latest version"""
cmd = [app.paths.python, "-m", "pip", "install", "--upgrade", "pip"]
app.popen(command=" ".join(cmd))
def unzip_file(self, zip_file: str | Path, dest_dir: str | Path = "") -> None:
"""
Unzip the given zip file to the specified destination directory.
Args:
zip_file (str | Path): The zip file to unzip.
dest_dir (str | Path, optional): The destination directory to unzip to.
Returns:
None:
"""
from zipfile import ZipFile
zip_file_path = Path(zip_file) if isinstance(zip_file, str) else zip_file
if not zip_file_path.is_file():
raise ValueError(f"Expected file, got '{zip_file_path}'")
if not zip_file_path.is_absolute():
zip_file_path = zip_file_path.absolute()
if not zip_file_path.exists():
raise FileNotFoundError(f"File '{zip_file_path}' not found")
if isinstance(dest_dir, str):
dest_dir = zip_file_path.parent if dest_dir == "" else Path(dest_dir)
else:
dest_dir = dest_dir.absolute()
if not dest_dir.is_dir():
raise ValueError(f"Expected folder, got '{dest_dir}'")
if not dest_dir.exists():
try:
dest_dir.mkdir(parents=True)
except Exception as e:
raise FileNotFoundError(
f"Folder '{dest_dir}' not found, unable to create folder."
) from e
if not dest_dir.exists():
raise FileNotFoundError(f"Folder '{dest_dir}' not found")
with change_dir(dest_dir):
with ZipFile(zip_file_path) as f:
f.extractall(dest_dir)
# with change_dir(dest_dir):
# shutil.unpack_archive(zip_file_path, dest_dir)
class FlatpakInstaller:
"""class for the PIP install."""
def __init__(self, pip_wheel_url: str, lo_identifier: str) -> None:
self.path_python = app.Paths.python
app.debug(f"Python path: {self.path_python}")
self._pip_url = pip_wheel_url
self._lo_identifier = lo_identifier
self._site_packages = cast(str, app.get_flatpak_site_packages_dir())
def install_pip(self) -> None:
if self.is_pip_installed():
app.info("PIP is already installed")
return
if self._install_wheel():
if self.is_pip_installed():
app.info("PIP was installed successfully")
else:
app.error("PIP installation has failed")
return
def _get_pip_cmd(self, filename: Path) -> List[str]:
return [str(self.path_python), f"{filename}", "--user"]
def _get_env(self) -> Dict[str, str]:
"""
Gets Environment used for subprocess.
"""
my_env = os.environ.copy()
py_path = ""
p_sep = ";" if app.IS_WIN else ":"
for d in sys.path:
py_path = py_path + d + p_sep
my_env["PYTHONPATH"] = py_path
return my_env
def _cmd_pip(self, *args: str) -> List[str]:
cmd: List[str] = [str(self.path_python), "-m", "pip", *args]
return cmd
def _install_wheel(self) -> bool:
result = False
installer = InstallPipFromWheel(
pip_wheel_url=self._pip_url, lo_identifier=self._lo_identifier
)
try:
installer.install(self._site_packages)
if self._site_packages not in sys.path:
sys.path.append(self._site_packages)
result = True
except Exception as err:
app.error(err)
return result
return result
def is_pip_installed(self) -> bool:
"""Check if PIP is installed."""
# cmd = self._cmd_pip("--version")
# cmd = '"{}" -m pip -V'.format(self.path_python)
cmd = [str(self.path_python), "-m", "pip", "-V"]
result = subprocess.run(
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=self._get_env()
)
return result.returncode == 0

View File

@ -0,0 +1,146 @@
"""
On some systems such as Mac and AppImage (Linux) the python extension suffix does not match the
cpython suffix used by the embedded python interpreter.
This class creates symlinks for all .so files in dest folder that match the current python embedded suffix.
For example a file named ``indexers.cpython-38-x86_64-linux-gnu.so`` would be symlinked to ``indexers.cpython-3.8.so``.
This renaming allows the python interpreter to find the import.
"""
from __future__ import annotations
from typing import List
from pathlib import Path
from importlib import machinery
import easymacro as app
class LinkCPython:
def __init__(self, pth: str) -> None:
"""
Constructor
Args:
pth (str): Path to site-packages folder.
"""
self._current_suffix = self._get_current_suffix()
app.debug("CPythonLink.__init__")
self._link_root = Path(pth)
if not self._link_root.exists():
raise FileNotFoundError(f"Path does not exist {self._link_root}")
app.debug("CPythonLink.__init__ done")
def _get_current_suffix(self) -> str:
"""Gets suffix currently used by the embedded python interpreter such as ``cpython-3.8``"""
for suffix in machinery.EXTENSION_SUFFIXES:
if suffix.startswith(".cpython-") and suffix.endswith(".so"):
# remove leading . and trailing .so
return suffix[1:][:-3]
return ""
def _get_all_files(self, path: Path) -> List[Path]:
return [p for p in path.glob(f"**/*{self.file_suffix}.so") if p.is_file()]
def _get_all_links(self, path: Path) -> List[Path]:
return [p for p in path.glob(f"**/*{self.current_suffix}.so") if p.is_symlink()]
def _create_symlink(self, src: Path, dst: Path, overwrite: bool) -> None:
if dst.is_symlink():
if overwrite:
app.debug(f"Removing existing symlink {dst}")
dst.unlink()
else:
app.debug(f"Symlink already exists {dst}")
return
dst.symlink_to(src)
app.debug(f"Created symlink {dst} -> {src}")
def _find_current_installed_suffix(self, path: Path) -> str:
"""
Finds the current suffix from the current installed python so files such as ``cpython-38-x86_64-linux-gnu``.
Args:
path (Path): Path to search in. Usually site-packages.
Returns:
str: suffix if found, otherwise empty string.
"""
return next(
(str(p).rsplit(".", 2)[1] for p in path.glob("**/*.cpython-*.so") if not p.is_symlink()),
"",
)
def link(self, overwrite:bool = False) -> None:
"""
Creates symlinks for all .so files in site-packages that match the current suffix.
Args:
overwrite (bool, optional): Override any existing sys links. Defaults to False.
"""
app.debug("CPythonLink.link starting")
if not self._link_root:
app.debug("No site-packages found")
return
if not self.file_suffix:
app.debug("No current file suffix found")
return
if not self._link_root.exists():
app.debug(f"Site-packages does not exist {self._link_root}")
return
app.debug(f"Python current suffix: {self._current_suffix}")
app.debug(f"Found file suffix: {self.file_suffix}")
files = self._get_all_files(self._link_root)
if not files:
app.debug(f"No files found in {self._link_root}")
return
cp_old = self.file_suffix
cp_new = self._current_suffix
if cp_old == cp_new:
app.debug(f"Suffixes match, no need to link: {cp_old} == {cp_new}")
return
for file in files:
ln_name = file.name.replace(cp_old, cp_new)
src = file
if not src.is_absolute():
src = file.resolve()
dst = src.parent / ln_name
self._create_symlink(src, dst, overwrite)
app.debug("CPythonLink.link done")
def unlink(self) -> None:
"""Unlinks all broken sys links"""
links = self._get_all_links(self._link_root)
if not links:
app.debug(f"No links found in {self._link_root}")
return
for link in links:
if not link.exists():
app.debug(f"Removing broken symlink {link}")
link.unlink()
# region Properties
@property
def cpy_name(self) -> str:
"""Gets/Sets CPython name, e.g. cpython-3.8"""
return self._current_suffix
@cpy_name.setter
def cpy_name(self, value: str) -> None:
self._current_suffix = value
@property
def current_suffix(self) -> str:
"""Current Suffix such as ``cpython-3.8``"""
return self._current_suffix
@property
def file_suffix(self) -> str:
"""Current Suffix such as ``cpython-38-x86_64-linux-gnu``"""
try:
return self._file_suffix
except AttributeError:
self._file_suffix = self._find_current_installed_suffix(self._link_root)
return self._file_suffix
# endregion Properties

View File

@ -10,6 +10,7 @@ _ = None
TITLE = 'ZAZ-PIP'
URL_PIP = 'https://bootstrap.pypa.io/get-pip.py'
URL_PIP_WHEEL = 'https://files.pythonhosted.org/packages/47/6a/453160888fab7c6a432a6e25f8afe6256d0d9f2cbd25971021da6491d899/pip-23.3.1-py3-none-any.whl'
URL_TEST = 'http://duckduckgo.com'
PIP = 'pip'
URL_GIT = 'https://git.cuates.net/elmau/zaz-pip'
@ -48,10 +49,13 @@ def open_dialog_pip():
return
def run(args, path_locales):
def run(path_locales):
global _
_ = app.install_locales(path_locales)
globals()[args]()
open_dialog_pip()
return
@ -75,34 +79,33 @@ class Controllers(object):
return
def cmd_install_pip_action(self, event):
msg = _('Do you want install PIP?')
msg = _("Do you want to install 'Python installer package' (PIP)?")
if not app.question(msg, TITLE):
return
self._install_pip()
return
@app.run_in_thread
def _install_pip(self):
def _install_pip_normal(self) -> None:
self.d.link_proyect.visible = False
self.d.lst_log.visible = True
path_pip = app.paths.tmp()
self.d.lst_log.insert(_('Download PIP...'))
self.d.lst_log.insert(_('Downloading PIP…'))
data, h, err = app.url_open(URL_PIP, verify=False)
if err:
msg = _('Do you have internet connection?')
msg = _('Unable to connect to internet')
app.errorbox('{}\n\n{}'.format(msg, err))
return
app.paths.save_bin(path_pip, data)
if not app.paths.exists(path_pip):
msg = _('File PIP not save')
msg = _('Unable to copy PIP installation file')
app.errorbox(msg)
return
self.d.lst_log.insert(_('PIP save correctly...'))
self.d.lst_log.insert(_('PIP installation file has been saved'))
try:
self.d.lst_log.insert(_('Start installing PIP...'))
self.d.lst_log.insert(_("Starting PIP installation…"))
cmd = f'"{self.path_python}" "{path_pip}" --user'
for line in app.popen(cmd):
if isinstance(line, tuple):
@ -116,16 +119,45 @@ class Controllers(object):
self.d.lbl_pip.value = label
self.d.cmd_install_pip.visible = False
self.d.cmd_admin_pip.visible = True
msg = _('PIP installed sucesfully')
msg = _('PIP was installed successfully')
app.msgbox(msg)
else:
msg = _('PIP not installed, see log')
msg = _('PIP installation has failed, see log')
app.warning(msg)
except Exception as e:
app.errorbox(e)
return
def _install_pip_flatpak(self) -> None:
try:
from install_flatpak import FlatpakInstaller
installer = FlatpakInstaller(pip_wheel_url=URL_PIP_WHEEL, lo_identifier=ID_EXTENSION)
installer.install_pip()
msg = _('PIP was installed successfully')
# app.msgbox(msg)
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 was installed successfully')
app.msgbox(msg)
else:
msg = _('PIP installation has failed, see log')
app.warning(msg)
except Exception as e:
app.errorbox(e)
@app.run_in_thread
def _install_pip(self):
if app.IS_FLATPAK:
self._install_pip_flatpak()
else:
self._install_pip_normal()
return
def _cmd_pip(self, args):
cmd = '"{}" -m pip {}'.format(self.path_python, args)
return cmd
@ -148,7 +180,8 @@ class Controllers(object):
def txt_search_key_released(self, event):
if event.KeyCode == app.KEY['enter']:
self.cmd_search_action(None)
# ~ self.cmd_search_action(None)
self.cmd_install_action(None)
return
if not self.d.txt_search.value.strip():
@ -192,7 +225,7 @@ class Controllers(object):
if line:
self.d.lst_package.select()
else:
self.d.lst_package.insert(_('Not found...'), 'error.png', show=False)
self.d.lst_package.insert(_('Package not found…'), 'error.png', show=False)
return
def cmd_search_action(self, event):
@ -207,12 +240,12 @@ class Controllers(object):
def cmd_install_action(self, event):
name = self.d.txt_search.value.strip()
if not name:
msg = _('Enter package name to install')
msg = _('Enter the package name to install')
app.warning(msg)
self.d.txt_search.set_focus()
return
msg = _(f'Install package: {name} ?')
msg = _('Do you really want to install package: {}?').format(name)
if not app.question(msg):
return
@ -226,7 +259,10 @@ class Controllers(object):
self.d.lst_log.visible = True
line = ''
cmd = ' install --upgrade --user'
if app.IS_FLATPAK:
cmd = f' install --upgrade --target={app.get_site_packages_dir()}'
else:
cmd = ' install --upgrade --user'
if value:
name = value.split(' ')[0].strip()
cmd = self._cmd_pip(f'{cmd} {name}')
@ -238,15 +274,40 @@ class Controllers(object):
self.d.lst_log.insert(line, 'ok.png')
else:
self.d.lst_log.insert(line)
self._link_cpython()
return
def _link_cpython(self):
if not app.IS_MAC and not app.IS_APP_IMAGE:
return
try:
app.debug("Linking CPython")
from link_cpython import LinkCPython
cpy_link = LinkCPython(pth=app.get_site_packages_dir())
cpy_link.link()
except Exception as err:
app.error(err)
return
def _unlink_cpython(self):
if not app.IS_MAC and not app.IS_APP_IMAGE:
return
try:
app.debug("Unlinking CPython")
from link_cpython import LinkCPython
cpy_link = LinkCPython(pth=app.get_site_packages_dir())
cpy_link.unlink()
except Exception as err:
app.error(err)
return
def lst_package_double_click(self, event):
opt = 'install'
opt = _('install')
if self._states['list']:
opt = 'upgrade'
opt = _('upgrade')
name = self.d.lst_package.value
msg = _('Do you want {}:\n\n{} ?').format(opt, name)
msg = _('Do you want to {}:\n\n{}?').format(opt, name)
if not app.question(msg, TITLE):
return
@ -268,6 +329,7 @@ class Controllers(object):
self.d.lst_log.insert(line, 'ok.png')
else:
self.d.lst_log.insert(line)
self._unlink_cpython()
return
def cmd_uninstall_action(self, event):
@ -277,7 +339,7 @@ class Controllers(object):
return
name = self.d.lst_package.value
msg = _('Do you want uninstall:\n\n{} ?').format(name)
msg = _('Do you want to uninstall:\n\n{}?').format(name)
if not app.question(msg):
return
@ -304,7 +366,7 @@ class Controllers(object):
if not path:
return
msg = _(f'Confirm install from:\n\n{path}')
msg = _('Do you want to install from:\n\n{}').format(path)
if not app.question(msg):
return
@ -331,25 +393,25 @@ class ControllersProxy(object):
txt_proxy_user = self.d.txt_proxy_user.value,
txt_proxy_pass = self.d.txt_proxy_pass.value,
)
msg = _('Are you shure save data?')
msg = _('Do you want to save this Proxy settings?')
if not app.question(msg):
return
app.set_config('proxy', data, TITLE)
msg = _('Save data sucesfully')
msg = _('Proxy settings saved sucessfully')
app.msgbox(msg)
self.d.close()
return
def cmd_proxy_delete_action(self, event):
msg = _("Are you shure delete data?")
msg = _("Do you want to remove Proxy settings?")
if not app.question(msg):
return
app.set_config('proxy', {}, TITLE)
msg = _('Delete data sucesfully')
msg = _('Proxy settings deleted sucessfully')
app.msgbox(msg)
self.d.close()
return
@ -407,7 +469,7 @@ def _create_dialog():
exists_pip = True
if not label:
exists_pip = False
label = _('PIP not installed')
label = _("'Python installer package' (PIP) is not installed")
args = {
'Type': 'Label',
'Name': 'lbl_pip',
@ -629,7 +691,7 @@ def _create_dialog():
def _create_dialog_proxy():
args= {
'Name': 'dlg_proxy',
'Title': 'Zaz-Pip - Config Proxy',
'Title': _('Zaz-Pip - Proxy settings'),
'Width': 150,
'Height': 100,
}
@ -640,7 +702,7 @@ def _create_dialog_proxy():
args = {
'Type': 'Label',
'Name': 'lbl_proxy_host',
'Label': 'Host: ',
'Label': _('Host: '),
'Width': 40,
'Height': 12,
'Border': 1,
@ -663,7 +725,7 @@ def _create_dialog_proxy():
args = {
'Type': 'Label',
'Name': 'lbl_proxy_port',
'Label': 'Port: ',
'Label': _('Port: '),
'Width': 40,
'Height': 12,
'Border': 1,
@ -684,7 +746,7 @@ def _create_dialog_proxy():
args = {
'Type': 'Label',
'Name': 'lbl_proxy_user',
'Label': 'User: ',
'Label': _('User: '),
'Width': 40,
'Height': 12,
'Border': 1,
@ -705,7 +767,7 @@ def _create_dialog_proxy():
args = {
'Type': 'Label',
'Name': 'lbl_proxy_pass',
'Label': 'Password: ',
'Label': _('Password: '),
'Width': 40,
'Height': 12,
'Border': 1,

View File

@ -0,0 +1,14 @@
This file is part of ZAZPip.
ZAZPip is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ZAZPip is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ZAZPip. If not, see <https://www.gnu.org/licenses/>.

29
zaz.py
View File

@ -75,10 +75,16 @@ class LiboXML(object):
'manifest': 'urn:oasis:names:tc:opendocument:xmlns:manifest:1.0',
'xmlns:loext': 'urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0',
}
xmlns = 'http://openoffice.org/extensions/description/2006'
xmlns_xlink = 'http://www.w3.org/1999/xlink'
xmlns_l = 'http://libreoffice.org/extensions/description/2011'
NS_DESCRIPTION = {
'xmlns': 'http://openoffice.org/extensions/description/2006',
'xmlns:xlink': 'http://www.w3.org/1999/xlink',
'xmlns:d': 'http://openoffice.org/extensions/description/2006',
'xmlns': xmlns,
'xmlns:xlink': xmlns_xlink,
'xmlns:d': xmlns,
'xmlns:l': xmlns_l,
}
NS_ADDONS = {
'xmlns:xs': 'http://www.w3.org/2001/XMLSchema',
@ -87,7 +93,7 @@ class LiboXML(object):
NS_UPDATE = {
'xmlns': 'http://openoffice.org/extensions/update/2006',
'xmlns:d': 'http://openoffice.org/extensions/description/2006',
'xmlns:xlink': 'http://www.w3.org/1999/xlink',
'xmlns:xlink': xmlns_xlink,
}
def __init__(self):
@ -158,6 +164,13 @@ class LiboXML(object):
key = 'version'
ET.SubElement(doc, key, data[key])
key = 'minimal'
if data[key]:
node = ET.SubElement(doc, 'dependencies')
# ~ attr = {'value': data[key], 'name': f'LibreOffice {data[key]}'}
attr = {'value': data[key]}
ET.SubElement(node, 'l:LibreOffice-minimal-version', attr)
key = 'display-name'
node = ET.SubElement(doc, key)
for k, v in data[key].items():
@ -413,14 +426,14 @@ def _compress_oxt():
z.write(fullpath, file_name, zipfile.ZIP_DEFLATED)
z.close()
log.info('Extension OXT created sucesfully...')
log.info('Extension OXT created successfully...')
return
def _install_and_test():
path_oxt = (_join(DIRS['files'], FILES['oxt']),)
call(PATHS['install'] + path_oxt)
log.info('Install extension sucesfully...')
log.info('Install extension successfully...')
log.info('Start LibreOffice...')
call(PATHS['soffice'])
return
@ -525,7 +538,7 @@ def _compile_idl():
call([PATHS['regmerge'], path_rdb, '/UCR', path_urd])
os.remove(path_urd)
log.info('Compilate IDL sucesfully...')
log.info('Compilate IDL successfully...')
return
@ -742,7 +755,7 @@ def _new(args):
path = _join(args.target, args.name)
_mkdir(path)
_mkdir(_join(path, 'files'))
_mkdir(_join(path, 'ext'))
_mkdir(_join(path, 'images'))
path_logo = 'images/pymacros.png'
copyfile(path_logo, _join(path, 'images/logo.png'))