<commit_before>var util = require('util');
var BaseTrigger = require('./baseTrigger.js').BaseTrigger;
if (typeof localStorage === "undefined" || localStorage === null) {
  var LocalStorage = require('node-localstorage').LocalStorage;
}
/*
An infobot trigger. Does not learn on its own (e.g. things need to be defined with !learn)
options:
commands = string or array of strings (optional) - what is the command for the given function?
	cmdLearn - default '!learn' - !learn X is Y
	cmdTell - default 'what is' - What is X?
	cmdLock - default '!lockword' - !lockword X
	cmdUnlock - default '!unlockword' - !unlockword X
	cmdFull - default '!wordinfo' - shows all information on command. Who changed it last, when, etc.
admin = string or Array - steamid64(s) of those allowed to lock/unlock values
userlearn = bool - are regular users allowed to make the bot learn stuff? defaults to true
command = string - command to change the message. Defaults to !status
*/

var InfobotTrigger = function() {
	InfobotTrigger.super_.apply(this, arguments);
};

util.inherits(InfobotTrigger, BaseTrigger);

var type = "InfobotTrigger";
exports.triggerType = type;
exports.create = function(name, chatBot, options) {
	var trigger = new InfobotTrigger(type, name, chatBot, options);
	trigger.options.userlearn = trigger.options.userlearn || true;
	trigger.options.cmdLearn = trigger.options.cmdLearn || "!learn";
	trigger.options.cmdTell = trigger.options.cmdTell || ["what is","who is"];
	trigger.options.cmdLock = trigger.options.cmdLock || '!lockword';
	trigger.options.cmdUnlock = trigger.options.cmdUnlock || '!unlockword';
	trigger.options.cmdInfo = trigger.options.cmdInfo || '!wordinfo';
	trigger.options.location = trigger.options.location || './bot.'+chatBot.username+'.storage/'+type+'/'+name;
	try{ //node-localstorage doesn't make parent directories. BOO. I refuse to look up how to do this properly, we'll just require mkdirp instead.
		trigger.store = new LocalStorage(trigger.options.location);
	}catch(err){
		require('mkdirp').sync(trigger.options.location);
		trigger.store = new LocalStorage(trigger.options.location);
	}
	return trigger;
};

InfobotTrigger.prototype._respondToFriendMessage = function(userId, message) {
	return this._respond(userId, userId, message);
}

// Return true if a message was sent
InfobotTrigger.prototype._respondToChatMessage = function(roomId, chatterId, message) {
	return this._respond(roomId, chatterId, message);
}

InfobotTrigger.prototype._respond = function(toId,userId,message) {
//console.log(this.options.cmdLearn + (this.options.cmdLearn==message.split(' ')[0] ? " == " : " != ") + message.split(' ')[0]);
try{
	var msg = this._stripCommand(message, this.options.cmdLearn);
	if(msg && msg.pair.length==2 && (this.options.userlearn==true || this.options.admin==userId || userId in this.options.admin)) {
		if(this.store.getItem(msg.pair[0]) && JSON.parse(this.store.getItem(msg.pair[0])).locked==true) {
			this._sendMessageAfterDelay(toId, "That factoid is locked!");
			return true;
		}
		this.store.setItem(msg.pair[0],JSON.stringify({word:msg.pair[0],definition:msg.pair[1],author:userId,time:(new Date()-0),locked:false}));
		console.log(this.store.getItem(msg.pair[0]));
		this._sendMessageAfterDelay(toId, "Learned: "+msg.pair[0]+" is "+msg.pair[1]);
		return true;
	}
	msg = this._stripCommand(message, this.options.cmdTell);
	if(msg && this.store.getItem(msg.pair[0])) {
		var factoid = this.store.getItem(msg.pair[0]);
		if(factoid) {
			factoid = JSON.parse(factoid);
			this._sendMessageAfterDelay(toId, factoid.word+" is "+factoid.definition);
			return true;
		} else return false;
	}
	msg = this._stripCommand(message, this.options.cmdLock);
	if(msg && (!this.options.admin || (this.options.admin==userId||userId in this.options.admin))) {
		var factoid = this.store.getItem(msg.pair.splice(0));
		if(factoid) {
			var factoid=JSON.parse(factoid);
			factoid.locked=true;
			this.store.setItem(factoid.word,JSON.stringify(factoid));
			this._sendMessageAfterDelay(toId, "Locked "+factoid.word);
			return true;
		} else {
			this._sendMessageAfterDelay(toId, "No such factoid");
			return true;
		}
	}
	msg = this._stripCommand(message, this.options.cmdUnlock);
	if(msg && (!this.options.admin || (this.options.admin==userId||userId in this.options.admin))) {
		var factoid = this.store.getItem(msg.pair.splice(0));
		if(factoid) {
			factoid=JSON.parse(factoid);
			factoid.locked=false;
			this.store.setItem(factoid.word,JSON.stringify(factoid));
			this._sendMessageAfterDelay(toId, "Unlocked "+factoid.word);
			return true;
		} else {
			this._sendMessageAfterDelay(toId, "No such factoid");
			return true;
		}
	}
	msg = this._stripCommand(message, this.options.cmdInfo);
	if(msg) {
		var factoid = this.store.getItem(msg.pair.splice(0));
		if(factoid) {
			factoid=JSON.parse(factoid);
			var date = new Date(factoid.time);
			var who = ((this.chatBot.steamClient.users && factoid.author in this.chatBot.steamClient.users) ? (this.chatBot.steamClient.users[factoid.author].playerName + "/"+factoid.author) : "http://steamcommunity.com/profiles/"+factoid.author);
			this._sendMessageAfterDelay(toId, factoid.word+" was last modified by " + who + " at "+date.toLocaleTimeString()+" on "+date.toDateString());
			return true;
		} else {
			this._sendMessageAfterDelay(toId, "No such factoid");
			return true;
		}
	}
	return false;
}catch(err){console.log(err.stack);}
}
InfobotTrigger.prototype._stripCommand = function(message, command){
	var that = this;
	if (command && typeof command=="string" && message && message.toLowerCase().indexOf(command.toLowerCase())==0) {
		return {message: message, params: message.split(' '), pair: message.substring(command.length + 1).split(' is ')};
	} else if(command instanceof Array) {
		for(x=0;x<command.length;x++){
			if(message.toLowerCase().indexOf(command[x].toLowerCase())==0)
				return that._stripCommand(message, command[x]);
		}
	}
	return null;
}
<commit_msg>Add \!unlearn; 'are' delimiter; and 'see X' and '<reply>' for direct replies; store things with lowecase keys<commit_after>var util = require('util');
var BaseTrigger = require('./baseTrigger.js').BaseTrigger;
if (typeof localStorage === "undefined" || localStorage === null) {
  var LocalStorage = require('node-localstorage').LocalStorage;
}
/*
An infobot trigger. Does not learn on its own (e.g. things need to be defined with !learn)
options:
commands = string or array of strings (optional) - what is the command for the given function?
	cmdLearn - default '!learn' - !learn X is Y
	cmdTell - default 'what is' - What is X?
	cmdLock - default '!lockword' - !lockword X
	cmdUnlock - default '!unlockword' - !unlockword X
	cmdFull - default '!wordinfo' - shows all information on command. Who changed it last, when, etc.
admin = string or Array - steamid64(s) of those allowed to lock/unlock values
userlearn = bool - are regular users allowed to make the bot learn stuff? defaults to true
command = string - command to change the message. Defaults to !status
*/

var InfobotTrigger = function() {
	InfobotTrigger.super_.apply(this, arguments);
};

util.inherits(InfobotTrigger, BaseTrigger);

var type = "InfobotTrigger";
exports.triggerType = type;
exports.create = function(name, chatBot, options) {
	var trigger = new InfobotTrigger(type, name, chatBot, options);
	trigger.options.userlearn = options.hasOwnProperty('userlearn') ? options.userlearn : true;
	trigger.options.cmdDelete = trigger.options.cmdDelete || "!unlearn";
	trigger.options.cmdLearn = trigger.options.cmdLearn || "!learn";
	trigger.options.cmdTell = trigger.options.cmdTell || ["what is","who is"];
	trigger.options.cmdLock = trigger.options.cmdLock || '!lockword';
	trigger.options.cmdUnlock = trigger.options.cmdUnlock || '!unlockword';
	trigger.options.cmdInfo = trigger.options.cmdInfo || '!wordinfo';
	trigger.options.location = options.location         || (process.cwd()+"/"+chatBot.username + '/'+type+'/'+name);
	try{ //node-localstorage doesn't make parent directories. BOO. I refuse to look up how to do this properly, we'll just require mkdirp instead.
		trigger.store = new LocalStorage(trigger.options.location);
	}catch(err){
		require('mkdirp').sync(trigger.options.location);
		trigger.store = new LocalStorage(trigger.options.location);
	}
	return trigger;
};

InfobotTrigger.prototype._respondToFriendMessage = function(userId, message) {
	return this._respond(userId, userId, message);
}

// Return true if a message was sent
InfobotTrigger.prototype._respondToChatMessage = function(roomId, chatterId, message) {
	return this._respond(roomId, chatterId, message);
}

