Merge branch 'hotfix'

This commit is contained in:
Sahil Khan 2019-05-30 12:08:16 +05:30
commit 88ce01a28a
14 changed files with 82 additions and 32 deletions

View file

@ -23,7 +23,7 @@ if sys.version[0] == '2':
reload(sys)
sys.setdefaultencoding("utf-8")
__version__ = '11.1.31'
__version__ = '11.1.32'
__title__ = "Frappe Framework"
local = Local()

View file

@ -987,12 +987,26 @@ class Database:
if values:
query = self._cursor.mogrify(query, values)
if query.strip().lower().split()[0] in ('insert', 'delete', 'update', 'alter'):
# ([`\"']?) Captures ', " or ` at the begining of the table name (if provided)
# single_word_regex is designed to match following patterns
# `tabXxx`, tabXxx and "tabXxx"
# multi_word_regex is designed to match following patterns
# `tabXxx Xxx` and "tabXxx Xxx"
# ([`"]?) Captures " or ` at the begining of the table name (if provided)
# \1 matches the first captured group (quote character) at the end of the table name
# multi word table name must have surrounding quotes.
# (tab([A-Z]\w+)( [A-Z]\w+)*) Captures table names that start with "tab"
# and are continued with multiple words that start with a captital letter
# e.g. 'tabXxx' or 'tabXxx Xxx' or 'tabXxx Xxx Xxx' and so on
# \1 matches the first captured group (quote character) at the end of the table name
tables = [groups[1] for groups in re.findall(r'([`"\']?)(tab([A-Z]\w+)( [A-Z]\w+)*)\1', query)]
single_word_regex = r'([`"]?)(tab([A-Z]\w+))\1'
multi_word_regex = r'([`"])(tab([A-Z]\w+)( [A-Z]\w+)+)\1'
tables = []
for regex in (single_word_regex, multi_word_regex):
tables += [groups[1] for groups in re.findall(regex, query)]
if frappe.flags.touched_tables is None:
frappe.flags.touched_tables = set()
frappe.flags.touched_tables.update(tables)

View file

@ -23,7 +23,7 @@ def get_contact_list(txt, page_length=20):
out = frappe.db.sql("""select email_id as value,
concat(first_name, ifnull(concat(' ',last_name), '' )) as description
from tabContact
where name like %(txt)s
where name like %(txt)s or email_id like %(txt)s
%(condition)s
limit %(page_length)s
""", {'txt': "%%%s%%" % frappe.db.escape(txt),

View file

@ -3,7 +3,7 @@
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2015-03-18 09:41:20.216319",
"creation": "2015-03-18 09:41:20.216320",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
@ -35,7 +35,7 @@
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"search_index": 1,
"set_only_once": 0,
"unique": 0
},
@ -172,4 +172,4 @@
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0
}
}

View file

