示例#1
0
def run_tests(context, app=None, module=None, doctype=None, test=(), driver=None, profile=False):
    "Run tests"
    import frappe.test_runner
    from frappe.utils import sel

    tests = test

    site = get_site(context)
    frappe.init(site=site)

    if frappe.conf.run_selenium_tests and False:
        sel.start(context.verbose, driver)

    try:
        ret = frappe.test_runner.main(
            app, module, doctype, context.verbose, tests=tests, force=context.force, profile=profile
        )
        if len(ret.failures) == 0 and len(ret.errors) == 0:
            ret = 0
    finally:
        pass
        if frappe.conf.run_selenium_tests:
            sel.close()

    sys.exit(ret)
示例#2
0
def restore(context, sql_file_path, mariadb_root_username=None, mariadb_root_password=None, db_name=None, verbose=None, install_app=None, admin_password=None, force=None, with_public_files=None, with_private_files=None):
	"Restore site database from an sql file"
	from frappe.installer import extract_sql_gzip, extract_tar_files
	# Extract the gzip file if user has passed *.sql.gz file instead of *.sql file

	if not os.path.exists(sql_file_path):
		sql_file_path = '../' + sql_file_path
		if not os.path.exists(sql_file_path):
			print('Invalid path {0}' + sql_file_path[3:])
			sys.exit(1)

	if sql_file_path.endswith('sql.gz'):
		sql_file_path = extract_sql_gzip(os.path.abspath(sql_file_path))

	site = get_site(context)
	frappe.init(site=site)
	_new_site(frappe.conf.db_name, site, mariadb_root_username=mariadb_root_username,
		mariadb_root_password=mariadb_root_password, admin_password=admin_password,
		verbose=context.verbose, install_apps=install_app, source_sql=sql_file_path,
		force=context.force)

	# Extract public and/or private files to the restored site, if user has given the path
	if with_public_files:
		public = extract_tar_files(site, with_public_files, 'public')
		os.remove(public)

	if with_private_files:
		private = extract_tar_files(site, with_private_files, 'private')
		os.remove(private)
示例#3
0
def list_apps(context):
	"List apps in site"
	site = get_site(context)
	frappe.init(site=site)
	frappe.connect()
	print("\n".join(frappe.get_installed_apps()))
	frappe.destroy()
示例#4
0
def scheduler(context, state, site=None):
    from frappe.installer import update_site_config
    import frappe.utils.scheduler

    if not site:
        site = get_site(context)

    try:
        frappe.init(site=site)

        if state == "pause":
            update_site_config("pause_scheduler", 1)
        elif state == "resume":
            update_site_config("pause_scheduler", 0)
        elif state == "disable":
            frappe.connect()
            frappe.utils.scheduler.disable_scheduler()
            frappe.db.commit()
        elif state == "enable":
            frappe.connect()
            frappe.utils.scheduler.enable_scheduler()
            frappe.db.commit()

        print "Scheduler {0}d for site {1}".format(state, site)

    finally:
        frappe.destroy()
示例#5
0
文件: utils.py 项目: ESS-LLP/frappe
def run_tests(context, app=None, module=None, doctype=None, test=(),
	driver=None, profile=False, coverage=False, junit_xml_output=False, ui_tests = False,
	doctype_list_path=None, skip_test_records=False, skip_before_tests=False, failfast=False):

	"Run tests"
	import frappe.test_runner
	tests = test

	site = get_site(context)
	frappe.init(site=site)

	frappe.flags.skip_before_tests = skip_before_tests
	frappe.flags.skip_test_records = skip_test_records

	if coverage:
		# Generate coverage report only for app that is being tested
		source_path = os.path.join(get_bench_path(), 'apps', app or 'frappe')
		cov = Coverage(source=[source_path], omit=['*.html', '*.js', '*.css'])
		cov.start()

	ret = frappe.test_runner.main(app, module, doctype, context.verbose, tests=tests,
		force=context.force, profile=profile, junit_xml_output=junit_xml_output,
		ui_tests = ui_tests, doctype_list_path = doctype_list_path, failfast=failfast)

	if coverage:
		cov.stop()
		cov.save()

	if len(ret.failures) == 0 and len(ret.errors) == 0:
		ret = 0

	if os.environ.get('CI'):
		sys.exit(ret)
示例#6
0
def _set_limits(context, site, limits):
	import datetime

	if not limits:
		return

	if not site:
		site = get_site(context)

	with frappe.init_site(site):
		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'):
				frappe.throw(_('Invalid limit {0}').format(limit))

			if limit=='expiry' and value:
				try:
					datetime.datetime.strptime(value, '%Y-%m-%d')
				except ValueError:
					raise ValueError("Incorrect data format, should be YYYY-MM-DD")

			elif limit=='space':
				value = float(value)

			elif limit in ('users', 'emails', 'email_group', 'daily_emails'):
				value = int(value)

			new_limits[limit] = value

		update_limits(new_limits)
示例#7
0
def import_csv(context, path, only_insert=False, submit_after_import=False, ignore_encoding_errors=False, no_email=True):
	"Import CSV using data import tool"
	from frappe.core.page.data_import_tool import importer
	from frappe.utils.csvutils import read_csv_content
	site = get_site(context)

	if not os.path.exists(path):
		path = os.path.join('..', path)
	if not os.path.exists(path):
		print('Invalid path {0}'.format(path))
		sys.exit(1)

	with open(path, 'r') as csvfile:
		content = read_csv_content(csvfile.read())

	frappe.init(site=site)
	frappe.connect()

	try:
		importer.upload(content, submit_after_import=submit_after_import, no_email=no_email,
			ignore_encoding_errors=ignore_encoding_errors, overwrite=not only_insert,
			via_console=True)
		frappe.db.commit()
	except Exception:
		print(frappe.get_traceback())

	frappe.destroy()