InfobotTrigger.prototype._respond = function(toId,userId,message,options) {
	var msg = this._stripCommand(message, this.options.cmdLearn);
	if(msg && msg.pair.length==2 && (this.options.userlearn==true || this.options.admin.indexOf(userId) > -1)) {
		if(this.store.getItem(msg.pair[0].toLowerCase()) && JSON.parse(this.store.getItem(msg.pair[0].toLowerCase())).locked==true) {
			this._sendMessageAfterDelay(toId, "That factoid is locked!");
			return true;
		}
		var factoid = {
			word: msg.pair[0],
			definition: msg.pair[1],
			delim: msg.delim,
			author: userOd,
			time: (new Date()-0),
			locked: false
		}
		this.store.setItem(factoid.word.toLowerCase(),JSON.stringify(factoid));
		this._sendMessageAfterDelay(toId, "Learned: "+msg.pair[0]+msg.delim+msg.pair[1]);
		return true;
	}
	var msg = this._stripCommand(message, this.options.cmdDelete);
	if(msg && (this.options.userlearn==true || this.options.admin.indexOf(userId) > -1)) {
		if(this.store.getItem(msg.pair[0].toLowerCase()) && JSON.parse(this.store.getItem(msg.pair[0].toLowerCase())).locked==true) {
			this._sendMessageAfterDelay(toId, "That factoid is locked!");
			return true;
		}
		this.store.removeItem(msg.pair[0].toLowerCase());
		this._sendMessageAfterDelay(toId, "Removed: "+msg.pair[0]);
		return true;
	}
	msg = this._stripCommand(message, this.options.cmdTell);
	if((msg && this.store.getItem(msg.pair[0].toLowerCase()))||(options && options.see)) {
		if(options.see) var factoid = this.store.getItem(options.see);
		else var factoid = this.store.getItem(msg.pair[0].toLowerCase());
		if(factoid) {
			factoid = JSON.parse(factoid);
			if(!factoid.delim) factoid.delim = ' is ';
			if(factoid.delim==' is <reply>') { factoid.word=""; factoid.delim=""; }
			if(factoid.delim==' is see ') {
				return that._respond(toId,userId,factoid.message,{see:factoid.definition});
			} else {
				this._sendMessageAfterDelay(toId, factoid.word+factoid.delim+factoid.definition);
			} return true;
		} else return false;
	}
	msg = this._stripCommand(message, this.options.cmdLock);
	if(msg && (!this.options.admin || (this.options.admin.indexOf(userId) > -1))) {
		var factoid = this.store.getItem(msg.pair.splice(0)[0].toLowerCase());
		if(factoid) {
			var factoid=JSON.parse(factoid);
			factoid.locked=true;
			this.store.setItem(factoid.word,JSON.stringify(factoid));
			this._sendMessageAfterDelay(toId, "Locked "+factoid.word);
			return true;
		} else {
			this._sendMessageAfterDelay(toId, "No such factoid");
			return true;
		}
	}
	msg = this._stripCommand(message, this.options.cmdUnlock);
	if(msg && (!this.options.admin || (this.options.admin.indexOf(userId) > -1))) {
		var factoid = this.store.getItem(msg.pair.splice(0)[0].toLowerCase());
		if(factoid) {
			factoid=JSON.parse(factoid);
			factoid.locked=false;
			this.store.setItem(factoid.word,JSON.stringify(factoid));
			this._sendMessageAfterDelay(toId, "Unlocked "+factoid.word);
			return true;
		} else {
			this._sendMessageAfterDelay(toId, "No such factoid");
			return true;
		}
	}
	msg = this._stripCommand(message, this.options.cmdInfo);
	if(msg) {
		var factoid = this.store.getItem(msg.pair.splice(0)[0].toLowerCase());
		if(factoid) {
			factoid=JSON.parse(factoid);
			var date = new Date(factoid.time);
			var who = ((this.chatBot.steamClient.users && factoid.author in this.chatBot.steamClient.users) ? (this.chatBot.steamClient.users[factoid.author].playerName + "/"+factoid.author) : "http://steamcommunity.com/profiles/"+factoid.author);
			this._sendMessageAfterDelay(toId, factoid.word+" was last modified by " + who + " at "+date.toLocaleTimeString()+" on "+date.toDateString());
			return true;
		} else {
			this._sendMessageAfterDelay(toId, "No such factoid");
			return true;
		}
	}
	return false;
//}catch(err){console.log(err.stack);}
}
InfobotTrigger.prototype._stripCommand = function(msg, command){
	var message = msg;
	var that = this;
	if (command && typeof command=="string" && message && message.toLowerCase().indexOf(command.toLowerCase())==0) {
		if(message[message.length-1]==='?') message = message.substring(0,message.length-1);
		var obj = {message: message,params: message.split(' '),delim:' is <reply>'};
		var pair = message.substring(command.length+1).split(' is <reply>');
		if(pair.length==1) { pair = message.substring(command.length+1).split(' is see'); obj.delim=' is see '; }
		if(pair.length==1) { pair = message.substring(command.length+1).split(' is '); obj.delim=' is '; }
		if(pair.length==1) { pair = message.substring(command.length+1).split(' are '); obj.delim=' are '; }
		obj.pair = [pair.splice(0,1)[0],pair.join(obj.delim)];
		return obj;
	} else if(command instanceof Array) {
		if(message[message.length-1]==='?') message = message.substring(0,message.length-1);
		for(x=0;x<command.length;x++){
			if(message.toLowerCase().indexOf(command[x].toLowerCase())==0)
				return that._stripCommand(message, command[x]);
		}
	}
	return null;
}
<|endoftext|>


<commit_before>'use strict';

angular
.module('report-editor')
.controller('ConceptOverviewCtrl', function($scope, $state, $modal, $location, ConceptIsStillReferencedError){

    $scope.error = undefined;
    $scope.conceptCopy = angular.copy($scope.concept);
    $scope.isRootElementInPresentation = $scope.report.isRootElement('Presentation', $scope.concept.Name);

    $scope.updateConcept = function(){
        $scope.error = undefined;
        if(!angular.equals($scope.conceptCopy, $scope.concept)){
            try {
                $scope.report.updateConcept($scope.conceptCopy.Name,$scope.conceptCopy.Label,$scope.conceptCopy.IsAbstract);

                // as long as we don't have individual labels for elements we update all of them
                var elementIds = $scope.report.findInTree('Presentation', $scope.concept.Name);
                angular.forEach(
                    elementIds,
                    function(id){
                        var element = $scope.report.getElementFromTree('Presentation', id);
                        if(element !== undefined && element !== null){
                            element.Label = $scope.conceptCopy.Label;
                        }
                    }
                );

                if($scope.conceptCopy.IsAbstract !== $scope.concept.IsAbstract){
                    $scope.loadPresentationTree();
                }
                $scope.conceptCopy = angular.copy($scope.concept);
            } catch (e) {
                $scope.error =
                    {
                        'title': 'Updating concept failed',
                        'message': e.message
                    };
                $scope.conceptCopy = angular.copy($scope.concept);
            }
        }
    };

    var element;
    var initElement = function(){
        element = $scope.report.createNewElement($scope.concept);
        $scope.element = [angular.copy(element)];
    };

    initElement();

    $scope.$watch(
        function(){ return $location.search(); },
        function(search){
            if(search.action === 'addElement') {
                $scope.report.addElement('Presentation', search.parent === 'undefined' ? undefined : search.parent, element, parseInt(search.offset, 10));
            }
        }
    );

    $scope.elementOptions = {
        accept: function(){
            return false;
        },
        dropped: function(event){
            if(event.source.nodesScope !== event.dest.nodesScope) {
                if(event.dest.nodesScope.$nodeScope !== undefined && event.dest.nodesScope.$nodeScope !== null) {
                    $scope.report.addElement('Presentation', event.dest.nodesScope.$nodeScope.$modelValue.Id, element, event.dest.index);
                } else {
                    // dropped as root -> disabled right now in accept of taxonomy.js
                    $scope.report.addElement('Presentation', undefined, element, event.dest.index);
                }
                initElement();
                $scope.loadPresentationTree();
            }
        }
    };

    $scope.refs = $scope.report.findInTree('Presentation', $scope.concept.Name);

    $scope.deleteConcept = function(){
        try {
            $scope.report.removeConcept($scope.concept.Name);
            $state.go('report.taxonomy.concepts');
        } catch(e) {
            if(e instanceof ConceptIsStillReferencedError) {
                $modal.open({
                    controller: 'DeleteConceptCtrl',
                    templateUrl: '/report/taxonomy/concept/overview/delete-concept.html',
                    resolve: {
                        report: function() {
                            return $scope.report;
                        },
                        concept: function(){
                            return $scope.concept;
                        },
                        references: function() {
                            return e.references;
                        },
                        dependentRules: function() {
                            var rules = {
                                Computing: [],
                                Validating: []
                            };
                            for (var i in e.references.Rules.Dependent){
                                if(e.references.Rules.Dependent.hasOwnProperty(i)){
                                    var id = e.references.Rules.Dependent[i];
                                    var rule = $scope.report.getRule(id);
                                    if(rule.Type === 'xbrl28:validation'){
                                        rules.Validating.push(rule);
                                    } else {
                                        rules.Computing.push(rule);
                                    }
                                }
                            }
                            return rules;
                        }
                    }
                }).result.then(function(result){
                    if(result) {
                        $scope.report.removeConcept($scope.concept.Name, true /*force*/);
                        $scope.loadPresentationTree();
                        $state.go('report.taxonomy.concepts');
                    }
                });
            }
        }
    };
})
.controller('DeleteConceptCtrl', function($scope, $modalInstance, report, concept, references, dependentRules){
    $scope.concept = concept;
    $scope.references = references;
    $scope.dependentRules = dependentRules;

    $scope.confirm = function(){
        $modalInstance.close(true);
    };

    $scope.cancel = function(){
        $modalInstance.close();
    };
});
<commit_msg>extended addElement action to work with parent<commit_after>'use strict';

angular
.module('report-editor')
.controller('ConceptOverviewCtrl', function($scope, $state, $modal, $location, ConceptIsStillReferencedError){

    $scope.error = undefined;
    $scope.conceptCopy = angular.copy($scope.concept);
    $scope.isRootElementInPresentation = $scope.report.isRootElement('Presentation', $scope.concept.Name);

    $scope.updateConcept = function(){
        $scope.error = undefined;
        if(!angular.equals($scope.conceptCopy, $scope.concept)){
            try {
                $scope.report.updateConcept($scope.conceptCopy.Name,$scope.conceptCopy.Label,$scope.conceptCopy.IsAbstract);

                // as long as we don't have individual labels for elements we update all of them
                var elementIds = $scope.report.findInTree('Presentation', $scope.concept.Name);
                angular.forEach(
                    elementIds,
                    function(id){
                        var element = $scope.report.getElementFromTree('Presentation', id);
                        if(element !== undefined && element !== null){
                            element.Label = $scope.conceptCopy.Label;
                        }
                    }
                );

                if($scope.conceptCopy.IsAbstract !== $scope.concept.IsAbstract){
                    $scope.loadPresentationTree();
                }
                $scope.conceptCopy = angular.copy($scope.concept);
            } catch (e) {
                $scope.error =
                    {
                        'title': 'Updating concept failed',
                        'message': e.message
                    };
                $scope.conceptCopy = angular.copy($scope.concept);
            }
        }
    };

    var element;
    var initElement = function(){
        element = $scope.report.createNewElement($scope.concept);
        $scope.element = [angular.copy(element)];
    };

    initElement();

    $scope.$watch(
        function(){ return $location.search(); },
        function(search){
            if(search.action === 'addElement') {
                var parentId;
                if(search.parent !== 'undefined'){
                    var parentIds = $scope.report.findInTree('Presentation', search.parent);
                    parentId = parentIds[0];
                }
                $scope.report.addElement('Presentation', parentId, element, parseInt(search.offset, 10));
            }
        }
    );

    $scope.elementOptions = {
        accept: function(){
            return false;
        },
        dropped: function(event){
            if(event.source.nodesScope !== event.dest.nodesScope) {
                if(event.dest.nodesScope.$nodeScope !== undefined && event.dest.nodesScope.$nodeScope !== null) {
                    $scope.report.addElement('Presentation', event.dest.nodesScope.$nodeScope.$modelValue.Id, element, event.dest.index);
                } else {
                    // dropped as root -> disabled right now in accept of taxonomy.js
                    $scope.report.addElement('Presentation', undefined, element, event.dest.index);
                }
                initElement();
                $scope.loadPresentationTree();
            }
        }
    };

    $scope.refs = $scope.report.findInTree('Presentation', $scope.concept.Name);

    $scope.deleteConcept = function(){
        try {
            $scope.report.removeConcept($scope.concept.Name);
            $state.go('report.taxonomy.concepts');
        } catch(e) {
            if(e instanceof ConceptIsStillReferencedError) {
                $modal.open({
                    controller: 'DeleteConceptCtrl',
                    templateUrl: '/report/taxonomy/concept/overview/delete-concept.html',
                    resolve: {
                        report: function() {
                            return $scope.report;
                        },
                        concept: function(){
                            return $scope.concept;
                        },
                        references: function() {
                            return e.references;
                        },
                        dependentRules: function() {
                            var rules = {
                                Computing: [],
                                Validating: []
                            };
                            for (var i in e.references.Rules.Dependent){
                                if(e.references.Rules.Dependent.hasOwnProperty(i)){
                                    var id = e.references.Rules.Dependent[i];
                                    var rule = $scope.report.getRule(id);
                                    if(rule.Type === 'xbrl28:validation'){
                                        rules.Validating.push(rule);
                                    } else {
                                        rules.Computing.push(rule);
                                    }
                                }
                            }
                            return rules;
                        }
                    }
                }).result.then(function(result){
                    if(result) {
                        $scope.report.removeConcept($scope.concept.Name, true /*force*/);
                        $scope.loadPresentationTree();
                        $state.go('report.taxonomy.concepts');
                    }
                });
            }
        }
    };
})
.controller('DeleteConceptCtrl', function($scope, $modalInstance, report, concept, references, dependentRules){
    $scope.concept = concept;
    $scope.references = references;
    $scope.dependentRules = dependentRules;

    $scope.confirm = function(){
        $modalInstance.close(true);
    };

    $scope.cancel = function(){
        $modalInstance.close();
    };
});
<|endoftext|>


