Skip to content

Commit

Permalink
Merge pull request #348 from jeanslack/locale_features
Browse files Browse the repository at this point in the history
Locale features
  • Loading branch information
jeanslack authored Jul 15, 2024
2 parents ec48353 + d4961c6 commit 92fbbac
Show file tree
Hide file tree
Showing 37 changed files with 28,855 additions and 27,301 deletions.
16 changes: 15 additions & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,26 @@ License: GPL3
Change Log:

+------------------------------------+
Sat, 06 July 2024 V.5.0.17
Mon, 15 July 2024 V.5.0.17

* Created new gettext utilities.
* Italian translation completed thanks to @bovirus .
* Improved AUTHORS and traslation list on about dialog.
* Enabling the Queue button on any panel if a queue is set up.
* Create `generate_MO_file.sh` script.
* Improved `gettext_utils` scripts.
* Provide a Hatch Build Hook to compile catalogs when building wheels.
* All MO files have been removed as they will be compiled when building
packages.
* Added `babel` as a new dependency needed for compiling language catalogs
when building binaries.
* Added compile MO files option before build standalone App using pyinstaller.
* Fixed accelerators shortcuts on Italian language catalog (leave same as
English language).
* Added a new Python script that includes some functionality based on the
babel program, convenient on operating systems that do not have gettext
installed.
* Fixed `app_const` not listing the es_CU locale code language.

+------------------------------------+
Wed, 03 July 2024 V.5.0.16
Expand Down
18 changes: 16 additions & 2 deletions debian/changelog
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,22 @@ videomass (5.0.17-1) UNRELEASED; urgency=medium
* Italian translation completed thanks to @bovirus .
* Improved AUTHORS and traslation list on about dialog.
* Enabling the Queue button on any panel if a queue is set up.

-- Gianluca Pernigotto <[email protected]> Sat, 06 Jul 2024 12:00:00 +0200
* Create `generate_MO_file.sh` script.
* Improved `gettext_utils` scripts.
* Provide a Hatch Build Hook to compile catalogs when building wheels.
* All MO files have been removed as they will be compiled when building
packages.
* Added `babel` as a new dependency needed for compiling language catalogs
when building binaries.
* Added compile MO files option before build standalone App using pyinstaller.
* Fixed accelerators shortcuts on Italian language catalog (leave same as
English language).
* Added a new Python script that includes some functionality based on the
babel program, convenient on operating systems that do not have gettext
installed.
* Fixed `app_const` not listing the es_CU locale code language.

-- Gianluca Pernigotto <[email protected]> Mon, 15 Jul 2024 09:00:00 +0200

videomass (5.0.16-1) UNRELEASED; urgency=medium

Expand Down
1 change: 1 addition & 0 deletions debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Build-Depends: debhelper-compat (= 13),
dh-sequence-python3,
pybuild-plugin-pyproject,
python3-all,
python3-babel,
python3-hatchling
Standards-Version: 4.1.4
Homepage: https://github.com/jeanslack/Videomass
Expand Down
318 changes: 318 additions & 0 deletions develop/gettext_utils/babelutils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,318 @@
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
""""
Copyleft (c) Videomass Development Team.
Distributed under the terms of the GPL3 License.
Rev: July.15.2024
Code checker: flake8, pylint
This file is part of Videomass.
Videomass 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.
Videomass 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 Videomass. If not, see <http://www.gnu.org/licenses/>.
"""

import os
import sys
import argparse
try:
from babel.messages.frontend import (compile_catalog,
extract_messages,
update_catalog,
init_catalog
)
except ModuleNotFoundError:
sys.exit('babel is required, please install babel (or python3-babel)')


def description():
"""
print description of the program
"""
descr = ('Encapsulates the main functionalities for managing '
'the translation message catalog based on babel.')

return descr


def long_description():
"""
print a long description of the program
"""
descr = ('Encapsulates the main functionalities for managing '
'the translation message catalog based on babel.\n\n'
'It provides the following main features:\n'
'- Extracts translation messages from the catalog and adds them '
'to a new POT file\n'
'- Automatically creates a new language catalog based on the '
'provided POT file and a locale code.\n'
'- Updates all existing PO files found on the given locale '
'directory based on a POT template file.\n'
'- Automatically compiles MO (Machine Object) files from all PO '
'(portable object) files found in the provided locale '
'directory.\n\nPlease note that these features are mutually '
'exclusive, use one at a time.\n')

return descr


def exit_from_prog(nameprogram):
"""
print message error and exit from program
"""
print(f"usage: {nameprogram} [-h] (--extract-msg | --new-catalog | "
f"--update-catalogs | --compile-catalogs)\n")
sys.exit(long_description())


def build_translation_catalog(nameprogram):
"""
Compile MO files for this macchine using babel.
"""
parser = argparse.ArgumentParser(prog=f'{nameprogram}',
description=description(),
add_help=True,
)
parser.add_argument('--compile-catalogs',
help=("Compile recursively MO (Machine Object) files "
"for this macchine."),
action="store_true",
required=True,
)
parser.add_argument("-o", "--output-dir",
action="store",
dest="locale_directory",
help=("Absolute or relative destination path to "
"locale directory."),
required=True
)
parser.add_argument("-d", "--domain",
action="store",
dest="domain_name",
help=("The name given to the domain of the PO file "
"of any catalogs"),
required=True,
)
args = parser.parse_args()
try:
cmd = compile_catalog()
cmd.directory = args.locale_directory
cmd.domain = args.domain_name
cmd.statistics = True
cmd.finalize_options()
cmd.run()
except Exception as err:
return err