示例#8
0
def scheduler(context, state, site=None):
	from frappe.installer import update_site_config
	import frappe.utils.scheduler

	if not site:
		site = get_site(context)

	try:
		frappe.init(site=site)

		if state == 'pause':
			update_site_config('pause_scheduler', 1)
		elif state == 'resume':
			update_site_config('pause_scheduler', 0)
		elif state == 'disable':
			frappe.connect()
			frappe.utils.scheduler.disable_scheduler()
			frappe.db.commit()
		elif state == 'enable':
			frappe.connect()
			frappe.utils.scheduler.enable_scheduler()
			frappe.db.commit()

		print('Scheduler {0}d for site {1}'.format(state, site))

	finally:
		frappe.destroy()
示例#9
0
def import_csv(context, path, only_insert=False, submit_after_import=False, ignore_encoding_errors=False):
    "Import CSV using data import tool"
    from frappe.core.page.data_import_tool import importer
    from frappe.utils.csvutils import read_csv_content

    site = get_site(context)

    with open(path, "r") as csvfile:
        content = read_csv_content(csvfile.read())

    frappe.init(site=site)
    frappe.connect()

    try:
        importer.upload(
            content,
            submit_after_import=submit_after_import,
            ignore_encoding_errors=ignore_encoding_errors,
            overwrite=not only_insert,
            via_console=True,
        )
        frappe.db.commit()
    except Exception:
        print frappe.get_traceback()

    frappe.destroy()
示例#10
0
def show_pending_jobs(context, site=None):
	"Get diagnostic info about background jobs"
	if not site:
		site = get_site(context)

	from frappe.utils.doctor import pending_jobs as _pending_jobs
	return _pending_jobs(site=site)
示例#11
0
def disable_user(context, email):
	site = get_site(context)
	with frappe.init_site(site):
		frappe.connect()
		user = frappe.get_doc("User", email)
		user.enabled = 0
		user.save(ignore_permissions=True)
		frappe.db.commit()
示例#12
0
def console(context):
	"Start ipython console for a site"
	site = get_site(context)
	frappe.init(site=site)
	frappe.connect()
	frappe.local.lang = frappe.db.get_default("lang")
	import IPython
	IPython.embed()
示例#13
0
def add_to_email_queue(context, email):
	"Add an email to the Email Queue"
	site = get_site(context)
	with frappe.init_site(site):
		frappe.connect()
		kwargs = json.loads(email)
		kwargs['delayed'] = True
		frappe.sendmail(**kwargs)
		frappe.db.commit()
示例#14
0
def import_translations(context, lang, path):
	"Update translated strings"
	import frappe.translate
	site = get_site(context)
	try:
		frappe.init(site=site)
		frappe.connect()
		frappe.translate.import_translations(lang, path)
	finally:
		frappe.destroy()
示例#15
0
def update_translations(context, lang, untranslated_file, translated_file):
	"Update translated strings"
	import frappe.translate
	site = get_site(context)
	try:
		frappe.init(site=site)
		frappe.connect()
		frappe.translate.update_translations(lang, untranslated_file, translated_file)
	finally:
		frappe.destroy()
示例#16
0
def get_untranslated(context, lang, untranslated_file, all=None):
	"Get untranslated strings for language"
	import frappe.translate
	site = get_site(context)
	try:
		frappe.init(site=site)
		frappe.connect()
		frappe.translate.get_untranslated(lang, untranslated_file, get_all=all)
	finally:
		frappe.destroy()
示例#17
0
def set_maintenance_mode(context, state, site=None):
	from frappe.installer import update_site_config
	if not site:
		site = get_site(context)

	try:
		frappe.init(site=site)
		update_site_config('maintenance_mode', 1 if (state == 'on') else 0)

	finally:
		frappe.destroy()
示例#18
0
def set_training_mode(context, state, site=None):
	if not site:
		site = get_site(context)

	try:
		frappe.init(site=site)
		frappe.connect()
		frappe.db.set_value("BioTrack Settings", None, "is_training", 1 if (state == 'on') else 0)
		frappe.db.commit()
		print "Training mode set for site {}".format(site)
	finally:
		frappe.destroy()
示例#19
0
def add_to_email_queue(context, email_path):
	"Add an email to the Email Queue"
	site = get_site(context)

	if os.path.isdir(email_path):
		with frappe.init_site(site):
			frappe.connect()
			for email in os.listdir(email_path):
				with open(os.path.join(email_path, email)) as email_data:
					kwargs = json.load(email_data)
					kwargs['delayed'] = True
					frappe.sendmail(**kwargs)
					frappe.db.commit()
示例#20
0
def run_setup_wizard_ui_test(context, app=None, profile=False):
	"Run setup wizard UI test"
	import frappe.test_runner

	site = get_site(context)
	frappe.init(site=site)
	frappe.connect()

	ret = frappe.test_runner.run_setup_wizard_ui_test(app=app, verbose=context.verbose,
		profile=profile)
	if len(ret.failures) == 0 and len(ret.errors) == 0:
		ret = 0

	if os.environ.get('CI'):
		sys.exit(ret)
