from json import loads, dump from subprocess import run, PIPE from argparse import ArgumentParser from pathlib import Path from re import compile as re_compile def main(path : str, php :str, output_groups : str, output_group_folders : str, exclude_group: str): output_groups = Path(output_groups) if output_group_folders: output_group_folders = Path(output_group_folders) if exclude_group: exclude_group = re_compile(exclude_group) out = run([php, "occ", "-V"], cwd=path, check=True, stdout=PIPE, stderr=PIPE) version = list(map(int, out.stdout.decode().split(" ")[-1].split("."))) out = run([php, "occ", "config:list", "--private", "--output", "json"], cwd=path, check=True, stdout=PIPE, stderr=PIPE) config = loads(out.stdout.decode().strip()) groups = {} offset = 0 if version[0] >= 22: while True: out = run( [php, "occ", "group:list", "--offset", str(offset), "--info", "--output", "json"], cwd=path, check=True, stdout=PIPE, stderr=PIPE) new_groups = loads(out.stdout.decode().strip()) if not new_groups: break for group in new_groups.keys(): out = run([php, "occ", "group:info", group, "--output", "json"], cwd=path, check=True, stdout=PIPE, stderr=PIPE) infos = loads(out.stdout.decode().strip()) new_groups[group]["displayName"] = infos["displayName"] groups.update(new_groups) offset = len(groups) else: db_type = config["system"]["dbtype"] db_host, db_port = config["system"]["dbhost"].split(":") if not db_port: db_port = config["system"]["dbport"] db_user = config["system"]["dbuser"] db_password = config["system"]["dbpassword"] db_name = config["system"]["dbname"] db_prefix = config["system"]["dbtableprefix"] if db_type == "mysql": out = run(["mysql", "-B", "-r", "--disable-column-names", "-h", db_host, "-P", db_port, "-u", db_user, f"-p{db_password}","-e", "select JSON_OBJECT('gid', gid, 'displayname', displayname) "\ f"from {db_prefix}groups", db_name], cwd=path, check=True, stdout=PIPE, stderr=PIPE) for line in map(loads, filter(lambda l: l != "", out.stdout.decode().split("\n"))): groups[line["gid"]] = {"displayName": line["displayname"]} elif db_type == "psql": pass elif db_type == "sqlite": pass print(f"Got {len(groups)} groups") if exclude_group: groups = {k: v for k, v in groups.items() if not exclude_group.findall(k)} print(f"Got {len(groups)} filtered groups") with output_groups.open("w", encoding="UTF-8") as file: dump({k: v["displayName"] for (k, v) in groups.items()}, file) if output_group_folders: out = run([php, "occ", "groupfolders:list", "--output", "json"], cwd=path, check=True, stdout=PIPE, stderr=PIPE) group_folders = loads(out.stdout.decode().strip()) with output_group_folders.open("w", encoding="UTF-8") as file: dump(group_folders, file) if __name__ == '__main__': parser = ArgumentParser(prog="groups_export") parser.add_argument("--path", "-p", default="/var/www/nextcloud") parser.add_argument("--php", "-P", default="php7.4") parser.add_argument("--output-groups", "-g", default="groups.json") parser.add_argument("--output-group-folders", "-f", default=None) parser.add_argument("--exclude-group", "-e", default=None) args = parser.parse_args() main(args.path, args.php, args.output_groups, args.output_group_folders, args.exclude_group)