@@ -21,7 +21,7 @@ install: | |||||
script: | script: | ||||
- cd ~/frappe-bench | - cd ~/frappe-bench | ||||
- bench use test_site | - bench use test_site | ||||
- bench reinstall | |||||
- bench reinstall --yes | |||||
- bench build | - bench build | ||||
- bench start & | - bench start & | ||||
- sleep 10 | - sleep 10 | ||||
@@ -13,7 +13,7 @@ import os, importlib, inspect, json | |||||
from .exceptions import * | from .exceptions import * | ||||
from .utils.jinja import get_jenv, get_template, render_template | from .utils.jinja import get_jenv, get_template, render_template | ||||
__version__ = "7.0.0" | |||||
__version__ = "7.0.1" | |||||
local = Local() | local = Local() | ||||
@@ -154,6 +154,12 @@ def has_permission(doctype, docname, perm_type="read"): | |||||
# perm_type can be one of read, write, create, submit, cancel, report | # perm_type can be one of read, write, create, submit, cancel, report | ||||
return {"has_permission": frappe.has_permission(doctype, perm_type.lower(), docname)} | return {"has_permission": frappe.has_permission(doctype, perm_type.lower(), docname)} | ||||
@frappe.whitelist() | |||||
def get_password(doctype, name, fieldname): | |||||
frappe.only_for("System Manager") | |||||
return frappe.get_doc(doctype, name).get_password(fieldname) | |||||
@frappe.whitelist() | @frappe.whitelist() | ||||
def get_js(items): | def get_js(items): | ||||
items = json.loads(items) | items = json.loads(items) | ||||
@@ -100,15 +100,22 @@ def restore(context, sql_file_path, mariadb_root_username=None, mariadb_root_pas | |||||
# Extract public and/or private files to the restored site, if user has given the path | # Extract public and/or private files to the restored site, if user has given the path | ||||
if with_public_files: | if with_public_files: | ||||
extract_tar_files(site, with_public_files, 'public') | |||||
public = extract_tar_files(site, with_public_files, 'public') | |||||
os.remove(public) | |||||
if with_private_files: | if with_private_files: | ||||
extract_tar_files(site, with_private_files, 'private') | |||||
private = extract_tar_files(site, with_private_files, 'private') | |||||
os.remove(private) | |||||
@click.command('reinstall') | @click.command('reinstall') | ||||
@click.option('--yes', is_flag=True, default=False, help='Pass --yes to skip confirmation') | |||||
@pass_context | @pass_context | ||||
def reinstall(context): | |||||
def reinstall(context, yes=False): | |||||
"Reinstall site ie. wipe all data and start over" | "Reinstall site ie. wipe all data and start over" | ||||
if not yes: | |||||
click.confirm('This will wipe your database. Are you sure you want to reinstall?', abort=True) | |||||
site = get_site(context) | site = get_site(context) | ||||
try: | try: | ||||
frappe.init(site=site) | frappe.init(site=site) | ||||
@@ -178,7 +185,7 @@ def disable_user(context, email): | |||||
user = frappe.get_doc("User", email) | user = frappe.get_doc("User", email) | ||||
user.enabled = 0 | user.enabled = 0 | ||||
user.save(ignore_permissions=True) | user.save(ignore_permissions=True) | ||||
frappe.db.commit() | |||||
frappe.db.commit() | |||||
@click.command('migrate') | @click.command('migrate') | ||||
@@ -76,7 +76,7 @@ class File(NestedSet): | |||||
"""Set folder size if folder""" | """Set folder size if folder""" | ||||
if self.is_folder and not self.is_new(): | if self.is_folder and not self.is_new(): | ||||
self.file_size = self.get_folder_size() | self.file_size = self.get_folder_size() | ||||
frappe.db.set_value("File", self.name, "file_size", self.file_size) | |||||
self.db_set('file_size', self.file_size) | |||||
for folder in self.get_ancestors(): | for folder in self.get_ancestors(): | ||||
frappe.db.set_value("File", folder, "file_size", self.get_folder_size(folder)) | frappe.db.set_value("File", folder, "file_size", self.get_folder_size(folder)) | ||||
@@ -93,7 +93,7 @@ class File(NestedSet): | |||||
def update_parent_folder_size(self): | def update_parent_folder_size(self): | ||||
"""Update size of parent folder""" | """Update size of parent folder""" | ||||
if self.folder and not self.is_folder: # it not home | if self.folder and not self.is_folder: # it not home | ||||
frappe.get_doc("File", self.folder).save(ignore_permissions=True) | |||||
frappe.get_doc("File", self.folder).set_folder_size() | |||||
def set_folder_name(self): | def set_folder_name(self): | ||||
"""Make parent folders if not exists based on reference doctype and name""" | """Make parent folders if not exists based on reference doctype and name""" | ||||
@@ -345,42 +345,36 @@ def check_if_ready_for_barracuda(): | |||||
# raise Exception, "MariaDB needs to be configured!" | # raise Exception, "MariaDB needs to be configured!" | ||||
def extract_sql_gzip(sql_gz_path): | def extract_sql_gzip(sql_gz_path): | ||||
success = -1 | |||||
try: | try: | ||||
subprocess.check_output(['gzip', '-d', '-v', '-f', sql_gz_path]) | |||||
except Exception as subprocess.CalledProcessError: | |||||
print subprocess.CalledProcessError.output | |||||
finally: | |||||
# subprocess.check_call returns '0' on success. On success, return path to sql file | |||||
return sql_gz_path[:-3] | |||||
success = subprocess.check_output(['gzip', '-d', '-v', '-f', sql_gz_path]) | |||||
except: | |||||
raise | |||||
path = sql_gz_path[:-3] if success else None | |||||
return path | |||||
def extract_tar_files(site_name, file_path, folder_name): | def extract_tar_files(site_name, file_path, folder_name): | ||||
# Need to do frappe.init to maintain the site locals | # Need to do frappe.init to maintain the site locals | ||||
frappe.init(site=site_name) | frappe.init(site=site_name) | ||||
abs_site_path = os.path.abspath(frappe.get_site_path()) | abs_site_path = os.path.abspath(frappe.get_site_path()) | ||||
# While creating tar files during backup, a complete recursive structure is created. | |||||
# For example, <site_name>/<private>/<files>/*.* | |||||
# Shift to parent directory and make it as current directory and do the extraction. | |||||
_parent_dir = os.path.dirname(abs_site_path) | |||||
os.chdir(_parent_dir) | |||||
# Copy the files to the parent directory and extract | # Copy the files to the parent directory and extract | ||||
shutil.copy2(os.path.abspath(file_path), _parent_dir) | |||||
shutil.copy2(os.path.abspath(file_path), abs_site_path) | |||||
# Get the file name splitting the file path on | # Get the file name splitting the file path on | ||||
filename = file_path.split('/')[-1] | |||||
filepath = os.path.join(_parent_dir, filename) | |||||
tar_name = os.path.split(file_path)[1] | |||||
tar_path = os.path.join(abs_site_path, tar_name) | |||||
try: | try: | ||||
error = subprocess.check_output(['tar', 'xvf', filepath]) | |||||
except Exception as subprocess.CalledProcessError: | |||||
print subprocess.CalledProcessError.output | |||||
subprocess.check_output(['tar', 'xvf', tar_path, '--strip', '2'], cwd=abs_site_path) | |||||
except: | |||||
raise | |||||
finally: | finally: | ||||
# On successful extraction delete the tarfile to avoid any abuse through command line | |||||
os.remove(filepath) | |||||
frappe.destroy() | frappe.destroy() | ||||
return tar_path | |||||
expected_config_for_barracuda = """[mysqld] | expected_config_for_barracuda = """[mysqld] | ||||
innodb-file-format=barracuda | innodb-file-format=barracuda | ||||
innodb-file-per-table=1 | innodb-file-per-table=1 | ||||
@@ -718,7 +718,7 @@ frappe.ui.form.GridRow = Class.extend({ | |||||
var me = this; | var me = this; | ||||
// show static for field based on | // show static for field based on | ||||
// whether grid is editable | // whether grid is editable | ||||
if(this.grid.is_editable() && this.doc && show !== false) { | |||||
if(this.grid.allow_on_grid_editing() && this.grid.is_editable() && this.doc && show !== false) { | |||||
// disable other editale row | // disable other editale row | ||||
if(frappe.ui.form.editable_row | if(frappe.ui.form.editable_row | ||||
@@ -127,7 +127,12 @@ def has_gravatar(email): | |||||
# since querying gravatar for every item will be slow | # since querying gravatar for every item will be slow | ||||
return '' | return '' | ||||
gravatar_url = "https://secure.gravatar.com/avatar/{hash}?d=404&s=200".format(hash=md5.md5(email).hexdigest()) | |||||
if not isinstance(email, unicode): | |||||
email = unicode(email, 'utf-8') | |||||
hexdigest = md5.md5(email).hexdigest() | |||||
gravatar_url = "https://secure.gravatar.com/avatar/{hash}?d=404&s=200".format(hash=hexdigest) | |||||
try: | try: | ||||
res = requests.get(gravatar_url) | res = requests.get(gravatar_url) | ||||
if res.status_code==200: | if res.status_code==200: | ||||
@@ -514,6 +519,7 @@ def get_site_info(): | |||||
'language': system_settings.language or 'english', | 'language': system_settings.language or 'english', | ||||
'time_zone': system_settings.time_zone, | 'time_zone': system_settings.time_zone, | ||||
'setup_complete': cint(system_settings.setup_complete), | 'setup_complete': cint(system_settings.setup_complete), | ||||
'scheduler_enabled': system_settings.enable_scheduler, | |||||
# usage | # usage | ||||
'emails_sent': get_emails_sent_this_month(), | 'emails_sent': get_emails_sent_this_month(), | ||||