Пример #1
0
    def cmd_reloadall(self, msg):
        before = util.time_us()

        self.bot.save_config()

        self.bot.mresult(msg, 'Unloading all modules...')
        self.bot.unload_all_modules()

        self.bot.mresult(msg, 'Reloading module classes...')
        self.bot.reload_module_pkg()

        self.bot.mresult(msg, 'Loading new modules...')
        try:
            self.bot.load_all_modules()
        except module.ExistingModuleError:
            pass

        self.bot.mresult(msg, 'Dispatching load and start events...')
        self.bot.dispatch_event('load')
        self.bot.dispatch_event('start', util.time_us())

        self.bot.save_config()

        after = util.time_us()
        delta = after - before

        return f'All modules reloaded in {util.format_duration_us(delta)}.'
Пример #2
0
    def cmd_speedtest(self, msg):
        self.bot.mresult(msg,
                         'Testing Internet speed, this may take a while...')

        before = util.time_us()
        try:
            proc = subprocess.run(['speedtest'],
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.STDOUT,
                                  timeout=120,
                                  text=True)
        except subprocess.TimeoutExpired:
            return 'ЁЯХС `speedtest` took longer than 2 minutes to run.'
        after = util.time_us()

        el_us = after - before
        el_str = f'\nTime: {util.format_duration_us(el_us)}'

        err = f'тЪая╕П Return code: {proc.returncode}' if proc.returncode != 0 else ''

        out = proc.stdout.strip()
        if proc.returncode == 0:
            lines = out.split('\n')
            out = '\n'.join((lines[4], lines[6], lines[8]))  # Server, down, up

        return f'```{out}```{err}{el_str}'
Пример #3
0
    async def cmd_reloadall(self, msg):
        before = util.time_us()

        await self.bot.dispatch_event("stop")
        await self.bot.save_config()

        await msg.result("Unloading all modules...")
        self.bot.unload_all_modules()

        await msg.result("Reloading module classes...")
        await self.bot.reload_module_pkg()

        await msg.result("Loading new modules...")
        try:
            self.bot.load_all_modules()
        except module.ExistingModuleError:
            pass

        await msg.result("Dispatching events...")
        await self.bot.dispatch_event("load")
        await self.bot.dispatch_event("start", util.time_us())

        await self.bot.save_config()

        after = util.time_us()
        delta = after - before

        return f"All modules reloaded in {util.format_duration_us(delta)}."
Пример #4
0
    def cmd_time11(self, msg: tg.Message) -> str:
        before = util.time_us()
        self.var = 1 + 1
        after = util.time_us()

        el_us = after - before
        return '`var = 1 + 1`: %.3f ms / %.2f μs / %.0f ns' % (
            el_us / 1000.0, el_us, el_us * 1000.0)
Пример #5
0
    def cmd_eval(self, msg, raw_args):
        before = util.time_us()
        result = eval(util.filter_input_block(raw_args))
        after = util.time_us()

        el_us = after - before
        el_str = util.format_duration_us(el_us)

        return f'''```{str(result)}```
Пример #6
0
    def cmd_eval(self, msg: tg.Message, raw_args: str) -> str:
        before = util.time_us()
        result = eval(raw_args)
        after = util.time_us()

        el_us = after - before
        el_str = '%.3f ms, %.2f μs' % (el_us / 1000.0, el_us)

        return f'''In:
Пример #7
0
 def run(self):
     while True:
         for i in range(5):
             before = time_us()
             self.socket.send("")
             during, = TIME_STRUCT.unpack(self.socket.recv())
             after = time_us()
             self.deltas.append((after + before) / 2 - during)
         time.sleep(5)
Пример #8
0
    async def cmd_time11(self, msg):
        reps = 1000000

        before = util.time_us()
        for _ in range(reps):
            _ = 1 + 1
        after = util.time_us()

        el_us = (after - before) / reps
        return "`1 + 1`: %.0f ns" % (el_us * 1000)
