<commit_before>var util    = require('./util');
var Torrent = require('./torrent');

/**
 * Check if field that should be a buffer and exists is a buffer.
 *
 * @param {Object} torrent
 * @param {String} field Key from torrent object to check
 * @return {!String} Possible error
 */
var checkBuffer = function(torrent, field) {
  return torrent[field] && !Buffer.isBuffer(torrent[field]) ?
    '`' + field + '` is not a buffer' : null;
};

/**
 * Checks announce fields are correct.
 *
 * @param {Object} torrent
 * @return {!String} Possible error
 */
var checkAnnounce = function(torrent) {
  var err;
  if (!torrent.announce && !torrent['announce-list']) {
    return '`announce` and `announce-list` fields not found';
  }
  if (err = checkBuffer(torrent, 'announce')) return err;
  if (!util.isURL(torrent.announce)) return '`announce` is not a URL';
  return null;
};

/**
 * Checks announce list field.
 *
 * @param {Object} torrent
 * @return {!String} Possible error
 */
var checkAnnounceList = exports.announceList = function(list) {
  if (list) {
    if (!Array.isArray(list)) return '`announce-list` is not a list';

    for (var i = 0, l = list.length; i < l; i++) {
      var item = list[i];
      if (!Array.isArray(item)) {
        return '`announce-list` is not a list of lists';
      }
      for (var k = 0, l2 = item.length; k < l2; k++) {
        var ann = item[k];
        if (!Buffer.isBuffer(ann)) {
          return 'Item in `announce-list` is not a buffer';
        }
        if (!util.isURL(ann)) {
          return 'Item in `announce-list` list is not a URL';
        }
      }
    }
  }
  return null;
};

/**
 * Check if the creation date exists and is an integer.
 *
 * @param {Number} date
 * @return {!String} Possible error
 */
var checkCreationDate = function(date) {
  return date != null && !util.isInteger(date) ?
    '`creation-date` is not an integer' : null;
};

/**
 * Check md5 sum of torrent is correct.
 *
 * @param {Object} parent Info metadata of torrent or file object if
 *   in multi file mode.
 * @return {!String} Possible error
 */
var checkmd5sum = function(parent) {
  if (parent.md5sum != null) {
    if (!Buffer.isBuffer(parent.md5sum)) return '`md5sum` is not a buffer';
    if (!/[a-f0-9]{32}/i.test(parent.md5sum)) {
      return '`md5sum` is not a 32 length hex in file';
    }
  }
  return null;
};

/**
 * Converts all buffers in the torrent object to utf8 strings.
 * Except for the key `info.pieces` which will remain a buffer.
 *
 * @param {Object} torrent
 */
var buf2str = function(torrent, path) {
  Object.keys(torrent).forEach(function(key) {
    var val = torrent[key];

    if (Buffer.isBuffer(val)) {
      if (path !== '.info' || key !== 'pieces') {
        torrent[key] = val.toString('utf8');
      }
    } else if (typeof val === 'object') {
      buf2str(val, path + '.' + key);
    }
  });
};

/**
 * Checks torrent metadata is correct.
 *
 * @param {Object} torrent
 * @return {!String} Possible error with the torrent object
 */
var checkTorrent = exports.checkTorrent = function(torrent) {
  var err;

  if (typeof torrent !== 'object') return 'Torrent is not hash';
  if (err = checkAnnounce(torrent, 'announce')) return err;
  if (err = checkAnnounceList(torrent['announce-list'])) return err;
  if (err = checkCreationDate(torrent['creation date'])) return err;
  if (err = checkBuffer(torrent, 'comment')) return err;
  if (err = checkBuffer(torrent, 'created by')) return err;
  if (err = checkBuffer(torrent, 'encoding')) return err;

  if (torrent.info == null) return '`info` field not found';

  // Multi file mode.
  if (torrent.info.files != null) {
    if (!Array.isArray(torrent.info.files)) return '`info.files` is not a list';
    for (var i = 0, l = torrent.info.files.length; i < l; i++) {
      var file = torrent.info.files[i];
      if (file.length == null) {
        return '`length` field not found in file';
      }
      if (!util.isInteger(file.length) || file.length < 0) {
        return '`length` is not a positive integer in file';
      }
      if (err = checkmd5sum(file)) return err;
      if (!file.path) return '`path` field not found in file';
      if (!Array.isArray(file.path)) return '`path` is not a list in file';

      if (!file.path.some(Buffer.isBuffer)) {
        return '`path` is not a list of strings in file';
      }
    }
    if (torrent.info.length != null) {
      return 'Cannot have `info.length` in multi file mode';
    }
    if (torrent.info.md5sum != null) {
      return 'Cannot have `info.md5sum` in multi file mode';
    }

  // Single file mode.
  } else {
    if (torrent.info.length == null) {
      return '`info.length` not found in single file mode';
    }
    if (!util.isInteger(torrent.info.length || torrent.info.length < 0)) {
      return '`info.length` is not a positive integer in file';
    }
    if (err = checkmd5sum(torrent.info)) return err;
  }

  if (err = checkBuffer(torrent.info, 'name')) return err;
  if (torrent.info['piece length'] == null) {
    return '`info.piece length` not found';
  }
  if (!util.isInteger(torrent.info['piece length']) ||
      torrent.info['piece length'] < 0) {
    return '`info.piece length` is not a positive integer';
  }
  if (torrent.info.pieces == null) return '`info.pieces` not found';
  if (!Buffer.isBuffer(torrent.info.pieces)) {
    return '`info.pieces` is not a buffer';
  }
  if (torrent.info.pieces.length % 20 !== 0) {
    return '`info.pieces` length is not divisible by 20';
  }
  if (torrent.info.private != null &&
      torrent.info.private !== 0 && torrent.info.private !== 1) {
      return '`info.private` can only be 0 or 1';
  }
  if (err = checkBuffer(torrent.info, 'source')) return err;
  return null;
};

/**
 * Checks a torrent object, makes sure its metadata matches the schema.
 *
 * @param {Object} torrent
 * @param {Function(!Error, Torrent)} callback
 */
exports.validate = function(torrent, callback) {
  var errmsg = checkTorrent(torrent);
  if (errmsg !== null) {
    var err = new Error(errmsg);
    err.name = 'SchemaError';
    return callback(err);
  }

  // Convert all buffers into strings that are not hash pieces.
  buf2str(torrent, '');

  // Put metadata into torrent object and call callback with the result.
  callback(null, new Torrent(torrent));
};
<commit_msg>`creation date` not `creation-date`<commit_after>var util    = require('./util');
var Torrent = require('./torrent');

/**
 * Check if field that should be a buffer and exists is a buffer.
 *
 * @param {Object} torrent
 * @param {String} field Key from torrent object to check
 * @return {!String} Possible error
 */
var checkBuffer = function(torrent, field) {
  return torrent[field] && !Buffer.isBuffer(torrent[field]) ?
    '`' + field + '` is not a buffer' : null;
};

/**
 * Checks announce fields are correct.
 *
 * @param {Object} torrent
 * @return {!String} Possible error
 */
var checkAnnounce = function(torrent) {
  var err;
  if (!torrent.announce && !torrent['announce-list']) {
    return '`announce` and `announce-list` fields not found';
  }
  if (err = checkBuffer(torrent, 'announce')) return err;
  if (!util.isURL(torrent.announce)) return '`announce` is not a URL';
  return null;
};

/**
 * Checks announce list field.
 *
 * @param {Object} torrent
 * @return {!String} Possible error
 */
var checkAnnounceList = exports.announceList = function(list) {
  if (list) {
    if (!Array.isArray(list)) return '`announce-list` is not a list';

    for (var i = 0, l = list.length; i < l; i++) {
      var item = list[i];
      if (!Array.isArray(item)) {
        return '`announce-list` is not a list of lists';
      }
      for (var k = 0, l2 = item.length; k < l2; k++) {
        var ann = item[k];
        if (!Buffer.isBuffer(ann)) {
          return 'Item in `announce-list` is not a buffer';
        }
        if (!util.isURL(ann)) {
          return 'Item in `announce-list` list is not a URL';
        }
      }
    }
  }
  return null;
};

/**
 * Check if the creation date exists and is an integer.
 *
 * @param {Number} date
 * @return {!String} Possible error
 */
var checkCreationDate = function(date) {
  return date != null && !util.isInteger(date) ?
    '`creation date` is not an integer' : null;
};

/**
 * Check md5 sum of torrent is correct.
 *
 * @param {Object} parent Info metadata of torrent or file object if
 *   in multi file mode.
 * @return {!String} Possible error
 */
var checkmd5sum = function(parent) {
  if (parent.md5sum != null) {
    if (!Buffer.isBuffer(parent.md5sum)) return '`md5sum` is not a buffer';
    if (!/[a-f0-9]{32}/i.test(parent.md5sum)) {
      return '`md5sum` is not a 32 length hex in file';
    }
  }
  return null;
};

/**
 * Converts all buffers in the torrent object to utf8 strings.
 * Except for the key `info.pieces` which will remain a buffer.
 *
 * @param {Object} torrent
 */
var buf2str = function(torrent, path) {
  Object.keys(torrent).forEach(function(key) {
    var val = torrent[key];

    if (Buffer.isBuffer(val)) {
      if (path !== '.info' || key !== 'pieces') {
        torrent[key] = val.toString('utf8');
      }
    } else if (typeof val === 'object') {
      buf2str(val, path + '.' + key);
    }
  });
};

/**
 * Checks torrent metadata is correct.
 *
 * @param {Object} torrent
 * @return {!String} Possible error with the torrent object
 */
var checkTorrent = exports.checkTorrent = function(torrent) {
  var err;

  if (typeof torrent !== 'object') return 'Torrent is not hash';
  if (err = checkAnnounce(torrent, 'announce')) return err;
  if (err = checkAnnounceList(torrent['announce-list'])) return err;
  if (err = checkCreationDate(torrent['creation date'])) return err;
  if (err = checkBuffer(torrent, 'comment')) return err;
  if (err = checkBuffer(torrent, 'created by')) return err;
  if (err = checkBuffer(torrent, 'encoding')) return err;

  if (torrent.info == null) return '`info` field not found';

  // Multi file mode.
  if (torrent.info.files != null) {
    if (!Array.isArray(torrent.info.files)) return '`info.files` is not a list';
    for (var i = 0, l = torrent.info.files.length; i < l; i++) {
      var file = torrent.info.files[i];
      if (file.length == null) {
        return '`length` field not found in file';
      }
      if (!util.isInteger(file.length) || file.length < 0) {
        return '`length` is not a positive integer in file';
      }
      if (err = checkmd5sum(file)) return err;
      if (!file.path) return '`path` field not found in file';
      if (!Array.isArray(file.path)) return '`path` is not a list in file';

      if (!file.path.some(Buffer.isBuffer)) {
        return '`path` is not a list of strings in file';
      }
    }
    if (torrent.info.length != null) {
      return 'Cannot have `info.length` in multi file mode';
    }
    if (torrent.info.md5sum != null) {
      return 'Cannot have `info.md5sum` in multi file mode';
    }

  // Single file mode.
  } else {
    if (torrent.info.length == null) {
      return '`info.length` not found in single file mode';
    }
    if (!util.isInteger(torrent.info.length || torrent.info.length < 0)) {
      return '`info.length` is not a positive integer in file';
    }
    if (err = checkmd5sum(torrent.info)) return err;
  }

  if (err = checkBuffer(torrent.info, 'name')) return err;
  if (torrent.info['piece length'] == null) {
    return '`info.piece length` not found';
  }
  if (!util.isInteger(torrent.info['piece length']) ||
      torrent.info['piece length'] < 0) {
    return '`info.piece length` is not a positive integer';
  }
  if (torrent.info.pieces == null) return '`info.pieces` not found';
  if (!Buffer.isBuffer(torrent.info.pieces)) {
    return '`info.pieces` is not a buffer';
  }
  if (torrent.info.pieces.length % 20 !== 0) {
    return '`info.pieces` length is not divisible by 20';
  }
  if (torrent.info.private != null &&
      torrent.info.private !== 0 && torrent.info.private !== 1) {
      return '`info.private` can only be 0 or 1';
  }
  if (err = checkBuffer(torrent.info, 'source')) return err;
  return null;
};

