コード例 #1
0
 def c_pyramid(self, msg: twitchirc.ChannelMessage):
     if not self._get_pyramid_enabled(msg.channel):
         return f'@{msg.user}, This command is disabled here.'
     cd_state = main.do_cooldown('pyramid',
                                 msg,
                                 global_cooldown=60,
                                 local_cooldown=60)
     if cd_state:
         return
     t = main.delete_spammer_chrs(msg.text).split(' ', 1)
     if len(t) == 1:
         return f'@{msg.user}, Usage: pyramid <size> <text...>'
     args = t[1].rstrip()
     size = ''
     for arg in args.split(' '):
         arg: str
         if arg.isnumeric():
             size = arg
             break  # prefer first number!
     if size != '':
         args: str = args.replace(size, '', 1).rstrip() + ' '
         size = int(size)
         if not args.strip(' '):
             return f'@{msg.user}, Nothing to send. NaM'
         for i in range(1, size):
             main.bot.send(msg.reply(args * i))
         for i in range(size, 0, -1):
             main.bot.send(msg.reply(args * i))
コード例 #2
0
def command_not_active(msg: twitchirc.ChannelMessage):
    global plebs
    argv = delete_spammer_chrs(msg.text).split(' ')
    if len(argv) < 2:
        bot.send(
            msg.reply(
                f'@{msg.user} Usage: not_active <user> Marks the user as not active'
            ))
        return
    text = argv[1:]
    if len(text) == 1:
        print(text[0])
        rem_count = 0
        if text[0] in plebs[msg.channel]:
            del plebs[msg.channel][text[0]]
            rem_count += 1
        if text[0] in subs[msg.channel]:
            del subs[msg.channel][text[0]]
            rem_count += 1
        if not rem_count:
            bot.send(
                msg.reply(f'@{msg.user} {text[0]!r}: No such chatter found.'))
        else:
            bot.send(
                msg.reply(
                    f'@{msg.user} {text[0]!r}: Marked person as not active.'))
コード例 #3
0
ファイル: stock_commands.py プロジェクト: Mm2PL/twitchirc
 def command_part(msg: twitchirc.ChannelMessage):
     p = twitchirc.ArgumentParser(prog='!part', add_help=False)
     p.add_argument('channel',
                    metavar='CHANNEL',
                    nargs='?',
                    const=msg.channel,
                    default=msg.channel)
     p.add_argument('-h', '--help', action='store_true', dest='help')
     args = p.parse_args(msg.text.split(' ')[1:])
     if args is None or args.help:
         usage = msg.reply(f'@{msg.user} {p.format_usage()}')
         bot.send(usage)
         return
     if args.channel == '':
         args.channel = msg.channel
     channel = args.channel.lower()
     if channel != msg.channel.lower() and bot.check_permissions(
             msg, [twitchirc.PERMISSION_COMMAND_PART_OTHER],
             enable_local_bypass=False):
         bot.send(
             msg.reply(
                 f"Cannot part from channel {channel}: your permissions are not valid in that channel."
             ))
         return
     if channel not in bot.channels_connected:
         bot.send(msg.reply(f'Not in {channel}'))
         return
     else:
         bot.send(msg.reply(f'Parting from {channel}'))
         m = twitchirc.ChannelMessage('Bye.', 'OUTGOING', channel)
         m.outgoing = True
         bot.send(m)
         bot.flush_single_queue(msg.channel)
         bot.part(channel)
コード例 #4
0
def command_resolve_suggestion(msg: twitchirc.ChannelMessage):
    t = main.delete_spammer_chrs(msg.text).split(' ', 3)
    if len(t) < 3:
        return f'@{msg.user}, Usage: resolve_suggestion <ID> <state> [notes...]'

    if not t[1].isnumeric():
        return f'@{msg.user}, Unknown suggestion {t[1]!r}.'
    target = int(t[1])
    state_names = [i.name for i in Suggestion.SuggestionState]
    if t[2] in state_names:
        state = Suggestion.SuggestionState[t[2]]
    else:
        main.bot.send(
            msg.reply(
                f'@{msg.user}, Invalid state: {t[2]!r}. Choose between '
                f'{", ".join([repr(i.name) for i in Suggestion.SuggestionState])}'
            ))
        return
    if len(t) == 4:
        notes = t[3]
    else:
        notes = None
    with main.session_scope() as session:
        suggestion = session.query(Suggestion).filter(
            Suggestion.id == target).first()
        suggestion.state = state
        if notes is not None:
            suggestion.notes = notes
        session.add(suggestion)
    main.bot.send(
        msg.reply(f'@{msg.user} Modified suggestion id {target!r}, '
                  f'new state {state}, '
                  f'new notes {notes}.'))
