From 4df9a203f0019dfd1faacaf1be5c47cb5b2eb073 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Tue, 29 Dec 2020 14:14:29 +0530 Subject: [PATCH 01/16] feat: fetch email account signature in email dialog --- frappe/public/js/frappe/views/communication.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/views/communication.js b/frappe/public/js/frappe/views/communication.js index 29b21242af..fe14ad4793 100755 --- a/frappe/public/js/frappe/views/communication.js +++ b/frappe/public/js/frappe/views/communication.js @@ -464,6 +464,7 @@ frappe.views.CommunicationComposer = Class.extend({ }, send_action: function() { + debugger; var me = this; var btn = me.dialog.get_primary_btn(); @@ -625,10 +626,19 @@ frappe.views.CommunicationComposer = Class.extend({ } }, - setup_earlier_reply: function() { + get_default_outgoing_email_account_signature: function() { + return frappe.db.get_value('Email Account', { 'default_outgoing': 1, 'add_signature': 1 }, 'signature'); + }, + + setup_earlier_reply: async function() { let fields = this.dialog.fields_dict; let signature = frappe.boot.user.email_signature || ""; + if (!signature) { + const res = await this.get_default_outgoing_email_account_signature(); + signature = res.message.signature; + } + if(!frappe.utils.is_html(signature)) { signature = signature.replace(/\n/g, "
"); } From 1591cee1457b51d1d58765abd92afbd435b5cfac Mon Sep 17 00:00:00 2001 From: Saqib Date: Wed, 6 Jan 2021 17:08:57 +0530 Subject: [PATCH 02/16] fix: remove debugger --- frappe/public/js/frappe/views/communication.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/frappe/public/js/frappe/views/communication.js b/frappe/public/js/frappe/views/communication.js index fe14ad4793..e974cd52ed 100755 --- a/frappe/public/js/frappe/views/communication.js +++ b/frappe/public/js/frappe/views/communication.js @@ -464,7 +464,6 @@ frappe.views.CommunicationComposer = Class.extend({ }, send_action: function() { - debugger; var me = this; var btn = me.dialog.get_primary_btn(); @@ -719,4 +718,3 @@ frappe.views.CommunicationComposer = Class.extend({ return text.replace(/\n{3,}/g, '\n\n'); } }); - From 64f3887dce25da4d93d9bc2b0eccc4f04a744ce2 Mon Sep 17 00:00:00 2001 From: "hasnain2808@gmail.com" Date: Wed, 13 Jan 2021 16:00:23 +0530 Subject: [PATCH 03/16] fix: html download of auto download report broken --- .../doctype/auto_email_report/auto_email_report.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/frappe/email/doctype/auto_email_report/auto_email_report.py b/frappe/email/doctype/auto_email_report/auto_email_report.py index 539f6c9db8..de27fafee3 100644 --- a/frappe/email/doctype/auto_email_report/auto_email_report.py +++ b/frappe/email/doctype/auto_email_report/auto_email_report.py @@ -81,7 +81,7 @@ class AutoEmailReport(Document): if self.format == 'HTML': columns, data = make_links(columns, data) - + columns = update_field_types(columns) return self.get_html_table(columns, data) elif self.format == 'XLSX': @@ -236,5 +236,14 @@ def make_links(columns, data): elif col.fieldtype == "Dynamic Link": if col.options and row.get(col.fieldname) and row.get(col.options): row[col.fieldname] = get_link_to_form(row[col.options], row[col.fieldname]) + elif col.fieldtype == "Currency": + row[col.fieldname] = frappe.format_value(row[col.fieldname], col) return columns, data + +def update_field_types(columns): + for col in columns: + if col.fieldtype in ("Link", "Dynamic Link", "Currency") and col.options != "Currency": + col.fieldtype = "Data" + col.options = "" + return columns \ No newline at end of file From 962fff15c4a350362edeedabb5cf2a452972f045 Mon Sep 17 00:00:00 2001 From: shariquerik Date: Mon, 18 Jan 2021 20:49:09 +0530 Subject: [PATCH 04/16] Link Field Validation doesn't use Filter criteria defined for link field In link field if we enter invalid i.e not available record it will clear field but if we enter valid record that is not available in filter but available in db than it will accept that record --- frappe/public/js/frappe/form/controls/link.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frappe/public/js/frappe/form/controls/link.js b/frappe/public/js/frappe/form/controls/link.js index 4c0fe39f60..019ea5ca58 100644 --- a/frappe/public/js/frappe/form/controls/link.js +++ b/frappe/public/js/frappe/form/controls/link.js @@ -455,6 +455,11 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({ fetch = this.frm.fetch_dict[df.fieldname].columns.join(', '); } + // check if value exist in the filtered dropdown values + if(this.$input.cache[doctype][""] && !this.$input.cache[doctype][""].some(d => d.value === value)){ + value = "" + } + return frappe.call({ method:'frappe.desk.form.utils.validate_link', type: "GET", From ebcb8438de691eb085528912253a0b17ee03dee9 Mon Sep 17 00:00:00 2001 From: shariquerik Date: Mon, 18 Jan 2021 21:45:07 +0530 Subject: [PATCH 05/16] fix: semantic commit and sider issues --- frappe/public/js/frappe/form/controls/link.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/public/js/frappe/form/controls/link.js b/frappe/public/js/frappe/form/controls/link.js index 019ea5ca58..6ac10c8534 100644 --- a/frappe/public/js/frappe/form/controls/link.js +++ b/frappe/public/js/frappe/form/controls/link.js @@ -456,8 +456,8 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({ } // check if value exist in the filtered dropdown values - if(this.$input.cache[doctype][""] && !this.$input.cache[doctype][""].some(d => d.value === value)){ - value = "" + if (this.$input.cache[doctype][""] && !this.$input.cache[doctype][""].some(d => d.value === value)) { + value = ""; } return frappe.call({ From 83822b14c6e6aded305c00fefee679833c4ee2ab Mon Sep 17 00:00:00 2001 From: shariquerik Date: Tue, 19 Jan 2021 14:07:19 +0530 Subject: [PATCH 06/16] fix: Updated if condition --- frappe/public/js/frappe/form/controls/link.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/form/controls/link.js b/frappe/public/js/frappe/form/controls/link.js index 6ac10c8534..77716ee60a 100644 --- a/frappe/public/js/frappe/form/controls/link.js +++ b/frappe/public/js/frappe/form/controls/link.js @@ -456,7 +456,7 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({ } // check if value exist in the filtered dropdown values - if (this.$input.cache[doctype][""] && !this.$input.cache[doctype][""].some(d => d.value === value)) { + if (this.$input.cache[doctype] && !this.$input.cache[doctype][""].some(d => d.value === value)) { value = ""; } From bcae1cc294fac0aeeb90f68d57f7db1f673865aa Mon Sep 17 00:00:00 2001 From: shariquerik Date: Tue, 19 Jan 2021 22:29:23 +0530 Subject: [PATCH 07/16] revert --- frappe/public/js/frappe/form/controls/link.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/public/js/frappe/form/controls/link.js b/frappe/public/js/frappe/form/controls/link.js index 77716ee60a..019ea5ca58 100644 --- a/frappe/public/js/frappe/form/controls/link.js +++ b/frappe/public/js/frappe/form/controls/link.js @@ -456,8 +456,8 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({ } // check if value exist in the filtered dropdown values - if (this.$input.cache[doctype] && !this.$input.cache[doctype][""].some(d => d.value === value)) { - value = ""; + if(this.$input.cache[doctype][""] && !this.$input.cache[doctype][""].some(d => d.value === value)){ + value = "" } return frappe.call({ From 099474a441f922fab40e8ac1aa1fc26c851b7344 Mon Sep 17 00:00:00 2001 From: shariquerik Date: Tue, 19 Jan 2021 22:29:30 +0530 Subject: [PATCH 08/16] Revert "Link Field Validation doesn't use Filter criteria defined for link field" This reverts commit 962fff15c4a350362edeedabb5cf2a452972f045. --- frappe/public/js/frappe/form/controls/link.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/frappe/public/js/frappe/form/controls/link.js b/frappe/public/js/frappe/form/controls/link.js index 019ea5ca58..4c0fe39f60 100644 --- a/frappe/public/js/frappe/form/controls/link.js +++ b/frappe/public/js/frappe/form/controls/link.js @@ -455,11 +455,6 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({ fetch = this.frm.fetch_dict[df.fieldname].columns.join(', '); } - // check if value exist in the filtered dropdown values - if(this.$input.cache[doctype][""] && !this.$input.cache[doctype][""].some(d => d.value === value)){ - value = "" - } - return frappe.call({ method:'frappe.desk.form.utils.validate_link', type: "GET", From bddb7034cfe67f3669c1a97b915621b03cab422d Mon Sep 17 00:00:00 2001 From: shariquerik Date: Tue, 19 Jan 2021 22:36:33 +0530 Subject: [PATCH 09/16] fix: Geolocation field with Column Break & Section Break (Collapsible) does not seems to work. --- frappe/public/js/frappe/form/controls/geolocation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/form/controls/geolocation.js b/frappe/public/js/frappe/form/controls/geolocation.js index 9e4d1d82ec..dfd0f4d174 100644 --- a/frappe/public/js/frappe/form/controls/geolocation.js +++ b/frappe/public/js/frappe/form/controls/geolocation.js @@ -17,7 +17,7 @@ frappe.ui.form.ControlGeolocation = frappe.ui.form.ControlData.extend({ this.map_area.prependTo($input_wrapper); this.$wrapper.find('.control-input').addClass("hidden"); - if ($input_wrapper.is(':visible')) { + if (this.frm) { this.make_map(); } else { $(document).on('frappe.ui.Dialog:shown', () => { From 19c6e0218db9b1dd95132693a96a8174fac2dc94 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Wed, 20 Jan 2021 22:57:25 +0000 Subject: [PATCH 10/16] fix: requirements.txt to reduce vulnerabilities The following vulnerabilities are fixed by pinning transitive dependencies: - https://snyk.io/vuln/SNYK-PYTHON-PYYAML-590151 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 3cc92264a2..e128790e45 100644 --- a/requirements.txt +++ b/requirements.txt @@ -49,7 +49,7 @@ pypng==0.0.20 PyQRCode==1.2.1 python-dateutil==2.8.1 pytz==2019.3 -PyYAML==5.3.1 +PyYAML==5.4 rauth==0.7.3 redis==3.5.3 requests-oauthlib==1.3.0 From 33ea496a8bd5953714941cfde4d2c1da1982c0b3 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Thu, 21 Jan 2021 13:12:42 +0530 Subject: [PATCH 11/16] feat: Added get_datetime_in_timezone in frappe.utils to get datetime in specific timezones * Added util in safe_exec to access via Server Scripts and System Console --- frappe/utils/data.py | 12 ++++++++++-- frappe/utils/safe_exec.py | 1 + 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/frappe/utils/data.py b/frappe/utils/data.py index c24b9f186e..c60e64b015 100644 --- a/frappe/utils/data.py +++ b/frappe/utils/data.py @@ -154,14 +154,22 @@ def get_time_zone(): return frappe.cache().get_value("time_zone", _get_time_zone) -def convert_utc_to_user_timezone(utc_timestamp): +def convert_utc_to_timezone(utc_timestamp, time_zone): from pytz import timezone, UnknownTimeZoneError utcnow = timezone('UTC').localize(utc_timestamp) try: - return utcnow.astimezone(timezone(get_time_zone())) + return utcnow.astimezone(timezone(time_zone)) except UnknownTimeZoneError: return utcnow +def get_datetime_in_timezone(time_zone): + utc_timestamp = datetime.datetime.utcnow() + return convert_utc_to_timezone(utc_timestamp, time_zone) + +def convert_utc_to_user_timezone(utc_timestamp): + time_zone = get_time_zone() + return convert_utc_to_timezone(utc_timestamp, time_zone) + def now(): """return current datetime as yyyy-mm-dd hh:mm:ss""" if frappe.flags.current_date: diff --git a/frappe/utils/safe_exec.py b/frappe/utils/safe_exec.py index 2aacf5eda8..06a192c05e 100644 --- a/frappe/utils/safe_exec.py +++ b/frappe/utils/safe_exec.py @@ -222,6 +222,7 @@ VALID_UTILS = ( "get_last_day_of_week", "get_last_day", "get_time", +"get_datetime_in_timezone", "get_datetime_str", "get_date_str", "get_time_str", From 16f2b29cb3c1395e8fbaae50d3076b410b4555b7 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Thu, 21 Jan 2021 13:15:14 +0530 Subject: [PATCH 12/16] style: Trim extra whitespace --- frappe/utils/data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/utils/data.py b/frappe/utils/data.py index c60e64b015..da2c910e20 100644 --- a/frappe/utils/data.py +++ b/frappe/utils/data.py @@ -377,7 +377,7 @@ def format_duration(seconds, hide_days=False): example: converts 12885 to '3h 34m 45s' where 12885 = seconds in float """ - + seconds = cint(seconds) total_duration = { From 5c9cc655cfd9b09a40a7f8b5ba555b94899a8225 Mon Sep 17 00:00:00 2001 From: Shariq Ansari <30859809+shariquerik@users.noreply.github.com> Date: Fri, 22 Jan 2021 11:50:04 +0530 Subject: [PATCH 13/16] fix: Insufficient Permission for Leads > Dashboard Chart (#12243) Co-authored-by: Suraj Shetty <13928957+surajshetty3416@users.noreply.github.com> --- frappe/desk/doctype/dashboard_chart/dashboard_chart.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/desk/doctype/dashboard_chart/dashboard_chart.py b/frappe/desk/doctype/dashboard_chart/dashboard_chart.py index 2fa36b5514..b19f6cf9f0 100644 --- a/frappe/desk/doctype/dashboard_chart/dashboard_chart.py +++ b/frappe/desk/doctype/dashboard_chart/dashboard_chart.py @@ -73,7 +73,7 @@ def has_permission(doc, ptype, user): if doc.report_name in allowed_reports: return True else: - allowed_doctypes = [frappe.permissions.get_doctypes_with_read()] + allowed_doctypes = frappe.permissions.get_doctypes_with_read() if doc.document_type in allowed_doctypes: return True From 9b59b59e44211812fe24443ba66cfd56fd9e02cf Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 22 Jan 2021 13:13:50 +0530 Subject: [PATCH 14/16] test: Update TestNewsletter.test_unsubscribe * Update selecting email to unsubscribe email logic * style fixes --- .../doctype/newsletter/test_newsletter.py | 69 ++++++++++--------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/frappe/email/doctype/newsletter/test_newsletter.py b/frappe/email/doctype/newsletter/test_newsletter.py index ee7f123b7e..bd8fadc29c 100644 --- a/frappe/email/doctype/newsletter/test_newsletter.py +++ b/frappe/email/doctype/newsletter/test_newsletter.py @@ -2,58 +2,66 @@ # License: GNU General Public License v3. See license.txt from __future__ import unicode_literals -import frappe, unittest -from frappe.utils import getdate, add_days +import unittest +from random import choice -from frappe.email.doctype.newsletter.newsletter import confirmed_unsubscribe, send_scheduled_email -from six.moves.urllib.parse import unquote +import frappe +from frappe.email.doctype.newsletter.newsletter import ( + confirmed_unsubscribe, + send_scheduled_email, +) +from frappe.email.doctype.newsletter.newsletter import get_newsletter_list +from frappe.email.queue import flush +from frappe.utils import add_days, getdate test_dependencies = ["Email Group"] +emails = [ + "test_subscriber1@example.com", + "test_subscriber2@example.com", + "test_subscriber3@example.com", + "test1@example.com", +] -emails = ["test_subscriber1@example.com", "test_subscriber2@example.com", - "test_subscriber3@example.com", "test1@example.com"] class TestNewsletter(unittest.TestCase): def setUp(self): frappe.set_user("Administrator") - frappe.db.sql('delete from `tabEmail Group Member`') + frappe.db.sql("delete from `tabEmail Group Member`") + + if not frappe.db.exists("Email Group", "_Test Email Group"): + frappe.get_doc({"doctype": "Email Group", "title": "_Test Email Group"}).insert() - group_exist=frappe.db.exists("Email Group", "_Test Email Group") - if len(group_exist) == 0: - frappe.get_doc({ - "doctype": "Email Group", - "title": "_Test Email Group" - }).insert() for email in emails: - frappe.get_doc({ - "doctype": "Email Group Member", - "email": email, - "email_group": "_Test Email Group" - }).insert() + frappe.get_doc({ + "doctype": "Email Group Member", + "email": email, + "email_group": "_Test Email Group" + }).insert() def test_send(self): - name = self.send_newsletter() + self.send_newsletter() - email_queue_list = [frappe.get_doc('Email Queue', e.name) for e in frappe.get_all("Email Queue")] + email_queue_list = [frappe.get_doc("Email Queue", e.name) for e in frappe.get_all("Email Queue")] self.assertEqual(len(email_queue_list), 4) - recipients = [e.recipients[0].recipient for e in email_queue_list] - for email in emails: - self.assertTrue(email in recipients) + + recipients = set([e.recipients[0].recipient for e in email_queue_list]) + self.assertTrue(set(emails).issubset(recipients)) def test_unsubscribe(self): - # test unsubscribe name = self.send_newsletter() - from frappe.email.queue import flush + to_unsubscribe = choice(emails) + group = frappe.get_all("Newsletter Email Group", filters={"parent": name}, fields=["email_group"]) + flush(from_test=True) - to_unsubscribe = unquote(frappe.local.flags.signed_query_string.split("email=")[1].split("&")[0]) - group = frappe.get_all("Newsletter Email Group", filters={"parent" : name}, fields=["email_group"]) confirmed_unsubscribe(to_unsubscribe, group[0].email_group) name = self.send_newsletter() - - email_queue_list = [frappe.get_doc('Email Queue', e.name) for e in frappe.get_all("Email Queue")] + email_queue_list = [ + frappe.get_doc("Email Queue", e.name) for e in frappe.get_all("Email Queue") + ] self.assertEqual(len(email_queue_list), 3) recipients = [e.recipients[0].recipient for e in email_queue_list] + for email in emails: if email != to_unsubscribe: self.assertTrue(email in recipients) @@ -86,7 +94,6 @@ class TestNewsletter(unittest.TestCase): def test_portal(self): self.send_newsletter(1) frappe.set_user("test1@example.com") - from frappe.email.doctype.newsletter.newsletter import get_newsletter_list newsletters = get_newsletter_list("Newsletter", None, None, 0) self.assertEqual(len(newsletters), 1) @@ -106,4 +113,4 @@ class TestNewsletter(unittest.TestCase): self.assertEqual(len(email_queue_list), 4) recipients = [e.recipients[0].recipient for e in email_queue_list] for email in emails: - self.assertTrue(email in recipients) \ No newline at end of file + self.assertTrue(email in recipients) From a2fba77116609c089f281ee92c15cccb13c0e610 Mon Sep 17 00:00:00 2001 From: Suraj Shetty <13928957+surajshetty3416@users.noreply.github.com> Date: Mon, 25 Jan 2021 15:37:37 +0530 Subject: [PATCH 15/16] fix: Skip translation of gender while creating it (#12260) --- frappe/desk/page/setup_wizard/install_fixtures.py | 4 ++-- frappe/utils/oauth.py | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/frappe/desk/page/setup_wizard/install_fixtures.py b/frappe/desk/page/setup_wizard/install_fixtures.py index 60e1f3242a..6d3aaee22b 100644 --- a/frappe/desk/page/setup_wizard/install_fixtures.py +++ b/frappe/desk/page/setup_wizard/install_fixtures.py @@ -18,14 +18,14 @@ def install(): @frappe.whitelist() def update_genders(): - default_genders = [_("Male"), _("Female"), _("Other"),_("Transgender"), _("Genderqueer"), _("Non-Conforming"),_("Prefer not to say")] + default_genders = ["Male", "Female", "Other","Transgender", "Genderqueer", "Non-Conforming","Prefer not to say"] records = [{'doctype': 'Gender', 'gender': d} for d in default_genders] for record in records: frappe.get_doc(record).insert(ignore_permissions=True, ignore_if_duplicate=True) @frappe.whitelist() def update_salutations(): - default_salutations = [_("Mr"), _("Ms"), _('Mx'), _("Dr"), _("Mrs"), _("Madam"), _("Miss"), _("Master"), _("Prof")] + default_salutations = ["Mr", "Ms", 'Mx', "Dr", "Mrs", "Madam", "Miss", "Master", "Prof"] records = [{'doctype': 'Salutation', 'salutation': d} for d in default_salutations] for record in records: doc = frappe.new_doc(record.get("doctype")) diff --git a/frappe/utils/oauth.py b/frappe/utils/oauth.py index d090aabffc..e7672cedb3 100644 --- a/frappe/utils/oauth.py +++ b/frappe/utils/oauth.py @@ -230,12 +230,19 @@ def update_oauth_user(user, data, provider): save = True user = frappe.new_doc("User") + + gender = (data.get("gender") or "").title() + + if not frappe.db.exists("Gender", gender): + doc = frappe.new_doc("Gender", {"gender": gender}) + doc.insert(ignore_permissions=True) + user.update({ "doctype":"User", "first_name": get_first_name(data), "last_name": get_last_name(data), "email": get_email(data), - "gender": (data.get("gender") or "").title(), + "gender": gender, "enabled": 1, "new_password": frappe.generate_hash(get_email(data)), "location": data.get("location"), From a4396a83d080e7b07d3fca67159025c981f64562 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bonicoli Date: Mon, 25 Jan 2021 11:06:02 +0100 Subject: [PATCH 16/16] ci: fix a regex used in Travis config Fix this line in Procfile: redis_# socketio: redis-server config/redis_socketio.conf --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2331217363..23fb525138 100644 --- a/.travis.yml +++ b/.travis.yml @@ -104,11 +104,11 @@ install: - cd ./frappe-bench - - sed -i 's/watch:/# watch:/g' Procfile - - sed -i 's/schedule:/# schedule:/g' Procfile + - sed -i 's/^watch:/# watch:/g' Procfile + - sed -i 's/^schedule:/# schedule:/g' Procfile - - if [ $TYPE == "server" ]; then sed -i 's/socketio:/# socketio:/g' Procfile; fi - - if [ $TYPE == "server" ]; then sed -i 's/redis_socketio:/# redis_socketio:/g' Procfile; fi + - if [ $TYPE == "server" ]; then sed -i 's/^socketio:/# socketio:/g' Procfile; fi + - if [ $TYPE == "server" ]; then sed -i 's/^redis_socketio:/# redis_socketio:/g' Procfile; fi - if [ $TYPE == "ui" ]; then bench setup requirements --node; fi