-
Notifications
You must be signed in to change notification settings - Fork 61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
예약대기 기능 추가 #247
예약대기 기능 추가 #247
Changes from 8 commits
c3e6699
ce2c686
c199bc3
11ae993
071595d
375bf03
2eb4c78
4093cc7
b75c8de
087e24a
fb8689d
2dd86f6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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,161 @@ 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) | ||
|
||
if passengers is not None: | ||
passengersCount = len(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 = { | ||
"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 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) | ||
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( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 예약대기를 하면 기본 알림 설정이 어떻게 되나요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아시다시피 해당 내용을 정확하게 파악하기 어려움이 있습니다 ㅠ 웹페이지 예약대기 프로세스 상 기준으로 작업했고, 아래와 같습니다.
기본적으로 실제 프로세스에서 예약대기 신청 이후, 진행하지 않은 경우에 따른 작동과 동일합니다. 이해를 돕기위해 간략히 프로세스에 대해 기록합니다. 1. 아래 이미지에서 예약하기 버튼을 클릭하면, 예약대기 신청(reserve_standby) 요청이 전송됩니다.2. 아래 이미지에서 동의버튼을 누르면, 네트워크 요청없이, 단순히 다음화면으로 진입합니다.3. 이전 화면에서 동의를 누른 경우, 전화번호가 자동으로 입력되며, 아니오를 누른 경우 전화번호는 비어있으며, textfield에 수동으로 입력이 불가합니다. | 신청하기 버튼을 누르면 예약대기 옵션(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]: | ||
"""전체 예약 정보를 얻습니다. | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
jobId를 제외하면 대부분의 내용이 reserve함수와 동일한 듯하니, 아래와 같이 공통된 부분을 따로 빼고 재사용하면 좋을 것 같습니다. 혹은 reserve 함수 자체에 파라미터로 추가하는 것도 방법이겠으나, 유저가 기대하는 결과가 다르니 지금처럼 두 개의 reserve, reserve_standby 함수를 가지는 것은 좋아보여요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
안녕하세요 :)
피드백 감사합니다 👍
불필요한 파라미터가 흘러 들어가는게 우려되어 별도로 분리하였으나, 중복되는 코드에 대한 고민이 충분치 않았습니다.
실제 예매 페이지에서도 공통되는 파라미터가 포함된 상태로 요청이 들어가고 있음을 확인했고,
결과적으로는 의미가 크지 않을거라 판단되어, 말씀주신 방향대로 srt.py 파일 내 _reserve 함수로 분리하여, 공통된 코드를 일원화 했습니다.
아래는 웹페이지 예메 시 전송되는 요청별 파라미터입니다. 참고해주세요.
[1101] 개인 예매 요청 시 param
[1102] 예약대기 요청 시 param