<commit_before>/*jslint browser: true, devel: true, node: true, ass: true, nomen: true, unparam: true, indent: 4 */

(function () {
  "use strict";

  // Vars
  var prompt = require('prompt'),
  fs = require('fs'),
  exp = require('express'),
  cors = require('cors'),
  apicache = require('apicache'),
  cache = apicache.middleware,
  RateLimit = require('express-rate-limit'),
  helmet = require('helmet'),
  cluster = require('cluster'), // Cluster for better performance
  XP  = require('expandjs'),
  API = require('lol-riot-api-module'),
  app = exp(),
  api,

  // Route map for the relative API methods
  routes = {
    '/champions': 'getChampions',
    '/champions/:id': 'getChampionById',
    '/featuredGames': 'getFeaturedGames',
    '/leagues/challenger': 'getChallengerLeague',
    '/leagues/master': 'getMasterLeague',
    '/match/:id': 'getMatchById',
    '/static/champions': 'getChampionData',
    '/static/champions/:id': 'getChampionDataById',
    '/static/items': 'getItemData',
    '/static/items/:id': 'getItemDataById',
    '/static/languages': 'getLanguages',
    '/static/languageStrings': 'getLanguageStrings',
    '/static/maps': 'getMaps',
    '/static/masteries': 'getMasteryData',
    '/static/masteries/:id': 'getMasteryDataById',
    '/static/realms': 'getRealms',
    '/static/runes': 'getRuneData',
    '/static/runes/:id': 'getRuneDataById',
    '/static/spells': 'getSummonerSpellData',
    '/static/spells/:id': 'getSummonerSpellDataById',
    '/static/versions': 'getVersions',
    '/status': 'getStatus',
    '/status/:region': 'getStatusByRegion',
    '/summoner/:id/currentGame': 'getCurrentGameBySummonerId',
    '/summoner/:id/matchList': 'getMatchListBySummonerId',
    '/summoner/:id/rankedStats': 'getRankedStatsBySummonerId',
    '/summoner/:id/recentGames': 'getRecentGamesBySummonerId',
    '/summoner/:id/statsSummary': 'getStatsSummaryBySummonerId',
    '/summoner/:id/championMastery': 'getChampionMastery',
    '/summoner/:id/championMastery/score': 'getChampionMasteryScore',
    '/summoner/:id/championMastery/top': 'getChampionMasteryTop',
    '/summoner/:id/championMastery/:champId': 'getChampionMasteryById',
    '/summoner/:ids': 'getSummonersByIds',
    '/summoner/:ids/league': 'getLeagueBySummonerIds',
    '/summoner/:ids/league/entry': 'getLeagueEntryBySummonerIds',
    '/summoner/:ids/masteries': 'getMasteriesBySummonerIds',
    '/summoner/:ids/name': 'getSummonerNamesByIds',
    '/summoner/:ids/runes': 'getRunesBySummonerIds',
    '/summoner/:ids/teams': 'getTeamsBySummonerIds',
    '/summoner/by-name/:names': 'getSummonersByNames',
    '/team/:ids': 'getTeamsByIds',
    '/team/:ids/league': 'getLeagueByTeamIds',
    '/team/:ids/league/entry': 'getLeagueEntryByTeamIds'
  },

  // Handler for the request received from the client
  requestHandler = function (req, res) {
    // Create cache groups
    if ((req.url.startsWith('/summoner') || req.url.startsWith('/team')) && !req.url.endsWith('/currentGame')){
      if(req.params.ids != null)
      req.apicacheGroup = req.params.ids;
      else if(req.params.id != null)
      req.apicacheGroup = req.params.id;
    }

    var opt = XP.merge({}, req.query, req.params),
    method = routes[req.route.path],

    //RegExp used to identify methods that don't need an `opt` as first parameter
    noOptRegExp = /^\/status\/?$/,
    noOpt = !!req.route.path.match(noOptRegExp),
    cb = function (err, data) {
      res.json(err || data);
    };

    opt = noOpt ? cb : opt;
    cb  = noOpt ? null : cb;

    api[method](opt, cb);
  };

  // Main function of the API
  function init() {

    // Code to run if we're in the master process
    if (cluster.isMaster) {

      // Count the machine's CPUs
      var cpuCount = require('os').cpus().length;

      // Create a worker for each CPU
      for (var i = 0; i < cpuCount; i += 1) {
        cluster.fork();
      }

      // Code to run if we're in a worker process
    } else {

      require('dotenv').load();
      app.use(cors()); // use CORS
      app.use(helmet()); // Secure the API with helmet. Readmore: https://expressjs.com/en/advanced/best-practice-security.html
      app.enable('trust proxy'); // only if you're behind a reverse proxy (Heroku, Bluemix, AWS if you use an ELB, custom Nginx setup, etc)

      // Ratelimiter
      var limiter = new RateLimit({
        windowMs: 10*60*1000, // 10 minutes
        max: 1000, // limit each IP to 100 requests per windowMs
        delayMs: 0 // disable delaying - full speed until the max limit is reached
      });
      //  apply to all requests
      app.use(limiter);

      api = new API({
        key: process.env.KEY || null,
        region: process.env.REGION || null
      });

      app.port = process.env.PORT || 3001;

      // Default route
      app.get('/', function (req, res) {
        res.json({
          name: 'League of Legends API',
          version: "1.4.1",
          author: "<NAME> <<EMAIL>> and <NAME> <<EMAIL>>",
          repository: "https://github.com/Pupix/lol-riot-api"
        });
      });

      // Chache Clear for update the data
      app.get('/summoner/:id/clear', function (req, res) {
        apicache.clear(req.params.id);
        res.status(404).json({message: "Cache cleared"});
      });

      // Dynamic API routes with cache
      XP.forEach(routes, function (func, route) {
        if(route.startsWith('/summoner') && route.endsWith('/currentGame')){
          app.get(route, requestHandler);
        }  else if (route.startsWith('/summoner') || route.startsWith('/team')) {
          app.get(route, cache('1 hour'), requestHandler);
        } else if (route.startsWith('/static') || route.startsWith('/champions') || route.startsWith('/leagues') || route.startsWith('/match')) {
          app.get(route, cache('12 hours'), requestHandler);
        } else {
          app.get(route, requestHandler);
        }
      });

      //Error Handling
      app.use(function (req, res) { res.status(404).json({error: 404, message: "Not Found"}); });
      app.use(function (req, res) { res.status(500).json({error: 500, message: 'Internal Server Error'}); });
      app.use(function (req, res) { res.status(429).json({error: 429, message: 'Too many requests'}); });<commit_msg>Update app.js<commit_after>/*jslint browser: true, devel: true, node: true, ass: true, nomen: true, unparam: true, indent: 4 */

(function () {
  "use strict";

  // Vars
  var prompt = require('prompt'),
  fs = require('fs'),
  exp = require('express'),
  cors = require('cors'),
  apicache = require('apicache'),
  cache = apicache.middleware,
  RateLimit = require('express-rate-limit'),
  helmet = require('helmet'),
  cluster = require('cluster'), // Cluster for better performance
  XP  = require('expandjs'),
  API = require('lol-riot-api-module'),
  app = exp(),
  api,

  // Route map for the relative API methods
  routes = {
    '/champions': 'getChampions',
    '/champions/:id': 'getChampionById',
    '/featuredGames': 'getFeaturedGames',
    '/leagues/challenger': 'getChallengerLeague',
    '/leagues/master': 'getMasterLeague',
    '/match/:id': 'getMatchById',
    '/static/champions': 'getChampionData',
    '/static/champions/:id': 'getChampionDataById',
    '/static/items': 'getItemData',
    '/static/items/:id': 'getItemDataById',
    '/static/languages': 'getLanguages',
    '/static/languageStrings': 'getLanguageStrings',
    '/static/maps': 'getMaps',
    '/static/masteries': 'getMasteryData',
    '/static/masteries/:id': 'getMasteryDataById',
    '/static/realms': 'getRealms',
    '/static/runes': 'getRuneData',
    '/static/runes/:id': 'getRuneDataById',
    '/static/spells': 'getSummonerSpellData',
    '/static/spells/:id': 'getSummonerSpellDataById',
    '/static/versions': 'getVersions',
    '/status': 'getStatus',
    '/status/:region': 'getStatusByRegion',
    '/summoner/:id/currentGame': 'getCurrentGameBySummonerId',
    '/summoner/:id/matchList': 'getMatchListBySummonerId',
    '/summoner/:id/rankedStats': 'getRankedStatsBySummonerId',
    '/summoner/:id/recentGames': 'getRecentGamesBySummonerId',
    '/summoner/:id/statsSummary': 'getStatsSummaryBySummonerId',
    '/summoner/:id/championMastery': 'getChampionMastery',
    '/summoner/:id/championMastery/score': 'getChampionMasteryScore',
    '/summoner/:id/championMastery/top': 'getChampionMasteryTop',
    '/summoner/:id/championMastery/:champId': 'getChampionMasteryById',
    '/summoner/:ids': 'getSummonersByIds',
    '/summoner/:ids/league': 'getLeagueBySummonerIds',
    '/summoner/:ids/league/entry': 'getLeagueEntryBySummonerIds',
    '/summoner/:ids/masteries': 'getMasteriesBySummonerIds',
    '/summoner/:ids/name': 'getSummonerNamesByIds',
    '/summoner/:ids/runes': 'getRunesBySummonerIds',
    '/summoner/:ids/teams': 'getTeamsBySummonerIds',
    '/summoner/by-name/:names': 'getSummonersByNames',
    '/team/:ids': 'getTeamsByIds',
    '/team/:ids/league': 'getLeagueByTeamIds',
    '/team/:ids/league/entry': 'getLeagueEntryByTeamIds'
  },

  // Handler for the request received from the client
  requestHandler = function (req, res) {
    // Create cache groups
    if ((req.url.startsWith('/summoner') || req.url.startsWith('/team')) && !req.url.endsWith('/currentGame')){
      if(req.params.ids != null)
      req.apicacheGroup = req.params.ids;
      else if(req.params.id != null)
      req.apicacheGroup = req.params.id;
    }

    var opt = XP.merge({}, req.query, req.params),
    method = routes[req.route.path],

    //RegExp used to identify methods that don't need an `opt` as first parameter
    noOptRegExp = /^\/status\/?$/,
    noOpt = !!req.route.path.match(noOptRegExp),
    cb = function (err, data) {
      res.json(err || data);
    };

    opt = noOpt ? cb : opt;
    cb  = noOpt ? null : cb;

    api[method](opt, cb);
  };

  // Main function of the API
  function init() {

    // Code to run if we're in the master process
    if (cluster.isMaster) {

      // Count the machine's CPUs
      var cpuCount = require('os').cpus().length;

      // Create a worker for each CPU
      for (var i = 0; i < cpuCount; i += 1) {
        cluster.fork();
      }

      // Code to run if we're in a worker process
    } else {

      require('dotenv').load();
      app.use(cors()); // use CORS
      app.use(helmet()); // Secure the API with helmet. Readmore: https://expressjs.com/en/advanced/best-practice-security.html
      app.enable('trust proxy'); // only if you're behind a reverse proxy (Heroku, Bluemix, AWS if you use an ELB, custom Nginx setup, etc)

      // Cache only if the stat
      const onlyStatus200 = req => req.statusCode === 200

      
      // Ratelimiter
      var limiter = new RateLimit({
        windowMs: 10*60*1000, // 10 minutes
        max: 1000, // limit each IP to 100 requests per windowMs
        delayMs: 0 // disable delaying - full speed until the max limit is reached
      });
      //  apply to all requests
      app.use(limiter);

      api = new API({
        key: process.env.KEY || null,
        region: process.env.REGION || null
      });

      app.port = process.env.PORT || 3001;

      // Default route
      app.get('/', function (req, res) {
        res.json({
          name: 'League of Legends API',
          version: "1.4.1",
          author: "<NAME> <<EMAIL>> and <NAME> <<EMAIL>>",
          repository: "https://github.com/Pupix/lol-riot-api"
        });
      });

      // Chache Clear for update the data
      app.get('/summoner/:id/clear', function (req, res) {
        apicache.clear(req.params.id);
        res.status(200).json({message: "Cache cleared"});
      });

      // Dynamic API routes with cache
      XP.forEach(routes, function (func, route) {
        if(route.startsWith('/summoner') && route.endsWith('/currentGame')){
          app.get(route, requestHandler);
        }  else if (route.startsWith('/summoner') || route.startsWith('/team')) {
          app.get(route, cache('1 day', onlyStatus200), requestHandler);
        } else if (route.startsWith('/static') || route.startsWith('/champions') || route.startsWith('/leagues') || route.startsWith('/match')) {
          app.get(route, cache('12 hours', onlyStatus200), requestHandler);
        } else {
          app.get(route, requestHandler);
        }
      });

      //Error Handling
      app.use(function (req, res) { res.status(404).json({error: 404, message: "Not Found"}); });
      app.use(function (req, res) { res.status(500).json({error: 500, message: 'Internal Server Error'}); });
      app.use(function (req, res) { res.status(429).json({error: 429, message: 'Too many requests'}); });
{'fraction_non_alphanumeric': 0.1703205381875742, 'fraction_numerical': 0.009180846853977048, 'mean_word_length': 3.0293367346938775, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 16, 'https://': 4, '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': '3757864', 'n_tokens_mistral': 4259, 'n_tokens_neox': 4172, 'n_words': 893}