<commit_before>"use strict";
var fs = require("fs"),
	path = require("path"),
	exec = require("child_process").exec;

var gpioAdmin = "gpio-admin",
	sysFsPathOld = "/sys/devices/virtual/gpio", // pre 3.18.x kernel
	sysFsPathNew = "/sys/class/gpio", // post 3.18.x kernel
	sysFsPath;

var rev = fs.readFileSync("/proc/cpuinfo").toString().split("\n").filter(function(line) {
	return line.indexOf("Revision") == 0;
})[0].split(":")[1].trim();

// tests the device tree directory to determine the actual gpio path
if (fs.existsSync('/sys/devices/soc')) {
	sysFsPath = sysFsPathNew;
} else {
	sysFsPath = sysFsPathOld; // fallback for old kernels
}

rev = parseInt(rev, 16) < 3 ? 1 : 2; // http://elinux.org/RPi_HardwareHistory#Board_Revision_History

var pinMapping = {
	"3": 0,
	"5": 1,
	"7": 4,
	"8": 14,
	"10": 15,
	"11": 17,
	"12": 18,
	"13": 21,
	"15": 22,
	"16": 23,
	"18": 24,
	"19": 10,
	"21": 9,
	"22": 25,
	"23": 11,
	"24": 8,
	"26": 7,

	// Model A+ and Model B+ pins
	"29": 5,
	"31": 6,
	"32": 12,
	"33": 13,
	"35": 19,
	"36": 16,
	"37": 26,
	"38": 20,
	"40": 21
};

if (rev == 2) {
	pinMapping["3"] = 2;
	pinMapping["5"] = 3;
	pinMapping["13"] = 27;
}

function isNumber(number) {
	return !isNaN(parseInt(number, 10));
}

function noop() {}

function handleExecResponse(method, pinNumber, callback) {
	return function(err, stdout, stderr) {
		if (err) {
			console.error("Error when trying to", method, "pin", pinNumber);
			console.error(stderr);
			callback(err);
		} else {
			callback();
		}
	}
}

function sanitizePinNumber(pinNumber) {
	if (!isNumber(pinNumber) || !isNumber(pinMapping[pinNumber])) {
		throw new Error("Pin number isn't valid");
	}

	return parseInt(pinNumber, 10);
}

function sanitizeDirection(direction) {
	direction = (direction || "").toLowerCase().trim();
	if (direction === "in" || direction === "input") {
		return "in";
	} else if (direction === "out" || direction === "output" || !direction) {
		return "out";
	} else {
		throw new Error("Direction must be 'input' or 'output'");
	}
}

function sanitizeOptions(options) {
	var sanitized = {};

	options.split(" ").forEach(function(token) {
		if (token == "in" || token == "input") {
			sanitized.direction = "in";
		}

		if (token == "pullup" || token == "up") {
			sanitized.pull = "pullup";
		}

		if (token == "pulldown" || token == "down") {
			sanitized.pull = "pulldown";
		}
	});

	if (!sanitized.direction) {
		sanitized.direction = "out";
	}

	if (!sanitized.pull) {
		sanitized.pull = "";
	}

	return sanitized;
}

var gpio = {
	rev: rev,

	open: function(pinNumber, options, callback) {
		pinNumber = sanitizePinNumber(pinNumber);

		if (!callback && typeof options === "function") {
			callback = options;
			options = "out";
		}

		options = sanitizeOptions(options);

		exec(gpioAdmin + " export " + pinMapping[pinNumber] + " " + options.pull, handleExecResponse("open", pinNumber, function(err) {
			if (err) return (callback || noop)(err);

			gpio.setDirection(pinNumber, options.direction, callback);
		}));
	},

	setDirection: function(pinNumber, direction, callback) {
		pinNumber = sanitizePinNumber(pinNumber);
		direction = sanitizeDirection(direction);

		fs.writeFile(sysFsPath + "/gpio" + pinMapping[pinNumber] + "/direction", direction, (callback || noop));
	},

	getDirection: function(pinNumber, callback) {
		pinNumber = sanitizePinNumber(pinNumber);
		callback = callback || noop;

		fs.readFile(sysFsPath + "/gpio" + pinMapping[pinNumber] + "/direction", "utf8", function(err, direction) {
			if (err) return callback(err);
			callback(null, sanitizeDirection(direction.trim()));
		});
	},

	close: function(pinNumber, callback) {
		pinNumber = sanitizePinNumber(pinNumber);

		exec(gpioAdmin + " unexport " + pinMapping[pinNumber], handleExecResponse("close", pinNumber, callback || noop));
	},

	read: function(pinNumber, callback) {
		pinNumber = sanitizePinNumber(pinNumber);

		fs.readFile(sysFsPath + "/gpio" + pinMapping[pinNumber] + "/value", function(err, data) {
			if (err) return (callback || noop)(err);

			(callback || noop)(null, parseInt(data, 10));
		});
	},

	write: function(pinNumber, value, callback) {
		pinNumber = sanitizePinNumber(pinNumber);

		value = !!value ? "1" : "0";

		fs.writeFile(sysFsPath + "/gpio" + pinMapping[pinNumber] + "/value", value, "utf8", callback);
	}
};

gpio.export = gpio.open;
gpio.unexport = gpio.close;

module.exports = gpio;
<commit_msg>Changed path to existing GPIO class on new kernel<commit_after>"use strict";
var fs = require("fs"),
	path = require("path"),
	exec = require("child_process").exec;

var gpioAdmin = "gpio-admin",
	sysFsPathOld = "/sys/devices/virtual/gpio", // pre 3.18.x kernel
	sysFsPathNew = "/sys/class/gpio", // post 3.18.x kernel
	sysFsPath;

var rev = fs.readFileSync("/proc/cpuinfo").toString().split("\n").filter(function(line) {
	return line.indexOf("Revision") == 0;
})[0].split(":")[1].trim();

// tests the device tree directory to determine the actual gpio path
if (fs.existsSync(sysFsPathNew)) {
	sysFsPath = sysFsPathNew;
} else {
	sysFsPath = sysFsPathOld; // fallback for old kernels
}

rev = parseInt(rev, 16) < 3 ? 1 : 2; // http://elinux.org/RPi_HardwareHistory#Board_Revision_History

var pinMapping = {
	"3": 0,
	"5": 1,
	"7": 4,
	"8": 14,
	"10": 15,
	"11": 17,
	"12": 18,
	"13": 21,
	"15": 22,
	"16": 23,
	"18": 24,
	"19": 10,
	"21": 9,
	"22": 25,
	"23": 11,
	"24": 8,
	"26": 7,

	// Model A+ and Model B+ pins
	"29": 5,
	"31": 6,
	"32": 12,
	"33": 13,
	"35": 19,
	"36": 16,
	"37": 26,
	"38": 20,
	"40": 21
};

if (rev == 2) {
	pinMapping["3"] = 2;
	pinMapping["5"] = 3;
	pinMapping["13"] = 27;
}

function isNumber(number) {
	return !isNaN(parseInt(number, 10));
}

function noop() {}

function handleExecResponse(method, pinNumber, callback) {
	return function(err, stdout, stderr) {
		if (err) {
			console.error("Error when trying to", method, "pin", pinNumber);
			console.error(stderr);
			callback(err);
		} else {
			callback();
		}
	}
}

function sanitizePinNumber(pinNumber) {
	if (!isNumber(pinNumber) || !isNumber(pinMapping[pinNumber])) {
		throw new Error("Pin number isn't valid");
	}

	return parseInt(pinNumber, 10);
}

function sanitizeDirection(direction) {
	direction = (direction || "").toLowerCase().trim();
	if (direction === "in" || direction === "input") {
		return "in";
	} else if (direction === "out" || direction === "output" || !direction) {
		return "out";
	} else {
		throw new Error("Direction must be 'input' or 'output'");
	}
}

function sanitizeOptions(options) {
	var sanitized = {};

	options.split(" ").forEach(function(token) {
		if (token == "in" || token == "input") {
			sanitized.direction = "in";
		}

		if (token == "pullup" || token == "up") {
			sanitized.pull = "pullup";
		}

		if (token == "pulldown" || token == "down") {
			sanitized.pull = "pulldown";
		}
	});

	if (!sanitized.direction) {
		sanitized.direction = "out";
	}

	if (!sanitized.pull) {
		sanitized.pull = "";
	}

	return sanitized;
}