コード例 #5
0
    def chan_msg_handler(self, event: str, msg: twitchirc.ChannelMessage):
        if msg.user in ['supibot', 'mm2pl'] and msg.text.startswith('HONEYDETECTED RECONNECTED') \
                and msg.channel == 'supinic':
            random_msg = random.choice(RECONNECTION_MESSAGES)
            while '{ping}' in random_msg:
                random_msg = random_msg.replace(
                    '{ping}', random.choice(self.random_pings), 1)
            main.bot.send(msg.reply(random_msg))
        if msg.channel in ['supinic', 'mm2pl'] and msg.user in ['thepositivebot', 'linkusbanned'] \
                and msg.text.startswith('\x01ACTION [Cookies]'):
            m = COOKIE_PATTERN.findall(
                main.delete_spammer_chrs(msg.text.replace('\x01ACTION ', '')))
            if m and m[0][1].lower() in self.cookie_optin:
                time_ = self._time_from_rank(msg.text)

                main.bot.send(
                    msg.reply(
                        f'$remind {m[0][1].lower()} cookie :) in {time_}'))
            elif not m:
                log('warn', f'matching against regex failed: {msg.text!r}')

        if msg.text.startswith('$ps sneeze') and msg.channel in [
                'supinic', 'mm2pl'
        ]:
            self._sneeze = (time.time() + self.cooldown_timeout, msg)

        if msg.user == 'supibot' and self._sneeze[1] is not None and (
                msg.text.startswith(
                    self._sneeze[1].user +
                    ', The playsound\'s cooldown has not passed yet! Try again in'
                ) or
                msg.text.startswith(self._sneeze[1].user +
                                    ', Playsounds are currently disabled!')):
            # don't respond if the playsound didn't play
            self._sneeze = (-1, None)
コード例 #6
0
async def command_reload(msg: twitchirc.ChannelMessage):
    argv = delete_spammer_chrs(msg.text).rstrip(' ').split(' ', 1)
    if len(argv) == 1:
        bot.send(
            msg.reply(
                f'Usage: {command_reload.chat_command} <target>, list of possible reloadable targets: '
                f'{", ".join(reloadables.keys())}'))
    else:
        for name, func in reloadables.items():
            if name.lower() == argv[1].lower():
                reload_start = time.time()
                if inspect.iscoroutinefunction(func):
                    bot.send(
                        msg.reply(f'@{msg.user}, reloading {name} (async)...'))
                    try:
                        o = await func()
                    except Exception as e:
                        message = f'@{msg.user}, failed. Error: {e} (Time taken: {time.time() - reload_start}s)'
                    else:
                        message = f'@{msg.user}, done. Output: {o} (Time taken: {time.time() - reload_start}s)'
                else:
                    bot.send(
                        msg.reply(f'@{msg.user}, reloading {name} (sync)...'))

                    try:
                        o = reloadables[name]()
                    except Exception as e:
                        message = f'@{msg.user}, failed. Error: {e} (Time taken: {time.time() - reload_start}s)'
                    else:
                        message = f'@{msg.user}, done. Output: {o} (Time taken: {time.time() - reload_start}s)'
                return message

        return f'@{msg.user} Couldn\'t reload {argv[1]}: no such target.'
コード例 #7
0
def command_vote(msg: twitchirc.ChannelMessage):
    if msg.user in ['__vote_info', '__vote_results']:
        return f'@{get_user_name(msg)} No crashing the bot for you ;)'
        return
    cd_state = main.do_cooldown('vote',
                                msg,
                                global_cooldown=0,
                                local_cooldown=1 * 60)
    if cd_state:
        return

    if msg.channel not in votes:
        return f"@{get_user_name(msg)} There's no on-going vote in this channel."
    else:
        vote_obj: Vote = votes[msg.channel]['__vote_info']
        if vote_obj.closed:
            return f"@{get_user_name(msg)} There's no on-going vote in this channel."
        argv = msg.text.split(' ')
        if len(argv) < 2:
            return f'@{get_user_name(msg)} Usage: !vote <option(s)>'
        already_voted = msg.user in votes[msg.channel]
        if votes[msg.channel]['__vote_info'].allow_multiple:
            user_votes = argv[1].split(',') if ',' in argv[1] else [argv[1]]
            invalid_votes = []
            for i in user_votes:
                if i not in vote_obj.options:
                    invalid_votes.append(i)

            if not invalid_votes:
                votes[msg.channel][msg.user] = user_votes
                if already_voted:
                    main.bot.send(
                        msg.reply(
                            f'@{get_user_name(msg)} Successfully overridden vote. '
                            f'New vote is {user_votes!r}'))
                else:
                    return f'@{get_user_name(msg)} Successfully voted for {user_votes!r}'
            else:

                if len(invalid_votes) == 1:
                    return f'@{get_user_name(msg)} Invalid option: {invalid_votes[0]!r}'
                else:
                    return f'@{get_user_name(msg)} Invalid option(s): {invalid_votes!r}'
        if argv[1] in vote_obj.options:
            votes[msg.channel][msg.user] = argv[1]
            if already_voted:
                main.bot.send(
                    msg.reply(
                        f'@{get_user_name(msg)} Successfully overridden vote. '
                        f'New vote is {argv[1]!r}'))
            else:
                return f'@{get_user_name(msg)} Successfully voted for {argv[1]!r}'
        else:
            if ',' in argv[1]:
                return f'@{get_user_name(msg)} Cannot vote for multiple options in this poll.'
            else:
                return f'@{get_user_name(msg)} Invalid option: {argv[1]}'
コード例 #8
0
ファイル: stock_commands.py プロジェクト: Mm2PL/twitchirc
 def command_join(msg: twitchirc.ChannelMessage):
     chan = msg.text.split(' ')[1].lower()
     if chan in ['all']:
         bot.send(msg.reply(f'Cannot join #{chan}.'))
         return
     if chan in bot.channels_connected:
         bot.send(msg.reply(f'This bot is already in channel #{chan}.'))
     else:
         bot.send(msg.reply(f'Joining channel #{chan}.'))
         bot.join(chan)
コード例 #9
0
def command_restart(msg: twitchirc.ChannelMessage):
    if 'debug' in msg.text and not prog_args.debug:
        return
    bot.send(msg.reply(f'Restarting MrDestructoid {chr(128299)}'))
    # Restaring MrDestructoid :gun:
    print('.')
    while 1:
        print(
            f'\033[A\033[KFlushing queues... Non-empty queues: {list(filter(lambda i: bool(i), bot.queue))}'
        )
        bot.flush_queue(1000)
        all_empty = True
        for q in bot.queue:
            if bot.queue[q]:
                all_empty = False
        if all_empty:
            break
    print('\033[A\033[KFlushing queues: DONE!')
    time.sleep(1)

    bot.stop()
    python = f'python{sys.version_info.major}.{sys.version_info.minor}'

    @atexit.register
    def run_on_shutdown():
        if prog_args.debug:
            _exec(python, [
                python, __file__, '--_restart_from', msg.user, msg.channel,
                '--debug'
            ])
        else:
            _exec(python,
                  [python, __file__, '--_restart_from', msg.user, msg.channel])

    raise SystemExit('restart.')
コード例 #10
0
    def command(msg: twitchirc.ChannelMessage):
        global counters
        if isinstance(limit_to_channel, (str, list)):
            if isinstance(limit_to_channel,
                          list) and msg.channel not in limit_to_channel:
                return
            if isinstance(limit_to_channel,
                          str) and msg.channel != limit_to_channel:
                return

        cd_state = do_cooldown(counter_name,
                               msg,
                               global_cooldown=30,
                               local_cooldown=0)
        if cd_state:
            return
        c = counters[counter_name]
        if msg.channel not in c:
            c[msg.channel] = 0
        text = msg.text[len(bot.prefix):].replace(counter_name + ' ', '')
        old_val = c[msg.channel]
        print(repr(text), msg.text)
        new_counter_value = counter_difference(text, c[msg.channel])
        if new_counter_value is None:
            bot.send(msg.reply(f'Not a number: {text}'))
            return
        else:
            c[msg.channel] = new_counter_value
        val = c[msg.channel]
        bot.send(
            show_counter_status(val, old_val, counter_name, counter_message,
                                msg))
コード例 #11
0
    def c_ping_output(self, msg: twitchirc.ChannelMessage):
        cd_state = main.do_cooldown('ping_optout',
                                    msg,
                                    global_cooldown=0,
                                    local_cooldown=30)
        if cd_state:
            return
        if msg.user in self.ping_optouts:
            del self.ping_optouts[msg.user]
            return f'@{msg.user}, you can be pinged by the bot now.'

        args = main.delete_spammer_chrs(msg.text).rstrip(' ').split(' ', 1)
        if len(args) == 1:
            main.bot.send(
                msg.reply(
                    f'@{msg.user}, please select a mode. Available modes: '
                    f'replacement (will replace ping with [PING]), '
                    f'invisibles (will add invisible characters to pings), '
                    f'no@ (will remove the @)'))
            return
        args = args[1]

        if self._in(['replace', 'replacement', 'repl', 'r'], args.lower()):
            mode = OPTOUT_MODE_REPLACEMENT
        elif self._in(
            ['invis', 'invisibles', 'invisible', 'characters', 'i', 'chars'],
                args.lower()):
            mode = OPTOUT_MODE_INVISIBLE_CHARACTERS
        elif self._in(['at', 'noat', '@', 'no@', 'n@', 'no_at'], args.lower()):
            mode = OPTOUT_MODE_NO_AT
        # noinspection PyUnboundLocalVariable
        self.ping_optouts[msg.user] = mode
        return f'@{msg.user}, i will no longer ping you :)'
コード例 #12
0
def command_quick_clip(msg: twitchirc.ChannelMessage):
    cd_state = do_cooldown(cmd='quick_clip', msg=msg)
    if cd_state:
        return
    bot.send(msg.reply(f'@{msg.flags["display-name"]}: Clip is on the way!'))
    qc_proc = sp.Popen(['python3.7', 'clip.py', '-cC', msg.channel],
                       stdout=sp.PIPE)
    tasks.append({'proc': qc_proc, 'owner': msg.user, 'msg': msg})
コード例 #13
0
def count_pleb_command(msg: twitchirc.ChannelMessage):
    global plebs
    cd_state = do_cooldown(cmd='count_plebs', msg=msg)
    if cd_state:
        return
    fix_pleb_list(msg.channel)
    bot.send(
        msg.reply(
            f'@{msg.flags["display-name"]} Counted {len(plebs[msg.channel])} '
            f'plebs active in chat during the last hour.'))
コード例 #14
0
ファイル: stock_commands.py プロジェクト: Mm2PL/twitchirc
 def permission_error_handler(event, msg: twitchirc.ChannelMessage,
                              command: twitchirc.Command,
                              missing_permissions: typing.List[str]):
     del event
     if command is None:
         return
     bot.send(
         msg.reply(
             f"@{msg.user} You are missing permissions ({', '.join(missing_permissions)}) to use "
             f"command {command.chat_command}."))
コード例 #15
0
def count_chatters(msg: twitchirc.ChannelMessage):
    global plebs, subs
    cd_state = do_cooldown(cmd='count_chatters', msg=msg)
    if cd_state:
        return
    fix_pleb_list(msg.channel)
    fix_sub_list(msg.channel)
    bot.send(
        msg.reply(
            f'@{msg.flags["display-name"]} Counted {len(plebs[msg.channel]) + len(subs[msg.channel])} '
            f'chatters active here in the last hour.'))
コード例 #16
0
def command_check_suggestion(msg: twitchirc.ChannelMessage):
    cd_state = main.do_cooldown('check_suggestion',
                                msg,
                                global_cooldown=0,
                                local_cooldown=30)
    if cd_state:
        return
    t = main.delete_spammer_chrs(msg.text).split(' ')
    if len(t) == 1:
        return f'@{msg.user}, Usage: check_suggestion <ID> or check_suggestion.'
    target = t[1]
    if target.isnumeric():
        target = int(target)
        with main.session_scope() as session:
            suggestion = session.query(Suggestion).filter(
                Suggestion.id == target).first()
            if suggestion is None:
                return f'@{msg.user} Suggestion id {target!r} not found.'
            else:
                main.bot.send(
                    msg.reply(
                        f'@{msg.user} '
                        f'{suggestion.humanize(suggestion.author.last_known_username == msg.user)}'
                    ))
    else:
        with main.session_scope() as session:
            user = main.User.get_by_message(msg, no_create=True)
            if user is None:
                return f'@{msg.user}, You are a new user, you don\'t have any suggestions.'
            suggestions = (session.query(Suggestion).filter(
                Suggestion.author == user).filter(
                    Suggestion.state.notin_([
                        Suggestion.SuggestionState.done,
                        Suggestion.SuggestionState.rejected,
                        Suggestion.SuggestionState.not_a_suggestion
                    ])))
            main.bot.send(
                msg.reply(
                    f'@{msg.user} Your suggestions: '
                    f'{", ".join([f"{s.id} ({s.nice_state()})" for s in suggestions])}'
                ))
コード例 #17
0
def msg_handler(event, msg: twitchirc.ChannelMessage):
    if not check_if_command_is_allowed('EMOTE_LIMITER',
                                       msg.channel) or msg.text.startswith(
                                           main.bot.prefix):
        return  # Ignore commands and non active channels

    if msg.channel not in channels:
        make_new_channel(msg.channel)
    log('info', channels[msg.channel])
    cost = _calculate_message_cost(msg)
    result, limit_blocking, limit_blocking_amount = _check_message_cost(
        msg, cost)
    if result:
        _subtract_cost(msg, cost)
    else:
        main.bot.send(msg.reply(f'/timeout {msg.user} 1'))
        main.bot.send(
            msg.reply(
                f'@{msg.user} The channel you tried posting your message on run out of {limit_blocking}'
                f'your message cost {limit_blocking_amount} {limit_blocking}, but you only have '
                f'{channels[msg.channel][limit_blocking]} {limit_blocking}'))
コード例 #18
0
 def echo_command(msg: twitchirc.ChannelMessage):
     cd_state = do_cooldown(cmd=command_name, msg=msg)
     if cd_state:
         return
     data = (echo_data.replace('{user}',
                               msg.user).replace('{cmd}', command_name))
     for num, i in enumerate(
             msg.text.replace(bot.prefix + command_name, '', 1).split(' ')):
         data = data.replace(f'{{{num}}}', i)
         data = data.replace('{+}', i + ' {+}')
     data = data.replace('{+}', '')
     bot.send(msg.reply(data))
コード例 #19
0
 def _no_permission_handler(self, event, message: twitchirc.ChannelMessage,
                            command: typing.Optional[twitchirc.Command],
                            missing_permissions: typing.List[str]):
     del event
     if command is None:  # ignore cooldown bypass checks
         return
     if message.channel in plugin_manager.channel_settings:
         settings = plugin_manager.channel_settings[message.channel]
         if settings.get(self.no_perm_handler.name) == NO_PERM_MESSAGE:
             main.bot.send(
                 message.reply(
                     f"@{message.user} You are missing permissions "
                     f"({', '.join(missing_permissions)}) to use command "
                     f"{command.chat_command}."))
コード例 #20
0
    async def _cookie(self, msg: twitchirc.ChannelMessage):
        m = COOKIE_PATTERN.findall(main.delete_spammer_chrs(msg.text.replace('\x01ACTION ', '')))
        print(msg.user, m)
        if m and m[0][1].lower() in self.cookie_optin:
            time_ = 2 * 60 * 60
            print(time_)
            print('cookie opt in okay')

            params = {
                'username': m[0][1].lower(),
                'text': 'Cookie :)',
                'schedule': (
                        (
                                datetime.datetime.utcnow() + datetime.timedelta(seconds=time_)
                        ).isoformat() + 'Z'
                ),
                'private': 1,
            }
            print(params)
            async with (await main.supibot_api.request('post /bot/reminder/',
                                                       params=params)) as r:
                print(f'request {r}')
                j = await r.json()
                print(j)
                if r.status == 200:
                    await main.bot.send(msg.reply(
                        f'@{m[0][1].lower()}, I set up a cookie reminder for you :), '
                        f'id: {j["data"]["reminderID"]}'
                    ))
                else:
                    await main.bot.send(msg.reply(
                        f'@{m[0][1].lower()}, monkaS {chr(0x1f6a8)}'
                        f'failed to create cookie reminder '
                    ))

        elif not m:
            log('warn', f'matching against regex failed: {msg.text!r}')
コード例 #21
0
def command_join_blacklisted(msg: twitchirc.ChannelMessage) -> str:
    ensure_blacklist(msg.channel)
    chan = msg.text.split(' ')[1].lower()
    if chan in ['all']:
        return f'Cannot join #{chan}.'
    if chan in main.bot.channels_connected:
        return f'This bot is already in channel #{chan}.'
    else:
        blacklist[msg.channel] = [i.chat_command for i in main.bot.commands]
        blacklist[msg.channel].remove('mb.blacklist_command')
        blacklist[msg.channel].remove('mb.unblacklist_command')
        blacklist[msg.channel].remove('mb.list_blacklisted_commands')
        main.bot.send(
            msg.reply(
                f'Joining channel #{chan} with all commands blacklisted apart from '
                f'mb.blacklist_command, mb.unblacklist_command and mb.list_blacklisted_command'
            ))
        main.bot.join(chan)
コード例 #22
0
def command_worldrecord(msg: twitchirc.ChannelMessage):
    if msg.channel in current_categories:
        category = current_categories[msg.channel]
        time_ = category.runs[0]["run"].times['primary_t']
        players = ' and '.join(
            [p.name for p in category.runs[0]["run"].players])

        return (
            f'@{msg.user} Current WR for {current_games[msg.channel].name} '
            f'({category.category.name}) is '
            f'{_format_time(time_)} by {players}')
    else:
        if msg.channel in current_games:
            return f'@{msg.user}, There is a game set but there is no category set. Cannot fetch WR.'
        else:
            main.bot.send(
                msg.reply(
                    f'@{msg.user}, There is no game set on this channel. Ask a mod to run the '
                    f'update_game command.'))
コード例 #23
0
def command_update_game(msg: twitchirc.ChannelMessage):
    picked = (msg.text + ' ').split(' ', 1)[1].rstrip(' ')

    if picked == '':
        picked = None
    elif picked.isnumeric():
        picked = int(picked)

    st, ret_msg, err_name = _refresh_game(msg.channel, picked=picked)
    if st is False:
        if err_name == 'multiple':
            main.bot.send(
                msg.reply(
                    f'@{msg.user} {ret_msg}. Use {command_update_game.chat_command} [number] '
                    f'or {command_update_game.chat_command} [game title]'
                    f'or {command_update_game.chat_command} [part of title] to select the game.'
                ))
        else:
            return f'@{msg.user} Error: {ret_msg}'
    else:
        return f'@{msg.user}, Okay, set game to {ret_msg}'
コード例 #24
0
ファイル: plugin_debug.py プロジェクト: Mm2PL/MmsUtilityBot
def command_say(msg: twitchirc.ChannelMessage):
    return msg.reply(msg.text.split(' ', 1)[1], True)
