<commit_before>var traverse = require("../../traverse");
var util     = require("../../util");
var t        = require("../../types");
var _        = require("lodash");

var isLet = function (node) {
  if (!t.isVariableDeclaration(node)) return false;
  if (node._let) return true;
  if (node.kind !== "let") return false;

  node._let = true;
  node.kind = "var";
  return true;
};

var isVar = function (node) {
  return t.isVariableDeclaration(node, { kind: "var" }) && !isLet(node);
};

exports.VariableDeclaration = function (node) {
  isLet(node);
};

exports.For = function (node, parent, file, scope) {
  var init = node.left || node.init;
  if (isLet(init)) {
    t.ensureBlock(node);
    node.body._letDeclars = [init];
  }

  if (t.isLabeledStatement(parent)) {
    // set label so `run` has access to it
    node.label = parent.label;
  }

  run(node, node.body, parent, file, scope);

  if (node.label && !t.isLabeledStatement(parent)) {
    // we've been given a label so let's wrap ourselves
    return t.labeledStatement(node.label, node);
  }
};

exports.BlockStatement = function (block, parent, file, scope) {
  if (!t.isFor(parent)) {
    run(false, block, parent, file, scope);
  }
};

var noClosure = function (letDeclars, block, replacements) {
  standardiseLets(letDeclars);

  if (_.isEmpty(replacements)) return;

  traverse(block, function (node, parent) {
    if (!t.isIdentifier(node)) return;
    if (!t.isReferenced(node, parent)) return;
    node.name = replacements[node.name] || node.name;
  });
};

var standardiseLets = function (declars) {
  _.each(declars, function (declar) {
    delete declar._let;
  });
};

var getInfo = function (block, file, scope) {
  var opts = {
    // array of `Identifier` names of let variables that appear lexically out of
    // this scope but should be accessible - eg. `ForOfStatement`.left
    outsideKeys: [],

    // array of let `VariableDeclarator`s that are a part of this block
    declarators: block._letDeclars || [],

    // object of duplicate ids and their aliases - if there's an `Identifier`
    // name that's used in an upper scope we generate a unique id and replace
    // all references with it
    duplicates:  {},

    // array of `Identifier` names of let variables that are accessible within
    // the current block
    keys:        []
  };

  _.each(opts.declarators, function (declar) {
    opts.declarators.push(declar);

    var keys = t.getIds(declar);
    opts.outsideKeys = opts.outsideKeys.concat(keys);
    opts.keys = opts.keys.concat(keys);
  });

  _.each(block.body, function (declar) {
    if (!isLet(declar)) return;

    _.each(t.getIds(declar, true), function (id, key) {
      var has = scope.parentGet(key);

      if (has && has !== id) {
        // there's a variable with this exact name in an upper scope so we need
        // to generate a new name
        opts.duplicates[key] = id.name = file.generateUid(key, scope);
      }

      opts.keys.push(key);
    });
  });

  return opts;
};

var checkFor = function (forParent, block) {
  var has = {
    hasContinue: false,
    hasReturn:   false,
    hasBreak:    false,
  };

  if (forParent) {
    traverse(block, function (node) {
      var replace;

      if (t.isFunction(node) || t.isFor(node)) {
        return false;
      } else if (t.isBreakStatement(node) && !node.label) {
        has.hasBreak = true;
        replace = t.returnStatement(t.literal("break"));
      } else if (t.isContinueStatement(node) && !node.label) {
        has.hasContinue = true;
        replace = t.returnStatement(t.literal("continue"));
      } else if (t.isReturnStatement(node)) {
        has.hasReturn = true;
        replace = t.returnStatement(t.objectExpression([
          t.property("init", t.identifier("v"), node.argument)
        ]));
      }

      if (replace) return t.inherits(replace, node);
    });
  }

  return has;
};

var hoistVarDeclarations = function (block, pushDeclar) {
  traverse(block, function (node) {
    if (t.isForStatement(node)) {
      if (isVar(node.init)) {
        node.init = t.sequenceExpression(pushDeclar(node.init));
      }
    } else if (t.isFor(node)) {
      if (isVar(node.left)) {
        node.left = node.left.declarations[0].id;
      }
    } else if (isVar(node)) {
      return pushDeclar(node).map(t.expressionStatement);
    } else if (t.isFunction(node)) {
      return false;
    }
  });
};

var getParams = function (info, letReferences) {
  var params = _.cloneDeep(letReferences);
  _.each(params, function (param) {
    param.name = info.duplicates[param.name] || param.name;
  });
  return params;
};

var getLetReferences = function (block, info, letReferences) {
  var closurify = false;

  // traverse through this block, stopping on functions and checking if they
  // contain any outside let references
  traverse(block, function (node, parent, scope) {
    if (t.isFunction(node)) {
      traverse(node, function (node, parent) {
        // not an identifier so we have no use
        if (!t.isIdentifier(node)) return;

        // not a direct reference
        if (!t.isReferenced(node, parent)) return;

        // this scope has a variable with the same name so it couldn't belong
        // to our let scope
        if (scope.hasOwn(node.name)) return;

        closurify = true;

        // this key doesn't appear just outside our scope
        if (!_.contains(info.outsideKeys, node.name)) return;

        // push this badboy
        letReferences[node.name] = node;
      });

      return false;
    } else if (t.isFor(node)) {
      return false;
    }
  });

  return closurify;
};

var buildPushDeclar = function (body) {
  return function (node) {
    body.push(t.variableDeclaration(node.kind, node.declarations.map(function (declar) {
      return t.variableDeclarator(declar.id);
    })));

    var replace = [];

    _.each(node.declarations, function (declar) {
      if (!declar.init) return;

      var expr = t.assignmentExpression("=", declar.id, declar.init);
      replace.push(t.inherits(expr, declar));
    });

    return replace;
  };
};

var run = function (forParent, block, parent, file, scope) {
  if (block._letDone) return;
  block._letDone = true;

  var info = getInfo(block, file, scope);
  var declarators = info.declarators;
  var letKeys = info.keys;

  // this is a block within a `Function` so we can safely leave it be
  if (t.isFunction(parent)) return;

  // this block has no let references so let's clean up
  if (!letKeys.length) return noClosure(declarators, block, info.duplicates);

  // outside let references that we need to wrap
  var letReferences = {};

  // returns whether or not there are any outside let references within any
  // functions
  var closurify = getLetReferences(block, info, letReferences);

  letReferences = _.values(letReferences);

  // no need for a closure so let's clean up
  if (!closurify) return noClosure(declarators, block, info.duplicates);

  // if we're inside of a for loop then we search to see if there are any
  // `break`s, `continue`s, `return`s etc
  var has = checkFor(forParent, block);

  var body = [];

  // hoist a `VariableDeclaration` and add `AssignmentExpression`s in it's place
  var pushDeclar = buildPushDeclar(body);

  // hoist var references to retain scope
  hoistVarDeclarations(block, pushDeclar);

  // set let references to plain var references
  standardiseLets(declarators);

  // build the closure that we're going to wrap the block with
  var fn = t.functionExpression(null, letReferences, t.blockStatement(block.body));
  fn._aliasFunction = true;

  // replace the current block body with the one we've built
  block.body = body;

  // change duplicate let references to their uid if they have one
  var params = getParams(info, letReferences);

  var call = t.callExpression(fn, params);
  var ret  = t.identifier(file.generateUid("ret", scope));

  if (has.hasReturn || has.hasBreak || has.hasContinue) {
    body.push(t.variableDeclaration("var", [
      t.variableDeclarator(ret, call)
    ]));

    var retCheck;

    if (has.hasReturn) {
      // typeof ret === "object"
      retCheck = util.template("let-scoping-return", {
        RETURN: ret,
      });

      // there's no `break` or `continue` so we can just push in the `if`
      if (!has.hasBreak && !has.hasContinue) {
        body.push(retCheck);
      }
    }

    if (has.hasBreak || has.hasContinue) {
      // ensure that the parent has a label as we're building a switch and we
      // need to be able to access it
      var label = forParent.label = forParent.label || t.identifier(file.generateUid("loop", scope));

      var cases = [];

      if (has.hasBreak) {
        cases.push(t.switchCase(t.literal("break"), [t.breakStatement(label)]));
      }

      if (has.hasContinue) {
        cases.push(t.switchCase(t.literal("continue"), [t.continueStatement(label)]));
      }

      if (has.hasReturn) {
        cases.push(t.switchCase(null, [retCheck]));
      }

      body.push(t.switchStatement(ret, cases));
    }
  } else {
    body.push(t.expressionStatement(call));
  }
};
<commit_msg>nicer let-scoping switch<commit_after>var traverse = require("../../traverse");
var util     = require("../../util");
var t        = require("../../types");
var _        = require("lodash");

var isLet = function (node) {
  if (!t.isVariableDeclaration(node)) return false;
  if (node._let) return true;
  if (node.kind !== "let") return false;

  node._let = true;
  node.kind = "var";
  return true;
};

var isVar = function (node) {
  return t.isVariableDeclaration(node, { kind: "var" }) && !isLet(node);
};

exports.VariableDeclaration = function (node) {
  isLet(node);
};

exports.For = function (node, parent, file, scope) {
  var init = node.left || node.init;
  if (isLet(init)) {
    t.ensureBlock(node);
    node.body._letDeclars = [init];
  }

  if (t.isLabeledStatement(parent)) {
    // set label so `run` has access to it
    node.label = parent.label;
  }

  run(node, node.body, parent, file, scope);

  if (node.label && !t.isLabeledStatement(parent)) {
    // we've been given a label so let's wrap ourselves
    return t.labeledStatement(node.label, node);
  }
};

exports.BlockStatement = function (block, parent, file, scope) {
  if (!t.isFor(parent)) {
    run(false, block, parent, file, scope);
  }
};

var noClosure = function (letDeclars, block, replacements) {
  standardiseLets(letDeclars);

  if (_.isEmpty(replacements)) return;

  traverse(block, function (node, parent) {
    if (!t.isIdentifier(node)) return;
    if (!t.isReferenced(node, parent)) return;
    node.name = replacements[node.name] || node.name;
  });
};

var standardiseLets = function (declars) {
  _.each(declars, function (declar) {
    delete declar._let;
  });
};

var getInfo = function (block, file, scope) {
  var opts = {
    // array of `Identifier` names of let variables that appear lexically out of
    // this scope but should be accessible - eg. `ForOfStatement`.left
    outsideKeys: [],

    // array of let `VariableDeclarator`s that are a part of this block
    declarators: block._letDeclars || [],

    // object of duplicate ids and their aliases - if there's an `Identifier`
    // name that's used in an upper scope we generate a unique id and replace
    // all references with it
    duplicates:  {},

    // array of `Identifier` names of let variables that are accessible within
    // the current block
    keys:        []
  };

  _.each(opts.declarators, function (declar) {
    opts.declarators.push(declar);

    var keys = t.getIds(declar);
    opts.outsideKeys = opts.outsideKeys.concat(keys);
    opts.keys = opts.keys.concat(keys);
  });

  _.each(block.body, function (declar) {
    if (!isLet(declar)) return;

    _.each(t.getIds(declar, true), function (id, key) {
      var has = scope.parentGet(key);

      if (has && has !== id) {
        // there's a variable with this exact name in an upper scope so we need
        // to generate a new name
        opts.duplicates[key] = id.name = file.generateUid(key, scope);
      }

      opts.keys.push(key);
    });
  });

  return opts;
};

