diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml index 0dcafa7a44..bb90188c4c 100644 --- a/.github/workflows/lock.yml +++ b/.github/workflows/lock.yml @@ -14,7 +14,7 @@ jobs: lock: runs-on: ubuntu-latest steps: - - uses: dessant/lock-threads@v3 + - uses: dessant/lock-threads@v4 with: github-token: ${{ github.token }} issue-inactive-days: 14 diff --git a/frappe/core/doctype/communication/email.py b/frappe/core/doctype/communication/email.py index c5585fd463..fbb34bc7e6 100755 --- a/frappe/core/doctype/communication/email.py +++ b/frappe/core/doctype/communication/email.py @@ -92,7 +92,7 @@ def make( send_me_a_copy=cint(send_me_a_copy), cc=cc, bcc=bcc, - read_receipt=read_receipt, + read_receipt=cint(read_receipt), print_letterhead=print_letterhead, email_template=email_template, communication_type=communication_type, diff --git a/frappe/core/doctype/rq_job/test_rq_job.py b/frappe/core/doctype/rq_job/test_rq_job.py index 654cdcd21f..2fbefda056 100644 --- a/frappe/core/doctype/rq_job/test_rq_job.py +++ b/frappe/core/doctype/rq_job/test_rq_job.py @@ -38,7 +38,6 @@ class TestRQJob(FrappeTestCase): "name": job.id, "queue": "short", "job_name": self.BG_JOB, - "status": "queued", "exc_info": None, }, rq_job, diff --git a/frappe/core/doctype/system_settings/system_settings.json b/frappe/core/doctype/system_settings/system_settings.json index 57e2b1a1be..f9d7adceef 100644 --- a/frappe/core/doctype/system_settings/system_settings.json +++ b/frappe/core/doctype/system_settings/system_settings.json @@ -33,7 +33,6 @@ "allow_guests_to_upload_files", "security", "session_expiry", - "session_expiry_mobile", "document_share_key_expiry", "column_break_13", "deny_multiple_sessions", @@ -211,13 +210,6 @@ "fieldtype": "Data", "label": "Session Expiry (idle timeout)" }, - { - "default": "720:00", - "description": "In Hours", - "fieldname": "session_expiry_mobile", - "fieldtype": "Data", - "label": "Session Expiry Mobile" - }, { "fieldname": "column_break_13", "fieldtype": "Column Break" @@ -517,7 +509,7 @@ "icon": "fa fa-cog", "issingle": 1, "links": [], - "modified": "2022-11-20 17:57:05.099512", + "modified": "2022-11-28 17:57:05.099512", "modified_by": "Administrator", "module": "Core", "name": "System Settings", diff --git a/frappe/core/doctype/system_settings/system_settings.py b/frappe/core/doctype/system_settings/system_settings.py index 1fc27ca114..0f7a7f0819 100644 --- a/frappe/core/doctype/system_settings/system_settings.py +++ b/frappe/core/doctype/system_settings/system_settings.py @@ -20,11 +20,10 @@ class SystemSettings(Document): elif not enable_password_policy: self.minimum_password_score = "" - for key in ("session_expiry", "session_expiry_mobile"): - if self.get(key): - parts = self.get(key).split(":") - if len(parts) != 2 or not (cint(parts[0]) or cint(parts[1])): - frappe.throw(_("Session Expiry must be in format {0}").format("hh:mm")) + if self.session_expiry: + parts = self.session_expiry.split(":") + if len(parts) != 2 or not (cint(parts[0]) or cint(parts[1])): + frappe.throw(_("Session Expiry must be in format {0}").format("hh:mm")) if self.enable_two_factor_auth: if self.two_factor_method == "SMS": diff --git a/frappe/database/mariadb/framework_mariadb.sql b/frappe/database/mariadb/framework_mariadb.sql index 70b37dfcf8..efeeaaf935 100644 --- a/frappe/database/mariadb/framework_mariadb.sql +++ b/frappe/database/mariadb/framework_mariadb.sql @@ -252,7 +252,6 @@ CREATE TABLE `tabSessions` ( `sessiondata` longtext, `ipaddress` varchar(16) DEFAULT NULL, `lastupdate` datetime(6) DEFAULT NULL, - `device` varchar(255) DEFAULT 'desktop', `status` varchar(20) DEFAULT NULL, KEY `sid` (`sid`) ) ENGINE=InnoDB ROW_FORMAT=DYNAMIC CHARACTER SET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/frappe/database/mariadb/setup_db.py b/frappe/database/mariadb/setup_db.py index 6c68a7692c..67f809abf7 100644 --- a/frappe/database/mariadb/setup_db.py +++ b/frappe/database/mariadb/setup_db.py @@ -1,17 +1,11 @@ import os +import click + import frappe from frappe.database.db_manager import DbManager -expected_settings_10_2_earlier = { - "innodb_file_format": "Barracuda", - "innodb_file_per_table": "ON", - "innodb_large_prefix": "ON", - "character_set_server": "utf8mb4", - "collation_server": "utf8mb4_unicode_ci", -} - -expected_settings_10_3_later = { +REQUIRED_MARIADB_CONFIG = { "character_set_server": "utf8mb4", "collation_server": "utf8mb4_unicode_ci", } @@ -109,16 +103,13 @@ def import_db_from_sql(source_sql=None, verbose=False): def check_database_settings(): - mariadb_variables = get_mariadb_variables() - versions = get_mariadb_version(mariadb_variables.get("version")) - if versions[0] <= "10.2": - expected_variables = expected_settings_10_2_earlier - else: - expected_variables = expected_settings_10_3_later + + check_compatible_versions() # Check each expected value vs. actuals: + mariadb_variables = get_mariadb_variables() result = True - for key, expected_value in expected_variables.items(): + for key, expected_value in REQUIRED_MARIADB_CONFIG.items(): if mariadb_variables.get(key) != expected_value: print( "For key %s. Expected value %s, found value %s" @@ -130,8 +121,7 @@ def check_database_settings(): print( ( "{sep2}Creation of your site - {site} failed because MariaDB is not properly {sep}" - "configured. If using version 10.2.x or earlier, make sure you use the {sep}" - "the Barracuda storage engine.{sep2}" + "configured.{sep2}" "Please verify the above settings in MariaDB's my.cnf. Restart MariaDB.{sep}" "And then run `bench new-site {site}` again.{sep2}" ).format(site=frappe.local.site, sep2="\n\n", sep="\n") @@ -140,6 +130,28 @@ def check_database_settings(): return result +def check_compatible_versions(): + try: + version = get_mariadb_version() + version_tuple = tuple(int(v) for v in version[0].split(".")) + + if version_tuple < (10, 6): + click.secho( + f"Warning: MariaDB version {version} is less than 10.6 which is not supported by Frappe", + fg="yellow", + ) + elif version_tuple >= (10, 9): + click.secho( + f"Warning: MariaDB version {version} is more than 10.8 which is not yet tested with Frappe Framework.", + fg="yellow", + ) + except Exception: + click.secho( + "MariaDB version compatibility checks failed, make sure you're running a supported version.", + fg="yellow", + ) + + def get_root_connection(root_login, root_password): import getpass diff --git a/frappe/database/postgres/framework_postgres.sql b/frappe/database/postgres/framework_postgres.sql index 7ce3cecff8..37605be0f6 100644 --- a/frappe/database/postgres/framework_postgres.sql +++ b/frappe/database/postgres/framework_postgres.sql @@ -256,7 +256,6 @@ CREATE TABLE "tabSessions" ( "sessiondata" text, "ipaddress" varchar(16) DEFAULT NULL, "lastupdate" timestamp(6) DEFAULT NULL, - "device" varchar(255) DEFAULT 'desktop', "status" varchar(20) DEFAULT NULL ); diff --git a/frappe/defaults.py b/frappe/defaults.py index 744a3fad5d..fcfef0b2fc 100644 --- a/frappe/defaults.py +++ b/frappe/defaults.py @@ -241,4 +241,6 @@ def get_defaults_for(parent="__default"): def _clear_cache(parent): + if frappe.flags.in_install: + return frappe.clear_cache(user=parent if parent not in common_default_keys else None) diff --git a/frappe/desk/form/meta.py b/frappe/desk/form/meta.py index ee975c8326..b5b58ebfa3 100644 --- a/frappe/desk/form/meta.py +++ b/frappe/desk/form/meta.py @@ -156,6 +156,9 @@ class FormMeta(Meta): list_script = "" form_script = "" for script in client_scripts: + if not script.script: + continue + if script.view == "List": list_script += f""" // {script.name} @@ -163,7 +166,7 @@ class FormMeta(Meta): """ - if script.view == "Form": + elif script.view == "Form": form_script += f""" // {script.name} {script.script} diff --git a/frappe/desk/query_report.py b/frappe/desk/query_report.py index a1e8a9368f..b4a51ffaf3 100644 --- a/frappe/desk/query_report.py +++ b/frappe/desk/query_report.py @@ -319,7 +319,7 @@ def format_duration_fields(data: frappe._dict) -> None: continue for row in data.result: - index = col.fieldname if isinstance(row, dict) else i + index = col.get("fieldname") if isinstance(row, dict) else i if row[index]: row[index] = format_duration(row[index]) diff --git a/frappe/email/receive.py b/frappe/email/receive.py index 0cf01083f7..7028dc1f11 100644 --- a/frappe/email/receive.py +++ b/frappe/email/receive.py @@ -987,10 +987,10 @@ class TimerMixin: self.sock.settimeout(self.timeout / 5.0) def _getline(self, *args, **kwargs): - start_time = time.time() + start_time = time.monotonic() ret = self._super._getline(self, *args, **kwargs) - self.elapsed_time += time.time() - start_time + self.elapsed_time += time.monotonic() - start_time if self.timeout and self.elapsed_time > self.timeout: raise EmailTimeoutError diff --git a/frappe/geo/doctype/country/country.py b/frappe/geo/doctype/country/country.py index f6be7a078d..8b1ec1364f 100644 --- a/frappe/geo/doctype/country/country.py +++ b/frappe/geo/doctype/country/country.py @@ -1,8 +1,63 @@ # Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE -from frappe.model.document import Document +import frappe +from frappe.model.document import Document, bulk_insert class Country(Document): + # NOTE: During installation country docs are bulk inserted. pass + + +def import_country_and_currency(): + from frappe.geo.doctype.currency.currency import enable_default_currencies + + countries, currencies = get_countries_and_currencies() + + bulk_insert("Country", countries, ignore_duplicates=True) + bulk_insert("Currency", currencies, ignore_duplicates=True) + + enable_default_currencies() + + +def get_countries_and_currencies(): + from frappe.geo.country_info import get_all as get_geo_data + + data = get_geo_data() + + countries = [] + currencies = [] + + added_currencies = set() + + for name, country in data.items(): + country = frappe._dict(country) + countries.append( + frappe.get_doc( + doctype="Country", + name=name, + country_name=name, + code=country.code, + date_format=country.date_format or "dd-mm-yyyy", + time_format=country.time_format or "HH:mm:ss", + time_zones="\n".join(country.timezones or []), + ) + ) + if country.currency and country.currency not in added_currencies: + added_currencies.add(country.currency) + + currencies.append( + frappe.get_doc( + doctype="Currency", + name=country.currency, + currency_name=country.currency, + fraction=country.currency_fraction, + symbol=country.currency_symbol, + fraction_units=country.currency_fraction_units, + smallest_currency_fraction_value=country.smallest_currency_fraction_value, + number_format=country.number_format, + ) + ) + + return countries, currencies diff --git a/frappe/geo/doctype/country/test_country.py b/frappe/geo/doctype/country/test_country.py index ecc2fb6863..cf4590aabc 100644 --- a/frappe/geo/doctype/country/test_country.py +++ b/frappe/geo/doctype/country/test_country.py @@ -2,5 +2,52 @@ # License: MIT. See LICENSE import frappe +from frappe.geo.doctype.country.country import ( + get_countries_and_currencies, + import_country_and_currency, +) +from frappe.geo.doctype.currency.currency import enable_default_currencies +from frappe.tests.utils import FrappeTestCase test_records = frappe.get_test_records("Country") + + +def get_table_snapshot(doctype): + data = frappe.db.sql(f"select * from `tab{doctype}` order by name", as_dict=True) + + inconsequential_keys = ["modified", "creation"] + for row in data: + for key in inconsequential_keys: + row.pop(key, None) + return data + + +class TestCountry(FrappeTestCase): + def test_bulk_insert_correctness(self): + def clear_tables(): + frappe.db.delete("Currency") + frappe.db.delete("Country") + + # Clear data + clear_tables() + + # Reimport and verify same results + import_country_and_currency() + + countries_before = get_table_snapshot("Country") + currencies_before = get_table_snapshot("Currency") + + clear_tables() + + countries, currencies = get_countries_and_currencies() + for country in countries: + country.db_insert(ignore_if_duplicate=True) + for currency in currencies: + currency.db_insert(ignore_if_duplicate=True) + enable_default_currencies() + + countries_after = get_table_snapshot("Country") + currencies_after = get_table_snapshot("Currency") + + self.assertEqual(countries_before, countries_after) + self.assertEqual(currencies_before, currencies_after) diff --git a/frappe/geo/doctype/currency/currency.py b/frappe/geo/doctype/currency/currency.py index 93bcc063f8..51317e8771 100644 --- a/frappe/geo/doctype/currency/currency.py +++ b/frappe/geo/doctype/currency/currency.py @@ -4,8 +4,14 @@ import frappe from frappe.model.document import Document +DEFAULT_ENABLED_CURRENCIES = ("INR", "USD", "GBP", "EUR", "AED", "AUD", "JPY", "CNY", "CHF") + class Currency(Document): + # NOTE: During installation country docs are bulk inserted. def validate(self): - if not frappe.flags.in_install_app: - frappe.clear_cache() + frappe.clear_cache() + + +def enable_default_currencies(): + frappe.db.set_value("Currency", {"name": ("in", DEFAULT_ENABLED_CURRENCIES)}, "enabled", 1) diff --git a/frappe/installer.py b/frappe/installer.py index 0cd9b32063..e78112df19 100644 --- a/frappe/installer.py +++ b/frappe/installer.py @@ -16,6 +16,7 @@ import frappe from frappe.defaults import _clear_cache from frappe.utils import cint, is_git_url from frappe.utils.dashboard import sync_dashboards +from frappe.utils.synchronization import filelock def _is_scheduler_enabled() -> bool: @@ -540,8 +541,11 @@ def make_site_config( f.write(json.dumps(site_config, indent=1, sort_keys=True)) +@filelock("site_config") def update_site_config(key, value, validate=True, site_config_path=None): """Update a value in site_config""" + from frappe.utils.synchronization import filelock + if not site_config_path: site_config_path = get_site_config_path() diff --git a/frappe/integrations/doctype/google_drive/google_drive.json b/frappe/integrations/doctype/google_drive/google_drive.json index 6742d9ee5d..592281be68 100644 --- a/frappe/integrations/doctype/google_drive/google_drive.json +++ b/frappe/integrations/doctype/google_drive/google_drive.json @@ -1,4 +1,5 @@ { + "actions": [], "creation": "2019-08-13 17:24:05.470876", "doctype": "DocType", "engine": "InnoDB", @@ -100,7 +101,8 @@ } ], "issingle": 1, - "modified": "2020-09-18 17:26:09.703215", + "links": [], + "modified": "2022-12-04 15:53:58.702389", "modified_by": "Administrator", "module": "Integrations", "name": "Google Drive", @@ -115,19 +117,10 @@ "role": "System Manager", "share": 1, "write": 1 - }, - { - "create": 1, - "delete": 1, - "email": 1, - "print": 1, - "read": 1, - "role": "All", - "share": 1, - "write": 1 } ], "sort_field": "modified", "sort_order": "ASC", + "states": [], "track_changes": 1 } \ No newline at end of file diff --git a/frappe/integrations/doctype/ldap_settings/ldap_settings.json b/frappe/integrations/doctype/ldap_settings/ldap_settings.json index f5472a5097..b8f73cebed 100644 --- a/frappe/integrations/doctype/ldap_settings/ldap_settings.json +++ b/frappe/integrations/doctype/ldap_settings/ldap_settings.json @@ -24,6 +24,7 @@ "ldap_email_field", "ldap_username_field", "ldap_first_name_field", + "do_not_create_new_user", "column_break_19", "ldap_middle_name_field", "ldap_last_name_field", @@ -289,12 +290,19 @@ "fieldname": "section_break_40", "fieldtype": "Section Break", "hide_border": 1 + }, + { + "default": "0", + "description": "Do not create new user if user with email does not exist in the system", + "fieldname": "do_not_create_new_user", + "fieldtype": "Check", + "label": "Do Not Create New User " } ], "in_create": 1, "issingle": 1, "links": [], - "modified": "2022-07-07 16:51:46.230793", + "modified": "2022-12-05 21:52:31.146035", "modified_by": "Administrator", "module": "Integrations", "name": "LDAP Settings", diff --git a/frappe/integrations/doctype/ldap_settings/ldap_settings.py b/frappe/integrations/doctype/ldap_settings/ldap_settings.py index 48e1f12bdb..094c440672 100644 --- a/frappe/integrations/doctype/ldap_settings/ldap_settings.py +++ b/frappe/integrations/doctype/ldap_settings/ldap_settings.py @@ -172,7 +172,7 @@ class LDAPSettings(Document): if frappe.db.exists("User", user_data["email"]): user = frappe.get_doc("User", user_data["email"]) LDAPSettings.update_user_fields(user=user, user_data=user_data) - else: + elif not self.do_not_create_new_user: doc = user_data | { "doctype": "User", "send_welcome_email": 0, @@ -181,6 +181,12 @@ class LDAPSettings(Document): } user = frappe.get_doc(doc) user.insert(ignore_permissions=True) + else: + frappe.throw( + _( + "User with email: {0} does not exist in the system. Please ask 'System Administrator' to create the user for you." + ).format(user_data["email"]) + ) if self.default_user_type == "System User": role = self.default_role @@ -324,11 +330,21 @@ class LDAPSettings(Document): def convert_ldap_entry_to_dict(self, user_entry: Entry): # support multiple email values - email = user_entry[self.ldap_email_field] + email = user_entry[self.ldap_email_field].value + + if isinstance(email, list): + # check if any of the email in the list already exist + for e in email: + if frappe.db.exists("User", e): + email = e + break + else: + # if none of the email exist, use the first email + email = email[0] data = { "username": user_entry[self.ldap_username_field].value, - "email": str(email.value[0] if isinstance(email.value, list) else email.value), + "email": email, "first_name": user_entry[self.ldap_first_name_field].value, } diff --git a/frappe/model/document.py b/frappe/model/document.py index c1d4575ae7..e6f90b2260 100644 --- a/frappe/model/document.py +++ b/frappe/model/document.py @@ -708,17 +708,16 @@ class Document(BaseDocument): d.reset_values_if_no_permlevel_access(has_access_to, high_permlevel_fields) def get_permlevel_access(self, permission_type="write"): - if not hasattr(self, "_has_access_to"): - self._has_access_to = {} - - self._has_access_to[permission_type] = [] + allowed_permlevels = [] roles = frappe.get_roles() - for perm in self.get_permissions(): - if perm.role in roles and perm.get(permission_type): - if perm.permlevel not in self._has_access_to[permission_type]: - self._has_access_to[permission_type].append(perm.permlevel) - return self._has_access_to[permission_type] + for perm in self.get_permissions(): + if ( + perm.role in roles and perm.get(permission_type) and perm.permlevel not in allowed_permlevels + ): + allowed_permlevels.append(perm.permlevel) + + return allowed_permlevels def has_permlevel_access_to(self, fieldname, df=None, permission_type="read"): if not df: @@ -1506,16 +1505,18 @@ class Document(BaseDocument): if self in frappe.local.locked_documents: frappe.local.locked_documents.remove(self) - # validation helpers - def validate_from_to_dates(self, from_date_field, to_date_field): - """ - Generic validation to verify date sequence - """ - if date_diff(self.get(to_date_field), self.get(from_date_field)) < 0: + def validate_from_to_dates(self, from_date_field: str, to_date_field: str) -> None: + """Validate that the value of `from_date_field` is not later than the value of `to_date_field`.""" + from_date = self.get(from_date_field) + to_date = self.get(to_date_field) + if not (from_date and to_date): + return + + if date_diff(to_date, from_date) < 0: frappe.throw( _("{0} must be after {1}").format( - frappe.bold(self.meta.get_label(to_date_field)), - frappe.bold(self.meta.get_label(from_date_field)), + frappe.bold(_(self.meta.get_label(to_date_field))), + frappe.bold(_(self.meta.get_label(from_date_field))), ), frappe.exceptions.InvalidDates, ) diff --git a/frappe/model/meta.py b/frappe/model/meta.py index ce30011d02..d9d18e98ce 100644 --- a/frappe/model/meta.py +++ b/frappe/model/meta.py @@ -259,14 +259,13 @@ class Meta(Document): def get_label(self, fieldname): """Get label of the given fieldname""" - if df := self.get_field(fieldname): return df.label if fieldname in DEFAULT_FIELD_LABELS: return DEFAULT_FIELD_LABELS[fieldname]() - return _("No Label") + return "No Label" def get_options(self, fieldname): return self.get_field(fieldname).options diff --git a/frappe/modules/patch_handler.py b/frappe/modules/patch_handler.py index 00d0e8167d..15144a1630 100644 --- a/frappe/modules/patch_handler.py +++ b/frappe/modules/patch_handler.py @@ -173,7 +173,7 @@ def execute_patch(patchmodule, method=None, methodargs=None): f"Executing {patchmodule or methodargs} in {frappe.local.site} ({frappe.db.cur_db_name}){docstring}" ) - start_time = time.time() + start_time = time.monotonic() frappe.db.begin() frappe.db.auto_commit_on_many_writes = 0 try: @@ -197,7 +197,7 @@ def execute_patch(patchmodule, method=None, methodargs=None): else: frappe.db.commit() - end_time = time.time() + end_time = time.monotonic() _patch_mode(False) print(f"Success: Done in {round(end_time - start_time, 3)}s") diff --git a/frappe/parallel_test_runner.py b/frappe/parallel_test_runner.py index 905296c5f3..b7c3966df1 100644 --- a/frappe/parallel_test_runner.py +++ b/frappe/parallel_test_runner.py @@ -42,7 +42,7 @@ class ParallelTestRunner: self.before_test_setup() def before_test_setup(self): - start_time = time.time() + start_time = time.monotonic() for fn in frappe.get_hooks("before_tests", app_name=self.app): frappe.get_attr(fn)() @@ -52,7 +52,7 @@ class ParallelTestRunner: for doctype in test_module.global_test_dependencies: make_test_records(doctype, commit=True) - elapsed = time.time() - start_time + elapsed = time.monotonic() - start_time elapsed = click.style(f" ({elapsed:.03}s)", fg="red") click.echo(f"Before Test {elapsed}") @@ -162,7 +162,7 @@ def split_by_weight(work, weights, chunk_count): class ParallelTestResult(unittest.TextTestResult): def startTest(self, test): self.tb_locals = True - self._started_at = time.time() + self._started_at = time.monotonic() super(unittest.TextTestResult, self).startTest(test) test_class = unittest.util.strclass(test.__class__) if not hasattr(self, "current_test_class") or self.current_test_class != test_class: @@ -174,7 +174,7 @@ class ParallelTestResult(unittest.TextTestResult): def addSuccess(self, test): super(unittest.TextTestResult, self).addSuccess(test) - elapsed = time.time() - self._started_at + elapsed = time.monotonic() - self._started_at threshold_passed = elapsed >= SLOW_TEST_THRESHOLD elapsed = click.style(f" ({elapsed:.03}s)", fg="red") if threshold_passed else "" click.echo(f" {click.style(' ✔ ', fg='green')} {self.getTestMethodName(test)}{elapsed}") diff --git a/frappe/permissions.py b/frappe/permissions.py index 0307952c62..2997165dc9 100644 --- a/frappe/permissions.py +++ b/frappe/permissions.py @@ -427,7 +427,9 @@ def get_roles(user=None, with_standard=True): table = DocType("Has Role") roles = ( frappe.qb.from_(table) - .where((table.parent == user) & (table.role.notin(["All", "Guest"]))) + .where( + (table.parenttype == "User") & (table.parent == user) & (table.role.notin(["All", "Guest"])) + ) .select(table.role) .run(pluck=True) ) diff --git a/frappe/public/js/frappe/form/layout.js b/frappe/public/js/frappe/form/layout.js index a4647af480..e070e1db0b 100644 --- a/frappe/public/js/frappe/form/layout.js +++ b/frappe/public/js/frappe/form/layout.js @@ -482,10 +482,37 @@ frappe.ui.form.Layout = class Layout { } setup_events() { + let last_scroll = 0; + let tabs_list = $(".form-tabs-list"); + let tabs_content = this.tabs_content[0]; + if (!tabs_list.length) return; + + $(window).scroll( + frappe.utils.throttle(() => { + let current_scroll = document.documentElement.scrollTop; + if (current_scroll > 0 && last_scroll <= current_scroll) { + tabs_list.removeClass("form-tabs-sticky-down"); + tabs_list.addClass("form-tabs-sticky-up"); + } else { + tabs_list.removeClass("form-tabs-sticky-up"); + tabs_list.addClass("form-tabs-sticky-down"); + } + last_scroll = current_scroll; + }, 500) + ); + this.tab_link_container.off("click").on("click", ".nav-link", (e) => { e.preventDefault(); e.stopImmediatePropagation(); $(e.currentTarget).tab("show"); + if (tabs_content.getBoundingClientRect().top < 100) { + tabs_content.scrollIntoView(); + setTimeout(() => { + $(".page-head").css("top", "-15px"); + $(".form-tabs-list").removeClass("form-tabs-sticky-down"); + $(".form-tabs-list").addClass("form-tabs-sticky-up"); + }, 3); + } }); } diff --git a/frappe/public/js/frappe/model/model.js b/frappe/public/js/frappe/model/model.js index 4aa90a0efb..18acf00ad3 100644 --- a/frappe/public/js/frappe/model/model.js +++ b/frappe/public/js/frappe/model/model.js @@ -699,6 +699,8 @@ $.extend(frappe.model, { doctype: doctype, name: docname, }, + freeze: true, + freeze_message: __("Deleting {0}...", [title]), callback: function (r, rt) { if (!r.exc) { frappe.utils.play_sound("delete"); diff --git a/frappe/public/js/frappe/ui/page.js b/frappe/public/js/frappe/ui/page.js index 2cb4f41038..b0df2d60fe 100644 --- a/frappe/public/js/frappe/ui/page.js +++ b/frappe/public/js/frappe/ui/page.js @@ -47,8 +47,7 @@ frappe.ui.Page = class Page { setup_scroll_handler() { let last_scroll = 0; - window.addEventListener( - "scroll", + $(window).scroll( frappe.utils.throttle(() => { $(".page-head").toggleClass("drop-shadow", !!document.documentElement.scrollTop); let current_scroll = document.documentElement.scrollTop; @@ -58,8 +57,7 @@ frappe.ui.Page = class Page { $(".page-head").css("top", "var(--navbar-height)"); } last_scroll = current_scroll; - }), - 500 + }, 500) ); } diff --git a/frappe/public/js/frappe/ui/toolbar/fuzzy_match.js b/frappe/public/js/frappe/ui/toolbar/fuzzy_match.js index 765377a0b4..9f86b03744 100644 --- a/frappe/public/js/frappe/ui/toolbar/fuzzy_match.js +++ b/frappe/public/js/frappe/ui/toolbar/fuzzy_match.js @@ -14,7 +14,7 @@ // J�rgen Tjern� - async helper // Anurag Awasthi - updated to 0.2.0 -const SEQUENTIAL_BONUS = 15; // bonus for adjacent matches +const SEQUENTIAL_BONUS = 25; // bonus for adjacent matches const SEPARATOR_BONUS = 30; // bonus if match occurs after a separator const CAMEL_BONUS = 30; // bonus if match is uppercase and prev is lower const FIRST_LETTER_BONUS = 15; // bonus if the first letter is matched diff --git a/frappe/public/js/frappe/web_form/web_form.js b/frappe/public/js/frappe/web_form/web_form.js index 52d417f025..980df7129b 100644 --- a/frappe/public/js/frappe/web_form/web_form.js +++ b/frappe/public/js/frappe/web_form/web_form.js @@ -379,7 +379,6 @@ export default class WebForm extends frappe.ui.FieldGroup { args: { data: this.doc, web_form: this.name, - docname: this.doc.name, for_payment, }, callback: (response) => { diff --git a/frappe/public/scss/desk/form.scss b/frappe/public/scss/desk/form.scss index 655c0a1539..183c4b9033 100644 --- a/frappe/public/scss/desk/form.scss +++ b/frappe/public/scss/desk/form.scss @@ -319,8 +319,13 @@ } .form-tabs-list { + position: sticky; + background-color: var(--card-bg); + z-index: 5; + transition: 0.5s top; padding-left: var(--padding-xs); - border-bottom: 1px solid var(--border-color); + border-bottom: 2px solid var(--border-color); + border-radius: var(--border-radius-md) var(--border-radius-md) 0 0; .form-tabs { .nav-item { @@ -338,6 +343,15 @@ } } } +.form-tab-content { + scroll-margin-top: calc(var(--navbar-height) + 52px); +} +.form-tabs-sticky-up { + top: calc(var(--navbar-height) - 1px); +} +.form-tabs-sticky-down { + top: calc(var(--navbar-height) + var(--page-head-height) - 1px); +} .progress-area { padding-top: var(--padding-md); diff --git a/frappe/query_builder/docs.md b/frappe/query_builder/docs.md new file mode 100644 index 0000000000..c1f170b3d4 --- /dev/null +++ b/frappe/query_builder/docs.md @@ -0,0 +1,117 @@ +# This documentation is added for query builder and related files. + +## Related Files + +- [builder](./builder.py) +- [custom](./custom.py) +- [functions](./functions.py) +- [terms](./terms.py) +- [query](../database/query.py) + +### Builder + +Database specefic classes are declared which are then selected during init to give either postgres or mariadb dialects. + +### Functions and Custom + +These file handle any custom function which needs to be either added or handled sperately by the different dialects which are not supported yet by pypika directly. + +### Terms + +The inherent terms or specefic classes of pypika builder are handled and declared here all the parameterization goes through this module (custom parameterization is also implemeted here). + +### Raw Query Generation Examples + +Check out some examples [here](https://frappeframework.com/docs/v14/user/en/api/query-builder) + +

Query

+ +## Goal + +```sql +select `name` from `tabUser` +``` + +## There are 3 major ways to reach this goal + +### 1. Direct SQL (Boring / Unsafe / inconsistent) + +```python +frappe.db.sql("select `name` from `tabUser`") +``` + +### 2. SQL through direct Query Builder objects + +```python +from frappe.query_builder import Field + +frappe.qb.from_("User").select(Field("name")) + +``` + +### 3. Through the database API (Which performs the second method under the hood) + +```python +frappe.db.get_values("User", fieldname="name", filters={}) +``` + +This module is used to support the 3rd way of query generation in frappe. +The database module is completely powered by this query module. +This module is also where the query `Engine` resides which is the class responsible for the handling of various filter & field notations. + +- Interating with the existing Database API. + - The old database API was running on raw sql generation in order to bridge the gap between the added new support and raw sql strings this intermediate module was added. + +This module supports almost all the features present in db_query which powers `frappe.get_all` and `frappe.get_list` + +Supporting all the features with the previous filter notations and the field notations few features were added -: + +1. Dict Query + + - To support this + + ```python + frappe.db.get_values("ToDo", fieldname="name", filters={"description": "Something Random"}) + ``` + + and many other possible caveats to the dict representation such as + + ```python + frappe.db.get_values("User", fieldname="name", + filters={"name": ("like", "admin%")}) + + frappe.db.get_values("ToDo", fieldname="name", filters={"description": ("in", ["somso%", "someome"])}) + ``` + +2. Misc Query + + - To support this + + ```python + frappe.db.get_values("ToDo", fieldname="name", filters=["description", "=", "someone"]) + ``` + + Along with other possible list filter use cases including implicit joins + +3. Criterion Query + + - To support Inherent Query Builder objects + + ```python + from frappe.query_builder import Field + + frappe.db.get_values("User", fieldname="name", filters=Field("name") == "Administrator") + + ``` + + and all the pypika filters and functions. + +## Things to be implemented in the `Engine` + +### 1. Support for Permissions + +As of now query builder has no concept of permissions and moving towards a singular database API this needs to be added in the `Engine`. + +### 2. Implementing the missing features which are present in `frappe.get_list` and `frappe.get_all` (do we even need so much magic?) + +Moving to a singular Database API (database.py + db_query.py) all the support present in `get_list` and `get_all` needs to be present in the new `Engine` as well however this creates alot of security cracks, so moving the a *new and more restrictive version* of the database API with backward compatibility perhaps would be the right way to go? diff --git a/frappe/recorder.py b/frappe/recorder.py index 6df3077fa5..b00f15c6b5 100644 --- a/frappe/recorder.py +++ b/frappe/recorder.py @@ -20,9 +20,9 @@ TRACEBACK_PATH_PATTERN = re.compile(".*/apps/") def sql(*args, **kwargs): - start_time = time.time() + start_time = time.monotonic() result = frappe.db._sql(*args, **kwargs) - end_time = time.time() + end_time = time.monotonic() stack = list(get_current_stack_frames()) query = sqlparse.format(str(frappe.db.last_query).strip(), keyword_case="upper", reindent=True) diff --git a/frappe/sessions.py b/frappe/sessions.py index 20891db2e6..9c739f3a96 100644 --- a/frappe/sessions.py +++ b/frappe/sessions.py @@ -32,12 +32,11 @@ def clear(): frappe.response["message"] = _("Cache Cleared") -def clear_sessions(user=None, keep_current=False, device=None, force=False): +def clear_sessions(user=None, keep_current=False, force=False): """Clear other sessions of the current user. Called at login / logout :param user: user name (default: current user) :param keep_current: keep current session (default: false) - :param device: delete sessions of this device (default: desktop, mobile) :param force: triggered by the user (default false) """ @@ -45,35 +44,26 @@ def clear_sessions(user=None, keep_current=False, device=None, force=False): if force: reason = "Force Logged out by the user" - for sid in get_sessions_to_clear(user, keep_current, device): + for sid in get_sessions_to_clear(user, keep_current): delete_session(sid, reason=reason) -def get_sessions_to_clear(user=None, keep_current=False, device=None): +def get_sessions_to_clear(user=None, keep_current=False): """Returns sessions of the current user. Called at login / logout :param user: user name (default: current user) :param keep_current: keep current session (default: false) - :param device: delete sessions of this device (default: desktop, mobile) """ if not user: user = frappe.session.user - if not device: - device = ("desktop", "mobile") - - if not isinstance(device, (tuple, list)): - device = (device,) - offset = 0 if user == frappe.session.user: simultaneous_sessions = frappe.db.get_value("User", user, "simultaneous_sessions") or 1 offset = simultaneous_sessions - 1 session = DocType("Sessions") - session_id = frappe.qb.from_(session).where( - (session.user == user) & (session.device.isin(device)) - ) + session_id = frappe.qb.from_(session).where(session.user == user) if keep_current: session_id = session_id.where(session.sid != frappe.session.sid) @@ -121,25 +111,18 @@ def clear_all_sessions(reason=None): def get_expired_sessions(): """Returns list of expired sessions""" + sessions = DocType("Sessions") - expired = [] - for device in ("desktop", "mobile"): - expired.extend( - frappe.db.get_values( - sessions, - filters=( - PseudoColumn(f"({Now()} - {sessions.lastupdate.get_sql()})") - > get_expiry_period_for_query(device) - ) - & (sessions.device == device), - fieldname="sid", - order_by=None, - pluck=True, - ) - ) - - return expired + return frappe.db.get_values( + sessions, + filters=( + PseudoColumn(f"({Now()} - {sessions.lastupdate.get_sql()})") > get_expiry_period_for_query() + ), + fieldname="sid", + order_by=None, + pluck=True, + ) def clear_expired_sessions(): @@ -218,14 +201,13 @@ def generate_csrf_token(): class Session: - __slots__ = ("user", "device", "user_type", "full_name", "data", "time_diff", "sid") + __slots__ = ("user", "user_type", "full_name", "data", "time_diff", "sid") def __init__(self, user, resume=False, full_name=None, user_type=None): self.sid = cstr( frappe.form_dict.get("sid") or unquote(frappe.request.cookies.get("sid", "Guest")) ) self.user = user - self.device = frappe.form_dict.get("device") or "desktop" self.user_type = user_type self.full_name = full_name self.data = frappe._dict({"data": frappe._dict({})}) @@ -257,10 +239,9 @@ class Session: self.data.data.update( { "last_updated": frappe.utils.now(), - "session_expiry": get_expiry_period(self.device), + "session_expiry": get_expiry_period(), "full_name": self.full_name, "user_type": self.user_type, - "device": self.device, "session_country": get_geo_ip_country(frappe.local.request_ip) if frappe.local.request_ip else None, @@ -289,9 +270,9 @@ class Session: def insert_session_record(self): frappe.db.sql( """insert into `tabSessions` - (`sessiondata`, `user`, `lastupdate`, `sid`, `status`, `device`) - values (%s , %s, NOW(), %s, 'Active', %s)""", - (str(self.data["data"]), self.data["user"], self.data["sid"], self.device), + (`sessiondata`, `user`, `lastupdate`, `sid`, `status`) + values (%s , %s, NOW(), %s, 'Active')""", + (str(self.data["data"]), self.data["user"], self.data["sid"]), ) # also add to memcache @@ -308,7 +289,6 @@ class Session: self.data.update({"data": data, "user": data.user, "sid": self.sid}) self.user = data.user validate_ip_address(self.user) - self.device = data.device else: self.start_as_guest() @@ -359,22 +339,11 @@ class Session: def get_session_data_from_db(self): sessions = DocType("Sessions") - - self.device = ( - frappe.db.get_value( - sessions, - filters=sessions.sid == self.sid, - fieldname="device", - order_by=None, - ) - or "desktop" - ) rec = frappe.db.get_values( sessions, filters=(sessions.sid == self.sid) & ( - PseudoColumn(f"({Now()} - {sessions.lastupdate.get_sql()})") - < get_expiry_period_for_query(self.device) + PseudoColumn(f"({Now()} - {sessions.lastupdate.get_sql()})") < get_expiry_period_for_query() ), fieldname=["user", "sessiondata"], order_by=None, @@ -437,29 +406,23 @@ class Session: return updated_in_db -def get_expiry_period_for_query(device=None): +def get_expiry_period_for_query(): if frappe.db.db_type == "postgres": - return get_expiry_period(device) + return get_expiry_period() else: - return get_expiry_in_seconds(device=device) + return get_expiry_in_seconds() -def get_expiry_in_seconds(expiry=None, device=None): +def get_expiry_in_seconds(expiry=None): if not expiry: - expiry = get_expiry_period(device) + expiry = get_expiry_period() + parts = expiry.split(":") return (cint(parts[0]) * 3600) + (cint(parts[1]) * 60) + cint(parts[2]) -def get_expiry_period(device="desktop"): - if device == "mobile": - key = "session_expiry_mobile" - default = "720:00:00" - else: - key = "session_expiry" - default = "06:00:00" - - exp_sec = frappe.defaults.get_global_default(key) or default +def get_expiry_period(): + exp_sec = frappe.defaults.get_global_default("session_expiry") or "06:00:00" # incase seconds is missing if len(exp_sec.split(":")) == 2: diff --git a/frappe/templates/includes/login/login.js b/frappe/templates/includes/login/login.js index 8365947e6c..60dd0396de 100644 --- a/frappe/templates/includes/login/login.js +++ b/frappe/templates/includes/login/login.js @@ -19,7 +19,6 @@ login.bind_events = function () { args.cmd = "login"; args.usr = frappe.utils.xss_sanitise(($("#login_email").val() || "").trim()); args.pwd = $("#login_password").val(); - args.device = "desktop"; if (!args.usr || !args.pwd) { frappe.msgprint('{{ _("Both login and password required") }}'); return false; @@ -73,7 +72,6 @@ login.bind_events = function () { args.cmd = "{{ ldap_settings.method }}"; args.usr = ($("#login_email").val() || "").trim(); args.pwd = $("#login_password").val(); - args.device = "desktop"; if (!args.usr || !args.pwd) { login.set_status('{{ _("Both login and password required") }}', 'red'); return false; diff --git a/frappe/test_runner.py b/frappe/test_runner.py index 7e2c7e724f..3876d065b1 100644 --- a/frappe/test_runner.py +++ b/frappe/test_runner.py @@ -148,11 +148,11 @@ def set_test_email_config(): class TimeLoggingTestResult(unittest.TextTestResult): def startTest(self, test): - self._started_at = time.time() + self._started_at = time.monotonic() super().startTest(test) def addSuccess(self, test): - elapsed = time.time() - self._started_at + elapsed = time.monotonic() - self._started_at name = self.getDescription(test) if elapsed >= SLOW_TEST_THRESHOLD: self.stream.write(f"\n{name} ({elapsed:.03}s)\n") diff --git a/frappe/tests/test_document.py b/frappe/tests/test_document.py index 4ad2d85a19..474971c935 100644 --- a/frappe/tests/test_document.py +++ b/frappe/tests/test_document.py @@ -424,6 +424,30 @@ class TestDocument(FrappeTestCase): self.assertRaises(frappe.DoesNotExistError, doc.save) + def test_validate_from_to_dates(self): + doc = frappe.new_doc("Web Page") + doc.start_date = None + doc.end_date = None + doc.validate_from_to_dates("start_date", "end_date") + + doc.start_date = "2020-01-01" + doc.end_date = None + doc.validate_from_to_dates("start_date", "end_date") + + doc.start_date = None + doc.end_date = "2020-12-31" + doc.validate_from_to_dates("start_date", "end_date") + + doc.start_date = "2020-01-01" + doc.end_date = "2020-12-31" + doc.validate_from_to_dates("start_date", "end_date") + + doc.end_date = "2020-01-01" + doc.start_date = "2020-12-31" + self.assertRaises( + frappe.exceptions.InvalidDates, doc.validate_from_to_dates, "start_date", "end_date" + ) + class TestDocumentWebView(FrappeTestCase): def get(self, path, user="Guest"): diff --git a/frappe/tests/test_utils.py b/frappe/tests/test_utils.py index 44966691a0..cf6134d101 100644 --- a/frappe/tests/test_utils.py +++ b/frappe/tests/test_utils.py @@ -68,6 +68,7 @@ from frappe.utils.identicon import Identicon from frappe.utils.image import optimize_image, strip_exif_data from frappe.utils.make_random import can_make, get_random, how_many from frappe.utils.response import json_handler +from frappe.utils.synchronization import LockTimeoutError, filelock class Capturing(list): @@ -880,6 +881,22 @@ class TestContainerUtils(FrappeTestCase): self.assertEqual(a["c"], "d") +class TestLocks(FrappeTestCase): + def test_locktimeout(self): + lock_name = "test_lock" + with filelock(lock_name): + with self.assertRaises(LockTimeoutError): + with filelock(lock_name, timeout=1): + self.fail("Locks not working") + + def test_global_lock(self): + lock_name = "test_global" + with filelock(lock_name, is_global=True): + with self.assertRaises(LockTimeoutError): + with filelock(lock_name, timeout=1, is_global=True): + self.fail("Global locks not working") + + class TestMiscUtils(FrappeTestCase): def test_get_file_timestamp(self): self.assertIsInstance(get_file_timestamp(__file__), str) diff --git a/frappe/tests/utils.py b/frappe/tests/utils.py index 647720a78f..15e0c3d9c0 100644 --- a/frappe/tests/utils.py +++ b/frappe/tests/utils.py @@ -22,6 +22,7 @@ class FrappeTestCase(unittest.TestCase): TEST_SITE = "test_site" SHOW_TRANSACTION_COMMIT_WARNINGS = False + maxDiff = None # prints long diffs but useful in CI @classmethod def setUpClass(cls) -> None: diff --git a/frappe/translations/af.csv b/frappe/translations/af.csv index 88f30be096..53bb3f1946 100644 --- a/frappe/translations/af.csv +++ b/frappe/translations/af.csv @@ -1395,7 +1395,7 @@ Is Submittable,Is Submittable, Is Table,Is Tabel, Is Your Company Address,Is u maatskappy se adres, It is risky to delete this file: {0}. Please contact your System Manager.,Dit is riskant om hierdie lêer te verwyder: {0}. Kontak asseblief u stelselbestuurder., -Item cannot be added to its own descendents,Item kan nie by sy eie afstammelinge bygevoeg word nie, +Item cannot be added to its own descendants,Item kan nie by sy eie afstammelinge bygevoeg word nie, JS,JS, JSON,into, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript-formaat: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/am.csv b/frappe/translations/am.csv index 5321621e03..34856d1a6b 100644 --- a/frappe/translations/am.csv +++ b/frappe/translations/am.csv @@ -1395,7 +1395,7 @@ Is Submittable,Submittable ነው, Is Table,ማውጫ ነው, Is Your Company Address,የእርስዎ ኩባንያ አድራሻ ነው, It is risky to delete this file: {0}. Please contact your System Manager.,ይህ ፋይል መሰረዝ አደገኛ ነው: {0}. እባክዎ የስርዓት አስተዳዳሪዎን ያግኙ., -Item cannot be added to its own descendents,ንጥል የራሱን ዘር ሊታከሉ አይችሉም, +Item cannot be added to its own descendants,ንጥል የራሱን ዘር ሊታከሉ አይችሉም, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},ጃቫስክሪፕት ቅርጸት: frappe.query_reports [ 'REPORTNAME'] = {}, diff --git a/frappe/translations/ar.csv b/frappe/translations/ar.csv index 95caebd35f..d712576ebd 100644 --- a/frappe/translations/ar.csv +++ b/frappe/translations/ar.csv @@ -1395,7 +1395,7 @@ Is Submittable,يستطيع الاعتماد, Is Table,هو الجدول, Is Your Company Address,يكون عنوان شركتك, It is risky to delete this file: {0}. Please contact your System Manager.,أنه أمر محفوف بالمخاطر لحذف هذا الملف: {0}. يرجى الاتصال بمدير النظام الخاص بك., -Item cannot be added to its own descendents,البند لا يمكن أن تضاف الى أحفادها
Item cannot be added to its own descendents, +Item cannot be added to its own descendants,البند لا يمكن أن تضاف الى أحفادها
Item cannot be added to its own descendants, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},جافا سكريبت الصيغة: frappe.query_reports [' REPORTNAME '] = { }, diff --git a/frappe/translations/bg.csv b/frappe/translations/bg.csv index 553b9eab13..6ac12e9f0e 100644 --- a/frappe/translations/bg.csv +++ b/frappe/translations/bg.csv @@ -1395,7 +1395,7 @@ Is Submittable,Дали Правят, Is Table,Е таблица, Is Your Company Address,Вашата компания Адрес, It is risky to delete this file: {0}. Please contact your System Manager.,"Рисковано е да изтриете този файл: {0}. Моля, обърнете се към вашия System Manager.", -Item cannot be added to its own descendents,Позицията не може да бъде добавена към собствените си потомци, +Item cannot be added to its own descendants,Позицията не може да бъде добавена към собствените си потомци, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript Формат: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/bn.csv b/frappe/translations/bn.csv index b6465fc555..a22149cbff 100644 --- a/frappe/translations/bn.csv +++ b/frappe/translations/bn.csv @@ -1395,7 +1395,7 @@ Is Submittable,Submittable হয়, Is Table,টেবিল, Is Your Company Address,আপনার কোম্পানির ঠিকানা, It is risky to delete this file: {0}. Please contact your System Manager.,এটা এই ফাইলটি মোছার জন্য ঝুঁকিপূর্ণ: {0}. আপনার সিস্টেম ম্যানেজার সাথে যোগাযোগ করুন., -Item cannot be added to its own descendents,আইটেমটি নিজস্ব সন্তান যোগ করা যাবে না, +Item cannot be added to its own descendants,আইটেমটি নিজস্ব সন্তান যোগ করা যাবে না, JS,js, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},জাভাস্ক্রিপ্ট বিন্যাস: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/bs.csv b/frappe/translations/bs.csv index 9ddb78dfe0..d691d770ed 100644 --- a/frappe/translations/bs.csv +++ b/frappe/translations/bs.csv @@ -1395,7 +1395,7 @@ Is Submittable,Je Submittable, Is Table,je Tabela, Is Your Company Address,Is Your Company Adresa, It is risky to delete this file: {0}. Please contact your System Manager.,To je rizično izbrisati ovu datoteku: {0}. Molimo vas da se obratite System Manager., -Item cannot be added to its own descendents,Stavka ne može se dodati u svojim potomcima, +Item cannot be added to its own descendants,Stavka ne može se dodati u svojim potomcima, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript format : frappe.query_reports [ ' REPORTNAME ' ] = { }, diff --git a/frappe/translations/ca.csv b/frappe/translations/ca.csv index 3de89a8620..39aca480f4 100644 --- a/frappe/translations/ca.csv +++ b/frappe/translations/ca.csv @@ -1395,7 +1395,7 @@ Is Submittable,És submittable, Is Table,és Taula, Is Your Company Address,La seva adreça és l'empresa, It is risky to delete this file: {0}. Please contact your System Manager.,"És arriscat eliminar aquesta imatge: {0}. Si us plau, poseu-vos en contacte amb l'administrador del sistema.", -Item cannot be added to its own descendents,L'article no es pot afegir als seus propis descendents, +Item cannot be added to its own descendants,L'article no es pot afegir als seus propis descendants, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript Format: frappe.query_reports['REPORTNAME'] = {}, @@ -1675,7 +1675,7 @@ No {0} permission,No {0} permís, None: End of Workflow,Cap: Final de flux de treball, Not Allowed: Disabled User,No permès: usuari desactivat, Not Ancestors Of,Sense avantpassats de, -Not Descendants Of,Sense descendents de, +Not Descendants Of,Sense descendants de, Not Equals,No Equival, Not In,No En, Not Linked to any record,No vinculats a cap registre, @@ -3045,7 +3045,7 @@ zoom-out,menys-zoom, {0} has been successfully added to the Email Group.,{0} s'ha afegit al Grup de Correu Electrònic., {0} has left the conversation in {1} {2},{0} ha deixat la conversa en {1} {2}, {0} hours ago,Fa {0} hores, -{0} in row {1} cannot have both URL and child items,{0} a la fila {1} no pot tenir les dues coses URL i elements descendents, +{0} in row {1} cannot have both URL and child items,{0} a la fila {1} no pot tenir les dues coses URL i elements descendants, {0} is a mandatory field,{0} és un camp obligatori, {0} is an invalid email address in 'Recipients',{0} és una adreça electrònica no vàlida a "Destinataris", {0} is not a raw printing format.,{0} no és un format d'impressió en brut., @@ -3086,7 +3086,7 @@ zoom-out,menys-zoom, {0} {1} added,S'ha afegit {0} {1}, {0} {1} already exists,{0} {1} ja existeix, "{0} {1} cannot be ""{2}"". It should be one of ""{3}""","{0} {1} no pot ser ""{2}"". Ha de ser un de ""{3}""", -{0} {1} cannot be a leaf node as it has children,{0} {1} no pot ser un node fulla perquè té descendents, +{0} {1} cannot be a leaf node as it has children,{0} {1} no pot ser un node fulla perquè té descendants, "{0} {1} does not exist, select a new target to merge","{0} {1} no existeix, seleccioneu un nou objectiu per unir", {0} {1} not found,{0} {1} no trobat, {0} {1} to {2},{0} {1} a {2}, diff --git a/frappe/translations/cs.csv b/frappe/translations/cs.csv index 262d8bb1e5..0c35b6eaa1 100644 --- a/frappe/translations/cs.csv +++ b/frappe/translations/cs.csv @@ -1395,7 +1395,7 @@ Is Submittable,Je Odeslatelné, Is Table,je Tabulka, Is Your Company Address,Je vaše firma adresa, It is risky to delete this file: {0}. Please contact your System Manager.,"Je to riskantní smazat tento soubor: {0}. Prosím, obraťte se na správce systému.", -Item cannot be added to its own descendents,Položka nemůže být přidána jako svůj vlastní podřízený potomek, +Item cannot be added to its own descendants,Položka nemůže být přidána jako svůj vlastní podřízený potomek, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript Formát: frappe.query_reports['REPORTNAME'] = {}, diff --git a/frappe/translations/cz.csv b/frappe/translations/cz.csv index 818d2b2d9e..de01db0a29 100644 --- a/frappe/translations/cz.csv +++ b/frappe/translations/cz.csv @@ -850,7 +850,7 @@ DocType: Workflow State,trash,koš apps/frappe/frappe/desk/page/activity/activity.js +153,Dec,Pro DocType: Event,Leave blank to repeat always,Nechte prázdné pro opakování vždy DocType: Event,Ends on,Končí -apps/frappe/frappe/utils/nestedset.py +181,Item cannot be added to its own descendents,Položka nemůže být přidána jako svůj vlastní podřízený potomek +apps/frappe/frappe/utils/nestedset.py +181,Item cannot be added to its own descendants,Položka nemůže být přidána jako svůj vlastní podřízený potomek sites/assets/js/form.min.js +270,{0} created this {1},{0} vytvoření této {1} apps/frappe/frappe/desk/form/assign_to.py +120,"The task {0}, that you assigned to {1}, has been closed by {2}.","Úkol {0}, které jste přiřadili k {1}, bylo uzavřeno {2}." DocType: Blogger,Short Name,Zkrácené jméno diff --git a/frappe/translations/da.csv b/frappe/translations/da.csv index 8a6398986c..c2cc077aac 100644 --- a/frappe/translations/da.csv +++ b/frappe/translations/da.csv @@ -1395,7 +1395,7 @@ Is Submittable,Kan godkendes, Is Table,er Table, Is Your Company Address,Er din virksomhedsadresse, It is risky to delete this file: {0}. Please contact your System Manager.,Det er risikabelt at slette denne fil: {0}. Kontakt din systemadministrator., -Item cannot be added to its own descendents,Punkt kan ikke føjes til sine egne efterkommere, +Item cannot be added to its own descendants,Punkt kan ikke føjes til sine egne efterkommere, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript Format: frappe.query_reports ['rapportnavn'] = {}, diff --git a/frappe/translations/de.csv b/frappe/translations/de.csv index 6cd8133f94..fd81f8e87c 100644 --- a/frappe/translations/de.csv +++ b/frappe/translations/de.csv @@ -1404,7 +1404,7 @@ Is Table,ist eine Tabelle, Is Template, Ist Vorlage, Is Your Company Address,Ist Ihre Unternehmensadresse, It is risky to delete this file: {0}. Please contact your System Manager.,"Es ist riskant, diese Datei zu löschen: {0}. Bitte kontaktieren Sie Ihren System-Manager.", -Item cannot be added to its own descendents,Artikel kann nicht zu seinen eigenen Abkömmlingen hinzugefügt werden, +Item cannot be added to its own descendants,Artikel kann nicht zu seinen eigenen Abkömmlingen hinzugefügt werden, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript- Format: frappe.query_reports [' REPORT '] = {}, diff --git a/frappe/translations/el.csv b/frappe/translations/el.csv index d966526e44..e6bfe4eb5b 100644 --- a/frappe/translations/el.csv +++ b/frappe/translations/el.csv @@ -1395,7 +1395,7 @@ Is Submittable,Είναι υποβλητέο, Is Table,είναι πίνακας, Is Your Company Address,Η εταιρεία σας Διεύθυνση, It is risky to delete this file: {0}. Please contact your System Manager.,Είναι επικίνδυνο να διαγράψετε αυτό το αρχείο: {0}. Επικοινωνήστε με το διαχειριστή του συστήματός σας., -Item cannot be added to its own descendents,Το είδος δεν μπορεί να προστεθεί στους δικούς του απογόνους, +Item cannot be added to its own descendants,Το είδος δεν μπορεί να προστεθεί στους δικούς του απογόνους, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript Format: frappe.query_reports['REPORTNAME'] = {}, diff --git a/frappe/translations/es.csv b/frappe/translations/es.csv index 0e88b7c2be..997ee859a5 100644 --- a/frappe/translations/es.csv +++ b/frappe/translations/es.csv @@ -1409,7 +1409,7 @@ Is Submittable,Se puede validar, Is Table,es Tabla, Is Your Company Address,Es la Dirección de su Compañia, It is risky to delete this file: {0}. Please contact your System Manager.,"Es arriesgado eliminar este archivo: {0}. Por favor, póngase en contacto con el administrador del sistema.", -Item cannot be added to its own descendents,El producto no se puede añadir a sus propios heredados, +Item cannot be added to its own descendants,El producto no se puede añadir a sus propios heredados, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},Formato de JavaScript: : frappe.query_reports['REPORTNAME'] = {}, diff --git a/frappe/translations/et.csv b/frappe/translations/et.csv index c4ca980045..9bd1f6e829 100644 --- a/frappe/translations/et.csv +++ b/frappe/translations/et.csv @@ -1395,7 +1395,7 @@ Is Submittable,Kas esitatav, Is Table,Kas tabelis, Is Your Company Address,Kas teie firma Aadress, It is risky to delete this file: {0}. Please contact your System Manager.,See on riskantne kustutada seda faili: {0}. Palun võtke System Manager., -Item cannot be added to its own descendents,Punkt ei saa lisada oma järeltulijad, +Item cannot be added to its own descendants,Punkt ei saa lisada oma järeltulijad, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript Formaat: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/fa.csv b/frappe/translations/fa.csv index 99df9a9dca..0509056542 100644 --- a/frappe/translations/fa.csv +++ b/frappe/translations/fa.csv @@ -1395,7 +1395,7 @@ Is Submittable,Submittable است, Is Table,است جدول, Is Your Company Address,آیا شرکت شما در نشانی, It is risky to delete this file: {0}. Please contact your System Manager.,این خطرناک است این فایل را حذف کنید: {0}. لطفا با مدیر سیستم تماس بگیرید., -Item cannot be added to its own descendents,مورد می تواند به بازماندگان خود را اضافه نمی شوند, +Item cannot be added to its own descendants,مورد می تواند به بازماندگان خود را اضافه نمی شوند, JS,جی اس, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},جاوا اسکریپت فرمت: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/fi.csv b/frappe/translations/fi.csv index 2c62458fbb..0de73aca37 100644 --- a/frappe/translations/fi.csv +++ b/frappe/translations/fi.csv @@ -1395,7 +1395,7 @@ Is Submittable,On vahvistettavissa, Is Table,taulukkomuotoinen, Is Your Company Address,Is Your Company Osoite, It is risky to delete this file: {0}. Please contact your System Manager.,Se on riskialtista poistaa tiedoston: {0}. Ota yhteyttä System Manager., -Item cannot be added to its own descendents,tuotetta ei voi lisätä omaksi alatuotteekseen, +Item cannot be added to its own descendants,tuotetta ei voi lisätä omaksi alatuotteekseen, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},formaatti JavaScript: frappe.query_reports ['raportin_nimi'] = {}, diff --git a/frappe/translations/fr.csv b/frappe/translations/fr.csv index da330d3534..9a1e4350c0 100644 --- a/frappe/translations/fr.csv +++ b/frappe/translations/fr.csv @@ -1397,7 +1397,7 @@ Is Submittable,Est Validable, Is Table,Est Table, Is Your Company Address,Est l'Adresse de votre Entreprise, It is risky to delete this file: {0}. Please contact your System Manager.,Il est risqué de supprimer ce fichier : {0}. Veuillez contactez votre Administrateur Système., -Item cannot be added to its own descendents,L'article ne peut être ajouté à ses propres descendants, +Item cannot be added to its own descendants,L'article ne peut être ajouté à ses propres descendants, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},"""Format JavaScript :\nfrappe.query_reports [' NOMDURAPPORT '] = {}""", diff --git a/frappe/translations/gu.csv b/frappe/translations/gu.csv index e13637d26a..1eeeb813a9 100644 --- a/frappe/translations/gu.csv +++ b/frappe/translations/gu.csv @@ -1395,7 +1395,7 @@ Is Submittable,Submittable છે, Is Table,ટેબલ છે, Is Your Company Address,તમારી કંપની સરનામું, It is risky to delete this file: {0}. Please contact your System Manager.,તે આ ફાઇલ કાઢી જોખમી છે: {0}. તમારી સિસ્ટમ મેનેજરનો સંપર્ક કરો., -Item cannot be added to its own descendents,આઇટમ તેના પોતાના વંશજ ઉમેરવામાં કરી શકાતી નથી, +Item cannot be added to its own descendants,આઇટમ તેના પોતાના વંશજ ઉમેરવામાં કરી શકાતી નથી, JS,જેએસ, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},જાવાસ્ક્રિપ્ટ ફોર્મેટ: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/he.csv b/frappe/translations/he.csv index dda9f2b233..d7e06060a8 100644 --- a/frappe/translations/he.csv +++ b/frappe/translations/he.csv @@ -1395,7 +1395,7 @@ Is Submittable,האם Submittable, Is Table,האם לוח, Is Your Company Address,האם כתובת החברה שלך, It is risky to delete this file: {0}. Please contact your System Manager.,זה מסוכן כדי למחוק קובץ זה: {0}. אנא צור קשר עם מנהל המערכת שלך., -Item cannot be added to its own descendents,פריט לא ניתן להוסיף לצאצאים משלו, +Item cannot be added to its own descendants,פריט לא ניתן להוסיף לצאצאים משלו, JS,Js, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},פורמט JavaScript: frappe.query_reports ['את REPORTTYPE'] = {}, diff --git a/frappe/translations/hi.csv b/frappe/translations/hi.csv index fcf3a32263..d5a8119145 100644 --- a/frappe/translations/hi.csv +++ b/frappe/translations/hi.csv @@ -1395,7 +1395,7 @@ Is Submittable,Submittable है, Is Table,टेबल है, Is Your Company Address,आपकी कंपनी पता है, It is risky to delete this file: {0}. Please contact your System Manager.,यह इस फ़ाइल को नष्ट करने के लिए जोखिम भरा है: {0}। अपने सिस्टम मैनेजर से संपर्क करें।, -Item cannot be added to its own descendents,आइटम अपने खुद के वंशजों को जोड़ा नहीं जा सकता, +Item cannot be added to its own descendants,आइटम अपने खुद के वंशजों को जोड़ा नहीं जा सकता, JS,जे एस, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},जावास्क्रिप्ट स्वरूप: frappe.query_reports [' REPORTNAME '] = {}, diff --git a/frappe/translations/hr.csv b/frappe/translations/hr.csv index 4846876c82..3f2dfe1065 100644 --- a/frappe/translations/hr.csv +++ b/frappe/translations/hr.csv @@ -1395,7 +1395,7 @@ Is Submittable,Je Submittable, Is Table,je Tablica, Is Your Company Address,Je li Vaše poduzeće adresa, It is risky to delete this file: {0}. Please contact your System Manager.,To je rizično izbrisati ovu datoteku: {0}. Molimo kontaktirajte svog sustava Manageru., -Item cannot be added to its own descendents,Proizvod ne može se dodati u svojim potomcima, +Item cannot be added to its own descendants,Proizvod ne može se dodati u svojim potomcima, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript format : frappe.query_reports [ ' REPORTNAME ' ] = { }, diff --git a/frappe/translations/hu.csv b/frappe/translations/hu.csv index 677447b809..7e5b9b3c36 100644 --- a/frappe/translations/hu.csv +++ b/frappe/translations/hu.csv @@ -1395,7 +1395,7 @@ Is Submittable,Ez küldhető, Is Table,Ez táblázat, Is Your Company Address,Az Ön cége címe, It is risky to delete this file: {0}. Please contact your System Manager.,"Kockázatos törölni ezt a fájlt: {0}. Kérjük, forduljon a Rendszergazdához.", -Item cannot be added to its own descendents,Tételt nem lehet hozzáadni a saját leszármazottaikhoz, +Item cannot be added to its own descendants,Tételt nem lehet hozzáadni a saját leszármazottaikhoz, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript Format: frappe.query_reports ['JELENTÉSNÉV'] = {}, diff --git a/frappe/translations/id.csv b/frappe/translations/id.csv index ff46ec82a9..8b39cd0c5c 100644 --- a/frappe/translations/id.csv +++ b/frappe/translations/id.csv @@ -1395,7 +1395,7 @@ Is Submittable,Apakah Submittable, Is Table,Apakah Tabel, Is Your Company Address,Apakah Alamat Perusahaan Anda, It is risky to delete this file: {0}. Please contact your System Manager.,Hal ini berisiko untuk menghapus file ini: {0}. Silahkan hubungi System Manager Anda., -Item cannot be added to its own descendents,Item tidak dapat ditambahkan ke keturunan sendiri, +Item cannot be added to its own descendants,Item tidak dapat ditambahkan ke keturunan sendiri, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript Format: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/is.csv b/frappe/translations/is.csv index f870b63254..bc6dab989a 100644 --- a/frappe/translations/is.csv +++ b/frappe/translations/is.csv @@ -1395,7 +1395,7 @@ Is Submittable,er Submittable, Is Table,er Tafla, Is Your Company Address,Er fyrirtækið Heimilisfang þitt, It is risky to delete this file: {0}. Please contact your System Manager.,Það er áhættusamt að eyða þessari skrá: {0}. Vinsamlegast hafðu samband System Manager., -Item cannot be added to its own descendents,Atriði er ekki hægt að bæta við eigin afkomenda sinna, +Item cannot be added to its own descendants,Atriði er ekki hægt að bæta við eigin afkomenda sinna, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript Format: frappe.query_reports [ 'REPORTNAME'] = {}, diff --git a/frappe/translations/it.csv b/frappe/translations/it.csv index 3a46044681..99c0bae9b8 100644 --- a/frappe/translations/it.csv +++ b/frappe/translations/it.csv @@ -1395,7 +1395,7 @@ Is Submittable,È Confermabile, Is Table,è Tabella, Is Your Company Address,È il vostro indirizzo azienda, It is risky to delete this file: {0}. Please contact your System Manager.,E' rischioso cancellare questo file: {0}. Si prega di contattare il Responsabile di Sistema., -Item cannot be added to its own descendents,L'articolo non può essere aggiunto ai propri discendenti, +Item cannot be added to its own descendants,L'articolo non può essere aggiunto ai propri discendenti, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},Formato JavaScript: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/ja.csv b/frappe/translations/ja.csv index 8a1e3d0884..460dd4a4b9 100644 --- a/frappe/translations/ja.csv +++ b/frappe/translations/ja.csv @@ -1395,7 +1395,7 @@ Is Submittable,提出可能, Is Table,表, Is Your Company Address,あなたの会社の住所, It is risky to delete this file: {0}. Please contact your System Manager.,このファイル {0} を削除することは危険です。システム管理者にお問い合わせください。, -Item cannot be added to its own descendents,アイテムは自身の子孫に追加することはできません, +Item cannot be added to its own descendants,アイテムは自身の子孫に追加することはできません, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript形式:frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/km.csv b/frappe/translations/km.csv index 6b7ad32f40..73c0b2b27e 100644 --- a/frappe/translations/km.csv +++ b/frappe/translations/km.csv @@ -1395,7 +1395,7 @@ Is Submittable,តើការ Submittable, Is Table,គឺជាតារាង, Is Your Company Address,គឺជាអាសយដ្ឋានក្រុមហ៊ុនរបស់អ្នក, It is risky to delete this file: {0}. Please contact your System Manager.,វាគឺជាការប្រថុយប្រថានក្នុងការលុបឯកសារនេះ: {0} ។ សូមទាក់ទងកម្មវិធីគ្រប់គ្រងប្រព័ន្ធរបស់អ្នក។, -Item cannot be added to its own descendents,ធាតុមិនអាចត្រូវបានបន្ថែមទៅជនជាតិផ្ទាល់របស់ខ្លួន, +Item cannot be added to its own descendants,ធាតុមិនអាចត្រូវបានបន្ថែមទៅជនជាតិផ្ទាល់របស់ខ្លួន, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript ទ្រង់ទ្រាយ: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/kn.csv b/frappe/translations/kn.csv index ef5e06a016..68f4a6cf18 100644 --- a/frappe/translations/kn.csv +++ b/frappe/translations/kn.csv @@ -1395,7 +1395,7 @@ Is Submittable,Submittable ಈಸ್, Is Table,ಟೇಬಲ್, Is Your Company Address,ನಿಮ್ಮ ಕಂಪನಿ ವಿಳಾಸ, It is risky to delete this file: {0}. Please contact your System Manager.,ಇದು ಈ ಕಡತ ಅಳಿಸಲು ಅಪಾಯಕಾರಿ: {0}. ನಿಮ್ಮ ಸಿಸ್ಟಂ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ., -Item cannot be added to its own descendents,ಐಟಂ ತನ್ನದೇ ಸಂತತಿಯವರು ಸೇರಿಸಲಾಗಿದೆ ಸಾಧ್ಯವಿಲ್ಲ, +Item cannot be added to its own descendants,ಐಟಂ ತನ್ನದೇ ಸಂತತಿಯವರು ಸೇರಿಸಲಾಗಿದೆ ಸಾಧ್ಯವಿಲ್ಲ, JS,ಉಪಯೋಗಿಸಿದ, JSON,JSON ಅನ್ನು, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಫಾರ್ಮ್ಯಾಟ್: frappe.query_reports [ 'ವರದಿಯನ್ನು ಹೆಸರು '] = {}, diff --git a/frappe/translations/ko.csv b/frappe/translations/ko.csv index a40c2b787d..d5f2ace782 100644 --- a/frappe/translations/ko.csv +++ b/frappe/translations/ko.csv @@ -1395,7 +1395,7 @@ Is Submittable,Submittable입니다, Is Table,표입니다, Is Your Company Address,귀하의 회사 주소입니다, It is risky to delete this file: {0}. Please contact your System Manager.,그것은이 파일을 삭제하는 위험 : {0}. 시스템 관리자에게 문의하시기 바랍니다., -Item cannot be added to its own descendents,항목은 자체 하위에 추가 할 수없는, +Item cannot be added to its own descendants,항목은 자체 하위에 추가 할 수없는, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},자바 스크립트 형식 : frappe.query_reports [ 'REPORTNAME'] = {}, diff --git a/frappe/translations/ku.csv b/frappe/translations/ku.csv index a30ffc115d..e9fde50046 100644 --- a/frappe/translations/ku.csv +++ b/frappe/translations/ku.csv @@ -1395,7 +1395,7 @@ Is Submittable,Submittable e, Is Table,e Table, Is Your Company Address,E Company te Address, It is risky to delete this file: {0}. Please contact your System Manager.,Ev metirsiyek e li vê pelê jê bibî: {0}. Ji kerema xwe ve Manager Pergala xwe re bikeve têkiliyê., -Item cannot be added to its own descendents,Babetê dikarin ji bo neviyên xwe bi xwe ne bê added, +Item cannot be added to its own descendants,Babetê dikarin ji bo neviyên xwe bi xwe ne bê added, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript Format: frappe.query_reports [ 'REPORTNAME'] = {}, diff --git a/frappe/translations/lo.csv b/frappe/translations/lo.csv index fceaa5a31f..b48f7b3e71 100644 --- a/frappe/translations/lo.csv +++ b/frappe/translations/lo.csv @@ -1395,7 +1395,7 @@ Is Submittable,ແມ່ນສົ່ງ, Is Table,ເປັນຕາຕະລາງ, Is Your Company Address,ທີ່ຢູ່ຂອງບໍລິສັດ, It is risky to delete this file: {0}. Please contact your System Manager.,ມັນເປັນຄວາມສ່ຽງສູງທີ່ຈະລຶບເອກະສານນີ້:. {0} ກະລຸນາຕິດຕໍ່ຈັດການລະບົບຂອງທ່ານ., -Item cannot be added to its own descendents,ລາຍການບໍ່ສາມາດໄດ້ຮັບການເພີ່ມລູກຫລານຂອງຕົນເອງ, +Item cannot be added to its own descendants,ລາຍການບໍ່ສາມາດໄດ້ຮັບການເພີ່ມລູກຫລານຂອງຕົນເອງ, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript Format: frappe.query_reports [ 'REPORTNAME'] = {}, diff --git a/frappe/translations/lt.csv b/frappe/translations/lt.csv index 22979f9b69..071a7cd2d7 100644 --- a/frappe/translations/lt.csv +++ b/frappe/translations/lt.csv @@ -1395,7 +1395,7 @@ Is Submittable,Ar Submittable, Is Table,Ar lentelė, Is Your Company Address,Ar Jūsų įmonė Adresas, It is risky to delete this file: {0}. Please contact your System Manager.,Tai rizikinga ištrinti šį failą: {0}. Prašome susisiekti su savo sistemos valdytojas., -Item cannot be added to its own descendents,Prekė negali būti įtraukta į savo palikuonims, +Item cannot be added to its own descendants,Prekė negali būti įtraukta į savo palikuonims, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript Formatas: frappe.query_reports [ 'REPORTNAME'] = {}, diff --git a/frappe/translations/lv.csv b/frappe/translations/lv.csv index 1b14a6c5da..48c773b620 100644 --- a/frappe/translations/lv.csv +++ b/frappe/translations/lv.csv @@ -1395,7 +1395,7 @@ Is Submittable,Vai Submittable, Is Table,ir tabula, Is Your Company Address,Vai Jūsu uzņēmuma adrese, It is risky to delete this file: {0}. Please contact your System Manager.,"Tas ir riskanti, lai izdzēstu šo failu: {0}. Lūdzu, sazinieties ar sistēmas pārzini.", -Item cannot be added to its own descendents,Posteni nevar pievienot saviem pēcnācējiem, +Item cannot be added to its own descendants,Posteni nevar pievienot saviem pēcnācējiem, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript Formāts: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/mk.csv b/frappe/translations/mk.csv index 6d171823fb..e045e30c72 100644 --- a/frappe/translations/mk.csv +++ b/frappe/translations/mk.csv @@ -1395,7 +1395,7 @@ Is Submittable,Е Submittable, Is Table,е маса, Is Your Company Address,Дали вашата компанија адреса, It is risky to delete this file: {0}. Please contact your System Manager.,Премногу е ризично да ја избришете оваа датотека: {0}. Контактирајте со вашиот систем менаџер., -Item cannot be added to its own descendents,Точка не може да се додаде свои потомци, +Item cannot be added to its own descendants,Точка не може да се додаде свои потомци, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},Го вклучите Javascript-формат: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/ml.csv b/frappe/translations/ml.csv index 6f0a22b53c..ecb4b42874 100644 --- a/frappe/translations/ml.csv +++ b/frappe/translations/ml.csv @@ -1395,7 +1395,7 @@ Is Submittable,Submittable Is, Is Table,മേശ, Is Your Company Address,നിങ്ങളുടെ കമ്പനി വിലാസമാണ്, It is risky to delete this file: {0}. Please contact your System Manager.,{0}: അതു ഈ ചിത്രം ഇല്ലാതാക്കാൻ മാറഡോണ. നിങ്ങളുടെ സിസ്റ്റം മാനേജർ ബന്ധപ്പെടുക., -Item cannot be added to its own descendents,ഇനം അതിന്റേതായ descendents ചേർക്കില്ല കഴിയില്ല, +Item cannot be added to its own descendants,ഇനം അതിന്റേതായ descendants ചേർക്കില്ല കഴിയില്ല, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},ജാവാസ്ക്രിപ്റ്റ് ഫോർമാറ്റ്: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/mr.csv b/frappe/translations/mr.csv index a4d5dadfd6..cbc24e3863 100644 --- a/frappe/translations/mr.csv +++ b/frappe/translations/mr.csv @@ -1395,7 +1395,7 @@ Is Submittable,Submittable आहे, Is Table,टेबल आहे, Is Your Company Address,आपल्या कंपनीचा पत्ता आहे का ?, It is risky to delete this file: {0}. Please contact your System Manager.,हि फाइल तुम्ही डिलीट करणे धोकादायक आहे: {0}. तुमची प्रणाली व्यवस्थापकाशी संपर्क साधा., -Item cannot be added to its own descendents,आयटम त्याच्या स्वत: च्या descendents ला जोडला जाऊ शकत नाही, +Item cannot be added to its own descendants,आयटम त्याच्या स्वत: च्या descendants ला जोडला जाऊ शकत नाही, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},जावास्क्रिप्ट स्वरूप: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/ms.csv b/frappe/translations/ms.csv index c562355b75..e55b860658 100644 --- a/frappe/translations/ms.csv +++ b/frappe/translations/ms.csv @@ -1395,7 +1395,7 @@ Is Submittable,Adalah Submittable, Is Table,adalah Jadual, Is Your Company Address,Adakah anda Alamat Syarikat, It is risky to delete this file: {0}. Please contact your System Manager.,Ia adalah berisiko untuk memadam fail ini: {0}. Sila hubungi Pengurus Sistem anda., -Item cannot be added to its own descendents,Item tidak boleh ditambah kepada keturunan sendiri, +Item cannot be added to its own descendants,Item tidak boleh ditambah kepada keturunan sendiri, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript Format: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/my.csv b/frappe/translations/my.csv index 724e65e4c5..66951f0f3b 100644 --- a/frappe/translations/my.csv +++ b/frappe/translations/my.csv @@ -1395,7 +1395,7 @@ Is Submittable,Submittable ဖြစ်ပါသည်, Is Table,စားပွဲတင် Is, Is Your Company Address,သင့်ရဲ့ကုမ္ပဏီလိပ်စာဖြစ်ပါသည်, It is risky to delete this file: {0}. Please contact your System Manager.,{0}: ဒါဟာဒီဖိုင်ကိုဖျက်ပစ်ရန်အန္တရာယ်များသည်။ သင့်ရဲ့ System ကို Manager ကဆက်သွယ်နိုင်ပါသည်။, -Item cannot be added to its own descendents,item ၎င်း၏ကိုယ်ပိုင်ဆင်းသက်လာမှဆက်ပြောသည်မရနိုင်ပါ, +Item cannot be added to its own descendants,item ၎င်း၏ကိုယ်ပိုင်ဆင်းသက်လာမှဆက်ပြောသည်မရနိုင်ပါ, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript ကိုစီစဉ်ဖွဲ့စည်းမှုပုံစံ: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/nl.csv b/frappe/translations/nl.csv index 677cc279aa..8c11a364a2 100644 --- a/frappe/translations/nl.csv +++ b/frappe/translations/nl.csv @@ -1395,7 +1395,7 @@ Is Submittable,Kan ingediend worden, Is Table,is Table, Is Your Company Address,Is uw bedrijf Adres, It is risky to delete this file: {0}. Please contact your System Manager.,Het is riskant om dit bestand te verwijderen: {0}. Neem dan contact op met uw systeembeheerder., -Item cannot be added to its own descendents,Artikel kan niet worden toegevoegd aan zijn eigen onderliggende artikelen., +Item cannot be added to its own descendants,Artikel kan niet worden toegevoegd aan zijn eigen onderliggende artikelen., JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript Formaat : frappe.query_reports ['REPORTNAME'] = { }, diff --git a/frappe/translations/no.csv b/frappe/translations/no.csv index 03564cc5f2..daa93710e0 100644 --- a/frappe/translations/no.csv +++ b/frappe/translations/no.csv @@ -1395,7 +1395,7 @@ Is Submittable,Er Submittable, Is Table,er Table, Is Your Company Address,Er din bedrift Adresse, It is risky to delete this file: {0}. Please contact your System Manager.,Det er risikabelt å slette denne filen: {0}. Ta kontakt med din System Manager., -Item cannot be added to its own descendents,Elementet kan ikke legges til sine egne etterkommere, +Item cannot be added to its own descendants,Elementet kan ikke legges til sine egne etterkommere, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},Javascript Format: frappe.query_reports ['rapportnavn'] = {}, diff --git a/frappe/translations/pl.csv b/frappe/translations/pl.csv index fb2f52179f..e7dd255555 100644 --- a/frappe/translations/pl.csv +++ b/frappe/translations/pl.csv @@ -1395,7 +1395,7 @@ Is Submittable,Jest możliwe do przesłania, Is Table,Czy Table, Is Your Company Address,Czy Twój adres firmy, It is risky to delete this file: {0}. Please contact your System Manager.,"To jest ryzykowne, aby usunąć ten plik: {0}. Proszę skontaktować się z System Manager.", -Item cannot be added to its own descendents,Przedmiot nie może być dodany do własnych potomków, +Item cannot be added to its own descendants,Przedmiot nie może być dodany do własnych potomków, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},Format JavaScript: raporty frappe.query [ 'ReportName'] = {}, diff --git a/frappe/translations/ps.csv b/frappe/translations/ps.csv index 66380b546a..1911d4a02e 100644 --- a/frappe/translations/ps.csv +++ b/frappe/translations/ps.csv @@ -1395,7 +1395,7 @@ Is Submittable,ده Submittable, Is Table,ده جدول, Is Your Company Address,آیا ستاسو شرکت پته, It is risky to delete this file: {0}. Please contact your System Manager.,دا خطرناکه چې د دغې دوتنې د ړنګولو: {0}. لطفا د خپل سیستم د مدیر سره اړیکه., -Item cannot be added to its own descendents,د قالب د خپل descendents زياته نه شي, +Item cannot be added to its own descendants,د قالب د خپل descendants زياته نه شي, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},د جاوا شکل: frappe.query_reports [ 'REPORTNAME'] = {}, diff --git a/frappe/translations/pt-BR.csv b/frappe/translations/pt-BR.csv index d4dfe920ae..7fd601bfa0 100644 --- a/frappe/translations/pt-BR.csv +++ b/frappe/translations/pt-BR.csv @@ -1395,7 +1395,7 @@ Is Submittable,Pode ser Enviado, Is Table,É Tabela, Is Your Company Address,É o seu endereço comercial, It is risky to delete this file: {0}. Please contact your System Manager.,É arriscado excluir este arquivo: {0}. Entre em contato com o administrador do sistema., -Item cannot be added to its own descendents,O artigo não pode ser acrescentado para os seus próprios descendentes, +Item cannot be added to its own descendants,O artigo não pode ser acrescentado para os seus próprios descendentes, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},Formato JavaScript: frappe.query_reports [' REPORTNAME '] = {}, diff --git a/frappe/translations/pt.csv b/frappe/translations/pt.csv index cf4a72e458..0078d6ae7c 100644 --- a/frappe/translations/pt.csv +++ b/frappe/translations/pt.csv @@ -1395,7 +1395,7 @@ Is Submittable,É Enviável, Is Table,É uma Tabela, Is Your Company Address,É o Seu Endereço Empresarial, It is risky to delete this file: {0}. Please contact your System Manager.,"É arriscado eliminar este ficheiro: {0}. Por favor, contate o administrador do sistema.", -Item cannot be added to its own descendents,O item não pode ser acrescentado para aos seus próprios subitens, +Item cannot be added to its own descendants,O item não pode ser acrescentado para aos seus próprios subitens, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},Formato JavaScript:\nfrappe.query_reports['REPORTNAME'] = {}, diff --git a/frappe/translations/ro.csv b/frappe/translations/ro.csv index 89a7b2edb6..ac20252022 100644 --- a/frappe/translations/ro.csv +++ b/frappe/translations/ro.csv @@ -1395,7 +1395,7 @@ Is Submittable,Este Submittable, Is Table,este Tabelul, Is Your Company Address,Este Adresa companie, It is risky to delete this file: {0}. Please contact your System Manager.,Este riscant să ștergeți acest fișier: {0}. Vă rugăm să contactați Managerul de sistem., -Item cannot be added to its own descendents,Articol nu poate fi adăugat la propriile descendenți, +Item cannot be added to its own descendants,Articol nu poate fi adăugat la propriile descendenți, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript Format: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/ru.csv b/frappe/translations/ru.csv index bcd02baf93..e508ec2cb8 100644 --- a/frappe/translations/ru.csv +++ b/frappe/translations/ru.csv @@ -1391,7 +1391,7 @@ Is Submittable,Подлежит исполнению, Is Table,Является таблицей, Is Your Company Address,Является адресом вашей компании, It is risky to delete this file: {0}. Please contact your System Manager.,"Рискованно удалять этот файл: {0}. Пожалуйста, обратитесь к менеджеру системы.", -Item cannot be added to its own descendents,Продукт не может быть добавлен к своим подпродуктам, +Item cannot be added to its own descendants,Продукт не может быть добавлен к своим подпродуктам, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},Формат JavaScript: frappe.query_reports ['REPORTNAME'] = {}, Javascript to append to the head section of the page.,Javascript для добавления к головной части страницы., John Doe,Джон Доу, diff --git a/frappe/translations/rw.csv b/frappe/translations/rw.csv index c33436fd2a..d924c53f2a 100644 --- a/frappe/translations/rw.csv +++ b/frappe/translations/rw.csv @@ -1395,7 +1395,7 @@ Is Submittable,Birashoboka, Is Table,Ni Imbonerahamwe, Is Your Company Address,Ese Aderesi Yawe, It is risky to delete this file: {0}. Please contact your System Manager.,Ni bibi gusiba iyi dosiye: {0}. Nyamuneka saba umuyobozi wa sisitemu., -Item cannot be added to its own descendents,Ikintu ntigishobora kongerwaho ababakomokaho, +Item cannot be added to its own descendants,Ikintu ntigishobora kongerwaho ababakomokaho, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},Imiterere ya JavaScript: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/si.csv b/frappe/translations/si.csv index 8ee60ca34f..7af030cf6e 100644 --- a/frappe/translations/si.csv +++ b/frappe/translations/si.csv @@ -1395,7 +1395,7 @@ Is Submittable,Submittable වේ, Is Table,වගුව වේ, Is Your Company Address,ඔබේ සමාගම ලිපිනය වේ, It is risky to delete this file: {0}. Please contact your System Manager.,{0}: මෙම ගොනුව මකා දමන්න කිරීම අවදානම් හගත. ඔබේ පද්ධතිය කළමනාකරු හා සම්බන්ධ වන්න., -Item cannot be added to its own descendents,අයිතමය තමන්ගේ ම පැවත එන්නන් එකතු කළ නොහැකි, +Item cannot be added to its own descendants,අයිතමය තමන්ගේ ම පැවත එන්නන් එකතු කළ නොහැකි, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},ජාවාස්ක්රිප්ට් ආකෘතිය: frappe.query_reports [ 'REPORTNAME'] = {}, diff --git a/frappe/translations/sk.csv b/frappe/translations/sk.csv index d167f710a6..8d3bd829d2 100644 --- a/frappe/translations/sk.csv +++ b/frappe/translations/sk.csv @@ -1395,7 +1395,7 @@ Is Submittable,Je Odeslatelné, Is Table,je Tabuľka, Is Your Company Address,Je vaša firma adresa, It is risky to delete this file: {0}. Please contact your System Manager.,"Je to riskantné zmazať tento súbor: {0}. Prosím, obráťte sa na správcu systému.", -Item cannot be added to its own descendents,Položka nemůže být přidána jako svůj vlastní podřízený potomek, +Item cannot be added to its own descendants,Položka nemůže být přidána jako svůj vlastní podřízený potomek, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript Formát: frappe.query_reports['REPORTNAME'] = {}, diff --git a/frappe/translations/sl.csv b/frappe/translations/sl.csv index ef6d0aba90..ba3959a523 100644 --- a/frappe/translations/sl.csv +++ b/frappe/translations/sl.csv @@ -1395,7 +1395,7 @@ Is Submittable,Je Submittable, Is Table,je tabela, Is Your Company Address,Je vaše podjetje naslov, It is risky to delete this file: {0}. Please contact your System Manager.,To je tvegano izbrisati to datoteko: {0}. Obrnite se na upravitelja sistema., -Item cannot be added to its own descendents,Postavka ni mogoče dodati na svoje potomce, +Item cannot be added to its own descendants,Postavka ni mogoče dodati na svoje potomce, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript obliko: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/sq.csv b/frappe/translations/sq.csv index cf2c1a5f4e..dd314df2c6 100644 --- a/frappe/translations/sq.csv +++ b/frappe/translations/sq.csv @@ -1395,7 +1395,7 @@ Is Submittable,Është Submittable, Is Table,A Tabela, Is Your Company Address,Është kompania juaj Adresa, It is risky to delete this file: {0}. Please contact your System Manager.,Kjo është e rrezikshme për të fshirë këtë skedë: {0}. Ju lutemi të kontaktoni Sistemit Soccer tuaj., -Item cannot be added to its own descendents,Item nuk mund të shtohet për të pasardhësve të vet, +Item cannot be added to its own descendants,Item nuk mund të shtohet për të pasardhësve të vet, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript Formati: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/sr.csv b/frappe/translations/sr.csv index 59f41cedb7..5a607d2a81 100644 --- a/frappe/translations/sr.csv +++ b/frappe/translations/sr.csv @@ -1395,7 +1395,7 @@ Is Submittable,Да ли Субмиттабле, Is Table,је Табела, Is Your Company Address,Ис Иоур Адреса фирме, It is risky to delete this file: {0}. Please contact your System Manager.,То је ризично да избришете ову датотеку: {0}. Обратите се свом Систем Манагер., -Item cannot be added to its own descendents,Продукт не может быть добавлен в своих собственных потомков, +Item cannot be added to its own descendants,Продукт не может быть добавлен в своих собственных потомков, JS,ЈС, JSON,ЈСОН, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},Јава формат : вн.куери_репортс [ ' РЕПОРТНАМЕ ' ] = { }, diff --git a/frappe/translations/sv.csv b/frappe/translations/sv.csv index 5c6a4fc20f..be38d7fef5 100644 --- a/frappe/translations/sv.csv +++ b/frappe/translations/sv.csv @@ -1395,7 +1395,7 @@ Is Submittable,Är Skickad, Is Table,är Table, Is Your Company Address,Är ditt Företag Adress, It is risky to delete this file: {0}. Please contact your System Manager.,Det är riskabelt att ta bort denna fil: {0}. Kontakta din systemadministratören., -Item cannot be added to its own descendents,Produkt kan inte läggas till sina egna underprodukter, +Item cannot be added to its own descendants,Produkt kan inte läggas till sina egna underprodukter, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript Format: frappe.query_reports ['rapportnamn'] = {}, diff --git a/frappe/translations/sw.csv b/frappe/translations/sw.csv index 21d0e364d3..82da08bee9 100644 --- a/frappe/translations/sw.csv +++ b/frappe/translations/sw.csv @@ -1395,7 +1395,7 @@ Is Submittable,Inawasilishwa, Is Table,"Je, ni Jedwali", Is Your Company Address,Ni Anwani ya Kampuni Yako, It is risky to delete this file: {0}. Please contact your System Manager.,Ni hatari kufuta faili hii: {0}. Tafadhali wasiliana na Meneja wa Mfumo wako., -Item cannot be added to its own descendents,Kipengee hawezi kuongezwa kwa wazazi wake, +Item cannot be added to its own descendants,Kipengee hawezi kuongezwa kwa wazazi wake, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},Jarida la Javascript: vivutio vya usafiri ['REPORTNAME'] = {}, diff --git a/frappe/translations/ta.csv b/frappe/translations/ta.csv index faf857b714..75690e2769 100644 --- a/frappe/translations/ta.csv +++ b/frappe/translations/ta.csv @@ -1395,7 +1395,7 @@ Is Submittable,சமர்ப்பிக்க, Is Table,அட்டவணை உள்ளது, Is Your Company Address,உங்கள் நிறுவனத்தின் முகவரி, It is risky to delete this file: {0}. Please contact your System Manager.,இந்த கோப்பு நீக்க ஆபத்தானது: {0}. உங்கள் கணினி மேலாளரைத் தொடர்பு கொள்ளவும்., -Item cannot be added to its own descendents,பொருள் அதன் சொந்த ஆதரவாளர்வரை சேர்க்க முடியாது, +Item cannot be added to its own descendants,பொருள் அதன் சொந்த ஆதரவாளர்வரை சேர்க்க முடியாது, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},ஜாவா வடிவம்: frappe.query_reports [' REPORTNAME '] = { }, diff --git a/frappe/translations/te.csv b/frappe/translations/te.csv index df72e7e710..4ea5b55143 100644 --- a/frappe/translations/te.csv +++ b/frappe/translations/te.csv @@ -1395,7 +1395,7 @@ Is Submittable,Submittable ఉంది, Is Table,పట్టిక, Is Your Company Address,మీ కంపెనీ అడ్రస్ ఇస్, It is risky to delete this file: {0}. Please contact your System Manager.,ఇది ఈ ఫైల్ను మీరు తొలగించాలని ప్రమాదకర ఉంది: {0}. మీ సిస్టమ్ నిర్వాహకుడిని సంప్రదించండి., -Item cannot be added to its own descendents,అంశం దాని సొంత వంశస్థులు జోడించబడింది సాధ్యం కాదు, +Item cannot be added to its own descendants,అంశం దాని సొంత వంశస్థులు జోడించబడింది సాధ్యం కాదు, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},జావాస్క్రిప్ట్ ఫార్మాట్: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/th.csv b/frappe/translations/th.csv index f168e5ac00..452ef0e961 100644 --- a/frappe/translations/th.csv +++ b/frappe/translations/th.csv @@ -1395,7 +1395,7 @@ Is Submittable,เป็น Submittable, Is Table,เป็นตาราง, Is Your Company Address,คือที่อยู่ บริษัท ของคุณ, It is risky to delete this file: {0}. Please contact your System Manager.,มันเป็นความเสี่ยงที่จะลบไฟล์นี้: {0} โปรดติดต่อผู้จัดการของระบบ, -Item cannot be added to its own descendents,รายการที่ ไม่สามารถเพิ่ม ไปยัง ลูกหลาน ของตัวเอง, +Item cannot be added to its own descendants,รายการที่ ไม่สามารถเพิ่ม ไปยัง ลูกหลาน ของตัวเอง, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},รูปแบบ JavaScript : frappe.query_reports [ 'ชื่อรายงาน' ] = { }, diff --git a/frappe/translations/tr.csv b/frappe/translations/tr.csv index a16e68f640..11d7c03535 100644 --- a/frappe/translations/tr.csv +++ b/frappe/translations/tr.csv @@ -1395,7 +1395,7 @@ Is Submittable,Submittable mi, Is Table,Tablo mu, Is Your Company Address,Firmanız Adresi, It is risky to delete this file: {0}. Please contact your System Manager.,Bu dosyayı silmek için riskli: {0}. Sistem Yöneticisi irtibata geçiniz., -Item cannot be added to its own descendents,"Ürün, kendi soyundan ilave edilemez", +Item cannot be added to its own descendants,"Ürün, kendi soyundan ilave edilemez", JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript Format: frappe.query_reports ['ReportName'] = {}, diff --git a/frappe/translations/uk.csv b/frappe/translations/uk.csv index bdc06f4b1a..3caa7e6608 100644 --- a/frappe/translations/uk.csv +++ b/frappe/translations/uk.csv @@ -1395,7 +1395,7 @@ Is Submittable,Є Submittable, Is Table,Чи є таблиця, Is Your Company Address,Є адресою Вашої компанії, It is risky to delete this file: {0}. Please contact your System Manager.,"Це ризиковано, щоб видалити цей файл: {0}. Будь ласка, зверніться до менеджера системи.", -Item cannot be added to its own descendents,Товар не може бути доданий у власних нащадків, +Item cannot be added to its own descendants,Товар не може бути доданий у власних нащадків, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript Формат: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/ur.csv b/frappe/translations/ur.csv index 21101a7975..639833fa3b 100644 --- a/frappe/translations/ur.csv +++ b/frappe/translations/ur.csv @@ -1395,7 +1395,7 @@ Is Submittable,Submittable ہے, Is Table,ٹیبل ہے, Is Your Company Address,آپ کی کمپنی ایڈریس ہے, It is risky to delete this file: {0}. Please contact your System Manager.,اس فائل کو حذف کرنا خطرناک ہے: {0}. آپ کے سسٹم مینیجر سے رابطہ کریں., -Item cannot be added to its own descendents,آئٹم کو اس کی اپنی اولاد میں شامل نہیں کیا جا سکتا, +Item cannot be added to its own descendants,آئٹم کو اس کی اپنی اولاد میں شامل نہیں کیا جا سکتا, JS,جے ایس, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},جاوا کی شکل: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/uz.csv b/frappe/translations/uz.csv index 8c1056286b..a94c5ac9b8 100644 --- a/frappe/translations/uz.csv +++ b/frappe/translations/uz.csv @@ -1395,7 +1395,7 @@ Is Submittable,Submittable mavjud, Is Table,Jadval bormi?, Is Your Company Address,Sizning kompaniyangiz manzili, It is risky to delete this file: {0}. Please contact your System Manager.,"Ushbu faylni o'chirish xavfli: {0}. Iltimos, tizim boshqaruvchisiga murojaat qiling.", -Item cannot be added to its own descendents,Mavzu o'z avlodlariga qo'shilmaydi, +Item cannot be added to its own descendants,Mavzu o'z avlodlariga qo'shilmaydi, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript formati: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/vi.csv b/frappe/translations/vi.csv index a3e92fd3df..64d27bd96d 100644 --- a/frappe/translations/vi.csv +++ b/frappe/translations/vi.csv @@ -1395,7 +1395,7 @@ Is Submittable,CÓ thể đệ trình, Is Table,là Bảng, Is Your Company Address,Là Địa chỉ công ty của bạn, It is risky to delete this file: {0}. Please contact your System Manager.,Có rủi ro khi xóa tập tin này: {0}. Vui lòng liên hệ Quản lý Hệ thống của bạn., -Item cannot be added to its own descendents,Mẫu hàng không thể được thêm vào các phần sau của mình, +Item cannot be added to its own descendants,Mẫu hàng không thể được thêm vào các phần sau của mình, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},Định dạng JavaScript: frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/translations/zh-TW.csv b/frappe/translations/zh-TW.csv index b95eda8b01..3531daa4c0 100644 --- a/frappe/translations/zh-TW.csv +++ b/frappe/translations/zh-TW.csv @@ -1765,7 +1765,7 @@ apps/frappe/frappe/public/js/frappe/form/linked_with.js +104,Not enough permissi apps/frappe/frappe/contacts/doctype/address/address.py +37,Address Title is mandatory.,地址標題是強制性的。 DocType: Website Settings,"Added HTML in the <head> section of the web page, primarily used for website verification and SEO",在<head>添加HTML網頁的部分,主要用於網站的驗證和搜索引擎優化 apps/frappe/frappe/core/doctype/error_snapshot/error_snapshot_list.js +9,Relapsed,復發 -apps/frappe/frappe/utils/nestedset.py +183,Item cannot be added to its own descendents,項目不能被添加到自己的後代 +apps/frappe/frappe/utils/nestedset.py +183,Item cannot be added to its own descendants,項目不能被添加到自己的後代 DocType: System Settings,Expiry time of QR Code Image Page,QR碼圖像頁面的到期時間 apps/frappe/frappe/public/js/frappe/views/reports/reportview.js +614,Show Totals,顯示總計 DocType: Error Snapshot,Relapses,復發 diff --git a/frappe/translations/zh.csv b/frappe/translations/zh.csv index c82c64b5f5..6f3b3b597f 100644 --- a/frappe/translations/zh.csv +++ b/frappe/translations/zh.csv @@ -1395,7 +1395,7 @@ Is Submittable,是否可以提交, Is Table,为表, Is Your Company Address,是你的公司地址, It is risky to delete this file: {0}. Please contact your System Manager.,删除这个文件是有风险的:{0}。请联系您的系统管理员。, -Item cannot be added to its own descendents,项目不能被添加到自己的后代, +Item cannot be added to its own descendants,项目不能被添加到自己的后代, JS,JS, JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},JavaScript格式:frappe.query_reports ['REPORTNAME'] = {}, diff --git a/frappe/utils/file_lock.py b/frappe/utils/file_lock.py index fc399f7c96..5be89c42f6 100644 --- a/frappe/utils/file_lock.py +++ b/frappe/utils/file_lock.py @@ -1,22 +1,34 @@ # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE -""" -File based locking utility +"""Utils for inter-process synchronization using file-locks. + +This file implements a "weak" form lock which is not suitable for synchroniztion. This is only used +for document locking for queue_action. +Use `frappe.utils.synchroniztion.filelock` for process synchroniztion. """ import os from time import time +from frappe import _ from frappe.utils import get_site_path, touch_file +LOCKS_DIR = "locks" + class LockTimeoutError(Exception): pass def create_lock(name): - """Creates a file in the /locks folder by the given name""" + """Creates a file in the /locks folder by the given name. + + Note: This is a "weak lock" and is prone to race conditions. Do not use this lock for small + sections of code that execute immediately. + + This is primarily use for locking documents for background submission. + """ lock_path = get_lock_path(name) if not check_lock(lock_path): return touch_file(lock_path) @@ -48,6 +60,5 @@ def delete_lock(name): def get_lock_path(name): name = name.lower() - locks_dir = "locks" - lock_path = get_site_path(locks_dir, name + ".lock") + lock_path = get_site_path(LOCKS_DIR, name + ".lock") return lock_path diff --git a/frappe/utils/install.py b/frappe/utils/install.py index 1f1f648503..cd15c957f9 100644 --- a/frappe/utils/install.py +++ b/frappe/utils/install.py @@ -3,6 +3,7 @@ import getpass import frappe +from frappe.geo.doctype.country.country import import_country_and_currency from frappe.utils.password import update_password @@ -22,13 +23,10 @@ def after_install(): install_basic_docs() from frappe.core.doctype.file.utils import make_home_folder - - make_home_folder() - - import_country_and_currency() - from frappe.core.doctype.language.language import sync_languages + make_home_folder() + import_country_and_currency() sync_languages() # save default print setting @@ -171,6 +169,7 @@ def before_tests(): if not int(frappe.db.get_single_value("System Settings", "setup_complete") or 0): complete_setup_wizard() + frappe.db.set_value("Website Settings", "Website Settings", "disable_signup", 0) frappe.db.commit() frappe.clear_cache() @@ -191,53 +190,6 @@ def complete_setup_wizard(): ) -def import_country_and_currency(): - from frappe.geo.country_info import get_all - from frappe.utils import update_progress_bar - - data = get_all() - - for i, name in enumerate(data): - update_progress_bar("Updating country info", i, len(data)) - country = frappe._dict(data[name]) - add_country_and_currency(name, country) - - print("") - - # enable frequently used currencies - for currency in ("INR", "USD", "GBP", "EUR", "AED", "AUD", "JPY", "CNY", "CHF"): - frappe.db.set_value("Currency", currency, "enabled", 1) - - -def add_country_and_currency(name, country): - if not frappe.db.exists("Country", name): - frappe.get_doc( - { - "doctype": "Country", - "country_name": name, - "code": country.code, - "date_format": country.date_format or "dd-mm-yyyy", - "time_format": country.time_format or "HH:mm:ss", - "time_zones": "\n".join(country.timezones or []), - "docstatus": 0, - } - ).db_insert() - - if country.currency and not frappe.db.exists("Currency", country.currency): - frappe.get_doc( - { - "doctype": "Currency", - "currency_name": country.currency, - "fraction": country.currency_fraction, - "symbol": country.currency_symbol, - "fraction_units": country.currency_fraction_units, - "smallest_currency_fraction_value": country.smallest_currency_fraction_value, - "number_format": country.number_format, - "docstatus": 0, - } - ).db_insert() - - def add_standard_navbar_items(): navbar_settings = frappe.get_single("Navbar Settings") diff --git a/frappe/utils/nestedset.py b/frappe/utils/nestedset.py index 1112b593c5..374851e019 100644 --- a/frappe/utils/nestedset.py +++ b/frappe/utils/nestedset.py @@ -234,7 +234,7 @@ def validate_loop(doctype, name, lft, rgt): if name in frappe.get_all( doctype, filters={"lft": ["<=", lft], "rgt": [">=", rgt]}, pluck="name" ): - frappe.throw(_("Item cannot be added to its own descendents"), NestedSetRecursionError) + frappe.throw(_("Item cannot be added to its own descendants"), NestedSetRecursionError) def remove_subtree(doctype: str, name: str, throw=True): diff --git a/frappe/utils/synchronization.py b/frappe/utils/synchronization.py new file mode 100644 index 0000000000..841fab85ff --- /dev/null +++ b/frappe/utils/synchronization.py @@ -0,0 +1,49 @@ +""" Utils for thread/process synchronization. """ + +import os +from contextlib import contextmanager + +from filelock import FileLock as _StrongFileLock +from filelock import Timeout + +import frappe +from frappe import _ +from frappe.utils import get_bench_path, get_site_path +from frappe.utils.file_lock import LockTimeoutError + +LOCKS_DIR = "locks" + + +@contextmanager +def filelock(lock_name: str, *, timeout=30, is_global=False): + """Create a lockfile to prevent concurrent operations acrosss processes. + + args: + lock_name: Unique name to identify a specific lock. Lockfile called `{name}.lock` will be + created. + timeout: time to wait before failing. + is_global: if set lock is global to bench + + Lock file location: + global - {bench_dir}/config/{name}.lock + site - {bench_dir}/sites/sitename/{name}.lock + + """ + + lock_filename = lock_name + ".lock" + if not is_global: + lock_path = os.path.abspath(get_site_path(LOCKS_DIR, lock_filename)) + else: + lock_path = os.path.abspath(os.path.join(get_bench_path(), "config", lock_filename)) + + try: + with _StrongFileLock(lock_path, timeout=timeout): + yield + except Timeout as e: + frappe.log_error("Filelock: Failed to aquire {lock_path}") + + raise LockTimeoutError( + _("Failed to aquire lock: {}").format(lock_name) + + "
" + + _("You can manually remove the lock if you think it's safe: {}").format(lock_path) + ) from e diff --git a/frappe/website/doctype/web_form/web_form.py b/frappe/website/doctype/web_form/web_form.py index d102ac2fd8..73b2dc2331 100644 --- a/frappe/website/doctype/web_form/web_form.py +++ b/frappe/website/doctype/web_form/web_form.py @@ -342,7 +342,7 @@ def get_context(context): return False if self.apply_document_permissions: - return frappe.get_doc(doctype, name).has_permission() + return frappe.get_doc(doctype, name).has_permission(permtype=ptype) # owner matches elif frappe.db.get_value(doctype, name, "owner") == frappe.session.user: @@ -365,7 +365,7 @@ def get_web_form_module(doc): @frappe.whitelist(allow_guest=True) @rate_limit(key="web_form", limit=5, seconds=60, methods=["POST"]) -def accept(web_form, data, docname=None): +def accept(web_form, data): """Save the web form""" data = frappe._dict(json.loads(data)) @@ -373,19 +373,20 @@ def accept(web_form, data, docname=None): files_to_delete = [] web_form = frappe.get_doc("Web Form", web_form) + doctype = web_form.doc_type if data.name and not web_form.allow_edit: frappe.throw(_("You are not allowed to update this Web Form Document")) frappe.flags.in_web_form = True - meta = frappe.get_meta(data.doctype) + meta = frappe.get_meta(doctype) - if docname: + if data.name: # update - doc = frappe.get_doc(data.doctype, docname) + doc = frappe.get_doc(doctype, data.name) else: # insert - doc = frappe.new_doc(data.doctype) + doc = frappe.new_doc(doctype) # set values for field in web_form.web_form_fields: @@ -406,7 +407,7 @@ def accept(web_form, data, docname=None): doc.set(fieldname, value) if doc.name: - if web_form.has_web_form_permission(doc.doctype, doc.name, "write"): + if web_form.has_web_form_permission(doctype, doc.name, "write"): doc.save(ignore_permissions=True) else: # only if permissions are present @@ -428,7 +429,7 @@ def accept(web_form, data, docname=None): # remove earlier attached file (if exists) if doc.get(fieldname): - remove_file_by_url(doc.get(fieldname), doctype=doc.doctype, name=doc.name) + remove_file_by_url(doc.get(fieldname), doctype=doctype, name=doc.name) # save new file filename, dataurl = filedata.split(",", 1) @@ -436,7 +437,7 @@ def accept(web_form, data, docname=None): { "doctype": "File", "file_name": filename, - "attached_to_doctype": doc.doctype, + "attached_to_doctype": doctype, "attached_to_name": doc.name, "content": dataurl, "decode": True, @@ -452,7 +453,7 @@ def accept(web_form, data, docname=None): if files_to_delete: for f in files_to_delete: if f: - remove_file_by_url(f, doctype=doc.doctype, name=doc.name) + remove_file_by_url(f, doctype=doctype, name=doc.name) frappe.flags.web_form_doc = doc return doc diff --git a/frappe/website/doctype/website_settings/website_settings.json b/frappe/website/doctype/website_settings/website_settings.json index 29827afd80..3bf7e4cb30 100644 --- a/frappe/website/doctype/website_settings/website_settings.json +++ b/frappe/website/doctype/website_settings/website_settings.json @@ -247,7 +247,7 @@ "read_only": 1 }, { - "default": "0", + "default": "1", "description": "Disable Customer Signup link in Login page", "fieldname": "disable_signup", "fieldtype": "Check", @@ -476,7 +476,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2022-10-18 09:50:24.621839", + "modified": "2022-12-05 04:17:56.478757", "modified_by": "Administrator", "module": "Website", "name": "Website Settings", diff --git a/pyproject.toml b/pyproject.toml index f5ab8c94b2..dcd7599e9a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,6 +11,7 @@ dependencies = [ # core dependencies "Babel~=2.9.0", "Click~=7.1.2", + "filelock~=3.8.0", "GitPython~=3.1.14", "Jinja2~=3.1.2", "Pillow~=9.3.0", diff --git a/yarn.lock b/yarn.lock index a4204b0c64..acf5e0c9c0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -89,14 +89,16 @@ integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== "@types/cors@^2.8.12": - version "2.8.12" - resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" - integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== + version "2.8.13" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.13.tgz#b8ade22ba455a1b8cb3b5d3f35910fd204f84f94" + integrity sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA== + dependencies: + "@types/node" "*" -"@types/node@>=10.0.0": - version "18.0.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.0.tgz#67c7b724e1bcdd7a8821ce0d5ee184d3b4dd525a" - integrity sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA== +"@types/node@*", "@types/node@>=10.0.0": + version "18.11.11" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.11.tgz#1d455ac0211549a8409d3cdb371cd55cc971e8dc" + integrity sha512-KJ021B1nlQUBLopzZmPBVuGU9un7WJd/W4ya7Ih02B4Uwky5Nja0yGYav2EfYIk0RR2Q9oVhf60S2XR1BCWJ2g== "@types/web-bluetooth@^0.0.16": version "0.0.16" @@ -316,12 +318,12 @@ abbrev@1: integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== accepts@~1.3.4: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" + mime-types "~2.1.34" + negotiator "0.6.3" ace-builds@^1.4.8: version "1.4.8" @@ -726,15 +728,10 @@ constantinople@^4.0.1: "@babel/parser" "^7.6.0" "@babel/types" "^7.6.1" -cookie@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" - integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== - -cookie@~0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" - integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== +cookie@^0.4.0, cookie@~0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== cookiejar@^2.1.0: version "2.1.2" @@ -1070,9 +1067,9 @@ engine.io-parser@~5.0.3: integrity sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg== engine.io@~6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.2.0.tgz#003bec48f6815926f2b1b17873e576acd54f41d0" - integrity sha512-4KzwW3F3bk+KlzSOY57fj/Jx6LyRQ1nbcyIadehl+AnXjKT7gDO0ORdRi/84ixvMKTym6ZKuxvbzN62HDDU1Lg== + version "6.2.1" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.2.1.tgz#e3f7826ebc4140db9bbaa9021ad6b1efb175878f" + integrity sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA== dependencies: "@types/cookie" "^0.4.1" "@types/cors" "^2.8.12" @@ -2104,16 +2101,16 @@ micromatch@^4.0.2: braces "^3.0.1" picomatch "^2.0.5" -mime-db@1.43.0: - version "1.43.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" - integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== - mime-db@1.44.0: version "1.44.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + mime-types@^2.1.12: version "2.1.27" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" @@ -2121,12 +2118,12 @@ mime-types@^2.1.12: dependencies: mime-db "1.44.0" -mime-types@~2.1.24: - version "2.1.26" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" - integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== +mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: - mime-db "1.43.0" + mime-db "1.52.0" mime@^1.4.1: version "1.6.0" @@ -2201,10 +2198,10 @@ needle@^2.5.2: iconv-lite "^0.4.4" sax "^1.2.4" -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== node-releases@^1.1.71: version "1.1.77" @@ -3551,7 +3548,7 @@ util-deprecate@^1.0.2, util-deprecate@~1.0.1: vary@^1: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== void-elements@^3.1.0: version "3.1.0"