@ -78,19 +78,35 @@ def send(recipients=None, sender=None, subject=None, message=None, text_content=
except HTMLParser.HTMLParseError:
text_content = "See html attachment"
if reference_doctype and reference_name:
unsubscribed = [d.email for d in frappe.db.get_all("Email Unsubscribe", "email",
{"reference_doctype": reference_doctype, "reference_name": reference_name})]
recipients = list(set(recipients))
cc = list(set(cc))
unsubscribed += [d.email for d in frappe.db.get_all("Email Unsubscribe", "email",
{"global_unsubscribe": 1})]
else:
unsubscribed = []
all_ids = recipients + cc
recipients = [r for r in list(set(recipients)) if r and r not in unsubscribed]
unsubscribed = frappe.db.sql_list('''
SELECT
distinct email
from
`tabEmail Unsubscribe`
where
email in %(all_ids)s
and (
(
reference_doctype = %(reference_doctype)s
and reference_name = %(reference_name)s
)
or global_unsubscribe = 1
)
''', {
'all_ids': all_ids,
'reference_doctype': reference_doctype,
'reference_name': reference_name,
})
recipients = [r for r in recipients if r and r not in unsubscribed]
if cc:
cc = [r for r in list(set(cc)) if r and r not in unsubscribed]
cc = [r for r in cc if r and r not in unsubscribed]
if not recipients and not cc:
# Recipients may have been unsubscribed, exit quietly

View file

@ -381,7 +381,7 @@ class DatabaseQuery(object):
elif f.operator.lower() in ('in', 'not in'):
values = f.value or ''
if not isinstance(values, (list, tuple)):
if isinstance(values, frappe.string_types):
values = values.split(",")
fallback = "''"

View file

@ -39,13 +39,17 @@ def execute():
df.set(ps.property, value)
for cf in custom_fields:
df = frappe.new_doc('DocField', meta, 'fields')
cf.pop('parenttype')
cf.pop('parentfield')
cf.pop('parent')
cf.pop('name')
df.update(cf)
meta.fields.append(df)
field = meta.get_field(cf.fieldname)
if field:
field.update(cf)
else:
df = frappe.new_doc('DocField', meta, 'fields')
df.update(cf)
meta.fields.append(df)
frappe.db.sql('DELETE FROM `tabCustom Field` WHERE name=%s', cf.name)
meta.save()

View file

@ -376,7 +376,6 @@ frappe.ui.form.Timeline = class Timeline {
@abc with the below line of code.
*/
c.content_html = c.content_html.replace(/(<[a][^>]*>)/g, "");
// bold the @mentions
c.content_html = c.content_html.replace(/(@[^\s@]*)@[^\s@|<]*/g, "<b>$1</b>");
}

View file

@ -59,6 +59,7 @@ frappe.ui.form.MultiSelectDialog = Class.extend({
{ fieldtype: "Button", fieldname: "more_btn", label: __("More"),
click: function(){
me.start += 20;
frappe.flags.auto_scroll = true;
me.get_results();
}
}
@ -117,10 +118,12 @@ frappe.ui.form.MultiSelectDialog = Class.extend({
});
this.$parent.find('.input-with-feedback').on('change', (e) => {
frappe.flags.auto_scroll = false;
this.get_results();
});
this.$parent.find('[data-fieldname="date_range"]').on('blur', (e) => {
frappe.flags.auto_scroll = false;
this.get_results();
});
@ -128,6 +131,7 @@ frappe.ui.form.MultiSelectDialog = Class.extend({
var $this = $(this);
clearTimeout($this.data('timeout'));
$this.data('timeout', setTimeout(function() {
frappe.flags.auto_scroll = false;
me.get_results();
}, 300));
});
@ -176,11 +180,17 @@ frappe.ui.form.MultiSelectDialog = Class.extend({
var me = this;
var more_btn = me.dialog.fields_dict.more_btn.$wrapper;
// Make empty result set if filter is set
if (!frappe.flags.auto_scroll) {
this.$results.empty();
}
if(results.length === 0) {
this.$results.empty();
more_btn.hide();
return;
} else {
} else if(more) {
more_btn.show();
}
@ -188,7 +198,9 @@ frappe.ui.form.MultiSelectDialog = Class.extend({
me.$results.append(me.make_list_row(result));
});
this.$results.animate({scrollTop: me.$results.prop('scrollHeight')}, 500);
if (frappe.flags.auto_scroll) {
this.$results.animate({scrollTop: me.$results.prop('scrollHeight')}, 500);
}
},
get_results: function() {

View file

@ -642,7 +642,7 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
.includes(user) ? '' : 'bold';
let subject_html = `
<input class="level-item list-row-checkbox hidden-xs" type="checkbox" data-name="${doc.name}">
<input class="level-item list-row-checkbox hidden-xs" type="checkbox" data-name="${escape(doc.name)}">
<span class="level-item" style="margin-bottom: 1px;">
<i class="octicon octicon-heart like-action ${heart_class}"
data-name="${doc.name}" data-doctype="${this.doctype}"
@ -898,7 +898,7 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
get_checked_items(only_docnames) {
const docnames = Array.from(this.$checks || [])
.map(check => cstr($(check).data().name));
.map(check => cstr(unescape($(check).data().name)));
if (only_docnames) return docnames;

View file

@ -45,6 +45,11 @@ class TestDB(unittest.TestCase):
todo.save()
self.assertIn('tabToDo', frappe.flags.touched_tables)
frappe.flags.touched_tables = set()
frappe.db.sql("UPDATE tabToDo SET description = 'Updated Description'")
self.assertNotIn('tabToDo SET', frappe.flags.touched_tables)
self.assertIn('tabToDo', frappe.flags.touched_tables)
frappe.flags.touched_tables = set()
todo.delete()
self.assertIn('tabToDo', frappe.flags.touched_tables)

View file

@ -20,7 +20,7 @@
"cookie": "^0.3.1",
"express": "^4.16.2",
"fast-deep-equal": "^2.0.1",
"frappe-datatable": "^1.13.1",
"frappe-datatable": "^1.13.2",
"frappe-gantt": "^0.1.0",
"fuse.js": "^3.2.0",
"highlight.js": "^9.12.0",

View file

@ -15,7 +15,7 @@ rauth>=0.6.2
requests
redis==2.10.6
selenium
babel
babel==2.6.0
ipython
html2text==2016.9.19
email_reply_parser

View file

@ -1224,10 +1224,10 @@ forwarded@~0.1.2:
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=
frappe-datatable@^1.13.1:
version "1.13.1"
resolved "https://registry.yarnpkg.com/frappe-datatable/-/frappe-datatable-1.13.1.tgz#dbfa27fe735832cea54a0b35e3d3bfb839778c8d"
integrity sha512-FOC8dpsOSI+KnF5sBrYja9b2Y+3qUvYy/H6108QchKSvXYvuWVr/uuLk2N5xlz38PWU3d7n5lK0dkx+zXTKJ0w==
frappe-datatable@^1.13.2:
version "1.13.2"
resolved "https://registry.yarnpkg.com/frappe-datatable/-/frappe-datatable-1.13.2.tgz#8b36c7cfc0ea660fc72eea8b1ae3c5dcc2a7d67d"
integrity sha512-4PyPDX22K4e4S3WGlLQx3oyxIW+ENsbGiN9L6aUpmjU+fOCC7J/FfSwGKdua2f+4yD+2ObpkyJYazBl3inAeCA==
dependencies:
hyperlist "^1.0.0-beta"
lodash "^4.17.5"