<commit_before>/**
 * @module util/named-group-regexp
 */
'use strict';

const pattern = [
	// Capture group start
	'\\(\\?',
	// Capture group name begins either `P<`, `<` or `'`
	'(?:P<|<|\')',
	// Everything up to the next `>`` or `'` (depending) will be the capture group name
	'([^>\']+)',
	// Capture group end
	'[>\']',
	// Get everything up to the end of the capture group: this is the RegExp used
	// when matching URLs to this route, which we can use for validation purposes.
	'([^\\)]*(\))?)\??)',
	// Capture group end
	'\\)',
].join( '' );

module.exports = {
	/**
	 * String representation of the exported Regular Expression; we construct this
	 * RegExp from a string to enable more detailed annotation and permutation
	 *
	 * @prop {String} pattern
	 */
	pattern: pattern,

	/**
	 * Regular Expression to identify a capture group in PCRE formats
	 * `(?<name>regex)`, `(?'name'regex)` or `(?P<name>regex)` (see
	 * regular-expressions.info/refext.html)
	 *
	 * @prop {RegExp} namedGroupRE
	 */
	namedGroupRE: new RegExp( pattern ),
};
<commit_msg>Fixed some copy an paste mistakes<commit_after>/**
 * @module util/named-group-regexp
 */
'use strict';

const pattern = [
	// Capture group start
	'\\(\\?',
	// Capture group name begins either `P<`, `<` or `'`
	'(?:P<|<|\')',
	// Everything up to the next `>`` or `'` (depending) will be the capture group name
	'([^>\']+)',
	// Capture group end
	'[>\']',
	// Get everything up to the end of the capture group: this is the RegExp used
	// when matching URLs to this route, which we can use for validation purposes.
	'([^\\)]*(\\))?)\\??',
	// Capture group end
	'\\)',
].join( '' );

module.exports = {
	/**
	 * String representation of the exported Regular Expression; we construct this
	 * RegExp from a string to enable more detailed annotation and permutation
	 *
	 * @prop {String} pattern
	 */
	pattern: pattern,

	/**
	 * Regular Expression to identify a capture group in PCRE formats
	 * `(?<name>regex)`, `(?'name'regex)` or `(?P<name>regex)` (see
	 * regular-expressions.info/refext.html)
	 *
	 * @prop {RegExp} namedGroupRE
	 */
	namedGroupRE: new RegExp( pattern ),
};
<|endoftext|>


<commit_before>'use strict';

/** @typedef {import('postcss').Rule} Rule */
/** @typedef {import('postcss').AtRule} AtRule */

/**
 * @param {Rule | AtRule} statement
 * @param {{
 * 	noRawBefore?: boolean
 * }} options
 *
 * @returns {string}
 */
