Adding speedy mode for reservations
This commit is contained in:
parent
1fcd49af2a
commit
c4fcb38df8
2 changed files with 154 additions and 5 deletions
|
|
@ -43,7 +43,7 @@ export class ReservationsWorker {
|
||||||
reservation.dateRangeStart,
|
reservation.dateRangeStart,
|
||||||
reservation.dateRangeEnd,
|
reservation.dateRangeEnd,
|
||||||
)
|
)
|
||||||
await this.performReservation(reservation, job.attemptsMade, false)
|
await this.performReservation(reservation, job.attemptsMade, true, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private async handleReservationErrors(
|
private async handleReservationErrors(
|
||||||
|
|
@ -78,9 +78,14 @@ export class ReservationsWorker {
|
||||||
reservation: Reservation,
|
reservation: Reservation,
|
||||||
attemptsMade: number,
|
attemptsMade: number,
|
||||||
timeSensitive = true,
|
timeSensitive = true,
|
||||||
|
speedyMode = true,
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
await this.brService.performReservation(reservation)
|
if (speedyMode) {
|
||||||
|
await this.brService.performSpeedyReservation(reservation)
|
||||||
|
} else {
|
||||||
|
await this.brService.performReservation(reservation, timeSensitive)
|
||||||
|
}
|
||||||
await this.reservationsService.deleteById(reservation.id)
|
await this.reservationsService.deleteById(reservation.id)
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
await this.handleReservationErrors(
|
await this.handleReservationErrors(
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ enum CourtSlot {
|
||||||
Thirteen = '63',
|
Thirteen = '63',
|
||||||
}
|
}
|
||||||
|
|
||||||
const CourtSlotToNumber = {
|
const CourtSlotToNumber: Record<CourtSlot, number> = {
|
||||||
[CourtSlot.One]: 1,
|
[CourtSlot.One]: 1,
|
||||||
[CourtSlot.Two]: 2,
|
[CourtSlot.Two]: 2,
|
||||||
[CourtSlot.Three]: 3,
|
[CourtSlot.Three]: 3,
|
||||||
|
|
@ -66,7 +66,7 @@ const CourtSlotToNumber = {
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
// Lower is better
|
// Lower is better
|
||||||
const CourtRank = {
|
const CourtRank: Record<CourtSlot, number> = {
|
||||||
[CourtSlot.One]: 0,
|
[CourtSlot.One]: 0,
|
||||||
[CourtSlot.Two]: 0,
|
[CourtSlot.Two]: 0,
|
||||||
[CourtSlot.Three]: 0,
|
[CourtSlot.Three]: 0,
|
||||||
|
|
@ -82,6 +82,105 @@ const CourtRank = {
|
||||||
[CourtSlot.Thirteen]: 1, // no one likes upstairs
|
[CourtSlot.Thirteen]: 1, // no one likes upstairs
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
|
enum StartTimeClass {
|
||||||
|
First = 'first',
|
||||||
|
Second = 'second',
|
||||||
|
Third = 'third',
|
||||||
|
}
|
||||||
|
|
||||||
|
const StartTimeClassCourtSlots: Record<StartTimeClass, readonly CourtSlot[]> = {
|
||||||
|
[StartTimeClass.First]: [
|
||||||
|
CourtSlot.One,
|
||||||
|
CourtSlot.Two,
|
||||||
|
CourtSlot.Three,
|
||||||
|
CourtSlot.Four,
|
||||||
|
CourtSlot.Five,
|
||||||
|
],
|
||||||
|
[StartTimeClass.Second]: [
|
||||||
|
CourtSlot.Six,
|
||||||
|
CourtSlot.Seven,
|
||||||
|
CourtSlot.Eight,
|
||||||
|
CourtSlot.Nine,
|
||||||
|
CourtSlot.Ten,
|
||||||
|
],
|
||||||
|
[StartTimeClass.Third]: [
|
||||||
|
CourtSlot.Eleven,
|
||||||
|
CourtSlot.Twelve,
|
||||||
|
CourtSlot.Thirteen,
|
||||||
|
],
|
||||||
|
} as const
|
||||||
|
|
||||||
|
const StartTimeClassStartTimes = {
|
||||||
|
[StartTimeClass.First]: [
|
||||||
|
'07:15',
|
||||||
|
'08:00',
|
||||||
|
'08:45',
|
||||||
|
'09:30',
|
||||||
|
'10:15',
|
||||||
|
'11:00',
|
||||||
|
'11:45',
|
||||||
|
'12:30',
|
||||||
|
'13:15',
|
||||||
|
'14:00',
|
||||||
|
'14:45',
|
||||||
|
'15:30',
|
||||||
|
'16:15',
|
||||||
|
'17:00',
|
||||||
|
'17:45',
|
||||||
|
'18:30',
|
||||||
|
'19:15',
|
||||||
|
'20:00',
|
||||||
|
'20:45',
|
||||||
|
'21:30',
|
||||||
|
'22:15',
|
||||||
|
],
|
||||||
|
[StartTimeClass.Second]: [
|
||||||
|
'07:45',
|
||||||
|
'08:30',
|
||||||
|
'09:15',
|
||||||
|
'10:00',
|
||||||
|
'10:45',
|
||||||
|
'11:30',
|
||||||
|
'12:15',
|
||||||
|
'13:00',
|
||||||
|
'13:45',
|
||||||
|
'14:30',
|
||||||
|
'15:15',
|
||||||
|
'16:00',
|
||||||
|
'16:45',
|
||||||
|
'17:30',
|
||||||
|
'18:15',
|
||||||
|
'19:00',
|
||||||
|
'19:45',
|
||||||
|
'20:30',
|
||||||
|
'21:15',
|
||||||
|
'22:00',
|
||||||
|
],
|
||||||
|
[StartTimeClass.Third]: [
|
||||||
|
'07:30',
|
||||||
|
'08:15',
|
||||||
|
'09:00',
|
||||||
|
'09:45',
|
||||||
|
'10:30',
|
||||||
|
'11:15',
|
||||||
|
'12:00',
|
||||||
|
'12:45',
|
||||||
|
'13:30',
|
||||||
|
'14:15',
|
||||||
|
'15:00',
|
||||||
|
'15:45',
|
||||||
|
'16:30',
|
||||||
|
'17:15',
|
||||||
|
'18:00',
|
||||||
|
'18:45',
|
||||||
|
'19:30',
|
||||||
|
'20:15',
|
||||||
|
'21:00',
|
||||||
|
'21:45',
|
||||||
|
'22:30',
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
const TYPING_DELAY_MS = 2
|
const TYPING_DELAY_MS = 2
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
|
@ -234,6 +333,17 @@ export class BaanReserverenService {
|
||||||
return lastDayOfMonth.add(daysToAdd, 'day')
|
return lastDayOfMonth.add(daysToAdd, 'day')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async navigateToReservationPrompt(courtSlot: CourtSlot, date: Dayjs) {
|
||||||
|
this.loggerService.debug('Navigating to reservation prompt', {
|
||||||
|
courtSlot,
|
||||||
|
date,
|
||||||
|
})
|
||||||
|
const utcSeconds = date.valueOf() / 1000
|
||||||
|
await this.page.goto(
|
||||||
|
`${BAAN_RESERVEREN_ROOT_URL}/reservations/make/${courtSlot}/${utcSeconds}`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private async navigateToDay(date: Dayjs) {
|
private async navigateToDay(date: Dayjs) {
|
||||||
this.loggerService.debug('Navigating to day', { date })
|
this.loggerService.debug('Navigating to day', { date })
|
||||||
if (this.getLastVisibleDay().isBefore(date)) {
|
if (this.getLastVisibleDay().isBefore(date)) {
|
||||||
|
|
@ -473,7 +583,7 @@ export class BaanReserverenService {
|
||||||
throw new RunnerReservationConfirmButtonError(e)
|
throw new RunnerReservationConfirmButtonError(e)
|
||||||
})
|
})
|
||||||
await this.page
|
await this.page
|
||||||
.waitForSelector('input#__make_submit2')
|
.waitForSelector('input#__make_submit2', { timeout: 500 }) // quick timeout here because all it is checking is that the reservation is still available
|
||||||
.then((b) => b?.click())
|
.then((b) => b?.click())
|
||||||
.catch((e: Error) => {
|
.catch((e: Error) => {
|
||||||
throw new RunnerReservationConfirmSubmitError(e)
|
throw new RunnerReservationConfirmSubmitError(e)
|
||||||
|
|
@ -565,6 +675,15 @@ export class BaanReserverenService {
|
||||||
return courtStatuses
|
return courtStatuses
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getCourtSlotsForDate(date: Dayjs) {
|
||||||
|
const time = date.format('HH:mm')
|
||||||
|
for (const [timeClass, times] of Object.entries(StartTimeClassStartTimes)) {
|
||||||
|
if (times.includes(time)) {
|
||||||
|
return StartTimeClassCourtSlots[timeClass as StartTimeClass]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async performReservation(
|
public async performReservation(
|
||||||
reservation: Reservation,
|
reservation: Reservation,
|
||||||
timeSensitive = true,
|
timeSensitive = true,
|
||||||
|
|
@ -582,6 +701,31 @@ export class BaanReserverenService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async performSpeedyReservation(reservation: Reservation) {
|
||||||
|
await this.init()
|
||||||
|
const courtSlots = this.getCourtSlotsForDate(reservation.dateRangeStart)
|
||||||
|
|
||||||
|
if (courtSlots == null) {
|
||||||
|
throw new NoCourtAvailableError('Improper time for courts')
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const courtSlot of courtSlots) {
|
||||||
|
await this.navigateToReservationPrompt(
|
||||||
|
courtSlot,
|
||||||
|
reservation.dateRangeStart,
|
||||||
|
)
|
||||||
|
await this.selectOwner(reservation.ownerId)
|
||||||
|
await this.selectOpponents(reservation.opponents)
|
||||||
|
await this.confirmReservation().catch((error: Error) => {
|
||||||
|
if (error instanceof RunnerReservationConfirmSubmitError) {
|
||||||
|
this.loggerService.warn('Court taken, retrying', { courtSlot })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
throw error
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async addReservationToWaitList(
|
public async addReservationToWaitList(
|
||||||
reservation: Reservation,
|
reservation: Reservation,
|
||||||
timeSensitive = true,
|
timeSensitive = true,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue