diff --git a/booking-checker.html b/booking-checker.html new file mode 100644 index 000000000..9d2b7ded4 --- /dev/null +++ b/booking-checker.html @@ -0,0 +1,530 @@ + + + + + + EDR Booking Checker + + + + +

EDR Booking Checker

+ +
+ + +

No trailing slash. e.g. https://api.edrsc.com

+
+ +
+ + +

Supports any format: one per line, comma-separated, or {REF1,REF2} groups.

+ +
+ + + + +
+
+
+
+
+ +
+
+ +
+ + + + + +
+
+ + + + + + + +
+ +
+ + + + + + + + +
JourneyDuplicate Bookings
+
+
+ + + + + diff --git a/booking-extractor.html b/booking-extractor.html new file mode 100644 index 000000000..844c98b2c --- /dev/null +++ b/booking-extractor.html @@ -0,0 +1,256 @@ + + + + + + EDR Booking Extractor + + + + +

EDR Booking Extractor

+ +
+ +
+ + Drop bookings.json here or click to browse +
+

Accepts a JSON array of bookings or an object with a bookings key.

+
+ + + +
+
+ +
+
+
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + +
#Booking RefStatusBooking TypePhoneEmailDepartureOriginDestinationPassenger(s)Coach - SeatPayment MethodPayment StatusTotal (DJF)Created At
+
+
+ + + + + diff --git a/booking-proxy.mjs b/booking-proxy.mjs new file mode 100644 index 000000000..27f9248ee --- /dev/null +++ b/booking-proxy.mjs @@ -0,0 +1,53 @@ +import http from 'http'; +import https from 'https'; +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const PORT = 8080; +const __dir = path.dirname(fileURLToPath(import.meta.url)); + +const server = http.createServer((req, res) => { + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); + + if (req.method === 'OPTIONS') { res.writeHead(204); res.end(); return; } + + // Serve any .html file in the same directory + if (req.url === '/' || req.url.endsWith('.html')) { + const filename = req.url === '/' ? 'booking-checker.html' : req.url.slice(1); + const filepath = path.join(__dir, filename); + if (fs.existsSync(filepath)) { + res.writeHead(200, { 'Content-Type': 'text/html' }); + fs.createReadStream(filepath).pipe(res); + } else { + res.writeHead(404); res.end('Not found'); + } + return; + } + + // Proxy /proxy?url= + if (req.url.startsWith('/proxy?url=')) { + const target = decodeURIComponent(req.url.slice('/proxy?url='.length)); + const parsed = new URL(target); + const mod = parsed.protocol === 'https:' ? https : http; + const options = { + hostname: parsed.hostname, + port: parsed.port || (parsed.protocol === 'https:' ? 443 : 80), + path: parsed.pathname + parsed.search, + method: req.method, + headers: { ...req.headers, host: parsed.hostname }, + }; + const proxy = mod.request(options, (apiRes) => { + res.writeHead(apiRes.statusCode, apiRes.headers); + apiRes.pipe(res); + }); + proxy.on('error', (e) => { res.writeHead(502); res.end(e.message); }); + req.pipe(proxy); + return; + } + + res.writeHead(404); res.end(); +}); + +server.listen(PORT, () => console.log(`Booking checker: http://localhost:${PORT}/booking-checker.html`)); diff --git a/ticket-extractor.html b/ticket-extractor.html new file mode 100644 index 000000000..17be60576 --- /dev/null +++ b/ticket-extractor.html @@ -0,0 +1,239 @@ + + + + + + EDR Ticket Extractor + + + + +

EDR Ticket Extractor

+ +
+ +
+ + Drop tickets.json here or click to browse +
+

Accepts a JSON array of tickets or an object with a tickets key.

+
+ + + +
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + +
#Ticket No.Booking RefPassengerPhoneEmailJourney TypeOriginDestinationSeat ClassCoachSeat
+
+
+ + + + +