var gpio = {
	rev: rev,

	open: function(pinNumber, options, callback) {
		pinNumber = sanitizePinNumber(pinNumber);

		if (!callback && typeof options === "function") {
			callback = options;
			options = "out";
		}

		options = sanitizeOptions(options);

		exec(gpioAdmin + " export " + pinMapping[pinNumber] + " " + options.pull, handleExecResponse("open", pinNumber, function(err) {
			if (err) return (callback || noop)(err);

			gpio.setDirection(pinNumber, options.direction, callback);
		}));
	},

	setDirection: function(pinNumber, direction, callback) {
		pinNumber = sanitizePinNumber(pinNumber);
		direction = sanitizeDirection(direction);

		fs.writeFile(sysFsPath + "/gpio" + pinMapping[pinNumber] + "/direction", direction, (callback || noop));
	},

	getDirection: function(pinNumber, callback) {
		pinNumber = sanitizePinNumber(pinNumber);
		callback = callback || noop;

		fs.readFile(sysFsPath + "/gpio" + pinMapping[pinNumber] + "/direction", "utf8", function(err, direction) {
			if (err) return callback(err);
			callback(null, sanitizeDirection(direction.trim()));
		});
	},

	close: function(pinNumber, callback) {
		pinNumber = sanitizePinNumber(pinNumber);

		exec(gpioAdmin + " unexport " + pinMapping[pinNumber], handleExecResponse("close", pinNumber, callback || noop));
	},

	read: function(pinNumber, callback) {
		pinNumber = sanitizePinNumber(pinNumber);

		fs.readFile(sysFsPath + "/gpio" + pinMapping[pinNumber] + "/value", function(err, data) {
			if (err) return (callback || noop)(err);

			(callback || noop)(null, parseInt(data, 10));
		});
	},

	write: function(pinNumber, value, callback) {
		pinNumber = sanitizePinNumber(pinNumber);

		value = !!value ? "1" : "0";

		fs.writeFile(sysFsPath + "/gpio" + pinMapping[pinNumber] + "/value", value, "utf8", callback);
	}
};

gpio.export = gpio.open;
gpio.unexport = gpio.close;

module.exports = gpio;
<|endoftext|>


<commit_before>moduleAid.VERSION = '1.0.1';

this.__defineGetter__('devToolsBox', function() { return $('devtools-sidebar-box'); });

this.devToolsMove = function() {
	if(devToolsBox.getAttribute('hidden') == 'true') {
		delete moveRightBy.devTools;
	} else {
		moveRightBy.__defineGetter__('devTools', function() { return devToolsBox.clientWidth; });
	}
	dispatch(window, { type: 'sidebarWidthChanged', cancelable: false, detail: { bar: rightSidebar } });
};

this.devToolsHover = function() {
	if(rightSidebar.above && rightSidebar.autoHide) {
		setAttribute(rightSidebar.box, 'dontReHover', 'true');
	}
};

moduleAid.LOADMODULE = function() {
	if(typeof(moveRightBy) == 'undefined') { self.moveRightBy = {}; }

	objectWatcher.addAttributeWatcher(devToolsBox, 'hidden', devToolsMove, false, false);

	listenerAid.add(devToolsBox, 'mouseover', devToolsHover);

	devToolsMove();
};

moduleAid.UNLOADMODULE = function() {
	delete moveRightBy.devTools;

	listenerAid.remove(devToolsBox, 'mouseover', devToolsHover);

	objectWatcher.removeAttributeWatcher(devToolsBox, 'hidden', devToolsMove, false, false);
};
<commit_msg>bugfix for devTools<commit_after>moduleAid.VERSION = '1.0.2';

this.__defineGetter__('devToolsBox', function() { return $('devtools-sidebar-box'); });
this.__defineGetter__('devToolsSplitter', function() { return $('devtools-side-splitter'); });

this.devToolsMove = function() {
	if(devToolsBox.getAttribute('hidden') == 'true') {
		delete moveRightBy.devTools;
	} else {
		moveRightBy.__defineGetter__('devTools', function() { return devToolsBox.clientWidth; });
	}
	dispatch(window, { type: 'sidebarWidthChanged', cancelable: false, detail: { bar: rightSidebar } });
};

this.devToolsHover = function() {
	if(rightSidebar.above && rightSidebar.autoHide) {
		setAttribute(rightSidebar.box, 'dontReHover', 'true');
	}
};

moduleAid.LOADMODULE = function() {
	if(typeof(moveRightBy) == 'undefined') { self.moveRightBy = {}; }

	objectWatcher.addAttributeWatcher(devToolsBox, 'hidden', devToolsMove, false, false);

	listenerAid.add(devToolsBox, 'mouseover', devToolsHover);
	listenerAid.add(devToolsSplitter, 'mouseover', devToolsHover);

	devToolsMove();
};

moduleAid.UNLOADMODULE = function() {
	delete moveRightBy.devTools;

	listenerAid.remove(devToolsBox, 'mouseover', devToolsHover);
	listenerAid.remove(devToolsSplitter, 'mouseover', devToolsHover);

	objectWatcher.removeAttributeWatcher(devToolsBox, 'hidden', devToolsMove, false, false);
};
<|endoftext|>


<commit_before>/**
 * Split into declaration and initialization for better startup performance.
 */

var slug = require('slug')
var markdown = require('markdown-it')
var mdnh = require('markdown-it-named-headers')
var md = markdown({ html: true }).use(mdnh)
// markdown()

var Projects = require('../models/Projects')
var Users = require('../models/Users')

