Merge branch 'hotfix' into css
This commit is contained in:
commit
35c8a1db4b
9 changed files with 92 additions and 70 deletions
|
|
@ -14,7 +14,7 @@ import os, sys, importlib, inspect, json
|
|||
from .exceptions import *
|
||||
from .utils.jinja import get_jenv, get_template, render_template, get_email_from_template
|
||||
|
||||
__version__ = '10.1.62'
|
||||
__version__ = '10.1.64'
|
||||
__title__ = "Frappe Framework"
|
||||
|
||||
local = Local()
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ def get_list(doctype, fields=None, filters=None, order_by=None,
|
|||
:param limit_start: Start at this index
|
||||
:param limit_page_length: Number of records to be returned (default 20)'''
|
||||
if frappe.is_table(doctype):
|
||||
check_parent_permission(parent)
|
||||
check_parent_permission(parent, doctype)
|
||||
|
||||
return frappe.get_list(doctype, fields=fields, filters=filters, order_by=order_by,
|
||||
limit_start=limit_start, limit_page_length=limit_page_length, ignore_permissions=False)
|
||||
|
|
@ -41,7 +41,7 @@ def get(doctype, name=None, filters=None, parent=None):
|
|||
:param name: return document of this `name`
|
||||
:param filters: If name is not set, filter by these values and return the first match'''
|
||||
if frappe.is_table(doctype):
|
||||
check_parent_permission(parent)
|
||||
check_parent_permission(parent, doctype)
|
||||
|
||||
if filters and not name:
|
||||
name = frappe.db.get_value(doctype, json.loads(filters))
|
||||
|
|
@ -62,7 +62,7 @@ def get_value(doctype, fieldname, filters=None, as_dict=True, debug=False, paren
|
|||
:param fieldname: Field to be returned (default `name`)
|
||||
:param filters: dict or string for identifying the record'''
|
||||
if frappe.is_table(doctype):
|
||||
check_parent_permission(parent)
|
||||
check_parent_permission(parent, doctype)
|
||||
|
||||
if not frappe.has_permission(doctype):
|
||||
frappe.throw(_("No permission for {0}".format(doctype)), frappe.PermissionError)
|
||||
|
|
@ -314,9 +314,14 @@ def get_time_zone():
|
|||
'''Returns default time zone'''
|
||||
return {"time_zone": frappe.defaults.get_defaults().get("time_zone")}
|
||||
|
||||
def check_parent_permission(parent):
|
||||
def check_parent_permission(parent, child_doctype):
|
||||
if parent:
|
||||
# User may pass fake parent and get the information from the child table
|
||||
if child_doctype and not frappe.db.exists('DocField',
|
||||
{'parent': parent, 'options': child_doctype}):
|
||||
raise frappe.PermissionError
|
||||
|
||||
if frappe.permissions.has_permission(parent):
|
||||
return
|
||||
# Either parent not passed or the user doesn't have permission on parent doctype of child table!
|
||||
raise frappe.PermissionError
|
||||
raise frappe.PermissionError
|
||||
|
|
@ -455,8 +455,10 @@ def _set_limits(context, site, limits):
|
|||
frappe.connect()
|
||||
new_limits = {}
|
||||
for limit, value in limits:
|
||||
if limit not in ('daily_emails', 'emails', 'space', 'users', 'email_group',
|
||||
'expiry', 'support_email', 'support_chat', 'upgrade_url'):
|
||||
if limit not in ('daily_emails', 'emails', 'space', 'users', 'email_group', 'currency',
|
||||
'expiry', 'support_email', 'support_chat', 'upgrade_url', 'subscription_id',
|
||||
'subscription_type', 'current_plan', 'subscription_base_price', 'upgrade_plan',
|
||||
'upgrade_base_price'):
|
||||
frappe.throw(_('Invalid limit {0}').format(limit))
|
||||
|
||||
if limit=='expiry' and value:
|
||||
|
|
@ -465,7 +467,7 @@ def _set_limits(context, site, limits):
|
|||
except ValueError:
|
||||
raise ValueError("Incorrect data format, should be YYYY-MM-DD")
|
||||
|
||||
elif limit=='space':
|
||||
elif limit in ('space', 'subscription_base_price', 'upgrade_base_price'):
|
||||
value = float(value)
|
||||
|
||||
elif limit in ('users', 'emails', 'email_group', 'daily_emails'):
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ class AutoEmailReport(Document):
|
|||
new_row = []
|
||||
out.append(new_row)
|
||||
for df in columns:
|
||||
if not row.get(df.fieldname): continue
|
||||
if not row.has_key(df.fieldname): continue
|
||||
new_row.append(frappe.format(row[df.fieldname], df, row))
|
||||
|
||||
return out
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import frappe.permissions
|
|||
from frappe.utils import flt, cint, getdate, get_datetime, get_time, make_filter_tuple, get_filter, add_to_date
|
||||
from frappe import _
|
||||
from frappe.model import optional_fields
|
||||
from frappe.client import check_parent_permission
|
||||
from frappe.model.utils.user_settings import get_user_settings, update_user_settings
|
||||
from datetime import datetime
|
||||
|
||||
|
|
@ -619,6 +620,19 @@ def get_list(doctype, *args, **kwargs):
|
|||
'''wrapper for DatabaseQuery'''
|
||||
kwargs.pop('cmd', None)
|
||||
kwargs.pop('ignore_permissions', None)
|
||||
|
||||
# If doctype is child table
|
||||
if frappe.is_table(doctype):
|
||||
# Example frappe.db.get_list('Purchase Receipt Item', {'parent': 'Purchase Receipt'})
|
||||
# Here purchase receipt is the parent doctype of the child doctype Purchase Receipt Item
|
||||
|
||||
if not kwargs.get('parent'):
|
||||
frappe.flags.error_message = _('Parent is required to get child table data')
|
||||
raise frappe.PermissionError(doctype)
|
||||
|
||||
check_parent_permission(kwargs.get('parent'), doctype)
|
||||
del kwargs['parent']
|
||||
|
||||
return DatabaseQuery(doctype).execute(None, *args, **kwargs)
|
||||
|
||||
def is_parent_only_filter(doctype, filters):
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ def rename_doc(doctype, old, new, force=False, merge=False, ignore_permissions=F
|
|||
frappe.delete_doc(doctype, old)
|
||||
|
||||
frappe.clear_cache()
|
||||
frappe.enqueue('frappe.utils.global_search.rebuild_for_doctype', doctype=doctype)
|
||||
|
||||
return new
|
||||
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@ frappe.search.SearchDialog = Class.extend({
|
|||
no_results_status: (keyword) => __("<p>No results found for '" + keyword + "' in Global Search</p>"),
|
||||
|
||||
get_results: function(keywords, callback) {
|
||||
var start = 0, limit = 100;
|
||||
var start = 0, limit = 1000;
|
||||
var results = frappe.search.utils.get_nav_results(keywords);
|
||||
frappe.search.utils.get_global_results(keywords, start, limit)
|
||||
.then(function(global_results) {
|
||||
|
|
|
|||
|
|
@ -122,16 +122,16 @@ class RedisWrapper(redis.Redis):
|
|||
pass
|
||||
|
||||
def lpush(self, key, value):
|
||||
super(redis.Redis, self).lpush(self.make_key(key), value)
|
||||
super(RedisWrapper, self).lpush(self.make_key(key), value)
|
||||
|
||||
def rpush(self, key, value):
|
||||
super(redis.Redis, self).rpush(self.make_key(key), value)
|
||||
super(RedisWrapper, self).rpush(self.make_key(key), value)
|
||||
|
||||
def lpop(self, key):
|
||||
return super(redis.Redis, self).lpop(self.make_key(key))
|
||||
return super(RedisWrapper, self).lpop(self.make_key(key))
|
||||
|
||||
def llen(self, key):
|
||||
return super(redis.Redis, self).llen(self.make_key(key))
|
||||
return super(RedisWrapper, self).llen(self.make_key(key))
|
||||
|
||||
def hset(self, name, key, value, shared=False):
|
||||
_name = self.make_key(name, shared=shared)
|
||||
|
|
@ -143,14 +143,14 @@ class RedisWrapper(redis.Redis):
|
|||
|
||||
# set in redis
|
||||
try:
|
||||
super(redis.Redis, self).hset(_name,
|
||||
super(RedisWrapper, self).hset(_name,
|
||||
key, pickle.dumps(value))
|
||||
except redis.exceptions.ConnectionError:
|
||||
pass
|
||||
|
||||
def hgetall(self, name):
|
||||
return {key: pickle.loads(value) for key, value in
|
||||
iteritems(super(redis.Redis, self).hgetall(self.make_key(name)))}
|
||||
iteritems(super(RedisWrapper, self).hgetall(self.make_key(name)))}
|
||||
|
||||
def hget(self, name, key, generator=None, shared=False):
|
||||
_name = self.make_key(name, shared=shared)
|
||||
|
|
@ -162,7 +162,7 @@ class RedisWrapper(redis.Redis):
|
|||
|
||||
value = None
|
||||
try:
|
||||
value = super(redis.Redis, self).hget(_name, key)
|
||||
value = super(RedisWrapper, self).hget(_name, key)
|
||||
except redis.exceptions.ConnectionError:
|
||||
pass
|
||||
|
||||
|
|
@ -184,7 +184,7 @@ class RedisWrapper(redis.Redis):
|
|||
if key in frappe.local.cache[_name]:
|
||||
del frappe.local.cache[_name][key]
|
||||
try:
|
||||
super(redis.Redis, self).hdel(_name, key)
|
||||
super(RedisWrapper, self).hdel(_name, key)
|
||||
except redis.exceptions.ConnectionError:
|
||||
pass
|
||||
|
||||
|
|
@ -196,31 +196,31 @@ class RedisWrapper(redis.Redis):
|
|||
|
||||
def hkeys(self, name):
|
||||
try:
|
||||
return super(redis.Redis, self).hkeys(self.make_key(name))
|
||||
return super(RedisWrapper, self).hkeys(self.make_key(name))
|
||||
except redis.exceptions.ConnectionError:
|
||||
return []
|
||||
|
||||
def sadd(self, name, *values):
|
||||
"""Add a member/members to a given set"""
|
||||
super(redis.Redis, self).sadd(self.make_key(name), *values)
|
||||
super(RedisWrapper, self).sadd(self.make_key(name), *values)
|
||||
|
||||
def srem(self, name, *values):
|
||||
"""Remove a specific member/list of members from the set"""
|
||||
super(redis.Redis, self).srem(self.make_key(name), *values)
|
||||
super(RedisWrapper, self).srem(self.make_key(name), *values)
|
||||
|
||||
def sismember(self, name, value):
|
||||
"""Returns True or False based on if a given value is present in the set"""
|
||||
return super(redis.Redis, self).sismember(self.make_key(name), value)
|
||||
return super(RedisWrapper, self).sismember(self.make_key(name), value)
|
||||
|
||||
def spop(self, name):
|
||||
"""Removes and returns a random member from the set"""
|
||||
return super(redis.Redis, self).spop(self.make_key(name))
|
||||
return super(RedisWrapper, self).spop(self.make_key(name))
|
||||
|
||||
def srandmember(self, name, count=None):
|
||||
"""Returns a random member from the set"""
|
||||
return super(redis.Redis, self).srandmember(self.make_key(name))
|
||||
return super(RedisWrapper, self).srandmember(self.make_key(name))
|
||||
|
||||
def smembers(self, name):
|
||||
"""Return all members of the set"""
|
||||
return super(redis.Redis, self).smembers(self.make_key(name))
|
||||
return super(RedisWrapper, self).smembers(self.make_key(name))
|
||||
|
||||
|
|
|
|||
|
|
@ -1,53 +1,53 @@
|
|||
boto3
|
||||
chardet
|
||||
cssmin
|
||||
boto3==1.9.45
|
||||
chardet==3.0.4
|
||||
cssmin==0.2.0
|
||||
dropbox==7.3.1
|
||||
gunicorn
|
||||
httplib2
|
||||
jinja2
|
||||
markdown2
|
||||
markupsafe
|
||||
PyMySQL
|
||||
python-geoip
|
||||
python-geoip-geolite2
|
||||
python-dateutil
|
||||
pytz
|
||||
six
|
||||
termcolor
|
||||
werkzeug
|
||||
semantic_version
|
||||
gunicorn==19.9.0
|
||||
httplib2==0.12.0
|
||||
jinja2==2.10
|
||||
markdown2==2.3.6
|
||||
markupsafe==1.1.0
|
||||
PyMySQL==0.9.2
|
||||
python-geoip==1.2
|
||||
python-geoip-geolite2==2015.303
|
||||
python-dateutil==2.7.5
|
||||
pytz==2018.7
|
||||
six==1.11.0
|
||||
termcolor==1.1.0
|
||||
werkzeug==0.14.1
|
||||
semantic_version==2.6.0
|
||||
rauth>=0.6.2
|
||||
requests
|
||||
requests==2.20.1
|
||||
redis==2.10.6
|
||||
selenium
|
||||
babel
|
||||
ipython
|
||||
selenium==3.141.0
|
||||
babel==2.6.0
|
||||
ipython==5.8.0
|
||||
html2text==2016.9.19
|
||||
email_reply_parser
|
||||
click
|
||||
email_reply_parser==0.5.9
|
||||
click==7.0
|
||||
num2words==0.5.5
|
||||
watchdog==0.8.0
|
||||
bleach==2.1.4
|
||||
bleach-whitelist
|
||||
Pillow
|
||||
beautifulsoup4
|
||||
rq
|
||||
schedule
|
||||
cryptography
|
||||
pyopenssl
|
||||
ndg-httpsclient
|
||||
pyasn1
|
||||
zxcvbn-python
|
||||
unittest-xml-reporting
|
||||
oauthlib
|
||||
PyJWT
|
||||
PyPDF2
|
||||
openpyxl
|
||||
pyotp
|
||||
pyqrcode
|
||||
pypng
|
||||
premailer
|
||||
croniter
|
||||
googlemaps
|
||||
bleach-whitelist==0.0.9
|
||||
Pillow==5.3.0
|
||||
beautifulsoup4==4.6.3
|
||||
rq==0.12.0
|
||||
schedule==0.5.0
|
||||
cryptography==2.4.1
|
||||
pyopenssl==18.0.0
|
||||
ndg-httpsclient==0.5.1
|
||||
pyasn1==0.4.4
|
||||
zxcvbn-python==4.4.24
|
||||
unittest-xml-reporting==2.2.0
|
||||
oauthlib==2.1.0
|
||||
PyJWT==1.6.4
|
||||
PyPDF2==1.26.0
|
||||
openpyxl==2.5.10
|
||||
pyotp==2.2.7
|
||||
pyqrcode==1.2.1
|
||||
pypng==0.0.18
|
||||
premailer==3.2.0
|
||||
croniter==0.3.26
|
||||
googlemaps==3.0.2
|
||||
urllib3==1.23
|
||||
GitPython==2.1.11
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue