Skip to content

Commit

Permalink
feat/unittesting (#11)
Browse files Browse the repository at this point in the history
* Add options for multiple Connections
  • Loading branch information
joachimprinzbach authored Nov 26, 2017
1 parent b1794a2 commit f825ba8
Show file tree
Hide file tree
Showing 8 changed files with 337 additions and 128 deletions.
26 changes: 24 additions & 2 deletions config.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,26 @@
{
"chatId": "123456789",
"token": "12345678:ASADJKJSADJ2jbJLJKBJB-Abcd"
"token": "12345678:ASADJKJSADJ2jbJLJKBJB-Abcd",
"delay": "4",
"connections": [
{
"connectionId": "1",
"chatId": "123456789",
"start": "Müllheim (Baden)",
"destination": "Basel SBB",
"exactConnection": {
"hour": "7",
"minute": "49"
},
"crawlStart": {
"hour": "6",
"minute": "50"
},
"crawlEnd": {
"hour": "9",
"minute": "1"
},
"runOnWeekend": false,
"minDelay": "1"
}
]
}
26 changes: 26 additions & 0 deletions crawl.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const onTime = require('./on-time/crawl');
const sinon = require('sinon');
const moment = require('moment');
const assert = require('assert');

describe('On Time', () => {
xit('should work', async () => {
await onTime(START_STATION, TARGET_STATION, shouldRunOnWeekend, spy);

assert.equal(1, spy.callCount);
assert.equal(false, spy.args[0][0]);
assert.equal(shouldRunOnWeekend, spy.args[0][1]);
assert.equal('07:49', spy.args[0][2]);
assert.equal(false, spy.args[0][3]);
assert.equal(START_STATION, getStartStationValue(spy));
assert.equal(TARGET_STATION, getTargetStationValue(spy));
});
});

const getStartStationValue = spy => {
return spy.args[0][4];
};

const getTargetStationValue = spy => {
return spy.args[0][5];
};
78 changes: 6 additions & 72 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,83 +1,17 @@
const puppeteer = require('puppeteer');
const TelegramBot = require('node-telegram-bot-api');
const moment = require('moment-timezone');
moment.locale('de');
moment.tz.setDefault("Europe/Berlin");
const getDelays = require('./on-time/db-facade');

const config = require('./config.json');
const dbSearchPageURL = 'https://www.bahn.de/p/view/index.shtml';

const app = require("express")();
const port = process.env.PORT || 4201;

const chatId = process.env.TELEGRAM_CHAT_ID || config.chatId;
const token = process.env.TELEGRAM_TOKEN || config.token;
const bot = new TelegramBot(token, {polling: false});
const config = require('./config.json');
const crawl = require('./on-time/crawl');

app.listen(port, () => {
const delay = 1000 * 60 * 4;
const START_STATION = 'Müllheim (Baden)';
const TARGET_STATION = 'Basel SBB';
const shouldRunOnWeekend = true;
const sendStartMessage = false;
const delay = 1000 * 60 * config.delay;
try {
if (sendStartMessage) {
const version = require('./package.json').version;
const githubUrl = 'https://github.com/joachimprinzbach/db-ontime';
const versionText = "Bot is running version " + version + ". Report any issues on [Github](" + githubUrl + ")!";
bot.sendMessage(chatId, versionText, {parse_mode: 'Markdown'});
}
const crawlFunc = crawlForDelays.bind(this, START_STATION, TARGET_STATION, shouldRunOnWeekend);
const crawlFunc = crawl.bind(this);
crawlFunc();
setInterval(crawlFunc, delay);
}
catch (e) {
console.error("Error occurred: ", e);
} catch (error) {
console.error("Error occurred: ", error);
}
});

const crawlForDelays = async (START_STATION, TARGET_STATION, shouldRunOnWeekend) => {
const now = moment();
const exactDepartureTime = moment({hour: 7, minute: 49}).format('HH:mm');
const startCrawlTime = moment({hour: 6, minute: 50});
const finishCrawlTime = moment({hour: 9, minute: 1});
const isWorkingDay = !(now.weekday() == 5 || now.weekday() == 6);
const isInTimeFrame = now.isBetween(startCrawlTime, finishCrawlTime);
console.log("Time: " + now.format('HH:mm'));
console.log("StartTime: " + startCrawlTime.format('HH:mm'));
console.log("FinishTime: " + finishCrawlTime.format('HH:mm'));
console.log('shouldRunOnWeekend: ', shouldRunOnWeekend, ' isWorkingDay: ', isWorkingDay, ' isInTimeFrame: ', isInTimeFrame);
if ((isWorkingDay || shouldRunOnWeekend) && isInTimeFrame) {
console.log('Crawling...');
const {browser, page} = await openBrowserWindow(dbSearchPageURL);
const messages = await getDelays(page, START_STATION, TARGET_STATION, exactDepartureTime);
messages.forEach(msg => {
console.log('Sending Telegram msg: ', msg);
bot.sendMessage(chatId, msg, {parse_mode: 'Markdown'});
});
if (messages.length == 0) {
console.log('No delays found.');
} else {
console.log('Found delays. Message has been sent.');
}
browser.close();
} else {
console.log('Not checking. Outside of time window.');
}
}

const openBrowserWindow = async urlToOpen => {
const browser = await puppeteer.launch({
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
],
});
const page = await browser.newPage();
page.setViewport({width: 1200, height: 900});
await page.goto(urlToOpen, {waitUntil: 'networkidle'});
return {browser, page};
};

module.exports = app;
55 changes: 55 additions & 0 deletions on-time/crawl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
const getDelays = require('./db-facade');
const dbSearchPageURL = 'https://www.bahn.de/p/view/index.shtml';
const puppeteer = require('puppeteer');
const moment = require('moment-timezone');
const config = require('../config.json');
const TelegramBot = require('node-telegram-bot-api');
const token = process.env.TELEGRAM_TOKEN || config.token;
const bot = new TelegramBot(token, {polling: false});
moment.locale('de');
moment.tz.setDefault("Europe/Berlin");

const crawlForDelays = async () => {
for (let connection of config.connections) {
const now = moment();
const exactDepartureTime = moment(connection.exactConnection).format('HH:mm');
const startCrawlTime = moment(connection.crawlStart);
const finishCrawlTime = moment(connection.crawlEnd);
const isWorkingDay = !(now.weekday() == 5 || now.weekday() == 6);
const isInTimeFrame = now.isBetween(startCrawlTime, finishCrawlTime);
if ((isWorkingDay || connection.runOnWeekend) && isInTimeFrame) {
console.log('Crawling...');
const {browser, page} = await openBrowserWindow(dbSearchPageURL);
const messages = await getDelays(page, connection.start, connection.destination, exactDepartureTime, connection.minDelay);
messages.forEach(msg => {
console.log('Sending Telegram msg: ', msg);
const chatId = "TELEGRAM_CHAT_ID_" + connection.connectionId;
console.log(chatId);
bot.sendMessage(process.env[chatId] || connection.chatId, msg, {parse_mode: 'Markdown'});
});
if (messages.length == 0) {
console.log('No delays found.');
} else {
console.log('Found delays. Message has been sent.');
}
browser.close();
} else {
console.log('Not checking. Outside of time window.');
}
}
};

const openBrowserWindow = async urlToOpen => {
const browser = await puppeteer.launch({
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
],
});
const page = await browser.newPage();
page.setViewport({width: 1200, height: 900});
await page.goto(urlToOpen, {waitUntil: 'networkidle2'});
return {browser, page};
};

module.exports = crawlForDelays;
4 changes: 2 additions & 2 deletions on-time/db-facade.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const searchForConnections = require('./search-page.facade');
const getDelayMessages = require('./result-page.facade');

const getDelays = async (page, startStation, targetStation, exactDepartureTime) => {
const getDelays = async (page, startStation, targetStation, exactDepartureTime, minDelay) => {
await searchForConnections(page, startStation, targetStation, exactDepartureTime);
return getDelayMessages(page, exactDepartureTime);
return getDelayMessages(page, exactDepartureTime, minDelay);
};

module.exports = getDelays;
23 changes: 10 additions & 13 deletions on-time/result-page.facade.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const cheerio = require('cheerio');
const delayThreshold = 0;

const getDelayMessages = async (page, exactDepartureTime) => {
const getDelayMessages = async (page, exactDepartureTime, minDelay) => {
const messages = [];
await page.waitFor(2 * 1000);
const resultSelector = '#resultsOverview';
Expand All @@ -12,22 +11,20 @@ const getDelayMessages = async (page, exactDepartureTime) => {
const tableRows = $(connection).children('tr');
const departureRow = $(tableRows).eq(0).children('td');
const arrivalRow = $(tableRows).eq(1).children('td');
const scheduledStartTime = $(departureRow).eq(1);
const scheduledStartTime = $(departureRow).eq(2);
const startStationName = $(departureRow).eq(0).text();
const destinationStationName = $(arrivalRow).eq(0).text();
const scheduledDepartureTime = $(scheduledStartTime).clone().children().remove().end().text();
const delay = $(scheduledStartTime).children('span.ontime').first().text();
const hardDelay = $(scheduledStartTime).children('span.delay').first().text();
const delayTime = parseInt(delay.replace(/\+/g, ''), 10);
const hardDelayTime = parseInt(hardDelay.replace(/\+/g, ''), 10);
logConnectionInfo(startStationName, destinationStationName, scheduledDepartureTime, delayTime);
if (trainHasDelay(delayTime, hardDelayTime) && exactTimeIsMatching(scheduledDepartureTime, exactDepartureTime)) {
console.log(hardDelayTime);
console.log(delayTime);
let finalDelayTime = hardDelayTime;
if (isNaN(hardDelayTime)) {
finalDelayTime = delayTime;
}
let finalDelayTime = hardDelayTime;
if (isNaN(hardDelayTime)) {
finalDelayTime = delayTime;
}
logConnectionInfo(startStationName, destinationStationName, scheduledDepartureTime, finalDelayTime);
if (trainHasDelay(delayTime, hardDelayTime, minDelay) && exactTimeIsMatching(scheduledDepartureTime, exactDepartureTime)) {
const text = "*+" + finalDelayTime + " - VERSPÄTUNG!*\n" + scheduledDepartureTime + " Uhr\nvon: " + startStationName.trim() + "\nnach: " + destinationStationName.trim() + "\n*" + finalDelayTime + " Minuten*";
messages.push(text);
console.log(text);
Expand All @@ -36,8 +33,8 @@ const getDelayMessages = async (page, exactDepartureTime) => {
return messages;
};

const trainHasDelay = (delayTime, hardDelayTime) => {
const hasDelay = (delayTime > delayThreshold) || (hardDelayTime > delayThreshold);
const trainHasDelay = (delayTime, hardDelayTime, minDelay) => {
const hasDelay = (delayTime > minDelay) || (hardDelayTime > minDelay);
return hasDelay;
};

Expand Down
Loading

0 comments on commit f825ba8

Please sign in to comment.