module.exports = {
  /**
   * GET /projects
   * List of Project examples.
   */
  getProjects: function (req, res) {
    var mongooseQuery = {brigade: res.locals.brigade.slug}
    // var page
    if (req.query.keyword) {
      mongooseQuery.keywords = req.query.keyword
    }
    if (req.query.need) {
      mongooseQuery.needs = req.query.need
    }
    // if (req.query.page) {
    //   page = req.query.page
    // }
    Projects.find({}, function (err, foundProjects) {
      if (err) console.error(err)
      var allKeywords = []
      var allNeeds = []
      foundProjects.forEach(function (project) {
        project.keywords.forEach(function (keyword) {
          if (allKeywords.indexOf(keyword) < 0) {
            allKeywords.push(keyword)
          }
        })
        project.needs.forEach(function (need) {
          if (allNeeds.indexOf(need) < 0) {
            allNeeds.push(need)
          }
        })
      })
      Projects.find(mongooseQuery, function (err, foundProjects) {
        if (err) console.error(err)
        res.render(res.locals.brigade.theme.slug + '/views/projects/index', {
          view: 'project-list',
          title: 'Projects',
          brigade: res.locals.brigade,
          projects: foundProjects,
          selectedKeyword: req.query.keyword,
          selectedNeed: req.query.need,
          keywords: allKeywords.sort(),
          needs: allNeeds.sort()
        })
      })
    })
  },
  /**
   * GET /projects/manage
   * Manage Projects.
   */
  getProjectsManage: function (req, res) {
    Projects.find({brigade: res.locals.brigade.slug}, function (err, foundProjects) {
      if (err) console.error(err)
      console.log(foundProjects)
      res.render(res.locals.brigade.theme.slug + '/views/projects/manage', {
        view: 'project-list-manage',
        title: 'Manage Projects',
        brigade: res.locals.brigade,
        projects: foundProjects
      })
    })
  },
  /**
   * POST /projects/manage
   * Update all Projects.
   */
  postProjectsManage: function (req, res) {
    req.flash('success', { msg: 'Success! Projects edited' })
    var mongooseQuery = {}
    //  if (!res.locals.user.isAdmin()) {
    //   //  mongooseQuery.author = res.locals.user.username
    //  }
    Projects.find(mongooseQuery, function (err, projects) {
      if (err) console.error(err)
      projects.reverse() // so that most recent are first
      projects.forEach(function (project) {
        var projectInfo = req.body[project.id]
        if (projectInfo.delete) {
          project.remove()
          return
        }
        project.name = projectInfo.name
        project.published = !!projectInfo.published
        project.save(function (err) {
          if (err) throw err
        })
      })
    })
    return res.redirect('/projects/manage/')
  },
  /**
   * GET /projects/new
   * New Projects.
   */
  getProjectsNew: function (req, res) {
    res.render(res.locals.brigade.theme.slug + '/views/projects/new', {
      view: 'project-new',
      title: 'New Projects',
      brigade: res.locals.brigade
    })
  },
  /**
   * POST /projects/new
   * Submit New Projects.
   */
  postProjectsNew: function (req, res) {
    var newProject = new Projects(req.body)
    newProject.id = res.locals.brigade.slug + '-' + req.body.name
    newProject.brigade = res.locals.brigade.slug
    if (req.body.categories) {
      newProject.categories = req.body.categories.replace(/\s/g, '').split(',')
    }
    if (req.body.contact) {
      newProject.contact = req.body.contact.replace(/\s/g, '').split(',')
    }
    if (req.body.needs) {
      newProject.needs = req.body.needs.replace(/\s/g, '').split(',')
    }
    if (req.body.keywords) {
      newProject.keywords = req.body.keywords.replace(/\s/g, '').split(',')
    }
    if (req.body.data) {
      newProject.data = req.body.data.replace(/\s/g, '').split(',')
    }
    newProject.save(function (err) {
      if (err) console.error(err)
    })
    req.flash('success', {msg: 'Success! You have created a project.'})
    res.redirect('/projects/new')
  },

  /**
   * GET /projects/:projectID
   * Display Project by ID.
   */
  getProjectsID: function (req, res) {
    Projects.findOne({
      brigade: res.locals.brigade.slug,
      id: req.params.projectId
    }, function (err, foundProject) {
      if (err) console.error(err)

      foundProject.content = md.render(foundProject.content)
      if (foundProject.contact.length) {
        Projects.fetchGitHubUsers(foundProject.contact, function (contactList) {
          res.render(res.locals.brigade.theme.slug + '/views/projects/project', {
            view: 'project',
            projectId: req.params.projectId,
            title: foundProject.name,
            brigade: res.locals.brigade,
            project: foundProject,
            contacts: contactList
          })
        })
      } else {
        res.render(res.locals.brigade.theme.slug + '/views/projects/project', {
          view: 'project',
          projectId: req.params.projectId,
          title: foundProject.name,
          brigade: res.locals.brigade,
          project: foundProject,
          contacts: []
        })
      }
    })
  },
  /**
   * GET /projects/:projectID/settings
   * IDSettings Projects.
   */
  getProjectsIDSettings: function (req, res) {
    Projects.find({'id': req.params.projectId}, function (err, foundProject) {
      if (err) console.log(err)
      Users.find({}, function (err, allUsers) {
        if (err) console.error(err)
        res.render(res.locals.brigade.theme.slug + '/views/projects/settings', {
          view: 'project-settings',
          project: foundProject[0],
          users: allUsers,
          title: 'IDSettings Projects',
          brigade: res.locals.brigade
        })
      })
    })
  },
  /**
   * POST /projects/:projectID/settings
   * Submit IDSettings Projects.
   */
  postProjectsIDSettings: function (req, res) {
    Projects.find({'id': req.params.projectId}, function (err, foundProject) {
      if (err) console.log(err)
      var thisProject = foundProject[0]
      if (thisProject) {
        console.log(req.body)
        thisProject.categories = []
        thisProject.needs = []
        thisProject.contact = []
        thisProject.data = []
        thisProject.keywords = []
        thisProject.name = req.body.title || ''
        thisProject.id = slug(thisProject.name)
        thisProject.status = req.body.status || ''
        thisProject.politicalEntity = req.body.politicalEntity || ''
        thisProject.geography = req.body.geography || ''
        thisProject.homepage = req.body.homepage || ''
        thisProject.repository = req.body.repository || ''
        thisProject.description = req.body.description || ''
        thisProject.content = req.body.content || ''
        thisProject.thumbnailUrl = req.body.thumbnailUrl || ''
        thisProject.bannerUrl = req.body.bannerUrl || ''
        if (req.body.categories) {
          req.body.categories.replace(/\s/g, '').split(',').forEach(function (category) {
            thisProject.categories.push(category)
          })
        }
        if (req.body.contacts) {
          req.body.contacts.replace(/\s/g, '').split(',').forEach(function (contact) {
            thisProject.contact.push(contact)
          })
        }
        if (req.body.needs) {
          req.body.needs.replace(/\s/g, '').split(',').forEach(function (need) {
            thisProject.needs.push(need)
          })
        }
        if (req.body.keywords) {
          req.body.keywords.replace(/\s/g, '').split(',').forEach(function (keyword) {
            thisProject.keywords.push(keyword)
          })
        }
        return thisProject.save(function (err) {
          if (err) console.log(err)
          req.flash('success', { msg: 'Success! You have updated your project.' })
          res.redirect('/projects/' + thisProject.id + '/settings')
        })
      }
      req.flash('errors', { msg: 'Could not find project with id ' + req.params.projectId })
      res.redirect('/projects/manage')
    })
  },
  /**
   * POST /projects/sync
   * Sync Projects.
   */
  postProjectsSync: function (req, res) {
    Projects.fetchGithubRepos(res.locals.brigade, req.user, function (results) {
      req.flash('success', { msg: 'Success! You have successfully synced projects from Github.' })
      res.redirect('/projects/manage')
    })
  },
  /**
   * POST /projects/delete
   * Delete a project
   */
  postDeleteProject: function (req, res) {
    Projects.remove({id: req.params.projectId}, function (err) {
      if (err) {
        console.log(err)
        return res.redirect('/projects/' + req.params.projectId)
      } else {
        req.flash('success', {msg: 'Your project was deleted.'})
        return res.redirect('/projects/')
      }
    })
  },
  /**
   * POST /projects/:projectID/settings
   * Submit IDSettings Projects.
   */
  postProjectsIDSync: function (req, res) {
    res.redirect('projects/:projectID/settings')
  }
}
<commit_msg>fix(projects): fixed issue with posting data to projects<commit_after>/**
 * Split into declaration and initialization for better startup performance.
 */

var slug = require('slug')
var markdown = require('markdown-it')
var mdnh = require('markdown-it-named-headers')
var md = markdown({ html: true }).use(mdnh)
// markdown()

var Projects = require('../models/Projects')
var Users = require('../models/Users')