/**
 * Checks a torrent object, makes sure its metadata matches the schema.
 *
 * @param {Object} torrent
 * @param {Function(!Error, Torrent)} callback
 */
exports.validate = function(torrent, callback) {
  var errmsg = checkTorrent(torrent);
  if (errmsg !== null) {
    var err = new Error(errmsg);
    err.name = 'SchemaError';
    return callback(err);
  }

  // Convert all buffers into strings that are not hash pieces.
  buf2str(torrent, '');

  // Put metadata into torrent object and call callback with the result.
  callback(null, new Torrent(torrent));
};
<|endoftext|>


<commit_before>import { getRequest, postRequest } from './apiActions';

export const FETCH_ASSIGNMENTS_TO_REVIEW_SUCCESS = 'FETCH_ASSIGNMENTS_TO_REVIEW_SUCCESS';
export const FETCH_ASSIGNMENTS_TO_REVIEW_ERROR = 'FETCH_ASSIGNMENTS_TO_REVIEW_ERROR';
export const FETCH_STUDENT_UPDATES_SUCCESS = 'FETCH_STUDENT_UPDATES_SUCCESS';
export const FETCH_STUDENT_UPDATES_ERROR = 'FETCH_STUDENT_UPDATES_ERROR';
export const GET_CURRENT_RESPONSE_SUCCESS = 'GET_CURRENT_RESPONSE_SUCCESS';
export const GET_CURRENT_ASSIGNMENT_SUCCESS = 'GET_CURRENT_ASSIGNMENT_SUCCESS';
export const CREATE_REVIEW_SUCCESS = 'CREATE_REVIEW_SUCCESS';
export const CREATE_REVIEW_ERROR = 'CREATE_REVIEW_ERROR';

const URL_MY_REVIEWS = '/api/assignment-reviews/me';
const URL_REVIEWS = '/api/assignment-reviews';
const URL_STUDENT_UPDATES = '/api/teacher/me/updates';

const csrfToken = [].slice.call(document.getElementsByTagName('meta'))
    .filter((meta) => meta.name === 'csrf-token')[0].content;

const _headers = {
  'X-CSRF-TOKEN': csrfToken
};

function assignmentToReviewFetched(data) {
  return {
    type: FETCH_ASSIGNMENTS_TO_REVIEW_SUCCESS,
    payload: data.assignment_reviews
  };
}

function assignmentToReviewFetchedError(err) {
  return {
    type: FETCH_ASSIGNMENTS_TO_REVIEW_ERROR,
    payload: err
  };
}

function getCurrentResponseSuccess(response) {
  return {
    type: GET_CURRENT_RESPONSE_SUCCESS,
    payload: response
  };
}

function getCurrentAssignmentSuccess(assignment) {
  return {
    type: GET_CURRENT_ASSIGNMENT_SUCCESS,
    payload: assignment
  };
}

export function fetchAssignmentsToReview(optionalCallback = null) {
  return getRequest(URL_MY_REVIEWS,
    (data) => {
      if (optionalCallback) {
        optionalCallback(data);
      }

      return assignmentToReviewFetched(data);
    }, assignmentToReviewFetchedError);
}

export function getResponse(responseId) {
  const getCurrentResponse = (assignmentsToReview, _responseId) => {
    return assignmentsToReview.map(assignmentToReview => assignmentToReview.response)
      .find(currentResponse => currentResponse.id === _responseId);
  }
  return (dispatch, getState) => {
    const assignmentsToReview = getState().teacherReviewsReducer.assignmentsToReview;
    if (assignmentsToReview !== null) {
      const response = getCurrentResponse(assignmentsToReview, responseId);
      dispatch(getCurrentResponseSuccess(response));
    } else {
      const successHandler = (data) => {
        const response = getCurrentResponse(data.assignment_reviews, responseId);
        return dispatch(getCurrentResponseSuccess(response));
      }
      dispatch(fetchAssignmentsToReview(successHandler));
    }
  }
}

export function getAssignment(responseId) {
  const getCurrentAssignment = (assignmentsToReview, _responseId) => {
    return assignmentsToReview.filter(assignmentToReview => assignmentToReview.response)
      .find(assignmentToReview => assignmentToReview.response.id === _responseId);
  }

  return (dispatch, getState) => {
    const assignmentsToReview = getState().teacherReviewsReducer.assignmentsToReview;
    if (assignmentsToReview !== null) {
      const assignment = getCurrentAssignment(assignmentsToReview, responseId)
      dispatch(getCurrentAssignmentSuccess(assignment));
    } else {
      const successHandler = (data) => {
        const assignment = getCurrentAssignment(data.assignment_reviews, responseId);
        return dispatch(getCurrentAssignmentSuccess(assignment));
      }
      dispatch(fetchAssignmentsToReview(successHandler));
    }
  }
}

function createReviewError() {
  return {
    type: CREATE_REVIEW_ERROR
  };
}

function createReviewSuccess() {
  return {
    type: CREATE_REVIEW_SUCCESS
  };
}

export function createReview(responseId, props) {
  return postRequest(URL_REVIEWS, props, createReviewSuccess, createReviewError, _headers);
}

function fetchStudentUpdatesSuccess(data) {
  return {
    type: FETCH_STUDENT_UPDATES_SUCCESS,
    payload: data.updates
  };
}

function fetchStudentsUpdatesError() {
  return {
    type: FETCH_STUDENT_UPDATES_ERROR
  };
}

export function fetchStudentsUpdates() {
  return getRequest(URL_STUDENT_UPDATES, fetchStudentUpdatesSuccess,
    fetchStudentsUpdatesError, _headers);
}
<commit_msg>add some more alerts on teacher side<commit_after>import { getRequest, postRequest } from './apiActions';
import { displaySuccessAlert, displayErrorAlert } from './alertsActions';

export const FETCH_ASSIGNMENTS_TO_REVIEW_SUCCESS = 'FETCH_ASSIGNMENTS_TO_REVIEW_SUCCESS';
export const FETCH_ASSIGNMENTS_TO_REVIEW_ERROR = 'FETCH_ASSIGNMENTS_TO_REVIEW_ERROR';
export const FETCH_STUDENT_UPDATES_SUCCESS = 'FETCH_STUDENT_UPDATES_SUCCESS';
export const FETCH_STUDENT_UPDATES_ERROR = 'FETCH_STUDENT_UPDATES_ERROR';
export const GET_CURRENT_RESPONSE_SUCCESS = 'GET_CURRENT_RESPONSE_SUCCESS';
export const GET_CURRENT_ASSIGNMENT_SUCCESS = 'GET_CURRENT_ASSIGNMENT_SUCCESS';
export const CREATE_REVIEW_SUCCESS = 'CREATE_REVIEW_SUCCESS';
export const CREATE_REVIEW_ERROR = 'CREATE_REVIEW_ERROR';

const URL_MY_REVIEWS = '/api/assignment-reviews/me';
const URL_REVIEWS = '/api/assignment-reviews';
const URL_STUDENT_UPDATES = '/api/teacher/me/updates';

const csrfToken = [].slice.call(document.getElementsByTagName('meta'))
    .filter((meta) => meta.name === 'csrf-token')[0].content;

const _headers = {
  'X-CSRF-TOKEN': csrfToken
};

function assignmentToReviewFetched(data) {
  return {
    type: FETCH_ASSIGNMENTS_TO_REVIEW_SUCCESS,
    payload: data.assignment_reviews
  };
}

function assignmentToReviewFetchedError(err) {
  return dispatch => {
    dispatch(displayErrorAlert('Error while fetching your assignments to review!'))
    return {
      type: FETCH_ASSIGNMENTS_TO_REVIEW_ERROR,
      payload: err
    };
  }
}

function getCurrentResponseSuccess(response) {
  return {
    type: GET_CURRENT_RESPONSE_SUCCESS,
    payload: response
  };
}

function getCurrentAssignmentSuccess(assignment) {
  return {
    type: GET_CURRENT_ASSIGNMENT_SUCCESS,
    payload: assignment
  };
}

export function fetchAssignmentsToReview(optionalCallback = null) {
  return getRequest(URL_MY_REVIEWS,
    (data) => {
      if (optionalCallback) {
        optionalCallback(data);
      }

      return assignmentToReviewFetched(data);
    }, assignmentToReviewFetchedError);
}

export function getResponse(responseId) {
  const getCurrentResponse = (assignmentsToReview, _responseId) => {
    return assignmentsToReview.map(assignmentToReview => assignmentToReview.response)
      .find(currentResponse => currentResponse.id === _responseId);
  }
  return (dispatch, getState) => {
    const assignmentsToReview = getState().teacherReviewsReducer.assignmentsToReview;
    if (assignmentsToReview !== null) {
      const response = getCurrentResponse(assignmentsToReview, responseId);
      dispatch(getCurrentResponseSuccess(response));
    } else {
      const successHandler = (data) => {
        const response = getCurrentResponse(data.assignment_reviews, responseId);
        return dispatch(getCurrentResponseSuccess(response));
      }
      dispatch(fetchAssignmentsToReview(successHandler));
    }
  }
}

export function getAssignment(responseId) {
  const getCurrentAssignment = (assignmentsToReview, _responseId) => {
    return assignmentsToReview.filter(assignmentToReview => assignmentToReview.response)
      .find(assignmentToReview => assignmentToReview.response.id === _responseId);
  }

  return (dispatch, getState) => {
    const assignmentsToReview = getState().teacherReviewsReducer.assignmentsToReview;
    if (assignmentsToReview !== null) {
      const assignment = getCurrentAssignment(assignmentsToReview, responseId)
      dispatch(getCurrentAssignmentSuccess(assignment));
    } else {
      const successHandler = (data) => {
        const assignment = getCurrentAssignment(data.assignment_reviews, responseId);
        return dispatch(getCurrentAssignmentSuccess(assignment));
      }
      dispatch(fetchAssignmentsToReview(successHandler));
    }
  }
}

