From c3e66997ec4db24825704f916ca79e77b0114992 Mon Sep 17 00:00:00 2001 From: Monsteel Date: Wed, 6 Sep 2023 13:06:04 +0900 Subject: [PATCH 01/12] =?UTF-8?q?=EC=98=88=EC=95=BD=EB=8C=80=EA=B8=B0=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SRT/srt.py | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++ SRT/train.py | 5 ++ 2 files changed, 151 insertions(+) diff --git a/SRT/srt.py b/SRT/srt.py index 3330eb3..a8a0f60 100644 --- a/SRT/srt.py +++ b/SRT/srt.py @@ -30,6 +30,7 @@ SRT_TICKETS = f"{SRT_MOBILE}/atc/selectListAtc14016_n.do" SRT_TICKET_INFO = f"{SRT_MOBILE}/ard/selectListArd02017_n.do?" SRT_CANCEL = f"{SRT_MOBILE}/ard/selectListArd02045_n.do" +SRT_STANDBY_OPTION = f"{SRT_MOBILE}/ata/selectListAta01135_n.do" DEFAULT_HEADERS = { "User-Agent": ( @@ -347,6 +348,151 @@ def reserve( # if ticket not found, it's an error raise SRTError("Ticket not found: check reservation status") + def reserve_standby( + self, + train: SRTTrain, + passengers: list[Passenger] | None = None, + special_seat: SeatType = SeatType.GENERAL_FIRST, + mblPhone: str | None = None, + ) -> SRTReservation: + """예약대기 신청 합니다. + + >>> trains = srt.search_train("수서", "부산", "210101", "000000") + >>> srt.reserve_standby(trains[0]) + + Args: + train (:class:`SRTrain`): 예약할 열차 + passengers (list[:class:`Passenger`], optional): 예약 인원 (default: 어른 1명) + special_seat (:class:`SeatType`): 일반실/특실 선택 유형 (default: 일반실 우선) + mblPhone (str, optional): 휴대폰 번호 + + Returns: + :class:`SRTReservation`: 예약 내역 + """ + if not self.is_login: + raise SRTNotLoggedInError() + + if not isinstance(train, SRTTrain): + raise TypeError('"train" parameter must be a SRTTrain instance') + + if train.train_name != "SRT": + raise ValueError( + f'"SRT" expected for a train name, {train.train_name} given' + ) + + if passengers is None: + passengers = [Adult()] + passengers = Passenger.combine(passengers) + + # 일반식 / 특실 좌석 선택 옵션에 따라 결정. + is_special_seat = None + if special_seat == SeatType.GENERAL_ONLY: # 일반실만 + is_special_seat = False + elif special_seat == SeatType.SPECIAL_ONLY: # 특실만 + is_special_seat = True + elif special_seat == SeatType.GENERAL_FIRST: # 일반실 우선 + if train.general_seat_available(): + is_special_seat = False + else: + is_special_seat = True + elif special_seat == SeatType.SPECIAL_FIRST: # 특실 우선 + if train.special_seat_available(): + is_special_seat = True + else: + is_special_seat = False + + url = SRT_RESERVE + data = { + "type": "1", + "jobId": "1102", # 예약대기 + "jrnyTpCd": "11", + "jrnyCnt": "1", + "stlbTrnClsfCd1": train.train_code, # 역무열차종별코드1 (열차 목록 값) + "stlbTrnClsfCd2": "05", + "stndFlg": "N", + "jrnySqno1": "001", + "trnGpCd1": "300", # 열차그룹코드1 (열차 목록 값) + "dptRsStnCd1": train.dep_station_code, # 출발역코드1 (열차 목록 값) + "dptRsStnCdNm1": train.dep_station_name, + "arvRsStnCd1": train.arr_station_code, # 도착역코드1 (열차 목록 값) + "arvRsStnCdNm1": train.arr_station_name, + "dptDt1": train.dep_date, # 출발일자1 (열차 목록 값) + "dptTm1": train.dep_time, # 출발일자1 (열차 목록 값) + "arvTm1": train.arr_time, # 도착일자1 (열차 목록 값) + "totPrnb": len(passengers), # 승차인원 + "psgGridcnt": len(passengers), # 승차인원 + "psgTpCd1": len(passengers), # 승차인원 + "psgInfoPerPrnb1": len(passengers), # 승차인원 + "trnNo1": "%05d" % int(train.train_number), # 열차번호1 (열차 목록 값) + "runDt1": train.dep_date, # 운행일자1 (열차 목록 값) + "psrmClCd1": "2" if is_special_seat == True else "1", # 객실등급코드1 (1:일반실, 2:특실) + "dptStnConsOrdr1": train.dep_station_constitution_order, # 출발역구성순서1 (열차 목록 값) + "arvStnConsOrdr1": train.arr_station_constitution_order, # 도착역구성순서1 (열차 목록 값) + "dptStnRunOrdr1": train.dep_station_run_order, # 출발역운행순서1 (열차 목록 값) + "arvStnRunOrdr1": train.arr_station_run_order, # 도착역운행순서1 (열차 목록 값) + "trnGpCd": "109", # 열차그룹코드 + "mblPhone": mblPhone + } + + r = self._session.post(url=url, data=data) + print(r.text) + parser = SRTResponseData(r.text) + + if not parser.success(): + raise SRTResponseError(parser.message()) + + self._log(parser.message()) + reservation_result = parser.get_all()["reservListMap"][0] + + # find corresponding ticket and return it + tickets = self.get_reservations() + for ticket in tickets: + if ticket.reservation_number == reservation_result["pnrNo"]: + return ticket + + # if ticket not found, it's an error + raise SRTError("Ticket not found: check reservation status") + + def reserve_standby_option_settings( + self, + reservation: SRTReservation | int, + isAgreeSMS: bool, + isAgreeClassChange: bool, + telNo: str | None = None, + ) -> bool: + """예약대기 옵션을 적용 합니다. + + >>> trains = srt.search_train("수서", "부산", "210101", "000000") + >>> srt.reserve_standby(trains[0]) + >>> srt.reserve_standby_option_settings("1234567890", True, True, "010-1234-xxxx") + + Args: + reservation (:class:`SRTReservation` or int): 예약 번호 + isAgreeSMS (bool): SMS 수신 동의 여부 + isAgreeClassChange (bool): 좌석등급 변경 동의 여부 + telNo (str, optional): 휴대폰 번호 + Returns: + bool: 예약대기 옵션 적용 성공 여부 + """ + if not self.is_login: + raise SRTNotLoggedInError() + + if isinstance(reservation, SRTReservation): + reservation = reservation.reservation_number + + url = SRT_STANDBY_OPTION + + data = { + "pnrNo": reservation, + "psrmClChgFlg": "Y" if isAgreeClassChange else "N", + "smsSndFlg": "Y" if isAgreeSMS else "N", + "telNo": telNo if isAgreeSMS else "", + } + + r = self._session.post(url=url, data=data) + + return r.status_code == 200 + def get_reservations(self, paid_only: bool = False) -> list[SRTReservation]: """전체 예약 정보를 얻습니다. diff --git a/SRT/train.py b/SRT/train.py index 9e03d33..74d162c 100644 --- a/SRT/train.py +++ b/SRT/train.py @@ -20,6 +20,11 @@ def __init__(self, data): self.arr_station_name = STATION_NAME[self.arr_station_code] self.general_seat_state = data["gnrmRsvPsbStr"] self.special_seat_state = data["sprmRsvPsbStr"] + self.arr_station_run_order = data["arvStnRunOrdr"] + self.arr_station_constitution_order = data["arvStnConsOrdr"] + self.arr_station_constitution_order = data["arvStnConsOrdr"] + self.dep_station_run_order = data["dptStnRunOrdr"] + self.dep_station_constitution_order = data["dptStnConsOrdr"] def __str__(self): return self.dump() From ce2c686a43cf9c36c91ab88eed247a0acf4e2370 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 6 Sep 2023 04:07:22 +0000 Subject: [PATCH 02/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- SRT/srt.py | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/SRT/srt.py b/SRT/srt.py index a8a0f60..5691567 100644 --- a/SRT/srt.py +++ b/SRT/srt.py @@ -404,38 +404,40 @@ def reserve_standby( url = SRT_RESERVE data = { "type": "1", - "jobId": "1102", # 예약대기 + "jobId": "1102", # 예약대기 "jrnyTpCd": "11", "jrnyCnt": "1", - "stlbTrnClsfCd1": train.train_code, # 역무열차종별코드1 (열차 목록 값) + "stlbTrnClsfCd1": train.train_code, # 역무열차종별코드1 (열차 목록 값) "stlbTrnClsfCd2": "05", "stndFlg": "N", "jrnySqno1": "001", - "trnGpCd1": "300", # 열차그룹코드1 (열차 목록 값) - "dptRsStnCd1": train.dep_station_code, # 출발역코드1 (열차 목록 값) - "dptRsStnCdNm1": train.dep_station_name, - "arvRsStnCd1": train.arr_station_code, # 도착역코드1 (열차 목록 값) + "trnGpCd1": "300", # 열차그룹코드1 (열차 목록 값) + "dptRsStnCd1": train.dep_station_code, # 출발역코드1 (열차 목록 값) + "dptRsStnCdNm1": train.dep_station_name, + "arvRsStnCd1": train.arr_station_code, # 도착역코드1 (열차 목록 값) "arvRsStnCdNm1": train.arr_station_name, - "dptDt1": train.dep_date, # 출발일자1 (열차 목록 값) - "dptTm1": train.dep_time, # 출발일자1 (열차 목록 값) - "arvTm1": train.arr_time, # 도착일자1 (열차 목록 값) - "totPrnb": len(passengers), # 승차인원 - "psgGridcnt": len(passengers), # 승차인원 - "psgTpCd1": len(passengers), # 승차인원 - "psgInfoPerPrnb1": len(passengers), # 승차인원 - "trnNo1": "%05d" % int(train.train_number), # 열차번호1 (열차 목록 값) - "runDt1": train.dep_date, # 운행일자1 (열차 목록 값) - "psrmClCd1": "2" if is_special_seat == True else "1", # 객실등급코드1 (1:일반실, 2:특실) + "dptDt1": train.dep_date, # 출발일자1 (열차 목록 값) + "dptTm1": train.dep_time, # 출발일자1 (열차 목록 값) + "arvTm1": train.arr_time, # 도착일자1 (열차 목록 값) + "totPrnb": len(passengers), # 승차인원 + "psgGridcnt": len(passengers), # 승차인원 + "psgTpCd1": len(passengers), # 승차인원 + "psgInfoPerPrnb1": len(passengers), # 승차인원 + "trnNo1": "%05d" % int(train.train_number), # 열차번호1 (열차 목록 값) + "runDt1": train.dep_date, # 운행일자1 (열차 목록 값) + "psrmClCd1": "2" + if is_special_seat is True + else "1", # 객실등급코드1 (1:일반실, 2:특실) "dptStnConsOrdr1": train.dep_station_constitution_order, # 출발역구성순서1 (열차 목록 값) "arvStnConsOrdr1": train.arr_station_constitution_order, # 도착역구성순서1 (열차 목록 값) - "dptStnRunOrdr1": train.dep_station_run_order, # 출발역운행순서1 (열차 목록 값) - "arvStnRunOrdr1": train.arr_station_run_order, # 도착역운행순서1 (열차 목록 값) - "trnGpCd": "109", # 열차그룹코드 - "mblPhone": mblPhone + "dptStnRunOrdr1": train.dep_station_run_order, # 출발역운행순서1 (열차 목록 값) + "arvStnRunOrdr1": train.arr_station_run_order, # 도착역운행순서1 (열차 목록 값) + "trnGpCd": "109", # 열차그룹코드 + "mblPhone": mblPhone, } r = self._session.post(url=url, data=data) - print(r.text) + print(r.text) parser = SRTResponseData(r.text) if not parser.success(): @@ -485,7 +487,7 @@ def reserve_standby_option_settings( data = { "pnrNo": reservation, "psrmClChgFlg": "Y" if isAgreeClassChange else "N", - "smsSndFlg": "Y" if isAgreeSMS else "N", + "smsSndFlg": "Y" if isAgreeSMS else "N", "telNo": telNo if isAgreeSMS else "", } From c199bc34de47bc4bc764450d52a915e859efd20b Mon Sep 17 00:00:00 2001 From: Monsteel Date: Wed, 6 Sep 2023 13:24:32 +0900 Subject: [PATCH 03/12] =?UTF-8?q?reserve=5Fstandby=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EB=82=B4=20passengers=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0?= =?UTF-8?q?=20=ED=83=80=EC=9E=85=20=EC=95=88=EC=A0=95=EC=84=B1=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SRT/srt.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/SRT/srt.py b/SRT/srt.py index 5691567..e21a159 100644 --- a/SRT/srt.py +++ b/SRT/srt.py @@ -384,6 +384,10 @@ def reserve_standby( passengers = [Adult()] passengers = Passenger.combine(passengers) + if passengers is not None: + passengersCount = len(passengers); + + # 일반식 / 특실 좌석 선택 옵션에 따라 결정. is_special_seat = None if special_seat == SeatType.GENERAL_ONLY: # 일반실만 @@ -419,10 +423,10 @@ def reserve_standby( "dptDt1": train.dep_date, # 출발일자1 (열차 목록 값) "dptTm1": train.dep_time, # 출발일자1 (열차 목록 값) "arvTm1": train.arr_time, # 도착일자1 (열차 목록 값) - "totPrnb": len(passengers), # 승차인원 - "psgGridcnt": len(passengers), # 승차인원 - "psgTpCd1": len(passengers), # 승차인원 - "psgInfoPerPrnb1": len(passengers), # 승차인원 + "totPrnb": passengersCount, # 승차인원 + "psgGridcnt": passengersCount, # 승차인원 + "psgTpCd1": passengersCount, # 승차인원 + "psgInfoPerPrnb1": passengersCount, # 승차인원 "trnNo1": "%05d" % int(train.train_number), # 열차번호1 (열차 목록 값) "runDt1": train.dep_date, # 운행일자1 (열차 목록 값) "psrmClCd1": "2" From 11ae993a220f91ffd30132bed3816b6fc7a83bbf Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 6 Sep 2023 04:25:43 +0000 Subject: [PATCH 04/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- SRT/srt.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/SRT/srt.py b/SRT/srt.py index e21a159..cdd4c45 100644 --- a/SRT/srt.py +++ b/SRT/srt.py @@ -385,8 +385,7 @@ def reserve_standby( passengers = Passenger.combine(passengers) if passengers is not None: - passengersCount = len(passengers); - + passengersCount = len(passengers) # 일반식 / 특실 좌석 선택 옵션에 따라 결정. is_special_seat = None From 071595d46e6f0589b6a2ac3578b3760cc877733d Mon Sep 17 00:00:00 2001 From: Monsteel Date: Wed, 6 Sep 2023 15:02:20 +0900 Subject: [PATCH 05/12] =?UTF-8?q?=EC=98=88=EC=95=BD=EB=8C=80=EA=B8=B0,=20[?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=EA=B0=92=20=EC=98=A4=EB=A5=98]=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SRT/srt.py | 67 +++++++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/SRT/srt.py b/SRT/srt.py index cdd4c45..d781222 100644 --- a/SRT/srt.py +++ b/SRT/srt.py @@ -406,41 +406,46 @@ def reserve_standby( url = SRT_RESERVE data = { - "type": "1", - "jobId": "1102", # 예약대기 - "jrnyTpCd": "11", + "jobId": "1102", # 예약대기 jobID "jrnyCnt": "1", - "stlbTrnClsfCd1": train.train_code, # 역무열차종별코드1 (열차 목록 값) - "stlbTrnClsfCd2": "05", - "stndFlg": "N", + "jrnyTpCd": "11", "jrnySqno1": "001", - "trnGpCd1": "300", # 열차그룹코드1 (열차 목록 값) - "dptRsStnCd1": train.dep_station_code, # 출발역코드1 (열차 목록 값) - "dptRsStnCdNm1": train.dep_station_name, - "arvRsStnCd1": train.arr_station_code, # 도착역코드1 (열차 목록 값) - "arvRsStnCdNm1": train.arr_station_name, - "dptDt1": train.dep_date, # 출발일자1 (열차 목록 값) - "dptTm1": train.dep_time, # 출발일자1 (열차 목록 값) - "arvTm1": train.arr_time, # 도착일자1 (열차 목록 값) - "totPrnb": passengersCount, # 승차인원 - "psgGridcnt": passengersCount, # 승차인원 - "psgTpCd1": passengersCount, # 승차인원 - "psgInfoPerPrnb1": passengersCount, # 승차인원 - "trnNo1": "%05d" % int(train.train_number), # 열차번호1 (열차 목록 값) - "runDt1": train.dep_date, # 운행일자1 (열차 목록 값) - "psrmClCd1": "2" - if is_special_seat is True - else "1", # 객실등급코드1 (1:일반실, 2:특실) - "dptStnConsOrdr1": train.dep_station_constitution_order, # 출발역구성순서1 (열차 목록 값) - "arvStnConsOrdr1": train.arr_station_constitution_order, # 도착역구성순서1 (열차 목록 값) - "dptStnRunOrdr1": train.dep_station_run_order, # 출발역운행순서1 (열차 목록 값) - "arvStnRunOrdr1": train.arr_station_run_order, # 도착역운행순서1 (열차 목록 값) - "trnGpCd": "109", # 열차그룹코드 - "mblPhone": mblPhone, + "stndFlg": "N", + "trnGpCd1": "300", # 열차그룹코드 (좌석선택은 SRT만 가능하기때문에 무조건 300을 셋팅한다)" + "trnGpCd": "109", # 열차그룹코드 + "grpDv": "0", # 단체 구분 (1: 단체) + "rtnDv": "0", # 편도 구분 (0: 편도, 1: 왕복) + "stlbTrnClsfCd1": train.train_code, # 역무열차종별코드1 (열차 목록 값) + "dptRsStnCd1": train.dep_station_code, # 출발역코드1 (열차 목록 값) + "dptRsStnCdNm1": train.dep_station_name, # 출발역이름1 (열차 목록 값) + "arvRsStnCd1": train.arr_station_code, # 도착역코드1 (열차 목록 값) + "arvRsStnCdNm1": train.arr_station_name, # 도착역이름1 (열차 목록 값) + "dptDt1": train.dep_date, # 출발일자1 (열차 목록 값) + "dptTm1": train.dep_time, # 출발일자1 (열차 목록 값) + "arvTm1": train.arr_time, # 도착일자1 (열차 목록 값) + "totPrnb": passengersCount, # 승차인원 + "psgGridcnt": passengersCount, # 승차인원 + "psgTpCd1": passengersCount, # 승차인원 + "psgInfoPerPrnb1": passengersCount, # 승차인원 + "trnNo1": "%05d" % int(train.train_number), # 열차번호1 (열차 목록 값) + "runDt1": train.dep_date, # 운행일자1 (열차 목록 값) + "psrmClCd1": "2" if is_special_seat == True else "1", + "dptStnConsOrdr1": train.dep_station_constitution_order, # 출발역구성순서1 (열차 목록 값) + "arvStnConsOrdr1": train.arr_station_constitution_order, # 도착역구성순서1 (열차 목록 값) + "dptStnRunOrdr1": train.dep_station_run_order, # 출발역운행순서1 (열차 목록 값) + "arvStnRunOrdr1": train.arr_station_run_order, # 도착역운행순서1 (열차 목록 값) + "smkSeatAttCd1": "000", # 흡연좌석속성코드1 + "dirSeatAttCd1": "009", # 방향좌석속성코드 + "locSeatAttCd1": "000", # 위치좌석속성코드1 + "rqSeatAttCd1": "015", # 요구좌석속성코드1 + "etcSeatAttCd1": "000", # 기타좌석속성코드1 + "smkSeatAttCd2": "000", # 흡연좌석속성코드2 + "dirSeatAttCd2": "009", # 방향좌석속성코드2 + "rqSeatAttCd2": "015", # 요구좌석속성코드2 + "mblPhone": mblPhone } r = self._session.post(url=url, data=data) - print(r.text) parser = SRTResponseData(r.text) if not parser.success(): @@ -600,4 +605,4 @@ def cancel(self, reservation: SRTReservation | int) -> bool: self._log(parser.message()) - return True + return True \ No newline at end of file From 375bf034954a0058f87fbc4213688a6c833f0611 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 6 Sep 2023 06:03:01 +0000 Subject: [PATCH 06/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- SRT/srt.py | 68 +++++++++++++++++++++++++++--------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/SRT/srt.py b/SRT/srt.py index d781222..d31e1f3 100644 --- a/SRT/srt.py +++ b/SRT/srt.py @@ -406,43 +406,43 @@ def reserve_standby( url = SRT_RESERVE data = { - "jobId": "1102", # 예약대기 jobID + "jobId": "1102", # 예약대기 jobID "jrnyCnt": "1", "jrnyTpCd": "11", "jrnySqno1": "001", "stndFlg": "N", - "trnGpCd1": "300", # 열차그룹코드 (좌석선택은 SRT만 가능하기때문에 무조건 300을 셋팅한다)" - "trnGpCd": "109", # 열차그룹코드 - "grpDv": "0", # 단체 구분 (1: 단체) - "rtnDv": "0", # 편도 구분 (0: 편도, 1: 왕복) - "stlbTrnClsfCd1": train.train_code, # 역무열차종별코드1 (열차 목록 값) - "dptRsStnCd1": train.dep_station_code, # 출발역코드1 (열차 목록 값) - "dptRsStnCdNm1": train.dep_station_name, # 출발역이름1 (열차 목록 값) - "arvRsStnCd1": train.arr_station_code, # 도착역코드1 (열차 목록 값) - "arvRsStnCdNm1": train.arr_station_name, # 도착역이름1 (열차 목록 값) - "dptDt1": train.dep_date, # 출발일자1 (열차 목록 값) - "dptTm1": train.dep_time, # 출발일자1 (열차 목록 값) - "arvTm1": train.arr_time, # 도착일자1 (열차 목록 값) - "totPrnb": passengersCount, # 승차인원 - "psgGridcnt": passengersCount, # 승차인원 - "psgTpCd1": passengersCount, # 승차인원 - "psgInfoPerPrnb1": passengersCount, # 승차인원 - "trnNo1": "%05d" % int(train.train_number), # 열차번호1 (열차 목록 값) - "runDt1": train.dep_date, # 운행일자1 (열차 목록 값) - "psrmClCd1": "2" if is_special_seat == True else "1", - "dptStnConsOrdr1": train.dep_station_constitution_order, # 출발역구성순서1 (열차 목록 값) - "arvStnConsOrdr1": train.arr_station_constitution_order, # 도착역구성순서1 (열차 목록 값) - "dptStnRunOrdr1": train.dep_station_run_order, # 출발역운행순서1 (열차 목록 값) - "arvStnRunOrdr1": train.arr_station_run_order, # 도착역운행순서1 (열차 목록 값) - "smkSeatAttCd1": "000", # 흡연좌석속성코드1 - "dirSeatAttCd1": "009", # 방향좌석속성코드 - "locSeatAttCd1": "000", # 위치좌석속성코드1 - "rqSeatAttCd1": "015", # 요구좌석속성코드1 - "etcSeatAttCd1": "000", # 기타좌석속성코드1 - "smkSeatAttCd2": "000", # 흡연좌석속성코드2 - "dirSeatAttCd2": "009", # 방향좌석속성코드2 - "rqSeatAttCd2": "015", # 요구좌석속성코드2 - "mblPhone": mblPhone + "trnGpCd1": "300", # 열차그룹코드 (좌석선택은 SRT만 가능하기때문에 무조건 300을 셋팅한다)" + "trnGpCd": "109", # 열차그룹코드 + "grpDv": "0", # 단체 구분 (1: 단체) + "rtnDv": "0", # 편도 구분 (0: 편도, 1: 왕복) + "stlbTrnClsfCd1": train.train_code, # 역무열차종별코드1 (열차 목록 값) + "dptRsStnCd1": train.dep_station_code, # 출발역코드1 (열차 목록 값) + "dptRsStnCdNm1": train.dep_station_name, # 출발역이름1 (열차 목록 값) + "arvRsStnCd1": train.arr_station_code, # 도착역코드1 (열차 목록 값) + "arvRsStnCdNm1": train.arr_station_name, # 도착역이름1 (열차 목록 값) + "dptDt1": train.dep_date, # 출발일자1 (열차 목록 값) + "dptTm1": train.dep_time, # 출발일자1 (열차 목록 값) + "arvTm1": train.arr_time, # 도착일자1 (열차 목록 값) + "totPrnb": passengersCount, # 승차인원 + "psgGridcnt": passengersCount, # 승차인원 + "psgTpCd1": passengersCount, # 승차인원 + "psgInfoPerPrnb1": passengersCount, # 승차인원 + "trnNo1": "%05d" % int(train.train_number), # 열차번호1 (열차 목록 값) + "runDt1": train.dep_date, # 운행일자1 (열차 목록 값) + "psrmClCd1": "2" if is_special_seat is True else "1", + "dptStnConsOrdr1": train.dep_station_constitution_order, # 출발역구성순서1 (열차 목록 값) + "arvStnConsOrdr1": train.arr_station_constitution_order, # 도착역구성순서1 (열차 목록 값) + "dptStnRunOrdr1": train.dep_station_run_order, # 출발역운행순서1 (열차 목록 값) + "arvStnRunOrdr1": train.arr_station_run_order, # 도착역운행순서1 (열차 목록 값) + "smkSeatAttCd1": "000", # 흡연좌석속성코드1 + "dirSeatAttCd1": "009", # 방향좌석속성코드 + "locSeatAttCd1": "000", # 위치좌석속성코드1 + "rqSeatAttCd1": "015", # 요구좌석속성코드1 + "etcSeatAttCd1": "000", # 기타좌석속성코드1 + "smkSeatAttCd2": "000", # 흡연좌석속성코드2 + "dirSeatAttCd2": "009", # 방향좌석속성코드2 + "rqSeatAttCd2": "015", # 요구좌석속성코드2 + "mblPhone": mblPhone, } r = self._session.post(url=url, data=data) @@ -605,4 +605,4 @@ def cancel(self, reservation: SRTReservation | int) -> bool: self._log(parser.message()) - return True \ No newline at end of file + return True From 2eb4c783fe497afdf2986d78a513bf16b09d06c7 Mon Sep 17 00:00:00 2001 From: Monsteel Date: Wed, 6 Sep 2023 17:05:37 +0900 Subject: [PATCH 07/12] =?UTF-8?q?SRTTrain=20model=EC=97=90=20=EC=98=88?= =?UTF-8?q?=EC=95=BD=EB=8C=80=EA=B8=B0=20=EA=B0=80=EB=8A=A5=EC=97=AC?= =?UTF-8?q?=EB=B6=80=20=EC=83=81=ED=83=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SRT/train.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/SRT/train.py b/SRT/train.py index 74d162c..f123042 100644 --- a/SRT/train.py +++ b/SRT/train.py @@ -20,6 +20,7 @@ def __init__(self, data): self.arr_station_name = STATION_NAME[self.arr_station_code] self.general_seat_state = data["gnrmRsvPsbStr"] self.special_seat_state = data["sprmRsvPsbStr"] + self.reserve_wait_possible_code = data["rsvWaitPsbCd"] self.arr_station_run_order = data["arvStnRunOrdr"] self.arr_station_constitution_order = data["arvStnConsOrdr"] self.arr_station_constitution_order = data["arvStnConsOrdr"] @@ -38,7 +39,7 @@ def dump(self): "{month}월 {day}일, " "{dep}~{arr}" "({dep_hour}:{dep_min}~{arr_hour}:{arr_min}) " - "특실 {special_state}, 일반실 {general_state}" + "특실 {special_state}, 일반실 {general_state}, 예약대기 {reserve_standby_state}" ).format( name=self.train_name, number=self.train_number, @@ -52,6 +53,7 @@ def dump(self): arr_min=self.arr_time[2:4], special_state=self.special_seat_state, general_state=self.general_seat_state, + reserve_standby_state="가능" if self.reserve_standby_available() else "불가능" ) return d @@ -61,6 +63,9 @@ def general_seat_available(self): def special_seat_available(self): return "예약가능" in self.special_seat_state + + def reserve_standby_available(self): + return "9" in self.reserve_wait_possible_code # 9인 경우, 예약대기 가능한 상태임 def seat_available(self): - return self.general_seat_available() or self.special_seat_available() + return self.general_seat_available() or self.special_seat_available() \ No newline at end of file From 4093cc79b3fafd2dad19268e84a93b2326fc8ce0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 6 Sep 2023 08:06:34 +0000 Subject: [PATCH 08/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- SRT/train.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SRT/train.py b/SRT/train.py index f123042..3734a0f 100644 --- a/SRT/train.py +++ b/SRT/train.py @@ -53,7 +53,7 @@ def dump(self): arr_min=self.arr_time[2:4], special_state=self.special_seat_state, general_state=self.general_seat_state, - reserve_standby_state="가능" if self.reserve_standby_available() else "불가능" + reserve_standby_state="가능" if self.reserve_standby_available() else "불가능", ) return d @@ -63,9 +63,9 @@ def general_seat_available(self): def special_seat_available(self): return "예약가능" in self.special_seat_state - + def reserve_standby_available(self): - return "9" in self.reserve_wait_possible_code # 9인 경우, 예약대기 가능한 상태임 + return "9" in self.reserve_wait_possible_code # 9인 경우, 예약대기 가능한 상태임 def seat_available(self): - return self.general_seat_available() or self.special_seat_available() \ No newline at end of file + return self.general_seat_available() or self.special_seat_available() From b75c8defd969394d143eebae11f7b4c170481186 Mon Sep 17 00:00:00 2001 From: Monsteel Date: Wed, 6 Sep 2023 22:00:54 +0900 Subject: [PATCH 09/12] =?UTF-8?q?=EC=98=88=EC=95=BD=EB=8C=80=EA=B8=B0=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=EC=97=90=20=EB=8C=80=ED=95=9C=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SRT/tests/test_srt.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/SRT/tests/test_srt.py b/SRT/tests/test_srt.py index b2e84f6..e7c2d27 100644 --- a/SRT/tests/test_srt.py +++ b/SRT/tests/test_srt.py @@ -43,6 +43,25 @@ def test_search_train(srt): def test_get_reservations(srt): srt.get_reservations() +def test_reserve_and_standby_option_settings(srt): + dep = "수서" + arr = "대전" + time = "000000" + time_limit = "120000" + date = (datetime.now() + timedelta(days=3)).strftime("%Y%m%d") + + trains = srt.search_train(dep, arr, date, time, time_limit, available_only=False) + trains = list(filter(lambda t: t.reserve_standby_available(), trains)) + + assert len(trains) != 0 + + train = trains[0] + reservation = srt.reserve_standby(train) + + if reservation is None: + pytest.warns(Warning("Empty seat not found, skipping reservation test")) + + srt.reserve_standby_option_settings(reservation, True, True, "010-1234-5678") def test_reserve_and_cancel(srt, pytestconfig): pytestconfig.getoption("--full", skip=True) From 087e24a71496b925beb17a85146108a7e7a3a4d9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 6 Sep 2023 13:01:24 +0000 Subject: [PATCH 10/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- SRT/tests/test_srt.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SRT/tests/test_srt.py b/SRT/tests/test_srt.py index e7c2d27..083d560 100644 --- a/SRT/tests/test_srt.py +++ b/SRT/tests/test_srt.py @@ -43,6 +43,7 @@ def test_search_train(srt): def test_get_reservations(srt): srt.get_reservations() + def test_reserve_and_standby_option_settings(srt): dep = "수서" arr = "대전" @@ -63,6 +64,7 @@ def test_reserve_and_standby_option_settings(srt): srt.reserve_standby_option_settings(reservation, True, True, "010-1234-5678") + def test_reserve_and_cancel(srt, pytestconfig): pytestconfig.getoption("--full", skip=True) dep = "수서" From fb8689d6ffe535493c9ad7a7668bb105f06232c1 Mon Sep 17 00:00:00 2001 From: Monsteel Date: Wed, 6 Sep 2023 22:27:46 +0900 Subject: [PATCH 11/12] =?UTF-8?q?=EC=98=88=EC=95=BD=EB=8C=80=EA=B8=B0,=20?= =?UTF-8?q?=EC=98=88=EC=95=BD=ED=95=A8=EC=88=98=20=EA=B3=B5=ED=86=B5=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EB=B6=84=EB=A6=AC=20->=5Freserve?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SRT/srt.py | 134 +++++++++++++++++++++++------------------------------ 1 file changed, 59 insertions(+), 75 deletions(-) diff --git a/SRT/srt.py b/SRT/srt.py index d31e1f3..2187a09 100644 --- a/SRT/srt.py +++ b/SRT/srt.py @@ -43,6 +43,11 @@ RESULT_SUCCESS = "SUCC" RESULT_FAIL = "FAIL" +RESERVE_JOBID = { + "PERSONAL": "1101", # 개인예약 + "STANDBY": "1102", # 예약대기 +} + class SRT: """SRT 클라이언트 클래스 @@ -272,88 +277,21 @@ def reserve( Returns: :class:`SRTReservation`: 예약 내역 """ - if not self.is_login: - raise SRTNotLoggedInError() - - if not isinstance(train, SRTTrain): - raise TypeError('"train" parameter must be a SRTTrain instance') - - if train.train_name != "SRT": - raise ValueError( - f'"SRT" expected for a train name, {train.train_name} given' - ) - - if passengers is None: - passengers = [Adult()] - passengers = Passenger.combine(passengers) - - # 일반식 / 특실 좌석 선택 옵션에 따라 결정. - is_special_seat = None - if special_seat == SeatType.GENERAL_ONLY: # 일반실만 - is_special_seat = False - elif special_seat == SeatType.SPECIAL_ONLY: # 특실만 - is_special_seat = True - elif special_seat == SeatType.GENERAL_FIRST: # 일반실 우선 - if train.general_seat_available(): - is_special_seat = False - else: - is_special_seat = True - elif special_seat == SeatType.SPECIAL_FIRST: # 특실 우선 - if train.special_seat_available(): - is_special_seat = True - else: - is_special_seat = False - - url = SRT_RESERVE - data = { - "reserveType": "11", - "jobId": "1101", # 개인 예약 - "jrnyCnt": "1", - "jrnyTpCd": "11", - "jrnySqno1": "001", - "stndFlg": "N", - "trnGpCd1": "300", # 열차그룹코드 (좌석선택은 SRT만 가능하기때문에 무조건 300을 셋팅한다)" - "stlbTrnClsfCd1": train.train_code, - "dptDt1": train.dep_date, - "dptTm1": train.dep_time, - "runDt1": train.dep_date, - "trnNo1": "%05d" % int(train.train_number), - "dptRsStnCd1": train.dep_station_code, - "dptRsStnCdNm1": train.dep_station_name, - "arvRsStnCd1": train.arr_station_code, - "arvRsStnCdNm1": train.arr_station_name, - } - data.update( - Passenger.get_passenger_dict( - passengers, special_seat=is_special_seat, window_seat=window_seat - ) + return self._reserve( + RESERVE_JOBID["PERSONAL"], + train, + passengers, + special_seat, + window_seat = window_seat ) - r = self._session.post(url=url, data=data) - parser = SRTResponseData(r.text) - - if not parser.success(): - raise SRTResponseError(parser.message()) - - self._log(parser.message()) - reservation_result = parser.get_all()["reservListMap"][0] - - # find corresponding ticket and return it - tickets = self.get_reservations() - for ticket in tickets: - if ticket.reservation_number == reservation_result["pnrNo"]: - return ticket - - # if ticket not found, it's an error - raise SRTError("Ticket not found: check reservation status") - def reserve_standby( self, train: SRTTrain, passengers: list[Passenger] | None = None, special_seat: SeatType = SeatType.GENERAL_FIRST, - mblPhone: str | None = None, + mblPhone: str | None = None ) -> SRTReservation: """예약대기 신청 합니다. @@ -366,6 +304,36 @@ def reserve_standby( special_seat (:class:`SeatType`): 일반실/특실 선택 유형 (default: 일반실 우선) mblPhone (str, optional): 휴대폰 번호 + Returns: + :class:`SRTReservation`: 예약 내역 + """ + + return self._reserve( + RESERVE_JOBID["STANDBY"], + train, + passengers, + special_seat, + mblPhone = mblPhone + ) + + def _reserve( + self, + jobid: str, + train: SRTTrain, + passengers: list[Passenger] | None = None, + special_seat: SeatType = SeatType.GENERAL_FIRST, + mblPhone: str | None = None, + window_seat: bool | None = None, + ) -> SRTReservation: + """예약 신청 요청 공통 함수 + + Args: + train (:class:`SRTrain`): 예약할 열차 + passengers (list[:class:`Passenger`], optional): 예약 인원 (default: 어른 1명) + special_seat (:class:`SeatType`): 일반실/특실 선택 유형 (default: 일반실 우선) + mblPhone (str, optional): 휴대폰 번호 | jobid가 RESERVE_JOBID["STANDBY"]일 경우에만 사용 + window_seat (bool, optional): 창가 자리 우선 예약 여부 | jobid가 RESERVE_JOBID["PERSONAL"]일 경우에만 사용 + Returns: :class:`SRTReservation`: 예약 내역 """ @@ -406,7 +374,7 @@ def reserve_standby( url = SRT_RESERVE data = { - "jobId": "1102", # 예약대기 jobID + "jobId": jobid, "jrnyCnt": "1", "jrnyTpCd": "11", "jrnySqno1": "001", @@ -445,6 +413,22 @@ def reserve_standby( "mblPhone": mblPhone, } + # jobid가 RESERVE_JOBID["PERSONAL"]일 경우, data에 reserveType 추가 + if jobid == RESERVE_JOBID["PERSONAL"]: + data.update( + { + "reserveType": "1", + } + ) + + # jobid가 RESERVE_JOBID["PERSONAL"]일 경우, data에 windowSeat 추가 + if jobid == RESERVE_JOBID["PERSONAL"]: + data.update( + Passenger.get_passenger_dict( + passengers, special_seat=is_special_seat, window_seat=window_seat + ) + ) + r = self._session.post(url=url, data=data) parser = SRTResponseData(r.text) From 2dd86f6ba08bfffea024b1b0dde2054e9ceecf3a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 6 Sep 2023 13:28:11 +0000 Subject: [PATCH 12/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- SRT/srt.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/SRT/srt.py b/SRT/srt.py index 2187a09..ca6b6f4 100644 --- a/SRT/srt.py +++ b/SRT/srt.py @@ -44,7 +44,7 @@ RESULT_FAIL = "FAIL" RESERVE_JOBID = { - "PERSONAL": "1101", # 개인예약 + "PERSONAL": "1101", # 개인예약 "STANDBY": "1102", # 예약대기 } @@ -283,7 +283,7 @@ def reserve( train, passengers, special_seat, - window_seat = window_seat + window_seat=window_seat, ) def reserve_standby( @@ -291,7 +291,7 @@ def reserve_standby( train: SRTTrain, passengers: list[Passenger] | None = None, special_seat: SeatType = SeatType.GENERAL_FIRST, - mblPhone: str | None = None + mblPhone: str | None = None, ) -> SRTReservation: """예약대기 신청 합니다. @@ -309,13 +309,9 @@ def reserve_standby( """ return self._reserve( - RESERVE_JOBID["STANDBY"], - train, - passengers, - special_seat, - mblPhone = mblPhone + RESERVE_JOBID["STANDBY"], train, passengers, special_seat, mblPhone=mblPhone ) - + def _reserve( self, jobid: str, @@ -420,7 +416,7 @@ def _reserve( "reserveType": "1", } ) - + # jobid가 RESERVE_JOBID["PERSONAL"]일 경우, data에 windowSeat 추가 if jobid == RESERVE_JOBID["PERSONAL"]: data.update(