<commit_before>"use strict";

var request = require('request');
var jsdom = require('jsdom').jsdom;
var util = require("util");
var EventEmitter = require("events").EventEmitter;
var _ = require('lodash');
var TimetableEntry = require('./TimetableEntry');

var Timetable = function(studentId) {
	this.studentId = studentId;
	this.completedTimestamp = null;
	this.isParsing = false;
	this.messages = [];
	this.entries = [];
};

util.inherits(Timetable, EventEmitter);

Timetable.prototype.orderedEntries = function() {
	return _.sortBy(this.entries, 'startTime');
};

Timetable.prototype.finished = function() {
	return this.completedTimestamp !== null;
};

Timetable.prototype.addMessage = function(message) {
	this.messages.push(message);
	this.emit('addMessage', message);
};

Timetable.prototype.getDataForWeek = function(week, viewState, viewStateGenerator, eventValidation, callback) {
	let self = this;
	this.messages.push(`Getting data for week ${week}`);

	request.post('https://mytimetable.hud.ac.uk/schedule_S.aspx', {
			form: {
				'ctl00$ContentPlaceHolder1$HF_stuNum': self.studentId,
				'ctl00$ContentPlaceHolder1$ddlWeeks': week,
				'__EVENTTARGET': 'ctl00$ContentPlaceHolder1$ddlWeeks',
				'ctl00$ScriptManager1': 'ctl00$ContentPlaceHolder1$UpdatePanel1|ctl00$ContentPlaceHolder1$ddlWeeks',
				'__EVENTVALIDATION': eventValidation,
				'__VIEWSTATEGENERATOR': viewStateGenerator,
				'__VIEWSTATE': viewState
			}
		}, function(err, httpResponse, body) {
			if (err) {
				self.emit('error', err);
			} else {
				jsdom.env(
					body,
					function (err, window) {
						if (err) {
							self.emit('error', err);
						} else {
							let tableContainer = window.document.getElementById('ctl00_ContentPlaceHolder1_Schedule1');
							if (tableContainer !== null) {
								let table = tableContainer.firstChild;
								self.parseTimetableHTML(table, week, callback);
							}
						}
					}
				);

			}
		});
};

Timetable.prototype.parseTimetableHTML = function(table, date, callback) {
	let self = this;

	this.addMessage(`Getting data for week ${date}`);

	let rows = table.tBodies[0].rows;
	let rowsCount = rows.length;
	if (rowsCount == 7) {
		// Start at 2 because the first row has all of the times in and
		// the seonc row has nothing (just for layout reasons I guess)
		// Yey for semantics :)
		for (var i = 2; i < 7; i++) {
			let row = rows[i];

			let daysOffset = i - 2;
			let baseDate = new Date(date);
			baseDate.setDate(baseDate.getDate() + daysOffset);

			let lectures = row.getElementsByClassName('lect');
			let practicals = row.getElementsByClassName('prac');

			this.addMessage(`Found ${lectures.length} lectures`);
			this.addMessage(`Found ${practicals.length} lectures`);

			function parseEntries(entries, entryType) {
				_.forEach(entries, function(entrie) {
					let containingSpan = entrie.firstChild;
					var textNodeIndex = 0;
<commit_msg>Updated messages about number of lectures and practicals found in a timetable to be correct and more verbose<commit_after>"use strict";

var request = require('request');
var jsdom = require('jsdom').jsdom;
var util = require("util");
var EventEmitter = require("events").EventEmitter;
var _ = require('lodash');
var TimetableEntry = require('./TimetableEntry');

var Timetable = function(studentId) {
	this.studentId = studentId;
	this.completedTimestamp = null;
	this.isParsing = false;
	this.messages = [];
	this.entries = [];
};

util.inherits(Timetable, EventEmitter);

Timetable.prototype.orderedEntries = function() {
	return _.sortBy(this.entries, 'startTime');
};

Timetable.prototype.finished = function() {
	return this.completedTimestamp !== null;
};

Timetable.prototype.addMessage = function(message) {
	this.messages.push(message);
	this.emit('addMessage', message);
};

Timetable.prototype.getDataForWeek = function(week, viewState, viewStateGenerator, eventValidation, callback) {
	let self = this;
	this.messages.push(`Getting data for week ${week}`);

	request.post('https://mytimetable.hud.ac.uk/schedule_S.aspx', {
			form: {
				'ctl00$ContentPlaceHolder1$HF_stuNum': self.studentId,
				'ctl00$ContentPlaceHolder1$ddlWeeks': week,
				'__EVENTTARGET': 'ctl00$ContentPlaceHolder1$ddlWeeks',
				'ctl00$ScriptManager1': 'ctl00$ContentPlaceHolder1$UpdatePanel1|ctl00$ContentPlaceHolder1$ddlWeeks',
				'__EVENTVALIDATION': eventValidation,
				'__VIEWSTATEGENERATOR': viewStateGenerator,
				'__VIEWSTATE': viewState
			}
		}, function(err, httpResponse, body) {
			if (err) {
				self.emit('error', err);
			} else {
				jsdom.env(
					body,
					function (err, window) {
						if (err) {
							self.emit('error', err);
						} else {
							let tableContainer = window.document.getElementById('ctl00_ContentPlaceHolder1_Schedule1');
							if (tableContainer !== null) {
								let table = tableContainer.firstChild;
								self.parseTimetableHTML(table, week, callback);
							}
						}
					}
				);

			}
		});
};

Timetable.prototype.parseTimetableHTML = function(table, date, callback) {
	let self = this;

	this.addMessage(`Getting data for week ${date}`);

	let rows = table.tBodies[0].rows;
	let rowsCount = rows.length;
	if (rowsCount == 7) {
		// Start at 2 because the first row has all of the times in and
		// the seonc row has nothing (just for layout reasons I guess)
		// Yey for semantics :)
		for (var i = 2; i < 7; i++) {
			let row = rows[i];

			let daysOffset = i - 2;
			let baseDate = new Date(date);
			baseDate.setDate(baseDate.getDate() + daysOffset);

			let lectures = row.getElementsByClassName('lect');
			let practicals = row.getElementsByClassName('prac');

			if (lectures.length == 1) {
				this.addMessage(`Found 1 lecture in week beginning ${date}`);
			} else {
				this.addMessage(`Found ${lectures.length} lectures in week beginning ${date}`);
			}

			if (practicals.length == 1) {
				this.addMessage(`Found 1 practical in week beginning ${date}`);
			} else {
				this.addMessage(`Found ${practicals.length} practicals in week beginning ${date}`);
			}

			function parseEntries(entries, entryType) {
				_.forEach(entries, function(entrie) {
					let containingSpan = entrie.firstChild;
					var textNodeIndex = 0;

{'fraction_non_alphanumeric': 0.13606981254040076, 'fraction_numerical': 0.010342598577892695, 'mean_word_length': 4.11065235342692, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7176582', 'n_tokens_mistral': 2311, 'n_tokens_neox': 1931, 'n_words': 445}