Exemplo n.º 1
0
def _drop_site(site, root_login='******', root_password=None, archived_sites_path=None, force=False, no_backup=False):
	"Remove site from database and filesystem"
	from frappe.database import drop_user_and_database
	from frappe.utils.backups import scheduled_backup

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

	try:
		if not no_backup:
			scheduled_backup(ignore_files=False, force=True)
	except Exception as err:
		if force:
			pass
		else:
			messages = [
				"=" * 80,
				"Error: The operation has stopped because backup of {0}'s database failed.".format(site),
				"Reason: {0}\n".format(str(err)),
				"Fix the issue and try again.",
				"Hint: Use 'bench drop-site {0} --force' to force the removal of {0}".format(site)
			]
			click.echo("\n".join(messages))
			sys.exit(1)

	drop_user_and_database(frappe.conf.db_name, root_login, root_password)

	if not archived_sites_path:
		archived_sites_path = os.path.join(frappe.get_app_path('frappe'), '..', '..', '..', 'archived_sites')

	if not os.path.exists(archived_sites_path):
		os.mkdir(archived_sites_path)

	move(archived_sites_path, site)
Exemplo n.º 2
0
def _drop_site(site, root_login='******', root_password=None, archived_sites_path=None, force=False):
	"Remove site from database and filesystem"
	from frappe.database import drop_user_and_database
	from frappe.utils.backups import scheduled_backup

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

	try:
		scheduled_backup(ignore_files=False, force=True)
	except Exception as err:
		if force:
			pass
		else:
			click.echo("="*80)
			click.echo("Error: The operation has stopped because backup of {s}'s database failed.".format(s=site))
			click.echo("Reason: {reason}{sep}".format(reason=err[1], sep="\n"))
			click.echo("Fix the issue and try again.")
			click.echo(
				"Hint: Use 'bench drop-site {s} --force' to force the removal of {s}".format(sep="\n", tab="\t", s=site)
			)
			sys.exit(1)

	drop_user_and_database(frappe.conf.db_name, root_login, root_password)

	if not archived_sites_path:
		archived_sites_path = os.path.join(frappe.get_app_path('frappe'), '..', '..', '..', 'archived_sites')

	if not os.path.exists(archived_sites_path):
		os.mkdir(archived_sites_path)

	move(archived_sites_path, site)
Exemplo n.º 3
0
def remove_app(app_name, dry_run=False, yes=False):
    """Delete app and all linked to the app's module with the app."""

    if not dry_run and not yes:
        confirm = raw_input(
            "All doctypes (including custom), modules related to this app will be deleted. Are you sure you want to continue (y/n) ? "
        )
        if confirm != "y":
            return

    from frappe.utils.backups import scheduled_backup
    print "Backing up..."
    scheduled_backup(ignore_files=True)

    drop_doctypes = []

    # remove modules, doctypes, roles
    for module_name in frappe.get_module_list(app_name):
        for doctype in frappe.get_list("DocType",
                                       filters={"module": module_name},
                                       fields=["name", "issingle"]):
            print "removing DocType {0}...".format(doctype.name)
            # drop table

            if not dry_run:
                frappe.delete_doc("DocType", doctype.name)

                if not doctype.issingle:
                    drop_doctypes.append(doctype.name)

        # remove reports
        for report in frappe.get_list("Report",
                                      filters={"module": module_name}):
            print "removing {0}...".format(report.name)
            if not dry_run:
                frappe.delete_doc("Report", report.name)

        for page in frappe.get_list("Page", filters={"module": module_name}):
            print "removing Page {0}...".format(page.name)
            # drop table

            if not dry_run:
                frappe.delete_doc("Page", page.name)

        print "removing Module {0}...".format(module_name)

        if not dry_run:
            frappe.delete_doc("Module Def", module_name)

    # delete desktop icons
    frappe.db.sql('delete from `tabDesktop Icon` where app=%s', app_name)

    remove_from_installed_apps(app_name)

    if not dry_run:
        # drop tables after a commit
        frappe.db.commit()

        for doctype in set(drop_doctypes):
            frappe.db.sql("drop table `tab{0}`".format(doctype))
