Skip to content

Instantly share code, notes, and snippets.

@Pitbi
Created October 26, 2012 19:53
Show Gist options
  • Save Pitbi/3961068 to your computer and use it in GitHub Desktop.
Save Pitbi/3961068 to your computer and use it in GitHub Desktop.
var util = require("util");
var RfactorXmlParser = require("./rfactor_xml_parser");
var Qualification = require("../models/qualification");
var QualificationParser = function QualificationParser(filePath) {
console.log("QualificationPARSER");
this.constructor.super_.call(this, filePath);
this.Session = Qualification;
};
util.inherits(QualificationParser, RfactorXmlParser);
module.exports = QualificationParser;
var util = require("util");
var RfactorXmlParser = require("./rfactor_xml_parser");
var Race = require("../models/race");
var RaceParser = function RaceParser(filePath) {
this.constructor.super_.call(this, filePath);
this.Session = Race;
};
util.inherits(RaceParser, RfactorXmlParser);
module.exports = RaceParser;
var fs = require("fs");
var async = require("async");
var libxmljs = require("libxmljs");
var Iconv = require("iconv").Iconv;
var Driver = require("../models/driver");
var Race = require("../models/race");
var Track = require("../models/track");
var Mod = require("../models/mod");
var RFactorXmlParser = function RFactorXmlParser(filePath) {
this.filePath = filePath;
};
RFactorXmlParser.prototype.parse = function parse(callback) {
var self = this;
fs.readFile(self.filePath, function (err, contents) {
var iconv = new Iconv("ISO-8859-15", "UTF-8");
var utf8Contents = iconv.convert(contents);
self.xml = libxmljs.parseXml(utf8Contents);
async.series([
function (callback) { self._loadTrack(callback); },
function (callback) { self._loadMod(callback); },
function (callback) { self._loadDrivers(callback); },
function (callback) { self._loadDriveSession(callback); }
], function(err, results) {
var message = results[results.length - 1];
callback(err, message);
});
});
}
RFactorXmlParser.prototype._loadTrack = function _loadTrack(callback) {
var self = this;
var trackAttributes = {
name : self.xml.get("/rFactorXML/RaceResults/TrackEvent").text(),
length : self.xml.get("/rFactorXML/RaceResults/TrackLength").text()
};
console.log("1", trackAttributes.name);
Track.findOrCreate(trackAttributes, function (err, track) {
console.log("2");
if (err)
return callback(err);
self.track = track;
callback(null);
});
};
RFactorXmlParser.prototype._loadMod = function _loadMod(callback) {
var self = this;
var modName = self.xml.get("/rFactorXML/RaceResults/Mod").text();
console.log("3");
Mod.findOrCreate({name: modName}, function (err, mod) {
console.log("4");
self.mod = mod;
self._addVehiclesToMod();
self._addTrackToMod();
mod.save(function (err) {
if (err)
return callback(err);
callback();
});
});
};
RFactorXmlParser.prototype._addVehiclesToMod = function _addVehiclesToMod() {
var self = this;
var vehicleNames = [];
var drivers = self.xml.find("//Driver");
self.mod.vehicles.forEach(function (vehicle) {
vehicleNames.push(vehicle.name);
});
drivers.forEach(function (driver) {
var vehicleName = driver.get("CarType").text();
var vehicleClass = driver.get("CarClass").text();
if (vehicleNames.indexOf(vehicleName) == -1) {
self.mod.vehicles.push({name: vehicleName, group: vehicleClass});
vehicleNames.push(vehicleName);
}
});
};
RFactorXmlParser.prototype._addTrackToMod = function _addTrackToMod() {
var self = this;
var tracks = [];
self.mod.tracks.forEach(function (track) {
tracks.push("" + track);
});
var trackId = "" + self.track._id;
if(tracks.indexOf(trackId) === -1) {
self.mod.tracks.push(self.track);
}
};
RFactorXmlParser.prototype._loadDrivers = function _loadDrivers(callback) {
var self = this;
var chatLogs = self.xml.find("//Chat");
async.forEach(chatLogs, tokenSearch, callback);
function tokenSearch(value, callback) {
var chatLine = value.text();
var tokenFound = /^(.*): \[!(.*)\]/.exec(chatLine);
if (tokenFound) {
Driver.findOne({token: tokenFound[2]}).exec(function (err, driver) {
if (driver) {
if (err)
return callback(err);
driver.gameName = tokenFound[1];
driver.skipPasswordValidation = true;
driver.save(callback);
} else {
callback();
}
});
} else {
callback();
}
};
}
RFactorXmlParser.prototype._loadDriveSession = function _loadDriveSession(callback) {
var self = this;
var drivers = self.xml.find("//Driver");
var dateText = self.xml.get("/rFactorXML/RaceResults/TimeString").text();
var dateMatches = /^(\d{4})\/(\d{2})\/(\d{2}) (\d\d):(\d\d):(\d\d)/.exec(dateText);
var date = new Date(dateMatches[1], dateMatches[2], dateMatches[3], dateMatches[4], dateMatches[5], dateMatches[6]);
self.Session.findOne({date: date}).exec(function (err, existingSession) {
if (err)
return callback(err);
if(!existingSession) {
var session = new self.Session({date: date, track: self.track.id, mod: self.mod.id});
async.forEach(drivers, function (driver, cb) {
driverTreatment(driver, function (err) {
cb(err);
});
}, function (err) {
if (err)
return callback(err);
session.save(function (err) {
if (err) {
callback(err);
} else {
callback(null, "Session Added");
}
});
});
function driverTreatment(driver, callback) {
var driverName = driver.get("Name").text();
if (driver.get("BestLapTime")) {
var driverBestLapTime = self._parseDriveTime(driver.get("BestLapTime").text());
}
var driverCar = driver.get("CarType").text();
var driverPosition = driver.get("Position").text();
var driverLaps = driver.find("Lap");
var driverBestLapAttributes = {track: self.track.id, mod: self.mod.id, time: driverBestLapTime, session: session.id};
var driverAttributes = {gameName: driverName};
Driver.findOrCreate(driverAttributes, function (err, driverFound) {
if (err)
return callback(err);
if (driverFound) {
var participation = {
driver : driverFound.id,
bestLapTime: driverBestLapTime,
car : driverCar,
position : driverPosition,
laps : []
};
async.forEach(driverLaps, function (driverLap, callback) {
var lap = buildLap(driverLap);
participation.laps.push(lap);
callback();
}, function (err) {
if (err)
return callback(err);
session.participations.push(participation);
driverFound.qualifParticipation.push(1);
if (driverPosition == 1) {
driverFound.qualifFirst.push(driverPosition);
}
if (driverPosition == 2) {
driverFound.qualifSecond.push(driverPosition);
}
if (driverPosition == 3) {
driverFound.qualifThird.push(driverPosition);
}
bestLap = driverFound.getBestLapForTrackAndMod(self.track.id, self.mod.id);
var changed = false;
if (driverBestLapAttributes.time && !bestLap) {
driverFound.bestLaps.push(driverBestLapAttributes);
changed = true;
} else if (driverBestLapAttributes.time && driverBestLapAttributes.time < bestLap.time) {
bestLap.time = driverBestLapAttributes.time;
changed = true;
}
if (changed) {
driverFound.markModified('bestLaps');
driverFound.skipPasswordValidation = true;
driverFound.save(callback);
} else {
callback();
};
});
function buildLap(driverLap) {
var lapTime = self._parseDriveTime(driverLap.text());
var lap = { lapTime: lapTime };
driverLap.attrs().forEach(function (attribute) {
var attributeName = attribute.name();
var attributeValue = attribute.value();
if (attributeName == "et")
attributeValue = self._parseDriveTime(attributeValue);
lap[attributeName] = attributeValue;
});
return lap;
}
} else {
callback();
}
});
}
} else {
return callback(null, "Existing Session");
}
});
}
RFactorXmlParser.prototype._parseDriveTime = function _parseDriveTime(string) {
return /^\d+\.\d+$/.test(string) ? parseInt(string.replace('.', '')) : null;
};
module.exports = RFactorXmlParser;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment