Exemplo n.º 1
0
def show_thx_to(message, user_name=None):
    """誰にGJしたか表示します

    :param message: slackbot.dispatcher.Message
    :param str user_name:  GJしたユーザー名
    """
    channel_id = message.body['channel']
    if not user_name:
        user_name = get_user_name(message.body['user'])
    s = Session()
    slack_id = get_slack_id(s, user_name)
    if not slack_id:
        message.send('{}はSlackのユーザーとして存在しません'.format(user_name))
        return

    rows = [['GJされたユーザー', 'GJ内容']]
    thx = (s.query(ThxHistory).filter(
        ThxHistory.from_user_id == slack_id).filter(
            ThxHistory.channel_id == channel_id))
    for t in thx:
        rows.append([get_user_name(t.user_id), t.word])
    output = StringIO()
    w = csv.writer(output)
    w.writerows(rows)

    param = {
        'token': settings.API_TOKEN,
        'channels': channel_id,
        'title': '{}がGJした一覧'.format(user_name)
    }
    requests.post(settings.FILE_UPLOAD_URL,
                  params=param,
                  files={'file': output.getvalue()})
Exemplo n.º 2
0
def unalias_name(message, user_name, alias_name=None):
    """ユーザーに紐づくエイリアス名を削除する

    :param message: slackbotの各種パラメータを保持したclass
    :param str user_name: 削除するエイリアス名を持つSlackユーザー
    :param str alias_name: 削除するエイリアス名
       alias_nameがNoneの場合、user_nameをalias_nameとして扱う
       上記の場合user_nameは投稿者となる
    """
    if alias_name:
        # ユーザー名とエイリアス名が指定されているパターン
        slack_id = get_slack_id_by_name(user_name)
    else:
        # 投稿者のエイリアス名を更新するパターン
        alias_name = user_name
        slack_id = message.body['user']
        user_name = get_user_name(slack_id)

    if not slack_id:
        botsend(message, '{}に紐づくSlackのuser_idは存在しません'.format(user_name))
        return

    s = Session()
    alias_user_name = (s.query(UserAliasName).filter(
        UserAliasName.slack_id == slack_id).filter(
            UserAliasName.alias_name == alias_name).one_or_none())

    if alias_user_name:
        s.delete(alias_user_name)
        s.commit()
        botsend(message,
                '{}のエイリアス名から `{}` を削除しました'.format(user_name, alias_name))
    else:
        botsend(message,
                '{}のエイリアス名 `{}` は登録されていません'.format(user_name, alias_name))
Exemplo n.º 3
0
def show_user_alias_name(message, user_name=None):
    """ユーザーのエイリアス名一覧を表示する

    :param message: slackbotの各種パラメータを保持したclass
    :param str user: Slackのユーザー名
    """
    if user_name:
        slack_id = get_slack_id_by_name(user_name)
    else:
        slack_id = message.body['user']
        user_name = get_user_name(slack_id)

    if not slack_id:
        botsend(message, '{}に紐づくSlackのuser_idは存在しません'.format(user_name))
        return

    s = Session()
    alias_names = [
        user.alias_name for user in s.query(UserAliasName).filter(
            UserAliasName.slack_id == slack_id)
    ]

    pt = PrettyTable(['ユーザー名', 'Slack ID', 'エイリアス名'])
    alias_name = ','.join(alias_names)
    pt.add_row([user_name, slack_id, alias_name])
    botsend(message, '```{}```'.format(pt))
Exemplo n.º 4
0
def show_kintai_history(message):
    """直近40日分の勤怠記録を表示します

    :param message: slackbotの各種パラメータを保持したclass
    """
    user_id = message.body['user']
    today = datetime.date.today()
    target_day = today - datetime.timedelta(days=40)

    s = Session()
    qs = (s.query(KintaiHistory).filter(
        KintaiHistory.user_id == user_id).filter(
            KintaiHistory.registered_at >= target_day).order_by(
                KintaiHistory.registered_at.asc()))

    kintai = OrderedDict()
    for q in qs:
        day_of_week = DAY_OF_WEEK[q.registered_at.date().weekday()]
        prefix_day = '{:%Y年%m月%d日}({})'.format(q.registered_at, day_of_week)
        registered_at = '{:%I:%M:%S}'.format(q.registered_at)
        kind = '出社' if q.is_workon else '退社'
        kintai.setdefault(prefix_day,
                          []).append('{}  {}'.format(kind, registered_at))

    rows = []
    for prefix, registered_ats in kintai.items():
        sorted_times = ' '.join(sorted(registered_ats))
        rows.append('{} {}'.format(prefix, sorted_times))

    if not rows:
        rows = ['勤怠記録はありません']

    user_name = get_user_name(user_id)
    message.send('{}の勤怠:\n{}'.format(user_name, '\n'.join(rows)))
Exemplo n.º 5
0
def check_user_name(session, user_names):
    """Slackユーザー情報と照ら合わせ結果を辞書で返す

    :param list user_names: Slackで++対象のSlackユーザー名
    :return dict user_dict:
       keyが `matched`: Slackユーザーに紐付いた名前
       keyが `hint_name`: 紐付かなかったが、似た名前が存在する名前
       keyが `not_matched`: Slackユーザーに紐付かなかった名前
    """
    user_dict = {}
    for name in [x for x in user_names.split(' ') if x]:

        # slackのsuggest機能でユーザーを++した場合(例: @wan++)、name引数は
        # `<@{slack_id}>` というstr型で渡ってくるので対応
        if get_user_name(name.lstrip('<@').rstrip('>')):
            slack_id = name.lstrip('<@').rstrip('>')
        else:
            slack_id = get_slack_id(session, name)

        if slack_id:
            # slack_idに紐づくユーザーが存在
            user_dict.setdefault('matched', []).append((slack_id, name))
        else:
            # 一番近いユーザー名を算出
            hint = get_close_matches(name, get_users_info().values())
            if hint:
                user_dict.setdefault('hint_name', []).append(hint[0])
            # 紐づくユーザーが存在しなかった場合
            else:
                user_dict.setdefault('not_matched', []).append(name)
    return user_dict
Exemplo n.º 6
0
def update_kudo(message, names):
    """ 指定された名前に対して ++ する

    OK:
       name++、name ++、name  ++、@name++、name1 name2++

    NG:
       name+ +、name++hoge、 name1,name2++


    :param message: slackbot.dispatcher.Message
    :param name str: ++する対象の名前
    """
    slack_id = message.body['user']
    name_list = []
    for name in [x for x in names.split(' ') if x]:
        # slackのsuggest機能でユーザーを++した場合(例: @wan++)、name引数は
        # `<@{slack_id}>` というstr型で渡ってくるので対応
        if get_user_name(name.lstrip('<@').rstrip('>')):
            name = get_user_name(name.lstrip('<@').rstrip('>'))

        s = Session()
        kudo = (s.query(KudoHistory)
                .filter(KudoHistory.name == name)
                .filter(KudoHistory.from_user_id == slack_id)
                .one_or_none())

        if kudo is None:
            # name ×from_user_id の組み合わせが存在していない -> 新規登録
            s.add(KudoHistory(name=name, from_user_id=slack_id, delta=1))
            s.commit()
        else:
            # name ×from_user_id の組み合わせが存在 -> 更新
            kudo.delta = kudo.delta + 1
            s.commit()

        q = (s.query(
            func.sum(KudoHistory.delta).label('total_count'))
            .filter(KudoHistory.name == name))
        total_count = q.one().total_count
        name_list.append((name, total_count))

    msg = ['({}: 通算 {})'.format(n, tc) for n, tc in name_list]
    botsend(message, '\n'.join(msg))
Exemplo n.º 7
0
def show_today_cleaning_list(message):
    """今日の掃除当番を表示する

    :param message: slackbot.dispatcher.Message
    """
    dow = datetime.datetime.today().weekday()

    s = Session()
    users = [
        get_user_name(c.slack_id)
        for c in s.query(Cleaning).filter(Cleaning.day_of_week == dow)
    ]
    botsend(message, '今日の掃除当番は{}です'.format('、'.join(users)))
Exemplo n.º 8
0
def show_cleaning_list(message):
    """掃除当番の一覧を表示する

    :param message: slackbot.dispatcher.Message
    """
    s = Session()
    dow2users = OrderedDict()
    cleaning = s.query(Cleaning).order_by(Cleaning.day_of_week.asc(),
                                          Cleaning.id.asc())
    for c in cleaning:
        user = get_user_name(c.slack_id)
        dow2users.setdefault(c.day_of_week, []).append(user)

    pt = PrettyTable(['曜日', '掃除当番'])
    pt.align['掃除当番'] = 'l'
    for day_of_week, users in dow2users.items():
        dow = DAY_OF_WEEK[day_of_week]
        str_users = ', '.join(users)
        pt.add_row([dow, str_users])
    botsend(message, '```{}```'.format(pt))
Exemplo n.º 9
0
def show_user_redbull_history(message):
    """RedBullのUserごとの消費履歴を返すコマンド

    :param message: slackbotの各種パラメータを保持したclass
    """
    user_id = message.body['user']
    user_name = get_user_name(user_id)
    s = Session()
    qs = (s.query(RedbullHistory).filter(RedbullHistory.user_id == user_id,
                                         RedbullHistory.delta < 0).order_by(
                                             RedbullHistory.id.asc()))
    tmp = []
    for line in qs:
        tmp.append('[{:%Y年%m月%d日}]  {}本'.format(line.ctime, -line.delta))

    ret = '消費履歴はありません'
    if tmp:
        ret = '\n'.join(tmp)

    message.send('{}の消費したレッドブル:\n{}'.format(user_name, ret))
Exemplo n.º 10
0
def manage_redbull_stock(message, delta):
    """RedBullの本数の増減を行うコマンド

    :param message: slackbotの各種パラメータを保持したclass
    :param str delta: POSTされた増減する本数
        UserからPOSTされるdeltaの値は投入の場合は負数、消費の場合は正数
        DBは投入の場合正数、消費の場合は負数を記録する
    """
    delta = -int(delta)
    user_id = message.body['user']
    user_name = get_user_name(user_id)

    s = Session()
    s.add(RedbullHistory(user_id=user_id, delta=delta))
    s.commit()

    if delta > 0:
        message.send('レッドブルが{}により{}本投入されました'.format(user_name, delta))
    else:
        message.send('レッドブルが{}により{}本消費されました'.format(user_name, -delta))
Exemplo n.º 11
0
def find_thx(s, text):
    """Slackに投稿されたメッセージからthxを見つけて返す

    :param s: sqlalchemy.orm.session.Session
    :param str text: ユーザーが投稿した内容
    :return Dict[str, List[Tuple[str, str]]] word_map_names_dict:
       キーがthx内容、バリューが対象Slackユーザーのリスト
    :return list hint_names: Slackユーザーに似た名前が存在する名前一覧
    :return list not_matched: Slackユーザーとして存在しなかった名前の一覧
    """
    word_map_names_dict = {}
    hint_names = []
    not_matched = []

    thx_matcher = re.compile(
        r'(?P<user_names>.+)[ \t\f\v]*(?<!\+)\+\+[ \t\f\v]+(?P<word>.+)',
        re.MULTILINE)
    for thx in thx_matcher.finditer(text):
        user_names = [x for x in thx.group('user_names').split(' ') if x]
        for name in user_names:
            if get_user_name(name.lstrip('<@').rstrip('>')):
                slack_id = name.lstrip('<@').rstrip('>')
            else:
                slack_id = get_slack_id(s, name)

            if slack_id:
                word_map_names_dict.setdefault(thx.group('word'), []).append(
                    (slack_id, name))
            else:
                # 一番近いユーザー名を算出
                names = [
                    profile['name'] for profile in get_users_info().values()
                ]
                hint = get_close_matches(name, names)
                if hint:
                    hint_names.append(hint[0])
                # 紐づくユーザーが存在しなかった場合
                else:
                    not_matched.append(name)

    return word_map_names_dict, hint_names, not_matched
Exemplo n.º 12
0
def alias_name(message, user_name, alias_name=None):
    """指定したユーザにエイリアス名を紐付ける

    :param message: slackbotの各種パラメータを保持したclass
    :param str user_name: エイリアス名を紐付けるSlackユーザー
    :param str alias_name: Slackユーザーに紐付けるエイリアス名
       alias_nameがNoneの場合、user_nameをalias_nameとして扱う
       上記の場合user_nameは投稿者となる
    """
    if alias_name:
        # ユーザー名とエイリアス名が指定されているパターン
        slack_id = get_slack_id_by_name(user_name)
    else:
        # 投稿者のエイリアス名を更新するパターン
        alias_name = user_name
        slack_id = message.body['user']
        user_name = get_user_name(slack_id)

    user = get_slack_id_by_name(alias_name)
    if user:
        botsend(message, '`{}` はユーザーが存在しているので使用できません'.format(alias_name))
        return

    if not slack_id:
        botsend(message, '{}に紐づくSlackのuser_idは存在しません'.format(user_name))
        return

    s = Session()
    alias_user_name = (s.query(UserAliasName).filter(
        UserAliasName.alias_name == alias_name))
    if s.query(alias_user_name.exists()).scalar():
        botsend(message, 'エイリアス名 `{}` は既に登録されています'.format(alias_name))
        return

    s.add(UserAliasName(slack_id=slack_id, alias_name=alias_name))
    s.commit()
    botsend(message, '{}のエイリアス名に `{}` を追加しました'.format(user_name, alias_name))