Exemplo n.º 4
0
def drop_site(site,
              root_login='******',
              root_password=None,
              archived_sites_path=None):
    "Remove site from database and filesystem"
    from frappe.installer import get_current_host, make_connection
    from frappe.model.db_schema import DbManager
    from frappe.utils.backups import scheduled_backup

    frappe.init(site=site)
    frappe.connect()
    scheduled_backup(ignore_files=False, force=True)

    db_name = frappe.local.conf.db_name
    frappe.local.db = make_connection(root_login, root_password)
    dbman = DbManager(frappe.local.db)
    dbman.delete_user(db_name, get_current_host())
    dbman.drop_database(db_name)

    if not archived_sites_path:
        archived_sites_path = os.path.join(frappe.get_app_path('frappe'), '..',
                                           '..', '..', 'archived_sites')

    if not os.path.exists(archived_sites_path):
        os.mkdir(archived_sites_path)

    move(archived_sites_path, site)
Exemplo n.º 5
0
def remove_app(app_name, dry_run=False):
	"""Delete app and all linked to the app's module with the app."""

	if not dry_run:
		confirm = raw_input("All doctypes (including custom), modules related to this app will be deleted. Are you sure you want to continue (y/n) ? ")
		if confirm!="y":
			return

	from frappe.utils.backups import scheduled_backup
	print "Backing up..."
	scheduled_backup(ignore_files=True)

	# remove modules, doctypes, roles
	for module_name in frappe.get_module_list(app_name):
		for doctype in frappe.get_list("DocType", filters={"module": module_name},
			fields=["name", "issingle"]):
			print "removing {0}...".format(doctype.name)
			# drop table

			if not dry_run:
				if not doctype.issingle:
					frappe.db.sql("drop table `tab{0}`".format(doctype.name))
				frappe.delete_doc("DocType", doctype.name)

		print "removing Module {0}...".format(module_name)
		if not dry_run:
			frappe.delete_doc("Module Def", module_name)

	remove_from_installed_apps(app_name)
Exemplo n.º 6
0
def remove_app(app_name, dry_run=False, yes=False):
	"""Delete app and all linked to the app's module with the app."""

	if not dry_run and not yes:
		confirm = input("All doctypes (including custom), modules related to this app will be deleted. Are you sure you want to continue (y/n) ? ")
		if confirm!="y":
			return

	from frappe.utils.backups import scheduled_backup
	print("Backing up...")
	scheduled_backup(ignore_files=True)

	drop_doctypes = []

	# remove modules, doctypes, roles
	for module_name in frappe.get_module_list(app_name):
		for doctype in frappe.get_list("DocType", filters={"module": module_name},
			fields=["name", "issingle"]):
			print("removing DocType {0}...".format(doctype.name))

			if not dry_run:
				frappe.delete_doc("DocType", doctype.name)

				if not doctype.issingle:
					drop_doctypes.append(doctype.name)
Exemplo n.º 7
0
def remove_app(app_name, dry_run=False, yes=False):
	"""Delete app and all linked to the app's module with the app."""

	if not dry_run and not yes:
		confirm = raw_input("All doctypes (including custom), modules related to this app will be deleted. Are you sure you want to continue (y/n) ? ")
		if confirm!="y":
			return

	from frappe.utils.backups import scheduled_backup
	print "Backing up..."
	scheduled_backup(ignore_files=True)

	drop_doctypes = []

	# remove modules, doctypes, roles
	for module_name in frappe.get_module_list(app_name):
		for doctype in frappe.get_list("DocType", filters={"module": module_name},
			fields=["name", "issingle"]):
			print "removing DocType {0}...".format(doctype.name)
			# drop table

			if not dry_run:
				frappe.delete_doc("DocType", doctype.name)

				if not doctype.issingle:
					drop_doctypes.append(doctype.name)

		# remove reports
		for report in frappe.get_list("Report", filters={"module": module_name}):
			print "removing {0}...".format(report.name)
			if not dry_run:
				frappe.delete_doc("Report", report.name)

		for page in frappe.get_list("Page", filters={"module": module_name}):
			print "removing Page {0}...".format(page.name)
			# drop table

			if not dry_run:
				frappe.delete_doc("Page", page.name)

		print "removing Module {0}...".format(module_name)

		if not dry_run:
			frappe.delete_doc("Module Def", module_name)

	# delete desktop icons
	frappe.db.sql('delete from `tabDesktop Icon` where app=%s', app_name)

	remove_from_installed_apps(app_name)

	if not dry_run:
		# drop tables after a commit
		frappe.db.commit()

		for doctype in set(drop_doctypes):
			frappe.db.sql("drop table `tab{0}`".format(doctype))
Exemplo n.º 8
0
def remove_app(app_name, dry_run=False, yes=False):
	"""Delete app and all linked to the app's module with the app."""

	if not dry_run and not yes:
		confirm = input("All doctypes (including custom), modules related to this app will be deleted. Are you sure you want to continue (y/n) ? ")
		if confirm!="y":
			return

	from frappe.utils.backups import scheduled_backup
	print("Backing up...")
	scheduled_backup(ignore_files=True)

	drop_doctypes = []

	# remove modules, doctypes, roles
	for module_name in frappe.get_module_list(app_name):
		for doctype in frappe.get_list("DocType", filters={"module": module_name},
			fields=["name", "issingle"]):
			print("removing DocType {0}...".format(doctype.name))

			if not dry_run:
				frappe.delete_doc("DocType", doctype.name)

				if not doctype.issingle:
					drop_doctypes.append(doctype.name)

		# remove reports, pages and web forms
		for doctype in ("Report", "Page", "Web Form", "Print Format"):
			for record in frappe.get_list(doctype, filters={"module": module_name}):
				print("removing {0} {1}...".format(doctype, record.name))
				if not dry_run:
					frappe.delete_doc(doctype, record.name)

		# remove data migration plans and linked data migration runs
		for plan in frappe.get_list("Data Migration Plan", filters={"module": module_name}):
			print("removing Data Migration Runs for Data Migration Plan {0}...".format(plan.name))
			for record in frappe.get_list("Data Migration Run", filters={"data_migration_plan": plan.name}):
				if not dry_run:
					frappe.delete_doc("Data Migration Run", record.name)

			print("removing Data Migration Plan {0}...".format(plan.name))
			if not dry_run:
				frappe.delete_doc("Data Migration Plan", plan.name)

		print("removing Module {0}...".format(module_name))
		if not dry_run:
			frappe.delete_doc("Module Def", module_name)

	remove_from_installed_apps(app_name)

	if not dry_run:
		# drop tables after a commit
		frappe.db.commit()

		for doctype in set(drop_doctypes):
			frappe.db.sql("drop table `tab{0}`".format(doctype))
Exemplo n.º 9
0
def remove_app(app_name,
               dry_run=False,
               yes=False,
               no_backup=False,
               force=False):
    """Remove app and all linked to the app's module with the app from a site."""
    import click

    site = frappe.local.site
    app_hooks = frappe.get_hooks(app_name=app_name)

    # dont allow uninstall app if not installed unless forced
    if not force:
        if app_name not in frappe.get_installed_apps():
            click.secho(f"App {app_name} not installed on Site {site}",
                        fg="yellow")
            return

    print(f"Uninstalling App {app_name} from Site {site}...")

    if not dry_run and not yes:
        confirm = click.confirm(
            "All doctypes (including custom), modules related to this app will be"
            " deleted. Are you sure you want to continue?")
        if not confirm:
            return

    if not (dry_run or no_backup):
        from frappe.utils.backups import scheduled_backup

        print("Backing up...")
        scheduled_backup(ignore_files=True)

    frappe.flags.in_uninstall = True

    for before_uninstall in app_hooks.before_uninstall or []:
        frappe.get_attr(before_uninstall)()

    modules = frappe.get_all("Module Def",
                             filters={"app_name": app_name},
                             pluck="name")

    drop_doctypes = _delete_modules(modules, dry_run=dry_run)
    _delete_doctypes(drop_doctypes, dry_run=dry_run)

    if not dry_run:
        remove_from_installed_apps(app_name)
        frappe.get_single("Installed Applications").update_versions()
        frappe.db.commit()

    for after_uninstall in app_hooks.after_uninstall or []:
        frappe.get_attr(after_uninstall)()

    click.secho(f"Uninstalled App {app_name} from Site {site}", fg="green")
    frappe.flags.in_uninstall = False
Exemplo n.º 10
0
def backup(context, with_files=False, backup_path_db=None, backup_path_files=None,
	backup_path_private_files=None, quiet=False, verbose=False):
	"Backup"
	from frappe.utils.backups import scheduled_backup
	verbose = verbose or context.verbose
	exit_code = 0
	for site in context.sites:
		try:
			frappe.init(site=site)
			frappe.connect()
			odb = scheduled_backup(ignore_files=not with_files, backup_path_db=backup_path_db, backup_path_files=backup_path_files, backup_path_private_files=backup_path_private_files, force=True, verbose=verbose)
		except Exception as e:
			if verbose:
				print("Backup failed for {0}. Database or site_config.json may be corrupted".format(site))
			exit_code = 1
			continue

		if verbose:
			from frappe.utils import now
			summary_title = "Backup Summary at {0}".format(now())
			print(summary_title + "\n" + "-" * len(summary_title))
			print("Database backup:", odb.backup_path_db)
			if with_files:
				print("Public files:   ", odb.backup_path_files)
				print("Private files:  ", odb.backup_path_private_files)

		frappe.destroy()
	if not context.sites:
		raise SiteNotSpecifiedError

	sys.exit(exit_code)
Exemplo n.º 11
0
def backup(
    context, with_files=False, backup_path_db=None, backup_path_files=None, backup_path_private_files=None, quiet=False
):
    "Backup"
    from frappe.utils.backups import scheduled_backup

    verbose = context.verbose
    for site in context.sites:
        frappe.init(site=site)
        frappe.connect()
        odb = scheduled_backup(
            ignore_files=not with_files,
            backup_path_db=backup_path_db,
            backup_path_files=backup_path_files,
            backup_path_private_files=backup_path_private_files,
            force=True,
        )
        if verbose:
            from frappe.utils import now

            print "database backup taken -", odb.backup_path_db, "- on", now()
            if with_files:
                print "files backup taken -", odb.backup_path_files, "- on", now()
                print "private files backup taken -", odb.backup_path_private_files, "- on", now()

        frappe.destroy()
Exemplo n.º 12
0
def backup(context,
           with_files=False,
           backup_path_db=None,
           backup_path_files=None,
           backup_path_private_files=None,
           quiet=False):
    "Backup"
    from frappe.utils.backups import scheduled_backup
    verbose = context.verbose
    for site in context.sites:
        frappe.init(site=site)
        frappe.connect()
        odb = scheduled_backup(
            ignore_files=not with_files,
            backup_path_db=backup_path_db,
            backup_path_files=backup_path_files,
            backup_path_private_files=backup_path_private_files,
            force=True)
        if verbose:
            from frappe.utils import now
            print "database backup taken -", odb.backup_path_db, "- on", now()
            if with_files:
                print "files backup taken -", odb.backup_path_files, "- on", now(
                )
                print "private files backup taken -", odb.backup_path_private_files, "- on", now(
                )

        frappe.destroy()
Exemplo n.º 13
0
def trim_tables(context, dry_run, format, no_backup):
    if not context.sites:
        raise SiteNotSpecifiedError

    from frappe.model.meta import trim_tables
    from frappe.utils.backups import scheduled_backup

    for site in context.sites:
        frappe.init(site=site)
        frappe.connect()

        if not (no_backup or dry_run):
            click.secho(f"Taking backup for {frappe.local.site}", fg="green")
            odb = scheduled_backup(ignore_files=False, force=True)
            odb.print_summary()

        try:
            trimmed_data = trim_tables(dry_run=dry_run, quiet=format == 'json')

            if format == 'table' and not dry_run:
                click.secho(
                    f"The following data have been removed from {frappe.local.site}",
                    fg='green')

            handle_data(trimmed_data, format=format)
        finally:
            frappe.destroy()
