Exemple #1
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())
Exemple #2
0
def vote(bot: DeltaBot, args: str, message: Message, replies: Replies) -> None:
    """Vote in polls."""
    if len(args) == 2:
        option_id = int(args[1])
        addr = message.get_sender_contact().addr
        try:
            with session_scope() as session:
                poll = session.query(Poll).filter_by(id=int(args[0])).one()
                if addr in [v.addr for v in poll.votes]:
                    text, html = "❌ You already voted", None
                elif option_id not in [o.id for o in poll.options]:
                    text, html = "❌ Invalid option number", None
                else:
                    poll.votes.append(Vote(addr=addr, value=option_id))
                    is_admin = addr == poll.addr
                    text, html = _format_poll(bot,
                                              poll,
                                              voted=True,
                                              is_admin=is_admin)
            replies.add(text=text, html=html, chat=message.get_sender_chat())
        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())
Exemple #3
0
def poll_status(bot: DeltaBot, args: str, message: Message,
                replies: Replies) -> None:
    """Get poll status."""
    addr = message.get_sender_contact().addr
    if args:
        try:
            with session_scope() as session:
                poll = session.query(Poll).filter_by(id=int(args[0])).one()
                is_admin = addr == poll.addr
                voted = is_admin or addr in [v.addr for v in poll.votes]
                if voted:
                    text, html = _format_poll(bot,
                                              poll,
                                              voted=True,
                                              is_admin=is_admin)
                else:
                    text = "❌ You can't see poll status until you vote"
                    html = None
            replies.add(text=text, html=html, chat=message.get_sender_chat())
        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())
Exemple #4
0
    def ac_incoming_message(self, message: Message) -> None:
        # we always accept incoming messages to remove the need  for
        # bot authors to having to deal with deaddrop/contact requests.
        message.create_chat()
        self.logger.debug(
            f"incoming message from {message.get_sender_contact().addr} id={message.id} chat={message.chat.id} text={message.text[:50]!r}"
        )

        self.db.put_msg(message.id)
        # message is now in DB, schedule a check
        self._needs_check.set()
Exemple #5
0
def poll_list(message: Message, replies: Replies) -> None:
    """Show your public polls."""
    with session_scope() as session:
        text = ""
        for poll in (session.query(Poll).filter_by(
                addr=message.get_sender_contact().addr).all()):
            if len(poll.question) > 100:
                q = poll.question[:100] + "..."
            else:
                q = poll.question
            text += "📊 /poll_get_{} {}\n\n".format(poll.id, q)
    replies.add(text=text or "❌ Empty list", chat=message.get_sender_chat())
Exemple #6
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')
Exemple #7
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)
Exemple #8
0
def corpse_join(bot: DeltaBot, message: Message, replies: Replies) -> None:
    """Join in a Exquisite Corpse game

    Example: `/corpse_join`
    """
    sender = message.get_sender_contact()
    gid = message.chat.id
    g = db.get_game_by_gid(gid)

    if not message.chat.is_group():
        replies.add(text='❌ This is not a group.')
        return
    if g is None:
        replies.add(text='❌ There is not a game running in this group.')
        return

    player = db.get_player_by_addr(sender.addr)
    if player:
        if player['game'] == g['gid']:
            replies.add(text='❌ You already joined this game.')
        else:
            replies.add(text='❌ You are already playing in another group.')
        return

    if g['turn'] and db.get_player_by_addr(g['turn'])['round'] != 1:
        replies.add(text="⌛ Too late!!! You can't join the game at this time")
        return

    db.add_player(sender.addr, 1, gid)
    replies.add(text=_show_status(bot, gid, g['turn']))
Exemple #9
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)
Exemple #10
0
def w(bot: DeltaBot, payload: str, message: Message, replies: Replies) -> None:
    """Search in Wikipedia."""
    sender = message.get_sender_contact().addr
    lang = _get_locale(bot, sender)
    url = "https://{}.m.wikipedia.org/wiki/?search={}".format(
        lang, quote_plus(payload))
    replies.add(**_download_file(bot, url, _get_mode(bot, sender)))
