<commit_before>import debugModule from "debug";
const debug = debugModule("debugger:data:decode:utils");

import { BigNumber } from "bignumber.js";
import Web3 from "web3";

export const WORD_SIZE = 0x20;
export const MAX_WORD = new BigNumber(2).pow(256).minus(1);

/**
 * recursively converts big numbers into something nicer to look at
 */
export function cleanBigNumbers(value) {
  if (BigNumber.isBigNumber(value)) {
    return value.toNumber();

  } else if (value && value.map != undefined) {
    return value.map( (inner) => cleanBigNumbers(inner) );

  } else if (value && typeof value == "object") {
    return Object.assign(
      {}, ...Object.entries(value)
        .map( ([key, inner]) => ({ [key]: cleanBigNumbers(inner) }) )
    );

  } else {
    return value;
  }
}

export function typeIdentifier(definition) {
  return definition.typeDescriptions.typeIdentifier;
}

/**
 * returns basic type class for a variable definition node
 * e.g.:
 *  `t_uint256` becomes `uint`
 *  `t_struct$_Thing_$20_memory_ptr` becomes `struct`
 */
export function typeClass(definition) {
  return typeIdentifier(definition).match(/t_([^$_0-9]+)/)[1];
}

/**
 * Allocate storage for given variable declarations
 *
 * Postcondition: starts a new slot and occupies whole slots
 */
export function allocateDeclarations(
  declarations,
  refs,
  slot = 0,
  index = WORD_SIZE - 1,
  path = []
) {
  if (index < WORD_SIZE - 1) {  // starts a new slot
    slot++;
    index = WORD_SIZE - 1;
  }

  let parentFrom = { slot, index: 0 };
  var parentTo = { slot, index: WORD_SIZE - 1 };
  let mapping = {};

  for (let declaration of declarations) {
    let { from, to, next, children } =
      allocateDeclaration(declaration, refs, slot, index);

    mapping[declaration.id] = { from, to, name: declaration.name };
    if (children !== undefined) {
      mapping[declaration.id].children = children;
    }

    slot = next.slot;
    index = next.index;

    parentTo = { slot: to.slot, index: WORD_SIZE - 1 };
  }

  if (index < WORD_SIZE - 1) {
    slot++;
    index = WORD_SIZE - 1;
  }

  return {
    from: parentFrom,
    to: parentTo,
    next: { slot, index },
    children: mapping
  };
}

function allocateValue(slot, index, bytes) {
  slot = normalizeSlot(slot);

  let from = (index - bytes + 1 >= 0)
    ? { slot, index: index - bytes + 1 }
    : {
        slot: {
          path: slot.path,
          offset: slot.offset + 1
        },
        index: WORD_SIZE - bytes
      };

  let to = { slot: from.slot, index: from.index + bytes - 1 };

  let next = (from.index == 0)
    ? {
        slot: {
          path: from.slot.path,
          offset: from.slot.offset + 1
        },
        index: WORD_SIZE - 1
      }
    : { slot: from.slot, index: from.index - 1 };

  return { from, to, next };
}

function allocateDeclaration(declaration, refs, slot, index) {
  let definition = refs[declaration.id].definition;
  var byteSize = storageSize(definition);  // yum

  if (typeClass(definition) != "struct") {
    return allocateValue(slot, index, byteSize);
  }

  let struct = refs[definition.typeName.referencedDeclaration];
  debug("struct: %O", struct);

  let result =  allocateDeclarations(struct.variables || [], refs, slot, index);
  debug("struct result %o", result);
  return result;
}

/**
 * Convert polymorphic slot value into canonical { path, offset } pair.
 */
export function normalizeSlot(slot) {
  if (typeof slot == "object" && slot.path != undefined) {
    return {
      path: slot.path,
      offset: slot.offset || 0
    };
  }

  return {
    path: slot,
    offset: 0
  };
}

/**
 * e.g. uint48 -> 6
 * @return size in bytes for explicit type size, or `null` if not stated
 */
export function specifiedSize(definition) {
  let specified = typeIdentifier(definition).match(/t_[a-z]+([0-9]+)/);

  if (!specified) {
    return null;
  }

  let num = specified[1];

  switch (typeClass(definition)) {
    case "int":
    case "uint":
      return num / 8;

    case "bytes":
      return num;

    default:
      debug("Unknown type for size specification: %s", typeIdentifier(definition));
  }
}

export function storageSize(definition) {
  switch (typeClass(definition)) {
    case "bool":
      return 1;

    case "address":
      return 20;

    case "int":
    case "uint":
      // is this a HACK? ("256" / 8)
      return typeIdentifier(definition).match(/t_[a-z]+([0-9]+)/)[1] / 8;

    case "string":
    case "bytes":
    case "array":
      return WORD_SIZE;

    case "mapping":
      // HACK just to reserve slot. mappings have no size as such
      return WORD_SIZE;
  }
}

export function isMapping(definition) {
  return typeIdentifier(definition).match(/^t_mapping/) != null;
}

export function isReference(definition) {
  return typeIdentifier(definition).match(/_(memory|storage)(_ptr)?$/) != null;
}

export function referenceType(definition) {
  return typeIdentifier(definition).match(/_([^_]+)(_ptr)?$/)[1];
}

export function baseDefinition(definition) {
  let baseIdentifier = typeIdentifier(definition)
    // first dollar sign     last dollar sign
    //   `---------.       ,---'
    .match(/^[^$]+\$_(.+)_\$[^$]+$/)[1]
    //              `----' greedy match

  // HACK - internal types for memory or storage also seem to be pointers
  if (baseIdentifier.match(/_(memory|storage)$/) != null) {
    baseIdentifier = `${baseIdentifier}_ptr`;
  }

  // another HACK - we get away with it becausewe're only using that one property
  return {
    typeDescriptions: {
      typeIdentifier: baseIdentifier
    }
  };
}

export function toBigNumber(bytes) {
  if (bytes == undefined) {
    return undefined;
  } else if (typeof bytes == "string") {
    return new BigNumber(bytes, 16);
  } else if (typeof bytes == "number" || BigNumber.isBigNumber(bytes)) {
    return new BigNumber(bytes);
  } else if (bytes.reduce) {
    return bytes.reduce(
      (num, byte) => num.times(0x100).plus(byte),
      new BigNumber(0)
    );
  }
}

export function toSignedBigNumber(bytes) {
  if (bytes[0] < 0b10000000) {  // first bit is 0
    return toBigNumber(bytes);
  } else {
    return toBigNumber(bytes.map( (b) => 0xff - b )).plus(1).negated();
  }
}

/**
 * @param bytes - Uint8Array
 * @param length - desired byte length (pad with zeroes)
 * @param trim - omit leading zeroes
 */
export function toHexString(bytes, length = 0, trim = false) {
  if (typeof length == "boolean") {
    trim = length;
    length = 0;
  }

  if (BigNumber.isBigNumber(bytes)) {
    bytes = toBytes(bytes);
  }

  const pad = (s) => `${"00".slice(0, 2 - s.length)}${s}`

  //                                          0  1  2  3  4
  //                                 0  1  2  3  4  5  6  7
  // bytes.length:        5  -  0x(          e5 c2 aa 09 11 )
  // length (preferred):  8  -  0x( 00 00 00 e5 c2 aa 09 11 )
  //                                `--.---'
  //                                     offset 3
  if (bytes.length < length) {
    let prior = bytes;
    bytes = new Uint8Array(length);

    bytes.set(prior, length - prior.length);
  }

  debug("bytes: %o", bytes);

  let string = bytes.reduce(
    (str, byte) => `${str}${pad(byte.toString(16))}`, ""
  );

  if (trim) {
    string = string.replace(/^(00)+/, "");
  }

  if (string.length == 0) {
    string = "00";
  }

  return `0x${string}`;
}

export function toBytes(number, length = 0) {
  if (number < 0 || number === "") {
    return [];
  }

  let hex = number.toString(16);
  if (hex.length % 2 == 1) {
    hex = `0${hex}`;
  }

  let bytes = new Uint8Array(
    hex.match(/.{2}/g)
      .map( (byte) => parseInt(byte, 16) )
  );

  if (bytes.length < length) {
    let prior = bytes;
    bytes = new Uint8Array(length);
    bytes.set(prior, length - prior.length);
  }

  return bytes;
}

export function keccak256(...args) {
  let web3 = new Web3();

  debug("args %o", args);

  let sha = web3.utils.soliditySha3(...args);
  debug("sha %o", sha);
  return toBigNumber(sha);
}
<commit_msg>Remove unused argument<commit_after>import debugModule from "debug";
const debug = debugModule("debugger:data:decode:utils");

import { BigNumber } from "bignumber.js";
import Web3 from "web3";

export const WORD_SIZE = 0x20;
export const MAX_WORD = new BigNumber(2).pow(256).minus(1);

/**
 * recursively converts big numbers into something nicer to look at
 */
export function cleanBigNumbers(value) {
  if (BigNumber.isBigNumber(value)) {
    return value.toNumber();

  } else if (value && value.map != undefined) {
    return value.map( (inner) => cleanBigNumbers(inner) );

  } else if (value && typeof value == "object") {
    return Object.assign(
      {}, ...Object.entries(value)
        .map( ([key, inner]) => ({ [key]: cleanBigNumbers(inner) }) )
    );

  } else {
    return value;
  }
}

export function typeIdentifier(definition) {
  return definition.typeDescriptions.typeIdentifier;
}

/**
 * returns basic type class for a variable definition node
 * e.g.:
 *  `t_uint256` becomes `uint`
 *  `t_struct$_Thing_$20_memory_ptr` becomes `struct`
 */
export function typeClass(definition) {
  return typeIdentifier(definition).match(/t_([^$_0-9]+)/)[1];
}

/**
 * Allocate storage for given variable declarations
 *
 * Postcondition: starts a new slot and occupies whole slots
 */
export function allocateDeclarations(
  declarations,
  refs,
  slot = 0,
  index = WORD_SIZE - 1,
) {
  if (index < WORD_SIZE - 1) {  // starts a new slot
    slot++;
    index = WORD_SIZE - 1;
  }

  let parentFrom = { slot, index: 0 };
  var parentTo = { slot, index: WORD_SIZE - 1 };
  let mapping = {};

  for (let declaration of declarations) {
    let { from, to, next, children } =
      allocateDeclaration(declaration, refs, slot, index);

    mapping[declaration.id] = { from, to, name: declaration.name };
    if (children !== undefined) {
      mapping[declaration.id].children = children;
    }

    slot = next.slot;
    index = next.index;

    parentTo = { slot: to.slot, index: WORD_SIZE - 1 };
  }

  if (index < WORD_SIZE - 1) {
    slot++;
    index = WORD_SIZE - 1;
  }

  return {
    from: parentFrom,
    to: parentTo,
    next: { slot, index },
    children: mapping
  };
}

function allocateValue(slot, index, bytes) {
  slot = normalizeSlot(slot);

  let from = (index - bytes + 1 >= 0)
    ? { slot, index: index - bytes + 1 }
    : {
        slot: {
          path: slot.path,
          offset: slot.offset + 1
        },
        index: WORD_SIZE - bytes
      };

  let to = { slot: from.slot, index: from.index + bytes - 1 };

  let next = (from.index == 0)
    ? {
        slot: {
          path: from.slot.path,
          offset: from.slot.offset + 1
        },
        index: WORD_SIZE - 1
      }
    : { slot: from.slot, index: from.index - 1 };

  return { from, to, next };
}

function allocateDeclaration(declaration, refs, slot, index) {
  let definition = refs[declaration.id].definition;
  var byteSize = storageSize(definition);  // yum

  if (typeClass(definition) != "struct") {
    return allocateValue(slot, index, byteSize);
  }

  let struct = refs[definition.typeName.referencedDeclaration];
  debug("struct: %O", struct);

  let result =  allocateDeclarations(struct.variables || [], refs, slot, index);
  debug("struct result %o", result);
  return result;
}

/**
 * Convert polymorphic slot value into canonical { path, offset } pair.
 */