Exemplo n.º 14
0
def _drop_site(site,
               root_login='******',
               root_password=None,
               archived_sites_path=None,
               force=False):
    "Remove site from database and filesystem"
    from frappe.installer import get_root_connection
    from frappe.model.db_schema import DbManager
    from frappe.utils.backups import scheduled_backup

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

    try:
        scheduled_backup(ignore_files=False, force=True)
    except SQLError as err:
        if err[0] == ER.NO_SUCH_TABLE:
            if force:
                pass
            else:
                click.echo("=" * 80)
                click.echo(
                    "Error: The operation has stopped because backup of {s}'s database failed."
                    .format(s=site))
                click.echo("Reason: {reason}{sep}".format(reason=err[1],
                                                          sep="\n"))
                click.echo("Fix the issue and try again.")
                click.echo(
                    "Hint: Use 'bench drop-site {s} --force' to force the removal of {s}"
                    .format(sep="\n", tab="\t", s=site))
                sys.exit(1)

    db_name = frappe.local.conf.db_name
    frappe.local.db = get_root_connection(root_login, root_password)
    dbman = DbManager(frappe.local.db)
    dbman.delete_user(db_name, host="%")
    dbman.delete_user(db_name)
    dbman.drop_database(db_name)

    if not archived_sites_path:
        archived_sites_path = os.path.join(frappe.get_app_path('frappe'), '..',
                                           '..', '..', 'archived_sites')

    if not os.path.exists(archived_sites_path):
        os.mkdir(archived_sites_path)

    move(archived_sites_path, site)
Exemplo n.º 15
0
def drop_site(site, root_login='******', root_password=None):
	from frappe.installer import get_current_host, make_connection
	from frappe.model.db_schema import DbManager
	from frappe.utils.backups import scheduled_backup

	frappe.init(site=site)
	frappe.connect()
	scheduled_backup(ignore_files=False, force=True)

	db_name = frappe.local.conf.db_name
	frappe.local.db = make_connection(root_login, root_password)
	dbman = DbManager(frappe.local.db)
	dbman.delete_user(db_name, get_current_host())
	dbman.drop_database(db_name)

	archived_sites_dir = os.path.join(frappe.get_app_path('frappe'), '..', '..', '..', 'archived_sites')
	if not os.path.exists(archived_sites_dir):
		os.mkdir(archived_sites_dir)
	move(archived_sites_dir, site)
Exemplo n.º 16
0
def backup(context,
           with_files=False,
           backup_path=None,
           backup_path_db=None,
           backup_path_files=None,
           backup_path_private_files=None,
           backup_path_conf=None,
           ignore_backup_conf=False,
           verbose=False,
           compress=False,
           include="",
           exclude=""):
    "Backup"
    from frappe.utils.backups import scheduled_backup
    verbose = verbose or context.verbose
    exit_code = 0

    for site in context.sites:
        try:
            frappe.init(site=site)
            frappe.connect()
            odb = scheduled_backup(
                ignore_files=not with_files,
                backup_path=backup_path,
                backup_path_db=backup_path_db,
                backup_path_files=backup_path_files,
                backup_path_private_files=backup_path_private_files,
                backup_path_conf=backup_path_conf,
                ignore_conf=ignore_backup_conf,
                include_doctypes=include,
                exclude_doctypes=exclude,
                compress=compress,
                verbose=verbose,
                force=True)
        except Exception:
            click.secho(
                "Backup failed for Site {0}. Database or site_config.json may be corrupted"
                .format(site),
                fg="red")
            if verbose:
                print(frappe.get_traceback())
            exit_code = 1
            continue

        odb.print_summary()
        click.secho(
            "Backup for Site {0} has been successfully completed{1}".format(
                site, " with files" if with_files else ""),
            fg="green")
        frappe.destroy()

    if not context.sites:
        raise SiteNotSpecifiedError

    sys.exit(exit_code)
Exemplo n.º 17
0
def backup(with_files=False, verbose=True, backup_path_db=None, backup_path_files=None):
	from frappe.utils.backups import scheduled_backup
	frappe.connect()
	odb = scheduled_backup(ignore_files=not with_files, backup_path_db=backup_path_db, backup_path_files=backup_path_files)
	if verbose:
		from frappe.utils import now
		print "database backup taken -", odb.backup_path_db, "- on", now()
		if with_files:
			print "files backup taken -", odb.backup_path_files, "- on", now()
	frappe.destroy()
	return odb