var checkFor = function (forParent, block) {
  var has = {
    hasContinue: false,
    hasReturn:   false,
    hasBreak:    false,
  };

  if (forParent) {
    traverse(block, function (node) {
      var replace;

      if (t.isFunction(node) || t.isFor(node)) {
        return false;
      } else if (t.isBreakStatement(node) && !node.label) {
        has.hasBreak = true;
        replace = t.returnStatement(t.literal("break"));
      } else if (t.isContinueStatement(node) && !node.label) {
        has.hasContinue = true;
        replace = t.returnStatement(t.literal("continue"));
      } else if (t.isReturnStatement(node)) {
        has.hasReturn = true;
        replace = t.returnStatement(t.objectExpression([
          t.property("init", t.identifier("v"), node.argument || t.identifier("undefined"))
        ]));
      }

      if (replace) return t.inherits(replace, node);
    });
  }

  return has;
};

var hoistVarDeclarations = function (block, pushDeclar) {
  traverse(block, function (node) {
    if (t.isForStatement(node)) {
      if (isVar(node.init)) {
        node.init = t.sequenceExpression(pushDeclar(node.init));
      }
    } else if (t.isFor(node)) {
      if (isVar(node.left)) {
        node.left = node.left.declarations[0].id;
      }
    } else if (isVar(node)) {
      return pushDeclar(node).map(t.expressionStatement);
    } else if (t.isFunction(node)) {
      return false;
    }
  });
};

var getParams = function (info, letReferences) {
  var params = _.cloneDeep(letReferences);
  _.each(params, function (param) {
    param.name = info.duplicates[param.name] || param.name;
  });
  return params;
};

var getLetReferences = function (block, info, letReferences) {
  var closurify = false;

  // traverse through this block, stopping on functions and checking if they
  // contain any outside let references
  traverse(block, function (node, parent, scope) {
    if (t.isFunction(node)) {
      traverse(node, function (node, parent) {
        // not an identifier so we have no use
        if (!t.isIdentifier(node)) return;

        // not a direct reference
        if (!t.isReferenced(node, parent)) return;

        // this scope has a variable with the same name so it couldn't belong
        // to our let scope
        if (scope.hasOwn(node.name)) return;

        closurify = true;

        // this key doesn't appear just outside our scope
        if (!_.contains(info.outsideKeys, node.name)) return;

        // push this badboy
        letReferences[node.name] = node;
      });

      return false;
    } else if (t.isFor(node)) {
      return false;
    }
  });

  return closurify;
};

var buildPushDeclar = function (body) {
  return function (node) {
    body.push(t.variableDeclaration(node.kind, node.declarations.map(function (declar) {
      return t.variableDeclarator(declar.id);
    })));

    var replace = [];

    _.each(node.declarations, function (declar) {
      if (!declar.init) return;

      var expr = t.assignmentExpression("=", declar.id, declar.init);
      replace.push(t.inherits(expr, declar));
    });

    return replace;
  };
};

var run = function (forParent, block, parent, file, scope) {
  if (block._letDone) return;
  block._letDone = true;

  var info = getInfo(block, file, scope);
  var declarators = info.declarators;
  var letKeys = info.keys;

  // this is a block within a `Function` so we can safely leave it be
  if (t.isFunction(parent)) return;

  // this block has no let references so let's clean up
  if (!letKeys.length) return noClosure(declarators, block, info.duplicates);

  // outside let references that we need to wrap
  var letReferences = {};

  // returns whether or not there are any outside let references within any
  // functions
  var closurify = getLetReferences(block, info, letReferences);

  letReferences = _.values(letReferences);

  // no need for a closure so let's clean up
  if (!closurify) return noClosure(declarators, block, info.duplicates);

  // if we're inside of a for loop then we search to see if there are any
  // `break`s, `continue`s, `return`s etc
  var has = checkFor(forParent, block);

  var body = [];

  // hoist a `VariableDeclaration` and add `AssignmentExpression`s in it's place
  var pushDeclar = buildPushDeclar(body);

  // hoist var references to retain scope
  hoistVarDeclarations(block, pushDeclar);

  // set let references to plain var references
  standardiseLets(declarators);

  // build the closure that we're going to wrap the block with
  var fn = t.functionExpression(null, letReferences, t.blockStatement(block.body));
  fn._aliasFunction = true;

  // replace the current block body with the one we've built
  block.body = body;

  // change duplicate let references to their uid if they have one
  var params = getParams(info, letReferences);

  var call = t.callExpression(fn, params);
  var ret  = t.identifier(file.generateUid("ret", scope));

  if (has.hasReturn || has.hasBreak || has.hasContinue) {
    body.push(t.variableDeclaration("var", [
      t.variableDeclarator(ret, call)
    ]));

    var retCheck;

    var cases = [];

    if (has.hasReturn) {
      // typeof ret === "object"
      retCheck = util.template("let-scoping-return", {
        RETURN: ret,
      });
    }

    if (has.hasBreak || has.hasContinue) {
      // ensure that the parent has a label as we're building a switch and we
      // need to be able to access it
      var label = forParent.label = forParent.label || t.identifier(file.generateUid("loop", scope));

      if (has.hasBreak) {
        cases.push(t.switchCase(t.literal("break"), [t.breakStatement(label)]));
      }

      if (has.hasContinue) {
        cases.push(t.switchCase(t.literal("continue"), [t.continueStatement(label)]));
      }

      if (has.hasReturn) {
        cases.push(t.switchCase(null, [retCheck]));
      }

      if (cases.length === 1) {
        var single = cases[0];
        body.push(t.ifStatement(
          t.binaryExpression("===", ret, single.test),
          single.consequent[0]
        ));
      } else {
        body.push(t.switchStatement(ret, cases));
      }
    } else {
      if (has.hasReturn) body.push(retCheck);
    }
  } else {
    body.push(t.expressionStatement(call));
  }
};
<|endoftext|>


<commit_before>'use strict'

const {
  env: {
    GIST_TOKEN,
    GIST_ID,
    PROJECT_VERSION
  },
  exit,
  stdout,
  stderr
} = require('process')

if (!RELEASE_GIST) {
  stdout.write('Skipped Gist release\n')
  exit(1)
}

if (!GIST_ID || !GIST_TOKEN) {
  stderr.write('Missing environment variables\n')
  exit(1)
}
<commit_msg>Complete deploy gist<commit_after>'use strict'

const NOW = new Date()

const {join, parse} = require('path')

const {readFileSync, readdirSync} = require('fs')

const GitHubAPIs = require('github')

const {
  env: {
    GIST_TOKEN,
    GIST_ID,
    PROJECT_VERSION
  },
  exit,
  stdout,
  stderr
} = require('process')

if (!RELEASE_GIST) {
  stdout.write('Skipped Gist release\n')
  exit(1)
}

if (!GIST_ID || !GIST_TOKEN) {
  stderr.write('Missing environment variables\n')
  exit(1)
}

const github = new GitHubAPIs()
const files = {}
const ENCODING = {encoding: 'utf8'}
const CONTAINER = join(__dirname, '..', '..', 'out')
const LIST = readdirSync(CONTAINER)

const filename = item => {
  const {name, extname} = parse(item)
  return name + '-' + PROJECT_VERSION + extname
}

for (const item of LIST) {
  const content = readFileSync(join(CONTAINER, item), ENCODING)
  files[filename(item)] = {content}
}

github.authenticate({
  type: 'token',
  token: GIST_TOKEN
})

new Promise(
  (resolve, reject) => {
    github.gists.edit({
      id: GIST_ID,
      files
    })
      .then(
        response => {
          const rfiles = response.files
          let summary = `# Release ${PROJECT_VERSION} - ${NOW.toISOString()}\n\n`
          for (const item of LIST) {
            const {raw_url, type, language} = rfiles[filename(item)]
            summary += ` * [${item}](${raw_url})\n  - Type: ${type}\n  - Language: ${language}\n\n`
          }
          github.gists.edit({
            id: GIST_ID,
            files: {
              [ filename('summary.md') ]: summary
            }
          })
            .then(resolve)
            .catch(reject)
        }
      )
      .catch(reject)
  }
)
  .catch(
    () => {
      stderr.write('Upload to Gist failed.\n')
      exit(2)
    }
  )
<|endoftext|>


<commit_before>'use strict'

const NOW = new Date()

const {join, parse} = require('path')

const {readFileSync, readdirSync} = require('fs')

const GitHubAPIs = require('github')

const {
  env: {
    RELEASE_GIST,
    GIST_TOKEN,
    GIST_ID,
    PROJECT_VERSION
  },
  exit,
  stdout,
  stderr
} = require('process')

if (!RELEASE_GIST) {
  stdout.write('Skipped Gist release\n')
  exit(1)
}

if (!GIST_ID || !GIST_TOKEN) {
  stderr.write('Missing environment variables\n')
  exit(1)
}

const github = new GitHubAPIs()
const files = {}
const ENCODING = {encoding: 'utf8'}
const CONTAINER = join(__dirname, '..', '..', 'out')
const LIST = readdirSync(CONTAINER)

const filename = item => {
  const {name, ext} = parse(item)
  return name + '-' + PROJECT_VERSION + extname
}

for (const item of LIST) {
  const content = readFileSync(join(CONTAINER, item), ENCODING)
  files[filename(item)] = {content}
}

github.authenticate({
  type: 'token',
  token: GIST_TOKEN
})

new Promise(
  (resolve, reject) => {
    github.gists.edit({
      id: GIST_ID,
      files
    })
      .then(
        response => {
          const rfiles = response.files
          let summary = `# Release ${PROJECT_VERSION} - ${NOW.toISOString()}\n\n`
          for (const item of LIST) {
            const {raw_url: url, type, language} = rfiles[filename(item)]
            summary += ` * [${item}](${url})\n  - Type: ${type}\n  - Language: ${language}\n\n`
          }
          github.gists.edit({
            id: GIST_ID,
            files: {
              [ filename('summary.md') ]: summary
            }
          })
            .then(resolve)
            .catch(reject)
        }
      )
      .catch(reject)
  }
)
  .catch(
    () => {
      stderr.write('Upload to Gist failed.\n')
      exit(2)
    }
  )
<commit_msg>Fix JS error<commit_after>'use strict'

const NOW = new Date()

const {join, parse} = require('path')

const {readFileSync, readdirSync} = require('fs')

const GitHubAPIs = require('github')

const {
  env: {
    RELEASE_GIST,
    GIST_TOKEN,
    GIST_ID,
    PROJECT_VERSION
  },
  exit,
  stdout,
  stderr
} = require('process')

if (!RELEASE_GIST) {
  stdout.write('Skipped Gist release\n')
  exit(1)
}

if (!GIST_ID || !GIST_TOKEN) {
  stderr.write('Missing environment variables\n')
  exit(1)
}

const github = new GitHubAPIs()
const files = {}
const ENCODING = {encoding: 'utf8'}
const CONTAINER = join(__dirname, '..', '..', 'out')
const LIST = readdirSync(CONTAINER)

