Skip to content

Commit

Permalink
Restructured code to support human language translation.
Browse files Browse the repository at this point in the history
Also added Intel graphics dialog to display sequence  #245
  • Loading branch information
mliberty1 committed Mar 5, 2024
1 parent 3547464 commit 2c0f080
Show file tree
Hide file tree
Showing 43 changed files with 1,927 additions and 1,773 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/packaging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,16 @@ jobs:
run: |
python -VV
python -m pip install --upgrade pip
python -m pip install build wheel pytest
python -m pip install build wheel pytest babel polib
- name: Copy files to patch build
run: |
cp CHANGELOG.md joulescope_ui/
cp CREDITS.html joulescope_ui/
- name: Update translations
run: python ci/translations.py

- name: Update tokens using GitHub secrets
env:
JOULESCOPE_UI_REPORTER_TOKEN: ${{ secrets.JOULESCOPE_UI_REPORTER_TOKEN }}
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ This file contains the list of changes made to pyjoulescope_ui.
2024 Feb 28 [in progress]

* Added plugin framework with live code reload #14
* Restructured code to support human language translation.
* Added Intel graphics dialog to display sequence #245


## 1.0.59
Expand Down
2 changes: 1 addition & 1 deletion CREDITS.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

<body>
<p>The Joulescope User Interface is
Copyright (c) 2017-2023 Jetperch LLC and licensed under the permissive
Copyright (c) 2017-2024 Jetperch LLC and licensed under the permissive
<a href="https://github.com/jetperch/pyjoulescope_ui/blob/main/LICENSE.txt">
Apache 2.0 License</a>.</p>

Expand Down
68 changes: 68 additions & 0 deletions ci/translations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Copyright 2024 Jetperch LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


# pip install babel polib

from babel.messages.frontend import CommandLineInterface
import polib
import os
import re
import sys


_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
_PO_FILE = os.path.join(_PATH, 'joulescope_ui', 'locale', 'joulescope_ui.pot')
_whitespace = r'\s+'


with open(os.path.join(_PATH, 'joulescope_ui', 'version.py'), 'rt') as f:
__version__ = f.readline().split('=')[1].strip()[1:-1]


def run_babel():
os.chdir(os.path.join(_PATH, 'joulescope_ui'))
babel_args = [
sys.argv[0],
'extract',
'--no-default-keywords',
'--keywords=N_',
'--copyright-holder=Jetperch LLC',
f'--version={__version__}',
f"--input-dirs=.",
f"--output-file={_PO_FILE}",
]
rv = CommandLineInterface().run(babel_args)
if rv not in [None, 0]:
raise RuntimeError(f'BABEL failed with {rv}')


def _msgid_process(txt):
txt = txt.strip()
txt = re.sub(_whitespace, ' ', txt)
return txt


def run_po_patch():
print('Update POT msgid entries')
pofile = polib.pofile(_PO_FILE)
for entry in pofile:
entry.msgid = _msgid_process(entry.msgid)
pofile.save(_PO_FILE)
return 0


if __name__ == '__main__':
run_babel()
run_po_patch()
38 changes: 38 additions & 0 deletions docs/locale.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@

# Locale

The Joulescope UI supports translations.


## Adding text

When adding text, use US English. Surround all translatable text using
the "N_" function. You can use any string format, including multi-line
strings. However, all newlines will be removed from the contained text.

To create paragraphs, use the "P_" function, which takes a list of
strings already surrounded by the "N_" function.


## Process

To update the POT file:

```
pip install babel polib
python ci/translations.py
```



## References

* https://docs.python.org/3/library/gettext.html
* https://www.gnu.org/software/gettext/manual/gettext.html
* https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html
* https://www.mattlayman.com/blog/2015/i18n/
* https://babel.pocoo.org/
* https://app.transifex.com/ - Too expensive for our needs
* https://phrase.com/blog/posts/i18n-advantages-babel-python/
* https://poedit.net/
* https://www.deepl.com/translator
4 changes: 2 additions & 2 deletions joulescope.iss
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "Joulescope"
#define MyAppVersion "1.0.59"
#define MyAppVersionUnderscores "1_0_59"
#define MyAppVersion "1.1.0"
#define MyAppVersionUnderscores "1_1_0"
#define MyAppPublisher "Jetperch LLC"
#define MyAppURL "https://www.joulescope.com"
#define MyAppExeName "joulescope.exe"
Expand Down
10 changes: 9 additions & 1 deletion joulescope_ui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,18 @@
'time64',
'PUBSUB_TOPICS', 'REGISTRY_MANAGER_TOPICS',
'tooltip_format',
'CAPABILITIES', 'Metadata', 'N_',
'N_', 'PARAGRAPH_SEPARATOR', 'P_',
'CAPABILITIES', 'Metadata',
'get_instance', 'get_topic_name', 'get_unique_id']


PARAGRAPH_SEPARATOR = '\n\n'


def P_(text_list):
return PARAGRAPH_SEPARATOR.join(text_list)


def _pubsub_factory() -> PubSub:
"""Generate and configure the singleton pubsub instance."""
p = PubSub(skip_core_undo=True)
Expand Down
53 changes: 21 additions & 32 deletions joulescope_ui/about.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2018-2023 Jetperch LLC
# Copyright 2018-2024 Jetperch LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -14,36 +14,36 @@


from joulescope_ui import __version__ as ui_version
from joulescope_ui import N_
from pyjoulescope_driver import __version__ as jsdrv_version
from pyjls import __version__ as jls_version
import platform
import sys


_HEADER = """\
<html>
<head>
<title>About the Joulescope UI</title>
{style}
</head>
"""


_FOOTER = '</html>'
_TITLE = N_('About the Joulescope UI')
_VERSIONS = N_('Version Information')


_ABOUT = """\
ABOUT = f"""\
<html><head>
<title>{_TITLE}</title>
{{style}}
</head>
<body>
Joulescope UI version {ui_version}<br/>
Joulescope driver version {jsdrv_version}<br/>
JLS version {jls_version}<br/>
Python {sys_version}<br/>
Platform {platform}<br/>
Processor {processor}<br/>
<a href="https://www.joulescope.com">https://www.joulescope.com</a>
<p><a href="https://www.joulescope.com">https://www.joulescope.com</a></p>
<p>{_VERSIONS}:</p>
<table>
<tr><td>UI</td><td>{ui_version}</td></tr>
<tr><td>driver</td><td>{jsdrv_version}</td></tr>
<tr><td>JLS</td><td>{jls_version}</td></tr>
<tr><td>Python</td><td>{sys.version}</td></tr>
<tr><td>Platform</td><td>{platform.platform()}</td></tr>
<tr><td>Processor</td><td>{platform.processor()}</td></tr>
</table>
<pre>
Copyright 2018-2023 Jetperch LLC
Copyright 2018-2024 Jetperch LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -58,16 +58,5 @@
limitations under the License.
</pre>
</body>
</html>
"""


def load():
txt = _ABOUT.format(
ui_version=ui_version,
jsdrv_version=jsdrv_version,
jls_version=jls_version,
sys_version=sys.version,
platform=platform.platform(),
processor=platform.processor(),
)
return _HEADER + txt + _FOOTER

0 comments on commit 2c0f080

Please sign in to comment.