async def on_remove_sudoer(c, cq): lang = cq._lang who = tryint(cq.matches[0]["who"]) # Sanitize list sudoers[:] = [*map(tryint, sudoers)] removed = [x for x in sudoers if x != who] sudoers[:] = removed await Config.get(key="SUDOERS_LIST" ).update(value=" ".join([*map(str, sudoers)])) text, keyboard = await sudoers_interface(cq) await cq.edit(text, keyboard)
async def load_env(): environment_vars = { "DATABASE_URL": [ "sqlite://userlixo/database/database.sqlite", "Address of the database (sqlite or postgres).", ], "LANGUAGE": ["en", "Language for UserLixo's strings"], "LOGS_CHAT": [ "me", "Chat where the logs (e.g. startup alert) will be sent. Can be username, link or id.", ], "PREFIXES": [".", "Prefixes for the userbot commands"], "SUDOERS_LIST": [ "", "List of users (usernames and ids separated by space) that will have permission to use your userbot/assistant.", ], "BOT_TOKEN": ["", "Token of the assistant inline bot"], } restricted_vars = ["DATABASE_URL"] required_vars = ["BOT_TOKEN"] missing_vars = [] for env_key, (default_value, env_info) in environment_vars.items(): value_on_env = os.getenv(env_key, default_value) value_on_db = await Config.get_or_none(key=env_key) if not value_on_db: if "DYNO" in os.environ and env_key not in restricted_vars: os.environ[env_key] = value_on_env await Config.create(key=env_key, value=value_on_env) elif env_key in restricted_vars: os.environ[env_key] = value_on_env else: missing_vars.append([env_key, value_on_env, env_info]) continue os.environ[env_key] = value_on_db.value if missing_vars: if len(missing_vars) == len( environment_vars.keys()) - len(restricted_vars): text = "[dodger_blue1 bold underline]Welcome to UserLixo![/][deep_sky_blue1]\nAs the first step we need to setup some config vars.\n\nYou will be asked for a value for each var, but you can just press enter to leave it empty or use the default value. Let's get started![/]" else: text = ( "[bold yellow]Some required config vars are missing. Let's add them.[/]" ) print(text) for env_key, value_on_env, env_info in missing_vars: text = f"\n┌ [light_sea_green]{env_key}[/light_sea_green]" if value_on_env != "": text += f" [deep_sky_blue4](default: {value_on_env})[/]" elif env_key in required_vars: text += f" [yellow](required)[/]" text += f"\n├ [medium_purple4 italic]{env_info}[/]" print(text) try: user_value = input("└> ") except (KeyboardInterrupt, EOFError): print("[red1]Operation cancelled by user") exit() if not user_value: user_value = value_on_env if env_key in required_vars and not user_value: print(f"[red1]{env_key} is required, cannot be empty.") exit() row = await Config.create(key=env_key, value=user_value) os.environ[env_key] = row.value langs.code = os.environ["LANGUAGE"] # Sanitize sudoers list parts = os.getenv("SUDOERS_LIST").split() parts = [*map(lambda x: tryint(x.lstrip("@").lower()), parts)] parts = [*set(parts)] parts = [x for x in parts if x != "me"] sudoers.extend(parts)
async def main(): await connect_database() await load_env() os.system("clear") @aiocron.crontab("*/1 * * * *") async def clean_cache(): for file in glob.glob("cache/*"): if not os.path.isfile(file): continue creation_time = datetime.fromtimestamp(os.path.getctime(file)) now_time = datetime.now() diff = now_time - creation_time minutes_passed = diff.total_seconds() / 60 if minutes_passed >= 10: os.remove(file) if "DYNO" not in os.environ and not os.path.exists("user.session"): from userlixo.login import main as login await login() os.system("clear") await user.start() await bot.start() await unload_inactive_plugins() user.me = await user.get_me() bot.me = await bot.get_me() user.assistant = bot if user.me.id not in sudoers: sudoers.append(user.me.id) # Editing restaring alert restarting_alert = await Config.filter(key="restarting_alert") if len(restarting_alert) > 1: await Config.filter(key="restarting_alert").delete() restarting_alert = [] if restarting_alert: restarting_alert = restarting_alert[0] parts = restarting_alert.value.split("|") message_id, chat_id, cmd_timestamp, from_cmd = parts cmd_timestamp = float(cmd_timestamp) now_timestamp = datetime.now().timestamp() diff = round(now_timestamp - cmd_timestamp, 2) title, p = await shell_exec('git log --format="%B" -1') rev, p = await shell_exec("git rev-parse --short HEAD") date, p = await shell_exec( 'git log -1 --format=%cd --date=format:"%d/%m %H:%M"') timezone, p = await shell_exec( 'git log -1 --format=%cd --date=format:"%z"') local_version = int((await shell_exec("git rev-list --count HEAD"))[0]) timezone = timezone_shortener(timezone) date += f" ({timezone})" kwargs = {} text = (langs.upgraded_alert if from_cmd.startswith("upgrade") else langs.restarted_alert) text = text(rev=rev, date=date, seconds=diff, local_version=local_version) if "DYNO" in os.environ and from_cmd.startswith("upgrade"): text += "\n\n" + langs.alert_need_deploy try: editor = bot if from_cmd.endswith("_bot") else user if editor == bot: keyb = ikb([[(langs.back, "start")]]) kwargs.update(reply_markup=keyb) if chat_id == "inline": await bot.edit_inline_text(message_id, text, **kwargs) else: await editor.edit_message_text(tryint(chat_id), tryint(message_id), text, **kwargs) except Exception as e: print( f"[yellow]Failed to edit the restarting alert. Maybe the message has been deleted or somehow it became inacessible.\n>> {e}[/yellow]" ) await Config.get(id=restarting_alert.id).delete() # Showing alert in cli date, p = await shell_exec( 'git log -1 --format=%cd --date=format:"%d/%m %H:%M"') timezone, p = await shell_exec('git log -1 --format=%cd --date=format:"%z"' ) local_version = int((await shell_exec("git rev-list --count HEAD"))[0]) timezone = timezone_shortener(timezone) date += f" ({timezone})" mention = "@" + user.me.username if user.me.username else user.me.id text = f":ok: [bold green]UserLixo is running[/bold green] :ok:" userlixo_info = { "Version": local_version, "Account": mention, "Bot": "@" + bot.me.username, "Prefixes": os.getenv("PREFIXES"), "Logs_chat": os.getenv("LOGS_CHAT"), "Sudoers": ", ".join([*set(map(str, sudoers)) ]), # using set() to make the values unique "Commit_date": date, } for k, v in userlixo_info.items(): text += f"\n[dim cyan]{k}:[/dim cyan] [dim]{v}[/dim]" print(Panel.fit(text, border_style="green", box=box.ASCII)) # Sending alert via Telegram try: await alert_startup() except Exception as e: print( f"[bold yellow]Error while sending startup alert to LOGS_CHAT: {e}" ) # Alert about unused requirements if unused_requirements: unused = ", ".join(unused_requirements) print( f"[yellow]The following packages are not required by plugins anymore: [/][cyan]{unused}" ) try: await user.send_message( os.getenv("LOGS_CHAT"), f"The following packages are not required by plugins anymore: {unused}", ) except Exception as e: print("Error while sending alert about unused_requirements:\n > ", e) await idle()