diff --git a/Dockerfile b/Dockerfile index 05fd51f..e76f22a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -39,7 +39,7 @@ RUN apt-get update && \ rm -rf /var/lib/apt/lists/* ARG DATA_PATH=/var/lib/outline/data ARG USER=nodejs -RUN useradd -U ${USER} && \ +RUN useradd -m -U ${USER} && \ mkdir -p ${DATA_PATH} && \ chown -R ${USER}:${USER} ${APP_PATH} ${DATA_PATH}/.. && \ chmod 1777 ${DATA_PATH} diff --git a/outline b/outline index 4e2612d..8ab0c6f 160000 --- a/outline +++ b/outline @@ -1 +1 @@ -Subproject commit 4e2612d263e287c7feae94d456624d5e6def2f46 +Subproject commit 8ab0c6ff484f02b5d97e130b20376a17dd4546cc diff --git a/tools/diff.py b/tools/diff.py index d9d6ac9..64c4eb3 100755 --- a/tools/diff.py +++ b/tools/diff.py @@ -3,17 +3,17 @@ import json import os -def workdir(path): +def resolve(path): basepath = os.path.abspath(os.path.dirname(__file__)) abspath = os.path.abspath(basepath + '/' + path) return abspath -en_json_path = workdir('../outline/shared/i18n/locales/en_US/translation.json') -ru_json_path = workdir('./translation.json') +en_json_path = resolve('../outline/shared/i18n/locales/en_US/translation.json') +ru_json_path = resolve('./translation.json') -out_json_name = 'translation_merged.json' -out_json_path = workdir(f'./{out_json_name}') +out_json_name = 'translation.tmp.json' +out_json_path = resolve(out_json_name) translated_lines = {} untranslated_lines = {} @@ -28,15 +28,23 @@ with open(ru_json_path) as target: for key, value in en_json.items(): if key in ru_json.keys(): translated_lines[key] = ru_json[key] + elif key in en_json.keys() and f'{key}_plural' in en_json.keys(): + for i in range(0, 3): + plural = f'{key}_{i}' + if plural in ru_json.keys(): + translated_lines[plural] = ru_json[plural] + elif key.endswith('_plural'): + if key.replace('_plural', '_0') in ru_json.keys(): + pass + else: + untranslated_lines[key] = en_json[key] else: untranslated_lines[key] = en_json[key] - for key, value in ru_json.items(): if key == value: exception_lines[key] = value - out_json = {**translated_lines, **untranslated_lines} if (exception_lines): diff --git a/tools/translation.json b/tools/translation.json index e54dddb..4fe7c7b 100644 --- a/tools/translation.json +++ b/tools/translation.json @@ -57,6 +57,8 @@ "Download document": "Скачать документ", "Copy as Markdown": "Скопировать как Markdown", "Markdown copied to clipboard": "Markdown скопирован в буфер", + "Copy as text": "Скопировать как текст", + "Text copied to clipboard": "Текст скопирован в буфер", "Copy public link": "Скопировать публичную ссылку", "Link copied to clipboard": "Ссылка скопирована в буфер", "Copy link": "Скопировать ссылку", @@ -168,8 +170,6 @@ "Deleting": "Удаление", "Are you sure about that? Deleting the {{collectionName}} collection is permanent and cannot be restored, however all published documents within will be moved to the trash.": "Вы уверены, что? Удаление коллекции {{collectionName}} является безвозвратным и не может быть восстановлено, однако все опубликованные в ней документы будут перемещены в корзину.", "Also, {{collectionName}} is being used as the start view – deleting it will reset the start view to the Home page.": "Кроме того, {{collectionName}} используется в качестве начального экрана — его удаление приведет к сбросу начального экрана на главную.", - "Sorry, an error occurred saving the collection": "Произошла ошибка при сохранении коллекции", - "Add a description": "Добавить описание", "Type a command or search": "Введите команду или выполните поиск", "Choose a template": "Выберите шаблон", "Are you sure you want to permanently delete this entire comment thread?": "Вы уверены, что хотите НАВСЕГДА удалить эту ветку комментариев?", @@ -309,6 +309,7 @@ "Unknown": "Неизвестно", "Mark all as read": "Отметить все как прочитанное", "You're all caught up": "Вы в теме", + "Published": "Опубликовано", "{{ username }} reacted with {{ emoji }}": "{{ username }} оставил реакцию {{ emoji }}", "{{ firstUsername }} and {{ secondUsername }} reacted with {{ emoji }}": "{{ firstUsername }} и {{ secondUsername }} оставили реакцию {{ emoji }}", "{{ firstUsername }} and {{ count }} others reacted with {{ emoji }}_0": "{{ firstUsername }} и {{ count }} других оставили реакцию {{ emoji }}", @@ -403,7 +404,6 @@ "Star document": "Добавить документ в избранное", "Template created, go ahead and customize it": "Шаблон создан, теперь вы можете перейти к нему и продолжить настройку", "Creating a template from {{titleWithDefault}} is a non-destructive action – we'll make a copy of the document and turn it into a template that can be used as a starting point for new documents.": "Создание шаблона из {{titleWithDefault}} не уничтожит ваш документ — мы сделаем копию и превратим ее в шаблон, который можно будет использовать в качестве отправной точки для новых документов.", - "Published": "Опубликовано", "Enable other members to use the template immediately": "Разрешить другим участникам немедленно использовать шаблон", "Location": "Расположение", "Admins can manage the workspace and access billing.": "Администраторы могут управлять рабочим пространством и имеют доступ к биллингу.", @@ -519,15 +519,14 @@ "Unsubscribed from document": "Отписаться от документа", "Unsubscribed from collection": "Отменена подписка на коллекцию", "Account": "Аккаунт", - "API Keys": "Ключи API", "Details": "Подробности", "Security": "Безопасность", "Features": "Функции", "Members": "Участники", "Groups": "Группы", + "API Keys": "Ключи API", "Shared Links": "Общие ссылки", "Import": "Импорт", - "Self Hosted": "Прочее", "Integrations": "Интеграции", "Revoke token": "Отозвать токен", "Revoke": "Отозвать", @@ -553,12 +552,13 @@ "Delete group": "Удалить группу", "Group options": "Параметры группы", "Cancel": "Отменить", - "Import menu options": "Import menu options", + "Import menu options": "Импорт опций меню", "Member options": "Параметры участников", "New document in {{ collectionName }}": "Новый документ в {{ collectionName }}", "New child document": "Новый вложенный документ", "Save in workspace": "Сохранить в рабочем пространстве", "Notification settings": "Настройки уведомлений", + "Revoking": "Отзыв", "Revision options": "Настройка версии", "Share link revoked": "Ссылка общего доступа отозвана", "Share link copied": "Ссылка общего доступа скопирована", @@ -616,6 +616,8 @@ "{{ groupsCount }} groups with access_1": "{{ groupsCount }} группы с доступом", "{{ groupsCount }} groups with access_2": "{{ groupsCount }} групп с доступом", "Archived by {{userName}}": "Архивировано {{userName}}", + "Sorry, an error occurred saving the collection": "Произошла ошибка при сохранении коллекции", + "Add a description": "Добавить описание", "Share": "Поделиться", "Overview": "Обзор", "Recently updated": "Недавно обновлено", @@ -867,7 +869,6 @@ "Restricted scope": "Ограниченная область видимости", "API key copied to clipboard": "Ключ API скопирован в буфер", "Copied": "Скопировано", - "Revoking": "Отзыв", "Are you sure you want to revoke the {{ tokenName }} token?": "Вы уверены, что хотите отозвать токен {{ tokenName }}?", "Disconnect integration": "Отключить интеграцию", "Connected": "Подключено", @@ -914,7 +915,7 @@ "No people matching your search": "Нет людей, соответствующих вашему запросу", "No people left to add": "Не осталось людей для добавления", "Date created": "Дата создания", - "Upload": "Загрузить", + "Uploading": "Идёт загрузка", "How does this work?": "Как это работает?", "You can import a zip file that was previously exported from the JSON option in another instance. In {{ appName }}, open Export in the Settings sidebar and click on Export Data.": "Вы можете импортировать ZIP-архив, который ранее был экспортирован с помощью параметра JSON, в другой инстанс. В {{ appName }} откройте Экспорт на боковой панели настроек и нажмите Экспорт данных.", "Drag and drop the zip file from the JSON export option in {{appName}}, or click to upload": "Перетащите ZIP-архив из параметра экспорта JSON в {{appName}} или нажмите, чтобы загрузить", @@ -928,6 +929,7 @@ "{{ count }} document imported_2": "{{ count }} документов импортировано", "You can import a zip file that was previously exported from an Outline installation – collections, documents, and images will be imported. In Outline, open Export in the Settings sidebar and click on Export Data.": "Вы можете импортировать ZIP-архив, который ранее был экспортирован из Outline — коллекции, документы и изображения будут импортированы. В Outline откройте Экспорт на боковой панели настроек и нажмите Экспортировать данные.", "Drag and drop the zip file from the Markdown export option in {{appName}}, or click to upload": "Перетащите ZIP-архив из параметра экспорта Markdown в {{appName}} или нажмите, чтобы загрузить", + "Connect": "Подключить", "Last active": "Последняя активность", "Guest": "Гость", "Shared by": "Поделился", @@ -1014,8 +1016,6 @@ "Unsubscription successful. Your notification settings were updated": "Вы успешно отписались. Ваши настройки уведомлений обновлены", "Manage when and where you receive email notifications.": "Управляйте, когда и где вы будете получать уведомления на почту.", "The email integration is currently disabled. Please set the associated environment variables and restart the server to enable notifications.": "Интеграция с почтой в настоящее время отключена. Установите соответствующие переменные среды и перезапустите сервер, чтобы включить уведомления.", - "Create personal API keys to authenticate with the API and programatically control\n your workspace's data. API keys have the same permissions as your user account.\n For more details see the developer documentation.": "Создавайте ключи API для аутентификации с помощью API и программируемого управления\n данными вашего рабочего пространства. Ключи API имеют те же разрешения, что и ваш аккаунт пользователя.\n Более подробную информацию смотрите в документации разработчика.", - "Personal keys": "Персональные ключи", "Preferences saved": "Настройки сохранены", "Delete account": "Удалить аккаунт", "Manage settings that affect your personal experience.": "Настройте параметры, которые влияют на ваш пользовательский опыт.", @@ -1065,10 +1065,6 @@ "Allow editors to create new collections within the workspace": "Разрешить редакторам создавать новые коллекции в рабочем пространстве.", "Workspace creation": "Создание рабочего пространства", "Allow editors to create new workspaces": "Разрешить редакторам создавать рабочие пространства", - "Draw.io deployment": "draw.io", - "Add your self-hosted draw.io installation url here to enable automatic embedding of diagrams within documents.": "Укажите здесь URL-адрес вашего инстанса draw.io.", - "Grist deployment": "Grist", - "Add your self-hosted grist installation URL here.": "Укажите здесь URL-адрес вашего инстанса Grist.", "Could not load shares": "Не удалось загрузить поделённое", "Sharing is currently disabled.": "В настоящий момент общий доступ отключен.", "You can globally enable and disable public document sharing in the security settings.": "Вы можете глобально включить и отключить общий доступ к документам в настройках безопасности.", @@ -1076,7 +1072,6 @@ "You can create templates to help your team create consistent and accurate documentation.": "Вы можете создать шаблоны, чтобы помочь своей команде привести документацию к одному виду.", "Alphabetical": "По алфавиту", "There are no templates just yet.": "Не создано ни одного шаблона.", - "Zapier is a platform that allows {{appName}} to easily integrate with thousands of other business tools. Automate your workflows, sync data, and more.": "Zapier — это платформа, которая позволяет {{appName}} легко интегрироваться с тысячью других бизнес-инструментов. Автоматизируйте рабочие процессы, синхронизируйте данные и многое другое.", "A confirmation code has been sent to your email address, please enter the code below to permanently destroy this workspace.": "Код подтверждения был отправлен на ваш адрес почты. Пожалуйста, введите код ниже, чтобы навсегда уничтожить это рабочее пространство.", "Confirmation code": "Код подтверждения", "Deleting the <1>{{workspaceName}} workspace will destroy all collections, documents, users, and associated data. You will be immediately logged out of {{appName}}.": "Удаление рабочего пространства <1>{{workspaceName}} приведет к уничтожению всех коллекций, документов, пользователей и связанных данных. Вы немедленно выйдете из приложения {{appName}}.", @@ -1102,7 +1097,6 @@ "Expires today": "Истёк сегодня", "Expires tomorrow": "Истечёт завтра", "Expires {{ date }}": "Истечёт {{ date }}", - "Connect": "Подключить", "Whoops, you need to accept the permissions in GitHub to connect {{appName}} to your workspace. Try again?": "Вам нужно принять разрешения в GitHub, чтобы подключить {{appName}} к вашему рабочему пространству. Попробуйте еще раз?", "Something went wrong while authenticating your request. Please try logging in again.": "Что-то пошло не так во время обработки вашего запроса. Пожалуйста, попробуйте войти еще раз.", "The owner of GitHub account has been requested to install the {{githubAppName}} GitHub app. Once approved, previews will be shown for respective links.": "Владельцу аккаунта GitHub было предложено установить приложение GitHub {{githubAppName}}. Предпросмотр будет доступен для соответствующих ссылок после одобрения.", @@ -1169,6 +1163,7 @@ "Webhooks can be used to notify your application when events happen in {{appName}}. Events are sent as a https request with a JSON payload in near real-time.": "Вебхуки можно использовать для уведомления вашего приложения о событиях, происходящих в {{appName}}. События отправляются в виде HTTP-запроса с полезной JSON-нагрузкой практически в реальном времени.", "Inactive": "Неактивно", "Create a webhook": "Создать вебхук", + "Zapier is a platform that allows {{appName}} to easily integrate with thousands of other business tools. Automate your workflows, sync data, and more.": "Zapier — это платформа, которая позволяет {{appName}} легко интегрироваться с тысячью других бизнес-инструментов. Автоматизируйте рабочие процессы, синхронизируйте данные и многое другое.", "Never logged in": "Никогда не входил", "Online now": "Сейчас в сети", "Online {{ timeAgo }}": "В сети {{ timeAgo }}", @@ -1177,7 +1172,84 @@ "{{ user }} updated {{ timeAgo }}": "{{ user }} обновлен {{ timeAgo }}", "You created {{ timeAgo }}": "Вы создали {{ timeAgo }}", "{{ user }} created {{ timeAgo }}": "{{ user }} создан {{ timeAgo }}", - "Uploading": "Идёт загрузка", - "Copy as text": "Скопировать как текст", - "Text copied to clipboard": "Текст скопирован в буфер" + "New App": "Новое приложение", + "New Application": "Новое приложение", + "Icon": "Иконка", + "My App": "Мое приложение", + "Tagline": "Слоган", + "A short description": "Краткое описание", + "Callback URLs": "URL обратного вызова", + "Allow this app to be installed by other workspaces": "Разрешить установку этого приложения другими рабочими пространствами", + "Mention": "Упоминание", + "API & Apps": "API и приложения", + "Applications": "Приложения", + "Install": "Установить", + "Revoke {{ appName }}": "Отозвать доступ {{ appName }}", + "Are you sure you want to revoke access?": "Вы уверены, что хотите отозвать доступ?", + "Delete app": "Удалить приложение", + "Choose a workspace": "Выберите рабочее пространство", + "Choose an {{ appName }} workspace or login to continue connecting this app": "Выберите рабочее пространство {{ appName }} или войдите для подключения этого приложения", + "An error occurred": "Произошла ошибка", + "The OAuth client could not be found, please check the provided client ID": "OAuth-клиент не найден, проверьте указанный идентификатор клиента", + "The OAuth client could not be loaded, please check the redirect URI is valid": "Не удалось загрузить OAuth-клиент, проверьте правильность URI перенаправления", + "Required OAuth parameters are missing": "Отсутствуют обязательные параметры OAuth", + "Authorize": "Авторизовать", + "{{ appName }} wants to access {{ teamName }}": "{{ appName }} запрашивает доступ к {{ teamName }}", + "By {{ developerName }}": "От {{ developerName }}", + "{{ appName }} will be able to access your account and perform the following actions": "{{ appName }} сможет получить доступ к вашей учетной записи и выполнять следующие действия", + "read": "чтение", + "write": "запись", + "read and write": "чтение и запись", + "API keys": "API-ключи", + "attachments": "вложения", + "collections": "коллекции", + "comments": "комментарии", + "documents": "документы", + "events": "события", + "groups": "группы", + "integrations": "интеграции", + "notifications": "уведомления", + "reactions": "реакции", + "pins": "закрепленные", + "shares": "общие доступы", + "users": "пользователи", + "teams": "команды", + "workspace": "рабочее пространство", + "Read all data": "Чтение всех данных", + "Write all data": "Запись всех данных", + "Create personal API keys to authenticate with the API and programatically control\n your workspace's data. For more details see the developer documentation.": "Создавайте персональные API-ключи для аутентификации через API и программного управления\n данными вашего рабочего пространства. Подробности см. в документации для разработчиков.", + "{t(\"API keys have been disabled by an admin for your account\")}": "{t(\"API-ключи были отключены администратором для вашей учетной записи\")}", + "API keys have been disabled by an admin for your account": "API-ключи были отключены администратором для вашей учетной записи", + "Application access": "Доступ приложений", + "Manage which third-party and internal applications have been granted access to your {{ appName }} account.": "Управляйте сторонними и внутренними приложениями, получившими доступ к вашей учетной записи {{ appName }}.", + "Application published": "Приложение опубликовано", + "Application updated": "Приложение обновлено", + "Client secret rotated": "Секретный ключ клиента обновлен", + "Rotate secret": "Обновить секретный ключ", + "Rotating the client secret will invalidate the current secret. Make sure to update any applications using these credentials.": "Обновление секретного ключа клиента аннулирует текущий ключ. Обязательно обновите все приложения, использующие эти учетные данные.", + "Displayed to users when authorizing": "Отображается пользователям при авторизации", + "Developer information shown to users when authorizing": "Информация о разработчике, показываемая пользователям при авторизации", + "Developer name": "Имя разработчика", + "Developer URL": "URL разработчика", + "Allow users from other workspaces to authorize this app": "Разрешить пользователям из других рабочих пространств авторизовать это приложение", + "Credentials": "Учетные данные", + "OAuth client ID": "Идентификатор OAuth-клиента", + "The public identifier for this app": "Публичный идентификатор для этого приложения", + "OAuth client secret": "Секретный ключ OAuth-клиента", + "Store this value securely, do not expose it publicly": "Храните это значение в безопасности, не раскрывайте его публично", + "Where users are redirected after authorizing this app": "Куда перенаправляются пользователи после авторизации этого приложения", + "Authorization URL": "URL авторизации", + "Where users are redirected to authorize this app": "Куда перенаправляются пользователи для авторизации этого приложения", + "Applications allow you to build internal or public integrations with Outline and provide secure access via OAuth. For more details see the developer documentation.": "Приложения позволяют создавать внутренние или публичные интеграции с Outline и обеспечивать безопасный доступ через OAuth. Подробности см. в документации для разработчиков.", + "Crop Image": "Обрезать изображение", + "Crop image": "Обрезать изображение", + "Configure": "Настроить", + "Never used": "Никогда не использовалось", + "Are you sure you want to delete the {{ appName }} application? This cannot be undone.": "Вы уверены, что хотите удалить приложение {{ appName }}? Это действие нельзя отменить.", + "Configure a variety of integrations with third-party services.": "Настройте различные интеграции со сторонними сервисами.", + "Whoops, you need to accept the permissions in Linear to connect {{appName}} to your workspace. Try again?": "Упс, вам нужно принять разрешения в Linear, чтобы подключить {{appName}} к вашему рабочему пространству. Попробовать снова?", + "Enable previews of Linear issues in documents by connecting a Linear workspace to {appName}.": "Включите предпросмотр задач Linear в документах, подключив рабочее пространство Linear к {appName}.", + "Disconnecting will prevent previewing Linear links from this workspace in documents. Are you sure?": "Отключение предотвратит предпросмотр ссылок Linear из этого рабочего пространства в документах. Вы уверены?", + "The Linear integration is currently disabled. Please set the associated environment variables and restart the server to enable the integration.": "Интеграция с Linear в данный момент отключена. Пожалуйста, установите соответствующие переменные окружения и перезапустите сервер, чтобы включить интеграцию.", + "Error loading data": "Ошибка загрузки данных" }