コード例 #25
0
ファイル: stock_commands.py プロジェクト: Mm2PL/twitchirc
    def command_perm(msg: twitchirc.ChannelMessage):
        p = twitchirc.ArgumentParser(prog='!perm', add_help=False)
        g = p.add_mutually_exclusive_group(required=True)
        g.add_argument('-a',
                       '--add',
                       metavar=('USER', 'PERMISSION'),
                       nargs=2,
                       dest='add')
        g.add_argument('-r',
                       '--remove',
                       metavar=('USER', 'PERMISSION'),
                       nargs=2,
                       dest='remove')
        g.add_argument('-l',
                       '--list',
                       metavar='USER',
                       const=msg.user,
                       default=None,
                       nargs='?',
                       dest='list')
        g.add_argument('-h', '--help', action='store_true', dest='help')
        args = p.parse_args(args=msg.text.split(' ')[1:])
        if args is None or args.help:
            usage = msg.reply(f'@{msg.user} {p.format_usage()}')
            bot.send(usage)
            return
        if args.add:
            if bot.check_permissions(msg,
                                     [twitchirc.PERMISSION_COMMAND_PERM_ADD],
                                     enable_local_bypass=False):
                bot.send(
                    msg.reply(
                        f"@{msg.user} You cannot use !perm -a, since you don't have"
                        f"the {twitchirc.PERMISSION_COMMAND_PERM_ADD} permission"
                    ))
                return
            if args.add[0] not in bot.permissions:
                bot.permissions[args.add[0]] = []
            if args.add[1] not in bot.permissions[args.add[0]]:
                bot.permissions[args.add[0]].append(args.add[1])
                bot.send(
                    msg.reply(
                        f'@{msg.user} Given permission {args.add[1]} to user {args.add[0]}.'
                    ))
            else:
                bot.send(
                    msg.reply(
                        f'@{msg.user} User {args.add[0]} already has permission {args.add[1]}.'
                    ))
                return
        elif args.remove:
            if bot.check_permissions(
                    msg, [twitchirc.PERMISSION_COMMAND_PERM_REMOVE],
                    enable_local_bypass=False):
                bot.send(
                    msg.reply(
                        f"@{msg.user} You cannot use !perm -r, since you don't have"
                        f"the {twitchirc.PERMISSION_COMMAND_PERM_REMOVE} permission"
                    ))
                return
            if args.remove[0] not in bot.permissions:
                bot.permissions[args.remove[0]] = []
            if args.remove[1] not in bot.permissions[args.remove[0]]:
                bot.send(
                    msg.reply(f"@{msg.user} User {args.remove[0]} already "
                              f"doesn't have permission {args.remove[1]}."))
                return
            else:
                bot.permissions[args.remove[0]].remove(args.remove[1])
                bot.send(
                    msg.reply(
                        f'@{msg.user} Removed permission {args.remove[1]} from user {args.remove[0]}.'
                    ))
                return
        elif args.list:
            if bot.check_permissions(msg,
                                     [twitchirc.PERMISSION_COMMAND_PERM_LIST]):
                bot.send(
                    msg.reply(
                        f"@{msg.user} You cannot use !perm -l, since you don't have"
                        f"the {twitchirc.PERMISSION_COMMAND_PERM_LIST} permission"
                    ))
                return
            args.list = args.list.lower()
            if args.list not in bot.permissions:
                bot.permissions[args.list] = []
            if args.list == msg.user:
                output = ', '.join(bot.permissions.get_permission_state(msg))
                bot.send(msg.reply(f'You have permissions: {output}'))
            else:
                output = ', '.join(bot.permissions[args.list])
                bot.send(
                    msg.reply(f'User {args.list} has permissions: {output}'))

            return
コード例 #26
0
def delete_command(msg: twitchirc.ChannelMessage):
    argv = shlex.split(msg.text.replace('\U000e0000', ''))
    args = delete_command_parser.parse_args(argv[1:] if len(argv) > 1 else [])
    if args is None:
        usage = delete_command_parser.format_usage().replace('\n', '')
        return f'@{msg.user} {usage}'

    if args.confirm:
        if msg.user in delete_list:
            delete_action = delete_list[msg.user]
            del delete_list[msg.user]
            if delete_action.expiration_time < datetime.datetime.now():
                return f'@{msg.user} Your request has expired.'
            if delete_action.command_to_delete.chat_command != args.confirm:
                return (f'@{msg.user} Cannot confirm deletion of command '
                        f'{delete_action.command_to_delete.chat_command!r}. '
                        f'You typed {args.confirm!r}.')
            else:
                exit_code, message = _delete_command(
                    delete_action.command_to_delete, msg.channel,
                    args.is_global)
                if exit_code != 0:
                    return f'@{msg.user} Failed to delete command: {message}'
                else:
                    return (
                        f'@{msg.user} Deleted command '
                        f'{delete_action.command_to_delete.chat_command!r} successfully.'
                    )
                return
        else:
            return f'@{msg.user} You don\'t have an action to confirm.'
    else:
        t = args.target.rstrip().split('#')
        if len(t) == 2:
            target, t_info = t
        else:
            target = t[0]
            t_info = None

        if target in [i.chat_command for i in main.bot.commands]:
            cmd = None
            candidates = []
            for i in main.bot.commands:
                if i.chat_command.lower() == target.lower():
                    if args.is_global:
                        candidates.append(i)
                    elif i.limit_to_channels is not None and msg.channel in i.limit_to_channels:
                        candidates.append(i)
            if len(candidates) == 1:
                cmd = candidates[0]
            elif len(candidates) == 0:
                return f'@{msg.user} Command {target!r} doesn\'t exist in this scope.'
            else:
                if t_info.isnumeric():
                    t_info = int(t_info) + 1
                    if t_info > len(candidates) or t_info < 1:
                        main.bot.send(
                            msg.reply(
                                f'@{msg.user} Cannot pick number {t_info} of '
                                f'{", ".join([i.chat_command for i in candidates])}'
                            ))
                        return
                    cmd = candidates[t_info - 1]
                else:
                    targets = ", ".join([
                        f"{i.chat_command} (ch: {i.limit_to_channels})"
                        for i in candidates
                    ])
                    main.bot.send(
                        msg.reply(
                            f'@{msg.user} Multiple possible target commands: '
                            f'{targets}'))
                    return
            delete_list[msg.user] = Deletion(
                msg.user, cmd,
                datetime.datetime.now() +
                datetime.timedelta(seconds=TIME_DELETION))
            scope = 'the global scope.' if args.is_global else f'the scope of this channel (#{msg.channel})'
            main.bot.send(
                msg.reply(
                    f'@{msg.user} Confirm you want to delete command {target!r} in '
                    f'{scope} using (prefix)mb.delete_command --confirm-delete COMMAND_NAME. '
                    f'You have {TIME_DELETION} seconds to do this.'))
        else:
            return f'@{msg.user} Command {args.target} doesn\'t exist.'