Exemplo n.º 18
0
def backup(with_files=False, backup_path_db=None, backup_path_files=None, quiet=False):
	from frappe.utils.backups import scheduled_backup
	verbose = not quiet
	frappe.connect()
	odb = scheduled_backup(ignore_files=not with_files, backup_path_db=backup_path_db, backup_path_files=backup_path_files)
	if verbose:
		from frappe.utils import now
		print "database backup taken -", odb.backup_path_db, "- on", now()
		if with_files:
			print "files backup taken -", odb.backup_path_files, "- on", now()
	frappe.destroy()
Exemplo n.º 19
0
def _drop_site(site, root_login='******', root_password=None, archived_sites_path=None, force=False):
	"Remove site from database and filesystem"
	from frappe.installer import get_root_connection
	from frappe.model.db_schema import DbManager
	from frappe.utils.backups import scheduled_backup

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

	try:
		scheduled_backup(ignore_files=False, force=True)
	except SQLError as err:
		if err[0] == ER.NO_SUCH_TABLE:
			if force:
				pass
			else:
				click.echo("="*80)
				click.echo("Error: The operation has stopped because backup of {s}'s database failed.".format(s=site))
				click.echo("Reason: {reason}{sep}".format(reason=err[1], sep="\n"))
				click.echo("Fix the issue and try again.")
				click.echo(
					"Hint: Use 'bench drop-site {s} --force' to force the removal of {s}".format(sep="\n", tab="\t", s=site)
				)
				sys.exit(1)

	db_name = frappe.local.conf.db_name
	frappe.local.db = get_root_connection(root_login, root_password)
	dbman = DbManager(frappe.local.db)
	dbman.delete_user(db_name)
	dbman.drop_database(db_name)

	if not archived_sites_path:
		archived_sites_path = os.path.join(frappe.get_app_path('frappe'), '..', '..', '..', 'archived_sites')

	if not os.path.exists(archived_sites_path):
		os.mkdir(archived_sites_path)

	move(archived_sites_path, site)
Exemplo n.º 20
0
def drop_site(site, root_login='******', root_password=None, archived_sites_path=None):
	"Remove site from database and filesystem"
	from frappe.installer import get_root_connection
	from frappe.model.db_schema import DbManager
	from frappe.utils.backups import scheduled_backup

	frappe.init(site=site)
	frappe.connect()
	scheduled_backup(ignore_files=False, force=True)

	db_name = frappe.local.conf.db_name
	frappe.local.db = get_root_connection(root_login, root_password)
	dbman = DbManager(frappe.local.db)
	dbman.delete_user(db_name)
	dbman.drop_database(db_name)

	if not archived_sites_path:
		archived_sites_path = os.path.join(frappe.get_app_path('frappe'), '..', '..', '..', 'archived_sites')

	if not os.path.exists(archived_sites_path):
		os.mkdir(archived_sites_path)

	move(archived_sites_path, site)
Exemplo n.º 21
0
def backup(sites, with_files=False):
    for site in sites:
        frappe.init(site)
        frappe.connect()
        odb = scheduled_backup(ignore_files=not with_files,
                               backup_path_db=None,
                               backup_path_files=None,
                               backup_path_private_files=None,
                               force=True)
        print("database backup taken -", odb.backup_path_db, "- on", now())
        if with_files:
            print("files backup taken -", odb.backup_path_files, "- on", now())
            print("private files backup taken -",
                  odb.backup_path_private_files, "- on", now())
        frappe.destroy()