module.exports = function (statement, options = {}) {
	let result = '';
	/** @type {Rule | undefined} */
	let rule; /*?: postcss$rule*/
	/** @type {AtRule | undefined} */
	let atRule; /*?: postcss$atRule*/

	if (statement.type === 'rule') {
		rule = statement;
	}

	if (statement.type === 'atrule') {
		atRule = statement;
	}

	if (!rule && !atRule) {
		return result;
	}

	const before = statement.raws.before || '';

	if (!options.noRawBefore) {
		result += before;
	}

	if (rule) {
		result += rule.selector;
	}

	if (atRule) {
		result += `@${atRule.name}${atRule.raws.afterName || ''}${atRule.params}`;
	}

	const between = statement.raws.between;

	if (between !== undefined) {
		result += between;
	}

	return result;
};
<commit_msg>Refactor `lib/utils/beforeBlockString.js` (#5425)<commit_after>'use strict';

/** @typedef {import('postcss').Rule} Rule */
/** @typedef {import('postcss').AtRule} AtRule */

/**
 * @param {Rule | AtRule} statement
 * @returns {string}
 */
module.exports = function beforeBlockString(statement, { noRawBefore } = { noRawBefore: false }) {
	let result = '';

	const before = statement.raws.before || '';

	if (!noRawBefore) {
		result += before;
	}

	switch (statement.type) {
		case 'rule':
			result += statement.selector;
			break;
		case 'atrule':
			result += `@${statement.name}${statement.raws.afterName || ''}${statement.params}`;
			break;
		default:
			return '';
	}

	result += statement.raws.between || '';

	return result;
};
<|endoftext|>


<commit_before>var util = require('util'),
    winston = require('../../winston'),
    http = require('http'),
    https = require('https'),
    Stream = require('stream').Stream,
    Transport = require('./transport').Transport;

//
// ### function Http (options)
// #### @options {Object} Options for this instance.
// Constructor function for the Http transport object responsible
// for persisting log messages and metadata to a terminal or TTY.
//
var Http = exports.Http = function (options) {
  Transport.call(this, options);
  options = options || {};

  this.name = 'http';
  this.ssl = !!options.ssl;
  this.host = options.host || 'localhost';
  this.port = options.port;
  this.auth = options.auth;
  this.path = options.path || '';

  if (!this.port) {
    this.port = this.ssl ? 443 : 80;
  }
};

util.inherits(Http, winston.Transport);

//
// Expose the name of this Transport on the prototype
//
Http.prototype.name = 'http';

//
// ### function _request (options, callback)
// #### @callback {function} Continuation to respond to when complete.
// Make a request to a winstond server or any http server which can
// handle json-rpc.
//
Http.prototype._request = function (options, callback) {
  options = options || {};

  var auth = options.auth || this.auth,
      path = options.path || this.path || '';

  delete options.auth;
  delete options.path;

  // Prepare options for outgoing HTTP request
  req = (this.ssl ? https : http).request({
    host: this.host,
    port: this.port,
    path: path.replace(/^\//, ''),
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    auth: (auth) ? auth.username + ':' + auth.password : ''
  });

  req.end(new Buffer(JSON.stringify(options), 'utf8'));

  req.on('error', callback);
  req.on('response', function (res) {
    res.on('end', function () {
      callback(null, res);
    });
  });
};

//
// ### function log (level, msg, [meta], callback)
// #### @level {string} Level at which to log the message.
// #### @msg {string} Message to log
// #### @meta {Object} **Optional** Additional metadata to attach
// #### @callback {function} Continuation to respond to when complete.
// Core logging method exposed to Winston. Metadata is optional.
//
Http.prototype.log = function (level, msg, meta, callback) {
  var self = this;

  if (typeof meta === 'function') {
    callback = meta;
    meta = {};
  }

  var options = {
    method: 'collect',
    params: {
      level: level,
      message: msg,
      meta: meta
    }
  };

  if (meta) {
    if (meta.path) {
      options.path = meta.path;
      delete meta.path;
    }

    if (meta.auth) {
      options.auth = meta.auth;
      delete meta.auth;
    }
  }

  this._request(options, function (err, res) {
    if (res && res.statusCode !== 200) {
      err = new Error('HTTP Status Code: ' + res.statusCode);
    }

    if (err) return callback(err);

    // TODO: emit 'logged' correctly,
    // keep track of pending logs.
    self.emit('logged');

    if (callback) callback(null, true);
  });
};

//
// ### function query (options, callback)
// #### @options {Object} Loggly-like query options for this instance.
// #### @callback {function} Continuation to respond to when complete.
// Query the transport. Options object is optional.
//
Http.prototype.query = function (options, callback) {
  if (typeof options === 'function') {
    callback = options;
    options = {};
  }

  var self = this,
      options = this.normalizeQuery(options);

  options = {
    method: 'query',
    params: options
  };

  if (options.params.path) {
    options.path = options.params.path;
    delete options.params.path;
  }

  if (options.params.auth) {
    options.auth = options.params.auth;
    delete options.params.auth;
  }

  this._request(options, function (err, res, body) {
    if (res && res.statusCode !== 200) {
      err = new Error('HTTP Status Code: ' + res.statusCode);
    }

    if (err) return callback(err);

    if (typeof body === 'string') {
      try {
        body = JSON.parse(body);
      } catch (e) {
        return callback(e);
      }
    }

    callback(null, body);
  });
};

//
// ### function stream (options)
// #### @options {Object} Stream options for this instance.
// Returns a log stream for this transport. Options object is optional.
//
Http.prototype.stream = function (options) {
  var self = this,
      options = options || {},
      stream = new Stream,
      req,
      buff;

  stream.destroy = function () {
    req.destroy();
  };

  options = {
    method: 'stream',
    params: options
  };

  if (options.params.path) {
    options.path = options.params.path;
    delete options.params.path;
  }

  if (options.params.auth) {
    options.auth = options.params.auth;
    delete options.params.auth;
  }

  req = this._request(options);
  buff = '';

  req.on('data', function (data) {
    var data = (buff + data).split(/\n+/),
        l = data.length - 1,
        i = 0;

    for (; i < l; i++) {
      try {
        stream.emit('log', JSON.parse(data[i]));
      } catch (e) {
        stream.emit('error', e);
      }
    }

    buff = data[l];
  });

  req.on('error', function (err) {
    stream.emit('error', err);
  });

  return stream;
};
<commit_msg>[fix] Call `res.resume()` in HttpTransport to get around known issues in streams2.<commit_after>var util = require('util'),
    winston = require('../../winston'),
    http = require('http'),
    https = require('https'),
    Stream = require('stream').Stream,
    Transport = require('./transport').Transport;

//
// ### function Http (options)
// #### @options {Object} Options for this instance.
// Constructor function for the Http transport object responsible
// for persisting log messages and metadata to a terminal or TTY.
//
var Http = exports.Http = function (options) {
  Transport.call(this, options);
  options = options || {};

  this.name = 'http';
  this.ssl = !!options.ssl;
  this.host = options.host || 'localhost';
  this.port = options.port;
  this.auth = options.auth;
  this.path = options.path || '';

  if (!this.port) {
    this.port = this.ssl ? 443 : 80;
  }
};

util.inherits(Http, winston.Transport);

//
// Expose the name of this Transport on the prototype
//
Http.prototype.name = 'http';

//
// ### function _request (options, callback)
// #### @callback {function} Continuation to respond to when complete.
// Make a request to a winstond server or any http server which can
// handle json-rpc.
//
Http.prototype._request = function (options, callback) {
  options = options || {};

  var auth = options.auth || this.auth,
      path = options.path || this.path || '';

  delete options.auth;
  delete options.path;

  // Prepare options for outgoing HTTP request
  req = (this.ssl ? https : http).request({
    host: this.host,
    port: this.port,
    path: '/' + path.replace(/^\//, ''),
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    auth: (auth) ? auth.username + ':' + auth.password : ''
  });

  req.on('error', callback);
  req.on('response', function (res) {
    res.on('end', function () {
      callback(null, res);
    });

    res.resume();
  });

  req.end(new Buffer(JSON.stringify(options), 'utf8'));
};

//
// ### function log (level, msg, [meta], callback)
// #### @level {string} Level at which to log the message.
// #### @msg {string} Message to log
// #### @meta {Object} **Optional** Additional metadata to attach
// #### @callback {function} Continuation to respond to when complete.
// Core logging method exposed to Winston. Metadata is optional.
//
Http.prototype.log = function (level, msg, meta, callback) {
  var self = this;

  if (typeof meta === 'function') {
    callback = meta;
    meta = {};
  }

  var options = {
    method: 'collect',
    params: {
      level: level,
      message: msg,
      meta: meta
    }
  };

  if (meta) {
    if (meta.path) {
      options.path = meta.path;
      delete meta.path;
    }

    if (meta.auth) {
      options.auth = meta.auth;
      delete meta.auth;
    }
  }

  this._request(options, function (err, res) {
    if (res && res.statusCode !== 200) {
      err = new Error('HTTP Status Code: ' + res.statusCode);
    }

    if (err) return callback(err);

    // TODO: emit 'logged' correctly,
    // keep track of pending logs.
    self.emit('logged');

    if (callback) callback(null, true);
  });
};

//
// ### function query (options, callback)
// #### @options {Object} Loggly-like query options for this instance.
// #### @callback {function} Continuation to respond to when complete.
// Query the transport. Options object is optional.
//
Http.prototype.query = function (options, callback) {
  if (typeof options === 'function') {
    callback = options;
    options = {};
  }

  var self = this,
      options = this.normalizeQuery(options);

  options = {
    method: 'query',
    params: options
  };

  if (options.params.path) {
    options.path = options.params.path;
    delete options.params.path;
  }

  if (options.params.auth) {
    options.auth = options.params.auth;
    delete options.params.auth;
  }

  this._request(options, function (err, res, body) {
    if (res && res.statusCode !== 200) {
      err = new Error('HTTP Status Code: ' + res.statusCode);
    }

    if (err) return callback(err);

    if (typeof body === 'string') {
      try {
        body = JSON.parse(body);
      } catch (e) {
        return callback(e);
      }
    }

    callback(null, body);
  });
};

//
// ### function stream (options)
// #### @options {Object} Stream options for this instance.
// Returns a log stream for this transport. Options object is optional.
//
Http.prototype.stream = function (options) {
  var self = this,
      options = options || {},
      stream = new Stream,
      req,
      buff;

  stream.destroy = function () {
    req.destroy();
  };

  options = {
    method: 'stream',
    params: options
  };

  if (options.params.path) {
    options.path = options.params.path;
    delete options.params.path;
  }

  if (options.params.auth) {
    options.auth = options.params.auth;
    delete options.params.auth;
  }

  req = this._request(options);
  buff = '';

  req.on('data', function (data) {
    var data = (buff + data).split(/\n+/),
        l = data.length - 1,
        i = 0;

    for (; i < l; i++) {
      try {
        stream.emit('log', JSON.parse(data[i]));
      } catch (e) {
        stream.emit('error', e);
      }
    }

    buff = data[l];
  });

  req.on('error', function (err) {
    stream.emit('error', err);
  });

  return stream;
};
<|endoftext|>


<commit_before>/*
 Copyright (c) 2013-2017 by Tawi Jordan - ๖ۣۜĐJ - ɴᴇᴏɴ - TFL

 Permission to use this software for any purpose without fee is hereby granted, provided
 that the above copyright notice and this permission notice appear in all copies.

 Permission to copy and/or edit this software or parts of it for any purpose is permitted,
 provided that the following points are followed.
 - The above copyright notice and this permission notice appear in all copies
 - Within two (2) days after modification is proven working, any modifications are send back
   to the original authors to be inspected with the goal of inclusion in the official software
 - Any edited version are only test versions and not permitted to be run as a final product
 - Any edited version aren't to be distributed
 - Any edited version have the prerelease version set to something that can be distinguished
   from a version used in the original software

 TERMS OF REPRODUCTION USE

 Failure to follow these terms will result in me getting very angry at you
 and having your software tweaked or removed if possible. Either way, you're
 still an idiot for not following such a basic rule.
 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS
 BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
 RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

 * @Author:    Tawi Jordan - ๖ۣۜĐJ - ɴᴇᴏɴ - TFL (Member. on Plug.dj)

 * [NOTE]: THERE IS NOTHING HERE FOR YOU! COPYING ANY PART OF THIS SCRIPT AND USING "IT" or "AS" (yours)
 *         WELL SERIOUSLY GET YOU TO FACE THE CONSEQUENCES!
 */

var path = 'http://pastebin.com/raw.php?i=';

function message(contents) {
        var msg = '
Plugwoot™  ' + contents + '
';
        $('#chat-messages').append(msg);
}

var scriptFail = window.setTimeout(function() {
  message('Oops! An Error Occurred');
  }, 2000);

$.getScript(path/* + 'wwm3cyi8'*/, function() {
 message("Alpha version "+ PlugStation.version +" is now available!");
 console.log("Plugwoot Alpha "+ PlugStation.version +" - Created by ๖ۣۜĐل - ɴᴇᴏɴ - TFL");
 window.clearTimeout(scriptFail);
 });
<commit_msg>Update Alpha.js<commit_after>/*
 Copyright (c) 2013-2017 by Tawi Jordan - ๖ۣۜĐJ - ɴᴇᴏɴ - TFL

 Permission to use this software for any purpose without fee is hereby granted, provided
 that the above copyright notice and this permission notice appear in all copies.

 Permission to copy and/or edit this software or parts of it for any purpose is permitted,
 provided that the following points are followed.
 - The above copyright notice and this permission notice appear in all copies
 - Within two (2) days after modification is proven working, any modifications are send back
   to the original authors to be inspected with the goal of inclusion in the official software
 - Any edited version are only test versions and not permitted to be run as a final product
 - Any edited version aren't to be distributed
 - Any edited version have the prerelease version set to something that can be distinguished
   from a version used in the original software

 TERMS OF REPRODUCTION USE

 Failure to follow these terms will result in me getting very angry at you
 and having your software tweaked or removed if possible. Either way, you're
 still an idiot for not following such a basic rule.
 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS
 BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
 RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

 * @Author:    Tawi Jordan - ๖ۣۜĐJ - ɴᴇᴏɴ - TFL (Member. on Plug.dj)

 * [NOTE]: THERE IS NOTHING HERE FOR YOU! COPYING ANY PART OF THIS SCRIPT AND USING "IT" or "AS" (yours)
 *         WELL SERIOUSLY GET YOU TO FACE THE CONSEQUENCES!
 */

var path = 'http://pastebin.com/raw.php?i=';

function message(contents) {
        var msg = '
Plugwoot™  ' + contents + '
';
        $('#chat-messages').append(msg);
}

var scriptFail = window.setTimeout(function() {
  //message('Oops! An Error Occurred');
  message('Sorry plugwoot alpha is updating! :(');
  }, 2000);

$.getScript(path/* + 'wwm3cyi8'*/, function() {
 message("Alpha version "+ PlugStation.version +" is now available!");
 console.log("Plugwoot Alpha "+ PlugStation.version +" - Created by ๖ۣۜĐل - ɴᴇᴏɴ - TFL");
 window.clearTimeout(scriptFail);
 });
<|endoftext|>


<commit_before>var mongodb = require('mongodb'),
    MongoClient = require('mongodb').MongoClient,
    Db = require('mongodb').Db,
    Connection = require('mongodb').Connection,
    Server = require('mongodb').Server,
    BSON = require('mongodb').BSON,
    ObjectID = require('mongodb').ObjectID;

BookProvider = function(uri) {

  var that = this;
  mongodb.MongoClient.connect(uri, { server: { auto_reconnect: true } }, function (error, database) {
    if (error) console.log(error);
    that.db = database;
  });

  /* TO DEVELOP LOCALLY
      uncomment the following two lines
      comment out the beginning of this function
  */

  //this.db = new Db('books', new Server('localhost', 27017, {safe: false}, {auto_reconnect: true}, {}));
  //this.db.open(function(){});
};

//initialize info values
BookProvider.prototype.init = function(info, callback) {
  this.getCollection(function(error, book_collection) {
    if ( error ) callback(error);
    else {
      book_collection.insert({info:info}, function(error){
        if (error) callback(error);
        else callback(null);
      });
    }
  });
};

//delete book
BookProvider.prototype.delete = function(bookId, callback) {
  this.getCollection(function(error, book_collection) {
    if(error) callback(error);
    else {
      book_collection.remove(
      {_id: book_collection.db.bson_serializer.ObjectID.createFromHexString(bookId)},
      function(error, book){
        if(error) callback(error);
        else callback(null, book)
      });
    }
  });
};

BookProvider.prototype.getCollection = function(callback) {
  this.db.collection('bks', function(error, book_collection) {
    if( error ) callback(error);
    else callback(null, book_collection);
  });
};

//find all books
BookProvider.prototype.findAll = function(callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error);
      else {
        book_collection.find().toArray(function(error, results) {
          if( error ) callback(error);
          else callback(null, results);
        });
      }
    });
};

//find recently edited books
BookProvider.prototype.findRecentEdits = function(callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error);
      else {
        book_collection.find().sort({last_edit:-1}).limit(8).toArray(function(error, results) {
          if( error ) callback(error);
          else callback(null, results);
        });
      }
    });
};
//find recently edited books
BookProvider.prototype.findRecentLogs = function(callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error);
      else {
        book_collection.find().sort({created_at:-1}).limit(8).toArray(function(error, results) {
          if( error ) callback(error);
          else callback(null, results);
        });
      }
    });
};

