Compare commits
6 Commits
Author | SHA1 | Date |
---|---|---|
Mauricio Baeza | 57eeb5ce30 | |
El Mau | 1aab8f8cdd | |
El Mau | fb124c35d0 | |
El Mau | a29a7d0b81 | |
El Mau | aac5b910a5 | |
El Mau | f033f0e2c4 |
|
@ -1,4 +1,7 @@
|
||||||
# ---> Python
|
# ---> Python
|
||||||
|
|
||||||
|
nerd-dictation/
|
||||||
|
|
||||||
# Byte-compiled / optimized / DLL files
|
# Byte-compiled / optimized / DLL files
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
# zaz-talk2me
|
||||||
|
|
||||||
|
Soporte para dictado en LibreOffice
|
||||||
|
|
||||||
|
**Importante**: Solo para Linux y LibreOffice instalado desde el sistema de paquetes de tu distribución.
|
||||||
|
|
||||||
|
Soporte para inglés y español.
|
||||||
|
|
||||||
|
Dependencias:
|
||||||
|
|
||||||
|
Ubuntu y derivados.
|
||||||
|
```
|
||||||
|
sudo apt install libreoffice-script-provider-python python3-pip
|
||||||
|
sudo pip3 install --upgrade pip wheel
|
||||||
|
pip install --user vosk
|
||||||
|
```
|
||||||
|
|
||||||
|
Arch
|
||||||
|
```
|
||||||
|
pip install --user vosk
|
||||||
|
```
|
||||||
|
|
||||||
|
Gracias a:
|
||||||
|
https://alphacephei.com/vosk/
|
24
README.md
24
README.md
|
@ -1,3 +1,25 @@
|
||||||
# zaz-talk2me
|
# zaz-talk2me
|
||||||
|
|
||||||
Dictation support for LibreOffice
|
Dictation support for LibreOffice
|
||||||
|
|
||||||
|
**Important**: Only for Linux and LibreOffice install from distribute repositories.
|
||||||
|
|
||||||
|
Support for English and Spanish.
|
||||||
|
|
||||||
|
Dependencies:
|
||||||
|
|
||||||
|
Ubuntu and derivatives.
|
||||||
|
```
|
||||||
|
sudo apt install libreoffice-script-provider-python python3-pip
|
||||||
|
sudo pip3 install --upgrade pip wheel
|
||||||
|
pip install --user vosk
|
||||||
|
```
|
||||||
|
|
||||||
|
Arch
|
||||||
|
```
|
||||||
|
pip install --user vosk
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Thanks to:
|
||||||
|
https://alphacephei.com/vosk/
|
||||||
|
|
|
@ -0,0 +1,433 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# ~ This file is part of ZAZ.
|
||||||
|
|
||||||
|
# ~ ZAZ 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.
|
||||||
|
|
||||||
|
# ~ ZAZ 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 ZAZ. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
# ~ Type extension:
|
||||||
|
# ~ 1 = normal extension
|
||||||
|
# ~ 2 = new component
|
||||||
|
# ~ 3 = Calc addin
|
||||||
|
TYPE_EXTENSION = 1
|
||||||
|
|
||||||
|
# ~ Your great extension name, not used spaces
|
||||||
|
NAME = 'ZazTalk2Me'
|
||||||
|
|
||||||
|
# ~ https://semver.org/
|
||||||
|
VERSION = '0.1.0'
|
||||||
|
|
||||||
|
|
||||||
|
# ~ Should be unique, used URL inverse
|
||||||
|
ID = 'net.elmau.zaz.talk'
|
||||||
|
|
||||||
|
# ~ If you extension will be multilanguage set: True
|
||||||
|
# ~ This feature used gettext, set pythonpath and easymacro in True
|
||||||
|
# ~ You can used PoEdit for edit PO files and generate MO files.
|
||||||
|
# ~ https://poedit.net/
|
||||||
|
USE_LOCALES = True
|
||||||
|
DOMAIN = 'base'
|
||||||
|
PATH_LOCALES = 'locales'
|
||||||
|
PATH_PYGETTEXT = '/usr/lib/python3.10/Tools/i18n/pygettext.py'
|
||||||
|
# ~ You can use PoEdit for update locales too
|
||||||
|
PATH_MSGMERGE = 'msgmerge'
|
||||||
|
|
||||||
|
|
||||||
|
# ~ Show in extension manager
|
||||||
|
PUBLISHER = {
|
||||||
|
'en': {'text': 'El Mau', 'link': 'https://git.cuates.net/elmau/zaz-talk2me'},
|
||||||
|
'es': {'text': 'El Mau', 'link': 'https://git.cuates.net/elmau/zaz-talk2me'},
|
||||||
|
}
|
||||||
|
|
||||||
|
# ~ Name in this folder for copy
|
||||||
|
ICON = 'images/logo.png'
|
||||||
|
# ~ Name inside extensions
|
||||||
|
ICON_EXT = f'{NAME.lower()}.png'
|
||||||
|
|
||||||
|
DEPENDENCIES_MINIMAL = ''
|
||||||
|
|
||||||
|
# ~ Change for you favorite license
|
||||||
|
LICENSE_EN = f"""This file is part of {NAME}.
|
||||||
|
|
||||||
|
{NAME} 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.
|
||||||
|
|
||||||
|
{NAME} 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 {NAME}. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
"""
|
||||||
|
LICENSE_ES = LICENSE_EN
|
||||||
|
|
||||||
|
INFO = {
|
||||||
|
'en': {
|
||||||
|
'display_name': 'Zaz Talk2Me',
|
||||||
|
'description': 'Dictation support for LibreOffice',
|
||||||
|
'license': LICENSE_EN,
|
||||||
|
},
|
||||||
|
'es': {
|
||||||
|
'display_name': 'Zaz Hablame',
|
||||||
|
'description': 'Soporte para dictado en LibreOffice',
|
||||||
|
'license': LICENSE_ES,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ~ Menus, only for TYPE_EXTENSION = 1
|
||||||
|
# ~ Parent can be: AddonMenu or OfficeMenuBar
|
||||||
|
# ~ For icons con name: NAME_16.bmp, used only NAME
|
||||||
|
# ~ PARENT = ''
|
||||||
|
# ~ MENU_MAIN = {}
|
||||||
|
# ~ Shortcut: Key + "Modifier Keys"
|
||||||
|
# ~ Important: Not used any shortcuts used for LibreOffice
|
||||||
|
# ~ SHIFT is mapped to Shift on all platforms.
|
||||||
|
# ~ MOD1 is mapped to Ctrl on Windows/Linux, while it is mapped to Cmd on Mac.
|
||||||
|
# ~ MOD2 is mapped to Alt on all platforms.
|
||||||
|
# ~ For example: Shift+Ctrl+Alt+T -> T_SHIFT_MOD1_MOD2
|
||||||
|
PARENT = 'OfficeMenuBar'
|
||||||
|
MENU_MAIN = {
|
||||||
|
'en': 'Zaz Talk2Me',
|
||||||
|
'es': 'Zaz Hablame',
|
||||||
|
}
|
||||||
|
MENUS = (
|
||||||
|
{
|
||||||
|
'title': {'en': 'Start', 'es': 'Iniciar'},
|
||||||
|
'argument': 'start',
|
||||||
|
'context': 'writer,calc',
|
||||||
|
'icon': 'start',
|
||||||
|
'toolbar': True,
|
||||||
|
'shortcut': 'S_SHIFT_MOD1_MOD2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'title': {'en': 'End', 'es': 'Terminar'},
|
||||||
|
'argument': 'end',
|
||||||
|
'context': 'writer,calc',
|
||||||
|
'icon': 'end',
|
||||||
|
'toolbar': True,
|
||||||
|
'shortcut': 'E_SHIFT_MOD1_MOD2',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ~ Functions, only for TYPE_EXTENSION = 3
|
||||||
|
FUNCTIONS = {
|
||||||
|
'test': {
|
||||||
|
'displayname': {'en': 'test', 'es': 'prueba'},
|
||||||
|
'description': {'en': 'My test', 'es': 'Mi prueba'},
|
||||||
|
'parameters': {
|
||||||
|
'value': {
|
||||||
|
'displayname': {'en': 'value', 'es': 'valor'},
|
||||||
|
'description': {'en': 'The value', 'es': 'El valor'},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
# ~ FUNCTIONS = {}
|
||||||
|
|
||||||
|
EXTENSION = {
|
||||||
|
'version': VERSION,
|
||||||
|
'name': NAME,
|
||||||
|
'id': ID,
|
||||||
|
'icon': (ICON, ICON_EXT),
|
||||||
|
'languages': tuple(INFO.keys())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ~ If used more libraries set python path in True and copy inside
|
||||||
|
# ~ If used easymacro pythonpath always is True, recommended
|
||||||
|
DIRS = {
|
||||||
|
'meta': 'META-INF',
|
||||||
|
'source': 'source',
|
||||||
|
'description': 'description',
|
||||||
|
'images': 'images',
|
||||||
|
'registration': 'registration',
|
||||||
|
'files': 'extension',
|
||||||
|
'office': 'Office',
|
||||||
|
'locales': PATH_LOCALES,
|
||||||
|
'pythonpath': True,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FILES = {
|
||||||
|
'oxt': f'{NAME}_v{VERSION}.oxt',
|
||||||
|
'py': f'{NAME}.py',
|
||||||
|
'ext_desc': 'desc_{}.txt',
|
||||||
|
'manifest': 'manifest.xml',
|
||||||
|
'description': 'description.xml',
|
||||||
|
'idl': f'X{NAME}.idl',
|
||||||
|
'addons': 'Addons.xcu',
|
||||||
|
'urd': f'X{NAME}.urd',
|
||||||
|
'rdb': f'X{NAME}.rdb',
|
||||||
|
'update': f'{NAME.lower()}.update.xml',
|
||||||
|
'addin': 'CalcAddIn.xcu',
|
||||||
|
'shortcut': 'Accelerators.xcu',
|
||||||
|
'easymacro': True,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ~ URLs for update for example
|
||||||
|
# ~ URL_XML_UPDATE = 'https://gitlab.com/USER/PROYECT/raw/BRANCH/FOLDERs/FILE_NAME'
|
||||||
|
URL_XML_UPDATE = ''
|
||||||
|
URL_OXT = ''
|
||||||
|
|
||||||
|
|
||||||
|
# ~ Default program for test: --calc, --writer, --draw
|
||||||
|
PROGRAM = '--writer'
|
||||||
|
# ~ Path to file for test
|
||||||
|
FILE_TEST = ''
|
||||||
|
|
||||||
|
PATHS = {
|
||||||
|
'idlc': '/usr/lib/libreoffice/sdk/bin/idlc',
|
||||||
|
'include': '/usr/share/idl/libreoffice',
|
||||||
|
'regmerge': '/usr/lib/libreoffice/program/regmerge',
|
||||||
|
'soffice': ('soffice', PROGRAM, FILE_TEST),
|
||||||
|
'install': ('unopkg', 'add', '-v', '-f', '-s'),
|
||||||
|
'profile': '/home/mau/.config/libreoffice/4/user',
|
||||||
|
'gettext': PATH_PYGETTEXT,
|
||||||
|
'msgmerge': PATH_MSGMERGE,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SERVICES = {
|
||||||
|
'job': "('com.sun.star.task.Job',)",
|
||||||
|
'addin': "('com.sun.star.sheet.AddIn',)",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
|
||||||
|
DATE = '%d/%m/%Y %H:%M:%S'
|
||||||
|
LEVEL_ERROR = logging.getLevelName(logging.ERROR)
|
||||||
|
LEVEL_INFO = logging.getLevelName(logging.INFO)
|
||||||
|
logging.addLevelName(logging.ERROR, f'\033[1;41m{LEVEL_ERROR}\033[1;0m')
|
||||||
|
logging.addLevelName(logging.INFO, f'\x1b[32m{LEVEL_INFO}\033[1;0m')
|
||||||
|
logging.basicConfig(level=logging.DEBUG, format=FORMAT, datefmt=DATE)
|
||||||
|
log = logging.getLogger(NAME)
|
||||||
|
|
||||||
|
|
||||||
|
def _methods():
|
||||||
|
template = """ def {0}(self, {1}):
|
||||||
|
print({1})
|
||||||
|
return 'ok'\n"""
|
||||||
|
functions = ''
|
||||||
|
for k, v in FUNCTIONS.items():
|
||||||
|
args = ','.join(v['parameters'].keys())
|
||||||
|
functions += template.format(k, args)
|
||||||
|
return functions
|
||||||
|
|
||||||
|
|
||||||
|
SRV = SERVICES['job']
|
||||||
|
XSRV = 'XJobExecutor'
|
||||||
|
SRV_IMPORT = f'from com.sun.star.task import {XSRV}'
|
||||||
|
METHODS = """ def trigger(self, args='pyUNO'):
|
||||||
|
print('Hello World', args)
|
||||||
|
return\n"""
|
||||||
|
|
||||||
|
if TYPE_EXTENSION > 1:
|
||||||
|
MENUS = ()
|
||||||
|
XSRV = f'X{NAME}'
|
||||||
|
SRV_IMPORT = f'from {ID} import {XSRV}'
|
||||||
|
if TYPE_EXTENSION == 2:
|
||||||
|
SRV = f"('{ID}',)"
|
||||||
|
METHODS = """ def test(self, args='pyUNO'):
|
||||||
|
print('Hello World', args)
|
||||||
|
return\n"""
|
||||||
|
elif TYPE_EXTENSION == 3:
|
||||||
|
SRV = SERVICES['addin']
|
||||||
|
METHODS = _methods()
|
||||||
|
|
||||||
|
|
||||||
|
DATA_PY = f"""import uno
|
||||||
|
import unohelper
|
||||||
|
{SRV_IMPORT}
|
||||||
|
|
||||||
|
|
||||||
|
ID_EXTENSION = '{ID}'
|
||||||
|
SERVICE = {SRV}
|
||||||
|
|
||||||
|
|
||||||
|
class {NAME}(unohelper.Base, {XSRV}):
|
||||||
|
|
||||||
|
def __init__(self, ctx):
|
||||||
|
self.ctx = ctx
|
||||||
|
|
||||||
|
{METHODS}
|
||||||
|
|
||||||
|
g_ImplementationHelper = unohelper.ImplementationHelper()
|
||||||
|
g_ImplementationHelper.addImplementation({NAME}, ID_EXTENSION, SERVICE)
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _functions():
|
||||||
|
a = '[in] any {}'
|
||||||
|
t = ' any {}({});'
|
||||||
|
f = ''
|
||||||
|
for k, v in FUNCTIONS.items():
|
||||||
|
args = ','.join([a.format(k) for k, v in v['parameters'].items()])
|
||||||
|
f += t.format(k, args)
|
||||||
|
return f
|
||||||
|
|
||||||
|
|
||||||
|
FILE_IDL = ''
|
||||||
|
if TYPE_EXTENSION > 1:
|
||||||
|
id_ext = ID.replace('.', '_')
|
||||||
|
interface = f'X{NAME}'
|
||||||
|
module = ''
|
||||||
|
for i, P in enumerate(ID.split('.')):
|
||||||
|
module += f'module {P} {{ '
|
||||||
|
close_module = '}; ' * (i + 1)
|
||||||
|
functions = ' void test([in] any argument);'
|
||||||
|
if TYPE_EXTENSION == 3:
|
||||||
|
functions = _functions()
|
||||||
|
|
||||||
|
FILE_IDL = f"""#ifndef __{id_ext}_idl__
|
||||||
|
#define __{id_ext}_idl__
|
||||||
|
|
||||||
|
#include <com/sun/star/uno/XInterface.idl>
|
||||||
|
|
||||||
|
{module}
|
||||||
|
|
||||||
|
interface {interface} : com::sun::star::uno::XInterface
|
||||||
|
{{
|
||||||
|
{functions}
|
||||||
|
}};
|
||||||
|
|
||||||
|
service {P} {{
|
||||||
|
interface {interface};
|
||||||
|
}};
|
||||||
|
|
||||||
|
{close_module}
|
||||||
|
#endif
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def _parameters(args):
|
||||||
|
NODE = """ <node oor:name="{name}" oor:op="replace">
|
||||||
|
<prop oor:name="DisplayName">
|
||||||
|
{displayname}
|
||||||
|
</prop>
|
||||||
|
<prop oor:name="Description">
|
||||||
|
{description}
|
||||||
|
</prop>
|
||||||
|
</node>"""
|
||||||
|
line = '{}<value xml:lang="{}">{}</value>'
|
||||||
|
node = ''
|
||||||
|
for k, v in args.items():
|
||||||
|
displayname = '\n'.join(
|
||||||
|
[line.format(' ' * 16, k, v) for k, v in v['displayname'].items()])
|
||||||
|
description = '\n'.join(
|
||||||
|
[line.format(' ' * 16, k, v) for k, v in v['description'].items()])
|
||||||
|
values = {
|
||||||
|
'name': k,
|
||||||
|
'displayname': displayname,
|
||||||
|
'description': description,
|
||||||
|
}
|
||||||
|
node += NODE.format(**values)
|
||||||
|
return node
|
||||||
|
|
||||||
|
|
||||||
|
NODE_FUNCTIONS = ''
|
||||||
|
if TYPE_EXTENSION == 3:
|
||||||
|
tmp = '{}<value xml:lang="{}">{}</value>'
|
||||||
|
NODE_FUNCTION = """ <node oor:name="{name}" oor:op="replace">
|
||||||
|
<prop oor:name="DisplayName">
|
||||||
|
{displayname}
|
||||||
|
</prop>
|
||||||
|
<prop oor:name="Description">
|
||||||
|
{description}
|
||||||
|
</prop>
|
||||||
|
<prop oor:name="Category">
|
||||||
|
<value>Add-In</value>
|
||||||
|
</prop>
|
||||||
|
<prop oor:name="CompatibilityName">
|
||||||
|
<value xml:lang="en">AutoAddIn.{name}</value>
|
||||||
|
</prop>
|
||||||
|
<node oor:name="Parameters">
|
||||||
|
{parameters}
|
||||||
|
</node>
|
||||||
|
</node>"""
|
||||||
|
|
||||||
|
for k, v in FUNCTIONS.items():
|
||||||
|
displayname = '\n'.join(
|
||||||
|
[tmp.format(' ' * 12, k, v) for k, v in v['displayname'].items()])
|
||||||
|
description = '\n'.join(
|
||||||
|
[tmp.format(' ' * 12, k, v) for k, v in v['description'].items()])
|
||||||
|
parameters = _parameters(v['parameters'])
|
||||||
|
values = {
|
||||||
|
'name': k,
|
||||||
|
'displayname': displayname,
|
||||||
|
'description': description,
|
||||||
|
'parameters': parameters,
|
||||||
|
}
|
||||||
|
NODE_FUNCTIONS += NODE_FUNCTION.format(**values)
|
||||||
|
|
||||||
|
|
||||||
|
FILE_ADDIN = f"""<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:name="CalcAddIns" oor:package="org.openoffice.Office">
|
||||||
|
<node oor:name="AddInInfo">
|
||||||
|
<node oor:name="{ID}" oor:op="replace">
|
||||||
|
<node oor:name="AddInFunctions">
|
||||||
|
{NODE_FUNCTIONS}
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</oor:component-data>"""
|
||||||
|
|
||||||
|
|
||||||
|
DATA_MANIFEST = [FILES['py'], f"Office/{FILES['shortcut']}", 'Addons.xcu']
|
||||||
|
if TYPE_EXTENSION > 1:
|
||||||
|
DATA_MANIFEST.append(FILES['rdb'])
|
||||||
|
if TYPE_EXTENSION == 3:
|
||||||
|
DATA_MANIFEST.append('CalcAddIn.xcu')
|
||||||
|
|
||||||
|
DATA_DESCRIPTION = {
|
||||||
|
'identifier': {'value': ID},
|
||||||
|
'version': {'value': VERSION},
|
||||||
|
'display-name': {k: v['display_name'] for k, v in INFO.items()},
|
||||||
|
'icon': ICON_EXT,
|
||||||
|
'publisher': PUBLISHER,
|
||||||
|
'update': URL_XML_UPDATE,
|
||||||
|
'minimal': DEPENDENCIES_MINIMAL,
|
||||||
|
}
|
||||||
|
|
||||||
|
DATA_ADDONS = {
|
||||||
|
'parent': PARENT,
|
||||||
|
'images': DIRS['images'],
|
||||||
|
'main': MENU_MAIN,
|
||||||
|
'menus': MENUS,
|
||||||
|
}
|
||||||
|
|
||||||
|
DATA = {
|
||||||
|
'py': DATA_PY,
|
||||||
|
'manifest': DATA_MANIFEST,
|
||||||
|
'description': DATA_DESCRIPTION,
|
||||||
|
'addons': DATA_ADDONS,
|
||||||
|
'update': URL_OXT,
|
||||||
|
'idl': FILE_IDL,
|
||||||
|
'addin': FILE_ADDIN,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
with open('VERSION', 'w') as f:
|
||||||
|
f.write(VERSION)
|
||||||
|
|
||||||
|
|
||||||
|
# ~ LICENSE_ACCEPT_BY = 'user' # or admin
|
||||||
|
# ~ LICENSE_SUPPRESS_ON_UPDATE = True
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
|
@ -0,0 +1 @@
|
||||||
|
vosk
|
|
@ -0,0 +1,94 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<oor:component-data xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:oor="http://openoffice.org/2001/registry" oor:name="Addons" oor:package="org.openoffice.Office">
|
||||||
|
<node oor:name="AddonUI">
|
||||||
|
<node oor:name="OfficeMenuBar">
|
||||||
|
<node oor:name="net.elmau.zaz.talk" oor:op="replace">
|
||||||
|
<prop oor:name="Title" oor:type="xs:string">
|
||||||
|
<value xml:lang="en">Zaz Talk2Me</value>
|
||||||
|
<value xml:lang="es">Zaz Hablame</value>
|
||||||
|
</prop>
|
||||||
|
<prop oor:name="Target" oor:type="xs:string">
|
||||||
|
<value>_self</value>
|
||||||
|
</prop>
|
||||||
|
<node oor:name="Submenu">
|
||||||
|
<node oor:name="m0" oor:op="replace">
|
||||||
|
<prop oor:name="Title" oor:type="xs:string">
|
||||||
|
<value xml:lang="en">Start</value>
|
||||||
|
<value xml:lang="es">Iniciar</value>
|
||||||
|
</prop>
|
||||||
|
<prop oor:name="Context" oor:type="xs:string">
|
||||||
|
<value>com.sun.star.text.TextDocument,com.sun.star.sheet.SpreadsheetDocument</value>
|
||||||
|
</prop>
|
||||||
|
<prop oor:name="URL" oor:type="xs:string">
|
||||||
|
<value>service:net.elmau.zaz.talk?start</value>
|
||||||
|
</prop>
|
||||||
|
<prop oor:name="Target" oor:type="xs:string">
|
||||||
|
<value>_self</value>
|
||||||
|
</prop>
|
||||||
|
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||||
|
<value>%origin%/images/start</value>
|
||||||
|
</prop>
|
||||||
|
</node>
|
||||||
|
<node oor:name="m1" oor:op="replace">
|
||||||
|
<prop oor:name="Title" oor:type="xs:string">
|
||||||
|
<value xml:lang="en">End</value>
|
||||||
|
<value xml:lang="es">Terminar</value>
|
||||||
|
</prop>
|
||||||
|
<prop oor:name="Context" oor:type="xs:string">
|
||||||
|
<value>com.sun.star.text.TextDocument,com.sun.star.sheet.SpreadsheetDocument</value>
|
||||||
|
</prop>
|
||||||
|
<prop oor:name="URL" oor:type="xs:string">
|
||||||
|
<value>service:net.elmau.zaz.talk?end</value>
|
||||||
|
</prop>
|
||||||
|
<prop oor:name="Target" oor:type="xs:string">
|
||||||
|
<value>_self</value>
|
||||||
|
</prop>
|
||||||
|
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||||
|
<value>%origin%/images/end</value>
|
||||||
|
</prop>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node oor:name="OfficeToolBar">
|
||||||
|
<node oor:name="net.elmau.zaz.talk" oor:op="replace">
|
||||||
|
<node oor:name="t0" oor:op="replace">
|
||||||
|
<prop oor:name="Title" oor:type="xs:string">
|
||||||
|
<value xml:lang="en">Start</value>
|
||||||
|
<value xml:lang="es">Iniciar</value>
|
||||||
|
</prop>
|
||||||
|
<prop oor:name="Context" oor:type="xs:string">
|
||||||
|
<value>com.sun.star.text.TextDocument,com.sun.star.sheet.SpreadsheetDocument</value>
|
||||||
|
</prop>
|
||||||
|
<prop oor:name="URL" oor:type="xs:string">
|
||||||
|
<value>service:net.elmau.zaz.talk?start</value>
|
||||||
|
</prop>
|
||||||
|
<prop oor:name="Target" oor:type="xs:string">
|
||||||
|
<value>_self</value>
|
||||||
|
</prop>
|
||||||
|
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||||
|
<value>%origin%/images/start</value>
|
||||||
|
</prop>
|
||||||
|
</node>
|
||||||
|
<node oor:name="t1" oor:op="replace">
|
||||||
|
<prop oor:name="Title" oor:type="xs:string">
|
||||||
|
<value xml:lang="en">End</value>
|
||||||
|
<value xml:lang="es">Terminar</value>
|
||||||
|
</prop>
|
||||||
|
<prop oor:name="Context" oor:type="xs:string">
|
||||||
|
<value>com.sun.star.text.TextDocument,com.sun.star.sheet.SpreadsheetDocument</value>
|
||||||
|
</prop>
|
||||||
|
<prop oor:name="URL" oor:type="xs:string">
|
||||||
|
<value>service:net.elmau.zaz.talk?end</value>
|
||||||
|
</prop>
|
||||||
|
<prop oor:name="Target" oor:type="xs:string">
|
||||||
|
<value>_self</value>
|
||||||
|
</prop>
|
||||||
|
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||||
|
<value>%origin%/images/end</value>
|
||||||
|
</prop>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</oor:component-data>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?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="ZazTalk2Me.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>
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<oor:component-data xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:oor="http://openoffice.org/2001/registry" oor:name="Accelerators" oor:package="org.openoffice.Office">
|
||||||
|
<node oor:name="PrimaryKeys">
|
||||||
|
<node oor:name="Modules">
|
||||||
|
<node oor:name="com.sun.star.text.TextDocument">
|
||||||
|
<node oor:name="S_SHIFT_MOD1_MOD2" oor:op="fuse">
|
||||||
|
<prop oor:name="Command">
|
||||||
|
<value xml:lang="en-US">service:net.elmau.zaz.talk?start</value>
|
||||||
|
</prop>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node oor:name="com.sun.star.sheet.SpreadsheetDocument">
|
||||||
|
<node oor:name="S_SHIFT_MOD1_MOD2" oor:op="fuse">
|
||||||
|
<prop oor:name="Command">
|
||||||
|
<value xml:lang="en-US">service:net.elmau.zaz.talk?start</value>
|
||||||
|
</prop>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node oor:name="com.sun.star.text.TextDocument">
|
||||||
|
<node oor:name="E_SHIFT_MOD1_MOD2" oor:op="fuse">
|
||||||
|
<prop oor:name="Command">
|
||||||
|
<value xml:lang="en-US">service:net.elmau.zaz.talk?end</value>
|
||||||
|
</prop>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node oor:name="com.sun.star.sheet.SpreadsheetDocument">
|
||||||
|
<node oor:name="E_SHIFT_MOD1_MOD2" oor:op="fuse">
|
||||||
|
<prop oor:name="Command">
|
||||||
|
<value xml:lang="en-US">service:net.elmau.zaz.talk?end</value>
|
||||||
|
</prop>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</oor:component-data>
|
|
@ -0,0 +1,36 @@
|
||||||
|
import uno
|
||||||
|
import unohelper
|
||||||
|
from com.sun.star.task import XJobExecutor
|
||||||
|
|
||||||
|
import easymacro as app
|
||||||
|
import nerd_dictation as nd
|
||||||
|
|
||||||
|
|
||||||
|
ID_EXTENSION = 'net.elmau.zaz.talk'
|
||||||
|
SERVICE = ('com.sun.star.task.Job',)
|
||||||
|
|
||||||
|
|
||||||
|
class ZazTalk2Me(unohelper.Base, XJobExecutor):
|
||||||
|
|
||||||
|
def __init__(self, ctx):
|
||||||
|
self.ctx = ctx
|
||||||
|
|
||||||
|
@app.run_in_thread
|
||||||
|
def _start(self):
|
||||||
|
path_ext = app.paths.from_id(ID_EXTENSION)
|
||||||
|
path_model = app.paths.join(path_ext, 'model', app.LANG)
|
||||||
|
nd.main_begin(vosk_model_dir=path_model, config_override=None)
|
||||||
|
return
|
||||||
|
|
||||||
|
def trigger(self, args):
|
||||||
|
if args=='start':
|
||||||
|
self._start()
|
||||||
|
app.info('Start')
|
||||||
|
elif args=='end':
|
||||||
|
nd.main_end()
|
||||||
|
app.info('End')
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
g_ImplementationHelper = unohelper.ImplementationHelper()
|
||||||
|
g_ImplementationHelper.addImplementation(ZazTalk2Me, ID_EXTENSION, SERVICE)
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?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" xmlns:l="http://libreoffice.org/extensions/description/2011">
|
||||||
|
<identifier value="net.elmau.zaz.talk"/>
|
||||||
|
<version value="0.1.0"/>
|
||||||
|
<display-name>
|
||||||
|
<name lang="en">Zaz Talk2Me</name>
|
||||||
|
<name lang="es">Zaz Hablame</name>
|
||||||
|
</display-name>
|
||||||
|
<extension-description>
|
||||||
|
<src lang="en" xlink:href="description/desc_en.txt"/>
|
||||||
|
<src lang="es" xlink:href="description/desc_es.txt"/>
|
||||||
|
</extension-description>
|
||||||
|
<icon>
|
||||||
|
<default xlink:href="images/zaztalk2me.png"/>
|
||||||
|
</icon>
|
||||||
|
<publisher>
|
||||||
|
<name xlink:href="https://git.cuates.net/elmau/zaz-talk2me" lang="en">El Mau</name>
|
||||||
|
<name xlink:href="https://git.cuates.net/elmau/zaz-talk2me" lang="es">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"/>
|
||||||
|
</simple-license>
|
||||||
|
</registration>
|
||||||
|
</description>
|
|
@ -0,0 +1 @@
|
||||||
|
Dictation support for LibreOffice
|
|
@ -0,0 +1 @@
|
||||||
|
Soporte para dictado en LibreOffice
|
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
|
@ -0,0 +1,9 @@
|
||||||
|
US English model for mobile Vosk applications
|
||||||
|
|
||||||
|
Copyright 2020 Alpha Cephei Inc
|
||||||
|
|
||||||
|
Accuracy: 10.38 (tedlium test) 9.85 (librispeech test-clean)
|
||||||
|
Speed: 0.11xRT (desktop)
|
||||||
|
Latency: 0.15s (right context)
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,7 @@
|
||||||
|
--sample-frequency=16000
|
||||||
|
--use-energy=false
|
||||||
|
--num-mel-bins=40
|
||||||
|
--num-ceps=40
|
||||||
|
--low-freq=20
|
||||||
|
--high-freq=7600
|
||||||
|
--allow-downsample=true
|
|
@ -0,0 +1,10 @@
|
||||||
|
--min-active=200
|
||||||
|
--max-active=3000
|
||||||
|
--beam=10.0
|
||||||
|
--lattice-beam=2.0
|
||||||
|
--acoustic-scale=1.0
|
||||||
|
--frame-subsampling-factor=3
|
||||||
|
--endpoint.silence-phones=1:2:3:4:5:6:7:8:9:10
|
||||||
|
--endpoint.rule2.min-trailing-silence=0.5
|
||||||
|
--endpoint.rule3.min-trailing-silence=0.75
|
||||||
|
--endpoint.rule4.min-trailing-silence=1.0
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,17 @@
|
||||||
|
10015
|
||||||
|
10016
|
||||||
|
10017
|
||||||
|
10018
|
||||||
|
10019
|
||||||
|
10020
|
||||||
|
10021
|
||||||
|
10022
|
||||||
|
10023
|
||||||
|
10024
|
||||||
|
10025
|
||||||
|
10026
|
||||||
|
10027
|
||||||
|
10028
|
||||||
|
10029
|
||||||
|
10030
|
||||||
|
10031
|
|
@ -0,0 +1,166 @@
|
||||||
|
1 nonword
|
||||||
|
2 begin
|
||||||
|
3 end
|
||||||
|
4 internal
|
||||||
|
5 singleton
|
||||||
|
6 nonword
|
||||||
|
7 begin
|
||||||
|
8 end
|
||||||
|
9 internal
|
||||||
|
10 singleton
|
||||||
|
11 begin
|
||||||
|
12 end
|
||||||
|
13 internal
|
||||||
|
14 singleton
|
||||||
|
15 begin
|
||||||
|
16 end
|
||||||
|
17 internal
|
||||||
|
18 singleton
|
||||||
|
19 begin
|
||||||
|
20 end
|
||||||
|
21 internal
|
||||||
|
22 singleton
|
||||||
|
23 begin
|
||||||
|
24 end
|
||||||
|
25 internal
|
||||||
|
26 singleton
|
||||||
|
27 begin
|
||||||
|
28 end
|
||||||
|
29 internal
|
||||||
|
30 singleton
|
||||||
|
31 begin
|
||||||
|
32 end
|
||||||
|
33 internal
|
||||||
|
34 singleton
|
||||||
|
35 begin
|
||||||
|
36 end
|
||||||
|
37 internal
|
||||||
|
38 singleton
|
||||||
|
39 begin
|
||||||
|
40 end
|
||||||
|
41 internal
|
||||||
|
42 singleton
|
||||||
|
43 begin
|
||||||
|
44 end
|
||||||
|
45 internal
|
||||||
|
46 singleton
|
||||||
|
47 begin
|
||||||
|
48 end
|
||||||
|
49 internal
|
||||||
|
50 singleton
|
||||||
|
51 begin
|
||||||
|
52 end
|
||||||
|
53 internal
|
||||||
|
54 singleton
|
||||||
|
55 begin
|
||||||
|
56 end
|
||||||
|
57 internal
|
||||||
|
58 singleton
|
||||||
|
59 begin
|
||||||
|
60 end
|
||||||
|
61 internal
|
||||||
|
62 singleton
|
||||||
|
63 begin
|
||||||
|
64 end
|
||||||
|
65 internal
|
||||||
|
66 singleton
|
||||||
|
67 begin
|
||||||
|
68 end
|
||||||
|
69 internal
|
||||||
|
70 singleton
|
||||||
|
71 begin
|
||||||
|
72 end
|
||||||
|
73 internal
|
||||||
|
74 singleton
|
||||||
|
75 begin
|
||||||
|
76 end
|
||||||
|
77 internal
|
||||||
|
78 singleton
|
||||||
|
79 begin
|
||||||
|
80 end
|
||||||
|
81 internal
|
||||||
|
82 singleton
|
||||||
|
83 begin
|
||||||
|
84 end
|
||||||
|
85 internal
|
||||||
|
86 singleton
|
||||||
|
87 begin
|
||||||
|
88 end
|
||||||
|
89 internal
|
||||||
|
90 singleton
|
||||||
|
91 begin
|
||||||
|
92 end
|
||||||
|
93 internal
|
||||||
|
94 singleton
|
||||||
|
95 begin
|
||||||
|
96 end
|
||||||
|
97 internal
|
||||||
|
98 singleton
|
||||||
|
99 begin
|
||||||
|
100 end
|
||||||
|
101 internal
|
||||||
|
102 singleton
|
||||||
|
103 begin
|
||||||
|
104 end
|
||||||
|
105 internal
|
||||||
|
106 singleton
|
||||||
|
107 begin
|
||||||
|
108 end
|
||||||
|
109 internal
|
||||||
|
110 singleton
|
||||||
|
111 begin
|
||||||
|
112 end
|
||||||
|
113 internal
|
||||||
|
114 singleton
|
||||||
|
115 begin
|
||||||
|
116 end
|
||||||
|
117 internal
|
||||||
|
118 singleton
|
||||||
|
119 begin
|
||||||
|
120 end
|
||||||
|
121 internal
|
||||||
|
122 singleton
|
||||||
|
123 begin
|
||||||
|
124 end
|
||||||
|
125 internal
|
||||||
|
126 singleton
|
||||||
|
127 begin
|
||||||
|
128 end
|
||||||
|
129 internal
|
||||||
|
130 singleton
|
||||||
|
131 begin
|
||||||
|
132 end
|
||||||
|
133 internal
|
||||||
|
134 singleton
|
||||||
|
135 begin
|
||||||
|
136 end
|
||||||
|
137 internal
|
||||||
|
138 singleton
|
||||||
|
139 begin
|
||||||
|
140 end
|
||||||
|
141 internal
|
||||||
|
142 singleton
|
||||||
|
143 begin
|
||||||
|
144 end
|
||||||
|
145 internal
|
||||||
|
146 singleton
|
||||||
|
147 begin
|
||||||
|
148 end
|
||||||
|
149 internal
|
||||||
|
150 singleton
|
||||||
|
151 begin
|
||||||
|
152 end
|
||||||
|
153 internal
|
||||||
|
154 singleton
|
||||||
|
155 begin
|
||||||
|
156 end
|
||||||
|
157 internal
|
||||||
|
158 singleton
|
||||||
|
159 begin
|
||||||
|
160 end
|
||||||
|
161 internal
|
||||||
|
162 singleton
|
||||||
|
163 begin
|
||||||
|
164 end
|
||||||
|
165 internal
|
||||||
|
166 singleton
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
[
|
||||||
|
1.682383e+11 -1.1595e+10 -1.521733e+10 4.32034e+09 -2.257938e+10 -1.969666e+10 -2.559265e+10 -1.535687e+10 -1.276854e+10 -4.494483e+09 -1.209085e+10 -5.64008e+09 -1.134847e+10 -3.419512e+09 -1.079542e+10 -4.145463e+09 -6.637486e+09 -1.11318e+09 -3.479773e+09 -1.245932e+08 -1.386961e+09 6.560655e+07 -2.436518e+08 -4.032432e+07 4.620046e+08 -7.714964e+07 9.551484e+08 -4.119761e+08 8.208582e+08 -7.117156e+08 7.457703e+08 -4.3106e+08 1.202726e+09 2.904036e+08 1.231931e+09 3.629848e+08 6.366939e+08 -4.586172e+08 -5.267629e+08 -3.507819e+08 1.679838e+09
|
||||||
|
1.741141e+13 8.92488e+11 8.743834e+11 8.848896e+11 1.190313e+12 1.160279e+12 1.300066e+12 1.005678e+12 9.39335e+11 8.089614e+11 7.927041e+11 6.882427e+11 6.444235e+11 5.151451e+11 4.825723e+11 3.210106e+11 2.720254e+11 1.772539e+11 1.248102e+11 6.691599e+10 3.599804e+10 1.207574e+10 1.679301e+09 4.594778e+08 5.821614e+09 1.451758e+10 2.55803e+10 3.43277e+10 4.245286e+10 4.784859e+10 4.988591e+10 4.925451e+10 5.074584e+10 4.9557e+10 4.407876e+10 3.421443e+10 3.138606e+10 2.539716e+10 1.948134e+10 1.381167e+10 0 ]
|
|
@ -0,0 +1 @@
|
||||||
|
# configuration file for apply-cmvn-online, used in the script ../local/run_online_decoding.sh
|
|
@ -0,0 +1,2 @@
|
||||||
|
--left-context=3
|
||||||
|
--right-context=3
|
|
@ -0,0 +1,10 @@
|
||||||
|
Copyright 2022-2050 Alpha Cephei Inc
|
||||||
|
|
||||||
|
Small Spanish model for Vosk
|
||||||
|
|
||||||
|
WER
|
||||||
|
|
||||||
|
%WER 18.51 [ 28200 / 152364, 3732 ins, 5395 del, 19073 sub ] exp/chain_a/tdnn/decode_test_cv_look_fast/wer_10_0.0
|
||||||
|
LOG (nnet3-latgen-faster-lookahead[5.5.916~6-7f57e]:main():nnet3-latgen-faster-lookahead.cc:215) Time taken 797.251s: real-time factor assuming 100 frames/sec is 0.0845848
|
||||||
|
%WER 20.39 [ 2939 / 14416, 495 ins, 745 del, 1699 sub ] exp/chain_a/tdnn/decode_test_mtedx_look_fast/wer_8_0.0
|
||||||
|
LOG (nnet3-latgen-faster-lookahead[5.5.916~6-7f57e]:main():nnet3-latgen-faster-lookahead.cc:215) Time taken 34.4051s: real-time factor assuming 100 frames/sec is 0.0877592
|
Binary file not shown.
|
@ -0,0 +1,7 @@
|
||||||
|
--use-energy=false
|
||||||
|
--num-mel-bins=40
|
||||||
|
--num-ceps=40
|
||||||
|
--low-freq=20
|
||||||
|
--high-freq=7600
|
||||||
|
--allow-upsample=true
|
||||||
|
--allow-downsample=true
|
|
@ -0,0 +1,10 @@
|
||||||
|
--min-active=200
|
||||||
|
--max-active=7000
|
||||||
|
--beam=13.0
|
||||||
|
--lattice-beam=4.0
|
||||||
|
--acoustic-scale=1.0
|
||||||
|
--frame-subsampling-factor=3
|
||||||
|
--endpoint.silence-phones=1:2:3:4:5:6:7:8:9:10
|
||||||
|
--endpoint.rule2.min-trailing-silence=0.5
|
||||||
|
--endpoint.rule3.min-trailing-silence=1.0
|
||||||
|
--endpoint.rule4.min-trailing-silence=2.0
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,10 @@
|
||||||
|
7837
|
||||||
|
7838
|
||||||
|
7839
|
||||||
|
7840
|
||||||
|
7841
|
||||||
|
7842
|
||||||
|
7843
|
||||||
|
7844
|
||||||
|
7845
|
||||||
|
7846
|
|
@ -0,0 +1,110 @@
|
||||||
|
1 nonword
|
||||||
|
2 begin
|
||||||
|
3 end
|
||||||
|
4 internal
|
||||||
|
5 singleton
|
||||||
|
6 nonword
|
||||||
|
7 begin
|
||||||
|
8 end
|
||||||
|
9 internal
|
||||||
|
10 singleton
|
||||||
|
11 begin
|
||||||
|
12 end
|
||||||
|
13 internal
|
||||||
|
14 singleton
|
||||||
|
15 begin
|
||||||
|
16 end
|
||||||
|
17 internal
|
||||||
|
18 singleton
|
||||||
|
19 begin
|
||||||
|
20 end
|
||||||
|
21 internal
|
||||||
|
22 singleton
|
||||||
|
23 begin
|
||||||
|
24 end
|
||||||
|
25 internal
|
||||||
|
26 singleton
|
||||||
|
27 begin
|
||||||
|
28 end
|
||||||
|
29 internal
|
||||||
|
30 singleton
|
||||||
|
31 begin
|
||||||
|
32 end
|
||||||
|
33 internal
|
||||||
|
34 singleton
|
||||||
|
35 begin
|
||||||
|
36 end
|
||||||
|
37 internal
|
||||||
|
38 singleton
|
||||||
|
39 begin
|
||||||
|
40 end
|
||||||
|
41 internal
|
||||||
|
42 singleton
|
||||||
|
43 begin
|
||||||
|
44 end
|
||||||
|
45 internal
|
||||||
|
46 singleton
|
||||||
|
47 begin
|
||||||
|
48 end
|
||||||
|
49 internal
|
||||||
|
50 singleton
|
||||||
|
51 begin
|
||||||
|
52 end
|
||||||
|
53 internal
|
||||||
|
54 singleton
|
||||||
|
55 begin
|
||||||
|
56 end
|
||||||
|
57 internal
|
||||||
|
58 singleton
|
||||||
|
59 begin
|
||||||
|
60 end
|
||||||
|
61 internal
|
||||||
|
62 singleton
|
||||||
|
63 begin
|
||||||
|
64 end
|
||||||
|
65 internal
|
||||||
|
66 singleton
|
||||||
|
67 begin
|
||||||
|
68 end
|
||||||
|
69 internal
|
||||||
|
70 singleton
|
||||||
|
71 begin
|
||||||
|
72 end
|
||||||
|
73 internal
|
||||||
|
74 singleton
|
||||||
|
75 begin
|
||||||
|
76 end
|
||||||
|
77 internal
|
||||||
|
78 singleton
|
||||||
|
79 begin
|
||||||
|
80 end
|
||||||
|
81 internal
|
||||||
|
82 singleton
|
||||||
|
83 begin
|
||||||
|
84 end
|
||||||
|
85 internal
|
||||||
|
86 singleton
|
||||||
|
87 begin
|
||||||
|
88 end
|
||||||
|
89 internal
|
||||||
|
90 singleton
|
||||||
|
91 begin
|
||||||
|
92 end
|
||||||
|
93 internal
|
||||||
|
94 singleton
|
||||||
|
95 begin
|
||||||
|
96 end
|
||||||
|
97 internal
|
||||||
|
98 singleton
|
||||||
|
99 begin
|
||||||
|
100 end
|
||||||
|
101 internal
|
||||||
|
102 singleton
|
||||||
|
103 begin
|
||||||
|
104 end
|
||||||
|
105 internal
|
||||||
|
106 singleton
|
||||||
|
107 begin
|
||||||
|
108 end
|
||||||
|
109 internal
|
||||||
|
110 singleton
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
[
|
||||||
|
5.206991e+10 -2.007229e+09 -4.328604e+09 5.49911e+07 -7.643476e+09 -9.501782e+09 -7.916147e+09 -5.964982e+09 -3.417672e+09 -2.90296e+09 -1.729187e+09 -2.994376e+09 -3.811278e+09 -9.768101e+08 -3.268531e+09 -2.405868e+09 -1.514416e+09 -8.461341e+08 -1.018629e+09 -2.062752e+08 -2.70429e+08 -1.184466e+08 -4.470086e+07 5591588 1.14964e+08 1.34052e+08 2.581257e+08 6.844078e+07 1.854583e+08 7597449 1.244031e+08 1.31236e+08 2.400246e+08 2.442383e+08 3.396472e+08 2.301846e+08 1.53252e+08 -9.70687e+07 -1.643316e+08 -1.051184e+08 5.0121e+08
|
||||||
|
5.548082e+12 1.901654e+11 2.493659e+11 2.369916e+11 3.321238e+11 4.469359e+11 3.488889e+11 2.948305e+11 2.37128e+11 2.259571e+11 1.850742e+11 2.219626e+11 1.79272e+11 1.295488e+11 1.300027e+11 9.150627e+10 6.573611e+10 4.872693e+10 3.349526e+10 1.837348e+10 9.650796e+09 3.471324e+09 4.574948e+08 1.280425e+08 1.622987e+09 4.072197e+09 6.965214e+09 9.330767e+09 1.133664e+10 1.261221e+10 1.321959e+10 1.292789e+10 1.348439e+10 1.409859e+10 1.181245e+10 9.12475e+09 8.949862e+09 7.389243e+09 5.498101e+09 3.763717e+09 0 ]
|
|
@ -0,0 +1 @@
|
||||||
|
# configuration file for apply-cmvn-online, used in the script ../local/run_online_decoding.sh
|
|
@ -0,0 +1,2 @@
|
||||||
|
--left-context=3
|
||||||
|
--right-context=3
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
Portuguese model for android
|
|
@ -0,0 +1,9 @@
|
||||||
|
11381
|
||||||
|
11382
|
||||||
|
11383
|
||||||
|
11384
|
||||||
|
11385
|
||||||
|
11386
|
||||||
|
11387
|
||||||
|
11388
|
||||||
|
11389
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
[
|
||||||
|
5.621864e+09 -3.61508e+08 8.637199e+07 3.324517e+08 -3.323625e+08 -3.969682e+08 -5.677247e+08 -3.363187e+08 -2.560426e+08 -5.828718e+07 -5.735994e+07 -1.727248e+08 -1.921315e+08 -243469.1 -1.114188e+08 -1.499579e+08 -2.986899e+07 -2.723944e+07 -3.31755e+07 758787.7 7.084189e+07
|
||||||
|
4.552163e+11 1.696032e+10 1.358537e+10 1.90937e+10 1.775472e+10 1.721642e+10 1.958017e+10 1.442598e+10 1.461493e+10 1.236114e+10 9.68765e+09 9.376157e+09 7.71376e+09 5.798623e+09 4.252169e+09 3.14616e+09 1.832301e+09 1.183567e+09 7.921606e+08 4.095449e+08 0 ]
|
|
@ -0,0 +1 @@
|
||||||
|
# configuration file for apply-cmvn-online, used in the script ../local/run_online_decoding.sh
|
|
@ -0,0 +1,2 @@
|
||||||
|
--left-context=3
|
||||||
|
--right-context=3
|
|
@ -0,0 +1,8 @@
|
||||||
|
--sample-frequency=16000
|
||||||
|
--use-energy=false
|
||||||
|
--num-mel-bins=20
|
||||||
|
--num-ceps=20
|
||||||
|
--low-freq=20
|
||||||
|
--high-freq=7600
|
||||||
|
--allow-upsample=true
|
||||||
|
--allow-downsample=true
|
|
@ -0,0 +1,240 @@
|
||||||
|
<eps> 0
|
||||||
|
SIL 1
|
||||||
|
SIL_B 2
|
||||||
|
SIL_E 3
|
||||||
|
SIL_I 4
|
||||||
|
SIL_S 5
|
||||||
|
GBG 6
|
||||||
|
GBG_B 7
|
||||||
|
GBG_E 8
|
||||||
|
GBG_I 9
|
||||||
|
GBG_S 10
|
||||||
|
E_B 11
|
||||||
|
E_E 12
|
||||||
|
E_I 13
|
||||||
|
E_S 14
|
||||||
|
J_B 15
|
||||||
|
J_E 16
|
||||||
|
J_I 17
|
||||||
|
J_S 18
|
||||||
|
L_B 19
|
||||||
|
L_E 20
|
||||||
|
L_I 21
|
||||||
|
L_S 22
|
||||||
|
O_B 23
|
||||||
|
O_E 24
|
||||||
|
O_I 25
|
||||||
|
O_S 26
|
||||||
|
R_B 27
|
||||||
|
R_E 28
|
||||||
|
R_I 29
|
||||||
|
R_S 30
|
||||||
|
S_B 31
|
||||||
|
S_E 32
|
||||||
|
S_I 33
|
||||||
|
S_S 34
|
||||||
|
X_B 35
|
||||||
|
X_E 36
|
||||||
|
X_I 37
|
||||||
|
X_S 38
|
||||||
|
Z_B 39
|
||||||
|
Z_E 40
|
||||||
|
Z_I 41
|
||||||
|
Z_S 42
|
||||||
|
a_B 43
|
||||||
|
a_E 44
|
||||||
|
a_I 45
|
||||||
|
a_S 46
|
||||||
|
aa_B 47
|
||||||
|
aa_E 48
|
||||||
|
aa_I 49
|
||||||
|
aa_S 50
|
||||||
|
a~_B 51
|
||||||
|
a~_E 52
|
||||||
|
a~_I 53
|
||||||
|
a~_S 54
|
||||||
|
b_B 55
|
||||||
|
b_E 56
|
||||||
|
b_I 57
|
||||||
|
b_S 58
|
||||||
|
d_B 59
|
||||||
|
d_E 60
|
||||||
|
d_I 61
|
||||||
|
d_S 62
|
||||||
|
dZ_B 63
|
||||||
|
dZ_E 64
|
||||||
|
dZ_I 65
|
||||||
|
dZ_S 66
|
||||||
|
dz_B 67
|
||||||
|
dz_E 68
|
||||||
|
dz_I 69
|
||||||
|
dz_S 70
|
||||||
|
e_B 71
|
||||||
|
e_E 72
|
||||||
|
e_I 73
|
||||||
|
e_S 74
|
||||||
|
ee_B 75
|
||||||
|
ee_E 76
|
||||||
|
ee_I 77
|
||||||
|
ee_S 78
|
||||||
|
em_B 79
|
||||||
|
em_E 80
|
||||||
|
em_I 81
|
||||||
|
em_S 82
|
||||||
|
e~_B 83
|
||||||
|
e~_E 84
|
||||||
|
e~_I 85
|
||||||
|
e~_S 86
|
||||||
|
f_B 87
|
||||||
|
f_E 88
|
||||||
|
f_I 89
|
||||||
|
f_S 90
|
||||||
|
g_B 91
|
||||||
|
g_E 92
|
||||||
|
g_I 93
|
||||||
|
g_S 94
|
||||||
|
i_B 95
|
||||||
|
i_E 96
|
||||||
|
i_I 97
|
||||||
|
i_S 98
|
||||||
|
ii_B 99
|
||||||
|
ii_E 100
|
||||||
|
ii_I 101
|
||||||
|
ii_S 102
|
||||||
|
i~_B 103
|
||||||
|
i~_E 104
|
||||||
|
i~_I 105
|
||||||
|
i~_S 106
|
||||||
|
j_B 107
|
||||||
|
j_E 108
|
||||||
|
j_I 109
|
||||||
|
j_S 110
|
||||||
|
jj_B 111
|
||||||
|
jj_E 112
|
||||||
|
jj_I 113
|
||||||
|
jj_S 114
|
||||||
|
jm_B 115
|
||||||
|
jm_E 116
|
||||||
|
jm_I 117
|
||||||
|
jm_S 118
|
||||||
|
j~_B 119
|
||||||
|
j~_E 120
|
||||||
|
j~_I 121
|
||||||
|
j~_S 122
|
||||||
|
k_B 123
|
||||||
|
k_E 124
|
||||||
|
k_I 125
|
||||||
|
k_S 126
|
||||||
|
l_B 127
|
||||||
|
l_E 128
|
||||||
|
l_I 129
|
||||||
|
l_S 130
|
||||||
|
lm_B 131
|
||||||
|
lm_E 132
|
||||||
|
lm_I 133
|
||||||
|
lm_S 134
|
||||||
|
m_B 135
|
||||||
|
m_E 136
|
||||||
|
m_I 137
|
||||||
|
m_S 138
|
||||||
|
n_B 139
|
||||||
|
n_E 140
|
||||||
|
n_I 141
|
||||||
|
n_S 142
|
||||||
|
o_B 143
|
||||||
|
o_E 144
|
||||||
|
o_I 145
|
||||||
|
o_S 146
|
||||||
|
om_B 147
|
||||||
|
om_E 148
|
||||||
|
om_I 149
|
||||||
|
om_S 150
|
||||||
|
oo_B 151
|
||||||
|
oo_E 152
|
||||||
|
oo_I 153
|
||||||
|
oo_S 154
|
||||||
|
o~_B 155
|
||||||
|
o~_E 156
|
||||||
|
o~_I 157
|
||||||
|
o~_S 158
|
||||||
|
p_B 159
|
||||||
|
p_E 160
|
||||||
|
p_I 161
|
||||||
|
p_S 162
|
||||||
|
r_B 163
|
||||||
|
r_E 164
|
||||||
|
r_I 165
|
||||||
|
r_S 166
|
||||||
|
rm_B 167
|
||||||
|
rm_E 168
|
||||||
|
rm_I 169
|
||||||
|
rm_S 170
|
||||||
|
s_B 171
|
||||||
|
s_E 172
|
||||||
|
s_I 173
|
||||||
|
s_S 174
|
||||||
|
sm_B 175
|
||||||
|
sm_E 176
|
||||||
|
sm_I 177
|
||||||
|
sm_S 178
|
||||||
|
t_B 179
|
||||||
|
t_E 180
|
||||||
|
t_I 181
|
||||||
|
t_S 182
|
||||||
|
tS_B 183
|
||||||
|
tS_E 184
|
||||||
|
tS_I 185
|
||||||
|
tS_S 186
|
||||||
|
ts_B 187
|
||||||
|
ts_E 188
|
||||||
|
ts_I 189
|
||||||
|
ts_S 190
|
||||||
|
u_B 191
|
||||||
|
u_E 192
|
||||||
|
u_I 193
|
||||||
|
u_S 194
|
||||||
|
uu_B 195
|
||||||
|
uu_E 196
|
||||||
|
uu_I 197
|
||||||
|
uu_S 198
|
||||||
|
u~_B 199
|
||||||
|
u~_E 200
|
||||||
|
u~_I 201
|
||||||
|
u~_S 202
|
||||||
|
v_B 203
|
||||||
|
v_E 204
|
||||||
|
v_I 205
|
||||||
|
v_S 206
|
||||||
|
w_B 207
|
||||||
|
w_E 208
|
||||||
|
w_I 209
|
||||||
|
w_S 210
|
||||||
|
ww_B 211
|
||||||
|
ww_E 212
|
||||||
|
ww_I 213
|
||||||
|
ww_S 214
|
||||||
|
w~_B 215
|
||||||
|
w~_E 216
|
||||||
|
w~_I 217
|
||||||
|
w~_S 218
|
||||||
|
xm_B 219
|
||||||
|
xm_E 220
|
||||||
|
xm_I 221
|
||||||
|
xm_S 222
|
||||||
|
z_B 223
|
||||||
|
z_E 224
|
||||||
|
z_I 225
|
||||||
|
z_S 226
|
||||||
|
zm_B 227
|
||||||
|
zm_E 228
|
||||||
|
zm_I 229
|
||||||
|
zm_S 230
|
||||||
|
#0 231
|
||||||
|
#1 232
|
||||||
|
#2 233
|
||||||
|
#3 234
|
||||||
|
#4 235
|
||||||
|
#5 236
|
||||||
|
#6 237
|
||||||
|
#7 238
|
||||||
|
#8 239
|
|
@ -0,0 +1,230 @@
|
||||||
|
1 nonword
|
||||||
|
2 begin
|
||||||
|
3 end
|
||||||
|
4 internal
|
||||||
|
5 singleton
|
||||||
|
6 nonword
|
||||||
|
7 begin
|
||||||
|
8 end
|
||||||
|
9 internal
|
||||||
|
10 singleton
|
||||||
|
11 begin
|
||||||
|
12 end
|
||||||
|
13 internal
|
||||||
|
14 singleton
|
||||||
|
15 begin
|
||||||
|
16 end
|
||||||
|
17 internal
|
||||||
|
18 singleton
|
||||||
|
19 begin
|
||||||
|
20 end
|
||||||
|
21 internal
|
||||||
|
22 singleton
|
||||||
|
23 begin
|
||||||
|
24 end
|
||||||
|
25 internal
|
||||||
|
26 singleton
|
||||||
|
27 begin
|
||||||
|
28 end
|
||||||
|
29 internal
|
||||||
|
30 singleton
|
||||||
|
31 begin
|
||||||
|
32 end
|
||||||
|
33 internal
|
||||||
|
34 singleton
|
||||||
|
35 begin
|
||||||
|
36 end
|
||||||
|
37 internal
|
||||||
|
38 singleton
|
||||||
|
39 begin
|
||||||
|
40 end
|
||||||
|
41 internal
|
||||||
|
42 singleton
|
||||||
|
43 begin
|
||||||
|
44 end
|
||||||
|
45 internal
|
||||||
|
46 singleton
|
||||||
|
47 begin
|
||||||
|
48 end
|
||||||
|
49 internal
|
||||||
|
50 singleton
|
||||||
|
51 begin
|
||||||
|
52 end
|
||||||
|
53 internal
|
||||||
|
54 singleton
|
||||||
|
55 begin
|
||||||
|
56 end
|
||||||
|
57 internal
|
||||||
|
58 singleton
|
||||||
|
59 begin
|
||||||
|
60 end
|
||||||
|
61 internal
|
||||||
|
62 singleton
|
||||||
|
63 begin
|
||||||
|
64 end
|
||||||
|
65 internal
|
||||||
|
66 singleton
|
||||||
|
67 begin
|
||||||
|
68 end
|
||||||
|
69 internal
|
||||||
|
70 singleton
|
||||||
|
71 begin
|
||||||
|
72 end
|
||||||
|
73 internal
|
||||||
|
74 singleton
|
||||||
|
75 begin
|
||||||
|
76 end
|
||||||
|
77 internal
|
||||||
|
78 singleton
|
||||||
|
79 begin
|
||||||
|
80 end
|
||||||
|
81 internal
|
||||||
|
82 singleton
|
||||||
|
83 begin
|
||||||
|
84 end
|
||||||
|
85 internal
|
||||||
|
86 singleton
|
||||||
|
87 begin
|
||||||
|
88 end
|
||||||
|
89 internal
|
||||||
|
90 singleton
|
||||||
|
91 begin
|
||||||
|
92 end
|
||||||
|
93 internal
|
||||||
|
94 singleton
|
||||||
|
95 begin
|
||||||
|
96 end
|
||||||
|
97 internal
|
||||||
|
98 singleton
|
||||||
|
99 begin
|
||||||
|
100 end
|
||||||
|
101 internal
|
||||||
|
102 singleton
|
||||||
|
103 begin
|
||||||
|
104 end
|
||||||
|
105 internal
|
||||||
|
106 singleton
|
||||||
|
107 begin
|
||||||
|
108 end
|
||||||
|
109 internal
|
||||||
|
110 singleton
|
||||||
|
111 begin
|
||||||
|
112 end
|
||||||
|
113 internal
|
||||||
|
114 singleton
|
||||||
|
115 begin
|
||||||
|
116 end
|
||||||
|
117 internal
|
||||||
|
118 singleton
|
||||||
|
119 begin
|
||||||
|
120 end
|
||||||
|
121 internal
|
||||||
|
122 singleton
|
||||||
|
123 begin
|
||||||
|
124 end
|
||||||
|
125 internal
|
||||||
|
126 singleton
|
||||||
|
127 begin
|
||||||
|
128 end
|
||||||
|
129 internal
|
||||||
|
130 singleton
|
||||||
|
131 begin
|
||||||
|
132 end
|
||||||
|
133 internal
|
||||||
|
134 singleton
|
||||||
|
135 begin
|
||||||
|
136 end
|
||||||
|
137 internal
|
||||||
|
138 singleton
|
||||||
|
139 begin
|
||||||
|
140 end
|
||||||
|
141 internal
|
||||||
|
142 singleton
|
||||||
|
143 begin
|
||||||
|
144 end
|
||||||
|
145 internal
|
||||||
|
146 singleton
|
||||||
|
147 begin
|
||||||
|
148 end
|
||||||
|
149 internal
|
||||||
|
150 singleton
|
||||||
|
151 begin
|
||||||
|
152 end
|
||||||
|
153 internal
|
||||||
|
154 singleton
|
||||||
|
155 begin
|
||||||
|
156 end
|
||||||
|
157 internal
|
||||||
|
158 singleton
|
||||||
|
159 begin
|
||||||
|
160 end
|
||||||
|
161 internal
|
||||||
|
162 singleton
|
||||||
|
163 begin
|
||||||
|
164 end
|
||||||
|
165 internal
|
||||||
|
166 singleton
|
||||||
|
167 begin
|
||||||
|
168 end
|
||||||
|
169 internal
|
||||||
|
170 singleton
|
||||||
|
171 begin
|
||||||
|
172 end
|
||||||
|
173 internal
|
||||||
|
174 singleton
|
||||||
|
175 begin
|
||||||
|
176 end
|
||||||
|
177 internal
|
||||||
|
178 singleton
|
||||||
|
179 begin
|
||||||
|
180 end
|
||||||
|
181 internal
|
||||||
|
182 singleton
|
||||||
|
183 begin
|
||||||
|
184 end
|
||||||
|
185 internal
|
||||||
|
186 singleton
|
||||||
|
187 begin
|
||||||
|
188 end
|
||||||
|
189 internal
|
||||||
|
190 singleton
|
||||||
|
191 begin
|
||||||
|
192 end
|
||||||
|
193 internal
|
||||||
|
194 singleton
|
||||||
|
195 begin
|
||||||
|
196 end
|
||||||
|
197 internal
|
||||||
|
198 singleton
|
||||||
|
199 begin
|
||||||
|
200 end
|
||||||
|
201 internal
|
||||||
|
202 singleton
|
||||||
|
203 begin
|
||||||
|
204 end
|
||||||
|
205 internal
|
||||||
|
206 singleton
|
||||||
|
207 begin
|
||||||
|
208 end
|
||||||
|
209 internal
|
||||||
|
210 singleton
|
||||||
|
211 begin
|
||||||
|
212 end
|
||||||
|
213 internal
|
||||||
|
214 singleton
|
||||||
|
215 begin
|
||||||
|
216 end
|
||||||
|
217 internal
|
||||||
|
218 singleton
|
||||||
|
219 begin
|
||||||
|
220 end
|
||||||
|
221 internal
|
||||||
|
222 singleton
|
||||||
|
223 begin
|
||||||
|
224 end
|
||||||
|
225 internal
|
||||||
|
226 singleton
|
||||||
|
227 begin
|
||||||
|
228 end
|
||||||
|
229 internal
|
||||||
|
230 singleton
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,14 @@
|
||||||
|
This file is part of ZazTalk2Me.
|
||||||
|
|
||||||
|
ZazTalk2Me 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.
|
||||||
|
|
||||||
|
ZazTalk2Me 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 ZazTalk2Me. If not, see <https://www.gnu.org/licenses/>.
|
|
@ -0,0 +1,14 @@
|
||||||
|
This file is part of ZazTalk2Me.
|
||||||
|
|
||||||
|
ZazTalk2Me 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.
|
||||||
|
|
||||||
|
ZazTalk2Me 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 ZazTalk2Me. If not, see <https://www.gnu.org/licenses/>.
|
|
@ -0,0 +1,837 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# == Rapid Develop Macros in LibreOffice ==
|
||||||
|
|
||||||
|
# ~ This file is part of ZAZ.
|
||||||
|
|
||||||
|
# ~ https://git.elmau.net/elmau/zaz
|
||||||
|
|
||||||
|
# ~ ZAZ 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.
|
||||||
|
|
||||||
|
# ~ ZAZ 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 ZAZ. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import py_compile
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import zipfile
|
||||||
|
from datetime import datetime
|
||||||
|
from pathlib import Path
|
||||||
|
from shutil import copyfile
|
||||||
|
from subprocess import call
|
||||||
|
from xml.etree import ElementTree as ET
|
||||||
|
from xml.dom.minidom import parseString
|
||||||
|
|
||||||
|
|
||||||
|
from conf import (
|
||||||
|
DATA,
|
||||||
|
DIRS,
|
||||||
|
DOMAIN,
|
||||||
|
EXTENSION,
|
||||||
|
FILES,
|
||||||
|
INFO,
|
||||||
|
PATHS,
|
||||||
|
TYPE_EXTENSION,
|
||||||
|
USE_LOCALES,
|
||||||
|
log)
|
||||||
|
|
||||||
|
|
||||||
|
EASYMACRO = 'easymacro.py'
|
||||||
|
|
||||||
|
|
||||||
|
class LiboXML(object):
|
||||||
|
CONTEXT = {
|
||||||
|
'calc': 'com.sun.star.sheet.SpreadsheetDocument',
|
||||||
|
'writer': 'com.sun.star.text.TextDocument',
|
||||||
|
'impress': 'com.sun.star.presentation.PresentationDocument',
|
||||||
|
'draw': 'com.sun.star.drawing.DrawingDocument',
|
||||||
|
'base': 'com.sun.star.sdb.OfficeDatabaseDocument',
|
||||||
|
'math': 'com.sun.star.formula.FormulaProperties',
|
||||||
|
'basic': 'com.sun.star.script.BasicIDE',
|
||||||
|
}
|
||||||
|
TYPES = {
|
||||||
|
'py': 'application/vnd.sun.star.uno-component;type=Python',
|
||||||
|
'pyc': 'application/binary',
|
||||||
|
'zip': 'application/binary',
|
||||||
|
'xcu': 'application/vnd.sun.star.configuration-data',
|
||||||
|
'rdb': 'application/vnd.sun.star.uno-typelibrary;type=RDB',
|
||||||
|
'xcs': 'application/vnd.sun.star.configuration-schema',
|
||||||
|
'help': 'application/vnd.sun.star.help',
|
||||||
|
'component': 'application/vnd.sun.star.uno-components',
|
||||||
|
}
|
||||||
|
NS_MANIFEST = {
|
||||||
|
'manifest_version': '1.2',
|
||||||
|
'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': xmlns,
|
||||||
|
'xmlns:xlink': xmlns_xlink,
|
||||||
|
'xmlns:d': xmlns,
|
||||||
|
'xmlns:l': xmlns_l,
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ADDONS = {
|
||||||
|
'xmlns:xs': 'http://www.w3.org/2001/XMLSchema',
|
||||||
|
'xmlns:oor': 'http://openoffice.org/2001/registry',
|
||||||
|
}
|
||||||
|
|
||||||
|
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',
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._manifest = None
|
||||||
|
self._paths = []
|
||||||
|
self._path_images = ''
|
||||||
|
self._toolbars = []
|
||||||
|
|
||||||
|
def _save_path(self, attr):
|
||||||
|
self._paths.append(attr['{{{}}}full-path'.format(self.NS_MANIFEST['manifest'])])
|
||||||
|
return
|
||||||
|
|
||||||
|
def _clean(self, name, nodes):
|
||||||
|
has_words = re.compile('\\w')
|
||||||
|
|
||||||
|
if not re.search(has_words, str(nodes.tail)):
|
||||||
|
nodes.tail = ''
|
||||||
|
if not re.search(has_words, str(nodes.text)):
|
||||||
|
nodes.text = ''
|
||||||
|
|
||||||
|
for node in nodes:
|
||||||
|
if name == 'manifest':
|
||||||
|
self._save_path(node.attrib)
|
||||||
|
if not re.search(has_words, str(node.tail)):
|
||||||
|
node.tail = ''
|
||||||
|
if not re.search(has_words, str(node.text)):
|
||||||
|
node.text = ''
|
||||||
|
return
|
||||||
|
|
||||||
|
def new_manifest(self, data):
|
||||||
|
attr = {
|
||||||
|
'manifest:version': self.NS_MANIFEST['manifest_version'],
|
||||||
|
'xmlns:manifest': self.NS_MANIFEST['manifest'],
|
||||||
|
'xmlns:loext': self.NS_MANIFEST['xmlns:loext'],
|
||||||
|
}
|
||||||
|
self._manifest = ET.Element('manifest:manifest', attr)
|
||||||
|
return self.add_data_manifest(data)
|
||||||
|
|
||||||
|
def parse_manifest(self, data):
|
||||||
|
ET.register_namespace('manifest', self.NS_MANIFEST['manifest'])
|
||||||
|
self._manifest = ET.fromstring(data)
|
||||||
|
attr = {'xmlns:loext': self.NS_MANIFEST['xmlns:loext']}
|
||||||
|
self._manifest.attrib.update(**attr)
|
||||||
|
self._clean('manifest', self._manifest)
|
||||||
|
return
|
||||||
|
|
||||||
|
def add_data_manifest(self, data):
|
||||||
|
node_name = 'manifest:file-entry'
|
||||||
|
attr = {
|
||||||
|
'manifest:full-path': '',
|
||||||
|
'manifest:media-type': '',
|
||||||
|
}
|
||||||
|
for path in data:
|
||||||
|
if path in self._paths:
|
||||||
|
continue
|
||||||
|
ext = path.split('.')[-1]
|
||||||
|
attr['manifest:full-path'] = path
|
||||||
|
attr['manifest:media-type'] = self.TYPES.get(ext, '')
|
||||||
|
ET.SubElement(self._manifest, node_name, attr)
|
||||||
|
return self._get_xml(self._manifest)
|
||||||
|
|
||||||
|
def new_description(self, data):
|
||||||
|
doc = ET.Element('description', self.NS_DESCRIPTION)
|
||||||
|
|
||||||
|
key = 'identifier'
|
||||||
|
ET.SubElement(doc, key, data[key])
|
||||||
|
|
||||||
|
key = 'version'
|
||||||
|
ET.SubElement(doc, key, data[key])
|
||||||
|
|
||||||
|
key = 'minimal'
|
||||||
|
if data[key]:
|
||||||
|
node = ET.SubElement(doc, 'dependencies')
|
||||||
|
attr = {'value': data[key], 'l:name': f'LibreOffice {data[key]}'}
|
||||||
|
ET.SubElement(node, 'LibreOffice-minimal-version', attr)
|
||||||
|
|
||||||
|
key = 'display-name'
|
||||||
|
node = ET.SubElement(doc, key)
|
||||||
|
for k, v in data[key].items():
|
||||||
|
sn = ET.SubElement(node, 'name', {'lang': k})
|
||||||
|
sn.text = v
|
||||||
|
|
||||||
|
node = ET.SubElement(doc, 'extension-description')
|
||||||
|
for k in data[key].keys():
|
||||||
|
attr = {
|
||||||
|
'lang': k,
|
||||||
|
'xlink:href': f'description/desc_{k}.txt',
|
||||||
|
}
|
||||||
|
ET.SubElement(node, 'src', attr)
|
||||||
|
|
||||||
|
key = 'icon'
|
||||||
|
node = ET.SubElement(doc, key)
|
||||||
|
attr = {'xlink:href': f"images/{data[key]}"}
|
||||||
|
ET.SubElement(node, 'default', attr)
|
||||||
|
|
||||||
|
key = 'publisher'
|
||||||
|
node = ET.SubElement(doc, key)
|
||||||
|
for k, v in data[key].items():
|
||||||
|
attr = {
|
||||||
|
'xlink:href': v['link'],
|
||||||
|
'lang': k,
|
||||||
|
}
|
||||||
|
sn = ET.SubElement(node, 'name', attr)
|
||||||
|
sn.text = v['text']
|
||||||
|
|
||||||
|
key = 'display-name'
|
||||||
|
node = ET.SubElement(doc, 'registration')
|
||||||
|
attr = {
|
||||||
|
'accept-by': 'user',
|
||||||
|
'suppress-on-update': 'true',
|
||||||
|
}
|
||||||
|
node = ET.SubElement(node, 'simple-license', attr)
|
||||||
|
for k in data[key].keys():
|
||||||
|
attr = {
|
||||||
|
'xlink:href': f"{DIRS['registration']}/license_{k}.txt",
|
||||||
|
'lang': k
|
||||||
|
}
|
||||||
|
ET.SubElement(node, 'license-text', attr)
|
||||||
|
|
||||||
|
if data['update']:
|
||||||
|
node = ET.SubElement(doc, 'update-information')
|
||||||
|
ET.SubElement(node, 'src', {'xlink:href': data['update']})
|
||||||
|
|
||||||
|
return self._get_xml(doc)
|
||||||
|
|
||||||
|
def _get_context(self, args):
|
||||||
|
if not args:
|
||||||
|
return ''
|
||||||
|
context = ','.join([self.CONTEXT[v] for v in args.split(',')])
|
||||||
|
return context
|
||||||
|
|
||||||
|
def _add_node_value(self, node, name, value='_self'):
|
||||||
|
attr = {'oor:name': name, 'oor:type': 'xs:string'}
|
||||||
|
sn = ET.SubElement(node, 'prop', attr)
|
||||||
|
sn = ET.SubElement(sn, 'value')
|
||||||
|
sn.text = value
|
||||||
|
return
|
||||||
|
|
||||||
|
def _add_menu(self, id_extension, node, index, menu, in_menu_bar=True):
|
||||||
|
if in_menu_bar:
|
||||||
|
attr = {
|
||||||
|
'oor:name': index,
|
||||||
|
'oor:op': 'replace',
|
||||||
|
}
|
||||||
|
subnode = ET.SubElement(node, 'node', attr)
|
||||||
|
else:
|
||||||
|
subnode = node
|
||||||
|
|
||||||
|
attr = {'oor:name': 'Title', 'oor:type': 'xs:string'}
|
||||||
|
sn1 = ET.SubElement(subnode, 'prop', attr)
|
||||||
|
for k, v in menu['title'].items():
|
||||||
|
sn2 = ET.SubElement(sn1, 'value', {'xml:lang': k})
|
||||||
|
sn2.text = v
|
||||||
|
value = self._get_context(menu['context'])
|
||||||
|
self._add_node_value(subnode, 'Context', value)
|
||||||
|
|
||||||
|
if 'submenu' in menu:
|
||||||
|
sn = ET.SubElement(subnode, 'node', {'oor:name': 'Submenu'})
|
||||||
|
for i, m in enumerate(menu['submenu']):
|
||||||
|
self._add_menu(id_extension, sn, f'{index}.s{i}', m)
|
||||||
|
if m.get('toolbar', False):
|
||||||
|
self._toolbars.append(m)
|
||||||
|
return
|
||||||
|
|
||||||
|
value = f"service:{id_extension}?{menu['argument']}"
|
||||||
|
self._add_node_value(subnode, 'URL', value)
|
||||||
|
self._add_node_value(subnode, 'Target')
|
||||||
|
value = f"%origin%/{self._path_images}/{menu['icon']}"
|
||||||
|
self._add_node_value(subnode, 'ImageIdentifier', value)
|
||||||
|
return
|
||||||
|
|
||||||
|
def new_addons(self, id_extension, data):
|
||||||
|
in_menu_bar = data['parent'] == 'OfficeMenuBar'
|
||||||
|
self._path_images = data['images']
|
||||||
|
attr = {
|
||||||
|
'oor:name': 'Addons',
|
||||||
|
'oor:package': 'org.openoffice.Office',
|
||||||
|
}
|
||||||
|
attr.update(self.NS_ADDONS)
|
||||||
|
doc = ET.Element('oor:component-data', attr)
|
||||||
|
parent = ET.SubElement(doc, 'node', {'oor:name': 'AddonUI'})
|
||||||
|
node = ET.SubElement(parent, 'node', {'oor:name': data['parent']})
|
||||||
|
|
||||||
|
op = 'fuse'
|
||||||
|
if in_menu_bar:
|
||||||
|
op = 'replace'
|
||||||
|
|
||||||
|
attr = {'oor:name': id_extension, 'oor:op': op}
|
||||||
|
node = ET.SubElement(node, 'node', attr)
|
||||||
|
|
||||||
|
if in_menu_bar:
|
||||||
|
attr = {'oor:name': 'Title', 'oor:type': 'xs:string'}
|
||||||
|
subnode = ET.SubElement(node, 'prop', attr)
|
||||||
|
for k, v in data['main'].items():
|
||||||
|
sn = ET.SubElement(subnode, 'value', {'xml:lang': k})
|
||||||
|
sn.text = v
|
||||||
|
|
||||||
|
self._add_node_value(node, 'Target')
|
||||||
|
node = ET.SubElement(node, 'node', {'oor:name': 'Submenu'})
|
||||||
|
|
||||||
|
for i, menu in enumerate(data['menus']):
|
||||||
|
self._add_menu(id_extension, node, f'm{i}', menu, in_menu_bar)
|
||||||
|
if menu.get('toolbar', False):
|
||||||
|
self._toolbars.append(menu)
|
||||||
|
|
||||||
|
if self._toolbars:
|
||||||
|
attr = {'oor:name': 'OfficeToolBar'}
|
||||||
|
toolbar = ET.SubElement(parent, 'node', attr)
|
||||||
|
attr = {'oor:name': id_extension, 'oor:op': 'replace'}
|
||||||
|
toolbar = ET.SubElement(toolbar, 'node', attr)
|
||||||
|
for t, menu in enumerate(self._toolbars):
|
||||||
|
self._add_menu(id_extension, toolbar, f't{t}', menu)
|
||||||
|
|
||||||
|
return self._get_xml(doc)
|
||||||
|
|
||||||
|
def _add_shortcut(self, node, key, id_extension, arg):
|
||||||
|
attr = {'oor:name': key, 'oor:op': 'fuse'}
|
||||||
|
subnode = ET.SubElement(node, 'node', attr)
|
||||||
|
subnode = ET.SubElement(subnode, 'prop', {'oor:name': 'Command'})
|
||||||
|
subnode = ET.SubElement(subnode, 'value', {'xml:lang': 'en-US'})
|
||||||
|
subnode.text = f"service:{id_extension}?{arg}"
|
||||||
|
return
|
||||||
|
|
||||||
|
def _get_acceleartors(self, menu):
|
||||||
|
if 'submenu' in menu:
|
||||||
|
for m in menu['submenu']:
|
||||||
|
return self._get_acceleartors(m)
|
||||||
|
|
||||||
|
if not menu.get('shortcut', ''):
|
||||||
|
return ''
|
||||||
|
|
||||||
|
return menu
|
||||||
|
|
||||||
|
def new_accelerators(self, id_extension, menus):
|
||||||
|
attr = {
|
||||||
|
'oor:name': 'Accelerators',
|
||||||
|
'oor:package': 'org.openoffice.Office',
|
||||||
|
}
|
||||||
|
attr.update(self.NS_ADDONS)
|
||||||
|
doc = ET.Element('oor:component-data', attr)
|
||||||
|
parent = ET.SubElement(doc, 'node', {'oor:name': 'PrimaryKeys'})
|
||||||
|
|
||||||
|
data = []
|
||||||
|
for m in menus:
|
||||||
|
info = self._get_acceleartors(m)
|
||||||
|
if info:
|
||||||
|
data.append(info)
|
||||||
|
|
||||||
|
node_global = None
|
||||||
|
node_modules = None
|
||||||
|
for m in data:
|
||||||
|
if m['context']:
|
||||||
|
if node_modules is None:
|
||||||
|
node_modules = ET.SubElement(
|
||||||
|
parent, 'node', {'oor:name': 'Modules'})
|
||||||
|
for app in m['context'].split(','):
|
||||||
|
node = ET.SubElement(
|
||||||
|
node_modules, 'node', {'oor:name': self.CONTEXT[app]})
|
||||||
|
self._add_shortcut(
|
||||||
|
node, m['shortcut'], id_extension, m['argument'])
|
||||||
|
else:
|
||||||
|
if node_global is None:
|
||||||
|
node_global = ET.SubElement(
|
||||||
|
parent, 'node', {'oor:name': 'Global'})
|
||||||
|
self._add_shortcut(
|
||||||
|
node_global, m['shortcut'], id_extension, m['argument'])
|
||||||
|
|
||||||
|
return self._get_xml(doc)
|
||||||
|
|
||||||
|
def new_update(self, extension, url_oxt):
|
||||||
|
doc = ET.Element('description', self.NS_UPDATE)
|
||||||
|
ET.SubElement(doc, 'identifier', {'value': extension['id']})
|
||||||
|
ET.SubElement(doc, 'version', {'value': extension['version']})
|
||||||
|
node = ET.SubElement(doc, 'update-download')
|
||||||
|
ET.SubElement(node, 'src', {'xlink:href': url_oxt})
|
||||||
|
node = ET.SubElement(doc, 'release-notes')
|
||||||
|
return self._get_xml(doc)
|
||||||
|
|
||||||
|
def _get_xml(self, doc):
|
||||||
|
xml = parseString(ET.tostring(doc, encoding='utf-8'))
|
||||||
|
return xml.toprettyxml(indent=' ', encoding='utf-8').decode('utf-8')
|
||||||
|
|
||||||
|
|
||||||
|
def _exists(path):
|
||||||
|
return os.path.exists(path)
|
||||||
|
|
||||||
|
|
||||||
|
def _join(*paths):
|
||||||
|
return os.path.join(*paths)
|
||||||
|
|
||||||
|
|
||||||
|
def _mkdir(path):
|
||||||
|
return Path(path).mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
|
def _save(path, data):
|
||||||
|
with open(path, 'w') as f:
|
||||||
|
f.write(data)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def _get_files(path, filters=''):
|
||||||
|
paths = []
|
||||||
|
if filters in ('*', '*.*'):
|
||||||
|
filters = ''
|
||||||
|
for folder, _, files in os.walk(path):
|
||||||
|
if filters:
|
||||||
|
pattern = re.compile(r'\.(?:{})$'.format(filters), re.IGNORECASE)
|
||||||
|
paths += [_join(folder, f) for f in files if pattern.search(f)]
|
||||||
|
else:
|
||||||
|
paths += files
|
||||||
|
return paths
|
||||||
|
|
||||||
|
|
||||||
|
def _compress_oxt():
|
||||||
|
log.info('Compress OXT extension...')
|
||||||
|
|
||||||
|
path_oxt = _join(DIRS['files'], FILES['oxt'])
|
||||||
|
|
||||||
|
z = zipfile.ZipFile(path_oxt, 'w', compression=zipfile.ZIP_DEFLATED)
|
||||||
|
root_len = len(os.path.abspath(DIRS['source']))
|
||||||
|
for root, dirs, files in os.walk(DIRS['source']):
|
||||||
|
relative = os.path.abspath(root)[root_len:]
|
||||||
|
for f in files:
|
||||||
|
fullpath = _join(root, f)
|
||||||
|
file_name = _join(relative, f)
|
||||||
|
if file_name == FILES['idl']:
|
||||||
|
continue
|
||||||
|
z.write(fullpath, file_name, zipfile.ZIP_DEFLATED)
|
||||||
|
z.close()
|
||||||
|
|
||||||
|
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 successfully...')
|
||||||
|
log.info('Start LibreOffice...')
|
||||||
|
call(PATHS['soffice'])
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def _validate_new():
|
||||||
|
path_source = DIRS['source']
|
||||||
|
if not _exists(path_source):
|
||||||
|
return True
|
||||||
|
|
||||||
|
msg = f'Path: {path_source}, exists, delete first'
|
||||||
|
log.error(msg)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _create_new_directories():
|
||||||
|
path_source = DIRS['source']
|
||||||
|
_mkdir(path_source)
|
||||||
|
path = _join(path_source, DIRS['meta'])
|
||||||
|
_mkdir(path)
|
||||||
|
path = _join(path_source, DIRS['description'])
|
||||||
|
_mkdir(path)
|
||||||
|
path = _join(path_source, DIRS['images'])
|
||||||
|
_mkdir(path)
|
||||||
|
path = _join(path_source, DIRS['registration'])
|
||||||
|
_mkdir(path)
|
||||||
|
path = _join(path_source, DIRS['office'])
|
||||||
|
_mkdir(path)
|
||||||
|
|
||||||
|
if FILES['easymacro'] or DIRS['pythonpath']:
|
||||||
|
path = _join(path_source, 'pythonpath')
|
||||||
|
_mkdir(path)
|
||||||
|
|
||||||
|
path = DIRS['files']
|
||||||
|
if not _exists(path):
|
||||||
|
_mkdir(path)
|
||||||
|
|
||||||
|
msg = 'Created directories...'
|
||||||
|
log.info(msg)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def _create_new_files():
|
||||||
|
path_source = DIRS['source']
|
||||||
|
|
||||||
|
for k, v in INFO.items():
|
||||||
|
file_name = f'license_{k}.txt'
|
||||||
|
path = _join(path_source, DIRS['registration'], file_name)
|
||||||
|
_save(path, v['license'])
|
||||||
|
|
||||||
|
if TYPE_EXTENSION > 1:
|
||||||
|
path = _join(path_source, FILES['idl'])
|
||||||
|
_save(path, DATA['idl'])
|
||||||
|
|
||||||
|
path = _join(path_source, FILES['py'])
|
||||||
|
_save(path, DATA['py'])
|
||||||
|
|
||||||
|
|
||||||
|
msg = 'Created files...'
|
||||||
|
log.info(msg)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def _validate_update():
|
||||||
|
if TYPE_EXTENSION == 1:
|
||||||
|
return True
|
||||||
|
|
||||||
|
if not _exists(PATHS['idlc']):
|
||||||
|
msg = 'Binary: "idlc" not found'
|
||||||
|
log.error(msg)
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not _exists(PATHS['include']):
|
||||||
|
msg = 'Directory: "include" not found'
|
||||||
|
log.error(msg)
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not _exists(PATHS['regmerge']):
|
||||||
|
msg = 'Binary: "regmerge" not found'
|
||||||
|
log.error(msg)
|
||||||
|
return False
|
||||||
|
|
||||||
|
path = _join(DIRS['source'], FILES['idl'])
|
||||||
|
if not _exists(path):
|
||||||
|
msg = f'File: "{FILES["idl"]}" not found'
|
||||||
|
log.error(msg)
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def _compile_idl():
|
||||||
|
if TYPE_EXTENSION == 1:
|
||||||
|
return
|
||||||
|
|
||||||
|
log.info('Compilate IDL...')
|
||||||
|
path_rdb = _join(DIRS['source'], FILES['rdb'])
|
||||||
|
path_urd = _join(DIRS['source'], FILES['urd'])
|
||||||
|
|
||||||
|
path = _join(DIRS['source'], FILES['idl'])
|
||||||
|
call([PATHS['idlc'], '-I', PATHS['include'], path])
|
||||||
|
call([PATHS['regmerge'], path_rdb, '/UCR', path_urd])
|
||||||
|
os.remove(path_urd)
|
||||||
|
|
||||||
|
log.info('Compilate IDL successfully...')
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def _update_files():
|
||||||
|
path_files = DIRS['files']
|
||||||
|
if not _exists(path_files):
|
||||||
|
_mkdir(path_files)
|
||||||
|
|
||||||
|
path_source = DIRS['source']
|
||||||
|
|
||||||
|
for k, v in INFO.items():
|
||||||
|
file_name = FILES['ext_desc'].format(k)
|
||||||
|
path = _join(path_source, DIRS['description'], file_name)
|
||||||
|
_save(path, v['description'])
|
||||||
|
|
||||||
|
path_logo = EXTENSION['icon'][0]
|
||||||
|
if _exists(path_logo):
|
||||||
|
file_name = EXTENSION['icon'][1]
|
||||||
|
path = _join(path_source, DIRS['images'], file_name)
|
||||||
|
copyfile(path_logo, path)
|
||||||
|
|
||||||
|
files = os.listdir(DIRS['images'])
|
||||||
|
for f in files:
|
||||||
|
if f[-3:].lower() == 'bmp':
|
||||||
|
source = _join(DIRS['images'], f)
|
||||||
|
target = _join(path_source, DIRS['images'], f)
|
||||||
|
copyfile(source, target)
|
||||||
|
|
||||||
|
if FILES['easymacro']:
|
||||||
|
source = EASYMACRO
|
||||||
|
target = _join(path_source, 'pythonpath', source)
|
||||||
|
copyfile(source, target)
|
||||||
|
|
||||||
|
xml = LiboXML()
|
||||||
|
|
||||||
|
path = _join(path_source, DIRS['meta'], FILES['manifest'])
|
||||||
|
data = xml.new_manifest(DATA['manifest'])
|
||||||
|
_save(path, data)
|
||||||
|
|
||||||
|
path = _join(path_source, FILES['description'])
|
||||||
|
data = xml.new_description(DATA['description'])
|
||||||
|
_save(path, data)
|
||||||
|
|
||||||
|
if TYPE_EXTENSION == 1:
|
||||||
|
path = _join(path_source, FILES['addons'])
|
||||||
|
data = xml.new_addons(EXTENSION['id'], DATA['addons'])
|
||||||
|
_save(path, data)
|
||||||
|
|
||||||
|
path = _join(path_source, DIRS['office'])
|
||||||
|
_mkdir(path)
|
||||||
|
path = _join(path_source, DIRS['office'], FILES['shortcut'])
|
||||||
|
data = xml.new_accelerators(EXTENSION['id'], DATA['addons']['menus'])
|
||||||
|
_save(path, data)
|
||||||
|
|
||||||
|
|
||||||
|
if TYPE_EXTENSION == 3:
|
||||||
|
path = _join(path_source, FILES['addin'])
|
||||||
|
_save(path, DATA['addin'])
|
||||||
|
|
||||||
|
if USE_LOCALES:
|
||||||
|
msg = "Don't forget generate DOMAIN.pot for locales"
|
||||||
|
for lang in EXTENSION['languages']:
|
||||||
|
path = _join(path_source, DIRS['locales'], lang, 'LC_MESSAGES')
|
||||||
|
Path(path).mkdir(parents=True, exist_ok=True)
|
||||||
|
log.info(msg)
|
||||||
|
|
||||||
|
if DATA['update']:
|
||||||
|
path_xml = _join(path_files, FILES['update'])
|
||||||
|
data = xml.new_update(EXTENSION, DATA['update'])
|
||||||
|
_save(path_xml, data)
|
||||||
|
|
||||||
|
_compile_idl()
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def _create():
|
||||||
|
if not _validate_new():
|
||||||
|
return
|
||||||
|
|
||||||
|
_create_new_directories()
|
||||||
|
_create_new_files()
|
||||||
|
_update_files()
|
||||||
|
|
||||||
|
msg = f"New extension: {EXTENSION['name']} make sucesfully...\n"
|
||||||
|
msg += '\tNow, you can install and test: zaz.py -i'
|
||||||
|
log.info(msg)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def _get_info_path(path):
|
||||||
|
path, filename = os.path.split(path)
|
||||||
|
name, extension = os.path.splitext(filename)
|
||||||
|
return (path, filename, name, extension)
|
||||||
|
|
||||||
|
|
||||||
|
def _zip_embed(source, files):
|
||||||
|
PATH = 'Scripts/python/'
|
||||||
|
FILE_PYC = 'easymacro.pyc'
|
||||||
|
|
||||||
|
p, f, name, e = _get_info_path(source)
|
||||||
|
now = datetime.now().strftime('_%Y%m%d_%H%M%S')
|
||||||
|
path_source = _join(p, name + now + e)
|
||||||
|
copyfile(source, path_source)
|
||||||
|
target = source
|
||||||
|
|
||||||
|
py_compile.compile(EASYMACRO, FILE_PYC)
|
||||||
|
xml = LiboXML()
|
||||||
|
|
||||||
|
path_easymacro = PATH + FILE_PYC
|
||||||
|
names = [f[1] for f in files] + [path_easymacro]
|
||||||
|
nodes = []
|
||||||
|
with zipfile.ZipFile(target, 'w', compression=zipfile.ZIP_DEFLATED) as zt:
|
||||||
|
with zipfile.ZipFile(path_source, compression=zipfile.ZIP_DEFLATED) as zs:
|
||||||
|
for name in zs.namelist():
|
||||||
|
if FILES['manifest'] in name:
|
||||||
|
path_manifest = name
|
||||||
|
xml_manifest = zs.open(name).read()
|
||||||
|
elif name in names:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
zt.writestr(name, zs.open(name).read())
|
||||||
|
|
||||||
|
data = []
|
||||||
|
for path, name in files:
|
||||||
|
data.append(name)
|
||||||
|
zt.write(path, name)
|
||||||
|
|
||||||
|
zt.write(FILE_PYC, path_easymacro)
|
||||||
|
data.append(path_easymacro)
|
||||||
|
|
||||||
|
xml.parse_manifest(xml_manifest)
|
||||||
|
xml_manifest = xml.add_data_manifest(data)
|
||||||
|
zt.writestr(path_manifest, xml_manifest)
|
||||||
|
|
||||||
|
os.unlink(FILE_PYC)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def _embed(args):
|
||||||
|
PATH = 'Scripts/python'
|
||||||
|
PYTHONPATH = 'pythonpath'
|
||||||
|
|
||||||
|
doc = args.document
|
||||||
|
if not doc:
|
||||||
|
msg = '-d/--document Path file to embed is mandatory'
|
||||||
|
log.error(msg)
|
||||||
|
return
|
||||||
|
if not _exists(doc):
|
||||||
|
msg = 'Path file not exists'
|
||||||
|
log.error(msg)
|
||||||
|
return
|
||||||
|
|
||||||
|
files = []
|
||||||
|
if args.files:
|
||||||
|
files = args.files.split(',')
|
||||||
|
source = _join(PATHS['profile'], PATH)
|
||||||
|
content = os.listdir(source)
|
||||||
|
if PYTHONPATH in content:
|
||||||
|
content.remove(PYTHONPATH)
|
||||||
|
|
||||||
|
if files:
|
||||||
|
files = [(_join(source, f), _join(PATH, f)) for f in files if f in content]
|
||||||
|
else:
|
||||||
|
files = [(_join(source, f), _join(PATH, f)) for f in content]
|
||||||
|
|
||||||
|
_zip_embed(doc, files)
|
||||||
|
|
||||||
|
log.info('Embedded macros successfully...')
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def _locales(args):
|
||||||
|
if args.files:
|
||||||
|
files = args.files.split(',')
|
||||||
|
else:
|
||||||
|
files = _get_files(DIRS['source'], 'py')
|
||||||
|
paths = ' '.join([f for f in files if not EASYMACRO in f])
|
||||||
|
path_pot = _join(DIRS['source'], DIRS['locales'], '{}.pot'.format(DOMAIN))
|
||||||
|
call([PATHS['gettext'], '-o', path_pot, paths])
|
||||||
|
log.info('POT generate successfully...')
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def _update():
|
||||||
|
path_locales = _join(DIRS['source'], DIRS['locales'])
|
||||||
|
path_pot = _join(DIRS['source'], DIRS['locales'], '{}.pot'.format(DOMAIN))
|
||||||
|
if not _exists(path_pot):
|
||||||
|
log.error('Not exists file POT...')
|
||||||
|
return
|
||||||
|
|
||||||
|
files = _get_files(path_locales, 'po')
|
||||||
|
if not files:
|
||||||
|
log.error('First, generate files PO...')
|
||||||
|
return
|
||||||
|
|
||||||
|
for f in files:
|
||||||
|
call([PATHS['msgmerge'], '-U', f, path_pot])
|
||||||
|
log.info('\tUpdate: {}'.format(f))
|
||||||
|
|
||||||
|
log.info('Locales update successfully...')
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def _new(args):
|
||||||
|
if not args.target:
|
||||||
|
msg = 'Add argument target: -t PATH_TARGET'
|
||||||
|
log.error(msg)
|
||||||
|
return
|
||||||
|
|
||||||
|
if not args.name:
|
||||||
|
msg = 'Add argument name: -n name-new-extension'
|
||||||
|
log.error(msg)
|
||||||
|
return
|
||||||
|
|
||||||
|
path = _join(args.target, args.name)
|
||||||
|
_mkdir(path)
|
||||||
|
_mkdir(_join(path, 'extension'))
|
||||||
|
_mkdir(_join(path, 'images'))
|
||||||
|
path_logo = 'images/pymacros.png'
|
||||||
|
copyfile(path_logo, _join(path, 'images/logo.png'))
|
||||||
|
copyfile('zaz.py', _join(path, 'zaz.py'))
|
||||||
|
copyfile(EASYMACRO, _join(path, 'easymacro.py'))
|
||||||
|
copyfile('conf.py.example', _join(path, 'conf.py'))
|
||||||
|
|
||||||
|
msg = 'Folders and files copy successfully for new extension.'
|
||||||
|
log.info(msg)
|
||||||
|
msg = f'Change to folder: {path}'
|
||||||
|
log.info(msg)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def main(args):
|
||||||
|
if args.new:
|
||||||
|
_new(args)
|
||||||
|
return
|
||||||
|
|
||||||
|
if args.update:
|
||||||
|
_update()
|
||||||
|
return
|
||||||
|
|
||||||
|
if args.locales:
|
||||||
|
_locales(args)
|
||||||
|
return
|
||||||
|
|
||||||
|
if args.embed:
|
||||||
|
_embed(args)
|
||||||
|
return
|
||||||
|
|
||||||
|
if args.create:
|
||||||
|
_create()
|
||||||
|
return
|
||||||
|
|
||||||
|
if not _validate_update():
|
||||||
|
return
|
||||||
|
|
||||||
|
if not args.only_compress:
|
||||||
|
_update_files()
|
||||||
|
|
||||||
|
_compress_oxt()
|
||||||
|
|
||||||
|
if args.install:
|
||||||
|
_install_and_test()
|
||||||
|
|
||||||
|
log.info('Extension make successfully...')
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def _process_command_line_arguments():
|
||||||
|
parser = argparse.ArgumentParser(description='Make LibreOffice extensions')
|
||||||
|
|
||||||
|
parser.add_argument('-new', '--new', dest='new', action='store_true',
|
||||||
|
default=False, required=False)
|
||||||
|
parser.add_argument('-t', '--target', dest='target', default='')
|
||||||
|
parser.add_argument('-n', '--name', dest='name', default='', required=False)
|
||||||
|
parser.add_argument('-c', '--create', dest='create', action='store_true',
|
||||||
|
default=False, required=False)
|
||||||
|
parser.add_argument('-i', '--install', dest='install', action='store_true',
|
||||||
|
default=False, required=False)
|
||||||
|
parser.add_argument('-e', '--embed', dest='embed', action='store_true',
|
||||||
|
default=False, required=False)
|
||||||
|
parser.add_argument('-d', '--document', dest='document', default='')
|
||||||
|
parser.add_argument('-f', '--files', dest='files', default='')
|
||||||
|
parser.add_argument('-l', '--locales', dest='locales', action='store_true',
|
||||||
|
default=False, required=False)
|
||||||
|
parser.add_argument('-u', '--update', dest='update', action='store_true',
|
||||||
|
default=False, required=False)
|
||||||
|
parser.add_argument('-oc', '--only_compress', dest='only_compress',
|
||||||
|
action='store_true', default=False, required=False)
|
||||||
|
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
args = _process_command_line_arguments()
|
||||||
|
main(args)
|
||||||
|
|
Loading…
Reference in New Issue