Exemplo n.º 22
0
def backup(context, with_files=False, backup_path_db=None, backup_path_files=None, quiet=False):
	"Backup"
	from frappe.utils.backups import scheduled_backup
	verbose = context.verbose
	# for site in context.sites:
	# All sites bachup with sites - Gangadhar Sir
	for site in frappe.utils.get_sites():
		frappe.init(site=site)
		frappe.connect()
		odb = scheduled_backup(ignore_files=not with_files, backup_path_db=backup_path_db, backup_path_files=backup_path_files, force=True)
		if verbose:
			from frappe.utils import now
			print "database backup taken -", odb.backup_path_db, "- on", now()
			if with_files:
				print "files backup taken -", odb.backup_path_files, "- on", now()
		frappe.destroy()
Exemplo n.º 23
0
def trim_database(context, dry_run, format, no_backup):
    if not context.sites:
        raise SiteNotSpecifiedError

    from frappe.utils.backups import scheduled_backup

    ALL_DATA = {}

    for site in context.sites:
        frappe.init(site=site)
        frappe.connect()

        TABLES_TO_DROP = []
        STANDARD_TABLES = get_standard_tables()
        information_schema = frappe.qb.Schema("information_schema")
        table_name = frappe.qb.Field("table_name").as_("name")

        queried_result = frappe.qb.from_(
            information_schema.tables).select(table_name).where(
                information_schema.tables.table_schema ==
                frappe.conf.db_name).run()

        database_tables = [x[0] for x in queried_result]
        doctype_tables = frappe.get_all("DocType", pluck="name")

        for x in database_tables:
            doctype = x.lstrip("tab")
            if not (doctype in doctype_tables or x.startswith("__")
                    or x in STANDARD_TABLES):
                TABLES_TO_DROP.append(x)

        if not TABLES_TO_DROP:
            if format == "text":
                click.secho(
                    f"No ghost tables found in {frappe.local.site}...Great!",
                    fg="green")
        else:
            if not (no_backup or dry_run):
                if format == "text":
                    print(f"Backing Up Tables: {', '.join(TABLES_TO_DROP)}")

                odb = scheduled_backup(
                    ignore_conf=False,
                    include_doctypes=",".join(
                        x.lstrip("tab") for x in TABLES_TO_DROP),
                    ignore_files=True,
                    force=True,
                )
                if format == "text":
                    odb.print_summary()
                    print("\nTrimming Database")

            for table in TABLES_TO_DROP:
                if format == "text":
                    print(f"* Dropping Table '{table}'...")
                if not dry_run:
                    frappe.db.sql_ddl(f"drop table `{table}`")

            ALL_DATA[frappe.local.site] = TABLES_TO_DROP
        frappe.destroy()

    if format == "json":
        import json
        print(json.dumps(ALL_DATA, indent=1))
Exemplo n.º 24
0
def remove_app(app_name,
               dry_run=False,
               yes=False,
               no_backup=False,
               force=False):
    """Remove app and all linked to the app's module with the app from a site."""
    import click

    # dont allow uninstall app if not installed unless forced
    if not force:
        if app_name not in frappe.get_installed_apps():
            click.secho("App {0} not installed on Site {1}".format(
                app_name, frappe.local.site),
                        fg="yellow")
            return

    print("Uninstalling App {0} from Site {1}...".format(
        app_name, frappe.local.site))

    if not dry_run and not yes:
        confirm = click.confirm(
            "All doctypes (including custom), modules related to this app will be deleted. Are you sure you want to continue?"
        )
        if not confirm:
            return

    if not no_backup:
        from frappe.utils.backups import scheduled_backup
        print("Backing up...")
        scheduled_backup(ignore_files=True)

    frappe.flags.in_uninstall = True
    drop_doctypes = []

    modules = (
        x.name
        for x in frappe.get_all("Module Def", filters={"app_name": app_name}))
    for module_name in modules:
        print("Deleting Module '{0}'".format(module_name))

        for doctype in frappe.get_list("DocType",
                                       filters={"module": module_name},
                                       fields=["name", "issingle"]):
            print("* removing DocType '{0}'...".format(doctype.name))

            if not dry_run:
                frappe.delete_doc("DocType", doctype.name)

                if not doctype.issingle:
                    drop_doctypes.append(doctype.name)

        linked_doctypes = frappe.get_all("DocField",
                                         filters={
                                             "fieldtype": "Link",
                                             "options": "Module Def"
                                         },
                                         fields=['parent'])
        ordered_doctypes = ["Desk Page", "Report", "Page", "Web Form"]
        doctypes_with_linked_modules = ordered_doctypes + [
            doctype.parent for doctype in linked_doctypes
            if doctype.parent not in ordered_doctypes
        ]

        for doctype in doctypes_with_linked_modules:
            for record in frappe.get_list(doctype,
                                          filters={"module": module_name}):
                print("* removing {0} '{1}'...".format(doctype, record.name))
                if not dry_run:
                    frappe.delete_doc(doctype, record.name)

        print("* removing Module Def '{0}'...".format(module_name))
        if not dry_run:
            frappe.delete_doc("Module Def", module_name)

    if not dry_run:
        remove_from_installed_apps(app_name)

        for doctype in set(drop_doctypes):
            print("* dropping Table for '{0}'...".format(doctype))
            frappe.db.sql("drop table `tab{0}`".format(doctype))

        frappe.db.commit()
        click.secho("Uninstalled App {0} from Site {1}".format(
            app_name, frappe.local.site),
                    fg="green")

    frappe.flags.in_uninstall = False