//find subset of books with tag
BookProvider.prototype.findTag = function(tag, callback) {
  this.getCollection(function(error, book_collection) {
    if(error) callback(error);
    else {
      book_collection.find({tags:tag}).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
    }
  });
};

//search all books
BookProvider.prototype.search = function(query, callback) {
  var name = query._field;
  var value = query._query;
  var dbQuery = {};
  dbQuery[name] = {$regex:value, $options:"-i"};
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

//search books and return subset based on a feild and query (_ref)
BookProvider.prototype.searchRefs = function(query, callback) {
  var name = query._field;
  var value = query._ref;
  var dbQuery = {};
  if (query._refs != undefined) {
    var exclude = query._refs;
    if (exclude.constructor == Array) {
      for (var i = 0; i < exclude.length; i++) {
        var obj = new ObjectID(exclude[i]);
        exclude[i] = obj;
      }
      dbQuery = {_id:{$nin:exclude}};
    } else {
      exclude = new ObjectID(exclude);
      dbQuery = {_id:{$ne:exclude}};
    }
  }
  dbQuery[name] = {$regex:value, $options:"-i"};
  console.log(JSON.stringify(dbQuery));
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

//search books and return subset based on a feild and query (_ref)
BookProvider.prototype.browseRefs = function(query, callback) {
  var dbQuery = {};
  var f = query._field;
  var q = query[query._field];
  if (f == "_fields") {
      dbQuery[query[query._field]] = {$exists:true};
  } else if (query._field == "_types") {
    dbQuery = {type:q};
  } else if (f == "_tags") {
    dbQuery = {tags:{$in:[q]}};
  }
  if (query._refs != undefined) {
    var exclude = query._refs;
    if (exclude.constructor == Array) {
      for (var i = 0; i < exclude.length; i++) {
        var obj = new ObjectID(exclude[i]);
        exclude[i] = obj;
      }
      dbQuery = {_id:{$nin:exclude}};
    } else {
      exclude = new ObjectID(exclude);
      dbQuery = {_id:{$ne:exclude}};
    }
  }
  console.log(dbQuery);
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};
//search books and return subset based on a feild and query (_ref)
BookProvider.prototype.browse = function(query, callback) {
  var dbQuery = {};
  var f = query._field;
  var q = query[query._field];
  if (f == "_fields") {
      dbQuery[query[query._field]] = {$exists:true};
  } else if (query._field == "_types") {
    dbQuery = {type:q};
  } else if (f == "_tags") {
    dbQuery = {tags:{$in:[q]}};
  }
  console.log(dbQuery);
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

// get references from single book to display query from id
BookProvider.prototype.getRefs = function(refs, callback) {
  var query = {_id:{$in:[]}};
  for (var i = 0; i < refs.length; i++) {
    var objId = new ObjectID(refs[i].refId);
    query._id["$in"].push(objId);
  }
  this.getCollection(function(error, book_collection) {
      book_collection.find(query).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

//save new book
BookProvider.prototype.save = function(books, callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error)
      else {
        if( typeof(books.length)=="undefined")
          books = [books];

        for( var i =0;i< books.length;i++ ) {
          book = books[i];
          book.created_at = new Date();
        }

        book_collection.insert(books, function() {
          callback(null, books);
        });
      }
    });
};

BookProvider.prototype.addType = function(type, callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
      book_collection.update({info:{$exists:true}}, {$addToSet:{"info._types":type}});
    }
  });
};

// find a book by id
BookProvider.prototype.findById = function(id, callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
      book_collection.findOne({info:{$exists:true}}, function(error, info) {
          book_collection.findOne({_id:book_collection.db.bson_serializer.ObjectID.createFromHexString(id)}, function(error, result) {
            if (error) callback(error);
            else callback(null, result, info);
        });
      });
    }
  });
};

// get info
BookProvider.prototype.getInfo = function(callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
      book_collection.findOne({info:{$exists:true}}, function(error, info) {
          if (error) callback(error);
          else callback(null, info);
      });
    }
  });
};

// add a tag
BookProvider.prototype.addTag = function(query, set) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else book_collection.update(query, set);
  });
};

// referenced by add note
BookProvider.prototype.addReferencedBy = function(refId, id, title, note) {
  var query = {_id:new ObjectID(refId)};
  var set = { referencedBy: {}};
  set["referencedBy"] = {id:id, note:note, title:title};
  this.getCollection(function(error, book_collection){
    if (error) console.log(error);
    else {
      book_collection.update(query, {$addToSet:set}, );
    }
  });
};
// edit referenced by
BookProvider.prototype.editReferencedBy = function(refId, id, title, note) {
  var query = {_id:new ObjectID(refId), referencedBy:{$elemMatch:{id:id}}};
  var set = {};
  set["referencedBy.$.note"] = note;
  this.getCollection(function(error, book_collection){
    if (error) callback(error);
    else {
      book_collection.update(query, {$set:set}, function(error){
        if (error) callback(error);
        else callback(null);
      });
    }
  });
};
// edit reference
BookProvider.prototype.editRef = function(refId, id, title, note) {
  var query = {_id:new ObjectID(refId), refs:{$elemMatch:{id:id}}};
  var set = {};
  set["refs.$.note"] = note;
  this.getCollection(function(error, book_collection){
    if (error) callback(error);
    else {
      book_collection.update(query, {$set:set});
    }
  });
};

// update a book
BookProvider.prototype.update = function(bookId, books, callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
       book_collection.update(
          {_id:book_collection.db.bson_serializer.ObjectID.createFromHexString(bookId)},
          books,
          function(error, books) {
            if (error) callback(error);
            else callback(null, books);
          });
    }
  });
};

exports.BookProvider = BookProvider;<commit_msg>oops wrong referencedBy<commit_after>var mongodb = require('mongodb'),
    MongoClient = require('mongodb').MongoClient,
    Db = require('mongodb').Db,
    Connection = require('mongodb').Connection,
    Server = require('mongodb').Server,
    BSON = require('mongodb').BSON,
    ObjectID = require('mongodb').ObjectID;

BookProvider = function(uri) {

  var that = this;
  mongodb.MongoClient.connect(uri, { server: { auto_reconnect: true } }, function (error, database) {
    if (error) console.log(error);
    that.db = database;
  });

  /* TO DEVELOP LOCALLY
      uncomment the following two lines
      comment out the beginning of this function
  */

  //this.db = new Db('books', new Server('localhost', 27017, {safe: false}, {auto_reconnect: true}, {}));
  //this.db.open(function(){});
};

//initialize info values
BookProvider.prototype.init = function(info, callback) {
  this.getCollection(function(error, book_collection) {
    if ( error ) callback(error);
    else {
      book_collection.insert({info:info}, function(error){
        if (error) callback(error);
        else callback(null);
      });
    }
  });
};

//delete book
BookProvider.prototype.delete = function(bookId, callback) {
  this.getCollection(function(error, book_collection) {
    if(error) callback(error);
    else {
      book_collection.remove(
      {_id: book_collection.db.bson_serializer.ObjectID.createFromHexString(bookId)},
      function(error, book){
        if(error) callback(error);
        else callback(null, book)
      });
    }
  });
};

BookProvider.prototype.getCollection = function(callback) {
  this.db.collection('bks', function(error, book_collection) {
    if( error ) callback(error);
    else callback(null, book_collection);
  });
};

//find all books
BookProvider.prototype.findAll = function(callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error);
      else {
        book_collection.find().toArray(function(error, results) {
          if( error ) callback(error);
          else callback(null, results);
        });
      }
    });
};

//find recently edited books
BookProvider.prototype.findRecentEdits = function(callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error);
      else {
        book_collection.find().sort({last_edit:-1}).limit(8).toArray(function(error, results) {
          if( error ) callback(error);
          else callback(null, results);
        });
      }
    });
};
//find recently edited books
BookProvider.prototype.findRecentLogs = function(callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error);
      else {
        book_collection.find().sort({created_at:-1}).limit(8).toArray(function(error, results) {
          if( error ) callback(error);
          else callback(null, results);
        });
      }
    });
};

//find subset of books with tag
BookProvider.prototype.findTag = function(tag, callback) {
  this.getCollection(function(error, book_collection) {
    if(error) callback(error);
    else {
      book_collection.find({tags:tag}).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
    }
  });
};

//search all books
BookProvider.prototype.search = function(query, callback) {
  var name = query._field;
  var value = query._query;
  var dbQuery = {};
  dbQuery[name] = {$regex:value, $options:"-i"};
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

//search books and return subset based on a feild and query (_ref)
BookProvider.prototype.searchRefs = function(query, callback) {
  var name = query._field;
  var value = query._ref;
  var dbQuery = {};
  if (query._refs != undefined) {
    var exclude = query._refs;
    if (exclude.constructor == Array) {
      for (var i = 0; i < exclude.length; i++) {
        var obj = new ObjectID(exclude[i]);
        exclude[i] = obj;
      }
      dbQuery = {_id:{$nin:exclude}};
    } else {
      exclude = new ObjectID(exclude);
      dbQuery = {_id:{$ne:exclude}};
    }
  }
  dbQuery[name] = {$regex:value, $options:"-i"};
  console.log(JSON.stringify(dbQuery));
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

//search books and return subset based on a feild and query (_ref)
BookProvider.prototype.browseRefs = function(query, callback) {
  var dbQuery = {};
  var f = query._field;
  var q = query[query._field];
  if (f == "_fields") {
      dbQuery[query[query._field]] = {$exists:true};
  } else if (query._field == "_types") {
    dbQuery = {type:q};
  } else if (f == "_tags") {
    dbQuery = {tags:{$in:[q]}};
  }
  if (query._refs != undefined) {
    var exclude = query._refs;
    if (exclude.constructor == Array) {
      for (var i = 0; i < exclude.length; i++) {
        var obj = new ObjectID(exclude[i]);
        exclude[i] = obj;
      }
      dbQuery = {_id:{$nin:exclude}};
    } else {
      exclude = new ObjectID(exclude);
      dbQuery = {_id:{$ne:exclude}};
    }
  }
  console.log(dbQuery);
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};
//search books and return subset based on a feild and query (_ref)
BookProvider.prototype.browse = function(query, callback) {
  var dbQuery = {};
  var f = query._field;
  var q = query[query._field];
  if (f == "_fields") {
      dbQuery[query[query._field]] = {$exists:true};
  } else if (query._field == "_types") {
    dbQuery = {type:q};
  } else if (f == "_tags") {
    dbQuery = {tags:{$in:[q]}};
  }
  console.log(dbQuery);
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

// get references from single book to display query from id
BookProvider.prototype.getRefs = function(refs, callback) {
  var query = {_id:{$in:[]}};
  for (var i = 0; i < refs.length; i++) {
    var objId = new ObjectID(refs[i].refId);
    query._id["$in"].push(objId);
  }
  this.getCollection(function(error, book_collection) {
      book_collection.find(query).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

//save new book
BookProvider.prototype.save = function(books, callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error)
      else {
        if( typeof(books.length)=="undefined")
          books = [books];

        for( var i =0;i< books.length;i++ ) {
          book = books[i];
          book.created_at = new Date();
        }

        book_collection.insert(books, function() {
          callback(null, books);
        });
      }
    });
};

BookProvider.prototype.addType = function(type, callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
      book_collection.update({info:{$exists:true}}, {$addToSet:{"info._types":type}});
    }
  });
};