export function normalizeSlot(slot) {
  if (typeof slot == "object" && slot.path != undefined) {
    return {
      path: slot.path,
      offset: slot.offset || 0
    };
  }

  return {
    path: slot,
    offset: 0
  };
}

/**
 * e.g. uint48 -> 6
 * @return size in bytes for explicit type size, or `null` if not stated
 */
export function specifiedSize(definition) {
  let specified = typeIdentifier(definition).match(/t_[a-z]+([0-9]+)/);

  if (!specified) {
    return null;
  }

  let num = specified[1];

  switch (typeClass(definition)) {
    case "int":
    case "uint":
      return num / 8;

    case "bytes":
      return num;

    default:
      debug("Unknown type for size specification: %s", typeIdentifier(definition));
  }
}

export function storageSize(definition) {
  switch (typeClass(definition)) {
    case "bool":
      return 1;

    case "address":
      return 20;

    case "int":
    case "uint":
      // is this a HACK? ("256" / 8)
      return typeIdentifier(definition).match(/t_[a-z]+([0-9]+)/)[1] / 8;

    case "string":
    case "bytes":
    case "array":
      return WORD_SIZE;

    case "mapping":
      // HACK just to reserve slot. mappings have no size as such
      return WORD_SIZE;
  }
}

export function isMapping(definition) {
  return typeIdentifier(definition).match(/^t_mapping/) != null;
}

export function isReference(definition) {
  return typeIdentifier(definition).match(/_(memory|storage)(_ptr)?$/) != null;
}

export function referenceType(definition) {
  return typeIdentifier(definition).match(/_([^_]+)(_ptr)?$/)[1];
}

export function baseDefinition(definition) {
  let baseIdentifier = typeIdentifier(definition)
    // first dollar sign     last dollar sign
    //   `---------.       ,---'
    .match(/^[^$]+\$_(.+)_\$[^$]+$/)[1]
    //              `----' greedy match

  // HACK - internal types for memory or storage also seem to be pointers
  if (baseIdentifier.match(/_(memory|storage)$/) != null) {
    baseIdentifier = `${baseIdentifier}_ptr`;
  }

  // another HACK - we get away with it becausewe're only using that one property
  return {
    typeDescriptions: {
      typeIdentifier: baseIdentifier
    }
  };
}

export function toBigNumber(bytes) {
  if (bytes == undefined) {
    return undefined;
  } else if (typeof bytes == "string") {
    return new BigNumber(bytes, 16);
  } else if (typeof bytes == "number" || BigNumber.isBigNumber(bytes)) {
    return new BigNumber(bytes);
  } else if (bytes.reduce) {
    return bytes.reduce(
      (num, byte) => num.times(0x100).plus(byte),
      new BigNumber(0)
    );
  }
}

export function toSignedBigNumber(bytes) {
  if (bytes[0] < 0b10000000) {  // first bit is 0
    return toBigNumber(bytes);
  } else {
    return toBigNumber(bytes.map( (b) => 0xff - b )).plus(1).negated();
  }
}

/**
 * @param bytes - Uint8Array
 * @param length - desired byte length (pad with zeroes)
 * @param trim - omit leading zeroes
 */
export function toHexString(bytes, length = 0, trim = false) {
  if (typeof length == "boolean") {
    trim = length;
    length = 0;
  }

  if (BigNumber.isBigNumber(bytes)) {
    bytes = toBytes(bytes);
  }

  const pad = (s) => `${"00".slice(0, 2 - s.length)}${s}`

  //                                          0  1  2  3  4
  //                                 0  1  2  3  4  5  6  7
  // bytes.length:        5  -  0x(          e5 c2 aa 09 11 )
  // length (preferred):  8  -  0x( 00 00 00 e5 c2 aa 09 11 )
  //                                `--.---'
  //                                     offset 3
  if (bytes.length < length) {
    let prior = bytes;
    bytes = new Uint8Array(length);

    bytes.set(prior, length - prior.length);
  }

  debug("bytes: %o", bytes);

  let string = bytes.reduce(
    (str, byte) => `${str}${pad(byte.toString(16))}`, ""
  );

  if (trim) {
    string = string.replace(/^(00)+/, "");
  }

  if (string.length == 0) {
    string = "00";
  }

  return `0x${string}`;
}

export function toBytes(number, length = 0) {
  if (number < 0 || number === "") {
    return [];
  }

  let hex = number.toString(16);
  if (hex.length % 2 == 1) {
    hex = `0${hex}`;
  }

  let bytes = new Uint8Array(
    hex.match(/.{2}/g)
      .map( (byte) => parseInt(byte, 16) )
  );

  if (bytes.length < length) {
    let prior = bytes;
    bytes = new Uint8Array(length);
    bytes.set(prior, length - prior.length);
  }

  return bytes;
}

export function keccak256(...args) {
  let web3 = new Web3();

  debug("args %o", args);

  let sha = web3.utils.soliditySha3(...args);
  debug("sha %o", sha);
  return toBigNumber(sha);
}
<|endoftext|>


<commit_before>'use strict';
// A general purpose logging service that can be used anywhere in the app

/**
 * Module dependencies.
 */
var path = require('path'),
    _ = require('lodash'),
    winston = require('winston'),
    config = require(path.resolve('./config/config'));

// Requiring `winston-papertrail` will expose
// `winston.transports.Papertrail`
require('winston-papertrail').Papertrail;

var papertrailConfig = _.get(config, 'log.papertrail');

// Add the `logFormat()` function to the papertrail config
papertrailConfig.logFormat = function(level, message) {
  return level + ': ' + message;
}

// If there we have a host and port for papertrail, then configure it
if (papertrailConfig.host && papertrailConfig.port) {
  // Add and instantiate the papertrail transport
  winston.add(winston.transports.Papertrail, papertrailConfig);
  // NOTE: We don't instantiate the papertrail transport, the call to `.add()`
  // does that on its own.
}

// Log that the logger has been instantiated
winston.log('info', 'Logger started #a5fKSK');

// We export `winston.log` so we can use `logger('info', ...)` etc
module.exports = winston.log;
<commit_msg>Another missing semicolon. #444<commit_after>'use strict';
// A general purpose logging service that can be used anywhere in the app

/**
 * Module dependencies.
 */
var path = require('path'),
    _ = require('lodash'),
    winston = require('winston'),
    config = require(path.resolve('./config/config'));

// Requiring `winston-papertrail` will expose
// `winston.transports.Papertrail`
require('winston-papertrail').Papertrail;

var papertrailConfig = _.get(config, 'log.papertrail');

// Add the `logFormat()` function to the papertrail config
papertrailConfig.logFormat = function(level, message) {
  return level + ': ' + message;
};

// If there we have a host and port for papertrail, then configure it
if (papertrailConfig.host && papertrailConfig.port) {
  // Add and instantiate the papertrail transport
  winston.add(winston.transports.Papertrail, papertrailConfig);
  // NOTE: We don't instantiate the papertrail transport, the call to `.add()`
  // does that on its own.
}

// Log that the logger has been instantiated
winston.log('info', 'Logger started #a5fKSK');

// We export `winston.log` so we can use `logger('info', ...)` etc
module.exports = winston.log;
<|endoftext|>


<commit_before>import React, { Component } from 'react';

import {
	addComponent,
	removeComponent,
	watchComponent,
	updateQuery,
} from '@appbaseio/reactivecore/lib/actions';
import {
	checkValueChange,
	checkPropChange,
	getClassName,
	handleA11yAction,
	isEqual,
} from '@appbaseio/reactivecore/lib/utils/helper';
import types from '@appbaseio/reactivecore/lib/utils/types';

import Title from '../../styles/Title';
import StarRating from './addons/StarRating';
import { ratingsList } from '../../styles/ratingsList';
import { connect } from '../../utils';

class RatingsFilter extends Component {
	constructor(props) {
		super(props);

		this.type = 'range';
		this.state = {
			currentValue: null,
		};
		this.locked = false;
	}

	componentWillMount() {
		this.props.addComponent(this.props.componentId);
		this.setReact(this.props);

		if (this.props.selectedValue) {
			this.setValue(this.props.selectedValue);
		} else if (this.props.defaultSelected) {
			this.setValue([
				this.props.defaultSelected.start,
				this.props.defaultSelected.end,
			]);
		}
	}

	componentWillReceiveProps(nextProps) {
		checkPropChange(this.props.react, nextProps.react, () => {
			this.setReact(nextProps);
		});

		checkPropChange(this.props.dataField, nextProps.dataField, () => {
			this.updateQuery(this.state.currentValue, nextProps);
		});

		if (!isEqual(this.props.defaultSelected, nextProps.defaultSelected)) {
			this.setValue(
				nextProps.defaultSelected
					? [
						nextProps.defaultSelected.start,
						nextProps.defaultSelected.end,
					]
					: null,
				nextProps,
			);
		} else if (!isEqual(this.state.currentValue, nextProps.selectedValue)) {
			this.setValue(nextProps.selectedValue || null, nextProps);
		}
	}

	componentWillUnmount() {
		this.props.removeComponent(this.props.componentId);
	}

	setReact(props) {
		if (props.react) {
			props.watchComponent(props.componentId, props.react);
		}
	}

	defaultQuery = (value, props) => {
		if (value) {
			return {
				range: {
					[props.dataField]: {
						gte: value[0],
						lte: value[1],
						boost: 2.0,
					},
				},
			};
		}
		return null;
	}

	setValue = (value, props = this.props) => {
		// ignore state updates when component is locked
		if (props.beforeValueChange && this.locked) {
			return;
		}

		this.locked = true;
		const performUpdate = () => {
			this.setState({
				currentValue: value,
			}, () => {
				this.updateQuery(value, props);
				this.locked = false;
			});
		};
		checkValueChange(
			props.componentId,
			value,
			props.beforeValueChange,
			props.onValueChange,
			performUpdate,
		);
	};

	updateQuery = (value, props) => {
		const query = props.customQuery || this.defaultQuery;

		const { onQueryChange = null } = props;

		props.updateQuery({
			componentId: props.componentId,
			query: query(value, props),
			value,
			label: props.filterLabel,
			showFilter: false,
			onQueryChange,
			URLParams: props.URLParams,
		});
	};

	render() {
		return (

				{this.props.title && <Title className={getClassName(this.props.innerClass, 'title') || null}>{this.props.title}</Title>}

					{
						this.props.data.map(item => (

 this.setValue([item.start, item.end])}
								onKeyPress={e => handleA11yAction(e, () => this.setValue([item.start, item.end]))}
								key={item.label}
							>
								<StarRating stars={item.start} />
								{
									item.label
										? ({item.label})
										: null
								}

						))
					}

		);
	}
}

RatingsFilter.propTypes = {
	addComponent: types.funcRequired,
	removeComponent: types.funcRequired,
	updateQuery: types.funcRequired,
	watchComponent: types.funcRequired,
	selectedValue: types.selectedValue,
	// component props
	beforeValueChange: types.func,
	className: types.string,
	componentId: types.stringRequired,
	customQuery: types.func,
	data: types.data,
	dataField: types.stringRequired,
	defaultSelected: types.range,
	filterLabel: types.string,
	innerClass: types.style,
	onQueryChange: types.func,
	onValueChange: types.func,
	react: types.react,
	style: types.style,
	title: types.title,
	URLParams: types.boolRequired,
};

RatingsFilter.defaultProps = {
	className: null,
	style: {},
	URLParams: false,
};

const mapStateToProps = (state, props) => ({
	selectedValue: (state.selectedValues[props.componentId]
		&& state.selectedValues[props.componentId].value) || null,
});

const mapDispatchtoProps = dispatch => ({
	addComponent: component => dispatch(addComponent(component)),
	removeComponent: component => dispatch(removeComponent(component)),
	updateQuery: updateQueryObject => dispatch(updateQuery(updateQueryObject)),
	watchComponent: (component, react) => dispatch(watchComponent(component, react)),
});

export default connect(mapStateToProps, mapDispatchtoProps)(RatingsFilter);
<commit_msg>web: fix #266 keys in RatingsFilter<commit_after>import React, { Component } from 'react';