module.exports = {
  /**
   * GET /projects
   * List of Project examples.
   */
  getProjects: function (req, res) {
    var mongooseQuery = {brigade: res.locals.brigade.slug}
    // var page
    if (req.query.keyword) {
      mongooseQuery.keywords = req.query.keyword
    }
    if (req.query.need) {
      mongooseQuery.needs = req.query.need
    }
    // if (req.query.page) {
    //   page = req.query.page
    // }
    Projects.find({}, function (err, foundProjects) {
      if (err) console.error(err)
      var allKeywords = []
      var allNeeds = []
      foundProjects.forEach(function (project) {
        project.keywords.forEach(function (keyword) {
          if (allKeywords.indexOf(keyword) < 0) {
            allKeywords.push(keyword)
          }
        })
        project.needs.forEach(function (need) {
          if (allNeeds.indexOf(need) < 0) {
            allNeeds.push(need)
          }
        })
      })
      Projects.find(mongooseQuery, function (err, foundProjects) {
        if (err) console.error(err)
        res.render(res.locals.brigade.theme.slug + '/views/projects/index', {
          view: 'project-list',
          title: 'Projects',
          brigade: res.locals.brigade,
          projects: foundProjects,
          selectedKeyword: req.query.keyword,
          selectedNeed: req.query.need,
          keywords: allKeywords.sort(),
          needs: allNeeds.sort()
        })
      })
    })
  },
  /**
   * GET /projects/manage
   * Manage Projects.
   */
  getProjectsManage: function (req, res) {
    Projects.find({brigade: res.locals.brigade.slug}, function (err, foundProjects) {
      if (err) console.error(err)
      console.log(foundProjects)
      res.render(res.locals.brigade.theme.slug + '/views/projects/manage', {
        view: 'project-list-manage',
        title: 'Manage Projects',
        brigade: res.locals.brigade,
        projects: foundProjects
      })
    })
  },
  /**
   * POST /projects/manage
   * Update all Projects.
   */
  postProjectsManage: function (req, res) {
    req.flash('success', { msg: 'Success! Projects edited' })
    var mongooseQuery = {}
    //  if (!res.locals.user.isAdmin()) {
    //   //  mongooseQuery.author = res.locals.user.username
    //  }
    Projects.find(mongooseQuery, function (err, projects) {
      if (err) console.error(err)
      projects.reverse() // so that most recent are first
      projects.forEach(function (project) {
        var projectInfo = req.body[project.id]
        if (projectInfo.delete) {
          project.remove()
          return
        }
        project.name = projectInfo.name
        project.published = !!projectInfo.published
        project.save(function (err) {
          if (err) throw err
        })
      })
    })
    return res.redirect('/projects/manage/')
  },
  /**
   * GET /projects/new
   * New Projects.
   */
  getProjectsNew: function (req, res) {
    res.render(res.locals.brigade.theme.slug + '/views/projects/new', {
      view: 'project-new',
      title: 'New Projects',
      brigade: res.locals.brigade
    })
  },
  /**
   * POST /projects/new
   * Submit New Projects.
   */
  postProjectsNew: function (req, res) {
    var newProject = new Projects(req.body)
    newProject.id = res.locals.brigade.slug + '-' + req.body.name
    newProject.brigade = res.locals.brigade.slug
    newProject.team = []
    newProject.needs = []
    newProject.keywords = []
    if (req.body.team) {
      if (typeof req.body.team === 'string' && req.body.team.indexOf(',') > -1) {
        req.body.team.replace(/\s/g, '').split(',').forEach(function (member) {
          newProject.team.push(member)
        })
      } else if (typeof req.body.team === 'string') {
        newProject.team.push(req.body.team)
      } else {
        newProject.team.concat(req.body.team)
      }
    }
    if (req.body.needs) {
      if (typeof req.body.needs === 'string' && req.body.needs.indexOf(',') > -1) {
        req.body.needs.replace(/\s/g, '').split(',').forEach(function (need) {
          newProject.needs.push(need)
        })
      } else if (typeof req.body.needs === 'string') {
        newProject.needs.push(req.body.needs)
      } else {
        newProject.needs.concat(req.body.needs)
      }
    }
    if (req.body.keywords) {
      if (typeof req.body.keywords === 'string' && req.body.keywords.indexOf(',') > -1) {
        req.body.keywords.replace(/\s/g, '').split(',').forEach(function (keyword) {
          newProject.keywords.push(keyword)
        })
      } else if (typeof req.body.keywords === 'string') {
        newProject.keywords.push(req.body.keywords)
      } else {
        newProject.keywords.concat(req.body.keywords)
      }
    }
    newProject.save(function (err) {
      if (err) console.error(err)
    })
    req.flash('success', {msg: 'Success! You have created a project.'})
    res.redirect('/projects/new')
  },

  /**
   * GET /projects/:projectID
   * Display Project by ID.
   */
  getProjectsID: function (req, res) {
    Projects.findOne({
      brigade: res.locals.brigade.slug,
      id: req.params.projectId
    }, function (err, foundProject) {
      if (err) console.error(err)

      foundProject.content = md.render(foundProject.content)
      if (foundProject.contact.length) {
        Projects.fetchGitHubUsers(foundProject.contact, function (contactList) {
          res.render(res.locals.brigade.theme.slug + '/views/projects/project', {
            view: 'project',
            projectId: req.params.projectId,
            title: foundProject.name,
            brigade: res.locals.brigade,
            project: foundProject,
            contacts: contactList
          })
        })
      } else {
        res.render(res.locals.brigade.theme.slug + '/views/projects/project', {
          view: 'project',
          projectId: req.params.projectId,
          title: foundProject.name,
          brigade: res.locals.brigade,
          project: foundProject,
          contacts: []
        })
      }
    })
  },
  /**
   * GET /projects/:projectID/settings
   * IDSettings Projects.
   */
  getProjectsIDSettings: function (req, res) {
    Projects.find({'id': req.params.projectId}, function (err, foundProject) {
      if (err) console.log(err)
      Users.find({}, function (err, allUsers) {
        if (err) console.error(err)
        res.render(res.locals.brigade.theme.slug + '/views/projects/settings', {
          view: 'project-settings',
          project: foundProject[0],
          users: allUsers,
          title: 'IDSettings Projects',
          brigade: res.locals.brigade
        })
      })
    })
  },
  /**
   * POST /projects/:projectID/settings
   * Submit IDSettings Projects.
   */
  postProjectsIDSettings: function (req, res) {
    Projects.find({'id': req.params.projectId}, function (err, foundProject) {
      if (err) console.log(err)
      var thisProject = foundProject[0]
      if (thisProject) {
        console.log(req.body)
        thisProject.categories = []
        thisProject.needs = []
        thisProject.team = []
        thisProject.data = []
        thisProject.keywords = []
        thisProject.name = req.body.title || ''
        thisProject.id = slug(thisProject.name)
        thisProject.status = req.body.status || ''
        thisProject.politicalEntity = req.body.politicalEntity || ''
        thisProject.geography = req.body.geography || ''
        thisProject.homepage = req.body.homepage || ''
        thisProject.repository = req.body.repository || ''
        thisProject.description = req.body.description || ''
        thisProject.content = req.body.content || ''
        thisProject.thumbnailUrl = req.body.thumbnailUrl || ''
        thisProject.bannerUrl = req.body.bannerUrl || ''
        if (req.body.team) {
          if (typeof req.body.team === 'string' && req.body.team.indexOf(',') > -1) {
            req.body.team.replace(/\s/g, '').split(',').forEach(function (member) {
              thisProject.team.push(member)
            })
          } else if (typeof req.body.team === 'string') {
            thisProject.team.push(req.body.team)
          } else {
            thisProject.team.concat(req.body.team)
          }
        }
        if (req.body.needs) {
          if (typeof req.body.needs === 'string' && req.body.needs.indexOf(',') > -1) {
            req.body.needs.replace(/\s/g, '').split(',').forEach(function (need) {
              thisProject.needs.push(need)
            })
          } else if (typeof req.body.needs === 'string') {
            thisProject.needs.push(req.body.needs)
          } else {
            thisProject.needs.concat(req.body.needs)
          }
        }
        if (req.body.keywords) {
          if (typeof req.body.keywords === 'string' && req.body.keywords.indexOf(',') > -1) {
            req.body.keywords.replace(/\s/g, '').split(',').forEach(function (keyword) {
              thisProject.keywords.push(keyword)
            })
          } else if (typeof req.body.keywords === 'string') {
            thisProject.keywords.push(req.body.keywords)
          } else {
            thisProject.keywords.concat(req.body.keywords)
          }
        }
        return thisProject.save(function (err) {
          if (err) console.log(err)
          req.flash('success', { msg: 'Success! You have updated your project.' })
          res.redirect('/projects/' + thisProject.id + '/settings')
        })
      }
      req.flash('errors', { msg: 'Could not find project with id ' + req.params.projectId })
      res.redirect('/projects/manage')
    })
  },
  /**
   * POST /projects/sync
   * Sync Projects.
   */
  postProjectsSync: function (req, res) {
    Projects.fetchGithubRepos(res.locals.brigade, req.user, function (results) {
      req.flash('success', { msg: 'Success! You have successfully synced projects from Github.' })
      res.redirect('/projects/manage')
    })
  },
  /**
   * POST /projects/delete
   * Delete a project
   */
  postDeleteProject: function (req, res) {
    Projects.remove({id: req.params.projectId}, function (err) {
      if (err) {
        console.log(err)
        return res.redirect('/projects/' + req.params.projectId)
      } else {
        req.flash('success', {msg: 'Your project was deleted.'})
        return res.redirect('/projects/')
      }
    })
  },
  /**
   * POST /projects/:projectID/settings
   * Submit IDSettings Projects.
   */
  postProjectsIDSync: function (req, res) {
    res.redirect('projects/:projectID/settings')
  }
}
<|endoftext|>