// find a book by id
BookProvider.prototype.findById = function(id, callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
      book_collection.findOne({info:{$exists:true}}, function(error, info) {
          book_collection.findOne({_id:book_collection.db.bson_serializer.ObjectID.createFromHexString(id)}, function(error, result) {
            if (error) callback(error);
            else callback(null, result, info);
        });
      });
    }
  });
};

// get info
BookProvider.prototype.getInfo = function(callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
      book_collection.findOne({info:{$exists:true}}, function(error, info) {
          if (error) callback(error);
          else callback(null, info);
      });
    }
  });
};

// add a tag
BookProvider.prototype.addTag = function(query, set) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else book_collection.update(query, set);
  });
};

// referenced by add note
BookProvider.prototype.addReferencedBy = function(refId, id, title, note) {
  var query = {_id:new ObjectID(refId)};
  var set = { referencedBy: {}};
  set["referencedBy"] = {id:id, note:note, title:title};
  this.getCollection(function(error, book_collection){
    if (error) console.log(error);
    else {
      book_collection.update(query, {$addToSet:set}, function(error){
        if (error) callback(error);
        else callback(null);
      });
    }
  });
};
// edit referenced by
BookProvider.prototype.editReferencedBy = function(refId, id, title, note) {
  var query = {_id:new ObjectID(refId), referencedBy:{$elemMatch:{id:id}}};
  var set = {};
  set["referencedBy.$.note"] = note;
  this.getCollection(function(error, book_collection){
    if (error) callback(error);
    else {
      book_collection.update(query, {$set:set});
    }
  });
};
// edit reference
BookProvider.prototype.editRef = function(refId, id, title, note) {
  var query = {_id:new ObjectID(refId), refs:{$elemMatch:{id:id}}};
  var set = {};
  set["refs.$.note"] = note;
  this.getCollection(function(error, book_collection){
    if (error) callback(error);
    else {
      book_collection.update(query, {$set:set});
    }
  });
};

// update a book
BookProvider.prototype.update = function(bookId, books, callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
       book_collection.update(
          {_id:book_collection.db.bson_serializer.ObjectID.createFromHexString(bookId)},
          books,
          function(error, books) {
            if (error) callback(error);
            else callback(null, books);
          });
    }
  });
};

exports.BookProvider = BookProvider;<|endoftext|>


<commit_before>var mongodb = require('mongodb'),
    MongoClient = require('mongodb').MongoClient,
    Db = require('mongodb').Db,
    Connection = require('mongodb').Connection,
    Server = require('mongodb').Server,
    BSON = require('mongodb').BSON,
    ObjectID = require('mongodb').ObjectID;

BookProvider = function(uri) {

  var that = this;
  mongodb.MongoClient.connect(uri, { server: { auto_reconnect: true } }, function (error, database) {
    if (error) console.log(error);
    that.db = database;
  });

  /*
   TO DEVELOP LOCALLY
      uncomment the following two lines
      comment out the beginning of this function
  */

  //this.db = new Db('books', new Server('localhost', 27017, {safe: false}, {auto_reconnect: true}, {}));
  //this.db.open(function(){});
};

//initialize info values
BookProvider.prototype.init = function(info, callback) {
  this.getCollection(function(error, book_collection) {
    if ( error ) callback(error);
    else {
      book_collection.insert({info:info}, function(error){
        if (error) callback(error);
        else callback(null);
      });
    }
  });
};

//delete book
BookProvider.prototype.delete = function(bookId, callback) {
  this.getCollection(function(error, book_collection) {
    if(error) callback(error);
    else {
      book_collection.remove(
      {_id: book_collection.db.bson_serializer.ObjectID.createFromHexString(bookId)},
      function(error, book){
        if(error) callback(error);
        else callback(null, book)
      });
    }
  });
};

BookProvider.prototype.getCollection = function(callback) {
  this.db.collection('bks', function(error, book_collection) {
    if( error ) callback(error);
    else callback(null, book_collection);
  });
};

//find all books
BookProvider.prototype.findAll = function(callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error);
      else {
        book_collection.find().toArray(function(error, results) {
          if( error ) callback(error);
          else callback(null, results);
        });
      }
    });
};

//find recently edited books
BookProvider.prototype.findRecentEdits = function(callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error);
      else {
        book_collection.find().sort({last_edit:-1}).limit(8).toArray(function(error, results) {
          if( error ) callback(error);
          else callback(null, results);
        });
      }
    });
};
//find recently edited books
BookProvider.prototype.findRecentLogs = function(callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error);
      else {
        book_collection.find().sort({created_at:-1}).limit(8).toArray(function(error, results) {
          if( error ) callback(error);
          else callback(null, results);
        });
      }
    });
};

//find subset of books with tag
BookProvider.prototype.findTag = function(tag, callback) {
  this.getCollection(function(error, book_collection) {
    if(error) callback(error);
    else {
      book_collection.find({tags:tag}).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
    }
  });
};

//search all books
BookProvider.prototype.search = function(query, callback) {
  var name = query._field;
  var value = query._query;
  var dbQuery = {};
  dbQuery[name] = {$regex:value, $options:"-i"};
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

//search books and return subset based on a feild and query (_ref)
BookProvider.prototype.searchRefs = function(query, callback) {
  var name = query._field;
  var value = query._ref;
  var dbQuery = {};
  if (query._refs != undefined) {
    var exclude = query._refs;
    if (exclude.constructor == Array) {
      for (var i = 0; i < exclude.length; i++) {
        var obj = new ObjectID(exclude[i]);
        exclude[i] = obj;
      }
      dbQuery = {_id:{$nin:exclude}};
    } else {
      exclude = new ObjectID(exclude);
      dbQuery = {_id:{$ne:exclude}};
    }
  }
  dbQuery[name] = {$regex:value, $options:"-i"};
  console.log(JSON.stringify(dbQuery));
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

//search books and return subset based on a feild and query (_ref)
BookProvider.prototype.browseRefs = function(query, callback) {
  var dbQuery = {};
  var f = query._field;
  var q = query[query._field];
  if (f == "_fields") {
      dbQuery[query[query._field]] = {$exists:true};
  } else if (query._field == "_types") {
    dbQuery = {type:q};
  } else if (f == "_tags") {
    dbQuery = {tags:{$in:[q]}};
  }
  if (query._refs != undefined) {
    var exclude = query._refs;
    if (exclude.constructor == Array) {
      for (var i = 0; i < exclude.length; i++) {
        var obj = new ObjectID(exclude[i]);
        exclude[i] = obj;
      }
      dbQuery = {_id:{$nin:exclude}};
    } else {
      exclude = new ObjectID(exclude);
      dbQuery = {_id:{$ne:exclude}};
    }
  }
  console.log(dbQuery);
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};
//search books and return subset based on a feild and query (_ref)
BookProvider.prototype.browse = function(query, callback) {
  var dbQuery = {};
  var f = query._field;
  var q = query[query._field];
  if (f == "_fields") {
      dbQuery[query[query._field]] = {$exists:true};
  } else if (query._field == "_types") {
    dbQuery = {type:q};
  } else if (f == "_tags") {
    dbQuery = {tags:{$in:[q]}};
  }
  console.log(dbQuery);
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

// get references from single book to display query from id
BookProvider.prototype.getRefs = function(refs, callback) {
  var query = {_id:{$in:[]}};
  for (var i = 0; i < refs.length; i++) {
    var objId = new ObjectID(refs[i].refId);
    query._id["$in"].push(objId);
  }
  this.getCollection(function(error, book_collection) {
      book_collection.find(query).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

//save new book
BookProvider.prototype.save = function(books, callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error)
      else {
        if( typeof(books.length)=="undefined")
          books = [books];

        for( var i =0;i< books.length;i++ ) {
          book = books[i];
          book.created_at = new Date();
        }

        book_collection.insert(books, function() {
          callback(null, books);
        });
      }
    });
};

BookProvider.prototype.addType = function(type, callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
      book_collection.update({info:{$exists:true}}, {$addToSet:{"info._types":type}});
    }
  });
};

// find a book by id
BookProvider.prototype.findById = function(id, callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
      book_collection.findOne({info:{$exists:true}}, function(error, info) {
          book_collection.findOne({_id:book_collection.db.bson_serializer.ObjectID.createFromHexString(id)}, function(error, result) {
            if (error) callback(error);
            else callback(null, result, info);
        });
      });
    }
  });
};

// get info
BookProvider.prototype.getInfo = function(callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
      book_collection.findOne({info:{$exists:true}}, function(error, info) {
          if (error) callback(error);
          else callback(null, info);
      });
    }
  });
};

// add a tag
BookProvider.prototype.addTag = function(query, set) {
  this.getCollection(function(error, book_collection) {
    if (error) console.log("add tag: " + error);
    else book_collection.update(query, set);
  });
};

// referenced by add note
BookProvider.prototype.addReferencedBy = function(refId, id, title, note) {
  var query = {_id:new ObjectID(refId)};
  var set = { referencedBy: {}};
  set["referencedBy"] = {id:id, note:note, title:title};
  this.getCollection(function(error, book_collection){
    if (error) console.log(error);
    else {
      book_collection.update(query, {$addToSet:set}, function(error){
        if (error) console.log("addReferencedBy: " + error);
      });
    }
  });
};
// edit referenced by
BookProvider.prototype.editReferencedBy = function(refId, id, title, note) {
  var query = {_id:new ObjectID(refId), referencedBy:{$elemMatch:{id:id}}};
  var set = {};
  set["referencedBy.$.note"] = note;
  this.getCollection(function(error, book_collection){
    if (error) console.log("edit ref by: " + error);
    else {
      book_collection.update(query, {$set:set}, function(error) {
        console.log("edit ref by: " + error);
      });
    }
  });
};
// edit reference
BookProvider.prototype.editRef = function(refId, id, title, note) {
  var query = {_id:new ObjectID(refId), refs:{$elemMatch:{id:id}}};
  var set = {};
  set["refs.$.note"] = note;
  this.getCollection(function(error, book_collection){
    if (error) console.log("editRef: " + error);
    else {
      book_collection.update(query, {$set:set}, function(error){
        console.log("edit ref: " + error);
      });
    }
  });
};

// update a book
BookProvider.prototype.update = function(bookId, books, callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
       book_collection.update(
          {_id:book_collection.db.bson_serializer.ObjectID.createFromHexString(bookId)},
          books,
          function(error, books) {
            if (error) callback(error);
            else callback(null, books);
          });
    }
  });
};