コード例 #27
0
    async def c_braillefy(self, msg: twitchirc.ChannelMessage):
        cd_state = main.do_cooldown('braille',
                                    global_cooldown=0,
                                    local_cooldown=60,
                                    msg=msg)
        if cd_state:
            return
        try:
            args = arg_parser.parse_args(msg.text.split(' ', 1)[1], {
                'url': str,
                'sensitivity_r': float,
                'sensitivity_g': float,
                'sensitivity_b': float,
                'sensitivity_a': float,
                'size_percent': float,
                'max_y': int,
                'pad_y': int,
                'reverse': bool,
                'hastebin': bool
            },
                                         strict_escapes=True,
                                         strict_quotes=True)
        except arg_parser.ParserError as e:
            return f'Error: {e.message}'
        missing_args = arg_parser.check_required_keys(args, ['url'])
        if missing_args:
            return (
                f'Error: You are missing the {",".join(missing_args)} '
                f'argument{"s" if len(missing_args) > 1 else ""} to run this command.'
            )

        num_defined = sum(
            [args[f'sensitivity_{i}'] is not Ellipsis for i in 'rgb'])
        alpha = args['sensitivity_a'] if args[
            'sensitivity_a'] is not Ellipsis else 1
        if num_defined == 3:
            sens: typing.Tuple[float, float, float,
                               float] = (args['sensitivity_r'],
                                         args['sensitivity_g'],
                                         args['sensitivity_b'], alpha)
            is_zero = bool(sum([args[f'sensitivity_{i}'] == 0
                                for i in 'rgba']))
            if is_zero:
                return f'Error: Sensitivity cannot be zero. MEGADANK'
        elif num_defined == 0:
            sens = (1, 1, 1, 1)
        else:
            return f'Error: you need to define either all sensitivity fields (r, g, b, a) or none.'
        if args['size_percent'] is not ... and args['max_y'] is not ...:
            return f'Error: you cannot provide the size percentage and maximum height at the same time.'

        max_x = 60 if args['size_percent'] is Ellipsis else None
        max_y = (args['max_y'] if args['max_y'] is not Ellipsis else
                 60) if args['size_percent'] is Ellipsis else None
        size_percent = None if args['size_percent'] is Ellipsis else args[
            'size_percent']

        img = await braille.download_image(args['url'])
        img: Image.Image
        if img.format.lower() != 'gif':
            img, o = await braille.crop_and_pad_image(
                True, img, max_x, max_y, '',
                (60, args['pad_y'] if args['pad_y'] is not Ellipsis else 60),
                size_percent)
            o += await braille.to_braille_from_image(
                img,
                reverse=True if args['reverse'] is not Ellipsis else False,
                size_percent=size_percent,
                max_x=max_x,
                max_y=max_y,
                sensitivity=sens,
                enable_padding=True,
                pad_size=(60, args['pad_y']
                          if args['pad_y'] is not Ellipsis else 60),
                enable_processing=False)
        else:
            missing_permissions = main.bot.check_permissions(
                msg, ['cancer.braille.gif'], enable_local_bypass=False)
            if missing_permissions:
                o = 'Note: missing permissions to convert a gif. \n'
            else:
                o = ''
                frame = -1
                start_time = time.time()
                while 1:
                    try:
                        img.seek(frame + 1)
                    except EOFError:
                        break
                    frame += 1
                    o += f'\nFrame {frame}\n'
                    frame_start = time.time()
                    o += await braille.to_braille_from_image(
                        img.copy(),
                        reverse=True
                        if args['reverse'] is not Ellipsis else False,
                        size_percent=size_percent,
                        max_x=max_x,
                        max_y=max_y,
                        sensitivity=sens,
                        enable_padding=True,
                        pad_size=(60, (args['pad_y'] if args['pad_y']
                                       is not Ellipsis else 60)),
                        enable_processing=True)
                    time_taken = round(time.time() - start_time)
                    frame_time = round(time.time() - frame_start)

                    if frame % self.status_every_frames == 0 and time_taken > self.time_before_status:
                        speed = round(1 / frame_time)
                        main.bot.send(
                            msg.reply(
                                f'@{msg.user}, ppCircle Converted {frame} frames in '
                                f'{time_taken} seconds, speed: {round(speed)} fps, '
                                f'eta: {(img.n_frames - frame) * speed} seconds.'
                            ))
                        await asyncio.sleep(0)

        sendable = ' '.join(o.split('\n')[1:])
        if args['hastebin'] is not Ellipsis or len(sendable) > 500:
            return (
                f'{"This braille was too big to be posted." if not args["hastebin"] is not Ellipsis else ""} '
                f'Here\'s a link to a hastebin: '
                f'{plugin_hastebin.hastebin_addr}'
                f'{await plugin_hastebin.upload(o)}')
        else:
            return sendable
コード例 #28
0
ファイル: plugin_manager.py プロジェクト: Mm2PL/MmsUtilityBot
def command_list_blacklisted(msg: twitchirc.ChannelMessage) -> None:
    ensure_blacklist(msg.channel)
    main.bot.send(
        msg.reply(
            f'@{msg.user}, There are {len(blacklist[msg.channel])} blacklisted commands: '
            f'{", ".join(blacklist[msg.channel])}'))
コード例 #29
0
ファイル: stock_commands.py プロジェクト: Mm2PL/twitchirc
 def command_quit(msg: twitchirc.ChannelMessage):
     bot.send(msg.reply('Quitting.'))
     bot.stop()
コード例 #30
0
def command_reminder(msg: twitchirc.ChannelMessage):
    aargs = c_rem_parser.parse_args(msg.text.split(' ')[1:])
    if aargs is None or aargs.help:
        return f'@{msg.user} {c_rem_parser.format_usage()}'
    # for i in dir(aargs):
    #     if i.startswith('_'):
    #         continue
    #     print(i, getattr(aargs, i, None))
    if aargs.for_user:
        missing_perms = main.bot.check_permissions(
            msg, ['reminder.reminder.for_other'], enable_local_bypass=True)
        if missing_perms:
            return (
                f'@{msg.user} Cannot add reminder for other user, you don\'t have the permissions '
                f'needed')
    if aargs.remove:
        if msg.channel not in reminders:
            return (
                f'@{msg.user} Cannot remove reminders: channel is not registered. '
                f'No reminders here.')
        count = 0
        for r in reminders[msg.channel].copy():
            if r['user'] == aargs.remove.lower():
                count += 1
                reminders[msg.channel].remove(r)
        return f'@{msg.user} removed {count} reminder(s).'
    if aargs.list:
        output = ''
        if msg.channel not in reminders:
            main.bot.send(
                msg.reply(
                    f'@{msg.user} Cannot list reminders: channel is not registered. '
                    f'No reminders here.'))
            return
        for r in reminders[msg.channel]:
            output += f'<{r["text"]!r} on ' \
                      f'{datetime.datetime.fromtimestamp(r["timestamp"]).strftime("%Y-%M-%d %H:%m:%S")}>, '
        output = output[:-2]
        return f'@{msg.user} List: {output}'
    if aargs.add:
        # if not aargs.time:
        #     bot.send(msg.reply(f'@{msg.user} Argument -t/--time is required with -a/--add.'))
        #     return
        text = ' '.join(aargs.add)
        seconds = process_time(aargs.time)
        print(text, seconds)
        new_timestamp = time.time() + seconds
        if msg.channel not in reminders:
            reminders[msg.channel] = []
        reminders[msg.channel].append({
            'text': text,
            'seconds': seconds,
            'timestamp': new_timestamp,
            'user': msg.user,
            'nr': aargs.nr
        })
        if not aargs.nr:
            return (
                f'@{msg.user} , I will be messaging you in {seconds} seconds '
                f'or ({seconds // 3600:.0f} hours, '
                f'{seconds % 3600 / 60:.0f} minutes and {seconds % 3600 % 60:.0f} seconds) with '
                f'the message {text!r}')
        else:
            return (
                f'@{msg.user} , I will be messaging you every {seconds} seconds '
                f'or ({seconds // 3600:.0f} hours, '
                f'{seconds % 3600 / 60:.0f} minutes and {seconds % 3600 % 60:.0f} seconds) with '
                f'the message {text!r}')