<commit_before>module.exports = function(app, helpers, agenda) {

    app.post('/groupme', function(req, res) {
        agenda.now('import single message', req.body)
        if(req.body.sender_type != "bot") {
            if(req.body.text.indexOf('Imitate') > -1) {
                var markov = 4
                if(req.body.text.indexOf('good') > -1) markov = 6
                else if(req.body.text.indexOf('really good') > -1) markov = 8
                else if(req.body.text.indexOf('bad') > -1) markov = 2
                else if(req.body.text.indexOf('really bad') > -1) markov = 1
                agenda.now('generate markov message', {markov, sender_id: req.body.sender_id});
            }
            else if(req.body.sender_id === '19747855') {
                if(Math.random() > .075) {
                    agenda.now('send message', 'Stop shitposting, Connor');
                }
            }
        }
    })

};
<commit_msg>customization<commit_after>module.exports = function(app, helpers, agenda) {

    var badWords = ["4r5e", "5h1t", "5hit", "a55", "anal", "anus", "ar5e", "arrse", "arse", "ass", "ass-fucker", "asses", "assfucker", "assfukka", "asshole", "assholes", "asswhole", "a_s_s", "b!tch", "b00bs", "b17ch", "b1tch", "ballbag", "balls", "ballsack", "bastard", "beastial", "beastiality", "bellend", "bestial", "bestiality", "bi+ch", "biatch", "bitch", "bitcher", "bitchers", "bitches", "bitchin", "bitching", "bloody", "blow job", "blowjob", "blowjobs", "boiolas", "bollock", "bollok", "boner", "boob", "boobs", "booobs", "boooobs", "booooobs", "booooooobs", "breasts", "buceta", "bugger", "bum", "bunny fucker", "butt", "butthole", "buttmuch", "buttplug", "c0ck", "c0cksucker", "carpet muncher", "cawk", "chink", "cipa", "cl1t", "clit", "clitoris", "clits", "cnut", "cock", "cock-sucker", "cockface", "cockhead", "cockmunch", "cockmuncher", "cocks", "cocksuck", "cocksucked", "cocksucker", "cocksucking", "cocksucks", "cocksuka", "cocksukka", "cok", "cokmuncher", "coksucka", "coon", "cox", "crap", "cum", "cummer", "cumming", "cums", "cumshot", "cunilingus", "cunillingus", "cunnilingus", "cunt", "cuntlick", "cuntlicker", "cuntlicking", "cunts", "cyalis", "cyberfuc", "cyberfuck", "cyberfucked", "cyberfucker", "cyberfuckers", "cyberfucking", "d1ck", "damn", "dick", "dickhead", "dildo", "dildos", "dink", "dinks", "dirsa", "dlck", "dog-fucker", "doggin", "dogging", "donkeyribber", "doosh", "duche", "dyke", "ejaculate", "ejaculated", "ejaculates", "ejaculating", "ejaculatings", "ejaculation", "ejakulate", "f u c k", "f u c k e r", "f4nny", "fag", "fagging", "faggitt", "faggot", "faggs", "fagot", "fagots", "fags", "fanny", "fannyflaps", "fannyfucker", "fanyy", "fatass", "fcuk", "fcuker", "fcuking", "feck", "fecker", "felching", "fellate", "fellatio", "fingerfuck", "fingerfucked", "fingerfucker", "fingerfuckers", "fingerfucking", "fingerfucks", "fistfuck", "fistfucked", "fistfucker", "fistfuckers", "fistfucking", "fistfuckings", "fistfucks", "flange", "fook", "fooker", "fuck", "fucka", "fucked", "fucker", "fuckers", "fuckhead", "fuckheads", "fuckin", "fucking", "fuckings", "fuckingshitmotherfucker", "fuckme", "fucks", "fuckwhit", "fuckwit", "fudge packer", "fudgepacker", "fuk", "fuker", "fukker", "fukkin", "fuks", "fukwhit", "fukwit", "fux", "fux0r", "f_u_c_k", "gangbang", "gangbanged", "gangbangs", "gaylord", "gaysex", "goatse", "God", "god-dam", "god-damned", "goddamn", "goddamned", "hardcoresex", "hell", "heshe", "hoar", "hoare", "hoer", "homo", "hore", "horniest", "horny", "hotsex", "jack-off", "jackoff", "jap", "jerk-off", "jism", "jiz", "jizm", "jizz", "kawk", "knob", "knobead", "knobed", "knobend", "knobhead", "knobjocky", "knobjokey", "kock", "kondum", "kondums", "kum", "kummer", "kumming", "kums", "kunilingus", "l3i+ch", "l3itch", "labia", "lust", "lusting", "m0f0", "m0fo", "m45terbate", "ma5terb8", "ma5terbate", "masochist", "master-bate", "masterb8", "masterbat*", "masterbat3", "masterbate", "masterbation", "masterbations", "masturbate", "mo-fo", "mof0", "mofo", "mothafuck", "mothafucka", "mothafuckas", "mothafuckaz", "mothafucked", "mothafucker", "mothafuckers", "mothafuckin", "mothafucking", "mothafuckings", "mothafucks", "mother fucker", "motherfuck", "motherfucked", "motherfucker", "motherfuckers", "motherfuckin", "motherfucking", "motherfuckings", "motherfuckka", "motherfucks", "muff", "mutha", "muthafecker", "muthafuckker", "muther", "mutherfucker", "n1gga", "n1gger", "nazi", "nigg3r", "nigg4h", "nigga", "niggah", "niggas", "niggaz", "nigger", "niggers", "nob", "nob jokey", "nobhead", "nobjocky", "nobjokey", "numbnuts", "nutsack", "orgasim", "orgasims", "orgasm", "orgasms", "p0rn", "pawn", "pecker", "penis", "penisfucker", "phonesex", "phuck", "phuk", "phuked", "phuking", "phukked", "phukking", "phuks", "phuq", "pigfucker", "pimpis", "piss", "pissed", "pisser", "pissers", "pisses", "pissflaps", "pissin", "pissing", "pissoff", "poop", "porn", "porno", "pornography", "pornos", "prick", "pricks", "pron", "pube", "pusse", "pussi", "pussies", "pussy", "pussys", "rectum", "retard", "rimjaw", "rimming", "s hit", "s.o.b.", "sadist", "schlong", "screwing", "scroat", "scrote", "scrotum", "semen", "sex", "sh!+", "sh!t", "sh1t", "shag", "shagger", "shaggin", "shagging", "shemale", "shi+", "shit", "shitdick", "shite", "shited", "shitey", "shitfuck", "shitfull", "shithead", "shiting", "shitings", "shits", "shitted", "shitter", "shitters", "shitting", "shittings", "shitty", "skank", "slut", "sluts", "smegma", "smut", "snatch", "son-of-a-bitch", "spac", "spunk", "s_h_i_t", "t1tt1e5", "t1tties", "teets", "teez", "testical", "testicle", "tit", "titfuck", "tits", "titt", "tittie5", "tittiefucker", "titties", "tittyfuck", "tittywank", "titwank", "tosser", "turd", "tw4t", "twat", "twathead", "twatty", "twunt", "twunter", "v14gra", "v1gra", "vagina", "viagra", "vulva", "w00se", "wang", "wank", "wanker", "wanky", "whoar", "whore", "willies", "willy", "xrated", "xxx"]

    var profanityResponses = ["watch your profanity", "watch your language, asshole", "do you kiss your mother with that mouth?", "eat shit and die, you foul-mouthed whore", "grow up and stop cursing like some 5-year-old dumbass", "wow, look at this guy. think's he's cool or some shit, using words like that", "fuck you, cunt", "vulgarity isn't cool, you're a dumb piece of shit"]

    app.post('/groupme', function(req, res) {
        agenda.now('import single message', req.body)
        if(req.body.sender_type != "bot") {
            var text = req.body.text.toLowerCase()
            if(text.indexOf('imitate') > -1) {
                var markov = 4
                if(text.indexOf('good') > -1) markov = 6
                else if(text.indexOf('really good') > -1) markov = 8
                else if(text.indexOf('bad') > -1) markov = 2
                else if(text.indexOf('really bad') > -1) markov = 1
                agenda.now('generate markov message', {markov, sender_id: req.body.sender_id});
            }
            else if(req.body.sender_id === '19747855') {
                if(Math.random() > .075) {
                    agenda.now('send message', 'Stop shitposting, Connor');
                }
            }
            else if(req.body.sender_id === '30010919') {
                if(Math.random() > .075) {
                    agenda.now('send message', "don't forget your manners, Ravn")
                }
            }
            else if (new RegExp(badWords.join("|")).test(text)) {
                agenda.now('send message', profanityResponses[Math.floor(Math.random()*profanityResponses.length)]);
            }
            else if(req.body.text.toLowerCase().indexOf('meme machine') > -1) {
                agenda.now('send message', 'You called?');
            }
        }
    })

};
<|endoftext|>


<commit_before>/* eslint no-nested-ternary: 0 */
/* eslint guard-for-in: 0 */
/* eslint no-console: 0 */
/* eslint eqeqeq: 0 */
import Const from '../Const';

function _sort(arr, sortField, order, sortFunc, sortFuncExtraData) {
  order = order.toLowerCase();
  const isDesc = order === Const.SORT_DESC;
  arr.sort((a, b) => {
    if (sortFunc) {
      return sortFunc(a, b, order, sortField, sortFuncExtraData);
    } else {
      if (isDesc) {
        if (b[sortField] === null) return false;
        if (a[sortField] === null) return true;
        if (typeof b[sortField] === 'string') {
          return b[sortField].localeCompare(a[sortField]);
        } else {
          return a[sortField] > b[sortField] ? -1 : ((a[sortField] < b[sortField]) ? 1 : 0);
        }
      } else {
        if (b[sortField] === null) return true;
        if (a[sortField] === null) return false;
        if (typeof a[sortField] === 'string') {
          return a[sortField].localeCompare(b[sortField]);
        } else {
          return a[sortField] < b[sortField] ? -1 : ((a[sortField] > b[sortField]) ? 1 : 0);
        }
      }
    }
  });

  return arr;
}

export class TableDataStore {

  constructor(data) {
    this.data = data;
    this.colInfos = null;
    this.filteredData = null;
    this.isOnFilter = false;
    this.filterObj = null;
    this.searchText = null;
    this.sortObj = null;
    this.pageObj = {};
    this.selected = [];
    this.multiColumnSearch = false;
    this.showOnlySelected = false;
    this.remote = false; // remote data
  }