示例#21
0
def update(context):
	app = __name__.split('.')[0]
	app_dir = os.path.join('.', '../apps', app)

	if os.path.exists(os.path.join(app_dir, '.git')):
		print "Pulling app..."
		s = subprocess.Popen(['git', 'pull'], cwd=app_dir, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
		out = s.stdout.read()
		s.stdout.close()
		print out

	site = get_site(context)
	frappe.init(site=site)
	frappe.connect()
	migrate()
	frappe.destroy()
示例#22
0
def clear_limits(context, site, limits):
	"""Clears given limit from the site config, and removes limit from site config if its empty"""
	from frappe.limits import clear_limit as _clear_limit
	if not limits:
		return

	if not site:
		site = get_site(context)

	with frappe.init_site(site):
		_clear_limit(limits)

		# Remove limits from the site_config, if it's empty
		limits = get_limits()
		if not limits:
			update_site_config('limits', 'None', validate=False)
示例#23
0
def _bulk_rename(context, doctype, path):
	"Rename multiple records via CSV file"
	from frappe.model.rename_doc import bulk_rename
	from frappe.utils.csvutils import read_csv_content

	site = get_site(context)

	with open(path, 'r') as csvfile:
		rows = read_csv_content(csvfile.read())

	frappe.init(site=site)
	frappe.connect()

	bulk_rename(doctype, rows, via_console = True)

	frappe.destroy()
示例#24
0
def run_tests(context, app=None, module=None, doctype=None, test=(),
	driver=None, profile=False, junit_xml_output=False, ui_tests = False):
	"Run tests"
	import frappe.test_runner
	tests = test

	site = get_site(context)
	frappe.init(site=site)

	ret = frappe.test_runner.main(app, module, doctype, context.verbose, tests=tests,
		force=context.force, profile=profile, junit_xml_output=junit_xml_output,
		ui_tests = ui_tests)
	if len(ret.failures) == 0 and len(ret.errors) == 0:
		ret = 0

	if os.environ.get('CI'):
		sys.exit(ret)
示例#25
0
def mysql(context):
    "Start Mariadb console for a site"
    site = get_site(context)
    frappe.init(site=site)
    msq = find_executable("mysql")
    os.execv(
        msq,
        [
            msq,
            "-u",
            frappe.conf.db_name,
            "-p" + frappe.conf.db_password,
            frappe.conf.db_name,
            "-h",
            frappe.conf.db_host or "localhost",
            "-A",
        ],
    )
示例#26
0
def restore(context, sql_file_path, mariadb_root_username=None, mariadb_root_password=None, db_name=None, verbose=None, install_app=None, admin_password=None, force=None, with_public_files=None, with_private_files=None):
	"Restore site database from an sql file"
	from frappe.installer import extract_sql_gzip, extract_tar_files
	# Extract the gzip file if user has passed *.sql.gz file instead of *.sql file
	if sql_file_path.endswith('sql.gz'):
		sql_file_path = extract_sql_gzip(os.path.abspath(sql_file_path))

	site = get_site(context)
	frappe.init(site=site)
	db_name = db_name or frappe.conf.db_name or hashlib.sha1(site).hexdigest()[:10]
	_new_site(db_name, site, mariadb_root_username=mariadb_root_username, mariadb_root_password=mariadb_root_password, admin_password=admin_password, verbose=context.verbose, install_apps=install_app, source_sql=sql_file_path, force=context.force)

	# Extract public and/or private files to the restored site, if user has given the path
	if with_public_files:
		extract_tar_files(site, with_public_files, 'public')

	if with_private_files:
		extract_tar_files(site, with_private_files, 'private')
示例#27
0
def reinstall(context):
	"Reinstall site ie. wipe all data and start over"
	site = get_site(context)
	try:
		frappe.init(site=site)
		frappe.connect()
		frappe.clear_cache()
		installed = frappe.get_installed_apps()
		frappe.clear_cache()
	except Exception:
		installed = []
	finally:
		if frappe.db:
			frappe.db.close()
		frappe.destroy()

	frappe.init(site=site)
	_new_site(frappe.conf.db_name, site, verbose=context.verbose, force=True, reinstall=True, install_apps=installed)
示例#28
0
def set_last_active_for_user(context, user=None):
	"Set users last active date to current datetime"

	from frappe.core.doctype.user.user import get_system_users
	from frappe.utils.user import set_last_active_to_now

	site = get_site(context)

	with frappe.init_site(site):
		frappe.connect()
		if not user:
			user = get_system_users(limit=1)
			if len(user) > 0:
				user = user[0]
			else:
				return

		set_last_active_to_now(user)
		frappe.db.commit()
示例#29
0
文件: site.py 项目: rlesouef/frappe
def set_last_active_for_user(context, user=None):
	"Set users last active date to current datetime"

	from frappe.core.doctype.user.user import get_system_users
	from frappe.utils.user import set_last_active_to_now
	
	site = get_site(context)

	with frappe.init_site(site):
		frappe.connect()
		if not user:
			user = get_system_users(limit=1)
			if len(user) > 0:
				user = user[0]
			else:
				return

		set_last_active_to_now(user)
		frappe.db.commit()
示例#30
0
文件: utils.py 项目: ESS-LLP/frappe
def mariadb(context):
	"""
		Enter into mariadb console for a given site.
	"""
	import os

	site  = get_site(context)
	frappe.init(site=site)

	# This is assuming you're within the bench instance.
	mysql = find_executable('mysql')
	os.execv(mysql, [
		mysql,
		'-u', frappe.conf.db_name,
		'-p'+frappe.conf.db_password,
		frappe.conf.db_name,
		'-h', frappe.conf.db_host or "localhost",
		'--pager=less -SFX',
		"-A"])
示例#31
0
def run_tests(context, app=None, module=None, doctype=None, test=(),
	driver=None, profile=False, coverage=False, junit_xml_output=False, ui_tests = False,
	doctype_list_path=None, skip_test_records=False, skip_before_tests=False, failfast=False):

	"Run tests"
	import frappe.test_runner
	tests = test

	site = get_site(context)

	allow_tests = frappe.get_conf(site).allow_tests

	if not (allow_tests or os.environ.get('CI')):
		click.secho('Testing is disabled for the site!', bold=True)
		click.secho('You can enable tests by entering following command:')
		click.secho('bench --site {0} set-config allow_tests true'.format(site), fg='green')
		return

	frappe.init(site=site)

	frappe.flags.skip_before_tests = skip_before_tests
	frappe.flags.skip_test_records = skip_test_records

	if coverage:
		# Generate coverage report only for app that is being tested
		source_path = os.path.join(get_bench_path(), 'apps', app or 'frappe')
		cov = Coverage(source=[source_path], omit=['*.html', '*.js', '*.xml', '*.css', '*/doctype/*/*_dashboard.py', '*/patches/*'])
		cov.start()

	ret = frappe.test_runner.main(app, module, doctype, context.verbose, tests=tests,
		force=context.force, profile=profile, junit_xml_output=junit_xml_output,
		ui_tests = ui_tests, doctype_list_path = doctype_list_path, failfast=failfast)

	if coverage:
		cov.stop()
		cov.save()

	if len(ret.failures) == 0 and len(ret.errors) == 0:
		ret = 0

	if os.environ.get('CI'):
		sys.exit(ret)
示例#32
0
def run_ui_tests(context, app, headless=False, parallel=True, ci_build_id=None):
	"Run UI tests"
	site = get_site(context)
	app_base_path = os.path.abspath(os.path.join(frappe.get_app_path(app), '..'))
	site_url = frappe.utils.get_site_url(site)
	admin_password = frappe.get_conf(site).admin_password

	# override baseUrl using env variable
	site_env = f'CYPRESS_baseUrl={site_url}'
	password_env = f'CYPRESS_adminPassword={admin_password}' if admin_password else ''

	os.chdir(app_base_path)

	node_bin = subprocess.getoutput("npm bin")
	cypress_path = f"{node_bin}/cypress"
	plugin_path = f"{node_bin}/../cypress-file-upload"
	testing_library_path = f"{node_bin}/../@testing-library"

	# check if cypress in path...if not, install it.
	if not (
		os.path.exists(cypress_path)
		and os.path.exists(plugin_path)
		and os.path.exists(testing_library_path)
		and cint(subprocess.getoutput("npm view cypress version")[:1]) >= 6
	):
		# install cypress
		click.secho("Installing Cypress...", fg="yellow")
		frappe.commands.popen("yarn add cypress@^6 cypress-file-upload@^5 @testing-library/cypress@^8 --no-lockfile")

	# run for headless mode
	run_or_open = 'run --browser firefox --record' if headless else 'open'
	command = '{site_env} {password_env} {cypress} {run_or_open}'
	formatted_command = command.format(site_env=site_env, password_env=password_env, cypress=cypress_path, run_or_open=run_or_open)

	if parallel:
		formatted_command += ' --parallel'

	if ci_build_id:
		formatted_command += f' --ci-build-id {ci_build_id}'

	click.secho("Running Cypress...", fg="yellow")
	frappe.commands.popen(formatted_command, cwd=app_base_path, raise_err=True)
def mariadb(context):
    """
		Enter into mariadb console for a given site.
	"""
    import os
    import os.path as osp

    site = get_site(context)
    frappe.init(site=site)

    # This is assuming you're within the bench instance.
    path = os.getcwd()
    mysql = osp.join(path, '..', 'env', 'bin', 'mycli')
    args = [
        mysql, '-u', frappe.conf.db_name, '-p', frappe.conf.db_password, '-h',
        frappe.conf.db_host or "localhost", '-D', frappe.conf.db_name, '-R',
        '{site}> '.format(site=site), '--auto-vertical-output', '--warn'
    ]

    os.execv(mysql, args)
示例#34
0
def run_ui_tests(context, app, headless=False):
	"Run UI tests"

	site = get_site(context)
	app_base_path = os.path.abspath(os.path.join(frappe.get_app_path(app), '..'))
	site_url = frappe.utils.get_site_url(site)
	admin_password = frappe.get_conf(site).admin_password

	# override baseUrl using env variable
	site_env = 'CYPRESS_baseUrl={}'.format(site_url)
	password_env = 'CYPRESS_adminPassword={}'.format(admin_password) if admin_password else ''

	# run for headless mode
	run_or_open = 'run' if headless else 'open'

    # Brian - This may not work, simply substituting "npm" for "yarn"
    # Here's some info on the cypress CLI https://docs.cypress.io/guides/guides/command-line.html
	command = '{site_env} {password_env} npm run cypress:{run_or_open}'
	formatted_command = command.format(site_env=site_env, password_env=password_env, run_or_open=run_or_open)
	frappe.commands.popen(formatted_command, cwd=app_base_path, raise_err=True)
示例#35
0
文件: utils.py 项目: shiva032/frappe
def run_ui_tests(context, app=None, ci=False):
    "Run UI tests"
    import subprocess

    site = get_site(context)
    frappe.init(site=site)

    if app is None:
        app = ",".join(frappe.get_installed_apps())

    cmd = [
        './node_modules/.bin/nightwatch', '--config',
        './apps/frappe/frappe/nightwatch.js', '--app', app, '--site', site
    ]

    if ci:
        cmd.extend(['--env', 'ci_server'])

    bench_path = frappe.utils.get_bench_path()
    subprocess.call(cmd, cwd=bench_path)
示例#36
0
def ready_for_migration(context, site=None):
	from frappe.utils.doctor import get_pending_jobs

	if not site:
		site = get_site(context)

	try:
		frappe.init(site=site)
		pending_jobs = get_pending_jobs(site=site)

		if pending_jobs:
			print('NOT READY for migration: site {0} has pending background jobs'.format(site))
			sys.exit(1)

		else:
			print('READY for migration: site {0} does not have any background jobs'.format(site))
			return 0

	finally:
		frappe.destroy()
示例#37
0
文件: utils.py 项目: yered1/frappe
def mariadb(context):
	"""
		Enter into mariadb console for a given site.
	"""
	import os

	site  = get_site(context)
	frappe.init(site=site)

	# This is assuming you're within the bench instance.
	mysql = find_executable('mysql')
	os.execv(mysql, [
		mysql,
		'-u', frappe.conf.db_name,
		'-p'+frappe.conf.db_password,
		frappe.conf.db_name,
		'-h', frappe.conf.db_host or "localhost",
		'--pager=less -SFX',
		'--safe-updates',
		"-A"])
示例#38
0
文件: utils.py 项目: ektai/frappe3
def run_ui_tests(context, app, headless=False):
    "Run UI tests"

    site = get_site(context)
    app_base_path = os.path.abspath(
        os.path.join(frappe.get_app_path(app), '..'))
    site_url = frappe.utils.get_site_url(site)
    admin_password = frappe.get_conf(site).admin_password

    # override baseUrl using env variable
    site_env = 'CYPRESS_baseUrl={}'.format(site_url)
    password_env = 'CYPRESS_adminPassword={}'.format(
        admin_password) if admin_password else ''

    # run for headless mode
    run_or_open = 'run' if headless else 'open'
    command = '{site_env} {password_env} yarn run cypress {run_or_open}'
    formatted_command = command.format(site_env=site_env,
                                       password_env=password_env,
                                       run_or_open=run_or_open)
    frappe.commands.popen(formatted_command, cwd=app_base_path, raise_err=True)
示例#39
0
def _set_limits(context, site, limits):
    import datetime

    if not limits:
        return

    if not site:
        site = get_site(context)

    with frappe.init_site(site):
        frappe.connect()
        new_limits = {}
        for limit, value in limits:
            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',
                             'cancellation_url', 'subscription_status',
                             'support_tickets_limit'):
                frappe.throw(_('Invalid limit {0}').format(limit))

            if limit == 'expiry' and value:
                try:
                    datetime.datetime.strptime(value, '%Y-%m-%d')
                except ValueError:
                    raise ValueError(
                        "Incorrect data format, should be YYYY-MM-DD")

            elif limit in ('space', 'subscription_base_price',
                           'upgrade_base_price'):
                value = float(value)

            elif limit in ('users', 'emails', 'email_group', 'daily_emails'):
                value = int(value)

            new_limits[limit] = value

        update_limits(new_limits)
示例#40
0
def import_csv(
	context,
	path,
	only_insert=False,
	submit_after_import=False,
	ignore_encoding_errors=False,
	no_email=True,
):
	"Import CSV using data import"
	from frappe.core.doctype.data_import_legacy import importer
	from frappe.utils.csvutils import read_csv_content

	site = get_site(context)

	if not os.path.exists(path):
		path = os.path.join("..", path)
	if not os.path.exists(path):
		print("Invalid path {0}".format(path))
		sys.exit(1)

	with open(path, "r") as csvfile:
		content = read_csv_content(csvfile.read())

	frappe.init(site=site)
	frappe.connect()

	try:
		importer.upload(
			content,
			submit_after_import=submit_after_import,
			no_email=no_email,
			ignore_encoding_errors=ignore_encoding_errors,
			overwrite=not only_insert,
			via_console=True,
		)
		frappe.db.commit()
	except Exception:
		print(frappe.get_traceback())

	frappe.destroy()
示例#41
0
def console(context):
    "Start ipython console for a site"
    site = get_site(context)
    frappe.init(site=site)
    frappe.connect()
    frappe.local.lang = frappe.db.get_default("lang")

    import IPython
    all_apps = frappe.get_installed_apps()
    failed_to_import = []

    for app in all_apps:
        try:
            locals()[app] = __import__(app)
        except ModuleNotFoundError:
            failed_to_import.append(app)

    print("Apps in this namespace:\n{}".format(", ".join(all_apps)))
    if failed_to_import:
        print("\nFailed to import:\n{}".format(", ".join(failed_to_import)))

    IPython.embed(display_banner="", header="", colors="neutral")
示例#42
0
def run_ui_tests(context,
                 app=None,
                 test=False,
                 test_list=False,
                 profile=False):
    "Run UI tests"
    import frappe.test_runner

    site = get_site(context)
    frappe.init(site=site)
    frappe.connect()

    ret = frappe.test_runner.run_ui_tests(app=app,
                                          test=test,
                                          test_list=test_list,
                                          verbose=context.verbose,
                                          profile=profile)
    if len(ret.failures) == 0 and len(ret.errors) == 0:
        ret = 0

    if os.environ.get('CI'):
        sys.exit(ret)
示例#43
0
def jupyter(context):
    try:
        from pip import main
    except ImportError:
        from pip._internal import main

    reqs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze'])
    installed_packages = [r.decode().split('==')[0] for r in reqs.split()]
    if 'jupyter' not in installed_packages:
        main(['install', 'jupyter'])
    site = get_site(context)
    frappe.init(site=site)
    jupyter_notebooks_path = os.path.abspath(
        frappe.get_site_path('jupyter_notebooks'))
    sites_path = os.path.abspath(frappe.get_site_path('..'))
    try:
        os.stat(jupyter_notebooks_path)
    except OSError:
        print('Creating folder to keep jupyter notebooks at {}'.format(
            jupyter_notebooks_path))
        os.mkdir(jupyter_notebooks_path)
    bin_path = os.path.abspath('../env/bin')
    print('''
Stating Jupyter notebook
Run the following in your first cell to connect notebook to frappe
```
import frappe
frappe.init(site='{site}', sites_path='{sites_path}')
frappe.connect()
frappe.local.lang = frappe.db.get_default('lang')
frappe.db.connect()
```
	'''.format(site=site, sites_path=sites_path))
    os.execv('{0}/jupyter'.format(bin_path), [
        '{0}/jupyter'.format(bin_path),
        'notebook',
        jupyter_notebooks_path,
    ])
示例#44
0
def reinstall(context, admin_password=None, yes=False):
	"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)
	try:
		frappe.init(site=site)
		frappe.connect()
		frappe.clear_cache()
		installed = frappe.get_installed_apps()
		frappe.clear_cache()
	except Exception:
		installed = []
	finally:
		if frappe.db:
			frappe.db.close()
		frappe.destroy()

	frappe.init(site=site)
	_new_site(frappe.conf.db_name, site, verbose=context.verbose, force=True, reinstall=True,
		install_apps=installed, admin_password=admin_password)
示例#45
0
def reinstall(context):
    "Reinstall site ie. wipe all data and start over"
    site = get_site(context)
    try:
        frappe.init(site=site)
        frappe.connect()
        frappe.clear_cache()
        installed = frappe.get_installed_apps()
        frappe.clear_cache()
    except Exception:
        installed = []
    finally:
        if frappe.db:
            frappe.db.close()
        frappe.destroy()

    frappe.init(site=site)
    _new_site(frappe.conf.db_name,
              site,
              verbose=context.verbose,
              force=True,
              reinstall=True,
              install_apps=installed)
示例#46
0
def run_ui_tests(context, app, headless=False):
    "Run UI tests"
    site = get_site(context)
    app_base_path = os.path.abspath(
        os.path.join(frappe.get_app_path(app), '..'))
    site_url = frappe.utils.get_site_url(site)
    admin_password = frappe.get_conf(site).admin_password

    # override baseUrl using env variable
    site_env = 'CYPRESS_baseUrl={}'.format(site_url)
    password_env = 'CYPRESS_adminPassword={}'.format(
        admin_password) if admin_password else ''

    os.chdir(app_base_path)

    node_bin = subprocess.getoutput("npm bin")
    cypress_path = "{0}/cypress".format(node_bin)
    plugin_path = "{0}/cypress-file-upload".format(node_bin)

    # check if cypress in path...if not, install it.
    if not (os.path.exists(cypress_path) or os.path.exists(plugin_path)) \
     or not subprocess.getoutput("npm view cypress version").startswith("6."):
        # install cypress
        click.secho("Installing Cypress...", fg="yellow")
        frappe.commands.popen(
            "yarn add cypress@^6 cypress-file-upload@^5 --no-lockfile")

    # run for headless mode
    run_or_open = 'run --browser firefox --record --key 4a48f41c-11b3-425b-aa88-c58048fa69eb' if headless else 'open'
    command = '{site_env} {password_env} {cypress} {run_or_open}'
    formatted_command = command.format(site_env=site_env,
                                       password_env=password_env,
                                       cypress=cypress_path,
                                       run_or_open=run_or_open)

    click.secho("Running Cypress...", fg="yellow")
    frappe.commands.popen(formatted_command, cwd=app_base_path, raise_err=True)
示例#47
0
def restore(context,
            sql_file_path,
            mariadb_root_username=None,
            mariadb_root_password=None,
            db_name=None,
            verbose=None,
            install_app=None,
            admin_password=None,
            force=None,
            with_public_files=None,
            with_private_files=None):
    "Restore site database from an sql file"
    from frappe.installer import extract_sql_gzip, extract_tar_files
    # Extract the gzip file if user has passed *.sql.gz file instead of *.sql file
    if sql_file_path.endswith('sql.gz'):
        sql_file_path = extract_sql_gzip(os.path.abspath(sql_file_path))

    site = get_site(context)
    frappe.init(site=site)
    db_name = db_name or frappe.conf.db_name or hashlib.sha1(
        site).hexdigest()[:10]
    _new_site(db_name,
              site,
              mariadb_root_username=mariadb_root_username,
              mariadb_root_password=mariadb_root_password,
              admin_password=admin_password,
              verbose=context.verbose,
              install_apps=install_app,
              source_sql=sql_file_path,
              force=context.force)

    # Extract public and/or private files to the restored site, if user has given the path
    if with_public_files:
        extract_tar_files(site, with_public_files, 'public')

    if with_private_files:
        extract_tar_files(site, with_private_files, 'private')