Пример #9
0
    async def start(self):
        # Get and store current event loop, since this is the first coroutine
        self.loop = asyncio.get_event_loop()

        # Load modules and save config in case any migration changes were made
        self.load_all_modules()
        await self.dispatch_event('load')
        await self.save_config()

        # Start Telegram client
        await self.client.start()

        # Get info
        self.user = await self.client.get_me()
        self.uid = self.user.id

        # Hijack Message class to provide result function
        async def result(msg, new_text, **kwargs):
            t = self.config['telegram']
            api_id = str(t['api_id'])
            api_hash = t['api_hash']

            if api_id in new_text:
                new_text = new_text.replace(api_id, '[REDACTED]')
            if api_hash in new_text:
                new_text = new_text.replace(api_hash, '[REDACTED]')
            if self.user.phone in new_text:
                new_text = new_text.replace(self.user.phone, '[REDACTED]')

            if 'link_preview' not in kwargs:
                kwargs['link_preview'] = False

            await msg.edit(text=new_text, **kwargs)

        tg.types.Message.result = result

        # Record start time and dispatch start event
        self.start_time_us = util.time_us()
        await self.dispatch_event('start', self.start_time_us)

        # Register handlers
        self.client.add_event_handler(self.on_message, tg.events.NewMessage)
        self.client.add_event_handler(self.on_message_edit,
                                      tg.events.MessageEdited)
        self.client.add_event_handler(
            self.on_command,
            tg.events.NewMessage(outgoing=True, func=self.command_predicate))

        # Save config in the background
        self.loop.create_task(self.writer())

        self.log.info('Bot is ready')

        # Catch up on missed events
        self.log.info('Catching up on missed events')
        await self.client.catch_up()
        self.log.info('Finished catching up')

        # Save config to sync updated stats after catching up
        await self.save_config()
Пример #10
0
    async def cmd_eval(self, msg, raw_args):
        def _eval():
            nonlocal msg, raw_args, self

            def send(text):
                return self.bot.loop.create_task(msg.respond(text))

            return eval(util.filter_code_block(raw_args))

        before = util.time_us()
        result = await util.run_sync(_eval)
        after = util.time_us()

        el_us = after - before
        el_str = util.format_duration_us(el_us)

        return f"""```{str(result)}```
Пример #11
0
    async def cmd_shell(self, msg, parsed_snip):
        if not parsed_snip:
            return "__Provide a snippet to run in shell.__"

        await msg.result("Running snippet...")
        before = util.time_us()

        try:
            proc = await self.run_process(parsed_snip, shell=True, timeout=120)
        except subprocess.TimeoutExpired:
            return "🕑 Snippet failed to finish within 2 minutes."

        after = util.time_us()

        el_us = after - before
        el_str = f"\nTime: {util.format_duration_us(el_us)}"

        err = f"⚠️ Return code: {proc.returncode}" if proc.returncode != 0 else ""

        return f"```{proc.stdout.strip()}```{err}{el_str}"
Пример #12
0
    async def cmd_speedtest(self, msg):
        await msg.result("Testing Internet speed; this may take a while...")

        before = util.time_us()
        try:
            proc = await self.run_process("speedtest", timeout=120)
        except subprocess.TimeoutExpired:
            return "🕑 `speedtest` failed to finish within 2 minutes."
        except FileNotFoundError:
            return "❌ The `speedtest` [program](https://github.com/sivel/speedtest-cli) (package name: `speedtest-cli`) must be installed on the host system."
        after = util.time_us()

        el_us = after - before
        el_str = f"\nTime: {util.format_duration_us(el_us)}"

        err = f"⚠️ Return code: {proc.returncode}" if proc.returncode != 0 else ""

        out = proc.stdout.strip()
        if proc.returncode == 0:
            lines = out.split("\n")
            out = "\n".join((lines[4], lines[6], lines[8]))  # Server, down, up

        return f"```{out}```{err}{el_str}"
Пример #13
0
    def cmd_shell(self, msg, snip):
        if not snip:
            return '__Provide a snippet to run in shell.__'
        snip = util.filter_input_block(snip)

        self.bot.mresult(msg, 'Running snippet...')
        before = util.time_us()
        try:
            proc = subprocess.run(snip,
                                  shell=True,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.STDOUT,
                                  timeout=120,
                                  text=True)
        except subprocess.TimeoutExpired:
            return 'ЁЯХС Snippet took longer than 2 minutes to run.'
        after = util.time_us()

        el_us = after - before
        el_str = f'\nTime: {util.format_duration_us(el_us)}'

        err = f'тЪая╕П Return code: {proc.returncode}' if proc.returncode != 0 else ''

        return f'```{proc.stdout.strip()}```{err}{el_str}'
Пример #14
0
    def start(self):
        self.client.start()

        # Get info
        self.user = self.client.get_me()
        self.uid = self.user.id

        # Record start time and dispatch start event
        self.start_time_us = util.time_us()
        self.dispatch_event('start', self.start_time_us)

        # Register handlers with new info
        self.client.add_handler(tg.MessageHandler(self.on_message), group=1)
        self.register_command_handler()

        # Save config in the background
        self.writer_thread = threading.Thread(target=self.writer)
        self.writer_thread.daemon = True
        self.writer_thread.start()

        print('Bot is ready')
Пример #15
0
    def cmd_stats(self, msg, args):
        if args == "reset":
            self.bot.config['stats'] = {}
            self.on_load()
            self.on_start(util.time_us())
            return '__All stats have been reset.__'

        self.update_uptime()
        self.bot.save_config()

        st = self.bot.config['stats']
        uptime = st['uptime']
        sent = st['sent']
        sent_stickers = st['sent_stickers']
        recv = st['received']
        recv_stickers = st['received_stickers']
        processed = st['processed']
        replaced = st['replaced']
        banned = st['spambots_banned']
        stickers = st['stickers_created']

        return f'''**Stats since last reset**:
Пример #16
0
    async def cmd_stats(self, msg, args):
        if args == "reset":
            self.bot.config["stats"] = {}
            await self.on_load()
            await self.on_start(util.time_us())
            return "__All stats have been reset.__"

        self.update_uptime()
        await self.bot.save_config()

        st = self.bot.config["stats"]
        uptime = st["uptime"]
        sent = st["sent"]
        sent_stickers = st["sent_stickers"]
        sent_edits = st["sent_edits"]
        recv = st["received"]
        recv_stickers = st["received_stickers"]
        recv_edits = st["received_edits"]
        processed = st["processed"]
        replaced = st["replaced"]
        banned = st["spambots_banned"]
        stickers = st["stickers_created"]

        return f"""**Stats since last reset**:
Пример #17
0
 def update_uptime(self):
     now = util.time_us()
     delta_us = now - self.last_time
     self.bot.config["stats"]["uptime"] += delta_us
     self.last_time = now
Пример #18
0
 def run(self):
     while True:
         message = self.socket.recv()
         now = time_us()
         self.socket.send(TIME_STRUCT.pack(now))
Пример #19
0
broadcaster.send("new song")

name, start_us = "", 0

while True:
    msg = receiver.recv_multipart()
    command = msg[0]
    if command == "play":
        if len(msg) != 3:
            receiver.send("bad format")
        else:
            name, data = msg[1:]
            with open(name, "wb") as f:
                f.write(data)
            data = None
            start_us = time_us() + 10**6 * 2
            receiver.send("ok")
            broadcaster.send("new song")

    if command == "get song":
        if len(msg) != 1:
            receiver.send("bad format")
        else:
            receiver.send_multipart(["ok", name, str(start_us)])

    if command == "get file":
        if len(msg) != 2:
            receiver.send("bad format")
        else:
            name = msg[1]
            try:
Пример #20
0
    async def start(self, config):
        # Get and store current event loop, since this is the first coroutine
        self.loop = asyncio.get_event_loop()

        # Load modules and save config in case any migration changes were made
        self.load_all_modules()
        await self.dispatch_event("load")
        await self.save_config()

        # Start Telegram client
        await self.client.start(bot_token=config["telegram"]["bot_key"])

        # Get info
        self.user = await self.client.get_me()
        self.uid = self.user.id

        self.log.info(f"User is @{self.user.username}")

        # Hijack Message class to provide result function
        async def result(msg, new_text, **kwargs):
            t = self.config["telegram"]
            api_id = str(t["api_id"])
            api_hash = t["api_hash"]

            if api_id in new_text:
                new_text = new_text.replace(api_id, "[REDACTED]")
            if api_hash in new_text:
                new_text = new_text.replace(api_hash, "[REDACTED]")

            if "link_preview" not in kwargs:
                kwargs["link_preview"] = False

            await self.client.send_message(msg.chat_id, new_text, **kwargs)

        tg.types.Message.result = result

        # Record start time and dispatch start event
        self.start_time_us = util.time_us()
        await self.dispatch_event("start", self.start_time_us)

        # Register handlers
        self.client.add_event_handler(self.on_message, tg.events.NewMessage)
        self.client.add_event_handler(self.on_message_edit,
                                      tg.events.MessageEdited)
        self.client.add_event_handler(
            self.on_command,
            tg.events.NewMessage(outgoing=False, func=self.command_predicate))
        self.client.add_event_handler(self.on_chat_action,
                                      tg.events.ChatAction)

        # Save config in the background
        self.loop.create_task(self.writer())

        self.log.info("Bot is ready")

        # Catch up on missed events
        self.log.info("Catching up on missed events")
        # await self.client.catch_up()
        self.log.info("Finished catching up")

        # Save config to sync updated stats after catching up
        await self.save_config()