Exemplo n.º 25
0
def remove_app(app_name,
               dry_run=False,
               yes=False,
               no_backup=False,
               force=False):
    """Remove app and all linked to the app's module with the app from a site."""
    import click

    site = frappe.local.site

    # dont allow uninstall app if not installed unless forced
    if not force:
        if app_name not in frappe.get_installed_apps():
            click.secho(f"App {app_name} not installed on Site {site}",
                        fg="yellow")
            return

    print(f"Uninstalling App {app_name} from Site {site}...")

    if not dry_run and not yes:
        confirm = click.confirm(
            "All doctypes (including custom), modules related to this app will be"
            " deleted. Are you sure you want to continue?")
        if not confirm:
            return

    if not (dry_run or no_backup):
        from frappe.utils.backups import scheduled_backup

        print("Backing up...")
        scheduled_backup(ignore_files=True)

    frappe.flags.in_uninstall = True
    drop_doctypes = []

    modules = frappe.get_all("Module Def",
                             filters={"app_name": app_name},
                             pluck="name")
    for module_name in modules:
        print(f"Deleting Module '{module_name}'")

        for doctype in frappe.get_all("DocType",
                                      filters={"module": module_name},
                                      fields=["name", "issingle"]):
            print(f"* removing DocType '{doctype.name}'...")

            if not dry_run:
                frappe.delete_doc("DocType",
                                  doctype.name,
                                  ignore_on_trash=True)

                if not doctype.issingle:
                    drop_doctypes.append(doctype.name)

        linked_doctypes = frappe.get_all("DocField",
                                         filters={
                                             "fieldtype": "Link",
                                             "options": "Module Def"
                                         },
                                         fields=["parent"])
        ordered_doctypes = ["Workspace", "Report", "Page", "Web Form"]
        all_doctypes_with_linked_modules = ordered_doctypes + [
            doctype.parent for doctype in linked_doctypes
            if doctype.parent not in ordered_doctypes
        ]
        doctypes_with_linked_modules = [
            x for x in all_doctypes_with_linked_modules
            if frappe.db.exists("DocType", x)
        ]
        for doctype in doctypes_with_linked_modules:
            for record in frappe.get_all(doctype,
                                         filters={"module": module_name},
                                         pluck="name"):
                print(f"* removing {doctype} '{record}'...")
                if not dry_run:
                    frappe.delete_doc(doctype,
                                      record,
                                      ignore_on_trash=True,
                                      force=True)

        print(f"* removing Module Def '{module_name}'...")
        if not dry_run:
            frappe.delete_doc("Module Def",
                              module_name,
                              ignore_on_trash=True,
                              force=True)

    for doctype in set(drop_doctypes):
        print(f"* dropping Table for '{doctype}'...")
        if not dry_run:
            frappe.db.sql_ddl(f"drop table `tab{doctype}`")

    if not dry_run:
        remove_from_installed_apps(app_name)
        frappe.db.commit()

    click.secho(f"Uninstalled App {app_name} from Site {site}", fg="green")
    frappe.flags.in_uninstall = False