function createReviewError() {
  return dispatch => {
    dispatch(displayErrorAlert('Error while creating review!'));

    return {
      type: CREATE_REVIEW_ERROR
    };
  }
}

function createReviewSuccess() {
  return dispatch => {
    dispatch(displaySuccessAlert('Review successfully created!'));
    return {
      type: CREATE_REVIEW_SUCCESS
    };
  }
}

export function createReview(responseId, props) {
  return postRequest(URL_REVIEWS, props, createReviewSuccess, createReviewError, _headers);
}

function fetchStudentUpdatesSuccess(data) {
  return {
    type: FETCH_STUDENT_UPDATES_SUCCESS,
    payload: data.updates
  };
}

function fetchStudentsUpdatesError() {
  return {
    type: FETCH_STUDENT_UPDATES_ERROR
  };
}

export function fetchStudentsUpdates() {
  return getRequest(URL_STUDENT_UPDATES, fetchStudentUpdatesSuccess,
    fetchStudentsUpdatesError, _headers);
}
<|endoftext|>


<commit_before>'use strict';

let gulp = require('gulp');
let requireDir = require('require-dir');
let gulpLoadPlugin = require('gulp-load-plugins');
let $ = gulpLoadPlugin();
let runSequence = require('run-sequence');
let config = require('./gulp/config');
let exec = require('child_process').exec;

requireDir('./gulp/task', {recurse: true});

gulp.task('watch', () => {
  $.watch(config.style.src, () => {
    gulp.start(['style', 'lint:style']);
  });
  $.watch(config.script.src, () => {
    gulp.start(['script', 'lint:script']);
  });
});

gulp.task('serve', (cb) => {
  exec('./node_modules/.bin/harp server --port 8888', (err, stdout, stderr) => {
    console.log(stdout);
    console.log(stderr);
    cb(err);
  });
});

gulp.task('develop', ['watch', 'serve']);

gulp.task('default', () => {
  return runSequence(
    'lint',
    'style',
    'minify',
    'watch'
  );
});
<commit_msg>Tweak gulp watch task<commit_after>'use strict';

let gulp = require('gulp');
let requireDir = require('require-dir');
let gulpLoadPlugin = require('gulp-load-plugins');
let $ = gulpLoadPlugin();
let runSequence = require('run-sequence');
let config = require('./gulp/config');
let exec = require('child_process').exec;

requireDir('./gulp/task', {recurse: true});

gulp.task('watch', () => {
  $.watch(config.style.src, () => {
    gulp.start(['style', 'lint:style', 'minify:style']);
  });
  $.watch(config.script.src, () => {
    gulp.start(['script', 'lint:script']);
  });
});

gulp.task('serve', (cb) => {
  exec('./node_modules/.bin/harp server --port 8888', (err, stdout, stderr) => {
    console.log(stdout);
    console.log(stderr);
    cb(err);
  });
});

gulp.task('develop', ['watch', 'serve']);

gulp.task('default', () => {
  return runSequence(
    'lint',
    'style',
    'minify',
    'watch'
  );
});
<|endoftext|>


<commit_before>var _ = require('underscore');
var express = require('express');
var request = require('request');
var handlebars = require('handlebars');
var hbs = require('hbs');
var sendgrid = require('sendgrid');
var keys = require(__dirname + '/keys.js');
console.log(keys);
var Firebase = require('firebase');
var FirebaseTokenGenerator = require('firebase-token-generator');
var fb_root = new Firebase('https://feedlisten.firebaseio.com/');
var tokenGenerator = new FirebaseTokenGenerator('nkn6OpQUq6gILOZq2vlrcH21P7aFtVCjgVLwQTYt');
var APP_ID = '384422024994164';

console.log(tokenGenerator.mSecret);
var adminToken = tokenGenerator.createToken({}, {
	admin: true,
	debug: false,
	expires: 1577836800
});

fb_root.auth(adminToken);

var app = express();

hbs.registerHelper('foreach', function(context, options) {
    var ret = "";
    for(var prop in context)
    {
        ret = ret + options.fn({
			property:prop, value:context[prop]
        });
    }
    return ret;
});

app.configure('development', function() {
	app.use(express.bodyParser());
	app.use(express.errorHandler());
	app.locals.pretty = true;

	app.set("view engine", 'tmpl');
	app.set("view options", { layout: false });

	app.engine('tmpl', require('hbs').__express);

	app.use(express.static(__dirname + '/public'));
	app.use(express.vhost('realtime.feedlisten.com', require('./realtime/index.js')));
});

app.get('/', function(req, res){
	if(req.query.token){
		//show page with selection of groups
		//maybe should be client-side js for loading the groups?
	} else {
		//send them a facebook auth screen - this could be done on the client side, too
	}
	res.send(__dirname + '/public/index.html');
});

app.get('/selection', function(req, res){
	if(req.query.token && req.query.fbid){
		request({json: true, url:'https://graph.facebook.com/me', qs:{'access_token':req.query.token}}, function(error, response, body){
			if(!error && response.statusCode == 200){
				var user_info = body;
				request({json: true, url:'https://graph.facebook.com/me/accounts', qs:{'access_token':req.query.token}}, function(error, response, body){
					if(!error && response.statusCode == 200){
						var data = {
							name: user_info.first_name,
							accessToken: req.query.token,
							pages: body.data
						};
						console.log(data);
						res.render('pages', data, function(err, html){
							if(err){
								console.log(err);
							} else {
								res.send(html);
							}
						});
					}
				});
			}
		});
	} else {
		res.redirect('/');
	}
});

app.get('/:pageid', function(req, res){
	if(req.query.token){
		request({json: true, url:'https://graph.facebook.com/me/accounts', qs:{'access_token':req.query.token}}, function(error, response, body){
			if(!error && response.statusCode == 200){
				var page;
				_.each(body.data, function(element){
					if(element.id == req.params.pageid){
						page = element;
					}
				});
				res.redirect('/' + page.id + '?pageToken=' + page.access_token);
			}
		});
	} else if(req.query.pageToken) {
		request({json: true, url:'https://graph.facebook.com/' + req.params.pageid, qs:{'access_token':req.query.pageToken}}, function(error, response, body){
			if(!error && response.statusCode == 200){
				var page = body;
				request({json: true, url:'https://graph.facebook.com/' + req.params.pageid, qs:{'fields':'feed', 'access_token':req.query.pageToken}}, function(error, response, body){
					if(!error && response.statusCode == 200){
						var item;
						if(body.feed){
							item = body.feed.data[0];
						} else {
							var viewData = {
								page:page,
								name:'Random User'
							};
							res.render('page', viewData, function(err, html){
								if(err){
									console.log(err);
								} else {
									res.send(html);
								}
							});
							return;
						}
						var bodyData = 'apikey=' + keys.ALCHEMY + '&text=' + encodeURIComponent(item.message) + '&outputMode=json';
						request({method: 'post', url:'http://access.alchemyapi.com/calls/text/TextGetTextSentiment', body:bodyData}, function(error, response, body){
							if(!error && response.statusCode == 200){
								body = JSON.parse(body);
								if(body.docSentiment){
									var sentiment = {
										type: body.docSentiment.type,
										value: body.docSentiment.score
									};
									var viewData = {
										post: item,
										sentiment: sentiment,
										page: page,
										name: 'Random User'
									};
									res.render('page', viewData, function(err, html){
										if(err){
											console.log(err);
										} else {
											res.send(html);
										}
									});
								} else {
									console.log(body);
									console.log(bodyData);
									res.send(500, 'Could not get a sentiment');
								}
							} else {
								console.log(body);
								console.log(bodyData);
								res.send(500, 'Could not get a sentiment');
							}
						});
					}
				});
			}
		});
	} else {
		res.redirect('/');
	}
});

app.post('/:pageid', function(req, res){
	if(req.query.pageToken){
		//have to register with facebook and save some data to firebase
		var bodyData = 'object=page&fields=feed&verify_token=flashing7&callback_url=' + encodeURIComponent('http://realtime.feedlisten.com/');
		bodyData = bodyData + '&access_token='req.query.pageToken;
		request({json: true, url: 'https://graph.facebook.com/' + APP_ID + '/subscriptions', method: 'post', body:bodyData}, function(error, response, body){
			if(!error && response.statusCode == 200){
				fb_root.child(req.params.pageid).set({
					token: req.query.pageToken,
					email: req.body.email,
					type: req.body.type
				}, function(fbError){
					if(fbError){
						console.log(fbError);
					} else {
						res.send('The email was registered successfully! There\'s no way to unregister :-P');
					}
				});

			} else {
				console.log(error);
				console.log(bodyData);
				console.log(response);
				res.send(500, 'We had a problem.');
			}
		});
	} else {
		res.send(500, 'Could not register the email');
	}
});

app.get('/:pageid/:postid', function(req, res){
	res.send('Nope');
});

app.listen(80);<commit_msg>plus sign<commit_after>var _ = require('underscore');
var express = require('express');
var request = require('request');
var handlebars = require('handlebars');
var hbs = require('hbs');
var sendgrid = require('sendgrid');
var keys = require(__dirname + '/keys.js');
console.log(keys);
var Firebase = require('firebase');
var FirebaseTokenGenerator = require('firebase-token-generator');
var fb_root = new Firebase('https://feedlisten.firebaseio.com/');
var tokenGenerator = new FirebaseTokenGenerator('nkn6OpQUq6gILOZq2vlrcH21P7aFtVCjgVLwQTYt');
var APP_ID = '384422024994164';

console.log(tokenGenerator.mSecret);
var adminToken = tokenGenerator.createToken({}, {
	admin: true,
	debug: false,
	expires: 1577836800
});

fb_root.auth(adminToken);

var app = express();

hbs.registerHelper('foreach', function(context, options) {
    var ret = "";
    for(var prop in context)
    {
        ret = ret + options.fn({
			property:prop, value:context[prop]
        });
    }
    return ret;
});

app.configure('development', function() {
	app.use(express.bodyParser());
	app.use(express.errorHandler());
	app.locals.pretty = true;

	app.set("view engine", 'tmpl');
	app.set("view options", { layout: false });

	app.engine('tmpl', require('hbs').__express);

	app.use(express.static(__dirname + '/public'));
	app.use(express.vhost('realtime.feedlisten.com', require('./realtime/index.js')));
});

app.get('/', function(req, res){
	if(req.query.token){
		//show page with selection of groups
		//maybe should be client-side js for loading the groups?
	} else {
		//send them a facebook auth screen - this could be done on the client side, too
	}
	res.send(__dirname + '/public/index.html');
});