Пример #21
0
 def update_uptime(self):
     now = util.time_us()
     delta_us = now - self.last_time
     self.bot.config['stats']['uptime'] += delta_us
     self.last_time = now
Пример #22
0
 async def cmd_uptime(self, msg):
     delta_us = util.time_us() - self.bot.start_time_us
     return f"Uptime: {util.format_duration_us(delta_us)}"
Пример #23
0
    def cmd_bsetup(self, msg, params):
        if not msg.chat:
            return '__This can only be used in groups.__'
        plain_params = util.filter_input_block(params)

        cfg_err = '''**Invalid TOML config.** The following options are supported:

```
# Bot to setup
target = "MissRose_bot"

# Default rules
rules = ["No spam", "English only", "Respect others", "No NSFW"]
extra_rules = ["No extreme off-topic"]

# Add ":same" at the end of links to put buttons on the same line
[buttons]
"XDA Thread" = "https://forum.xda-developers.com/"
GitHub = "https://github.com/"```

{}'''

        if plain_params.startswith('?') or plain_params.startswith('help'):
            return cfg_err.format('')

        extra_btn = ''
        rules = [
            'No spam', 'English only', 'Respect others', 'No NSFW content',
            'No extreme off-topic'
        ]
        target = 'MissRose_bot'

        ex_btn_map = {}

        if plain_params:
            try:
                cfg = toml.loads(plain_params)
            except Exception as e:
                return cfg_err.format(str(e))

            if 'target' in cfg:
                target = cfg['target']

            if 'rules' in cfg:
                rules = cfg['rules']
            if 'extra_rules' in cfg:
                rules.extend(cfg['extra_rules'])

            if 'buttons' in cfg:
                for name, dest in cfg['buttons'].items():
                    ex_btn_map[name] = dest

        rule_str = f'    \u2022 {rules[0]}'
        for rule in rules[1:]:
            rule_str += f'\n    \u2022 {rule}'

        for name, dest in ex_btn_map.items():
            extra_btn += f'\n[{name}](buttonurl://{dest})'

        before = util.time_us()

        try:
            self.bot.client.promote_chat_member(msg.chat.id,
                                                target,
                                                can_change_info=False)
        except Exception:
            self.bot.mresult(msg, f'**WARNING**: Unable to promote @{target}')

        first = '{first}'
        srules = '{rules}'
        commands = [
            'welcome on', 'goodbye off', 'warnlimit 3', 'strongwarn off',
            f'''setwelcome *Welcome*, {first}!
Please read the rules before chatting. {srules}{extra_btn}''',
            'cleanwelcome on', f'setrules \u200b{rule_str}', 'setflood 20',
            'setfloodmode tmute 3h', 'gbanstat on', 'gmutestat on',
            'reports on', 'cleanservice on', 'welcomemute on',
            'welcomemutetime 3h'
        ]

        for cmd in commands:
            csplit = cmd.split(' ')
            _cmd = '/' + csplit[0] + f'@{target} ' + ' '.join(csplit[1:])
            self.bot.client.send_message(msg.chat.id, _cmd, parse_mode='HTML')
            time.sleep(0.180)  # ratelimit

        # Clean up the mess
        if msg.reply_to_message:
            msg.reply_to_message.reply(f'/purge@{target}')
        else:
            msg.reply(f'/purge@{target}')

        after = util.time_us()

        return f'Setup completed in {util.format_duration_us(after - before)}.'