import {
	addComponent,
	removeComponent,
	watchComponent,
	updateQuery,
} from '@appbaseio/reactivecore/lib/actions';
import {
	checkValueChange,
	checkPropChange,
	getClassName,
	handleA11yAction,
	isEqual,
} from '@appbaseio/reactivecore/lib/utils/helper';
import types from '@appbaseio/reactivecore/lib/utils/types';

import Title from '../../styles/Title';
import StarRating from './addons/StarRating';
import { ratingsList } from '../../styles/ratingsList';
import { connect } from '../../utils';

class RatingsFilter extends Component {
	constructor(props) {
		super(props);

		this.type = 'range';
		this.state = {
			currentValue: null,
		};
		this.locked = false;
	}

	componentWillMount() {
		this.props.addComponent(this.props.componentId);
		this.setReact(this.props);

		if (this.props.selectedValue) {
			this.setValue(this.props.selectedValue);
		} else if (this.props.defaultSelected) {
			this.setValue([
				this.props.defaultSelected.start,
				this.props.defaultSelected.end,
			]);
		}
	}

	componentWillReceiveProps(nextProps) {
		checkPropChange(this.props.react, nextProps.react, () => {
			this.setReact(nextProps);
		});

		checkPropChange(this.props.dataField, nextProps.dataField, () => {
			this.updateQuery(this.state.currentValue, nextProps);
		});

		if (!isEqual(this.props.defaultSelected, nextProps.defaultSelected)) {
			this.setValue(
				nextProps.defaultSelected
					? [
						nextProps.defaultSelected.start,
						nextProps.defaultSelected.end,
					]
					: null,
				nextProps,
			);
		} else if (!isEqual(this.state.currentValue, nextProps.selectedValue)) {
			this.setValue(nextProps.selectedValue || null, nextProps);
		}
	}

	componentWillUnmount() {
		this.props.removeComponent(this.props.componentId);
	}

	setReact(props) {
		if (props.react) {
			props.watchComponent(props.componentId, props.react);
		}
	}

	defaultQuery = (value, props) => {
		if (value) {
			return {
				range: {
					[props.dataField]: {
						gte: value[0],
						lte: value[1],
						boost: 2.0,
					},
				},
			};
		}
		return null;
	}

	setValue = (value, props = this.props) => {
		// ignore state updates when component is locked
		if (props.beforeValueChange && this.locked) {
			return;
		}

		this.locked = true;
		const performUpdate = () => {
			this.setState({
				currentValue: value,
			}, () => {
				this.updateQuery(value, props);
				this.locked = false;
			});
		};
		checkValueChange(
			props.componentId,
			value,
			props.beforeValueChange,
			props.onValueChange,
			performUpdate,
		);
	};

	updateQuery = (value, props) => {
		const query = props.customQuery || this.defaultQuery;

		const { onQueryChange = null } = props;

		props.updateQuery({
			componentId: props.componentId,
			query: query(value, props),
			value,
			label: props.filterLabel,
			showFilter: false,
			onQueryChange,
			URLParams: props.URLParams,
		});
	};

	render() {
		return (

				{this.props.title && <Title className={getClassName(this.props.innerClass, 'title') || null}>{this.props.title}</Title>}

					{
						this.props.data.map(item => (

 this.setValue([item.start, item.end])}
								onKeyPress={e => handleA11yAction(e, () => this.setValue([item.start, item.end]))}
								key={`${this.props.componentId}-${item.start}-${item.end}`}
							>
								<StarRating stars={item.start} />
								{
									item.label
										? ({item.label})
										: null
								}

						))
					}

		);
	}
}

RatingsFilter.propTypes = {
	addComponent: types.funcRequired,
	removeComponent: types.funcRequired,
	updateQuery: types.funcRequired,
	watchComponent: types.funcRequired,
	selectedValue: types.selectedValue,
	// component props
	beforeValueChange: types.func,
	className: types.string,
	componentId: types.stringRequired,
	customQuery: types.func,
	data: types.data,
	dataField: types.stringRequired,
	defaultSelected: types.range,
	filterLabel: types.string,
	innerClass: types.style,
	onQueryChange: types.func,
	onValueChange: types.func,
	react: types.react,
	style: types.style,
	title: types.title,
	URLParams: types.boolRequired,
};

RatingsFilter.defaultProps = {
	className: null,
	style: {},
	URLParams: false,
};

const mapStateToProps = (state, props) => ({
	selectedValue: (state.selectedValues[props.componentId]
		&& state.selectedValues[props.componentId].value) || null,
});

const mapDispatchtoProps = dispatch => ({
	addComponent: component => dispatch(addComponent(component)),
	removeComponent: component => dispatch(removeComponent(component)),
	updateQuery: updateQueryObject => dispatch(updateQuery(updateQueryObject)),
	watchComponent: (component, react) => dispatch(watchComponent(component, react)),
});

export default connect(mapStateToProps, mapDispatchtoProps)(RatingsFilter);
<|endoftext|>


<commit_before>
 /* jshint multistr: true */
(function ($) {

    var sidebar = '

Media gallery
<input placeholder="Search..." id="gallery-filter" type="text" class="form-control">

Drag and drop or click to upload Media

</div';
    var sidebar_size = 200;
    var loaded = false;
    var initialized = false;
    var id= null;
    var toggle_button = null;
    var count = 0;

    var modal = '
\

\

\

\
        <button type="button" class="close" data-dismiss="modal">×Close</button>\

Modal title
\

\

\
        <video src="" id="modal-video" controls style="width:100%" preload="auto"></video>\

\

\
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>\
        <button type="button" class="btn btn-primary">Save changes</button>\

\

\

\

';

    function SidebarGallery(options){
        this.options = options;
        this._init();
        Dropzone.autoDiscover = false;
    }

    function notify_user(descr, level){
        $('body').prepend('
'+ descr + '
');
        setTimeout(function(){
            $('.notify-user-label').remove();
        }, 5000);
    }

    function update_progress_info() {
        $.getJSON("/get-progress/upload/", {'X-Progress-ID': id}, function(data, status){
            if(data){
                $('#progress-span').text((data.uploaded /data.lenght)*100);
            }
            else{
                $('#progress-span').text(100);
                return false;
            }
            setTimeout(update_progress_info, 10);
        });
    }

    SidebarGallery.prototype = {

        _init: function(){
            _this = this;

            if (_this.options.toggle){
                toggle_button = _this.options.toggle;
            }else{
                toggle_button = '<button class="btn btn-default" id="btn-toggle">Gallery</button>';
            }

            $('body').append(toggle_button).append(sidebar);
            $('body').wrapInner('

');
            $(document).on('click','#btn-toggle', _this._toggle_sidebar);
            $(document).on('keyup', '#gallery-filter', _this.filterImage);
            $(document).on('start_upload', function(){

                setTimeout(update_progress_info, 20);
            });

            $(document).on('editInputVisible', function(){
                $('#input_editor').droppable({
                    drop: function(event, ui){
                        var droppable = $(this);
                        var draggable = ui.draggable;
                        droppable.focus();
                        droppable.selection('insert',{text:'![Alt text]('+ draggable.attr('src') +')' ,mode:'before'});
                        $(ui.helper).remove();
                        $('#input_editor').trigger('autosize.resize');
                    }
                });
            });

            $('.droppable-image').droppable({
                drop: function( event, ui ) {
                    var droppable = $(this);
                    if (droppable.prop("tagName") == 'IMG'){

                        if (ui.draggable.attr('src').indexOf(".png") > 0 || ui.draggable.attr('src').indexOf(".jpg") > 0){
                            droppable.attr('src', ui.draggable.attr('src'));
                            $(ui.helper).remove();
                            _this.saveImage(droppable);
                        }else{
                            notify_user("You can't put other file than image in this place", 'error');
                        }
                    }else if (droppable.prop("tagName") == 'VIDEO'){
                        if (ui.draggable.attr('src').indexOf(".mp4") > 0){
                            droppable.attr('src', ui.draggable.attr('src'));
                            $(ui.helper).remove();
                            _this.saveImage(droppable);
                        }else{
                            notify_user("You can't put other file than video in this place", 'error');
                        }
                    }
              }
            });

            var DocDropzone = new Dropzone('#media-container', { // Make the whole body a dropzone
                paramName: 'file',
                url: _this.options.base_media_url,
                maxFilesize: 50,
                parallelUploads: 2,
                clickable: true,
                createImageThumbnails:false,
            });

            DocDropzone.on("processing", function(file){
                id = (new Date()).getTime();
                this.options.url = _this.options.base_media_url + '?X-Progress-ID=' +id;
            });

            DocDropzone.on("cancel", function(file){
                $('.progress-text').remove();
            });

            DocDropzone.on("sending", function(file, xhr, formData){
                formData.append('csrfmiddlewaretoken', _this.options.csrf_token);
                formData.append('csrfmiddlewaretoken', _this.options.csrf_token);
                $('#media-container').append('
Upload in progress

0%
Please wait...
');
                $.event.trigger({
                  type:    "start_upload",
                  message: "myTrigger fired.",
                  time:    new Date()
                });
            });

            DocDropzone.on("dragover", function(event){
                if (count == 0){
                    $('body').prepend('
Release your file to upload it
');
                    count = 1;
                }
            });

            DocDropzone.on("drop", function(event){
                $('.notify-user-label').remove();
                count = 0;
            });

            DocDropzone.on("dragleave", function(event){
                $('.notify-user-label').remove();
                count = 0;
            });

            DocDropzone.on("success", function(data, response){
                $('.progress-text').remove();
                $('.dz-preview').remove();
                var last_index = $('#list-media').children().last().children().attr('id');
                if (last_index){
                    last_index = parseInt(last_index.split('image_')[1]) + 1;
                }else{
                    last_index = 0;
                }
                if (!response.exist){
                    if (response.uploaded_file_temp.indexOf('.mp4') > 0){
                        $('#list-media').append('
<video data-id="'+ response.id + '" id="image_'+ last_index + '" class="image  clickable-menu image_media" src="'+ response.uploaded_file_temp +'" width="50px"></video>
');
                    }else{
                        $('#list-media').append('

');
                    }

                    $('#image_' + last_index).draggable({
                        helper: 'clone',
                        revert: true,
                        appendTo: "body",
                        start: function() {
                            $(".ui-draggable").not(this).css({
                                width: 50
                            });
                        },
                    });
                    _this.makemenu();
                    var descr = "We're processing your uploaded file. You can start use it by using the sample in your gallery.";
                    notify_user(descr, 'info');
                }else{
                    $('#media-container').append('
Image already in your gallery
');
                    setTimeout(function() {
                        $('.alert').remove();
                    }, 3000);

                }
                if (!$('#sidebar-gallery').hasClass('active')){
                    _this._open_sidebar();
                }
            });
        },

        saveImage: function(element){
            id_element = element.attr('id');
            data = {text: element.attr('src')};
            $.ajax({
                method:'PUT',
                async:false,
                url: _this.options.base_save_url + id_element +'/',
                data:data,
                success: function(data){
                    console.log('saved');
                }
            });
        },

        _toggle_sidebar: function(){

            if ($('#sidebar-gallery').hasClass('active')){
                _this._close_sidebar();
            }else{
                _this._open_sidebar();
            }
        },

        _open_sidebar: function(){
            var width_wrap = $('#gallery-wrapper').css('width').split('px')[0];
            $('#btn-toggle').addClass('active');
            $('#sidebar-gallery').addClass('active');
            $('#gallery-wrapper').css({'max-width':width_wrap - sidebar_size});
            $('.row').css({'padding-right':'30px'});
            $('.row').css({'padding-left':'30px'});
            $('.row').css({'margin-right':'30px'});
            _this.loadImage();
        },

        _close_sidebar: function(){
            var width_wrap = $('#gallery-wrapper').css('width').split('px')[0];
            $('#sidebar-gallery').removeClass('active');
            $('#btn-toggle').removeClass('active');
            $('#gallery-wrapper').css({'max-width': '100%'});
            $('.row').css({'padding-right':'0px'});
            $('.row').css({'padding-left':'0px'});
            $('.row').css({'margin-right':'0px'});
            $('.row').css({'margin-left':'0px'});
            $('.image-gallery').remove();
        },

        filterImage: function(){
            var search_string = $(this).val();
            _this.loadImage(search_string);
        },

        loadImage: function(search){
            if (!search){
                search = "";
            }
            $('#list-media').empty();
            $.ajax({
                method:'GET',
                url:_this.options.base_media_url + '?search='+search,
                success: function(data){
                    $.each(data, function(index,element){
                        var src_file = null;
                        if (element.file_src){
                            src_file = element.file_src;
                        }else{
                            src_file = element.file_src_temp;
                        }
                        if (src_file.indexOf('.mp4') > 0){
                            $('#list-media').append('

');
                        }else{
                            $('#list-media').append('

');
                        }
                        // $('#list-images').append('

');
                        $('#image_' + index).draggable({
                            helper: 'clone',
                            revert: true,
                            appendTo: "body",
                            start: function() {
                                $(".ui-draggable").not(this).css({
                                    // height: 50,
                                    width: 50
                                });
                            },
                        });
                    });
                }
            });
            _this.makemenu();
        },

        makemenu: function(){
            $(document).contextmenu({
                delegate: ".clickable-menu",
                menu: [
                    {title: "Delete", cmd: "delete_media"},
                    {title: "Add tag", cmd: "add_tag"},
                    {title: "Preview Video", cmd: "preview_video" }
                    ],
                select: function(event, ui) {
                    var id = $(ui.target).data('id');
                    if (ui.cmd == 'delete_media'){
                        $.ajax({
                            method: 'delete',
                            url:_this.options.base_media_url +id +'/',
                            success: function(){
                                $(ui.target).parent('.col-md-6').remove();
                            }
                        });
                    }else if (ui.cmd == 'add_tag'){
                        var orginal_tags = null;
                        $.ajax({
                            method: 'get',
                            async:false,
                            url:_this.options.base_media_url+id+'/',
                            success: function(response){
                                orginal_tags = response.tags;
                            }
                        });

                        var tags = prompt('Please enter tags', orginal_tags);
                        if (tags !== null){
                            $.ajax({
                                method: 'patch',
                                url:_this.options.base_media_url+id+'/',
                                data:{'tags': tags},
                                success: function(){
                                    console.log('updated');
                                }
                            });
                        }

                    }else if (ui.cmd == 'preview_video'){
                        $('body').append(modal);
                        $('#modal-video').attr('src',$(ui.target).attr('src'));
                        $('#myModal').modal('show');
                    }
                }
            });
        }

    };

    $.sidebargallery = function(options) {
        var opts = $.extend( {}, $.sidebargallery.defaults, options );
        gallery = new SidebarGallery(options);
    };

    $.sidebargallery.defaults = {
        base_save_url: null, // Url to send request to server
        csrf_token:'',
        base_media_url:'',
        toggle: null
    };
})(jQuery);<commit_msg>fix djaodjin-sidebar non closed tag<commit_after>
 /* jshint multistr: true */
(function ($) {

    var sidebar = '

Media gallery
<input placeholder="Search..." id="gallery-filter" type="text" class="form-control">

Drag and drop or click to upload Media

';
    var sidebar_size = 200;
    var loaded = false;
    var initialized = false;
    var id= null;
    var toggle_button = null;
    var count = 0;

    var modal = '
\

\

\

\
        <button type="button" class="close" data-dismiss="modal">×Close</button>\

Modal title
\

\

\
        <video src="" id="modal-video" controls style="width:100%" preload="auto"></video>\

\

\
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>\
        <button type="button" class="btn btn-primary">Save changes</button>\

\

\

\

';

    function SidebarGallery(options){
        this.options = options;
        this._init();
        Dropzone.autoDiscover = false;
    }

    function notify_user(descr, level){
        $('body').prepend('
'+ descr + '
');
        setTimeout(function(){
            $('.notify-user-label').remove();
        }, 5000);
    }

    function update_progress_info() {
        $.getJSON("/get-progress/upload/", {'X-Progress-ID': id}, function(data, status){
            if(data){
                $('#progress-span').text((data.uploaded /data.lenght)*100);
            }
            else{
                $('#progress-span').text(100);
                return false;
            }
            setTimeout(update_progress_info, 10);
        });
    }

    SidebarGallery.prototype = {

        _init: function(){
            _this = this;

            if (_this.options.toggle){
                toggle_button = _this.options.toggle;
            }else{
                toggle_button = '<button class="btn btn-default" id="btn-toggle">Gallery</button>';
            }

            $('body').append(toggle_button).append(sidebar);
            $('body').wrapInner('

');
            $(document).on('click','#btn-toggle', _this._toggle_sidebar);
            $(document).on('keyup', '#gallery-filter', _this.filterImage);
            $(document).on('start_upload', function(){

                setTimeout(update_progress_info, 20);
            });

            $(document).on('editInputVisible', function(){
                $('#input_editor').droppable({
                    drop: function(event, ui){
                        var droppable = $(this);
                        var draggable = ui.draggable;
                        droppable.focus();
                        droppable.selection('insert',{text:'![Alt text]('+ draggable.attr('src') +')' ,mode:'before'});
                        $(ui.helper).remove();
                        $('#input_editor').trigger('autosize.resize');
                    }
                });
            });

            $('.droppable-image').droppable({
                drop: function( event, ui ) {
                    var droppable = $(this);
                    if (droppable.prop("tagName") == 'IMG'){

                        if (ui.draggable.attr('src').indexOf(".png") > 0 || ui.draggable.attr('src').indexOf(".jpg") > 0){
                            droppable.attr('src', ui.draggable.attr('src'));
                            $(ui.helper).remove();
                            _this.saveImage(droppable);
                        }else{
                            notify_user("You can't put other file than image in this place", 'error');
                        }
                    }else if (droppable.prop("tagName") == 'VIDEO'){
                        if (ui.draggable.attr('src').indexOf(".mp4") > 0){
                            droppable.attr('src', ui.draggable.attr('src'));
                            $(ui.helper).remove();
                            _this.saveImage(droppable);
                        }else{
                            notify_user("You can't put other file than video in this place", 'error');
                        }
                    }
              }
            });

            var DocDropzone = new Dropzone('#media-container', { // Make the whole body a dropzone
                paramName: 'file',
                url: _this.options.base_media_url,
                maxFilesize: 50,
                parallelUploads: 2,
                clickable: true,
                createImageThumbnails:false,
            });

            DocDropzone.on("processing", function(file){
                id = (new Date()).getTime();
                this.options.url = _this.options.base_media_url + '?X-Progress-ID=' +id;
            });

            DocDropzone.on("cancel", function(file){
                $('.progress-text').remove();
            });

            DocDropzone.on("sending", function(file, xhr, formData){
                formData.append('csrfmiddlewaretoken', _this.options.csrf_token);
                formData.append('csrfmiddlewaretoken', _this.options.csrf_token);
                $('#media-container').append('
Upload in progress

0%
Please wait...
');
                $.event.trigger({
                  type:    "start_upload",
                  message: "myTrigger fired.",
                  time:    new Date()
                });
            });

            DocDropzone.on("dragover", function(event){
                if (count == 0){
                    $('body').prepend('
Release your file to upload it
');
                    count = 1;
                }
            });

            DocDropzone.on("drop", function(event){
                $('.notify-user-label').remove();
                count = 0;
            });

            DocDropzone.on("dragleave", function(event){
                $('.notify-user-label').remove();
                count = 0;
            });

            DocDropzone.on("success", function(data, response){
                $('.progress-text').remove();
                $('.dz-preview').remove();
                var last_index = $('#list-media').children().last().children().attr('id');
                if (last_index){
                    last_index = parseInt(last_index.split('image_')[1]) + 1;
                }else{
                    last_index = 0;
                }
                if (!response.exist){
                    if (response.uploaded_file_temp.indexOf('.mp4') > 0){
                        $('#list-media').append('
<video data-id="'+ response.id + '" id="image_'+ last_index + '" class="image  clickable-menu image_media" src="'+ response.uploaded_file_temp +'" width="50px"></video>
');
                    }else{
                        $('#list-media').append('

');
                    }

                    $('#image_' + last_index).draggable({
                        helper: 'clone',
                        revert: true,
                        appendTo: "body",
                        start: function() {
                            $(".ui-draggable").not(this).css({
                                width: 50
                            });
                        },
                    });
                    _this.makemenu();
                    var descr = "We're processing your uploaded file. You can start use it by using the sample in your gallery.";
                    notify_user(descr, 'info');
                }else{
                    $('#media-container').append('
Image already in your gallery
');
                    setTimeout(function() {
                        $('.alert').remove();
                    }, 3000);

                }
                if (!$('#sidebar-gallery').hasClass('active')){
                    _this._open_sidebar();
                }
            });
        },

        saveImage: function(element){
            id_element = element.attr('id');
            data = {text: element.attr('src')};
            $.ajax({
                method:'PUT',
                async:false,
                url: _this.options.base_save_url + id_element +'/',
                data:data,
                success: function(data){
                    console.log('saved');
                }
            });
        },

        _toggle_sidebar: function(){

            if ($('#sidebar-gallery').hasClass('active')){
                _this._close_sidebar();
            }else{
                _this._open_sidebar();
            }
        },

        _open_sidebar: function(){
            var width_wrap = $('#gallery-wrapper').css('width').split('px')[0];
            $('#btn-toggle').addClass('active');
            $('#sidebar-gallery').addClass('active');
            $('#gallery-wrapper').css({'max-width':width_wrap - sidebar_size});
            $('.row').css({'padding-right':'30px'});
            $('.row').css({'padding-left':'30px'});
            $('.row').css({'margin-right':'30px'});
            _this.loadImage();
        },

        _close_sidebar: function(){
            var width_wrap = $('#gallery-wrapper').css('width').split('px')[0];
            $('#sidebar-gallery').removeClass('active');
            $('#btn-toggle').removeClass('active');
            $('#gallery-wrapper').css({'max-width': '100%'});
            $('.row').css({'padding-right':'0px'});
            $('.row').css({'padding-left':'0px'});
            $('.row').css({'margin-right':'0px'});
            $('.row').css({'margin-left':'0px'});
            $('.image-gallery').remove();
        },

        filterImage: function(){
            var search_string = $(this).val();
            _this.loadImage(search_string);
        },

        loadImage: function(search){
            if (!search){
                search = "";
            }
            $('#list-media').empty();
            $.ajax({
                method:'GET',
                url:_this.options.base_media_url + '?search='+search,
                success: function(data){
                    $.each(data, function(index,element){
                        var src_file = null;
                        if (element.file_src){
                            src_file = element.file_src;
                        }else{
                            src_file = element.file_src_temp;
                        }
                        if (src_file.indexOf('.mp4') > 0){
                            $('#list-media').append('

');
                        }else{
                            $('#list-media').append('

');
                        }
                        // $('#list-images').append('

');
                        $('#image_' + index).draggable({
                            helper: 'clone',
                            revert: true,
                            appendTo: "body",
                            start: function() {
                                $(".ui-draggable").not(this).css({
                                    // height: 50,
                                    width: 50
                                });
                            },
                        });
                    });
                }
            });
            _this.makemenu();
        },

        makemenu: function(){
            $(document).contextmenu({
                delegate: ".clickable-menu",
                menu: [
                    {title: "Delete", cmd: "delete_media"},
                    {title: "Add tag", cmd: "add_tag"},
                    {title: "Preview Video", cmd: "preview_video" }
                    ],
                select: function(event, ui) {
                    var id = $(ui.target).data('id');
                    if (ui.cmd == 'delete_media'){
                        $.ajax({
                            method: 'delete',
                            url:_this.options.base_media_url +id +'/',
                            success: function(){
                                $(ui.target).parent('.col-md-6').remove();
                            }
                        });
                    }else if (ui.cmd == 'add_tag'){
                        var orginal_tags = null;
                        $.ajax({
                            method: 'get',
                            async:false,
                            url:_this.options.base_media_url+id+'/',
                            success: function(response){
                                orginal_tags = response.tags;
                            }
                        });

                        var tags = prompt('Please enter tags', orginal_tags);
                        if (tags !== null){
                            $.ajax({
                                method: 'patch',
                                url:_this.options.base_media_url+id+'/',
                                data:{'tags': tags},
                                success: function(){
                                    console.log('updated');
                                }
                            });
                        }

                    }else if (ui.cmd == 'preview_video'){
                        $('body').append(modal);
                        $('#modal-video').attr('src',$(ui.target).attr('src'));
                        $('#myModal').modal('show');
                    }
                }
            });
        }

    };

    $.sidebargallery = function(options) {
        var opts = $.extend( {}, $.sidebargallery.defaults, options );
        gallery = new SidebarGallery(options);
    };

    $.sidebargallery.defaults = {
        base_save_url: null, // Url to send request to server
        csrf_token:'',
        base_media_url:'',
        toggle: null
    };
})(jQuery);<|endoftext|>


<commit_before>var http = require("http");
var querystring = require("querystring");

// callback || noop borrowed from node/lib/fs.js
function noop() {};

var Client = function(host, port, core, path) {
  this.host = host || "127.0.0.1";
  this.port = port || "8983";
  this.fullHost = this.host + ":" + this.port;
  this.core = core || ""; // if defined, should begin with a slash
  this.path = path || "solr";
};

Client.prototype.add = function(doc, options, callback) {
  if (callback === undefined) {
    callback = options;
    options = {};
  }
  options = options || {};
  var addParams = {};
  if (options.overwrite !== undefined) {
    addParams["overwrite"] = Boolean(options.overwrite);
  }
  if (options.commitWithin !== undefined) {
    addParams["commitWithin"] = options.commitWithin;
  }
  if (options.commit !== undefined) {
    addParams["commit"] = Boolean(options.commit);
  }
  var data = "<add>";
  var docs = Array.isArray(doc) ? doc : [doc];
  for (var i = 0; i < docs.length; i++) {
    data += "<doc>";
    var doc = docs[i];
    for (field in doc) if (doc.hasOwnProperty(field)) {
      value = doc[field];
      if (!Array.isArray(value)) {
        data += serializeScalar(field, value);
      } else {
        data += serializeList(field, value);
      }
    }
    data += "</doc>";
  }
  data += "</add>";
  this.update(data, callback);
};

Client.prototype.commit = function(callback) {
  var data = "<commit/>";
  this.update(data, callback);
};

Client.prototype.del = function(id, query, callback) {
  var data = "<delete>";
  if (id) {
    if (Array.isArray(id)) {
      for (var i=0; i<id.length; i++) {
        data = data + "<id>" + id[i] + "</id>";
      }
    } else {
      data = data + "<id>" + id + "</id>";
    }
  }
  if (query) {
    if (Array.isArray(query)) {
      for (var i=0; i<query.length; i++) {
        data = data + "<query>" + query[i] + "</query>";
      }
    } else {
      data = data + "<query>" + query + "</query>";
    }
  }
  data = data + "</delete>";
  this.update(data, callback);
};

Client.prototype.optimize = function(callback) {
  var data = "<optimize/>";
  this.update(data, callback);
};

Client.prototype.query = function(query, options, callback) {
  if (callback === undefined) {
    callback = options;
    options = {};
  }
  var queryParams = options || {};
  queryParams.q = query;
  queryParams.wt = "json";
  queryParams = querystring.stringify(queryParams, '&', '=', false);
  this.rawQuery(queryParams, callback);
};

Client.prototype.rawQuery = function(queryParams, callback) {
  var queryPath, options;
  queryPath = "/" + this.path + this.core + "/select?";
  options = {
    method: "GET",
    path: queryPath + queryParams,
    headers: {
      "Host": this.fullHost
    }
  };
  this.sendRequest(options, callback || noop);
};

Client.prototype.rollback = function(callback) {
  var data = "<rollback/>";
  this.update(data, callback);
};

Client.prototype.update = function(data, callback) {
  var updatePath, options;
  updatePath = "/" + this.path + this.core + "/update";
  options = {
    method: "POST",
    path: updatePath,
    headers: {
      // Keep-Alive needed for Node v0.2.4 and v0.2.5, but sometimes
      // leaves connection hanging that must be manually destroyed
      // http://groups.google.com/group/nodejs-dev/browse_thread/thread/e9044c0778ac67d0
      //"Connection": "Keep-Alive",
      "Content-Length": Buffer.byteLength(data),
      "Host": this.fullHost
    },
    data: data,
  };
  this.sendRequest(options, callback || noop);
};

exports.getStatus = function(statusMessage) {
  if (!statusMessage) {
    return 1;
  }
  var statusTag = '<int name="status">';
  return statusMessage.charAt(statusMessage.indexOf(statusTag) +
      statusTag.length);
};

exports.getError = function(errorMessage) {
  return (errorMessage.match(/<pre>([\s\S]+)<\/pre>/) || ['', errorMessage])[1];
};

exports.valueEscape = function(query) {
  return query.replace(/\\?([&|+\-!(){}[\]^"~*?\:]{1})/g, function(str, c) {
    return '\\' + c;
  });
}

exports.createClient = function(host, port, core) {
  var client = new Client(host, port, core);
  //client.httpClient = http.createClient(client.port, client.host);
  //client.destroy = function() {client.httpClient.destroy()};
  //client.on = function(eventType, fn) {client.httpClient.on(eventType, fn)};
  client.sendRequest = function(options, callback) {
    var requestOptions = {
      host: client.host,
      port: client.port,
      method: options.method.toUpperCase(),
      path: options.path,
      headers: options.headers
    };
    var buffer = '';
    var request = http.request(requestOptions, function(response) {
      response.on("data", function(chunk) {
        buffer += chunk;
      });
      response.on("end", function() {
        if (response.statusCode !== 200) {
          var err = new Error(exports.getError(buffer));
          callback(err, null);
        } else {
          callback(null, buffer);
        }
      });
    });
    request.on('error', function (e) {
      throw new Error('Unable to connect to Solr ('+e.message+')');
    });
    if (options.data) {
      request.write(options.data, options.requestEncoding || 'utf8');
    }
    request.end();
  };
  return client;
};

// Helper functions

var escapeXml = function(str) {
  return str.replace('&', '&').replace('<', '<').replace('>', '>');
};

var serializeScalar = function(field, value) {
  value = '' + value;
  return '<field name = "' + field + '">' + escapeXml(value) + '</field>';
};

var serializeList = function(field, list) {
  var data = '';
  list.forEach(function(value) {
    if (!Array.isArray(value)) {
      data += serializeScalar(field, value);
    }
  });
  return data;
};

<commit_msg>Added missing slash to path variable<commit_after>var http = require("http");
var querystring = require("querystring");

// callback || noop borrowed from node/lib/fs.js
function noop() {};

var Client = function(host, port, core, path) {
  this.host = host || "127.0.0.1";
  this.port = port || "8983";
  this.fullHost = this.host + ":" + this.port;
  this.core = core || ""; // if defined, should begin with a slash
  this.path = path ? path + "/" : "solr/";
};

Client.prototype.add = function(doc, options, callback) {
  if (callback === undefined) {
    callback = options;
    options = {};
  }
  options = options || {};
  var addParams = {};
  if (options.overwrite !== undefined) {
    addParams["overwrite"] = Boolean(options.overwrite);
  }
  if (options.commitWithin !== undefined) {
    addParams["commitWithin"] = options.commitWithin;
  }
  if (options.commit !== undefined) {
    addParams["commit"] = Boolean(options.commit);
  }
  var data = "<add>";
  var docs = Array.isArray(doc) ? doc : [doc];
  for (var i = 0; i < docs.length; i++) {
    data += "<doc>";
    var doc = docs[i];
    for (field in doc) if (doc.hasOwnProperty(field)) {
      value = doc[field];
      if (!Array.isArray(value)) {
        data += serializeScalar(field, value);
      } else {
        data += serializeList(field, value);
      }
    }
    data += "</doc>";
  }
  data += "</add>";
  this.update(data, callback);
};

Client.prototype.commit = function(callback) {
  var data = "<commit/>";
  this.update(data, callback);
};

Client.prototype.del = function(id, query, callback) {
  var data = "<delete>";
  if (id) {
    if (Array.isArray(id)) {
      for (var i=0; i<id.length; i++) {
        data = data + "<id>" + id[i] + "</id>";
      }
    } else {
      data = data + "<id>" + id + "</id>";
    }
  }
  if (query) {
    if (Array.isArray(query)) {
      for (var i=0; i<query.length; i++) {
        data = data + "<query>" + query[i] + "</query>";
      }
    } else {
      data = data + "<query>" + query + "</query>";
    }
  }
  data = data + "</delete>";
  this.update(data, callback);
};

Client.prototype.optimize = function(callback) {
  var data = "<optimize/>";
  this.update(data, callback);
};

Client.prototype.query = function(query, options, callback) {
  if (callback === undefined) {
    callback = options;
    options = {};
  }
  var queryParams = options || {};
  queryParams.q = query;
  queryParams.wt = "json";
  queryParams = querystring.stringify(queryParams, '&', '=', false);
  this.rawQuery(queryParams, callback);
};

Client.prototype.rawQuery = function(queryParams, callback) {
  var queryPath, options;
  queryPath = "/" + this.path + this.core + "/select?";
  options = {
    method: "GET",
    path: queryPath + queryParams,
    headers: {
      "Host": this.fullHost
    }
  };
  this.sendRequest(options, callback || noop);
};

Client.prototype.rollback = function(callback) {
  var data = "<rollback/>";
  this.update(data, callback);
};

Client.prototype.update = function(data, callback) {
  var updatePath, options;
  updatePath = "/" + this.path + this.core + "/update";
  options = {
    method: "POST",
    path: updatePath,
    headers: {
      // Keep-Alive needed for Node v0.2.4 and v0.2.5, but sometimes
      // leaves connection hanging that must be manually destroyed
      // http://groups.google.com/group/nodejs-dev/browse_thread/thread/e9044c0778ac67d0
      //"Connection": "Keep-Alive",
      "Content-Length": Buffer.byteLength(data),
      "Host": this.fullHost
    },
    data: data,
  };
  this.sendRequest(options, callback || noop);
};

exports.getStatus = function(statusMessage) {
  if (!statusMessage) {
    return 1;
  }
  var statusTag = '<int name="status">';
  return statusMessage.charAt(statusMessage.indexOf(statusTag) +
      statusTag.length);
};

exports.getError = function(errorMessage) {
  return (errorMessage.match(/<pre>([\s\S]+)<\/pre>/) || ['', errorMessage])[1];
};

exports.valueEscape = function(query) {
  return query.replace(/\\?([&|+\-!(){}[\]^"~*?\:]{1})/g, function(str, c) {
    return '\\' + c;
  });
}

exports.createClient = function(host, port, core) {
  var client = new Client(host, port, core);
  //client.httpClient = http.createClient(client.port, client.host);
  //client.destroy = function() {client.httpClient.destroy()};
  //client.on = function(eventType, fn) {client.httpClient.on(eventType, fn)};
  client.sendRequest = function(options, callback) {
    var requestOptions = {
      host: client.host,
      port: client.port,
      method: options.method.toUpperCase(),
      path: options.path,
      headers: options.headers
    };
    var buffer = '';
    var request = http.request(requestOptions, function(response) {
      response.on("data", function(chunk) {
        buffer += chunk;
      });
      response.on("end", function() {
        if (response.statusCode !== 200) {
          var err = new Error(exports.getError(buffer));
          callback(err, null);
        } else {
          callback(null, buffer);
        }
      });
    });
    request.on('error', function (e) {
      throw new Error('Unable to connect to Solr ('+e.message+')');
    });
    if (options.data) {
      request.write(options.data, options.requestEncoding || 'utf8');
    }
    request.end();
  };
  return client;
};

// Helper functions

var escapeXml = function(str) {
  return str.replace('&', '&').replace('<', '<').replace('>', '>');
};

var serializeScalar = function(field, value) {
  value = '' + value;
  return '<field name = "' + field + '">' + escapeXml(value) + '</field>';
};

var serializeList = function(field, list) {
  var data = '';
  list.forEach(function(value) {
    if (!Array.isArray(value)) {
      data += serializeScalar(field, value);
    }
  });
  return data;
};

<|endoftext|>


<commit_before>// Load modules.
var debug = require('debug')('electrolyte');

/**
 * A specification of an object.
 *
 * A specification defines how an object is created.  The specification includes
 * a "factory" which is used to create objects.  A factory is typically a
 * function which returns the object or a constructor that is invoked with the
 * `new` operator.  A specification also declares any objects required by the
 * object.  Any such required objects will be injected into the object when it
 * is created.
 *
 * Specifications have an identifier, which uniquely identifies the
 * specification, and hence any objects created from it, within a container.
 *
 * @constructor
 * @protected
 */
function Spec(id, dependencies, mod) {
  var keys = Object.keys(mod)
    , i, len;

  this.id = id;
  this.dependencies = dependencies;
  this.singleton = mod['@singleton'];
  this.implements = mod['@implements'];
  if (typeof this.implements == 'string') {
    this.implements = [ this.implements ]
  }
  this.a = {};
  for (i = 0, len = keys.length; i < len; ++i) {
    if (keys[i].indexOf('@') == 0) {
      this.a[keys[i]] = mod[keys[i]];
    }
  }

  this._module = mod;
  this._initialized = false;
}

/**
 * Create an object from the specification.
 *
 * @protected
 */
Spec.prototype.create = function(container) {
  debug('create %s', this.id);

  // Immediately return cached instance.  Optimization for singleton and literal
  // components.
  if (this.instance) { return this.instance; }

  if (!this._initialized) {
    if (this._module.initialize) { this._module.initialize(container); }
    this._initialized = true;
  }

  var source = container._sources[this._sid];

  var deps = this.dependencies
    , args = [];
  for (var i = 0, len = deps.length; i < len; ++i) {
    var inst = container.create(deps[i], this);
    if (source) {
      if (typeof source.mod.scope == 'function') {
        inst = source.mod.scope(deps[i], inst, { prefix: source.prefix, options: source.options });
      }
    }
    args.push(inst);
  }

  var i = this.instantiate.apply(this, args);

  // Cache the instance if the component was annotated as being a singleton.
  if (this.singleton) { this.instance = i; }

  if (container._expose) {
    container._expose.call(container, this.id, i, this.singleton)
  }

  return i;
}

/**
 * Instantiate an object from the specification.
 *
 * @private
 */
Spec.prototype.instantiate = function() {
  throw new Error("Unable to instantiate object from spec '" + this.id + "'");
}

// Expose constructor.
module.exports = Spec;
<commit_msg>Remove bundle scoping.<commit_after>// Load modules.
var debug = require('debug')('electrolyte');

/**
 * A specification of an object.
 *
 * A specification defines how an object is created.  The specification includes
 * a "factory" which is used to create objects.  A factory is typically a
 * function which returns the object or a constructor that is invoked with the
 * `new` operator.  A specification also declares any objects required by the
 * object.  Any such required objects will be injected into the object when it
 * is created.
 *
 * Specifications have an identifier, which uniquely identifies the
 * specification, and hence any objects created from it, within a container.
 *
 * @constructor
 * @protected
 */
function Spec(id, dependencies, mod) {
  var keys = Object.keys(mod)
    , i, len;

  this.id = id;
  this.dependencies = dependencies;
  this.singleton = mod['@singleton'];
  this.implements = mod['@implements'];
  if (typeof this.implements == 'string') {
    this.implements = [ this.implements ]
  }
  this.a = {};
  for (i = 0, len = keys.length; i < len; ++i) {
    if (keys[i].indexOf('@') == 0) {
      this.a[keys[i]] = mod[keys[i]];
    }
  }

  this._module = mod;
  this._initialized = false;
}

/**
 * Create an object from the specification.
 *
 * @protected
 */
Spec.prototype.create = function(container) {
  debug('create %s', this.id);

  // Immediately return cached instance.  Optimization for singleton and literal
  // components.
  if (this.instance) { return this.instance; }

  if (!this._initialized) {
    if (this._module.initialize) { this._module.initialize(container); }
    this._initialized = true;
  }

  var deps = this.dependencies
    , args = [];
  for (var i = 0, len = deps.length; i < len; ++i) {
    var inst = container.create(deps[i], this);
    args.push(inst);
  }

  var i = this.instantiate.apply(this, args);

  // Cache the instance if the component was annotated as being a singleton.
  if (this.singleton) { this.instance = i; }

  if (container._expose) {
    container._expose.call(container, this.id, i, this.singleton)
  }

  return i;
}

/**
 * Instantiate an object from the specification.
 *
 * @private
 */
Spec.prototype.instantiate = function() {
  throw new Error("Unable to instantiate object from spec '" + this.id + "'");
}

// Expose constructor.
module.exports = Spec;
<|endoftext|>


<commit_before>var browserify = require('browserify');
var brfs = require('brfs');
var through = require('through');
var fs = require('fs');

var browserify_builtins = require('browserify/lib/builtins');
browserify_builtins.child_process = 'child_process.js';
browserify_builtins.fs = require.resolve('browserify-fs'); // TODO: what is the api equivalent of cli -r fs:browserify-fs?
browserify_builtins['graceful-fs'] = browserify_builtins.fs;
browserify_builtins['request'] = require.resolve('browser-request');

var b = browserify();

//b.require('browserify-fs', {expose:'fs'});

//b.transform('brfs');

var textReplacements = [
  [/require\.resolve/g, 'require'], // TODO: what is require.resolve for browserify?

  // semi-dynamic fs.readFileSync()
  [/fs\.readFileSync/g, 'window.staticReadFileSync'],
  [/require\('fs'\)\.readFileSync/g, 'window.staticReadFileSync'],

  // semi-dynamic require()

  // node_modules/npm/lib/npm.js
  [/require\(__dirname\+"\/"\+a\+"\.js"\)/g, 'window.npmCommandRequire(__dirname+"/"+a+".js")'],

  // npm/node_modules/npm-registry-client/index.js
  [/client\[name\] = require\(entry\)/g, 'client[name] = window.npmRegistryClientRequire(entry)'],

  // npm/node_modules/npm-registry-client/lib/request.js
  // workaround https://github.com/iriscouch/browser-request/pull/44 browser-request cannot request URL objects
  [/(var req = request\(opts, decodeResponseBody\(done\)\))/g, 'opts.url = opts.url.href; $1'],
];

// Included file data for staticReadFileSync; this is similar to
// brfs's fs.readFileSync transclusion but ours is looked up dynamically,
// because brfs can only replace files from static source code analysis.
var preloadedFilenames = [
  'node_modules/browserify/node_modules/umd/template.js',
  'node_modules/browserify/node_modules/browser-pack/_prelude.js',
  'node_modules/npm/package.json',
];

// directly include rfile TODO: use brfs, but it replaces fs.readFileSync
b.transform(function(s) {
  var data = '';
  return through(write, end);

  function write(buf) { data += buf; }
  function end() {
    for (var i = 0; i < textReplacements.length; i += 1) {
      var regex = textReplacements[i][0];
      var replacement = textReplacements[i][1];

      data  = data.replace(regex, replacement);
    }

    this.queue(data);
    this.queue(null);
  };
}, { global: true });

b.add('./webnpm.js');

var preloadedReadFileSyncs = {};
for (var i = 0; i < preloadedFilenames.length; i += 1) {
  var path = preloadedFilenames[i];
  preloadedReadFileSyncs['/' + path] = JSON.stringify(fs.readFileSync(path, 'utf8'));
}

process.stdout.write('window.preloadedReadFileSyncs = ' + JSON.stringify(preloadedReadFileSyncs) + '\n;');

b.bundle().pipe(process.stdout);

<commit_msg>Disable followRedirect for browser-request. Closes GH-2<commit_after>var browserify = require('browserify');
var brfs = require('brfs');
var through = require('through');
var fs = require('fs');

var browserify_builtins = require('browserify/lib/builtins');
browserify_builtins.child_process = 'child_process.js';
browserify_builtins.fs = require.resolve('browserify-fs'); // TODO: what is the api equivalent of cli -r fs:browserify-fs?
browserify_builtins['graceful-fs'] = browserify_builtins.fs;
browserify_builtins['request'] = require.resolve('browser-request');

var b = browserify();

//b.require('browserify-fs', {expose:'fs'});

//b.transform('brfs');

var textReplacements = [
  [/require\.resolve/g, 'require'], // TODO: what is require.resolve for browserify?

  // semi-dynamic fs.readFileSync()
  [/fs\.readFileSync/g, 'window.staticReadFileSync'],
  [/require\('fs'\)\.readFileSync/g, 'window.staticReadFileSync'],

  // semi-dynamic require()

  // node_modules/npm/lib/npm.js
  [/require\(__dirname\+"\/"\+a\+"\.js"\)/g, 'window.npmCommandRequire(__dirname+"/"+a+".js")'],

  // npm/node_modules/npm-registry-client/index.js
  [/client\[name\] = require\(entry\)/g, 'client[name] = window.npmRegistryClientRequire(entry)'],

  // npm/node_modules/npm-registry-client/lib/request.js
  [/(var req = request\(opts, decodeResponseBody\(done\)\))/g,
    'opts.url = opts.url.href; ' // workaround https://github.com/iriscouch/browser-request/pull/44 browser-request cannot request URL objects
    + 'opts.followRedirect = false; ' // unsupported option by browser-request TODO: support it? via a corsproxy?
    + '$1'],
];

// Included file data for staticReadFileSync; this is similar to
// brfs's fs.readFileSync transclusion but ours is looked up dynamically,
// because brfs can only replace files from static source code analysis.
var preloadedFilenames = [
  'node_modules/browserify/node_modules/umd/template.js',
  'node_modules/browserify/node_modules/browser-pack/_prelude.js',
  'node_modules/npm/package.json',
];

// directly include rfile TODO: use brfs, but it replaces fs.readFileSync
b.transform(function(s) {
  var data = '';
  return through(write, end);

  function write(buf) { data += buf; }
  function end() {
    for (var i = 0; i < textReplacements.length; i += 1) {
      var regex = textReplacements[i][0];
      var replacement = textReplacements[i][1];

      data  = data.replace(regex, replacement);
    }

    this.queue(data);
    this.queue(null);
  };
}, { global: true });

b.add('./webnpm.js');

var preloadedReadFileSyncs = {};
for (var i = 0; i < preloadedFilenames.length; i += 1) {
  var path = preloadedFilenames[i];
  preloadedReadFileSyncs['/' + path] = JSON.stringify(fs.readFileSync(path, 'utf8'));
}

process.stdout.write('window.preloadedReadFileSyncs = ' + JSON.stringify(preloadedReadFileSyncs) + '\n;');

b.bundle().pipe(process.stdout);

<|endoftext|>


<commit_before>// require('./dbapi')前，先在项目目录下执行 npm install rethinkdb , 安装rethnkdb的nodejs driver.
// dbapi/config/index.js文件中指定rethinkdb的地址和端口.

var db = require('./dbapi'); // 后台数据库相关api
// var app = require('express')();
// var http = require('http').Server(app);

// 要启用socket.io，后端按照A1，A2，A3三个步骤。前端按index.html文件的script实现。

// A1. 添加引用
// var sio = require('./sio');

// app.get('/', (req, res)=>{
//   res.sendFile(__dirname + '/index.html');
// });

// http.listen(3000, ()=>{
//   console.log('listening on *:3000');
// });

db.useRethinkDb(); // 默认内存数据库，使用这个切换成实际部署数据库。

setTimeout(()=> {

  // A2. 将socket.io绑定到http上。
  //sio.configSio(http);
  // A3. 开始监听消息，目前只示范实现了一个游戏添加的消息。前端代码具体参考index.html中的script。
  //sio.watch();

  // 添加管理员
  // 1： 用户登录名，2：昵称，3：密码（经过md5运算），4：回调，err如果成功为null，否则表示失败。属性error表示错误描述。
  // db.users.addAdmin('admin2', '昵称2', 'e10adc3949ba59abbe56e057f20f883e', (err, user)=> {
  //   if (err) { console.log(err); return; };
  //   console.log(`======= add Admin success. user = `, user);
  // });

  // 添加团长
  // 1： 用户登录名，2：昵称，3：密码（经过md5运算），4：回调，err如果成功为null，否则表示失败。属性error表示错误描述。
  // db.users.addTZ('tz2', '团长2', 'e10adc3949ba59abbe56e057f20f883e', (err, user)=> {
  //   if (err) { console.log(err); return; };
  //   console.log(`======= add 团长 success. user = `, user);
  // });

  // 添加团员
  // 1： 用户登录名，2：昵称，3：密码（经过md5运算），4：回调，err如果成功为null，否则表示失败。属性error表示错误描述。
  // db.users.addTY('ty2', '团员3', 'e10adc3949ba59abbe56e057f20f883e', (err, user)=> {
  //   if (err) { console.log(err); return; };
  //   console.log(`======= add 团员 success. user = `, user);
  // });

  // 登录时检查是否可以登录
  // 1：usname, 2：密码（前端输入的密码加密后的md5串，小写
  // 3：回调 ，err不空时表示错误，空时user为相应的用户信息
  // db.users.checkUserPwd('admin2', 'e10adc3949ba59abbe56e057f20f883e', (err, user) => {
  //   if (err) { console.log(err); return; }
  //   console.log(`admin valid!user:`, user);
  // });

  // 返回单个用户信息
  // 1. id: uuid
  // 2. 回调，err: 不为空时表示有错误。为空user则为查找到的用户信息
  // db.users.single_user('756f0c1d-769e-4b51-849f-b0a1e80e4bfe', (err, user) => {
  //   if (err) { console.log("single_user: " + err); return; };
  //   console.log(user);
  // });

  // 查询所有用户
  // 1：页号，从1开始，2：每页记录条数，3：role，0所有，1管理员，2团长，3团员
  // 4：回调，err如果成功为null，否则表示失败。属性error表示错误描述。users对应的用户信息
  // db.users.all_users(1, 2, 2, (err, users) => {
  //   if (err) { console.log(err); return; };
  //   console.log(users);
  // });

  // 添加日志
  // 1. type
  // 2. doer
  // 3. 内容
  // 4. ip?
  // db.logs.addlog(1, 1, "log 1", "122.21.23.11", (err) => {
  //   if (err) { console.log(err); return; };
  //
  //   console.log("========= log added");
  // });
  //
  // db.logs.addlog(2, 'd2007270-30e7-4471-af99-a910303f9047', "log 2", "122.21.23.11", (err) => {
  //   if (err) { console.log(err); return; };
  //
  //   console.log("========= log added");
  // });

  // 获取日志
  // 1. 页号
  // 2. 每页数量
  // 3. 哪个用户的日志，null或者''表示所有，其它表示按用户id过滤
  // db.logs.getlogs(1, 10, '', (err, logs) => {
  //  if (err) { console.log(err); return; };
  //
  //   console.log(logs);
  //   console.log(logs.logs[0].addtime.toLocaleString());
  // });

  // 修改用户
  // 1：用户id，2：昵称，3：密码（为null不修改），4：回调，err如果成功为null，否则表示失败。属性error表示错误描述。
  // db.users.updateUser('6e681a22-b137-4afd-85b8-edadfe06a06f', '团员团员', 'e10adc3949ba59abbe56e057f20f883e', (err) => {
  //   if (err) { console.log(err); return; };
  //   console.log('======= edit success');
  // });

  // 删除用户
  // 1：用户id，2：回调，err如果成功为null，否则表示失败。属性error表示错误描述。
  // db.users.delUser('3460caad-3560-4ed8-903d-a61e62f530bc', (err) => {
  //   if (err) { console.log(err); return; };
  //   console.log('======= del success');
  // });

  // 更新用户状态
  // 1：用户id，2：status值，3：回调，err如果成功为null，否则表示失败。属性error表示错误描述。
  // db.users.changeUserStatus('6e681a22-b137-4afd-85b8-edadfe06a06f', 2, (err) => {
  //   if (err) { console.log(err); return; };
  //   console.log(`======= changed`);
  // });

  // 更新用户上次登录IP
  // 1. userid
  // 2. 新的IP
  // 3. 回调，err如果成功为null，否则表示失败。属性error表示错误描述。
  // db.users.updateUserLastIp('6e681a22-b137-4afd-85b8-edadfe06a06f', "1.1.1.3", (err) => {
  //   if (err) { console.log(err); return; }
  //   console.log("update last ip success!");
  // });

  // 更新用户上次登录时间
  // 1. userid
  // 2. 回调，err如果成功为null，否则表示失败。属性error表示错误描述。
  // db.users.updateUserLastTime('6e681a22-b137-4afd-85b8-edadfe06a06f', (err) => {
  //   if (err) { console.log(err); return; }
  //   console.log("update last time success!");
  // });

  // 添加一个游戏
  // 1. userid
  // 2. gnickname
  // 3. content
  // 4. 淘宝订单号
  // 5. 分配者用户id
  // db.games.addGame('1732152d-a7f7-43cd-9ee0-83e9105cb44d', "游戏昵称6", "游戏信息6", "tbdd6", '1732152d-a7f7-43cd-9ee0-83e9105cb44d', (err, game) => {
  //   if (err) { console.log(err); return; }
  //   console.log('======== added game.', game);
  // });

  // 查询所有游戏
  // 1.pageIndex
  // 2.pageCount
  // 3.userid, 为''或null时不限制用户，返回所有，否则返回已经被分配到用户的游戏列表。
  // 4.status, 将status加进查询条件，为null时不使用此条件。
  // 5.assignerid, 将 assignerid加进查询条件，为null不使用此条件。
  // db.games.all_games(1, 20, '1732152d-a7f7-43cd-9ee0-83e9105cb44d', 1, null, (err, games) => {
  //   if (err) { console.log(err); return; };
  //   console.log(games);
  // });

  // 查询是谁分配的所有游戏
  // 1.pageIndex
  // 2.pageCount
  // 3.agsignerid
  // db.games.all_games_with_assigner(1, 20, 'cb5c2c5c-2669-4a36-b8be-fe25ba59b859', (err, games) => {
  //   if (err) { console.log(err); return; };
  //   console.log(games);
  // });

  // 按任务状态来查询游戏
  // 1.pageIndex
  // 2.pageCount
  // 3.status 按任务来查询游戏
  // db.games.all_games_with_status(1, 20, 0, (err, games) => {
  //   if (err) { console.log(err); return; };
  //   console.log(games);
  // });

  // 修改游戏
  // 1. id
  // 2. userid,为null或者''时，表示不更改分配的用户。否则将更改分配到的用户。
  // 3. gnickname
  // 4. content
  // 5. 淘宝订单号
  // 6. 分配者用户id，为null或者''时，表示不更改，否则将更改为新指定的分配者。
  // db.games.updateGame('481cc2f6-37d0-44bc-94ef-76786b040f13', '70c46afc-88de-40de-b11c-f87bd72398e9', "gnickname76786b040f13", "content76786b040f13", "tbdd76786b040f13", 'd2007270-30e7-4471-af99-a910303f9047', (err) => {
  //   if (err) { console.log(err); return; }
  //   console.log('======== updated game.');
  // });

  // 删除游戏
  // 1. id
  // db.games.delGame('dc5e9213-08b6-4841-a4b7-d8b4de0a1b84', (err) => {
  //   if (err) { console.log(err); return; };
  //   console.log("======== deleted game.");
  // });

  // 更新游戏状态
  // 1. id
  // 2. status, 见需求文档
  // db.games.updateGameStatus('14933ec2-4e5d-43a7-b253-ea71bae4fb1f', 2, (err) => {
  //   if (err) { console.log(err); return; };
  //   console.log("======== updated game status.");
  // });

  // 添加游戏任务
  // 1. gameid
  // 2. 任务标题
  // 3. 任务内容
  db.games.addtask('b3d09403-77f5-4ae1-b4e3-b52472b6f540', "task2", "task2", (err, task) => {
    if (err) { console.log(err); return; };
    console.log("======= task added", task);
  });

  // 获取任务
  // 1. gameid
  // 由于任务数记录条数不会很多，基本不用分页
  // db.games.gettasks('499bcb63-d54a-4e25-bb47-2708b94ea7ef', (err, tasks) => {
  //   if (err) { console.log(err); return; };
  //   console.log(tasks);
  // });

  // 更新任务
  // 1. 任务id
  // 2. 任务标题
  // 3. 任务内容
  // db.games.updatetask('c00adefe-249f-422f-a6c4-95a644985560', "title", "content", (err) => {
  //   if (err) { console.log(err); return; };
  //   console.log('========= updated task');
  // });

  // 更新任务状态
  // 1. 任务id
  // 2. 新状态，见需求文档
  // db.games.changeTaskStatus('c00adefe-249f-422f-a6c4-95a644985560', 2, (err) => {
  //   if (err) { console.log(err); return; };
  //   console.log('========= changeTaskStatus ok');
  // });

  // 删除任务
  // 1.任务id
  // db.games.deltask('c368e478-023f-4ac3-95b1-0682b0f7c5e5', (err) => {
  //   if (err) { console.log(err); return; };
  //   console.log('==== deleted task');
  // });

  // 添加进度
  // 1. taskid
  // 2. content
  db.games.addprogress('c36f1e36-75ed-4940-bbf9-1c3adf0dd441', "progress content 1", (err, progress) => {
    if (err) { console.log(err); return; };
    console.log("======= progress added", progress);
  });

  // 获取进度
  // 1. 任务id
  // db.games.getprogresss('14933ec2-4e5d-43a7-b253-ea71bae4fb1f', (err, progresses) => {
  //   if (err) { console.log(err); return; };
  //   console.log(progresses);
  // });

  // 更新进度
  // 1. 进度id
  // 2. 进度内容
  // db.games.updateprogresss('135bb902-5e33-44fd-88af-50d0fc7c78d7', "content 33333333", (err) => {
  //   if (err) { console.log(err); return; };
  //   console.log('========= updated progress');
  // });

  // 删除进度
  // 1. 进度id
  // db.games.delprogress('135bb902-5e33-44fd-88af-50d0fc7c78d7', (err) => {
  //   if (err) { console.log(err); return; };
  //   console.log('==== deleted progress');
  // });

}, 1000);
<commit_msg>demo.js updated.<commit_after>// require('./dbapi')前，先在项目目录下执行 npm install rethinkdb , 安装rethnkdb的nodejs driver.
// dbapi/config/index.js文件中指定rethinkdb的地址和端口.

var db = require('./dbapi'); // 后台数据库相关api
// var app = require('express')();
// var http = require('http').Server(app);

// 要启用socket.io，后端按照A1，A2，A3三个步骤。前端按index.html文件的script实现。

// A1. 添加引用
// var sio = require('./sio');

// app.get('/', (req, res)=>{
//   res.sendFile(__dirname + '/index.html');
// });

// http.listen(3000, ()=>{
//   console.log('listening on *:3000');
// });

db.useRethinkDb(); // 默认内存数据库，使用这个切换成实际部署数据库。

setTimeout(()=> {

  // A2. 将socket.io绑定到http上。
  //sio.configSio(http);
  // A3. 开始监听消息，目前只示范实现了一个游戏添加的消息。前端代码具体参考index.html中的script。
  //sio.watch();

  // 添加管理员
  // 1： 用户登录名，2：昵称，3：密码（经过md5运算），4：回调，err如果成功为null，否则表示失败。属性error表示错误描述。
  // db.users.addAdmin('admin2', '昵称2', 'e10adc3949ba59abbe56e057f20f883e', (err, user)=> {
  //   if (err) { console.log(err); return; };
  //   console.log(`======= add Admin success. user = `, user);
  // });

  // 添加团长
  // 1： 用户登录名，2：昵称，3：密码（经过md5运算），4：回调，err如果成功为null，否则表示失败。属性error表示错误描述。
  // db.users.addTZ('tz2', '团长2', 'e10adc3949ba59abbe56e057f20f883e', (err, user)=> {
  //   if (err) { console.log(err); return; };
  //   console.log(`======= add 团长 success. user = `, user);
  // });

  // 添加团员
  // 1： 用户登录名，2：昵称，3：密码（经过md5运算），4：回调，err如果成功为null，否则表示失败。属性error表示错误描述。
  // db.users.addTY('ty2', '团员3', 'e10adc3949ba59abbe56e057f20f883e', (err, user)=> {
  //   if (err) { console.log(err); return; };
  //   console.log(`======= add 团员 success. user = `, user);
  // });

  // 登录时检查是否可以登录
  // 1：usname, 2：密码（前端输入的密码加密后的md5串，小写
  // 3：回调 ，err不空时表示错误，空时user为相应的用户信息
  // db.users.checkUserPwd('admin2', 'e10adc3949ba59abbe56e057f20f883e', (err, user) => {
  //   if (err) { console.log(err); return; }
  //   console.log(`admin valid!user:`, user);
  // });

  // 返回单个用户信息
  // 1. id: uuid
  // 2. 回调，err: 不为空时表示有错误。为空user则为查找到的用户信息
  // db.users.single_user('756f0c1d-769e-4b51-849f-b0a1e80e4bfe', (err, user) => {
  //   if (err) { console.log("single_user: " + err); return; };
  //   console.log(user);
  // });

  // 查询所有用户
  // 1：页号，从1开始，2：每页记录条数，3：role，0所有，1管理员，2团长，3团员
  // 4：回调，err如果成功为null，否则表示失败。属性error表示错误描述。users对应的用户信息
  // db.users.all_users(1, 2, 2, (err, users) => {
  //   if (err) { console.log(err); return; };
  //   console.log(users);
  // });

  // 添加日志
  // 1. type
  // 2. doer
  // 3. 内容
  // 4. ip?
  // db.logs.addlog(1, 1, "log 1", "122.21.23.11", (err) => {
  //   if (err) { console.log(err); return; };
  //
  //   console.log("========= log added");
  // });
  //
  // db.logs.addlog(2, 'd2007270-30e7-4471-af99-a910303f9047', "log 2", "122.21.23.11", (err) => {
  //   if (err) { console.log(err); return; };
  //
  //   console.log("========= log added");
  // });

  // 获取日志
  // 1. 页号
  // 2. 每页数量
  // 3. 哪个用户的日志，null或者''表示所有，其它表示按用户id过滤
  // db.logs.getlogs(1, 10, '', (err, logs) => {
  //  if (err) { console.log(err); return; };
  //
  //   console.log(logs);
  //   console.log(logs.logs[0].addtime.toLocaleString());
  // });

  // 修改用户
  // 1：用户id，2：昵称，3：密码（为null不修改），4：回调，err如果成功为null，否则表示失败。属性error表示错误描述。
  // db.users.updateUser('6e681a22-b137-4afd-85b8-edadfe06a06f', '团员团员', 'e10adc3949ba59abbe56e057f20f883e', (err) => {
  //   if (err) { console.log(err); return; };
  //   console.log('======= edit success');
  // });

  // 删除用户
  // 1：用户id，2：回调，err如果成功为null，否则表示失败。属性error表示错误描述。
  // db.users.delUser('3460caad-3560-4ed8-903d-a61e62f530bc', (err) => {
  //   if (err) { console.log(err); return; };
  //   console.log('======= del success');
  // });

  // 更新用户状态
  // 1：用户id，2：status值，3：回调，err如果成功为null，否则表示失败。属性error表示错误描述。
  // db.users.changeUserStatus('6e681a22-b137-4afd-85b8-edadfe06a06f', 2, (err) => {
  //   if (err) { console.log(err); return; };
  //   console.log(`======= changed`);
  // });

  // 更新用户上次登录IP
  // 1. userid
  // 2. 新的IP
  // 3. 回调，err如果成功为null，否则表示失败。属性error表示错误描述。
  // db.users.updateUserLastIp('6e681a22-b137-4afd-85b8-edadfe06a06f', "1.1.1.3", (err) => {
  //   if (err) { console.log(err); return; }
  //   console.log("update last ip success!");
  // });

  // 更新用户上次登录时间
  // 1. userid
  // 2. 回调，err如果成功为null，否则表示失败。属性error表示错误描述。
  // db.users.updateUserLastTime('6e681a22-b137-4afd-85b8-edadfe06a06f', (err) => {
  //   if (err) { console.log(err); return; }
  //   console.log("update last time success!");
  // });

  // 添加一个游戏
  // 1. userid
  // 2. gnickname
  // 3. content
  // 4. 淘宝订单号
  // 5. 分配者用户id
  // db.games.addGame('', "游戏昵称6", "游戏信息6", "tbdd6", '1732152d-a7f7-43cd-9ee0-83e9105cb44d', (err, game) => {
  //   if (err) { console.log(err); return; }
  //   console.log('======== added game.', game);
  // });

  // 查询所有游戏
  // 1.pageIndex
  // 2.pageCount
  // 3.userid, 为''或null时不限制用户，返回所有，否则返回已经被分配到用户的游戏列表。
  // 4.status, 将status加进查询条件，为null时不使用此条件。
  // 5.assignerid, 将 assignerid加进查询条件，为null不使用此条件。
  // db.games.all_games(1, 20, '', null, null, (err, games) => {
  //   if (err) { console.log(err); return; };
  //   console.log(games);
  // });

  // 查询是谁分配的所有游戏
  // 1.pageIndex
  // 2.pageCount
  // 3.agsignerid
  // db.games.all_games_with_assigner(1, 20, 'cb5c2c5c-2669-4a36-b8be-fe25ba59b859', (err, games) => {
  //   if (err) { console.log(err); return; };
  //   console.log(games);
  // });

  // 按任务状态来查询游戏
  // 1.pageIndex
  // 2.pageCount
  // 3.status 按任务来查询游戏
  // db.games.all_games_with_status(1, 20, 0, (err, games) => {
  //   if (err) { console.log(err); return; };
  //   console.log(games);
  // });

  // 修改游戏
  // 1. id
  // 2. userid,为null或者''时，表示不更改分配的用户。否则将更改分配到的用户。
  // 3. gnickname
  // 4. content
  // 5. 淘宝订单号
  // 6. 分配者用户id，为null或者''时，表示不更改，否则将更改为新指定的分配者。
  // db.games.updateGame('481cc2f6-37d0-44bc-94ef-76786b040f13', '70c46afc-88de-40de-b11c-f87bd72398e9', "gnickname76786b040f13", "content76786b040f13", "tbdd76786b040f13", 'd2007270-30e7-4471-af99-a910303f9047', (err) => {
  //   if (err) { console.log(err); return; }
  //   console.log('======== updated game.');
  // });

  // 删除游戏
  // 1. id
  // db.games.delGame('dc5e9213-08b6-4841-a4b7-d8b4de0a1b84', (err) => {
  //   if (err) { console.log(err); return; };
  //   console.log("======== deleted game.");
  // });

  // 更新游戏状态
  // 1. id
  // 2. status, 见需求文档
  // db.games.updateGameStatus('14933ec2-4e5d-43a7-b253-ea71bae4fb1f', 2, (err) => {
  //   if (err) { console.log(err); return; };
  //   console.log("======== updated game status.");
  // });

  // 添加游戏任务
  // 1. gameid
  // 2. 任务标题
  // 3. 任务内容
  // db.games.addtask('b3d09403-77f5-4ae1-b4e3-b52472b6f540', "task2", "task2", (err, task) => {
  //   if (err) { console.log(err); return; };
  //   console.log("======= task added", task);
  // });

  // 获取任务
  // 1. gameid
  // 由于任务数记录条数不会很多，基本不用分页
  // db.games.gettasks('499bcb63-d54a-4e25-bb47-2708b94ea7ef', (err, tasks) => {
  //   if (err) { console.log(err); return; };
  //   console.log(tasks);
  // });

  // 更新任务
  // 1. 任务id
  // 2. 任务标题
  // 3. 任务内容
  // db.games.updatetask('c00adefe-249f-422f-a6c4-95a644985560', "title", "content", (err) => {
  //   if (err) { console.log(err); return; };
  //   console.log('========= updated task');
  // });

  // 更新任务状态
  // 1. 任务id
  // 2. 新状态，见需求文档
  // db.games.changeTaskStatus('c00adefe-249f-422f-a6c4-95a644985560', 2, (err) => {
  //   if (err) { console.log(err); return; };
  //   console.log('========= changeTaskStatus ok');
  // });

  // 删除任务
  // 1.任务id
  // db.games.deltask('c368e478-023f-4ac3-95b1-0682b0f7c5e5', (err) => {
  //   if (err) { console.log(err); return; };
  //   console.log('==== deleted task');
  // });

  // 添加进度
  // 1. taskid
  // 2. content
  // db.games.addprogress('c36f1e36-75ed-4940-bbf9-1c3adf0dd441', "progress content 1", (err, progress) => {
  //   if (err) { console.log(err); return; };
  //   console.log("======= progress added", progress);
  // });

  // 获取进度
  // 1. 任务id
  // db.games.getprogresss('14933ec2-4e5d-43a7-b253-ea71bae4fb1f', (err, progresses) => {
  //   if (err) { console.log(err); return; };
  //   console.log(progresses);
  // });

  // 更新进度
  // 1. 进度id
  // 2. 进度内容
  // db.games.updateprogresss('135bb902-5e33-44fd-88af-50d0fc7c78d7', "content 33333333", (err) => {
  //   if (err) { console.log(err); return; };
  //   console.log('========= updated progress');
  // });

  // 删除进度
  // 1. 进度id
  // db.games.delprogress('135bb902-5e33-44fd-88af-50d0fc7c78d7', (err) => {
  //   if (err) { console.log(err); return; };
  //   console.log('==== deleted progress');
  // });

}, 1000);
<|endoftext|>


<commit_before>"use strict";

/**
 * @param {string} deviceId
 * @param {number} step
 * @param {string|Array.<string>} command
 * @param {Buffer} image
 * @param deviceOptions
 * @constructor
 */
function Step(deviceId, step, command, image, deviceOptions) {

    if (!(image instanceof Buffer)) {
        throw new Error('image must be of type Buffer');
    }

    this.deviceId = deviceId;
    this.step = step;
    this.commands = Array.isArray(command) ? command : [command];
    this.image = image;
    this.deviceOptions = deviceOptions || {};
}

/**
 * @param {string|object} json
 * @returns {Step}
 */
Step.fromJson = function(json) {
    if (typeof json === 'string') {
        json = JSON.parse(json);
    }
    return new Step(json.deviceId, json.step, json.commands, new Buffer(json.image, 'base64'), this.options);
}

/**
 * @returns {string}
 */
Step.prototype.toJson = function() {
    return {
        'deviceId': this.deviceId,
        'step': this.step,
        'commands': this.commands,
        'image': this.image.toString('base64')
    };
}

module.exports = Step;
<commit_msg>Store deviceOptions<commit_after>"use strict";

/**
 * @param {string} deviceId
 * @param {number} step
 * @param {string|Array.<string>} command
 * @param {Buffer} image
 * @param deviceOptions
 * @constructor
 */
function Step(deviceId, step, command, image, deviceOptions) {

    if (!(image instanceof Buffer)) {
        throw new Error('image must be of type Buffer');
    }

    this.deviceId = deviceId;
    this.step = step;
    this.commands = Array.isArray(command) ? command : [command];
    this.image = image;
    this.deviceOptions = deviceOptions || {};
}

/**
 * @param {string|object} json
 * @returns {Step}
 */
Step.fromJson = function(json) {
    if (typeof json === 'string') {
        json = JSON.parse(json);
    }
    return new Step(json.deviceId, json.step, json.commands, new Buffer(json.image, 'base64'), json.options);
}

/**
 * @returns {string}
 */
Step.prototype.toJson = function() {
    return {
        'deviceId': this.deviceId,
        'step': this.step,
        'commands': this.commands,
        'image': this.image.toString('base64'),
        'deviceOptions': this.deviceOptions
    };
}

module.exports = Step;
<|endoftext|>