-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
102 lines (88 loc) · 3.05 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
const bookingURL = '/SouthWarkPark/Booking/Book';
const sessionURL = '/v0/VenueBooking/SouthwarkPark/GetVenueSessions';
const bookingParams = ['ResourceID', 'SessionID', 'Date', 'startTime', 'endTime'];
const sessionParams = ['startDate', 'endDate'];
const courtPreference = [3, 1, 4, 2];
const defaultFilters = {
is_available: true,
is_full_hour: true
}
const latestFilters = {
...defaultFilters,
is_late_evening: true
}
init()
async function init () {
const res = await getSessions(7, latestFilters);
const json = await res.json();
const sessions = await json.sort(byCourtPreference);
for (const session of sessions) {
try {
bookSession(session);
break;
} catch (e) {
console.warn(e);
}
}
}
function byCourtPreference (a, b) {
return courtPreference.indexOf(a.courtNumber) - courtPreference.indexOf(b.courtNumber);
}
async function getSessions(startOffset = 0, filters = defaultFilters){
const today = new Date();
const maxPeriod = today.getHours() >= 20 ? 7 : 6;
const startDate = dateByOffset(today, startOffset).toISOString().slice(0, 10);
const endDate = dateByOffset(today, maxPeriod).toISOString().slice(0, 10);
const res = await fetchSessionsRaw(startDate, endDate);
const json = await res.json();
const processedData = processRawSessionData(json);
return filterSessions(processedData, filters);
}
function filterSessions(sessions, opts){
return sessions.filter(item => (
Object
.entries(opts)
.every(([key, val]) => item[key] == val)
))
}
function processRawSessionData(data){
return data.Resources
.flatMap(court => court.Days
.flatMap(day => day.Sessions
.map(session => {
return {
is_available: !!session.Capacity,
is_full_hour: session.EndTime - session.StartTime >= 60,
is_late_evening: session.StartTime >= 1140,
startTime: session.StartTime,
endTime: session.EndTime,
SessionID: session.ID,
ResourceID: court.ID,
courtNumber: court.Number,
Date: day.Date.slice(0, 10),
originalResource: session
}
})))
}
function fetchSessionsRaw(startDate, endDate){
const query = new URLSearchParams({ startDate, endDate }).toString();
return fetch(`${ sessionURL }?${ query }`);
}
function bookSession(params){
const validatedOpts = reduceObject(params, bookingParams);
const query = new URLSearchParams(validatedOpts).toString();
return fetch(`${ bookingURL }?${ query }`);
}
/**
* Helpers
*/
function dateByOffset(date, offset){
let newDate = new Date(date + offset);
newDate.setDate(date.getDate() + offset);
return newDate;
}
function reduceObject(obj, validKeys){
return Object.fromEntries(
Object.entries(obj).filter(([key,]) => validKeys.includes(key))
)
}