summaryrefslogtreecommitdiffhomepage
path: root/gui/scripts/integrate-into-app.py
blob: 86eeff63fbc25086ca4de03d160fb79473b6f060 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/env python3

"""
A helper script to integrate the generated geo data into the app.
"""

import os
from os import path
from subprocess import Popen, PIPE
import shutil
import colorful as c

SCRIPT_DIR = path.dirname(path.realpath(__file__))

# The name of the relay locations gettext catalogue template file
RELAY_LOCATIONS_POT_FILENAME = "relay-locations.pot"

# The directory with the generated content
GENERATED_CONTENT_OUTPUT_PATH = path.join(SCRIPT_DIR, "out")

# The directory with the generated localizations content
GENERATED_TRANSLATIONS_PATH = path.join(GENERATED_CONTENT_OUTPUT_PATH, "locales")

# The directory with the app's geo assets
APP_GEO_ASSETS_PATH = path.realpath(path.join(SCRIPT_DIR, "../assets/geo"))

# The directory with the existing app localizations
APP_TRANSLATIONS_PATH = path.realpath(path.join(SCRIPT_DIR, "../locales"))

# Geo assets for copying from generated content folder into the app folder
GEO_ASSETS_TO_COPY = [
  "geometry.json",
  "geometry.rbush.json",
  "states-provinces-lines.json",
  "states-provinces-lines.rbush.json",
]

# The filenames of gettext catalogues that should be merged using msgcat
TRANSLATIONS_TO_MERGE = [
  "relay-locations.po"
]


def copy_geo_assets():
  for f in GEO_ASSETS_TO_COPY:
    src = path.join(GENERATED_CONTENT_OUTPUT_PATH, f)
    dst = path.join(APP_GEO_ASSETS_PATH, f)

    print("Copying {} to {}".format(src, dst))

    shutil.copyfile(src, dst)


def merge_relay_locations_catalogue_template():
  existing_pot_file = path.join(APP_TRANSLATIONS_PATH, RELAY_LOCATIONS_POT_FILENAME)
  generated_pot_file = path.join(GENERATED_TRANSLATIONS_PATH, RELAY_LOCATIONS_POT_FILENAME)

  merge_gettext_catalogues(existing_pot_file, generated_pot_file)


def copy_and_merge_translations():
  for f in os.listdir(GENERATED_TRANSLATIONS_PATH):
    src = path.join(GENERATED_TRANSLATIONS_PATH, f)
    dst = path.join(APP_TRANSLATIONS_PATH, f)

    if path.isdir(src):
      merge_single_locale_folder(src, dst)


def merge_single_locale_folder(src, dst):
  for f in os.listdir(src):
    src_po = path.join(src, f)
    dst_po = path.join(dst, f)

    if f in TRANSLATIONS_TO_MERGE:
      # merge ../locales/*/file.po with ./out/locales/*/file.po
      # use existing translation to resolve conflicts
      merge_gettext_catalogues(dst_po, src_po)
    else:
      print(c.orange("Unexpected file: {}".format(src_po)))


def merge_gettext_catalogues(existing_catalogue_file, generated_catalogue_file):
  if path.exists(existing_catalogue_file):
    args = (
      existing_catalogue_file, generated_catalogue_file,

      "--output-file", existing_catalogue_file,

      # ensure that the first occurence takes precedence in merge conflict
      "--use-first",

      # sort by msgid
      "--sort-output",

      # disable wrapping long strings because crowdin does not do that
      "--no-wrap"
    )

    (exit_code, errors) = run_program("msgcat", *args)

    if exit_code == 0:
      print(c.green("Merged {} into {}.".format(generated_catalogue_file, existing_catalogue_file)))
    else:
      print(c.red("msgcat exited with {}: {}".format(exit_code, errors.decode().strip())))
  else:
    print(c.orange("The existing catalogue does not exist. Copying {} to {}")
      .format(generated_catalogue_file, existing_catalogue_file))
    shutil.copyfile(generated_catalogue_file, existing_catalogue_file)


def run_program(*args):
  with Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE) as subproc:
    print("Run: {}".format(' '.join(args)))

    errors = subproc.communicate()[1]
    return (subproc.returncode, errors)


# Program main()

def main():
  if not path.exists(APP_GEO_ASSETS_PATH):
    os.makedirs(APP_GEO_ASSETS_PATH)

  copy_geo_assets()
  merge_relay_locations_catalogue_template()
  copy_and_merge_translations()

main()