exports.BookProvider = BookProvider;<commit_msg>add type callback<commit_after>var mongodb = require('mongodb'),
    MongoClient = require('mongodb').MongoClient,
    Db = require('mongodb').Db,
    Connection = require('mongodb').Connection,
    Server = require('mongodb').Server,
    BSON = require('mongodb').BSON,
    ObjectID = require('mongodb').ObjectID;

BookProvider = function(uri) {

  var that = this;
  mongodb.MongoClient.connect(uri, { server: { auto_reconnect: true } }, function (error, database) {
    if (error) console.log(error);
    that.db = database;
  });

  /*
   TO DEVELOP LOCALLY
      uncomment the following two lines
      comment out the beginning of this function
  */

  //this.db = new Db('books', new Server('localhost', 27017, {safe: false}, {auto_reconnect: true}, {}));
  //this.db.open(function(){});
};

//initialize info values
BookProvider.prototype.init = function(info, callback) {
  this.getCollection(function(error, book_collection) {
    if ( error ) callback(error);
    else {
      book_collection.insert({info:info}, function(error){
        if (error) callback(error);
        else callback(null);
      });
    }
  });
};

//delete book
BookProvider.prototype.delete = function(bookId, callback) {
  this.getCollection(function(error, book_collection) {
    if(error) callback(error);
    else {
      book_collection.remove(
      {_id: book_collection.db.bson_serializer.ObjectID.createFromHexString(bookId)},
      function(error, book){
        if(error) callback(error);
        else callback(null, book)
      });
    }
  });
};

BookProvider.prototype.getCollection = function(callback) {
  this.db.collection('bks', function(error, book_collection) {
    if( error ) callback(error);
    else callback(null, book_collection);
  });
};

//find all books
BookProvider.prototype.findAll = function(callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error);
      else {
        book_collection.find().toArray(function(error, results) {
          if( error ) callback(error);
          else callback(null, results);
        });
      }
    });
};

//find recently edited books
BookProvider.prototype.findRecentEdits = function(callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error);
      else {
        book_collection.find().sort({last_edit:-1}).limit(8).toArray(function(error, results) {
          if( error ) callback(error);
          else callback(null, results);
        });
      }
    });
};
//find recently logged books
BookProvider.prototype.findRecentLogs = function(callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error);
      else {
        book_collection.find().sort({created_at:-1}).limit(8).toArray(function(error, results) {
          if( error ) callback(error);
          else callback(null, results);
        });
      }
    });
};

//find subset of books with tag
BookProvider.prototype.findTag = function(tag, callback) {
  this.getCollection(function(error, book_collection) {
    if(error) callback(error);
    else {
      book_collection.find({tags:tag}).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
    }
  });
};

//search all books
BookProvider.prototype.search = function(query, callback) {
  var name = query._field;
  var value = query._query;
  var dbQuery = {};
  dbQuery[name] = {$regex:value, $options:"-i"};
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

//search books and return subset based on a feild and query (_ref)
BookProvider.prototype.searchRefs = function(query, callback) {
  var name = query._field;
  var value = query._ref;
  var dbQuery = {};
  if (query._refs != undefined) {
    var exclude = query._refs;
    if (exclude.constructor == Array) {
      for (var i = 0; i < exclude.length; i++) {
        var obj = new ObjectID(exclude[i]);
        exclude[i] = obj;
      }
      dbQuery = {_id:{$nin:exclude}};
    } else {
      exclude = new ObjectID(exclude);
      dbQuery = {_id:{$ne:exclude}};
    }
  }
  dbQuery[name] = {$regex:value, $options:"-i"};
  console.log(JSON.stringify(dbQuery));
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

//search books and return subset based on a feild and query (_ref)
BookProvider.prototype.browseRefs = function(query, callback) {
  var dbQuery = {};
  var f = query._field;
  var q = query[query._field];
  if (f == "_fields") {
      dbQuery[query[query._field]] = {$exists:true};
  } else if (query._field == "_types") {
    dbQuery = {type:q};
  } else if (f == "_tags") {
    dbQuery = {tags:{$in:[q]}};
  }
  if (query._refs != undefined) {
    var exclude = query._refs;
    if (exclude.constructor == Array) {
      for (var i = 0; i < exclude.length; i++) {
        var obj = new ObjectID(exclude[i]);
        exclude[i] = obj;
      }
      dbQuery = {_id:{$nin:exclude}};
    } else {
      exclude = new ObjectID(exclude);
      dbQuery = {_id:{$ne:exclude}};
    }
  }
  console.log(dbQuery);
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};
//search books and return subset based on a feild and query (_ref)
BookProvider.prototype.browse = function(query, callback) {
  var dbQuery = {};
  var f = query._field;
  var q = query[query._field];
  if (f == "_fields") {
      dbQuery[query[query._field]] = {$exists:true};
  } else if (query._field == "_types") {
    dbQuery = {type:q};
  } else if (f == "_tags") {
    dbQuery = {tags:{$in:[q]}};
  }
  console.log(dbQuery);
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

// get references from single book to display query from id
BookProvider.prototype.getRefs = function(refs, callback) {
  var query = {_id:{$in:[]}};
  for (var i = 0; i < refs.length; i++) {
    var objId = new ObjectID(refs[i].refId);
    query._id["$in"].push(objId);
  }
  this.getCollection(function(error, book_collection) {
      book_collection.find(query).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

//save new book
BookProvider.prototype.save = function(books, callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error)
      else {
        if( typeof(books.length)=="undefined")
          books = [books];

        for( var i =0;i< books.length;i++ ) {
          book = books[i];
          book.created_at = new Date();
        }

        book_collection.insert(books, function() {
          callback(null, books);
        });
      }
    });
};

BookProvider.prototype.addType = function(type, callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
      book_collection.update({info:{$exists:true}}, {$addToSet:{"info._types":type}},
        function (error) {
          console.log(error);
        });
    }
  });
};

// find a book by id
BookProvider.prototype.findById = function(id, callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
      book_collection.findOne({info:{$exists:true}}, function(error, info) {
          book_collection.findOne({_id:book_collection.db.bson_serializer.ObjectID.createFromHexString(id)}, function(error, result) {
            if (error) callback(error);
            else callback(null, result, info);
        });
      });
    }
  });
};

// get info
BookProvider.prototype.getInfo = function(callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
      book_collection.findOne({info:{$exists:true}}, function(error, info) {
          if (error) callback(error);
          else callback(null, info);
      });
    }
  });
};

// add a tag
BookProvider.prototype.addTag = function(query, set) {
  this.getCollection(function(error, book_collection) {
    if (error) console.log("add tag: " + error);
    else book_collection.update(query, set);
  });
};

// referenced by add note
BookProvider.prototype.addReferencedBy = function(refId, id, title, note) {
  var query = {_id:new ObjectID(refId)};
  var set = { referencedBy: {}};
  set["referencedBy"] = {id:id, note:note, title:title};
  this.getCollection(function(error, book_collection){
    if (error) console.log(error);
    else {
      book_collection.update(query, {$addToSet:set}, function(error){
        if (error) console.log("addReferencedBy: " + error);
      });
    }
  });
};
// edit referenced by
BookProvider.prototype.editReferencedBy = function(refId, id, title, note) {
  var query = {_id:new ObjectID(refId), referencedBy:{$elemMatch:{id:id}}};
  var set = {};
  set["referencedBy.$.note"] = note;
  this.getCollection(function(error, book_collection){
    if (error) console.log("edit ref by: " + error);
    else {
      book_collection.update(query, {$set:set}, function(error) {
        console.log("edit ref by: " + error);
      });
    }
  });
};
// edit reference
BookProvider.prototype.editRef = function(refId, id, title, note) {
  var query = {_id:new ObjectID(refId), refs:{$elemMatch:{id:id}}};
  var set = {};
  set["refs.$.note"] = note;
  this.getCollection(function(error, book_collection){
    if (error) console.log("editRef: " + error);
    else {
      book_collection.update(query, {$set:set}, function(error){
        console.log("edit ref: " + error);
      });
    }
  });
};

// update a book
BookProvider.prototype.update = function(bookId, books, callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
       book_collection.update(
          {_id:book_collection.db.bson_serializer.ObjectID.createFromHexString(bookId)},
          books,
          function(error, books) {
            if (error) callback(error);
            else callback(null, books);
          });
    }
  });
};

exports.BookProvider = BookProvider;<|endoftext|>


<commit_before>"use strict";

// actually _run_ the lifecycles, gorrammit
jest.unmock("@lerna/run-lifecycle");

const fs = require("fs-extra");
const path = require("path");
const normalizePath = require("normalize-path");
const { printObjectProperties } = require("pretty-format/build/collections");
const npmConf = require("@lerna/npm-conf");
const Package = require("@lerna/package");
const { getPackages } = require("@lerna/project");
const initFixture = require("@lerna-test/init-fixture")(path.resolve(__dirname, "../../../integration"));

const packDirectory = require("..");

// temp-write creates temp directories that are 36 characters long (uuid.v4())
const TAR_DIR_REGEXP = /([^\s"]*[\\/][-0-9a-f]{36})([^\s"]*)/g;
const hasOwn = Object.prototype.hasOwnProperty;

function isObject(val) {
  return val && typeof val === "object" && Array.isArray(val) === false;
}

function isString(val) {
  return val && typeof val === "string";
}

function serializeTempDir(match, cwd, subPath) {
  return normalizePath(path.join("__TMP_DIR__", subPath));
}

// process.umask() differs between macOS and Ubuntu,
// so we need to overwrite derived hashes for consistency
expect.addSnapshotSerializer({
  test(val) {
    if (isObject(val)) {
      // 420 in macOS, 436 in Ubuntu
      return hasOwn.call(val, "mode") || hasOwn.call(val, "size");
    }

    if (isString(val)) {
      // integrity or shasum
      return /sha512-[\S]{88}/.test(val) || /[0-9a-f]{40}/.test(val) || TAR_DIR_REGEXP.test(val);
    }
  },
  serialize(val, config, indentation, depth, refs, printer) {
    if (isString(val)) {
      if (/tgz$/.test(val)) {
        const str = val.replace(TAR_DIR_REGEXP, serializeTempDir);

        // top-level strings don't need quotes, but nested ones do (object properties, etc)
        // ...and this is always an object property
        return `"${str}"`;
      }

      if (val.indexOf("sha512") > -1) {
        return '"INTEGRITY"';
      }

      return '"SHASUM"';
    }

    /* eslint-disable no-param-reassign */
    if (depth) {
      // nested file objects
      val.mode = "MODE";
    } else {
      // bloody tar algorithms
      val.size = "TAR_SIZE";
    }
    /* eslint-enable no-param-reassign */

    let result = "Object {";
    result += printObjectProperties(val, config, indentation, depth, refs, printer);
    result += "}";

    return result;
  },
});