app.get('/selection', function(req, res){
	if(req.query.token && req.query.fbid){
		request({json: true, url:'https://graph.facebook.com/me', qs:{'access_token':req.query.token}}, function(error, response, body){
			if(!error && response.statusCode == 200){
				var user_info = body;
				request({json: true, url:'https://graph.facebook.com/me/accounts', qs:{'access_token':req.query.token}}, function(error, response, body){
					if(!error && response.statusCode == 200){
						var data = {
							name: user_info.first_name,
							accessToken: req.query.token,
							pages: body.data
						};
						console.log(data);
						res.render('pages', data, function(err, html){
							if(err){
								console.log(err);
							} else {
								res.send(html);
							}
						});
					}
				});
			}
		});
	} else {
		res.redirect('/');
	}
});

app.get('/:pageid', function(req, res){
	if(req.query.token){
		request({json: true, url:'https://graph.facebook.com/me/accounts', qs:{'access_token':req.query.token}}, function(error, response, body){
			if(!error && response.statusCode == 200){
				var page;
				_.each(body.data, function(element){
					if(element.id == req.params.pageid){
						page = element;
					}
				});
				res.redirect('/' + page.id + '?pageToken=' + page.access_token);
			}
		});
	} else if(req.query.pageToken) {
		request({json: true, url:'https://graph.facebook.com/' + req.params.pageid, qs:{'access_token':req.query.pageToken}}, function(error, response, body){
			if(!error && response.statusCode == 200){
				var page = body;
				request({json: true, url:'https://graph.facebook.com/' + req.params.pageid, qs:{'fields':'feed', 'access_token':req.query.pageToken}}, function(error, response, body){
					if(!error && response.statusCode == 200){
						var item;
						if(body.feed){
							item = body.feed.data[0];
						} else {
							var viewData = {
								page:page,
								name:'Random User'
							};
							res.render('page', viewData, function(err, html){
								if(err){
									console.log(err);
								} else {
									res.send(html);
								}
							});
							return;
						}
						var bodyData = 'apikey=' + keys.ALCHEMY + '&text=' + encodeURIComponent(item.message) + '&outputMode=json';
						request({method: 'post', url:'http://access.alchemyapi.com/calls/text/TextGetTextSentiment', body:bodyData}, function(error, response, body){
							if(!error && response.statusCode == 200){
								body = JSON.parse(body);
								if(body.docSentiment){
									var sentiment = {
										type: body.docSentiment.type,
										value: body.docSentiment.score
									};
									var viewData = {
										post: item,
										sentiment: sentiment,
										page: page,
										name: 'Random User'
									};
									res.render('page', viewData, function(err, html){
										if(err){
											console.log(err);
										} else {
											res.send(html);
										}
									});
								} else {
									console.log(body);
									console.log(bodyData);
									res.send(500, 'Could not get a sentiment');
								}
							} else {
								console.log(body);
								console.log(bodyData);
								res.send(500, 'Could not get a sentiment');
							}
						});
					}
				});
			}
		});
	} else {
		res.redirect('/');
	}
});

app.post('/:pageid', function(req, res){
	if(req.query.pageToken){
		//have to register with facebook and save some data to firebase
		var bodyData = 'object=page&fields=feed&verify_token=flashing7&callback_url=' + encodeURIComponent('http://realtime.feedlisten.com/');
		bodyData = bodyData + '&access_token=' + req.query.pageToken;
		request({json: true, url: 'https://graph.facebook.com/' + APP_ID + '/subscriptions', method: 'post', body:bodyData}, function(error, response, body){
			if(!error && response.statusCode == 200){
				fb_root.child(req.params.pageid).set({
					token: req.query.pageToken,
					email: req.body.email,
					type: req.body.type
				}, function(fbError){
					if(fbError){
						console.log(fbError);
					} else {
						res.send('The email was registered successfully! There\'s no way to unregister :-P');
					}
				});

			} else {
				console.log(error);
				console.log(bodyData);
				console.log(response);
				res.send(500, 'We had a problem.');
			}
		});
	} else {
		res.send(500, 'Could not register the email');
	}
});

app.get('/:pageid/:postid', function(req, res){
	res.send('Nope');
});

app.listen(80);<|endoftext|>


<commit_before>/**
 * nrbac - lib/schema.js
 *
 * Data schema.
 *
 * Copyright(c) 2014 Heroic Yang <me@heroicyang.com> (http://heroicyang.com)
 * MIT Licensed
 */

'use strict';

/**
 * Module dependencies
 */
var _ = require('lodash');
var Schema = require('warehouse').Schema;

// Common methods

/**
 * Creates batch documents, Model class method
 *
 * @param {Object|Array}  params
 * @param {Function}  callback(err, documents)
 */
var createBatch = function(params, callback) {
  try {
    this.insert(params, function(results) {
      callback(null, results);
    });
  } catch (e) {
    callback(e);
  }
};

/**
 * Overrides document's update method, Model instance method
 *
 * @param {Object}  obj
 * @param {Function}  callback(err, document)
 */
var update = function(obj, callback) {
  var _update = this.constructor.prototype.__proto__.update;
  try {
    _update.call(this, obj, function(updatedObj) {
      callback(null, updatedObj);
    });
  } catch (e) {
    callback(e);
  }
};

/**
 * Overrides document's remove method, Model instance method
 *
 * @param {Function}  callback(err, document)
 */
var remove = function(callback) {
  var _remove = this.constructor.prototype.__proto__.remove;
  _remove.call(this, function(obj) {
    callback(null, obj);
  });
};

// Schema definition

/**
 * Defines permissionSchema
 */
var permissionSchema = new Schema({
  action: { type: String, required: true },
  resource: { type: String, required: true },
  displayName: String,
  description: String
});

// Defines Permission Model class methods
permissionSchema.statics = {
  create: createBatch,
  /**
   * Lists all permissions
   *
   * @returns {Array}
   */
  list: function() {
    return this.find({}).toArray();
  }
};

// Defines Permission Model instance methods
permissionSchema.methods = {
  update: update,
  remove: remove
};

/**
 * Defines roleSchema
 */
var roleSchema = new Schema({
  name: { type: String, required: true },
  displayName: String,
  description: String,
  permissions: [{ type: String, ref: 'permissions' }]
});

// Defines Role Model class methods
roleSchema.statics = {
  create: createBatch,
  /**
   * Lists all roles
   *
   * @returns {Array}
   */
  list: function() {
    return this.find({}).populate('permissions').map(function(role) {
      role.permissions = role.permissions.toArray();
      return role;
    });
  }
};

// Defines Role Model instance methods
roleSchema.methods = {
  update: update,
  remove: remove,
  /**
   * Grants permissions to the role
   *
   * @param {Object|Array}  permission  instance of PermissionModel
   * @param {Function}  callback(err, role)
   */
  grant: function(permission, callback) {
    var _update = this.constructor.prototype.__proto__.update;

    if (_.isArray(permission)) {
      _update.call(this, {
        permissions: {
          $addToSet: _.pluck(permission, '_id')
        }
      }, function(role) {
        callback(null, role);
      });
    } else {
      _update.call(this, {
        permissions: { $addToSet: permission._id }
      }, function(role) {
        callback(null, role);
      });
    }
  },
  /**
   * Checks if the role has the given permission
   *
   * @param {String}  action
   * @param {String}  resource
   * @returns {Boolean}
   */
  can: function(action, resource) {
    var permissions = this.populate('permissions').permissions.toArray();
    var can = _.find(permissions, function(permission) {
      return permission && permission.action === action && permission.resource === resource;
    });
    return !!can;
  }
};

/**
 * Compile Models from Schemas
 *
 * @param {Provider} provider
 * @returns {Object}
 */
exports.model = function (provider) {
  var validPattern = /^[a-zA-Z0-9_\-]+$/;

  /**
   * Saves data to storage after permission or role has been changed
   */
  var saveToStorage = function() {
    if (!provider._storage) {
      return;
    }

    var data = JSON.parse(provider._db._export());
    provider._storage.save(data, function(err) {
      if (err) {
        throw err;
      }
    });
  };

  // Adds pre save hooks
  permissionSchema.pre('save', function(permission, next) {
    if (!validPattern.test(permission.action) ||
        !validPattern.test(permission.resource)) {
      return next(new Error('Invlid action or resource'));
    }

    var exists = provider._db.model('permissions').findOne({
      action: permission.action,
      resource: permission.resource
    });
    if (exists && exists._id !== permission._id) {
      return next(new Error('Permission action and resource must be unique'));
    }

    next();
  });

  // Add post save hook
  permissionSchema.post('save', saveToStorage);

  // Add pre save hooks
  roleSchema.pre('save', function(role, next) {
    if (!validPattern.test(role.name)) {
      return next(new Error('Invlid role name'));
    }

    var exists = provider._db.model('roles').findOne({
      name: role.name
    });
    if (exists && exists._id !== role._id) {
      return next(new Error('Role name must be unique'));
    }

    next();
  });

  // Add post save hook
  roleSchema.post('save', saveToStorage);

  return {
    Permission: provider._db.model('permissions', permissionSchema),
    Role: provider._db.model('roles', roleSchema)
  };
};
<commit_msg>add role revoke method<commit_after>/**
 * nrbac - lib/schema.js
 *
 * Data schema.
 *
 * Copyright(c) 2014 Heroic Yang <me@heroicyang.com> (http://heroicyang.com)
 * MIT Licensed
 */

'use strict';

/**
 * Module dependencies
 */
var _ = require('lodash');
var Schema = require('warehouse').Schema;

// Common methods

/**
 * Creates batch documents, Model class method
 *
 * @param {Object|Array}  params
 * @param {Function}  callback(err, documents)
 */
var createBatch = function(params, callback) {
  try {
    this.insert(params, function(results) {
      callback(null, results);
    });
  } catch (e) {
    callback(e);
  }
};

/**
 * Overrides document's update method, Model instance method
 *
 * @param {Object}  obj
 * @param {Function}  callback(err, document)
 */
var update = function(obj, callback) {
  var _update = this.constructor.prototype.__proto__.update;
  try {
    _update.call(this, obj, function(updatedObj) {
      callback(null, updatedObj);
    });
  } catch (e) {
    callback(e);
  }
};

/**
 * Overrides document's remove method, Model instance method
 *
 * @param {Function}  callback(err, document)
 */
var remove = function(callback) {
  var _remove = this.constructor.prototype.__proto__.remove;
  _remove.call(this, function(obj) {
    callback(null, obj);
  });
};

// Schema definition

/**
 * Defines permissionSchema
 */
var permissionSchema = new Schema({
  action: { type: String, required: true },
  resource: { type: String, required: true },
  displayName: String,
  description: String
});

// Defines Permission Model class methods
permissionSchema.statics = {
  create: createBatch,
  /**
   * Lists all permissions
   *
   * @returns {Array}
   */
  list: function() {
    return this.find({}).toArray();
  }
};

// Defines Permission Model instance methods
permissionSchema.methods = {
  update: update,
  remove: remove
};

/**
 * Defines roleSchema
 */
