<commit_before>const PORT = 8080;
const TOKEN_SECRET = process.env.QUICKSYNC_TOKEN_SECRET;
const SESSION_SECRET = process.env.QUICKSYNC_SESSION_SECRET;
const SOUNDCLOUD_APP_ID = process.env.QUICKSYNC_SOUNDCLOUD_APP_ID;
const SOUNDCLOUD_APP_SECRET = process.env.QUICKSYNC_SOUNDCLOUD_APP_SECRET;
const YOUTUBE_APP_ID = process.env.QUICKSYNC_YOUTUBE_APP_ID;
const YOUTUBE_APP_SECRET = process.env.QUICKSYNC_YOUTUBE_APP_SECRET;
const YOUTUBE_API_KEY = process.env.QUICKSYNC_YOUTUBE_API_KEY;
const URL = 'http://dev.quick.tksync.com:8080';
const SOUNDCLOUD_API_BASE_URL = 'https://api.soundcloud.com';
const YOUTUBE_API_BASE_URL = 'https://www.googleapis.com/youtube/v3';

var http = require('http');
var Stream = require('stream');
var crypto = require('crypto');
var es = require('event-stream');
var _ = require('underscore');
var request = require('request');
var express = require('express');
var expose = require('express-expose');
var server = express();
var http_server = http.createServer( server );

// generate auth token for use with streaming endpoints
// pass any data we need attached to message objects
var generateAuthToken = function( id, name ){
	var hmac = crypto.createHmac( 'sha256', TOKEN_SECRET );
	hmac.setEncoding('hex');
	hmac.write( id );
	hmac.write( name );
	hmac.end();
	return hmac.read();
};

// Sockets
var EngineServer = require('engine.io-stream');
var room_streams = {};

// Database
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/quicksync');

