예제 #1
0
def join(bot: DeltaBot, payload: str, message: Message,
         replies: Replies) -> None:
    """Join the given IRC channel."""
    sender = message.get_sender_contact()
    if not payload:
        replies.add(text="Wrong syntax")
        return
    if not bot.is_admin(sender.addr) and \
       not db.is_whitelisted(payload):
        replies.add(text="That channel isn't in the whitelist")
        return

    g = bot.get_chat(db.get_chat(payload))
    if g and sender in g.get_contacts():
        replies.add(text='You are already a member of this group', chat=g)
        return
    if g is None:
        chat = bot.create_group(payload, [sender])
        db.add_channel(payload, chat.id)
        irc_bridge.join_channel(payload)
        irc_bridge.preactor.join_channel(sender.addr, payload)
    else:
        _add_contact(g, sender)
        chat = bot.get_chat(sender)

    nick = db.get_nick(sender.addr)
    text = '** You joined {} as {}'.format(payload, nick)
    replies.add(text=text, chat=chat)
예제 #2
0
def filter_messages(bot: DeltaBot, message: Message, replies: Replies) -> None:
    """Process turns in Exquisite Corpse game groups
    """
    if not message.chat.is_group():
        sender = message.get_sender_contact()
        g = db.get_game_by_turn(sender.addr)

        if g is None:
            return

        if len(message.text.split()) < 10:
            text = '❌ Text too short. Send a message with at least 10 words'
            replies.add(text=text)
        else:
            paragraph = g['text'] + ' ' + message.text
            db.set_text(g['gid'], paragraph)

            p = db.get_player_by_addr(sender.addr)
            assert p is not None
            if p['round'] == 3:
                db.delete_player(p['addr'])
            else:
                db.set_player(p['addr'], p['round'] + 1, g['gid'])

            p = _get_by_round(g['gid'])

            if p is None:  # End Game
                text = _end_game(g['gid'])
                replies.add(text=text, chat=bot.get_chat(g['gid']))
            else:
                db.set_turn(g['gid'], p['addr'])
                _run_turn(bot, p, bot.get_chat(g['gid']), paragraph)
예제 #3
0
def group_adminchan(bot: DeltaBot, args: list, message: Message,
                    replies: Replies) -> None:
    """Join the admin group of the given channel.
    """
    ch = db.get_channel_by_id(int(args[0]))
    if ch:
        sender = message.get_sender_contact()
        _add_contact(bot.get_chat(ch['admin']), sender)
        text = '{}\n\n{}'.format(ch['name'], ch['topic'] or '-')
        replies.add(text=text, chat=bot.get_chat(sender))
    else:
        replies.add(text='❌ Invalid ID')
예제 #4
0
def group_join(bot: DeltaBot, args: list, message: Message,
               replies: Replies) -> None:
    """Join the given group/channel.
    """
    sender = message.get_sender_contact()
    is_admin = bot.is_admin(sender.addr)
    text = '{}\n\n{}\n\n⬅️ /group_remove_{}'
    arg = args[0] if args else ''
    if arg.startswith('g'):
        gid = int(arg[1:])
        gr = db.get_group(gid)
        if gr:
            g = bot.get_chat(gr['id'])
            contacts = g.get_contacts()
            if sender in contacts:
                replies.add(
                    text='❌ {}, you are already a member of this group'.format(
                        sender.addr),
                    chat=g)
            elif len(contacts) < int(_getdefault(
                    bot, 'max_group_size')) or is_admin:
                _add_contact(g, sender)
                replies.add(chat=bot.get_chat(sender),
                            text=text.format(g.get_name(), gr['topic'] or '-',
                                             arg))
            else:
                replies.add(text='❌ Group is full')
            return
    elif arg.startswith('c'):
        gid = int(arg[1:])
        ch = db.get_channel_by_id(gid)
        if ch:
            for g in _get_cchats(bot, ch['id'], include_admin=True):
                if sender in g.get_contacts():
                    replies.add(
                        text='❌ {}, you are already a member of this channel'.
                        format(sender.addr),
                        chat=g)
                    return
            g = bot.create_group(ch['name'], [sender])
            db.add_cchat(g.id, ch['id'])
            img = bot.get_chat(ch['id']).get_profile_image()
            if img:
                g.set_profile_image(img)
            replies.add(text=text.format(ch['name'], ch['topic'] or '-', arg),
                        chat=g)
            return

    replies.add(text='❌ Invalid ID')
예제 #5
0
def _run_turn(bot: DeltaBot, player: sqlite3.Row, group: Chat,
              paragraph: str) -> None:
    contact = bot.get_contact(player['addr'])
    text = ec + "⏳ Round {}/3\n\n{}, it's your turn...".format(
        player['round'], contact.name)
    group.send_text(text)

    if paragraph:
        text = ec + '📝 Complete the phrase:\n...{}\n\n'.format(' '.join(
            paragraph.rsplit(maxsplit=5)[-5:]))
    else:
        text = '📝 You are the first!\nSend a message with at least 10 words.'
        text = ec + text

    bot.get_chat(contact).send_text(text)
예제 #6
0
def _check_feed(bot: DeltaBot, f: sqlite3.Row) -> None:
    fchats = db.get_fchats(f['url'])

    if not fchats:
        db.remove_feed(f['url'])
        return

    bot.logger.debug('Checking feed: %s', f['url'])
    d = feedparser.parse(f['url'], etag=f['etag'], modified=f['modified'])

    bozo_exception = d.get('bozo_exception', '')
    if d.get('bozo') == 1 and not isinstance(bozo_exception,
                                             CharacterEncodingOverride):
        bot.logger.exception(bozo_exception)
        return

    if d.entries and f['latest']:
        d.entries = get_new_entries(d.entries,
                                    tuple(map(int, f['latest'].split())))
    if not d.entries:
        return

    html = format_entries(d.entries[:50])
    replies = Replies(bot, logger=bot.logger)
    for gid in fchats:
        try:
            replies.add(html=html, chat=bot.get_chat(gid))
        except (ValueError, AttributeError):
            db.remove_fchat(gid)
    replies.send_reply_messages()

    latest = get_latest_date(d.entries) or f['latest']
    modified = d.get('modified') or d.get('updated')
    db.update_feed(f['url'], d.get('etag'), modified, latest)
예제 #7
0
def poll_get(bot: DeltaBot, payload: str, message: Message,
             replies: Replies) -> None:
    """Get poll with given id.
    """
    args = payload.split()
    if len(args) not in (1, 2):
        replies.add(text='Invalid syntax')
        return
    if len(args) == 2:
        chat = bot.get_chat(int(args[0]))
        payload = args[1]
        if message.get_sender_contact() not in chat.get_contacts():
            replies.add(text='You are not a member of that group')
            return
    else:
        chat = message.chat

    pid = int(payload)
    poll = db.get_gpoll_by_id(pid)
    if poll and chat.id == poll['gid']:
        closed = poll['status'] == Status.CLOSED
        replies.add(text=format_gpoll(poll, closed=closed))
    elif len(args) == 1:
        poll = db.get_poll_by_id(pid)
        if poll:
            closed = poll['status'] == Status.CLOSED
            replies.add(text=_format_poll(bot, poll, closed=closed))
        else:
            replies.add(text='Invalid poll id')
    else:
        replies.add(text='Invalid poll id')
예제 #8
0
def lines_play(bot: DeltaBot, message: Message, replies: Replies) -> None:
    """Start a new Color Lines game.

    Example: `/lines_play`
    """
    player = message.get_sender_contact()
    if not db.get_nick(player.addr):
        text = "You need to set a nick before start playing,"
        text += " send /lines_nick Your Nick"
        replies.add(text=text)
        return
    game = db.get_game_by_addr(player.addr)

    if game is None:  # create a new chat
        chat = bot.create_group('🌈 Color Lines', [player.addr])
        db.add_game(player.addr, chat.id, Board().export())
        text = 'Hello {}, in this group you can play Color Lines.\n\n'
        replies.add(text=text.format(player.name) + _run_turn(chat.id),
                    chat=chat)
    else:
        db.set_board(game['addr'], Board(old_score=game['score']).export())
        if message.chat.id == game['gid']:
            chat = message.chat
        else:
            chat = bot.get_chat(game['gid'])
        replies.add(text='Game started!\n\n' + _run_turn(game['gid']),
                    chat=chat)
예제 #9
0
def c4_play(bot: DeltaBot, payload: str, message: Message, replies: Replies) -> None:
    """Invite a friend to play Connect4.

    Example: `/c4_play [email protected]`
    """
    if not payload:
        replies.add(text="Missing address")
        return

    if payload == bot.self_contact.addr:
        replies.add(text="Sorry, I don't want to play")
        return

    p1 = message.get_sender_contact().addr
    p2 = payload
    if p1 == p2:
        replies.add(text="You can't play with yourself")
        return

    g = db.get_game_by_players(p1, p2)

    if g is None:  # first time playing with p2
        chat = bot.create_group(
            '4️⃣ {} 🆚 {} [c4]'.format(p1, p2), [p1, p2])
        b = Board()
        db.add_game(p1, p2, chat.id, b.export(), p1)
        text = 'Hello {1},\nYou have been invited by {0} to play Connect4'
        text += '\n\n{2}: {0}\n{3}: {1}\n\n'
        text = text.format(
            p1, p2, b.get_disc(BLACK), b.get_disc(WHITE))
        replies.add(text=text + _run_turn(chat.id), chat=chat)
    else:
        text = 'You already have a game group with {}'.format(p2)
        replies.add(text=text, chat=bot.get_chat(g['gid']))
예제 #10
0
def poll_end(bot: DeltaBot, args: str, message: Message,
             replies: Replies) -> None:
    """Close the poll with the given id."""
    if args:
        addr = message.get_sender_contact().addr
        try:
            with session_scope() as session:
                poll = session.query(Poll).filter_by(id=int(args[0]),
                                                     addr=addr).one()
                text, html = _format_poll(bot, poll, closed=True)
                addresses = set(vote.addr for vote in poll.votes)
                session.delete(poll)
            addresses.add(addr)
            for addr in addresses:
                contact = bot.get_contact(addr)
                if not contact.is_blocked():
                    replies.add(text=text,
                                html=html,
                                chat=bot.get_chat(contact))
        except NoResultFound:
            replies.add(text="❌ Invalid poll",
                        quote=message,
                        chat=message.get_sender_chat())
    else:
        replies.add(text="❌ Invalid poll",
                    quote=message,
                    chat=message.get_sender_chat())
예제 #11
0
def _get_cchats(bot: DeltaBot,
                cgid: int,
                include_admin: bool = False) -> Generator:
    if include_admin:
        ch = db.get_channel_by_id(cgid)
        if ch:
            g = bot.get_chat(ch['admin'])
            if g:
                yield g
            else:
                db.remove_channel(cgid)
    for gid in db.get_cchats(cgid):
        g = bot.get_chat(gid)
        if g and bot.self_contact in g.get_contacts():
            yield g
        else:
            db.remove_cchat(gid)
예제 #12
0
def group_remove(bot: DeltaBot, args: list, message: Message,
                 replies: Replies) -> None:
    """Remove the member with the given address from the group with the given id. If no address is provided, removes yourself from group/channel.
    """
    sender = message.get_sender_contact()

    if not args:
        replies.add(text='❌ Invalid ID')
        return

    type_, gid = args[0][0], int(args[0][1:])
    if type_ == 'c':
        ch = db.get_channel_by_id(gid)
        if not ch:
            replies.add(text='❌ Invalid ID')
            return
        for g in _get_cchats(bot, ch['id'], include_admin=True):
            if sender in g.get_contacts():
                g.remove_contact(sender)
                return
        replies.add(text='❌ You are not a member of that channel')
    elif type_ == 'g':
        gr = db.get_group(gid)
        if not gr:
            replies.add(text='❌ Invalid ID')
            return
        g = bot.get_chat(gr['id'])
        if sender not in g.get_contacts():
            replies.add(text='❌ You are not a member of that group')
            return
        addr = args[-1] if '@' in args[-1] else ''
        if addr:
            if addr == bot.self_contact.addr:
                replies.add(text='❌ You can not remove me from the group')
                return
            contact = bot.get_contact(addr)
            g.remove_contact(contact)
            if not contact.is_blocked():
                chat = bot.get_chat(contact)
                replies.add(text='❌ Removed from {} by {}'.format(
                    g.get_name(), sender.addr),
                            chat=chat)
            replies.add(text='✔️{} removed'.format(addr))
        else:
            g.remove_contact(sender)
예제 #13
0
def poll_end(bot: DeltaBot, payload: str, message: Message,
             replies: Replies) -> None:
    """Close the poll with the given id.
    """
    args = payload.split()
    if len(args) not in (1, 2):
        replies.add(text='Invalid syntax')
        return
    if len(args) == 2:
        chat = bot.get_chat(int(args[0]))
        payload = args[1]
        if message.get_sender_contact() not in chat.get_contacts():
            replies.add(text='You are not a member of that group')
            return
    else:
        chat = message.chat

    pid = int(payload)
    poll = db.get_gpoll_by_id(pid)
    addr = message.get_sender_contact().addr
    if poll and chat.id == poll['gid']:
        db.end_gpoll(poll['id'])
        text = format_gpoll(poll, closed=True)
        text += '\n\n(Poll closed by {})'.format(addr)
        replies.add(text=text, chat=chat)
        db.remove_gpoll_by_id(pid)
    elif len(args) == 1:
        poll = db.get_poll_by_id(pid)
        if poll and addr == poll['addr']:
            db.end_poll(poll['id'])
            text = _format_poll(bot, poll, closed=True)
            for addr in db.get_poll_participants(poll['id']):
                contact = bot.get_contact(addr)
                if not contact.is_blocked():
                    replies.add(text=text, chat=bot.get_chat(contact))
            db.remove_poll_by_id(poll['id'])
        else:
            replies.add(text='Invalid poll id')
    else:
        replies.add(text='Invalid poll id')
예제 #14
0
def _remove_from_game(bot: DeltaBot, player: sqlite3.Row,
                      game: sqlite3.Row) -> None:
    db.delete_player(player['addr'])
    if player['addr'] == game['turn']:
        p = _get_by_round(player['game'])
        chat = bot.get_chat(player['game'])
        if p is None or len(db.get_players(player['game'])) <= 1:
            chat.send_text(_end_game(player['game']))
        else:
            db.set_turn(player['game'], p['addr'])
            _run_turn(bot, p, chat, game['text'])
    else:
        chat.send_text(game['gid'], game['turn'])
예제 #15
0
 def __init__(self, server, port, db: DBManager,
              dbot: DeltaBot) -> None:
     super().__init__()
     self.server = server
     self.port = port
     self.dbot = dbot
     self.db = db
     self.puppets = dict()
     for chan, gid in db.get_channels():
         for c in dbot.get_chat(gid).get_contacts():
             if dbot.self_contact == c:
                 continue
             self._get_puppet(c.addr).channels.add(chan)
예제 #16
0
def remove(bot: DeltaBot, payload: str, message: Message,
           replies: Replies) -> None:
    """Remove the member with the given nick from the IRC channel, if no nick is given remove yourself.
    """
    sender = message.get_sender_contact()

    channel = db.get_channel_by_gid(message.chat.id)
    if not channel:
        args = payload.split(maxsplit=1)
        channel = args[0]
        payload = args[1] if len(args) == 2 else ''
        g = bot.get_chat(db.get_chat(channel))
        if not g or sender not in g.get_contacts():
            replies.add(text='You are not a member of that channel')
            return

    if not payload:
        payload = sender.addr
    if '@' not in payload:
        t = db.get_addr(payload)
        if not t:
            replies.add(text='Unknow user: {}'.format(payload))
            return
        payload = t

    g = bot.get_chat(db.get_chat(channel))
    for c in g.get_contacts():
        if c.addr == payload:
            g.remove_contact(c)
            if c == sender:
                return
            s_nick = db.get_nick(sender.addr)
            nick = db.get_nick(c.addr)
            text = '** {} removed by {}'.format(nick, s_nick)
            bot.get_chat(db.get_chat(channel)).send_text(text)
            text = 'Removed from {} by {}'.format(channel, s_nick)
            replies.add(text=text, chat=bot.get_chat(c))
            return
예제 #17
0
def lines_repeat(bot: DeltaBot, message: Message, replies: Replies) -> None:
    """Send Color Lines game board again.

    Example: `/lines_repeat`
    """
    game = db.get_game_by_addr(message.get_sender_contact().addr)
    if game and game['board']:
        if message.chat.id == game['gid']:
            chat = message.chat
        else:
            chat = bot.get_chat(game['gid'])
        replies.add(text=_run_turn(game['gid']), chat=chat)
    else:
        replies.add(text="No active game, send /lines_play to start playing.")
예제 #18
0
def deltabot_ban(bot: DeltaBot, contact: Contact) -> None:
    me = bot.self_contact
    for g in db.get_groups():
        chat = bot.get_chat(g['id'])
        if chat:
            contacts = chat.get_contacts()
            if contact in contacts and me in contacts:
                chat.remove_contact(contact)

    for ch in db.get_channels():
        for chat in _get_cchats(bot, ch['id']):
            contacts = chat.get_contacts()
            if contact in contacts and me in contacts:
                chat.remove_contact(contact)
예제 #19
0
def vote(bot: DeltaBot, payload: str, message: Message,
         replies: Replies) -> None:
    """Vote in polls.
    """
    args = payload.split()
    if len(args) not in (2, 3):
        replies.add(text='Invalid syntax')
        return
    if len(args) == 3:
        chat = bot.get_chat(int(args[0]))
        if message.get_sender_contact() not in chat.get_contacts():
            replies.add(text='You are not a member of that group')
            return
        pid = int(args[1])
        oid = int(args[2]) - 1
    else:
        chat = message.chat
        pid = int(args[0])
        oid = int(args[1]) - 1

    addr = message.get_sender_contact().addr
    poll = db.get_gpoll_by_id(pid)
    if poll and chat.id == poll['gid']:
        if poll['status'] == Status.CLOSED:
            replies.add(text='That poll is closed')
        elif db.get_gvote(pid, addr):
            replies.add(text='You already voted')
        elif oid not in [opt['id'] for opt in db.get_goptions(pid)]:
            replies.add(text='Invalid option number')
        else:
            db.add_gvote(poll['id'], addr, oid)
            replies.add(text=format_gpoll(poll, voted=True))
    elif len(args) == 2:
        poll = db.get_poll_by_id(pid)
        if poll:
            if poll['status'] == Status.CLOSED:
                replies.add(text='That poll is closed')
            elif db.get_vote(pid, addr):
                replies.add(text='You already voted')
            elif oid not in [opt['id'] for opt in db.get_options(pid)]:
                replies.add(text='Invalid option number')
            else:
                is_admin = addr == poll['addr']
                db.add_vote(poll['id'], addr, oid)
                replies.add(text=_format_poll(
                    bot, poll, voted=True, is_admin=is_admin))
        else:
            replies.add(text='Invalid poll id')
    else:
        replies.add(text='Invalid poll id')
예제 #20
0
def group_info(bot: DeltaBot, message: Message, replies: Replies) -> None:
    """Show the group/channel info.
    """
    if not message.chat.is_group():
        replies.add(text='❌ This is not a group')
        return

    text = '{0}\n👤 {1}\n{2}\n\n'
    text += '⬅️ /group_remove_{3}{4}\n➡️ /group_join_{3}{4}'

    ch = db.get_channel(message.chat.id)
    if ch:
        count = sum(
            map(lambda g: len(g.get_contacts()) - 1,
                _get_cchats(bot, ch['id'])))
        replies.add(text=text.format(ch['name'], count, ch['topic'] or '-',
                                     'c', ch['id']))
        return

    g = db.get_group(message.chat.id)
    if not g:
        addr = message.get_sender_contact().addr
        _add_group(bot, message.chat.id, as_admin=bot.is_admin(addr))
        g = db.get_group(message.chat.id)
        assert g is not None

    chat = bot.get_chat(g['id'])
    img = qrcode.make(chat.get_join_qr())
    buffer = io.BytesIO()
    img.save(buffer, format='jpeg')
    buffer.seek(0)
    count = len(bot.get_chat(g['id']).get_contacts())
    replies.add(text=text.format(chat.get_name(), count, g['topic'] or '-',
                                 'g', g['id']),
                filename='img.jpg',
                bytefile=buffer)
예제 #21
0
def poll_status(bot: DeltaBot, payload: str, message: Message,
                replies: Replies) -> None:
    """Get poll status.
    """
    args = payload.split()
    if len(args) not in (1, 2):
        replies.add(text='Invalid syntax')
        return
    if len(args) == 2:
        chat = bot.get_chat(int(args[0]))
        payload = args[1]
        if message.get_sender_contact() not in chat.get_contacts():
            replies.add(text='You are not a member of that group')
            return
    else:
        chat = message.chat

    pid = int(payload)
    addr = message.get_sender_contact().addr
    poll = db.get_gpoll_by_id(pid)
    if poll and chat.id == poll['gid']:
        voted = db.get_gvote(poll['id'], addr) is not None
        if voted:
            closed = poll['status'] == Status.CLOSED
            replies.add(text=format_gpoll(poll, voted=voted, closed=closed))
        else:
            replies.add(text="You can't see poll status until you vote")
    elif len(args) == 1:
        poll = db.get_poll_by_id(pid)
        if poll:
            is_admin = addr == poll['addr']
            voted = is_admin or db.get_vote(poll['id'], addr) is not None
            if voted:
                closed = poll['status'] == Status.CLOSED
                replies.add(text=_format_poll(
                    bot, poll, voted=voted, closed=closed, is_admin=is_admin))
            else:
                replies.add(text="You can't see poll status until you vote")
        else:
            replies.add(text='Invalid poll id')
    else:
        replies.add(text='Invalid poll id')
예제 #22
0
def chr_play(payload: str, message: Message, bot: DeltaBot,
             replies: Replies) -> None:
    """Invite a friend to play Chain Reaction.

    Example: `/chr_play [email protected]`
    """
    if not payload:
        replies.add(text="Missing address")
        return

    if payload == bot.self_contact.addr:
        replies.add(text="Sorry, I don't want to play")
        return

    player1 = message.get_sender_contact()
    player2 = bot.get_contact(payload)
    if player1 == player2:
        replies.add(text="You can't play with yourself")
        return

    game = DBASE.get_game_by_players(player1.addr, player2.addr)

    if game is None:  # first time playing with player2
        board = Board()
        chat = bot.create_group(
            '🧬 {} 🆚 {} [ChainReaction]'.format(player1.addr, player2.addr),
            [player1, player2])
        DBASE.add_game(player1.addr, player2.addr, chat.id,
                       Board().export(), player1.addr)
        text = 'Hello {1},' \
               'You have been invited by {0} to play Chain Reaction'
        text += '\n\n{2}: {0}\n{3}: {1}\n\n'
        text = text.format(player1.name,
                           player2.name, board.get_orb(Atom.BLACK),
                           board.get_orb(Atom.WHITE))
        replies.add(text=text + _run_turn(chat.id, DBASE, bot), chat=chat)
    else:
        text = 'You already have a game group with {}'.format(player2.name)
        replies.add(text=text, chat=bot.get_chat(game['gid']))
예제 #23
0
def group_me(bot: DeltaBot, message: Message, replies: Replies) -> None:
    """Show the list of groups and channels you are in.
    """
    sender = message.get_sender_contact()
    groups = []
    for group in db.get_groups():
        g = bot.get_chat(group['id'])
        contacts = g.get_contacts()
        if bot.self_contact not in contacts:
            db.remove_group(group['id'])
            continue
        if sender in contacts:
            groups.append((g.get_name(), 'g{}'.format(g.id)))

    for ch in db.get_channels():
        for c in _get_cchats(bot, ch['id']):
            if sender in c.get_contacts():
                groups.append((ch['name'], 'c{}'.format(ch['id'])))
                break

    text = '{0}:\n⬅️ /group_remove_{1}\n\n'
    replies.add(text=''.join(text.format(*g) for g in groups) or 'Empty list')
예제 #24
0
def chess_play(bot: DeltaBot, payload: str, message: Message,
               replies: Replies) -> None:
    """Invite a friend to play Chess.

    Example: `/chess_play [email protected]`
    To move use Standard Algebraic Notation or Long Algebraic Notation
    (without hyphens), more info in Wikipedia.
    For example, to move pawn from e2 to e4, send a message: e4 or: e2e4,
    to move knight from g1 to f3, send a message: Nf3 or: g1f3
    """
    if not payload:
        replies.add(text="Missing address")
        return

    if payload == bot.self_contact.addr:
        replies.add(text="Sorry, I don't want to play")
        return

    p1 = message.get_sender_contact().addr
    p2 = payload
    if p1 == p2:
        replies.add(text="You can't play with yourself")
        return

    g = db.get_game_by_players(p1, p2)

    if g is None:  # first time playing with p2
        chat = bot.create_group('♞ {} 🆚 {} [Chess]'.format(p1, p2), [p1, p2])
        b = chgame.Board(p1=p1, p2=p2, theme=int(_getdefault(bot, 'theme')))
        db.add_game(p1, p2, chat.id, b.export())
        text = 'Hello {1},\nYou have been invited by {0} to play Chess'
        text += '\n\n{2} White: {0}\n{3} Black: {1}\n\n'
        text = text.format(p1, p2, b.theme['P'], b.theme['p'])
        text += _run_turn(bot, chat.id)
        replies.add(text=text, chat=chat)
    else:
        text = 'You already have a game group with {}'.format(p2)
        replies.add(text=text, chat=bot.get_chat(g['gid']))
예제 #25
0
def sudoku_play(bot: DeltaBot, message: Message, replies: Replies) -> None:
    """Start a new Sudoku game.

    Example: `/sudoku_play`
    """
    player = message.get_sender_contact()
    game = db.get_game_by_addr(player.addr)

    if game is None:  # make a new chat
        b = Board()
        chat = bot.create_group('#️⃣ Sudoku', [player.addr])
        db.add_game(player.addr, chat.id, b.export(), time.time())
        text = 'Hello {}, in this group you can play Sudoku.\n\n'.format(
            player.name)
        replies.add(text=text + _run_turn(chat.id), chat=chat)
    else:
        db.set_game(game['addr'], Board().export(), time.time())
        if message.chat.id == game['gid']:
            chat = message.chat
        else:
            chat = bot.get_chat(game['gid'])
        replies.add(
            text='Game started!\n\n' + _run_turn(game['gid']), chat=chat)
예제 #26
0
def checkers_play(bot: DeltaBot, payload: str, message: Message,
                  replies: Replies) -> None:
    """Invite a friend to play Checkers.

    Example: `/checkers_play [email protected]`
    """
    if not payload:
        replies.add(text="Missing address")
        return

    if payload == bot.self_contact.addr:
        replies.add(text="Sorry, I don't want to play")
        return

    player1 = message.get_sender_contact().addr
    player2 = payload
    if player1 == player2:
        replies.add(text="You can't play with yourself")
        return

    game = DBASE.get_game_by_players(player1, player2)

    if game is None:  # first time playing with player2
        board = Board()
        chat = bot.create_group(
            '🔴 {} 🆚 {} [checkers]'.format(player1, player2),
            [player1, player2])
        DBASE.add_game(player1, player2, chat.id, board.export(), player1)
        text = 'Hello {1},\nYou have been invited by {0} to play Checkers'
        text += '\n\n{2}: {0}\n{3}: {1}\n\n'
        text = text.format(player1, player2, board.get_disc(BLACK),
                           board.get_disc(WHITE))
        replies.add(text=text + _run_turn(chat.id), chat=chat)
    else:
        text = 'You already have a game group with {}'.format(player2)
        replies.add(text=text, chat=bot.get_chat(game['gid']))
예제 #27
0
def poll_settings(bot: DeltaBot, payload: str, message: Message,
                  replies: Replies) -> None:
    """Get poll advanced settings.
    """
    args = payload.split()
    if len(args) not in (1, 2):
        replies.add(text='Invalid syntax')
        return
    if len(args) == 2:
        chat = bot.get_chat(int(args[0]))
        payload = args[1]
        if message.get_sender_contact() not in chat.get_contacts():
            replies.add(text='You are not a member of that group')
            return
    else:
        chat = message.chat

    pid = int(payload)
    poll = db.get_gpoll_by_id(pid)
    if poll and chat.id == poll['gid']:
        gid = '{}_{}'.format(poll['gid'], poll['id'])
        text = '📊 /poll_get_{}\n{}\n\n'.format(gid, poll['question'])
        text += '🛑 /poll_end_{}\n\n'.format(gid)
        replies.add(text=text)
    elif len(args) == 1:
        addr = message.get_sender_contact().addr
        poll = db.get_poll_by_id(pid)
        if poll and addr == poll['addr']:
            text = '📊 /poll_get_{}\n{}\n\n'.format(poll['id'],
                                                   poll['question'])
            text += '🛑 /poll_end_{}\n\n'.format(poll['id'])
            replies.add(text=text)
        else:
            replies.add(text='Invalid poll id')
    else:
        replies.add(text='Invalid poll id')
예제 #28
0
def group_list(bot: DeltaBot, replies: Replies) -> None:
    """Show the list of public groups and channels.
    """
    def get_list(chats):
        return Template('''
<style>
.w3-card-2{box-shadow:0 2px 4px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12) !important; margin-bottom: 15px;}
.w3-btn{border:none;display:inline-block;outline:0;padding:6px 16px;vertical-align:middle;overflow:hidden;text-decoration:none !important;color:#fff;background-color:#5a6f78;text-align:center;cursor:pointer;white-space:nowrap}
.w3-container:after,.w3-container:before{content:"";display:table;clear:both}
.w3-container{padding:0.01em 16px}
.w3-right{float:right !important}
.w3-large{font-size:18px !important}
.w3-delta,.w3-hover-delta:hover{color:#fff !important;background-color:#5a6f78 !important}
</style>
{% for name, topic, gid, last_pub, bot_addr, count in chats %}
<div class="w3-card-2">
<header class="w3-container w3-delta">
<h2>{{ name }}</h2>
</header>
<div class="w3-container">
<p>👤 {{ count }}</p>
{% if last_pub %}
📝 {{ last_pub }}
{% endif %}
<p>{{ topic }}</p>
</div>
<a class="w3-btn w3-large" href="mailto:{{ bot_addr }}?body=/group_remove_{{ gid }}">« Leave</a>
<a class="w3-btn w3-large w3-right" href="mailto:{{ bot_addr }}?body=/group_join_{{ gid }}">Join »</a>
</div>
{% endfor %}
''').render(chats=chats)

    groups = []
    for g in db.get_groups():
        chat = bot.get_chat(g['id'])
        if not chat:
            db.remove_group(g['id'])
            continue
        groups.append(
            (chat.get_name(), g['topic']
             or '-', 'g{}'.format(chat.id), None, bot.self_contact.addr,
             len(chat.get_contacts())))
    total_groups = len(groups)
    if groups:
        groups.sort(key=lambda g: g[-1], reverse=True)
        text = '⬇️ Groups ({}) ⬇️'.format(total_groups)
        replies.add(text=text, html=get_list(groups))

    channels = []
    for ch in db.get_channels():
        count = sum(
            map(lambda g: len(g.get_contacts()) - 1,
                _get_cchats(bot, ch['id'])))
        if ch['last_pub']:
            last_pub = time.strftime('%d-%m-%Y', time.gmtime(ch['last_pub']))
        else:
            last_pub = '-'
        channels.append(
            (ch['name'], ch['topic'] or '-', 'c{}'.format(ch['id']), last_pub,
             bot.self_contact.addr, count))
    total_channels = len(channels)
    if channels:
        channels.sort(key=lambda g: g[-1], reverse=True)
        text = '⬇️ Channels ({}) ⬇️'.format(total_channels)
        replies.add(text=text, html=get_list(channels))

    if 0 == total_groups == total_channels:
        replies.add(text='❌ Empty List')
예제 #29
0
def _add_group(bot: DeltaBot, gid: int, as_admin=False) -> None:
    if as_admin or _getdefault(bot, 'allow_groups') == '1':
        db.upsert_group(gid, None)
    else:
        bot.get_chat(gid).remove_contact(bot.self_contact)