From 2cda66dd0b89c9295194b8a8db8308d4985f9827 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Tue, 6 Aug 2024 12:39:26 -0400 Subject: [PATCH 01/74] Add human readable errors for config.json post --- .../web/routes/api/crafty/config/index.py | 58 ++++++++++--------- app/translations/en_EN.json | 6 +- 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/app/classes/web/routes/api/crafty/config/index.py b/app/classes/web/routes/api/crafty/config/index.py index d625d339..fe33f161 100644 --- a/app/classes/web/routes/api/crafty/config/index.py +++ b/app/classes/web/routes/api/crafty/config/index.py @@ -9,29 +9,27 @@ from app.classes.web.base_api_handler import BaseApiHandler config_json_schema = { "type": "object", "properties": { - "https_port": {"type": "integer"}, - "language": { - "type": "string", - }, - "cookie_expire": {"type": "integer"}, - "show_errors": {"type": "boolean"}, - "history_max_age": {"type": "integer"}, - "stats_update_frequency_seconds": {"type": "integer"}, - "delete_default_json": {"type": "boolean"}, - "show_contribute_link": {"type": "boolean"}, - "virtual_terminal_lines": {"type": "integer"}, - "max_log_lines": {"type": "integer"}, - "max_audit_entries": {"type": "integer"}, - "disabled_language_files": {"type": "array"}, - "stream_size_GB": {"type": "integer"}, - "keywords": {"type": "array"}, - "allow_nsfw_profile_pictures": {"type": "boolean"}, - "enable_user_self_delete": {"type": "boolean"}, - "reset_secrets_on_next_boot": {"type": "boolean"}, - "monitored_mounts": {"type": "array"}, - "dir_size_poll_freq_minutes": {"type": "integer"}, - "crafty_logs_delete_after_days": {"type": "integer"}, - "big_bucket_repo": {"type": "string"}, + "https_port": {"type": "integer", "error": "typeInteger"}, + "language": {"type": "string", "error": "typeString"}, + "cookie_expire": {"type": "integer", "error": "typeInteger"}, + "show_errors": {"type": "boolean", "error": "typeBool"}, + "history_max_age": {"type": "integer", "error": "typeInteger"}, + "stats_update_frequency_seconds": {"type": "integer", "error": "typeInteger"}, + "delete_default_json": {"type": "boolean", "error": "typeBool"}, + "show_contribute_link": {"type": "boolean", "error": "typeBool"}, + "virtual_terminal_lines": {"type": "integer", "error": "typeInteger"}, + "max_log_lines": {"type": "integer", "error": "typeInteger"}, + "max_audit_entries": {"type": "integer", "error": "typeInteger"}, + "disabled_language_files": {"type": "array", "error": "typeList"}, + "stream_size_GB": {"type": "integer", "error": "typeInteger"}, + "keywords": {"type": "array", "error": "typeList"}, + "allow_nsfw_profile_pictures": {"type": "boolean", "error": "typeBool"}, + "enable_user_self_delete": {"type": "boolean", "error": "typeBool"}, + "reset_secrets_on_next_boot": {"type": "boolean", "error": "typeBool"}, + "monitored_mounts": {"type": "array", "error": "typeList"}, + "dir_size_poll_freq_minutes": {"type": "integer", "error": "typeInteger"}, + "crafty_logs_delete_after_days": {"type": "integer", "error": "typeInteger"}, + "big_bucket_repo": {"type": "string", "error": "typeString"}, }, "additionalProperties": False, "minProperties": 1, @@ -39,8 +37,8 @@ config_json_schema = { customize_json_schema = { "type": "object", "properties": { - "photo": {"type": "string"}, - "opacity": {"type": "string"}, + "photo": {"type": "string", "error": "typeString"}, + "opacity": {"type": "string", "error": "typeString"}, }, "additionalProperties": False, "minProperties": 1, @@ -49,7 +47,7 @@ customize_json_schema = { photo_delete_schema = { "type": "object", "properties": { - "photo": {"type": "string"}, + "photo": {"type": "string", "error": "typeString"}, }, "additionalProperties": False, "minProperties": 1, @@ -110,12 +108,18 @@ class ApiCraftyConfigIndexHandler(BaseApiHandler): try: validate(data, config_json_schema) except ValidationError as e: + offending_key = e.path[0] if e.path else None + err = f"""{self.translator.translate( + "validators", + e.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {offending_key}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) diff --git a/app/translations/en_EN.json b/app/translations/en_EN.json index ed35ae9c..0562c0a0 100644 --- a/app/translations/en_EN.json +++ b/app/translations/en_EN.json @@ -668,6 +668,10 @@ "uses": "Number of uses allowed (-1==No Limit)" }, "validators": { + "typeBool": "Type error: True or False required for ", + "typeInteger": "Type error: Integer required for ", + "typeList": "Type error: List required for ", + "typeString": "Type error: String required for ", "passLength": "Password Too Short. Minimum Length: 8" }, "webhooks": { @@ -695,4 +699,4 @@ "webhook_body": "Webhook Body", "webhooks": "Webhooks" } -} +} \ No newline at end of file From 53bf5a07308fa778c1ad51ce141e79c440acd256 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Tue, 6 Aug 2024 12:40:39 -0400 Subject: [PATCH 02/74] Use why instead of e --- app/classes/web/routes/api/crafty/config/index.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/classes/web/routes/api/crafty/config/index.py b/app/classes/web/routes/api/crafty/config/index.py index fe33f161..85379316 100644 --- a/app/classes/web/routes/api/crafty/config/index.py +++ b/app/classes/web/routes/api/crafty/config/index.py @@ -100,18 +100,19 @@ class ApiCraftyConfigIndexHandler(BaseApiHandler): try: data = orjson.loads(self.request.body) - except orjson.JSONDecodeError as e: + except orjson.JSONDecodeError as why: return self.finish_json( - 400, {"status": "error", "error": "INVALID_JSON", "error_data": str(e)} + 400, + {"status": "error", "error": "INVALID_JSON", "error_data": str(why)}, ) try: validate(data, config_json_schema) - except ValidationError as e: - offending_key = e.path[0] if e.path else None + except ValidationError as why: + offending_key = why.path[0] if why.path else None err = f"""{self.translator.translate( "validators", - e.schema.get("error"), + why.schema.get("error"), self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), )} {offending_key}""" return self.finish_json( From 332f19c21251ee4286c12e90f50b0f87a79d4f59 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Tue, 6 Aug 2024 12:41:27 -0400 Subject: [PATCH 03/74] Use human readable errors for server_dir --- .../web/routes/api/crafty/config/server_dir.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/app/classes/web/routes/api/crafty/config/server_dir.py b/app/classes/web/routes/api/crafty/config/server_dir.py index bc88cba9..106964c3 100644 --- a/app/classes/web/routes/api/crafty/config/server_dir.py +++ b/app/classes/web/routes/api/crafty/config/server_dir.py @@ -6,7 +6,7 @@ from app.classes.web.base_api_handler import BaseApiHandler server_dir_schema = { "type": "object", "properties": { - "new_dir": {"type": "string"}, + "new_dir": {"type": "string", "error": "typeString"}, }, "additionalProperties": False, "minProperties": 1, @@ -70,20 +70,27 @@ class ApiCraftyConfigServerDirHandler(BaseApiHandler): try: data = orjson.loads(self.request.body) - except orjson.JSONDecodeError as e: + except orjson.JSONDecodeError as why: return self.finish_json( - 400, {"status": "error", "error": "INVALID_JSON", "error_data": str(e)} + 400, + {"status": "error", "error": "INVALID_JSON", "error_data": str(why)}, ) try: validate(data, server_dir_schema) - except ValidationError as e: + except ValidationError as why: + offending_key = why.path[0] if why.path else None + err = f"""{self.translator.translate( + "validators", + why.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {offending_key}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) if self.helper.dir_migration: From 7ae7c0f50d5cff27eb6a708bb15796bb793fe089 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Tue, 6 Aug 2024 12:55:07 -0400 Subject: [PATCH 04/74] Add human readable error for getting server files --- .../web/routes/api/crafty/imports/index.py | 22 ++++++++++++++----- app/translations/en_EN.json | 5 +++-- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/app/classes/web/routes/api/crafty/imports/index.py b/app/classes/web/routes/api/crafty/imports/index.py index 2aca2fa9..47b19b81 100644 --- a/app/classes/web/routes/api/crafty/imports/index.py +++ b/app/classes/web/routes/api/crafty/imports/index.py @@ -13,10 +13,14 @@ logger = logging.getLogger(__name__) files_get_schema = { "type": "object", "properties": { - "page": {"type": "string", "minLength": 1}, - "folder": {"type": "string"}, - "upload": {"type": "boolean", "default": "False"}, - "unzip": {"type": "boolean", "default": "True"}, + "page": { + "type": "string", + "minLength": 1, + "error": "filesPageLen", + }, + "folder": {"type": "string", "error": "typeString"}, + "upload": {"type": "boolean", "default": "False", "error": "typeBool"}, + "unzip": {"type": "boolean", "default": "True", "error": "typeBool"}, }, "additionalProperties": False, "minProperties": 1, @@ -47,13 +51,19 @@ class ApiImportFilesIndexHandler(BaseApiHandler): ) try: validate(data, files_get_schema) - except ValidationError as e: + except ValidationError as why: + offending_key = why.path[0] if why.path else None + err = f"""{self.translator.translate( + "validators", + why.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {offending_key}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) # TODO: limit some columns for specific permissions? diff --git a/app/translations/en_EN.json b/app/translations/en_EN.json index 0562c0a0..50ab88c5 100644 --- a/app/translations/en_EN.json +++ b/app/translations/en_EN.json @@ -668,11 +668,12 @@ "uses": "Number of uses allowed (-1==No Limit)" }, "validators": { + "filesPageLen": "Length must be greater than 1 for property ", + "passLength": "Password Too Short. Minimum Length: 8", "typeBool": "Type error: True or False required for ", "typeInteger": "Type error: Integer required for ", "typeList": "Type error: List required for ", - "typeString": "Type error: String required for ", - "passLength": "Password Too Short. Minimum Length: 8" + "typeString": "Type error: String required for " }, "webhooks": { "areYouSureDel": "Are you sure you want to delete this webhook?", From dcd81102faf4ffe7a50a69534aa7838434f7009e Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Tue, 6 Aug 2024 13:13:11 -0400 Subject: [PATCH 05/74] Use human readable errors for roles schema --- app/classes/web/routes/api/roles/index.py | 12 ++++++++++-- app/classes/web/routes/api/roles/role/index.py | 12 ++++++++++-- app/translations/en_EN.json | 4 ++++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/app/classes/web/routes/api/roles/index.py b/app/classes/web/routes/api/roles/index.py index 45a00bf0..69bbf4df 100644 --- a/app/classes/web/routes/api/roles/index.py +++ b/app/classes/web/routes/api/roles/index.py @@ -12,25 +12,29 @@ create_role_schema = { "type": "string", "minLength": 1, "pattern": r"^[^,\[\]]*$", + "error": "roleName", }, "servers": { "type": "array", + "error": "typeList", "items": { "type": "object", "properties": { "server_id": { "type": "string", "minimum": 1, + "error": "roleServerId", }, "permissions": { "type": "string", "pattern": r"^[01]{8}$", # 8 bits, see EnumPermissionsServer + "error": "roleServerPerms", }, }, "required": ["server_id", "permissions"], }, }, - "manager": {"type": ["integer", "null"]}, + "manager": {"type": ["integer", "null"], "error": "roleManager"}, }, "additionalProperties": False, "minProperties": 1, @@ -42,19 +46,23 @@ basic_create_role_schema = { "name": { "type": "string", "minLength": 1, + "error": "roleName", }, "servers": { "type": "array", + "error": "typeList", "items": { "type": "object", "properties": { "server_id": { "type": "string", "minimum": 1, + "error": "roleServerId", }, "permissions": { "type": "string", - "pattern": "^[01]{8}$", # 8 bits, see EnumPermissionsServer + "pattern": r"^[01]{8}$", # 8 bits, see EnumPermissionsServer + "error": "roleServerPerms", }, }, "required": ["server_id", "permissions"], diff --git a/app/classes/web/routes/api/roles/role/index.py b/app/classes/web/routes/api/roles/role/index.py index 1eab6183..2d1be660 100644 --- a/app/classes/web/routes/api/roles/role/index.py +++ b/app/classes/web/routes/api/roles/role/index.py @@ -11,25 +11,29 @@ modify_role_schema = { "type": "string", "minLength": 1, "pattern": r"^[^,\[\]]*$", + "error": "roleName", }, "servers": { "type": "array", + "error": "typeList", "items": { "type": "object", "properties": { "server_id": { "type": "string", "minimum": 1, + "error": "roleServerId", }, "permissions": { "type": "string", "pattern": r"^[01]{8}$", # 8 bits, see EnumPermissionsServer + "error": "roleServerPerms", }, }, "required": ["server_id", "permissions"], }, }, - "manager": {"type": ["integer", "null"]}, + "manager": {"type": ["integer", "null"], "error": "roleManager"}, }, "additionalProperties": False, "minProperties": 1, @@ -41,19 +45,23 @@ basic_modify_role_schema = { "name": { "type": "string", "minLength": 1, + "error": "roleName", }, "servers": { "type": "array", + "error": "typeList", "items": { "type": "object", "properties": { "server_id": { "type": "string", "minimum": 1, + "error": "roleServerId", }, "permissions": { "type": "string", - "pattern": "^[01]{8}$", # 8 bits, see EnumPermissionsServer + "pattern": r"^[01]{8}$", # 8 bits, see EnumPermissionsServer + "error": "roleServerPerms", }, }, "required": ["server_id", "permissions"], diff --git a/app/translations/en_EN.json b/app/translations/en_EN.json index 50ab88c5..831f7542 100644 --- a/app/translations/en_EN.json +++ b/app/translations/en_EN.json @@ -670,6 +670,10 @@ "validators": { "filesPageLen": "Length must be greater than 1 for property ", "passLength": "Password Too Short. Minimum Length: 8", + "roleManager": "Role manager must be of type integer (manager ID) or None", + "roleName": "Role name must be a string that is greater than 1 character. It must not include any of the following symbols: [ ] , ", + "roleServerId": "Server ID property must be a string with a minimum length of 1", + "roleServerPerms": "Server permissions must be an 8-bit string", "typeBool": "Type error: True or False required for ", "typeInteger": "Type error: Integer required for ", "typeList": "Type error: List required for ", From ed9accc1e4279a3c1004e5cf9a7e2bd412a7d611 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Tue, 6 Aug 2024 13:31:54 -0400 Subject: [PATCH 06/74] Add fill/no fill for schema props --- .../web/routes/api/crafty/config/index.py | 148 +++++++++++++++--- .../web/routes/api/crafty/imports/index.py | 21 ++- app/classes/web/routes/api/roles/index.py | 14 +- .../web/routes/api/roles/role/index.py | 14 +- app/translations/en_EN.json | 3 +- 5 files changed, 166 insertions(+), 34 deletions(-) diff --git a/app/classes/web/routes/api/crafty/config/index.py b/app/classes/web/routes/api/crafty/config/index.py index 85379316..fa4c83bf 100644 --- a/app/classes/web/routes/api/crafty/config/index.py +++ b/app/classes/web/routes/api/crafty/config/index.py @@ -9,27 +9,111 @@ from app.classes.web.base_api_handler import BaseApiHandler config_json_schema = { "type": "object", "properties": { - "https_port": {"type": "integer", "error": "typeInteger"}, - "language": {"type": "string", "error": "typeString"}, - "cookie_expire": {"type": "integer", "error": "typeInteger"}, - "show_errors": {"type": "boolean", "error": "typeBool"}, - "history_max_age": {"type": "integer", "error": "typeInteger"}, - "stats_update_frequency_seconds": {"type": "integer", "error": "typeInteger"}, - "delete_default_json": {"type": "boolean", "error": "typeBool"}, - "show_contribute_link": {"type": "boolean", "error": "typeBool"}, - "virtual_terminal_lines": {"type": "integer", "error": "typeInteger"}, - "max_log_lines": {"type": "integer", "error": "typeInteger"}, - "max_audit_entries": {"type": "integer", "error": "typeInteger"}, - "disabled_language_files": {"type": "array", "error": "typeList"}, - "stream_size_GB": {"type": "integer", "error": "typeInteger"}, - "keywords": {"type": "array", "error": "typeList"}, - "allow_nsfw_profile_pictures": {"type": "boolean", "error": "typeBool"}, - "enable_user_self_delete": {"type": "boolean", "error": "typeBool"}, - "reset_secrets_on_next_boot": {"type": "boolean", "error": "typeBool"}, - "monitored_mounts": {"type": "array", "error": "typeList"}, - "dir_size_poll_freq_minutes": {"type": "integer", "error": "typeInteger"}, - "crafty_logs_delete_after_days": {"type": "integer", "error": "typeInteger"}, - "big_bucket_repo": {"type": "string", "error": "typeString"}, + "https_port": { + "type": "integer", + "error": "typeInteger", + "fill": True, + }, + "language": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "cookie_expire": { + "type": "integer", + "error": "typeInteger", + "fill": True, + }, + "show_errors": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, + "history_max_age": { + "type": "integer", + "error": "typeInteger", + "fill": True, + }, + "stats_update_frequency_seconds": { + "type": "integer", + "error": "typeInteger", + "fill": True, + }, + "delete_default_json": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, + "show_contribute_link": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, + "virtual_terminal_lines": { + "type": "integer", + "error": "typeInteger", + "fill": True, + }, + "max_log_lines": { + "type": "integer", + "error": "typeInteger", + "fill": True, + }, + "max_audit_entries": { + "type": "integer", + "error": "typeInteger", + "fill": True, + }, + "disabled_language_files": { + "type": "array", + "error": "typeList", + "fill": True, + }, + "stream_size_GB": { + "type": "integer", + "error": "typeInteger", + "fill": True, + }, + "keywords": { + "type": "array", + "error": "typeList", + "fill": True, + }, + "allow_nsfw_profile_pictures": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, + "enable_user_self_delete": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, + "reset_secrets_on_next_boot": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, + "monitored_mounts": { + "type": "array", + "error": "typeList", + "fill": True, + }, + "dir_size_poll_freq_minutes": { + "type": "integer", + "error": "typeInteger", + "fill": True, + }, + "crafty_logs_delete_after_days": { + "type": "integer", + "error": "typeInteger", + "fill": True, + }, + "big_bucket_repo": { + "type": "string", + "error": "typeString", + "fill": True, + }, }, "additionalProperties": False, "minProperties": 1, @@ -37,8 +121,16 @@ config_json_schema = { customize_json_schema = { "type": "object", "properties": { - "photo": {"type": "string", "error": "typeString"}, - "opacity": {"type": "string", "error": "typeString"}, + "photo": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "opacity": { + "type": "string", + "error": "typeString", + "fill": True, + }, }, "additionalProperties": False, "minProperties": 1, @@ -47,7 +139,11 @@ customize_json_schema = { photo_delete_schema = { "type": "object", "properties": { - "photo": {"type": "string", "error": "typeString"}, + "photo": { + "type": "string", + "error": "typeString", + "fill": True, + }, }, "additionalProperties": False, "minProperties": 1, @@ -109,7 +205,9 @@ class ApiCraftyConfigIndexHandler(BaseApiHandler): try: validate(data, config_json_schema) except ValidationError as why: - offending_key = why.path[0] if why.path else None + offending_key = None + if why.get("fill", None): + offending_key = why.path[0] if why.path else None err = f"""{self.translator.translate( "validators", why.schema.get("error"), diff --git a/app/classes/web/routes/api/crafty/imports/index.py b/app/classes/web/routes/api/crafty/imports/index.py index 47b19b81..ff00722a 100644 --- a/app/classes/web/routes/api/crafty/imports/index.py +++ b/app/classes/web/routes/api/crafty/imports/index.py @@ -17,10 +17,21 @@ files_get_schema = { "type": "string", "minLength": 1, "error": "filesPageLen", + "fill": True, + }, + "folder": {"type": "string", "error": "typeString", "fill": True}, + "upload": { + "type": "boolean", + "default": "False", + "error": "typeBool", + "fill": True, + }, + "unzip": { + "type": "boolean", + "default": "True", + "error": "typeBool", + "fill": True, }, - "folder": {"type": "string", "error": "typeString"}, - "upload": {"type": "boolean", "default": "False", "error": "typeBool"}, - "unzip": {"type": "boolean", "default": "True", "error": "typeBool"}, }, "additionalProperties": False, "minProperties": 1, @@ -52,7 +63,9 @@ class ApiImportFilesIndexHandler(BaseApiHandler): try: validate(data, files_get_schema) except ValidationError as why: - offending_key = why.path[0] if why.path else None + offending_key = None + if why.get("fill", None): + offending_key = why.path[0] if why.path else None err = f"""{self.translator.translate( "validators", why.schema.get("error"), diff --git a/app/classes/web/routes/api/roles/index.py b/app/classes/web/routes/api/roles/index.py index 69bbf4df..ee057e26 100644 --- a/app/classes/web/routes/api/roles/index.py +++ b/app/classes/web/routes/api/roles/index.py @@ -17,6 +17,7 @@ create_role_schema = { "servers": { "type": "array", "error": "typeList", + "fill": True, "items": { "type": "object", "properties": { @@ -51,6 +52,7 @@ basic_create_role_schema = { "servers": { "type": "array", "error": "typeList", + "fill": True, "items": { "type": "object", "properties": { @@ -142,13 +144,21 @@ class ApiRolesIndexHandler(BaseApiHandler): validate(data, create_role_schema) else: validate(data, basic_create_role_schema) - except ValidationError as e: + except ValidationError as why: + offending_key = None + if why.get("fill", None): + offending_key = why.path[0] if why.path else None + err = f"""{self.translator.translate( + "validators", + why.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {offending_key}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) diff --git a/app/classes/web/routes/api/roles/role/index.py b/app/classes/web/routes/api/roles/role/index.py index 2d1be660..e36b4b36 100644 --- a/app/classes/web/routes/api/roles/role/index.py +++ b/app/classes/web/routes/api/roles/role/index.py @@ -16,6 +16,7 @@ modify_role_schema = { "servers": { "type": "array", "error": "typeList", + "fill": True, "items": { "type": "object", "properties": { @@ -50,6 +51,7 @@ basic_modify_role_schema = { "servers": { "type": "array", "error": "typeList", + "fill": True, "items": { "type": "object", "properties": { @@ -173,13 +175,21 @@ class ApiRolesRoleIndexHandler(BaseApiHandler): validate(data, modify_role_schema) else: validate(data, basic_modify_role_schema) - except ValidationError as e: + except ValidationError as why: + offending_key = None + if why.get("fill", None): + offending_key = why.path[0] if why.path else None + err = f"""{self.translator.translate( + "validators", + why.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {offending_key}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) diff --git a/app/translations/en_EN.json b/app/translations/en_EN.json index 831f7542..39c558f7 100644 --- a/app/translations/en_EN.json +++ b/app/translations/en_EN.json @@ -668,12 +668,13 @@ "uses": "Number of uses allowed (-1==No Limit)" }, "validators": { - "filesPageLen": "Length must be greater than 1 for property ", + "filesPageLen": "Length must be greater than 1 for property for prop", "passLength": "Password Too Short. Minimum Length: 8", "roleManager": "Role manager must be of type integer (manager ID) or None", "roleName": "Role name must be a string that is greater than 1 character. It must not include any of the following symbols: [ ] , ", "roleServerId": "Server ID property must be a string with a minimum length of 1", "roleServerPerms": "Server permissions must be an 8-bit string", + "serverCreateName": "Server name must be a string with a minimum length of 2 and must not include: \\ / or # ", "typeBool": "Type error: True or False required for ", "typeInteger": "Type error: Integer required for ", "typeList": "Type error: List required for ", From f1fd57ea26868146a152a6582626c582ee7124e0 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Tue, 6 Aug 2024 13:54:28 -0400 Subject: [PATCH 07/74] Server patch and server create human readable errors --- app/classes/web/routes/api/servers/index.py | 144 ++++++++++++- .../web/routes/api/servers/server/index.py | 194 +++++++++++++++--- app/translations/en_EN.json | 4 + 3 files changed, 307 insertions(+), 35 deletions(-) diff --git a/app/classes/web/routes/api/servers/index.py b/app/classes/web/routes/api/servers/index.py index ca551326..e6b3ffcb 100644 --- a/app/classes/web/routes/api/servers/index.py +++ b/app/classes/web/routes/api/servers/index.py @@ -23,15 +23,23 @@ new_server_schema = { "type": "string", "examples": ["My Server"], "minLength": 2, - "pattern": "^[^/\\\\]*$", + "pattern": r"^[^/\\\\#]*$", + "error": "serverCreateName", + }, + "roles": { + "title": "Roles to add", + "type": "array", + "examples": [1, 2, 3], + "error": "typeList", }, - "roles": {"title": "Roles to add", "type": "array", "examples": [1, 2, 3]}, "stop_command": { "title": "Stop command", "description": '"" means the default for the server creation type.', "type": "string", "default": "", "examples": ["stop", "end"], + "error": "typeString", + "fill": True, }, "log_location": { "title": "Log file", @@ -39,11 +47,15 @@ new_server_schema = { "type": "string", "default": "", "examples": ["./logs/latest.log", "./proxy.log.0"], + "error": "typeString", + "fill": True, }, "crashdetection": { "title": "Crash detection", "type": "boolean", "default": False, + "error": "typeBool", + "fill": True, }, "autostart": { "title": "Autostart", @@ -51,6 +63,8 @@ new_server_schema = { + " automatically when Crafty is launched.", "type": "boolean", "default": False, + "error": "typeBool", + "fill": True, }, "autostart_delay": { "title": "Autostart delay", @@ -58,12 +72,16 @@ new_server_schema = { "type": "number", "default": 10, "minimum": 0, + "error": "typeIntMinVal0", + "fill": True, }, "monitoring_type": { "title": "Server monitoring type", "type": "string", "default": "minecraft_java", "enum": ["minecraft_java", "minecraft_bedrock", "none"], + "error": "serverAPI", + "fill": True, # TODO: SteamCMD, RakNet, etc. }, "minecraft_java_monitoring_data": { @@ -77,6 +95,8 @@ new_server_schema = { "default": "127.0.0.1", "examples": ["127.0.0.1"], "minLength": 1, + "error": "typeString", + "fill": True, }, "port": { "title": "Port", @@ -84,6 +104,8 @@ new_server_schema = { "examples": [25565], "default": 25565, "minimum": 0, + "error": "typeIntMinVal0", + "fill": True, }, }, }, @@ -98,6 +120,8 @@ new_server_schema = { "default": "127.0.0.1", "examples": ["127.0.0.1"], "minLength": 1, + "error": "typeString", + "fill": True, }, "port": { "title": "Port", @@ -105,6 +129,8 @@ new_server_schema = { "examples": [19132], "default": 19132, "minimum": 0, + "error": "typeIntMinVal0", + "fill": True, }, }, }, @@ -114,6 +140,8 @@ new_server_schema = { "type": "string", "default": "minecraft_java", "enum": ["minecraft_java", "minecraft_bedrock", "custom"], + "error": "serverAPI", + "fill": True, }, "minecraft_java_create_data": { "title": "Java creation data", @@ -125,10 +153,14 @@ new_server_schema = { "type": "string", "default": "download_jar", "enum": ["download_jar", "import_server", "import_zip"], + "error": "serverAPI", + "fill": True, }, "download_jar_create_data": { "title": "JAR download data", "type": "object", + "error": "serverAPI", + "fill": True, "required": [ "type", "version", @@ -141,6 +173,8 @@ new_server_schema = { "title": "Jar Category", "type": "string", "examples": ["Mc_java_servers", "Mc_java_proxies"], + "error": "serverAPI", + "fill": True, }, "properties": { "type": { @@ -148,12 +182,16 @@ new_server_schema = { "type": "string", "examples": ["Paper"], "minLength": 1, + "error": "typeString", + "fill": True, }, "version": { "title": "Server JAR Version", "type": "string", "examples": ["1.18.2"], "minLength": 1, + "error": "typeString", + "fill": True, }, "mem_min": { "title": "Minimum JVM memory (in GiBs)", @@ -161,6 +199,8 @@ new_server_schema = { "examples": [1], "default": 1, "exclusiveMinimum": 0, + "error": "typeInteger", + "fill": True, }, "mem_max": { "title": "Maximum JVM memory (in GiBs)", @@ -168,6 +208,8 @@ new_server_schema = { "examples": [2], "default": 2, "exclusiveMinimum": 0, + "error": "typeInteger", + "fill": True, }, "server_properties_port": { "title": "Port", @@ -175,17 +217,23 @@ new_server_schema = { "examples": [25565], "default": 25565, "minimum": 0, + "error": "typeInteger", + "fill": True, }, "agree_to_eula": { "title": "Agree to the EULA", "type": "boolean", "default": False, + "error": "typeBool", + "fill": True, }, }, }, "import_server_create_data": { "title": "Import server data", "type": "object", + "error": "serverAPI", + "fill": True, "required": [ "existing_server_path", "jarfile", @@ -200,6 +248,8 @@ new_server_schema = { "type": "string", "examples": ["/var/opt/server"], "minLength": 1, + "error": "typeString", + "fill": True, }, "jarfile": { "title": "JAR file", @@ -207,6 +257,8 @@ new_server_schema = { "type": "string", "examples": ["paper.jar", "jars/vanilla-1.12.jar"], "minLength": 1, + "error": "typeString", + "fill": True, }, "mem_min": { "title": "Minimum JVM memory (in GiBs)", @@ -214,6 +266,8 @@ new_server_schema = { "examples": [1], "default": 1, "exclusiveMinimum": 0, + "error": "typeInteger", + "fill": True, }, "mem_max": { "title": "Maximum JVM memory (in GiBs)", @@ -221,6 +275,8 @@ new_server_schema = { "examples": [2], "default": 2, "exclusiveMinimum": 0, + "error": "typeInteger", + "fill": True, }, "server_properties_port": { "title": "Port", @@ -228,17 +284,23 @@ new_server_schema = { "examples": [25565], "default": 25565, "minimum": 0, + "error": "typeInteger", + "fill": True, }, "agree_to_eula": { "title": "Agree to the EULA", "type": "boolean", "default": False, + "error": "typeBool", + "fill": True, }, }, }, "import_zip_create_data": { "title": "Import ZIP server data", "type": "object", + "error": "serverAPI", + "fill": True, "required": [ "zip_path", "zip_root", @@ -254,6 +316,8 @@ new_server_schema = { "type": "string", "examples": ["/var/opt/server.zip"], "minLength": 1, + "error": "typeString", + "fill": True, }, "zip_root": { "title": "Server root directory", @@ -261,6 +325,8 @@ new_server_schema = { "type": "string", "examples": ["/", "/paper-server/", "server-1"], "minLength": 1, + "error": "typeString", + "fill": True, }, "jarfile": { "title": "JAR file", @@ -268,6 +334,8 @@ new_server_schema = { "type": "string", "examples": ["paper.jar", "jars/vanilla-1.12.jar"], "minLength": 1, + "error": "typeString", + "fill": True, }, "mem_min": { "title": "Minimum JVM memory (in GiBs)", @@ -275,6 +343,8 @@ new_server_schema = { "examples": [1], "default": 1, "exclusiveMinimum": 0, + "error": "typeInteger", + "fill": True, }, "mem_max": { "title": "Maximum JVM memory (in GiBs)", @@ -282,6 +352,8 @@ new_server_schema = { "examples": [2], "default": 2, "exclusiveMinimum": 0, + "error": "typeInteger", + "fill": True, }, "server_properties_port": { "title": "Port", @@ -289,11 +361,15 @@ new_server_schema = { "examples": [25565], "default": 25565, "minimum": 0, + "error": "typeInteger", + "fill": True, }, "agree_to_eula": { "title": "Agree to the EULA", "type": "boolean", "default": False, + "error": "typeBool", + "fill": True, }, }, }, @@ -342,10 +418,14 @@ new_server_schema = { "type": "string", "default": "import_server", "enum": ["download_exe", "import_server", "import_zip"], + "error": "serverAPI", + "fill": True, }, "download_exe_create_data": { "title": "Import server data", "type": "object", + "error": "serverAPI", + "fill": True, "required": [], "properties": { "agree_to_eula": { @@ -358,6 +438,8 @@ new_server_schema = { "import_server_create_data": { "title": "Import server data", "type": "object", + "error": "serverAPI", + "fill": True, "required": ["existing_server_path", "executable"], "properties": { "existing_server_path": { @@ -366,6 +448,8 @@ new_server_schema = { "type": "string", "examples": ["/var/opt/server"], "minLength": 1, + "error": "typeString", + "fill": True, }, "executable": { "title": "Executable File", @@ -374,6 +458,8 @@ new_server_schema = { "type": "string", "examples": ["bedrock_server.exe"], "minlength": 1, + "error": "typeString", + "fill": True, }, "command": { "title": "Command", @@ -381,12 +467,16 @@ new_server_schema = { "default": "echo foo bar baz", "examples": ["LD_LIBRARY_PATH=. ./bedrock_server"], "minLength": 1, + "error": "typeString", + "fill": True, }, }, }, "import_zip_create_data": { "title": "Import ZIP server data", "type": "object", + "error": "serverAPI", + "fill": True, "required": ["zip_path", "zip_root", "command"], "properties": { "zip_path": { @@ -395,6 +485,8 @@ new_server_schema = { "type": "string", "examples": ["/var/opt/server.zip"], "minLength": 1, + "error": "typeString", + "fill": True, }, "executable": { "title": "Executable File", @@ -403,6 +495,8 @@ new_server_schema = { "type": "string", "examples": ["bedrock_server.exe"], "minlength": 1, + "error": "typeString", + "fill": True, }, "zip_root": { "title": "Server root directory", @@ -410,6 +504,8 @@ new_server_schema = { "type": "string", "examples": ["/", "/paper-server/", "server-1"], "minLength": 1, + "error": "typeString", + "fill": True, }, "command": { "title": "Command", @@ -417,6 +513,8 @@ new_server_schema = { "default": "echo foo bar baz", "examples": ["LD_LIBRARY_PATH=. ./bedrock_server"], "minLength": 1, + "error": "typeString", + "fill": True, }, }, }, @@ -464,6 +562,8 @@ new_server_schema = { "custom_create_data": { "title": "Custom creation data", "type": "object", + "error": "serverAPI", + "fill": True, "required": [ "working_directory", "executable_update", @@ -476,28 +576,38 @@ new_server_schema = { "type": "string", "default": "", "examples": ["/mnt/mydrive/server-configs/", "./subdirectory", ""], + "error": "typeString", + "fill": True, }, "executable_update": { "title": "Executable Updation", "description": "Also configurable later on and for other servers", "type": "object", + "error": "serverAPI", + "fill": True, "required": ["enabled", "file", "url"], "properties": { "enabled": { "title": "Enabled", "type": "boolean", "default": False, + "error": "typeBool", + "fill": True, }, "file": { "title": "Executable to update", "type": "string", "default": "", "examples": ["./paper.jar"], + "error": "typeString", + "fill": True, }, "url": { "title": "URL to download the executable from", "type": "string", "default": "", + "error": "typeString", + "fill": True, }, }, }, @@ -506,6 +616,8 @@ new_server_schema = { "type": "string", "default": "raw_exec", "enum": ["raw_exec", "import_server", "import_zip"], + "error": "serverAPI", + "fill": True, }, "raw_exec_create_data": { "title": "Raw execution command create data", @@ -518,12 +630,16 @@ new_server_schema = { "default": "echo foo bar baz", "examples": ["caddy start"], "minLength": 1, + "error": "typeString", + "fill": True, } }, }, "import_server_create_data": { "title": "Import server data", "type": "object", + "error": "serverAPI", + "fill": True, "required": ["existing_server_path", "command"], "properties": { "existing_server_path": { @@ -532,6 +648,8 @@ new_server_schema = { "type": "string", "examples": ["/var/opt/server"], "minLength": 1, + "error": "typeString", + "fill": True, }, "command": { "title": "Command", @@ -539,12 +657,16 @@ new_server_schema = { "default": "echo foo bar baz", "examples": ["caddy start"], "minLength": 1, + "error": "typeString", + "fill": True, }, }, }, "import_zip_create_data": { "title": "Import ZIP server data", "type": "object", + "error": "serverAPI", + "fill": True, "required": ["zip_path", "zip_root", "command"], "properties": { "zip_path": { @@ -553,6 +675,8 @@ new_server_schema = { "type": "string", "examples": ["/var/opt/server.zip"], "minLength": 1, + "error": "typeString", + "fill": True, }, "zip_root": { "title": "Server root directory", @@ -560,6 +684,8 @@ new_server_schema = { "type": "string", "examples": ["/", "/paper-server/", "server-1"], "minLength": 1, + "error": "typeString", + "fill": True, }, "command": { "title": "Command", @@ -567,6 +693,8 @@ new_server_schema = { "default": "echo foo bar baz", "examples": ["caddy start"], "minLength": 1, + "error": "typeString", + "fill": True, }, }, }, @@ -700,13 +828,21 @@ class ApiServersIndexHandler(BaseApiHandler): ) try: validate(data, new_server_schema) - except ValidationError as e: + except ValidationError as why: + offending_key = None + if why.get("fill", None): + offending_key = why.path[0] if why.path else None + err = f"""{self.translator.translate( + "validators", + why.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {offending_key}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) # Check to make sure port is allowable diff --git a/app/classes/web/routes/api/servers/server/index.py b/app/classes/web/routes/api/servers/server/index.py index 3562334c..845e42eb 100644 --- a/app/classes/web/routes/api/servers/server/index.py +++ b/app/classes/web/routes/api/servers/server/index.py @@ -12,24 +12,101 @@ logger = logging.getLogger(__name__) server_patch_schema = { "type": "object", "properties": { - "server_name": {"type": "string", "minLength": 2, "pattern": "^[^/\\\\]*$"}, - "backup_path": {"type": "string"}, - "executable": {"type": "string"}, - "log_path": {"type": "string", "minLength": 1}, - "execution_command": {"type": "string", "minLength": 1}, - "java_selection": {"type": "string"}, - "auto_start": {"type": "boolean"}, - "auto_start_delay": {"type": "integer", "minimum": 0}, - "crash_detection": {"type": "boolean"}, - "stop_command": {"type": "string"}, - "executable_update_url": {"type": "string"}, - "server_ip": {"type": "string", "minLength": 1}, - "server_port": {"type": "integer"}, - "shutdown_timeout": {"type": "integer", "minimum": 0}, - "logs_delete_after": {"type": "integer", "minimum": 0}, - "ignored_exits": {"type": "string"}, - "show_status": {"type": "boolean"}, - "count_players": {"type": "boolean"}, + "server_name": { + "type": "string", + "minLength": 2, + "pattern": r"^[^/\\\\#]*$", + "error": "serverCreateName", + }, + "backup_path": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "executable": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "log_path": { + "type": "string", + "minLength": 1, + "error": "serverLogPath", + }, + "execution_command": { + "type": "string", + "minLength": 1, + "error": "serverExeCommand", + }, + "java_selection": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "auto_start": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, + "auto_start_delay": { + "type": "integer", + "minimum": 0, + "error": "typeIntMinVal0", + "fill": True, + }, + "crash_detection": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, + "stop_command": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "executable_update_url": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "server_ip": { + "type": "string", + "minLength": 1, + "error": "typeString", + "fill": True, + }, + "server_port": { + "type": "integer", + "error": "typeInt", + "fill": True, + }, + "shutdown_timeout": { + "type": "integer", + "minimum": 0, + "error": "typeIntMinVal0", + "fill": True, + }, + "logs_delete_after": { + "type": "integer", + "minimum": 0, + "error": "typeIntMinVal0", + "fill": True, + }, + "ignored_exits": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "show_status": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, + "count_players": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, }, "additionalProperties": False, "minProperties": 1, @@ -37,17 +114,64 @@ server_patch_schema = { basic_server_patch_schema = { "type": "object", "properties": { - "server_name": {"type": "string", "minLength": 1}, - "executable": {"type": "string"}, - "java_selection": {"type": "string"}, - "auto_start": {"type": "boolean"}, - "auto_start_delay": {"type": "integer", "minimum": 0}, - "crash_detection": {"type": "boolean"}, - "stop_command": {"type": "string"}, - "shutdown_timeout": {"type": "integer"}, - "logs_delete_after": {"type": "integer", "minimum": 0}, - "ignored_exits": {"type": "string"}, - "count_players": {"type": "boolean"}, + "server_name": { + "type": "string", + "minLength": 1, + "error": "serverCreateName", + "fill": True, + }, + "executable": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "java_selection": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "auto_start": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, + "auto_start_delay": { + "type": "integer", + "minimum": 0, + "error": "typeIntMinVal0", + "fill": True, + }, + "crash_detection": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, + "stop_command": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "shutdown_timeout": { + "type": "integer", + "error": "typeInteger", + "fill": True, + }, + "logs_delete_after": { + "type": "integer", + "minimum": 0, + "error": "typeIntMinVal0", + "fill": True, + }, + "ignored_exits": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "count_players": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, }, "additionalProperties": False, "minProperties": 1, @@ -89,13 +213,21 @@ class ApiServersServerIndexHandler(BaseApiHandler): validate(data, server_patch_schema) else: validate(data, basic_server_patch_schema) - except ValidationError as e: + except ValidationError as why: + offending_key = None + if why.get("fill", None): + offending_key = why.path[0] if why.path else None + err = f"""{self.translator.translate( + "validators", + why.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {offending_key}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) diff --git a/app/translations/en_EN.json b/app/translations/en_EN.json index 39c558f7..91281875 100644 --- a/app/translations/en_EN.json +++ b/app/translations/en_EN.json @@ -674,9 +674,13 @@ "roleName": "Role name must be a string that is greater than 1 character. It must not include any of the following symbols: [ ] , ", "roleServerId": "Server ID property must be a string with a minimum length of 1", "roleServerPerms": "Server permissions must be an 8-bit string", + "serverAPI": "Invalid Input detected. Please see API docs for information on ", "serverCreateName": "Server name must be a string with a minimum length of 2 and must not include: \\ / or # ", + "serverExeCommand": "Server execution command must be a string with a minimum length of 1.", + "serverLogPath": "Server log path must be a string with a minimum length of 1", "typeBool": "Type error: True or False required for ", "typeInteger": "Type error: Integer required for ", + "typeIntMinVal0": "Must be an integer with a minimum value of 0 for prop ", "typeList": "Type error: List required for ", "typeString": "Type error: String required for " }, From 2de9c90924d28d5b4ab628e9dfea343d9ead0589 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Tue, 6 Aug 2024 14:02:57 -0400 Subject: [PATCH 08/74] Refactor files to use human readable errors --- .../web/routes/api/servers/server/files.py | 140 +++++++++++++++--- 1 file changed, 117 insertions(+), 23 deletions(-) diff --git a/app/classes/web/routes/api/servers/server/files.py b/app/classes/web/routes/api/servers/server/files.py index 2699ae0c..5551dc29 100644 --- a/app/classes/web/routes/api/servers/server/files.py +++ b/app/classes/web/routes/api/servers/server/files.py @@ -14,8 +14,17 @@ logger = logging.getLogger(__name__) files_get_schema = { "type": "object", "properties": { - "page": {"type": "string", "minLength": 1}, - "path": {"type": "string"}, + "page": { + "type": "string", + "minLength": 1, + "error": "typeString", + "fill": True, + }, + "path": { + "type": "string", + "error": "typeString", + "fill": True, + }, }, "additionalProperties": False, "minProperties": 1, @@ -24,8 +33,16 @@ files_get_schema = { files_patch_schema = { "type": "object", "properties": { - "path": {"type": "string"}, - "contents": {"type": "string"}, + "path": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "contents": { + "type": "string", + "error": "typeString", + "fill": True, + }, }, "additionalProperties": False, "minProperties": 1, @@ -34,7 +51,11 @@ files_patch_schema = { files_unzip_schema = { "type": "object", "properties": { - "folder": {"type": "string"}, + "folder": { + "type": "string", + "error": "typeString", + "fill": True, + }, }, "additionalProperties": False, "minProperties": 1, @@ -43,9 +64,21 @@ files_unzip_schema = { files_create_schema = { "type": "object", "properties": { - "parent": {"type": "string"}, - "name": {"type": "string"}, - "directory": {"type": "boolean"}, + "parent": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "name": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "directory": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, }, "additionalProperties": False, "minProperties": 1, @@ -54,8 +87,16 @@ files_create_schema = { files_rename_schema = { "type": "object", "properties": { - "path": {"type": "string"}, - "new_name": {"type": "string"}, + "path": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "new_name": { + "type": "string", + "error": "typeString", + "fill": True, + }, }, "additionalProperties": False, "minProperties": 1, @@ -64,7 +105,12 @@ files_rename_schema = { file_delete_schema = { "type": "object", "properties": { - "filename": {"type": "string", "minLength": 5}, + "filename": { + "type": "string", + "minLength": 5, + "error": "typeString", + "fill": True, + }, }, "additionalProperties": False, "minProperties": 1, @@ -229,13 +275,21 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler): ) try: validate(data, file_delete_schema) - except ValidationError as e: + except ValidationError as why: + offending_key = None + if why.get("fill", None): + offending_key = why.path[0] if why.path else None + err = f"""{self.translator.translate( + "validators", + why.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {offending_key}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) if not Helpers.validate_traversal( @@ -287,13 +341,21 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler): ) try: validate(data, files_patch_schema) - except ValidationError as e: + except ValidationError as why: + offending_key = None + if why.get("fill", None): + offending_key = why.path[0] if why.path else None + err = f"""{self.translator.translate( + "validators", + why.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {offending_key}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) if not Helpers.validate_traversal( @@ -341,13 +403,21 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler): ) try: validate(data, files_create_schema) - except ValidationError as e: + except ValidationError as why: + offending_key = None + if why.get("fill", None): + offending_key = why.path[0] if why.path else None + err = f"""{self.translator.translate( + "validators", + why.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {offending_key}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) path = os.path.join(data["parent"], data["name"]) @@ -408,13 +478,21 @@ class ApiServersServerFilesCreateHandler(BaseApiHandler): ) try: validate(data, files_rename_schema) - except ValidationError as e: + except ValidationError as why: + offending_key = None + if why.get("fill", None): + offending_key = why.path[0] if why.path else None + err = f"""{self.translator.translate( + "validators", + why.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {offending_key}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) path = data["path"] @@ -474,13 +552,21 @@ class ApiServersServerFilesCreateHandler(BaseApiHandler): ) try: validate(data, files_create_schema) - except ValidationError as e: + except ValidationError as why: + offending_key = None + if why.get("fill", None): + offending_key = why.path[0] if why.path else None + err = f"""{self.translator.translate( + "validators", + why.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {offending_key}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) path = os.path.join(data["parent"], data["name"]) @@ -541,13 +627,21 @@ class ApiServersServerFilesZipHandler(BaseApiHandler): ) try: validate(data, files_unzip_schema) - except ValidationError as e: + except ValidationError as why: + offending_key = None + if why.get("fill", None): + offending_key = why.path[0] if why.path else None + err = f"""{self.translator.translate( + "validators", + why.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {offending_key}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) folder = data["folder"] From 5c9b59f9e8c206860d21f8d281fbced4ed7207e8 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Tue, 6 Aug 2024 14:08:49 -0400 Subject: [PATCH 09/74] Refactor human readable errors for webhooks --- .../api/servers/server/webhooks/index.py | 41 ++++++++++++++++--- .../servers/server/webhooks/webhook/index.py | 41 ++++++++++++++++--- 2 files changed, 70 insertions(+), 12 deletions(-) diff --git a/app/classes/web/routes/api/servers/server/webhooks/index.py b/app/classes/web/routes/api/servers/server/webhooks/index.py index 2557c309..851915de 100644 --- a/app/classes/web/routes/api/servers/server/webhooks/index.py +++ b/app/classes/web/routes/api/servers/server/webhooks/index.py @@ -16,16 +16,45 @@ new_webhook_schema = { "webhook_type": { "type": "string", "enum": WebhookFactory.get_supported_providers(), + "error": "typeString", + "fill": True, + }, + "name": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "url": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "bot_name": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "trigger": { + "type": "array", + "error": "typeString", + "fill": True, + }, + "body": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "color": { + "type": "string", + "default": "#005cd1", + "error": "typeString", + "fill": True, }, - "name": {"type": "string"}, - "url": {"type": "string"}, - "bot_name": {"type": "string"}, - "trigger": {"type": "array"}, - "body": {"type": "string"}, - "color": {"type": "string", "default": "#005cd1"}, "enabled": { "type": "boolean", "default": True, + "error": "typeBool", + "fill": True, }, }, "additionalProperties": False, diff --git a/app/classes/web/routes/api/servers/server/webhooks/webhook/index.py b/app/classes/web/routes/api/servers/server/webhooks/webhook/index.py index c94aa975..5578c3ed 100644 --- a/app/classes/web/routes/api/servers/server/webhooks/webhook/index.py +++ b/app/classes/web/routes/api/servers/server/webhooks/webhook/index.py @@ -17,16 +17,45 @@ webhook_patch_schema = { "webhook_type": { "type": "string", "enum": WebhookFactory.get_supported_providers(), + "error": "typeString", + "fill": True, + }, + "name": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "url": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "bot_name": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "trigger": { + "type": "array", + "error": "typeString", + "fill": True, + }, + "body": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "color": { + "type": "string", + "default": "#005cd1", + "error": "typeString", + "fill": True, }, - "name": {"type": "string"}, - "url": {"type": "string"}, - "bot_name": {"type": "string"}, - "trigger": {"type": "array"}, - "body": {"type": "string"}, - "color": {"type": "string", "default": "#005cd1"}, "enabled": { "type": "boolean", "default": True, + "error": "typeBool", + "fill": True, }, }, "additionalProperties": False, From 279ad61a1b25dce3b689d66ebfbf3af6450f8f66 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Tue, 6 Aug 2024 14:10:53 -0400 Subject: [PATCH 10/74] Fix exception in webhook validation --- .../web/routes/api/servers/server/webhooks/index.py | 12 ++++++++++-- .../api/servers/server/webhooks/webhook/index.py | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/app/classes/web/routes/api/servers/server/webhooks/index.py b/app/classes/web/routes/api/servers/server/webhooks/index.py index 851915de..94e14b24 100644 --- a/app/classes/web/routes/api/servers/server/webhooks/index.py +++ b/app/classes/web/routes/api/servers/server/webhooks/index.py @@ -99,13 +99,21 @@ class ApiServersServerWebhooksIndexHandler(BaseApiHandler): try: validate(data, new_webhook_schema) - except ValidationError as e: + except ValidationError as why: + offending_key = None + if why.get("fill", None): + offending_key = why.path[0] if why.path else None + err = f"""{self.translator.translate( + "validators", + why.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {offending_key}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) diff --git a/app/classes/web/routes/api/servers/server/webhooks/webhook/index.py b/app/classes/web/routes/api/servers/server/webhooks/webhook/index.py index 5578c3ed..d3c53623 100644 --- a/app/classes/web/routes/api/servers/server/webhooks/webhook/index.py +++ b/app/classes/web/routes/api/servers/server/webhooks/webhook/index.py @@ -137,13 +137,21 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler): try: validate(data, webhook_patch_schema) - except ValidationError as e: + except ValidationError as why: + offending_key = None + if why.get("fill", None): + offending_key = why.path[0] if why.path else None + err = f"""{self.translator.translate( + "validators", + why.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {offending_key}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) From 2520e4b00fcc029c0a671939350fc4443cd6b6b3 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Tue, 6 Aug 2024 14:44:01 -0400 Subject: [PATCH 11/74] Enable enum errors --- .../web/routes/api/crafty/config/index.py | 8 ++-- .../web/routes/api/crafty/imports/index.py | 8 ++-- app/classes/web/routes/api/roles/index.py | 8 ++-- .../web/routes/api/roles/role/index.py | 8 ++-- app/classes/web/routes/api/servers/index.py | 40 ++++++++-------- .../web/routes/api/servers/server/files.py | 48 +++++++++---------- .../web/routes/api/servers/server/index.py | 8 ++-- .../api/servers/server/webhooks/index.py | 8 ++-- .../servers/server/webhooks/webhook/index.py | 8 ++-- app/translations/en_EN.json | 15 +++--- 10 files changed, 80 insertions(+), 79 deletions(-) diff --git a/app/classes/web/routes/api/crafty/config/index.py b/app/classes/web/routes/api/crafty/config/index.py index fa4c83bf..42065d72 100644 --- a/app/classes/web/routes/api/crafty/config/index.py +++ b/app/classes/web/routes/api/crafty/config/index.py @@ -205,14 +205,14 @@ class ApiCraftyConfigIndexHandler(BaseApiHandler): try: validate(data, config_json_schema) except ValidationError as why: - offending_key = None - if why.get("fill", None): + offending_key = "" + if why.schema.get("fill", None): offending_key = why.path[0] if why.path else None - err = f"""{self.translator.translate( + err = f"""{offending_key} {self.translator.translate( "validators", why.schema.get("error"), self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), - )} {offending_key}""" + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { diff --git a/app/classes/web/routes/api/crafty/imports/index.py b/app/classes/web/routes/api/crafty/imports/index.py index ff00722a..9487b31c 100644 --- a/app/classes/web/routes/api/crafty/imports/index.py +++ b/app/classes/web/routes/api/crafty/imports/index.py @@ -63,14 +63,14 @@ class ApiImportFilesIndexHandler(BaseApiHandler): try: validate(data, files_get_schema) except ValidationError as why: - offending_key = None - if why.get("fill", None): + offending_key = "" + if why.schema.get("fill", None): offending_key = why.path[0] if why.path else None - err = f"""{self.translator.translate( + err = f"""{offending_key} {self.translator.translate( "validators", why.schema.get("error"), self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), - )} {offending_key}""" + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { diff --git a/app/classes/web/routes/api/roles/index.py b/app/classes/web/routes/api/roles/index.py index ee057e26..8ea494e5 100644 --- a/app/classes/web/routes/api/roles/index.py +++ b/app/classes/web/routes/api/roles/index.py @@ -145,14 +145,14 @@ class ApiRolesIndexHandler(BaseApiHandler): else: validate(data, basic_create_role_schema) except ValidationError as why: - offending_key = None - if why.get("fill", None): + offending_key = "" + if why.schema.get("fill", None): offending_key = why.path[0] if why.path else None - err = f"""{self.translator.translate( + err = f"""{offending_key} {self.translator.translate( "validators", why.schema.get("error"), self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), - )} {offending_key}""" + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { diff --git a/app/classes/web/routes/api/roles/role/index.py b/app/classes/web/routes/api/roles/role/index.py index e36b4b36..b013f167 100644 --- a/app/classes/web/routes/api/roles/role/index.py +++ b/app/classes/web/routes/api/roles/role/index.py @@ -176,14 +176,14 @@ class ApiRolesRoleIndexHandler(BaseApiHandler): else: validate(data, basic_modify_role_schema) except ValidationError as why: - offending_key = None - if why.get("fill", None): + offending_key = "" + if why.schema.get("fill", None): offending_key = why.path[0] if why.path else None - err = f"""{self.translator.translate( + err = f"""{offending_key} {self.translator.translate( "validators", why.schema.get("error"), self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), - )} {offending_key}""" + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { diff --git a/app/classes/web/routes/api/servers/index.py b/app/classes/web/routes/api/servers/index.py index e6b3ffcb..8d822653 100644 --- a/app/classes/web/routes/api/servers/index.py +++ b/app/classes/web/routes/api/servers/index.py @@ -80,7 +80,7 @@ new_server_schema = { "type": "string", "default": "minecraft_java", "enum": ["minecraft_java", "minecraft_bedrock", "none"], - "error": "serverAPI", + "error": "enumErr", "fill": True, # TODO: SteamCMD, RakNet, etc. }, @@ -140,7 +140,7 @@ new_server_schema = { "type": "string", "default": "minecraft_java", "enum": ["minecraft_java", "minecraft_bedrock", "custom"], - "error": "serverAPI", + "error": "enumErr", "fill": True, }, "minecraft_java_create_data": { @@ -153,13 +153,13 @@ new_server_schema = { "type": "string", "default": "download_jar", "enum": ["download_jar", "import_server", "import_zip"], - "error": "serverAPI", + "error": "enumErr", "fill": True, }, "download_jar_create_data": { "title": "JAR download data", "type": "object", - "error": "serverAPI", + "error": "enumErr", "fill": True, "required": [ "type", @@ -173,7 +173,7 @@ new_server_schema = { "title": "Jar Category", "type": "string", "examples": ["Mc_java_servers", "Mc_java_proxies"], - "error": "serverAPI", + "error": "enumErr", "fill": True, }, "properties": { @@ -232,7 +232,7 @@ new_server_schema = { "import_server_create_data": { "title": "Import server data", "type": "object", - "error": "serverAPI", + "error": "enumErr", "fill": True, "required": [ "existing_server_path", @@ -299,7 +299,7 @@ new_server_schema = { "import_zip_create_data": { "title": "Import ZIP server data", "type": "object", - "error": "serverAPI", + "error": "enumErr", "fill": True, "required": [ "zip_path", @@ -418,13 +418,13 @@ new_server_schema = { "type": "string", "default": "import_server", "enum": ["download_exe", "import_server", "import_zip"], - "error": "serverAPI", + "error": "enumErr", "fill": True, }, "download_exe_create_data": { "title": "Import server data", "type": "object", - "error": "serverAPI", + "error": "enumErr", "fill": True, "required": [], "properties": { @@ -438,7 +438,7 @@ new_server_schema = { "import_server_create_data": { "title": "Import server data", "type": "object", - "error": "serverAPI", + "error": "enumErr", "fill": True, "required": ["existing_server_path", "executable"], "properties": { @@ -475,7 +475,7 @@ new_server_schema = { "import_zip_create_data": { "title": "Import ZIP server data", "type": "object", - "error": "serverAPI", + "error": "enumErr", "fill": True, "required": ["zip_path", "zip_root", "command"], "properties": { @@ -562,7 +562,7 @@ new_server_schema = { "custom_create_data": { "title": "Custom creation data", "type": "object", - "error": "serverAPI", + "error": "enumErr", "fill": True, "required": [ "working_directory", @@ -583,7 +583,7 @@ new_server_schema = { "title": "Executable Updation", "description": "Also configurable later on and for other servers", "type": "object", - "error": "serverAPI", + "error": "enumErr", "fill": True, "required": ["enabled", "file", "url"], "properties": { @@ -616,7 +616,7 @@ new_server_schema = { "type": "string", "default": "raw_exec", "enum": ["raw_exec", "import_server", "import_zip"], - "error": "serverAPI", + "error": "enumErr", "fill": True, }, "raw_exec_create_data": { @@ -638,7 +638,7 @@ new_server_schema = { "import_server_create_data": { "title": "Import server data", "type": "object", - "error": "serverAPI", + "error": "enumErr", "fill": True, "required": ["existing_server_path", "command"], "properties": { @@ -665,7 +665,7 @@ new_server_schema = { "import_zip_create_data": { "title": "Import ZIP server data", "type": "object", - "error": "serverAPI", + "error": "enumErr", "fill": True, "required": ["zip_path", "zip_root", "command"], "properties": { @@ -829,14 +829,14 @@ class ApiServersIndexHandler(BaseApiHandler): try: validate(data, new_server_schema) except ValidationError as why: - offending_key = None - if why.get("fill", None): + offending_key = "" + if why.schema.get("fill", None): offending_key = why.path[0] if why.path else None - err = f"""{self.translator.translate( + err = f"""{offending_key} {self.translator.translate( "validators", why.schema.get("error"), self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), - )} {offending_key}""" + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { diff --git a/app/classes/web/routes/api/servers/server/files.py b/app/classes/web/routes/api/servers/server/files.py index 5551dc29..8e8fb108 100644 --- a/app/classes/web/routes/api/servers/server/files.py +++ b/app/classes/web/routes/api/servers/server/files.py @@ -276,14 +276,14 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler): try: validate(data, file_delete_schema) except ValidationError as why: - offending_key = None - if why.get("fill", None): + offending_key = "" + if why.schema.get("fill", None): offending_key = why.path[0] if why.path else None - err = f"""{self.translator.translate( + err = f"""{offending_key} {self.translator.translate( "validators", why.schema.get("error"), self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), - )} {offending_key}""" + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { @@ -342,14 +342,14 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler): try: validate(data, files_patch_schema) except ValidationError as why: - offending_key = None - if why.get("fill", None): + offending_key = "" + if why.schema.get("fill", None): offending_key = why.path[0] if why.path else None - err = f"""{self.translator.translate( + err = f"""{offending_key} {self.translator.translate( "validators", why.schema.get("error"), self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), - )} {offending_key}""" + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { @@ -404,14 +404,14 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler): try: validate(data, files_create_schema) except ValidationError as why: - offending_key = None - if why.get("fill", None): + offending_key = "" + if why.schema.get("fill", None): offending_key = why.path[0] if why.path else None - err = f"""{self.translator.translate( + err = f"""{offending_key} {self.translator.translate( "validators", why.schema.get("error"), self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), - )} {offending_key}""" + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { @@ -479,14 +479,14 @@ class ApiServersServerFilesCreateHandler(BaseApiHandler): try: validate(data, files_rename_schema) except ValidationError as why: - offending_key = None - if why.get("fill", None): + offending_key = "" + if why.schema.get("fill", None): offending_key = why.path[0] if why.path else None - err = f"""{self.translator.translate( + err = f"""{offending_key} {self.translator.translate( "validators", why.schema.get("error"), self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), - )} {offending_key}""" + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { @@ -553,14 +553,14 @@ class ApiServersServerFilesCreateHandler(BaseApiHandler): try: validate(data, files_create_schema) except ValidationError as why: - offending_key = None - if why.get("fill", None): + offending_key = "" + if why.schema.get("fill", None): offending_key = why.path[0] if why.path else None - err = f"""{self.translator.translate( + err = f"""{offending_key} {self.translator.translate( "validators", why.schema.get("error"), self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), - )} {offending_key}""" + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { @@ -628,14 +628,14 @@ class ApiServersServerFilesZipHandler(BaseApiHandler): try: validate(data, files_unzip_schema) except ValidationError as why: - offending_key = None - if why.get("fill", None): + offending_key = "" + if why.schema.get("fill", None): offending_key = why.path[0] if why.path else None - err = f"""{self.translator.translate( + err = f"""{offending_key} {self.translator.translate( "validators", why.schema.get("error"), self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), - )} {offending_key}""" + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { diff --git a/app/classes/web/routes/api/servers/server/index.py b/app/classes/web/routes/api/servers/server/index.py index 845e42eb..c54170cf 100644 --- a/app/classes/web/routes/api/servers/server/index.py +++ b/app/classes/web/routes/api/servers/server/index.py @@ -214,14 +214,14 @@ class ApiServersServerIndexHandler(BaseApiHandler): else: validate(data, basic_server_patch_schema) except ValidationError as why: - offending_key = None - if why.get("fill", None): + offending_key = "" + if why.schema.get("fill", None): offending_key = why.path[0] if why.path else None - err = f"""{self.translator.translate( + err = f"""{offending_key} {self.translator.translate( "validators", why.schema.get("error"), self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), - )} {offending_key}""" + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { diff --git a/app/classes/web/routes/api/servers/server/webhooks/index.py b/app/classes/web/routes/api/servers/server/webhooks/index.py index 94e14b24..35bbdbeb 100644 --- a/app/classes/web/routes/api/servers/server/webhooks/index.py +++ b/app/classes/web/routes/api/servers/server/webhooks/index.py @@ -100,14 +100,14 @@ class ApiServersServerWebhooksIndexHandler(BaseApiHandler): try: validate(data, new_webhook_schema) except ValidationError as why: - offending_key = None - if why.get("fill", None): + offending_key = "" + if why.schema.get("fill", None): offending_key = why.path[0] if why.path else None - err = f"""{self.translator.translate( + err = f"""{offending_key} {self.translator.translate( "validators", why.schema.get("error"), self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), - )} {offending_key}""" + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { diff --git a/app/classes/web/routes/api/servers/server/webhooks/webhook/index.py b/app/classes/web/routes/api/servers/server/webhooks/webhook/index.py index d3c53623..d530ffa0 100644 --- a/app/classes/web/routes/api/servers/server/webhooks/webhook/index.py +++ b/app/classes/web/routes/api/servers/server/webhooks/webhook/index.py @@ -138,14 +138,14 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler): try: validate(data, webhook_patch_schema) except ValidationError as why: - offending_key = None - if why.get("fill", None): + offending_key = "" + if why.schema.get("fill", None): offending_key = why.path[0] if why.path else None - err = f"""{self.translator.translate( + err = f"""{offending_key} {self.translator.translate( "validators", why.schema.get("error"), self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), - )} {offending_key}""" + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { diff --git a/app/translations/en_EN.json b/app/translations/en_EN.json index 91281875..d34919d2 100644 --- a/app/translations/en_EN.json +++ b/app/translations/en_EN.json @@ -668,21 +668,22 @@ "uses": "Number of uses allowed (-1==No Limit)" }, "validators": { - "filesPageLen": "Length must be greater than 1 for property for prop", + "enumErr": "failed validating. Acceptable data includes: ", + "filesPageLen": "length must be greater than 1 for property", "passLength": "Password Too Short. Minimum Length: 8", "roleManager": "Role manager must be of type integer (manager ID) or None", "roleName": "Role name must be a string that is greater than 1 character. It must not include any of the following symbols: [ ] , ", "roleServerId": "Server ID property must be a string with a minimum length of 1", "roleServerPerms": "Server permissions must be an 8-bit string", - "serverAPI": "Invalid Input detected. Please see API docs for information on ", "serverCreateName": "Server name must be a string with a minimum length of 2 and must not include: \\ / or # ", "serverExeCommand": "Server execution command must be a string with a minimum length of 1.", "serverLogPath": "Server log path must be a string with a minimum length of 1", - "typeBool": "Type error: True or False required for ", - "typeInteger": "Type error: Integer required for ", - "typeIntMinVal0": "Must be an integer with a minimum value of 0 for prop ", - "typeList": "Type error: List required for ", - "typeString": "Type error: String required for " + "taskIntervalType": "Task Interval Type must be one of the following: ", + "typeBool": "Type error: True or False required", + "typeInteger": "Type error: Integer required", + "typeIntMinVal0": "must be an integer with a minimum value of 0", + "typeList": "Type error: List required ", + "typeString": "Type error: String required" }, "webhooks": { "areYouSureDel": "Are you sure you want to delete this webhook?", From ddfc13d9fd9bac1a797e0b388211b47390c67ac4 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Tue, 6 Aug 2024 14:54:03 -0400 Subject: [PATCH 12/74] Include human readable errors in schedule edit/create --- .../routes/api/servers/server/tasks/index.py | 72 ++++++++++++++++--- .../api/servers/server/tasks/task/index.py | 72 ++++++++++++++++--- .../templates/panel/server_schedule_edit.html | 4 +- 3 files changed, 126 insertions(+), 22 deletions(-) diff --git a/app/classes/web/routes/api/servers/server/tasks/index.py b/app/classes/web/routes/api/servers/server/tasks/index.py index ed8b9df9..eba09d8b 100644 --- a/app/classes/web/routes/api/servers/server/tasks/index.py +++ b/app/classes/web/routes/api/servers/server/tasks/index.py @@ -13,18 +13,32 @@ logger = logging.getLogger(__name__) new_task_schema = { "type": "object", "properties": { - "name": {"type": "string"}, + "name": { + "type": "string", + "error": "typeString", + "fill": True, + }, "enabled": { "type": "boolean", "default": True, + "error": "typeBool", + "fill": True, }, "action": { "type": "string", + "error": "typeString", + "fill": True, }, "action_id": { "type": "string", + "error": "typeString", + "fill": True, + }, + "interval": { + "type": "integer", + "error": "typeInteger", + "fill": True, }, - "interval": {"type": "integer"}, "interval_type": { "type": "string", "enum": [ @@ -37,13 +51,43 @@ new_task_schema = { # CRON tasks: "", ], + "error": "enumErr", + "fill": True, + }, + "start_time": { + "type": "string", + "pattern": r"\d{1,2}:\d{1,2}", + "error": "typeString", + "fill": True, + }, + "command": { + "type": ["string", "null"], + "error": "typeString", + "fill": True, + }, + "one_time": { + "type": "boolean", + "default": False, + "error": "typeBool", + "fill": True, + }, + "cron_string": { + "type": "string", + "default": "", + "error": "typeString", + "fill": True, + }, + "parent": { + "type": ["integer", "null"], + "error": "typeInteger", + "fill": True, + }, + "delay": { + "type": "integer", + "default": 0, + "error": "typeInteger", + "fill": True, }, - "start_time": {"type": "string", "pattern": r"\d{1,2}:\d{1,2}"}, - "command": {"type": ["string", "null"]}, - "one_time": {"type": "boolean", "default": False}, - "cron_string": {"type": "string", "default": ""}, - "parent": {"type": ["integer", "null"]}, - "delay": {"type": "integer", "default": 0}, }, "additionalProperties": False, "minProperties": 1, @@ -68,13 +112,21 @@ class ApiServersServerTasksIndexHandler(BaseApiHandler): try: validate(data, new_task_schema) - except ValidationError as e: + except ValidationError as why: + offending_key = "" + if why.schema.get("fill", None): + offending_key = why.path[0] if why.path else None + err = f"""{offending_key} {self.translator.translate( + "validators", + why.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) diff --git a/app/classes/web/routes/api/servers/server/tasks/task/index.py b/app/classes/web/routes/api/servers/server/tasks/task/index.py index 05c8cee9..6a910a4a 100644 --- a/app/classes/web/routes/api/servers/server/tasks/task/index.py +++ b/app/classes/web/routes/api/servers/server/tasks/task/index.py @@ -18,14 +18,24 @@ task_patch_schema = { "enabled": { "type": "boolean", "default": True, + "error": "typeBool", + "fill": True, }, "action": { "type": "string", + "error": "typeString", + "fill": True, }, "action_id": { "type": "string", + "error": "typeString", + "fill": True, + }, + "interval": { + "type": "integer", + "error": "typeInteger", + "fill": True, }, - "interval": {"type": "integer"}, "interval_type": { "type": "string", "enum": [ @@ -38,14 +48,48 @@ task_patch_schema = { # CRON tasks: "", ], + "error": "enumErr", + "fill": True, + }, + "name": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "start_time": { + "type": "string", + "pattern": r"\d{1,2}:\d{1,2}", + "error": "typeString", + "fill": True, + }, + "command": { + "type": ["string", "null"], + "error": "typeString", + "fill": True, + }, + "one_time": { + "type": "boolean", + "default": False, + "error": "typeBool", + "fill": True, + }, + "cron_string": { + "type": "string", + "default": "", + "error": "typeString", + "fill": True, + }, + "parent": { + "type": ["integer", "null"], + "error": "typeInteger", + "fill": True, + }, + "delay": { + "type": "integer", + "default": 0, + "error": "typeInteger", + "fill": True, }, - "name": {"type": "string"}, - "start_time": {"type": "string", "pattern": r"\d{1,2}:\d{1,2}"}, - "command": {"type": ["string", "null"]}, - "one_time": {"type": "boolean", "default": False}, - "cron_string": {"type": "string", "default": ""}, - "parent": {"type": ["integer", "null"]}, - "delay": {"type": "integer", "default": 0}, }, "additionalProperties": False, "minProperties": 1, @@ -114,13 +158,21 @@ class ApiServersServerTasksTaskIndexHandler(BaseApiHandler): try: validate(data, task_patch_schema) - except ValidationError as e: + except ValidationError as why: + offending_key = "" + if why.schema.get("fill", None): + offending_key = why.path[0] if why.path else None + err = f"""{offending_key} {self.translator.translate( + "validators", + why.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) diff --git a/app/frontend/templates/panel/server_schedule_edit.html b/app/frontend/templates/panel/server_schedule_edit.html index 50b48b10..21826ac6 100644 --- a/app/frontend/templates/panel/server_schedule_edit.html +++ b/app/frontend/templates/panel/server_schedule_edit.html @@ -318,8 +318,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } }); From 693cda4239bf2a1945e3f87632f001580caafc8d Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Tue, 6 Aug 2024 18:11:35 -0400 Subject: [PATCH 13/74] Human readable backup errors --- .../servers/server/backups/backup/index.py | 130 +++++++++++++++--- .../api/servers/server/backups/index.py | 95 ++++++++++--- app/translations/en_EN.json | 1 + 3 files changed, 187 insertions(+), 39 deletions(-) diff --git a/app/classes/web/routes/api/servers/server/backups/backup/index.py b/app/classes/web/routes/api/servers/server/backups/backup/index.py index 5d8fd2b5..5d3c0d2a 100644 --- a/app/classes/web/routes/api/servers/server/backups/backup/index.py +++ b/app/classes/web/routes/api/servers/server/backups/backup/index.py @@ -14,7 +14,12 @@ logger = logging.getLogger(__name__) BACKUP_SCHEMA = { "type": "object", "properties": { - "filename": {"type": "string", "minLength": 5}, + "filename": { + "type": "string", + "minLength": 5, + "error": "typeString", + "fill": True, + }, }, "additionalProperties": False, "minProperties": 1, @@ -22,14 +27,47 @@ BACKUP_SCHEMA = { BACKUP_PATCH_SCHEMA = { "type": "object", "properties": { - "backup_name": {"type": "string", "minLength": 3}, - "backup_location": {"type": "string", "minLength": 1}, - "max_backups": {"type": "integer"}, - "compress": {"type": "boolean"}, - "shutdown": {"type": "boolean"}, - "before": {"type": "string"}, - "after": {"type": "string"}, - "excluded_dirs": {"type": "array"}, + "backup_name": { + "type": "string", + "minLength": 3, + "error": "backupName", + }, + "backup_location": { + "type": "string", + "minLength": 1, + "error": "typeString", + "fill": True, + }, + "max_backups": { + "type": "integer", + "error": "typeInteger", + "fill": True, + }, + "compress": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, + "shutdown": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, + "before": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "after": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "excluded_dirs": { + "type": "array", + "error": "typeList", + "fill": True, + }, }, "additionalProperties": False, "minProperties": 1, @@ -38,13 +76,37 @@ BACKUP_PATCH_SCHEMA = { BASIC_BACKUP_PATCH_SCHEMA = { "type": "object", "properties": { - "backup_name": {"type": "string", "minLength": 3}, - "max_backups": {"type": "integer"}, - "compress": {"type": "boolean"}, - "shutdown": {"type": "boolean"}, - "before": {"type": "string"}, - "after": {"type": "string"}, - "excluded_dirs": {"type": "array"}, + "backup_name": {"type": "string", "minLength": 3, "error": "backupName"}, + "max_backups": { + "type": "integer", + "error": "typeInteger", + "fill": True, + }, + "compress": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, + "shutdown": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, + "before": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "after": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "excluded_dirs": { + "type": "array", + "error": "typeList", + "fill": True, + }, }, "additionalProperties": False, "minProperties": 1, @@ -179,13 +241,21 @@ class ApiServersServerBackupsBackupIndexHandler(BaseApiHandler): ) try: validate(data, BACKUP_SCHEMA) - except ValidationError as e: + except ValidationError as why: + offending_key = "" + if why.schema.get("fill", None): + offending_key = why.path[0] if why.path else None + err = f"""{offending_key} {self.translator.translate( + "validators", + why.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) @@ -314,13 +384,21 @@ class ApiServersServerBackupsBackupIndexHandler(BaseApiHandler): validate(data, BACKUP_PATCH_SCHEMA) else: validate(data, BASIC_BACKUP_PATCH_SCHEMA) - except ValidationError as e: + except ValidationError as why: + offending_key = "" + if why.schema.get("fill", None): + offending_key = why.path[0] if why.path else None + err = f"""{offending_key} {self.translator.translate( + "validators", + why.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) backup_conf = self.controller.management.get_backup_config(backup_id) @@ -405,13 +483,21 @@ class ApiServersServerBackupsBackupFilesIndexHandler(BaseApiHandler): ) try: validate(data, BACKUP_SCHEMA) - except ValidationError as e: + except ValidationError as why: + offending_key = "" + if why.schema.get("fill", None): + offending_key = why.path[0] if why.path else None + err = f"""{offending_key} {self.translator.translate( + "validators", + why.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) self.helper.validate_traversal( diff --git a/app/classes/web/routes/api/servers/server/backups/index.py b/app/classes/web/routes/api/servers/server/backups/index.py index a155f943..407fb7cb 100644 --- a/app/classes/web/routes/api/servers/server/backups/index.py +++ b/app/classes/web/routes/api/servers/server/backups/index.py @@ -11,14 +11,43 @@ logger = logging.getLogger(__name__) backup_patch_schema = { "type": "object", "properties": { - "backup_name": {"type": "string", "minLength": 3}, - "backup_location": {"type": "string", "minLength": 1}, - "max_backups": {"type": "integer"}, - "compress": {"type": "boolean"}, - "shutdown": {"type": "boolean"}, - "before": {"type": "string"}, - "after": {"type": "string"}, - "excluded_dirs": {"type": "array"}, + "backup_name": {"type": "string", "minLength": 3, "error": "backupName"}, + "backup_location": { + "type": "string", + "minLength": 1, + "error": "typeString", + "fill": True, + }, + "max_backups": { + "type": "integer", + "error": "typeInteger", + "fill": True, + }, + "compress": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, + "shutdown": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, + "before": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "after": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "excluded_dirs": { + "type": "array", + "error": "typeList", + "fill": True, + }, }, "additionalProperties": False, "minProperties": 1, @@ -27,13 +56,37 @@ backup_patch_schema = { basic_backup_patch_schema = { "type": "object", "properties": { - "backup_name": {"type": "string", "minLength": 3}, - "max_backups": {"type": "integer"}, - "compress": {"type": "boolean"}, - "shutdown": {"type": "boolean"}, - "before": {"type": "string"}, - "after": {"type": "string"}, - "excluded_dirs": {"type": "array"}, + "backup_name": {"type": "string", "minLength": 3, "error": "backupName"}, + "max_backups": { + "type": "integer", + "error": "typeInt", + "fill": True, + }, + "compress": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, + "shutdown": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, + "before": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "after": { + "type": "string", + "error": "typeString", + "fill": True, + }, + "excluded_dirs": { + "type": "array", + "error": "typeList", + "fill": True, + }, }, "additionalProperties": False, "minProperties": 1, @@ -76,13 +129,21 @@ class ApiServersServerBackupsIndexHandler(BaseApiHandler): validate(data, backup_patch_schema) else: validate(data, basic_backup_patch_schema) - except ValidationError as e: + except ValidationError as why: + offending_key = "" + if why.schema.get("fill", None): + offending_key = why.path[0] if why.path else None + err = f"""{offending_key} {self.translator.translate( + "validators", + why.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) if server_id not in [str(x["server_id"]) for x in auth_data[0]]: diff --git a/app/translations/en_EN.json b/app/translations/en_EN.json index d34919d2..26c2f5af 100644 --- a/app/translations/en_EN.json +++ b/app/translations/en_EN.json @@ -668,6 +668,7 @@ "uses": "Number of uses allowed (-1==No Limit)" }, "validators": { + "backupName": "Backup name must be a string and a minimum length of 3.", "enumErr": "failed validating. Acceptable data includes: ", "filesPageLen": "length must be greater than 1 for property", "passLength": "Password Too Short. Minimum Length: 8", From 8b39ba5549ac1faae5109743dbd9970c95eb7876 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Tue, 6 Aug 2024 18:24:30 -0400 Subject: [PATCH 14/74] Refactor users human readable --- app/classes/controllers/users_controller.py | 44 ++++++++++++++++--- app/classes/web/routes/api/users/index.py | 11 +++-- .../web/routes/api/users/user/index.py | 12 ++++- app/translations/en_EN.json | 11 ++--- 4 files changed, 61 insertions(+), 17 deletions(-) diff --git a/app/classes/controllers/users_controller.py b/app/classes/controllers/users_controller.py index d45797bd..7abae8e0 100644 --- a/app/classes/controllers/users_controller.py +++ b/app/classes/controllers/users_controller.py @@ -38,8 +38,8 @@ class UsersController: for permission in PermissionsCrafty.get_permissions_list() ], }, - "quantity": {"type": "number", "minimum": -1}, - "enabled": {"type": "boolean"}, + "quantity": {"type": "number", "minimum": -1, "error": "typeInteger"}, + "enabled": {"type": "boolean", "error": "typeBool"}, } self.user_jsonschema_props: t.Final = { "username": { @@ -49,6 +49,8 @@ class UsersController: "pattern": "^[a-z0-9_]+$", "examples": ["admin"], "title": "Username", + "error": "typeString", + "fill": True, }, "password": { "type": "string", @@ -62,11 +64,15 @@ class UsersController: "format": "email", "examples": ["default@example.com"], "title": "E-Mail", + "error": "typeEmail", + "fill": True, }, "enabled": { "type": "boolean", "examples": [True], "title": "Enabled", + "error": "typeBool", + "fill": True, }, "lang": { "type": "string", @@ -74,16 +80,30 @@ class UsersController: "minLength": 2, "examples": ["en"], "title": "Language", + "error": "typeString", + "fill": True, }, "superuser": { "type": "boolean", "examples": [False], "title": "Superuser", + "error": "typeBool", + "fill": True, + }, + "manager": { + "type": ["integer", "null"], + "error": "typeInteger", + "fill": True, + }, + "theme": { + "type": "string", + "error": "typeString", + "fill": True, }, - "manager": {"type": ["integer", "null"]}, - "theme": {"type": "string"}, "permissions": { "type": "array", + "error": "typeList", + "fill": True, "items": { "type": "object", "properties": _permissions_props, @@ -92,13 +112,25 @@ class UsersController: }, "roles": { "type": "array", + "error": "typeList", + "fill": True, "items": { "type": "integer", "minLength": 1, + "error": "typeInteger", + "fill": True, }, }, - "hints": {"type": "boolean"}, - "server_order": {"type": "string"}, + "hints": { + "type": "boolean", + "error": "typeBool", + "fill": True, + }, + "server_order": { + "type": "string", + "error": "typeString", + "fill": True, + }, } # ********************************************************************************** diff --git a/app/classes/web/routes/api/users/index.py b/app/classes/web/routes/api/users/index.py index 32ebd283..0b021735 100644 --- a/app/classes/web/routes/api/users/index.py +++ b/app/classes/web/routes/api/users/index.py @@ -88,12 +88,15 @@ class ApiUsersIndexHandler(BaseApiHandler): try: validate(data, new_user_schema) - except ValidationError as e: - err = self.translator.translate( + except ValidationError as why: + offending_key = "" + if why.schema.get("fill", None): + offending_key = why.path[0] if why.path else None + err = f"""{offending_key} {self.translator.translate( "validators", - e.schema["error"], + why.schema.get("error"), self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), - ) + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { diff --git a/app/classes/web/routes/api/users/user/index.py b/app/classes/web/routes/api/users/user/index.py index b05e4ac3..391fc5f5 100644 --- a/app/classes/web/routes/api/users/user/index.py +++ b/app/classes/web/routes/api/users/user/index.py @@ -134,13 +134,21 @@ class ApiUsersUserIndexHandler(BaseApiHandler): ) try: validate(data, user_patch_schema) - except ValidationError as e: + except ValidationError as why: + offending_key = "" + if why.schema.get("fill", None): + offending_key = why.path[0] if why.path else None + err = f"""{offending_key} {self.translator.translate( + "validators", + why.schema.get("error"), + self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]), + )} {why.schema.get("enum", "")}""" return self.finish_json( 400, { "status": "error", "error": "INVALID_JSON_SCHEMA", - "error_data": str(e), + "error_data": f"{str(err)}", }, ) if user_id == "@me": diff --git a/app/translations/en_EN.json b/app/translations/en_EN.json index 26c2f5af..fc2c4422 100644 --- a/app/translations/en_EN.json +++ b/app/translations/en_EN.json @@ -680,11 +680,12 @@ "serverExeCommand": "Server execution command must be a string with a minimum length of 1.", "serverLogPath": "Server log path must be a string with a minimum length of 1", "taskIntervalType": "Task Interval Type must be one of the following: ", - "typeBool": "Type error: True or False required", - "typeInteger": "Type error: Integer required", - "typeIntMinVal0": "must be an integer with a minimum value of 0", - "typeList": "Type error: List required ", - "typeString": "Type error: String required" + "typeBool": "must be true or false (type boolean)", + "typeEmail": "must be of type email.", + "typeInteger": "must be a number.", + "typeIntMinVal0": "must be an integer with a minimum value of 0.", + "typeList": "must be of type list/array ", + "typeString": "must be of type string." }, "webhooks": { "areYouSureDel": "Are you sure you want to delete this webhook?", From 877bed101674dc549af9ae7c3c45cf4eeb91b4cc Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Tue, 6 Aug 2024 18:31:05 -0400 Subject: [PATCH 15/74] Fix enum error --- app/classes/controllers/users_controller.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/classes/controllers/users_controller.py b/app/classes/controllers/users_controller.py index 7abae8e0..24d63fc3 100644 --- a/app/classes/controllers/users_controller.py +++ b/app/classes/controllers/users_controller.py @@ -37,9 +37,16 @@ class UsersController: permission.name for permission in PermissionsCrafty.get_permissions_list() ], + "error": "enumErr", + "fill": True, }, - "quantity": {"type": "number", "minimum": -1, "error": "typeInteger"}, - "enabled": {"type": "boolean", "error": "typeBool"}, + "quantity": { + "type": "number", + "minimum": -1, + "error": "typeInteger", + "fill": True, + }, + "enabled": {"type": "boolean", "error": "typeBool", "fill": True}, } self.user_jsonschema_props: t.Final = { "username": { From 1167e46077c52d21942b267a024dbd82b8434940 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 18 Sep 2024 15:46:30 -0400 Subject: [PATCH 16/74] Fix translation error on user page --- app/classes/web/panel_handler.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/classes/web/panel_handler.py b/app/classes/web/panel_handler.py index 8df48431..3dd7d810 100644 --- a/app/classes/web/panel_handler.py +++ b/app/classes/web/panel_handler.py @@ -977,6 +977,8 @@ class PanelHandler(BaseHandler): for file in sorted( os.listdir(os.path.join(self.helper.root_dir, "app", "translations")) ): + if file == "humanized_index.json": + continue if file.endswith(".json"): if file.split(".")[0] not in self.helper.get_setting( "disabled_language_files" From 2d5d31cb6e4fa6df68daa6d1c753a920a23ae8af Mon Sep 17 00:00:00 2001 From: = Date: Wed, 18 Sep 2024 16:10:29 -0400 Subject: [PATCH 17/74] Use error_data for additional info EVERYWHERE --- app/classes/web/base_api_handler.py | 9 +- app/classes/web/public_handler.py | 6 +- app/classes/web/routes/api/auth/login.py | 21 ++- .../routes/api/crafty/announcements/index.py | 9 +- .../web/routes/api/crafty/clogs/index.py | 11 +- .../web/routes/api/crafty/config/index.py | 55 +++++- .../routes/api/crafty/config/server_dir.py | 31 +++- .../web/routes/api/crafty/exe_cache.py | 9 +- .../web/routes/api/crafty/imports/index.py | 9 +- .../web/routes/api/crafty/upload/index.py | 22 ++- app/classes/web/routes/api/not_found.py | 7 +- app/classes/web/routes/api/roles/index.py | 29 +++- .../web/routes/api/roles/role/index.py | 38 ++++- .../web/routes/api/roles/role/servers.py | 11 +- .../web/routes/api/roles/role/users.py | 11 +- app/classes/web/routes/api/servers/index.py | 18 +- .../web/routes/api/servers/server/action.py | 29 +++- .../servers/server/backups/backup/index.py | 5 +- .../api/servers/server/backups/index.py | 33 +++- .../web/routes/api/servers/server/files.py | 158 ++++++++++++++++-- .../web/routes/api/servers/server/history.py | 11 +- .../web/routes/api/servers/server/index.py | 62 ++++++- .../web/routes/api/servers/server/logs.py | 22 ++- .../web/routes/api/servers/server/stats.py | 11 +- .../web/routes/api/servers/server/stdin.py | 39 ++++- .../routes/api/servers/server/tasks/index.py | 22 ++- .../api/servers/server/tasks/task/index.py | 49 +++++- .../web/routes/api/servers/server/users.py | 33 +++- .../api/servers/server/webhooks/index.py | 33 +++- .../servers/server/webhooks/webhook/index.py | 84 +++++++++- app/classes/web/routes/api/users/index.py | 45 ++++- .../web/routes/api/users/user/index.py | 77 ++++++++- app/classes/web/routes/metrics/host.py | 11 +- app/classes/web/routes/metrics/servers.py | 20 ++- .../static/assets/js/shared/root-dir.js | 4 +- .../templates/panel/custom_login.html | 8 +- app/frontend/templates/panel/dashboard.html | 8 +- .../templates/panel/panel_config.html | 12 +- .../templates/panel/panel_edit_user.html | 4 +- .../templates/panel/server_backup.html | 8 +- .../templates/panel/server_backup_edit.html | 8 +- .../templates/panel/server_files.html | 32 ++-- app/frontend/templates/panel/server_logs.html | 4 +- app/frontend/templates/panel/server_term.html | 8 +- .../templates/panel/server_webhook_edit.html | 8 +- .../templates/panel/server_webhooks.html | 8 +- app/frontend/templates/server/wizard.html | 2 +- app/translations/en_EN.json | 4 +- 48 files changed, 986 insertions(+), 172 deletions(-) diff --git a/app/classes/web/base_api_handler.py b/app/classes/web/base_api_handler.py index 9fa028b4..7b7172cd 100644 --- a/app/classes/web/base_api_handler.py +++ b/app/classes/web/base_api_handler.py @@ -11,7 +11,14 @@ class BaseApiHandler(BaseHandler): # {{{ 405 Method Not Allowed as JSON def _unimplemented_method(self, *_args: str, **_kwargs: str) -> None: - self.finish_json(405, {"status": "error", "error": "METHOD_NOT_ALLOWED"}) + self.finish_json( + 405, + { + "status": "error", + "error": "METHOD_NOT_ALLOWED", + "error_data": "METHOD NOT ALLOWED", + }, + ) head = _unimplemented_method # type: Callable[..., Optional[Awaitable[None]]] get = _unimplemented_method # type: Callable[..., Optional[Awaitable[None]]] diff --git a/app/classes/web/public_handler.py b/app/classes/web/public_handler.py index a3d89d25..aa53cdc6 100644 --- a/app/classes/web/public_handler.py +++ b/app/classes/web/public_handler.py @@ -261,7 +261,11 @@ class PublicHandler(BaseHandler): ) return self.finish_json( 403, - {"status": "error", "error": error_msg}, + { + "status": "error", + "error": "INVALID CREDENTIALS", + "error_data": error_msg, + }, ) else: self.redirect("/login?") diff --git a/app/classes/web/routes/api/auth/login.py b/app/classes/web/routes/api/auth/login.py index 7e8131f3..a8c57d64 100644 --- a/app/classes/web/routes/api/auth/login.py +++ b/app/classes/web/routes/api/auth/login.py @@ -68,7 +68,12 @@ class ApiAuthLoginHandler(BaseApiHandler): ) return self.finish_json( 401, - {"status": "error", "error": "INCORRECT_CREDENTIALS", "token": None}, + { + "status": "error", + "error": "INCORRECT_CREDENTIALS", + "error_data": "INVALID CREDENTIALS", + "token": None, + }, ) if not user_data.enabled: @@ -78,7 +83,13 @@ class ApiAuthLoginHandler(BaseApiHandler): f" IP {self.get_remote_ip()} account disabled" ) self.finish_json( - 403, {"status": "error", "error": "ACCOUNT_DISABLED", "token": None} + 403, + { + "status": "error", + "error": "ACCOUNT_DISABLED", + "error_data": "ACCOUNT DISABLED", + "token": None, + }, ) return @@ -123,5 +134,9 @@ class ApiAuthLoginHandler(BaseApiHandler): ) self.finish_json( 401, - {"status": "error", "error": "INCORRECT_CREDENTIALS"}, + { + "status": "error", + "error": "INCORRECT_CREDENTIALS", + "error_data": "INCORRECT CREDENTIALS", + }, ) diff --git a/app/classes/web/routes/api/crafty/announcements/index.py b/app/classes/web/routes/api/crafty/announcements/index.py index d66c4473..74306deb 100644 --- a/app/classes/web/routes/api/crafty/announcements/index.py +++ b/app/classes/web/routes/api/crafty/announcements/index.py @@ -115,7 +115,14 @@ class ApiAnnounceIndexHandler(BaseApiHandler): if str(data["id"]) in str(res): cleared_notifs.append(data["id"]) else: - self.finish_json(200, {"status": "error", "error": "INVALID_DATA"}) + self.finish_json( + 200, + { + "status": "error", + "error": "INVALID_DATA", + "error_data": "INVALID NOTIFICATION ID", + }, + ) return updata = {"cleared_notifs": ",".join(cleared_notifs)} self.controller.users.update_user(auth_data[4]["user_id"], updata) diff --git a/app/classes/web/routes/api/crafty/clogs/index.py b/app/classes/web/routes/api/crafty/clogs/index.py index 35f48a7f..12b38d38 100644 --- a/app/classes/web/routes/api/crafty/clogs/index.py +++ b/app/classes/web/routes/api/crafty/clogs/index.py @@ -18,7 +18,16 @@ class ApiCraftyLogIndexHandler(BaseApiHandler): ) = auth_data if not superuser: - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) log_types = ["audit", "session", "schedule"] if log_type not in log_types: diff --git a/app/classes/web/routes/api/crafty/config/index.py b/app/classes/web/routes/api/crafty/config/index.py index 42065d72..10edeb4f 100644 --- a/app/classes/web/routes/api/crafty/config/index.py +++ b/app/classes/web/routes/api/crafty/config/index.py @@ -169,7 +169,16 @@ class ApiCraftyConfigIndexHandler(BaseApiHandler): get_only_ids = self.get_query_argument("ids", None) == "true" if not superuser: - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) self.finish_json( 200, @@ -192,7 +201,16 @@ class ApiCraftyConfigIndexHandler(BaseApiHandler): (_, _, _, superuser, user, _) = auth_data if not superuser: - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) try: data = orjson.loads(self.request.body) @@ -255,7 +273,16 @@ class ApiCraftyCustomizeIndexHandler(BaseApiHandler): get_only_ids = self.get_query_argument("ids", None) == "true" if not superuser: - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) self.finish_json( 200, @@ -284,7 +311,16 @@ class ApiCraftyCustomizeIndexHandler(BaseApiHandler): _, ) = auth_data if not superuser: - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) try: data = orjson.loads(self.request.body) @@ -350,7 +386,16 @@ class ApiCraftyCustomizeIndexHandler(BaseApiHandler): return if not auth_data[4]["superuser"]: - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) try: data = json.loads(self.request.body) diff --git a/app/classes/web/routes/api/crafty/config/server_dir.py b/app/classes/web/routes/api/crafty/config/server_dir.py index 106964c3..7a512529 100644 --- a/app/classes/web/routes/api/crafty/config/server_dir.py +++ b/app/classes/web/routes/api/crafty/config/server_dir.py @@ -31,7 +31,16 @@ class ApiCraftyConfigServerDirHandler(BaseApiHandler): get_only_ids = self.get_query_argument("ids", None) == "true" if not superuser: - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) self.finish_json( 200, @@ -61,10 +70,26 @@ class ApiCraftyConfigServerDirHandler(BaseApiHandler): ) = auth_data if not auth_data: - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": "NOT AUTHORIZED", + }, + ) if not auth_data[4]["superuser"]: - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) if self.helper.is_env_docker(): raise NotImplementedError diff --git a/app/classes/web/routes/api/crafty/exe_cache.py b/app/classes/web/routes/api/crafty/exe_cache.py index 7fa9743a..89ab5122 100644 --- a/app/classes/web/routes/api/crafty/exe_cache.py +++ b/app/classes/web/routes/api/crafty/exe_cache.py @@ -16,7 +16,14 @@ class ApiCraftyJarCacheIndexHandler(BaseApiHandler): ) = auth_data if not auth_data[4]["superuser"]: - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": "NOT A SUPER USER", + }, + ) self.controller.big_bucket.manual_refresh_cache() self.finish_json( diff --git a/app/classes/web/routes/api/crafty/imports/index.py b/app/classes/web/routes/api/crafty/imports/index.py index 9487b31c..83d3a539 100644 --- a/app/classes/web/routes/api/crafty/imports/index.py +++ b/app/classes/web/routes/api/crafty/imports/index.py @@ -52,7 +52,14 @@ class ApiImportFilesIndexHandler(BaseApiHandler): and not auth_data[4]["superuser"] ): # if the user doesn't have Files or Backup permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": "INSUFFICEN PERMISSIONS", + }, + ) try: data = json.loads(self.request.body) diff --git a/app/classes/web/routes/api/crafty/upload/index.py b/app/classes/web/routes/api/crafty/upload/index.py index b37ef796..ff56fed1 100644 --- a/app/classes/web/routes/api/crafty/upload/index.py +++ b/app/classes/web/routes/api/crafty/upload/index.py @@ -47,7 +47,14 @@ class ApiFilesUploadHandler(BaseApiHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error return self.finish_json( - 400, {"status": "error", "error": "NOT_AUTHORIZED"} + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, ) mask = self.controller.server_perms.get_lowest_api_perm_mask( self.controller.server_perms.get_user_permissions_mask( @@ -60,7 +67,14 @@ class ApiFilesUploadHandler(BaseApiHandler): if EnumPermissionsServer.FILES not in server_permissions: # if the user doesn't have Files permission, return an error return self.finish_json( - 400, {"status": "error", "error": "NOT_AUTHORIZED"} + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, ) u_type = "server_upload" @@ -111,9 +125,9 @@ class ApiFilesUploadHandler(BaseApiHandler): try: file_size = int(self.request.headers.get("fileSize", None)) total_chunks = int(self.request.headers.get("totalChunks", 0)) - except TypeError: + except TypeError as why: return self.finish_json( - 400, {"status": "error", "error": "TYPE ERROR", "data": {}} + 400, {"status": "error", "error": "TYPE ERROR", "error_data": {why}} ) self.chunk_index = self.request.headers.get("chunkId") if u_type == "server_upload": diff --git a/app/classes/web/routes/api/not_found.py b/app/classes/web/routes/api/not_found.py index ae5a1cb9..466d9a46 100644 --- a/app/classes/web/routes/api/not_found.py +++ b/app/classes/web/routes/api/not_found.py @@ -6,7 +6,12 @@ class ApiNotFoundHandler(BaseApiHandler): def _not_found(self, page: str) -> None: self.finish_json( 404, - {"status": "error", "error": "API_HANDLER_NOT_FOUND", "page": page}, + { + "status": "error", + "error": "API_HANDLER_NOT_FOUND", + "error_data": f"{page} not found", + "page": page, + }, ) head = _not_found # type: Callable[..., Optional[Awaitable[None]]] diff --git a/app/classes/web/routes/api/roles/index.py b/app/classes/web/routes/api/roles/index.py index 8ea494e5..caf14135 100644 --- a/app/classes/web/routes/api/roles/index.py +++ b/app/classes/web/routes/api/roles/index.py @@ -97,7 +97,16 @@ class ApiRolesIndexHandler(BaseApiHandler): not superuser and EnumPermissionsCrafty.ROLES_CONFIG not in exec_user_permissions_crafty ): - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) self.finish_json( 200, @@ -130,7 +139,16 @@ class ApiRolesIndexHandler(BaseApiHandler): not superuser and EnumPermissionsCrafty.ROLES_CONFIG not in exec_user_permissions_crafty ): - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) try: data = orjson.loads(self.request.body) @@ -183,7 +201,12 @@ class ApiRolesIndexHandler(BaseApiHandler): if self.controller.roles.get_roleid_by_name(role_name) is not None: return self.finish_json( - 400, {"status": "error", "error": "ROLE_NAME_ALREADY_EXISTS"} + 400, + { + "status": "error", + "error": "ROLE_NAME_ALREADY_EXISTS", + "error_data": "UNIQUE VALUE ERROR", + }, ) role_id = self.controller.roles.add_role_advanced(role_name, servers, manager) diff --git a/app/classes/web/routes/api/roles/role/index.py b/app/classes/web/routes/api/roles/role/index.py index b013f167..8d1f3487 100644 --- a/app/classes/web/routes/api/roles/role/index.py +++ b/app/classes/web/routes/api/roles/role/index.py @@ -93,15 +93,26 @@ class ApiRolesRoleIndexHandler(BaseApiHandler): not superuser and EnumPermissionsCrafty.ROLES_CONFIG not in exec_user_permissions_crafty ): - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) try: self.finish_json( 200, {"status": "ok", "data": self.controller.roles.get_role(role_id)}, ) - except DoesNotExist: - self.finish_json(404, {"status": "error", "error": "ROLE_NOT_FOUND"}) + except DoesNotExist as why: + self.finish_json( + 404, {"status": "error", "error": "ROLE_NOT_FOUND", "error_data": why} + ) def delete(self, role_id: str): auth_data = self.authenticate_user() @@ -120,7 +131,16 @@ class ApiRolesRoleIndexHandler(BaseApiHandler): str(role.get("manager", "no manager found")) != str(auth_data[4]["user_id"]) and not superuser ): - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) self.controller.roles.remove_role(role_id) @@ -206,11 +226,13 @@ class ApiRolesRoleIndexHandler(BaseApiHandler): data.get("servers", None), manager, ) - except DoesNotExist: - return self.finish_json(404, {"status": "error", "error": "ROLE_NOT_FOUND"}) - except IntegrityError: + except DoesNotExist as why: return self.finish_json( - 404, {"status": "error", "error": "ROLE_NAME_EXISTS"} + 404, {"status": "error", "error": "ROLE_NOT_FOUND", "error_data": why} + ) + except IntegrityError as why: + return self.finish_json( + 404, {"status": "error", "error": "ROLE_NAME_EXISTS", "error_data": why} ) self.controller.management.add_to_audit_log( user["user_id"], diff --git a/app/classes/web/routes/api/roles/role/servers.py b/app/classes/web/routes/api/roles/role/servers.py index 8f41f6c6..f0a14e88 100644 --- a/app/classes/web/routes/api/roles/role/servers.py +++ b/app/classes/web/routes/api/roles/role/servers.py @@ -20,7 +20,16 @@ class ApiRolesRoleServersHandler(BaseApiHandler): get_only_ids = self.get_query_argument("ids", None) == "true" if not superuser: - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) self.finish_json( 200, diff --git a/app/classes/web/routes/api/roles/role/users.py b/app/classes/web/routes/api/roles/role/users.py index 48444ead..24bbd534 100644 --- a/app/classes/web/routes/api/roles/role/users.py +++ b/app/classes/web/routes/api/roles/role/users.py @@ -16,7 +16,16 @@ class ApiRolesRoleUsersHandler(BaseApiHandler): ) = auth_data if not superuser: - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) all_user_ids = self.controller.users.get_all_user_ids() diff --git a/app/classes/web/routes/api/servers/index.py b/app/classes/web/routes/api/servers/index.py index 8d822653..f2e96f25 100644 --- a/app/classes/web/routes/api/servers/index.py +++ b/app/classes/web/routes/api/servers/index.py @@ -818,7 +818,16 @@ class ApiServersIndexHandler(BaseApiHandler): ) = auth_data if EnumPermissionsCrafty.SERVER_CREATION not in exec_user_crafty_permissions: - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) try: data = orjson.loads(self.request.body) @@ -858,7 +867,12 @@ class ApiServersIndexHandler(BaseApiHandler): port = 19132 if port > 65535 or port < 1: self.finish_json( - 405, {"status": "error", "error": "DATA CONSTRAINT FAILED"} + 405, + { + "status": "error", + "error": "DATA CONSTRAINT FAILED", + "error_data": "1 - 65535", + }, ) return new_server_id = self.controller.create_api_server(data, user["user_id"]) diff --git a/app/classes/web/routes/api/servers/server/action.py b/app/classes/web/routes/api/servers/server/action.py index d8e58b2f..8278a453 100644 --- a/app/classes/web/routes/api/servers/server/action.py +++ b/app/classes/web/routes/api/servers/server/action.py @@ -18,7 +18,16 @@ class ApiServersServerActionHandler(BaseApiHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) mask = self.controller.server_perms.get_lowest_api_perm_mask( self.controller.server_perms.get_user_permissions_mask( auth_data[4]["user_id"], server_id @@ -28,7 +37,16 @@ class ApiServersServerActionHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.COMMANDS not in server_permissions: # if the user doesn't have Commands permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) if action == "clone_server": if ( @@ -49,7 +67,12 @@ class ApiServersServerActionHandler(BaseApiHandler): self._clone_server(server_id, auth_data[4]["user_id"]) return self.finish_json(200, {"status": "ok"}) return self.finish_json( - 200, {"status": "error", "error": "SERVER_LIMIT_REACHED"} + 200, + { + "status": "error", + "error": "SERVER_LIMIT_REACHED", + "error_data": "LIMIT REACHED", + }, ) if action == "eula": return self._agree_eula(server_id, auth_data[4]["user_id"]) diff --git a/app/classes/web/routes/api/servers/server/backups/backup/index.py b/app/classes/web/routes/api/servers/server/backups/backup/index.py index 5d3c0d2a..03666b4b 100644 --- a/app/classes/web/routes/api/servers/server/backups/backup/index.py +++ b/app/classes/web/routes/api/servers/server/backups/backup/index.py @@ -272,7 +272,8 @@ class ApiServersServerBackupsBackupIndexHandler(BaseApiHandler): temp_dir = Helpers.unzip_backup_archive(backup_location, zip_name) except (FileNotFoundError, NotADirectoryError) as e: return self.finish_json( - 400, {"status": "error", "error": f"NO BACKUP FOUND {e}"} + 400, + {"status": "error", "error": "NO BACKUP FOUND", "error_data": e}, ) if server_data["type"] == "minecraft-java": new_server = self.controller.restore_java_zip_server( @@ -518,7 +519,7 @@ class ApiServersServerBackupsBackupFilesIndexHandler(BaseApiHandler): ) except Exception as e: return self.finish_json( - 400, {"status": "error", "error": f"DELETE FAILED with error {e}"} + 400, {"status": "error", "error": "DELETE FAILED", "error_data": e} ) self.controller.management.add_to_audit_log( auth_data[4]["user_id"], diff --git a/app/classes/web/routes/api/servers/server/backups/index.py b/app/classes/web/routes/api/servers/server/backups/index.py index 407fb7cb..641321e7 100644 --- a/app/classes/web/routes/api/servers/server/backups/index.py +++ b/app/classes/web/routes/api/servers/server/backups/index.py @@ -107,7 +107,16 @@ class ApiServersServerBackupsIndexHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.BACKUP not in server_permissions: # if the user doesn't have Schedule permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) self.finish_json( 200, self.controller.management.get_backups_by_server(server_id) ) @@ -148,7 +157,16 @@ class ApiServersServerBackupsIndexHandler(BaseApiHandler): ) if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) mask = self.controller.server_perms.get_lowest_api_perm_mask( self.controller.server_perms.get_user_permissions_mask( auth_data[4]["user_id"], server_id @@ -158,7 +176,16 @@ class ApiServersServerBackupsIndexHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.BACKUP not in server_permissions: # if the user doesn't have Schedule permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) # Set the backup location automatically for non-super users. We should probably # make the default location configurable for SU eventually if not auth_data[4]["superuser"]: diff --git a/app/classes/web/routes/api/servers/server/files.py b/app/classes/web/routes/api/servers/server/files.py index 8e8fb108..78818674 100644 --- a/app/classes/web/routes/api/servers/server/files.py +++ b/app/classes/web/routes/api/servers/server/files.py @@ -125,7 +125,16 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) mask = self.controller.server_perms.get_lowest_api_perm_mask( self.controller.server_perms.get_user_permissions_mask( auth_data[4]["user_id"], server_id @@ -138,7 +147,16 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler): and EnumPermissionsServer.BACKUP not in server_permissions ): # if the user doesn't have Files or Backup permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) try: data = json.loads(self.request.body) @@ -256,7 +274,16 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) mask = self.controller.server_perms.get_lowest_api_perm_mask( self.controller.server_perms.get_user_permissions_mask( auth_data[4]["user_id"], server_id @@ -266,7 +293,16 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.FILES not in server_permissions: # if the user doesn't have Files permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) try: data = json.loads(self.request.body) except json.decoder.JSONDecodeError as e: @@ -313,7 +349,9 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler): # but not a true boolean value if proc == True: # pylint: disable=singleton-comparison return self.finish_json(200, {"status": "ok"}) - return self.finish_json(500, {"status": "error", "error": str(proc)}) + return self.finish_json( + 500, {"status": "error", "error": "SERVER RUNNING", "error_data": str(proc)} + ) def patch(self, server_id: str, _backup_id): auth_data = self.authenticate_user() @@ -322,7 +360,16 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) mask = self.controller.server_perms.get_lowest_api_perm_mask( self.controller.server_perms.get_user_permissions_mask( auth_data[4]["user_id"], server_id @@ -332,7 +379,16 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.FILES not in server_permissions: # if the user doesn't have Files permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) try: data = json.loads(self.request.body) except json.decoder.JSONDecodeError as e: @@ -384,7 +440,16 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) mask = self.controller.server_perms.get_lowest_api_perm_mask( self.controller.server_perms.get_user_permissions_mask( auth_data[4]["user_id"], server_id @@ -394,7 +459,16 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.FILES not in server_permissions: # if the user doesn't have Files permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) try: data = json.loads(self.request.body) except json.decoder.JSONDecodeError as e: @@ -459,7 +533,16 @@ class ApiServersServerFilesCreateHandler(BaseApiHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) mask = self.controller.server_perms.get_lowest_api_perm_mask( self.controller.server_perms.get_user_permissions_mask( auth_data[4]["user_id"], server_id @@ -469,7 +552,16 @@ class ApiServersServerFilesCreateHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.FILES not in server_permissions: # if the user doesn't have Files permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) try: data = json.loads(self.request.body) except json.decoder.JSONDecodeError as e: @@ -533,7 +625,16 @@ class ApiServersServerFilesCreateHandler(BaseApiHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) mask = self.controller.server_perms.get_lowest_api_perm_mask( self.controller.server_perms.get_user_permissions_mask( auth_data[4]["user_id"], server_id @@ -543,7 +644,16 @@ class ApiServersServerFilesCreateHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.FILES not in server_permissions: # if the user doesn't have Files permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) try: data = json.loads(self.request.body) except json.decoder.JSONDecodeError as e: @@ -608,7 +718,16 @@ class ApiServersServerFilesZipHandler(BaseApiHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) mask = self.controller.server_perms.get_lowest_api_perm_mask( self.controller.server_perms.get_user_permissions_mask( auth_data[4]["user_id"], server_id @@ -618,7 +737,16 @@ class ApiServersServerFilesZipHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.FILES not in server_permissions: # if the user doesn't have Files permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) try: data = json.loads(self.request.body) except json.decoder.JSONDecodeError as e: diff --git a/app/classes/web/routes/api/servers/server/history.py b/app/classes/web/routes/api/servers/server/history.py index 1a4aac24..55ff785d 100644 --- a/app/classes/web/routes/api/servers/server/history.py +++ b/app/classes/web/routes/api/servers/server/history.py @@ -14,7 +14,16 @@ class ApiServersServerHistoryHandler(BaseApiHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) srv = ServersController().get_server_instance_by_id(server_id) history = srv.get_server_history() diff --git a/app/classes/web/routes/api/servers/server/index.py b/app/classes/web/routes/api/servers/server/index.py index c54170cf..46a4a40d 100644 --- a/app/classes/web/routes/api/servers/server/index.py +++ b/app/classes/web/routes/api/servers/server/index.py @@ -186,7 +186,16 @@ class ApiServersServerIndexHandler(BaseApiHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) server_obj = self.controller.servers.get_server_obj(server_id) server = model_to_dict(server_obj) @@ -233,7 +242,16 @@ class ApiServersServerIndexHandler(BaseApiHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) mask = self.controller.server_perms.get_lowest_api_perm_mask( self.controller.server_perms.get_user_permissions_mask( auth_data[4]["user_id"], server_id @@ -243,7 +261,16 @@ class ApiServersServerIndexHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.CONFIG not in server_permissions: # if the user doesn't have Config permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) server_obj = self.controller.servers.get_server_obj(server_id) java_flag = False @@ -257,7 +284,12 @@ class ApiServersServerIndexHandler(BaseApiHandler): setattr(server_obj, "execution_command", command) except ValueError: return self.finish_json( - 400, {"status": "error", "error": "INVALID EXECUTION COMMAND"} + 400, + { + "status": "error", + "error": "INVALID EXECUTION COMMAND", + "error_data": "INVALID COMMAND", + }, ) java_flag = True @@ -286,7 +318,16 @@ class ApiServersServerIndexHandler(BaseApiHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) mask = self.controller.server_perms.get_lowest_api_perm_mask( self.controller.server_perms.get_user_permissions_mask( auth_data[4]["user_id"], server_id @@ -296,7 +337,16 @@ class ApiServersServerIndexHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.CONFIG not in server_permissions: # if the user doesn't have Config permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) logger.info( ( diff --git a/app/classes/web/routes/api/servers/server/logs.py b/app/classes/web/routes/api/servers/server/logs.py index eb6ede00..8ee6ad3d 100644 --- a/app/classes/web/routes/api/servers/server/logs.py +++ b/app/classes/web/routes/api/servers/server/logs.py @@ -29,7 +29,16 @@ class ApiServersServerLogsHandler(BaseApiHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) mask = self.controller.server_perms.get_lowest_api_perm_mask( self.controller.server_perms.get_user_permissions_mask( auth_data[4]["user_id"], server_id @@ -39,7 +48,16 @@ class ApiServersServerLogsHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.LOGS not in server_permissions: # if the user doesn't have Logs permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) server_data = self.controller.servers.get_server_data_by_id(server_id) diff --git a/app/classes/web/routes/api/servers/server/stats.py b/app/classes/web/routes/api/servers/server/stats.py index 2e220d2b..f316d9fc 100644 --- a/app/classes/web/routes/api/servers/server/stats.py +++ b/app/classes/web/routes/api/servers/server/stats.py @@ -14,7 +14,16 @@ class ApiServersServerStatsHandler(BaseApiHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) srv = ServersController().get_server_instance_by_id(server_id) latest = srv.stats_helper.get_latest_server_stats() diff --git a/app/classes/web/routes/api/servers/server/stdin.py b/app/classes/web/routes/api/servers/server/stdin.py index ca2cd7d9..432460c7 100644 --- a/app/classes/web/routes/api/servers/server/stdin.py +++ b/app/classes/web/routes/api/servers/server/stdin.py @@ -15,7 +15,16 @@ class ApiServersServerStdinHandler(BaseApiHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) mask = self.controller.server_perms.get_lowest_api_perm_mask( self.controller.server_perms.get_user_permissions_mask( auth_data[4]["user_id"], server_id @@ -25,7 +34,16 @@ class ApiServersServerStdinHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.COMMANDS not in server_permissions: # if the user doesn't have Commands permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) svr = self.controller.servers.get_server_obj_optional(server_id) if svr is None: @@ -35,7 +53,16 @@ class ApiServersServerStdinHandler(BaseApiHandler): "Crafty can't access the server object. " "Please report this to the devs" ) - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) decoded = self.request.body.decode("utf-8") self.controller.management.add_to_audit_log( auth_data[4]["user_id"], @@ -50,5 +77,9 @@ class ApiServersServerStdinHandler(BaseApiHandler): ) self.finish_json( 200, - {"status": "error", "error": "SERVER_NOT_RUNNING"}, + { + "status": "error", + "error": "SERVER_NOT_RUNNING", + "error_data": "SERVER NOT RUNNING", + }, ) diff --git a/app/classes/web/routes/api/servers/server/tasks/index.py b/app/classes/web/routes/api/servers/server/tasks/index.py index eba09d8b..8933e7b8 100644 --- a/app/classes/web/routes/api/servers/server/tasks/index.py +++ b/app/classes/web/routes/api/servers/server/tasks/index.py @@ -132,7 +132,16 @@ class ApiServersServerTasksIndexHandler(BaseApiHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) mask = self.controller.server_perms.get_lowest_api_perm_mask( self.controller.server_perms.get_user_permissions_mask( auth_data[4]["user_id"], server_id @@ -142,7 +151,16 @@ class ApiServersServerTasksIndexHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.SCHEDULE not in server_permissions: # if the user doesn't have Schedule permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) data["server_id"] = server_id if not data.get("start_time"): data["start_time"] = "00:00" diff --git a/app/classes/web/routes/api/servers/server/tasks/task/index.py b/app/classes/web/routes/api/servers/server/tasks/task/index.py index 6a910a4a..6eda0a7b 100644 --- a/app/classes/web/routes/api/servers/server/tasks/task/index.py +++ b/app/classes/web/routes/api/servers/server/tasks/task/index.py @@ -110,7 +110,16 @@ class ApiServersServerTasksTaskIndexHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.SCHEDULE not in server_permissions: # if the user doesn't have Schedule permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) self.finish_json(200, self.controller.management.get_scheduled_task(task_id)) def delete(self, server_id: str, task_id: str): @@ -126,13 +135,23 @@ class ApiServersServerTasksTaskIndexHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.SCHEDULE not in server_permissions: # if the user doesn't have Schedule permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) try: self.tasks_manager.remove_job(task_id) - except Exception: + except Exception as why: return self.finish_json( - 400, {"status": "error", "error": "NO SCHEDULE FOUND"} + 400, + {"status": "error", "error": "NO SCHEDULE FOUND", "error_data": why}, ) self.controller.management.add_to_audit_log( auth_data[4]["user_id"], @@ -178,7 +197,16 @@ class ApiServersServerTasksTaskIndexHandler(BaseApiHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) mask = self.controller.server_perms.get_lowest_api_perm_mask( self.controller.server_perms.get_user_permissions_mask( auth_data[4]["user_id"], server_id @@ -188,7 +216,16 @@ class ApiServersServerTasksTaskIndexHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.SCHEDULE not in server_permissions: # if the user doesn't have Schedule permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) # Checks to make sure some doofus didn't actually make the newly # created task a child of itself. diff --git a/app/classes/web/routes/api/servers/server/users.py b/app/classes/web/routes/api/servers/server/users.py index c4df8832..82d0c870 100644 --- a/app/classes/web/routes/api/servers/server/users.py +++ b/app/classes/web/routes/api/servers/server/users.py @@ -14,13 +14,40 @@ class ApiServersServerUsersHandler(BaseApiHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) if EnumPermissionsCrafty.USER_CONFIG not in auth_data[1]: - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) if EnumPermissionsCrafty.ROLES_CONFIG not in auth_data[1]: - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) self.finish_json( 200, diff --git a/app/classes/web/routes/api/servers/server/webhooks/index.py b/app/classes/web/routes/api/servers/server/webhooks/index.py index 35bbdbeb..860276b5 100644 --- a/app/classes/web/routes/api/servers/server/webhooks/index.py +++ b/app/classes/web/routes/api/servers/server/webhooks/index.py @@ -76,7 +76,16 @@ class ApiServersServerWebhooksIndexHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.CONFIG not in server_permissions: # if the user doesn't have Schedule permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) self.finish_json( 200, { @@ -119,7 +128,16 @@ class ApiServersServerWebhooksIndexHandler(BaseApiHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) mask = self.controller.server_perms.get_lowest_api_perm_mask( self.controller.server_perms.get_user_permissions_mask( auth_data[4]["user_id"], server_id @@ -129,7 +147,16 @@ class ApiServersServerWebhooksIndexHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.CONFIG not in server_permissions: # if the user doesn't have Schedule permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) data["server_id"] = server_id self.controller.management.add_to_audit_log( diff --git a/app/classes/web/routes/api/servers/server/webhooks/webhook/index.py b/app/classes/web/routes/api/servers/server/webhooks/webhook/index.py index d530ffa0..369d3895 100644 --- a/app/classes/web/routes/api/servers/server/webhooks/webhook/index.py +++ b/app/classes/web/routes/api/servers/server/webhooks/webhook/index.py @@ -77,13 +77,27 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.CONFIG not in server_permissions: # if the user doesn't have Schedule permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) if ( not str(webhook_id) in self.controller.management.get_webhooks_by_server(server_id).keys() ): return self.finish_json( - 400, {"status": "error", "error": "NO WEBHOOK FOUND"} + 400, + { + "status": "error", + "error": "NO WEBHOOK FOUND", + "error_data": "NOT FOUND", + }, ) self.finish_json( 200, @@ -106,13 +120,27 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.CONFIG not in server_permissions: # if the user doesn't have Schedule permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) try: self.controller.management.delete_webhook(webhook_id) except Exception: return self.finish_json( - 400, {"status": "error", "error": "NO WEBHOOK FOUND"} + 400, + { + "status": "error", + "error": "NO WEBHOOK FOUND", + "error_data": "NOT FOUND", + }, ) self.controller.management.add_to_audit_log( auth_data[4]["user_id"], @@ -157,7 +185,16 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) mask = self.controller.server_perms.get_lowest_api_perm_mask( self.controller.server_perms.get_user_permissions_mask( auth_data[4]["user_id"], server_id @@ -167,7 +204,16 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.CONFIG not in server_permissions: # if the user doesn't have Schedule permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) data["server_id"] = server_id if "trigger" in data.keys(): @@ -200,7 +246,16 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler): ) if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) mask = self.controller.server_perms.get_lowest_api_perm_mask( self.controller.server_perms.get_user_permissions_mask( auth_data[4]["user_id"], server_id @@ -210,7 +265,16 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler): server_permissions = self.controller.server_perms.get_permissions(mask) if EnumPermissionsServer.CONFIG not in server_permissions: # if the user doesn't have Schedule permission, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) webhook = self.controller.management.get_webhook_by_id(webhook_id) try: webhook_provider = WebhookFactory.create_provider(webhook["webhook_type"]) @@ -225,6 +289,8 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler): bot_name="Crafty Webhooks Tester", ) except Exception as e: - self.finish_json(500, {"status": "error", "error": str(e)}) + self.finish_json( + 500, {"status": "error", "error": "WEBHOOK ERROR", "error_data": str(e)} + ) self.finish_json(200, {"status": "ok"}) diff --git a/app/classes/web/routes/api/users/index.py b/app/classes/web/routes/api/users/index.py index 0b021735..be0d3f09 100644 --- a/app/classes/web/routes/api/users/index.py +++ b/app/classes/web/routes/api/users/index.py @@ -77,7 +77,16 @@ class ApiUsersIndexHandler(BaseApiHandler): ) = auth_data if EnumPermissionsCrafty.USER_CONFIG not in exec_user_crafty_permissions: - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) try: data = json.loads(self.request.body) @@ -128,11 +137,23 @@ class ApiUsersIndexHandler(BaseApiHandler): if username.lower() in ["system", ""]: return self.finish_json( - 400, {"status": "error", "error": "INVALID_USERNAME"} + 400, + { + "status": "error", + "error": "INVALID_USERNAME", + "error_data": "INVALID USERNAME", + }, ) if self.controller.users.get_id_by_name(username) is not None: - return self.finish_json(400, {"status": "error", "error": "USER_EXISTS"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "USER_EXISTS", + "error_data": "UNIQUE VALUE ERROR", + }, + ) if roles is None: roles = set() @@ -158,7 +179,14 @@ class ApiUsersIndexHandler(BaseApiHandler): if new_superuser and not superuser: return self.finish_json( - 400, {"status": "error", "error": "INVALID_SUPERUSER_CREATE"} + 400, + { + "status": "error", + "error": "INVALID_SUPERUSER_CREATE", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, ) for role in roles: @@ -169,7 +197,14 @@ class ApiUsersIndexHandler(BaseApiHandler): and not superuser ): return self.finish_json( - 400, {"status": "error", "error": "INVALID_ROLES_CREATE"} + 400, + { + "status": "error", + "error": "INVALID_ROLES_CREATE", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, ) # TODO: do this in the most efficient way diff --git a/app/classes/web/routes/api/users/user/index.py b/app/classes/web/routes/api/users/user/index.py index 391fc5f5..68770dfa 100644 --- a/app/classes/web/routes/api/users/user/index.py +++ b/app/classes/web/routes/api/users/user/index.py @@ -169,7 +169,12 @@ class ApiUsersUserIndexHandler(BaseApiHandler): if "username" in data: if data["username"].lower() in ["system", ""]: return self.finish_json( - 400, {"status": "error", "error": "INVALID_USERNAME"} + 400, + { + "status": "error", + "error": "INVALID_USERNAME", + "error_data": "INVALID USERNAME", + }, ) if self.controller.users.get_id_by_name( data["username"] @@ -179,7 +184,12 @@ class ApiUsersUserIndexHandler(BaseApiHandler): user_id ): return self.finish_json( - 400, {"status": "error", "error": "USER_EXISTS"} + 400, + { + "status": "error", + "error": "USER_EXISTS", + "error_data": "UNIQUE CONSTAINT FAILED", + }, ) if "superuser" in data: @@ -187,7 +197,14 @@ class ApiUsersUserIndexHandler(BaseApiHandler): # Checks if user is trying to change super user status # of self without superuser. We don't want that. return self.finish_json( - 400, {"status": "error", "error": "INVALID_SUPERUSER_MODIFY"} + 400, + { + "status": "error", + "error": "INVALID_SUPERUSER_MODIFY", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, ) if not superuser: # The user is not superuser so they can't change the superuser status @@ -198,13 +215,27 @@ class ApiUsersUserIndexHandler(BaseApiHandler): # Checks if user is trying to change permissions # of self without superuser. We don't want that. return self.finish_json( - 400, {"status": "error", "error": "INVALID_PERMISSIONS_MODIFY"} + 400, + { + "status": "error", + "error": "INVALID_PERMISSIONS_MODIFY", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, ) if EnumPermissionsCrafty.USER_CONFIG not in exec_user_crafty_permissions: # Checks if user is trying to change permissions of someone # else without User Config permission. We don't want that. return self.finish_json( - 400, {"status": "error", "error": "INVALID_PERMISSIONS_MODIFY"} + 400, + { + "status": "error", + "error": "INVALID_PERMISSIONS_MODIFY", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, ) if "roles" in data: @@ -212,13 +243,27 @@ class ApiUsersUserIndexHandler(BaseApiHandler): # Checks if user is trying to change roles of # self without superuser. We don't want that. return self.finish_json( - 400, {"status": "error", "error": "INVALID_ROLES_MODIFY"} + 400, + { + "status": "error", + "error": "INVALID_ROLES_MODIFY", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, ) if EnumPermissionsCrafty.USER_CONFIG not in exec_user_crafty_permissions: # Checks if user is trying to change roles of someone # else without User Config permission. We don't want that. return self.finish_json( - 400, {"status": "error", "error": "INVALID_ROLES_MODIFY"} + 400, + { + "status": "error", + "error": "INVALID_ROLES_MODIFY", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, ) user_modify = self.controller.users.get_user_roles_id(user_id) @@ -237,7 +282,14 @@ class ApiUsersUserIndexHandler(BaseApiHandler): for item in user_modify: print(type(role), type(item)) return self.finish_json( - 400, {"status": "error", "error": "INVALID_ROLES_MODIFY"} + 400, + { + "status": "error", + "error": "INVALID_ROLES_MODIFY", + "error_data": self.helper.translation.translate( + "error", "no-file", auth_data[4]["lang"] + ), + }, ) user_obj = HelperUsers.get_user_model(user_id) @@ -245,7 +297,14 @@ class ApiUsersUserIndexHandler(BaseApiHandler): if str(user["user_id"]) != str(user_obj.manager) and not user["superuser"]: # TODO: edit your own password return self.finish_json( - 400, {"status": "error", "error": "INVALID_PASSWORD_MODIFY"} + 400, + { + "status": "error", + "error": "INVALID_PASSWORD_MODIFY", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, ) if "roles" in data: diff --git a/app/classes/web/routes/metrics/host.py b/app/classes/web/routes/metrics/host.py index fc4af9c5..6a65496f 100644 --- a/app/classes/web/routes/metrics/host.py +++ b/app/classes/web/routes/metrics/host.py @@ -13,7 +13,16 @@ class ApiOpenMetricsCraftyHandler(BaseMetricsHandler): if not auth_data[3]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) self.get_registry() diff --git a/app/classes/web/routes/metrics/servers.py b/app/classes/web/routes/metrics/servers.py index 7f374ec1..f2ec00cd 100644 --- a/app/classes/web/routes/metrics/servers.py +++ b/app/classes/web/routes/metrics/servers.py @@ -14,13 +14,29 @@ class ApiOpenMetricsServersHandler(BaseMetricsHandler): if server_id not in [str(x["server_id"]) for x in auth_data[0]]: # if the user doesn't have access to the server, return an error - return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) + return self.finish_json( + 400, + { + "status": "error", + "error": "NOT_AUTHORIZED", + "error_data": self.helper.translation.translate( + "validators", "insufficientPerms", auth_data[4]["lang"] + ), + }, + ) self.get_registry(server_id) def get_registry(self, server_id=None) -> None: if server_id is None: - return self.finish_json(500, {"status": "error", "error": "UNKNOWN_SERVER"}) + return self.finish_json( + 500, + { + "status": "error", + "error": "UNKNOWN_SERVER", + "error_data": "UNKNOWN SERVER", + }, + ) # Prepare parameters registry = ( diff --git a/app/frontend/static/assets/js/shared/root-dir.js b/app/frontend/static/assets/js/shared/root-dir.js index 1f82c2f5..9e4a878d 100644 --- a/app/frontend/static/assets/js/shared/root-dir.js +++ b/app/frontend/static/assets/js/shared/root-dir.js @@ -55,8 +55,8 @@ async function getTreeView(path, unzip = false, upload = false) { } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } } diff --git a/app/frontend/templates/panel/custom_login.html b/app/frontend/templates/panel/custom_login.html index 84af79e6..534cfe57 100644 --- a/app/frontend/templates/panel/custom_login.html +++ b/app/frontend/templates/panel/custom_login.html @@ -325,8 +325,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } }) @@ -349,8 +349,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } }) diff --git a/app/frontend/templates/panel/dashboard.html b/app/frontend/templates/panel/dashboard.html index e5cc46d4..4d017158 100644 --- a/app/frontend/templates/panel/dashboard.html +++ b/app/frontend/templates/panel/dashboard.html @@ -617,8 +617,8 @@ setTimeout(function(){ $('.modal').modal('hide'); bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); }, 2000) } @@ -1024,8 +1024,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } } diff --git a/app/frontend/templates/panel/panel_config.html b/app/frontend/templates/panel/panel_config.html index fee5c65d..8fad0c86 100644 --- a/app/frontend/templates/panel/panel_config.html +++ b/app/frontend/templates/panel/panel_config.html @@ -372,8 +372,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } } @@ -410,8 +410,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } } @@ -451,8 +451,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } }); diff --git a/app/frontend/templates/panel/panel_edit_user.html b/app/frontend/templates/panel/panel_edit_user.html index fdb5afd8..49fae048 100644 --- a/app/frontend/templates/panel/panel_edit_user.html +++ b/app/frontend/templates/panel/panel_edit_user.html @@ -122,7 +122,7 @@ data['lang']) }}{% end %} name="lang" form="user_form"> {% for lang in data['languages'] %} {% if not 'incomplete' in lang %} - + {% else %} {% end %} @@ -547,7 +547,7 @@ data['lang']) }}{% end %} bootbox.alert({ title: responseData.error, - message: responseData.error + message: responseData.error_data }); } } diff --git a/app/frontend/templates/panel/server_backup.html b/app/frontend/templates/panel/server_backup.html index 73fde1cc..297bd173 100644 --- a/app/frontend/templates/panel/server_backup.html +++ b/app/frontend/templates/panel/server_backup.html @@ -266,8 +266,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } return; @@ -485,8 +485,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } } diff --git a/app/frontend/templates/panel/server_backup_edit.html b/app/frontend/templates/panel/server_backup_edit.html index 078c0231..41ab53ae 100644 --- a/app/frontend/templates/panel/server_backup_edit.html +++ b/app/frontend/templates/panel/server_backup_edit.html @@ -342,8 +342,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } return; @@ -676,8 +676,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } } diff --git a/app/frontend/templates/panel/server_files.html b/app/frontend/templates/panel/server_files.html index d116681b..04e9c962 100644 --- a/app/frontend/templates/panel/server_files.html +++ b/app/frontend/templates/panel/server_files.html @@ -429,8 +429,8 @@ else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } } @@ -605,8 +605,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } } @@ -627,8 +627,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } } @@ -650,8 +650,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } } @@ -672,8 +672,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } } @@ -695,8 +695,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } } @@ -717,8 +717,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } } @@ -841,8 +841,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } } diff --git a/app/frontend/templates/panel/server_logs.html b/app/frontend/templates/panel/server_logs.html index 3605adba..237e61e1 100644 --- a/app/frontend/templates/panel/server_logs.html +++ b/app/frontend/templates/panel/server_logs.html @@ -212,8 +212,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } } diff --git a/app/frontend/templates/panel/server_term.html b/app/frontend/templates/panel/server_term.html index 7467781a..1d7c662f 100644 --- a/app/frontend/templates/panel/server_term.html +++ b/app/frontend/templates/panel/server_term.html @@ -189,8 +189,8 @@ console.log("Command received successfully") } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } } @@ -256,8 +256,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } } diff --git a/app/frontend/templates/panel/server_webhook_edit.html b/app/frontend/templates/panel/server_webhook_edit.html index 80610a49..c0e351cf 100644 --- a/app/frontend/templates/panel/server_webhook_edit.html +++ b/app/frontend/templates/panel/server_webhook_edit.html @@ -218,8 +218,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } }); @@ -259,8 +259,8 @@ } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } }); diff --git a/app/frontend/templates/panel/server_webhooks.html b/app/frontend/templates/panel/server_webhooks.html index 432b0148..d64df6d6 100644 --- a/app/frontend/templates/panel/server_webhooks.html +++ b/app/frontend/templates/panel/server_webhooks.html @@ -359,8 +359,8 @@ } else { console.log(responseData); bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } } @@ -379,8 +379,8 @@ window.location.reload(); } else { bootbox.alert({ - title: responseData.status, - message: responseData.error + title: responseData.error, + message: responseData.error_data }); } } diff --git a/app/frontend/templates/server/wizard.html b/app/frontend/templates/server/wizard.html index 40c09ec2..ff9ab978 100644 --- a/app/frontend/templates/server/wizard.html +++ b/app/frontend/templates/server/wizard.html @@ -1099,7 +1099,7 @@ bootbox.alert({ title: responseData.error, - message: responseData.error + message: responseData.error_data }); } } diff --git a/app/translations/en_EN.json b/app/translations/en_EN.json index fc2c4422..c9fbe5b0 100644 --- a/app/translations/en_EN.json +++ b/app/translations/en_EN.json @@ -671,6 +671,7 @@ "backupName": "Backup name must be a string and a minimum length of 3.", "enumErr": "failed validating. Acceptable data includes: ", "filesPageLen": "length must be greater than 1 for property", + "insufficientPerms": "Permission Error: Missing permissions for this resource", "passLength": "Password Too Short. Minimum Length: 8", "roleManager": "Role manager must be of type integer (manager ID) or None", "roleName": "Role name must be a string that is greater than 1 character. It must not include any of the following symbols: [ ] , ", @@ -685,7 +686,8 @@ "typeInteger": "must be a number.", "typeIntMinVal0": "must be an integer with a minimum value of 0.", "typeList": "must be of type list/array ", - "typeString": "must be of type string." + "typeString": "must be of type string.", + "userName": " must be of type string, all LOWERCASE, a minimum of 4 characters and a max of 20 characters" }, "webhooks": { "areYouSureDel": "Are you sure you want to delete this webhook?", From db7a3cfde81f0efe1107c3ca9e30afa18a4e3053 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 18 Sep 2024 16:10:41 -0400 Subject: [PATCH 18/74] Use more descript username error --- app/classes/controllers/users_controller.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/classes/controllers/users_controller.py b/app/classes/controllers/users_controller.py index 24d63fc3..75ab41ef 100644 --- a/app/classes/controllers/users_controller.py +++ b/app/classes/controllers/users_controller.py @@ -56,7 +56,7 @@ class UsersController: "pattern": "^[a-z0-9_]+$", "examples": ["admin"], "title": "Username", - "error": "typeString", + "error": "userName", "fill": True, }, "password": { From 9f5a214b6023da2d574578d1aac93b66bbc55ef5 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 20 Sep 2024 12:59:12 -0400 Subject: [PATCH 19/74] Fix malformed data errors --- app/classes/minecraft/mc_ping.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/classes/minecraft/mc_ping.py b/app/classes/minecraft/mc_ping.py index 72a91351..df63ae01 100644 --- a/app/classes/minecraft/mc_ping.py +++ b/app/classes/minecraft/mc_ping.py @@ -77,8 +77,8 @@ class Server: class Players(list): def __init__(self, data): super().__init__(Player(x) for x in data.get("sample", [])) - self.max = data["max"] - self.online = data["online"] + self.max = data.get("max", 0) + self.online = data.get("online", 0) def report(self): players = [] @@ -93,8 +93,8 @@ class Players(list): class Player: def __init__(self, data): - self.id = data["id"] - self.name = data["name"] + self.id = data.get("id", "") + self.name = data("name", "Anonymous") def __str__(self): return self.name @@ -174,7 +174,7 @@ def ping(ip, port): logger.debug(f"Server reports this data on ping: {data}") try: return Server(json.loads(data)) - except KeyError: + except (KeyError, json.decoder.JSONDecodeError): return {} finally: sock.close() From 9140899a3259bb5f9fb79e7ce6a98d6fa3983ddb Mon Sep 17 00:00:00 2001 From: Analicia Abernathy Date: Tue, 1 Oct 2024 17:56:41 -0500 Subject: [PATCH 20/74] ran .gitlab scripts --- app/translations/en_EN.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/translations/en_EN.json b/app/translations/en_EN.json index c9fbe5b0..511e3e59 100644 --- a/app/translations/en_EN.json +++ b/app/translations/en_EN.json @@ -683,8 +683,8 @@ "taskIntervalType": "Task Interval Type must be one of the following: ", "typeBool": "must be true or false (type boolean)", "typeEmail": "must be of type email.", - "typeInteger": "must be a number.", "typeIntMinVal0": "must be an integer with a minimum value of 0.", + "typeInteger": "must be a number.", "typeList": "must be of type list/array ", "typeString": "must be of type string.", "userName": " must be of type string, all LOWERCASE, a minimum of 4 characters and a max of 20 characters" @@ -714,4 +714,4 @@ "webhook_body": "Webhook Body", "webhooks": "Webhooks" } -} \ No newline at end of file +} From f65899c0f9a49f6dd3a80b3bbd531f9f57c2f6af Mon Sep 17 00:00:00 2001 From: Analicia Abernathy Date: Tue, 1 Oct 2024 17:59:31 -0500 Subject: [PATCH 21/74] translations for lv_LV and nl_BE --- app/translations/lv_LV.json | 21 ++++++++++++++++++++- app/translations/nl_BE.json | 21 ++++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/app/translations/lv_LV.json b/app/translations/lv_LV.json index 96753531..322b6b1f 100644 --- a/app/translations/lv_LV.json +++ b/app/translations/lv_LV.json @@ -673,7 +673,26 @@ "uses": "Dauzums, cik reizes lietot (-1==Bez Limita)" }, "validators": { - "passLength": "Parole pārāk īsa. Minimālais Garums: 8" + "passLength": "Parole pārāk īsa. Minimālais Garums: 8", + "backupName": "Dublējuma nosaukumam jābūt tekstam (string) ar minimālo garumu 3.", + "enumErr": "pārbaude neizdevās. Pieņemamie dati ietver: ", + "filesPageLen": "garumam jābūt lielākam par 1 priekš vienības", + "insufficientPerms": "Piekļuves Kļūda: Nepietiekama atļauja priekš šī resursa", + "roleManager": "Lomas pārvaldniekam jābūt skaitlim (pārvaldnieka ID) vai Nekam (None)", + "roleName": "Lomas nosaukumam jābūt tekstam (string) kas ir garāks par 1 rakstzīmi. Tas nevar iekļaut sekojošos simbolus: [ ] , ", + "roleServerId": "Servera ID vienībai jābūt tekstam (string) ar minimālo garumu 1", + "roleServerPerms": "Servera atļaujām jābūt 8-bitu tekstam (string)", + "serverCreateName": "Servera nosaukumam jābūt tekstam (string) ar minimumālo garumu 2 un tas nevar saturēt: \\ / vai # ", + "serverExeCommand": "Servera izpildes komandai jābūt tekstam (string) ar minimālo garumu 1.", + "serverLogPath": "Servera log datņu ceļam ir jābūt tekstam (string) ar minimālo garumu 1", + "taskIntervalType": "Notikumu Intervala Tipam jābūt vienam no sekojošiem: ", + "typeBool": "jābūt patiesam vai nepatiesam (true vai false, boolean tips)", + "typeEmail": "jābūt tipam e-pasts.", + "typeInteger": "jābūt skaitlim.", + "typeIntMinVal0": "jābūt skaitlim (integer) ar minimālo vērtību 0.", + "typeList": "jābūt tipam saraksts/masīvs (list/array) ", + "typeString": "jābūt tipam teksts (string).", + "userName": " jābūt tipam teksts (string), tikai ar MAZAJIEM BURTIEM, ar 4 rakstzīmju minimālo un 20 rakstzīmju maksimālo garumu" }, "webhooks": { "areYouSureDel": "Vai tiešām vēlies noņemt šo webhook?", diff --git a/app/translations/nl_BE.json b/app/translations/nl_BE.json index d776a0aa..bc67111e 100644 --- a/app/translations/nl_BE.json +++ b/app/translations/nl_BE.json @@ -672,7 +672,26 @@ "uses": "Aantal toegestane gebruiken (-1==Geen Limiet)" }, "validators": { - "passLength": "Wachtwoord te kort. Minimumlengte: 8 tekens" + "passLength": "Wachtwoord te kort. Minimumlengte: 8 tekens", + "backupName": "De naam van de back-up moet een string zijn en een minimale lengte van 3 hebben.", + "enumErr": "validatie mislukt. Accepteerbare gegevens zijn: ", + "filesPageLen": "De lengte moet groter zijn dan 1 voor eigenschap", + "insufficientPerms": "Machtigingsfout: Ontbrekende machtigingen voor deze resource", + "roleManager": "Rollenbeheerder moet van het type integer (manager-ID) of None zijn", + "roleName": "De rolnaam moet een string zijn die groter is dan 1 teken. Deze mag geen van de volgende symbolen bevatten: [ ] , ", + "roleServerId": "De eigenschap Server ID moet een string zijn met een minimale lengte van 1", + "roleServerPerms": "Servermachtigingen moeten een 8-bits string zijn", + "serverCreateName": "De servernaam moet een string zijn met een minimale lengte van 2 en mag niet bevatten: \\ / of # ", + "serverExeCommand": "Het serveruitvoeringscommando moet een string zijn met een minimale lengte van 1.", + "serverLogPath": "Het pad naar het serverlogboek moet een string zijn met een minimale lengte van 1", + "taskIntervalType": "Het type taakinterval moet een van de volgende zijn: ", + "typeBool": "moet true of false zijn (type boolean)", + "typeEmail": "moet van het type e-mail zijn.", + "typeInteger": "moet een getal zijn.", + "typeIntMinVal0": "moet een geheel getal zijn met een minimale waarde van 0.", + "typeList": "moet van het type lijst/array zijn ", + "typeString": "moet van het type string zijn.", + "userName": " moet van het type string zijn, volledig in KLEINE LETTERS, minimaal 4 tekens en maximaal 20 tekens" }, "webhooks": { "areYouSureDel": "Weet u zeker dat u deze webhook wilt verwijderen?", From 01bb0b12298137a18f3f87679ee4c026a6185b9c Mon Sep 17 00:00:00 2001 From: = Date: Thu, 3 Oct 2024 12:45:03 -0400 Subject: [PATCH 22/74] Strip EXIF data to secure photo location --- .../web/routes/api/crafty/upload/index.py | 16 ++++++++++++++++ requirements.txt | 1 + 2 files changed, 17 insertions(+) diff --git a/app/classes/web/routes/api/crafty/upload/index.py b/app/classes/web/routes/api/crafty/upload/index.py index b37ef796..e1500792 100644 --- a/app/classes/web/routes/api/crafty/upload/index.py +++ b/app/classes/web/routes/api/crafty/upload/index.py @@ -1,6 +1,7 @@ import os import logging import shutil +from PIL import Image from app.classes.models.server_permissions import EnumPermissionsServer from app.classes.shared.helpers import Helpers from app.classes.web.base_api_handler import BaseApiHandler @@ -281,6 +282,21 @@ class ApiFilesUploadHandler(BaseApiHandler): with open(chunk_file, "rb") as infile: outfile.write(infile.read()) os.remove(chunk_file) + if upload_type == "background": + # Strip EXIF data + image_path = os.path.join(file_path) + logger.debug("Stripping exif data from image") + image = Image.open(image_path) + + # Get current raw pixel data from image + image_data = list(image.getdata()) + # Create new image + image_no_exif = Image.new(image.mode, image.size) + # Restore pixel data + image_no_exif.putdata(image_data) + + image_no_exif.save(image_path) + logger.info( f"File upload completed. Filename: {self.filename}" f" Path: {file_path} Type: {u_type}" diff --git a/requirements.txt b/requirements.txt index 2ca0ff8b..743da0a8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -20,3 +20,4 @@ tzlocal==5.1 jsonschema==4.19.1 orjson==3.9.15 prometheus-client==0.17.1 +pillow==10.4.0 \ No newline at end of file From 5e1d7ed4bd023c9ecb5ec3c2ca337f1d6681dd78 Mon Sep 17 00:00:00 2001 From: Zedifus Date: Wed, 16 Oct 2024 21:15:45 +0100 Subject: [PATCH 23/74] Bump requests to 2.32.0 -> 2.32.3 Resolves yanked ver: 2.32.0 Conflics w/ CVE-2024-35195 mitigation --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 99415099..7bc5ae87 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,7 +13,7 @@ psutil==5.9.5 pyOpenSSL==24.2.1 pyjwt==2.8.0 PyYAML==6.0.1 -requests==2.32.0 +requests==2.32.3 termcolor==1.1 tornado==6.4.1 tzlocal==5.1 From 8d91cd7ec5d8bcc449c3bff132a119f0c2802bcf Mon Sep 17 00:00:00 2001 From: Zedifus Date: Wed, 16 Oct 2024 21:20:11 +0100 Subject: [PATCH 24/74] Update changelog !808 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35b6066d..251cf6c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ### New features TBD ### Bug fixes -TBD +- Bump requests to resolve yank for CVE-2024-35195 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/808)) ### Tweaks TBD ### Lang From e3af7e612e54de0f399ffade9a4e31d153911864 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 19 Nov 2024 15:40:01 -0500 Subject: [PATCH 25/74] Remove incomplete for new workflow --- app/translations/{fi_FI_incomplete.json => fi_FI.json} | 0 app/translations/{fy_NL_incomplete.json => fy_NL.json} | 0 app/translations/{hr_HR_incomplete.json => hr_HR.json} | 0 app/translations/{id_ID_incomplete.json => id_ID.json} | 0 app/translations/{nl_NL_incomplete.json => nl_NL.json} | 0 app/translations/{pt_BR_incomplete.json => pt_BR.json} | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename app/translations/{fi_FI_incomplete.json => fi_FI.json} (100%) rename app/translations/{fy_NL_incomplete.json => fy_NL.json} (100%) rename app/translations/{hr_HR_incomplete.json => hr_HR.json} (100%) rename app/translations/{id_ID_incomplete.json => id_ID.json} (100%) rename app/translations/{nl_NL_incomplete.json => nl_NL.json} (100%) rename app/translations/{pt_BR_incomplete.json => pt_BR.json} (100%) diff --git a/app/translations/fi_FI_incomplete.json b/app/translations/fi_FI.json similarity index 100% rename from app/translations/fi_FI_incomplete.json rename to app/translations/fi_FI.json diff --git a/app/translations/fy_NL_incomplete.json b/app/translations/fy_NL.json similarity index 100% rename from app/translations/fy_NL_incomplete.json rename to app/translations/fy_NL.json diff --git a/app/translations/hr_HR_incomplete.json b/app/translations/hr_HR.json similarity index 100% rename from app/translations/hr_HR_incomplete.json rename to app/translations/hr_HR.json diff --git a/app/translations/id_ID_incomplete.json b/app/translations/id_ID.json similarity index 100% rename from app/translations/id_ID_incomplete.json rename to app/translations/id_ID.json diff --git a/app/translations/nl_NL_incomplete.json b/app/translations/nl_NL.json similarity index 100% rename from app/translations/nl_NL_incomplete.json rename to app/translations/nl_NL.json diff --git a/app/translations/pt_BR_incomplete.json b/app/translations/pt_BR.json similarity index 100% rename from app/translations/pt_BR_incomplete.json rename to app/translations/pt_BR.json From 5058d0ee36c5d24b87388c885b6a739918d91990 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 19 Nov 2024 15:51:06 -0500 Subject: [PATCH 26/74] Remove empty translations --- app/translations/cs_CS.json | 6 +++--- app/translations/de_DE.json | 6 +++--- app/translations/en_EN.json | 6 +++--- app/translations/es_ES.json | 6 +++--- app/translations/fi_FI.json | 4 ++-- app/translations/fr_FR.json | 6 +++--- app/translations/fy_NL.json | 4 ++-- app/translations/he_IL.json | 6 +++--- app/translations/hr_HR.json | 4 ++-- app/translations/id_ID.json | 4 ++-- app/translations/it_IT.json | 6 +++--- app/translations/lol_EN.json | 6 +++--- app/translations/lv_LV.json | 6 +++--- app/translations/nl_BE.json | 6 +++--- app/translations/nl_NL.json | 2 +- app/translations/pl_PL.json | 6 +++--- app/translations/pt_BR.json | 4 ++-- app/translations/ru_RU.json | 6 +++--- app/translations/th_TH.json | 6 +++--- app/translations/tr_TR.json | 6 +++--- app/translations/uk_UA.json | 6 +++--- app/translations/zh_CN.json | 6 +++--- 22 files changed, 59 insertions(+), 59 deletions(-) diff --git a/app/translations/cs_CS.json b/app/translations/cs_CS.json index 72b4ecd0..c7ab617b 100644 --- a/app/translations/cs_CS.json +++ b/app/translations/cs_CS.json @@ -149,12 +149,12 @@ "pdf": "PDF", "print": "Tisk" }, - "decimal": "", + "decimal": ".", "emptyTable": "V tabulce nejsou k dispozici žádné údaje", "info": "Zobrazeno _START_ až _END_ z _TOTAL_ záznamů", "infoEmpty": "Zobrazeno 0 až 0 z 0 záznamů", "infoFiltered": "(filtrováno z _MAX_ celkových záznamů)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "Zobrazit položky _MENU_", "loadingRecords": "Načítání...", "paginate": { @@ -718,4 +718,4 @@ "webhook_body": "Webhook Body", "webhooks": "Webhooky" } -} +} \ No newline at end of file diff --git a/app/translations/de_DE.json b/app/translations/de_DE.json index ae55ed5b..4716fda8 100644 --- a/app/translations/de_DE.json +++ b/app/translations/de_DE.json @@ -143,12 +143,12 @@ "pdf": "PDF", "print": "Drucken" }, - "decimal": "", + "decimal": ".", "emptyTable": "Keine Daten in der Tabelle verfügbar", "info": "Zeige _START_ bis _END_ von insges. _TOTAL_ Einträge(n)", "infoEmpty": "Zeige 0 bis 0 von insges. 0 Einträgen", "infoFiltered": "(gefiltert von _MAX_ maximalen Einträgen)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "Zeige _MENU_ Einträge", "loadingRecords": "Laden...", "paginate": { @@ -699,4 +699,4 @@ "webhook_body": "Webhook-Inhalt", "webhooks": "Webhooks" } -} +} \ No newline at end of file diff --git a/app/translations/en_EN.json b/app/translations/en_EN.json index f4b79bd0..cd401a56 100644 --- a/app/translations/en_EN.json +++ b/app/translations/en_EN.json @@ -142,12 +142,12 @@ "pdf": "PDF", "print": "Print" }, - "decimal": "", + "decimal": ".", "emptyTable": "No data available in table", "info": "Showing _START_ to _END_ of _TOTAL_ entries", "infoEmpty": "Showing 0 to 0 of 0 entries", "infoFiltered": "(filtered from _MAX_ total entries)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "Show _MENU_ entries", "loadingRecords": "Loading...", "paginate": { @@ -699,4 +699,4 @@ "webhook_body": "Webhook Body", "webhooks": "Webhooks" } -} +} \ No newline at end of file diff --git a/app/translations/es_ES.json b/app/translations/es_ES.json index 5a58c75b..53448405 100644 --- a/app/translations/es_ES.json +++ b/app/translations/es_ES.json @@ -143,12 +143,12 @@ "pdf": "PDF", "print": "Imprimir" }, - "decimal": "", + "decimal": ".", "emptyTable": "No hay datos disponibles en la tabla", "info": "Mostrando _START_ hasta _END_ de _TOTAL_ entradas", "infoEmpty": "Mostrando 0 de 0 entradas", "infoFiltered": "(filtrado de _MAX_ entradas totales)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "Mostrar entradas de _MENU_", "loadingRecords": "Cargando...", "paginate": { @@ -699,4 +699,4 @@ "webhook_body": "Cuerpo del Webhook", "webhooks": "Webhooks" } -} +} \ No newline at end of file diff --git a/app/translations/fi_FI.json b/app/translations/fi_FI.json index 14a7d6dc..5ed58acc 100644 --- a/app/translations/fi_FI.json +++ b/app/translations/fi_FI.json @@ -127,12 +127,12 @@ "pdf": "PDF", "print": "Tulosta" }, - "decimal": "", + "decimal": ".", "emptyTable": "Tietoja ei löytynyt", "info": "Näytetään rivit _START_ - _END_ (yhteensä _TOTAL_ )", "infoEmpty": "Näytetään 0 - 0 (yhteensä 0)", "infoFiltered": "(suodatettu _MAX_ tuloksen joukosta)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "Näytä kerralla _MENU_ riviä", "loadingRecords": "Ladataan...", "paginate": { diff --git a/app/translations/fr_FR.json b/app/translations/fr_FR.json index 137e4455..d25de966 100644 --- a/app/translations/fr_FR.json +++ b/app/translations/fr_FR.json @@ -143,12 +143,12 @@ "pdf": "PDF", "print": "Imprimer" }, - "decimal": "", + "decimal": ".", "emptyTable": "Aucune donnée disponible dans le table", "info": "Affichage de _START_ to _END_ entrées sur _TOTAL_", "infoEmpty": "Affichage des entrées 0 à 0 sur 0 entrées", "infoFiltered": "(filtré sur un total de _MAX_ entrées)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "Afficher _MENU_ entrées", "loadingRecords": "Chargement ...", "paginate": { @@ -699,4 +699,4 @@ "webhook_body": "Corps du Webhook", "webhooks": "Webhooks" } -} +} \ No newline at end of file diff --git a/app/translations/fy_NL.json b/app/translations/fy_NL.json index 54105eab..a1658298 100644 --- a/app/translations/fy_NL.json +++ b/app/translations/fy_NL.json @@ -126,12 +126,12 @@ "pdf": "PDF", "print": "Ôfdrukke" }, - "decimal": "", + "decimal": ".", "emptyTable": "Gjin gegevens beskikber yn tabel", "info": "Toant _START_ oant _END_ fan _TOTAL_ ynstjoerings", "infoEmpty": "Toant 0 oan 0 fan 0 ynstjoerings", "infoFiltered": "(filtrearre út _MAX_ totaal ynstjoerings)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "Lit _MENU_ ynstjoerings sjen", "loadingRecords": "Laden...", "paginate": { diff --git a/app/translations/he_IL.json b/app/translations/he_IL.json index f17a60b4..1283d7d9 100644 --- a/app/translations/he_IL.json +++ b/app/translations/he_IL.json @@ -143,12 +143,12 @@ "pdf": "PDF", "print": "הדפסה" }, - "decimal": "", + "decimal": ".", "emptyTable": "אין נתונים זמינים בטבלה", "info": "רשומות _TOTAL_ מ _END_ עד _START_ מראה", "infoEmpty": "מציג 0 עד 0 מתוך 0 ערכים", "infoFiltered": "(רשומות _MAX_ מסונן מתוך)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "רשומות _MENU_ הצגת", "loadingRecords": "...טוען", "paginate": { @@ -699,4 +699,4 @@ "webhook_body": "גוף ה-Webhook", "webhooks": "Webhooks" } -} +} \ No newline at end of file diff --git a/app/translations/hr_HR.json b/app/translations/hr_HR.json index 975741e7..ce99c5db 100644 --- a/app/translations/hr_HR.json +++ b/app/translations/hr_HR.json @@ -126,12 +126,12 @@ "pdf": "PDF", "print": "Isprintaj" }, - "decimal": "", + "decimal": ".", "emptyTable": "Nema dostupnih podataka u tablici", "info": "Prikazuje se _START_ do _END_ od _TOTAL_ unosa", "infoEmpty": "Prikazuje se 0 do 0 od 0 unosa", "infoFiltered": "(filtrirano od ukupno _MAX_ unosa)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "Prikaži _MENU_ unose", "loadingRecords": "Učitavanje...", "paginate": { diff --git a/app/translations/id_ID.json b/app/translations/id_ID.json index c7a1fb6f..c0494e42 100644 --- a/app/translations/id_ID.json +++ b/app/translations/id_ID.json @@ -127,12 +127,12 @@ "pdf": "PDF", "print": "Print" }, - "decimal": "", + "decimal": ".", "emptyTable": "Tidak Ada Data Yang Ada Di Meja", "info": "Showing _START_ to _END_ of _TOTAL_ entries", "infoEmpty": "Showing 0 to 0 of 0 entries", "infoFiltered": "(filtered from _MAX_ total entries)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "Show _MENU_ entries", "loadingRecords": "Loading...", "paginate": { diff --git a/app/translations/it_IT.json b/app/translations/it_IT.json index a3ce46e2..3d9a0e34 100644 --- a/app/translations/it_IT.json +++ b/app/translations/it_IT.json @@ -143,12 +143,12 @@ "pdf": "PDF", "print": "Stampa" }, - "decimal": "", + "decimal": ".", "emptyTable": "Nessun dato disponibile nella tabella", "info": "Mostro da _START_ a _END_ di _TOTAL_ record", "infoEmpty": "Mostro da 0 a 0 di 0 record", "infoFiltered": "(filtrato da _MAX_ record totali)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "Mostra _MENU_ record", "loadingRecords": "Carico...", "paginate": { @@ -699,4 +699,4 @@ "webhook_body": "Corpo del Webhook", "webhooks": "Webhook" } -} +} \ No newline at end of file diff --git a/app/translations/lol_EN.json b/app/translations/lol_EN.json index 6941a662..44675983 100644 --- a/app/translations/lol_EN.json +++ b/app/translations/lol_EN.json @@ -143,12 +143,12 @@ "pdf": "PDF", "print": "Print" }, - "decimal": "", + "decimal": ".", "emptyTable": "No data available in table", "info": "Showing _START_ to _END_ of _TOTAL_ entries", "infoEmpty": "Showing 0 to 0 of 0 entries", "infoFiltered": "(filtered from _MAX_ total entries)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "Show _MENU_ entries", "loadingRecords": "Loading...", "paginate": { @@ -699,4 +699,4 @@ "webhook_body": "WEBHOOK FISH", "webhooks": "WEBHOOKZ" } -} +} \ No newline at end of file diff --git a/app/translations/lv_LV.json b/app/translations/lv_LV.json index 64274784..ec68e6c1 100644 --- a/app/translations/lv_LV.json +++ b/app/translations/lv_LV.json @@ -144,12 +144,12 @@ "pdf": "PDF", "print": "Drukāt" }, - "decimal": "", + "decimal": ".", "emptyTable": "Tabulā nav pieejami dati", "info": "Attēlo _START_ līdz _END_ no _TOTAL_ ierakstiem", "infoEmpty": "Attēlo 0 līdz 0 no 0 ierakstiem", "infoFiltered": "(filtrēts no _MAX_ kopējiem ierkstiem)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "Attēlo _MENU_ ierakstus", "loadingRecords": "Ielādē...", "paginate": { @@ -704,4 +704,4 @@ "webhook_body": "Webhook Saturs", "webhooks": "Webhooki" } -} +} \ No newline at end of file diff --git a/app/translations/nl_BE.json b/app/translations/nl_BE.json index c75654f4..3c01207b 100644 --- a/app/translations/nl_BE.json +++ b/app/translations/nl_BE.json @@ -143,12 +143,12 @@ "pdf": "PDF", "print": "Afdrukken" }, - "decimal": "", + "decimal": ".", "emptyTable": "Geen data beschikbaar in de tabel", "info": "_START_ tot _END_ van _TOTAL_ inzendingen weergeven", "infoEmpty": "0 tot 0 van 0 items weergeven", "infoFiltered": "(gefilterd uit _MAX_ totale inzendingen)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "Toon _MENU_ items", "loadingRecords": "Bezig met laden...", "paginate": { @@ -703,4 +703,4 @@ "webhook_body": "Webhook-body", "webhooks": "Webhooks" } -} +} \ No newline at end of file diff --git a/app/translations/nl_NL.json b/app/translations/nl_NL.json index 53db0def..8cf88ecf 100644 --- a/app/translations/nl_NL.json +++ b/app/translations/nl_NL.json @@ -131,7 +131,7 @@ "info": "_START_ tot _END_ van _TOTAL_ entries", "infoEmpty": "0 tot 0 van 0 entries", "infoFiltered": "(Gefilterd van _MAX_ totale entries)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "_MENU_ entries laten zien", "loadingRecords": "Laden...", "paginate": { diff --git a/app/translations/pl_PL.json b/app/translations/pl_PL.json index 6e73a9d2..8b2eae84 100644 --- a/app/translations/pl_PL.json +++ b/app/translations/pl_PL.json @@ -143,12 +143,12 @@ "pdf": "PDF", "print": "Wydrukuj" }, - "decimal": "", + "decimal": ".", "emptyTable": "Brak danych w tej tabeli danych", "info": "Pokazywanie od _START_ do _END_ z _TOTAL_ wszystkich wejść", "infoEmpty": "Pokazywanie 0 do 0 z 0 wejść", "infoFiltered": "(Pokazuje z _MAX_ wejść)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "Pokazuj _MENU_ wejść", "loadingRecords": "Wczytywanie...", "paginate": { @@ -698,4 +698,4 @@ "webhook_body": "Treść Webhooka", "webhooks": "Webhooki" } -} +} \ No newline at end of file diff --git a/app/translations/pt_BR.json b/app/translations/pt_BR.json index 037c1aac..0b79e207 100644 --- a/app/translations/pt_BR.json +++ b/app/translations/pt_BR.json @@ -127,12 +127,12 @@ "pdf": "PDF", "print": "Imprimir" }, - "decimal": "", + "decimal": ".", "emptyTable": "Nenhum dado disponível na tabela", "info": "Exibindo de _START_ a _END_ de _TOTAL_ entradas", "infoEmpty": "Exibindo de 0 a 0 de 0 entradas", "infoFiltered": "(filtrado de _MAX_ entradas totais)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "Exibir _MENU_ entradas", "loadingRecords": "Carregando...", "paginate": { diff --git a/app/translations/ru_RU.json b/app/translations/ru_RU.json index 6698ef81..6ec42f7c 100644 --- a/app/translations/ru_RU.json +++ b/app/translations/ru_RU.json @@ -142,12 +142,12 @@ "pdf": "PDF", "print": "Печать" }, - "decimal": "", + "decimal": ".", "emptyTable": "Данные в таблице отсутствуют", "info": "Отображение от _START_ до _END_ из _TOTAL_ записей", "infoEmpty": "Отображение от 0 до 0 из 0 записей", "infoFiltered": "(отфильтровано по _MAX_ количеству записей)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "Показывать записи _MENU_", "loadingRecords": "Загрузка...", "paginate": { @@ -696,4 +696,4 @@ "webhook_body": "Тело вебхука", "webhooks": "Вебхуки" } -} +} \ No newline at end of file diff --git a/app/translations/th_TH.json b/app/translations/th_TH.json index 2e447473..b7cc2223 100644 --- a/app/translations/th_TH.json +++ b/app/translations/th_TH.json @@ -143,12 +143,12 @@ "pdf": "PDF", "print": "Print" }, - "decimal": "", + "decimal": ".", "emptyTable": "ไม่มีข้อมูลในตาราง", "info": "แสดงรายการ _START_ ถึง _END_ จากทั้งหมด _TOTAL_ รายการ", "infoEmpty": "แสดงรายการ 0 ถึง 0 จากทั้งหมด 0 รายการ", "infoFiltered": "(กรองจากรายการทั้งหมด _MAX_ รายการ)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "แสดง _MENU_ รายการ", "loadingRecords": "กำลังโหลด...", "paginate": { @@ -698,4 +698,4 @@ "webhook_body": "ภายใน Webhook", "webhooks": "Webhooks" } -} +} \ No newline at end of file diff --git a/app/translations/tr_TR.json b/app/translations/tr_TR.json index 22dbc990..52e1f369 100644 --- a/app/translations/tr_TR.json +++ b/app/translations/tr_TR.json @@ -143,12 +143,12 @@ "pdf": "PDF", "print": "Yazdır" }, - "decimal": "", + "decimal": ".", "emptyTable": "Tabloda veri bulunmuyor", "info": "_TOTAL_ kayıttan _START_ - _END_ arasındaki kayıtlar gösteriliyor", "infoEmpty": "0 kayıttan 0 - 0 arasındaki kayıtlar gösteriliyor", "infoFiltered": "(_MAX_ kayıt içerisinden filtrelenen)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "_MENU_ kayıt göster", "loadingRecords": "Yükleniyor...", "paginate": { @@ -698,4 +698,4 @@ "webhook_body": "Webhook Gövdesi", "webhooks": "Webhooklar" } -} +} \ No newline at end of file diff --git a/app/translations/uk_UA.json b/app/translations/uk_UA.json index ac6e10d9..fec444b1 100644 --- a/app/translations/uk_UA.json +++ b/app/translations/uk_UA.json @@ -143,12 +143,12 @@ "pdf": "PDF", "print": "Друк" }, - "decimal": "", + "decimal": ".", "emptyTable": "Немає даних у цій таблиці", "info": "Показ _START_ до _END_ з _TOTAL_ рядків", "infoEmpty": "Показ 0 до 0 з 0 рядків", "infoFiltered": "(відфльтровано з _MAX_ загалом рядків)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "Показати _MENU_ рядки", "loadingRecords": "Завантаження...", "paginate": { @@ -702,4 +702,4 @@ "webhook_body": "Код Вебхука", "webhooks": "Вебхуки" } -} +} \ No newline at end of file diff --git a/app/translations/zh_CN.json b/app/translations/zh_CN.json index a0768bc4..be6f3892 100644 --- a/app/translations/zh_CN.json +++ b/app/translations/zh_CN.json @@ -143,12 +143,12 @@ "pdf": "PDF", "print": "打印" }, - "decimal": "", + "decimal": ".", "emptyTable": "数据表中没有可用的数据", "info": "正在显示从 _START_ 到 _END_ 的共 _TOTAL_ 个项目", "infoEmpty": "正在显示从 0 到 0 的共 0 个项目", "infoFiltered": "(从 _MAX_ 个项目中筛选出)", - "infoPostFix": "", + "infoPostFix": "|", "lengthMenu": "显示 _MENU_ 个项目", "loadingRecords": "正在加载……", "paginate": { @@ -699,4 +699,4 @@ "webhook_body": "Webhook 消息体(Body)", "webhooks": "Webhook" } -} +} \ No newline at end of file From 137fc1b88d431e18ccfbf9c269a3d6091a51a763 Mon Sep 17 00:00:00 2001 From: Iain Powrie Date: Tue, 19 Nov 2024 22:18:27 +0000 Subject: [PATCH 27/74] Update changelog !810 --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 251cf6c0..f34ee2c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,8 @@ TBD ### Tweaks TBD ### Lang -TBD +- Weblate Translation Platform Integration +- Remove incomplete labels from translation files to better support new translation workflow ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/810))

## --- [4.4.4] - 2024/10/03 From 81457271cc4ef95f70943d3dd4043ca5d47dc922 Mon Sep 17 00:00:00 2001 From: Iain Powrie Date: Tue, 19 Nov 2024 22:27:32 +0000 Subject: [PATCH 28/74] Disable lang check as now managed by Weblate --- .gitlab/lint.yml | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/.gitlab/lint.yml b/.gitlab/lint.yml index 37649e1a..945efab3 100644 --- a/.gitlab/lint.yml +++ b/.gitlab/lint.yml @@ -87,24 +87,25 @@ sonarcloud-check: - sonar-scanner # Lang file checking -lang-check: - stage: lint - image: alpine:latest - tags: - - saas-linux-medium-amd64 - rules: - - if: "$CODE_QUALITY_DISABLED" - when: never - - if: "$CI_COMMIT_TAG || $CI_COMMIT_BRANCH" - allow_failure: true - before_script: - - apk add --no-cache jq bash - script: - - chmod +x .gitlab/scripts/lang_sort.sh - - bash .gitlab/scripts/lang_sort.sh ./app/translations/ - after_script: - - if [ -f .gitlab/scripts/lang_sort_log.txt ]; then cat .gitlab/scripts/lang_sort_log.txt; fi - artifacts: - paths: - - .gitlab/scripts/lang_sort_log.txt - expire_in: 1 week +# lang-check: +# stage: lint +# image: alpine:latest +# tags: +# - saas-linux-medium-amd64 +# rules: +# - if: "$CODE_QUALITY_DISABLED" +# when: never +# - if: "$CI_COMMIT_TAG || $CI_COMMIT_BRANCH" +# allow_failure: true +# before_script: +# - apk add --no-cache jq bash +# script: +# - chmod +x .gitlab/scripts/lang_sort.sh +# - bash .gitlab/scripts/lang_sort.sh ./app/translations/ +# after_script: +# - if [ -f .gitlab/scripts/lang_sort_log.txt ]; then cat .gitlab/scripts/lang_sort_log.txt; fi +# artifacts: +# paths: +# - .gitlab/scripts/lang_sort_log.txt +# expire_in: 1 week +# DISABLED - As Weblate managed. \ No newline at end of file From 69c4b1b7169ebe151e4c67cadc88839c09521f04 Mon Sep 17 00:00:00 2001 From: Iain Powrie Date: Tue, 19 Nov 2024 22:33:36 +0000 Subject: [PATCH 29/74] Appease Lint --- .gitlab/lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab/lint.yml b/.gitlab/lint.yml index 945efab3..c6f8ed5c 100644 --- a/.gitlab/lint.yml +++ b/.gitlab/lint.yml @@ -108,4 +108,4 @@ sonarcloud-check: # paths: # - .gitlab/scripts/lang_sort_log.txt # expire_in: 1 week -# DISABLED - As Weblate managed. \ No newline at end of file +# DISABLED - As Weblate managed. From dedbc9a1e280b5cc6ea25172cb93ad8861374b9c Mon Sep 17 00:00:00 2001 From: Weblate Date: Sun, 1 Dec 2024 18:15:52 +0000 Subject: [PATCH 30/74] Update translation files Updated by "Cleanup translation files" add-on in Weblate. Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/ --- app/translations/cs_CS.json | 25 +------------------------ app/translations/de_DE.json | 6 +----- app/translations/es_ES.json | 6 +----- app/translations/fi_FI.json | 28 +--------------------------- app/translations/fr_FR.json | 6 +----- app/translations/fy_NL.json | 4 +--- app/translations/he_IL.json | 6 +----- app/translations/hr_HR.json | 4 +--- app/translations/id_ID.json | 4 +--- app/translations/it_IT.json | 6 +----- app/translations/lol_EN.json | 6 +----- app/translations/lv_LV.json | 7 +------ app/translations/nl_BE.json | 6 +----- app/translations/nl_NL.json | 4 +--- app/translations/pl_PL.json | 5 +---- app/translations/pt_BR.json | 4 +--- app/translations/ru_RU.json | 3 +-- app/translations/th_TH.json | 5 +---- app/translations/tr_TR.json | 5 +---- app/translations/uk_UA.json | 5 +---- app/translations/zh_CN.json | 6 +----- 21 files changed, 21 insertions(+), 130 deletions(-) diff --git a/app/translations/cs_CS.json b/app/translations/cs_CS.json index c7ab617b..c662d5f7 100644 --- a/app/translations/cs_CS.json +++ b/app/translations/cs_CS.json @@ -29,7 +29,6 @@ "permName": "Název oprávnění", "perms": "Oprávnění", "server": "Server: ", - "superUser": "Super uživatel", "yes": "Ano" }, "base": { @@ -130,9 +129,6 @@ "copyKeys": "Stisknutím kláves Ctrl nebo u2318 + C zkopírujete data tabulky do systémové schránky.

Chcete-li tuto zprávu zrušit, klikněte na ni nebo stiskněte klávesu ESC.", "copySuccess": { "1": "Zkopírován 1 řádek do schránky", - "2": "Zkopírovány 2 řádky do schránky", - "3": "Zkopírovány 3 řádky do schránky", - "4": "Zkopírovány 4 řádky do schránky", "_": "Zkopírováno %d řádků do schránky" }, "copyTitle": "Zkopírovat do schránky", @@ -141,9 +137,6 @@ "pageLength": { "-1": "Zobrazit všechny řádky", "1": "Zobrazit 1 řádek", - "2": "Zobrazit 2 řádky", - "3": "Zobrazit 3 řádky", - "4": "Zobrazit 4 řádky", "_": "Zobrazit %d řádků" }, "pdf": "PDF", @@ -169,25 +162,16 @@ "cells": { "0": "Kliknutím na buňku ji vyberete", "1": "Vybraná %d buňka", - "2": "Vybrané %d buňky", - "3": "Vybrané %d buňky", - "4": "Vybrané %d buňky", "_": "Vybráno %d buněk" }, "columns": { "0": "Kliknutím na sloupec jej vyberete", "1": "Vybraný %d sloupec", - "2": "Vybrané %d sloupce", - "3": "Vybrané %d sloupce", - "4": "Vybrané %d sloupce", "_": "Vybráno %d sloupců" }, "rows": { "0": "Kliknutím na řádek jej vyberete", "1": "Vybraný %d řádek", - "2": "Vybrané %d řádky", - "3": "Vybrané %d řádky", - "4": "Vybrané %d řádky", "_": "Vybráno %d řádků" } }, @@ -224,8 +208,6 @@ "privMsg": "a ", "return": "vrátit se na hlavní stránku", "selfHost": "Pokud Hostujete sami toto uložiště prosím zkontrolujte adresu nebo si přečtěte náš průvodce odstraňováním problémů.", - "serverJars1": "Server JAR api je nepřístupná. Prosím zkontrolujte", - "serverJars2": "pro aktualní informace.", "start-error": "Server {} se nepodařilo spustit s kódem chyby: {}", "superError": "Pro dokončení této akce musíte být super uživatel.", "terribleFailure": "Jaké strašné selhání!" @@ -264,7 +246,6 @@ "allowedServers": "Povolené servery", "apply": "Použít", "assignedRoles": "Přidělené role", - "backgroundUpload": "Nahrání pozadí", "cancel": "Zrušit", "clearComms": "Vymazat nevykonané příkazy", "custom": "Upravit Crafty", @@ -275,20 +256,16 @@ "globalExplain": "Kde má Crafty ukládat všechny soubory serverů. (Cestu doplníme o /server/[uuid serveru])", "globalServer": "Globalní cesta k serverům", "json": "Config.json", - "loginBackground": "Přihlašovací obrázek na pozadí", - "loginImage": "Nahrajte obrázek na pozadí přihlašovací obrazovky.", "match": "Hesla musí být stejná", "newRole": "Přidat novou roli", "newUser": "Přidat nového uživatele", "noMounts": "Ukazatel zaplněnosti disků na hlavní stránce", "pageTitle": "Nastavení panelu", - "preview": "Náhled", "role": "Role", "roleUsers": "Uživatelé s rolí", "roles": "Role", "save": "Uložit", "select": "Vyberte", - "selectImage": "Vyberte obrázek", "superConfirm": "Postupujte pouze v případě, že chcete, aby měl tento uživatel přístup ke VŠEM (ke všem uživatelským účtům, serverům, nastavení panelu atd.). Může vám dokonce odebrat práva superuživatele.", "superConfirmTitle": "Povolit superuživatele? Jste si jisti?", "title": "Crafty Konfigurace", @@ -718,4 +695,4 @@ "webhook_body": "Webhook Body", "webhooks": "Webhooky" } -} \ No newline at end of file +} diff --git a/app/translations/de_DE.json b/app/translations/de_DE.json index 4716fda8..5e42ad93 100644 --- a/app/translations/de_DE.json +++ b/app/translations/de_DE.json @@ -29,7 +29,6 @@ "permName": "Berechtigungs Name", "perms": "Berechtigungen", "server": "Server: ", - "superUser": "Super Benutzer", "yes": "Ja" }, "base": { @@ -209,8 +208,6 @@ "privMsg": "und der/die/das ", "return": "Zurück zum Dashboard", "selfHost": "Wenn Sie dieses Repo selbst hosten, überprüfen Sie bitte Ihre Adresse oder konsultieren Sie unsere Anleitung zur Fehlerbehebung.", - "serverJars1": "Server-JAR-API nicht erreichbar. Bitte überprüfen Sie ", - "serverJars2": "um die aktuellsten Informationen zu erhalten.", "start-error": "Der Server {} konnte wegen dem Fehlercode: {} nicht gestartet werden", "superError": "Sie müssen ein Administrator sein, um diese Aktion abzuschließen.", "terribleFailure": "Was für ein furchtbarer Fehler!" @@ -554,7 +551,6 @@ "serverTerm": { "commandInput": "Geben Sie Ihren Befehl ein", "delay-explained": "Der Dienst wurde kürzlich gestartet und verzögert den Start der Minecraft-Serverinstanz", - "downloading": "Lädt herunter...", "importing": "Importieren...", "installing": "Installation läuft...", "restart": "Neustart", @@ -699,4 +695,4 @@ "webhook_body": "Webhook-Inhalt", "webhooks": "Webhooks" } -} \ No newline at end of file +} diff --git a/app/translations/es_ES.json b/app/translations/es_ES.json index 53448405..9d88bcee 100644 --- a/app/translations/es_ES.json +++ b/app/translations/es_ES.json @@ -29,7 +29,6 @@ "permName": "Nombre del Permiso", "perms": "Permisos", "server": "Servidor: ", - "superUser": "Super Usuario", "yes": "Si" }, "base": { @@ -209,8 +208,6 @@ "privMsg": "y el ", "return": "Volver al panel de control", "selfHost": "Si estás autoalojando este repositorio, revisa tu dirección o consulta nuestra guía de solución de problemas.", - "serverJars1": "API de Servidor JAR no disponible. por favor, compruebe", - "serverJars2": "para la información más actualizada.", "start-error": "Servidor {} fallo al iniciar con código de error: {}", "superError": "Debes ser un super usuario para completar esta acción.", "terribleFailure": "¡Un terrible error!" @@ -554,7 +551,6 @@ "serverTerm": { "commandInput": "Introducir tu comando", "delay-explained": "El agente/servicio se inicio recientemente y está retrasando iniciar la instancia del servidor de Minecraft.", - "downloading": "Descargando...", "importing": "Importando...", "installing": "Instalando...", "restart": "Reiniciar", @@ -699,4 +695,4 @@ "webhook_body": "Cuerpo del Webhook", "webhooks": "Webhooks" } -} \ No newline at end of file +} diff --git a/app/translations/fi_FI.json b/app/translations/fi_FI.json index 5ed58acc..e1f68685 100644 --- a/app/translations/fi_FI.json +++ b/app/translations/fi_FI.json @@ -28,7 +28,6 @@ "permName": "Käyttoikeuden nimi", "perms": "Käyttoikeudet", "server": "Palvelin: ", - "superUser": "Järjestelmänvalvoja", "yes": "Kyllä" }, "base": { @@ -147,40 +146,16 @@ "cells": { "0": "Klikkaa solua valitaksesi sen", "1": "Yksi solu valittuna", - "2": "Kaksi solua valittuna", - "3": "Kolme solua valittuna", - "4": "Neljä solua valittuna", - "5": "Viisi solua valittuna", - "6": "Kuusi solua valittuna", - "7": "Seitsemän solua valittuna", - "8": "Kahdeksan solua valittuna", - "9": "Yhdeksän solua valittuna", "_": "%d solua valittuna" }, "columns": { "0": "Klikkaa saraketta valitaksesi sen", "1": "Yksi sarake valittuna", - "2": "Kaksi saraketta valittuna", - "3": "Kolme saraketta valittuna", - "4": "Neljä saraketta valittuna", - "5": "Viisi saraketta valittuna", - "6": "Kuusi saraketta valittuna", - "7": "Seitsemän saraketta valittuna", - "8": "Kahdeksan saraketta valittuna", - "9": "Yhdeksän saraketta valittuna", "_": "%d saraketta valittuna" }, "rows": { "0": "Klikkaa riviä valitaksesi sen", "1": "Yksi rivi valittuna", - "2": "Kaksi riviä valittuna", - "3": "Kolme riviä valittuna", - "4": "Neljä riviä valittuna", - "5": "Viisi riviä valittuna", - "6": "Kuusi riviä valittuna", - "7": "Seitsemän riviä valittuna", - "8": "Kahdeksan riviä valittuna", - "9": "Yhdeksän riviä valittuna", "_": "%d riviä valittuna" } }, @@ -468,7 +443,6 @@ "serverTerm": { "commandInput": "Kirjoita komento", "delay-explained": "Palvelu/agentti on äskettäin aloittanut ja viivästyttää minecraft -palvelimen ilmentymän alkua", - "downloading": "Ladataan...", "restart": "Uudelleen­käynnistä", "sendCommand": "Lähetä komento", "start": "Käynnistä", @@ -560,4 +534,4 @@ "userSettings": "Käyttäjäasetukset", "uses": "Sallittujen käyttäkertojen määtä (-1 == Ei rajaa)" } -} \ No newline at end of file +} diff --git a/app/translations/fr_FR.json b/app/translations/fr_FR.json index d25de966..ba500080 100644 --- a/app/translations/fr_FR.json +++ b/app/translations/fr_FR.json @@ -29,7 +29,6 @@ "permName": "Nom de la Permission", "perms": "Permissions", "server": "Serveur: ", - "superUser": "Super Utilisateur", "yes": "Oui" }, "base": { @@ -209,8 +208,6 @@ "privMsg": "et le ", "return": "Revenir au Tableau de Bord", "selfHost": "Si vous hébergez vous-même ce repo, veuillez vérifier votre adresse et votre guide de dépannage.", - "serverJars1": "l'API Server JARs est inaccessible. Merci de vérifier", - "serverJars2": "pour les informations les plus à jour.", "start-error": "Le serveur {} n'a pas pu démarrer avec le code d'erreur : {}", "superError": "Tu dois être un super utilisateur pour effectuer cette action.", "terribleFailure": "C'est une Terrible Erreur !" @@ -554,7 +551,6 @@ "serverTerm": { "commandInput": "Entre ta commande", "delay-explained": "Le service/agent a récemment démarré et retarde le démarrage de l'instance du serveur minecraft", - "downloading": "Téléchargement ...", "importing": "Importation ...", "installing": "Installation ...", "restart": "Redémarrer", @@ -699,4 +695,4 @@ "webhook_body": "Corps du Webhook", "webhooks": "Webhooks" } -} \ No newline at end of file +} diff --git a/app/translations/fy_NL.json b/app/translations/fy_NL.json index a1658298..b64e90a1 100644 --- a/app/translations/fy_NL.json +++ b/app/translations/fy_NL.json @@ -28,7 +28,6 @@ "permName": "Namme fan tastimming", "perms": "Tastimmingen", "server": "Server: ", - "superUser": "Superbrûker", "yes": "Ja" }, "base": { @@ -437,7 +436,6 @@ "serverTerm": { "commandInput": "Fier jo kommando yn", "delay-explained": "De tsjinst / agint is koartlyn begon en fertraget it begjin fan 'e Minecraft-server", - "downloading": "Ynladen...", "restart": "Opnij starte", "sendCommand": "Kommando stjoere", "start": "Starte", @@ -529,4 +527,4 @@ "userSettings": "Brûkersynstellingen", "uses": "Oantal gebrûk tastien (-1==Gjin limyt)" } -} \ No newline at end of file +} diff --git a/app/translations/he_IL.json b/app/translations/he_IL.json index 1283d7d9..b76bc30d 100644 --- a/app/translations/he_IL.json +++ b/app/translations/he_IL.json @@ -29,7 +29,6 @@ "permName": "שם הגישה", "perms": "גישות", "server": "שרת: ", - "superUser": "משתמש על", "yes": "כן" }, "base": { @@ -209,8 +208,6 @@ "privMsg": "וה", "return": "חזרה לפאנל", "selfHost": "אם אתה מארח בעצמך את הריפו הזה, אנא בדוק את הכתובת שלך או התייעץ עם מדריך פתרון הבעיות שלנו.", - "serverJars1": "API של צנצנות השרת אינו נגיש. אנא בדוק", - "serverJars2": "למידע מעודכן ביותר.", "start-error": "השרת {} לא הצליח להתחיל עם קוד שגיאה: {}", "superError": "חובה להיות משתמש על כדי לבצע פעולה זו.", "terribleFailure": "איזה כישלון נורא!" @@ -554,7 +551,6 @@ "serverTerm": { "commandInput": "הקלידו את הפקודה שלכם", "delay-explained": "השירות/סוכן התחיל לאחרונה והוא מעכב את הדלקת שרת המיינקראפט", - "downloading": "...מוריד", "importing": "מייבא...", "installing": "מתקין...", "restart": "הפעלה מחדש", @@ -699,4 +695,4 @@ "webhook_body": "גוף ה-Webhook", "webhooks": "Webhooks" } -} \ No newline at end of file +} diff --git a/app/translations/hr_HR.json b/app/translations/hr_HR.json index ce99c5db..b47b4379 100644 --- a/app/translations/hr_HR.json +++ b/app/translations/hr_HR.json @@ -28,7 +28,6 @@ "permName": "Naziv dopuštenja", "perms": "Dopuštenja", "server": "Poslužitelj: ", - "superUser": "Superkorisnik", "yes": "Da" }, "base": { @@ -437,7 +436,6 @@ "serverTerm": { "commandInput": "Unesi naredbu", "delay-explained": "Usluga je nedavno započeta i odgađa pokretanje instance poslužitelja Minecrafta", - "downloading": "Preuzimanje...", "restart": "Ponovno pokreni", "sendCommand": "Pošalji naredbu", "start": "Pokreni", @@ -529,4 +527,4 @@ "userSettings": "Korisničke postavke", "uses": "Broj dopuštenih upotreba (-1==Bez ograničenja)" } -} \ No newline at end of file +} diff --git a/app/translations/id_ID.json b/app/translations/id_ID.json index c0494e42..068ad969 100644 --- a/app/translations/id_ID.json +++ b/app/translations/id_ID.json @@ -28,7 +28,6 @@ "permName": "Nama Izin", "perms": "Izin", "server": "Server: ", - "superUser": "Super User", "yes": "Iya" }, "base": { @@ -444,7 +443,6 @@ "serverTerm": { "commandInput": "Masukan Perintah Anda", "delay-explained": "Layanan / agen baru-baru ini dimulai dan menunda dimulainya instans server minecraft", - "downloading": "Mengunduh...", "restart": "Mulai Ulang", "sendCommand": "Kirim Perintah", "start": "Mulai", @@ -536,4 +534,4 @@ "userSettings": "Pengaturan Pengguna", "uses": "Jumlah penggunaan yang diizinkan (-1==No Limit)" } -} \ No newline at end of file +} diff --git a/app/translations/it_IT.json b/app/translations/it_IT.json index 3d9a0e34..f7148ef6 100644 --- a/app/translations/it_IT.json +++ b/app/translations/it_IT.json @@ -29,7 +29,6 @@ "permName": "Nome Permesso", "perms": "Permessi", "server": "Server: ", - "superUser": "Super User", "yes": "Sì" }, "base": { @@ -209,8 +208,6 @@ "privMsg": "e il ", "return": "Torna alla pagina iniziale", "selfHost": "se stai ospitando te questo repo, controlla il tuo indirizzo o consulta la nostra guida di risoluzione dei problemi.", - "serverJars1": "API JAR del server non raggiungibile. Si prega di controllare", - "serverJars2": "per informazioni più aggiornate.", "start-error": "Server {} failed to start with error code: {}", "superError": "Devi essere un super utente per eseguire questa azione.", "terribleFailure": "What a Terrible Failure!" @@ -554,7 +551,6 @@ "serverTerm": { "commandInput": "Inserisci il comando", "delay-explained": "Il servizio/agente è stato avviato di recente e sta ritardando l'avvio del server di Minecraft", - "downloading": "Scaricando...", "importing": "Importazione...", "installing": "Installazione...", "restart": "Riavvia", @@ -699,4 +695,4 @@ "webhook_body": "Corpo del Webhook", "webhooks": "Webhook" } -} \ No newline at end of file +} diff --git a/app/translations/lol_EN.json b/app/translations/lol_EN.json index 44675983..e5d99a0e 100644 --- a/app/translations/lol_EN.json +++ b/app/translations/lol_EN.json @@ -29,7 +29,6 @@ "permName": "PERMISSION NAME", "perms": "PERMISSIONS", "server": "SERVER: ", - "superUser": "SUPA DOOPA USR", "yes": "YESH!" }, "base": { @@ -209,8 +208,6 @@ "privMsg": "AND THEEZ ", "return": "Go Bak to Dashbored", "selfHost": "If u iz self-hostin' dis repo, check ur addy or peep our fix-it guide.", - "serverJars1": "CAN'T TALK TO SERVER JARS API. CHECKZ", - "serverJars2": "TO SEE NEWZ STUFFZ.", "start-error": "CHAIR {} FAILD 2 START WIF OOF CODE: {}", "superError": "U MUST BE A BIG CAT TO DO DIS.", "terribleFailure": "SUMTIN DUN BWOKE" @@ -554,7 +551,6 @@ "serverTerm": { "commandInput": "ENTR YOUR COMARNED", "delay-explained": "TEH SERVICE/AGENT HUS RESENTLY STARTD AN IZ DELAYIN TEH STARTD OV TEH SERVR", - "downloading": "WAIT PLZ!?!?!", "importing": "BRINGINGZ IN...", "installing": "PUTTINGZ TOGETHER...", "restart": "COPYZ", @@ -699,4 +695,4 @@ "webhook_body": "WEBHOOK FISH", "webhooks": "WEBHOOKZ" } -} \ No newline at end of file +} diff --git a/app/translations/lv_LV.json b/app/translations/lv_LV.json index ec68e6c1..48982234 100644 --- a/app/translations/lv_LV.json +++ b/app/translations/lv_LV.json @@ -29,7 +29,6 @@ "permName": "Atļaujas Nosaukums", "perms": "Atļaujas", "server": "Serveris: ", - "superUser": "Super Lietotājs", "yes": "Jā" }, "base": { @@ -59,7 +58,6 @@ "backgroundUpload": "Fona attēla augšupielāde", "customLoginPage": "Pielāgo Pieteikšanās Lapa", "delete": "Dzēst", - "installing": "Uztāda...", "labelLoginImage": "Izvēlies savu Pieteikšanās Lapas Fonu", "loginBackground": "Pieteikšanās Fona Attēls", "loginImage": "Augšupielādē fona attēlu priekš pieteikšanās ekrāna.", @@ -210,8 +208,6 @@ "privMsg": "un ", "return": "Atgriezties uz pārskatu", "selfHost": "Ja jūs paši uzturat šo repozitoriju, pārbaudiet savu adresi vai apskatiet mūsu kļūdu novēršanas dokumentāciju.", - "serverJars1": "Serveru JAR API nav sasniedzams. Lūdzu pārbaudiet", - "serverJars2": "priekš jaunākās informācijas.", "start-error": "Serveris {} neveiskmīgi startējās ar kļūdas kodu: {}", "superError": "Jums ir jābūt super lietotājam lai veiktu šo darbību.", "terribleFailure": "Kas par neveiksmi!" @@ -559,7 +555,6 @@ "serverTerm": { "commandInput": "Ievadi savu komandu", "delay-explained": "Serviss/aģents tika nesen startēts, un aizkavē Minecraft servera instances startu", - "downloading": "Lejupielādē...", "importing": "Importē...", "installing": "Uzstāda...", "restart": "Restartēt", @@ -704,4 +699,4 @@ "webhook_body": "Webhook Saturs", "webhooks": "Webhooki" } -} \ No newline at end of file +} diff --git a/app/translations/nl_BE.json b/app/translations/nl_BE.json index 3c01207b..2f4b87ae 100644 --- a/app/translations/nl_BE.json +++ b/app/translations/nl_BE.json @@ -29,7 +29,6 @@ "permName": "Machtigingsnaam", "perms": "Machtigingen", "server": "Server: ", - "superUser": "Supergebruiker", "yes": "Ja" }, "base": { @@ -209,8 +208,6 @@ "privMsg": "en de ", "return": "Terug naar Dashboard", "selfHost": "Als u deze repository zelf host, controleer dan uw adres of raadpleeg onze handleiding voor probleemoplossing.", - "serverJars1": "Server JARs API niet bereikbaar. Controleer alstublieft", - "serverJars2": "voor de meest recente informatie.", "start-error": "Server {} kan niet starten met foutcode: {}", "superError": "U moet een supergebruiker zijn om deze actie te voltooien.", "terribleFailure": "Wat een verschrikkelijke mislukking!" @@ -558,7 +555,6 @@ "serverTerm": { "commandInput": "Voer uw opdracht in", "delay-explained": "De service/agent is onlangs gestart en vertraagt ​​de start van de minecraft-serverinstantie", - "downloading": "Aan het downloaden...", "importing": "Importeren...", "installing": "Installeren...", "restart": "Herstarten", @@ -703,4 +699,4 @@ "webhook_body": "Webhook-body", "webhooks": "Webhooks" } -} \ No newline at end of file +} diff --git a/app/translations/nl_NL.json b/app/translations/nl_NL.json index 8cf88ecf..5a1694ec 100644 --- a/app/translations/nl_NL.json +++ b/app/translations/nl_NL.json @@ -28,7 +28,6 @@ "permName": "Toestemming naam", "perms": "Toestemmingen", "server": "Server: ", - "superUser": "Super Gebruiker", "yes": "Ja" }, "base": { @@ -437,7 +436,6 @@ "serverTerm": { "commandInput": "Commando invoeren", "delay-explained": "De service/agent is recentelijk gestart en stelt de start uit van de Minecraft-serverinstantie", - "downloading": "Aan het downloaden...", "restart": "Restarten", "sendCommand": "Commando versturen", "start": "Starten", @@ -529,4 +527,4 @@ "userSettings": "Gebruikersinstellingen", "uses": "Aantal keer toegestaan (-1==Geen limiet)" } -} \ No newline at end of file +} diff --git a/app/translations/pl_PL.json b/app/translations/pl_PL.json index 8b2eae84..3a450a16 100644 --- a/app/translations/pl_PL.json +++ b/app/translations/pl_PL.json @@ -29,7 +29,6 @@ "permName": "Nazwa permisji", "perms": "Permisje", "server": "Serwer: ", - "superUser": "Super użytkownik", "yes": "Tak" }, "base": { @@ -209,8 +208,6 @@ "privMsg": "i także ", "return": "Powrót do panelu", "selfHost": "Jeśli zarządasz tą repozytorią upewnij się że adres hest poprawny, w innym przypadku odwiedź strone rozwiązywania problemów.", - "serverJars1": "API Server Jars jest niedostępne. Proszę sprawdź", - "serverJars2": "dla najnowzsych informacji.", "start-error": "Serwer {} nie mógł się odpalić z powodu: {}", "superError": "Potrzebujesz uprawnienie Adminitsratora aby zakończyć tę akcję.", "terribleFailure": "Okropny błąd!" @@ -698,4 +695,4 @@ "webhook_body": "Treść Webhooka", "webhooks": "Webhooki" } -} \ No newline at end of file +} diff --git a/app/translations/pt_BR.json b/app/translations/pt_BR.json index 0b79e207..6878abc7 100644 --- a/app/translations/pt_BR.json +++ b/app/translations/pt_BR.json @@ -28,7 +28,6 @@ "permName": "Nome da Permissão", "perms": "Permissões", "server": "Servidor: ", - "superUser": "Super Usuário", "yes": "Sim" }, "base": { @@ -445,7 +444,6 @@ "serverTerm": { "commandInput": "Insira seu comando", "delay-explained": "O serviço/agente iniciou recentemente e está atrasando o início da instância do servidor de minecraft", - "downloading": "Baixando...", "restart": "Reiniciar", "sendCommand": "Enviar comando", "start": "Iniciar", @@ -537,4 +535,4 @@ "userSettings": "Configurações do Usuário", "uses": "Número de Usos Permitidos (-1==Sem Limite)" } -} \ No newline at end of file +} diff --git a/app/translations/ru_RU.json b/app/translations/ru_RU.json index 6ec42f7c..a86b1b30 100644 --- a/app/translations/ru_RU.json +++ b/app/translations/ru_RU.json @@ -614,7 +614,6 @@ "dashboard": "Приборная панель", "documentation": "Документация", "inApp": "Документация в приложении", - "navigation": "Навигация", "newServer": "Создать новый сервер", "servers": "Серверы" }, @@ -696,4 +695,4 @@ "webhook_body": "Тело вебхука", "webhooks": "Вебхуки" } -} \ No newline at end of file +} diff --git a/app/translations/th_TH.json b/app/translations/th_TH.json index b7cc2223..d408adf6 100644 --- a/app/translations/th_TH.json +++ b/app/translations/th_TH.json @@ -29,7 +29,6 @@ "permName": "ชื่อการอนุญาต", "perms": "สิทธิ์อนุญาต", "server": "เซิร์ฟเวอร์: ", - "superUser": "Super User", "yes": "ใช่" }, "base": { @@ -209,8 +208,6 @@ "privMsg": "และ ", "return": "ย้อนกลับไปยังแผงควบคุม", "selfHost": "หากคุณโฮสต์ repo นี้ด้วยตนเอง โปรดตรวจสอบที่อยู่ของคุณ หรือศึกษาคู่มือแก้ปัญหาของเรา", - "serverJars1": "ไม่สามารถเข้าถึงเซิร์ฟเวอร์ JARs API กรุณาตรวจสอบ", - "serverJars2": "เพื่อข้อมูลที่ทันสมัยที่สุด", "start-error": "เซิร์ฟเวอร์ {} ไม่สามารถเริ่มต้นได้เนื่องจากรหัสข้อผิดพลาด: {}", "superError": "คุณต้องเป็น Super User จึงจะดำเนินการนี้ได้", "terribleFailure": "นี่มันเป็นความล้มเหลวครั้งยิ่งใหญ่!" @@ -698,4 +695,4 @@ "webhook_body": "ภายใน Webhook", "webhooks": "Webhooks" } -} \ No newline at end of file +} diff --git a/app/translations/tr_TR.json b/app/translations/tr_TR.json index 52e1f369..3f928609 100644 --- a/app/translations/tr_TR.json +++ b/app/translations/tr_TR.json @@ -29,7 +29,6 @@ "permName": "Yetki İsmi", "perms": "Yetkiler", "server": "Sunucu: ", - "superUser": "Süper Kullanıcı", "yes": "Evet" }, "base": { @@ -209,8 +208,6 @@ "privMsg": "ve ", "return": "Arayüze Geri Dön", "selfHost": "Bu depoyu kendiniz barındırıyorsanız lütfen adresinizi kontrol ediniz veya sorun giderme kılavuzumuza bakınız.", - "serverJars1": "Sunucu JARs API'ına erişilemiyor.", - "serverJars2": "en güncel bilgilere sahiptir", "start-error": "{} sunucusu başlamatılamadı. Hata kodu: {}", "superError": "Bu işlemi tamamlamak için süper kullanıcı olmanız gerekir.", "terribleFailure": "Ne Korkunç Bir Hata!" @@ -698,4 +695,4 @@ "webhook_body": "Webhook Gövdesi", "webhooks": "Webhooklar" } -} \ No newline at end of file +} diff --git a/app/translations/uk_UA.json b/app/translations/uk_UA.json index fec444b1..4c4ff9e6 100644 --- a/app/translations/uk_UA.json +++ b/app/translations/uk_UA.json @@ -29,7 +29,6 @@ "permName": "Назва дозволу", "perms": "Дозволи", "server": "Сервер: ", - "superUser": "СуперЮзер", "yes": "Так" }, "base": { @@ -209,8 +208,6 @@ "privMsg": "і ", "return": "Повернутись до панелі", "selfHost": "Якщо ви самостійно розміщуєте цей репозеторій, перевірте свою адресу або зверніться до нашого посібника з усунення несправностей.", - "serverJars1": "API сервера JAR недоступний. Будь ласка, перевірте", - "serverJars2": "для найактуальнішої інформації.", "start-error": "Сервер {} не запустився через помилку: {}", "superError": "Ви маєте мати права суперюзера для виконання даного завдання.", "terribleFailure": "Яка Жахлива Невдача!" @@ -702,4 +699,4 @@ "webhook_body": "Код Вебхука", "webhooks": "Вебхуки" } -} \ No newline at end of file +} diff --git a/app/translations/zh_CN.json b/app/translations/zh_CN.json index be6f3892..48c748f3 100644 --- a/app/translations/zh_CN.json +++ b/app/translations/zh_CN.json @@ -29,7 +29,6 @@ "permName": "权限名称", "perms": "权限", "server": "服务器:", - "superUser": "超级用户", "yes": "是" }, "base": { @@ -209,8 +208,6 @@ "privMsg": "以及", "return": "返回仪表板", "selfHost": "如果您自托管此仓库,请检查您的地址或参考我们的故障排除指南。", - "serverJars1": "无法访问服务器 JAR API。请检查", - "serverJars2": "以获取最新信息。", "start-error": "服务器 {} 启动失败,错误代码为:{}", "superError": "您必须作为超级用户来完成此操作。", "terribleFailure": "多糟糕的错误!" @@ -554,7 +551,6 @@ "serverTerm": { "commandInput": "输入您的指令", "delay-explained": "服务进程已经在刚才启动,并且正在延迟 Minecraft 服务器实例的启动", - "downloading": "下载中……", "importing": "正在导入……", "installing": "正在安装……", "restart": "重启", @@ -699,4 +695,4 @@ "webhook_body": "Webhook 消息体(Body)", "webhooks": "Webhook" } -} \ No newline at end of file +} From 11338c01d94a91f5983d539fcc5bd335227abec4 Mon Sep 17 00:00:00 2001 From: Andrew Date: Sun, 1 Dec 2024 17:48:58 +0000 Subject: [PATCH 31/74] Translated (Czech) Currently translated at 99.3% (610 of 614 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/cs/ --- app/translations/cs_CS.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/translations/cs_CS.json b/app/translations/cs_CS.json index c662d5f7..ea69fb45 100644 --- a/app/translations/cs_CS.json +++ b/app/translations/cs_CS.json @@ -235,7 +235,8 @@ "finishedPreparing": "Dokončili jsme přípravu protokolů podpory. Klikněte na tlačítko Stáhnout pro stažení", "logout": "Odhlásit se", "preparingLogs": " Počkejte prosím, než připravíme vaše protokoly... Až budou připraveny, pošleme vám oznámení. U rozsáhlých zavádění to může chvíli trvat.", - "supportLogs": "Protokoly podpory" + "supportLogs": "Protokoly podpory", + "backup_desc": "" }, "offline": { "offline": "Offline", From 806217020c7151803cc27378cabe5e10acfbc238 Mon Sep 17 00:00:00 2001 From: Iain Powrie Date: Sun, 1 Dec 2024 18:23:01 +0000 Subject: [PATCH 32/74] Translated (Mongo (lol_EN)) Currently translated at 100.0% (614 of 614 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/lol_EN/ --- app/translations/lol_EN.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/translations/lol_EN.json b/app/translations/lol_EN.json index e5d99a0e..0de8e017 100644 --- a/app/translations/lol_EN.json +++ b/app/translations/lol_EN.json @@ -235,7 +235,11 @@ "finishedPreparing": "I HAS FINISHD PREPARIN UR FISH. PLZ CLICK DOWNLOAD 2 DOWNLOAD", "logout": "GO BYE BYE", "preparingLogs": " PLZ WAIT WHILE I GATHR UR FISHZ... ILL MAK NOIZE WHEN THEY`RE READY. DIS CUD TAEK WHILE IF UR HOUZ IZ HOOJ.", - "supportLogs": "SUPPORT FISHIEZ" + "supportLogs": "SUPPORT FISHIEZ", + "schedule_desc": "WE NOTICED SOME OR ALL UR SCHEDULED FISH DIDN’T MOVE RIGHT DURING DA UPGRADE. PLS CONFIRM ALL UR FISH IN DA SCHEDULES TAB.", + "backup_desc": "WE NOTICED DA BACKUP MIGRASHUN MIGHTA GONE BOOM. PLS CHECK UR BACKUP RECORDZ ON DA BACKUP TAB.", + "backup_title": "BACKUP MIGRASHUN OOPSIE", + "schedule_title": "SCHEDULES MIGRASHUN OOPSIE" }, "offline": { "offline": "NOT HEREZ", From 5dc1051c5bf4797b55dde8faf80c085c9873bb93 Mon Sep 17 00:00:00 2001 From: Andrew Date: Sun, 1 Dec 2024 18:24:33 +0000 Subject: [PATCH 33/74] Added translation (Japanese) --- app/translations/ja_JP.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 app/translations/ja_JP.json diff --git a/app/translations/ja_JP.json b/app/translations/ja_JP.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/app/translations/ja_JP.json @@ -0,0 +1 @@ +{} From 40956a751bb5196077a3dfbb7b8960e4a907ac00 Mon Sep 17 00:00:00 2001 From: Zedifus Date: Sun, 1 Dec 2024 18:55:59 +0000 Subject: [PATCH 34/74] Update changelog !786 --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f34ee2c1..830f57ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,15 @@ ## --- [4.4.5] - 2024/TBD ### New features TBD +### Refactor +- Refactor and standardize all JSON validator errors returning human readable translations ### Bug fixes - Bump requests to resolve yank for CVE-2024-35195 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/808)) ### Tweaks TBD ### Lang - Weblate Translation Platform Integration -- Remove incomplete labels from translation files to better support new translation workflow ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/810)) +- Remove incomplete labels from translation files to better support new translation workflow ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/810))

## --- [4.4.4] - 2024/10/03 From a247aa4752c74c67cb3bd00439542b67a8e86a48 Mon Sep 17 00:00:00 2001 From: Zedifus Date: Sun, 1 Dec 2024 19:03:47 +0000 Subject: [PATCH 35/74] Fix lint missing deps for orjson --- .gitlab/lint.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitlab/lint.yml b/.gitlab/lint.yml index c6f8ed5c..5cfae504 100644 --- a/.gitlab/lint.yml +++ b/.gitlab/lint.yml @@ -53,7 +53,7 @@ pylint: - if: "$CI_COMMIT_TAG || $CI_COMMIT_BRANCH" before_script: - apk update - - apk add gcc python3-dev linux-headers build-base + - apk add gcc python3-dev linux-headers build-base rust cargo - pip3 install --no-cache-dir -r requirements.txt script: - pylint --exit-zero --load-plugins=pylint_gitlab --output-format=gitlab-codeclimate:codeclimate.json $(find -type f -name "*.py" ! -path "**/.venv/**" ! -path "**/app/migrations/**") @@ -85,7 +85,6 @@ sonarcloud-check: - .sonar/cache script: - sonar-scanner - # Lang file checking # lang-check: # stage: lint From 0a466a0a34592933e28af39f1885b4e2737ccf8a Mon Sep 17 00:00:00 2001 From: Zedifus Date: Sun, 1 Dec 2024 19:15:19 +0000 Subject: [PATCH 36/74] Fix changelog !786 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 830f57ad..477fb3fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ### New features TBD ### Refactor -- Refactor and standardize all JSON validator errors returning human readable translations +- Refactor and standardize all JSON validator errors returning human readable translations ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/786)) ### Bug fixes - Bump requests to resolve yank for CVE-2024-35195 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/808)) ### Tweaks From 642cdefbf6905150195ef166e7bc8849c7b55363 Mon Sep 17 00:00:00 2001 From: Seal Date: Sun, 1 Dec 2024 18:55:24 +0000 Subject: [PATCH 37/74] Translated (Turkish) Currently translated at 100.0% (614 of 614 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/tr/ --- app/translations/tr_TR.json | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/app/translations/tr_TR.json b/app/translations/tr_TR.json index 3f928609..58796a2d 100644 --- a/app/translations/tr_TR.json +++ b/app/translations/tr_TR.json @@ -23,7 +23,7 @@ "fullAccess": "Tam Erişim", "getToken": "Bir Token Al", "name": "Ad", - "nameDesc": "Bu API tokeninin adı ne olsun?", + "nameDesc": "Bu API tokeninin adı ne olsun? ", "no": "Hayır", "pageTitle": "Kullanıcı API Anahtarlarını Düzenle", "permName": "Yetki İsmi", @@ -74,7 +74,7 @@ "backups": "Yedeklemeler", "bePatientClone": "Sunucuyu klonlarken lütfen sabırlı olunuz.
Bu ekran birazdan kendini yenileyecektir", "bePatientRestart": "Sunucuyu yeniden başlatırken lütfen sabırlı olunuz.
Bu ekran birazdan kendini yenileyecektir", - "bePatientStart": "Sunucuyu başlatırken başlatırken lütfen sabırlı olunuz.
Bu ekran birazdan kendini yenileyecektir", + "bePatientStart": "Sunucuyu başlatırken lütfen sabırlı olunuz.
Bu ekran birazdan kendini yenileyecektir.", "bePatientStop": "Sunucuyu durdururken başlatırken lütfen sabırlı olunuz.
Bu ekran birazdan kendini yenileyecektir", "cannotSee": "Gözükmeyen şeyler mi var?", "cannotSeeOnMobile": "Mobilde gözükmeyen şeyler mi var?", @@ -235,7 +235,11 @@ "finishedPreparing": "Destek günlüklerinizi hazırlamayı tamamladık. İndirmek için lütfen indir'e tıklayın", "logout": "Oturumu Kapat", "preparingLogs": " Günlüklerinizi hazırlarken lütfen bekleyin... Hazır olduklarında bir bildirim göndereceğiz. Bu, büyük dağıtımlar için biraz zaman alabilir.", - "supportLogs": "Destek Günlükleri" + "supportLogs": "Destek Günlükleri", + "backup_desc": "Yedek taşımasının kısmen veya tamamen başarısız olmuş olabileceğini tespit ettik. Lütfen yedekler sekmesindeki yedek kayıtlarınızı kontrol edin.", + "schedule_desc": "Yükseltme sırasında zamanlanmış görevlerinizin bir kısmının veya tamamının başarıyla aktarılmadığını tespit ettik. Lütfen zamanlamalar sekmesinden zamanlamalarınızı onaylayın.", + "backup_title": "Yedek Taşıma Uyarısı", + "schedule_title": "Zamanlama Taşıma Uyarısı" }, "offline": { "offline": "Çevrimdışı", @@ -301,7 +305,7 @@ "actions": "Eylemler", "after": "Yedeklemeden sonra bir komut çalıştır", "backupAtMidnight": "Gece yarısında otomatik yedekleme yapılsın mı?", - "backupNow": "Backup Now!", + "backupNow": "Şimdi Yedekle!", "backupTask": "Bir yedekleme görevi başlatıldı.", "backups": "Sunucu Yedekleri", "before": "Yedeklemeden önce bir komut çalıştır", @@ -526,7 +530,7 @@ "newSchedule": "Yeni Zamanlama", "nextRun": "Sonraki Çalışma", "no": "Hayır", - "no-schedule": "Şu anda bu sunucu için herhangi bir zamanlama bulunmamaktadır. Başlamak için: ", + "no-schedule": "Şu anda bu sunucu için herhangi bir zamanlama bulunmamaktadır. Başlamak için:", "scheduledTasks": "Zamanlanmış Görevler", "yes": "Evet" }, From cdcb1759ef5ab367f1193a7f68bfbb8fbe476c15 Mon Sep 17 00:00:00 2001 From: Analicia A Date: Sun, 1 Dec 2024 19:06:08 +0000 Subject: [PATCH 38/74] Translated (Japanese) Currently translated at 98.8% (607 of 614 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/ja/ --- app/translations/ja_JP.json | 696 +++++++++++++++++++++++++++++++++++- 1 file changed, 695 insertions(+), 1 deletion(-) diff --git a/app/translations/ja_JP.json b/app/translations/ja_JP.json index 0967ef42..1457824c 100644 --- a/app/translations/ja_JP.json +++ b/app/translations/ja_JP.json @@ -1 +1,695 @@ -{} +{ + "error": { + "cancel": "キャンセル", + "agree": "同意", + "bedrockError": "Bedrockダウンロードは利用できませんでした。確認してください。", + "bigBucket1": "Big Bucketヘルスチェックは失敗しました。", + "bigBucket2": "最新の情報を確認してください。", + "contact": "DiscordでCraftyサポートに連絡", + "craftyStatus": "Crafty ステータスページ", + "cronFormat": "無効な Cronフォーマットを検知", + "embarassing": "いやあ、これは恥ずかしいですなあ。", + "error": "エラー!", + "eulaAgree": "同意しますか?", + "eulaMsg": "同意する必要があります: ", + "eulaTitle": "EULAに同意", + "fileError": "ファイルの種類は画像である必要があります。", + "fileTooLarge": "アップロードに失敗しました。ファイルが大きすぎます。アップロードしたい場合は、システム管理者に連絡してください。", + "hereIsTheError": "以下がエラーです。", + "installerJava": "インストール失敗 {} : ForgeサーバーのインストールにはJavaが必要です。 Javaがインストールされていないことを検知しました。Javaをインストールした後に、サーバーをインストールしてください。", + "internet": "Craftyが実行中のサーバーが、インターネットに接続されていないことを検知しました。クライアントのサーバーへの接続が制限されるかもしれません。", + "migration": "Craftyのメインサーバーのストレージが新しいサーバーへ移行中です。そのため全てのサーバーの起動が遅延されています。この移行が終わるまでお待ちください。", + "no-file": "要求されたファイルを移動することができないようです。パスを再確認して、Craftyに適切な権限があるかを確認してください。", + "noInternet": "インターネットへの接続に問題があります。 サーバーの作成は無効になっています。インターネットへの接続を確認し、ページを更新してください。", + "noJava": "サーバー {} は起動に失敗しました。エラーコード: Javaがインストールされていないことを検知しました。Javaがインストールされていないことを検知しました。Javaをインストールした後に、サーバーをインストールしてください。", + "not-downloaded": "実行ファイルが見つかりません。実行ファイルのダウンロードが終了しているか、実行権限があるかを確認してください。", + "portReminder": "今回が {} のはじめての起動であることを検知しました。インターネットからリモートアクセスできるように、ルータ・ファイヤーウォールでポート{}を転送してください。", + "privMsg": "と ", + "return": "ダッシュボードに戻る", + "selfHost": "このリポジトリをセルフホストしている場合は、アドレスを確認し、トラブルシューティングを参照してください。", + "start-error": "サーバー {} は起動に失敗しました。エラーコード: {}", + "superError": "この動作を実行するには管理者である必要があります。", + "terribleFailure": "深刻なエラーが発生しました。" + }, + "serverDetails": { + "terminal": "ターミナル", + "backup": "バックパップ", + "config": "設定", + "files": "ファイル", + "filter": "フィルターされたログ", + "filterList": "フィルターする単語", + "logs": "ログ", + "metrics": "メトリクス", + "playerControls": "プレイヤー管理", + "reset": "スクロールをリセット", + "schedule": "スケジュール", + "serverDetails": "サーバー情報" + }, + "webhooks": { + "name": "名前", + "new": "新しいウェブフック", + "newWebhook": "新しいウェブフック", + "no-webhook": "このサーバーには現在ウェブフックがありません。クリックして作成してください。", + "run": "ウェブフックをテストする", + "send_command": "サーバーがコマンドを受け取りました。", + "start_server": "サーバーが起動しました。", + "stop_server": "サーバーが停止しました。", + "trigger": "トリガー", + "type": "ウェブフックの種類", + "url": "ウェブフックのURL", + "areYouSureDel": "このウェブフックを削除しますか。", + "areYouSureRun": "このウェブフックをテストしますか。", + "backup_server": "サーバーのバックアップが完了しました。", + "bot_name": "ボットの名前", + "color": "アクセント色を選択", + "crash_detected": "サーバーがクラッシュしました。", + "edit": "編集", + "enabled": "有効化", + "jar_update": "サーバーの実行ファイルがアップデートされました。", + "kill": "サーバーが終了しました。", + "webhook_body": "ウェブフックの本文", + "webhooks": "すべてのウェブフック" + }, + "404": { + "contact": "DiscordでCraftyサポートに連絡", + "notFound": "ページが見つかりませんでした", + "unableToFind": "お探しのページが見つかりませんでした。再度お試しいただくか、元のページに戻りページを更新してください。" + }, + "accessDenied": { + "accessDenied": "アクセス拒否", + "contact": "DiscordでCraftyサポートに連絡", + "contactAdmin": "このページにアクセスするにはサーバー管理者に連絡してください。アクセスできるはずなのにページにアクセスできない場合は、サポートに連絡してください。", + "noAccess": "このページにアクセスすることができませんでした。" + }, + "apiKeys": { + "apiKeys": "APIキー", + "auth": "認証されていますか? ", + "buttons": "ボタン", + "config": "設定", + "crafty": "Crafty: ", + "createNew": "新しいAPIトークンを作成", + "created": "作成済み", + "deleteKeyConfirmation": "このAPIキーを削除してもよろしいですか。この操作は元に戻せません。", + "deleteKeyConfirmationTitle": "APIキー:${keyId} を削除してもよろしいですか。", + "fullAccess": "フルアクセス", + "getToken": "APIトークンを取得", + "name": "名前", + "nameDesc": "このAPIトークンをどのように呼びますか。 ", + "no": "いいえ", + "pageTitle": "ユーザーのAPIキーを編集", + "permName": "権限名", + "perms": "権限", + "server": "サーバー: ", + "yes": "はい" + }, + "base": { + "doesNotWorkWithoutJavascript": "警告: JavaScriptが無効の状態では、Craftyは正常に動作しない恐れがあります!" + }, + "credits": { + "developmentTeam": "開発チーム", + "hugeDesc": "多大なる", + "pageDescription": "この方々のご支援がなくては、Craftyは存在しません。", + "pageTitle": "クレジット", + "patreonDesc": "私たちの Patreon / Ko-fi の支援者たちに!", + "patreonOther": "その他", + "patreonSupporter": "Patreon / Ko-fi でのご支援者", + "patreonUpdate": "最終更新日時:", + "retiredStaff": "引退したスタッフ", + "subscriberName": "お名前", + "subscriptionLevel": "レベル", + "supportTeam": "サポート・ドキュメントチーム", + "thankYou": "感謝を!", + "translationDesc": "私たちのコミュニティを翻訳している方たちです! [ 活動中 = 🟢 休止中・引退済み = ⚪ ]", + "translationName": "言語名", + "translationTitle": "多言語への翻訳", + "translator": "翻訳者" + }, + "customLogin": { + "apply": "適用", + "backgroundUpload": "背景アップロード", + "customLoginPage": "ログインページをカスタマイズ", + "delete": "削除", + "labelLoginImage": "ログインページの背景を選択してください。", + "loginBackground": "ログインページの背景画像", + "loginImage": "ログイン画面に表示する背景画像をアップロード", + "loginOpacity": "ログインフォームの透明度を選択", + "pageTitle": "ログインページをカスタマイズ", + "preview": "プレビュー", + "select": "選択", + "selectImage": "画像を選択" + }, + "dashboard": { + "actions": "操作", + "allServers": "サーバー一覧", + "avg": "平均", + "backups": "バックアップ", + "bePatientClone": "サーバーを複製している間、しばらくお待ちください。
この画面はしばらくした後に更新されます。", + "bePatientRestart": "サーバーを再起動している間、しばらくお待ちください。
この画面はしばらくした後に更新されます。", + "bePatientStart": "サーバーを起動している間、しばらくお待ちください。
この画面はしばらくした後に更新されます。", + "bePatientStop": "サーバーを停止している間、しばらくお待ちください。
この画面はしばらくした後に更新されます。", + "cannotSee": "すべて表示されていますか?", + "cannotSeeOnMobile": "モバイルですべて表示されていませんか?", + "cannotSeeOnMobile2": "左右に表をスクロールしてみてください。", + "clone": "複製", + "cloneConfirm": "このサーバーを複製しますか。この処理には時間を要します。", + "cpuCores": "CPU コア数", + "cpuCurFreq": "CPU クロック周波数", + "cpuMaxFreq": "CPU 最大クロック周波数", + "cpuUsage": "CPU 使用率", + "crashed": "クラッシュ", + "dashboard": "ダッシュボード", + "delay-explained": "サービス・エージェントが先ほど起動したため、マインクラフトサーバーインスタンスの起動を遅らせています。", + "host": "ホスト", + "installing": "インストール中...", + "kill": "プロセスを終了", + "killing": "プロセスを終了中...", + "lastBackup": "最終:", + "max": "最大", + "memUsage": "メモリ使用率", + "motd": "MOTD (サーバー説明文)", + "newServer": "新しいサーバーを作成", + "nextBackup": "次回:", + "no-servers": "サーバーがありません。ボタンをクリックして開始してください。", + "offline": "オフライン", + "online": "オンライン", + "players": "プレイヤー数", + "restart": "再起動", + "sendingCommand": "コマンドを送信", + "server": "サーバー", + "servers": "サーバー数", + "size": "サーバーディレクトリサイズServer Dir Size", + "start": "起動", + "starting": "遅延して起動", + "status": "状態", + "stop": "終了", + "storage": "ストレージ", + "version": "バージョン", + "welcome": "Craftyコントローラーへようこそ" + }, + "datatables": { + "i18n": { + "aria": { + "sortAscending": ": 行を昇順に並び替え中", + "sortDescending": ": 行を降順に並び替え中" + }, + "buttons": { + "collection": "コレクション ", + "colvis": "列を非表示にする", + "colvisRestore": "列を再表示する", + "copy": "コピー", + "copyKeys": "ctrlキーか、 u2318 + C を教えて表のデータをクリップボードにコピーしてください。

取り消すためには、このメッセージをクリックするか、Escキーを教えてください。", + "copySuccess": { + "1": "1行をクリップボードにコピー", + "_": "%d行をクリップボードにコピー" + }, + "copyTitle": "クリップボードにコピー", + "csv": "CSV", + "excel": "Excel", + "pageLength": { + "-1": "すべての行を表示", + "1": "1行を表示", + "_": "%d行を表示" + }, + "pdf": "PDF", + "print": "印刷" + }, + "emptyTable": "表に利用可能なデータがありません。", + "info": "_START_ 件目から _END_ 件目までの _TOTAL_ 件のデータを表示中", + "infoEmpty": "0 件目から 0 件目までの 0 件のデータを表示中", + "infoFiltered": "(filtered from _MAX_ total entries)", + "lengthMenu": "_MENU_ 件のメニューを表示中", + "loadingRecords": "読み込み中...", + "paginate": { + "first": "最初へ", + "last": "最後へ", + "next": "次へ", + "previous": "前へ" + }, + "processing": "処理中...", + "search": "検索:", + "select": { + "cells": { + "0": "セルを選択するにはクリックしてください。", + "1": "%d 個のセルが選択中", + "_": "%d 個のセルが選択中" + }, + "columns": { + "0": "列を選択するにはクリックしてください。", + "1": "%d 列が選択中", + "_": "%d 列が選択中" + }, + "rows": { + "0": "行を選択するにはクリックしてください。", + "1": "%d 行が選択中", + "_": "%d 行が選択中" + } + }, + "thousands": ",", + "zeroRecords": "条件に当てはまるデータがありませんでした。" + }, + "loadingRecords": "読み込み中..." + }, + "footer": { + "allRightsReserved": "無断複写・転載を禁じます", + "copyright": "Copyright", + "version": "バージョン" + }, + "login": { + "defaultPath": "入力されたパスワードは、デフォルト証明書のパスであり、パスワードではありません。そのパスからデフォルトパスワードを見つけて入力してください。", + "disabled": "ユーザーアカウントは無効です。詳細な情報を得るにはシステム管理者に連絡してください。", + "forgotPassword": "パスワードを忘れた場合", + "incorrect": "ユーザー名・パスワードが正しくありません。", + "login": "ログイン", + "password": "パスワード", + "username": "ユーザー名", + "viewStatus": "公開ステータスページを確認" + }, + "notify": { + "activityLog": "アクティブログ", + "backupComplete": "サーバー {} のバックアップは正常に完了しました。", + "backupStarted": "サーバー {} のバックアップが開始しました。", + "downloadLogs": "サポートログをダウンロードしますか?", + "finishedPreparing": "サポートログの準備が完了しました。クリックしてダウンロードしてください。", + "logout": "ログアウト", + "preparingLogs": " ログを準備している間しばらくお待ちください... 準備が出来たら通知を送ります。大容量のファイルの展開には時間がかかることがあります。", + "supportLogs": "サポートログ" + }, + "offline": { + "offline": "オフライン", + "pleaseConnect": "Craftyを使うにはインターネットに接続してください。" + }, + "panelConfig": { + "adminControls": "管理者コントロール", + "allowedServers": "許可されたサーバー", + "apply": "適用", + "assignedRoles": "割り当てられたロール", + "cancel": "キャンセル", + "clearComms": "未実行のコマンドを削除", + "custom": "Cratfyをカスタマイズ", + "delete": "削除", + "edit": "編集", + "enableLang": "すべての言語を有効化", + "enabled": "有効", + "globalExplain": "Craftyがサーバーファイルを保存する場所です。 (Craftyは /servers/[uuid of server] 内に保存します。)", + "globalServer": "グローバルサーバーディレクトリ", + "json": "Config.json", + "match": "パスワードが一致する必要があります。", + "newRole": "新しいロールを作成", + "newUser": "新しいユーザーを作成", + "noMounts": "ダッシュボードにマウントを表示しない", + "pageTitle": "パネル設定", + "role": "ロール", + "roleUsers": "ユーザー", + "roles": "すべてのロール", + "save": "保存", + "select": "選択", + "superConfirm": "このユーザーにすべて(全ユーザーアカウント、サーバー、パネル設定など)の権限を付与したいときのみ実行してください。このユーザーはあなたのスーパーユーザー権限をはく奪することもできます。", + "superConfirmTitle": "スーパーユーザーを有効化しますが、よろしいですか。", + "title": "Craftyの設定", + "user": "ユーザー", + "users": "すべてのユーザー" + }, + "rolesConfig": { + "config": "ロール設定", + "configDesc": "ここでロールの設定を変えることができます。", + "configUpdate": "最終更新: ", + "created": "作成: ", + "delRole": "削除済みのロール", + "doesNotExist": "存在しないものを削除するととはできません。", + "pageTitle": "ロールを編集", + "pageTitleNew": "新しいロールを作成", + "permAccess": "アクセス?", + "permName": "権限名", + "permsServer": "一部のサーバーに対して、このロールが持つ権限", + "roleConfigArea": "ロール編集画面", + "roleDesc": "このロールをどのように呼びますか。", + "roleName": "ロール名: ", + "rolePerms": "ロールの権限", + "roleServers": "許可のあるサーバー", + "roleTitle": "ロールの設定", + "roleUserName": "ユーザー名", + "roleUsers": "ユーザー一覧: ", + "selectManager": "このロールのマネージャーを選択", + "serverAccess": "閲覧できるか", + "serverName": "サーバー名", + "serversDesc": "アクセスを許可するサーバーを選択してください。" + }, + "serverBackups": { + "actions": "操作", + "after": "バックアップ後にコマンドを実行", + "backupAtMidnight": "真夜中に自動でバックパップを実行するか", + "backupNow": "今すぐバックアップ", + "backupTask": "バックパップ処理が開始しました。", + "backups": "サーバーのバックアップ", + "before": "バックアップ前にコマンドを実行", + "cancel": "キャンセル", + "clickExclude": "除外するファイルを選択", + "compress": "バックパップを圧縮", + "confirm": "確認", + "confirmDelete": "このバックアップを削除しますか。この操作は元に戻せません。", + "confirmRestore": "このバックアップを復元しますか。現在のサーバーファイルはバックパップ時のものに変更され、復元することができません。", + "currentBackups": "バックパップ一覧", + "default": "デフォルトのバックアップ", + "defaultExplain": "更新前にCraftyが使用するバックアップです。変更・削除することができません。", + "delete": "削除", + "destroyBackup": "\" + file_to_del + \"を削除しますか。", + "download": "ダウンロード", + "edit": "編集", + "enabled": "有効化", + "excludedBackups": "除外されるパス: ", + "excludedChoose": "バックアップから除外するパスを選択してください。", + "exclusionsTitle": "バックアップの除外設定", + "failed": "失敗", + "maxBackups": "最大バックパップ数", + "maxBackupsDesc": "Craftyは古いバックアップを削除することで、N個より多くのバックアップを保存しません。(0を入力するとすべてのバックアップを保存します。)", + "myBackup": "新しいバックパップ", + "name": "名前", + "newBackup": "新しいバックパップを作成", + "no-backup": "バックアップはありません。新しくバックアップの設定を作成するには、ボタンをクリックしてください。", + "options": "設定", + "path": "パス", + "restore": "復元", + "restoring": "バックアップを復元しています。この処理には時間がかかることがあります。しばらくお待ちください。", + "run": "バックアップを実行", + "save": "保存", + "shutdown": "バックアップ中はサーバーをシャットダウンする", + "size": "サイズ", + "standby": "待機中", + "status": "ステータス", + "storage": "バックアップ保存場所", + "storageLocation": "保存場所", + "storageLocationDesc": "バックアップを保存する場所を選択してください。" + }, + "serverConfig": { + "bePatientDelete": "サーバーをCraftyパネルから削除する間、しばらくお待ちください。この画面はしばらくした後に閉じられます。", + "bePatientDeleteFiles": "サーバーをCraftyパネルから削除し、すべてのファイルを削除する間、しばらくお待ちください。 この画面はしばらくした後に閉じられます。", + "bePatientUpdate": "サーバーを更新している間、しばらくお待ちください。ダウンロードに要する時間はインターネット速度によって異なります。
この画面はしばらくした後に更新されます。", + "cancel": "キャンセル", + "countPlayers": "サーバーをプレイヤー数に含める", + "crashTime": "クラッシュタイムアウト", + "crashTimeDesc": "どのくらいの時間が経てばクラッシュしたとみなしますか。", + "deleteFilesQuestion": "ホストからサーバーファイルを削除しますか。", + "deleteFilesQuestionMessage": "ホストからサーバーファイルを削除しますか。

サーバーのバックアップも含まれます。", + "deleteServer": "サーバーを削除", + "deleteServerQuestion": "サーバーを削除しますか。", + "deleteServerQuestionMessage": "このサーバーを削除しますか。この処理の後にはなにも残りません...", + "exeUpdateURL": "サーバー実行ファイルのアップデートURL", + "exeUpdateURLDesc": "アップデートをURLから直接ダウンロードします。", + "ignoredExits": "無視する終了コード", + "ignoredExitsExplain": "Craftyがクラッシュを検知するときに通常終了だと考える終了コード (コンマで区切ってください。)", + "javaNoChange": "上書きしない", + "javaVersion": "現在のJavaのバージョンを上書き", + "javaVersionDesc": "Javaを上書きしようとする場合、「サーバー実行コマンド」にJavaのパスが引用符で囲まれていることを確認してください。(デフォルトの'java'は除外)", + "noDelete": "いいえ、元に戻る", + "noDeleteFiles": "いいえ、ただパネルから削除する", + "removeOldLogsAfter": "古いログを削除する日数", + "removeOldLogsAfterDesc": "何日後にログを削除するかを入力してください。(0にすると無効になります。)", + "save": "保存", + "sendingDelete": "サーバーを削除中", + "sendingRequest": "リクエストを送信中...", + "serverAutoStart": "サーバーを自動で起動する", + "serverAutostartDelay": "サーバーの起動を遅延させる秒数", + "serverAutostartDelayDesc": "自動で起動するまでの秒数(有効になっている場合)", + "serverCrashDetection": "サーバーのクラッシュを検知する", + "serverExecutable": "サーバーの実行ファイル", + "serverExecutableDesc": "サーバーの実行ファイル", + "serverExecutionCommand": "サーバー実行コマンド", + "serverExecutionCommandDesc": "サーバー起動時にターミナルで実行されるコマンド", + "serverIP": "サーバーのIPアドレス", + "serverIPDesc": "Craftyが統計情報を取得するIPアドレス (問題が生じた場合は、本当のIPアドレスの代わりに 127.0.0.1 を試してください。)", + "serverLogLocation": "サーバーログの保存場所", + "serverLogLocationDesc": "ログファイルを保存する場所", + "serverName": "サーバー名", + "serverNameDesc": "このサーバーをどのように呼びますか。", + "serverPath": "サーバーのディレクトリ", + "serverPathDesc": "絶対パスで指定してください。(実行ファイルを含まないでください。)", + "serverPort": "サーバーのポート", + "serverPortDesc": "Craftyが統計情報を取得するポート", + "serverStopCommand": "サーバーの停止コマンド", + "serverStopCommandDesc": "サーバーを停止させるときに送信するコマンド", + "showStatus": "公開ステータスページにサーバーの状態を表示する", + "shutdownTimeout": "シャットダウンするまで秒数", + "statsHint1": "サーバーが稼働しているポートをここに入力してください。統計情報を取得するためにCraftyが接続します。", + "statsHint2": "これはサーバーのポートを変更するものではありません。ポートを変更するにはサーバーの設定ファイルを変更してください。", + "stopBeforeDeleting": "削除する前にサーバーを停止してください。", + "timeoutExplain1": "サーバーを終了するコマンドを実行した後に、Craftyがプロセスを強制終了するまでに待機する時間", + "update": "実行ファイルをアップデート", + "yesDelete": "はい、削除してください。", + "yesDeleteFiles": "はい、ファイルを削除してください。" + }, + "serverConfigHelp": { + "desc": "ここではサーバーの設定を帰ることができます。", + "perms": [ + "Craftyによって管理されているパスを変更しないことが推奨されています。", + "パスを変更することは、特にファイルの権限がより厳密に管理されているLinuxにおいては、システムを損傷させる恐れがあります。CAN", + "

", + "サーバーの位置を変更する必要がある場合、\"crafty\" ユーザーにサーバーのパスの読み取り・書き込み権限を付与してください。", + "
", + "
", + "Linuxでは、以下のコマンドを実行することが最善です。
", + "", + " sudo chown crafty:crafty /path/to/your/server -R
", + " sudo chmod 2775 /path/to/your/server -R
", + "
" + ], + "title": "サーバー設定" + }, + "serverFiles": { + "clickUpload": "ここをクリックしてファイルを選択", + "close": "閉じる", + "createDir": "新しいディレクトリを作成", + "createDirQuestion": "新しいディレクトリの名前を入力してください。", + "createFile": "新しいファイルを作成", + "createFileQuestion": "新しいファイルの名前を入力してください。", + "default": "デフォルト", + "delete": "削除", + "deleteItemQuestion": "\" + name + \"を削除しますか。", + "deleteItemQuestionMessage": "\\\"\" + path + \"\\\"を削除しようとしています。!

この操作は復元できず、完全に削除されます。", + "download": "ダウンロード", + "editingFile": "ファイルを編集", + "error": "ファイル取得エラー", + "fileReadError": "ファイル読み込みエラー", + "files": "ファイル", + "keybindings": "キーバインド設定", + "loadingRecords": "ファイル読み込み中...", + "noDelete": "いいえ", + "noscript": "ファイルマネージャーはJavaScriptなしでは正常に動作しません。", + "rename": "名前を変更", + "renameItemQuestion": "変更後の名前を入力してください。", + "save": "保存", + "size": "エディターの大きさを変更", + "stayHere": "このページから移動しないでください。", + "unsupportedLanguage": "警告: サポートされていないファイルの種類です。", + "unzip": "解凍", + "upload": "アップロード", + "uploadTitle": "アップロード先: ", + "waitUpload": "ファイルをアップロードしています。しばらくお待ちください。この処理には時間がかかることがあります。", + "yesDelete": "はい、この状況を理解しています。" + }, + "serverMetrics": { + "resetZoom": "ズームをリセット", + "zoomHint1": "グラフをズームするには、シフトキーを押しながらスクロールしてください。", + "zoomHint2": "または、シフトキーを押しながら、拡大したい範囲をドラックして選択してください。" + }, + "serverPlayerManagement": { + "bannedPlayers": "アクセスが禁止されたプレイヤー", + "loadingBannedPlayers": "アクセスが禁止されたプレイヤーを表示中", + "players": "プレイヤー" + }, + "serverScheduleConfig": { + "backup": "サーバーをバックアップ", + "basic": "Basic", + "children": "関連付けられた子タスク: ", + "command": "コマンド", + "command-explain": "実行するコマンドを入力してください。'/'を含まないでください。", + "cron": "Cron", + "cron-explain": "cronの設定を入力してください。-- 注意: 0 = 最後のオプションの月曜日", + "custom": "カスタムコマンド", + "days": "日ごと", + "enabled": "有効化", + "hours": "時間ごと", + "interval": "実行間隔", + "interval-explain": "どの頻度でこのスケジュールを実行しますか。", + "minutes": "分ごと", + "offset": "遅延オフセット", + "offset-explain": "最初のタスクを実行してから、どのくらいの時間待機してからこのコマンドを実行しますか。(秒数)", + "one-time": "実行後にこのスケジュールを削除", + "parent": "親スケジュールを選択", + "parent-explain": "どのスケジュールがこのスケジュール実行されるかを選択してください。", + "reaction": "Reaction", + "restart": "サーバーを再起動", + "select": "Basic / Cron / Chain Reaction を選択", + "start": "サーバーを起動", + "stop": "サーバーを停止", + "time": "実行時刻", + "time-explain": "何時何分にスケジュールを実行しますか。" + }, + "serverSchedules": { + "action": "操作", + "actionId": "子スケジュールを選択", + "areYouSure": "スケジュールされたタスクを削除しますか。", + "cancel": "キャンセル", + "cannotSee": "すべて表示されていますか?", + "cannotSeeOnMobile": "詳細を表示するためにはスケジュールされたタスクをクリックしてください。", + "child": "子スケジュールのID ", + "close": "閉じる", + "command": "コマンド", + "confirm": "確認", + "confirmDelete": "このスケジュールされたタスクを削除しますか。この操作は元に戻せません。", + "create": "スケジュールを新しく作成", + "cron": "Cron 文字列", + "delete": "削除", + "details": "スケジュールの詳細", + "edit": "編集", + "enabled": "有効化", + "every": "毎日", + "interval": "間隔", + "name": "名前", + "newSchedule": "新しいスケジュール", + "nextRun": "次回実行時", + "no": "いいえ", + "no-schedule": "このサーバーには現在スケジュールがありません。クリックして作成してください。", + "scheduledTasks": "スケジュールされたタスク", + "yes": "はい" + }, + "serverStats": { + "cpuUsage": "CPU使用率", + "description": "説明文", + "errorCalculatingUptime": "稼働時間計算エラー", + "loadingMotd": "MOTD(サーバー説明文)を読み込み中", + "memUsage": "メモリ使用率", + "offline": "オフライン", + "online": "オンライン", + "players": "プレイヤー数", + "serverStarted": "サーバー最終起動日時", + "serverStatus": "サーバーの状態", + "serverTime": "UTC時間", + "serverTimeZone": "サーバーのタイムゾーン", + "serverUptime": "サーバー稼働時間", + "starting": "遅延起動", + "unableToConnect": "接続不可", + "version": "バージョン" + }, + "serverTerm": { + "commandInput": "コマンドを送信", + "delay-explained": "サービス・エージェントが先ほど起動したため、マインクラフトサーバーインスタンスの起動を遅らせています。", + "importing": "インポート中...", + "installing": "インストール中...", + "restart": "再起動", + "sendCommand": "コマンドを送信", + "start": "起動", + "starting": "遅延起動", + "stop": "停止", + "stopScroll": "自動スクロールを停止", + "updating": "更新中..." + }, + "serverWizard": { + "absoluteServerPath": "サーバーファイルの絶対パス", + "absoluteZipPath": "サーバーファイルの絶対パス", + "addRole": "既存のロールにサーバーを追加する。", + "autoCreate": "何も選択されない場合、新しいロールを作成します。", + "bePatient": "必要なファイルを' + (importing ? 'インポート' : 'ダウンロード') + 'している間、しばらくお待ちください。", + "buildServer": "サーバーを作成", + "clickRoot": "ルートディレクトリを選択", + "close": "閉じる", + "defaultPort": "デフォルトは25565番ポートです。", + "downloading": "サーバーをダウンロード中...", + "explainRoot": "下のボタンをクリックして、アーカイブ内のサーバーのルートディレクトリを選択してください。", + "importServer": "既存のサーバーをインポート", + "importServerButton": "サーバーをインポート", + "importZip": "zipファイルからサーバーをインポート", + "importing": "サーバーをインポート中...", + "labelZipFile": "zipファイルをインポート", + "maxMem": "最大メモリ使用量", + "minMem": "最小メモリ使用量", + "myNewServer": "新しいサーバー", + "newServer": "新規でサーバーを作成", + "noRole": "検索パラメータにあてはまるロールはありません。", + "noneRoles": "ロールが選択されていません。", + "quickSettings": "クイック設定", + "quickSettingsDescription": "これらの値は後から変更できます。", + "resetForm": "リセット", + "save": "保存", + "selectRole": "ロールを選択", + "selectRoot": "アーカイブのルートディレクトリを選択", + "selectServer": "サーバーを選択", + "selectType": "サーバーの種類を選択 (Vanilla, Servers, Moddedなど)", + "selectVersion": "バージョンを選択", + "selectZipDir": "ファイルを解凍したいアーカイブのディレクトリを選択", + "serverJar": "サーバーの実行ファイルを選択", + "serverName": "サーバー名", + "serverPath": "サーバーパス", + "serverPort": "サーバーポート", + "serverSelect": "サーバーを選択", + "serverType": "サーバーの種類", + "serverUpload": "圧縮されたサーバーファイルをアップロード", + "serverVersion": "サーバーバージョン", + "sizeInGB": "ファイルサイズ(GB)", + "unsupported": "バージョン1.8未満のマインクラフトはCraftyでサポートされていません。インストールした場合、正常に動作しないかもしれません。", + "uploadButton": "アップロード", + "uploadZip": "サーバーをインポートするためにzipファイルをアップロード", + "zipPath": "サーバーファイルのパス" + }, + "sidebar": { + "contribute": "貢献", + "credits": "クレジット", + "dashboard": "ダッシュボート", + "documentation": "ドキュメント", + "inApp": "アプリ内ドキュメント", + "newServer": "新しいサーバーを作成", + "servers": "サーバー" + }, + "startup": { + "almost": "もうすぐ完了します。", + "cache": "Big Bucketのキャッシュファイルを更新中です。", + "internals": "Craftyの内部コンポーネントを設定・起動中です。", + "internet": "インターネット接続を確認中", + "server": "初期化中 ", + "serverInit": "サーバーを初期化中", + "starting": "Craftyは起動中です...", + "tasks": "タスクスケジュラーを起動中" + }, + "userConfig": { + "apiKey": "APIキー", + "auth": "認証されているか ", + "config": "設定", + "configArea": "ユーザー設定", + "configAreaDesc": "ここではユーザー設定をすべて変えることができます。", + "confirmDelete": "本当にユーザーを削除しますか。この操作は元に戻せません。", + "craftyPermDesc": "ユーザーのCraftyにおける権限 ", + "craftyPerms": "Craftyにおける権限 ", + "created": "作成日時: ", + "delSuper": "スーパーユーザーを削除することはできません。", + "deleteUser": "ユーザーを削除: ", + "deleteUserB": "ユーザーを削除", + "enabled": "有効化", + "gravDesc": "このメールアドレスはGravatar™を使用するために用いられます。Craftyはどのような状況でも、あなたのGravatar™プロフィールを見つける以外の目的には使用しません。", + "gravEmail": "Gravatar™ メールアドレス", + "lastIP": "最終アクセス IPアドレス: ", + "lastLogin": "最終ログイン: ", + "lastUpdate": "最終更新: ", + "leaveBlank": "パスワードを変更せずにユーザーを編集するためには、空欄にしてください。", + "manager": "マネージャー", + "member": "メンバーか", + "notExist": "存在しないものを削除することはできません。", + "pageTitle": "ユーザーを変種", + "pageTitleNew": "ユーザーを作成", + "password": "新しいパスワード", + "permName": "権限名", + "repeat": "パスワードを変更", + "roleName": "ロール名", + "selectManager": "ユーザーのマネージャーを選択", + "super": "スーパーユーザー", + "userLang": "ユーザーの使用する言語", + "userName": "ユーザー名", + "userNameDesc": "このユーザーをどのように呼びますか。", + "userRoles": "ユーザーのロール", + "userRolesDesc": "ユーザーの属しているロール", + "userSettings": "ユーザー設定", + "userTheme": "UIテーマ", + "uses": "許可されている使用回数 (-1で無制限)" + }, + "validators": { + "passLength": "パスワードが短すぎます。最小文字数は8文字です。" + } +} From 018d297f3a69a4c2bac0cf29240db8e6b5376609 Mon Sep 17 00:00:00 2001 From: Analicia A Date: Sun, 1 Dec 2024 19:25:59 +0000 Subject: [PATCH 39/74] Translated (Mongo (lol_EN)) Currently translated at 100.0% (614 of 614 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/lol_EN/ --- app/translations/lol_EN.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/translations/lol_EN.json b/app/translations/lol_EN.json index 0de8e017..7a15ffa4 100644 --- a/app/translations/lol_EN.json +++ b/app/translations/lol_EN.json @@ -7,7 +7,7 @@ "accessDenied": { "accessDenied": "ACCES DENID", "contact": "CONTACK CWAFTY CONTROLLR SUPORT ON DA DWISCORDZ", - "contactAdmin": "PLZ TALKZ TO UR SERVR HOOMAN FOR DIS, OR IF U FINKZ U SHUD GET IN, ASK SUPORT", + "contactAdmin": "PLZ TALKZ TO UR SERVR HOOMAN FOR DIS, OR IF U FINKZ U SHUD GET IN, ASK SUPORT.", "noAccess": "U DO NOT HAZ ACCES 2 DIS LITTERBOX" }, "apiKeys": { From 2e03fc3f9bc537a05f1a68942d93a5de1324be96 Mon Sep 17 00:00:00 2001 From: Analicia A Date: Sun, 1 Dec 2024 19:42:39 +0000 Subject: [PATCH 40/74] Translated (Czech) Currently translated at 96.3% (610 of 633 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/cs/ --- app/translations/cs_CS.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/translations/cs_CS.json b/app/translations/cs_CS.json index ea69fb45..00ba247c 100644 --- a/app/translations/cs_CS.json +++ b/app/translations/cs_CS.json @@ -620,7 +620,7 @@ }, "startup": { "almost": "Dokončuji. Držte se...", - "cache": "Znovu načítam mezipaměť Big Bucket", + "cache": "Znovu načítam mezipaměť Big Bucket", "internals": "Nastavuji a startuji Crafty interní komponenty", "internet": "Kontroluju připojení k internetu", "server": "Konfigurace ", From b98f5f4cf11c44e772c879e956092c0e38bf97c4 Mon Sep 17 00:00:00 2001 From: Analicia A Date: Sun, 1 Dec 2024 19:42:57 +0000 Subject: [PATCH 41/74] Translated (Spanish) Currently translated at 96.3% (610 of 633 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/es/ --- app/translations/es_ES.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/translations/es_ES.json b/app/translations/es_ES.json index 9d88bcee..18bd1609 100644 --- a/app/translations/es_ES.json +++ b/app/translations/es_ES.json @@ -563,7 +563,7 @@ }, "serverWizard": { "absoluteServerPath": "Ruta absoluta del servidor", - "absoluteZipPath": "Ruta absoluta servidor", + "absoluteZipPath": "Ruta absoluta servidor", "addRole": "Añadir Servidor a grupos existentes...", "autoCreate": "Si ninguno es seleccionado, ¡Crafty creara uno!", "bePatient": "Por favor tenga paciencia, mientras se ' + (importing ? 'importa' : 'descarga') + ' el servidor.", From 06e1c58549787d264d235a7a3203f5070ba0a0a1 Mon Sep 17 00:00:00 2001 From: Iain Powrie Date: Sun, 1 Dec 2024 19:42:39 +0000 Subject: [PATCH 42/74] Translated (Mongo (lol_EN)) Currently translated at 100.0% (633 of 633 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/lol_EN/ --- app/translations/lol_EN.json | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/app/translations/lol_EN.json b/app/translations/lol_EN.json index 7a15ffa4..b808e164 100644 --- a/app/translations/lol_EN.json +++ b/app/translations/lol_EN.json @@ -672,7 +672,26 @@ "uses": "NUMBER OV USES ALLOWED (-1==NO LIMIT)" }, "validators": { - "passLength": "PASSWRD TOO SMOL. NEEDZ 8 CATZ PLZ" + "passLength": "PASSWRD TOO SMOL. NEEDZ 8 CATZ PLZ", + "backupName": "BACKUP NAME GOTTA BE WURDZ, AT LEAST 3 FISH.", + "enumErr": "OOFS IN VALIDATING. GOOD STUFF INCLUDES: ", + "serverExeCommand": "SERVER EXECUTION COMMAND GOTTA BE WURDZ, AT LEAST 1 FISH LONG.", + "filesPageLen": "LENGTH GOTTA BE MORE THAN 1 FOR DIS PROPERTY", + "insufficientPerms": "PERMISSION ERROR: U NEED MORE PERMISSIONZ FOR DIS RESOURCE", + "roleManager": "ROLE MANAGER GOTTA BE NUMBERS (MANAGER ID) OR NUFFIN", + "roleServerId": "SERVER ID GOTTA BE WURDZ, AT LEAST 1 FISH LONG", + "roleServerPerms": "SERVER PERMISSIONS GOTTA BE AN 8-BIT WURDZ", + "serverCreateName": "SERVER NAME GOTTA BE WURDZ, AT LEAST 2 FISH LONG AND CAN’T HAVE: \\\\ / or # ", + "taskIntervalType": "TASK INTERVAL TYPE GOTTA BE ONE OF: ", + "typeBool": "GOTTA BE MEOW OR NEOW (TYPE BOOLEAN)", + "typeEmail": "GOTTA BE EMAIL TYPE.", + "typeIntMinVal0": "GOTTA BE A WHOLE FISH AT LEAST... 0.", + "typeInteger": "GOTTA BE A NUMBR.", + "typeList": "GOTTA BE A ARAY ", + "typeString": "GOTTA BE STRINGY THINGY.", + "roleName": "ROLE NAME GOTTA BE WURDZ, MORE THAN 1 FISH. CAN’T HAVE THESE: [ ] , ", + "serverLogPath": "SERVER LOG PATH GOTTA BE WURDZ, AT LEAST 1 FISH LONG", + "userName": " GOTTA BE STRINGY THINGY, ALL LOW, AT LEAST 4 FISH, MAX 20 FISHIES" }, "webhooks": { "areYouSureDel": "U SURE U WANTZ TO EATZ DIS WEBHOOK?", From f00aff0fef4777755d7258fb7cf168ebf9ebd91c Mon Sep 17 00:00:00 2001 From: Yurii Prybyla Date: Sun, 1 Dec 2024 20:40:15 +0000 Subject: [PATCH 43/74] Translated (Ukrainian) Currently translated at 97.3% (616 of 633 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/uk/ --- app/translations/uk_UA.json | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/translations/uk_UA.json b/app/translations/uk_UA.json index 4c4ff9e6..1b759762 100644 --- a/app/translations/uk_UA.json +++ b/app/translations/uk_UA.json @@ -1,7 +1,7 @@ { "404": { "contact": "Зв'язатись з Crafty Control підтримкою через Discord", - "notFound": "Сторінку не найдено!", + "notFound": "Сторінку не найдено", "unableToFind": "Нам не вдалося знайти сторінку, яку ви шукаєте. Спробуйте ще раз або поверніться й оновіть." }, "accessDenied": { @@ -12,7 +12,7 @@ }, "apiKeys": { "apiKeys": "API Ключі", - "auth": "Авторизовані?", + "auth": "Авторизовані? ", "buttons": "Кнопки", "config": "Конфігурація", "crafty": "Crafty: ", @@ -672,7 +672,9 @@ "uses": "Дозволена кількість використань(-1==Без ліміту)" }, "validators": { - "passLength": "Пароль, надто короткий. Мінімальна довжина: 8 символів" + "passLength": "Пароль, надто короткий. Мінімальна довжина: 8 символів", + "enumErr": "помилка валідації. Прийнятні дані включають: ", + "insufficientPerms": "Помилка доступу: Відсутній доступ до цього ресурсу" }, "webhooks": { "areYouSureDel": "Ви впевнені, що хочете видалити цей Вебхук?", From d63968727565871fe7c05fc90217874f614eff99 Mon Sep 17 00:00:00 2001 From: Yurii Prybyla Date: Sun, 1 Dec 2024 20:47:56 +0000 Subject: [PATCH 44/74] Translated (Ukrainian) Currently translated at 97.3% (616 of 633 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/uk/ --- app/translations/uk_UA.json | 38 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/app/translations/uk_UA.json b/app/translations/uk_UA.json index 1b759762..d9eef914 100644 --- a/app/translations/uk_UA.json +++ b/app/translations/uk_UA.json @@ -8,7 +8,7 @@ "accessDenied": "Доступ заборонено", "contact": "Зв'язатись з Crafty Control підтримкою через Discord", "contactAdmin": "Щоб отримати доступ до цього ресурсу, зверніться до адміністратора свого сервера або, якщо ви вважаєте, що вже маєте доступ до цього ресурсу, зверніться до служби підтримки.", - "noAccess": "У вас немає доступу до цього ресурсу." + "noAccess": "У вас немає доступу до цього ресурсу" }, "apiKeys": { "apiKeys": "API Ключі", @@ -23,7 +23,7 @@ "fullAccess": "Повний доступ", "getToken": "Отримати Токен", "name": "Ім'я", - "nameDesc": "Як ви хочете назвати даний API токен?", + "nameDesc": "Як ви хочете назвати даний API токен? ", "no": "Ні", "pageTitle": "Редагування Користувацьких API ключів", "permName": "Назва дозволу", @@ -98,7 +98,7 @@ "motd": "MOTD", "newServer": "Створити новий сервер", "nextBackup": "Наступний:", - "no-servers": "Зараз відсутні сервери. Щоб розпочати, натисніть.", + "no-servers": "Зараз відсутні сервери. Щоб розпочати, натисніть", "offline": "Оффлайн", "online": "Онлайн", "players": "Гравці", @@ -199,7 +199,7 @@ "hereIsTheError": "Ось помилка", "installerJava": "Не вдалось встановити {} : Forge сервер потребує Java. Ми бачимо що, Java не інстальована. Будь ласка, встановіть java і лиш тоді сервер.", "internet": "Ми виявили, що машина, на якій працює Crafty, не має підключення до Інтернету. Підключення клієнта до сервера може бути обмежено.", - "migration": "Основне серверне сховище Crafty переноситься в нове місце. На цей час усі запуски серверів призупинено. Зачекайте, поки ми завершимо цю міграцію.", + "migration": "Основне серверне сховище Crafty переноситься в нове місце. На цей час усі запуски серверів призупинено. Зачекайте, поки ми завершимо цю міграцію", "no-file": "Здається, ми не можемо знайти потрібний файл. Ще раз перевірте шлях. Чи має Crafty належні дозволи?", "noInternet": "Crafty має проблеми з доступом до Інтернету. Створення сервера вимкнено. Перевірте підключення до Інтернету та оновіть сторінку.", "noJava": "Сервер {} не вдалося запустити з кодом помилки: ми виявили, що Java не встановлено. Установіть Java, а потім запустіть сервер.", @@ -236,7 +236,7 @@ "downloadLogs": "Завантажити логи для підтримки?", "finishedPreparing": "Ми підготували логи. Будь ласка натисніть завантажити", "logout": "Вихід", - "preparingLogs": "Будь ласка зачекайте поки ми підготуємо для вас логи... Ми надішлемо вам сповіщення коли усе буде готово. Це може зайняти трішки часу для великих проєктів.", + "preparingLogs": " Будь ласка зачекайте поки ми підготуємо для вас логи... Ми надішлемо вам сповіщення коли усе буде готово. Це може зайняти трішки часу для великих проєктів.", "schedule_desc": "Ми зафіксували, що деякі або всі ваші заплановані завдання не вдалось успішно перенести поки робиться оновлення. Будь ласка перевірте ваші заплановані завдання у відповідній вкладці.", "schedule_title": "Увага міграція запланованих завдань", "supportLogs": "Логи для підтримки" @@ -263,7 +263,7 @@ "match": "Паролі мають співпадати", "newRole": "Додати нову роль", "newUser": "Додати нового користувача", - "noMounts": "Show no Mounts on Dash", + "noMounts": "Не показувати диски на панелі", "pageTitle": "Панель конфігурації", "role": "Роль", "roleUsers": "Ролі юзерів", @@ -282,7 +282,7 @@ "configUpdate": "Востаннє оновлено: ", "created": "Створено: ", "delRole": "Видалити роль", - "doesNotExist": "Ви не можете видалити те, чого не існує!", + "doesNotExist": "Ви не можете видалити те, чого не існує", "pageTitle": "Редагувати роль", "pageTitleNew": "Нова роль", "permAccess": "Доступ?", @@ -314,7 +314,7 @@ "compress": "Стиснути бекап", "confirm": "Прийняти", "confirmDelete": "Ви дійсно бажаєте видати бекап? Ця дія незворотня.", - "confirmRestore": "Ви впевненні що бажаєте відновити даний бекап? При відновленні сервер буде вимкнуто та відновлено за допомогою даного бекапу, минулі файли будуть втрачені!", + "confirmRestore": "Ви впевненні що бажаєте відновити даний бекап? При відновленні сервер буде вимкнуто та відновлено за допомогою даного бекапу, минулі файли будуть втрачені.", "currentBackups": "Поточні бекапи", "default": "Звичайний Бекап", "defaultExplain": "Бекап цього Crafty буде створений перед оновленням. Це не можна змінити чи видалити.", @@ -350,7 +350,7 @@ "serverConfig": { "bePatientDelete": "Будь ласка зачекайте поки Crafty видалить сервер з панелі. Ця сторінка закриється через кілька секунд.", "bePatientDeleteFiles": "Будь ласка зачекайте поки Crafty видалить сервер з панелі та видалить усі його файли. Ця сторінка закриється через кілька секунд.", - "bePatientUpdate": "Please be patient while we update the server. Download times can vary depending upon your internet speeds.
This screen will refresh in a moment", + "bePatientUpdate": "Будь ласка, наберіться терпіння поки ми оновлюємо сервер. Час завантаження може змінюватись відповідно до швидкості вашого інтернету.
Цей екран оновиться, за хвилинку", "cancel": "Відміна", "countPlayers": "Враховувати сервер до загальної кількості гравців", "crashTime": "Краш таймаут", @@ -383,11 +383,11 @@ "serverExecutionCommand": "Виконувана команда запуску сервера", "serverExecutionCommandDesc": "Буде запущено у прихованому терміналі", "serverIP": "IP-адреса сервера", - "serverIPDesc": "IP-адреса Crafty для статистики (Спробуй справжню IP-адресу, або 127.0.0.1 якщо маєте проблеми)", + "serverIPDesc": "IP-адреса Crafty для статистики (Спробуй справжню IP-адресу, або 127.0.0.1 якщо маєте проблеми)", "serverLogLocation": "Логи сервера", "serverLogLocationDesc": "Шлях до логів сервера", "serverName": "Назва сервера", - "serverNameDesc": "Як назвати даний сервер?", + "serverNameDesc": "Як назвати даний сервер", "serverPath": "Робоча папка сервера", "serverPathDesc": "Повний шлях до папки сервера (не посилання на виконуваний файл)", "serverPort": "Порт сервера", @@ -400,13 +400,13 @@ "statsHint2": "Це не змінює порт вашого сервера. Ви мусите власноруч змінити налаштування в server.properties або іншому конфігураційному файлі.", "stopBeforeDeleting": "Будь ласка зупиніть сервер перед тим як видаляти його", "timeoutExplain1": "Скільки Crafty має чекати вимкнення вашого сервера після запуску", - "timeoutExplain2": "команди перед тим як примусово його вимкнути?", + "timeoutExplain2": "команди перед тим як примусово його вимкнути.", "update": "Оновити виконуваний файл", "yesDelete": "Так, видалити", "yesDeleteFiles": "Так, видалити файли" }, "serverConfigHelp": { - "desc": "Тут можна змінити конфігурацію вашого сервера.", + "desc": "Тут можна змінити конфігурацію вашого сервера", "perms": [ "Рекомендовано НЕ змінювати шлях до сервера який створив Crafty.", "Зміна шляхів МОЖЕ зламати щось, особливо в операційних системах типу Linux, де дозволи на файли більш заблоковані.", @@ -476,7 +476,7 @@ "serverPlayerManagement": { "bannedPlayers": "Заблоковані користувачі", "loadingBannedPlayers": "Завантаження заблокованих користувачів", - "players": "Користувачі" + "players": "Гравці" }, "serverScheduleConfig": { "backup": "Бекап серверу", @@ -579,7 +579,7 @@ "explainRoot": "Натисніть кнопку нижче, щоб вибрати кореневий каталог вашого сервера всередині архіву", "importServer": "Імпортувати готовий сервер", "importServerButton": "Імпортувати сервер!", - "importZip": "Імпортувати з Архіву(Zip) ", + "importZip": "Імпортувати з Архіву(Zip)", "importing": "Імпортування сервера...", "labelZipFile": "Виберіть архів (Zip)", "maxMem": "Максимум пам'яті", @@ -624,7 +624,7 @@ "startup": { "almost": "Закінчуємо. Тримайся міцніше...", "cache": "Оновлення файлу кешу Big Bucket", - "internals": "Налаштування та запуск внутрішніх компонентів Crafty ", + "internals": "Налаштування та запуск внутрішніх компонентів Crafty", "internet": "Перевірка доступу до інтернету", "server": "Ініціалізація ", "serverInit": "Ініціалізація серверів", @@ -638,10 +638,10 @@ "configArea": "Область конфігурації користувача", "configAreaDesc": "Тут ви можете змінити всі налаштування користувача", "confirmDelete": "Ви впевненні що бажаєте видалити даного користувача? Це незворотня дія.", - "craftyPermDesc": "Дозволи Crafty для цього користувача", + "craftyPermDesc": "Дозволи Crafty для цього користувача ", "craftyPerms": "Доступ Crafty: ", "created": "Створений: ", - "delSuper": "Ви не можете видалити суперюзера!", + "delSuper": "Ви не можете видалити суперюзера", "deleteUser": "Видалити користувача: ", "deleteUserB": "Видалити користувача", "enabled": "Увімкнуто", @@ -679,7 +679,7 @@ "webhooks": { "areYouSureDel": "Ви впевнені, що хочете видалити цей Вебхук?", "areYouSureRun": "Ви впевнені, що хочете перевірити цей Вебхук?", - "backup_server": "Бекап серверу завершено!", + "backup_server": "Бекап серверу завершено", "bot_name": "Назва бота", "color": "Вибрати колір", "crash_detected": "Сервер впав", From 58823a5222c71b84d37ff575ddad610785a02622 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 2 Dec 2024 00:29:11 +0000 Subject: [PATCH 45/74] Added translation (Korean) --- app/translations/ko_KR.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 app/translations/ko_KR.json diff --git a/app/translations/ko_KR.json b/app/translations/ko_KR.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/app/translations/ko_KR.json @@ -0,0 +1 @@ +{} From 9ac68d7218f54c5c1073fc4a15c3c9fb5eb1bf29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B9=B4=EB=82=98=EB=A6=AC?= Date: Mon, 2 Dec 2024 00:30:24 +0000 Subject: [PATCH 46/74] Translated (Korean) Currently translated at 96.6% (612 of 633 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/ko/ --- app/translations/ko_KR.json | 701 +++++++++++++++++++++++++++++++++++- 1 file changed, 700 insertions(+), 1 deletion(-) diff --git a/app/translations/ko_KR.json b/app/translations/ko_KR.json index 0967ef42..b50c8598 100644 --- a/app/translations/ko_KR.json +++ b/app/translations/ko_KR.json @@ -1 +1,700 @@ -{} +{ + "serverWizard": { + "serverVersion": "서버 버전", + "sizeInGB": "크기(GB 단위)", + "unsupported": "1.8 미만의 Minecraft 버전은 Crafty에서 지원되지 않습니다. 여전히 설치할 수 있지만, 결과는 다를 수 있습니다.", + "uploadButton": "업로드", + "uploadZip": "서버 가져오기를 위한 Zip 파일 업로드", + "zipPath": "서버 경로", + "absoluteServerPath": "서버의 절대 경로", + "absoluteZipPath": "서버의 절대 경로", + "addRole": "기존 역할에 서버 추가", + "autoCreate": "선택된 것이 없으면 Crafty가 하나를 만듭니다", + "bePatient": "서버를 ' + (importing ? '가져오고 있습니다' : '다운로드하고 있습니다') + ' 조금만 기다려 주세요", + "buildServer": "서버 빌드!", + "clickRoot": "여기를 클릭하여 루트 디렉터리를 선택하세요", + "close": "닫기", + "defaultPort": "25565가 기본포트입니다", + "downloading": "서버를 다운로드 중입니다...", + "explainRoot": "아카이브 내에서 서버의 루트 디렉터리를 선택하려면 아래 버튼을 클릭하세요", + "importServer": "기존 서버 가져오기", + "importServerButton": "서버 가져오기", + "importZip": "ZIP 파일에서 가져오기", + "importing": "서버 가져오는 중...", + "labelZipFile": "ZIP 파일을 선택하세요", + "maxMem": "최대 메모리", + "minMem": "최소 메모리", + "myNewServer": "새로운 서버 생성", + "newServer": "새 서버 생성", + "noRole": "현재 검색 매개변수로 찾은 역할이 없습니다", + "noneRoles": "선택된 역할이 없습니다", + "quickSettings": "빠른 설정", + "quickSettingsDescription": "걱정하지 마세요, 나중에 변경할 수 있습니다", + "resetForm": "폼 초기화", + "save": "저장", + "selectRole": "역할 선택", + "selectRoot": "아카이브 루트 디렉터리 선택", + "selectServer": "서버 선택", + "selectType": "서버 유형 (원본, 서버, 모드 등)", + "selectVersion": "버전 선택", + "selectZipDir": "파일을 압축 해제할 아카이브 내 디렉터리를 선택하세요", + "serverJar": "서버 실행 파일", + "serverName": "서버 이름", + "serverPath": "서버 경로", + "serverPort": "서버 포트", + "serverSelect": "서버 선택", + "serverType": "서버 타입", + "serverUpload": "ZIP으로 압축된 서버파일 업로드" + }, + "sidebar": { + "contribute": "기여자", + "credits": "크래딧", + "dashboard": "대시보드", + "documentation": "문서", + "inApp": "앱 내 문서", + "newServer": "새 서버 만들기", + "servers": "서버" + }, + "startup": { + "almost": "마무리 중입니다. 잠시만 기다려 주세요...", + "cache": "Big 버킷 캐시 파일 새로 고침", + "internals": "Crafty의 내부 구성 요소를 설정하고 시작하는 중", + "internet": "인터넷 연결 확인 중", + "server": "초기화 중 ", + "serverInit": "서버 초기화 중", + "starting": "Crafty가 시작 중입니다...", + "tasks": "작업 스케줄러 시작 중" + }, + "userConfig": { + "apiKey": "API 키", + "auth": "인증됨? ", + "config": "설정", + "configArea": "사용자 구성 영역", + "configAreaDesc": "여기에서 모든 사용자 설정을 변경할 수 있습니다", + "confirmDelete": "이 사용자를 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.", + "craftyPermDesc": "이 사용자가 가진 ", + "craftyPerms": "Crafty 권한: ", + "created": "생성됨: ", + "delSuper": "슈퍼 사용자를 삭제할 수 없습니다", + "deleteUser": "사용자 삭제: ", + "deleteUserB": "사용자 삭제", + "enabled": "활성화됨", + "gravDesc": "이 이메일은 Gravatar™와 함께 사용하기 위해서만 필요합니다. Crafty는 어떤 경우에도 이 이메일을 귀하의 Gravatar™를 조회하는 것 이외의 다른 용도로 사용하지 않습니다.", + "gravEmail": "Gravatar™ 이메일", + "lastIP": "마지막 IP: ", + "lastLogin": "마지막 로그인: ", + "lastUpdate": "마지막 업데이트: ", + "leaveBlank": "비밀번호를 변경하지 않고 사용자를 편집하려면 비워두세요.", + "manager": "관리자", + "member": "멤버?", + "notExist": "존재하지 않는 항목은 삭제할 수 없습니다!", + "pageTitle": "사용자 편집", + "pageTitleNew": "사용자 생성", + "password": "새 비밀번호", + "permName": "권한 이름", + "repeat": "비밀번호 확인", + "roleName": "역할 이름", + "selectManager": "사용자를 위한 관리자 선택", + "super": "슈퍼 사용자", + "userLang": "사용자 언어", + "userName": "사용자 이름", + "userNameDesc": "이 사용자의 이름을 무엇으로 설정하시겠습니까?", + "userRoles": "사용자 역할", + "userRolesDesc": "이 사용자가 속한 역할.", + "userSettings": "사용자 설정", + "userTheme": "UI 테마", + "uses": "허용되는 사용 횟수 (-1은 제한 없음)" + }, + "validators": { + "passLength": "비밀번호가 너무 짧아요! (최소 길이: 8)" + }, + "webhooks": { + "trigger": "트리거", + "type": "웹후크 유형", + "url": "웹후크 URL", + "webhook_body": "웹후크 본문", + "webhooks": "웹후크", + "areYouSureDel": "이 웹후크를 삭제하시겠습니까?", + "areYouSureRun": "이 웹후크를 테스트하시겠습니까?", + "backup_server": "서버 백업이 완료되었습니다", + "bot_name": "봇 이름", + "color": "색상 강조를 선택하세요", + "crash_detected": "서버가 크래시되었습니다", + "edit": "수정", + "enabled": "활성화", + "jar_update": "서버 실행 파일이 업데이트되었습니다", + "kill": "서버가 종료되었습니다", + "name": "이름", + "new": "새 웹후크", + "newWebhook": "새 웹후크", + "no-webhook": "현재 이 서버에는 웹후크가 없습니다. 시작하려면 클릭하세요.", + "run": "웹후크 테스트 실행", + "send_command": "서버 명령이 수신되었습니다", + "start_server": "서버가 시작되었습니다", + "stop_server": "서버가 정지되었습니다" + }, + "404": { + "contact": "디스코드로 Crafty Controll을 지원받으세요", + "notFound": "페이지를 찾을 수 없습니다", + "unableToFind": "찾고 계시는 페이지를 찾을 수 없습니다. 다시 시도하거나 뒤로가서 새로고침을 해주세요!" + }, + "accessDenied": { + "accessDenied": "접근 불가", + "contact": "디스코드로 Crafty Controll을 지원받으세요", + "contactAdmin": "해당 리소스에 접근하기 위해서는 서버 관리자에게 문의하시거나, 접근 권한이 있다고 생각되시면 지원팀에 문의해 주세요.", + "noAccess": "당신은 해당 리소스에 대한 권한이 없습니다" + }, + "apiKeys": { + "apiKeys": "API 키", + "auth": "인증됨? ", + "buttons": "버튼", + "config": "설정", + "crafty": "Crafty: ", + "createNew": "새 API 토큰 생성", + "created": "생성됨", + "deleteKeyConfirmation": "이 API 키를 삭제할건가요? 이 작업은 취소할 수 없어요", + "deleteKeyConfirmationTitle": "API 키 \"${keyId}\"를 제거하겠습니까?", + "fullAccess": "전체 액세스", + "getToken": "토큰 얻기", + "name": "이름", + "nameDesc": "이 API 토큰을 무엇이라고 부를건가요? ", + "no": "아니요", + "pageTitle": "사용자 API 키 편집", + "permName": "권한 이름", + "perms": "권한", + "server": "서버: ", + "yes": "예" + }, + "base": { + "doesNotWorkWithoutJavascript": "경고: JavaScript가 활성화되지 않으면 제대로 작동하지 않습니다!" + }, + "credits": { + "developmentTeam": "Development Team", + "hugeDesc": "진심으로", + "pageDescription": "이 사람들이 없었다면 Crafty가 없을거에요", + "pageTitle": "크래딧", + "patreonDesc": "Patreon/Ko-fi 후원자 여러분!", + "patreonOther": "Other", + "patreonSupporter": "Patreon / Ko-fi 후원자", + "patreonUpdate": "마지막 업데이트:", + "retiredStaff": "은퇴한 직원", + "subscriberName": "이름", + "subscriptionLevel": "후원 레벨", + "supportTeam": "지원 및 문서 팀", + "thankYou": "감사합니다", + "translationDesc": "번역해 주시는 우리 커뮤니티 여러분께! [ 활성 = 🟢 비활성/은퇴 = ⚪ ]", + "translationName": "이름", + "translationTitle": "언어 번역", + "translator": "번역가들" + }, + "customLogin": { + "apply": "적용", + "backgroundUpload": "배경 업로드", + "customLoginPage": "로그인 페이지 사용자 지정", + "delete": "삭제", + "labelLoginImage": "로그인 배경 선택", + "loginBackground": "로그인 배경 이미지", + "loginImage": "로그인 화면의 배경 이미지를 업로드합니다.", + "loginOpacity": "로그인 화면 불투명도 선택", + "pageTitle": "로그인 페이지 사용자 지정", + "preview": "미리보기", + "select": "선택", + "selectImage": "이미지 선택" + }, + "dashboard": { + "actions": "동작", + "allServers": "모든 서버", + "avg": "평균", + "backups": "백업", + "bePatientClone": "서버를 복사하는 동안 잠시 기달려주세요
이 화면은 자동으로 새로고침됩니다", + "bePatientRestart": "서버를 재시작하는 동안 잠시만 기다려 주세요.
이 화면은 자동으로 새로고침됩니다", + "bePatientStart": "서버를 시작하는 동안 잠시만 기다려 주세요.
이 화면은 자동으로 새로고침됩니다", + "bePatientStop": "서버를 정지하는 동안 잠시만 기달려주세요
이 화면은 자동으로 새로고침됩니다", + "cannotSee": "아무것도 보이지 않나요?", + "cannotSeeOnMobile": "모바일에서 아무것도 볼 수 없나요?", + "cannotSeeOnMobile2": "테이블을 옆으로 스크롤해 보세요.", + "clone": "복사", + "cloneConfirm": "이 서버를 복제하시겠습니까? 이 프로세스는 시간이 걸릴 수 있습니다.", + "cpuCores": "CPU 코어", + "cpuCurFreq": "CPU 현재 클럭", + "cpuMaxFreq": "CPU 최대 클럭", + "cpuUsage": "CPU 사용량", + "crashed": "충돌", + "dashboard": "대시보드", + "delay-explained": "서비스/에이전트가 최근에 시작되어 마인크래프트 서버 인스턴스의 시작을 지연하고있어요", + "host": "호스트", + "installing": "설치중...", + "kill": "프로세스 종료", + "killing": "프로세스를 종료 중...", + "lastBackup": "마지막:", + "max": "최대", + "memUsage": "메모리 사용량", + "motd": "MOTD", + "newServer": "새로운 서버 만들기", + "nextBackup": "다음:", + "no-servers": "현재 서버가 없습니다. 시작하려면 다음을 클릭해주세요", + "offline": "오프라인", + "online": "온라인", + "players": "플레이어", + "restart": "재시작", + "sendingCommand": "명령어 전송", + "server": "서버", + "servers": "서버", + "size": "서버 폴더 크기", + "start": "시작", + "starting": "시작 지연", + "status": "상태", + "stop": "정지", + "storage": "저장공간", + "version": "버전", + "welcome": "Crafty Controller에 오신걸 환영합니다!" + }, + "datatables": { + "i18n": { + "aria": { + "sortAscending": ": 활성화하여 오름차순 정렬", + "sortDescending": ": 활성화하여 내림차순 정렬" + }, + "buttons": { + "collection": "컬렉션 ", + "colvis": "열 표시 설정", + "colvisRestore": "가시성 복원", + "copy": "복사", + "copyKeys": "테이블데이터를 클립보드에 복사하려면 Ctrl 또는 ⌘ + C를 누르세요.

취소하려면 이 메시지를 클릭하거나 Esc 키를 누르세요.", + "copySuccess": { + "1": "1행이 클립보드에 복사되었습니다.", + "_": "%d행이 클립보드에 복사되었습니다." + }, + "copyTitle": "클립보드로 복사", + "csv": "CSV", + "excel": "엑셀", + "pageLength": { + "-1": "모든 행 표시", + "1": "1행 표시", + "_": "%d행 표시" + }, + "pdf": "PDF", + "print": "프린트" + }, + "emptyTable": "테이블에 데이터가 없습니다", + "info": "_START_부터 _END_까지 총 _TOTAL_개의 항목 표시", + "infoEmpty": "0부터 0까지 총 0개의 항목 표시", + "infoFiltered": "(총 _MAX_개의 항목 필터링됨)", + "lengthMenu": "_MENU_ 항목 표시", + "loadingRecords": "로딩 중...", + "paginate": { + "first": "첫번째", + "last": "마지막", + "next": "다음", + "previous": "이전" + }, + "processing": "처리중...", + "search": "검색:", + "select": { + "cells": { + "0": "셀을 클릭하여 선택합니다", + "1": "%d 셀을 선택했습니다!", + "_": "%d 셀을 선택했습니다!" + }, + "columns": { + "0": "열을 클릭하여 선택합니다", + "1": "%d 열을 선택했습니다", + "_": "%d 열을 선택했습니다" + }, + "rows": { + "0": "Row을 클릭하여 선택합니다", + "1": "%d Row를 선택했습니다", + "_": "%d Rows를 선택했습니다" + } + }, + "thousands": ",", + "zeroRecords": "레코드를 찾을 수 없습니다" + }, + "loadingRecords": "로딩 중..." + }, + "error": { + "agree": "동의", + "bedrockError": "베드락 서버를 다운로드를 사용할 수 없습니다. 확인해 주세요", + "bigBucket1": "Big Bucket 상태 확인을 실패했습니다. 확인해주세요", + "bigBucket2": "최신 정보를 확인할 수 있습니다.", + "cancel": "취소", + "contact": "디스코드로 Crafty Controll을 지원받으세요", + "craftyStatus": "Crafty의 상태 페이지", + "cronFormat": "잘못된 Cron 형식이 감지됨", + "embarassing": "이런, 당황스럽네요.", + "error": "오류!", + "eulaAgree": "동의를 할건가요?", + "eulaMsg": "다음에 동의해야 합니다 ", + "eulaTitle": "EULA 동의", + "fileError": "파일 유형은 이미지여야 합니다.", + "fileTooLarge": "업로드 실패. 파일 크기가 너무 큽니다. 시스템 관리자에게 도움을 요청하세요.", + "hereIsTheError": "여기 오류가 있습니다", + "installerJava": "{} 설치에 실패했습니다: Forge 서버 설치에는 Java가 필요합니다. Java가 설치되지 않은 것을 확인했습니다. Java를 설치한 후 서버를 설치하세요.", + "internet": "Crafty가 실행 중인 머신이 인터넷에 연결되어 있지 않은 것을 확인했습니다. 클라이언트의 서버 연결이 제한될 수 있습니다.", + "migration": "Crafty의 주요 서버 저장소가 새로운 위치로 이동되고 있습니다. 이 기간 동안 모든 서버 시작이 중단되었습니다. 마이그레이션이 완료될 때까지 기다려 주십시오.", + "no-file": "파일을 찾을 수 없습니다! 경로를 다시 확인해주세요. Crafty에 적절한 권한이 있나요?", + "noInternet": "Crafty가 인터넷에 접근하는 데 문제가 있습니다. 서버 생성이 비활성화되었습니다. 인터넷 연결을 확인하고 이 페이지를 새로고침하세요.", + "noJava": "서버 {} 시작에 실패했습니다. 오류 코드: Java가 설치되지 않은 것을 확인했습니다. Java를 설치한 후 서버를 시작하세요.", + "not-downloaded": "실행 파일을 찾을 수 없습니다. 다운로드가 완료되었나요? 실행 권한이 설정되어 있나요?", + "portReminder": "{}가 처음 실행된 것을 확인했습니다. 이 프로그램에 원격으로 접근할 수 있도록 라우터/방화벽에서 포트 {}를 포워딩해야 합니다.", + "privMsg": "그리고 ", + "return": "대시보드로 돌아가기", + "selfHost": "이 저장소를 호스팅하고 계신 경우, 주소를 확인하거나 문제 해결 가이드를 참조하세요.", + "start-error": "서버 {} 시작에 실패했습니다. 오류 코드: {}", + "superError": "이 작업을 수행할려면 Super User여야합니다", + "terribleFailure": "끔직한 실패에요!" + }, + "footer": { + "allRightsReserved": "All rights reserved", + "copyright": "Copyright", + "version": "Version" + }, + "login": { + "defaultPath": "입력한 비밀번호는 비밀번호가 아닌 기본 자격 증명 경로입니다. 해당 위치에서 기본 비밀번호를 찾아주세요.", + "disabled": "사용자 계정이 비활성화되었습니다. 자세한 내용은 시스템 관리자에게 문의하세요.", + "forgotPassword": "비밀번호 찾기", + "incorrect": "잘못된 아이디 또는 비밀번호", + "login": "로그인", + "password": "비밀번호", + "username": "아이디", + "viewStatus": "공개 상태 페이지 보기" + }, + "notify": { + "activityLog": "활동 로그", + "backupComplete": "{} 서버에 대한 백업이 성공적으로 완료되었습니다!", + "backupStarted": "{} 서버에 대한 백업이 시작되었습니다!", + "backup_desc": "백업 마이그레이션이 부분적으로 또는 완전히 실패했을 수 있음을 감지했습니다. 백업 탭에서 백업 기록을 확인하십시오.", + "backup_title": "백업 마이그레이션 경고", + "downloadLogs": "지원 로그 다운로드?", + "finishedPreparing": "지원 로그 준비를 완료했습니다. 다운로드를 클릭하여 다운로드하세요", + "logout": "로그아웃", + "preparingLogs": " 로그를 준비하는 동안 잠시만 기다려주세요... 로그가 준비되면 알림을 보내드리겠습니다. 대규모 배포의 경우 시간이 걸릴 수 있습니다.", + "schedule_desc": "업그레이드 중에 예약된 작업의 일부 또는 전부가 성공적으로 전송되지 않은 것을 발견했습니다. 일정 탭에서 일정을 확인하세요.", + "schedule_title": "스케줄 마이그레이션 경고", + "supportLogs": "지원 로그" + }, + "offline": { + "offline": "오프라인", + "pleaseConnect": "Crafty를 사용하려면 인터넷에 연결하세요." + }, + "panelConfig": { + "adminControls": "관리 컨트롤", + "allowedServers": "허용된 서버", + "apply": "적용", + "assignedRoles": "할당된 역할", + "cancel": "취소", + "clearComms": "실행되지 않은 명령 지우기", + "custom": "Crafty 사용자 지정", + "delete": "삭제", + "edit": "수정", + "enableLang": "모든 언어 활성화", + "enabled": "활성화", + "globalExplain": "Crafty는 모든 서버 파일을 저장합니다. ( /servers/[서버의 uuid]로 경로를 추가합니다.)", + "globalServer": "글로벌 서버 디렉토리", + "json": "Config.json", + "match": "비밀번호는 일치해야 합니다", + "newRole": "새 역할 추가", + "newUser": "새 사용자 추가", + "noMounts": "대시보드에 마운트 표시 안 함", + "pageTitle": "패널 설정", + "role": "역할", + "roleUsers": "사용자 역할", + "roles": "역할", + "save": "저장", + "select": "선택", + "superConfirm": "이 사용자가 모든 것(모든 사용자 계정, 서버, 패널 설정 등)에 접근하도록 하려면 진행하세요. 이 사용자는 심지어 당신의 슈퍼유저 권한을 박탈할 수 있습니다.", + "superConfirmTitle": "슈퍼유저를 활성화하시겠습니까? 확실합니까?", + "title": "Crafty 설정", + "user": "사용자", + "users": "사용자" + }, + "rolesConfig": { + "config": "역할 설정", + "configDesc": "여기에서 역할의 구성을 변경할 수 있습니다.", + "configUpdate": "마지막 업데이트: ", + "created": "생성됨: ", + "delRole": "역할 제거", + "doesNotExist": "아직 존재하지 않는 것을 삭제할 수 없습니다.", + "pageTitle": "역할 수정", + "pageTitleNew": "새 역할", + "permAccess": "접근 가능", + "permName": "권한 이름", + "permsServer": "이 역할이 지정된 서버에 대한 권한", + "roleConfigArea": "역할 구성 영역", + "roleDesc": "이 역할에 어떤 이름을 설정하고 싶으신가요?", + "roleName": "역할 이름: ", + "rolePerms": "역할 권한", + "roleServers": "허용된 서버", + "roleTitle": "역할 설정", + "roleUserName": "사용자 이름", + "roleUsers": "사용자 역할: ", + "selectManager": "이 역할의 관리자를 선택하세요.", + "serverAccess": "접근 가능", + "serverName": "서버 이름", + "serversDesc": "이 역할이 접근할 수 있는 서버" + }, + "serverBackups": { + "actions": "동작", + "after": "백업 후 명령어를 실행합니다", + "backupAtMidnight": "자정에 자동 백업을 수행할까요?", + "backupNow": "지금 백업하기", + "backupTask": "백업 작업이 시작되었습니다.", + "backups": "서버 백업", + "before": "백업 전 명령어를 실행합니다", + "cancel": "취소", + "clickExclude": "클릭하여 제외를 선택합니다", + "compress": "백업 파일을 압축하기", + "confirm": "확인", + "confirmDelete": "이 백업을 삭제하시겠습니까? 이 백업은 되돌릴 수 없습니다.", + "confirmRestore": "이 백업에서 복원하시겠습니까? 현재 서버 파일이 모두 백업 상태로 변경되어 복구할 수 없습니다.", + "currentBackups": "현재 백업", + "default": "기본 백업", + "defaultExplain": "Crafty가 업데이트하기 전에 사용할 백업입니다. 이 백업은 변경하거나 삭제할 수 없습니다.", + "delete": "삭제", + "destroyBackup": "백업 \" + file_to_del + \"을(를) 삭제하시겠습니까?", + "download": "다운로드", + "edit": "수정", + "enabled": "활성화", + "excludedBackups": "제외된 경로: ", + "excludedChoose": "백업에서 제외할 경로를 선택하세요.", + "exclusionsTitle": "백업 제외 항목", + "failed": "실패", + "maxBackups": "최대 백업 수", + "maxBackupsDesc": "Crafty는 N개의 백업 이상을 저장하지 않으며, 가장 오래된 백업을 삭제합니다(모든 백업을 유지하려면 0을 입력하세요).", + "myBackup": "새로운 백업", + "name": "이름", + "newBackup": "새로운 백업 만들기", + "no-backup": "백업이 없습니다. 새로운 백업 구성을 만들려면 '새로운 백업'을 클릭하세요.", + "options": "옵션", + "path": "경로", + "restore": "복원", + "restoring": "백업을 복원하는 중입니다. 시간이 좀 걸릴 수 있습니다. 잠시만 기다려 주세요.", + "run": "백업 실행", + "save": "저장", + "shutdown": "백업하는 동안 서버를 종료합니다.", + "size": "크기", + "standby": "대기중", + "status": "상태", + "storage": "저장 위치", + "storageLocation": "저장 위치", + "storageLocationDesc": "백업을 어디에 저장하시겠습니까?" + }, + "serverConfig": { + "bePatientDelete": "Crafty 패널에서 서버를 제거하는 동안 잠시만 기다려 주세요. 이 화면은 잠시 후 닫힙니다.", + "bePatientDeleteFiles": "Crafty 패널에서 서버를 제거하고 모든 파일을 삭제하는 동안 잠시만 기다려 주세요. 이 화면은 잠시 후 닫힙니다.", + "bePatientUpdate": "서버를 업데이트하는 동안 잠시만 기다려 주세요. 다운로드 시간은 인터넷 속도에 따라 달라질 수 있습니다.
이 화면은 잠시 후 새로고침됩니다", + "cancel": "취소", + "countPlayers": "서버의 총 플레이어 수", + "crashTime": "충돌 시간초과", + "crashTimeDesc": "서버가 충돌한 것으로 간주하려면 얼마나 기다려야 하나요?", + "deleteFilesQuestion": "서버파일을 서버에서 삭제할까요?", + "deleteFilesQuestionMessage": "Crafty가 호스트 머신에서 모든 서버 파일을 삭제하도록 하시겠습니까?

여기에는 서버 백업도 포함됩니다.", + "deleteServer": "서버 삭제", + "deleteServerQuestion": "서버를 제거할까요?", + "deleteServerQuestionMessage": "정말로 이 서버를 삭제하시겠습니까? 삭제 후에는 「복구」할 수 없습니다", + "exeUpdateURL": "서버 실행 파일 업데이트 URL", + "exeUpdateURLDesc": "업데이트를 하기위한 다이렉트 다운로드 URL", + "ignoredExits": "충돌 코드 무시", + "ignoredExitsExplain": "종료 코드 Crafty의 충돌 감지는 일반적인 '정지'로 무시해야 합니다(콤마로 구분)", + "javaNoChange": "덮어쓰지 않기", + "javaVersion": "현재 버전 덮어쓰기", + "javaVersionDesc": "Java를 덮어쓸 경우, '실행 명령'에서 현재 Java 경로가 따옴표로 감싸져 있는지 확인하세요(기본 'java' 변수 제외).", + "noDelete": "돌아가지 않기", + "noDeleteFiles": "아니요, 패널에서만 제거해 주세요.", + "removeOldLogsAfter": "오래된 로그 삭제 후", + "removeOldLogsAfterDesc": "로그 파일이 삭제되기 위해 얼마나 많은 시간이 지나야 하나요? (0은 비활성화)", + "save": "저장", + "sendingDelete": "서버 삭제 중", + "sendingRequest": "요청을 전송하는 중...", + "serverAutoStart": "서버 자동시작", + "serverAutostartDelay": "서버 자동시작 지연", + "serverAutostartDelayDesc": "자동 시작 지연(아래에서 활성화된 경우)", + "serverCrashDetection": "서버 충돌 감지", + "serverExecutable": "서버 실행 파일", + "serverExecutableDesc": "서버의 실행 파일", + "serverExecutionCommand": "서버 실행 명령", + "serverExecutionCommandDesc": "숨겨진 터미널에서 실행될 내용", + "serverIP": "서버 IP", + "serverIPDesc": "통계를 위해 Crafty가 연결할 IP(문제가 있는 경우 127.0.0.1 대신 실제 IP를 사용해 보세요)", + "serverLogLocation": "서버 로그 위치", + "serverLogLocationDesc": "로그 파일 경로", + "serverName": "서버 이름", + "serverNameDesc": "이 서버의 이름을 무엇으로 지정하시겠습니까?", + "serverPath": "서버가 작동할 폴더", + "serverPathDesc": "실행 파일을 제외한 절대경로", + "serverPort": "서버 포트", + "serverPortDesc": "Crafty가 통계를 보려면 연결해야 할 포트", + "serverStopCommand": "서버 중지 명령어", + "serverStopCommandDesc": "프로그램을 중지시키기 위한 명령", + "showStatus": "공개 상태 페이지에 표시", + "shutdownTimeout": "종료 대기 시간", + "statsHint1": "서버가 실행할 포트는 여기 입력해야 합니다. 이는 Crafty가 통계를 위해 서버에 연결을 여는 방법입니다.", + "statsHint2": "이 설정은 서버의 포트를 변경하지 않습니다. 서버 구성 파일에서 포트를 변경해야 합니다.", + "stopBeforeDeleting": "서버를 삭제하기 전에 반드시 중지해 주세요.", + "timeoutExplain1": "크래피가 명령 실행 후 서버가 종료될 때까지 기다리는 시간입니다.", + "timeoutExplain2": "이 시간이 지나면 프로세스를 강제로 종료합니다.", + "update": "실행 파일 업데이트", + "yesDelete": "삭제합니다", + "yesDeleteFiles": "모든 파일을 삭제합니다" + }, + "serverConfigHelp": { + "desc": "여기에서 서버 구성을 변경할 수 있습니다.", + "perms": [ + "Crafty가 관리하는 서버의 경로는 변경하지 않는 것이 좋습니다.", + "경로를 변경하면 시스템에 문제가 발생할 수 있으며, 특히 파일 권한이 더 제한적인 리눅스 계열 운영 체제에서 그렇습니다.", + "

", + "서버 위치를 변경해야 한다고 생각하시면, \"crafty\" 사용자에게 서버 경로에 대한 읽기/쓰기 권한을 부여하는 한 변경할 수 있습니다.", + "
", + "
", + "리눅스에서는 다음 명령을 실행하여 권한을 변경하는 것이 가장 좋습니다:
", + "", + " sudo chown crafty:crafty path/to/your/server -R
", + " sudo chmod 2775 /path/to/your/server -R
", + "
" + ], + "title": "서버 구성 영역" + }, + "serverDetails": { + "backup": "백업", + "config": "설정", + "files": "파일", + "filter": "로그 필터", + "filterList": "필터링된 단어", + "logs": "로그", + "metrics": "모니터링", + "playerControls": "플레이어 관리", + "reset": "스크롤 초기화", + "schedule": "스케줄", + "serverDetails": "서버 상세정보", + "terminal": "터미널" + }, + "serverFiles": { + "clickUpload": "파일을 선택하려면 여기를 클릭하세요", + "close": "닫기", + "createDir": "디렉토리 만들기", + "createDirQuestion": "새 디렉토리의 이름은 무엇으로 하시겠습니까?", + "createFile": "파일 만들기", + "createFileQuestion": "새 파일의 이름은 무엇으로 하시겠습니까?", + "default": "기본값", + "delete": "삭제", + "deleteItemQuestion": "\" + name + \"을(를) 삭제하시겠습니까?", + "deleteItemQuestionMessage": "\\\"\" + path + \"\\\"를 삭제합니다!

이 작업은 되돌릴 수 없으며 영원히 사라집니다!", + "download": "다운로드", + "editingFile": "파일 편집 중", + "error": "파일을 가져오는 중 오류 발생", + "fileReadError": "파일 읽기 오류", + "files": "파일", + "keybindings": "키 바인딩", + "loadingRecords": "파일 로딩 중...", + "noDelete": "아니요", + "noscript": "JavaScript가 없으면 파일 관리자가 작동하지 않습니다", + "rename": "이름 변경", + "renameItemQuestion": "새 이름은 무엇으로 하시겠습니까?", + "save": "저장", + "size": "편집기 크기 전환", + "stayHere": "이 페이지를 떠나지 마세요!", + "unsupportedLanguage": "경고: 지원되지 않는 파일 유형입니다", + "unzip": "압축 풀기", + "upload": "업로드", + "uploadTitle": "파일 업로드: ", + "waitUpload": "파일을 업로드하는 동안 잠시 기다려 주세요... 시간이 걸릴 수 있습니다.", + "yesDelete": "네, 결과를 이해했습니다" + }, + "serverMetrics": { + "resetZoom": "확대 초기화", + "zoomHint1": "그래프에서 확대하려면 Shift 키를 누른 채로 스크롤 휠을 사용하세요.", + "zoomHint2": "또는 Shift 키를 누른 채로 확대할 영역을 클릭하고 드래그하세요." + }, + "serverPlayerManagement": { + "bannedPlayers": "차단된 플레이어", + "loadingBannedPlayers": "차단된 플레이어를 불러오는 중", + "players": "플레이어" + }, + "serverScheduleConfig": { + "backup": "서버 백업", + "basic": "기본", + "children": "연결된 하위 작업: ", + "command": "명령어", + "command-explain": "어떤 명령을 실행할까요? '/'를 포함하지 마세요", + "cron": "크론", + "cron-explain": "크론 문자열을 입력하세요 -- 주의: 0은 마지막 옵션에서 월요일을 의미합니다.", + "custom": "커스텀 명령어", + "days": "일", + "enabled": "활성화", + "hours": "시간", + "interval": "주기", + "interval-explain": "이 스케줄을 얼마나 자주 실행하길 원하나요?", + "minutes": "분", + "offset": "오프셋 지연", + "offset-explain": "첫 번째 작업 실행 후 이 작업을 시작하기 위해 얼마나 기다려야 합니까? (초)", + "one-time": "실행 후 삭제", + "parent": "상위 일정을 선택하세요", + "parent-explain": "이 일정을 트리거할 일정은 무엇인가요?", + "reaction": "반응", + "restart": "서버 재시작", + "select": "기본 / 크론 / 체인 반응선택", + "start": "서버 시작", + "stop": "서버 종료", + "time": "시간", + "time-explain": "스케줄을 실행할 시간을 설정해주세요." + }, + "serverSchedules": { + "action": "작업", + "actionId": "하위 작업 선택", + "areYouSure": "스케줄 작업을 삭제할까요?", + "cancel": "취소", + "cannotSee": "모든 항목이 보이지 않나요?", + "cannotSeeOnMobile": "전체 세부정보를 보려면 예약된 작업을 클릭해 보세요.", + "child": "ID가 있는 하위 작업 ", + "close": "닫기", + "command": "명령어", + "confirm": "확인", + "confirmDelete": "이 스케줄 작업을 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.", + "create": "새 스케줄 만들기", + "cron": "크론 문자열", + "delete": "삭제", + "details": "스케줄 상세정보", + "edit": "수정", + "enabled": "활성화", + "every": "매", + "interval": "주기", + "name": "이름", + "newSchedule": "새 스케줄", + "nextRun": "다음 실행", + "no": "아니요", + "no-schedule": "현재 서버에 대한 예약이 없습니다. 시작하려면 다음을 클릭합니다", + "scheduledTasks": "스케줄 작업", + "yes": "예" + }, + "serverStats": { + "cpuUsage": "CPU 사용량", + "description": "설명", + "errorCalculatingUptime": "업타임 계산 오류", + "loadingMotd": "Loading MOTD", + "memUsage": "메모리 사용량", + "offline": "오프라인", + "online": "온라인", + "players": "플레이어", + "serverStarted": "서버 시작됨", + "serverStatus": "서버 상태", + "serverTime": "UTC 시간", + "serverTimeZone": "서버 시간대", + "serverUptime": "서버 업타임", + "starting": "시작 지연", + "unableToConnect": "연결할 수 없음", + "version": "버전" + }, + "serverTerm": { + "commandInput": "명령어 입력", + "delay-explained": "서비스/에이전트가 최근에 시작되어 마인크래프트 서버 인스턴스의 시작을 지연하고 있습니다", + "importing": "가져오는 중...", + "installing": "설치 중...", + "restart": "재시작", + "sendCommand": "명령어 보내기", + "start": "시작", + "starting": "시작 지연", + "stop": "정지", + "stopScroll": "자동 스크롤 중지", + "updating": "업데이트 중..." + } +} From 68e34e7101d6fc71bd73e0ed1f12abcfdf6c83c8 Mon Sep 17 00:00:00 2001 From: syu6 Date: Mon, 2 Dec 2024 01:26:28 +0000 Subject: [PATCH 47/74] Translated (Japanese) Currently translated at 98.8% (626 of 633 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/ja/ --- app/translations/ja_JP.json | 191 ++++++++++++++++++++---------------- 1 file changed, 105 insertions(+), 86 deletions(-) diff --git a/app/translations/ja_JP.json b/app/translations/ja_JP.json index 1457824c..be96babd 100644 --- a/app/translations/ja_JP.json +++ b/app/translations/ja_JP.json @@ -2,8 +2,8 @@ "error": { "cancel": "キャンセル", "agree": "同意", - "bedrockError": "Bedrockダウンロードは利用できませんでした。確認してください。", - "bigBucket1": "Big Bucketヘルスチェックは失敗しました。", + "bedrockError": "Bedrockダウンロードは利用できませんでした。確認してください", + "bigBucket1": "Big Bucketヘルスチェックは失敗しました。確認してください", "bigBucket2": "最新の情報を確認してください。", "contact": "DiscordでCraftyサポートに連絡", "craftyStatus": "Crafty ステータスページ", @@ -15,13 +15,13 @@ "eulaTitle": "EULAに同意", "fileError": "ファイルの種類は画像である必要があります。", "fileTooLarge": "アップロードに失敗しました。ファイルが大きすぎます。アップロードしたい場合は、システム管理者に連絡してください。", - "hereIsTheError": "以下がエラーです。", + "hereIsTheError": "エラーが発生しました", "installerJava": "インストール失敗 {} : ForgeサーバーのインストールにはJavaが必要です。 Javaがインストールされていないことを検知しました。Javaをインストールした後に、サーバーをインストールしてください。", "internet": "Craftyが実行中のサーバーが、インターネットに接続されていないことを検知しました。クライアントのサーバーへの接続が制限されるかもしれません。", - "migration": "Craftyのメインサーバーのストレージが新しいサーバーへ移行中です。そのため全てのサーバーの起動が遅延されています。この移行が終わるまでお待ちください。", + "migration": "Craftyのメインサーバーのストレージが新しいサーバーへ移行中です。そのため全てのサーバーの起動が遅延されています。この移行が終わるまでお待ちください", "no-file": "要求されたファイルを移動することができないようです。パスを再確認して、Craftyに適切な権限があるかを確認してください。", "noInternet": "インターネットへの接続に問題があります。 サーバーの作成は無効になっています。インターネットへの接続を確認し、ページを更新してください。", - "noJava": "サーバー {} は起動に失敗しました。エラーコード: Javaがインストールされていないことを検知しました。Javaがインストールされていないことを検知しました。Javaをインストールした後に、サーバーをインストールしてください。", + "noJava": "サーバー {} は起動に失敗しました。エラーコード: Javaがインストールされていないことを検知しました。Javaをインストールした後に、サーバーをインストールしてください。", "not-downloaded": "実行ファイルが見つかりません。実行ファイルのダウンロードが終了しているか、実行権限があるかを確認してください。", "portReminder": "今回が {} のはじめての起動であることを検知しました。インターネットからリモートアクセスできるように、ルータ・ファイヤーウォールでポート{}を転送してください。", "privMsg": "と ", @@ -29,7 +29,7 @@ "selfHost": "このリポジトリをセルフホストしている場合は、アドレスを確認し、トラブルシューティングを参照してください。", "start-error": "サーバー {} は起動に失敗しました。エラーコード: {}", "superError": "この動作を実行するには管理者である必要があります。", - "terribleFailure": "深刻なエラーが発生しました。" + "terribleFailure": "深刻なエラーが発生しました!" }, "serverDetails": { "terminal": "ターミナル", @@ -49,24 +49,24 @@ "name": "名前", "new": "新しいウェブフック", "newWebhook": "新しいウェブフック", - "no-webhook": "このサーバーには現在ウェブフックがありません。クリックして作成してください。", + "no-webhook": "このサーバーには現在ウェブフックがありません。クリックして作成してください", "run": "ウェブフックをテストする", - "send_command": "サーバーがコマンドを受け取りました。", - "start_server": "サーバーが起動しました。", - "stop_server": "サーバーが停止しました。", + "send_command": "サーバーがコマンドを受け取りました", + "start_server": "サーバーが起動しました", + "stop_server": "サーバーが停止しました", "trigger": "トリガー", "type": "ウェブフックの種類", "url": "ウェブフックのURL", - "areYouSureDel": "このウェブフックを削除しますか。", - "areYouSureRun": "このウェブフックをテストしますか。", - "backup_server": "サーバーのバックアップが完了しました。", + "areYouSureDel": "このウェブフックを削除しますか?", + "areYouSureRun": "このウェブフックをテストしますか?", + "backup_server": "サーバーのバックアップが完了しました", "bot_name": "ボットの名前", "color": "アクセント色を選択", - "crash_detected": "サーバーがクラッシュしました。", + "crash_detected": "サーバーがクラッシュしました", "edit": "編集", "enabled": "有効化", - "jar_update": "サーバーの実行ファイルがアップデートされました。", - "kill": "サーバーが終了しました。", + "jar_update": "サーバーの実行ファイルがアップデートされました", + "kill": "サーバーが終了しました", "webhook_body": "ウェブフックの本文", "webhooks": "すべてのウェブフック" }, @@ -79,7 +79,7 @@ "accessDenied": "アクセス拒否", "contact": "DiscordでCraftyサポートに連絡", "contactAdmin": "このページにアクセスするにはサーバー管理者に連絡してください。アクセスできるはずなのにページにアクセスできない場合は、サポートに連絡してください。", - "noAccess": "このページにアクセスすることができませんでした。" + "noAccess": "このページにアクセスすることができませんでした" }, "apiKeys": { "apiKeys": "APIキー", @@ -90,7 +90,7 @@ "createNew": "新しいAPIトークンを作成", "created": "作成済み", "deleteKeyConfirmation": "このAPIキーを削除してもよろしいですか。この操作は元に戻せません。", - "deleteKeyConfirmationTitle": "APIキー:${keyId} を削除してもよろしいですか。", + "deleteKeyConfirmationTitle": "APIキー:${keyId} を削除してもよろしいですか?", "fullAccess": "フルアクセス", "getToken": "APIトークンを取得", "name": "名前", @@ -108,7 +108,7 @@ "credits": { "developmentTeam": "開発チーム", "hugeDesc": "多大なる", - "pageDescription": "この方々のご支援がなくては、Craftyは存在しません。", + "pageDescription": "この方々のご支援がなくては、Craftyは存在しません", "pageTitle": "クレジット", "patreonDesc": "私たちの Patreon / Ko-fi の支援者たちに!", "patreonOther": "その他", @@ -118,7 +118,7 @@ "subscriberName": "お名前", "subscriptionLevel": "レベル", "supportTeam": "サポート・ドキュメントチーム", - "thankYou": "感謝を!", + "thankYou": "ありがとう", "translationDesc": "私たちのコミュニティを翻訳している方たちです! [ 活動中 = 🟢 休止中・引退済み = ⚪ ]", "translationName": "言語名", "translationTitle": "多言語への翻訳", @@ -129,9 +129,9 @@ "backgroundUpload": "背景アップロード", "customLoginPage": "ログインページをカスタマイズ", "delete": "削除", - "labelLoginImage": "ログインページの背景を選択してください。", + "labelLoginImage": "ログインページの背景を選択してください", "loginBackground": "ログインページの背景画像", - "loginImage": "ログイン画面に表示する背景画像をアップロード", + "loginImage": "ログイン画面に表示する背景画像をアップロードしてください。", "loginOpacity": "ログインフォームの透明度を選択", "pageTitle": "ログインページをカスタマイズ", "preview": "プレビュー", @@ -143,10 +143,10 @@ "allServers": "サーバー一覧", "avg": "平均", "backups": "バックアップ", - "bePatientClone": "サーバーを複製している間、しばらくお待ちください。
この画面はしばらくした後に更新されます。", - "bePatientRestart": "サーバーを再起動している間、しばらくお待ちください。
この画面はしばらくした後に更新されます。", - "bePatientStart": "サーバーを起動している間、しばらくお待ちください。
この画面はしばらくした後に更新されます。", - "bePatientStop": "サーバーを停止している間、しばらくお待ちください。
この画面はしばらくした後に更新されます。", + "bePatientClone": "サーバーを複製している間、しばらくお待ちください。
この画面はしばらくした後に更新されます", + "bePatientRestart": "サーバーを再起動している間、しばらくお待ちください。
この画面はしばらくした後に更新されます", + "bePatientStart": "サーバーを起動している間、しばらくお待ちください。
この画面はしばらくした後に更新されます", + "bePatientStop": "サーバーを停止している間、しばらくお待ちください。
この画面はしばらくした後に更新されます", "cannotSee": "すべて表示されていますか?", "cannotSeeOnMobile": "モバイルですべて表示されていませんか?", "cannotSeeOnMobile2": "左右に表をスクロールしてみてください。", @@ -158,7 +158,7 @@ "cpuUsage": "CPU 使用率", "crashed": "クラッシュ", "dashboard": "ダッシュボード", - "delay-explained": "サービス・エージェントが先ほど起動したため、マインクラフトサーバーインスタンスの起動を遅らせています。", + "delay-explained": "サービス・エージェントが先ほど起動したため、マインクラフトサーバーインスタンスの起動を遅らせています", "host": "ホスト", "installing": "インストール中...", "kill": "プロセスを終了", @@ -169,7 +169,7 @@ "motd": "MOTD (サーバー説明文)", "newServer": "新しいサーバーを作成", "nextBackup": "次回:", - "no-servers": "サーバーがありません。ボタンをクリックして開始してください。", + "no-servers": "サーバーがありません。ボタンをクリックして開始してください", "offline": "オフライン", "online": "オンライン", "players": "プレイヤー数", @@ -213,7 +213,7 @@ "pdf": "PDF", "print": "印刷" }, - "emptyTable": "表に利用可能なデータがありません。", + "emptyTable": "利用可能なデータがありません", "info": "_START_ 件目から _END_ 件目までの _TOTAL_ 件のデータを表示中", "infoEmpty": "0 件目から 0 件目までの 0 件のデータを表示中", "infoFiltered": "(filtered from _MAX_ total entries)", @@ -229,23 +229,25 @@ "search": "検索:", "select": { "cells": { - "0": "セルを選択するにはクリックしてください。", + "0": "セルを選択するにはクリックしてください", "1": "%d 個のセルが選択中", "_": "%d 個のセルが選択中" }, "columns": { - "0": "列を選択するにはクリックしてください。", + "0": "列を選択するにはクリックしてください", "1": "%d 列が選択中", "_": "%d 列が選択中" }, "rows": { - "0": "行を選択するにはクリックしてください。", + "0": "行を選択するにはクリックしてください", "1": "%d 行が選択中", "_": "%d 行が選択中" } }, "thousands": ",", - "zeroRecords": "条件に当てはまるデータがありませんでした。" + "zeroRecords": "条件に当てはまるデータがありませんでした", + "decimal": ".", + "infoPostFix": "|" }, "loadingRecords": "読み込み中..." }, @@ -258,7 +260,7 @@ "defaultPath": "入力されたパスワードは、デフォルト証明書のパスであり、パスワードではありません。そのパスからデフォルトパスワードを見つけて入力してください。", "disabled": "ユーザーアカウントは無効です。詳細な情報を得るにはシステム管理者に連絡してください。", "forgotPassword": "パスワードを忘れた場合", - "incorrect": "ユーザー名・パスワードが正しくありません。", + "incorrect": "ユーザー名・パスワードが正しくありません", "login": "ログイン", "password": "パスワード", "username": "ユーザー名", @@ -269,10 +271,14 @@ "backupComplete": "サーバー {} のバックアップは正常に完了しました。", "backupStarted": "サーバー {} のバックアップが開始しました。", "downloadLogs": "サポートログをダウンロードしますか?", - "finishedPreparing": "サポートログの準備が完了しました。クリックしてダウンロードしてください。", + "finishedPreparing": "サポートログの準備が完了しました。クリックしてダウンロードしてください", "logout": "ログアウト", "preparingLogs": " ログを準備している間しばらくお待ちください... 準備が出来たら通知を送ります。大容量のファイルの展開には時間がかかることがあります。", - "supportLogs": "サポートログ" + "supportLogs": "サポートログ", + "backup_desc": "バックアップの移行が失敗しました。バックアップタブからバックアップの記録を確認してください。", + "backup_title": "バックアップの移行についての警告", + "schedule_desc": "スケジュールタスクがアップグレード中に完全に移行できなかったことを検知しました。スケジュールタブからスケジュールを確認してください。", + "schedule_title": "スケジュールの移行についての警告" }, "offline": { "offline": "オフライン", @@ -293,7 +299,7 @@ "globalExplain": "Craftyがサーバーファイルを保存する場所です。 (Craftyは /servers/[uuid of server] 内に保存します。)", "globalServer": "グローバルサーバーディレクトリ", "json": "Config.json", - "match": "パスワードが一致する必要があります。", + "match": "パスワードが一致する必要があります", "newRole": "新しいロールを作成", "newUser": "新しいユーザーを作成", "noMounts": "ダッシュボードにマウントを表示しない", @@ -304,25 +310,25 @@ "save": "保存", "select": "選択", "superConfirm": "このユーザーにすべて(全ユーザーアカウント、サーバー、パネル設定など)の権限を付与したいときのみ実行してください。このユーザーはあなたのスーパーユーザー権限をはく奪することもできます。", - "superConfirmTitle": "スーパーユーザーを有効化しますが、よろしいですか。", + "superConfirmTitle": "スーパーユーザーを有効化しますが、よろしいですか?", "title": "Craftyの設定", "user": "ユーザー", "users": "すべてのユーザー" }, "rolesConfig": { "config": "ロール設定", - "configDesc": "ここでロールの設定を変えることができます。", + "configDesc": "ここでロールの設定を変えることができます", "configUpdate": "最終更新: ", "created": "作成: ", "delRole": "削除済みのロール", - "doesNotExist": "存在しないものを削除するととはできません。", + "doesNotExist": "存在しないものを削除するととはできません", "pageTitle": "ロールを編集", "pageTitleNew": "新しいロールを作成", "permAccess": "アクセス?", "permName": "権限名", "permsServer": "一部のサーバーに対して、このロールが持つ権限", "roleConfigArea": "ロール編集画面", - "roleDesc": "このロールをどのように呼びますか。", + "roleDesc": "このロールをどのように呼びますか?", "roleName": "ロール名: ", "rolePerms": "ロールの権限", "roleServers": "許可のあるサーバー", @@ -330,15 +336,15 @@ "roleUserName": "ユーザー名", "roleUsers": "ユーザー一覧: ", "selectManager": "このロールのマネージャーを選択", - "serverAccess": "閲覧できるか", + "serverAccess": "閲覧可能か", "serverName": "サーバー名", - "serversDesc": "アクセスを許可するサーバーを選択してください。" + "serversDesc": "アクセスを許可するサーバーを選択してください" }, "serverBackups": { "actions": "操作", "after": "バックアップ後にコマンドを実行", "backupAtMidnight": "真夜中に自動でバックパップを実行するか", - "backupNow": "今すぐバックアップ", + "backupNow": "今すぐバックアップ!", "backupTask": "バックパップ処理が開始しました。", "backups": "サーバーのバックアップ", "before": "バックアップ前にコマンドを実行", @@ -352,12 +358,12 @@ "default": "デフォルトのバックアップ", "defaultExplain": "更新前にCraftyが使用するバックアップです。変更・削除することができません。", "delete": "削除", - "destroyBackup": "\" + file_to_del + \"を削除しますか。", + "destroyBackup": "\" + file_to_del + \"を削除しますか?", "download": "ダウンロード", "edit": "編集", "enabled": "有効化", "excludedBackups": "除外されるパス: ", - "excludedChoose": "バックアップから除外するパスを選択してください。", + "excludedChoose": "バックアップから除外するパスを選択してください", "exclusionsTitle": "バックアップの除外設定", "failed": "失敗", "maxBackups": "最大バックパップ数", @@ -365,7 +371,7 @@ "myBackup": "新しいバックパップ", "name": "名前", "newBackup": "新しいバックパップを作成", - "no-backup": "バックアップはありません。新しくバックアップの設定を作成するには、ボタンをクリックしてください。", + "no-backup": "バックアップはありません。新しくバックアップの設定を作成するには、ボタンをクリックしてください", "options": "設定", "path": "パス", "restore": "復元", @@ -378,20 +384,20 @@ "status": "ステータス", "storage": "バックアップ保存場所", "storageLocation": "保存場所", - "storageLocationDesc": "バックアップを保存する場所を選択してください。" + "storageLocationDesc": "バックアップを保存する場所を選択してください" }, "serverConfig": { "bePatientDelete": "サーバーをCraftyパネルから削除する間、しばらくお待ちください。この画面はしばらくした後に閉じられます。", "bePatientDeleteFiles": "サーバーをCraftyパネルから削除し、すべてのファイルを削除する間、しばらくお待ちください。 この画面はしばらくした後に閉じられます。", - "bePatientUpdate": "サーバーを更新している間、しばらくお待ちください。ダウンロードに要する時間はインターネット速度によって異なります。
この画面はしばらくした後に更新されます。", + "bePatientUpdate": "サーバーを更新している間、しばらくお待ちください。ダウンロードに要する時間はインターネット速度によって異なります。
この画面はしばらくした後に更新されます", "cancel": "キャンセル", "countPlayers": "サーバーをプレイヤー数に含める", "crashTime": "クラッシュタイムアウト", - "crashTimeDesc": "どのくらいの時間が経てばクラッシュしたとみなしますか。", - "deleteFilesQuestion": "ホストからサーバーファイルを削除しますか。", + "crashTimeDesc": "どのくらいの時間が経てばクラッシュしたとみなしますか?", + "deleteFilesQuestion": "ホストからサーバーファイルを削除しますか?", "deleteFilesQuestionMessage": "ホストからサーバーファイルを削除しますか。

サーバーのバックアップも含まれます。", "deleteServer": "サーバーを削除", - "deleteServerQuestion": "サーバーを削除しますか。", + "deleteServerQuestion": "サーバーを削除しますか?", "deleteServerQuestionMessage": "このサーバーを削除しますか。この処理の後にはなにも残りません...", "exeUpdateURL": "サーバー実行ファイルのアップデートURL", "exeUpdateURLDesc": "アップデートをURLから直接ダウンロードします。", @@ -420,7 +426,7 @@ "serverLogLocation": "サーバーログの保存場所", "serverLogLocationDesc": "ログファイルを保存する場所", "serverName": "サーバー名", - "serverNameDesc": "このサーバーをどのように呼びますか。", + "serverNameDesc": "このサーバーをどのように呼びますか", "serverPath": "サーバーのディレクトリ", "serverPathDesc": "絶対パスで指定してください。(実行ファイルを含まないでください。)", "serverPort": "サーバーのポート", @@ -431,17 +437,18 @@ "shutdownTimeout": "シャットダウンするまで秒数", "statsHint1": "サーバーが稼働しているポートをここに入力してください。統計情報を取得するためにCraftyが接続します。", "statsHint2": "これはサーバーのポートを変更するものではありません。ポートを変更するにはサーバーの設定ファイルを変更してください。", - "stopBeforeDeleting": "削除する前にサーバーを停止してください。", + "stopBeforeDeleting": "削除する前にサーバーを停止してください", "timeoutExplain1": "サーバーを終了するコマンドを実行した後に、Craftyがプロセスを強制終了するまでに待機する時間", "update": "実行ファイルをアップデート", - "yesDelete": "はい、削除してください。", - "yesDeleteFiles": "はい、ファイルを削除してください。" + "yesDelete": "はい、削除してください", + "yesDeleteFiles": "はい、ファイルを削除してください", + "timeoutExplain2": "実行する前のコマンド" }, "serverConfigHelp": { - "desc": "ここではサーバーの設定を帰ることができます。", + "desc": "ここではサーバーの設定を帰ることができます", "perms": [ "Craftyによって管理されているパスを変更しないことが推奨されています。", - "パスを変更することは、特にファイルの権限がより厳密に管理されているLinuxにおいては、システムを損傷させる恐れがあります。CAN", + "パスを変更することは、特にファイルの権限がより厳密に管理されているLinuxにおいては、システムを損傷させる恐れがあります。", "

", "サーバーの位置を変更する必要がある場合、\"crafty\" ユーザーにサーバーのパスの読み取り・書き込み権限を付与してください。", "
", @@ -463,8 +470,8 @@ "createFileQuestion": "新しいファイルの名前を入力してください。", "default": "デフォルト", "delete": "削除", - "deleteItemQuestion": "\" + name + \"を削除しますか。", - "deleteItemQuestionMessage": "\\\"\" + path + \"\\\"を削除しようとしています。!

この操作は復元できず、完全に削除されます。", + "deleteItemQuestion": "\" + name + \"を削除しますか?", + "deleteItemQuestionMessage": "\\\"\" + path + \"\\\"を削除しようとしています。!

この操作は復元できず、完全に削除されます!", "download": "ダウンロード", "editingFile": "ファイルを編集", "error": "ファイル取得エラー", @@ -473,18 +480,18 @@ "keybindings": "キーバインド設定", "loadingRecords": "ファイル読み込み中...", "noDelete": "いいえ", - "noscript": "ファイルマネージャーはJavaScriptなしでは正常に動作しません。", + "noscript": "ファイルマネージャーはJavaScriptなしでは正常に動作しません", "rename": "名前を変更", - "renameItemQuestion": "変更後の名前を入力してください。", + "renameItemQuestion": "変更後の名前を入力してください?", "save": "保存", "size": "エディターの大きさを変更", - "stayHere": "このページから移動しないでください。", - "unsupportedLanguage": "警告: サポートされていないファイルの種類です。", + "stayHere": "このページから移動しないでください!", + "unsupportedLanguage": "警告: サポートされていないファイルの種類です", "unzip": "解凍", "upload": "アップロード", "uploadTitle": "アップロード先: ", "waitUpload": "ファイルをアップロードしています。しばらくお待ちください。この処理には時間がかかることがあります。", - "yesDelete": "はい、この状況を理解しています。" + "yesDelete": "はい、この状況を理解しています" }, "serverMetrics": { "resetZoom": "ズームをリセット", @@ -498,7 +505,7 @@ }, "serverScheduleConfig": { "backup": "サーバーをバックアップ", - "basic": "Basic", + "basic": "ベーシック", "children": "関連付けられた子タスク: ", "command": "コマンド", "command-explain": "実行するコマンドを入力してください。'/'を含まないでください。", @@ -509,7 +516,7 @@ "enabled": "有効化", "hours": "時間ごと", "interval": "実行間隔", - "interval-explain": "どの頻度でこのスケジュールを実行しますか。", + "interval-explain": "どの頻度でこのスケジュールを実行しますか?", "minutes": "分ごと", "offset": "遅延オフセット", "offset-explain": "最初のタスクを実行してから、どのくらいの時間待機してからこのコマンドを実行しますか。(秒数)", @@ -522,12 +529,12 @@ "start": "サーバーを起動", "stop": "サーバーを停止", "time": "実行時刻", - "time-explain": "何時何分にスケジュールを実行しますか。" + "time-explain": "何時何分にスケジュールを実行しますか?" }, "serverSchedules": { "action": "操作", "actionId": "子スケジュールを選択", - "areYouSure": "スケジュールされたタスクを削除しますか。", + "areYouSure": "スケジュールされたタスクを削除しますか?", "cancel": "キャンセル", "cannotSee": "すべて表示されていますか?", "cannotSeeOnMobile": "詳細を表示するためにはスケジュールされたタスクをクリックしてください。", @@ -548,7 +555,7 @@ "newSchedule": "新しいスケジュール", "nextRun": "次回実行時", "no": "いいえ", - "no-schedule": "このサーバーには現在スケジュールがありません。クリックして作成してください。", + "no-schedule": "このサーバーには現在スケジュールがありません。クリックして作成してください", "scheduledTasks": "スケジュールされたタスク", "yes": "はい" }, @@ -572,7 +579,7 @@ }, "serverTerm": { "commandInput": "コマンドを送信", - "delay-explained": "サービス・エージェントが先ほど起動したため、マインクラフトサーバーインスタンスの起動を遅らせています。", + "delay-explained": "サービス・エージェントが起動し、マインクラフトサーバーインスタンスの起動を遅らせています", "importing": "インポート中...", "installing": "インストール中...", "restart": "再起動", @@ -586,15 +593,15 @@ "serverWizard": { "absoluteServerPath": "サーバーファイルの絶対パス", "absoluteZipPath": "サーバーファイルの絶対パス", - "addRole": "既存のロールにサーバーを追加する。", - "autoCreate": "何も選択されない場合、新しいロールを作成します。", - "bePatient": "必要なファイルを' + (importing ? 'インポート' : 'ダウンロード') + 'している間、しばらくお待ちください。", + "addRole": "既存のロールにサーバーを追加する", + "autoCreate": "何も選択しない場合、Craftyは新しいロールを作成します!", + "bePatient": "必要なファイルを' + (importing ? 'インポート' : 'ダウンロード') + 'している間、しばらくお待ちください", "buildServer": "サーバーを作成", "clickRoot": "ルートディレクトリを選択", "close": "閉じる", - "defaultPort": "デフォルトは25565番ポートです。", + "defaultPort": "デフォルトは25565番ポートです", "downloading": "サーバーをダウンロード中...", - "explainRoot": "下のボタンをクリックして、アーカイブ内のサーバーのルートディレクトリを選択してください。", + "explainRoot": "下のボタンをクリックして、アーカイブ内のサーバーのルートディレクトリを選択してください", "importServer": "既存のサーバーをインポート", "importServerButton": "サーバーをインポート", "importZip": "zipファイルからサーバーをインポート", @@ -604,10 +611,10 @@ "minMem": "最小メモリ使用量", "myNewServer": "新しいサーバー", "newServer": "新規でサーバーを作成", - "noRole": "検索パラメータにあてはまるロールはありません。", - "noneRoles": "ロールが選択されていません。", + "noRole": "検索パラメータにあてはまるロールはありません", + "noneRoles": "ロールが選択されていません", "quickSettings": "クイック設定", - "quickSettingsDescription": "これらの値は後から変更できます。", + "quickSettingsDescription": "これらの値は後から変更できます", "resetForm": "リセット", "save": "保存", "selectRole": "ロールを選択", @@ -641,8 +648,8 @@ }, "startup": { "almost": "もうすぐ完了します。", - "cache": "Big Bucketのキャッシュファイルを更新中です。", - "internals": "Craftyの内部コンポーネントを設定・起動中です。", + "cache": "Big Bucketのキャッシュファイルを更新中です", + "internals": "Craftyの内部コンポーネントを設定・起動中です", "internet": "インターネット接続を確認中", "server": "初期化中 ", "serverInit": "サーバーを初期化中", @@ -654,12 +661,12 @@ "auth": "認証されているか ", "config": "設定", "configArea": "ユーザー設定", - "configAreaDesc": "ここではユーザー設定をすべて変えることができます。", + "configAreaDesc": "ここではユーザー設定をすべて変えることができます", "confirmDelete": "本当にユーザーを削除しますか。この操作は元に戻せません。", "craftyPermDesc": "ユーザーのCraftyにおける権限 ", "craftyPerms": "Craftyにおける権限 ", "created": "作成日時: ", - "delSuper": "スーパーユーザーを削除することはできません。", + "delSuper": "スーパーユーザーを削除することはできません", "deleteUser": "ユーザーを削除: ", "deleteUserB": "ユーザーを削除", "enabled": "有効化", @@ -671,7 +678,7 @@ "leaveBlank": "パスワードを変更せずにユーザーを編集するためには、空欄にしてください。", "manager": "マネージャー", "member": "メンバーか", - "notExist": "存在しないものを削除することはできません。", + "notExist": "存在しないものを削除することはできません!", "pageTitle": "ユーザーを変種", "pageTitleNew": "ユーザーを作成", "password": "新しいパスワード", @@ -682,7 +689,7 @@ "super": "スーパーユーザー", "userLang": "ユーザーの使用する言語", "userName": "ユーザー名", - "userNameDesc": "このユーザーをどのように呼びますか。", + "userNameDesc": "このユーザーをどのように呼びますか?", "userRoles": "ユーザーのロール", "userRolesDesc": "ユーザーの属しているロール", "userSettings": "ユーザー設定", @@ -690,6 +697,18 @@ "uses": "許可されている使用回数 (-1で無制限)" }, "validators": { - "passLength": "パスワードが短すぎます。最小文字数は8文字です。" + "passLength": "パスワードが短すぎます。最小文字数は8文字です。", + "backupName": "バックアップ名は3文字以上の文字列である必要があります。", + "enumErr": "データの検証に失敗しました。次を含む必要があります: ", + "filesPageLen": "1文字以上である必要があります", + "insufficientPerms": "権限エラー: このリソースにアクセスする権限がありません", + "roleManager": "ロールのマネージャーは数値(マネージャーID)か空欄である必要があります", + "roleName": "ロール名は1文字以上である必要があります。次の文字列を含んではいけません: [ ] , ", + "roleServerId": "サーバ-IDは1文字以上の文字列である必要があります", + "roleServerPerms": "サーバー権限は8-bitの文字列である必要があります", + "serverCreateName": "サーバ名は2文字以上の文字列で次の文字列を含んではいけません: \\ / # ", + "serverExeCommand": "サーバー実行コマンドは1文字以上の文字列である必要があります。", + "serverLogPath": "サーバログは1文字以上の文字列である必要があります", + "taskIntervalType": "タスクの実行間隔は次のうちのどれかである必要があります。: " } } From c897b1ded6ccffa6bab29964d7864189a4fdb522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B9=B4=EB=82=98=EB=A6=AC?= Date: Mon, 2 Dec 2024 01:14:03 +0000 Subject: [PATCH 48/74] Translated (Korean) Currently translated at 100.0% (633 of 633 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/ko/ --- app/translations/ko_KR.json | 75 ++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/app/translations/ko_KR.json b/app/translations/ko_KR.json index b50c8598..9184c43c 100644 --- a/app/translations/ko_KR.json +++ b/app/translations/ko_KR.json @@ -106,7 +106,26 @@ "uses": "허용되는 사용 횟수 (-1은 제한 없음)" }, "validators": { - "passLength": "비밀번호가 너무 짧아요! (최소 길이: 8)" + "passLength": "비밀번호가 너무 짧아요! (최소 길이: 8)", + "taskIntervalType": "작업 반복 유형은 다음 중 하나여야 합니다: ", + "typeBool": "'true' 또는 'false' 여야 합니다 (boolean 타입)", + "backupName": "백업 이름은 문자여야 하며 최소 3자 이상이어야 합니다.", + "enumErr": "검증에 실패했습니다. 허용되는 데이터는 다음과 같습니다: ", + "filesPageLen": "속성 값은 1자 이상이여야 합니다.", + "insufficientPerms": "권한 오류: 이 리소스에 대한 권한이 없습니다", + "roleManager": "역할관리자는 Type integer(manager ID) 또는 None이어야 합니다", + "roleName": "역할 이름은 1자보다 큰 문자열이어야 합니다. 다음 기호를 포함할 수 없습니다: [ ] , ", + "roleServerPerms": "서버 권한은 8 비트 문자열이어야 합니다.", + "roleServerId": "서버 ID 속성은 최소 길이가 1인 문자열이어야 합니다.", + "serverCreateName": "서버 이름에는 문자열이어야 하고, 최소 2자 이상이어야 하고, 그리고 다음이 포함 되지 않아야합니다: \\/ 또는 #. ", + "serverExeCommand": "서버 명령어를 실행하려면, 문자열이 최소 1자 이상 이어야 합니다.", + "serverLogPath": "서버 로그 경로는 문자열 이어야 하며, 최소 1자 이상이어야 합니다.", + "typeEmail": "이메일 유형이어야 합니다.", + "typeIntMinVal0": "최소값이 0인 정수여야 합니다.", + "typeInteger": "숫자여야 합니다.", + "typeList": "목럭/배열 타입이어여합니다. ", + "typeString": "문자열 이어야합니다.", + "userName": " 문자열이어야 하며, 모두 소문자로 입력해야 하고, 최소 4자에서 최대 20자까지 입력할 수 있습니다." }, "webhooks": { "trigger": "트리거", @@ -134,28 +153,28 @@ "stop_server": "서버가 정지되었습니다" }, "404": { - "contact": "디스코드로 Crafty Controll을 지원받으세요", + "contact": "디스코드를 통해 Crafty Control 지원팀에 문의하세요", "notFound": "페이지를 찾을 수 없습니다", - "unableToFind": "찾고 계시는 페이지를 찾을 수 없습니다. 다시 시도하거나 뒤로가서 새로고침을 해주세요!" + "unableToFind": "찾고 계시는 페이지를 찾을 수 없습니다. 다시 시도하거나 뒤로가서 새로고침을 해주세요." }, "accessDenied": { - "accessDenied": "접근 불가", - "contact": "디스코드로 Crafty Controll을 지원받으세요", + "accessDenied": "접근 불가능", + "contact": "디스코드를 통해 Crafty Controll 지원팀애 문의하세요", "contactAdmin": "해당 리소스에 접근하기 위해서는 서버 관리자에게 문의하시거나, 접근 권한이 있다고 생각되시면 지원팀에 문의해 주세요.", "noAccess": "당신은 해당 리소스에 대한 권한이 없습니다" }, "apiKeys": { "apiKeys": "API 키", - "auth": "인증됨? ", + "auth": "인증이 필요한가요? ", "buttons": "버튼", "config": "설정", "crafty": "Crafty: ", - "createNew": "새 API 토큰 생성", - "created": "생성됨", - "deleteKeyConfirmation": "이 API 키를 삭제할건가요? 이 작업은 취소할 수 없어요", - "deleteKeyConfirmationTitle": "API 키 \"${keyId}\"를 제거하겠습니까?", + "createNew": "새 Crafty API 토큰 생성", + "created": "생성 됨", + "deleteKeyConfirmation": "이 API 키를 삭제할건가요? 이 작업은 취소할 수 없어요.", + "deleteKeyConfirmationTitle": "API 키 '${keyId}'를 제거하겠습니까?", "fullAccess": "전체 액세스", - "getToken": "토큰 얻기", + "getToken": "토큰 가져오기", "name": "이름", "nameDesc": "이 API 토큰을 무엇이라고 부를건가요? ", "no": "아니요", @@ -166,23 +185,23 @@ "yes": "예" }, "base": { - "doesNotWorkWithoutJavascript": "경고: JavaScript가 활성화되지 않으면 제대로 작동하지 않습니다!" + "doesNotWorkWithoutJavascript": "경고: Crafty는 JavaScript가 활성화되지 않으면 제대로 작동하지 않습니다!" }, "credits": { - "developmentTeam": "Development Team", + "developmentTeam": "개발자 팀", "hugeDesc": "진심으로", - "pageDescription": "이 사람들이 없었다면 Crafty가 없을거에요", + "pageDescription": "이 사람들이 없었다면 Crafty가 없었을 겁니다", "pageTitle": "크래딧", "patreonDesc": "Patreon/Ko-fi 후원자 여러분!", - "patreonOther": "Other", + "patreonOther": "다른", "patreonSupporter": "Patreon / Ko-fi 후원자", "patreonUpdate": "마지막 업데이트:", - "retiredStaff": "은퇴한 직원", + "retiredStaff": "퇴직한 직원", "subscriberName": "이름", - "subscriptionLevel": "후원 레벨", + "subscriptionLevel": "레벨", "supportTeam": "지원 및 문서 팀", "thankYou": "감사합니다", - "translationDesc": "번역해 주시는 우리 커뮤니티 여러분께! [ 활성 = 🟢 비활성/은퇴 = ⚪ ]", + "translationDesc": "번역해 주시는 우리 커뮤니티 여러분께! [ 활성 = 🟢 비활성/퇴직 = ⚪ ]", "translationName": "이름", "translationTitle": "언어 번역", "translator": "번역가들" @@ -206,7 +225,7 @@ "allServers": "모든 서버", "avg": "평균", "backups": "백업", - "bePatientClone": "서버를 복사하는 동안 잠시 기달려주세요
이 화면은 자동으로 새로고침됩니다", + "bePatientClone": "서버를 복사하는 동안 잠시 기달려주세요.
이 화면은 자동으로 새로고침됩니다", "bePatientRestart": "서버를 재시작하는 동안 잠시만 기다려 주세요.
이 화면은 자동으로 새로고침됩니다", "bePatientStart": "서버를 시작하는 동안 잠시만 기다려 주세요.
이 화면은 자동으로 새로고침됩니다", "bePatientStop": "서버를 정지하는 동안 잠시만 기달려주세요
이 화면은 자동으로 새로고침됩니다", @@ -308,7 +327,9 @@ } }, "thousands": ",", - "zeroRecords": "레코드를 찾을 수 없습니다" + "zeroRecords": "레코드를 찾을 수 없습니다", + "decimal": ".", + "infoPostFix": "|" }, "loadingRecords": "로딩 중..." }, @@ -331,7 +352,7 @@ "hereIsTheError": "여기 오류가 있습니다", "installerJava": "{} 설치에 실패했습니다: Forge 서버 설치에는 Java가 필요합니다. Java가 설치되지 않은 것을 확인했습니다. Java를 설치한 후 서버를 설치하세요.", "internet": "Crafty가 실행 중인 머신이 인터넷에 연결되어 있지 않은 것을 확인했습니다. 클라이언트의 서버 연결이 제한될 수 있습니다.", - "migration": "Crafty의 주요 서버 저장소가 새로운 위치로 이동되고 있습니다. 이 기간 동안 모든 서버 시작이 중단되었습니다. 마이그레이션이 완료될 때까지 기다려 주십시오.", + "migration": "Crafty의 주요 서버 저장소가 새로운 위치로 이동되고 있습니다. 이 기간 동안 모든 서버 시작이 중단되었습니다. 마이그레이션이 완료될 때까지 기다려 주세요", "no-file": "파일을 찾을 수 없습니다! 경로를 다시 확인해주세요. Crafty에 적절한 권한이 있나요?", "noInternet": "Crafty가 인터넷에 접근하는 데 문제가 있습니다. 서버 생성이 비활성화되었습니다. 인터넷 연결을 확인하고 이 페이지를 새로고침하세요.", "noJava": "서버 {} 시작에 실패했습니다. 오류 코드: Java가 설치되지 않은 것을 확인했습니다. Java를 설치한 후 서버를 시작하세요.", @@ -341,7 +362,7 @@ "return": "대시보드로 돌아가기", "selfHost": "이 저장소를 호스팅하고 계신 경우, 주소를 확인하거나 문제 해결 가이드를 참조하세요.", "start-error": "서버 {} 시작에 실패했습니다. 오류 코드: {}", - "superError": "이 작업을 수행할려면 Super User여야합니다", + "superError": "이 작업을 수행할려면 'Super User' 이어야 합니다", "terribleFailure": "끔직한 실패에요!" }, "footer": { @@ -410,14 +431,14 @@ }, "rolesConfig": { "config": "역할 설정", - "configDesc": "여기에서 역할의 구성을 변경할 수 있습니다.", + "configDesc": "여기에서 역할의 구성을 변경할 수 있습니다", "configUpdate": "마지막 업데이트: ", "created": "생성됨: ", "delRole": "역할 제거", "doesNotExist": "아직 존재하지 않는 것을 삭제할 수 없습니다.", "pageTitle": "역할 수정", "pageTitleNew": "새 역할", - "permAccess": "접근 가능", + "permAccess": "액세스 가능?", "permName": "권한 이름", "permsServer": "이 역할이 지정된 서버에 대한 권한", "roleConfigArea": "역할 구성 영역", @@ -429,7 +450,7 @@ "roleUserName": "사용자 이름", "roleUsers": "사용자 역할: ", "selectManager": "이 역할의 관리자를 선택하세요.", - "serverAccess": "접근 가능", + "serverAccess": "액세스?", "serverName": "서버 이름", "serversDesc": "이 역할이 접근할 수 있는 서버" }, @@ -636,7 +657,7 @@ "start": "서버 시작", "stop": "서버 종료", "time": "시간", - "time-explain": "스케줄을 실행할 시간을 설정해주세요." + "time-explain": "스케줄을 실행할 시간을 언제로 하시겠습니까?" }, "serverSchedules": { "action": "작업", @@ -670,7 +691,7 @@ "cpuUsage": "CPU 사용량", "description": "설명", "errorCalculatingUptime": "업타임 계산 오류", - "loadingMotd": "Loading MOTD", + "loadingMotd": "MOTD 로드 중", "memUsage": "메모리 사용량", "offline": "오프라인", "online": "온라인", From 2d451dbcf6f8531102a1111151d7264e87464935 Mon Sep 17 00:00:00 2001 From: syu6 Date: Mon, 2 Dec 2024 01:46:10 +0000 Subject: [PATCH 49/74] Translated (Japanese) Currently translated at 100.0% (633 of 633 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/ja/ --- app/translations/ja_JP.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/translations/ja_JP.json b/app/translations/ja_JP.json index be96babd..ce178931 100644 --- a/app/translations/ja_JP.json +++ b/app/translations/ja_JP.json @@ -709,6 +709,13 @@ "serverCreateName": "サーバ名は2文字以上の文字列で次の文字列を含んではいけません: \\ / # ", "serverExeCommand": "サーバー実行コマンドは1文字以上の文字列である必要があります。", "serverLogPath": "サーバログは1文字以上の文字列である必要があります", - "taskIntervalType": "タスクの実行間隔は次のうちのどれかである必要があります。: " + "taskIntervalType": "タスクの実行間隔は次のうちのどれかである必要があります。: ", + "typeBool": "真か偽である必要があります", + "typeEmail": "メールアドレスである必要があります。", + "typeIntMinVal0": "1以上の数値である必要があります。", + "typeInteger": "数値である必要があります。", + "typeList": "リストか配列である必要があります ", + "typeString": "文字列である必要があります。", + "userName": " すべて小文字の文字列で、4文字以上20文字以下の文字列である必要があります" } } From 5d56a712644c7ffdf5698e886d73a63810d02f5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B9=B4=EB=82=98=EB=A6=AC?= Date: Mon, 2 Dec 2024 03:55:47 +0000 Subject: [PATCH 50/74] Translated (Korean) Currently translated at 100.0% (633 of 633 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/ko/ --- app/translations/ko_KR.json | 62 ++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/app/translations/ko_KR.json b/app/translations/ko_KR.json index 9184c43c..a541f3c0 100644 --- a/app/translations/ko_KR.json +++ b/app/translations/ko_KR.json @@ -9,7 +9,7 @@ "absoluteServerPath": "서버의 절대 경로", "absoluteZipPath": "서버의 절대 경로", "addRole": "기존 역할에 서버 추가", - "autoCreate": "선택된 것이 없으면 Crafty가 하나를 만듭니다", + "autoCreate": "선택된 항목이 없으면 Crafty가 하나를 자동으로 만듭니다!", "bePatient": "서버를 ' + (importing ? '가져오고 있습니다' : '다운로드하고 있습니다') + ' 조금만 기다려 주세요", "buildServer": "서버 빌드!", "clickRoot": "여기를 클릭하여 루트 디렉터리를 선택하세요", @@ -79,7 +79,7 @@ "deleteUser": "사용자 삭제: ", "deleteUserB": "사용자 삭제", "enabled": "활성화됨", - "gravDesc": "이 이메일은 Gravatar™와 함께 사용하기 위해서만 필요합니다. Crafty는 어떤 경우에도 이 이메일을 귀하의 Gravatar™를 조회하는 것 이외의 다른 용도로 사용하지 않습니다.", + "gravDesc": "이 이메일은 Gravatar™와 함께 사용하기 위해서만 필요합니다. Crafty는 어떤 경우에도 이 이메일을 귀하의 Gravatar™를 조회하는 것 이외의 다른 용도로 사용하지 않습니다", "gravEmail": "Gravatar™ 이메일", "lastIP": "마지막 IP: ", "lastLogin": "마지막 로그인: ", @@ -111,21 +111,21 @@ "typeBool": "'true' 또는 'false' 여야 합니다 (boolean 타입)", "backupName": "백업 이름은 문자여야 하며 최소 3자 이상이어야 합니다.", "enumErr": "검증에 실패했습니다. 허용되는 데이터는 다음과 같습니다: ", - "filesPageLen": "속성 값은 1자 이상이여야 합니다.", + "filesPageLen": "속성 값은 1자 이상이여야 합니다", "insufficientPerms": "권한 오류: 이 리소스에 대한 권한이 없습니다", "roleManager": "역할관리자는 Type integer(manager ID) 또는 None이어야 합니다", "roleName": "역할 이름은 1자보다 큰 문자열이어야 합니다. 다음 기호를 포함할 수 없습니다: [ ] , ", - "roleServerPerms": "서버 권한은 8 비트 문자열이어야 합니다.", - "roleServerId": "서버 ID 속성은 최소 길이가 1인 문자열이어야 합니다.", + "roleServerPerms": "서버 권한은 8 비트 문자열이어야 합니다", + "roleServerId": "서버 ID 속성은 최소 길이가 1인 문자열이어야 합니다", "serverCreateName": "서버 이름에는 문자열이어야 하고, 최소 2자 이상이어야 하고, 그리고 다음이 포함 되지 않아야합니다: \\/ 또는 #. ", "serverExeCommand": "서버 명령어를 실행하려면, 문자열이 최소 1자 이상 이어야 합니다.", - "serverLogPath": "서버 로그 경로는 문자열 이어야 하며, 최소 1자 이상이어야 합니다.", + "serverLogPath": "서버 로그 경로는 문자열 이어야 하며, 최소 1자 이상이어야 합니다", "typeEmail": "이메일 유형이어야 합니다.", "typeIntMinVal0": "최소값이 0인 정수여야 합니다.", "typeInteger": "숫자여야 합니다.", "typeList": "목럭/배열 타입이어여합니다. ", "typeString": "문자열 이어야합니다.", - "userName": " 문자열이어야 하며, 모두 소문자로 입력해야 하고, 최소 4자에서 최대 20자까지 입력할 수 있습니다." + "userName": " 문자열이어야 하며, 모두 소문자로 입력해야 하고, 최소 4자에서 최대 20자까지 입력할 수 있습니다" }, "webhooks": { "trigger": "트리거", @@ -146,7 +146,7 @@ "name": "이름", "new": "새 웹후크", "newWebhook": "새 웹후크", - "no-webhook": "현재 이 서버에는 웹후크가 없습니다. 시작하려면 클릭하세요.", + "no-webhook": "현재 이 서버에는 웹후크가 없습니다. 시작하려면 클릭하세요", "run": "웹후크 테스트 실행", "send_command": "서버 명령이 수신되었습니다", "start_server": "서버가 시작되었습니다", @@ -281,8 +281,8 @@ "copy": "복사", "copyKeys": "테이블데이터를 클립보드에 복사하려면 Ctrl 또는 ⌘ + C를 누르세요.

취소하려면 이 메시지를 클릭하거나 Esc 키를 누르세요.", "copySuccess": { - "1": "1행이 클립보드에 복사되었습니다.", - "_": "%d행이 클립보드에 복사되었습니다." + "1": "1행이 클립보드에 복사되었습니다", + "_": "%d행이 클립보드에 복사되었습니다" }, "copyTitle": "클립보드로 복사", "csv": "CSV", @@ -312,8 +312,8 @@ "select": { "cells": { "0": "셀을 클릭하여 선택합니다", - "1": "%d 셀을 선택했습니다!", - "_": "%d 셀을 선택했습니다!" + "1": "%d 셀을 선택했습니다", + "_": "%d 셀을 선택했습니다" }, "columns": { "0": "열을 클릭하여 선택합니다", @@ -362,7 +362,7 @@ "return": "대시보드로 돌아가기", "selfHost": "이 저장소를 호스팅하고 계신 경우, 주소를 확인하거나 문제 해결 가이드를 참조하세요.", "start-error": "서버 {} 시작에 실패했습니다. 오류 코드: {}", - "superError": "이 작업을 수행할려면 'Super User' 이어야 합니다", + "superError": "이 작업을 수행할려면 'Super User' 이어야 합니다.", "terribleFailure": "끔직한 실패에요!" }, "footer": { @@ -382,8 +382,8 @@ }, "notify": { "activityLog": "활동 로그", - "backupComplete": "{} 서버에 대한 백업이 성공적으로 완료되었습니다!", - "backupStarted": "{} 서버에 대한 백업이 시작되었습니다!", + "backupComplete": "서버 {} 에 대한 백업이 성공적으로 완료되었습니다!", + "backupStarted": "서버 {} 에 대한 백업이 시작되었습니다!", "backup_desc": "백업 마이그레이션이 부분적으로 또는 완전히 실패했을 수 있음을 감지했습니다. 백업 탭에서 백업 기록을 확인하십시오.", "backup_title": "백업 마이그레이션 경고", "downloadLogs": "지원 로그 다운로드?", @@ -449,7 +449,7 @@ "roleTitle": "역할 설정", "roleUserName": "사용자 이름", "roleUsers": "사용자 역할: ", - "selectManager": "이 역할의 관리자를 선택하세요.", + "selectManager": "이 역할의 관리자를 선택하세요", "serverAccess": "액세스?", "serverName": "서버 이름", "serversDesc": "이 역할이 접근할 수 있는 서버" @@ -458,7 +458,7 @@ "actions": "동작", "after": "백업 후 명령어를 실행합니다", "backupAtMidnight": "자정에 자동 백업을 수행할까요?", - "backupNow": "지금 백업하기", + "backupNow": "지금 백업하기!", "backupTask": "백업 작업이 시작되었습니다.", "backups": "서버 백업", "before": "백업 전 명령어를 실행합니다", @@ -477,22 +477,22 @@ "edit": "수정", "enabled": "활성화", "excludedBackups": "제외된 경로: ", - "excludedChoose": "백업에서 제외할 경로를 선택하세요.", + "excludedChoose": "백업에서 제외할 경로를 선택하세요", "exclusionsTitle": "백업 제외 항목", "failed": "실패", "maxBackups": "최대 백업 수", - "maxBackupsDesc": "Crafty는 N개의 백업 이상을 저장하지 않으며, 가장 오래된 백업을 삭제합니다(모든 백업을 유지하려면 0을 입력하세요).", + "maxBackupsDesc": "Crafty는 N개의 백업 이상을 저장하지 않으며, 가장 오래된 백업을 삭제합니다 (모든 백업을 유지하려면 0을 입력하세요)", "myBackup": "새로운 백업", "name": "이름", "newBackup": "새로운 백업 만들기", - "no-backup": "백업이 없습니다. 새로운 백업 구성을 만들려면 '새로운 백업'을 클릭하세요.", + "no-backup": "백업이 없습니다. 새로운 백업 구성을 만들려면 '새로운 백업'을 클릭하세요", "options": "옵션", "path": "경로", "restore": "복원", "restoring": "백업을 복원하는 중입니다. 시간이 좀 걸릴 수 있습니다. 잠시만 기다려 주세요.", "run": "백업 실행", "save": "저장", - "shutdown": "백업하는 동안 서버를 종료합니다.", + "shutdown": "백업하는 동안 서버를 종료합니다", "size": "크기", "standby": "대기중", "status": "상태", @@ -512,16 +512,16 @@ "deleteFilesQuestionMessage": "Crafty가 호스트 머신에서 모든 서버 파일을 삭제하도록 하시겠습니까?

여기에는 서버 백업도 포함됩니다.", "deleteServer": "서버 삭제", "deleteServerQuestion": "서버를 제거할까요?", - "deleteServerQuestionMessage": "정말로 이 서버를 삭제하시겠습니까? 삭제 후에는 「복구」할 수 없습니다", + "deleteServerQuestionMessage": "정말로 이 서버를 삭제하시겠습니까? 삭제 후에는 「복구」할 수 없어요.", "exeUpdateURL": "서버 실행 파일 업데이트 URL", - "exeUpdateURLDesc": "업데이트를 하기위한 다이렉트 다운로드 URL", + "exeUpdateURLDesc": "업데이트를 하기위한 다이렉트 다운로드 URL을 입력해주세요.", "ignoredExits": "충돌 코드 무시", "ignoredExitsExplain": "종료 코드 Crafty의 충돌 감지는 일반적인 '정지'로 무시해야 합니다(콤마로 구분)", "javaNoChange": "덮어쓰지 않기", "javaVersion": "현재 버전 덮어쓰기", - "javaVersionDesc": "Java를 덮어쓸 경우, '실행 명령'에서 현재 Java 경로가 따옴표로 감싸져 있는지 확인하세요(기본 'java' 변수 제외).", + "javaVersionDesc": "Java를 덮어쓸 경우, '실행 명령'에서 현재 Java 경로가 따옴표로 감싸져 있는지 확인하세요 (기본 'java' 변수 제외)", "noDelete": "돌아가지 않기", - "noDeleteFiles": "아니요, 패널에서만 제거해 주세요.", + "noDeleteFiles": "아니요, 패널에서만 제거해 주세요", "removeOldLogsAfter": "오래된 로그 삭제 후", "removeOldLogsAfterDesc": "로그 파일이 삭제되기 위해 얼마나 많은 시간이 지나야 하나요? (0은 비활성화)", "save": "저장", @@ -540,7 +540,7 @@ "serverLogLocation": "서버 로그 위치", "serverLogLocationDesc": "로그 파일 경로", "serverName": "서버 이름", - "serverNameDesc": "이 서버의 이름을 무엇으로 지정하시겠습니까?", + "serverNameDesc": "이 서버의 이름을 지정하세요", "serverPath": "서버가 작동할 폴더", "serverPathDesc": "실행 파일을 제외한 절대경로", "serverPort": "서버 포트", @@ -551,18 +551,18 @@ "shutdownTimeout": "종료 대기 시간", "statsHint1": "서버가 실행할 포트는 여기 입력해야 합니다. 이는 Crafty가 통계를 위해 서버에 연결을 여는 방법입니다.", "statsHint2": "이 설정은 서버의 포트를 변경하지 않습니다. 서버 구성 파일에서 포트를 변경해야 합니다.", - "stopBeforeDeleting": "서버를 삭제하기 전에 반드시 중지해 주세요.", - "timeoutExplain1": "크래피가 명령 실행 후 서버가 종료될 때까지 기다리는 시간입니다.", + "stopBeforeDeleting": "서버를 삭제하기 전에 반드시 중지해 주세요", + "timeoutExplain1": "Cratfy가 명령 실행 후 서버가 종료될 때까지 기다리는 시간입니다", "timeoutExplain2": "이 시간이 지나면 프로세스를 강제로 종료합니다.", "update": "실행 파일 업데이트", "yesDelete": "삭제합니다", "yesDeleteFiles": "모든 파일을 삭제합니다" }, "serverConfigHelp": { - "desc": "여기에서 서버 구성을 변경할 수 있습니다.", + "desc": "여기에서 서버의 설정을 변경할 수 있습니다", "perms": [ - "Crafty가 관리하는 서버의 경로는 변경하지 않는 것이 좋습니다.", - "경로를 변경하면 시스템에 문제가 발생할 수 있으며, 특히 파일 권한이 더 제한적인 리눅스 계열 운영 체제에서 그렇습니다.", + "Crafty가 관리하는 서버의 경로는 변경하지 않는 것을 권장합니다.", + "경로를 변경하면 시스템에 문제가 발생할 수 있으며, 특히 파일 권한이 더 제한적인 리눅스 계열 운영 체제에서 발생할 가능성이 높습니다.", "

", "서버 위치를 변경해야 한다고 생각하시면, \"crafty\" 사용자에게 서버 경로에 대한 읽기/쓰기 권한을 부여하는 한 변경할 수 있습니다.", "
", From 5e4aa932de1de4ed343d7f1d0ab16c4710280ab0 Mon Sep 17 00:00:00 2001 From: Augusto Micheletti Date: Mon, 2 Dec 2024 10:21:37 +0000 Subject: [PATCH 51/74] Translated (Italian) Currently translated at 96.6% (612 of 633 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/it/ --- app/translations/it_IT.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/translations/it_IT.json b/app/translations/it_IT.json index f7148ef6..74e275d5 100644 --- a/app/translations/it_IT.json +++ b/app/translations/it_IT.json @@ -235,7 +235,9 @@ "finishedPreparing": "Abbiamo finito di preparare i tuoi registri di supporto.Per favore clicca Scarica per scaricarli", "logout": "Disconnessione", "preparingLogs": "Per favore aspetta mentre prepariamo i tuoi registri... Ti invieremo una notifica quando saranno pronti. Potrebbe volerci un po' per installazioni grosse.", - "supportLogs": "Registri di supporto" + "supportLogs": "Registri di supporto", + "backup_desc": "Abbiamo rilevato che la migrazione del backup potrebbe essere parzialmente o completamente fallita. Controlla i backup effettuati nella scheda Backup.", + "backup_title": "Avviso migrazione di backup" }, "offline": { "offline": "Disconnesso", From cf8766b1bf832d008047a90d7489debf5a7698a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B9?= Date: Mon, 2 Dec 2024 19:10:33 +0000 Subject: [PATCH 52/74] Translated (Russian) Currently translated at 100.0% (633 of 633 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/ru/ --- app/translations/ru_RU.json | 39 +++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/app/translations/ru_RU.json b/app/translations/ru_RU.json index a86b1b30..8cace3f2 100644 --- a/app/translations/ru_RU.json +++ b/app/translations/ru_RU.json @@ -56,13 +56,13 @@ "customLogin": { "apply": "Применить", "backgroundUpload": "Загрузка фона", - "customLoginPage": "Настройки страницы входа в систему", + "customLoginPage": "Настройте страницу входа в систему", "delete": "Удалить", "labelLoginImage": "Выберите фон для входа в систему", "loginBackground": "Фоновое изображение входа в систему", "loginImage": "Загрузите фоновое изображение для экрана входа в систему.", "loginOpacity": "Выберите непрозрачность окна входа в систему", - "pageTitle": "Настройки страницы входа в систему", + "pageTitle": "Кастомизированная страница входа в систему", "preview": "Превью", "select": "Выбрать", "selectImage": "Выбрать изображение" @@ -70,7 +70,7 @@ "dashboard": { "actions": "Действия", "allServers": "Все серверы", - "avg": "Avg", + "avg": "Среднее значение", "backups": "Бэкапы", "bePatientClone": "Пожалуйста, наберитесь терпения, пока мы будем клонировать сервер.
Этот экран обновится через мгновение", "bePatientRestart": "Пожалуйста, наберитесь терпения, пока мы перезапускаем сервер.
Этот экран обновится через мгновение", @@ -192,7 +192,7 @@ "embarassing": "О боже, ну что ж, это так неловко.", "error": "Ошибка!", "eulaAgree": "Вы согласны?", - "eulaMsg": "Вы должны согласиться с", + "eulaMsg": "Вы должны согласиться с ", "eulaTitle": "Согласитесь с EULA", "fileError": "Типом файла должно быть изображение.", "fileTooLarge": "Ошибка загрузки. Загружен слишком большой файл. Обратитесь за помощью к системному администратору.", @@ -235,7 +235,11 @@ "finishedPreparing": "Мы закончили подготовку ваших журналов поддержки. Пожалуйста, нажмите загрузить, чтобы загрузить", "logout": "Выход из системы", "preparingLogs": " Пожалуйста, подождите, пока мы подготовим ваши журналы... Мы отправим уведомление, когда они будут готовы. При больших объемах развертывания это может занять некоторое время.", - "supportLogs": "Журналы поддержки" + "supportLogs": "Журналы поддержки", + "backup_desc": "Мы обнаружили, что перенос резервной копии, возможно, завершился частичным или полным сбоем. Пожалуйста, подтвердите свои записи в резервных копиях на вкладке резервные копии.", + "schedule_desc": "Мы обнаружили, что некоторые или все запланированные вами задачи не были успешно перенесены во время обновления. Пожалуйста, подтвердите свои расписания на вкладке расписания.", + "backup_title": "Предупреждение о переносе резервной копии", + "schedule_title": "Предупреждение о переносе расписаний" }, "offline": { "offline": "Оффлайн", @@ -324,7 +328,7 @@ "exclusionsTitle": "Исключения из резервного копирования", "failed": "Неудача", "maxBackups": "Максимально резервных копий", - "maxBackupsDesc": "Crafty не будет хранить более N резервных копий, удаляя самые старые (введите 0, чтобы сохранить все).", + "maxBackupsDesc": "Crafty не будет хранить более N резервных копий, удаляя самые старые (введите 0, чтобы сохранить все)", "myBackup": "Моя новая резервная копия", "name": "Имя", "newBackup": "Создать новую резервную копию", @@ -359,7 +363,7 @@ "exeUpdateURL": "URL-адрес обновления исполняемого файла сервера", "exeUpdateURLDesc": "Прямой URL-адрес для загрузки обновлений.", "ignoredExits": "Игнорируемые коды аварийного выхода", - "ignoredExitsExplain": "Коды выхода при обнаружении сбоя Crafty следует игнорировать как обычную 'остановку' (через запятую).", + "ignoredExitsExplain": "Коды выхода при обнаружении сбоя Crafty следует игнорировать как обычный 'stop' (через запятую)", "javaNoChange": "Не переопределять", "javaVersion": "Переопределить текущую версию Java", "javaVersionDesc": "Если вы собираетесь переопределить Java, убедитесь, что ваш текущий путь к Java указан в 'Команда выполнения сервера' и заключен в кавычки (по умолчанию 'java')", @@ -668,7 +672,26 @@ "uses": "Количество использований (-1==без ограничений)" }, "validators": { - "passLength": "Пароль слишком короткий. Минимальная длина: 8" + "passLength": "Пароль слишком короткий. Минимальная длина: 8", + "roleManager": "Роль менеджера должна быть типа integer (ID менеджера) или None", + "filesPageLen": "длина свойства должна быть больше 1", + "serverCreateName": "Имя сервера должно быть строкой длиной не менее 2-х символов и не должно содержать: \\ / или # ", + "typeString": "должен быть типа string.", + "backupName": "Имя резервной копии должно быть строкой и иметь длину не менее 3-х символов.", + "roleServerId": "Свойство «ID сервера» должно быть строкой с минимальной длиной 1", + "userName": " должно быть типа string, все в НИЖНЕМ регистре, минимум из 4 символов и максимум из 20 символов", + "taskIntervalType": "Тип интервала выполнения задачи должен быть одним из следующих: ", + "typeIntMinVal0": "должно быть целым числом с минимальным значением 0.", + "enumErr": "не удалось выполнить проверку. Допустимые данные включают: ", + "insufficientPerms": "Ошибка разрешения: Отсутствуют разрешения для этого ресурса", + "roleName": "Имя роли должно быть строкой длиной более 1 символа. Оно не должно содержать ни одного из следующих символов: [ ] , ", + "roleServerPerms": "Разрешения сервера должны быть 8-разрядной строкой", + "serverExeCommand": "Команда выполнения сервера должна представлять собой строку минимальной длины, равной 1 символ.", + "serverLogPath": "Путь к журналу сервера должен быть строкой длиной не менее 1 символ", + "typeBool": "должно быть true или false (тип boolean)", + "typeEmail": "должен быть тип email.", + "typeInteger": "должно быть типа - число.", + "typeList": "должен быть типа list/array " }, "webhooks": { "areYouSureDel": "Вы уверены, что хотите удалить этот вебхук?", From 3b8c2f07f2ef742377fb6cce8dbce5d7c76fb13b Mon Sep 17 00:00:00 2001 From: Frederic Franck Date: Mon, 2 Dec 2024 18:47:59 +0000 Subject: [PATCH 53/74] Translated (German) Currently translated at 100.0% (633 of 633 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/de/ --- app/translations/de_DE.json | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/app/translations/de_DE.json b/app/translations/de_DE.json index 5e42ad93..fbfaf0e2 100644 --- a/app/translations/de_DE.json +++ b/app/translations/de_DE.json @@ -219,7 +219,7 @@ }, "login": { "defaultPath": "Der eingegebene Text ist der Pfad zum Passwort, nicht das Passwort selbst. Das Standartpasswort kann unter diesen Pfad eingesehen werden.", - "disabled": "Account gesperrt. Für weitere Informationen den Serveradministrator kontaktieren", + "disabled": "Account gesperrt. Für weitere Informationen den Serveradministrator kontaktieren.", "forgotPassword": "Passwort vergessen", "incorrect": "Benutzername oder Passwort falsch", "login": "Einloggen", @@ -235,11 +235,15 @@ "finishedPreparing": "Wir haben die Bereitstellung der Supportprotokolle abgeschlossen. Bitte klicke 'Herunterladen' um diese herunterzuladen", "logout": "Abmelden", "preparingLogs": " Bitte warten, während wir die Protokolle vorbereiten... Wir schicken eine Benachrichtigung, wenn sie fertig sind. Dies kann bei großen Projekten eine Weile dauern.", - "supportLogs": "Supportprotokolle" + "supportLogs": "Supportprotokolle", + "backup_desc": "Wir haben fesgestellt, dass die Migration des Backups teilweise oder vollständig fehlgeschlagen ist. Bitte Backups im Backup Menü überprüfen.", + "schedule_desc": "Wir haben festgestellt, dass geplante Aufgaben während des Upgrades nicht erfolgreich übertragen wurden. Bitte die geplanten Aufgaben im Zeitplan überprüfen.", + "backup_title": "Backup Migrations Warnung", + "schedule_title": "Zeitplan Migrations Warnung" }, "offline": { "offline": "Offline", - "pleaseConnect": "Bitte stellen sie eine Internetverbindung her, um Crafty nutzen zu können" + "pleaseConnect": "Bitte stellen sie eine Internetverbindung her, um Crafty nutzen zu können." }, "panelConfig": { "adminControls": "Administrations-Werkzeuge", @@ -668,7 +672,26 @@ "uses": "Anzahl der erlaubten Verwendungen (-1==Keine Begrenzung)" }, "validators": { - "passLength": "Passwort zu kurz. Mindestlänge: 8" + "passLength": "Passwort zu kurz. Mindestlänge: 8", + "typeInteger": "muss eine Zahl sein.", + "typeList": "muss eine Liste (array) sein ", + "roleManager": "Rollenmanager muss vom Typ Ganzzahl (Manager ID) oder ohne Wert sein", + "typeIntMinVal0": "muss eine ganze Zahl und mindestens 0 sein.", + "backupName": "Der Name des Backups muss eine Zeichenkette mit mindestens drei Zeichen sein.", + "serverCreateName": "Server Name muss eine Zeichenkette mit der Mindestlänge 1 sein und darf die folgenden Zeichen nicht beinhalten: \\ / # ", + "userName": " muss vom Typ Zeichenkette, in kleinbuchstaben und zwischen 4 und 20 Zeichen lang sein", + "enumErr": "Validierung fehlgeschlagen. Erfolgreiche Prüfung der folgenden Daten: ", + "filesPageLen": "Länge der Eigenschaft muss größer als 1 sein", + "roleName": "Rollenmanager muss eine Zeichenkette Länger als 1 sein und darf folgende Symbole nicht enthalten: [], ", + "roleServerId": "Server ID muss eine Zeichenkette mit der Mindestlänge 1 sein", + "roleServerPerms": "Serverberechtigung muss eine 8 Bit Zeichenkette sein", + "serverLogPath": "Server log Pfad muss eine Zeichenkette mit einer Mindestlänge von 1 sein", + "taskIntervalType": "Aufgaben Intervall muss einer der folgenden sein: ", + "typeBool": "muss wahr oder falsch sein (typ boolean)", + "typeEmail": "muss eine Email sein.", + "insufficientPerms": "Berechtigungsfehler: Fehlende Berechtigungen für diese Ressource", + "serverExeCommand": "Server Ausführungbefehl muss eine Zeichenkette mit der Mindestlänge 1 sein.", + "typeString": "muss vom Typ Zeichenkette sein." }, "webhooks": { "areYouSureDel": "Sind Sie sicher, dass Sie diesen Webhook löschen möchten?", From 310cbbe010fbbe091caeb650a3ea12eba2b50958 Mon Sep 17 00:00:00 2001 From: Kanatsanan Date: Tue, 3 Dec 2024 17:07:01 +0000 Subject: [PATCH 54/74] Translated (Thai) Currently translated at 100.0% (633 of 633 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/th/ --- app/translations/th_TH.json | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/app/translations/th_TH.json b/app/translations/th_TH.json index d408adf6..dd0031ec 100644 --- a/app/translations/th_TH.json +++ b/app/translations/th_TH.json @@ -235,7 +235,11 @@ "finishedPreparing": "เราได้เตรียมบันทึกการสนับสนุนของคุณเสร็จแล้ว กรุณาคลิกดาวน์โหลดเพื่อดาวน์โหลด", "logout": "ออกจากระบบ", "preparingLogs": " โปรดรอสักครู่ในขณะที่เราเตรียมบันทึกของคุณ... เราจะส่งการแจ้งเตือนเมื่อเสร็จสิ้น การดำเนินการนี้อาจใช้เวลาสักครู่สำหรับการเตรียมข้อมูลขนาดใหญ่", - "supportLogs": "บันทึกการสนับสนุน" + "supportLogs": "บันทึกการสนับสนุน", + "schedule_desc": "เราตรวจพบว่างานตามกำหนดการบางส่วนหรือทั้งหมดของคุณโอนย้ายไม่สำเร็จในระหว่างการอัปเกรด โปรดยืนยันกำหนดการของคุณในแท็บกำหนดการ", + "backup_desc": "เราตรวจพบว่าการย้ายข้อมูลสำรองอาจล้มเหลวบางส่วนหรือทั้งหมด โปรดยืนยันข้อมูลสำรองของคุณในหน้าข้อมูลสำรอง", + "backup_title": "คำเตือนการโยกย้ายข้อมูลสำรอง", + "schedule_title": "คำเตือนการโยกย้ายกำหนดการ" }, "offline": { "offline": "ออฟไลน์", @@ -668,7 +672,26 @@ "uses": "จำนวนการใช้งานที่อนุญาต (-1==ไม่มีขีดจำกัด)" }, "validators": { - "passLength": "รหัสผ่านสั้นเกินไป จำนวนตัวอักขระขั้นต่ำ: 8" + "passLength": "รหัสผ่านสั้นเกินไป จำนวนตัวอักขระขั้นต่ำ: 8", + "roleManager": "ผู้จัดการบทบาทต้องเป็นประเภทจำนวนเต็ม (ID ผู้จัดการ) หรือเป็น None", + "roleName": "ชื่อบทบาทต้องเป็นสตริงที่มีความยาวมากกว่า 1 ตัวอักษร และต้องไม่มีสัญลักษณ์ใด ๆ ดังนี้: [ ] , ", + "filesPageLen": "ความยาวต้องมากกว่า 1 สำหรับคุณสมบัติ", + "typeIntMinVal0": "ต้องเป็นจำนวนเต็มที่มีค่าต่ำสุดเป็น 0", + "userName": " ต้องเป็นประเภทสตริง, ตัวอักษรตัวเล็กทั้งหมด, มีความยาวอย่างน้อย 4 ตัวอักษร และไม่เกิน 20 ตัวอักษร", + "serverCreateName": "ชื่อเซิร์ฟเวอร์ต้องเป็นสตริงที่มีความยาวอย่างน้อย 2 ตัวอักษร และต้องไม่มีสัญลักษณ์: \\\\ / หรือ # ", + "serverLogPath": "เส้นทางบันทึกเซิร์ฟเวอร์ต้องเป็นสตริงที่มีความยาวอย่างน้อย 1 ตัวอักษร", + "taskIntervalType": "ประเภทช่วงเวลาในการทำงานต้องเป็นหนึ่งในสิ่งต่อไปนี้: ", + "backupName": "ชื่อการสำรองข้อมูลจะต้องเป็นสตริงและมีความยาวขั้นต่ำ 3 ตัวอักษร", + "enumErr": "การตรวจสอบล้มเหลว ข้อมูลที่ยอมรับได้ ได้แก่: ", + "insufficientPerms": "ข้อผิดพลาดการอนุญาต: ขาดการอนุญาตสำหรับทรัพยากรนี้", + "roleServerId": "ID เซิร์ฟเวอร์ต้องเป็นสตริงที่มีความยาวอย่างน้อย 1 ตัวอักษร", + "roleServerPerms": "สิทธิ์การใช้งานเซิร์ฟเวอร์ต้องเป็นสตริงแบบ 8 บิต", + "serverExeCommand": "คำสั่งในการดำเนินการเซิร์ฟเวอร์ต้องเป็นสตริงที่มีความยาวอย่างน้อย 1 ตัวอักษร", + "typeBool": "ต้องเป็น true หรือ false (ชนิดบูลีน)", + "typeEmail": "ต้องเป็นประเภทอีเมล", + "typeInteger": "ต้องเป็นตัวเลข", + "typeList": "ต้องเป็นประเภทลิสต์/อาร์เรย์ ", + "typeString": "ต้องเป็นประเภทสตริง" }, "webhooks": { "areYouSureDel": "คุณแน่ใจหรือไม่ว่าต้องการลบ Webhook นี้?", From ef0b252e20adf80a8efd64d143fa0aeabc839322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B9?= Date: Wed, 4 Dec 2024 15:10:00 +0000 Subject: [PATCH 55/74] Translated (Russian) Currently translated at 100.0% (633 of 633 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/ru/ --- app/translations/ru_RU.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/translations/ru_RU.json b/app/translations/ru_RU.json index 8cace3f2..7ae49a9e 100644 --- a/app/translations/ru_RU.json +++ b/app/translations/ru_RU.json @@ -401,7 +401,7 @@ "stopBeforeDeleting": "Пожалуйста, остановите сервер перед его удалением", "timeoutExplain1": "Как долго Crafty будет ждать завершения работы вашего сервера после выполнения", "timeoutExplain2": "выполните команду до того, как она остановит процесс.", - "update": "Исполняемый файл обновления", + "update": "Обновить исполняемый файл", "yesDelete": "Да, удалить", "yesDeleteFiles": "Да, удалить файлы" }, From f807b87bcca05b349ac6dde97f0cdf95425f2af5 Mon Sep 17 00:00:00 2001 From: ThrRip Date: Wed, 4 Dec 2024 21:50:41 +0000 Subject: [PATCH 56/74] Translated (Chinese (Simplified Han script)) Currently translated at 96.3% (610 of 633 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/zh_Hans/ --- app/translations/zh_CN.json | 54 ++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/app/translations/zh_CN.json b/app/translations/zh_CN.json index 48c748f3..c2cc34b8 100644 --- a/app/translations/zh_CN.json +++ b/app/translations/zh_CN.json @@ -12,10 +12,10 @@ }, "apiKeys": { "apiKeys": "API 密钥", - "auth": "已授权?", + "auth": "已授权? ", "buttons": "按钮", "config": "配置", - "crafty": "Crafty:", + "crafty": "Crafty: ", "createNew": "创建新的 API 令牌", "created": "创建时间", "deleteKeyConfirmation": "您想要删除这个 API 密钥吗?此操作不能撤销。", @@ -23,12 +23,12 @@ "fullAccess": "完全访问", "getToken": "获得一个令牌", "name": "名称", - "nameDesc": "你想把这个 API 令牌叫做什么?", + "nameDesc": "你想把这个 API 令牌叫做什么? ", "no": "否", "pageTitle": "编辑用户 API 密钥", "permName": "权限名称", "perms": "权限", - "server": "服务器:", + "server": "服务器: ", "yes": "是" }, "base": { @@ -48,7 +48,7 @@ "subscriptionLevel": "等级", "supportTeam": "支持与文档团队", "thankYou": "感谢", - "translationDesc": "帮助我们翻译的社区!", + "translationDesc": "帮助我们翻译的社区![ 活跃 = 🟢 不活跃/已离职 = ⚪ ]", "translationName": "名称", "translationTitle": "语言翻译", "translator": "译者" @@ -192,7 +192,7 @@ "embarassing": "哦,天哪,这太尴尬了。", "error": "错误!", "eulaAgree": "你同意吗?", - "eulaMsg": "你必须同意最终用户许可协议(EULA)。一份 Minecraft EULA 副本的链接在此消息下方。", + "eulaMsg": "你必须同意 ", "eulaTitle": "同意最终用户许可协议(EULA)", "fileError": "文件类型必须是图片。", "fileTooLarge": "上传失败。上传的文件过大。联系系统管理员以获取协助。", @@ -205,7 +205,7 @@ "noJava": "服务器 {} 启动失败,并输出了如下错误码:我们检测到 Java 未安装。请先安装 java 然后再启动服务器。", "not-downloaded": "我们似乎找不到您的可执行文件。它下载完成了吗?可执行文件的权限设置正确了吗?", "portReminder": "我们检测到这是你首次运行 {}。请确保从您的路由器/防火墙转发 {} 端口,以使程序可以从公网远程访问。", - "privMsg": "以及", + "privMsg": "以及 ", "return": "返回仪表板", "selfHost": "如果您自托管此仓库,请检查您的地址或参考我们的故障排除指南。", "start-error": "服务器 {} 启动失败,错误代码为:{}", @@ -231,7 +231,7 @@ "activityLog": "活动日志", "backupComplete": "服务器 {} 的备份已完成", "backupStarted": "服务器 {} 的备份已开始", - "downloadLogs": "下载支持日志:", + "downloadLogs": "下载支持日志?", "finishedPreparing": "我们已准备好您的支持日志。请点击“下载”来下载", "logout": "退出登录", "preparingLogs": " 请等待,我们正在准备您的日志……准备好时我们会发送一次提醒。这对于大型的部署来说可能需要一点时间。", @@ -275,8 +275,8 @@ "rolesConfig": { "config": "角色配置", "configDesc": "您可以在这里更改您的角色设置", - "configUpdate": "上次更新:", - "created": "创建时间:", + "configUpdate": "上次更新: ", + "created": "创建时间: ", "delRole": "删除角色", "doesNotExist": "您不能删除还不存在的东西", "pageTitle": "编辑角色", @@ -286,12 +286,12 @@ "permsServer": "此角色拥有的对这些特定服务器的权限", "roleConfigArea": "角色配置区", "roleDesc": "您希望把这个角色叫做什么?", - "roleName": "角色名称:", + "roleName": "角色名称: ", "rolePerms": "角色权限", "roleServers": "允许的服务器", "roleTitle": "角色设置", "roleUserName": "用户名称", - "roleUsers": "角色用户:", + "roleUsers": "角色用户: ", "selectManager": "选择此角色的管理员", "serverAccess": "访问?", "serverName": "服务器名称", @@ -319,7 +319,7 @@ "download": "下载", "edit": "编辑", "enabled": "已启用", - "excludedBackups": "排除的路径:", + "excludedBackups": "排除的路径: ", "excludedChoose": "选择您希望从您的备份中排除的路径", "exclusionsTitle": "备份排除项", "failed": "失败", @@ -352,7 +352,7 @@ "crashTime": "崩溃超时", "crashTimeDesc": "我们应该在考虑您的服务器已崩溃之前等待多久?", "deleteFilesQuestion": "从设备上删除服务器文件?", - "deleteFilesQuestionMessage": "您想要 Crafty 从主机上删除所有的服务器文件吗?", + "deleteFilesQuestionMessage": "您想要 Crafty 从主机上删除所有的服务器文件吗?

包含服务器备份。", "deleteServer": "删除服务器", "deleteServerQuestion": "删除服务器?", "deleteServerQuestionMessage": "您确定要删除此服务器吗?在此之后将无法撤销……", @@ -460,7 +460,7 @@ "unsupportedLanguage": "警告:这不是一个受支持的文件类型", "unzip": "解压", "upload": "上传", - "uploadTitle": "上传文件到:", + "uploadTitle": "上传文件到: ", "waitUpload": "请等待,我们正在上传您的文件……这需要一点时间。", "yesDelete": "是,我知道结果" }, @@ -477,11 +477,11 @@ "serverScheduleConfig": { "backup": "备份服务器", "basic": "基本", - "children": "已链接的子任务:", + "children": "已链接的子任务: ", "command": "指令", "command-explain": "您想要让我们执行什么指令?不要包含“/”", "cron": "定时(Cron)", - "cron-explain": "输入您的定时(Cron)字符串", + "cron-explain": "输入您的定时(Cron)字符串 -- 注意:最后一项的 0 = 周一。", "custom": "自定义指令", "days": "天", "enabled": "启用", @@ -509,7 +509,7 @@ "cancel": "取消", "cannotSee": "什么都看不到?", "cannotSeeOnMobile": "尝试点击一个计划任务来查看全部详细信息。", - "child": "父计划 ID", + "child": "父计划 ID ", "close": "关闭", "command": "指令", "confirm": "确认", @@ -582,7 +582,7 @@ "minMem": "最小内存", "myNewServer": "我的新服务器", "newServer": "创建新服务器", - "noRole": "未找到角色。当前搜索参数:", + "noRole": "根据当前搜索参数未找到角色", "noneRoles": "未选择角色", "quickSettings": "快捷设置", "quickSettingsDescription": "别担心,你可以稍后再更改这些设置", @@ -629,23 +629,23 @@ }, "userConfig": { "apiKey": "API 密钥", - "auth": "已授权?", + "auth": "已授权? ", "config": "配置", "configArea": "用户配置区", "configAreaDesc": "您可以在这里更改您的所有用户设置", "confirmDelete": "您想要删除这个用户吗?此操作不可逆。", - "craftyPermDesc": "此用户拥有的 Crafty 权限", - "craftyPerms": "Crafty 权限:", - "created": "创建时间:", + "craftyPermDesc": "此用户拥有的 Crafty 权限 ", + "craftyPerms": "Crafty 权限: ", + "created": "创建时间: ", "delSuper": "您不能删除超级用户", - "deleteUser": "删除用户:", + "deleteUser": "删除用户: ", "deleteUserB": "删除用户", "enabled": "已启用", "gravDesc": "此电子邮件仅用于 Gravatar™。Crafty 不会在任何情况下使用该邮箱进行除了查阅您的 Gravatar™ 以外的操作", "gravEmail": "Gravatar™ 邮箱", - "lastIP": "上次使用 IP:", - "lastLogin": "上次登录:", - "lastUpdate": "上次更新:", + "lastIP": "上次使用 IP: ", + "lastLogin": "上次登录: ", + "lastUpdate": "上次更新: ", "leaveBlank": "如果要编辑此用户但不更改密码,请留空。", "manager": "管理员", "member": "成员?", From 60c566807a4ed759a7369863bdb6cf53ddd86f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B9?= Date: Sat, 7 Dec 2024 02:15:51 +0000 Subject: [PATCH 57/74] Translated (Russian) Currently translated at 100.0% (633 of 633 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/ru/ --- app/translations/ru_RU.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/translations/ru_RU.json b/app/translations/ru_RU.json index 7ae49a9e..0b14604e 100644 --- a/app/translations/ru_RU.json +++ b/app/translations/ru_RU.json @@ -317,7 +317,7 @@ "confirmRestore": "Вы уверены, что хотите выполнить восстановление из этой резервной копии? Все текущие файлы сервера перейдут в состояние резервной копии и будут недоступны восстановлению.", "currentBackups": "Текущие резервные копии", "default": "Резервное копирование по умолчанию", - "defaultExplain": "Резервная копия, которую Crafty будет использовать перед обновлением. Ее нельзя изменить или удалить.", + "defaultExplain": "Резервная копия, которую Crafty будет создавать перед обновлением. Ее нельзя изменить или удалить.", "delete": "Удалить", "destroyBackup": "Уничтожить резервную копию \" + file_to_del + \"?", "download": "Скачать", From 72d747210f0c77eff4dfa8fef5d18d750db9db94 Mon Sep 17 00:00:00 2001 From: ThrRip Date: Sat, 7 Dec 2024 16:34:04 +0000 Subject: [PATCH 58/74] Translated (Chinese (Simplified Han script)) Currently translated at 100.0% (633 of 633 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/zh_Hans/ --- app/translations/zh_CN.json | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/app/translations/zh_CN.json b/app/translations/zh_CN.json index c2cc34b8..60c9535b 100644 --- a/app/translations/zh_CN.json +++ b/app/translations/zh_CN.json @@ -235,7 +235,11 @@ "finishedPreparing": "我们已准备好您的支持日志。请点击“下载”来下载", "logout": "退出登录", "preparingLogs": " 请等待,我们正在准备您的日志……准备好时我们会发送一次提醒。这对于大型的部署来说可能需要一点时间。", - "supportLogs": "支持日志" + "supportLogs": "支持日志", + "backup_title": "备份迁移警告", + "schedule_title": "计划迁移警告", + "backup_desc": "我们检测到备份迁移可能已经部分或完全失败。请在备份选项卡中确认您的备份记录。", + "schedule_desc": "我们检测到您的一些或全部计划任务在升级时未成功转移。请在计划选项卡中确认您的计划。" }, "offline": { "offline": "离线", @@ -668,7 +672,26 @@ "uses": "使用次数限制(-1==无限制)" }, "validators": { - "passLength": "密码过短。最短长度:8" + "passLength": "密码过短。最短长度:8", + "backupName": "备份名称必须为字符串,且最短长度为 3。", + "filesPageLen": "属性的长度必须大于 1", + "typeList": "必须为列表/数组类型 ", + "userName": " 必须为字符串类型,全部小写,且最短为 4 个字符,最长为 20 个字符", + "roleName": "角色名称必须为多于 1 个字符的字符串。必须不包含以下符号:[ ] , ", + "serverCreateName": "服务器名称必须为长度至少为 2 的字符串,且必须不包含:\\ / 或 # ", + "enumErr": "验证失败。接受的数据包括: ", + "insufficientPerms": "权限错误:缺少此资源的权限", + "roleManager": "角色管理员必须为整数类型(管理员 ID)或无", + "roleServerId": "服务器 ID 属性必须为长度至少为 1 的字符串", + "roleServerPerms": "服务器权限必须为 8 位的字符串", + "serverExeCommand": "服务器运行命令必须为长度至少为 1 的字符串。", + "serverLogPath": "服务器日志路径必须为长度至少为 1 的字符串", + "taskIntervalType": "任务间隔类型必须为下列值之一: ", + "typeBool": "必须为 true 或 false(布尔类型)", + "typeEmail": "必须为邮箱类型。", + "typeIntMinVal0": "必须为最小值为 0 的整数。", + "typeInteger": "必须为数字。", + "typeString": "必须为字符串类型。" }, "webhooks": { "areYouSureDel": "您确定要删除此 webhook 吗?", From 0506c8bfa7510b7b2f6edfa8f1e2008c2829bfbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B9?= Date: Sun, 8 Dec 2024 02:34:30 +0000 Subject: [PATCH 59/74] Translated (Russian) Currently translated at 100.0% (633 of 633 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/ru/ --- app/translations/ru_RU.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/translations/ru_RU.json b/app/translations/ru_RU.json index 0b14604e..11cab8fc 100644 --- a/app/translations/ru_RU.json +++ b/app/translations/ru_RU.json @@ -362,8 +362,8 @@ "deleteServerQuestionMessage": "Вы уверены, что хотите удалить этот сервер? После этого пути назад не будет...", "exeUpdateURL": "URL-адрес обновления исполняемого файла сервера", "exeUpdateURLDesc": "Прямой URL-адрес для загрузки обновлений.", - "ignoredExits": "Игнорируемые коды аварийного выхода", - "ignoredExitsExplain": "Коды выхода при обнаружении сбоя Crafty следует игнорировать как обычный 'stop' (через запятую)", + "ignoredExits": "Игнорируемые коды аварийной остановки", + "ignoredExitsExplain": "Коды остановки сервера, при обнаружении которых Crafty будет их игнорировать, чтобы не воспринимать как сбой сервера (вводить через запятую)", "javaNoChange": "Не переопределять", "javaVersion": "Переопределить текущую версию Java", "javaVersionDesc": "Если вы собираетесь переопределить Java, убедитесь, что ваш текущий путь к Java указан в 'Команда выполнения сервера' и заключен в кавычки (по умолчанию 'java')", @@ -645,7 +645,7 @@ "deleteUser": "Удалить пользователя: ", "deleteUserB": "Удалить пользователя", "enabled": "Включён", - "gravDesc": "Это электронное письмо предназначено исключительно для использования с Gravatar™. Crafty ни при каких обстоятельствах не будет использовать это электронное письмо для чего-либо, кроме поиска вашего Gravatar™", + "gravDesc": "Эта электронная почта предназначена исключительно для использования с Gravatar™. Crafty ни при каких обстоятельствах не будет использовать эту электронную почту для чего-либо, кроме поиска вашего Gravatar™", "gravEmail": "Gravatar™ Email", "lastIP": "Последний IP: ", "lastLogin": "Последний вход в систему: ", From 5432ae49505a8908b081282252d8a318e21b8d37 Mon Sep 17 00:00:00 2001 From: Augusto Micheletti Date: Mon, 9 Dec 2024 08:48:11 +0000 Subject: [PATCH 60/74] Translated (Italian) Currently translated at 97.1% (615 of 633 strings) Translation: Crafty Controller/Crafty Controller Translate-URL: https://translate.arcadiatech.org/projects/crafty-controller/crafty-controller/it/ --- app/translations/it_IT.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/translations/it_IT.json b/app/translations/it_IT.json index 74e275d5..aef3ef49 100644 --- a/app/translations/it_IT.json +++ b/app/translations/it_IT.json @@ -670,7 +670,10 @@ "uses": "Numero di usi permessi (-1==Nessun limite)" }, "validators": { - "passLength": "La password è troppo corta. Lunghezza minima: 8" + "passLength": "La password è troppo corta. Lunghezza minima: 8", + "enumErr": "Validazione fallita. Valori accettabili includono: ", + "serverExeCommand": "Il comando di esecuzione del server dev’essere una stringa con lunghezza minima di 1.", + "serverLogPath": "Il percorso del registro del server dev’essere una stringa con lunghezza minima di 1" }, "webhooks": { "areYouSureDel": "Sei sicuro di voler eliminare questo webhook?", From 30948b4db9f95d986c0e98bf82bfc348e954de86 Mon Sep 17 00:00:00 2001 From: Zedifus Date: Tue, 10 Dec 2024 13:50:57 +0000 Subject: [PATCH 61/74] Append job id to builder & context Stops parallel jobs clashing --- .gitlab/docker-build.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.gitlab/docker-build.yml b/.gitlab/docker-build.yml index aa578e97..9af25062 100644 --- a/.gitlab/docker-build.yml +++ b/.gitlab/docker-build.yml @@ -30,6 +30,8 @@ docker-build-dev: - docker run --rm --privileged aptman/qus -s -- -p aarch64 x86_64 - echo $CI_JOB_TOKEN | docker login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY - echo $DOCKERHUB_TOKEN | docker login -u "$DOCKERHUB_USER" --password-stdin $DOCKERHUB_REGISTRY + - docker context create tls-environment-$CI_JOB_ID + - docker buildx create --name zedBuilder-$CI_JOB_ID --use tls-environment-$CI_JOB_ID script: - | tag=":$CI_COMMIT_REF_SLUG" @@ -37,8 +39,6 @@ docker-build-dev: - | echo "Running on branch '$CI_COMMIT_BRANCH': tag = $tag" echo "Crafty Version: $VERSION" - - docker context create tls-environment - - docker buildx create --name zedBuilder --use tls-environment - docker buildx build --cache-from type=registry,ref="$CI_REGISTRY_IMAGE${tag}" --build-arg BUILDKIT_INLINE_CACHE=1 @@ -52,8 +52,8 @@ docker-build-dev: --push . after_script: - | - docker buildx rm zedBuilder && echo "Successfully Stopped builder instance" || echo "Failed to stop builder instance." - docker context rm tls-environment || true + docker buildx rm zedBuilder-$CI_JOB_ID && echo "Successfully Stopped builder instance" || echo "Failed to stop builder instance." + docker context rm tls-environment-$CI_JOB_ID || true echo "Please review multi-arch manifests are present:" docker buildx imagetools inspect "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" @@ -87,6 +87,8 @@ docker-build-prod: - docker run --rm --privileged aptman/qus -s -- -p aarch64 x86_64 - echo $CI_JOB_TOKEN | docker login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY - echo $DOCKERHUB_TOKEN | docker login -u "$DOCKERHUB_USER" --password-stdin $DOCKERHUB_REGISTRY + - docker context create tls-environment-$CI_JOB_ID + - docker buildx create --name zedBuilder-$CI_JOB_ID --use tls-environment-$CI_JOB_ID script: - | VERSION="${MAJOR}.${MINOR}.${SUB}" @@ -110,7 +112,7 @@ docker-build-prod: --push . after_script: - | - docker buildx rm zedBuilder && echo "Successfully Stopped builder instance" || echo "Failed to stop builder instance." - docker context rm tls-environment || true + docker buildx rm zedBuilder-$CI_JOB_ID && echo "Successfully Stopped builder instance" || echo "Failed to stop builder instance." + docker context rm tls-environment-$CI_JOB_ID || true echo "Please review multi-arch manifests are present:" docker buildx imagetools inspect "$CI_REGISTRY_IMAGE${tag}" From 3eeb6d8a2a20036eca80184bfcf10de6e395f0ff Mon Sep 17 00:00:00 2001 From: Glenn Schuurman Date: Tue, 10 Dec 2024 19:24:56 +0000 Subject: [PATCH 62/74] Upgrade crafty to ubuntu 24.04 --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index d05cf3d0..8c16e3a3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.04 +FROM ubuntu:24.04 ENV DEBIAN_FRONTEND="noninteractive" @@ -36,7 +36,7 @@ WORKDIR /crafty COPY --chown=crafty:root requirements.txt ./ RUN python3 -m venv ./.venv \ && . .venv/bin/activate \ - && pip3 install --no-cache-dir --upgrade setuptools==50.3.2 pip==22.0.3 \ + && pip3 install --no-cache-dir --upgrade setuptools==75.6.0 pip==24.3.1 \ && pip3 install --no-cache-dir -r requirements.txt \ && deactivate USER root From dc8db04228ece3cca36d0d37f445ed85cf0c9dbb Mon Sep 17 00:00:00 2001 From: Zedifus Date: Tue, 10 Dec 2024 19:50:12 +0000 Subject: [PATCH 63/74] Consolidate separate prod & dev build jobs into one, adding rule for nightly builds --- .gitlab-ci.yml | 3 +- .gitlab/docker-build.yml | 151 ++++++++++++++++----------------------- 2 files changed, 64 insertions(+), 90 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 03144b48..4fbfb834 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,8 +5,7 @@ stages: - lint - test - - prod-deployment - - dev-deployment + - build-and-deploy - release variables: diff --git a/.gitlab/docker-build.yml b/.gitlab/docker-build.yml index 9af25062..454bc2d2 100644 --- a/.gitlab/docker-build.yml +++ b/.gitlab/docker-build.yml @@ -1,81 +1,42 @@ # yamllint disable rule:line-length --- -docker-build-dev: +docker-build: image: docker:latest services: - name: docker:dind - stage: dev-deployment + stage: build-and-deploy tags: - docker_priv - rules: - - if: $CI_COMMIT_BRANCH == 'dev' - environment: - name: development - before_script: - - | - apk --no-cache add jq - MAJOR=$(cat app/config/version.json | jq '.major' ) - MINOR=$(cat app/config/version.json | jq '.minor' ) - SUB=$(cat app/config/version.json | jq '.sub' ) - - | - apk --no-cache add curl - latest_tag=$(curl -s https://api.github.com/repos/docker/buildx/releases/latest | sed -Ene '/^ *"tag_name": *"(v.+)",$/s//\1/p') - echo "Using buildx version $latest_tag" - curl -sSLo docker-buildx "https://github.com/docker/buildx/releases/download/$latest_tag/buildx-$latest_tag.linux-amd64" - chmod a+x docker-buildx - mkdir -p ~/.docker/cli-plugins - mv docker-buildx ~/.docker/cli-plugins/docker-buildx - docker version - - docker run --rm --privileged aptman/qus -- -r - - docker run --rm --privileged aptman/qus -s -- -p aarch64 x86_64 - - echo $CI_JOB_TOKEN | docker login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY - - echo $DOCKERHUB_TOKEN | docker login -u "$DOCKERHUB_USER" --password-stdin $DOCKERHUB_REGISTRY - - docker context create tls-environment-$CI_JOB_ID - - docker buildx create --name zedBuilder-$CI_JOB_ID --use tls-environment-$CI_JOB_ID - script: - - | - tag=":$CI_COMMIT_REF_SLUG" - VERSION="${MAJOR}.${MINOR}.${SUB}" - - | - echo "Running on branch '$CI_COMMIT_BRANCH': tag = $tag" - echo "Crafty Version: $VERSION" - - docker buildx build - --cache-from type=registry,ref="$CI_REGISTRY_IMAGE${tag}" - --build-arg BUILDKIT_INLINE_CACHE=1 - --build-arg "BUILD_DATE=$(date +"%Y-%m-%dT%H:%M:%SZ")" - --build-arg "BUILD_REF=${CI_COMMIT_SHA}" - --build-arg "CRAFTY_VER=${VERSION}" - --provenance false - --tag "$CI_REGISTRY_IMAGE${tag}" - --tag "arcadiatechnology/crafty-4${tag}" - --platform linux/arm64/v8,linux/amd64 - --push . - after_script: - - | - docker buildx rm zedBuilder-$CI_JOB_ID && echo "Successfully Stopped builder instance" || echo "Failed to stop builder instance." - docker context rm tls-environment-$CI_JOB_ID || true - echo "Please review multi-arch manifests are present:" - docker buildx imagetools inspect "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" -docker-build-prod: - image: docker:latest - services: - - name: docker:dind - stage: prod-deployment - tags: - - docker_priv rules: - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + # Development branch + - if: $CI_COMMIT_BRANCH == 'dev' + variables: + ENVIRONMENT_NAME: "development" + DOCKER_TAGS: "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG arcadiatechnology/crafty-4:$CI_COMMIT_REF_SLUG" + # Production branch (main) when not scheduled + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "schedule" + variables: + ENVIRONMENT_NAME: "production" + # We'll set the version in the script and append stable tags + DOCKER_TAGS: "" # We'll determine in script + # Scheduled nightly builds on main + - if: $CI_PIPELINE_SOURCE == "schedule" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + variables: + ENVIRONMENT_NAME: "production" + DOCKER_TAGS: "$CI_REGISTRY_IMAGE:nightly arcadiatechnology/crafty-4:nightly" + environment: - name: production + name: $ENVIRONMENT_NAME + before_script: - | - apk --no-cache add jq - MAJOR=$(cat app/config/version.json | jq '.major' ) - MINOR=$(cat app/config/version.json | jq '.minor' ) - SUB=$(cat app/config/version.json | jq '.sub' ) + apk --no-cache add jq curl + MAJOR=$(cat app/config/version.json | jq -r '.major') + MINOR=$(cat app/config/version.json | jq -r '.minor') + SUB=$(cat app/config/version.json | jq -r '.sub') + VERSION="${MAJOR}.${MINOR}.${SUB}" - | - apk --no-cache add curl latest_tag=$(curl -s https://api.github.com/repos/docker/buildx/releases/latest | sed -Ene '/^ *"tag_name": *"(v.+)",$/s//\1/p') echo "Using buildx version $latest_tag" curl -sSLo docker-buildx "https://github.com/docker/buildx/releases/download/$latest_tag/buildx-$latest_tag.linux-amd64" @@ -89,30 +50,44 @@ docker-build-prod: - echo $DOCKERHUB_TOKEN | docker login -u "$DOCKERHUB_USER" --password-stdin $DOCKERHUB_REGISTRY - docker context create tls-environment-$CI_JOB_ID - docker buildx create --name zedBuilder-$CI_JOB_ID --use tls-environment-$CI_JOB_ID + script: + - echo "Running on branch '$CI_COMMIT_BRANCH', environment: $ENVIRONMENT_NAME" + - echo "Crafty Version: $VERSION" + + # If DOCKER_TAGS is empty (production default branch and not schedule), we set stable tags: + # This scenario adds both VERSION and 'latest' tags. - | - VERSION="${MAJOR}.${MINOR}.${SUB}" - - | - echo "Running on branch '$CI_COMMIT_BRANCH'" - echo "Crafty Version: $VERSION" - - docker context create tls-environment - - docker buildx create --name zedBuilder --use tls-environment - - docker buildx build - --cache-from type=registry,ref="$CI_REGISTRY_IMAGE:latest" - --build-arg BUILDKIT_INLINE_CACHE=1 - --build-arg "BUILD_DATE=$(date +"%Y-%m-%dT%H:%M:%SZ")" - --build-arg "BUILD_REF=${CI_COMMIT_SHA}" - --build-arg "CRAFTY_VER=${VERSION}" - --provenance false - --tag "$CI_REGISTRY_IMAGE:$VERSION" - --tag "$CI_REGISTRY_IMAGE:latest" - --tag "arcadiatechnology/crafty-4:$VERSION" - --tag "arcadiatechnology/crafty-4:latest" - --platform linux/arm64/v8,linux/amd64 + if [ "$ENVIRONMENT_NAME" = "production" ] && [ -z "$DOCKER_TAGS" ]; then + DOCKER_TAGS="$CI_REGISTRY_IMAGE:${VERSION} \ + $CI_REGISTRY_IMAGE:latest \ + arcadiatechnology/crafty-4:${VERSION} \ + arcadiatechnology/crafty-4:latest" + fi + + - echo "Using the following tags: $DOCKER_TAGS" + + # Prepare build command + # We break DOCKER_TAGS into separate --tag arguments + - TARGS="" + - for t in $DOCKER_TAGS; do TARGS="$TARGS --tag $t"; done + - echo "Tag arguments: $TARGS" + + - docker buildx build \ + --cache-from type=registry,ref="$CI_REGISTRY_IMAGE:latest" \ + --build-arg BUILDKIT_INLINE_CACHE=1 \ + --build-arg "BUILD_DATE=$(date +"%Y-%m-%dT%H:%M:%SZ")" \ + --build-arg "BUILD_REF=${CI_COMMIT_SHA}" \ + --build-arg "CRAFTY_VER=${VERSION}" \ + --provenance false \ + $TARGS \ + --platform linux/arm64/v8,linux/amd64 \ --push . + after_script: - - | - docker buildx rm zedBuilder-$CI_JOB_ID && echo "Successfully Stopped builder instance" || echo "Failed to stop builder instance." - docker context rm tls-environment-$CI_JOB_ID || true - echo "Please review multi-arch manifests are present:" - docker buildx imagetools inspect "$CI_REGISTRY_IMAGE${tag}" + - docker buildx rm zedBuilder-$CI_JOB_ID && echo "Successfully Stopped builder instance" || echo "Failed to stop builder instance." + - docker context rm tls-environment-$CI_JOB_ID || true + - echo "Please review multi-arch manifests are present:" + - if [ "$ENVIRONMENT_NAME" = "development" ]; then docker buildx imagetools inspect "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG"; fi + - if [ "$ENVIRONMENT_NAME" = "production" ] && [ -n "$VERSION" ]; then docker buildx imagetools inspect "$CI_REGISTRY_IMAGE:$VERSION"; fi + - if echo "$DOCKER_TAGS" | grep -q "nightly"; then docker buildx imagetools inspect "$CI_REGISTRY_IMAGE:nightly"; fi From 148a548df57ed01aaf3827e29bca2e65465c34fa Mon Sep 17 00:00:00 2001 From: Zedifus Date: Tue, 10 Dec 2024 19:59:56 +0000 Subject: [PATCH 64/74] Omit cache on nightly builds --- .gitlab/docker-build.yml | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/.gitlab/docker-build.yml b/.gitlab/docker-build.yml index 454bc2d2..342927ca 100644 --- a/.gitlab/docker-build.yml +++ b/.gitlab/docker-build.yml @@ -73,16 +73,31 @@ docker-build: - for t in $DOCKER_TAGS; do TARGS="$TARGS --tag $t"; done - echo "Tag arguments: $TARGS" - - docker buildx build \ - --cache-from type=registry,ref="$CI_REGISTRY_IMAGE:latest" \ - --build-arg BUILDKIT_INLINE_CACHE=1 \ - --build-arg "BUILD_DATE=$(date +"%Y-%m-%dT%H:%M:%SZ")" \ - --build-arg "BUILD_REF=${CI_COMMIT_SHA}" \ - --build-arg "CRAFTY_VER=${VERSION}" \ - --provenance false \ - $TARGS \ - --platform linux/arm64/v8,linux/amd64 \ - --push . + # Conditional build command: omit cache if schedule + - | + if [ "$CI_PIPELINE_SOURCE" = "schedule" ]; then + echo "Omitting cache for nightly build." + docker buildx build \ + --build-arg "BUILD_DATE=$(date +"%Y-%m-%dT%H:%M:%SZ")" \ + --build-arg "BUILD_REF=${CI_COMMIT_SHA}" \ + --build-arg "CRAFTY_VER=${VERSION}" \ + --provenance false \ + $TARGS \ + --platform linux/arm64/v8,linux/amd64 \ + --push . + else + echo "Using cache for build." + docker buildx build \ + --cache-from type=registry,ref="$CI_REGISTRY_IMAGE:latest" \ + --build-arg BUILDKIT_INLINE_CACHE=1 \ + --build-arg "BUILD_DATE=$(date +"%Y-%m-%dT%H:%M:%SZ")" \ + --build-arg "BUILD_REF=${CI_COMMIT_SHA}" \ + --build-arg "CRAFTY_VER=${VERSION}" \ + --provenance false \ + $TARGS \ + --platform linux/arm64/v8,linux/amd64 \ + --push . + fi after_script: - docker buildx rm zedBuilder-$CI_JOB_ID && echo "Successfully Stopped builder instance" || echo "Failed to stop builder instance." From a7c370f78261c3ae2500050d3f12805e819500ca Mon Sep 17 00:00:00 2001 From: Zedifus Date: Tue, 10 Dec 2024 20:46:05 +0000 Subject: [PATCH 65/74] Appease Gitlab's ci validator, also cache from dev for normal builds Nightlys omit cache, dev will be merged into master, so caching master from dev shortly after merge makes sense --- .gitlab/docker-build.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitlab/docker-build.yml b/.gitlab/docker-build.yml index 342927ca..af8b9673 100644 --- a/.gitlab/docker-build.yml +++ b/.gitlab/docker-build.yml @@ -52,8 +52,8 @@ docker-build: - docker buildx create --name zedBuilder-$CI_JOB_ID --use tls-environment-$CI_JOB_ID script: - - echo "Running on branch '$CI_COMMIT_BRANCH', environment: $ENVIRONMENT_NAME" - - echo "Crafty Version: $VERSION" + - echo "Running on branch '$CI_COMMIT_BRANCH', environment- $ENVIRONMENT_NAME" + - echo "Crafty Version- $VERSION" # If DOCKER_TAGS is empty (production default branch and not schedule), we set stable tags: # This scenario adds both VERSION and 'latest' tags. @@ -65,13 +65,13 @@ docker-build: arcadiatechnology/crafty-4:latest" fi - - echo "Using the following tags: $DOCKER_TAGS" + - echo "Using the following tags- $DOCKER_TAGS" # Prepare build command # We break DOCKER_TAGS into separate --tag arguments - TARGS="" - for t in $DOCKER_TAGS; do TARGS="$TARGS --tag $t"; done - - echo "Tag arguments: $TARGS" + - echo "Tag arguments- $TARGS" # Conditional build command: omit cache if schedule - | @@ -88,7 +88,7 @@ docker-build: else echo "Using cache for build." docker buildx build \ - --cache-from type=registry,ref="$CI_REGISTRY_IMAGE:latest" \ + --cache-from type=registry,ref="$CI_REGISTRY_IMAGE:dev" \ --build-arg BUILDKIT_INLINE_CACHE=1 \ --build-arg "BUILD_DATE=$(date +"%Y-%m-%dT%H:%M:%SZ")" \ --build-arg "BUILD_REF=${CI_COMMIT_SHA}" \ From 589448a244fe9b7f072418b95f81fcddbfc07c3f Mon Sep 17 00:00:00 2001 From: Zedifus Date: Tue, 10 Dec 2024 20:48:57 +0000 Subject: [PATCH 66/74] Fix windows builds after stage rename --- .gitlab/windows-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab/windows-build.yml b/.gitlab/windows-build.yml index 2dd6fb50..85437715 100644 --- a/.gitlab/windows-build.yml +++ b/.gitlab/windows-build.yml @@ -1,7 +1,7 @@ # yamllint disable rule:line-length --- win-dev-build: - stage: dev-deployment + stage: build-and-deploy tags: - win64 cache: @@ -48,7 +48,7 @@ win-dev-build: - app\classes\**\* win-prod-build: - stage: prod-deployment + stage: build-and-deploy tags: - win64 cache: From 6bb23db3bd6154eee208bc204e131e44c86fa8c5 Mon Sep 17 00:00:00 2001 From: Zedifus Date: Tue, 10 Dec 2024 21:11:28 +0000 Subject: [PATCH 67/74] Exclude other pipeline jobs from nightly schedule --- .gitlab/lint.yml | 12 ++++++++++++ .gitlab/release.yml | 2 ++ .gitlab/windows-build.yml | 4 ++++ 3 files changed, 18 insertions(+) diff --git a/.gitlab/lint.yml b/.gitlab/lint.yml index 5cfae504..db223801 100644 --- a/.gitlab/lint.yml +++ b/.gitlab/lint.yml @@ -9,6 +9,8 @@ yamllint: rules: - if: "$CODE_QUALITY_DISABLED" when: never + - if: $CI_PIPELINE_SOURCE == "schedule" + when: never - if: "$CI_COMMIT_TAG || $CI_COMMIT_BRANCH" script: - yamllint . @@ -22,6 +24,8 @@ jsonlint: rules: - if: "$CODE_QUALITY_DISABLED" when: never + - if: $CI_PIPELINE_SOURCE == "schedule" + when: never - if: "$CI_COMMIT_TAG || $CI_COMMIT_BRANCH" script: - | @@ -37,6 +41,8 @@ black: rules: - if: "$CODE_QUALITY_DISABLED" when: never + - if: $CI_PIPELINE_SOURCE == "schedule" + when: never - if: "$CI_COMMIT_TAG || $CI_COMMIT_BRANCH" script: - black --check --verbose -- . @@ -50,6 +56,8 @@ pylint: rules: - if: "$CODE_QUALITY_DISABLED" when: never + - if: $CI_PIPELINE_SOURCE == "schedule" + when: never - if: "$CI_COMMIT_TAG || $CI_COMMIT_BRANCH" before_script: - apk update @@ -75,6 +83,8 @@ sonarcloud-check: when: never - if: "$CODE_QUALITY_DISABLED" when: never + - if: $CI_PIPELINE_SOURCE == "schedule" + when: never - if: "$CI_COMMIT_TAG || $CI_COMMIT_BRANCH" variables: SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache @@ -94,6 +104,8 @@ sonarcloud-check: # rules: # - if: "$CODE_QUALITY_DISABLED" # when: never +# - if: $CI_PIPELINE_SOURCE == "schedule" +# when: never # - if: "$CI_COMMIT_TAG || $CI_COMMIT_BRANCH" # allow_failure: true # before_script: diff --git a/.gitlab/release.yml b/.gitlab/release.yml index f1ed61da..d9c05824 100644 --- a/.gitlab/release.yml +++ b/.gitlab/release.yml @@ -4,6 +4,8 @@ release: stage: release image: registry.gitlab.com/gitlab-org/release-cli:latest rules: + - if: $CI_PIPELINE_SOURCE == "schedule" + when: never - if: $CI_COMMIT_TAG needs: - job: win-prod-build diff --git a/.gitlab/windows-build.yml b/.gitlab/windows-build.yml index 85437715..a883e115 100644 --- a/.gitlab/windows-build.yml +++ b/.gitlab/windows-build.yml @@ -8,6 +8,8 @@ win-dev-build: paths: - .venv/ rules: + - if: $CI_PIPELINE_SOURCE == "schedule" + when: never - if: "$CI_COMMIT_BRANCH == 'dev'" environment: name: development @@ -55,6 +57,8 @@ win-prod-build: paths: - .venv/ rules: + - if: $CI_PIPELINE_SOURCE == "schedule" + when: never - if: "$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH" - if: $CI_COMMIT_TAG environment: From 8dc4e27db065ed6ea8695214eab196d63109586a Mon Sep 17 00:00:00 2001 From: Zedifus Date: Tue, 10 Dec 2024 21:22:49 +0000 Subject: [PATCH 68/74] Move nightly builds to their own environment --- .gitlab/docker-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab/docker-build.yml b/.gitlab/docker-build.yml index af8b9673..ad83f135 100644 --- a/.gitlab/docker-build.yml +++ b/.gitlab/docker-build.yml @@ -23,7 +23,7 @@ docker-build: # Scheduled nightly builds on main - if: $CI_PIPELINE_SOURCE == "schedule" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH variables: - ENVIRONMENT_NAME: "production" + ENVIRONMENT_NAME: "nightly" DOCKER_TAGS: "$CI_REGISTRY_IMAGE:nightly arcadiatechnology/crafty-4:nightly" environment: @@ -105,4 +105,4 @@ docker-build: - echo "Please review multi-arch manifests are present:" - if [ "$ENVIRONMENT_NAME" = "development" ]; then docker buildx imagetools inspect "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG"; fi - if [ "$ENVIRONMENT_NAME" = "production" ] && [ -n "$VERSION" ]; then docker buildx imagetools inspect "$CI_REGISTRY_IMAGE:$VERSION"; fi - - if echo "$DOCKER_TAGS" | grep -q "nightly"; then docker buildx imagetools inspect "$CI_REGISTRY_IMAGE:nightly"; fi + - if [ "$ENVIRONMENT_NAME" = "nightly" ]; then docker buildx imagetools inspect "$CI_REGISTRY_IMAGE:nightly"; fi From 656c967151d02340d4f1452f2e27b8a0b9bb355e Mon Sep 17 00:00:00 2001 From: Zedifus Date: Tue, 10 Dec 2024 21:34:36 +0000 Subject: [PATCH 69/74] Update changelog !813 !812 --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 477fb3fa..447cff09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,13 @@ TBD ### Refactor - Refactor and standardize all JSON validator errors returning human readable translations ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/786)) +- Improve docker-build CI/CD, supporting nightly builds ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/813)) ### Bug fixes - Bump requests to resolve yank for CVE-2024-35195 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/808)) ### Tweaks -TBD +- Bump Docker base image `22.04` -> `24.04` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/812)) +- Bump python pip `2.0.3` -> `24.3.1` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/812)) +- Bump python setuptools `50.3.2` -> `75.6.0` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/812)) ### Lang - Weblate Translation Platform Integration - Remove incomplete labels from translation files to better support new translation workflow ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/810)) From 8d6fe95393e30ceb2d3fd9bec0dd247a7bc2a78e Mon Sep 17 00:00:00 2001 From: Zedifus Date: Tue, 10 Dec 2024 22:35:39 +0000 Subject: [PATCH 70/74] Update changelog !811 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 447cff09..9a725bcc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ TBD ### Lang - Weblate Translation Platform Integration - Remove incomplete labels from translation files to better support new translation workflow ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/810)) +- New langs added `ja_JP`, `ko_KR` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/811))

## --- [4.4.4] - 2024/10/03 From 6d07ad651120d2fec79eddf330b09d42028ca34c Mon Sep 17 00:00:00 2001 From: Zedifus Date: Tue, 10 Dec 2024 22:39:56 +0000 Subject: [PATCH 71/74] Bump tornado for CVE-2024-52804 https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-52804 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7bc5ae87..b01144c8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,7 +15,7 @@ pyjwt==2.8.0 PyYAML==6.0.1 requests==2.32.3 termcolor==1.1 -tornado==6.4.1 +tornado==6.4.2 tzlocal==5.1 jsonschema==4.19.1 orjson==3.9.15 From 284a177580235ca8a761f90e70738628fdaf4de1 Mon Sep 17 00:00:00 2001 From: Zedifus Date: Tue, 10 Dec 2024 22:44:10 +0000 Subject: [PATCH 72/74] Update changelog !814 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a725bcc..68261b23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ TBD - Bump Docker base image `22.04` -> `24.04` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/812)) - Bump python pip `2.0.3` -> `24.3.1` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/812)) - Bump python setuptools `50.3.2` -> `75.6.0` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/812)) +- Bump tornado for CVE-2024-52804 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/814)) ### Lang - Weblate Translation Platform Integration - Remove incomplete labels from translation files to better support new translation workflow ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/810)) From f0471309a59213d596a12c7ecccee27dd8566316 Mon Sep 17 00:00:00 2001 From: Zedifus Date: Sun, 19 Jan 2025 17:22:31 +0000 Subject: [PATCH 73/74] Update changelog !799 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68261b23..549abca5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ TBD - Improve docker-build CI/CD, supporting nightly builds ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/813)) ### Bug fixes - Bump requests to resolve yank for CVE-2024-35195 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/808)) +- Better handle malformed mcping data ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/799)) ### Tweaks - Bump Docker base image `22.04` -> `24.04` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/812)) - Bump python pip `2.0.3` -> `24.3.1` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/812)) From 0b20c4f9db325bcdd9157064914a0fa3b2030b56 Mon Sep 17 00:00:00 2001 From: Zedifus Date: Sun, 19 Jan 2025 17:42:14 +0000 Subject: [PATCH 74/74] Update changelog !805 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 549abca5..25a5b3e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ TBD - Bump requests to resolve yank for CVE-2024-35195 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/808)) - Better handle malformed mcping data ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/799)) ### Tweaks +- Remove EXIF image data on app Background Photos ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/805)) - Bump Docker base image `22.04` -> `24.04` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/812)) - Bump python pip `2.0.3` -> `24.3.1` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/812)) - Bump python setuptools `50.3.2` -> `75.6.0` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/812))