describe("pack-directory", () => {
  it("resolves tarball metadata objects on success", async () => {
    const cwd = await initFixture("lerna-bootstrap");
    const conf = npmConf({ prefix: cwd }).snapshot;
    const pkgs = await getPackages(cwd);

    // choose first and last package since the middle two are repetitive
    const [head, tail] = await Promise.all(
      [pkgs.shift(), pkgs.pop()].map(pkg => packDirectory(pkg, pkg.location, conf))
    );

    const INTEGRITY_PATTERN = /sha512-[\S]{88}/;
    const SHASUM_PATTERN = /[0-9a-f]{40}/;

    expect(head).toMatchInlineSnapshot(`
Object {
  "bundled": Array [],
  "entryCount": 2,
  "filename": "integration-package-1-1.0.0.tgz",
  "files": Array [
    Object {
      "mode": "MODE",
      "path": "dist/index.js",
      "size": 141,
    },
    Object {
      "mode": "MODE",
      "path": "package.json",
      "size": 325,
    },
  ],
  "id": "@integration/package-1@1.0.0",
  "integrity": "INTEGRITY",
  "name": "@integration/package-1",
  "shasum": "SHASUM",
  "size": "TAR_SIZE",
  "tarFilePath": "__TMP_DIR__/integration-package-1-1.0.0.tgz",
  "unpackedSize": 466,
  "version": "1.0.0",
}
`);
    // integrity is an instance of Integrity
    // https://github.com/zkat/ssri/blob/a4337cd672f341deee2b52699b6720d82e4d0ddf/index.js#L83
    expect(head.integrity.toString()).toMatch(INTEGRITY_PATTERN);
    expect(head.shasum).toMatch(SHASUM_PATTERN);

    expect(tail).toMatchInlineSnapshot(`
Object {
  "bundled": Array [],
  "entryCount": 1,
  "filename": "package-4-1.0.0.tgz",
  "files": Array [
    Object {
      "mode": "MODE",
      "path": "package.json",
      "size": 224,
    },
  ],
  "id": "package-4@1.0.0",
  "integrity": "INTEGRITY",
  "name": "package-4",
  "shasum": "SHASUM",
  "size": "TAR_SIZE",
  "tarFilePath": "__TMP_DIR__/package-4-1.0.0.tgz",
  "unpackedSize": 224,
  "version": "1.0.0",
}
`);
    expect(tail.integrity.toString()).toMatch(INTEGRITY_PATTERN);
    expect(tail.shasum).toMatch(SHASUM_PATTERN);

    const mid = pkgs.pop();
    const json = Object.assign(mid.toJSON(), {
      name: "package-3",
      // omit scripts directory
      files: ["*.js"],
      // overwrite existing postinstall + test
      scripts: {
        prepublish: "exit 1",
        prepublishOnly: "node scripts/build.js",
      },
    });

    await Promise.all([
      fs.writeJSON(mid.manifestLocation, json, { spaces: 2 }),
      fs.outputFile(
        path.join(mid.location, "scripts", "build.js"),
        // Windows requires this ridiculous workaround
        // because echoing a file without CRLF garbage is apparently too hard :P
        "require('fs').writeFileSync(require('path').resolve('index.js'), 'badgerbadgerbadgerbadger');"
      ),
    ]);

    const mushroom = new Package(json, mid.location, mid.rootPath);
    const lazy = await packDirectory(
      mushroom,
      mushroom.location,
      Object.assign({}, conf, {
        "ignore-prepublish": true,
        "lerna-command": "publish",
      })
    );

    expect(lazy).toMatchInlineSnapshot(`
Object {
  "bundled": Array [],
  "entryCount": 4,
  "filename": "package-3-1.0.0.tgz",
  "files": Array [
    Object {
      "mode": "MODE",
      "path": "cli1.js",
      "size": 108,
    },
    Object {
      "mode": "MODE",
      "path": "cli2.js",
      "size": 108,
    },
    Object {
      "mode": "MODE",
      "path": "index.js",
      "size": 24,
    },
    Object {
      "mode": "MODE",
      "path": "package.json",
      "size": 465,
    },
  ],
  "id": "package-3@1.0.0",
  "integrity": "INTEGRITY",
  "name": "package-3",
  "shasum": "SHASUM",
  "size": "TAR_SIZE",
  "tarFilePath": "__TMP_DIR__/package-3-1.0.0.tgz",
  "unpackedSize": 705,
  "version": "1.0.0",
}
`);
  });
});
<commit_msg>test(pack-directory): Convert tests to use proper fixture<commit_after>"use strict";

// actually _run_ the lifecycles, gorrammit
jest.unmock("@lerna/run-lifecycle");

const path = require("path");
const normalizePath = require("normalize-path");
const { printObjectProperties } = require("pretty-format/build/collections");
const npmConf = require("@lerna/npm-conf");
const { getPackages } = require("@lerna/project");
const initFixture = require("@lerna-test/init-fixture")(__dirname);

const packDirectory = require("..");

// temp-write creates temp directories that are 36 characters long (uuid.v4())
const TAR_DIR_REGEXP = /([^\s"]*[\\/][-0-9a-f]{36})([^\s"]*)/g;
const hasOwn = Object.prototype.hasOwnProperty;

function isObject(val) {
  return val && typeof val === "object" && Array.isArray(val) === false;
}

function isString(val) {
  return val && typeof val === "string";
}

function serializeTempDir(match, cwd, subPath) {
  return normalizePath(path.join("__TMP_DIR__", subPath));
}

// process.umask() differs between macOS and Ubuntu,
// so we need to overwrite derived hashes for consistency
expect.addSnapshotSerializer({
  test(val) {
    if (isObject(val)) {
      // 420 in macOS, 436 in Ubuntu
      return hasOwn.call(val, "mode") || hasOwn.call(val, "size");
    }

    if (isString(val)) {
      // integrity or shasum
      return /sha512-[\S]{88}/.test(val) || /[0-9a-f]{40}/.test(val) || TAR_DIR_REGEXP.test(val);
    }
  },
  serialize(val, config, indentation, depth, refs, printer) {
    if (isString(val)) {
      if (/tgz$/.test(val)) {
        const str = val.replace(TAR_DIR_REGEXP, serializeTempDir);

        // top-level strings don't need quotes, but nested ones do (object properties, etc)
        // ...and this is always an object property
        return `"${str}"`;
      }

      if (val.indexOf("sha512") > -1) {
        return '"INTEGRITY"';
      }

      return '"SHASUM"';
    }

    /* eslint-disable no-param-reassign */
    if (depth) {
      // nested file objects
      val.mode = "MODE";
    } else {
      // bloody tar algorithms
      val.size = "TAR_SIZE";
    }
    /* eslint-enable no-param-reassign */

    let result = "Object {";
    result += printObjectProperties(val, config, indentation, depth, refs, printer);
    result += "}";

    return result;
  },
});

describe("pack-directory", () => {
  it("resolves tarball metadata objects on success", async () => {
    const cwd = await initFixture("pack-directory");
    const conf = npmConf({ prefix: cwd }).snapshot;
    const pkgs = await getPackages(cwd);

    // choose first and last package since the middle two are repetitive
    const [head, tail] = await Promise.all(
      [pkgs.shift(), pkgs.pop()].map(pkg => packDirectory(pkg, pkg.location, conf))
    );

    const INTEGRITY_PATTERN = /sha512-[\S]{88}/;
    const SHASUM_PATTERN = /[0-9a-f]{40}/;

    expect(head).toMatchInlineSnapshot(`
      Object {
        "bundled": Array [],
        "entryCount": 2,
        "filename": "scope-head-1.0.0.tgz",
        "files": Array [
          Object {
            "mode": "MODE",
            "path": "dist/index.js",
            "size": 37,
          },
          Object {
            "mode": "MODE",
            "path": "package.json",
            "size": 159,
          },
        ],
        "id": "@scope/head@1.0.0",
        "integrity": "INTEGRITY",
        "name": "@scope/head",
        "shasum": "SHASUM",
        "size": "TAR_SIZE",
        "tarFilePath": "__TMP_DIR__/scope-head-1.0.0.tgz",
        "unpackedSize": 196,
        "version": "1.0.0",
      }
    `);
    // integrity is an instance of Integrity
    // https://github.com/zkat/ssri/blob/a4337cd672f341deee2b52699b6720d82e4d0ddf/index.js#L83
    expect(head.integrity.toString()).toMatch(INTEGRITY_PATTERN);
    expect(head.shasum).toMatch(SHASUM_PATTERN);

    expect(tail).toMatchInlineSnapshot(`
      Object {
        "bundled": Array [],
        "entryCount": 2,
        "filename": "tail-4.0.0.tgz",
        "files": Array [
          Object {
            "mode": "MODE",
            "path": "index.js",
            "size": 37,
          },
          Object {
            "mode": "MODE",
            "path": "package.json",
            "size": 131,
          },
        ],
        "id": "tail@4.0.0",
        "integrity": "INTEGRITY",
        "name": "tail",
        "shasum": "SHASUM",
        "size": "TAR_SIZE",
        "tarFilePath": "__TMP_DIR__/tail-4.0.0.tgz",
        "unpackedSize": 168,
        "version": "4.0.0",
      }
    `);
    expect(tail.integrity.toString()).toMatch(INTEGRITY_PATTERN);
    expect(tail.shasum).toMatch(SHASUM_PATTERN);

    const next = pkgs.pop();
    const pubs = await packDirectory(
      next,
      next.location,
      Object.assign({}, conf, {
        "ignore-prepublish": true,
        "lerna-command": "publish",
      })
    );

    expect(pubs).toMatchInlineSnapshot(`
      Object {
        "bundled": Array [],
        "entryCount": 2,
        "filename": "pubs-3.0.0.tgz",
        "files": Array [
          Object {
            "mode": "MODE",
            "path": "index.js",
            "size": 21,
          },
          Object {
            "mode": "MODE",
            "path": "package.json",
            "size": 171,
          },
        ],
        "id": "pubs@3.0.0",
        "integrity": "INTEGRITY",
        "name": "pubs",
        "shasum": "SHASUM",
        "size": "TAR_SIZE",
        "tarFilePath": "__TMP_DIR__/pubs-3.0.0.tgz",
        "unpackedSize": 192,
        "version": "3.0.0",
      }
    `);

    const last = pkgs.pop();
    const subs = await packDirectory(
      last,
      // TODO: use location
      last.contents,
      conf
    );

    expect(subs).toMatchInlineSnapshot(`
      Object {
        "bundled": Array [],
        "entryCount": 2,
        "filename": "subs-2.0.0.tgz",
        "files": Array [
          Object {
            "mode": "MODE",
            "path": "prepacked.js",
            "size": 21,
          },
          Object {
            "mode": "MODE",
            "path": "package.json",
            "size": 115,
          },
        ],
        "id": "subs@2.0.0",
        "integrity": "INTEGRITY",
        "name": "subs",
        "shasum": "SHASUM",
        "size": "TAR_SIZE",
        "tarFilePath": "__TMP_DIR__/subs-2.0.0.tgz",
        "unpackedSize": 136,
        "version": "2.0.0",
      }
    `);
  });
});
<|endoftext|>