Doc for paths
This commit is contained in:
parent
22ac697de1
commit
44b07158c5
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
|
@ -40,11 +40,15 @@
|
||||||
.. autosummary::
|
.. autosummary::
|
||||||
|
|
||||||
Dates
|
Dates
|
||||||
|
Hash
|
||||||
Json
|
Json
|
||||||
LOServer
|
LOServer
|
||||||
MBT
|
MBT
|
||||||
Macro
|
Macro
|
||||||
MessageBoxType
|
MessageBoxType
|
||||||
|
Paths
|
||||||
|
Shell
|
||||||
|
Timer
|
||||||
commands
|
commands
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ You can used **easymacro** with any extension or directly in your macros.
|
||||||
install
|
install
|
||||||
tools_debug
|
tools_debug
|
||||||
tools
|
tools
|
||||||
|
paths
|
||||||
api
|
api
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
Paths and files
|
||||||
|
===============
|
||||||
|
|
||||||
|
Remember, always import library first.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import easymacro as app
|
||||||
|
|
||||||
|
|
||||||
|
Get info path
|
||||||
|
-------------
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
path = '/home/mau/myfile.ods'
|
||||||
|
p = app.path(path)
|
||||||
|
|
||||||
|
app.debug(p.path)
|
||||||
|
app.debug(p.file_name)
|
||||||
|
app.debug(p.name)
|
||||||
|
app.debug(p.ext)
|
||||||
|
app.debug(p.size)
|
||||||
|
app.debug(p.url)
|
||||||
|
|
||||||
|
.. image:: _static/images/path_01.png
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
|
Get info like tuple
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
app.debug(p.info)
|
||||||
|
|
||||||
|
.. image:: _static/images/path_02.png
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
|
Or like dict
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
app.debug(p.dict)
|
||||||
|
|
||||||
|
.. image:: _static/images/path_03.png
|
||||||
|
|
||||||
|
|
||||||
|
Get home path
|
||||||
|
-------------
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
p = app.path
|
||||||
|
app.debug(p.home)
|
||||||
|
|
||||||
|
|
||||||
|
Get documento path
|
||||||
|
------------------
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
p = app.path
|
||||||
|
app.debug(p.documents)
|
||||||
|
|
||||||
|
|
||||||
|
Get temporary directory
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
p = app.path
|
||||||
|
app.debug(p.temp_dir)
|
||||||
|
|
||||||
|
|
||||||
|
Get path user profile
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
p = app.path
|
||||||
|
app.debug(p.user_profile)
|
||||||
|
|
||||||
|
|
||||||
|
Get path user config
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
p = app.path
|
||||||
|
app.debug(p.user_config)
|
||||||
|
|
||||||
|
|
||||||
|
Get python executable path
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
p = app.path
|
||||||
|
app.debug(p.python)
|
||||||
|
|
|
@ -453,20 +453,20 @@ Execute macro in other thread
|
||||||
|
|
||||||
|
|
||||||
Call external program
|
Call external program
|
||||||
^^^^^^^^^^^^^^^^^^^^^
|
---------------------
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
app_name = 'gnome-calculator'
|
app_name = 'gnome-calculator'
|
||||||
app.run(app_name)
|
app.shell.run(app_name)
|
||||||
app.msgbox('ok')
|
app.debug(app_name)
|
||||||
|
|
||||||
Call command line and capture output
|
Call command line and capture output
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
args = 'ls -lh ~'
|
args = 'ls -lh ~'
|
||||||
result = app.run(args, True)
|
result = app.shell.run(args, True)
|
||||||
app.debug(result)
|
app.debug(result)
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
@ -502,7 +502,68 @@ Call command line and capture output line by line.
|
||||||
|
|
||||||
|
|
||||||
Timer
|
Timer
|
||||||
^^^^^
|
-----
|
||||||
|
|
||||||
|
Only once
|
||||||
|
^^^^^^^^^
|
||||||
|
|
||||||
|
Execute any macro only once in N seconds.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
TIMER_NAME = 'clock'
|
||||||
|
|
||||||
|
def show_time():
|
||||||
|
app.debug(app.dates.time)
|
||||||
|
return
|
||||||
|
|
||||||
|
def start_clock():
|
||||||
|
seconds = 5
|
||||||
|
macro = {
|
||||||
|
'library': 'test',
|
||||||
|
'name': 'show_time',
|
||||||
|
}
|
||||||
|
app.timer.once(TIMER_NAME, seconds, macro)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def main(args=None):
|
||||||
|
start_clock()
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
Cancel execution, before start.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
TIMER_NAME = 'clock'
|
||||||
|
|
||||||
|
def show_time():
|
||||||
|
app.debug(app.dates.time)
|
||||||
|
return
|
||||||
|
|
||||||
|
def start_clock():
|
||||||
|
seconds = 60
|
||||||
|
macro = {
|
||||||
|
'library': 'test',
|
||||||
|
'name': 'show_time',
|
||||||
|
}
|
||||||
|
app.timer.once(TIMER_NAME, seconds, macro)
|
||||||
|
return
|
||||||
|
|
||||||
|
def stop_clock():
|
||||||
|
app.timer.cancel(TIMER_NAME)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
26/02/2022 12:23:09 - INFO - Event: "clock", started... execute in 60 seconds
|
||||||
|
26/02/2022 12:23:16 - INFO - Cancel event: "clock", ok...
|
||||||
|
|
||||||
|
|
||||||
|
Every seconds
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
Execute any macro every seconds.
|
Execute any macro every seconds.
|
||||||
|
|
||||||
|
@ -511,7 +572,7 @@ Execute any macro every seconds.
|
||||||
TIMER_NAME = 'clock'
|
TIMER_NAME = 'clock'
|
||||||
|
|
||||||
def show_time():
|
def show_time():
|
||||||
app.debug(app.now(True))
|
app.debug(app.dates.time)
|
||||||
return
|
return
|
||||||
|
|
||||||
def start_clock():
|
def start_clock():
|
||||||
|
@ -520,46 +581,74 @@ Execute any macro every seconds.
|
||||||
'library': 'test',
|
'library': 'test',
|
||||||
'name': 'show_time',
|
'name': 'show_time',
|
||||||
}
|
}
|
||||||
app.start_timer(TIMER_NAME, seconds, macro)
|
app.timer.start(TIMER_NAME, seconds, macro)
|
||||||
return
|
return
|
||||||
|
|
||||||
def stop_clock():
|
def stop_clock():
|
||||||
app.stop_timer(TIMER_NAME)
|
app.timer.stop(TIMER_NAME)
|
||||||
return
|
return
|
||||||
|
|
||||||
def main(args=None):
|
def main(args=None):
|
||||||
start_clock()
|
start_clock()
|
||||||
return
|
return
|
||||||
|
|
||||||
Execute `stop_clock` for stop timer.
|
Execute **stop_clock** for stop timer.
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
21/06/2021 22:43:17 - INFO - Timer started... show_time
|
26/02/2022 11:28:01 - INFO - Timer 'clock' started, execute macro: 'show_time'
|
||||||
21/06/2021 22:43:18 - DEBUG - 22:43:18.080315
|
26/02/2022 11:28:02 - DEBUG - 11:28:02
|
||||||
21/06/2021 22:43:19 - DEBUG - 22:43:19.082211
|
26/02/2022 11:28:03 - DEBUG - 11:28:03
|
||||||
...
|
...
|
||||||
21/06/2021 22:43:46 - DEBUG - 22:43:46.126446
|
26/02/2022 11:28:08 - DEBUG - 11:28:08
|
||||||
21/06/2021 22:43:47 - DEBUG - 22:43:47.128487
|
26/02/2022 11:28:09 - DEBUG - 11:28:09
|
||||||
21/06/2021 22:43:47 - INFO - Timer stopped... show_time
|
26/02/2022 11:28:10 - INFO - Timer stopped...
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Be sure to use a unique name for each timer.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
Be sure to macro for execute not block UI LibO
|
||||||
|
|
||||||
|
|
||||||
Get digest
|
Get digest
|
||||||
^^^^^^^^^^
|
----------
|
||||||
|
|
||||||
|
For default get digest in hex
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
data = 'LibreOffice with Python'
|
data = 'LibreOffice with Python'
|
||||||
|
|
||||||
digest = app.sha256(data)
|
digest = app.hash.digest('md5', data)
|
||||||
app.msgbox(digest)
|
app.debug('MD5 = ', digest)
|
||||||
|
|
||||||
digest = app.sha512(data)
|
digest = app.hash.digest('sha1', data)
|
||||||
app.msgbox(digest)
|
app.debug('SHA1 = ', digest)
|
||||||
|
|
||||||
|
digest = app.hash.digest('sha256', data)
|
||||||
|
app.debug('SHA256 = ', digest)
|
||||||
|
|
||||||
|
digest = app.hash.digest('sha512', data)
|
||||||
|
app.debug('SHA512 = ', digest)
|
||||||
|
|
||||||
|
# Get bytes
|
||||||
|
digest = app.hash.digest('md5', data, False)
|
||||||
|
app.debug('MD5 = ', digest)
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
26/02/2022 15:57:53 - DEBUG - MD5 = e0cb96d2c04b26db79dbd30c4d56b555
|
||||||
|
26/02/2022 15:57:53 - DEBUG - SHA1 = 7006fb17b7a235245cfc986710a11f10543ae10d
|
||||||
|
26/02/2022 15:57:53 - DEBUG - SHA256 = 3fe4586d51fa3e352ec28c05b7e71eaee2e41d5ee78f372c44eeb2f433f7e002
|
||||||
|
26/02/2022 15:57:53 - DEBUG - SHA512 = b6eaea6bc11956eae7f990034ff950eba4b0fe51a577d301272cc8b4c1c603abd36ce852311766e5af2f603d1d96741797b62d4b405459348bacae7ec54e2982
|
||||||
|
26/02/2022 15:57:53 - DEBUG - MD5 = b'\xe0\xcb\x96\xd2\xc0K&\xdby\xdb\xd3\x0cMV\xb5U'
|
||||||
|
|
||||||
|
|
||||||
Save and get configurations
|
Save and get configurations
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
---------------------------
|
||||||
|
|
||||||
You can save any data.
|
You can save any data.
|
||||||
|
|
||||||
|
|
|
@ -20,18 +20,23 @@
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import getpass
|
import getpass
|
||||||
|
import hashlib
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
|
import shlex
|
||||||
|
import shutil
|
||||||
import socket
|
import socket
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import tempfile
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
from pathlib import Path
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
@ -64,6 +69,11 @@ _info_debug = f"Python: {sys.version}\n\n{platform.platform()}\n\n" + '\n'.join(
|
||||||
|
|
||||||
SALT = b'00a1bfb05353bb3fd8e7aa7fe5efdccc'
|
SALT = b'00a1bfb05353bb3fd8e7aa7fe5efdccc'
|
||||||
|
|
||||||
|
_EVENTS = {}
|
||||||
|
PYTHON = 'python'
|
||||||
|
if IS_WIN:
|
||||||
|
PYTHON = 'python.exe'
|
||||||
|
|
||||||
|
|
||||||
CTX = uno.getComponentContext()
|
CTX = uno.getComponentContext()
|
||||||
SM = CTX.getServiceManager()
|
SM = CTX.getServiceManager()
|
||||||
|
@ -80,56 +90,6 @@ class MessageBoxType():
|
||||||
MBT = MessageBoxType
|
MBT = MessageBoxType
|
||||||
|
|
||||||
|
|
||||||
def debug(*messages) -> None:
|
|
||||||
"""Show messages debug
|
|
||||||
|
|
||||||
:param messages: List of messages to debug
|
|
||||||
:type messages: list[Any]
|
|
||||||
"""
|
|
||||||
|
|
||||||
data = [str(m) for m in messages]
|
|
||||||
log.debug('\t'.join(data))
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
def error(message: Any) -> None:
|
|
||||||
"""Show message error
|
|
||||||
|
|
||||||
:param message: The message error
|
|
||||||
:type message: Any
|
|
||||||
"""
|
|
||||||
|
|
||||||
log.error(message)
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
def info(*messages) -> None:
|
|
||||||
"""Show messages info
|
|
||||||
|
|
||||||
:param messages: List of messages to debug
|
|
||||||
:type messages: list[Any]
|
|
||||||
"""
|
|
||||||
|
|
||||||
data = [str(m) for m in messages]
|
|
||||||
log.info('\t'.join(data))
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
def save_log(path: str, data: Any) -> None:
|
|
||||||
"""Save data in file, data append to end and automatic add current time.
|
|
||||||
|
|
||||||
:param path: Path to save log
|
|
||||||
:type path: str
|
|
||||||
:param data: Data to save in file log
|
|
||||||
:type data: Any
|
|
||||||
"""
|
|
||||||
|
|
||||||
with open(path, 'a') as f:
|
|
||||||
f.write(f'{str(now())[:19]} - ')
|
|
||||||
pprint(data, stream=f)
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
def create_instance(name: str, with_context: bool=False, argument: Any=None) -> Any:
|
def create_instance(name: str, with_context: bool=False, argument: Any=None) -> Any:
|
||||||
"""Create a service instance
|
"""Create a service instance
|
||||||
|
|
||||||
|
@ -183,6 +143,22 @@ def get_app_config(node_name: str, key: str='') -> Any:
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
# Get info LibO
|
||||||
|
NAME = TITLE = get_app_config('org.openoffice.Setup/Product', 'ooName')
|
||||||
|
VERSION = get_app_config('org.openoffice.Setup/Product','ooSetupVersion')
|
||||||
|
LANGUAGE = get_app_config('org.openoffice.Setup/L10N/', 'ooLocale')
|
||||||
|
LANG = LANGUAGE.split('-')[0]
|
||||||
|
|
||||||
|
INFO_DEBUG = f"{NAME} v{VERSION} {LANGUAGE}\n\n{_info_debug}"
|
||||||
|
|
||||||
|
# Get start date from Calc configuration
|
||||||
|
node = '/org.openoffice.Office.Calc/Calculate/Other/Date'
|
||||||
|
year = get_app_config(node, 'YY')
|
||||||
|
month = get_app_config(node, 'MM')
|
||||||
|
day = get_app_config(node, 'DD')
|
||||||
|
DATE_OFFSET = datetime.date(year, month, day).toordinal()
|
||||||
|
|
||||||
|
|
||||||
def set_app_config(node_name: str, key: str, new_value: Any) -> Any:
|
def set_app_config(node_name: str, key: str, new_value: Any) -> Any:
|
||||||
"""Update value for key in node name.
|
"""Update value for key in node name.
|
||||||
|
|
||||||
|
@ -217,6 +193,56 @@ def set_app_config(node_name: str, key: str, new_value: Any) -> Any:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def debug(*messages) -> None:
|
||||||
|
"""Show messages debug
|
||||||
|
|
||||||
|
:param messages: List of messages to debug
|
||||||
|
:type messages: list[Any]
|
||||||
|
"""
|
||||||
|
|
||||||
|
data = [str(m) for m in messages]
|
||||||
|
log.debug('\t'.join(data))
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def error(message: Any) -> None:
|
||||||
|
"""Show message error
|
||||||
|
|
||||||
|
:param message: The message error
|
||||||
|
:type message: Any
|
||||||
|
"""
|
||||||
|
|
||||||
|
log.error(message)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def info(*messages) -> None:
|
||||||
|
"""Show messages info
|
||||||
|
|
||||||
|
:param messages: List of messages to debug
|
||||||
|
:type messages: list[Any]
|
||||||
|
"""
|
||||||
|
|
||||||
|
data = [str(m) for m in messages]
|
||||||
|
log.info('\t'.join(data))
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def save_log(path: str, data: Any) -> None:
|
||||||
|
"""Save data in file, data append to end and automatic add current time.
|
||||||
|
|
||||||
|
:param path: Path to save log
|
||||||
|
:type path: str
|
||||||
|
:param data: Data to save in file log
|
||||||
|
:type data: Any
|
||||||
|
"""
|
||||||
|
|
||||||
|
with open(path, 'a') as f:
|
||||||
|
f.write(f'{str(now())[:19]} - ')
|
||||||
|
pprint(data, stream=f)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
def _set_app_command(command: str, disable: bool):
|
def _set_app_command(command: str, disable: bool):
|
||||||
NEW_NODE_NAME = f'zaz_disable_command_{command.lower()}'
|
NEW_NODE_NAME = f'zaz_disable_command_{command.lower()}'
|
||||||
name = 'com.sun.star.configuration.ConfigurationProvider'
|
name = 'com.sun.star.configuration.ConfigurationProvider'
|
||||||
|
@ -270,22 +296,6 @@ class commands():
|
||||||
return _set_app_command(self._command, False)
|
return _set_app_command(self._command, False)
|
||||||
|
|
||||||
|
|
||||||
# Get info LibO
|
|
||||||
NAME = TITLE = get_app_config('org.openoffice.Setup/Product', 'ooName')
|
|
||||||
VERSION = get_app_config('org.openoffice.Setup/Product','ooSetupVersion')
|
|
||||||
LANGUAGE = get_app_config('org.openoffice.Setup/L10N/', 'ooLocale')
|
|
||||||
LANG = LANGUAGE.split('-')[0]
|
|
||||||
|
|
||||||
INFO_DEBUG = f"{NAME} v{VERSION} {LANGUAGE}\n\n{_info_debug}"
|
|
||||||
|
|
||||||
# Get start date from Calc configuration
|
|
||||||
node = '/org.openoffice.Office.Calc/Calculate/Other/Date'
|
|
||||||
year = get_app_config(node, 'YY')
|
|
||||||
month = get_app_config(node, 'MM')
|
|
||||||
day = get_app_config(node, 'DD')
|
|
||||||
DATE_OFFSET = datetime.date(year, month, day).toordinal()
|
|
||||||
|
|
||||||
|
|
||||||
def mri(obj: Any) -> None:
|
def mri(obj: Any) -> None:
|
||||||
"""Inspect object with MRI Extension
|
"""Inspect object with MRI Extension
|
||||||
|
|
||||||
|
@ -487,6 +497,16 @@ class Dates(object):
|
||||||
"""
|
"""
|
||||||
return datetime.date.today()
|
return datetime.date.today()
|
||||||
|
|
||||||
|
@_classproperty
|
||||||
|
def time(cls):
|
||||||
|
"""Current local time
|
||||||
|
|
||||||
|
:return: Return the current local time
|
||||||
|
:rtype: datetime.time
|
||||||
|
"""
|
||||||
|
t = cls.now.time().replace(microsecond=0)
|
||||||
|
return t
|
||||||
|
|
||||||
@_classproperty
|
@_classproperty
|
||||||
def epoch(cls):
|
def epoch(cls):
|
||||||
"""Get unix time
|
"""Get unix time
|
||||||
|
@ -662,11 +682,372 @@ class Macro(object):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class Shell(object):
|
||||||
|
"""Class for subprocess
|
||||||
|
|
||||||
|
`See Subprocess <https://docs.python.org/3.7/library/subprocess.html>`_
|
||||||
|
"""
|
||||||
|
@classmethod
|
||||||
|
def run(cls, command, capture=False, split=False):
|
||||||
|
"""Execute commands
|
||||||
|
|
||||||
|
:param command: Command to run
|
||||||
|
:type command: str
|
||||||
|
:param capture: If capture result of command
|
||||||
|
:type capture: bool
|
||||||
|
:param split: Some commands need split.
|
||||||
|
:type split: bool
|
||||||
|
:return: Result of command
|
||||||
|
:rtype: Any
|
||||||
|
"""
|
||||||
|
if split:
|
||||||
|
cmd = shlex.split(command)
|
||||||
|
result = subprocess.run(cmd, capture_output=capture, text=True, shell=IS_WIN)
|
||||||
|
if capture:
|
||||||
|
result = result.stdout
|
||||||
|
else:
|
||||||
|
result = result.returncode
|
||||||
|
else:
|
||||||
|
if capture:
|
||||||
|
result = subprocess.check_output(command, shell=True).decode()
|
||||||
|
else:
|
||||||
|
result = subprocess.Popen(command)
|
||||||
|
return result
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def popen(cls, command):
|
||||||
|
"""Execute commands and return line by line
|
||||||
|
|
||||||
|
:param command: Command to run
|
||||||
|
:type command: str
|
||||||
|
:return: Result of command
|
||||||
|
:rtype: Any
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
proc = subprocess.Popen(shlex.split(command), shell=IS_WIN,
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
|
for line in proc.stdout:
|
||||||
|
yield line.decode().rstrip()
|
||||||
|
except Exception as e:
|
||||||
|
error(e)
|
||||||
|
yield (e.errno, e.strerror)
|
||||||
|
|
||||||
|
|
||||||
|
class Timer(object):
|
||||||
|
"""Class for timer thread"""
|
||||||
|
|
||||||
|
class TimerThread(threading.Thread):
|
||||||
|
|
||||||
|
def __init__(self, event, seconds, macro):
|
||||||
|
threading.Thread.__init__(self)
|
||||||
|
self._event = event
|
||||||
|
self._seconds = seconds
|
||||||
|
self._macro = macro
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
while not self._event.wait(self._seconds):
|
||||||
|
Macro.call(self._macro)
|
||||||
|
info('\tTimer stopped... ')
|
||||||
|
return
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def exists(cls, name):
|
||||||
|
"""Validate in timer **name** exists
|
||||||
|
|
||||||
|
:param name: Timer name, it must be unique
|
||||||
|
:type name: str
|
||||||
|
:return: True if exists timer name
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
|
global _EVENTS
|
||||||
|
return name in _EVENTS
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def start(cls, name: str, seconds: float, macro: dict):
|
||||||
|
"""Start timer **name** every **seconds** and execute **macro**
|
||||||
|
|
||||||
|
:param name: Timer name, it must be unique
|
||||||
|
:type name: str
|
||||||
|
:param seconds: Seconds for wait
|
||||||
|
:type seconds: float
|
||||||
|
:param macro: Macro for execute
|
||||||
|
:type macro: dict
|
||||||
|
"""
|
||||||
|
global _EVENTS
|
||||||
|
|
||||||
|
_EVENTS[name] = threading.Event()
|
||||||
|
info(f"Timer '{name}' started, execute macro: '{macro['name']}'")
|
||||||
|
thread = cls.TimerThread(_EVENTS[name], seconds, macro)
|
||||||
|
thread.start()
|
||||||
|
return
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def stop(cls, name: str):
|
||||||
|
"""Stop timer **name**
|
||||||
|
|
||||||
|
:param name: Timer name
|
||||||
|
:type name: str
|
||||||
|
"""
|
||||||
|
global _EVENTS
|
||||||
|
_EVENTS[name].set()
|
||||||
|
del _EVENTS[name]
|
||||||
|
return
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def once(cls, name: str, seconds: float, macro: dict):
|
||||||
|
"""Start timer **name** only once in **seconds** and execute **macro**
|
||||||
|
|
||||||
|
:param name: Timer name, it must be unique
|
||||||
|
:type name: str
|
||||||
|
:param seconds: Seconds for wait before execute macro
|
||||||
|
:type seconds: float
|
||||||
|
:param macro: Macro for execute
|
||||||
|
:type macro: dict
|
||||||
|
"""
|
||||||
|
global _EVENTS
|
||||||
|
|
||||||
|
_EVENTS[name] = threading.Timer(seconds, Macro.call, (macro,))
|
||||||
|
_EVENTS[name].start()
|
||||||
|
info(f'Event: "{name}", started... execute in {seconds} seconds')
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def cancel(cls, name: str):
|
||||||
|
"""Cancel timer **name** only once events.
|
||||||
|
|
||||||
|
:param name: Timer name, it must be unique
|
||||||
|
:type name: str
|
||||||
|
"""
|
||||||
|
global _EVENTS
|
||||||
|
|
||||||
|
if name in _EVENTS:
|
||||||
|
try:
|
||||||
|
_EVENTS[name].cancel()
|
||||||
|
del _EVENTS[name]
|
||||||
|
info(f'Cancel event: "{name}", ok...')
|
||||||
|
except Exception as e:
|
||||||
|
error(e)
|
||||||
|
else:
|
||||||
|
debug(f'Cancel event: "{name}", not exists...')
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
class Hash(object):
|
||||||
|
"""Class for hash
|
||||||
|
"""
|
||||||
|
@classmethod
|
||||||
|
def digest(cls, method: str, data: str, in_hex: bool=True):
|
||||||
|
"""Get digest from data with method
|
||||||
|
|
||||||
|
:param method: Digest method: md5, sha1, sha256, sha512, etc...
|
||||||
|
:type method: str
|
||||||
|
:param data: Data for get digest
|
||||||
|
:type data: str
|
||||||
|
:param in_hex: If True, get digest in hexadecimal, if False, get bytes
|
||||||
|
:type in_hex: bool
|
||||||
|
:return: bytes or hex digest
|
||||||
|
:rtype: bytes or str
|
||||||
|
"""
|
||||||
|
|
||||||
|
result = ''
|
||||||
|
obj = getattr(hashlib, method)(data.encode())
|
||||||
|
if in_hex:
|
||||||
|
result = obj.hexdigest()
|
||||||
|
else:
|
||||||
|
result = obj.digest()
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class Paths(object):
|
||||||
|
"""Class for paths
|
||||||
|
"""
|
||||||
|
FILE_PICKER = 'com.sun.star.ui.dialogs.FilePicker'
|
||||||
|
FOLDER_PICKER = 'com.sun.star.ui.dialogs.FolderPicker'
|
||||||
|
REMOTE_FILE_PICKER = 'com.sun.star.ui.dialogs.RemoteFilePicker'
|
||||||
|
OFFICE_FILE_PICKER = 'com.sun.star.ui.dialogs.OfficeFilePicker'
|
||||||
|
|
||||||
|
def __init__(self, path=''):
|
||||||
|
if path.startswith('file://'):
|
||||||
|
path = str(Path(uno.fileUrlToSystemPath(path)).resolve())
|
||||||
|
self._path = Path(path)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def path(self):
|
||||||
|
"""Get base path"""
|
||||||
|
return str(self._path.parent)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def file_name(self):
|
||||||
|
"""Get file name"""
|
||||||
|
return self._path.name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
"""Get name"""
|
||||||
|
return self._path.stem
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ext(self):
|
||||||
|
"""Get extension"""
|
||||||
|
return self._path.suffix[1:]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def size(self):
|
||||||
|
"""Get size"""
|
||||||
|
return self._path.stat().st_size
|
||||||
|
|
||||||
|
@property
|
||||||
|
def url(self):
|
||||||
|
"""Get like URL"""
|
||||||
|
return self._path.as_uri()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def info(self):
|
||||||
|
"""Get all info like tuple"""
|
||||||
|
i = (self.path, self.file_name, self.name, self.ext, self.size, self.url)
|
||||||
|
return i
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dict(self):
|
||||||
|
"""Get all info like dict"""
|
||||||
|
data = {
|
||||||
|
'path': self.path,
|
||||||
|
'file_name': self.file_name,
|
||||||
|
'name': self.name,
|
||||||
|
'ext': self.ext,
|
||||||
|
'size': self.size,
|
||||||
|
'url': self.url,
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
|
||||||
|
@_classproperty
|
||||||
|
def home(self):
|
||||||
|
"""Get user home"""
|
||||||
|
return str(Path.home())
|
||||||
|
|
||||||
|
@_classproperty
|
||||||
|
def documents(self):
|
||||||
|
"""Get user save documents"""
|
||||||
|
return self.config()
|
||||||
|
|
||||||
|
@_classproperty
|
||||||
|
def temp_dir(self):
|
||||||
|
"""Get temporary directory in system"""
|
||||||
|
return tempfile.gettempdir()
|
||||||
|
|
||||||
|
@_classproperty
|
||||||
|
def python(self):
|
||||||
|
"""Get path executable python"""
|
||||||
|
if IS_WIN:
|
||||||
|
path = self.join(self.config('Module'), PYTHON)
|
||||||
|
elif IS_MAC:
|
||||||
|
path = self.join(self.config('Module'), '..', 'Resources', PYTHON)
|
||||||
|
else:
|
||||||
|
path = sys.executable
|
||||||
|
return path
|
||||||
|
|
||||||
|
@_classproperty
|
||||||
|
def user_profile(self):
|
||||||
|
"""Get path user profile"""
|
||||||
|
path = self.config('UserConfig')
|
||||||
|
path = str(Path(path).parent)
|
||||||
|
return path
|
||||||
|
|
||||||
|
@_classproperty
|
||||||
|
def user_config(self):
|
||||||
|
"""Get path config in user profile"""
|
||||||
|
path = self.config('UserConfig')
|
||||||
|
return path
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def to_system(cls, path:str) -> str:
|
||||||
|
"""Convert paths in URL to system
|
||||||
|
|
||||||
|
:param path: Path to convert
|
||||||
|
:type path: str
|
||||||
|
:return: Path system format
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
if path.startswith('file://'):
|
||||||
|
path = str(Path(uno.fileUrlToSystemPath(path)).resolve())
|
||||||
|
return path
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def to_url(cls, path: str) -> str:
|
||||||
|
"""Convert paths in format system to URL
|
||||||
|
|
||||||
|
:param path: Path to convert
|
||||||
|
:type path: str
|
||||||
|
:return: Path in URL
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
if not path.startswith('file://'):
|
||||||
|
path = Path(path).as_uri()
|
||||||
|
return path
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def config(cls, name: str='Work') -> str:
|
||||||
|
"""Return path from config
|
||||||
|
|
||||||
|
:param name: Name in service PathSettings, default get path documents
|
||||||
|
:type name: str
|
||||||
|
:return: Path in config, if exists.
|
||||||
|
:rtype: str
|
||||||
|
|
||||||
|
`See Api XPathSettings <http://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1util_1_1XPathSettings.html>`_
|
||||||
|
"""
|
||||||
|
path = create_instance('com.sun.star.util.PathSettings')
|
||||||
|
path = cls.to_system(getattr(path, name))
|
||||||
|
return path
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def join(cls, *paths: str) -> str:
|
||||||
|
"""Join paths
|
||||||
|
|
||||||
|
:param paths: Paths to join
|
||||||
|
:type paths: list
|
||||||
|
:return: New path with joins
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
path = str(Path(paths[0]).joinpath(*paths[1:]))
|
||||||
|
return path
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def exists(cls, path: str) -> bool:
|
||||||
|
"""If exists path
|
||||||
|
|
||||||
|
:param path: Path for validate
|
||||||
|
:type path: str
|
||||||
|
:return: True if path exists, False if not.
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
|
path = cls.to_system(path)
|
||||||
|
result = Path(path).exists()
|
||||||
|
return result
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def exists_app(cls, name_app: str) -> bool:
|
||||||
|
"""If exists app in system
|
||||||
|
|
||||||
|
:param name_app: Name of application
|
||||||
|
:type name_app: str
|
||||||
|
:return: True if app exists, False if not.
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
|
result = bool(shutil.which(name_app))
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(name):
|
def __getattr__(name):
|
||||||
classes = {
|
classes = {
|
||||||
'dates': Dates,
|
'dates': Dates,
|
||||||
'json': Json,
|
'json': Json,
|
||||||
'macro': Macro,
|
'macro': Macro,
|
||||||
|
'shell': Shell,
|
||||||
|
'timer': Timer,
|
||||||
|
'hash': Hash,
|
||||||
|
'path': Paths,
|
||||||
}
|
}
|
||||||
if name in classes:
|
if name in classes:
|
||||||
return classes[name]
|
return classes[name]
|
||||||
|
|
Loading…
Reference in New Issue