diff --git a/i-form-data-repository/Dockerfile b/i-form-data-repository/Dockerfile index 1720b4f..4689448 100644 --- a/i-form-data-repository/Dockerfile +++ b/i-form-data-repository/Dockerfile @@ -39,9 +39,12 @@ RUN if [ "$INSTALL_LOCAL_WHEELS" = "true" ]; then \ fi ENV WEBPACKEXT_PROJECT="invenio_assets.webpack:rspack_project" +COPY patch_js_translations.py /opt/invenio/src/patch_js_translations.py RUN cp -r ./static/. ${INVENIO_INSTANCE_PATH}/static/ && \ cp -r ./assets/. ${INVENIO_INSTANCE_PATH}/assets/ && \ uv run invenio collect --verbose && \ + uv run invenio i18n js-translation build --all-packages && \ + uv run python patch_js_translations.py && \ npm config set legacy-peer-deps true && \ uv run invenio webpack buildall diff --git a/i-form-data-repository/docker/nginx/conf.d/default.conf b/i-form-data-repository/docker/nginx/conf.d/default.conf index ceb36ed..17825d8 100644 --- a/i-form-data-repository/docker/nginx/conf.d/default.conf +++ b/i-form-data-repository/docker/nginx/conf.d/default.conf @@ -15,12 +15,19 @@ server { return 301 https://$host$request_uri; } +# Upstream servers +upstream ui_server { + server web-ui:5000; +} +upstream api_server { + server web-api:5000; +} + # HTTPS server server { listen 443 default_server ssl http2; # IPv4 listen [::]:443 default_server ssl http2; # IPv6 server_name _; - resolver 10.89.1.1 valid=10s ipv6=off; charset utf-8; keepalive_timeout 5; @@ -52,11 +59,10 @@ server { # in case of chunked transfer encoding proxy_http_version 1.1; - # Proxying to the application server +# Proxying to the application server ## UI server location / { - set $ui_upstream web-ui:5000; - uwsgi_pass web-ui:5053; + uwsgi_pass ui_server; include uwsgi_params; uwsgi_buffering off; uwsgi_request_buffering off; @@ -75,8 +81,7 @@ server { } ## Most API location /api { - set $api_upstream web-api:5000; - uwsgi_pass web-api:5000; + uwsgi_pass api_server; include uwsgi_params; uwsgi_buffering off; uwsgi_request_buffering off; @@ -99,8 +104,7 @@ server { # request bodies. This includes part content uploads of multipart file uploads. location ~ /api/records/.+/draft/files/.+/content(/[0-9]+)?/?$ { gzip off; - set $api_upstream web-api:5000; - uwsgi_pass web-api:5000; + uwsgi_pass api_server; include uwsgi_params; uwsgi_buffering off; uwsgi_request_buffering off; diff --git a/i-form-data-repository/invenio.cfg b/i-form-data-repository/invenio.cfg index f7a4a33..70b2795 100644 --- a/i-form-data-repository/invenio.cfg +++ b/i-form-data-repository/invenio.cfg @@ -98,8 +98,7 @@ BABEL_DEFAULT_TIMEZONE = 'Europe/Zurich' # Other supported languages (do not include BABEL_DEFAULT_LOCALE in list). I18N_LANGUAGES = [ - # ('de', _('German')), - # ('tr', _('Turkish')), + ('ga', _('Irish')), ] diff --git a/i-form-data-repository/patch_js_translations.py b/i-form-data-repository/patch_js_translations.py new file mode 100644 index 0000000..4a84061 --- /dev/null +++ b/i-form-data-repository/patch_js_translations.py @@ -0,0 +1,104 @@ +import glob +import os +import shutil +import json + +def main(): + # 1. Ensure ga directories exist and have translations.json + packages = [ + 'invenio_communities', + 'invenio_search_ui', + 'invenio_app_rdm', + 'invenio_requests', + 'invenio_jobs', + 'invenio_rdm_records', + 'invenio_administration' + ] + bases = [ + '/opt/invenio/src/.venv/lib/python3.12/site-packages', + '/opt/invenio/var/instance/assets/translations' + ] + for pkg in packages: + for base in bases: + for root, dirs, files_in_dir in os.walk(base): + if root.endswith('messages') and pkg in root: + ga_dir = os.path.join(root, 'ga') + os.makedirs(ga_dir, exist_ok=True) + json_path = os.path.join(ga_dir, 'translations.json') + if not os.path.exists(json_path) or os.path.getsize(json_path) <= 2: + with open(json_path, 'w') as fp: + fp.write('{}') + print(f"Created empty translations.json: {json_path}") + + # 2. Copy the actual compiled translations if they exist + copies = [ + ( + '/opt/invenio/src/.venv/lib/python3.12/site-packages/invenio_communities/assets/semantic-ui/translations/invenio_communities/messages/ga/translations.json', + '/opt/invenio/var/instance/assets/translations/invenio_communities/messages/ga/translations.json' + ), + ( + '/opt/invenio/src/.venv/lib/python3.12/site-packages/invenio_search_ui/assets/semantic-ui/translations/invenio_search_ui/messages/ga/translations.json', + '/opt/invenio/var/instance/assets/translations/invenio_search_ui/messages/ga/translations.json' + ) + ] + for src, dst in copies: + if os.path.exists(src): + os.makedirs(os.path.dirname(dst), exist_ok=True) + shutil.copy2(src, dst) + print(f"Copied compiled translations: {src} -> {dst}") + + # 3. Extract app_rdm translations from global ga.json + global_ga = '/opt/invenio/var/instance/translations/ga.json' + app_rdm_dst = '/opt/invenio/var/instance/assets/translations/invenio_app_rdm/messages/ga/translations.json' + if os.path.exists(global_ga): + try: + with open(global_ga, 'r') as fp: + ga_data = json.load(fp) + app_rdm_data = ga_data.get('invenio_app_rdm', {}) + os.makedirs(os.path.dirname(app_rdm_dst), exist_ok=True) + with open(app_rdm_dst, 'w') as fp: + json.dump(app_rdm_data, fp, indent=2) + print(f"Extracted invenio_app_rdm translations to {app_rdm_dst}") + + # Also extract search_ui and communities if they were not copied + search_ui_dst = '/opt/invenio/var/instance/assets/translations/invenio_search_ui/messages/ga/translations.json' + if 'invenio_search_ui' in ga_data: + os.makedirs(os.path.dirname(search_ui_dst), exist_ok=True) + with open(search_ui_dst, 'w') as fp: + json.dump(ga_data['invenio_search_ui'], fp, indent=2) + print(f"Extracted invenio_search_ui translations to {search_ui_dst}") + + communities_dst = '/opt/invenio/var/instance/assets/translations/invenio_communities/messages/ga/translations.json' + if 'invenio_communities' in ga_data: + os.makedirs(os.path.dirname(communities_dst), exist_ok=True) + with open(communities_dst, 'w') as fp: + json.dump(ga_data['invenio_communities'], fp, indent=2) + print(f"Extracted invenio_communities translations to {communities_dst}") + except Exception as e: + print(f"Error extracting translations: {e}") + + # 4. Patch all _generatedTranslations.js files + files = glob.glob('/opt/invenio/src/.venv/lib/python3.12/site-packages/**/_generatedTranslations.js', recursive=True) + glob.glob('/opt/invenio/var/instance/assets/**/_generatedTranslations.js', recursive=True) + for f in files: + with open(f, 'r') as fp: + content = fp.read() + if 'TRANSLATE_GA' not in content: + lines = content.split('\n') + last_import = -1 + for i, line in enumerate(lines): + if line.startswith('import '): + last_import = i + if last_import != -1: + lines.insert(last_import + 1, 'import TRANSLATE_GA from "./ga/translations.json";') + content = '\n'.join(lines) + if 'export const translations = {' in content: + content = content.replace( + 'export const translations = {', + 'export const translations = {\n ga: { translation: TRANSLATE_GA },' + ) + with open(f, 'w') as fp: + fp.write(content) + print(f"Patched _generatedTranslations.js: {f}") + +if __name__ == '__main__': + main() diff --git a/i-form-data-repository/translations/ga.json b/i-form-data-repository/translations/ga.json new file mode 100644 index 0000000..a6878ba --- /dev/null +++ b/i-form-data-repository/translations/ga.json @@ -0,0 +1,23 @@ +{ + "invenio_search_ui": { + "invenio_search_ui:Search records...": "Cuardaigh taifid..." + }, + "invenio_communities": { + "invenio_communities:You are not a member of any community.": "Níl tú mar bhall d'aon phobal.", + "invenio_communities:There are no new communities.": "Níl aon phobail nua ann.", + "invenio_communities:My Communities": "Mo Phobail", + "invenio_communities:New Communities": "Pobail Nua", + "invenio_communities:Search communities...": "Cuardaigh pobail...", + "invenio_communities:Organize, curate and share your research. Ideal for research projects, departments or temporary working groups.": "Eagraigh, coimeád agus comhroinn do chuid taighde. Ideal do thionscadail taighde, ranna nó grúpaí oibre sealadacha." + }, + "invenio_app_rdm": { + "invenio_app_rdm:Search records...": "Cuardaigh taifid...", + "invenio_app_rdm:Search in my communities": "Cuardaigh i mo phobail", + "invenio_app_rdm:Search in my communities...": "Cuardaigh i mo phobail...", + "invenio_app_rdm:My communities": "Mo phobail", + "invenio_app_rdm:Search in my uploads...": "Cuardaigh i mo chuid uaslódálacha...", + "invenio_app_rdm:My uploads": "Mo chuid uaslódálacha", + "invenio_app_rdm:Overview": "Foramharc", + "invenio_app_rdm:Uploads": "Uaslódálacha" + } +} diff --git a/justfile b/justfile index eb8a948..002ecdb 100644 --- a/justfile +++ b/justfile @@ -93,16 +93,16 @@ test-local: mkdir -p i-form-data-repository/local_wheels rm -f i-form-data-repository/local_wheels/*.whl - (cd ../invenio-theme-iform && rm -rf dist && uvx --from build pyproject-build -w) + (cd ../invenio-theme-iform && rm -rf dist && uv run pybabel compile -d invenio_theme_iform/translations && uvx --from build pyproject-build -w) cp ../invenio-theme-iform/dist/*.whl i-form-data-repository/local_wheels/ - (cd ../invenio-config-iform && rm -rf dist && uvx --from build pyproject-build -w) + (cd ../invenio-config-iform && rm -rf dist && uv run pybabel compile -d invenio_config_iform/translations && uvx --from build pyproject-build -w) cp ../invenio-config-iform/dist/*.whl i-form-data-repository/local_wheels/ echo "Rebuilding and restarting local docker stack..." cd i-form-data-repository - docker compose -f docker-compose.full.yml --env-file ../.env build --build-arg INSTALL_LOCAL_WHEELS=true + docker compose -f docker-compose.full.yml --env-file ../.env down + docker compose -f docker-compose.full.yml --env-file ../.env build --no-cache --build-arg INSTALL_LOCAL_WHEELS=true docker compose -f docker-compose.full.yml --env-file ../.env up -d --wait - docker compose -f docker-compose.full.yml --env-file ../.env restart frontend docker compose -f docker-compose.full.yml --env-file ../.env exec worker bash -c "invenio db init || true; invenio db create || true; invenio alembic upgrade || true; invenio index init || true" curl -skI https://127.0.0.1:8443/ || echo "HTTPS verification failed"