var roleSchema = new Schema({
  name: { type: String, required: true },
  displayName: String,
  description: String,
  permissions: [{ type: String, ref: 'permissions' }]
});

// Defines Role Model class methods
roleSchema.statics = {
  create: createBatch,
  /**
   * Lists all roles
   *
   * @returns {Array}
   */
  list: function() {
    return this.find({}).populate('permissions').map(function(role) {
      role.permissions = role.permissions.toArray();
      return role;
    });
  }
};

// Defines Role Model instance methods
roleSchema.methods = {
  update: update,
  remove: remove,
  /**
   * Grants permissions for role
   *
   * @param {Object|Array}  permission  instance of PermissionModel
   * @param {Function}  callback(err, role)
   */
  grant: function(permission, callback) {
    var _update = this.constructor.prototype.__proto__.update;

    if (_.isArray(permission)) {
      _update.call(this, {
        permissions: {
          $addToSet: _.pluck(permission, '_id')
        }
      }, function(role) {
        callback(null, role);
      });
    } else {
      _update.call(this, {
        permissions: { $addToSet: permission._id }
      }, function(role) {
        callback(null, role);
      });
    }
  },
  /**
   * Revokes permissions for role
   *
   * @param {Object|Array}  permission  instance of PermissionModel
   * @param {Function}  callback(err, role)
   */
  revoke: function(permission, callback) {
    var _update = this.constructor.prototype.__proto__.update;

    if (_.isArray(permission)) {
      _update.call(this, {
        permissions: {
          $pull: _.pluck(permission, '_id')
        }
      }, function(role) {
        callback(null, role);
      });
    } else {
      _update.call(this, {
        permissions: { $pull: permission._id }
      }, function(role) {
        callback(null, role);
      });
    }
  },
  /**
   * Checks if the role has the given permission
   *
   * @param {String}  action
   * @param {String}  resource
   * @returns {Boolean}
   */
  can: function(action, resource) {
    var permissions = this.populate('permissions').permissions.toArray();
    var can = _.find(permissions, function(permission) {
      return permission && permission.action === action && permission.resource === resource;
    });
    return !!can;
  }
};

/**
 * Compile Models from Schemas
 *
 * @param {Provider} provider
 * @returns {Object}
 */
exports.model = function (provider) {
  var validPattern = /^[a-zA-Z0-9_\-]+$/;

  /**
   * Saves data to storage after permission or role has been changed
   */
  var saveToStorage = function() {
    if (!provider._storage) {
      return;
    }

    var data = JSON.parse(provider._db._export());
    provider._storage.save(data, function(err) {
      if (err) {
        throw err;
      }
    });
  };

  // Adds pre save hooks
  permissionSchema.pre('save', function(permission, next) {
    if (!validPattern.test(permission.action) ||
        !validPattern.test(permission.resource)) {
      return next(new Error('Invlid action or resource'));
    }

    var exists = provider._db.model('permissions').findOne({
      action: permission.action,
      resource: permission.resource
    });
    if (exists && exists._id !== permission._id) {
      return next(new Error('Permission action and resource must be unique'));
    }

    next();
  });

  // Add post save hook
  permissionSchema.post('save', saveToStorage);

  // Add pre save hooks
  roleSchema.pre('save', function(role, next) {
    if (!validPattern.test(role.name)) {
      return next(new Error('Invlid role name'));
    }

    var exists = provider._db.model('roles').findOne({
      name: role.name
    });
    if (exists && exists._id !== role._id) {
      return next(new Error('Role name must be unique'));
    }

    next();
  });

  // Add post save hook
  roleSchema.post('save', saveToStorage);

  return {
    Permission: provider._db.model('permissions', permissionSchema),
    Role: provider._db.model('roles', roleSchema)
  };
};
<|endoftext|>


<commit_before>// Note: edit this according to the Reddit subreddit to test
var subreddit = "indoclone"
var bsPort = 3500;
// --------

var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
// Two instances of BrowserSync — one for Reddit, the other for the local server
// for the stylesheet
var browserSync = require('browser-sync');
var util = require('util');
var runSequence = require('run-sequence');

gulp.task('reddit-proxy', function() {
  var runSnippetOnce = 0;
  var timesRun = 0;
  browserSync({
    proxy: "http://www.reddit.com/r/" + subreddit,
    port: bsPort + 1,

    // Use the snippetOptions to find the current subreddit CSS if any
    // and remove that along with putting the new CSS <link>
    snippetOptions: {
      rule: {
        // Matches the correct custom reddit stylesheet
        // If there's none, just match it with the
        match: new RegExp('<link rel="stylesheet" href="[^"]*" title="applied_subreddit_stylesheet" type="text/css">|', 'i'),
        fn: function(snippet, match) {
          // Since there's 2 matches on the snippet injection, check if the snippet
          // has been injected or not
          if (timesRun < 2 && runSnippetOnce === 0) {
            runSnippetOnce = 1;
            timesRun++;
            return snippet + '<link rel="stylesheet" href="http://localhost:'+bsPort+'/css/style.css" title="applied_subreddit_stylesheet" type="text/css">' + (match === '' ? match : '');
          }
          // If both <link> and  has been checked, reset the counter for
          // when the page is reloaded
          else if (timesRun === 1) {
            timesRun = 0;
          }
          else {
            timesRun++;
          }
          return match;
        }
      }
    }
  })
})

gulp.task('setup-servers', function() {
  // Run the local server first
  browserSync({
    server: {
      baseDir: './',
      directory: true,
    },
    files: "",
    open: false,
    codeSync: false,
    ghostMode: false,
    port: bsPort

  }, function(err, bs) {
    if (!err) {
      console.log('Local server running. Initializing Reddit proxy server now.');
      gulp.start('reddit-proxy');
      // TODO: This whole method is buggish. Needs to be updated when BrowserSync
      // supports multiple instances.
      // See https://github.com/shakyShane/browser-sync/issues/172
    }
  })
});

gulp.task('styles', function() {
  return gulp.src('scss/style.scss')
    .pipe($.sass({
      outputStyle: 'nested',
      precision: 3,
      onError: console.error.bind(console, 'Sass error:')
    }))
    // TODO: For some reason not working properly. Use $.autoprefixer fallback
    // .pipe($.postcss([
    //   require('autoprefixer-core')({browsers: ['last 2 version']})
    // ]))
    .pipe($.autoprefixer({browsers: 'last 2 version'}))
    .pipe(gulp.dest('css/'));
});

gulp.task('post-style-dev', function() {
  var fs = require('fs');
  var postcss = require('postcss');
  var url = require('postcss-url');
  var result = postcss()
    .use(url({
      url: function(url) {
        var name = url.substring(2, url.length - 2);
        if (fs.existsSync('images/' + name + '.jpg')) {
          return '"http://localhost:' + bsPort + '/images/' + name + '.jpg"';
        }
        else return '"http://localhost:' + bsPort + '/images/' + name + '.png"';
      }
    }))
    .process(fs.readFileSync('css/style.css'))
    .css;
  fs.writeFile('css/style.css', result);
  return gulp.src('css/style.css').pipe(browserSync.reload({stream: true}));
});

gulp.task('style-dev', function() {
  runSequence('styles', 'post-style-dev');
});

gulp.task('build', function() {
  gulp.src('css/style.css')
    .pipe($.csso())
    .pipe(gulp.dest('dist/css/'));
});

gulp.task('dev', ['setup-servers', 'style-dev'], function() {
  gulp.watch('scss/**/*.scss', ['style-dev'])
});
<commit_msg>BrowserSync inject bug (hopefully finally) fixed<commit_after>// Note: edit this according to the Reddit subreddit to test
var subreddit = "indoclone"
var bsPort = 3500;
// --------

var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
// Two instances of BrowserSync — one for Reddit, the other for the local server
// for the stylesheet
var browserSync = require('browser-sync');
var util = require('util');
var runSequence = require('run-sequence');

gulp.task('reddit-proxy', function() {
  var runSnippetOnce = 0;
  var timesRun = 0;
  browserSync({
    proxy: "http://www.reddit.com/r/" + subreddit,
    port: bsPort + 1,

    // Use the snippetOptions to find the current subreddit CSS if any
    // and remove that along with putting the new CSS <link>
    snippetOptions: {
      rule: {
        // Matches the correct custom reddit stylesheet
        // If there's none, just match it with the
        match: new RegExp('<link rel="stylesheet" href="[^"]*" title="applied_subreddit_stylesheet" type="text/css">|', 'i'),
        fn: function(snippet, match) {
          // Since there's 2 matches on the snippet injection, check if the snippet
          // has been injected or not
          if (timesRun < 2 && runSnippetOnce === 0) {
            runSnippetOnce = 1;
            timesRun++;
            return snippet + '<link rel="stylesheet" href="http://localhost:'+bsPort+'/css/style.css" title="applied_subreddit_stylesheet" type="text/css">' + (match === '' ? match : '');
          }
          // If both <link> and  has been checked, reset the counter for
          // when the page is reloaded
          else if (timesRun === 1) {
            timesRun = 0;
            runSnippetOnce = 0;
          }
          else {
            timesRun++;
          }
          return match;
        }
      }
    }
  })
})

gulp.task('setup-servers', function() {
  // Run the local server first
  browserSync({
    server: {
      baseDir: './',
      directory: true,
    },
    files: "",
    open: false,
    codeSync: false,
    ghostMode: false,
    port: bsPort

  }, function(err, bs) {
    if (!err) {
      console.log('Local server running. Initializing Reddit proxy server now.');
      gulp.start('reddit-proxy');
      // TODO: This whole method is buggish. Needs to be updated when BrowserSync
      // supports multiple instances.
      // See https://github.com/shakyShane/browser-sync/issues/172
    }
  })
});

gulp.task('styles', function() {
  return gulp.src('scss/style.scss')
    .pipe($.sass({
      outputStyle: 'nested',
      precision: 3,
      onError: console.error.bind(console, 'Sass error:')
    }))
    // TODO: For some reason not working properly. Use $.autoprefixer fallback
    // .pipe($.postcss([
    //   require('autoprefixer-core')({browsers: ['last 2 version']})
    // ]))
    .pipe($.autoprefixer({browsers: 'last 2 version'}))
    .pipe(gulp.dest('css/'));
});

gulp.task('post-style-dev', function() {
  var fs = require('fs');
  var postcss = require('postcss');
  var url = require('postcss-url');
  var result = postcss()
    .use(url({
      url: function(url) {
        var name = url.substring(2, url.length - 2);
        if (fs.existsSync('images/' + name + '.jpg')) {
          return '"http://localhost:' + bsPort + '/images/' + name + '.jpg"';
        }
        else return '"http://localhost:' + bsPort + '/images/' + name + '.png"';
      }
    }))
    .process(fs.readFileSync('css/style.css'))
    .css;
  fs.writeFile('css/style.css', result);
  return gulp.src('css/style.css').pipe(browserSync.reload({stream: true}));
});

gulp.task('style-dev', function() {
  runSequence('styles', 'post-style-dev');
});

gulp.task('build', function() {
  gulp.src('css/style.css')
    .pipe($.csso())
    .pipe(gulp.dest('dist/css/'));
});

gulp.task('dev', ['setup-servers', 'style-dev'], function() {
  gulp.watch('scss/**/*.scss', ['style-dev'])
});
<|endoftext|>


<commit_before>/*
Copyright [2009-2014] EMBL-European Bioinformatics Institute
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
     http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
 * Angular.js app for RNAcentral sequence search.
 */

;rnaMetasearch.controller('SeqResultsListCtrl', function($scope, $http) {

	$scope.query = {
		sequence: '',
		submit_attempted: false,
	};

	$scope.defaults = {
		page_size: 10,
		submit_endpoint: '/api/v1/sequence-search/submit?sequence=',
		messages: {
			get_results: 'Loading results',
			done: 'Done',
			failed: 'Error',
			poll_job_status: 'Waiting for results',
			submitting: 'Submitting query',
			loading_more_results: 'Loading more results',
		},
	};

	$scope.params = {
		search_in_progress: false,
		page_size: $scope.defaults.page_size,
		error_message: '',
		status_message: '',
		show_alignments: true,
	};

	$scope.results = results_init();

    /**
     * Retrive results given a results url.
     */
	var get_results = function() {
		$scope.params.search_in_progress = true;
		$scope.params.status_message = $scope.defaults.messages.get_results;

		$http({
			url: $scope.results.url,
			method: 'GET',
			params: {
				page_size: $scope.params.page_size,
				page: 1, // all results are always on 1 page
			}
		}).success(function(data){
			console.log(data);
			console.log(data.results.ena_count + ' ENA entries');
			$scope.results.count = data.results.count;
			$scope.results.alignments = data.results.alignments;
			$scope.params.search_in_progress = false;
			$scope.params.status_message = $scope.defaults.messages.done;
		}).error(function(){
			$scope.params.search_in_progress = false;
			$scope.params.status_message = $scope.defaults.messages.failed;
		});
	};

    /**
     * Poll job status in regular intervals.
     */
	var poll_job_status = function(url) {
		$scope.params.status_message = $scope.defaults.messages.poll_job_status;
		var polling_interval = 1000; // milliseconds
		var interval = setInterval(function(){
			$http({
				url: url,
				method: 'GET'
			}).success(function(data){
				if (data.status === 'Done') {
					window.clearInterval(interval);
					// get results
					$scope.results.url = data.url;
					get_results();
				}
			}).error(function(){
				$scope.params.status_message = $scope.defaults.messages.failed;
			});
		}, polling_interval);
	};

    /**
     * Initiate sequence search.
     */
	var search = function(sequence) {
		$scope.params.search_in_progress = true;
		$scope.params.status_message = $scope.defaults.messages.submitting;
		$http({
			url: $scope.defaults.submit_endpoint + sequence,
			method: 'GET', // todo: switch to POST
		}).success(function(data) {
			console.log(data);
			poll_job_status(data.url);
		}).error(function(data, status) {
			$scope.params.error_message = data.message;
			$scope.params.status_message = $scope.defaults.messages.failed;
			console.log(data);
			console.log(status);
			$scope.params.search_in_progress = false;
		});
	};

    /**
     * Public method for submitting the query.
     */
    $scope.submit_query = function() {
		$scope.query.submit_attempted = true;
    	if (!$scope.seqQueryForm.$valid) {
    		return;
    	}
        search($scope.query.sequence);
    };

    /**
     * Load more results.
     */
    $scope.load_more_results = function() {
        $scope.params.page_size += $scope.defaults.page_size;
		$scope.params.status_message = $scope.defaults.messages.loading_more_results;
        get_results();
    };

    /**
     * Calculate how many items are currently visible.
     */
    $scope.displayed_items = function() {
        return Math.min($scope.params.page_size, $scope.results.count);
    };

    /**
     * Initialize results object.
     */
	function results_init() {
		return {
			alignments: [],
			count: null,
			url: '',
		}
	};

    /**
     * Reset the form.
     */
    $scope.reset = function() {
		$scope.query.sequence = '';
		$scope.query.submit_attempted = false;
		$scope.results = results_init();
		$scope.params.status_message = '';
		$('textarea').focus();
	};

    /**
     * Launch the search from template.
     */
	$scope.sequence_search = function(sequence) {
		$scope.query.sequence = sequence;
		search($scope.query.sequence);
	};

    /**
     * Format e_value.
     */
	$scope.format_evalue = function(e_value) {
		return parseFloat(e_value).toExponential(2);
	};

    /**
     * Toggle alignments button.
     */
	$scope.toggle_alignments = function() {
		$scope.params.show_alignments = !$scope.params.show_alignments;
        $('#toggle-alignments').text(function(i, text){
          return text === "Show alignments" ? "Hide alignments" : "Show alignments";
        });
	};

    /**
     * Count the number of gaps in `formatted_alignment`.
     */
	$scope.count_gaps = function(formatted_alignment) {
		return (formatted_alignment.match(/-/g)||[]).length;
	};

    /**
     * Activate Bootstrap tooltips when the controller is created.
     */
	(function(){
		$('body').tooltip({
			selector: '.help',
			delay: { show: 200, hide: 100 },
			container: 'body',
		});
	})();

});
<commit_msg>Reset page_size between runs<commit_after>/*
Copyright [2009-2014] EMBL-European Bioinformatics Institute
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
     http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
 * Angular.js app for RNAcentral sequence search.
 */

;rnaMetasearch.controller('SeqResultsListCtrl', function($scope, $http) {

	$scope.query = {
		sequence: '',
		submit_attempted: false,
	};

	$scope.defaults = {
		page_size: 10,
		submit_endpoint: '/api/v1/sequence-search/submit?sequence=',
		messages: {
			get_results: 'Loading results',
			done: 'Done',
			failed: 'Error',
			poll_job_status: 'Waiting for results',
			submitting: 'Submitting query',
			loading_more_results: 'Loading more results',
		},
	};

	$scope.params = {
		search_in_progress: false,
		page_size: $scope.defaults.page_size,
		error_message: '',
		status_message: '',
		show_alignments: true,
	};

	$scope.results = results_init();

    /**
     * Retrive results given a results url.
     */
	var get_results = function() {
		$scope.params.search_in_progress = true;
		$scope.params.status_message = $scope.defaults.messages.get_results;

		$http({
			url: $scope.results.url,
			method: 'GET',
			params: {
				page_size: $scope.params.page_size,
				page: 1, // all results are always on 1 page
			}
		}).success(function(data){
			console.log(data);
			console.log(data.results.ena_count + ' ENA entries');
			$scope.results.count = data.results.count;
			$scope.results.alignments = data.results.alignments;
			$scope.params.search_in_progress = false;
			$scope.params.status_message = $scope.defaults.messages.done;
		}).error(function(){
			$scope.params.search_in_progress = false;
			$scope.params.status_message = $scope.defaults.messages.failed;
		});
	};

    /**
     * Poll job status in regular intervals.
     */
	var poll_job_status = function(url) {
		$scope.params.status_message = $scope.defaults.messages.poll_job_status;
		var polling_interval = 1000; // milliseconds
		var interval = setInterval(function(){
			$http({
				url: url,
				method: 'GET'
			}).success(function(data){
				if (data.status === 'Done') {
					window.clearInterval(interval);
					// get results
					$scope.results.url = data.url;
					get_results();
				}
			}).error(function(){
				$scope.params.status_message = $scope.defaults.messages.failed;
			});
		}, polling_interval);
	};

    /**
     * Initiate sequence search.
     */
	var search = function(sequence) {
		$scope.params.search_in_progress = true;
		$scope.params.status_message = $scope.defaults.messages.submitting;
		$http({
			url: $scope.defaults.submit_endpoint + sequence,
			method: 'GET', // todo: switch to POST
		}).success(function(data) {
			console.log(data);
			poll_job_status(data.url);
		}).error(function(data, status) {
			$scope.params.error_message = data.message;
			$scope.params.status_message = $scope.defaults.messages.failed;
			console.log(data);
			console.log(status);
			$scope.params.search_in_progress = false;
		});
	};

    /**
     * Public method for submitting the query.
     */
    $scope.submit_query = function() {
		$scope.query.submit_attempted = true;
    	if (!$scope.seqQueryForm.$valid) {
    		return;
    	}
        search($scope.query.sequence);
    };

    /**
     * Load more results.
     */
    $scope.load_more_results = function() {
        $scope.params.page_size += $scope.defaults.page_size;
		$scope.params.status_message = $scope.defaults.messages.loading_more_results;
        get_results();
    };

    /**
     * Calculate how many items are currently visible.
     */
    $scope.displayed_items = function() {
        return Math.min($scope.params.page_size, $scope.results.count);
    };

    /**
     * Initialize results object.
     */
	function results_init() {
		return {
			alignments: [],
			count: null,
			url: '',
		}
	};

    /**
     * Reset the form.
     */
    $scope.reset = function() {
		$scope.query.sequence = '';
		$scope.query.submit_attempted = false;
		$scope.results = results_init();
		$scope.params.status_message = '';
		$scope.params.page_size = $scope.defaults.page_size;
		$('textarea').focus();
	};

    /**
     * Launch the search from template.
     */
	$scope.sequence_search = function(sequence) {
		$scope.query.sequence = sequence;
		search($scope.query.sequence);
	};

    /**
     * Format e_value.
     */
	$scope.format_evalue = function(e_value) {
		return parseFloat(e_value).toExponential(2);
	};

    /**
     * Toggle alignments button.
     */
	$scope.toggle_alignments = function() {
		$scope.params.show_alignments = !$scope.params.show_alignments;
        $('#toggle-alignments').text(function(i, text){
          return text === "Show alignments" ? "Hide alignments" : "Show alignments";
        });
	};

    /**
     * Count the number of gaps in `formatted_alignment`.
     */
	$scope.count_gaps = function(formatted_alignment) {
		return (formatted_alignment.match(/-/g)||[]).length;
	};

    /**
     * Activate Bootstrap tooltips when the controller is created.
     */
	(function(){
		$('body').tooltip({
			selector: '.help',
			delay: { show: 200, hide: 100 },
			container: 'body',
		});
	})();

});
<|endoftext|>


<commit_before>/*globals Ext, JaztecAdmin*/
/**
 * A panel to house functionality for a master-detail editor.
 * @author Jasper van Herpt <jasper.v.herpt@gmail.com>
 */
Ext.define('JaztecAdmin.view.base.editor.Detail', {
    extend: 'Ext.panel.Panel',
    region: 'center',

    /**
     * @property {Object} data
     * Holds the internal data for this instance of a Detail component.
     * @private
     */
    data: null,

    /**
     * @cfg {Array} fields
     * The fields which are to be displayed in the detail form.
     */

    /**
     * @cfg {Object} formCfg
     * Extra configuration for the detail form..
     */

     /**
      * @cfg {Object} buttonCfg
      * Configuration for the toolbar in the bottom of the detail form.
      */

    initComponent: function()
    {
        var me = this,
            items = [],
            dockedItems = [],
            form,
            buttons;

        // Set the layout.
        this.layout = {
            type: 'vbox',
            align: 'stretch'
        };

        // Create the form.
        form = this.createForm(me);
        items.push(form);

        // Create the button panel.
        buttons = this.createButtons(this.buttonCfg);
        dockedItems.push(buttons);

        me.items = items;
        me.dockedItems = dockedItems;
        me.callParent(arguments);

        // Set the internal data.
        this.data = Ext.apply({
            form: form,
            buttonPanel: buttons
        }, this.data || {});
    },

    /**
     * Setup the detail form according to the provided record.
     *
     * @param   {Ext.data.Model}  record
     * @returns {Ext.data.Model}
     */
    setRecord: function(record)
    {
        if (!record) {
            return;
        }
        this.getForm().loadRecord(record);
        return record;
    },

    /**
     * Return the detail panels form.
     *
     * @returns {Ext.form.Panel}
     */
    getForm: function()
    {
        return this.data.form;
    },

    /**
     * Creates the underlying detail form.
     *
     * @param {type} [options]  Additional parameters
     * @returns {Ext.form.Panel}
     * @private
     */
    createForm: function(options)
    {
        var calcOptions = options || {},
            formCfg = calcOptions.formCfg || {},
            form;

        // Apply some defaults to the form configuration.
        formCfg = Ext.applyIf({
            border: false,
            region: 'center',
            bodyPadding: 10,
            layout: {
                type: 'vbox',
                align: 'stretch'
            }
        }, formCfg);

        // Add the fields to the configuration.
        formCfg = Ext.apply({
            items: calcOptions.fields || []
        }, formCfg);

        form = Ext.create('Ext.form.Panel', formCfg);

        return form;
    },

    /**
     * Create the button panel of the detail form.
     *
     * @param {Object} [config]     Additional parameters for the button toolbar.
     * @param {String} config.dock  The docked position of the toolbar.
     * @returns {JaztecAdmin.view.base.toolbar.Toolbar}
     * @private
     */
    createButtons: function(config)
    {
        var calcConfig = config || {},
            toolbar;

        // Prepare the configuration.
        calcConfig = Ext.apply({
            dock: 'bottom'
        }, calcConfig);

        // Create the toolbar.
        toolbar = Ext.create('JaztecAdmin.view.base.toolbar.Toolbar', calcConfig);

        // Add a save and cancel button.
        toolbar.addToolItem(1, {
            xtype: 'button',
            text: 'Save',
            iconCls: 'icon-save-small',
            handler: Ext.bind(this.onSaveRecord, this)
        });
        toolbar.addToolItem(2, {
            xtype: 'button',
            text: 'Cancel',
            handler: Ext.bind(this.onCancelRecord, this)
        });
        return toolbar;
    },

    /**
     * Calls to its owning masterdetail to save changes to the record.
     * @param {Ext.button.Button} button
     * @private
     */
    onSaveRecord: function(button)
    {
        var record = this.getForm().getRecord();
        this.getForm().getForm().updateRecord(record);
        this.getMasterDetail().saveRecord(record);
        // Return the button to unpressed.
        button.toggle(false, false);
    },

    /**
     * Calls to its owning masterdetail to cancel the current changes.
     * @param {Ext.button.Button} button
     * @private
     */
    onCancelRecord: function(button)
    {
        var record = this.getForm().getRecord();
        this.getForm().getForm().updateRecord(record);
        this.getMasterDetail().cancelRecord(record);
        // Return the button to unpressed.
        button.toggle(false, false);
    },

    /**
     * Get the parent master detail that houses this master panel.
     * @returns {JaztecAdmin.view.base.editor.MasterDetail}
     * @private
     */
    getMasterDetail: function()
    {
        return this.masterDetail;
    }
});
<commit_msg>Validate the form before save<commit_after>/*globals Ext, JaztecAdmin*/
/**
 * A panel to house functionality for a master-detail editor.
 * @author Jasper van Herpt <jasper.v.herpt@gmail.com>
 */
Ext.define('JaztecAdmin.view.base.editor.Detail', {
    extend: 'Ext.panel.Panel',
    region: 'center',

    /**
     * @property {Object} data
     * Holds the internal data for this instance of a Detail component.
     * @private
     */
    data: null,

    /**
     * @cfg {Array} fields
     * The fields which are to be displayed in the detail form.
     */

    /**
     * @cfg {Object} formCfg
     * Extra configuration for the detail form..
     */

     /**
      * @cfg {Object} buttonCfg
      * Configuration for the toolbar in the bottom of the detail form.
      */

    initComponent: function()
    {
        var me = this,
            items = [],
            dockedItems = [],
            form,
            buttons;

        // Set the layout.
        this.layout = {
            type: 'vbox',
            align: 'stretch'
        };

        // Create the form.
        form = this.createForm(me);
        items.push(form);

        // Create the button panel.
        buttons = this.createButtons(this.buttonCfg);
        dockedItems.push(buttons);

        me.items = items;
        me.dockedItems = dockedItems;
        me.callParent(arguments);

        // Set the internal data.
        this.data = Ext.apply({
            form: form,
            buttonPanel: buttons
        }, this.data || {});
    },

    /**
     * Setup the detail form according to the provided record.
     *
     * @param   {Ext.data.Model}  record
     * @returns {Ext.data.Model}
     */
    setRecord: function(record)
    {
        if (!record) {
            return;
        }
        this.getForm().loadRecord(record);
        return record;
    },

    /**
     * Return the detail panels form.
     *
     * @returns {Ext.form.Panel}
     */
    getForm: function()
    {
        return this.data.form;
    },

    /**
     * Creates the underlying detail form.
     *
     * @param {type} [options]  Additional parameters
     * @returns {Ext.form.Panel}
     * @private
     */
    createForm: function(options)
    {
        var calcOptions = options || {},
            formCfg = calcOptions.formCfg || {},
            form;

        // Apply some defaults to the form configuration.
        formCfg = Ext.applyIf({
            border: false,
            region: 'center',
            bodyPadding: 10,
            layout: {
                type: 'vbox',
                align: 'stretch'
            }
        }, formCfg);

        // Add the fields to the configuration.
        formCfg = Ext.apply({
            items: calcOptions.fields || []
        }, formCfg);

        form = Ext.create('Ext.form.Panel', formCfg);

        return form;
    },

    /**
     * Create the button panel of the detail form.
     *
     * @param {Object} [config]     Additional parameters for the button toolbar.
     * @param {String} config.dock  The docked position of the toolbar.
     * @returns {JaztecAdmin.view.base.toolbar.Toolbar}
     * @private
     */
    createButtons: function(config)
    {
        var calcConfig = config || {},
            toolbar;

        // Prepare the configuration.
        calcConfig = Ext.applyIf({
            dock: 'bottom'
        }, calcConfig);

        // Create the toolbar.
        toolbar = Ext.create('JaztecAdmin.view.base.toolbar.Toolbar', calcConfig);

        // Add a save and cancel button.
        toolbar.addToolItem(1, {
            xtype: 'button',
            text: 'Save',
            iconCls: 'icon-save-small',
            handler: Ext.bind(this.onSaveRecord, this)
        });
        toolbar.addToolItem(2, {
            xtype: 'button',
            text: 'Cancel',
            handler: Ext.bind(this.onCancelRecord, this)
        });
        return toolbar;
    },

    /**
     * Calls to its owning masterdetail to save changes to the record.
     * @param {Ext.button.Button} button
     * @private
     */
    onSaveRecord: function(button)
    {
        var record = this.getForm().getRecord(),
            form = this.getForm();

        // Test if the form is filled correctly.
        if (!form.isValid()) {
            return;
        }

        form.getForm().updateRecord(record);
        this.getMasterDetail().saveRecord(record);
        // Return the button to unpressed.
        button.toggle(false, false);
    },

    /**
     * Calls to its owning masterdetail to cancel the current changes.
     * @param {Ext.button.Button} button
     * @private
     */
    onCancelRecord: function(button)
    {
        var record = this.getForm().getRecord();
        this.getForm().getForm().updateRecord(record);
        this.getMasterDetail().cancelRecord(record);
        // Return the button to unpressed.
        button.toggle(false, false);
    },

    /**
     * Get the parent master detail that houses this master panel.
     * @returns {JaztecAdmin.view.base.editor.MasterDetail}
     * @private
     */
    getMasterDetail: function()
    {
        return this.masterDetail;
    }
});
<|endoftext|>


<commit_before>var express = require('express'), app = express();
var config = require('./config.json');
var mongoDB = require('mongodb').MongoClient;
var path = require('path');
var helper = require('./helper');
var userSession = require('./session');
var routes = require('./routes');
var ErrorHandler = require('./error');
var bodyParser = require('body-parser');

function CermaiJs() {
	this.app = app;
	this.run = function() {
		app.listen(config.app.port, config.app.host, function() {
			console.log("Application Running On " + config.app.host + ":" + config.app.port);
		});
	}

	this.connect = function(cb) {
		if (config.connection == undefined) {
			cb("connection null", null);
		}
		else if (config.connection.replica != null) {
			var sideList = config.connection.host + ':' + config.connection.port;
			config.connection.members.forEach(function(x) {
				sideList += "," + x.host + ':' + x.port;
			})
			if (config.connection.user == '' && config.connection.pwd == '') {
				mongoDB.connect('mongodb://' + sideList + '/' + config.connection.db, function(err, db) {
					cb(err, db);
				})
			}
			else {
				mongoDB.connect('mongodb://' + config.connection.user + ':' + config.connection.pwd + '@' + sideList + '/' + config.connection.db, function(err, db) {
					cb(err, db);
				})
			}
		}
		else {
			if (config.connection.user == '' && config.connection.pwd == '') {
				mongoDB.connect('mongodb://' + config.connection.host + ':' + config.connection.port + '/' + config.connection.db, function(err, db) {
					cb(err, db);
				})
			}
			else {
				mongoDB.connect('mongodb://' + config.connection.user + ':' + config.connection.pwd + '@' + config.connection.host + ':' + config.connection.port + '/' + config.connection.db, function(err, db) {
					cb(err, db);
				})
			}
		}
	}
	this.initCermai = function(cermai, db) {
		//// FOR POST REQUEST /////
		if (db == null) {
			console.log("CERMAI RUNNNIG WITHOUT CONNECTION");
		}
		app.use(bodyParser.json());
		app.use(bodyParser.urlencoded({ extended: false }));
		// ## SETTING VIEW ENGINE & CSS PRECOMPILER
		cermai.set('views', path.join(__dirname, '/views'));
		cermai.set('view engine', 'jade');
		cermai.use(require('stylus').middleware(path.join(__dirname, 'public')));
		cermai.use(express.static(path.join(__dirname, '/public')));

		// ## PANGGIL ROUTES
		////////// ERROR HANDLING ////////////////
		routes(cermai, db);
		cermai.use(new ErrorHandler().error404);
		cermai.use(new ErrorHandler().error500);
	}
	this.initHelper = function(cermai) {
		////////// AUTOLOAD HELPER ////////////////
		cermai.use(helper);
	}
	this.initSession = function(cermai) {
		var	session = require('express-session'),
			redisStore = require('connect-redis')(session),
			cookieParser = require('cookie-parser');

		cermai.use(cookieParser('cermaisession'));
		if (config.redis != null) {
			var redis = require('redis').createClient();
			cermai.use(session(
				{
					secret : 'cermaisession',
					store : new redisStore({
						host : config.redis.host.toString(),
						port : config.redis.port,
						client : redis,
						db : config.redis.db,
						pass : config.redis.pwd.toString()
					}),
					resave : true
				}
			));
		}
		else {
			cermai.use(session(
				{
					secret : 'cermaisession',
					store : '',
					resave : true
				}
			));
		}
		cermai.use(userSession);
	}
	this.isAuth = function(req,res,next) {
		if (req.session.cermaiSession) {
			next();
		}
		else {
			res.redirect(config.page.login);
		}
	}
}