const filename = item => {
  const {name, ext} = parse(item)
  return name + '-' + PROJECT_VERSION + ext
}

for (const item of LIST) {
  const content = readFileSync(join(CONTAINER, item), ENCODING)
  files[filename(item)] = {content}
}

github.authenticate({
  type: 'token',
  token: GIST_TOKEN
})

new Promise(
  (resolve, reject) => {
    github.gists.edit({
      id: GIST_ID,
      files
    })
      .then(
        response => {
          const rfiles = response.files
          let summary = `# Release ${PROJECT_VERSION} - ${NOW.toISOString()}\n\n`
          for (const item of LIST) {
            const {raw_url: url, type, language} = rfiles[filename(item)]
            summary += ` * [${item}](${url})\n  - Type: ${type}\n  - Language: ${language}\n\n`
          }
          github.gists.edit({
            id: GIST_ID,
            files: {
              [ filename('summary.md') ]: summary
            }
          })
            .then(resolve)
            .catch(reject)
        }
      )
      .catch(reject)
  }
)
  .catch(
    () => {
      stderr.write('Upload to Gist failed.\n')
      exit(2)
    }
  )
<|endoftext|>


<commit_before>
/*
================

================
*/
var Result = function(status,output,settings,exceptions){
  var _status=status;
  var _output=output;
  var _settings=settings;
  var _exceptions=exceptions;
  /*-- this.status --*/
  this.status = function(){
    return _status;
  };
  /*-- this.output --*/
  this.output = function(){
    return _output;
  };
  /*-- this.settings --*/
  this.settings = function(){
    return _settings;
  };
  /*-- this.exceptions --*/
  this.exceptions = function(){
    return _exceptions;
  };
};
/*
================

================
*/
var Chain = function(){
  var _defaults = {};
  var _options = {};
  var _defaultHandlers = {};
  var _customHandlers = {};
  var _defaultWorkers = {};
  var _customWorkers = {};
  _handlerFirst = true;
  _customHandlerFirst = true;
  _customWorkerFirst = true;
  _optionFirst = true;
  /*
  ====================================
  -- access utility method --
  ====================================
  */
  var _access = function(target,callerArguments){
    var args = callerArguments ||[];
    //alert('cLength : ' + args.length);
    if(args.length === 1){
      return typeof target === 'undefined' || target === null ?
          undefined : [args[0],target[args[0]]] ;
    } else if (args.length >= 2){
      // more than one
      if(target === undefined || target === null)
        target = {};
      target[args[0]] = args[1];
    }
    //no argument
    return target;
  };
  /*
  ====================================
  -- compound access utility method --
  ====================================
  */
  var _compoundAccess = function(couple,defaultTarget, customTarget,callerArguments){
    if(!arguments || arguments.length < 3)
      return undefined;
    var args = callerArguments||[];

    if(!args.length){
      return {defaults : _access(defaultTarget,args),
            options : _access(customTarget,args)};
    }

    var defaultResult = _access(defaultTarget, args)[1];
    var customResult = _access(customTarget, args)[1];
    // when one is null and other undefined vice versa
    // the
    return couple === 'settings' && this.optionFirst ||
        couple === 'handlers' && this.customHandlerFirst ||
        couple === 'workers' && this.customWorkerFirst  ?
        customResult ||defaultResult :
        defaultResult||customResult;
  };
  /*
  ====================================
  -- this.defaults method --
  ====================================
  */
  this.defaults = function(){
    //alert('defaults : ' + JSON.stringify(_defaults));
    var result = _access(_defaults, arguments);
    //result !== arguments[0] : when catalog === array
    if(Array.isArray(result) && result !== arguments[0])
      return result[1];
    else
      _defaults = result;
    return _defaults;
  };
  /*
  ====================================
  -- this.defaultsReset method --
  ====================================
  */
  this.defaultsReset = function(){
    if(arguments.length)
      _defaults = arguments[0];
    return _defaults;
  };
  /*
  ====================================
  -- this.options method --
  ====================================
  */
  this.options = function(){
    var result = _access(_options, arguments);
    //result !== arguments[0] : when catalog === array
    if(Array.isArray(result) && result !== arguments[0])
      return result[1];
    else
      _options = result;
    return _options;
  };
  /*
  ====================================
  -- this.optionsReset method --
  ====================================
  */
  this.optionsReset = function(){
    if(arguments.length)
      _options = arguments[0];
    return _options;
  };
  /*
  ====================================
  -- this.settings method --
  ====================================
  */
  this.settings = function(){
    //alert(JSON.stringify(arguments));
    return _compoundAccess('settings',_defaults,_options,arguments);
  };
  /*
  ====================================
  -- this.defaultWorkers method --
  ====================================
  */
  this.defaultWorkers = function(){
    var result = _access(_defaultWorkers, arguments);
    //result !== arguments[0] : when catalog === array
    if(Array.isArray(result) && result !== arguments[0])
      return result[1];
    else
      _defaultWorkers = result;
    return _defaultWorkers;
  };
  /*
  ====================================
  -- this.defaultWorkersReset method --
  ====================================
  */
  this.defaultWorkersReset = function(){
    if(arguments.length)
      _defaultWorkers = arguments[0];
    return _defaultWorkers;
  };
  /*
  ====================================
  -- this.customWorkers method --
  ====================================
  */
  this.customWorkers = function(){
    var result = _access(_customWorkers, arguments);
    //result !== arguments[0] : when catalog === array
    if(Array.isArray(result) && result !== arguments[0])
      return result[1];
    else
      _customWorkers = result;
    return _customWorkers;
  };
  /*
  ====================================
  -- this.customWorkersReset method --
  ====================================
  */
  this.customWorkersReset = function(){
    if(arguments.length)
      _customWorkers = arguments[0];
    return _customWorkers;
  };
  /*
  ====================================
  -- this.workers method --
  ====================================
  */
  /*-- this.workers --*/
  this.workers = function(){
    return _compoundAccess('workers',_defaultWorkers,_customWorkers,arguments);
  };
  /*
  ====================================
  -- this.defaultHandlers method --
  ====================================
  */
  this.defaultHandlers = function(){
    var result = _access(_defaultHandlers, arguments);
    //result !== arguments[0] : when catalog === array
    if(Array.isArray(result) && result !== arguments[0])
      return result[1];
    else
      _defaultHandlers = result;
    return _defaultHandlers;
  };
  /*
  ====================================
  -- this.defaultHandlersReset method --
  ====================================
  */
  this.defaultHandlersReset = function(){
    if(arguments.length)
      _defaultHandlers = arguments[0];
    return _defaultHandlers;
  };
  /*
  ====================================
  -- this.customHandlers method --
  ====================================
  */
  this.customHandlers = function(){
    var result = _access(_customHandlers, arguments);
    //result !== arguments[0] : when catalog === array
    if(Array.isArray(result) && result !== arguments[0])
      return result[1];
    else
      _customHandlers = result;
    return _customHandlers;
  };
  /*
  ====================================
  -- this.defaultHandlersReset method --
  ====================================
  */
  this.customHandlersReset = function(){
    if(arguments.length)
      _customHandlers = arguments[0];
    return _customHandlers;
  };
  /*
  ====================================
  -- this.handlers method --
  ====================================
  */
  this.handlers = function(){
    return _compoundAccess('handlers',_defaultHandlers,_customHandlers,arguments);
  };
  /*
  ====================================
  -- this.defaultHandlersReset method --
  ====================================
  */
  this.catalogsReset = function(){
    if(!arguments.length)
      return;
    var catalogs =
        ['_defaults','_options','_defaultHandlers',
         '_customHandlers','_defaultWorkers','_customWorkers'];
    catalogs.forEach(function(current,index, array){
      if(arguments[0].hasOwnProperty(current))
        switch (current){
          case catalogs[0] :
            _defaults = arguments[0][current];
            break;
          case catalogs[1] :
            _options = arguments[0][current];
            break;
          case catalogs[2] :
            _defaultHandlers = arguments[0][current];
            break;
          case catalogs[3] :
            _customHandlers = arguments[0][current];
            break;
          case catalogs[4] :
            _defaultWorkers = arguments[0][current];
            break;
          case catalogs[5] :
            _customWorkers = arguments[0][current];
            break;
        }
    });
  };
  /*
  ====================================
  -- this.handlerFirst method --
  ====================================
  */
  this.handlerFirst = function(){
    if(arguments.length)
      _handlerFirst = Boolean(arguments[0]);
    return _handlerFirst;
  };
  /*
  ====================================
  -- this.customHandlerFirst --
  ====================================
  */
  this.customHandlerFirst = function(){
    if(arguments.length)
      _customHandlerFirst = Boolean(arguments[0]);
    return _customHandlerFirst;
  };
  /*
  ====================================
  -- this.customWorkerFirst --
  ====================================
  */
  this.customWorkerFirst = function(){
    if(arguments.length)
      _customWorkerFirst = Boolean(arguments[0]);
    return _customWorkerFirst;
  };
  /*
  ====================================
  -- this.optionFirst --
  ====================================
  */
  this.optionFirst = function(){
    if(arguments.length)
      _optionFirst = Boolean(arguments[0]);
    return _optionFirst;
  };
  /*
  ====================================
  -- runWorker method --
  ====================================
  */
  var runWorker = function(work,workName,settings){
    if(work && typeof work === 'function'){
      var output;
      var exceptions;
      // simple function to execute
      try {
        output = work(settings);
      } catch(error){
        error.message = '[WorkerError for workName "' +
          workName + '"] : ' + error.message;
        error.name = 'workerError';
        exceptions = error;
      }
      return new Result('ok',output,settings,exceptions);
    } else
      return undefined;
  };
  /*
  ====================================
  -- runWorkerFirst method --
  ====================================
  */
  var runHandler = function(handler,workName,settings){
    if(handler && handler.handle && typeof handler.handle === 'function'){
      var output;
      var exceptions;
      var status = 'ok';
      // handle function to execute on a object
      try{
        output = handler.handle(settings);
      } catch(error){
        error.message = '[HandlerError for workname "' + workName +
          '"] : ' + error.message;
        error.name = 'handlerError';
        exceptions = error;
      }
      // ??? what if output null/undefined ?
      return output instanceof Result ?
          output : new Result(status,output,settings,exceptions);
    } else
      return undefined;
  };
  /*
  ====================================
  -- this.run method --
  ====================================
  */
  this.run = function(workName,parameters){
    var settings = this.optionFirst ?
        Object.assign({},this.defaults(),this.options(),parameters||{}) :
    Object.assign({},this.options(),parameters||{},this.defaults());
    var handler = this.handlers(workName||undefined);
    var work = this.workers(workName||undefined);
    var result =
        this.handlerFirst ?
        runHandler(handler, workName,settings) ||
        runWorker(work,workName,settings)
    :  runWorker(work,workName,settings) ||
        runHandler(handler, workName,settings);
    if(result)
      return result;
    // undefined result
    var unknownWorknameError = new Error(
        '[UnknownWorknameError for workname "' +
      workName + '"] : no handler and no worker function found.');
    unknownWorknameError.name = 'unknownWorknameError';
    // return
    return new Result('ok',undefined,settings,unknownWorknameError);
  };
};
<commit_msg>update catalogsReset<commit_after>
/*
================

================
*/
var Result = function(status,output,settings,exceptions){
  var _status=status;
  var _output=output;
  var _settings=settings;
  var _exceptions=exceptions;
  /*-- this.status --*/
  this.status = function(){
    return _status;
  };
  /*-- this.output --*/
  this.output = function(){
    return _output;
  };
  /*-- this.settings --*/
  this.settings = function(){
    return _settings;
  };
  /*-- this.exceptions --*/
  this.exceptions = function(){
    return _exceptions;
  };
};
/*
================

================
*/
var Chain = function(){
  var _defaults = {};
  var _options = {};
  var _defaultHandlers = {};
  var _customHandlers = {};
  var _defaultWorkers = {};
  var _customWorkers = {};
  var _handlerFirst = true;
  var _customHandlerFirst = true;
  var _customWorkerFirst = true;
  var _optionFirst = true;
  /*
  ====================================
  -- access utility method --
  ====================================
  */
  var _access = function(target,callerArguments){
    var args = callerArguments ||[];
    //alert('cLength : ' + args.length);
    if(args.length === 1){
      return typeof target === 'undefined' || target === null ?
          undefined : [args[0],target[args[0]]] ;
    } else if (args.length >= 2){
      // more than one
      if(target === undefined || target === null)
        target = {};
      target[args[0]] = args[1];
    }
    //no argument
    return target;
  };
  /*
  ====================================
  -- compound access utility method --
  ====================================
  */
  var _compoundAccess = function(couple,defaultTarget, customTarget,callerArguments){
    if(!arguments || arguments.length < 3)
      return undefined;
    var args = callerArguments||[];

    if(!args.length){
      return {defaults : _access(defaultTarget,args),
            options : _access(customTarget,args)};
    }

    var defaultResult = _access(defaultTarget, args)[1];
    var customResult = _access(customTarget, args)[1];
    // when one is null and other undefined vice versa
    // return null.
    if(defaultResult === null && typeof customResult === 'undefined' ||
      typeof defaultResult === 'undefined' && customResult === null)
      return null;
    return couple === 'settings' && _optionFirst ||
        couple === 'handlers' && _customHandlerFirst ||
        couple === 'workers' && _customWorkerFirst ?
        customResult ||defaultResult :
        defaultResult||customResult;
  };
  /*
  ====================================
  -- this.defaults method --
  ====================================
  */
  this.defaults = function(){
    //alert('defaults : ' + JSON.stringify(_defaults));
    var result = _access(_defaults, arguments);
    //result !== arguments[0] : when catalog === array
    if(Array.isArray(result) && result !== arguments[0])
      return result[1];
    else
      _defaults = result;
    return _defaults;
  };
  /*
  ====================================
  -- this.defaultsReset method --
  ====================================
  */
  this.defaultsReset = function(){
    if(arguments.length)
      _defaults = arguments[0];
    return _defaults;
  };
  /*
  ====================================
  -- this.options method --
  ====================================
  */
  this.options = function(){
    var result = _access(_options, arguments);
    //result !== arguments[0] : when catalog === array
    if(Array.isArray(result) && result !== arguments[0])
      return result[1];
    else
      _options = result;
    return _options;
  };
  /*
  ====================================
  -- this.optionsReset method --
  ====================================
  */
  this.optionsReset = function(){
    if(arguments.length)
      _options = arguments[0];
    return _options;
  };
  /*
  ====================================
  -- this.settings method --
  ====================================
  */
  this.settings = function(){
    //alert(JSON.stringify(arguments));
    return _compoundAccess('settings',_defaults,_options,arguments);
  };
  /*
  ====================================
  -- this.defaultWorkers method --
  ====================================
  */
  this.defaultWorkers = function(){
    var result = _access(_defaultWorkers, arguments);
    //result !== arguments[0] : when catalog === array
    if(Array.isArray(result) && result !== arguments[0])
      return result[1];
    else
      _defaultWorkers = result;
    return _defaultWorkers;
  };
  /*
  ====================================
  -- this.defaultWorkersReset method --
  ====================================
  */
  this.defaultWorkersReset = function(){
    if(arguments.length)
      _defaultWorkers = arguments[0];
    return _defaultWorkers;
  };
  /*
  ====================================
  -- this.customWorkers method --
  ====================================
  */
  this.customWorkers = function(){
    var result = _access(_customWorkers, arguments);
    //result !== arguments[0] : when catalog === array
    if(Array.isArray(result) && result !== arguments[0])
      return result[1];
    else
      _customWorkers = result;
    return _customWorkers;
  };
  /*
  ====================================
  -- this.customWorkersReset method --
  ====================================
  */
  this.customWorkersReset = function(){
    if(arguments.length)
      _customWorkers = arguments[0];
    return _customWorkers;
  };
  /*
  ====================================
  -- this.workers method --
  ====================================
  */
  /*-- this.workers --*/
  this.workers = function(){
    return _compoundAccess('workers',_defaultWorkers,_customWorkers,arguments);
  };
  /*
  ====================================
  -- this.defaultHandlers method --
  ====================================
  */
  this.defaultHandlers = function(){
    var result = _access(_defaultHandlers, arguments);
    //result !== arguments[0] : when catalog === array
    if(Array.isArray(result) && result !== arguments[0])
      return result[1];
    else
      _defaultHandlers = result;
    return _defaultHandlers;
  };
  /*
  ====================================
  -- this.defaultHandlersReset method --
  ====================================
  */
  this.defaultHandlersReset = function(){
    if(arguments.length)
      _defaultHandlers = arguments[0];
    return _defaultHandlers;
  };
  /*
  ====================================
  -- this.customHandlers method --
  ====================================
  */
  this.customHandlers = function(){
    var result = _access(_customHandlers, arguments);
    //result !== arguments[0] : when catalog === array
    if(Array.isArray(result) && result !== arguments[0])
      return result[1];
    else
      _customHandlers = result;
    return _customHandlers;
  };
  /*
  ====================================
  -- this.defaultHandlersReset method --
  ====================================
  */
  this.customHandlersReset = function(){
    if(arguments.length)
      _customHandlers = arguments[0];
    return _customHandlers;
  };
  /*
  ====================================
  -- this.handlers method --
  ====================================
  */
  this.handlers = function(){
    return _compoundAccess('handlers',_defaultHandlers,_customHandlers,arguments);
  };
  /*
  ====================================
  -- this.defaultHandlersReset method --
  ====================================
  */
  this.catalogsReset = function(){
    if(!arguments.length)
      return;
    var args = arguments;
    var catalogs =
        ['defaults','options','defaultHandlers',
         'customHandlers','defaultWorkers','customWorkers'];
    catalogs.forEach(function(current,index, array){
      if(args[0].hasOwnProperty(current))
        switch (current){
          case catalogs[0] ://alert('in catalogsReset : ' + arguments[0][current]);
            _defaults = args[0][current];
            break;
          case catalogs[1] :
            _options = args[0][current];
            break;
          case catalogs[2] :
            _defaultHandlers = args[0][current];
            break;
          case catalogs[3] :
            _customHandlers = args[0][current];
            break;
          case catalogs[4] :
            _defaultWorkers = args[0][current];
            break;
          case catalogs[5] :
            _customWorkers = args[0][current];
            break;
        }
    });
  };
  /*
  ====================================
  -- this.handlerFirst method --
  ====================================
  */
  this.handlerFirst = function(){
    if(arguments.length)
      _handlerFirst = Boolean(arguments[0]);
    return _handlerFirst;
  };
  /*
  ====================================
  -- this.customHandlerFirst --
  ====================================
  */
  this.customHandlerFirst = function(){
    if(arguments.length)
      _customHandlerFirst = Boolean(arguments[0]);
    return _customHandlerFirst;
  };
  /*
  ====================================
  -- this.customWorkerFirst --
  ====================================
  */
  this.customWorkerFirst = function(){
    if(arguments.length)
      _customWorkerFirst = Boolean(arguments[0]);
    return _customWorkerFirst;
  };
  /*
  ====================================
  -- this.optionFirst --
  ====================================
  */
  this.optionFirst = function(){
    if(arguments.length)
      _optionFirst = Boolean(arguments[0]);
    return _optionFirst;
  };
  /*
  ====================================
  -- runWorker method --
  ====================================
  */
  var runWorker = function(work,workName,settings){
    if(work && typeof work === 'function'){
      var output;
      var exceptions;
      // simple function to execute
      try {
        output = work(settings);
      } catch(error){
        error.message = '[WorkerError for workName "' +
          workName + '"] : ' + error.message;
        error.name = 'workerError';
        exceptions = error;
      }
      return new Result('ok',output,settings,exceptions);
    } else
      return undefined;
  };
  /*
  ====================================
  -- runWorkerFirst method --
  ====================================
  */
  var runHandler = function(handler,workName,settings){
    if(handler && handler.handle && typeof handler.handle === 'function'){
      var output;
      var exceptions;
      var status = 'ok';
      // handle function to execute on a object
      try{
        output = handler.handle(settings);
      } catch(error){
        error.message = '[HandlerError for workname "' + workName +
          '"] : ' + error.message;
        error.name = 'handlerError';
        exceptions = error;
      }
      // ??? what if output null/undefined ?
      return output instanceof Result ?
          output : new Result(status,output,settings,exceptions);
    } else
      return undefined;
  };
  /*
  ====================================
  -- this.run method --
  ====================================
  */
  this.run = function(workName,parameters){
    var settings = this.optionFirst() ?
        Object.assign({},this.defaults(),this.options(),parameters||{}) :
    Object.assign({},this.options(),parameters||{},this.defaults());
    var handler = this.handlers(workName||undefined);
    var work = this.workers(workName||undefined);
    var result =
        this.handlerFirst() ?
        runHandler(handler, workName,settings) ||
        runWorker(work,workName,settings)
    :  runWorker(work,workName,settings) ||
        runHandler(handler, workName,settings);
    if(result)
      return result;
    // undefined result
    var unknownWorknameError = new Error(
        '[UnknownWorknameError for workname "' +
      workName + '"] : no handler and no worker function found.');
    unknownWorknameError.name = 'unknownWorknameError';
    // return
    return new Result('ok',undefined,settings,unknownWorknameError);
  };
};
<|endoftext|>


