#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""This module collects utilities for installing and building message catalogs
while applying Univention specific options.
"""
#
# Copyright 2016-2022 Univention GmbH
#
# https://www.univention.de/
#
# All rights reserved.
#
# The source code of this program is made available
# under the terms of the GNU Affero General Public License version 3
# (GNU AGPL V3) as published by the Free Software Foundation.
#
# Binary versions of this program provided by Univention to you as
# well as other copyrighted, protected or trademarked materials like
# Logos, graphics, fonts, specific documentations and configurations,
# cryptographic keys etc. are subject to a license agreement between
# you and Univention and not subject to the GNU AGPL V3.
#
# In the case you use this program under the terms of the GNU AGPL V3,
# the program is provided 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License with the Debian GNU/Linux or Univention distribution in file
# /usr/share/common-licenses/AGPL-3; if not, see
# <https://www.gnu.org/licenses/>.
import polib
import os
from .helper import Error, call, make_parent_dir
try:
from typing import Any, List, Union # noqa: F401
except ImportError:
pass
def _clean_header(po_path):
# type: (str) -> None
pof = polib.pofile(po_path)
pof.header = ""
pof.metadata.update({
u'Content-Type': u'text/plain; charset=utf-8',
})
pof.metadata_is_fuzzy = None
pof.save(po_path)
[docs]def concatenate_po(src_po_path, dest_po_path):
# type: (str, str) -> None
"""
Append first to second `.po` file.
:param src_po_path: File to merge.
:param dest_po_path: File to merge into.
"""
call(
'msgcat',
'--unique',
'--output', dest_po_path,
src_po_path,
dest_po_path,
)
_clean_header(dest_po_path)
[docs]def create_empty_po(binary_pkg_name, new_po_path):
# type: (str, str) -> None
"""
Create a new empty `.po` file.
:param binary_pkg_name: Package name.
:param new_po_path: File name for new file.
"""
make_parent_dir(new_po_path)
call(
'xgettext',
'--force-po',
'--add-comments=i18n',
'--from-code=UTF-8',
'--sort-output',
'--package-name={}'.format(binary_pkg_name),
'--msgid-bugs-address=packages@univention.de',
'--copyright-holder=Univention GmbH',
# Suppress warning about /dev/null being an unknown source type
'--language', 'C',
'-o', new_po_path,
'/dev/null')
_clean_header(new_po_path)
[docs]def merge_po(template, translation):
# type: (str, str) -> None
"""
Merge old translation with new template file.
:param template: New template `.pot` file.
:param translation: Old translation `.po` file.
"""
call(
'msgmerge',
'--update',
'--sort-output',
'--backup=off',
translation,
template)
[docs]def join_existing(language, output_file, input_files, cwd=os.getcwd()):
# type: (str, str, Union[str, List[str]], str) -> None
"""
Extract strings from source code and merge into existing translation file.
:param language: Source code language, e.g. `JavaScript`, `Python`, `Shell`.
:param output_file: Template file name.
:param input_files: Sequence of input files.
:param cwd: Base directory used as new woring directory.
"""
if not os.path.isfile(output_file):
raise Error("Can't join input files into {}. File does not exist.".format(output_file))
if not isinstance(input_files, list):
input_files = [input_files]
# make input_files relative so the location lines in the resulting po
# will be relative to cwd
input_files = [os.path.relpath(p, start=cwd) for p in input_files]
call(
'xgettext',
'--from-code=UTF-8',
'--join-existing',
'--omit-header',
'--language', language,
'--keyword=N_:1',
'-o', output_file,
*input_files,
cwd=cwd)
[docs]def univention_location_lines(pot_path, abs_path_source_pkg):
# type: (str, str) -> None
"""
Convert absolute paths to relative paths.
:param pot_path: Path to :file:`.pot` file.
:param abs_path_source_pkg: Source package base path.
"""
po_file = polib.pofile(pot_path)
for entry in po_file:
entry.occurrences = [
((os.path.relpath(path, start=abs_path_source_pkg), linenum))
for path, linenum in entry.occurrences
]
po_file.save(pot_path)