Metadata-Version: 2.4
Name: hunayn
Version: 0.2.0
Summary: Command-line companion and quality checker for GNOME translators
Author: Ramal Rahimov
License-Expression: GPL-3.0-or-later
Project-URL: Homepage, https://gitlab.com/rehimovv/hunayn
Project-URL: Issues, https://gitlab.com/rehimovv/hunayn/-/issues
Keywords: gettext,po,translation,l10n,gnome,linter
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Localization
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Provides-Extra: keyring
Requires-Dist: keyring>=25; extra == "keyring"
Dynamic: license-file

# Hunayn

**A command-line companion and quality checker for GNOME translators.**

Hunayn helps translation teams around the world work with
[Damned Lies](https://l10n.gnome.org) from the terminal and catches
translation mistakes before they reach a release.

> **Status:** early development, but usable: `hunayn check` checks PO
> files, and `status`, `get`, `reserve` and `submit` work with Damned Lies.

## Why "Hunayn"?

The project is named after **Hunayn ibn Ishaq** (809–873), the most
celebrated translator of Baghdad's House of Wisdom. He was famous not only
for the amount he translated, but for his care: before translating a text,
he collected several manuscripts, compared them and corrected their errors.
Careful checking before publishing is exactly what this tool is about.

## Install

Hunayn needs Python 3.10 or newer and has no other dependencies:

```
pip install hunayn
```

To keep your Damned Lies API token in the system keyring (recommended for
`reserve` and `submit`), install the optional extra instead:

```
pip install "hunayn[keyring]"
```

## Working with Damned Lies

Reading needs no account:

```
hunayn status az                  # how complete is my team? every module, most work first
hunayn status az --todo           # only the modules with fuzzy or untranslated messages
hunayn status az nautilus         # one module
hunayn get nautilus az            # download the current PO file: nautilus.<branch>.az.po
hunayn get nautilus az --branch main
hunayn get --todo az -o todo/     # every file of the team that needs work
```

By default Hunayn uses the newest `gnome-N` release on Damned Lies, which
also decides the branch; `--release` and `--branch` choose others. `get`
never replaces an existing file unless you add `--force`; `get --todo`
skips the files you already have and ends with a summary, most fuzzy
messages first.

Writing needs your personal API token. Create one on your Damned Lies
profile page, then save it once:

```
hunayn login
```

The token is stored in the system keyring (with `hunayn[keyring]`), or
read from the `HUNAYN_DL_TOKEN` environment variable (for CI), or asked for
each time. It is never written to a file, never accepted on the command
line, and never shown. `hunayn logout` removes it.

```
hunayn reserve nautilus az --branch main
hunayn submit nautilus.main.az.po --comment "Fixed the last fuzzy strings"
hunayn submit nautilus.main.az.po --dry-run    # every step except the upload
```

Both tell your team's mailing list, so Hunayn checks the workflow state
first and asks before acting (`--yes` skips the question). `submit` takes
the module, branch and language from the file name that `get` writes, or
from `--module`, `--lang`, `--branch` and `--domain`. Before uploading it:

- checks the file like `hunayn check`, and **uploads nothing while there
  are errors**; a false alarm can be silenced for one rule (`--ignore`) or
  one message (`# hunayn: ignore=<rule>`);
- compares the file's plural rule with your language's rule on Damned
  Lies (a warning only);
- refuses a file whose `Language` header names another team;
- warns when the file is based on an older template than the one on
  Damned Lies.

Proofreading, "ready for submission" and the final commit stay in the
Damned Lies web interface; `submit` ends with a link to the page.

Every command has `--format json` for scripts, and `--server` for another
Damned Lies instance (Hunayn then names that server at the top of its
output). Hunayn is gentle with the server: it caches answers as long as
the server allows and never sends more than four requests at a time. The
design is described in
[ADR 0004](https://gitlab.com/rehimovv/hunayn/-/blob/main/docs/adr/0004-talking-to-damned-lies.md).

## Checking PO files

```
hunayn check az.po                     # report problems, exit 1 on errors
hunayn check po/*.po --format json     # for CI
hunayn check --ignore accelerator az.po
hunayn check --list-rules
```

Exit status: `0` no errors (warnings are allowed), `1` errors found (or
any finding with `--strict`), `2` Hunayn could not run (a file is
missing, an unknown rule was named).

Fuzzy messages are not checked unless you add `--include-fuzzy`. To
silence a rule for one message, add a translator comment:

```
# hunayn: ignore=accelerator
msgid "_Open"
msgstr "Aç"
```

The checks cover:

- broken or missing placeholders (`%s`, `%1$d`, `%(name)s`, `{name}`)
- broken or changed markup (`<b>…</b>`, Mallard help tags and links)
- missing, empty or unreadable plural forms
- lost keyboard accelerators (`_File`)

The rules, how each one was measured, and what they report are described
in [docs/rules.md](https://gitlab.com/rehimovv/hunayn/-/blob/main/docs/rules.md).
Still to come: terminology that does not match your team's glossary.

## Built for every language

The core knows nothing about any single language. Each team will describe
its own conventions (quotation marks, accelerator style, punctuation,
glossary) in a small data file, kept in a shared
[language repository](https://gitlab.com/rehimovv/hunayn#language-data) where every team maintains its own
folder.

## Language data

Coming soon: a separate `hunayn-languages` repository with one folder per
language code (`az/`, `fr/`, `pt_BR/` …). Hunayn will download the latest
data when it runs and keep a local copy for offline use. A team can also
point Hunayn at a glossary in its own repository.

## Roadmap

| Phase | Goal | State |
|-------|------|-------|
| 0 | Preparation: API notes, test corpus, local Damned Lies instance | done |
| 1 | Our own PO parser and writer (byte-identical round trip) | done |
| 2 | Sentinel: first checks (placeholders, tags, plurals) | done (0.1.1) |
| 3 | Damned Lies client: status, get, reserve, submit | done (0.2.0) |
| 4 | Language packs, glossary checks, CI templates → 1.0 | |

## Contributing

Contributions are welcome. See
[CONTRIBUTING.md](https://gitlab.com/rehimovv/hunayn/-/blob/main/CONTRIBUTING.md).
This project follows the
[GNOME Code of Conduct](https://conduct.gnome.org).

Write commands are never tried against l10n.gnome.org during
development; `tools/local-dl` builds a local Damned Lies for that (see its
[README](https://gitlab.com/rehimovv/hunayn/-/blob/main/tools/local-dl/README.md)).

## License

Hunayn is free software, licensed under the
[GNU General Public License v3.0 or later](https://gitlab.com/rehimovv/hunayn/-/blob/main/LICENSE).
