Beispiel #1
0
def check_exist_work(dates: list, slackid: str, action: sc.Actions):
    """
    指定された日付とアクションに対応するシフトを返す

    Args:
        dates (list): シフトを探す日付のリスト
        slackid (str): 検索対象のユーザーのslackid
        action (ShiftController.Actions): 呼び出し元の利用目的

    Returns:
        list: 見つかったシフトのリスト
    """
    work_found = []

    if action is sc.Actions.REQUEST:
        for date in dates:
            work_found.append(
                sc.get_shift(date=date, slackid=slackid, only_active=True))
    elif action is sc.Actions.CONTRACT:
        for date in dates:
            work_found.append(sc.get_shift(date=date, only_requested=True))

    if action is not sc.Actions.SHOWSHIFT and len(work_found) == 0:
        raise ShiftNotFoundError()

    return work_found
Beispiel #2
0
def request_shift(target: dict, slackid: str) -> dict:
    if not target:
        return error_message
    pprint(target)
    target_work = sc.get_shift(eventid=target["eventid"])
    start_dt = target_work.start.replace(
        hour=int(target["start"].split(":")[0]),
        minute=int(target["start"].split(":")[1]),
    )
    end_dt = target_work.end.replace(
        hour=int(target["end"].split(":")[0]), minute=int(target["end"].split(":")[1])
    )
    sc.request(target["eventid"], start_dt, end_dt)
    del start_dt, end_dt
    sc.post_message(
        sc.make_notice_message(
            slackid,
            sc.Actions.REQUEST,
            sc.get_shift(eventid=target["eventid"]),
            target["start"],
            target["end"],
            target["comment"],
        )
    )
    sc.record_use(slackid, sc.UseWay.BUTTONS, sc.Actions.REQUEST)
    return complate_request
Beispiel #3
0
def cui_img(args: list, slackid: str):
    """
    /d img コマンドの中身

    :param list atgs : ユーザーから与えられた引数
    :param dict : 投稿する文章を含んだdict
    """

    index = 1
    shift = None
    date = today = dt.datetime.now().astimezone(sc.timezone)

    # 引数の1つ目(eventid or date)を検証
    try:
        date = can_parse_date(args[index], today)
    except ValueError:
        if args[index] in ("-w", "-W"):
            pass
        else:
            return make_msg(IMG_HELPMSG)
    except IndexError:
        pass
    else:
        index += 1

    # 日付をもとに画像を作る
    try:
        if args[index] in ("-w", "-W"):
            shift = sc.get_week_shift(
                base_date=date, grouping_by_week=True, fill_blank=True
            )
        else:
            shift = sc.get_shift(date=date, fill_blank=True)
    except IndexError:
        shift = sc.get_shift(date=date, fill_blank=True)

    uploaded_file = sc.generate_shiftimg_url(shift=shift)
    print("ok,upload success.")

    sc.record_use(slackid, sc.UseWay.COMM, sc.Actions.SHOWSHIFT)

    show_shift = {
        "response_type": "ephemeral",
        "blocks": [
            {
                "type": "image",
                "title": {
                    "type": "plain_text",
                    "text": uploaded_file["filename"],
                    "emoji": True,
                },
                "image_url": uploaded_file["url"],
                "alt_text": "Example Image",
            }
        ],
    }
    return show_shift
Beispiel #4
0
def contract_shift(target: dict, slackid: str) -> dict:
    if not target:
        return error_message

    original_work = sc.get_shift(eventid=target["eventid"])
    start_dt = original_work.start.replace(
        hour=int(target["start"].split(":")[0]),
        minute=int(target["start"].split(":")[1]),
    )
    end_dt = original_work.end.replace(
        hour=int(target["end"].split(":")[0]), minute=int(target["end"].split(":")[1])
    )
    sc.contract(target["eventid"], slackid, start_dt, end_dt)
    sc.post_message(
        sc.make_notice_message(
            slackid,
            sc.Actions.CONTRACT,
            original_work,
            target["start"],
            target["end"],
            target["comment"],
        )
    )
    sc.record_use(slackid, sc.UseWay.BUTTONS, sc.Actions.CONTRACT)
    return complate_request
Beispiel #5
0
def get_shift_image(slackid, value):
    """
    シフト画像を生成,アップロードして画像を表示するメッセージを返す

    :param str slackid : 呼び出したユーザーのslackid
    """
    is_day = False
    date = dt.datetime.now().astimezone(sc.timezone)
    value_dict = {"date": None, "is_day": None}

    print(value)
    if "," in value.get("action_id"):
        value_dict = csv_to_dict(value.get("action_id"))

    if value.get("block_id") == "show_shift" and value.get("type") == "datepicker":
        date = dt.datetime.strptime(value.get("selected_date"), "%Y-%m-%d")
        is_day = literal_eval(value_dict.get("is_day"))
    elif value.get("block_id") == "switch_type":
        date = dt.datetime.strptime(value_dict.get("date"), "%Y-%m-%d")
        is_day = literal_eval(value.get("value"))
        print("ok, type is button")

    return_block = copy.deepcopy(show_shift)
    if is_day:
        shift = sc.get_shift(date=date, fill_blank=True)
    else:
        shift = sc.get_week_shift(
            base_date=date, grouping_by_week=True, fill_blank=True
        )
    uploaded_file = sc.generate_shiftimg_url(shift=shift)
    print("ok,upload success.")
    return_block["blocks"][0]["image_url"] = "{}".format(uploaded_file["url"])
    return_block["blocks"][0]["title"]["text"] = "{}".format(uploaded_file["filename"])
    return_block["blocks"][2]["accessory"]["initial_date"] = date.strftime("%Y-%m-%d")
    return_block["blocks"][2]["accessory"]["action_id"] = ",".join(
        ["is_day", str(is_day), "date", date.strftime("%Y-%m-%d")]
    )
    return_block["blocks"][3]["elements"][0]["action_id"] = ",".join(
        ["is_day", str(is_day), "date", date.strftime("%Y-%m-%d")]
    )
    return_block["blocks"][3]["elements"][0]["value"] = str(not is_day)
    sc.record_use(slackid, sc.UseWay.BUTTONS, sc.Actions.SHOWSHIFT)
    pprint(return_block)
    return return_block
Beispiel #6
0
def make_application_dialog(eventid: str, is_request: bool):
    """
    代行を依頼/請負申請のフォームをつくる

    :param str eventid : 代行依頼を出すシフトのeventid
    """
    return_block = copy.deepcopy(request_dialog if is_request else contract_dialog)
    target = sc.get_shift(eventid=eventid)
    date = target.start.strftime("%m/%d")
    start = target.start.strftime("%H:%M")
    end = target.end.strftime("%H:%M")
    return_block["dialog"]["state"] = (
        "eventid," + eventid + ",start," + start + ",end," + end + ",date," + date
    )
    return_block["dialog"]["elements"][0]["value"] = start
    return_block["dialog"]["elements"][1]["value"] = end
    return_block["dialog"]["elements"][0]["label"] = "開始時間 - {}~".format(start)
    return_block["dialog"]["elements"][1]["label"] = "終了時間 - ~{}".format(end)
    return return_block
Beispiel #7
0
def make_shift_list(slack_id, request: bool, date: str = None) -> dict:
    """
    シフトのリスト一覧を埋め込んだメッセージを返す

    :param      str  slack_id    : 対象の人のslackId
    :param      bool request     : 依頼か請負かを示す。True = 依頼
    :param      str  date        : 基準の日付。"%Y-%m-%d"書式。
    :return     dict
    """

    # slackのdate selectorの回答は"%Y-%m-%d"の文字列なので、dt.datetimeにconvert
    date = (
        dt.datetime.strptime(date, "%Y-%m-%d")
        if date is not None
        else dt.datetime.now().astimezone(sc.timezone)
    )
    # テンプレートをコピーして文言準備
    # 依頼か請負かでの文言変更
    made_block = copy.deepcopy(select_nearly)
    made_block["blocks"][0] = {
        "type": "section",
        "block_id": "select_shift",
        "text": {
            "type": "mrkdwn",
            "text": ("代行依頼を出すシフトを選んでください" if request else "代行依頼を受けるシフトを選んでください"),
        }
        if request
        else {"type": "mrkdwn", "text": "代行依頼を受けるシフトを選んでください"},
        "accessory": {
            "type": "static_select",
            "action_id": str(request),
            "placeholder": {
                "type": "plain_text",
                "text": "この日のあなたのシフト" if request else "この日の代行依頼",
                "emoji": True,
            },
            "options": [],
        },
    }

    # いずれかの状態のシフト一覧を取得
    shift_list = []
    if request:
        shift_list = sc.get_shift(date=date, slackid=slack_id, only_active=True)
    else:
        shift_list = sc.get_shift(date=date, only_requested=True)

    # シフト一覧部分のオブジェクトをつくる
    for work in shift_list:
        # 依頼済みリストのときは名前を表示するため名前を取得
        name = work.staff_name
        date = work.start.strftime("%m/%d")
        weekday = Shift.WORKDAYS_JP[work.start.weekday()]
        starttime = work.start.strftime("%H:%M")
        endtime = work.end.strftime("%H:%M")
        shift_block = {
            "text": {
                "type": "plain_text",
                "text": "{date}({weekday}) {name}{start}~{end}".format(
                    name="" if request else name,
                    date=date,
                    weekday=weekday,
                    start=starttime,
                    end=endtime,
                ),
                "emoji": True,
            },
            "value": work.eventid,
        }
        print(made_block["blocks"][0]["accessory"])
        made_block["blocks"][0]["accessory"]["options"].append(shift_block)

    # リストにするシフトがなかったときはない旨を書く
    if not made_block["blocks"][0]["accessory"]["options"]:
        made_block["blocks"][0] = {
            "type": "section",
            "text": {
                "type": "mrkdwn",
                "text": ("この日にはあなたのシフトはないようです" if request else "この日には代行依頼はないようです"),
            },
        }

    # このリストが依頼か代行かをflagでaction_idに記録
    made_block["blocks"][1]["accessory"]["action_id"] = str(request)

    return made_block
Beispiel #8
0
def do_action(
    slackid: str,
    action: sc.Actions,
    date: dt.datetime,
    work: Work,
    time_range: dict,
    text: str,
    ts: str,
    receive_channel: str,
):
    """

    情報をもとにactionに対応した処理を行う


    Args:
        slackid (str): ユーザーのslackid
        action (ShiftController.Actions): メッセージから判定した処理
        date (datetime.datetime): メッセージから判定した日付
        work (Work): メッセージから抽出したシフト
        time_range (dict): メッセージから抽出した時間範囲 {"start": %H:%M, "end": %H:%M}
        text (str): メッセージの本文
        ts (str): メッセージのタイムスタンプ
        receive_channel (str): メッセージを受け取ったチャンネルのchannel id

    """
    if action is sc.Actions.SHOWSHIFT:
        image = sc.generate_shiftimg_url(
            shift=sc.get_shift(date=date, fill_blank=True))
        print(image, file=sys.stderr)
        sc.post_message(
            "{}のシフトです".format(date.strftime("%Y/%m/%d")),
            attachments=[{
                "image_url": image["url"],
                "fields": []
            }],
            channel=receive_channel,
            ts=ts,
        )

    else:
        if not time_range:
            time_range = {"start": work.start, "end": work.end}
        if action is sc.Actions.REQUEST:
            sc.request(
                work.eventid,
                time_range["start"].strftime("%H:%M"),
                time_range["end"].strftime("%H:%M"),
            )
        elif action is sc.Actions.CONTRACT:
            sc.contract(
                work.eventid,
                slackid,
                time_range["start"].strftime("%H:%M"),
                time_range["end"].strftime("%H:%M"),
            )

            notice_message = sc.make_notice_message(slackid, action, work,
                                                    time_range["start"],
                                                    time_range["end"], text)
            sc.post_message(notice_message)

        sc.record_use(slackid, sc.UseWay.CHAT, action)
Beispiel #9
0
def cui_con(args: list, slackid: str):
    """
    /d con コマンドの中身

    :param list atgs : ユーザーから与えられた引数
    :param dict : 投稿する文章を含んだdict
    """
    index = 1
    date = today = dt.datetime.now().astimezone(sc.timezone)
    target = None
    target_time = None
    comment = ""

    # 1つ目の引数を精査する
    try:
        date = can_parse_date(args[index], today)
        target = sc.get_shift(date=date, only_requested=True)
        if len(target) == 0:
            return make_msg("> Error : 対象になるシフトがありません\n" + CON_HELPMSG)
    except ValueError:
        try:
            target = sc.get_shift(eventid=args[index])
        except (ValueError, KeyError):
            return make_msg("> Error : targetが無効です。\n" + CON_HELPMSG)
    except IndexError:
        return make_msg(CON_HELPMSG)

    # 2番めの引数をチェック
    index += 1
    try:
        # 時間指定オプションを確認
        if args[index] == "-r":
            index += 1
            try:
                # 引数の文字列が妥当かを判断
                target_time, _ = check_times(target, args[index])
            except TimeOverhangError:
                # 時刻の範囲がはみ出している
                return make_msg("> Error : 時刻の範囲が不適切です\n" + CON_HELPMSG)
            except InvalidTimeFormatError:
                # 与えられた文字列がHH:MM~HH:MMではない
                return make_msg("> Error : 時刻指定の文字列が不適切です\n" + CON_HELPMSG)
            except IndexError:
                return make_msg("> Error : rangeが不正です\n" + CON_HELPMSG)

            # 時間指定を受け取ったので次の引数を参照する
            index += 1
    except IndexError:
        # この位置でIndexErrorならrange指定がないだけなので問題なし
        pass

    try:
        # 2番めor4番目とそれ以降の引数をコメントとしてまとめる
        comment = " ".join(args[index:])
    except IndexError:
        # コメントは必須ではないので何もしない
        pass

        # 代行の開始時間と終了時間を整理
    start = target.start if target_time is None else target_time[0]
    end = target.end if target_time is None else target_time[1]

    sc.contract(slackid=slackid, eventid=target.eventid, start=start, end=end)
    sc.post_message(
        sc.make_notice_message(
            slackid, sc.Actions.CONTRACT, target, start, end, comment
        )
    )
    sc.record_use(slackid, sc.UseWay.COMM, sc.Actions.CONTRACT)

    return make_msg(
        "> 代行を請け負いました。\n> date : {} \n> time: {}~{}\n> comment: {}".format(
            target.start.strftime("%Y-%m-%d"), start, end, comment
        )
    )
Beispiel #10
0
def cui_req(args: list, slackid: str):
    """
    /d req コマンドの中身

    :param list atgs : ユーザーから与えられた引数
    :param dict : 投稿する文章を含んだdict
    """
    index = 1
    date = today = dt.datetime.now().astimezone(sc.timezone)
    target = None
    target_time = None
    comment = ""

    # 1つ目の引数を精査する
    try:
        date = can_parse_date(args[index], today)
        target = sc.get_shift(date=date, slackid=slackid, only_active=True)
        if len(target) == 0:
            return make_msg("> Error : この日にはシフトがありません\n" + REQ_HELPMSG)
    except ValueError:
        try:
            target = sc.get_shift(eventid=args[index])
        except ValueError:
            return make_msg("> Error : targetが無効です。\n" + REQ_HELPMSG)
    except IndexError:
        return make_msg(REQ_HELPMSG)

    # 2番めの引数をチェック
    index += 1
    try:
        # 時間指定オプションを確認
        if args[index] == "-r":
            index += 1
            try:
                # 引数の文字列が妥当かを判断
                target_time, devide = check_times(target, args[index])
            except TimeOverhangError:
                # 時刻の範囲がはみ出している
                return make_msg("> Error : 時刻の範囲が不適切です\n" + CON_HELPMSG)
            except InvalidTimeFormatError:
                # 与えられた文字列がHH:MM~HH:MMではない
                return make_msg("> Error : 時刻指定の文字列が不適切です\n" + CON_HELPMSG)
            except IndexError:
                return make_msg("> Error : rangeが不正です\n" + CON_HELPMSG)

            # 時間指定を受け取ったので次の引数を参照する
            index += 1

        # 2番めor4番目の引数をcheck
        if args[index]:
            comment = " ".join(args[index:])
    except IndexError:
        return make_msg("> Error : commentがありません\n" + REQ_HELPMSG)

        # 代行の開始時間と終了時間を整理
    start = target.start if target_time is None else target_time[0]
    end = target.end if target_time is None else target_time[1]

    sc.request(eventid=target.eventid, start=start, end=end)
    sc.post_message(
        sc.make_notice_message(slackid, sc.Actions.REQUEST, target, start, end, comment)
    )
    sc.record_use(slackid, sc.UseWay.COMM, sc.Actions.REQUEST)

    return make_msg(
        "> 代行を依頼しました。\n> date : {} \n> time: {}~{}\n> comment: {}".format(
            target.start.strftime("%Y-%m-%d"), start, end, comment
        )
    )