@transportme/vline-nsp-reader 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ export default {
2
+ VLINE_HOST: 'https://vline.com.au',
3
+ HEAT_PAGE: '/Timetables/heat'
4
+ }
@@ -0,0 +1,93 @@
1
+ import fetch from 'node-fetch';
2
+ import constants from './constants.mjs'
3
+ import { load as parseHTML } from 'cheerio'
4
+ import async from 'async'
5
+ import fs from 'fs/promises'
6
+ import path from 'path'
7
+ import { pipeline } from 'stream/promises'
8
+ import { createWriteStream } from 'fs'
9
+ import PassPDFReader from '../pass/pass-pdf-reader.mjs'
10
+
11
+ export class HeatTimetable {
12
+
13
+ files = []
14
+
15
+ constructor() {
16
+ }
17
+
18
+ addFile(file) {
19
+ this.files.push(file)
20
+ }
21
+
22
+ async saveFiles(outputDir) {
23
+ try {
24
+ await fs.mkdir(outputDir)
25
+ } catch (e) {}
26
+ await async.forEach(this.files, async file => {
27
+ await file.download(outputDir)
28
+ })
29
+ }
30
+
31
+ }
32
+
33
+ export class HeatTimetableFile {
34
+
35
+ line
36
+ type
37
+ href
38
+
39
+ #filePath
40
+
41
+ constructor(line, type, href) {
42
+ this.line = line
43
+ this.type = type
44
+ this.href = href
45
+ }
46
+
47
+ async download(outputDir) {
48
+ this.#filePath = path.join(outputDir, `${this.line} - ${this.type}.pdf`)
49
+
50
+ let response = await fetch(constants.VLINE_HOST + this.href)
51
+ let outputStream = createWriteStream(this.#filePath)
52
+
53
+ await pipeline(response.body, outputStream)
54
+ }
55
+
56
+ setFilePath(filePath) {
57
+ this.#filePath = filePath
58
+ }
59
+
60
+ async extractRuns() {
61
+ let reader = new PassPDFReader(this.#filePath)
62
+ return await reader.readRuns()
63
+ }
64
+
65
+ static fromFile(pathname) {
66
+ const filename = path.basename(pathname).replace('.pdf', '')
67
+ const [line, type] = filename.split(' - ')
68
+ const file = new HeatTimetableFile(line, type, '')
69
+ file.setFilePath(pathname)
70
+
71
+ return file
72
+ }
73
+
74
+ }
75
+
76
+ export async function getHeatTimetables() {
77
+ let body = await (await fetch(constants.VLINE_HOST + constants.HEAT_PAGE)).text()
78
+ let $ = parseHTML(body)
79
+
80
+ let buttons = Array.from($('div.TimeTableHeaderMainContainer > a.button-file-link-caption'))
81
+ const timetable = new HeatTimetable()
82
+
83
+ buttons.forEach(button => {
84
+ let text = $(button).text().replace(/PDF.+/, '').replace(' extreme heat timetable', '').replace(/via .+\(/, '(').replace(/ \/ \w+/, '')
85
+ let data = text.match(/([\w ]+) \((.+)\)/)
86
+ if (!data) return null
87
+
88
+ let [_, line, type] = data
89
+ timetable.addFile(new HeatTimetableFile(line, type, $(button).attr('href')))
90
+ })
91
+
92
+ return timetable.files.length ? timetable : null
93
+ }
@@ -43,6 +43,7 @@ export default class PassPDFReader {
43
43
  }
44
44
  if (stationName === 'Service Information') continue
45
45
  if (!stopData || stopData.length === 1) continue
46
+ if (stationName === 'Change Service' && !currentRun.stops.length) continue
46
47
  if (stationName === 'Change Service' && stopData.length) {
47
48
  currentRun.stops.push(lastStation)
48
49
  runs.push(currentRun)
@@ -67,8 +68,8 @@ export default class PassPDFReader {
67
68
  }
68
69
  }
69
70
 
70
- currentRun.stops.push(lastStation)
71
- runs.push(currentRun)
71
+ if (lastStation) currentRun.stops.push(lastStation)
72
+ if (currentRun.stops.length) runs.push(currentRun)
72
73
  }
73
74
  }
74
75
 
@@ -56,11 +56,12 @@ export default class PassTableReader {
56
56
  const tableData = []
57
57
 
58
58
  page.Texts.forEach(text => {
59
+ if (text.y < tableStart - commonHeight || text.y > tableEnd + commonHeight * 1.5) return
60
+
59
61
  let textContent = decodeURIComponent(text.R[0].T)
60
62
 
61
- let firstYGreater = rowStarts.find(r => r > text.y + 0.3)
62
- let currentRow = rowStarts.indexOf(firstYGreater) - 1
63
- if (currentRow < 0) return
63
+ let currentRow = rowStarts.findIndex(r => r > text.y + 0.3) - 1
64
+ if (currentRow < 0) currentRow = rowStarts.length - 1
64
65
 
65
66
  let currentCol = colStarts.findLastIndex(c => c < text.x + 0.4)
66
67
 
package/lib.mjs CHANGED
@@ -1,9 +1,13 @@
1
+ import { getHeatTimetables, HeatTimetable, HeatTimetableFile } from './lib/heat/vline-heat.mjs'
1
2
  import { getNSPVersion, NSPFile, NSPVersion } from './lib/nsp/vline-nsp.mjs'
2
3
  import PassPDFReader from './lib/pass/pass-pdf-reader.mjs'
3
4
 
4
5
  export {
5
6
  getNSPVersion,
7
+ getHeatTimetables,
6
8
  NSPFile,
7
9
  NSPVersion,
8
- PassPDFReader
10
+ PassPDFReader,
11
+ HeatTimetable,
12
+ HeatTimetableFile
9
13
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transportme/vline-nsp-reader",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "main": "lib.mjs",
5
5
  "scripts": {
6
6
  "test": "mocha './{,!(node_modules)/**}/*.test.mjs'"