var RoomSchema = new mongoose.Schema({
	name: String,
	users: [{
		name: String
	}],
	playlist: [{
		title: String,
		image: String,
		provider: String,
		url: String,
		media_url: String,
		duration: Number
	}],
	player: {
		elapsed: Number
	}
});
RoomSchema.post( 'init', function( room ){
	if( !room_streams[room.id] ){
		// create stream for all room data
		var room_stream = room_streams[room.id] = new Stream.Duplex({ objectMode: true });
		room_stream._read = function(){
		};
		room_stream._write = function( chunk, encoding, next ){
			this.push( chunk );
			next();
		};
		var engine = EngineServer( function( stream ){
			// stringify outgoing messages
			// parse incoming messages
			var stringify_stream = es.stringify();
			stringify_stream.pipe( stream );
			stream = es.duplex( stringify_stream, stream.pipe( es.parse() ) );
			// check user validity
			// close user connection if no auth sent in time
			var revokeAuth = function( reason ){
				reason = reason || 'Authentication error';
				stream.write({
					module: 'notifications',
					type: 'error',
					payload: {
						message: reason
					}
				});
				stream.end();
			};
			var checkAuth = function( id, name, token ){
				return generateAuthToken( id, name ) === token;
			};
			var auth_timeout = setTimeout( function(){
				revokeAuth('Authentication timed out');
			}, 15 * 1000 );
			stream.on( 'data', function( data ){
				if( data.type === 'auth' ){
					var id = data.payload.id;
					var name = data.payload.name;
					var token = data.payload.token;
					if( checkAuth( id, name, token ) ){
						clearTimeout( auth_timeout );
						// stream connection stream into room stream
						// stream room stream into connection stream
						stream
							// attach user data
							.pipe( es.through( function( data ){
								data.user = {
									id: id,
									name: name
								};
								this.queue( data );
							}))
							.pipe( room_stream )
							.pipe( stream );
					}
					else {
						revokeAuth();
					}
				}
			});
		});
		engine.attach( http_server, '/streaming/rooms/'+ room.id );<commit_msg>add/remove user presences from rooms<commit_after>const PORT = 8080;
const TOKEN_SECRET = process.env.QUICKSYNC_TOKEN_SECRET;
const SESSION_SECRET = process.env.QUICKSYNC_SESSION_SECRET;
const SOUNDCLOUD_APP_ID = process.env.QUICKSYNC_SOUNDCLOUD_APP_ID;
const SOUNDCLOUD_APP_SECRET = process.env.QUICKSYNC_SOUNDCLOUD_APP_SECRET;
const YOUTUBE_APP_ID = process.env.QUICKSYNC_YOUTUBE_APP_ID;
const YOUTUBE_APP_SECRET = process.env.QUICKSYNC_YOUTUBE_APP_SECRET;
const YOUTUBE_API_KEY = process.env.QUICKSYNC_YOUTUBE_API_KEY;
const URL = 'http://dev.quick.tksync.com:8080';
const SOUNDCLOUD_API_BASE_URL = 'https://api.soundcloud.com';
const YOUTUBE_API_BASE_URL = 'https://www.googleapis.com/youtube/v3';
const NO_OP = function(){};

var http = require('http');
var Stream = require('stream');
var crypto = require('crypto');
var es = require('event-stream');
var _ = require('underscore');
var request = require('request');
var express = require('express');
var expose = require('express-expose');
var server = express();
var http_server = http.createServer( server );

// generate auth token for use with streaming endpoints
// pass any data we need attached to message objects
var generateAuthToken = function( id, name ){
	var hmac = crypto.createHmac( 'sha256', TOKEN_SECRET );
	hmac.setEncoding('hex');
	hmac.write( id );
	hmac.write( name );
	hmac.end();
	return hmac.read();
};

// Sockets
var EngineServer = require('engine.io-stream');
var room_streams = {};

// Database
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/quicksync');

var RoomSchema = new mongoose.Schema({
	name: String,
	users: [{
		name: String,
		id: String,
		sids: Array
	}],
	playlist: [{
		title: String,
		image: String,
		provider: String,
		url: String,
		media_url: String,
		duration: Number
	}],
	player: {
		elapsed: Number
	}
});
// add a user presence
RoomSchema.methods.addPresence = function( presence, callback ){
	callback = callback || NO_OP;
	// check to see if id exists
	var existing_user = _.find( this.users, function( user ){
		return user.id === presence.id;
	});
	// if id exists, add sid to sids array
	if( existing_user ){
		existing_user.sids.push( presence.sid );
	}
	// if id does not exist, add new user to users array
	else {
		this.users.push({
			id: presence.id,
			name: presence.name,
			sids: [ presence.sid ]
		});
	}
	this.save( callback );
};
// remove a user presence
RoomSchema.methods.removePresence = function( presence, callback ){
	callback = callback || NO_OP;
	// find user with id
	var existing_user = _.find( this.users, function( user ){
		return user.id === presence.id;
	});
	if( !existing_user ) return callback( new Error('No user '+ presence.id ) );
	// remove sid
	existing_user.sids = _.without( existing_user.sids, presence.sid );
	// if sids.length === 0 remove user from users array
	if( existing_user.sids.length === 0 ){
		this.users = _.without( this.users, existing_user );
	}
	this.save( callback );
};
RoomSchema.post( 'init', function( room ){
	if( !room_streams[room.id] ){
		// create stream for all room data
		var room_stream = room_streams[room.id] = new Stream.Duplex({ objectMode: true });
		room_stream._read = function(){
		};
		room_stream._write = function( chunk, encoding, next ){
			this.push( chunk );
			next();
		};
		var engine = EngineServer( function( stream ){
			var sid = stream.transport.sid;
			// stringify outgoing messages
			// parse incoming messages
			var stringify_stream = es.stringify();
			stringify_stream.pipe( stream );
			stream = es.duplex( stringify_stream, stream.pipe( es.parse() ) );
			// check user validity
			// close user connection if no auth sent in time
			var revokeAuth = function( reason ){
				reason = reason || 'Authentication error';
				stream.write({
					module: 'notifications',
					type: 'error',
					payload: {
						message: reason
					}
				});
				stream.end();
			};
			var checkAuth = function( id, name, token ){
				return generateAuthToken( id, name ) === token;
			};
			var auth_timeout = setTimeout( function(){
				revokeAuth('Authentication timed out');
			}, 15 * 1000 );
			stream.on( 'data', function( data ){
				if( data.type === 'auth' ){
					var id = data.payload.id;
					var name = data.payload.name;
					var token = data.payload.token;
					if( checkAuth( id, name, token ) ){
						clearTimeout( auth_timeout );
						// stream connection stream into room stream
						// stream room stream into connection stream
						stream
							// attach user data
							.pipe( es.through( function( data ){
								data.user = {
									id: id,
									name: name
								};
								this.queue( data );
							}))
							.pipe( room_stream )
							.pipe( stream );
						// user join/leave
						var presence = {
							id: id,
							name: name,
							sid: sid
						};
						room.addPresence( presence );
						stream.on('close', function(){
							room.removePresence( presence );
						});
					}
					else {
						revokeAuth();
					}
				}
			});
		});
		engine.attach( http_server, '/streaming/rooms/'+ room.id );
{'fraction_non_alphanumeric': 0.13426138978370916, 'fraction_numerical': 0.0043718361711919005, 'mean_word_length': 3.3552104208416833, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, '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': '1228776', 'n_tokens_mistral': 3349, 'n_tokens_neox': 2837, 'n_words': 730}