module.exports = CermaiJs;<commit_msg>listen for all ip<commit_after>var express = require('express'), app = express();
var config = require('./config.json');
var mongoDB = require('mongodb').MongoClient;
var path = require('path');
var helper = require('./helper');
var userSession = require('./session');
var routes = require('./routes');
var ErrorHandler = require('./error');
var bodyParser = require('body-parser');

function CermaiJs() {
	this.app = app;
	this.run = function() {
		if (config.app.host == undefined) {
			app.listen(config.app.port, function() {
				console.log("Application Running On *:" + config.app.port);
			});
		}
		else {
			app.listen(config.app.port, config.app.host, function() {
				console.log("Application Running On " + config.app.host + ":" + config.app.port);
			});
		}
	}

	this.connect = function(cb) {
		if (config.connection == undefined) {
			cb("connection null", null);
		}
		else if (config.connection.replica != null) {
			var sideList = config.connection.host + ':' + config.connection.port;
			config.connection.members.forEach(function(x) {
				sideList += "," + x.host + ':' + x.port;
			})
			if (config.connection.user == '' && config.connection.pwd == '') {
				mongoDB.connect('mongodb://' + sideList + '/' + config.connection.db, function(err, db) {
					cb(err, db);
				})
			}
			else {
				mongoDB.connect('mongodb://' + config.connection.user + ':' + config.connection.pwd + '@' + sideList + '/' + config.connection.db, function(err, db) {
					cb(err, db);
				})
			}
		}
		else {
			if (config.connection.user == '' && config.connection.pwd == '') {
				mongoDB.connect('mongodb://' + config.connection.host + ':' + config.connection.port + '/' + config.connection.db, function(err, db) {
					cb(err, db);
				})
			}
			else {
				mongoDB.connect('mongodb://' + config.connection.user + ':' + config.connection.pwd + '@' + config.connection.host + ':' + config.connection.port + '/' + config.connection.db, function(err, db) {
					cb(err, db);
				})
			}
		}
	}
	this.initCermai = function(cermai, db) {
		//// FOR POST REQUEST /////
		if (db == null) {
			console.log("CERMAI RUNNNIG WITHOUT CONNECTION");
		}
		app.use(bodyParser.json());
		app.use(bodyParser.urlencoded({ extended: false }));
		// ## SETTING VIEW ENGINE & CSS PRECOMPILER
		cermai.set('views', path.join(__dirname, '/views'));
		cermai.set('view engine', 'jade');
		cermai.use(require('stylus').middleware(path.join(__dirname, 'public')));
		cermai.use(express.static(path.join(__dirname, '/public')));

		// ## PANGGIL ROUTES
		////////// ERROR HANDLING ////////////////
		routes(cermai, db);
		cermai.use(new ErrorHandler().error404);
		cermai.use(new ErrorHandler().error500);
	}
	this.initHelper = function(cermai) {
		////////// AUTOLOAD HELPER ////////////////
		cermai.use(helper);
	}
	this.initSession = function(cermai) {
		var	session = require('express-session'),
			redisStore = require('connect-redis')(session),
			cookieParser = require('cookie-parser');

		cermai.use(cookieParser('cermaisession'));
		if (config.redis != null) {
			var redis = require('redis').createClient();
			cermai.use(session(
				{
					secret : 'cermaisession',
					store : new redisStore({
						host : config.redis.host.toString(),
						port : config.redis.port,
						client : redis,
						db : config.redis.db,
						pass : config.redis.pwd.toString()
					}),
					resave : true
				}
			));
		}
		else {
			cermai.use(session(
				{
					secret : 'cermaisession',
					store : '',
					resave : true
				}
			));
		}
		cermai.use(userSession);
	}
	this.isAuth = function(req,res,next) {
		if (req.session.cermaiSession) {
			next();
		}
		else {
			res.redirect(config.page.login);
		}
	}
}

module.exports = CermaiJs;<|endoftext|>


<commit_before>'use strict';

const gulp   = require('gulp');
const jade   = require('gulp-jade');
const seq    = require('gulp-sequence');
const shell  = require('gulp-shell');
const dotenv = require('dotenv');
const fs     = require('fs');

// Public tasks (serial)
gulp.task('git:hooks:pre-commit', seq('jspm:unbundle'));
gulp.task('postinstall',          seq('jspm:install', 'typings:install', 'git:hooks:install'));
gulp.task('start',                seq('build:dev', 'env:watch', 'server:dev'));

// Build tasks (parallel)
gulp.task('build:dev', ['env:write', 'jade:index:dev', 'jspm:bundle:dev']);

// Server tasks
gulp.task('server:dev', shell.task(['lite-server --config=config/dev.bs.config.json']));

// JSPM bundle tasks
gulp.task('jspm:bundle:dev', shell.task('jspm bundle src/main - [src/app/**/*] ./.dev/vendor.js --inject'));
gulp.task('jspm:install',    shell.task('jspm install'));
gulp.task('jspm:unbundle',   shell.task('jspm unbundle'));

// Compile tasks
gulp.task('jade:index:dev', () => {
  return gulp
    .src('./src/index.jade')
    .pipe(jade({ locals: { dist: false } }))
    .pipe(gulp.dest('./src/'));
});

// Utility tasks
const loc = ['#!/bin/sh', 'PATH="/usr/local/bin:$PATH"', 'npm run git:hooks:pre-commit'];
gulp.task('git:hooks:install', shell.task([
  `printf '${loc.join('\n')}' > ./.git/hooks/pre-commit`,
  'chmod +x ./.git/hooks/pre-commit'
]));
gulp.task('typings:install', shell.task('typings install'));

// write constants for Env to src file
function parseDotFile(path, mustExist) {
  try { return dotenv.parse(fs.readFileSync(path, {encoding: 'utf8'})); }
  catch (e) { if (e.code != 'ENOENT' || mustExist) throw e; }
  return {};
}
function encodeDotValue(val) {
  if (['true', 'false', 'null', 'undefined'].indexOf(val) > -1) return val;
  if (isNaN(val) || val == '') return "'" + val + "'";
  return val;
}
gulp.task('env:write', function(cb) {
  var defaults = parseDotFile('env-defaults', true);
  var overrides = parseDotFile('.env', false);
  var s = '// GENERATED FILE, DO NOT EDIT OR CHECK IN\n';
  s += 'export class Env {\n';
  for (var k in defaults) {
    s += '  public static '+k+' = '+encodeDotValue(overrides[k]||defaults[k]) + ';\n';
  }
  s += '}\n';
  fs.writeFile('src/util/env.ts', s, cb);
});
gulp.task('env:watch', function() {
  gulp.watch(['env-defaults', '.env'], ['env:write']);
});
<commit_msg>Karma test targets<commit_after>'use strict';

const gulp   = require('gulp');
const jade   = require('gulp-jade');
const seq    = require('gulp-sequence');
const shell  = require('gulp-shell');
const dotenv = require('dotenv');
const fs     = require('fs');
const KarmaServer  = require('karma').Server

// Public tasks (serial)
gulp.task('git:hooks:pre-commit', seq('jspm:unbundle'));
gulp.task('postinstall',          seq('jspm:install', 'typings:install', 'git:hooks:install'));
gulp.task('start',                seq('build:dev', 'env:watch', 'server:dev'));

gulp.task('test', function (done) {
  new KarmaServer({
    configFile: __dirname + '/karma.conf.js',
    singleRun: true
  }, done).start();
});

gulp.task('tdd', function (done) {
  new KarmaServer({
    configFile: __dirname + '/karma.conf.js'
  }, done).start();
});

// Build tasks (parallel)
gulp.task('build:dev', ['env:write', 'jade:index:dev', 'jspm:bundle:dev']);

// Server tasks
gulp.task('server:dev', shell.task(['lite-server --config=config/dev.bs.config.json']));

// JSPM bundle tasks
gulp.task('jspm:bundle:dev', shell.task('jspm bundle src/main - [src/app/**/*] ./.dev/vendor.js --inject'));
gulp.task('jspm:install',    shell.task('jspm install'));
gulp.task('jspm:unbundle',   shell.task('jspm unbundle'));

// Compile tasks
gulp.task('jade:index:dev', () => {
  return gulp
    .src('./src/index.jade')
    .pipe(jade({ locals: { dist: false } }))
    .pipe(gulp.dest('./src/'));
});

// Utility tasks
const loc = ['#!/bin/sh', 'PATH="/usr/local/bin:$PATH"', 'npm run git:hooks:pre-commit'];
gulp.task('git:hooks:install', shell.task([
  `printf '${loc.join('\n')}' > ./.git/hooks/pre-commit`,
  'chmod +x ./.git/hooks/pre-commit'
]));
gulp.task('typings:install', shell.task('typings install'));

// write constants for Env to src file
function parseDotFile(path, mustExist) {
  try { return dotenv.parse(fs.readFileSync(path, {encoding: 'utf8'})); }
  catch (e) { if (e.code != 'ENOENT' || mustExist) throw e; }
  return {};
}
function encodeDotValue(val) {
  if (['true', 'false', 'null', 'undefined'].indexOf(val) > -1) return val;
  if (isNaN(val) || val == '') return "'" + val + "'";
  return val;
}
gulp.task('env:write', function(cb) {
  var defaults = parseDotFile('env-defaults', true);
  var overrides = parseDotFile('.env', false);
  var s = '// GENERATED FILE, DO NOT EDIT OR CHECK IN\n';
  s += 'export class Env {\n';
  for (var k in defaults) {
    s += '  public static '+k+' = '+encodeDotValue(overrides[k]||defaults[k]) + ';\n';
  }
  s += '}\n';
  fs.writeFile('src/util/env.ts', s, cb);
});
gulp.task('env:watch', function() {
  gulp.watch(['env-defaults', '.env'], ['env:write']);
});
<|endoftext|>