  setProps(props) {
    this.keyField = props.keyField;
    this.enablePagination = props.isPagination;
    this.colInfos = props.colInfos;
    this.remote = props.remote;
    this.multiColumnSearch = props.multiColumnSearch;
  }

  setData(data) {
    this.data = data;
    this._refresh();
  }

  getSortInfo() {
    return this.sortObj;
  }

  setSelectedRowKey(selectedRowKeys) {
    this.selected = selectedRowKeys;
  }

  getSelectedRowKeys() {
    return this.selected;
  }

  getCurrentDisplayData() {
    if (this.isOnFilter) return this.filteredData;
    else return this.data;
  }

  _refresh() {
    if (this.isOnFilter) {
      if (this.filterObj !== null) this.filter(this.filterObj);
      if (this.searchText !== null) this.search(this.searchText);
    }
    if (this.sortObj) {
      this.sort(this.sortObj.order, this.sortObj.sortField);
    }
  }

  ignoreNonSelected() {
    this.showOnlySelected = !this.showOnlySelected;
    if (this.showOnlySelected) {
      this.isOnFilter = true;
      this.filteredData = this.data.filter( row => {
        const result = this.selected.find(x => row[this.keyField] === x);
        return typeof result !== 'undefined' ? true : false;
      });
    } else {
      this.isOnFilter = false;
    }
  }

  sort(order, sortField) {
    this.sortObj = { order, sortField };

    let currentDisplayData = this.getCurrentDisplayData();
    if (!this.colInfos[sortField]) return this;

    const { sortFunc, sortFuncExtraData } = this.colInfos[sortField];
    currentDisplayData = _sort(currentDisplayData, sortField, order, sortFunc, sortFuncExtraData);

    return this;
  }

  page(page, sizePerPage) {
    this.pageObj.end = page * sizePerPage - 1;
    this.pageObj.start = this.pageObj.end - (sizePerPage - 1);
    return this;
  }

  edit(newVal, rowIndex, fieldName) {
    const currentDisplayData = this.getCurrentDisplayData();
    let rowKeyCache;
    if (!this.enablePagination) {
      currentDisplayData[rowIndex][fieldName] = newVal;
      rowKeyCache = currentDisplayData[rowIndex][this.keyField];
    } else {
      currentDisplayData[this.pageObj.start + rowIndex][fieldName] = newVal;
      rowKeyCache = currentDisplayData[this.pageObj.start + rowIndex][this.keyField];
    }
    if (this.isOnFilter) {
      this.data.forEach(function(row) {
        if (row[this.keyField] === rowKeyCache) {
          row[fieldName] = newVal;
        }
      }, this);
      if (this.filterObj !== null) this.filter(this.filterObj);
      if (this.searchText !== null) this.search(this.searchText);
    }
    return this;
  }

  addAtBegin(newObj) {
    if (!newObj[this.keyField] || newObj[this.keyField].toString() === '') {
      throw `${this.keyField} can't be empty value.`;
    }
    const currentDisplayData = this.getCurrentDisplayData();
    currentDisplayData.forEach(function(row) {
      if (row[this.keyField].toString() === newObj[this.keyField].toString()) {
        throw `${this.keyField} ${newObj[this.keyField]} already exists`;
      }
    }, this);
    currentDisplayData.unshift(newObj);
    if (this.isOnFilter) {
      this.data.unshift(newObj);
    }
    this._refresh();
  }

  add(newObj) {
    if (!newObj[this.keyField] || newObj[this.keyField].toString() === '') {
      throw `${this.keyField} can't be empty value.`;
    }
    const currentDisplayData = this.getCurrentDisplayData();
    currentDisplayData.forEach(function(row) {
      if (row[this.keyField].toString() === newObj[this.keyField].toString()) {
        throw `${this.keyField} ${newObj[this.keyField]} already exists`;
      }
    }, this);

    currentDisplayData.push(newObj);
    if (this.isOnFilter) {
      this.data.push(newObj);
    }
    this._refresh();
  }

  remove(rowKey) {
    const currentDisplayData = this.getCurrentDisplayData();
    const result = currentDisplayData.filter(row => {
      return rowKey.indexOf(row[this.keyField]) === -1;
    });

    if (this.isOnFilter) {
      this.data = this.data.filter(row => {
        return rowKey.indexOf(row[this.keyField]) === -1;
      });
      this.filteredData = result;
    } else {
      this.data = result;
    }
  }

  filter(filterObj) {
    if (Object.keys(filterObj).length === 0) {
      this.filteredData = null;
      this.isOnFilter = false;
      this.filterObj = null;
      if (this.searchText !== null) this.search(this.searchText);
    } else {
      this.filterObj = filterObj;
      this.filteredData = this.data.filter( row => {
        let valid = true;
        let filterVal;
        for (const key in filterObj) {
          let targetVal = row[key];

          switch (filterObj[key].type) {
          case Const.FILTER_TYPE.NUMBER: {
            filterVal = filterObj[key].value.number;
            break;
          }
          case Const.FILTER_TYPE.CUSTOM: {
            filterVal = (typeof filterObj[key].value === 'object') ?
              undefined :
              (typeof filterObj[key].value === 'string') ?
                filterObj[key].value.toLowerCase() :
                filterObj[key].value;
            break;
          }
          case Const.FILTER_TYPE.DATE: {
            filterVal = filterObj[key].value.date;
            break;
          }
          case Const.FILTER_TYPE.REGEX: {
            filterVal = filterObj[key].value;
            break;
          }
          default: {
            filterVal = (typeof filterObj[key].value === 'string') ?
              filterObj[key].value.toLowerCase() :
              filterObj[key].value;
            if (filterVal === undefined) {
              // Support old filter
              filterVal = filterObj[key].toLowerCase();
            }
            break;
          }
          }

          if (this.colInfos[key]) {
            const { format, filterFormatted, formatExtraData } = this.colInfos[key];
            if (filterFormatted && format) {
              targetVal = format(row[key], row, formatExtraData);
            }
          }

          switch (filterObj[key].type) {
          case Const.FILTER_TYPE.NUMBER: {
            valid = this.filterNumber(targetVal, filterVal, filterObj[key].value.comparator);
            break;
          }
          case Const.FILTER_TYPE.DATE: {
            valid = this.filterDate(targetVal, filterVal, filterObj[key].value.comparator);
            break;
          }
          case Const.FILTER_TYPE.REGEX: {
            valid = this.filterRegex(targetVal, filterVal);
            break;
          }
          case Const.FILTER_TYPE.CUSTOM: {
            valid = this.filterCustom(targetVal, filterVal, filterObj[key].value);
            break;
          }
          default: {
            valid = this.filterText(targetVal, filterVal);
            break;
          }
          }
          if (!valid) {
            break;
          }
        }
        return valid;
      });
      this.isOnFilter = true;
    }
  }

  filterNumber(targetVal, filterVal, comparator) {
    let valid = true;
    switch (comparator) {
    case '=': {
      if (targetVal != filterVal) {
        valid = false;
      }
      break;
    }
    case '>': {
      if (targetVal <= filterVal) {
        valid = false;
      }
      break;
    }
    case '>=': {
      if (targetVal < filterVal) {
        valid = false;
      }
      break;
    }
    case '<': {
      if (targetVal >= filterVal) {
        valid = false;
      }
      break;
    }
    case '<=': {
      if (targetVal > filterVal) {
        valid = false;
      }
      break;
    }
    case '!=': {
      if (targetVal == filterVal) {
        valid = false;
      }
      break;
    }
    default: {
      console.error('Number comparator provided is not supported');
      break;
    }
    }
    return valid;
  }

  filterDate(targetVal, filterVal, comparator) {
    // if (!targetVal) {
    //   return false;
    // }
    // return (targetVal.getDate() === filterVal.getDate() &&
    //     targetVal.getMonth() === filterVal.getMonth() &&
    //     targetVal.getFullYear() === filterVal.getFullYear());

    let valid = true;
    switch (comparator) {
    case '=': {
      if (targetVal != filterVal) {
        valid = false;
      }
      break;
    }
    case '>': {
      if (targetVal <= filterVal) {
        valid = false;
      }
      break;
    }
    case '>=': {
      // console.log(targetVal);
      // console.log(filterVal);
      // console.log(filterVal.getDate());
      if (targetVal < filterVal) {
        valid = false;
      }
      break;
    }
    case '<': {
      if (targetVal >= filterVal) {
        valid = false;
      }
      break;
    }
    case '<=': {
      if (targetVal > filterVal) {
        valid = false;
      }
      break;
    }
    case '!=': {
      if (targetVal == filterVal) {
        valid = false;
      }
      break;
    }
    default: {
      console.error('Date comparator provided is not supported');
      break;
    }
    }
    return valid;
  }

  filterRegex(targetVal, filterVal) {
    try {
      return new RegExp(filterVal, 'i').test(targetVal);
    } catch (e) {
      console.error('Invalid regular expression');
      return true;
    }
  }

  filterCustom(targetVal, filterVal, callbackInfo) {
    if (callbackInfo !== null && typeof callbackInfo === 'object') {
      return callbackInfo.callback(targetVal, callbackInfo.callbackParameters);
    }

    return this.filterText(targetVal, filterVal);
  }

  filterText(targetVal, filterVal) {
    if (targetVal.toString().toLowerCase().indexOf(filterVal) === -1) {
      return false;
    }
    return true;
  }

  /* General search function
   * It will search for the text if the input includes that text;
   */
  search(searchText) {
    if (searchText.trim() === '') {
      this.filteredData = null;
      this.isOnFilter = false;
      this.searchText = null;
      if (this.filterObj !== null) this.filter(this.filterObj);
    } else {
      this.searchText = searchText;
      let searchTextArray = [];

      if (this.multiColumnSearch) {
        searchTextArray = searchText.split(' ');
      } else {
        searchTextArray.push(searchText);
      }
      // Mark following code for fixing #363
      // To avoid to search on a data which be searched or filtered
      // But this solution have a poor performance, because I do a filter again
      // const source = this.isOnFilter ? this.filteredData : this.data;
      const source = this.filterObj !== null ? this.filter(this.filterObj) : this.data;

      this.filteredData = source.filter( row => {
        const keys = Object.keys(row);
        let valid = false;
        // for loops are ugly, but performance matters here.
        // And you cant break from a forEach.
        // http://jsperf.com/for-vs-foreach/66
        for (let i = 0, keysLength = keys.length; i < keysLength; i++) {
          const key = keys[i];
          if (this.colInfos[key] && row[key]) {
            const { format, filterFormatted, formatExtraData, searchable } = this.colInfos[key];
            let targetVal = row[key];
            if (searchable) {
              if (filterFormatted && format) {
                targetVal = format(targetVal, row, formatExtraData);
              }
              for (let j = 0, textLength = searchTextArray.length; j < textLength; j++) {
                const filterVal = searchTextArray[j].toLowerCase();
                if (targetVal.toString().toLowerCase().indexOf(filterVal) !== -1) {
                  valid = true;
                  break;
                }
              }
            }
          }
        }
        return valid;
      });
      this.isOnFilter = true;
    }
  }

  getDataIgnoringPagination() {
    return this.getCurrentDisplayData();
  }

  get() {
    const _data = this.getCurrentDisplayData();

    if (_data.length === 0) return _data;

    if (this.remote || !this.enablePagination) {
      return _data;
    } else {
      const result = [];
      for (let i = this.pageObj.start; i <= this.pageObj.end; i++) {
        result.push(_data[i]);
        if (i + 1 === _data.length) break;
      }
      return result;
    }
  }

  getKeyField() {
    return this.keyField;
  }

  getDataNum() {
    return this.getCurrentDisplayData().length;
  }

  isChangedPage() {
    return this.pageObj.start && this.pageObj.end ? true : false;
  }

  isEmpty() {
    return (this.data.length === 0 ||
      this.data === null ||
      this.data === undefined);
  }

  getAllRowkey() {
    return this.data.map(row => {
      return row[this.keyField];
    });
  }
}
<commit_msg>fix #427<commit_after>/* eslint no-nested-ternary: 0 */
/* eslint guard-for-in: 0 */
/* eslint no-console: 0 */
/* eslint eqeqeq: 0 */
import Const from '../Const';

function _sort(arr, sortField, order, sortFunc, sortFuncExtraData) {
  order = order.toLowerCase();
  const isDesc = order === Const.SORT_DESC;
  arr.sort((a, b) => {
    if (sortFunc) {
      return sortFunc(a, b, order, sortField, sortFuncExtraData);
    } else {
      if (isDesc) {
        if (b[sortField] === null) return false;
        if (a[sortField] === null) return true;
        if (typeof b[sortField] === 'string') {
          return b[sortField].localeCompare(a[sortField]);
        } else {
          return a[sortField] > b[sortField] ? -1 : ((a[sortField] < b[sortField]) ? 1 : 0);
        }
      } else {
        if (b[sortField] === null) return true;
        if (a[sortField] === null) return false;
        if (typeof a[sortField] === 'string') {
          return a[sortField].localeCompare(b[sortField]);
        } else {
          return a[sortField] < b[sortField] ? -1 : ((a[sortField] > b[sortField]) ? 1 : 0);
        }
      }
    }
  });

  return arr;
}

export class TableDataStore {

  constructor(data) {
    this.data = data;
    this.colInfos = null;
    this.filteredData = null;
    this.isOnFilter = false;
    this.filterObj = null;
    this.searchText = null;
    this.sortObj = null;
    this.pageObj = {};
    this.selected = [];
    this.multiColumnSearch = false;
    this.showOnlySelected = false;
    this.remote = false; // remote data
  }

  setProps(props) {
    this.keyField = props.keyField;
    this.enablePagination = props.isPagination;
    this.colInfos = props.colInfos;
    this.remote = props.remote;
    this.multiColumnSearch = props.multiColumnSearch;
  }

  setData(data) {
    this.data = data;
    this._refresh();
  }

  getSortInfo() {
    return this.sortObj;
  }

  setSelectedRowKey(selectedRowKeys) {
    this.selected = selectedRowKeys;
  }

  getSelectedRowKeys() {
    return this.selected;
  }

  getCurrentDisplayData() {
    if (this.isOnFilter) return this.filteredData;
    else return this.data;
  }

  _refresh() {
    if (this.isOnFilter) {
      if (this.filterObj !== null) this.filter(this.filterObj);
      if (this.searchText !== null) this.search(this.searchText);
    }
    if (this.sortObj) {
      this.sort(this.sortObj.order, this.sortObj.sortField);
    }
  }

  ignoreNonSelected() {
    this.showOnlySelected = !this.showOnlySelected;
    if (this.showOnlySelected) {
      this.isOnFilter = true;
      this.filteredData = this.data.filter( row => {
        const result = this.selected.find(x => row[this.keyField] === x);
        return typeof result !== 'undefined' ? true : false;
      });
    } else {
      this.isOnFilter = false;
    }
  }

  sort(order, sortField) {
    this.sortObj = { order, sortField };

    let currentDisplayData = this.getCurrentDisplayData();
    if (!this.colInfos[sortField]) return this;

    const { sortFunc, sortFuncExtraData } = this.colInfos[sortField];
    currentDisplayData = _sort(currentDisplayData, sortField, order, sortFunc, sortFuncExtraData);

    return this;
  }

  page(page, sizePerPage) {
    this.pageObj.end = page * sizePerPage - 1;
    this.pageObj.start = this.pageObj.end - (sizePerPage - 1);
    return this;
  }

  edit(newVal, rowIndex, fieldName) {
    const currentDisplayData = this.getCurrentDisplayData();
    let rowKeyCache;
    if (!this.enablePagination) {
      currentDisplayData[rowIndex][fieldName] = newVal;
      rowKeyCache = currentDisplayData[rowIndex][this.keyField];
    } else {
      currentDisplayData[this.pageObj.start + rowIndex][fieldName] = newVal;
      rowKeyCache = currentDisplayData[this.pageObj.start + rowIndex][this.keyField];
    }
    if (this.isOnFilter) {
      this.data.forEach(function(row) {
        if (row[this.keyField] === rowKeyCache) {
          row[fieldName] = newVal;
        }
      }, this);
      if (this.filterObj !== null) this.filter(this.filterObj);
      if (this.searchText !== null) this.search(this.searchText);
    }
    return this;
  }

  addAtBegin(newObj) {
    if (!newObj[this.keyField] || newObj[this.keyField].toString() === '') {
      throw `${this.keyField} can't be empty value.`;
    }
    const currentDisplayData = this.getCurrentDisplayData();
    currentDisplayData.forEach(function(row) {
      if (row[this.keyField].toString() === newObj[this.keyField].toString()) {
        throw `${this.keyField} ${newObj[this.keyField]} already exists`;
      }
    }, this);
    currentDisplayData.unshift(newObj);
    if (this.isOnFilter) {
      this.data.unshift(newObj);
    }
    this._refresh();
  }

  add(newObj) {
    if (!newObj[this.keyField] || newObj[this.keyField].toString() === '') {
      throw `${this.keyField} can't be empty value.`;
    }
    const currentDisplayData = this.getCurrentDisplayData();
    currentDisplayData.forEach(function(row) {
      if (row[this.keyField].toString() === newObj[this.keyField].toString()) {
        throw `${this.keyField} ${newObj[this.keyField]} already exists`;
      }
    }, this);

    currentDisplayData.push(newObj);
    if (this.isOnFilter) {
      this.data.push(newObj);
    }
    this._refresh();
  }

  remove(rowKey) {
    const currentDisplayData = this.getCurrentDisplayData();
    const result = currentDisplayData.filter(row => {
      return rowKey.indexOf(row[this.keyField]) === -1;
    });

    if (this.isOnFilter) {
      this.data = this.data.filter(row => {
        return rowKey.indexOf(row[this.keyField]) === -1;
      });
      this.filteredData = result;
    } else {
      this.data = result;
    }
  }

  filter(filterObj) {
    if (Object.keys(filterObj).length === 0) {
      this.filteredData = null;
      this.isOnFilter = false;
      this.filterObj = null;
      if (this.searchText !== null) this.search(this.searchText);
    } else {
      this.filterObj = filterObj;
      this.filteredData = this.data.filter( row => {
        let valid = true;
        let filterVal;
        for (const key in filterObj) {
          let targetVal = row[key];
          if (targetVal === null) return false;

          switch (filterObj[key].type) {
          case Const.FILTER_TYPE.NUMBER: {
            filterVal = filterObj[key].value.number;
            break;
          }
          case Const.FILTER_TYPE.CUSTOM: {
            filterVal = (typeof filterObj[key].value === 'object') ?
              undefined :
              (typeof filterObj[key].value === 'string') ?
                filterObj[key].value.toLowerCase() :
                filterObj[key].value;
            break;
          }
          case Const.FILTER_TYPE.DATE: {
            filterVal = filterObj[key].value.date;
            break;
          }
          case Const.FILTER_TYPE.REGEX: {
            filterVal = filterObj[key].value;
            break;
          }
          default: {
            filterVal = (typeof filterObj[key].value === 'string') ?
              filterObj[key].value.toLowerCase() :
              filterObj[key].value;
            if (filterVal === undefined) {
              // Support old filter
              filterVal = filterObj[key].toLowerCase();
            }
            break;
          }
          }

          if (this.colInfos[key]) {
            const { format, filterFormatted, formatExtraData } = this.colInfos[key];
            if (filterFormatted && format) {
              targetVal = format(row[key], row, formatExtraData);
            }
          }

          switch (filterObj[key].type) {
          case Const.FILTER_TYPE.NUMBER: {
            valid = this.filterNumber(targetVal, filterVal, filterObj[key].value.comparator);
            break;
          }
          case Const.FILTER_TYPE.DATE: {
            valid = this.filterDate(targetVal, filterVal, filterObj[key].value.comparator);
            break;
          }
          case Const.FILTER_TYPE.REGEX: {
            valid = this.filterRegex(targetVal, filterVal);
            break;
          }
          case Const.FILTER_TYPE.CUSTOM: {
            valid = this.filterCustom(targetVal, filterVal, filterObj[key].value);
            break;
          }
          default: {
            valid = this.filterText(targetVal, filterVal);
            break;
          }
          }
          if (!valid) {
            break;
          }
        }
        return valid;
      });
      this.isOnFilter = true;
    }
  }

  filterNumber(targetVal, filterVal, comparator) {
    let valid = true;
    switch (comparator) {
    case '=': {
      if (targetVal != filterVal) {
        valid = false;
      }
      break;
    }
    case '>': {
      if (targetVal <= filterVal) {
        valid = false;
      }
      break;
    }
    case '>=': {
      if (targetVal < filterVal) {
        valid = false;
      }
      break;
    }
    case '<': {
      if (targetVal >= filterVal) {
        valid = false;
      }
      break;
    }
    case '<=': {
      if (targetVal > filterVal) {
        valid = false;
      }
      break;
    }
    case '!=': {
      if (targetVal == filterVal) {
        valid = false;
      }
      break;
    }
    default: {
      console.error('Number comparator provided is not supported');
      break;
    }
    }
    return valid;
  }

  filterDate(targetVal, filterVal, comparator) {
    // if (!targetVal) {
    //   return false;
    // }
    // return (targetVal.getDate() === filterVal.getDate() &&
    //     targetVal.getMonth() === filterVal.getMonth() &&
    //     targetVal.getFullYear() === filterVal.getFullYear());

    let valid = true;
    switch (comparator) {
    case '=': {
      if (targetVal != filterVal) {
        valid = false;
      }
      break;
    }
    case '>': {
      if (targetVal <= filterVal) {
        valid = false;
      }
      break;
    }
    case '>=': {
      // console.log(targetVal);
      // console.log(filterVal);
      // console.log(filterVal.getDate());
      if (targetVal < filterVal) {
        valid = false;
      }
      break;
    }
    case '<': {
      if (targetVal >= filterVal) {
        valid = false;
      }
      break;
    }
    case '<=': {
      if (targetVal > filterVal) {
        valid = false;
      }
      break;
    }
    case '!=': {
      if (targetVal == filterVal) {
        valid = false;
      }
      break;
    }
    default: {
      console.error('Date comparator provided is not supported');
      break;
    }
    }
    return valid;
  }

  filterRegex(targetVal, filterVal) {
    try {
      return new RegExp(filterVal, 'i').test(targetVal);
    } catch (e) {
      console.error('Invalid regular expression');
      return true;
    }
  }

  filterCustom(targetVal, filterVal, callbackInfo) {
    if (callbackInfo !== null && typeof callbackInfo === 'object') {
      return callbackInfo.callback(targetVal, callbackInfo.callbackParameters);
    }

    return this.filterText(targetVal, filterVal);
  }

  filterText(targetVal, filterVal) {
    if (targetVal.toString().toLowerCase().indexOf(filterVal) === -1) {
      return false;
    }
    return true;
  }

  /* General search function
   * It will search for the text if the input includes that text;
   */
  search(searchText) {
    if (searchText.trim() === '') {
      this.filteredData = null;
      this.isOnFilter = false;
      this.searchText = null;
      if (this.filterObj !== null) this.filter(this.filterObj);
    } else {
      this.searchText = searchText;
      let searchTextArray = [];

      if (this.multiColumnSearch) {
        searchTextArray = searchText.split(' ');
      } else {
        searchTextArray.push(searchText);
      }
      // Mark following code for fixing #363
      // To avoid to search on a data which be searched or filtered
      // But this solution have a poor performance, because I do a filter again
      // const source = this.isOnFilter ? this.filteredData : this.data;
      const source = this.filterObj !== null ? this.filter(this.filterObj) : this.data;

      this.filteredData = source.filter( row => {
        const keys = Object.keys(row);
        let valid = false;
        // for loops are ugly, but performance matters here.
        // And you cant break from a forEach.
        // http://jsperf.com/for-vs-foreach/66
        for (let i = 0, keysLength = keys.length; i < keysLength; i++) {
          const key = keys[i];
          if (this.colInfos[key] && row[key]) {
            const { format, filterFormatted, formatExtraData, searchable } = this.colInfos[key];
            let targetVal = row[key];
            if (searchable) {
              if (filterFormatted && format) {
                targetVal = format(targetVal, row, formatExtraData);
              }
              for (let j = 0, textLength = searchTextArray.length; j < textLength; j++) {
                const filterVal = searchTextArray[j].toLowerCase();
                if (targetVal.toString().toLowerCase().indexOf(filterVal) !== -1) {
                  valid = true;
                  break;
                }
              }
            }
          }
        }
        return valid;
      });
      this.isOnFilter = true;
    }
  }

  getDataIgnoringPagination() {
    return this.getCurrentDisplayData();
  }

  get() {
    const _data = this.getCurrentDisplayData();

    if (_data.length === 0) return _data;

    if (this.remote || !this.enablePagination) {
      return _data;
    } else {
      const result = [];
      for (let i = this.pageObj.start; i <= this.pageObj.end; i++) {
        result.push(_data[i]);
        if (i + 1 === _data.length) break;
      }
      return result;
    }
  }

  getKeyField() {
    return this.keyField;
  }

  getDataNum() {
    return this.getCurrentDisplayData().length;
  }

  isChangedPage() {
    return this.pageObj.start && this.pageObj.end ? true : false;
  }

  isEmpty() {
    return (this.data.length === 0 ||
      this.data === null ||
      this.data === undefined);
  }

  getAllRowkey() {
    return this.data.map(row => {
      return row[this.keyField];
    });
  }
}
<|endoftext|>