return None


def create_pot_file(nameprogram):
"""
Extract messages from the catalog, similarly to what
the GNU gettext program does.
"""
here = os.getcwd()
parser = argparse.ArgumentParser(prog=f'{nameprogram}',
description=description(),
add_help=True,
)

parser.add_argument('--extract-msg',
help=("Extracts messages from the catalog and adds "
"them to a new POT file."),
action="store_true",
required=True
)
parser.add_argument("-o", "--output-dir",
action="store",
dest="locale_directory",
help=("Absolute or relative destination path to "
"locale directory."),
required=True
)
parser.add_argument("-d", "--domain",
action="store",
dest="domain_name",
help=("The name you want to give to the domain, "
"usually coincides with the name of your app "
"or the existing PO/POT file (in lowercase)."),
required=True,
)
parser.add_argument("-p", "--package-dir",
action="store",
dest="python_package_dir",
help=("Absolute or relative destination path to "
"the Python modules/package dir to extract "
"recursively all messages from *.py files."),
required=True,
# default='../../'
)
args = parser.parse_args()
makeabs_locdir = os.path.abspath(args.locale_directory)
makeabs_pydir = os.path.abspath(args.python_package_dir)
os.chdir(args.locale_directory)
pydir = os.path.relpath(makeabs_pydir)
try:
cmd = extract_messages()
cmd.input_dirs = pydir # path to Pytohn package
cmd.output_file = os.path.join(makeabs_locdir,
args.domain_name.lower() + ".pot")
cmd.no_wrap = True
cmd.finalize_options()
cmd.run()
except Exception as err:
os.chdir(here)
return err
os.chdir(here)
return None


def update_po_files(nameprogram):
"""
Updates all existing translations catalogs based on a
PO template file (POT), basically equivalent to the GNU
msgmerge program.
"""
parser = argparse.ArgumentParser(prog=f'{nameprogram}',
description=description(),
add_help=True,
)
parser.add_argument('--update-catalogs',
help=("Updates all existing translations catalogs "
"found on the given locale directory based on "
"a POT template file."),
action="store_true",
required=True,
)
parser.add_argument("-o", "--output-dir",
action="store",
dest="locale_directory",
help=("Absolute or relative destination path to "
"locale directory."),
required=True
)
parser.add_argument("-d", "--domain",
action="store",
dest="domain_name",
help=("The name given to the domain of the PO file "
"of any catalogs."),
required=True,
)
parser.add_argument("-f", "--pot-file",
action="store",
dest="pot_file",
help=("POT filename location."),
required=True
)
args = parser.parse_args()
try:
cmd = update_catalog()
cmd.input_file = args.pot_file
cmd.domain = args.domain_name
cmd.output_dir = args.locale_directory
cmd.no_wrap = True
cmd.no_fuzzy_matching = True
cmd.finalize_options()
cmd.run()
except Exception as err:
return err

return None


def init_new_catalog(nameprogram):
"""
Basically equivalent to the GNU msginit program: it creates
a new translation catalog based on a PO template file (POT).
"""
parser = argparse.ArgumentParser(prog=f'{nameprogram}',
description=description(),
add_help=True,
)
parser.add_argument('--new-catalog',
help=("It creates a new translation catalog based on "
"a POT template file."),
action="store_true",
required=True
)
parser.add_argument("-o", "--output-dir",
action="store",
dest="locale_directory",
help=("Absolute or relative destination path to "
"locale directory."),
required=True
)
parser.add_argument("-d", "--domain",
action="store",
dest="domain_name",
help=("The name you want to give to the domain, "
"usually coincides with the name of your app "
"or the POT file (in lowercase)"),
required=True,
)
parser.add_argument("-l", "--locale",
action="store",
dest="locale_code",
help=("Enter name of new locale code you want to "
"add, e.g 'de_DE' for German language."),
required=True,
)
args = parser.parse_args()
try:
cmd = init_catalog()
cmd.domain = args.domain.lower()
cmd.locale = args.locale_code
cmd.input_file = os.path.join(args.locale_directory,
args.domain.lower() + ".pot")
cmd.output_dir = args.locale_directory
cmd.finalize_options()
cmd.run()
except Exception as err:
return err

return None


if __name__ == '__main__':
prgname = os.path.basename(__file__)
mode = ('--new-catalog', '--extract-msg',
'--update-catalogs', '--compile-catalogs')
arg = sys.argv
appendact = [a for a in sys.argv if a in mode]
status = None

if not appendact:
exit_from_prog(prgname)

if len(appendact) > 1:
print(f"{prgname}: error: the following arguments "
f"are mutually exclusive: {mode}")
exit_from_prog(prgname)

if appendact[0] == "--new-catalog":
status = init_new_catalog(prgname)

elif appendact[0] == "--extract-msg":
status = create_pot_file(prgname)

elif appendact[0] == "--update-catalogs":
status = update_po_files(prgname)

elif appendact[0] == "--compile-catalogs":
status = build_translation_catalog(prgname)

if status:
print(f"\033[31;1mERROR:\033[0m babel: {status}")
else:
print("\033[32;1mCOMPLETED SUCCESSFULLY!\033[0m")
Loading

0 comments on commit 92fbbac

Please sign in to comment.