<commit_before>import path from 'path';
import fs from 'fs';
import isUndefined from 'lodash/isUndefined';
import merge from 'lodash/merge';
import isNil from 'lodash/isNil';
import isString from 'lodash/isString';
import { createChecksum } from './checksum';
import log from './log';
import Url from './url';
import Parse from './parse';
import Plugin from './plugin';
import cache from './cache';
import {
  renderMarkdown,
} from './markdown';
import {
  renderTemplate,
  renderTemplateString,
  TemplateErrorMessage,
} from './template';
import {
  renderAndWriteFileWithPlugins,
} from './render';

export default class File {
  constructor(filePath = '', getConfig = () => {}) {
    /**
     * Absolute path to file location.
     * @type {string}
     */
    this.path = filePath;

    /**
     * Unique ID for this file. Right now an alias for the file's path.
     * @type {string}
     */
    this.id = this.path;

    /**
     * Template accessible data.
     * @type {Object.<string, Object>}
     */
    this.data = Object.create(null);

    /**
     * An array of Collections that this file belongs to.
     * @type {Set.<string>}
     */
    this.collections = new Set();

    /**
     * An array of CollectionPages that this file belongs to.
     * @type {Set.<string>}
     */
    this.collectionPages = new Set();

    /**
     * Get the global config object.
     * @type {Function}
     * @private
     */
    this._getConfig = getConfig;

    this.updateDataFromFileSystem();
  }

  updateDataFromFileSystem() {
    /**
     * Raw contents of file, directly from file system.
     * @TODO: perhaps don't keep reference to this?
     * @type {string} One long string.
     */
    this.rawContent = fs.readFileSync(this.path, 'utf8');

    /**
     * Checksum hash of rawContent, for use in seeing if file is different.
     * @example:
     * 	'50de70409f11f87b430f248daaa94d67'
     * @type {string}
     */
    this.checksum = createChecksum(this.rawContent);

    // Parse file's frontmatter.
    let parsedFile = Parse.fromFrontMatter(this.rawContent);

    /**
     * Just the file's text content.
     * @type {string}
     */
    let content = parsedFile.content;

    /**
     * If the file itself wants to customize what its URL is then it will use
     * the `config.file.url_key` value of the File's frontmatter as the basis
     * for which the URL of this file should be.
     * So if you have a File with a frontmatter that has `url: /pandas/` then
     * the File's URL will be `/pandas/`.
     * @type {string?} url Relative path to file.
     */
    this.url = parsedFile.data[this._getConfig().get('file.url_key')];

    // Merge in new data that's accessible from template.
    merge(this.data, parsedFile.data, {
      // The content of the Page.
      content: content
    });

    this._calculateDestination();
  }

  /**
   * Path to file relative to root of project.
   * @type {string}
   */
  get pathRelative() {
    return this.path.replace(this._getConfig().get('path.source'), '');
  }

  /**
   * Set new permalink configuration this file should use.
   * @param {string} newPermalink New permalink.
   */
  setPermalink(newPermalink) {
    this.permalink = newPermalink;
    this._calculateDestination();
  }

  /**
   * Calculate both relative and absolute destination path for where to write
   * the file.
   * @private
   */
  _calculateDestination() {
    let destinationUrl;
    if (this.url) {
      // If the individual File defined its own unique URL that gets first
      // dibs at setting the official URL for this file.
      destinationUrl = this.url;
    } else if (this.permalink) {
      // If the file has no URL but has a permalink set on it then use it to
      // find the URL of the File.
      destinationUrl = Url.interpolatePermalink(
        this.permalink,
        this.data
      );
    } else {
      // If the file has no URL set and no permalink then use its relative file
      // path as its url.
      destinationUrl = this.pathRelative;

      const markdownExtensions = this._getConfig().get('markdown_extension');

      // Get file extension of file. i.e. 'post.md' would give 'md'.
      let fileExtension = path.extname(destinationUrl).replace(/^\./, '');
      let index = markdownExtensions.indexOf(fileExtension);

      // Is this file's extension one of our known markdown extensions?
      if (index > -1) {
        let foundExtension = markdownExtensions[index];
        destinationUrl = destinationUrl.replace(
          new RegExp(`.${foundExtension}$`),
          '.html'
        );
      }
    }

    let fileSystemSafeDestination = Url.makeUrlFileSystemSafe(destinationUrl);

    /**
     * Absolute destination path.
     * @type {string} destination Absolute path to file.
     */
    this.destination = path.join(
      this._getConfig().get('path.destination'),
      fileSystemSafeDestination
    );

    this.data.url = Url.makePretty(fileSystemSafeDestination);
  }

  render(template, globalData) {
    template = isUndefined(this.data.template) ? template : this.data.template;
    let result = this.data.content;

    let templateData = {
      ...globalData,
      file: this.data
    };

    try {
      // Set result of content to result content.
      result = renderTemplateString(
        this.data.content,
        templateData
      );

      // Set result to file's contents.
      this.data.content = result;
    } catch (e) {
      log.error(e.message);
      throw new Error(`File: Could not render file's contents.\n` +
        `File: ${JSON.stringify(this)}`);
    }

    // Convert to HTML.
    // Howeve if the File's frontmatter sets markdown value to false then
    // skip the markdown conversion.
    if (this.data.markdown !== false) {
      result = renderMarkdown(this.data.content);
      this.data.content = result;
    }

    if (!isNil(template) && !(isString(template) && template.length === 0)) {
      try {
        result = renderTemplate(template, templateData);
      } catch (e) {
        if (e.message.includes(TemplateErrorMessage.NO_TEMPLATE)) {
          throw new Error(`File: Template '${template}' not found.\n` +
            `File: ${JSON.stringify(this)}`);
        } else {
          throw e;
        }
      }
    }

    return result;
  }

  /**
   * Writes a given File object to the file system.
   * @param {Object} siteData Site wide data.
   * @return {Promise} Promise.
   */
  write(siteData) {
    if (this._getConfig().get('incremental') &&
        cache.get(this.path) === this.checksum) {
      return Promise.resolve();
    }

    let promises = [];

    for (let collection of this.collections) {
      // Don't render if we have no template defined.
      if (isUndefined(collection.template)) {
        continue;
      }

      let promise = renderAndWriteFileWithPlugins(
        this,
        collection.template,
        siteData,
        Plugin.Event.file.beforeRender,
        Plugin.Event.file.afterRender
      );

      promises.push(promise);
    }

    return Promise.all(promises).then(result => {
      // Save checksum to cache for incremental builds.
      cache.put(this.path, this.checksum);

      return result;
    });
  }

}
<commit_msg>fix typo<commit_after>import path from 'path';
import fs from 'fs';
import isUndefined from 'lodash/isUndefined';
import merge from 'lodash/merge';
import isNil from 'lodash/isNil';
import isString from 'lodash/isString';
import { createChecksum } from './checksum';
import log from './log';
import Url from './url';
import Parse from './parse';
import Plugin from './plugin';
import cache from './cache';
import {
  renderMarkdown,
} from './markdown';
import {
  renderTemplate,
  renderTemplateString,
  TemplateErrorMessage,
} from './template';
import {
  renderAndWriteFileWithPlugins,
} from './render';

export default class File {
  constructor(filePath = '', getConfig = () => {}) {
    /**
     * Absolute path to file location.
     * @type {string}
     */
    this.path = filePath;

    /**
     * Unique ID for this file. Right now an alias for the file's path.
     * @type {string}
     */
    this.id = this.path;

    /**
     * Template accessible data.
     * @type {Object.<string, Object>}
     */
    this.data = Object.create(null);

    /**
     * An array of Collections that this file belongs to.
     * @type {Set.<string>}
     */
    this.collections = new Set();

    /**
     * An array of CollectionPages that this file belongs to.
     * @type {Set.<string>}
     */
    this.collectionPages = new Set();

    /**
     * Get the global config object.
     * @type {Function}
     * @private
     */
    this._getConfig = getConfig;

    this.updateDataFromFileSystem();
  }

  updateDataFromFileSystem() {
    /**
     * Raw contents of file, directly from file system.
     * @TODO: perhaps don't keep reference to this?
     * @type {string} One long string.
     */
    this.rawContent = fs.readFileSync(this.path, 'utf8');

    /**
     * Checksum hash of rawContent, for use in seeing if file is different.
     * @example:
     * 	'50de70409f11f87b430f248daaa94d67'
     * @type {string}
     */
    this.checksum = createChecksum(this.rawContent);

    // Parse file's frontmatter.
    let parsedFile = Parse.fromFrontMatter(this.rawContent);

    /**
     * Just the file's text content.
     * @type {string}
     */
    let content = parsedFile.content;

    /**
     * If the file itself wants to customize what its URL is then it will use
     * the `config.file.url_key` value of the File's frontmatter as the basis
     * for which the URL of this file should be.
     * So if you have a File with a frontmatter that has `url: /pandas/` then
     * the File's URL will be `/pandas/`.
     * @type {string?} url Relative path to file.
     */
    this.url = parsedFile.data[this._getConfig().get('file.url_key')];

    // Merge in new data that's accessible from template.
    merge(this.data, parsedFile.data, {
      // The content of the Page.
      content: content
    });

    this._calculateDestination();
  }

  /**
   * Path to file relative to root of project.
   * @type {string}
   */
  get pathRelative() {
    return this.path.replace(this._getConfig().get('path.source'), '');
  }

  /**
   * Set new permalink configuration this file should use.
   * @param {string} newPermalink New permalink.
   */
  setPermalink(newPermalink) {
    this.permalink = newPermalink;
    this._calculateDestination();
  }

  /**
   * Calculate both relative and absolute destination path for where to write
   * the file.
   * @private
   */
  _calculateDestination() {
    let destinationUrl;
    if (this.url) {
      // If the individual File defined its own unique URL that gets first
      // dibs at setting the official URL for this file.
      destinationUrl = this.url;
    } else if (this.permalink) {
      // If the file has no URL but has a permalink set on it then use it to
      // find the URL of the File.
      destinationUrl = Url.interpolatePermalink(
        this.permalink,
        this.data
      );
    } else {
      // If the file has no URL set and no permalink then use its relative file
      // path as its url.
      destinationUrl = this.pathRelative;

      const markdownExtensions = this._getConfig().get('markdown_extension');

      // Get file extension of file. i.e. 'post.md' would give 'md'.
      let fileExtension = path.extname(destinationUrl).replace(/^\./, '');
      let index = markdownExtensions.indexOf(fileExtension);

      // Is this file's extension one of our known markdown extensions?
      if (index > -1) {
        let foundExtension = markdownExtensions[index];
        destinationUrl = destinationUrl.replace(
          new RegExp(`.${foundExtension}$`),
          '.html'
        );
      }
    }

    let fileSystemSafeDestination = Url.makeUrlFileSystemSafe(destinationUrl);

    /**
     * Absolute destination path.
     * @type {string} destination Absolute path to file.
     */
    this.destination = path.join(
      this._getConfig().get('path.destination'),
      fileSystemSafeDestination
    );

    this.data.url = Url.makePretty(fileSystemSafeDestination);
  }

  render(template, globalData) {
    template = isUndefined(this.data.template) ? template : this.data.template;
    let result = this.data.content;

    let templateData = {
      ...globalData,
      file: this.data
    };

    try {
      // Set result of content to result content.
      result = renderTemplateString(
        this.data.content,
        templateData
      );

      // Set result to file's contents.
      this.data.content = result;
    } catch (e) {
      log.error(e.message);
      throw new Error(`File: Could not render file's contents.\n` +
        `File: ${JSON.stringify(this)}`);
    }

    // Convert to HTML.
    // However if the File's frontmatter sets markdown value to false then
    // skip the markdown conversion.
    if (this.data.markdown !== false) {
      result = renderMarkdown(this.data.content);
      this.data.content = result;
    }

    if (!isNil(template) && !(isString(template) && template.length === 0)) {
      try {
        result = renderTemplate(template, templateData);
      } catch (e) {
        if (e.message.includes(TemplateErrorMessage.NO_TEMPLATE)) {
          throw new Error(`File: Template '${template}' not found.\n` +
            `File: ${JSON.stringify(this)}`);
        } else {
          throw e;
        }
      }
    }

    return result;
  }

  /**
   * Writes a given File object to the file system.
   * @param {Object} siteData Site wide data.
   * @return {Promise} Promise.
   */
  write(siteData) {
    if (this._getConfig().get('incremental') &&
        cache.get(this.path) === this.checksum) {
      return Promise.resolve();
    }

    let promises = [];

    for (let collection of this.collections) {
      // Don't render if we have no template defined.
      if (isUndefined(collection.template)) {
        continue;
      }

      let promise = renderAndWriteFileWithPlugins(
        this,
        collection.template,
        siteData,
        Plugin.Event.file.beforeRender,
        Plugin.Event.file.afterRender
      );

      promises.push(promise);
    }

    return Promise.all(promises).then(result => {
      // Save checksum to cache for incremental builds.
      cache.put(this.path, this.checksum);

      return result;
    });
  }

}
<|endoftext|>


<commit_before>if (global.GENTLY) require = GENTLY.hijack(require);

var util = require('./util'),
    WriteStream = require('fs').WriteStream,
    EventEmitter = require('events').EventEmitter,
    crypto = require('crypto');

function File(properties) {
  EventEmitter.call(this);

  this.size = 0;
  this.path = null;
  this.name = null;
  this.type = null;
  this.lastModifiedDate = null;

  this._writeStream = null;

  if(typeof properties === 'object') {
    if(typeof properties.hash === 'string') {
      this.hash = crypto.createHash(properties.hash);
    }
    delete(properties.hash);
    for (var key in properties) {
      this[key] = properties[key];
    }
  }

  this._backwardsCompatibility();
}
module.exports = File;
util.inherits(File, EventEmitter);

// @todo Next release: Show error messages when accessing these
File.prototype._backwardsCompatibility = function() {
  var self = this;
  this.__defineGetter__('length', function() {
    return self.size;
  });
  this.__defineGetter__('filename', function() {
    return self.name;
  });
  this.__defineGetter__('mime', function() {
    return self.type;
  });
};

File.prototype.open = function() {
  this._writeStream = new WriteStream(this.path);
};

File.prototype.write = function(buffer, cb) {
  var self = this;
  this._writeStream.write(buffer, function() {
    if(self.hash) {
      self.hash.update(buffer);
    }
    self.lastModifiedDate = new Date();
    self.size += buffer.length;
    self.emit('progress', self.size);
    cb();
  });
};

File.prototype.end = function(cb) {
  var self = this;
  this._writeStream.end(function() {
    if(self.hash) {
      self.hash = self.hash.digest('hex');
    }
    self.emit('end');
    cb();
  });
};
<commit_msg>moved hash creation to avoid delete call / mutating the passed options object.<commit_after>if (global.GENTLY) require = GENTLY.hijack(require);

var util = require('./util'),
    WriteStream = require('fs').WriteStream,
    EventEmitter = require('events').EventEmitter,
    crypto = require('crypto');

function File(properties) {
  EventEmitter.call(this);

  this.size = 0;
  this.path = null;
  this.name = null;
  this.type = null;
  this.lastModifiedDate = null;

  this._writeStream = null;

  if(typeof properties === 'object') {
    for (var key in properties) {
      this[key] = properties[key];
    }
  }

  if(typeof this.hash === 'string') {
    this.hash = crypto.createHash(properties.hash);
  }

  this._backwardsCompatibility();
}
module.exports = File;
util.inherits(File, EventEmitter);

// @todo Next release: Show error messages when accessing these
File.prototype._backwardsCompatibility = function() {
  var self = this;
  this.__defineGetter__('length', function() {
    return self.size;
  });
  this.__defineGetter__('filename', function() {
    return self.name;
  });
  this.__defineGetter__('mime', function() {
    return self.type;
  });
};

File.prototype.open = function() {
  this._writeStream = new WriteStream(this.path);
};

File.prototype.write = function(buffer, cb) {
  var self = this;
  this._writeStream.write(buffer, function() {
    if(self.hash) {
      self.hash.update(buffer);
    }
    self.lastModifiedDate = new Date();
    self.size += buffer.length;
    self.emit('progress', self.size);
    cb();
  });
};

File.prototype.end = function(cb) {
  var self = this;
  this._writeStream.end(function() {
    if(self.hash) {
      self.hash = self.hash.digest('hex');
    }
    self.emit('end');
    cb();
  });
};
<|endoftext|>


<commit_before>UI.registerHelper('roundToCents', function(value) {
  if(value) return Math.round(value * 100) /100;
});

Template.cart.onRendered(function() {
    $('[data-toggle="popover"]').popover();
});

Template.cart.onDestroyed(function() {
    $('[data-toggle="popover"]').popover("hide");
});

Template.cart.helpers({
  orders: function() {
    return ShoppingCart.find({userId: Meteor.userId()});
  },

  totalPrice: function() {
    var total = 0;
    var valueList = ShoppingCart.find({ userId: Meteor.userId() }, { fields: { vendorTotal: 1 }}).fetch();
    for (var i = 0, len = valueList.length; i < len; i++) {
      total += valueList[i].vendorTotal;
    }
    return Math.round(total * 100) /100;
  },
});

Template.cart.events({
  'click .addSample': function(event) {
    event.preventDefault();

    Meteor.call('addCartSampleItems');
  },

  // Pay to specific vendor
  'click .payVendor': function(event) {
    event.preventDefault();
    Meteor.call('payVendor',this.order);
    // TODO better response to user on error/correct payment
  },

  'click .increase': function(event) {
    var item = {
      quantity: this.product.quantity,
      productId: this.product.productId,
      name: this.product.name,
      description: this.product.description,
      photo: this.product.photo,
      unitType: this.product.unitType,
      unitPrice: this.product.unitPrice,
      currency: this.product.currency,
    };

    Meteor.call('increaseOrDecrease', true, item);
  },

  'click .decrease': function(event) {
    var item = {
      quantity: this.product.quantity,
      productId: this.product.productId,
      name: this.product.name,
      description: this.product.description,
      photo: this.product.photo,
      unitType: this.product.unitType,
      unitPrice: this.product.unitPrice,
      currency: this.product.currency,
    };

    Meteor.call('increaseOrDecrease', false, item);
  },

  'click .removeItem': function(event) {
    var item = {
      quantity: this.product.quantity,
      productId: this.product.productId,
      name: this.product.name,
      description: this.product.description,
      photo: this.product.photo,
      unitType: this.product.unitType,
      unitPrice: this.product.unitPrice,
      currency: this.product.currency,
    }

    Meteor.call('removeFromCart', item);
  },

});
<commit_msg>Re-enable click for payVendor popover<commit_after>UI.registerHelper('roundToCents', function(value) {
  if(value) return Math.round(value * 100) /100;
});

Template.cart.onRendered(function() {
    $('[data-toggle="popover"]').popover();
});

Template.cart.onDestroyed(function() {
    $('[data-toggle="popover"]').popover("hide");
});

Template.cart.helpers({
  orders: function() {
    return ShoppingCart.find({userId: Meteor.userId()});
  },

  totalPrice: function() {
    var total = 0;
    var valueList = ShoppingCart.find({ userId: Meteor.userId() }, { fields: { vendorTotal: 1 }}).fetch();
    for (var i = 0, len = valueList.length; i < len; i++) {
      total += valueList[i].vendorTotal;
    }
    return Math.round(total * 100) /100;
  },
});

Template.cart.events({
  'click .addSample': function(event) {
    event.preventDefault();

    Meteor.call('addCartSampleItems');
  },

  // Pay to specific vendor
  'click .payVendor': function(event) {
    // event.preventDefault();  // oops we need the click at the moment for the popover!
    Meteor.call('payVendor',this.order);
    // TODO better response to user on error/correct payment
  },

  'click .increase': function(event) {
    var item = {
      quantity: this.product.quantity,
      productId: this.product.productId,
      name: this.product.name,
      description: this.product.description,
      photo: this.product.photo,
      unitType: this.product.unitType,
      unitPrice: this.product.unitPrice,
      currency: this.product.currency,
    };

    Meteor.call('increaseOrDecrease', true, item);
  },

  'click .decrease': function(event) {
    var item = {
      quantity: this.product.quantity,
      productId: this.product.productId,
      name: this.product.name,
      description: this.product.description,
      photo: this.product.photo,
      unitType: this.product.unitType,
      unitPrice: this.product.unitPrice,
      currency: this.product.currency,
    };

    Meteor.call('increaseOrDecrease', false, item);
  },

  'click .removeItem': function(event) {
    var item = {
      quantity: this.product.quantity,
      productId: this.product.productId,
      name: this.product.name,
      description: this.product.description,
      photo: this.product.photo,
      unitType: this.product.unitType,
      unitPrice: this.product.unitPrice,
      currency: this.product.currency,
    }

    Meteor.call('removeFromCart', item);
  },

});
<|endoftext|>


<commit_before>'use strict';
var conf = require('./config');
var meta = require('./meta');
var fs = require('fs');
var path = require('path');
var appDir = path.dirname();
var _file = appDir + conf.vaultFile;
var cache;
try {
  cache = fs.readFileSync(_file);
} catch(e) {
  fs.writeFileSync(_file, JSON.stringify({}, null, 2));
}
if (cache) {
  try {
    cache = JSON.parse(cache);
  } catch(e) {}
} else {
  cache = {};
}
var File = {
  type: 'File',
  save: function(callback) {
    fs.writeFileSync(_file, JSON.stringify(cache, null, 2));
  },
  get: function(key, default_value) {
    var keyMeta = meta.checkKeyMeta(this, key);
    if (keyMeta) {
      return default_value;
    }
    return cache[key] || default_value;
  },
  getItem: function(key, default_value) {
    return this.get(key, default_value);
  },
  getAndRemove: function(key) {
    var value = cache[key];
    delete cache[key];
    this.save();
    return value;
  },
  getList: function() {
    var list = [];
    for (var key in cache) {
      var obj = {};
      obj[key] = cache[key];
      list.push(obj);
    }
    return list;
  },
  set: function(key, value, config) {
    cache[key] = value;
    meta.setKeyMeta(this, key, config);
    this.save();
    return cache[key];
  },
  setItem: function(key, value, config) {
    return this.set(key, value, config);
  },
  remove: function(key) {
    try {
      delete cache[key];
    } catch(e) {}
    this.save();
  },
  removeItem: function(key) {
    this.remove(key);
  },
  clear: function() {
    cache = {};
    this.save();
  },
  list: function() {
    for (var key in cache) {
      console.log(key, '=', cache[key]);
    }
  }
};
module.exports = File;
<commit_msg>bug fix for properly finding node app root dir<commit_after>'use strict';
var conf = require('./config');
var meta = require('./meta');
var fs = require('fs');
var path = require('path');
var appDir = path.dirname(require.main.filename);
var _file = appDir + conf.vaultFile;
var cache;
console.log('Vault File:', _file);
try {
  cache = fs.readFileSync(_file);
} catch(e) {
  fs.writeFileSync(_file, JSON.stringify({}, null, 2));
}
if (cache) {
  try {
    cache = JSON.parse(cache);
  } catch(e) {}
} else {
  cache = {};
}
var File = {
  type: 'File',
  save: function(callback) {
    fs.writeFileSync(_file, JSON.stringify(cache, null, 2));
  },
  get: function(key, default_value) {
    var keyMeta = meta.checkKeyMeta(this, key);
    if (keyMeta) {
      return default_value;
    }
    return cache[key] || default_value;
  },
  getItem: function(key, default_value) {
    return this.get(key, default_value);
  },
  getAndRemove: function(key) {
    var value = cache[key];
    delete cache[key];
    this.save();
    return value;
  },
  getList: function() {
    var list = [];
    for (var key in cache) {
      var obj = {};
      obj[key] = cache[key];
      list.push(obj);
    }
    return list;
  },
  set: function(key, value, config) {
    cache[key] = value;
    meta.setKeyMeta(this, key, config);
    this.save();
    return cache[key];
  },
  setItem: function(key, value, config) {
    return this.set(key, value, config);
  },
  remove: function(key) {
    try {
      delete cache[key];
    } catch(e) {}
    this.save();
  },
  removeItem: function(key) {
    this.remove(key);
  },
  clear: function() {
    cache = {};
    this.save();
  },
  list: function() {
    for (var key in cache) {
      console.log(key, '=', cache[key]);
    }
  }
};
module.exports = File;
<|endoftext|>


<commit_before>/*
* @Author: zoujie.wzj
* @Date:   2016-01-23 18:18:28
* @Last Modified by: Ayon Lee
* @Last Modified on: 2018-10-19
*/

'use strict'

const findPid = require('./find_pid')
const findProcess = require('./find_process')

const findBy = {
  port (port, strict) {
    return findPid(port, strict)
      .then(pid => {
        return findBy.pid(pid, strict)
      }, () => {
        // return empty array when pid not found
        return []
      })
  },
  pid (pid, strict) {
    return findProcess({
      pid: pid,
      strict
    })
  },
  name (name, strict) {
    return findProcess({
      name: name,
      strict
    })
  }
}

/**
 * find process by condition
 *
 * return Promise: [{
 *   pid: <process id>,
 *   ppid: <process parent id>,
 *   uid: <user id (*nix)>,
 *   gid: <user group id (*nix)>,
 *   name: <command name>,
 *   cmd: <process run args>
 * }, ...]
 *
 * If no process found, resolve process with empty array (only reject when error occured)
 *
 * @param  {String} by condition: port/pid/name ...
 * @param {Mixed} condition value
 * @return {Promise}
 */
function find (by, value, strict) {
  return new Promise((resolve, reject) => {
    if (!(by in findBy)) {
      reject(new Error(`do not support find by "${by}"`))
    } else {
      if (by === 'pid' && typeof value !== 'number') { reject(new Error('pid must be a number')) } else if (by === 'port' && typeof value !== 'number') { reject(new Error('port must be a number')) } else { findBy[by](value, strict).then(resolve, reject) }
    }
  })
}

module.exports = find
<commit_msg>fix: fix number check issue<commit_after>/*
* @Author: zoujie.wzj
* @Date:   2016-01-23 18:18:28
* @Last Modified by: Ayon Lee
* @Last Modified on: 2018-10-19
*/

'use strict'

const findPid = require('./find_pid')
const findProcess = require('./find_process')

const findBy = {
  port (port, strict) {
    return findPid(port, strict)
      .then(pid => {
        return findBy.pid(pid, strict)
      }, () => {
        // return empty array when pid not found
        return []
      })
  },
  pid (pid, strict) {
    return findProcess({
      pid: pid,
      strict
    })
  },
  name (name, strict) {
    return findProcess({
      name: name,
      strict
    })
  }
}

/**
 * find process by condition
 *
 * return Promise: [{
 *   pid: <process id>,
 *   ppid: <process parent id>,
 *   uid: <user id (*nix)>,
 *   gid: <user group id (*nix)>,
 *   name: <command name>,
 *   cmd: <process run args>
 * }, ...]
 *
 * If no process found, resolve process with empty array (only reject when error occured)
 *
 * @param  {String} by condition: port/pid/name ...
 * @param {Mixed} condition value
 * @return {Promise}
 */
function find (by, value, strict) {
  return new Promise((resolve, reject) => {
    if (!(by in findBy)) {
      reject(new Error(`do not support find by "${by}"`))
    } else {
      const isNumber = /^\d+$/.test(value)
      if (by === 'pid' && !isNumber) {
        reject(new Error('pid must be a number'))
      } else if (by === 'port' && !isNumber) {
        reject(new Error('port must be a number'))
      } else {
        findBy[by](value, strict).then(resolve, reject)
      }
    }
  })
}

module.exports = find
<|endoftext|>


<commit_before>var ADMIN_MEDIA_URL = '/admin/media/';
var CHAR_MAX_LENGTH = 30;

function GenericObject(i, objectIdEl) {
    this.objectIdEl = objectIdEl;
    this.contentTypeEl;

    this.contentTypeId; // Store the id of the content_type we want to look up
    this.objectId; // Store the id of the object (object_id) we want to look up

    // The lookup link
    this.lookupLink = $('  ');
    this.lookupLink.click(function() {
        if (self.contentTypeEl.value) {
            self.showRelatedObjectLookupPopup(this);
        }
        return false;
    });
    this.lookupLink.attr('id', 'lookup_'+this.objectIdEl.id);

    // The inline text element to store the display of the actual object
    this.lookupText = $(' ');

    var self = this;
    this.__init__ = function() {
        // sets the associated content_type element
        vars = this.objectIdEl.id.split('-');   // should return 3 items: ["id_ingredientlist_set", "2", "content_type"]

        if (vars.length==1) { //not an inline edit
            id = '#id_content_type';
        } else {
            id = '#' + vars[0] + '-' + vars[1] + '-content_type';
        }
        this.contentTypeEl = $(id)[0];

        if (this.contentTypeEl.value) {
            this.contentTypeId = this.contentTypeEl.value;  // If the content_type has an initial value, now is a good time to set it
            this.lookupLink.attr('href', '/admin/' + MODEL_URL_ARRAY[this.contentTypeEl.value] + '/');

            if (this.objectIdEl.value) {
                this.objectId = this.objectIdEl.value;
                this.updateObjectIdEl();
            }
        }

        $(this.contentTypeEl).change(function() {
            self.contentTypeId = this.value;    // Set our objectId when the content_type is changed
            self.lookupLink.attr('href', '/admin/' + MODEL_URL_ARRAY[this.value] + '/');
        });

        // Add the lookup icon
        $(this.objectIdEl).after(this.lookupText).after(this.lookupLink);

        // Bind to the onchange of the object_id input.
        // Unfortunatley this doesn't fire when the popup window closes, so we have another method below
        $(this.objectIdEl).change(function(){
            // Now we need to politely ask the server to give us some info on this content_type, object_id combo
            self.objectId = this.value;
            self.updateObjectIdEl();
        }).focus(function(){ // Temporary fix for Safari...
            self.objectId = this.value;
            self.updateObjectIdEl();
        });
    };

    this.updateObjectIdEl = function() {
        // Call the server for an update, but only if everything is good to go
        if (this.objectIdEl.value && this.contentTypeId) {
            self.lookupText.text('loading...');
            $.getJSON('/admin/obj_lookup/', {object_id: this.objectIdEl.value, content_type: this.contentTypeId},
                function(data) {
                    item = data[0];
                    self.lookupText.text(''); // Clear out the `loading...` text
                    if (item.objectText) {
                        if (item.objectText.length > CHAR_MAX_LENGTH) {
                            self.lookupText.text(decodeURI(item.objectText.substr(0, CHAR_MAX_LENGTH) + " ..."));
                        } else {
                            self.lookupText.text(decodeURI(item.objectText));
                        }
                    }
            });
        }
    };

    this.showRelatedObjectLookupPopup = function(triggeringLink) {
        // A copy of Django's showRelatedObjectLookupPopup, but we need to capture the window.onunload

        var name = triggeringLink.id.replace(/^lookup_/, '');
        // IE doesn't like periods in the window name, so convert temporarily.
        name = name.replace(/\./g, '___');
        var href;
        if (triggeringLink.href.search(/\?/) >= 0) {
            href = triggeringLink.href + '&pop=1';
        } else {
            href = triggeringLink.href + '?pop=1';
        }
        win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');

        // TODO: This apparently doesn't work in safari...
        $(win).bind('beforeunload', function() {
            // This complicated guy is needed because when the window is 'unloaded' the value selected isn't
            // inserted in the object_id field quite yet, so we set a small delay--setTimeout is a pain...
            function timedReset(me) {
                var me = me;
                this.update = function(){
                    me.updateObjectIdEl();
                };
                this.go = function() {
                    setTimeout(this.update, 200);
                }
            };
            updater = new timedReset(self);
            updater.go();
        });

        win.focus();
        return false;
    }

    // Run initialization and return
    this.__init__();

    return {
        objectIdEl: this.objectIdEl,
        contentTypeEl: this.contentTypeEl,
        lookupIcon: this.lookupIcon,
        lookupText: this.lookupText,
        lookupLink: this.lookupLink,
        updateObjectIdEl: this.updateObjectIdEl,
        showRelatedObjectLookupPopup: this.showRelatedObjectLookupPopup
    }
};

// Go for it!
$(document).ready(function(){
    $("[id$='object_id']").each(GenericObject);
});

<commit_msg>generic related lookup-window is wider now<commit_after>var ADMIN_MEDIA_URL = '/admin/media/';
var CHAR_MAX_LENGTH = 30;