示例#48
0
def make_demo(context, site, domain='Manufacturing', days=100,
	resume=False, reinstall=False):
	"Reinstall site and setup demo"
	from frappe.commands.site import _reinstall
	from frappe.installer import install_app

	site = get_site(context)

	if resume:
		with frappe.init_site(site):
			frappe.connect()
			from erpnext.demo import demo
			demo.simulate(days=days)
	else:
		if reinstall:
			_reinstall(site, yes=True)
		with frappe.init_site(site=site):
			frappe.connect()
			if not 'erpnext' in frappe.get_installed_apps():
				install_app('erpnext')

			# import needs site
			from erpnext.demo import demo
			demo.make(domain, days)
示例#49
0
def run_tests(context,
              app=None,
              module=None,
              doctype=None,
              test=(),
              driver=None,
              profile=False,
              junit_xml_output=False):
    "Run tests"
    import frappe.test_runner
    from frappe.utils import sel
    tests = test

    site = get_site(context)
    frappe.init(site=site)

    if frappe.conf.run_selenium_tests and False:
        sel.start(context.verbose, driver)

    try:
        ret = frappe.test_runner.main(app,
                                      module,
                                      doctype,
                                      context.verbose,
                                      tests=tests,
                                      force=context.force,
                                      profile=profile,
                                      junit_xml_output=junit_xml_output)
        if len(ret.failures) == 0 and len(ret.errors) == 0:
            ret = 0
    finally:
        pass
        if frappe.conf.run_selenium_tests:
            sel.close()

    sys.exit(ret)
示例#50
0
def restore(
    context,
    sql_file_path,
    db_root_username=None,
    db_root_password=None,
    db_name=None,
    verbose=None,
    install_app=None,
    admin_password=None,
    force=None,
    with_public_files=None,
    with_private_files=None,
):
    "Restore site database from an sql file"
    from frappe.installer import (
        _new_site,
        extract_files,
        extract_sql_from_archive,
        is_downgrade,
        is_partial,
        validate_database_sql,
    )

    force = context.force or force
    decompressed_file_name = extract_sql_from_archive(sql_file_path)

    # check if partial backup
    if is_partial(decompressed_file_name):
        click.secho(
            "Partial Backup file detected. You cannot use a partial file to restore a Frappe Site.",
            fg="red",
        )
        click.secho(
            "Use `bench partial-restore` to restore a partial backup to an existing site.",
            fg="yellow")
        sys.exit(1)

    # check if valid SQL file
    validate_database_sql(decompressed_file_name, _raise=not force)

    site = get_site(context)
    frappe.init(site=site)

    # dont allow downgrading to older versions of frappe without force
    if not force and is_downgrade(decompressed_file_name, verbose=True):
        warn_message = (
            "This is not recommended and may lead to unexpected behaviour. "
            "Do you want to continue anyway?")
        click.confirm(warn_message, abort=True)

    _new_site(
        frappe.conf.db_name,
        site,
        db_root_username=db_root_username,
        db_root_password=db_root_password,
        admin_password=admin_password,
        verbose=context.verbose,
        install_apps=install_app,
        source_sql=decompressed_file_name,
        force=True,
        db_type=frappe.conf.db_type,
    )

    # Extract public and/or private files to the restored site, if user has given the path
    if with_public_files:
        public = extract_files(site, with_public_files)
        os.remove(public)

    if with_private_files:
        private = extract_files(site, with_private_files)
        os.remove(private)

    # Removing temporarily created file
    if decompressed_file_name != sql_file_path:
        os.remove(decompressed_file_name)

    success_message = "Site {0} has been restored{1}".format(
        site, " with files" if
        (with_public_files or with_private_files) else "")
    click.secho(success_message, fg="green")
示例#51
0
def restore(context,
            sql_file_path,
            mariadb_root_username=None,
            mariadb_root_password=None,
            db_name=None,
            verbose=None,
            install_app=None,
            admin_password=None,
            force=None,
            with_public_files=None,
            with_private_files=None):
    "Restore site database from an sql file"
    from frappe.installer import extract_sql_gzip, extract_tar_files, is_downgrade
    force = context.force or force

    # Extract the gzip file if user has passed *.sql.gz file instead of *.sql file
    if not os.path.exists(sql_file_path):
        base_path = '..'
        sql_file_path = os.path.join(base_path, sql_file_path)
        if not os.path.exists(sql_file_path):
            print('Invalid path {0}'.format(sql_file_path[3:]))
            sys.exit(1)
    elif sql_file_path.startswith(os.sep):
        base_path = os.sep
    else:
        base_path = '.'

    if sql_file_path.endswith('sql.gz'):
        decompressed_file_name = extract_sql_gzip(
            os.path.abspath(sql_file_path))
    else:
        decompressed_file_name = sql_file_path

    site = get_site(context)
    frappe.init(site=site)

    # dont allow downgrading to older versions of frappe without force
    if not force and is_downgrade(decompressed_file_name, verbose=True):
        warn_message = "This is not recommended and may lead to unexpected behaviour. Do you want to continue anyway?"
        click.confirm(warn_message, abort=True)

    _new_site(frappe.conf.db_name,
              site,
              mariadb_root_username=mariadb_root_username,
              mariadb_root_password=mariadb_root_password,
              admin_password=admin_password,
              verbose=context.verbose,
              install_apps=install_app,
              source_sql=decompressed_file_name,
              force=True,
              db_type=frappe.conf.db_type)

    # Extract public and/or private files to the restored site, if user has given the path
    if with_public_files:
        with_public_files = os.path.join(base_path, with_public_files)
        public = extract_tar_files(site, with_public_files, 'public')
        os.remove(public)

    if with_private_files:
        with_private_files = os.path.join(base_path, with_private_files)
        private = extract_tar_files(site, with_private_files, 'private')
        os.remove(private)

    # Removing temporarily created file
    if decompressed_file_name != sql_file_path:
        os.remove(decompressed_file_name)

    success_message = "Site {0} has been restored{1}".format(
        site, " with files" if
        (with_public_files or with_private_files) else "")
    click.secho(success_message, fg="green")
