<commit_before>/*
TK102 GPS server for Node.js

Author:  <NAME>
Website: http://frankl.in/
Twitter: @unknownt

Source:  http://fvdm.github.com/nodejs-tk102
Version: 1.0.2
Date:    2012-04-19

License: CC BY-SA 3.0
This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/
*/

// INIT
var net = require('net');
var EventEmitter = require('events').EventEmitter;

var tk102 = new EventEmitter();

// defaults
tk102.settings = {
	ip:				'0.0.0.0',	// default listen on all IPs
	port:			0,			// 0 = random, 'listening' event reports port
	connections:	10,			// 10 simultaneous connections
	timeout:		10			// 10 seconds idle timeout
}

// Create server
tk102.createServer = function( vars ) {
	
	// override settings
	if( typeof vars == 'object' && Object.keys(vars).length >= 1 ) {
		for( var key in vars ) {
			tk102.settings[ key ] = vars[ key ]
		}
	}
	
	tk102.server = net.createServer( function( socket ) {
		if( settings.timeout > 0 ) {
			socket.setTimeout( settings.timeout * 1000, function() {
				tk102.emit( 'timeout', socket );
				socket.end();
			});
		}
	}).listen( settings.port, settings.ip, function() {
		tk102.emit( 'listening', tk102.server.address() );
	});
	
	tk102.server.maxConnections = settings.connections;
	
	tk102.server.on( 'connection', function( socket ) {
		tk102.emit( 'connection', socket );
		socket.setEncoding( 'utf8' );
		
		var data = ''
		
		// receiving data
		socket.on( 'data', function( chunk ) {
			tk102.emit( 'data', chunk )
			data += chunk
		})
		
			
			if( gps = tk102.parse( raw ) ) {
				tk102.emit( 'track', gps );
			}
		});
	});
}

// Parse GPRMC string
tk102.parse = function( raw ) {
	// 1203292316,0031698765432,GPRMC,211657.000,A,5213.0247,N,00516.7757,E,0.00,273.30,290312,,,A*62,F,imei:123456789012345,123
	var raw = raw.replace( /(^[\s\t\r\n]+|[\s\t\r\n]+$)/, '' );
	var str = raw.split(',');
	var data = false;
	
	// only continue with correct input, else the server may quit...
	if( str.length == 18 && str[2] == 'GPRMC' ) {
		
		// parse
		var datetime = str[0].replace( /([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})/, function( match, year, month, day, hour, minute ) {
			return '20'+ year +'-'+ month +'-'+ day +' '+ hour +':'+ minute
		});
		var gpsdate = str[11].replace( /([0-9]{2})([0-9]{2})([0-9]{2})/, function( match, day, month, year ) {
			return '20'+ year +'-'+ month +'-'+ day;
		});
		var gpstime = str[3].replace( /([0-9]{2})([0-9]{2})([0-9]{2})\.([0-9]{3})/, function( match, hour, minute, second, ms ) {
			return hour +':'+ minute +':'+ second +'.'+ ms;
		});<commit_msg>Emit 'track' event after socket is closed and data is received<commit_after>/*
TK102 GPS server for Node.js

Author:  <NAME>
Website: http://frankl.in/
Twitter: @unknownt

Source:  http://fvdm.github.com/nodejs-tk102
Version: 1.0.2
Date:    2012-04-19

License: CC BY-SA 3.0
This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/
*/

// INIT
var net = require('net');
var EventEmitter = require('events').EventEmitter;

var tk102 = new EventEmitter();

// defaults
tk102.settings = {
	ip:				'0.0.0.0',	// default listen on all IPs
	port:			0,			// 0 = random, 'listening' event reports port
	connections:	10,			// 10 simultaneous connections
	timeout:		10			// 10 seconds idle timeout
}

// Create server
tk102.createServer = function( vars ) {
	
	// override settings
	if( typeof vars == 'object' && Object.keys(vars).length >= 1 ) {
		for( var key in vars ) {
			tk102.settings[ key ] = vars[ key ]
		}
	}
	
	tk102.server = net.createServer( function( socket ) {
		if( settings.timeout > 0 ) {
			socket.setTimeout( settings.timeout * 1000, function() {
				tk102.emit( 'timeout', socket );
				socket.end();
			});
		}
	}).listen( settings.port, settings.ip, function() {
		tk102.emit( 'listening', tk102.server.address() );
	});
	
	tk102.server.maxConnections = settings.connections;
	
	tk102.server.on( 'connection', function( socket ) {
		tk102.emit( 'connection', socket );
		socket.setEncoding( 'utf8' );
		
		var data = ''
		
		// receiving data
		socket.on( 'data', function( chunk ) {
			tk102.emit( 'data', chunk )
			data += chunk
		})
		
		// complete
		socket.on( 'close', function() {
			
			var gps = {}
			if( data != '' && gps = tk102.parse( data ) ) {
				tk102.emit( 'track', gps )
			}
	});
			
		})
}

// Parse GPRMC string
tk102.parse = function( raw ) {
	// 1203292316,0031698765432,GPRMC,211657.000,A,5213.0247,N,00516.7757,E,0.00,273.30,290312,,,A*62,F,imei:123456789012345,123
	var raw = raw.replace( /(^[\s\t\r\n]+|[\s\t\r\n]+$)/, '' );
	var str = raw.split(',');
	var data = false;
	
	// only continue with correct input, else the server may quit...
	if( str.length == 18 && str[2] == 'GPRMC' ) {
		
		// parse
		var datetime = str[0].replace( /([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})/, function( match, year, month, day, hour, minute ) {
			return '20'+ year +'-'+ month +'-'+ day +' '+ hour +':'+ minute
		});
		var gpsdate = str[11].replace( /([0-9]{2})([0-9]{2})([0-9]{2})/, function( match, day, month, year ) {
			return '20'+ year +'-'+ month +'-'+ day;
		});
		var gpstime = str[3].replace( /([0-9]{2})([0-9]{2})([0-9]{2})\.([0-9]{3})/, function( match, hour, minute, second, ms ) {
			return hour +':'+ minute +':'+ second +'.'+ ms;
		});
{'fraction_non_alphanumeric': 0.20436760691537761, 'fraction_numerical': 0.07970882620564149, 'mean_word_length': 3.217958557175748, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, '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': '544907', 'n_tokens_mistral': 2466, 'n_tokens_neox': 2060, 'n_words': 491}