function GenericObject(i, objectIdEl) {
    this.objectIdEl = objectIdEl;
    this.contentTypeEl;

    this.contentTypeId; // Store the id of the content_type we want to look up
    this.objectId; // Store the id of the object (object_id) we want to look up

    // The lookup link
    this.lookupLink = $('  ');
    this.lookupLink.click(function() {
        if (self.contentTypeEl.value) {
            self.showRelatedObjectLookupPopup(this);
        }
        return false;
    });
    this.lookupLink.attr('id', 'lookup_'+this.objectIdEl.id);

    // The inline text element to store the display of the actual object
    this.lookupText = $(' ');

    var self = this;
    this.__init__ = function() {
        // sets the associated content_type element
        vars = this.objectIdEl.id.split('-');   // should return 3 items: ["id_ingredientlist_set", "2", "content_type"]

        if (vars.length==1) { //not an inline edit
            id = '#id_content_type';
        } else {
            id = '#' + vars[0] + '-' + vars[1] + '-content_type';
        }
        this.contentTypeEl = $(id)[0];

        if (this.contentTypeEl.value) {
            this.contentTypeId = this.contentTypeEl.value;  // If the content_type has an initial value, now is a good time to set it
            this.lookupLink.attr('href', '/admin/' + MODEL_URL_ARRAY[this.contentTypeEl.value] + '/');

            if (this.objectIdEl.value) {
                this.objectId = this.objectIdEl.value;
                this.updateObjectIdEl();
            }
        }

        $(this.contentTypeEl).change(function() {
            self.contentTypeId = this.value;    // Set our objectId when the content_type is changed
            self.lookupLink.attr('href', '/admin/' + MODEL_URL_ARRAY[this.value] + '/');
        });

        // Add the lookup icon
        $(this.objectIdEl).after(this.lookupText).after(this.lookupLink);

        // Bind to the onchange of the object_id input.
        // Unfortunatley this doesn't fire when the popup window closes, so we have another method below
        $(this.objectIdEl).change(function(){
            // Now we need to politely ask the server to give us some info on this content_type, object_id combo
            self.objectId = this.value;
            self.updateObjectIdEl();
        }).focus(function(){ // Temporary fix for Safari...
            self.objectId = this.value;
            self.updateObjectIdEl();
        });
    };

    this.updateObjectIdEl = function() {
        // Call the server for an update, but only if everything is good to go
        if (this.objectIdEl.value && this.contentTypeId) {
            self.lookupText.text('loading...');
            $.getJSON('/admin/obj_lookup/', {object_id: this.objectIdEl.value, content_type: this.contentTypeId},
                function(data) {
                    item = data[0];
                    self.lookupText.text(''); // Clear out the `loading...` text
                    if (item.objectText) {
                        if (item.objectText.length > CHAR_MAX_LENGTH) {
                            self.lookupText.text(decodeURI(item.objectText.substr(0, CHAR_MAX_LENGTH) + " ..."));
                        } else {
                            self.lookupText.text(decodeURI(item.objectText));
                        }
                    }
            });
        }
    };

    this.showRelatedObjectLookupPopup = function(triggeringLink) {
        // A copy of Django's showRelatedObjectLookupPopup, but we need to capture the window.onunload

        var name = triggeringLink.id.replace(/^lookup_/, '');
        // IE doesn't like periods in the window name, so convert temporarily.
        name = name.replace(/\./g, '___');
        var href;
        if (triggeringLink.href.search(/\?/) >= 0) {
            href = triggeringLink.href + '&pop=1';
        } else {
            href = triggeringLink.href + '?pop=1';
        }
        win = window.open(href, name, 'height=600,width=900,resizable=yes,scrollbars=yes');

        // TODO: This apparently doesn't work in safari...
        $(win).bind('beforeunload', function() {
            // This complicated guy is needed because when the window is 'unloaded' the value selected isn't
            // inserted in the object_id field quite yet, so we set a small delay--setTimeout is a pain...
            function timedReset(me) {
                var me = me;
                this.update = function(){
                    me.updateObjectIdEl();
                };
                this.go = function() {
                    setTimeout(this.update, 200);
                }
            };
            updater = new timedReset(self);
            updater.go();
        });

        win.focus();
        return false;
    }

    // Run initialization and return
    this.__init__();

    return {
        objectIdEl: this.objectIdEl,
        contentTypeEl: this.contentTypeEl,
        lookupIcon: this.lookupIcon,
        lookupText: this.lookupText,
        lookupLink: this.lookupLink,
        updateObjectIdEl: this.updateObjectIdEl,
        showRelatedObjectLookupPopup: this.showRelatedObjectLookupPopup
    }
};

// Go for it!
$(document).ready(function(){
    $("[id$='object_id']").each(GenericObject);
});

<|endoftext|>


<commit_before>
// [START app]
'use strict';

// [START setup]

var express = require('express');

var app = express();
var google = require('googleapis');
//var bigquery = google.bigquery('v2');

app.enable('trust proxy');

var Datastore = require('@google-cloud/datastore');
const BigQuery = require('@google-cloud/bigquery');
const projectId = "doolinhomeiot";
const datasetId = "OfficeData";
const tableId = "iotdata";

// Instantiate a datastore client
var datastore = Datastore();

var PubSub = require('@google-cloud/pubsub');

//Instantiate a pubsub client
var pubsub = PubSub();

//The following environment variables are set by app.yaml when running on GAE,
//but will need to be manually set when running locally.
var PUBSUB_VERIFICATION_TOKEN = process.env.PUBSUB_VERIFICATION_TOKEN;

var topic = pubsub.topic(process.env.PUBSUB_TOPIC);

var subscription = pubsub.subscription(process.env.PUBSUB_SUBSCRIPTION_NAME);
////google.auth.getApplicationDefault(function(err, authClient) {
////    if (err) {
////        console.log('Authentication failed because of ', err);
////        return;
////    }
////    if (authClient.createScopedRequired && authClient.createScopedRequired()) {
////        var scopes = ['https://www.googleapis.com/auth/cloud-platform'];
////        authClient = authClient.createScoped(scopes);
////    }});

//'insertId': 123456, 'json': '{"nameid": 123,"messagedata":"test1"

//var request = {projectId: projectId,datasetId: datasetId,tableID: tableId,resource: {"kind": "bigquery#tableDataInsertAllRequest","rows":
//    {}, auth: authClient]};

// [END setup]

function storeEvent(message) {
    var key = datastore.key('officedata');
    key.identifier = "id"
    // You can uncomment some of the other things if you want to store them in the database

    var obj = {
        messageid: message.id
        //deviceid: message.attributes.device_id,
        ////event: message.attributes.event,
        //published: message.attributes.published_at,
        //data: message.data
    }
    datastore.save(
        {
            key: key,
            data: obj
        }, function (err) {
            if (err) {
                console.log('There was an error storing the event', err);
            }
            console.log('stored in datastore', obj);
        }
    );
    //var response = "response";
    //var request = "{auth: authClient,'projectId':" + projectId + ", 'datasetId':" + datasetId + ", 'tableId':" + tableId + ", 'resource': {'kind': 'bigquery#tableDataInsertAllRequest','rows':[{'insertId': 123456, 'json': '{'nameid': '123','messagedata':'test1'}'}]}}";
    //save to BigQuery Tables
    //debug.log(request);
    ////bigquery.tabledata.insertAll(request, function (err, result) {
    ////   if (err) {
    ////       console.log(err);
    ////   } else {
    ////       console.log(result);
    ////   }
    ////});
    var content = "{'nameid': '123','messagedata': 'test1'}";
    let rows = null;
    try {
        rows = JSON.parse(content)
    } catch (err) {
    }
    const bigquery = BigQuery({
        projectId: projectId
    });
    bigquery.dataset(datasetId);
    bigquery.table(tableId);
    bigquery.insertrow(rows);

}
    ////bigquery.tables.insert({
    ////    'projectId': projectId,
    ////    'datasetId': datasetId,
    ////    'tableId': tableId,
    ////    'resource': {'kind': 'bigquery#tableDataInsertAllRequest','rows':[{'insertId': 123456, 'json': '{"nameid": "123"","messagedata":"test1"}'}]}, function (err, result) {
    ////        if (err) {
     ////           console.log(err);
     ////       } else {
     ////           console.log(result);
      ////      }
      ////  }})};
//});

//err: result});

subscription.on('message', function (message) {
    console.log('event received', message);
    // Called every time a message is received.
    // message.id = ID used to acknowledge its receival.
    // message.data = Contents of the message.
    // message.attributes = Attributes of the message.
    storeEvent(message);
    message.ack();
});

// [START listen]
var server = app.listen(process.env.PORT || 8080, function () {
    console.log('App listening on port %s', server.address().port);
    console.log('Press Ctrl+C to quit.');
});
// [END listen]
// [END app]

module.exports = app;
<commit_msg>Update app.js<commit_after>
// [START app]
'use strict';

// [START setup]

var express = require('express');

var app = express();
var google = require('googleapis');
//var bigquery = google.bigquery('v2');

app.enable('trust proxy');

var Datastore = require('@google-cloud/datastore');
const BigQuery = require('@google-cloud/bigquery');
const projectId = "doolinhomeiot";
const datasetId = "OfficeData";
const tableId = "iotdata";

// Instantiate a datastore client
var datastore = Datastore();

var PubSub = require('@google-cloud/pubsub');

//Instantiate a pubsub client
var pubsub = PubSub();

//The following environment variables are set by app.yaml when running on GAE,
//but will need to be manually set when running locally.
var PUBSUB_VERIFICATION_TOKEN = process.env.PUBSUB_VERIFICATION_TOKEN;

var topic = pubsub.topic(process.env.PUBSUB_TOPIC);

var subscription = pubsub.subscription(process.env.PUBSUB_SUBSCRIPTION_NAME);
////google.auth.getApplicationDefault(function(err, authClient) {
////    if (err) {
////        console.log('Authentication failed because of ', err);
////        return;
////    }
////    if (authClient.createScopedRequired && authClient.createScopedRequired()) {
////        var scopes = ['https://www.googleapis.com/auth/cloud-platform'];
////        authClient = authClient.createScoped(scopes);
////    }});

//'insertId': 123456, 'json': '{"nameid": 123,"messagedata":"test1"

//var request = {projectId: projectId,datasetId: datasetId,tableID: tableId,resource: {"kind": "bigquery#tableDataInsertAllRequest","rows":
//    {}, auth: authClient]};

// [END setup]

function storeEvent(message) {
    var key = datastore.key('officedata');
    key.identifier = "id"
    // You can uncomment some of the other things if you want to store them in the database

    var obj = {
        messageid: message.id
        //deviceid: message.attributes.device_id,
        ////event: message.attributes.event,
        //published: message.attributes.published_at,
        //data: message.data
    }
    datastore.save(
        {
            key: key,
            data: obj
        }, function (err) {
            if (err) {
                console.log('There was an error storing the event', err);
            }
            console.log('stored in datastore', obj);
        }
    );
    //var response = "response";
    //var request = "{auth: authClient,'projectId':" + projectId + ", 'datasetId':" + datasetId + ", 'tableId':" + tableId + ", 'resource': {'kind': 'bigquery#tableDataInsertAllRequest','rows':[{'insertId': 123456, 'json': '{'nameid': '123','messagedata':'test1'}'}]}}";
    //save to BigQuery Tables
    //debug.log(request);
    ////bigquery.tabledata.insertAll(request, function (err, result) {
    ////   if (err) {
    ////       console.log(err);
    ////   } else {
    ////       console.log(result);
    ////   }
    ////});
    var content = "{'nameid': '123','messagedata': 'test1'}";
    let rows = null;
    try {
        rows = JSON.parse(content)
    } catch (err) {
    }
    const bigquery = BigQuery({
        projectId: projectId
    });
    bigquery.dataset(datasetId);
    bigquery.tables(tableId);
    bigquery.insertrow(rows);

}
    ////bigquery.tables.insert({
    ////    'projectId': projectId,
    ////    'datasetId': datasetId,
    ////    'tableId': tableId,
    ////    'resource': {'kind': 'bigquery#tableDataInsertAllRequest','rows':[{'insertId': 123456, 'json': '{"nameid": "123"","messagedata":"test1"}'}]}, function (err, result) {
    ////        if (err) {
     ////           console.log(err);
     ////       } else {
     ////           console.log(result);
      ////      }
      ////  }})};
//});

//err: result});

subscription.on('message', function (message) {
    console.log('event received', message);
    // Called every time a message is received.
    // message.id = ID used to acknowledge its receival.
    // message.data = Contents of the message.
    // message.attributes = Attributes of the message.
    storeEvent(message);
    message.ack();
});

// [START listen]
var server = app.listen(process.env.PORT || 8080, function () {
    console.log('App listening on port %s', server.address().port);
    console.log('Press Ctrl+C to quit.');
});
// [END listen]
// [END app]

module.exports = app;
<|endoftext|>