<commit_before>var http = require('http');
var querystring = require('querystring');
var crypto = require("crypto");
var RecentTracksStream = require('lastfm/recenttracks-stream').RecentTracksStream;
var LastFmSession = require('lastfm/lastfm-session').LastFmSession;
var ResponseReader = require('lastfm/response-reader').ResponseReader;
var LastFmInfo = require('lastfm/lastfm-info').LastFmInfo;

var LastFmNode = exports.LastFmNode = function(options){
  if (!options) options = {};
  this.url = '/2.0';
  this.host = 'ws.audioscrobbler.com';
  this.secret = options.secret || '';
  this.params =  {
    format : "json",
    api_key : options.api_key 
  };
  var that = this;
};

LastFmNode.prototype.mergeParams = function(a, b) {
  function copyKeys(source, destination) {
    if (!source) {
      return;
    }
    Object.keys(source).forEach(function(key) {
      destination[key] = source[key];
    });
  }

  var c = {};
  copyKeys(a, c);
  copyKeys(b, c);
  return c;
};

LastFmNode.prototype.signature = function(params) {
  var sig = "";
  Object.keys(params).sort().forEach(function(key) {
    if (key != 'format') sig += key + params[key];
  });
  sig += this.secret;
  return crypto.createHash("md5").update(sig, "utf8").digest("hex");
};

LastFmNode.prototype.requestUrl = function(additionalParams, signed) {
  var params = this.mergeParams(this.params, additionalParams);
  if (signed) {
    params.api_sig = this.signature(params); 
  }
  return this.url + '?' + querystring.stringify(params);
};

LastFmNode.prototype.readRequest = function(params, signed, callback) {
  var connection = http.createClient(80, this.host);
  var request = connection.request('GET', this.requestUrl(params, signed), {
    host: this.host 
  });
  request.end();
  new ResponseReader(request, callback);
};

LastFmNode.prototype.writeRequest = function(params, signed, callback) {
  var connection = http.createClient(80, this.host);
  var writeParams = this.mergeParams(this.params, params);
  if (signed) {
    writeParams.api_sig = this.signature(writeParams);
  }
  var body = querystring.stringify(writeParams);
  var request = connection.request('POST', this.url, { 
    host: this.host,
    'Content-Length': body.length,
    'Content-Type': 'application/x-www-form-urlencoded' 
  });
  request.write(body);
  request.end();
  new ResponseReader(request, callback);
};

LastFmNode.prototype.stream = function(user, options) {
  return new RecentTracksStream(this, user, options);
};

LastFmNode.prototype.session = function(user, key) {
  return new LastFmSession(this, user, key);
};

LastFmNode.prototype.info = function(type, options) {
  return new LastFmInfo(this, type, options);
};

LastFmNode.prototype.update = function(method, session, options) {
  return new LastFmUpdate(this, method, session, options);
};
<commit_msg>Fixed missing dependency<commit_after>var http = require('http');
var querystring = require('querystring');
var crypto = require("crypto");
var RecentTracksStream = require('lastfm/recenttracks-stream').RecentTracksStream;
var LastFmSession = require('lastfm/lastfm-session').LastFmSession;
var LastFmUpdate = require('lastfm/lastfm-update').LastFmUpdate;
var ResponseReader = require('lastfm/response-reader').ResponseReader;
var LastFmInfo = require('lastfm/lastfm-info').LastFmInfo;

var LastFmNode = exports.LastFmNode = function(options){
  if (!options) options = {};
  this.url = '/2.0';
  this.host = 'ws.audioscrobbler.com';
  this.secret = options.secret || '';
  this.params =  {
    format : "json",
    api_key : options.api_key 
  };
  var that = this;
};

LastFmNode.prototype.mergeParams = function(a, b) {
  function copyKeys(source, destination) {
    if (!source) {
      return;
    }
    Object.keys(source).forEach(function(key) {
      destination[key] = source[key];
    });
  }

  var c = {};
  copyKeys(a, c);
  copyKeys(b, c);
  return c;
};

LastFmNode.prototype.signature = function(params) {
  var sig = "";
  Object.keys(params).sort().forEach(function(key) {
    if (key != 'format') sig += key + params[key];
  });
  sig += this.secret;
  return crypto.createHash("md5").update(sig, "utf8").digest("hex");
};

LastFmNode.prototype.requestUrl = function(additionalParams, signed) {
  var params = this.mergeParams(this.params, additionalParams);
  if (signed) {
    params.api_sig = this.signature(params); 
  }
  return this.url + '?' + querystring.stringify(params);
};

LastFmNode.prototype.readRequest = function(params, signed, callback) {
  var connection = http.createClient(80, this.host);
  var request = connection.request('GET', this.requestUrl(params, signed), {
    host: this.host 
  });
  request.end();
  new ResponseReader(request, callback);
};

LastFmNode.prototype.writeRequest = function(params, signed, callback) {
  var connection = http.createClient(80, this.host);
  var writeParams = this.mergeParams(this.params, params);
  if (signed) {
    writeParams.api_sig = this.signature(writeParams);
  }
  var body = querystring.stringify(writeParams);
  var request = connection.request('POST', this.url, { 
    host: this.host,
    'Content-Length': body.length,
    'Content-Type': 'application/x-www-form-urlencoded' 
  });
  request.write(body);
  request.end();
  new ResponseReader(request, callback);
};

LastFmNode.prototype.stream = function(user, options) {
  return new RecentTracksStream(this, user, options);
};

LastFmNode.prototype.session = function(user, key) {
  return new LastFmSession(this, user, key);
};

LastFmNode.prototype.info = function(type, options) {
  return new LastFmInfo(this, type, options);
};

LastFmNode.prototype.update = function(method, session, options) {
  return new LastFmUpdate(this, method, session, options);
};

{'fraction_non_alphanumeric': 0.15246870653685674, 'fraction_numerical': 0.0027816411682892906, 'mean_word_length': 4.585436893203884, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, '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': '7286161', 'n_tokens_mistral': 1873, 'n_tokens_neox': 1838, 'n_words': 363}