def make_demo(context, site, domain='Manufacturing', days=100, resume=False, reinstall=False): "Reinstall site and setup demo" from dataent.commands.site import _reinstall from dataent.installer import install_app site = get_site(context) if resume: with dataent.init_site(site): dataent.connect() from epaas.demo import demo demo.simulate(days=days) else: if reinstall: _reinstall(site, yes=True) with dataent.init_site(site=site): dataent.connect() if not 'epaas' in dataent.get_installed_apps(): install_app('epaas') # import needs site from epaas.demo import demo demo.make(domain, days)
def list_apps(context): "List apps in site" site = get_site(context) dataent.init(site=site) dataent.connect() print("\n".join(dataent.get_installed_apps())) dataent.destroy()
def scheduler(context, state, site=None): from dataent.installer import update_site_config import dataent.utils.scheduler if not site: site = get_site(context) try: dataent.init(site=site) if state == 'pause': update_site_config('pause_scheduler', 1) elif state == 'resume': update_site_config('pause_scheduler', 0) elif state == 'disable': dataent.connect() dataent.utils.scheduler.disable_scheduler() dataent.db.commit() elif state == 'enable': dataent.connect() dataent.utils.scheduler.enable_scheduler() dataent.db.commit() print('Scheduler {0}d for site {1}'.format(state, site)) finally: dataent.destroy()
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 dataent.core.doctype.data_import import importer from dataent.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()) dataent.init(site=site) dataent.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) dataent.db.commit() except Exception: print(dataent.get_traceback()) dataent.destroy()
def console(context): "Start ipython console for a site" site = get_site(context) dataent.init(site=site) dataent.connect() dataent.local.lang = dataent.db.get_default("lang") import IPython IPython.embed(display_banner="")
def disable_user(context, email): site = get_site(context) with dataent.init_site(site): dataent.connect() user = dataent.get_doc("User", email) user.enabled = 0 user.save(ignore_permissions=True) dataent.db.commit()
def show_pending_jobs(context, site=None): "Get diagnostic info about background jobs" from dataent.utils.doctor import pending_jobs as _pending_jobs if not site: site = get_site(context) with dataent.init_site(site): pending_jobs = _pending_jobs(site=site) return pending_jobs
def import_translations(context, lang, path): "Update translated strings" import dataent.translate site = get_site(context) try: dataent.init(site=site) dataent.connect() dataent.translate.import_translations(lang, path) finally: dataent.destroy()
def update_translations(context, lang, untranslated_file, translated_file): "Update translated strings" import dataent.translate site = get_site(context) try: dataent.init(site=site) dataent.connect() dataent.translate.update_translations(lang, untranslated_file, translated_file) finally: dataent.destroy()
def set_maintenance_mode(context, state, site=None): from dataent.installer import update_site_config if not site: site = get_site(context) try: dataent.init(site=site) update_site_config('maintenance_mode', 1 if (state == 'on') else 0) finally: dataent.destroy()
def get_untranslated(context, lang, untranslated_file, all=None): "Get untranslated strings for language" import dataent.translate site = get_site(context) try: dataent.init(site=site) dataent.connect() dataent.translate.get_untranslated(lang, untranslated_file, get_all=all) finally: dataent.destroy()
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 dataent.test_runner tests = test site = get_site(context) dataent.init(site=site) dataent.flags.skip_before_tests = skip_before_tests dataent.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 'dataent') cov = Coverage(source=[source_path], omit=['*.html', '*.js', '*.css']) cov.start() ret = dataent.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)
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 dataent.init_site(site): dataent.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 dataent.sendmail(**kwargs) dataent.db.commit()
def reinstall(context, admin_password=None, mariadb_root_username=None, mariadb_root_password=None, yes=False): "Reinstall site ie. wipe all data and start over" site = get_site(context) _reinstall(site, admin_password, mariadb_root_username, mariadb_root_password, yes, verbose=context.verbose)
def run_setup_wizard_ui_test(context, app=None, profile=False): "Run setup wizard UI test" import dataent.test_runner site = get_site(context) dataent.init(site=site) dataent.connect() ret = dataent.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)
def clear_limits(context, site, limits): """Clears given limit from the site config, and removes limit from site config if its empty""" from dataent.limits import clear_limit as _clear_limit if not limits: return if not site: site = get_site(context) with dataent.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)
def _bulk_rename(context, doctype, path): "Rename multiple records via CSV file" from dataent.model.rename_doc import bulk_rename from dataent.utils.csvutils import read_csv_content site = get_site(context) with open(path, 'r') as csvfile: rows = read_csv_content(csvfile.read()) dataent.init(site=site) dataent.connect() bulk_rename(doctype, rows, via_console=True) dataent.destroy()
def mariadb(context): """ Enter into mariadb console for a given site. """ import os site = get_site(context) dataent.init(site=site) # This is assuming you're within the bench instance. mysql = find_executable('mysql') os.execv(mysql, [ mysql, '-u', dataent.conf.db_name, '-p' + dataent.conf.db_password, dataent.conf.db_name, '-h', dataent.conf.db_host or "localhost", '--pager=less -SFX', "-A" ])
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 dataent.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}'.format(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) dataent.init(site=site) _new_site(dataent.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)
def set_last_active_for_user(context, user=None): "Set users last active date to current datetime" from dataent.core.doctype.user.user import get_system_users from dataent.utils.user import set_last_active_to_now site = get_site(context) with dataent.init_site(site): dataent.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) dataent.db.commit()
def ready_for_migration(context, site=None): from dataent.utils.doctor import get_pending_jobs if not site: site = get_site(context) try: dataent.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: dataent.destroy()
def _set_limits(context, site, limits): import datetime if not limits: return if not site: site = get_site(context) with dataent.init_site(site): dataent.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'): dataent.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)
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) dataent.init(site=site) jupyter_notebooks_path = os.path.abspath( dataent.get_site_path('jupyter_notebooks')) sites_path = os.path.abspath(dataent.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 dataent ``` import dataent dataent.init(site='{site}', sites_path='{sites_path}') dataent.connect() dataent.local.lang = dataent.db.get_default('lang') dataent.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, ])