示例#52
0
def transform_database(context, table, engine, row_format, failfast):
    "Transform site database through given parameters"
    site = get_site(context)
    check_table = []
    add_line = False
    skipped = 0
    frappe.init(site=site)

    if frappe.conf.db_type and frappe.conf.db_type != "mariadb":
        click.secho(
            "This command only has support for MariaDB databases at this point",
            fg="yellow")
        sys.exit(1)

    if not (engine or row_format):
        click.secho("Values for `--engine` or `--row_format` must be set")
        sys.exit(1)

    frappe.connect()

    if table == "all":
        information_schema = frappe.qb.Schema("information_schema")
        queried_tables = frappe.qb.from_(
            information_schema.tables).select("table_name").where(
                (information_schema.tables.row_format != row_format)
                & (information_schema.tables.table_schema ==
                   frappe.conf.db_name)).run()
        tables = [x[0] for x in queried_tables]
    else:
        tables = [x.strip() for x in table.split(",")]

    total = len(tables)

    for current, table in enumerate(tables):
        values_to_set = ""
        if engine:
            values_to_set += f" ENGINE={engine}"
        if row_format:
            values_to_set += f" ROW_FORMAT={row_format}"

        try:
            frappe.db.sql(f"ALTER TABLE `{table}`{values_to_set}")
            update_progress_bar("Updating table schema", current - skipped,
                                total)
            add_line = True

        except Exception as e:
            check_table.append([table, e.args])
            skipped += 1

            if failfast:
                break

    if add_line:
        print()

    for errored_table in check_table:
        table, err = errored_table
        err_msg = f"{table}: ERROR {err[0]}: {err[1]}"
        click.secho(err_msg, fg="yellow")

    frappe.destroy()
示例#53
0
def take(context, name):
	site = get_site(context)
	frappe.init(site=site)
	frappe.connect()
	SnapshotGenerator(name).take()
	frappe.db.close()
示例#54
0
def delete(context, name):
	site = get_site(context)
	frappe.init(site=site)
	SnapshotGenerator(name).delete()
示例#55
0
def list(context):
	site = get_site(context)
	frappe.init(site=site)

	for name, filename in get_snapshots_data().items():
		print name
示例#56
0
def restore(context,
            sql_file_path,
            mariadb_root_username=None,
            mariadb_root_password=None,
            db_name=None,
            verbose=None,
            install_app=None,
            admin_password=None,
            force=None,
            with_public_files=None,
            with_private_files=None):
    "Restore site database from an sql file"
    from frappe.installer import extract_sql_gzip, extract_tar_files
    # Extract the gzip file if user has passed *.sql.gz file instead of *.sql file

    if not os.path.exists(sql_file_path):
        base_path = '..'
        sql_file_path = os.path.join(base_path, sql_file_path)
        if not os.path.exists(sql_file_path):
            print('Invalid path {0}'.format(sql_file_path[3:]))
            sys.exit(1)
    elif sql_file_path.startswith(os.sep):
        base_path = os.sep
    else:
        base_path = '.'

    if sql_file_path.endswith('sql.gz'):
        decompressed_file_name = extract_sql_gzip(
            os.path.abspath(sql_file_path))
    else:
        decompressed_file_name = sql_file_path

    site = get_site(context)
    frappe.init(site=site)
    _new_site(frappe.conf.db_name,
              site,
              mariadb_root_username=mariadb_root_username,
              mariadb_root_password=mariadb_root_password,
              admin_password=admin_password,
              verbose=context.verbose,
              install_apps=install_app,
              source_sql=decompressed_file_name,
              force=True)

    # Extract public and/or private files to the restored site, if user has given the path
    if with_public_files:
        with_public_files = os.path.join(base_path, with_public_files)
        public = extract_tar_files(site, with_public_files, 'public')
        os.remove(public)

    if with_private_files:
        with_private_files = os.path.join(base_path, with_private_files)
        private = extract_tar_files(site, with_private_files, 'private')
        os.remove(private)

    # Removing temporarily created file
    if decompressed_file_name != sql_file_path:
        os.remove(decompressed_file_name)

    success_message = "Site {0} has been restored{1}".format(
        site, " with files" if
        (with_public_files or with_private_files) else "")
    click.secho(success_message, fg="green")
示例#57
0
def reinstall(context, admin_password=None, yes=False):
    "Reinstall site ie. wipe all data and start over"
    site = get_site(context)
    _reinstall(site, admin_password, yes, verbose=context.verbose)
示例#58
0
def mysql(context):
	"Start Mariadb console for a site"
	site = get_site(context)
	frappe.init(site=site)
	msq = find_executable('mysql')
	os.execv(msq, [msq, '-u', frappe.conf.db_name, '-p'+frappe.conf.db_password, frappe.conf.db_name, '-h', frappe.conf.db_host or "localhost", "-A"])
示例#59
0
def doctor(context, site=None):
	"Get diagnostic info about background workers"
	from frappe.utils.doctor import doctor as _doctor
	if not site:
		site = get_site(context, raise_err=False)
	return _doctor(site=site)