Exemple #11
0
def ddg(bot: DeltaBot, payload: str, message: Message,
        replies: Replies) -> None:
    """Search in DuckDuckGo."""
    mode = _get_mode(bot, message.get_sender_contact().addr)
    page = 'lite' if mode == 'htmlzip' else 'html'
    url = "https://duckduckgo.com/{}?q={}".format(page, quote_plus(payload))
    replies.add(**_download_file(bot, url, mode))
Exemple #12
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)
Exemple #13
0
def lines_top(message: Message, replies: Replies) -> None:
    """Send Color Lines scoreboard.

    Example: `/lines_top`
    """
    limit = 15
    text = '🏆 Color Lines Scoreboard\n\n'
    game = db.get_game_by_addr(message.get_sender_contact().addr)
    if not game:
        games = db.get_games(limit)
    else:
        games = db.get_games()
    if not games:
        text += '(Empty list)'
    for n, g in enumerate(games[:limit], 1):
        text += '#{} {} {}\n'.format(n, db.get_nick(g['addr']), g['score'])
    if game:
        player_pos = games.index(game)
        if player_pos >= limit:
            text += '\n'
            if player_pos > limit:
                pgame = games[player_pos - 1]
                text += '#{} {} {}\n'.format(player_pos,
                                             db.get_nick(pgame['addr']),
                                             pgame['score'])
            text += '#{} {} {}\n'.format(player_pos + 1,
                                         db.get_nick(game['addr']),
                                         game['score'])
            if player_pos < len(games) - 1:
                ngame = games[player_pos + 1]
                text += '#{} {} {}\n'.format(player_pos + 2,
                                             db.get_nick(ngame['addr']),
                                             ngame['score'])
    replies.add(text=text)
def login(bot: DeltaBot, payload: str, message: Message, replies: Replies) -> None:
    sender = message.get_sender_contact()
    with session_scope() as session:
        acc = session.query(Account).filter_by(addr=sender.addr).first()  # noqa
        if acc:
            replies.add(text="❌ You are already logged in.")
            return

    args = payload.split(maxsplit=2)
    if len(args) == 3:
        client = wf.client(host=args[0], user=args[1], password=args[2])
    else:
        client = wf.client(host=args[0], token=args[1])

    acc = Account(addr=sender.addr, host=client.host, token=client.token)
    for blog in client.get_collections():
        group = bot.create_group(f"📝 {blog['title'] or blog['alias']}", [sender])
        acc.blogs.append(Blog(chat_id=group.id, alias=blog["alias"]))
        replies.add(
            text="All messages sent here will be published to blog:\n"
            f"Alias: {blog['alias']}\nDescription: {blog['description']}",
            chat=group,
        )
    with session_scope() as session:
        session.add(acc)  # noqa
    replies.add(text="✔️Logged in")
def quote(bot: DeltaBot, payload: str, message: Message,
          replies: Replies) -> None:
    """Get Wikiquote quotes.

    Search in Wikiquote or get the quote of the day if no text is given.
    Example: `/quote Richard Stallman`
    """
    locale = _get_locale(bot, message.get_sender_contact().addr)
    if locale in wq.supported_languages():
        lang = locale
    else:
        lang = None
    if payload:
        authors = wq.search(payload, lang=lang)
        if authors:
            if payload.lower() == authors[0].lower():
                author = authors[0]
            else:
                author = choice(authors)
            text = f'"{choice(wq.quotes(author, max_quotes=200, lang=lang))}"\n\n― {author}'
        else:
            text = f"No quote found for: {payload}"
    else:
        _quote, author = wq.quote_of_the_day(lang=lang)
        text = f'"{_quote}"\n\n― {author}'

    replies.add(text=text)
Exemple #16
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']))
Exemple #17
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')
Exemple #18
0
def filter_messages(bot: DeltaBot, message: Message, replies: Replies) -> None:
    """Detect messages like +1 or -1 to increase/decrease score.
    """
    if not message.quote:
        return
    score = _parse(message.text)
    if not score:
        return
    sender = message.get_sender_contact().addr
    is_admin = bot.is_admin(sender)
    if score < 0 and not is_admin:
        return
    if not is_admin and db.get_score(sender) - score < 0:
        replies.add(text="❌ You can't give what you don't have...",
                    quote=message)
        return
    receiver = message.quote.get_sender_contact().addr
    if sender == receiver:
        return

    sender_score = _add_score(sender, -score)
    receiver_score = _add_score(receiver, score)
    if is_admin:
        text = '{0}: {1}{4}'
    else:
        text = '{0}: {1}{4}\n{2}: {3}{4}'
    text = text.format(
        bot.get_contact(receiver).name, receiver_score,
        bot.get_contact(sender).name, sender_score,
        _getdefault(bot, 'score_badge'))
    replies.add(text=text, quote=message)
Exemple #19
0
def poll_list(message: Message, replies: Replies) -> None:
    """Show group poll list or your public polls if sent in private.
    """
    if message.chat.is_group():
        polls = db.get_gpolls_by_gid(message.chat.id)
        if polls:
            text = ''
            for poll in polls:
                if len(poll['question']) > 100:
                    q = poll['question'][:100] + '...'
                else:
                    q = poll['question']
                text += '📊 /poll_get_{}_{} {}\n\n'.format(
                    poll['gid'], poll['id'], q)
            replies.add(text=text)
        else:
            replies.add(text='Empty list')
    else:
        polls = db.get_polls_by_addr(message.get_sender_contact().addr)
        if polls:
            text = ''
            for poll in polls:
                if len(poll['question']) > 100:
                    q = poll['question'][:100] + '...'
                else:
                    q = poll['question']
                text += '📊 /poll_get_{} {}\n\n'.format(poll['id'], q)
            replies.add(text=text)
        else:
            replies.add(text='Empty list')
Exemple #20
0
def poll_new(bot: DeltaBot, payload: str, message: Message,
             replies: Replies) -> None:
    """Create a new public poll.

    Example:
    /poll_new Do you like polls?
    yes
    no
    maybe
    """
    lines = []
    for ln in payload.split("\n"):
        ln = ln.strip()
        if ln:
            lines.append(ln)

    if len(lines) < 3:
        replies.add(text="❌ Invalid poll, at least two options needed")
        return

    question = lines.pop(0)

    poll = Poll(addr=message.get_sender_contact().addr, question=question)
    for i, opt in enumerate(lines, 1):
        poll.options.append(Option(id=i, text=opt))
    with session_scope() as session:
        session.add(poll)
        session.flush()
        text, html = _format_poll(bot, poll)
    replies.add(text=text, html=html)
Exemple #21
0
def wttr(bot: DeltaBot, payload: str, message: Message,
         replies: Replies) -> None:
    """Search weather info from wttr.in"""
    lang = _get_locale(bot, message.get_sender_contact().addr)
    url = 'https://wttr.in/{}_Fnp_lang={}.png'.format(quote(payload), lang)
    reply = _download_file(bot, url)
    reply.pop('text')
    replies.add(**reply)
Exemple #22
0
def group_topic(bot: DeltaBot, args: list, message: Message,
                replies: Replies) -> None:
    """Show or change group/channel topic.
    """
    if not message.chat.is_group():
        replies.add(text='❌ This is not a group')
        return

    if args:
        new_topic = ' '.join(args)
        max_size = int(_getdefault(bot, 'max_topic_size'))
        if len(new_topic) > max_size:
            new_topic = new_topic[:max_size] + '...'

        text = '** {} changed topic to:\n{}'

        ch = db.get_channel(message.chat.id)
        if ch and ch['admin'] == message.chat.id:
            name = _get_name(message.get_sender_contact())
            text = text.format(name, new_topic)
            db.set_channel_topic(ch['id'], new_topic)
            for chat in _get_cchats(bot, ch['id']):
                replies.add(text=text, chat=chat)
            replies.add(text=text)
            return
        if ch:
            replies.add(text='❌ Only channel operators can do that.')
            return

        addr = message.get_sender_contact().addr
        g = db.get_group(message.chat.id)
        if not g:
            _add_group(bot, message.chat.id, as_admin=bot.is_admin(addr))
            g = db.get_group(message.chat.id)
            assert g is not None
        db.upsert_group(g['id'], new_topic)
        replies.add(text=text.format(addr, new_topic))
        return

    g = db.get_channel(message.chat.id) or 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
    replies.add(text=g['topic'] or '-', quote=message)
Exemple #23
0
def web(bot: DeltaBot, payload: str, message: Message,
        replies: Replies) -> None:
    """Download a webpage or file."""
    mode = _get_mode(bot, message.get_sender_contact().addr)
    try:
        replies.add(**_download_file(bot, payload, mode))
    except FileTooBig as err:
        replies.add(text=str(err))
Exemple #24
0
def cmd_read(bot: DeltaBot, payload: str, message: Message,
             replies: Replies) -> None:
    """Download a webpage and try to improve its readability."""
    mode = _get_mode(bot, message.get_sender_contact().addr)
    try:
        replies.add(**_download_file(bot, payload, mode, True))
    except FileTooBig as err:
        replies.add(text=str(err))
Exemple #25
0
def friends_leave(message: Message, replies: Replies) -> None:
    """Remove you from the list.
    """
    addr = message.get_sender_contact().addr
    if db.get_bio(addr) is None:
        replies.add(text='You are not in the list yet')
    else:
        db.remove_user(addr)
        replies.add(text='You were removed from the list')
Exemple #26
0
def poll_settings(args: str, message: Message, replies: Replies) -> None:
    """Get poll's advanced settings."""
    if args:
        try:
            with session_scope() as session:
                poll = (session.query(Poll).filter_by(
                    id=int(args[0]),
                    addr=message.get_sender_contact().addr).one())
                text = "📊 /poll_get_{0}\n{1}\n\n🛑 /poll_end_{0}".format(
                    poll.id, poll.question)
            replies.add(text=text, chat=message.get_sender_chat())
        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())
Exemple #27
0
def me(payload: str, message: Message, replies: Replies) -> None:
    """Send a message to IRC using the /me IRC command.
    """
    chan = db.get_channel_by_gid(message.chat.id)
    if not chan:
        return

    addr = message.get_sender_contact().addr
    text = ' '.join(payload.split('\n'))
    irc_bridge.preactor.send_action(addr, chan, text)
Exemple #28
0
def corpse_leave(bot: DeltaBot, message: Message, replies: Replies) -> None:
    """Leave Exquisite Corpse game in current group.

    Example: `/corpse_leave`
    """
    p = db.get_player_by_addr(message.get_sender_contact().addr)
    if p:
        _remove_from_game(bot, p, db.get_game_by_gid(p['game']))
    else:
        replies.add(text='❌ You are not playing Exquisite Corpse.')
Exemple #29
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')
Exemple #30
0
def poll_new(bot: DeltaBot, payload: str, message: Message,
             replies: Replies) -> None:
    """Create a new poll in the group it is sent, or a public poll if sent in private.

    Example:
    /poll_new Do you like polls?
    yes
    no
    maybe
    """
    lns = payload.split('\n')
    if len(lns) < 3:
        replies.add(text='Invalid poll, at least two options needed')
        return

    lines = []
    for ln in lns:
        ln = ln.strip()
        if ln:
            lines.append(ln)

    question = lines.pop(0)
    if len(question) > 255:
        replies.add(text='Question can have up to 255 characters')
        return
    for opt in lines:
        if len(opt) > 150:
            replies.add(text='Up to 150 characters per option are allowed')
            return

    if message.chat.is_group():
        gid = message.chat.id
        poll = db.get_gpoll_by_question(gid, question)
        if poll:
            replies.add(text='Group already has a poll with that name')
            return
        db.add_gpoll(gid, question)
        poll = db.get_gpoll_by_question(gid, question)
        assert poll is not None
        for i, opt in enumerate(lines):
            db.add_goption(i, poll['id'], opt)
        replies.add(text=format_gpoll(poll))
    else:
        addr = message.get_sender_contact().addr
        poll = db.get_poll_by_question(addr, question)
        if poll:
            replies.add(text='You already have a poll with that name')
            return
        db.add_poll(addr, question, time.time())
        poll = db.get_poll_by_question(addr, question)
        assert poll is not None
        for i, opt in enumerate(lines):
            db.add_option(i, poll['id'], opt)
        replies.add(text=_format_poll(bot, poll))