<commit_before>var async     = require('async');
var crypto    = require('crypto');
var GitHubApi = require('github');
var leveldb   = require('level');
var lodash    = require('lodash');
var util      = require('util');
var debug     = require('debug')('github-cache');

/**
 * Copyright 2014
 * Author: <NAME> <<EMAIL>>
 *
 * GitHubCache is a transparent caching layer for node-github.
 * It overloads all API functions and introduces a caching mechanism.
 * You can call all the original functions by using an underscore in
 * front of their original function name.
 */
var GitHubCache = module.exports = function(global_options) {
  GitHubCache.super_.call(this, global_options);

  var apis = Object.keys(this[this.version].routes);

  var self = this;

  async.eachSeries(apis, function(api, api_callback) {
    api = toCamelCase(api);
    var keys = Object.keys(self[api]);

    async.eachSeries(keys, function(key, key_callback) {
      self[api]['_' + key] = self[api][key];

      self[api][key] = function(options, fun_callback) {
        var cache_id = self.cacheId(api, key, options);

        default_opts = lodash.merge({cache: true, validateCache: true}, lodash.pick(global_options, ['validateCache', 'cache']));
        options = lodash.merge(default_opts, options);

        self.getCache(cache_id, function(err, cached_etag, cached_data) {
          if (cached_etag && options.cache == true)
            options = lodash.merge({headers: {'If-None-Match': cached_etag}}, options);

          if (options.validateCache == false && typeof(cached_data) != "undefined") {
            return fun_callback(null, cached_data);
          }

          var opts = lodash.omit(options, ['cache', 'validateCache', 'invalidateCache']);
          self[api]['_' + key](opts, function(err, results) {
            if (err) return fun_callback(err);

            if (typeof(options.invalidateCache) != 'undefined')
              self.invalidateCache(options.invalidateCache, opts);

            if (options.cache == false)
              return fun_callback(null, results);

            if (results.meta.status == '304 Not Modified')
              return fun_callback(null, cached_data);

            self.putCache(cache_id, results, function(err) {
              if (err) return fun_callback(err);
              fun_callback(null, results);
            });
          });
        })
      };

      key_callback(null);
    }, function(err) {
      if (err) return api_callback(err);
      api_callback();
    })
  }, function(err) {
    if (err) throw Error(err);
  });

  this.config.cachedb = this.config.cachedb || './cachedb';
  if (typeof(this.config.cachedb.db) != 'undefined') {
    this.cachedb = this.config.cachedb;
  } else {
    this.cachedb = leveldb(this.config.cachedb || './cachedb');
  }
};

util.inherits(GitHubCache, GitHubApi);

GitHubCache.prototype.getCache = function(cache_id, callback) {
  var self = this;
  self.cachedb.get(cache_id + ':tag', function(err, tag) {
    if (err) return callback(err);<commit_msg>fixing the existing leveldb detection<commit_after>var async     = require('async');
var crypto    = require('crypto');
var GitHubApi = require('github');
var leveldb   = require('level');
var lodash    = require('lodash');
var util      = require('util');
var debug     = require('debug')('github-cache');

/**
 * Copyright 2014
 * Author: <NAME> <<EMAIL>>
 *
 * GitHubCache is a transparent caching layer for node-github.
 * It overloads all API functions and introduces a caching mechanism.
 * You can call all the original functions by using an underscore in
 * front of their original function name.
 */
var GitHubCache = module.exports = function(global_options) {
  GitHubCache.super_.call(this, global_options);

  var apis = Object.keys(this[this.version].routes);

  var self = this;

  async.eachSeries(apis, function(api, api_callback) {
    api = toCamelCase(api);
    var keys = Object.keys(self[api]);

    async.eachSeries(keys, function(key, key_callback) {
      self[api]['_' + key] = self[api][key];

      self[api][key] = function(options, fun_callback) {
        var cache_id = self.cacheId(api, key, options);

        default_opts = lodash.merge({cache: true, validateCache: true}, lodash.pick(global_options, ['validateCache', 'cache']));
        options = lodash.merge(default_opts, options);

        self.getCache(cache_id, function(err, cached_etag, cached_data) {
          if (cached_etag && options.cache == true)
            options = lodash.merge({headers: {'If-None-Match': cached_etag}}, options);

          if (options.validateCache == false && typeof(cached_data) != "undefined") {
            return fun_callback(null, cached_data);
          }

          var opts = lodash.omit(options, ['cache', 'validateCache', 'invalidateCache']);
          self[api]['_' + key](opts, function(err, results) {
            if (err) return fun_callback(err);

            if (typeof(options.invalidateCache) != 'undefined')
              self.invalidateCache(options.invalidateCache, opts);

            if (options.cache == false)
              return fun_callback(null, results);

            if (results.meta.status == '304 Not Modified')
              return fun_callback(null, cached_data);

            self.putCache(cache_id, results, function(err) {
              if (err) return fun_callback(err);
              fun_callback(null, results);
            });
          });
        })
      };

      key_callback(null);
    }, function(err) {
      if (err) return api_callback(err);
      api_callback();
    })
  }, function(err) {
    if (err) throw Error(err);
  });

  this.config.cachedb = this.config.cachedb || './cachedb';
  if (typeof(this.config.cachedb) == 'object' && typeof(this.config.cachedb.put) == 'function') {
    this.cachedb = this.config.cachedb;
  } else {
    this.cachedb = leveldb(this.config.cachedb || './cachedb');
  }
};

util.inherits(GitHubCache, GitHubApi);

GitHubCache.prototype.getCache = function(cache_id, callback) {
  var self = this;
  self.cachedb.get(cache_id + ':tag', function(err, tag) {
    if (err) return callback(err);
{'fraction_non_alphanumeric': 0.14269424987783028, 'fraction_numerical': 0.002280501710376283, 'mean_word_length': 3.074319840743198, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, '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': '3641889', 'n_tokens_mistral': 1867, 'n_tokens_neox': 1800, 'n_words': 425}