Пример #1
0
def order_coffee(slackclient, user, channel, match):
  print(match.groupdict())
  runid = match.groupdict().get('runid', None)
  run = None
  if runid and runid.isdigit():
    run = Run.query.filter_by(id=int(runid)).first()
  if not run:
    # Pick a run
    runs = Run.query.filter_by(is_open=True).order_by('time').all()
    if len(runs) > 1:
      slackclient.rtm_send_message(channel.id, 'More than one open run, please specify by adding run=<id> on the end.')
      list_runs(slackclient, user, channel, None)
      return
    if len(runs) == 0:
      slackclient.rtm_send_message(channel.id, 'No open runs')
      return
    run = runs[0]

  # Create the coffee
  coffee = Coffee(match.group(1))

  # Find the user that requested this
  dbuser = utils.get_or_create_user(user.id, TEAM_ID, user.name)
  print(dbuser)

  # Put it all together
  coffee.person = dbuser.id
  coffee.runid = run.id
  db.session.add(coffee)
  db.session.commit()
  print(coffee)

  runuser = User.query.filter_by(id=run.person).first()

  slackclient.rtm_send_message(channel.id, 'That\'s a {} for {} (added to <@{}>\'s run.)'.format(coffee.pretty_print(), mention(user), runuser.slack_user_id))
Пример #2
0
def warn_process(message: Message, bot: telebot) -> Message:
    """
    Warning user. User delete from chat member if get three warnings.
    Automatically one warning lives one week.
    :param message: Telegram API Message
    :param bot: Telebot instance
    :return response message from Telegram API server
    """
    msg = message.text.split()
    if len(msg) > 1:
        reason = msg[1:]
        user, created = get_or_create_user(message.reply_to_message)
        if user:
            warns_count = Warns.select().filter(user=user).count()
            warning_user = prepare_user_data(user)
            reason = ' '.join([i for i in reason])
            till_date = datetime.datetime.now() + datetime.timedelta(weeks=1)
            if warns_count == 2:
                warns_count += 1
                Warns.create(user=user,
                             warn_number=warns_count,
                             reason=reason,
                             datetime_add=datetime.datetime.now(),
                             till_date=till_date)
                msg = f'*{message.from_user.username} предупредил пользователя {warning_user}\nПричина:*\n`{reason}`\n' \
                      f'Предупреждение `{warns_count}/3`\n' \
                      f'`Пользователь заблокирован`'
                bot.kick_chat_member(message.chat.id,
                                     message.reply_to_message.from_user.id)
                return bot.reply_to(message.reply_to_message,
                                    text=msg,
                                    parse_mode='markdown')
            elif warns_count < 2:
                warns_count += 1
                print('here1', warns_count)
                Warns.create(user=user,
                             warn_number=warns_count,
                             reason=reason,
                             datetime_add=datetime.datetime.now(),
                             till_date=till_date)
                msg = f'*{message.from_user.username} предупредил пользователя {warning_user}\nПричина:*\n`{reason}`\n' \
                      f'Предупреждение `{warns_count}/3`\nДо {till_date.strftime("%Y-%m-%d %H:%M:%S")}\n' \
                      f'`После третьего предупреждения будет применена автоматическая блокировка`'
                return bot.reply_to(message.reply_to_message,
                                    text=msg,
                                    parse_mode='markdown')
            else:
                msg = '*Пользователь уже заблокирован*'
                bot.reply_to(message.reply_to_message,
                             text=msg,
                             parse_mode='markdown')
Пример #3
0
def ban_process(message: Message, bot: telebot) -> Message:
    """
    get_user_or_create check user in db and return user
    Creating User instance. Kicking user from chat and send group message about it.
    NOTE! mute_till.strftime('%s') not working on windows platform! Using timestamp() * 1000
    :param message: Current message data with user sender, chat_id and so on
    :param bot: Telebot instance
    :return Message: Telegram result api message
    """
    msg = message.text.split()
    if len(msg) > 1:
        dt, text = to_unix_time(message)
        user, created = get_or_create_user(message.reply_to_message)
        BlackList.create(user=user,
                         datetime_add=datetime.datetime.today(),
                         till_date=dt)
        banned_user = prepare_user_data(user)
        till_date = dt.strftime('%Y-%m-%d %H:%M:%S')
        if text:
            msg = f'*@{user.username} заблокировал пользователя {banned_user} До:{till_date}\nПричина:*\n`{text}`'
        else:
            msg = f'*@{user.username} заблокировал пользователя {banned_user} До: {till_date}*'
        if created:
            if msg[1] == 'kick':
                # kick user from chat aka ban forever
                response = bot.kick_chat_member(
                    message.chat.id, message.reply_to_message.from_user.id)
            else:
                bot.send_photo(
                    chat_id=message.chat.id,
                    photo=
                    'AgACAgIAAxkDAAIBt15iuBjifOydpm759urePec6VHJgAALirDEbV48YS6MzQ4NoFW4IRSbBDgAEAQADAgADbQADhKoDAAEYBA',
                    caption=msg,
                    reply_to_message_id=message.reply_to_message,
                    parse_mode='markdown',
                )
                # ban user for specific time
                response = bot.restrict_chat_member(
                    message.chat.id,
                    message.reply_to_message.from_user.id,
                    until_date=dt.timestamp() * 1000,
                    can_send_media_messages=False,
                    can_add_web_page_previews=False,
                    can_send_other_messages=False,
                    can_send_messages=False)
        else:
            response = '`Пользователь уже забанен`'
            bot.reply_to(message.reply_to_message,
                         text=response,
                         parse_mode='markdown')
        return response
Пример #4
0
    def close_run(self, slackclient, user, channel, match):
        """Close a run so that no more coffees may be added.

        Args:
            slackclient: the slackclient.SlackClient object for the current
                connection to Slack.
            user: the slackclient.User object for the user who send the
                message to us.
            channel: the slackclient.Channel object for the channel the
                message was received on.
            match: the object returned by re.match (an _sre.SRE_Match object).
        """
        logger = logging.getLogger('close_run')
        logger.info('Matches: %s', pprint.pformat(match.groupdict()))

        # Find the user that requested this
        person = utils.get_or_create_user(user.id, self.TEAM_ID, user.name)
        logger.info('User: %s', dbuser)

        runid = match.groupdict().get('runid', None)
        run = None
        if runid and runid.isdigit():
            run = Run.query.filter_by(id=int(runid)).first()
        else:
            runs = Run.query.filter(is_open=True) \
                .filter(Run.person == person.id) \
                .order_by('time').all()
            if len(runs) > 1:
                channel.send_message(
                        'More than one open run, please specify by adding run=<id> on the end.')
                self.list_runs(slackclient, user, channel, match=None)
                return
            if len(runs) == 0:
                channel.send_message('No open runs')
                return
            run = runs[0]

        # Change run to closed
        run.is_open = False
        db.session.add(run)
        db.session.commit()

        # Create event
        self.write_to_events("updated", "run", run.id, run.person)

        # Notify Slack
        try:
            events.run_closed(run.id)
        except Exception as e:
            logging.exception('Error while trying to send notifications.')
Пример #5
0
    def create_run(self, slackclient, user, channel, match):
        """Create an open run

        Args:
            slackclient: the slackclient.SlackClient object for the current
                connection to Slack.
            user: the slackclient.User object for the user who send the
                message to us.
            channel: the slackclient.Channel object for the channel the
                message was received on.
            match: the object returned by re.match (an _sre.SRE_Match object).
        """
        logger = logging.getLogger('create_run')
        logger.info('Matches: %s', pprint.pformat(match.groupdict()))
        cafeid = match.group('cafeid')
        if cafeid and cafeid.isdigit():
            cafe = Cafe.query.filter_by(id=int(cafeid)).first()
        if not cafe:
            channel.send_message('Cafe does not exist. These are the available cafes:')
            self.list_cafes(slackclient, user, channel, match=None)
            return

        pickup = match.groupdict().get('pickup', None)
        timestr = match.groupdict().get('time', None)

        # Get the person creating the run
        person = utils.get_or_create_user(user.id, self.TEAM_ID, user.name)
        logger.info('User: %s', dbuser)

        # Assume valid? Create the run
        run = Run(timestr)
        run.person = person
        run.fetcher = person
        run.cafeid = cafeid
        run.pickup = pickup
        run.modified = sydney_timezone_now()
        run.is_open = True

        db.session.add(run)
        db.session.commit()

        # Create the event
        self.write_to_events("created", "run", run.id, run.person)

        # Notify Slack
        try:
            events.run_created(run.id)
        except Exception as e:
            logging.exception('Error while trying to send notifications.')
Пример #6
0
def get_user_from_slack_token():
    token = session.get('slack_token')[0]
    resp = requests.get('http://slack.com/api/auth.test',
                        params={'token': token})
    if resp.status_code != 200:
        print(resp)
        flash('Error retrieving user info')
        return None

    content = json.loads(resp.content)
    if not content['ok']:
        print(content)
        flash('Error retrieving user info: ' + content['error'])
        return None

    user = utils.get_or_create_user(content['user_id'], content['team_id'],
                                    content['user'])
    return user
Пример #7
0
def sudo_process(message: Message, bot: telebot):
    """
    Add or remove user from sudoers. Bot replying result in private message.
    :param message: Telegram API Message
    :param bot: Telebot instance
    """
    msg = message.text.split()
    if len(msg) > 1:
        user, created = get_or_create_user(message.reply_to_message)
        is_sudo = user.is_sudo
        user = prepare_user_data(user)
        if user or created:
            if 'add' in msg:
                if not is_sudo:
                    User.update(is_sudo=True).where(
                        User.telegram_id ==
                        message.reply_to_message.from_user.id).execute()
                    msg = f'`{user} добавлен в группу sudoers`'
                    bot.send_message(message.from_user.id,
                                     text=msg,
                                     parse_mode='markdown')
                else:
                    msg = f'`{user} уже состоит в группе sudoers`'
                    bot.send_message(message.from_user.id,
                                     text=msg,
                                     parse_mode='markdown')
            elif 'del' in msg:
                if is_sudo:
                    User.update(is_sudo=False).where(
                        User.telegram_id ==
                        message.reply_to_message.from_user.id).execute()
                    msg = f'`{user} удален из группы sudoers`'
                    bot.send_message(message.from_user.id,
                                     text=msg,
                                     parse_mode='markdown')
                else:
                    msg = f'`{user} не состоит в группе sudoers`'
                    bot.send_message(message.from_user.id,
                                     text=msg,
                                     parse_mode='markdown')
        else:
            bot.send_message(message.from_user.id, text='Ошибка операции sudo')
Пример #8
0
def get_user_from_slack_token():
    logger = logging.getLogger('views.get_user_from_slack_token')
    token = session.get('slack_token')[0]
    resp = requests.get('http://slack.com/api/users.identity',
                        params={'token': token})
    if resp.status_code != 200:
        logger.info('Failed to get user from slack: %s', resp)
        flash('Error retrieving user info')
        return None

    content = json.loads(resp.content.decode('utf-8'))
    if not content['ok']:
        logger.info('Failed to get user from slack: %s', content)
        flash('Error retrieving user info: ' + content['error'])
        return None

    name = content['user']['name']
    slack_id = content['user']['id']
    slack_team = content['team']['id']
    user = utils.get_or_create_user(slack_id, slack_team, name)
    return user
Пример #9
0
def order_coffee(slackclient, user, channel, match):
    """Handle adding coffee to existing orders.

  Args:
    slackclient: the slackclient.SlackClient object for the current
      connection to Slack.
    user: the slackclient.User object for the user who send the
      message to us.
    channel: the slackclient.Channel object for the channel the
      message was received on.
    match: the object returned by re.match (an _sre.SRE_Match object).
  """
    logger = logging.getLogger('order_coffee')
    logger.info('Matches: %s', pprint.pformat(match.groupdict()))
    runid = match.groupdict().get('runid', None)
    run = None
    if runid and runid.isdigit():
        run = Run.query.filter_by(id=int(runid)).first()
    if not run:
        # Pick a run
        runs = Run.query.filter_by(is_open=True).order_by('time').all()
        if len(runs) > 1:

            def resolve_run_feedback():
                channel.send_message(
                    'More than one open run, please specify by adding run=<id> on the end.'
                )
                list_runs(slackclient, user, channel, match=None)

            return (False, resolve_run_feedback)
        if len(runs) == 0:

            def resolve_closed_feedback():
                channel.send_message('No open runs')

            return (False, resolve_closed_feedback)
        run = runs[0]

    # Create the coffee
    c = coffeespecs.Coffee(match.groupdict().get('order', None))
    validation_errors = list(c.validation_errors())
    if validation_errors:

        def resolve_validation_feedback():
            channel.send_message(
                'That coffee is not valid missing the following specs: {}. Got: {}'
                .format(
                    ', '.join(spec.name for spec in validation_errors),
                    c,
                ))

        return (False, resolve_validation_feedback)
    coffee = Coffee(c, 0, run.id)

    # Find the user that requested this
    dbuser = utils.get_or_create_user(user.id, TEAM_ID, user.name)
    logger.info('User: %s', dbuser)

    # Put it all together
    coffee.person = dbuser.id
    db.session.add(coffee)
    db.session.commit()
    events.coffee_added(run.id, coffee.id)

    # Write the event
    event = Event(coffee.person, "created", "coffee", coffee.id)
    event.time = sydney_timezone_now()
    db.session.add(event)
    db.session.commit()
    logger.info('Parsed coffee: %s', coffee)

    runuser = User.query.filter_by(id=run.person).first()
    if runuser.slack_user_id:
        mention_runner = '<@{}>'.format(runuser.slack_user_id)
    else:
        mention_runner = runuser.name
    channel.send_message('That\'s a {} for {} (added to {}\'s run.)'.format(
        coffee.pretty_print(), mention(user), mention_runner))
    return (True, None)