<commit_before>/**
 * @author Mat Groves http://matgroves.com/ @Doormat23
 */

/**
 * The CanvasRenderer draws the Stage and all its content onto a 2d canvas. This renderer should be used for browsers that do not support webGL.
 * Don't forget to add the CanvasRenderer.view to your DOM or you will not see anything :)
 *
 * @class CanvasRenderer
 * @constructor
 * @param [width=800] {Number} the width of the canvas view
 * @param [height=600] {Number} the height of the canvas view
 * @param [options] {Object} The optional renderer parameters
 * @param [options.view] {HTMLCanvasElement} the canvas to use as a view, optional
 * @param [options.transparent=false] {Boolean} If the render view is transparent, default false
 * @param [options.resolution=1] {Number} the resolution of the renderer retina would be 2
 * @param [options.clearBeforeRender=true] {Boolean} This sets if the CanvasRenderer will clear the canvas or not before the new render pass.
 */
PIXI.CanvasRenderer = function(width, height, options)
{
    if(options)
    {
        for (var i in PIXI.defaultRenderOptions)
        {
            if (typeof options[i] === "undefined") options[i] = PIXI.defaultRenderOptions[i];
        }
    }
    else
    {
        options = PIXI.defaultRenderOptions;
    }

    if(!PIXI.defaultRenderer)
    {
        PIXI.sayHello("Canvas");
        PIXI.defaultRenderer = this;
    }

    /**
     * The renderer type.
     *
     * @property type
     * @type Number
     */
    this.type = PIXI.CANVAS_RENDERER;

    /**
     * The resolution of the canvas.
     *
     * @property resolution
     * @type Number
     */
    this.resolution = options.resolution;

    /**
     * This sets if the CanvasRenderer will clear the canvas or not before the new render pass.
     * If the Stage is NOT transparent Pixi will use a canvas sized fillRect operation every frame to set the canvas background color.
     * If the Stage is transparent Pixi will use clearRect to clear the canvas every frame.
     * Disable this by setting this to false. For example if your game has a canvas filling background image you often don't need this set.
     *
     * @property clearBeforeRender
     * @type Boolean
     * @default
     */
    this.clearBeforeRender = options.clearBeforeRender;

    /**
     * Whether the render view is transparent
     *
     * @property transparent
     * @type Boolean
     */
    this.transparent = options.transparent;

    /**
     * The width of the canvas view
     *
     * @property width
     * @type Number
     * @default 800
     */
    this.width = width || 800;

    /**
     * The height of the canvas view
     *
     * @property height
     * @type Number
     * @default 600
     */
    this.height = height || 600;

    this.width *= this.resolution;
    this.height *= this.resolution;

    /**
     * The canvas element that everything is drawn to.
     *
     * @property view
     * @type HTMLCanvasElement
     */
    this.view = options.view || document.createElement( "canvas" );

    /**
     * The canvas 2d context that everything is drawn with
     * @property context
     * @type CanvasRenderingContext2D
     */
    this.context = this.view.getContext( "2d", { alpha: this.transparent } );

    /**
     * Boolean flag controlling canvas refresh.
     *
     * @property refresh
     * @type Boolean
     */
    this.refresh = true;

    this.view.width = this.width * this.resolution;
    this.view.height = this.height * this.resolution;

    /**
     * Internal var.
     *
     * @property count
     * @type Number
     */
    this.count = 0;

    /**
     * Instance of a PIXI.CanvasMaskManager, handles masking when using the canvas renderer
     * @property CanvasMaskManager
     * @type CanvasMaskManager
     */
    this.maskManager = new PIXI.CanvasMaskManager();

    /**
     * The render session is just a bunch of parameter used for rendering
     * @property renderSession
     * @type Object
     */
    this.renderSession = {
        context: this.context,
        maskManager: this.maskManager,
        scaleMode: null,
        smoothProperty: null,
        /**
         * If true Pixi will Math.floor() x/y values when rendering, stopping pixel interpolation.
         * Handy for crisp pixel art and speed on legacy devices.
         *
         */
        roundPixels: false
    };

    this.mapBlendModes();

    this.resize(width, height);

    if("imageSmoothingEnabled" in this.context)
        this.renderSession.smoothProperty = "imageSmoothingEnabled";
    else if("webkitImageSmoothingEnabled" in this.context)
        this.renderSession.smoothProperty = "webkitImageSmoothingEnabled";
    else if("mozImageSmoothingEnabled" in this.context)
        this.renderSession.smoothProperty = "mozImageSmoothingEnabled";
    else if("oImageSmoothingEnabled" in this.context)
        this.renderSession.smoothProperty = "oImageSmoothingEnabled";
    else if ("msImageSmoothingEnabled" in this.context)
        this.renderSession.smoothProperty = "msImageSmoothingEnabled";
};

// constructor
PIXI.CanvasRenderer.prototype.constructor = PIXI.CanvasRenderer;

/**
 * Renders the Stage to this canvas view
 *
 * @method render
 * @param stage {Stage} the Stage element to be rendered
 */
PIXI.CanvasRenderer.prototype.render = function(stage)
{
    stage.updateTransform();

    this.context.setTransform(1,0,0,1,0,0);

    this.context.globalAlpha = 1;

    this.renderSession.currentBlendMode = PIXI.blendModes.NORMAL;
    this.context.globalCompositeOperation = PIXI.blendModesCanvas[PIXI.blendModes.NORMAL];

    if (navigator.isCocoonJS && this.view.screencanvas) {
        this.context.fillStyle = "black";
        this.context.clear();
    }

    if (this.clearBeforeRender)
    {
        if (this.transparent)
        {
            this.context.clearRect(0, 0, this.width, this.height);
        }
        else
        {
            this.context.fillStyle = stage.backgroundColorString;
            this.context.fillRect(0, 0, this.width , this.height);
        }
    }

    this.renderDisplayObject(stage);

    // run interaction!
    if(stage.interactive)
    {
        //need to add some events!
        if(!stage._interactiveEventsAdded)
        {
            stage._interactiveEventsAdded = true;
            stage.interactionManager.setTarget(this);
        }
    }
};

/**
 * Removes everything from the renderer and optionally removes the Canvas DOM element.
 *
 * @method destroy
 * @param [removeView=true] {boolean} Removes the Canvas element from the DOM.
 */
PIXI.CanvasRenderer.prototype.destroy = function(removeView)
{
    if (typeof removeView === 'undefined') { removeView = true; }

    if (removeView && this.view.parent)
    {
        this.view.parent.removeChild(this.view);
    }

    this.view = null;
    this.context = null;
    this.maskManager = null;
    this.renderSession = null;

};

/**
 * Resizes the canvas view to the specified width and height
 *
 * @method resize
 * @param width {Number} the new width of the canvas view
 * @param height {Number} the new height of the canvas view
 */
PIXI.CanvasRenderer.prototype.resize = function(width, height)
{
    this.width = width * this.resolution;
    this.height = height * this.resolution;

    this.view.width = this.width;
    this.view.height = this.height;

    this.view.style.width = this.width / this.resolution + "px";
    this.view.style.height = this.height / this.resolution + "px";
};

/**
 * Renders a display object
 *
 * @method renderDisplayObject
 * @param displayObject {DisplayObject} The displayObject to render
 * @param context {CanvasRenderingContext2D} the context 2d method of the canvas
 * @private
 */
PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject, context)
{
    this.renderSession.context = context || this.context;
    this.renderSession.resolution = this.resolution;
    displayObject._renderCanvas(this.renderSession);
};

/**
 * Maps Pixi blend modes to canvas blend modes.
 *
 * @method mapBlendModes
 * @private
 */
PIXI.CanvasRenderer.prototype.mapBlendModes = function()
{
    if(!PIXI.blendModesCanvas)
    {
        PIXI.blendModesCanvas = [];

        if(PIXI.canUseNewCanvasBlendModes())
        {
            PIXI.blendModesCanvas[PIXI.blendModes.NORMAL]   = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.ADD]      = "lighter"; //IS THIS OK???
            PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply";
            PIXI.blendModesCanvas[PIXI.blendModes.SCREEN]   = "screen";
            PIXI.blendModesCanvas[PIXI.blendModes.OVERLAY]  = "overlay";
            PIXI.blendModesCanvas[PIXI.blendModes.DARKEN]   = "darken";
            PIXI.blendModesCanvas[PIXI.blendModes.LIGHTEN]  = "lighten";
            PIXI.blendModesCanvas[PIXI.blendModes.COLOR_DODGE] = "color-dodge";
            PIXI.blendModesCanvas[PIXI.blendModes.COLOR_BURN] = "color-burn";
            PIXI.blendModesCanvas[PIXI.blendModes.HARD_LIGHT] = "hard-light";
            PIXI.blendModesCanvas[PIXI.blendModes.SOFT_LIGHT] = "soft-light";
            PIXI.blendModesCanvas[PIXI.blendModes.DIFFERENCE] = "difference";
            PIXI.blendModesCanvas[PIXI.blendModes.EXCLUSION] = "exclusion";
            PIXI.blendModesCanvas[PIXI.blendModes.HUE]       = "hue";
            PIXI.blendModesCanvas[PIXI.blendModes.SATURATION] = "saturation";
            PIXI.blendModesCanvas[PIXI.blendModes.COLOR]      = "color";
            PIXI.blendModesCanvas[PIXI.blendModes.LUMINOSITY] = "luminosity";
        }
        else
        {
            // this means that the browser does not support the cool new blend modes in canvas "cough" ie "cough"
            PIXI.blendModesCanvas[PIXI.blendModes.NORMAL]   = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.ADD]      = "lighter"; //IS THIS OK???
            PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.SCREEN]   = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.OVERLAY]  = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.DARKEN]   = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.LIGHTEN]  = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.COLOR_DODGE] = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.COLOR_BURN] = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.HARD_LIGHT] = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.SOFT_LIGHT] = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.DIFFERENCE] = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.EXCLUSION] = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.HUE]       = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.SATURATION] = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.COLOR]      = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.LUMINOSITY] = "source-over";
        }
    }
};
<commit_msg>Fixed for jshint.<commit_after>/**
 * @author Mat Groves http://matgroves.com/ @Doormat23
 */

/**
 * The CanvasRenderer draws the Stage and all its content onto a 2d canvas. This renderer should be used for browsers that do not support webGL.
 * Don't forget to add the CanvasRenderer.view to your DOM or you will not see anything :)
 *
 * @class CanvasRenderer
 * @constructor
 * @param [width=800] {Number} the width of the canvas view
 * @param [height=600] {Number} the height of the canvas view
 * @param [options] {Object} The optional renderer parameters
 * @param [options.view] {HTMLCanvasElement} the canvas to use as a view, optional
 * @param [options.transparent=false] {Boolean} If the render view is transparent, default false
 * @param [options.resolution=1] {Number} the resolution of the renderer retina would be 2
 * @param [options.clearBeforeRender=true] {Boolean} This sets if the CanvasRenderer will clear the canvas or not before the new render pass.
 */
PIXI.CanvasRenderer = function(width, height, options)
{
    if(options)
    {
        for (var i in PIXI.defaultRenderOptions)
        {
            if (typeof options[i] === "undefined") options[i] = PIXI.defaultRenderOptions[i];
        }
    }
    else
    {
        options = PIXI.defaultRenderOptions;
    }

    if(!PIXI.defaultRenderer)
    {
        PIXI.sayHello("Canvas");
        PIXI.defaultRenderer = this;
    }

    /**
     * The renderer type.
     *
     * @property type
     * @type Number
     */
    this.type = PIXI.CANVAS_RENDERER;

    /**
     * The resolution of the canvas.
     *
     * @property resolution
     * @type Number
     */
    this.resolution = options.resolution;

    /**
     * This sets if the CanvasRenderer will clear the canvas or not before the new render pass.
     * If the Stage is NOT transparent Pixi will use a canvas sized fillRect operation every frame to set the canvas background color.
     * If the Stage is transparent Pixi will use clearRect to clear the canvas every frame.
     * Disable this by setting this to false. For example if your game has a canvas filling background image you often don't need this set.
     *
     * @property clearBeforeRender
     * @type Boolean
     * @default
     */
    this.clearBeforeRender = options.clearBeforeRender;

    /**
     * Whether the render view is transparent
     *
     * @property transparent
     * @type Boolean
     */
    this.transparent = options.transparent;

    /**
     * The width of the canvas view
     *
     * @property width
     * @type Number
     * @default 800
     */
    this.width = width || 800;

    /**
     * The height of the canvas view
     *
     * @property height
     * @type Number
     * @default 600
     */
    this.height = height || 600;

    this.width *= this.resolution;
    this.height *= this.resolution;

    /**
     * The canvas element that everything is drawn to.
     *
     * @property view
     * @type HTMLCanvasElement
     */
    this.view = options.view || document.createElement( "canvas" );

    /**
     * The canvas 2d context that everything is drawn with
     * @property context
     * @type CanvasRenderingContext2D
     */
    this.context = this.view.getContext( "2d", { alpha: this.transparent } );

    /**
     * Boolean flag controlling canvas refresh.
     *
     * @property refresh
     * @type Boolean
     */
    this.refresh = true;

    this.view.width = this.width * this.resolution;
    this.view.height = this.height * this.resolution;

    /**
     * Internal var.
     *
     * @property count
     * @type Number
     */
    this.count = 0;

    /**
     * Instance of a PIXI.CanvasMaskManager, handles masking when using the canvas renderer
     * @property CanvasMaskManager
     * @type CanvasMaskManager
     */
    this.maskManager = new PIXI.CanvasMaskManager();

    /**
     * The render session is just a bunch of parameter used for rendering
     * @property renderSession
     * @type Object
     */
    this.renderSession = {
        context: this.context,
        maskManager: this.maskManager,
        scaleMode: null,
        smoothProperty: null,
        /**
         * If true Pixi will Math.floor() x/y values when rendering, stopping pixel interpolation.
         * Handy for crisp pixel art and speed on legacy devices.
         *
         */
        roundPixels: false
    };

    this.mapBlendModes();

    this.resize(width, height);

    if("imageSmoothingEnabled" in this.context)
        this.renderSession.smoothProperty = "imageSmoothingEnabled";
    else if("webkitImageSmoothingEnabled" in this.context)
        this.renderSession.smoothProperty = "webkitImageSmoothingEnabled";
    else if("mozImageSmoothingEnabled" in this.context)
        this.renderSession.smoothProperty = "mozImageSmoothingEnabled";
    else if("oImageSmoothingEnabled" in this.context)
        this.renderSession.smoothProperty = "oImageSmoothingEnabled";
    else if ("msImageSmoothingEnabled" in this.context)
        this.renderSession.smoothProperty = "msImageSmoothingEnabled";
};

// constructor
PIXI.CanvasRenderer.prototype.constructor = PIXI.CanvasRenderer;

/**
 * Renders the Stage to this canvas view
 *
 * @method render
 * @param stage {Stage} the Stage element to be rendered
 */
PIXI.CanvasRenderer.prototype.render = function(stage)
{
    stage.updateTransform();

    this.context.setTransform(1,0,0,1,0,0);

    this.context.globalAlpha = 1;

    this.renderSession.currentBlendMode = PIXI.blendModes.NORMAL;
    this.context.globalCompositeOperation = PIXI.blendModesCanvas[PIXI.blendModes.NORMAL];

    if (navigator.isCocoonJS && this.view.screencanvas) {
        this.context.fillStyle = "black";
        this.context.clear();
    }

    if (this.clearBeforeRender)
    {
        if (this.transparent)
        {
            this.context.clearRect(0, 0, this.width, this.height);
        }
        else
        {
            this.context.fillStyle = stage.backgroundColorString;
            this.context.fillRect(0, 0, this.width , this.height);
        }
    }

    this.renderDisplayObject(stage);

    // run interaction!
    if(stage.interactive)
    {
        //need to add some events!
        if(!stage._interactiveEventsAdded)
        {
            stage._interactiveEventsAdded = true;
            stage.interactionManager.setTarget(this);
        }
    }
};

/**
 * Removes everything from the renderer and optionally removes the Canvas DOM element.
 *
 * @method destroy
 * @param [removeView=true] {boolean} Removes the Canvas element from the DOM.
 */
PIXI.CanvasRenderer.prototype.destroy = function(removeView)
{
    if (typeof removeView === "undefined") { removeView = true; }

    if (removeView && this.view.parent)
    {
        this.view.parent.removeChild(this.view);
    }

    this.view = null;
    this.context = null;
    this.maskManager = null;
    this.renderSession = null;

};

/**
 * Resizes the canvas view to the specified width and height
 *
 * @method resize
 * @param width {Number} the new width of the canvas view
 * @param height {Number} the new height of the canvas view
 */
PIXI.CanvasRenderer.prototype.resize = function(width, height)
{
    this.width = width * this.resolution;
    this.height = height * this.resolution;

    this.view.width = this.width;
    this.view.height = this.height;

    this.view.style.width = this.width / this.resolution + "px";
    this.view.style.height = this.height / this.resolution + "px";
};

/**
 * Renders a display object
 *
 * @method renderDisplayObject
 * @param displayObject {DisplayObject} The displayObject to render
 * @param context {CanvasRenderingContext2D} the context 2d method of the canvas
 * @private
 */
PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject, context)
{
    this.renderSession.context = context || this.context;
    this.renderSession.resolution = this.resolution;
    displayObject._renderCanvas(this.renderSession);
};

/**
 * Maps Pixi blend modes to canvas blend modes.
 *
 * @method mapBlendModes
 * @private
 */
PIXI.CanvasRenderer.prototype.mapBlendModes = function()
{
    if(!PIXI.blendModesCanvas)
    {
        PIXI.blendModesCanvas = [];

        if(PIXI.canUseNewCanvasBlendModes())
        {
            PIXI.blendModesCanvas[PIXI.blendModes.NORMAL]   = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.ADD]      = "lighter"; //IS THIS OK???
            PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply";
            PIXI.blendModesCanvas[PIXI.blendModes.SCREEN]   = "screen";
            PIXI.blendModesCanvas[PIXI.blendModes.OVERLAY]  = "overlay";
            PIXI.blendModesCanvas[PIXI.blendModes.DARKEN]   = "darken";
            PIXI.blendModesCanvas[PIXI.blendModes.LIGHTEN]  = "lighten";
            PIXI.blendModesCanvas[PIXI.blendModes.COLOR_DODGE] = "color-dodge";
            PIXI.blendModesCanvas[PIXI.blendModes.COLOR_BURN] = "color-burn";
            PIXI.blendModesCanvas[PIXI.blendModes.HARD_LIGHT] = "hard-light";
            PIXI.blendModesCanvas[PIXI.blendModes.SOFT_LIGHT] = "soft-light";
            PIXI.blendModesCanvas[PIXI.blendModes.DIFFERENCE] = "difference";
            PIXI.blendModesCanvas[PIXI.blendModes.EXCLUSION] = "exclusion";
            PIXI.blendModesCanvas[PIXI.blendModes.HUE]       = "hue";
            PIXI.blendModesCanvas[PIXI.blendModes.SATURATION] = "saturation";
            PIXI.blendModesCanvas[PIXI.blendModes.COLOR]      = "color";
            PIXI.blendModesCanvas[PIXI.blendModes.LUMINOSITY] = "luminosity";
        }
        else
        {
            // this means that the browser does not support the cool new blend modes in canvas "cough" ie "cough"
            PIXI.blendModesCanvas[PIXI.blendModes.NORMAL]   = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.ADD]      = "lighter"; //IS THIS OK???
            PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.SCREEN]   = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.OVERLAY]  = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.DARKEN]   = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.LIGHTEN]  = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.COLOR_DODGE] = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.COLOR_BURN] = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.HARD_LIGHT] = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.SOFT_LIGHT] = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.DIFFERENCE] = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.EXCLUSION] = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.HUE]       = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.SATURATION] = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.COLOR]      = "source-over";
            PIXI.blendModesCanvas[PIXI.blendModes.LUMINOSITY] = "source-over";
        }
    }
};
<|endoftext|>


<commit_before>import { PropTypes } from 'react';
import localizer from '../localizer';
import elementType from 'react-prop-types/lib/elementType';
import all from 'react-prop-types/lib/all';
import { views as Views } from './constants';
import {createChainableTypeChecker} from 'react-prop-types/lib/common';

export { elementType }

export let eventComponent = PropTypes.oneOfType([
  elementType,
  PropTypes.shape({
    month: elementType,
    week: elementType,
    day: elementType,
    agenda: elementType
  })
])

export let accessor = PropTypes.oneOfType([
  PropTypes.string,
  PropTypes.func
])

export let dateFormat = createChainableTypeChecker(
    (...args) => localizer.propType && localizer.propType(...args))

export let views = PropTypes.oneOfType([
  PropTypes.oneOf(
    Object.keys(Views).map(k => Views[k])
  ),
  all([
    PropTypes.object,
    (props, name, component)=>{
      let prop = props[name]
        , err;

      Object.keys(prop).every(
        key => !(err = elementType(prop, key, component)))

      return err || null
    }
  ])
])
<commit_msg>[fixed] view propType validation<commit_after>import { PropTypes } from 'react';
import localizer from '../localizer';
import elementType from 'react-prop-types/lib/elementType';
import all from 'react-prop-types/lib/all';
import { views as Views } from './constants';
import {createChainableTypeChecker} from 'react-prop-types/lib/common';

export { elementType }

export let eventComponent = PropTypes.oneOfType([
  elementType,
  PropTypes.shape({
    month: elementType,
    week: elementType,
    day: elementType,
    agenda: elementType
  })
])

let viewNames = PropTypes.oneOf(
  Object.keys(Views).map(k => Views[k])
);

export let accessor = PropTypes.oneOfType([
  PropTypes.string,
  PropTypes.func
])

export let dateFormat = createChainableTypeChecker(
    (...args) => localizer.propType && localizer.propType(...args))

export let views = PropTypes.oneOfType([
  PropTypes.arrayOf(viewNames),
  all([
    PropTypes.object,
    (props, name, component)=>{
      let prop = props[name]
        , err;

      Object.keys(prop).every(
        key => !(err = elementType(prop, key, component)))

      return err || null
    }
  ])
])
<|endoftext|>


<commit_before>import scitran from '../utils/scitran';
import uploads from '../utils/upload';
import actions from './upload.actions';

export default {

    /**
     * Current Files
     *
     * An array of file names that are currently being uploaded.
     */
    currentFiles: [],

    /**
     * Current Project Id
     */
    currentProjectId: null,

    /**
     * Handle Upload Response
     *
     * A generic response handler for all upload
     * related requests.
     */
    handleUploadResponse (err, res, callback) {
        if (err) {
            actions.uploadError();
        } else {
            callback(err, res);
        }
    },

    /**
     * Upload File
     *
     * Pushes upload details into an upload queue.
     */
    uploadFile (level, id, file, tag) {
        let url = level + '/' + id + '/file/' + file.name;
        uploads.add({url: url, file: file, tag: tag, progressStart: this.progressStart, progressEnd: this.progressEnd});
    },

    /**
     * Upload
     *
     * Takes an entire bids file tree and and file count
     * and recurses through and uploads all the files.
     * Additionally takes a progress callback that gets
     * updated at the start and end of every file or
     * folder upload request.
     */
    upload (userId, fileTree, count, progress) {
        let self = this;
        self.completed = 0;
        self.count = count;
        self.currentProjectId = null;
        self.progressStart = function (filename) {
            self.currentFiles.push(filename);
            progress({total: self.count, completed: self.completed, currentFiles: self.currentFiles});
        }
        self.progressEnd = function (filename) {
            let index = self.currentFiles.indexOf(filename);
            self.currentFiles.splice(index, 1);
            self.completed++;
            progress({total: self.count, completed: self.completed, currentFiles: self.currentFiles}, self.currentProjectId);
        }

        let existingProjectId = null;
        scitran.getProjects(function (projects) {
            for (let project of projects) {
                if (project.name === fileTree[0].name && project.group === userId) {
                    existingProjectId = project._id;
                    break;
                }
            }

            if (existingProjectId) {
                self.currentProjectId = existingProjectId;
                scitran.getBIDSDataset(existingProjectId, function (oldDataset) {
                    let newDataset = fileTree[0];
                    let oldDataset = oldDataset[0];
                    self.progressEnd();
                    self.resumeSubjects(newDataset.children, oldDataset.children, existingProjectId);
                });
            } else {
                let body = {
                    name: fileTree[0].name
                };
                scitran.createProject(userId,  body, function (err, res) {
                    let projectId = res.body._id;
                    let body2 = {
                        notes: [{author: 'uploadStatus', text: 'incomplete'}]
                    };
                    scitran.updateProject(projectId, body2, function (err1, res1) {
                        self.handleUploadResponse(err, res, function () {
                            self.progressEnd();
                            self.uploadSubjects(fileTree[0].children, projectId);
                        });
                    });
                });
            }

        });
    },

    /**
     * Upload Subjects
     *
     */
    uploadSubjects (subjects, projectId) {
        let self = this;
        self.currentProjectId = projectId;
        for (let subject of subjects) {
            if (subject.children && subject.children.length > 0) {
                self.progressStart(subject.name);
                scitran.createSubject(projectId, subject.name, function (err, res, name) {
                    self.handleUploadResponse(err, res, function () {
                        self.progressEnd(res.req._data.name);
                        let subjectId = res.body._id;
                        self.uploadSessions(subject.children, projectId, subjectId);
                    });
                });
            } else {
                self.uploadFile('projects', projectId, subject, 'project');
            }
        }
    },

    /**
     * Resume Subjects
     *
     */
    resumeSubjects (newSubjects, oldSubjects, projectId) {
        let subjectUploads = [];
        for (let i = 0; i < newSubjects.length; i++) {
            let newSubject = newSubjects[i];
            let oldSubject = this.contains(oldSubjects, newSubject);
            if (oldSubject) {
                this.progressStart(newSubject.name);
                this.progressEnd(newSubject.name);
                if (newSubject.type === 'folder') {
                    this.resumeSessions(newSubject.children, oldSubject.children, projectId, oldSubject._id);
                }
            } else {
                subjectUploads.push(newSubject);
            }
        }
        if (subjectUploads.length > 0) {
            this.uploadSubjects(subjectUploads, projectId);
        }
    },

    /**
     * Upload Sessions
     *
     */
    uploadSessions (sessions, projectId, subjectId) {
        let self = this;
        for (let session of sessions) {
            if (session.children && session.children.length > 0) {
                self.progressStart(session.name);
                scitran.createSession(projectId, subjectId, session.name, function (err, res, name) {
                    self.handleUploadResponse(err, res, function () {
                        self.progressEnd(res.req._data.name);
                        self.uploadModalities(session.children, res.body._id);
                    });
                });
            } else {
                self.uploadFile('sessions', subjectId, session, 'subject');
            }
        }
    },

    /**
     * Resume Sessions
     *
     */
    resumeSessions (newSessions, oldSessions, projectId, subjectId) {
        let sessionUploads = [];
        for (let i = 0; i < newSessions.length; i++) {
            let newSession = newSessions[i];
            let oldSession = this.contains(oldSessions, newSession);
            if (oldSession) {
                this.progressStart(newSession.name);
                this.progressEnd(newSession.name);
                if (newSession.type === 'folder') {
                    this.resumeModalities(newSession.children, oldSession.children, oldSession._id);
                }
            } else {
                sessionUploads.push(newSession);
            }
        }
        if (sessionUploads.length > 0) {
            this.uploadSessions(sessionUploads, projectId, subjectId);
        }
    },

    /**
     * Upload Modalities
     *
     */
    uploadModalities (modalities, subjectId) {
        let self = this;
        for (let modality of modalities) {
            if (modality.children && modality.children.length > 0) {
                self.progressStart(modality.name);
                scitran.createModality(subjectId, modality.name, function (err, res, name) {
                    self.handleUploadResponse(err, res, function () {
                        self.progressEnd(res.req._data.name);
                        let modalityId = res.body._id;
                        self.uploadAcquisitions(modality.children, modalityId);
                    });
                });
            } else {
                self.uploadFile('sessions', subjectId, modality, 'session');
            }
        }
    },

    /**
     * Resume Modalities
     *
     */
    resumeModalities (newModalities, oldModalities, subjectId) {
        let modalityUploads = [];
        for (let i = 0; i < newModalities.length; i++) {
            let newModality = newModalities[i];
            let oldModality = this.contains(oldModalities, newModality);
            if (oldModality) {
                this.progressStart(newModality.name);
                this.progressEnd(newModality.name);
                if (newModality.type === 'folder') {
                    this.resumeAcquisitions(newModality.children, oldModality.children, oldModality._id);
                }
            } else {
                modalityUploads.push(newModality);
            }
        }
        if (modalityUploads.length > 0) {
            this.uploadModalities(modalityUploads, subjectId);
        }
    },

    /**
     * Upload Acquisitions
     *
     */
    uploadAcquisitions (acquisitions, modalityId) {
        for (let acquisition of acquisitions) {
            this.uploadFile('acquisitions', modalityId, acquisition, 'modality');
        }
    },

    /**
     * Resume Acquisitions
     *
     */
    resumeAcquisitions (newAcquisitions, oldAcquisitions, modalityId) {
        let acquisitionUploads = [];
        for (let i = 0; i < newAcquisitions.length; i++) {
            let newAcquisition = newAcquisitions[i];
            let oldAcquisition = this.contains(oldAcquisitions, newAcquisition);
            if (oldAcquisition) {
                this.progressStart(newAcquisition.name);
                this.progressEnd(newAcquisition.name);
            } else {
                acquisitionUploads.push(newAcquisition);
            }
        }
        if (acquisitionUploads.length > 0) {
            this.uploadAcquisitions(acquisitionUploads, modalityId);
        }
    },

    /**
     * Contains
     *
     * Takes an array of container children and
     * an element. Checks if the element already
     * exists in the array and return the match
     * from the array.
     */
    contains (arr, elem) {
        let match = null;
        for (let i = 0; i < arr.length; i++) {
            let arrayElem = arr[i];
            if (arrayElem.name === elem.name) {
                match = arrayElem;
            }
        }
        return match;
    }

};
<commit_msg>moved progressEnd calls to the generic resnponse handler<commit_after>import scitran from '../utils/scitran';
import uploads from '../utils/upload';
import actions from './upload.actions';

export default {

    /**
     * Current Files
     *
     * An array of file names that are currently being uploaded.
     */
    currentFiles: [],

    /**
     * Current Project Id
     */
    currentProjectId: null,

    /**
     * Handle Upload Response
     *
     * A generic response handler for all upload
     * related requests.
     */
    handleUploadResponse (err, res, callback) {
        let name = res.req._data.name;
        this.progressEnd(name);
        if (err) {
            actions.uploadError();
        } else {
            callback(err, res);
        }
    },

    /**
     * Upload File
     *
     * Pushes upload details into an upload queue.
     */
    uploadFile (level, id, file, tag) {
        let url = level + '/' + id + '/file/' + file.name;
        uploads.add({url: url, file: file, tag: tag, progressStart: this.progressStart, progressEnd: this.progressEnd});
    },

    /**
     * Upload
     *
     * Takes an entire bids file tree and and file count
     * and recurses through and uploads all the files.
     * Additionally takes a progress callback that gets
     * updated at the start and end of every file or
     * folder upload request.
     */
    upload (userId, fileTree, count, progress) {
        let self = this;
        self.completed = 0;
        self.count = count;
        self.currentProjectId = null;
        self.progressStart = function (filename) {
            self.currentFiles.push(filename);
            progress({total: self.count, completed: self.completed, currentFiles: self.currentFiles});
        }
        self.progressEnd = function (filename) {
            let index = self.currentFiles.indexOf(filename);
            self.currentFiles.splice(index, 1);
            self.completed++;
            progress({total: self.count, completed: self.completed, currentFiles: self.currentFiles}, self.currentProjectId);
        }

        let existingProjectId = null;
        scitran.getProjects(function (projects) {
            for (let project of projects) {
                if (project.name === fileTree[0].name && project.group === userId) {
                    existingProjectId = project._id;
                    break;
                }
            }

            if (existingProjectId) {
                self.currentProjectId = existingProjectId;
                scitran.getBIDSDataset(existingProjectId, function (oldDataset) {
                    let newDataset = fileTree[0];
                    let oldDataset = oldDataset[0];
                    self.progressEnd();
                    self.resumeSubjects(newDataset.children, oldDataset.children, existingProjectId);
                });
            } else {
                let body = {
                    name: fileTree[0].name
                };
                scitran.createProject(userId,  body, function (err, res) {
                    let projectId = res.body._id;
                    let body2 = {
                        notes: [{author: 'uploadStatus', text: 'incomplete'}]
                    };
                    scitran.updateProject(projectId, body2, function (err1, res1) {
                        self.handleUploadResponse(err, res, function () {
                            self.uploadSubjects(fileTree[0].children, projectId);
                        });
                    });
                });
            }

        });
    },

    /**
     * Upload Subjects
     *
     */
    uploadSubjects (subjects, projectId) {
        let self = this;
        self.currentProjectId = projectId;
        for (let subject of subjects) {
            if (subject.children && subject.children.length > 0) {
                self.progressStart(subject.name);
                scitran.createSubject(projectId, subject.name, function (err, res, name) {
                    self.handleUploadResponse(err, res, function () {
                        let subjectId = res.body._id;
                        self.uploadSessions(subject.children, projectId, subjectId);
                    });
                });
            } else {
                self.uploadFile('projects', projectId, subject, 'project');
            }
        }
    },

    /**
     * Resume Subjects
     *
     */
    resumeSubjects (newSubjects, oldSubjects, projectId) {
        let subjectUploads = [];
        for (let i = 0; i < newSubjects.length; i++) {
            let newSubject = newSubjects[i];
            let oldSubject = this.contains(oldSubjects, newSubject);
            if (oldSubject) {
                this.progressStart(newSubject.name);
                this.progressEnd(newSubject.name);
                if (newSubject.type === 'folder') {
                    this.resumeSessions(newSubject.children, oldSubject.children, projectId, oldSubject._id);
                }
            } else {
                subjectUploads.push(newSubject);
            }
        }
        if (subjectUploads.length > 0) {
            this.uploadSubjects(subjectUploads, projectId);
        }
    },

    /**
     * Upload Sessions
     *
     */
    uploadSessions (sessions, projectId, subjectId) {
        let self = this;
        for (let session of sessions) {
            if (session.children && session.children.length > 0) {
                self.progressStart(session.name);
                scitran.createSession(projectId, subjectId, session.name, function (err, res, name) {
                    self.handleUploadResponse(err, res, function () {
                        self.uploadModalities(session.children, res.body._id);
                    });
                });
            } else {
                self.uploadFile('sessions', subjectId, session, 'subject');
            }
        }
    },

    /**
     * Resume Sessions
     *
     */
    resumeSessions (newSessions, oldSessions, projectId, subjectId) {
        let sessionUploads = [];
        for (let i = 0; i < newSessions.length; i++) {
            let newSession = newSessions[i];
            let oldSession = this.contains(oldSessions, newSession);
            if (oldSession) {
                this.progressStart(newSession.name);
                this.progressEnd(newSession.name);
                if (newSession.type === 'folder') {
                    this.resumeModalities(newSession.children, oldSession.children, oldSession._id);
                }
            } else {
                sessionUploads.push(newSession);
            }
        }
        if (sessionUploads.length > 0) {
            this.uploadSessions(sessionUploads, projectId, subjectId);
        }
    },

    /**
     * Upload Modalities
     *
     */
    uploadModalities (modalities, subjectId) {
        let self = this;
        for (let modality of modalities) {
            if (modality.children && modality.children.length > 0) {
                self.progressStart(modality.name);
                scitran.createModality(subjectId, modality.name, function (err, res, name) {
                    self.handleUploadResponse(err, res, function () {
                        let modalityId = res.body._id;
                        self.uploadAcquisitions(modality.children, modalityId);
                    });
                });
            } else {
                self.uploadFile('sessions', subjectId, modality, 'session');
            }
        }
    },

    /**
     * Resume Modalities
     *
     */
    resumeModalities (newModalities, oldModalities, subjectId) {
        let modalityUploads = [];
        for (let i = 0; i < newModalities.length; i++) {
            let newModality = newModalities[i];
            let oldModality = this.contains(oldModalities, newModality);
            if (oldModality) {
                this.progressStart(newModality.name);
                this.progressEnd(newModality.name);
                if (newModality.type === 'folder') {
                    this.resumeAcquisitions(newModality.children, oldModality.children, oldModality._id);
                }
            } else {
                modalityUploads.push(newModality);
            }
        }
        if (modalityUploads.length > 0) {
            this.uploadModalities(modalityUploads, subjectId);
        }
    },

    /**
     * Upload Acquisitions
     *
     */
    uploadAcquisitions (acquisitions, modalityId) {
        for (let acquisition of acquisitions) {
            this.uploadFile('acquisitions', modalityId, acquisition, 'modality');
        }
    },

    /**
     * Resume Acquisitions
     *
     */
    resumeAcquisitions (newAcquisitions, oldAcquisitions, modalityId) {
        let acquisitionUploads = [];
        for (let i = 0; i < newAcquisitions.length; i++) {
            let newAcquisition = newAcquisitions[i];
            let oldAcquisition = this.contains(oldAcquisitions, newAcquisition);
            if (oldAcquisition) {
                this.progressStart(newAcquisition.name);
                this.progressEnd(newAcquisition.name);
            } else {
                acquisitionUploads.push(newAcquisition);
            }
        }
        if (acquisitionUploads.length > 0) {
            this.uploadAcquisitions(acquisitionUploads, modalityId);
        }
    },

    /**
     * Contains
     *
     * Takes an array of container children and
     * an element. Checks if the element already
     * exists in the array and return the match
     * from the array.
     */
    contains (arr, elem) {
        let match = null;
        for (let i = 0; i < arr.length; i++) {
            let arrayElem = arr[i];
            if (arrayElem.name === elem.name) {
                match = arrayElem;
            }
        }
        return match;
    }

};
<|endoftext|>


<commit_before>'use strict';

var tmp      = require('../helpers/tmp');
var conf     = require('../helpers/conf');
var Promise  = require('../../lib/ext/promise');
var exec     = Promise.denodeify(require('child_process').exec);
var path     = require('path');
var rimraf   = Promise.denodeify(require('rimraf'));
var fs       = require('fs');
var crypto   = require('crypto');
var assert   = require('assert');
var walkSync = require('walk-sync');
var appName  = 'some-cool-app';

describe('Acceptance: smoke-test', function() {
  before(conf.setup);

  after(conf.restore);

  beforeEach(function() {
    tmp.setup('./tmp');
    process.chdir('./tmp');
  });

  afterEach(function() {
    tmp.teardown('./tmp');
  });

  it('ember new foo, clean from scratch', function() {
    console.log('    running the slow end-to-end it will take some time');

    this.timeout(360000);

    var appsECLIPath = path.join(appName, 'node_modules', 'ember-cli');

    return exec('pwd').then(function(pwd) {
      return exec(path.join('..', 'bin', 'ember') + ' new ' + appName).then(function() {
        return rimraf(appsECLIPath).then(function() {
          fs.symlinkSync(path.join(pwd, '..'), appsECLIPath);

          process.chdir(appName);

          return exec(path.join('.', 'node_modules', 'ember-cli', 'bin', 'ember') + ' test').then(console.log);
        });
      });
    }).finally(function() {
      console.log('done!');
    });
  });

  it('ember new foo, build production and verify fingerprint', function() {
    console.log('    running the slow fingerprint it will take some time');

    this.timeout(360000);

    var appsECLIPath = path.join(appName, 'node_modules', 'ember-cli');
    var globalPwd = null;

    return exec('pwd').then(function(pwd) {
      globalPwd = pwd;

      return exec(path.join('..', 'bin', 'ember') + ' new ' + appName);
    }).then(function() {
      return rimraf(appsECLIPath);
    }).then(function() {
      fs.symlinkSync(path.join(globalPwd, '..'), appsECLIPath);

      process.chdir(appName);

      return exec(path.join('.', 'node_modules', 'ember-cli', 'bin', 'ember') + ' build --environment=production');
    }).then(function() {
      var dirPath = path.join('.', 'dist', 'assets');
      var dir = fs.readdirSync(dirPath);
      var files = [];

      dir.forEach(function (filepath) {
        if (filepath === '.gitkeep') {
          return;
        }

        files.push(filepath);

        var file = fs.readFileSync(path.join(dirPath, filepath), { encoding: 'utf8' });

        var md5 = crypto.createHash('md5');
        md5.update(file);
        var hex = md5.digest('hex');

        var possibleNames = [appName + '-' + hex + '.js', appName + '-' + hex + '.css', 'vendor-' + hex + '.css'];
        assert(possibleNames.indexOf(filepath) > -1);
      });

      var indexHtml = fs.readFileSync(path.join('.', 'dist', 'index.html'), { encoding: 'utf8' });

      files.forEach(function (filename) {
        assert(indexHtml.indexOf(filename) > -1);
      });
    }).finally(function() {
      console.log('done');
    });
  });

  it('ember new foo, build development, and verify generated files', function() {
    console.log('    running the slow build tests');

    this.timeout(360000);

    var appsECLIPath = path.join(appName, 'node_modules', 'ember-cli');
    var globalPwd = null;

    return exec('pwd').then(function(pwd) {
      globalPwd = pwd;

      return exec(path.join('..', 'bin', 'ember') + ' new ' + appName);
    }).then(function() {
      return rimraf(appsECLIPath);
    }).then(function() {
      fs.symlinkSync(path.join(globalPwd, '..'), appsECLIPath);

      process.chdir(appName);

      return exec(path.join('.', 'node_modules', 'ember-cli', 'bin', 'ember') + ' build');
    }).then(function() {
      var dirPath = path.join('.', 'dist');
      var paths = walkSync(dirPath);

      assert(paths.length < 20);
    }).finally(function() {
      console.log('done');
    });
  });
});
<commit_msg>Make the smoke-test timeout two minutes longer<commit_after>'use strict';

var tmp      = require('../helpers/tmp');
var conf     = require('../helpers/conf');
var Promise  = require('../../lib/ext/promise');
var exec     = Promise.denodeify(require('child_process').exec);
var path     = require('path');
var rimraf   = Promise.denodeify(require('rimraf'));
var fs       = require('fs');
var crypto   = require('crypto');
var assert   = require('assert');
var walkSync = require('walk-sync');
var appName  = 'some-cool-app';

describe('Acceptance: smoke-test', function() {
  before(conf.setup);

  after(conf.restore);

  beforeEach(function() {
    tmp.setup('./tmp');
    process.chdir('./tmp');
  });

  afterEach(function() {
    tmp.teardown('./tmp');
  });

  it('ember new foo, clean from scratch', function() {
    console.log('    running the slow end-to-end it will take some time');

    this.timeout(450000);

    var appsECLIPath = path.join(appName, 'node_modules', 'ember-cli');

    return exec('pwd').then(function(pwd) {
      return exec(path.join('..', 'bin', 'ember') + ' new ' + appName).then(function() {
        return rimraf(appsECLIPath).then(function() {
          fs.symlinkSync(path.join(pwd, '..'), appsECLIPath);

          process.chdir(appName);

          return exec(path.join('.', 'node_modules', 'ember-cli', 'bin', 'ember') + ' test').then(console.log);
        });
      });
    }).finally(function() {
      console.log('done!');
    });
  });

  it('ember new foo, build production and verify fingerprint', function() {
    console.log('    running the slow fingerprint it will take some time');

    this.timeout(360000);

    var appsECLIPath = path.join(appName, 'node_modules', 'ember-cli');
    var globalPwd = null;

    return exec('pwd').then(function(pwd) {
      globalPwd = pwd;

      return exec(path.join('..', 'bin', 'ember') + ' new ' + appName);
    }).then(function() {
      return rimraf(appsECLIPath);
    }).then(function() {
      fs.symlinkSync(path.join(globalPwd, '..'), appsECLIPath);

      process.chdir(appName);

      return exec(path.join('.', 'node_modules', 'ember-cli', 'bin', 'ember') + ' build --environment=production');
    }).then(function() {
      var dirPath = path.join('.', 'dist', 'assets');
      var dir = fs.readdirSync(dirPath);
      var files = [];

      dir.forEach(function (filepath) {
        if (filepath === '.gitkeep') {
          return;
        }

        files.push(filepath);

        var file = fs.readFileSync(path.join(dirPath, filepath), { encoding: 'utf8' });

        var md5 = crypto.createHash('md5');
        md5.update(file);
        var hex = md5.digest('hex');

        var possibleNames = [appName + '-' + hex + '.js', appName + '-' + hex + '.css', 'vendor-' + hex + '.css'];
        assert(possibleNames.indexOf(filepath) > -1);
      });

      var indexHtml = fs.readFileSync(path.join('.', 'dist', 'index.html'), { encoding: 'utf8' });

      files.forEach(function (filename) {
        assert(indexHtml.indexOf(filename) > -1);
      });
    }).finally(function() {
      console.log('done');
    });
  });

  it('ember new foo, build development, and verify generated files', function() {
    console.log('    running the slow build tests');

    this.timeout(360000);

    var appsECLIPath = path.join(appName, 'node_modules', 'ember-cli');
    var globalPwd = null;

    return exec('pwd').then(function(pwd) {
      globalPwd = pwd;

      return exec(path.join('..', 'bin', 'ember') + ' new ' + appName);
    }).then(function() {
      return rimraf(appsECLIPath);
    }).then(function() {
      fs.symlinkSync(path.join(globalPwd, '..'), appsECLIPath);

      process.chdir(appName);

      return exec(path.join('.', 'node_modules', 'ember-cli', 'bin', 'ember') + ' build');
    }).then(function() {
      var dirPath = path.join('.', 'dist');
      var paths = walkSync(dirPath);

      assert(paths.length < 20);
    }).finally(function() {
      console.log('done');
    });
  });
});
<|endoftext|>


<commit_before>import scitran from '../utils/scitran';
import bids    from '../utils/bids';
import uploads from '../utils/upload';
import files   from '../utils/files';
import config  from '../../../config';
import diff    from './diff';

export default {

// progress --------------------------------------------------------------------------

    /**
     * Current Project Id
     */
    currentProjectId: null,

    /**
     * Current Files
     *
     * An array of file names that are currently being uploaded.
     */
    currentFiles: [],

    /**
     * Total
     */
    total: 0,

    /**
     * Completed
     */
    completed: 0,

// upload ----------------------------------------------------------------------------

    /**
     * Handle Upload Response
     *
     * A generic response handler for all upload
     * related requests.
     */
    handleUploadResponse (err, res, callback) {
        let name = res.req._data.name;
        this.progressEnd(name);
        if (err) {
            this.error(err, res.req);
        } else {
            callback(err, res);
        }
    },

    /**
     * Upload File
     *
     * Pushes upload details into an upload queue.
     */
    uploadFile (level, id, file, tag) {
        let url = config.scitran.url +  level + '/' + id + '/files';
        uploads.add({url: url, file: file, tags: [tag], progressStart: this.progressStart, progressEnd: this.progressEnd, error: this.error});
    },

    /**
     * Upload
     *
     * Takes an entire bids file tree and and file count
     * and recurses through and uploads all the files.
     * Additionally takes a progress callback that gets
     * updated at the start and end of every file or
     * folder upload request and an error callback.
     */
    upload (userId, fileTree, validation, summary, count, progress, error) {
        this.total = count;
        this.currentProjectId = null;
        this.progressStart = (filename) => {
            this.currentFiles.push(filename);
            progress({type: 'upload', total: this.total, completed: this.completed, currentFiles: this.currentFiles});
        };
        this.progressEnd = (filename) => {
            let index = this.currentFiles.indexOf(filename);
            this.currentFiles.splice(index, 1);
            this.completed++;
            progress({type: 'upload', total: this.total, completed: this.completed, currentFiles: this.currentFiles}, this.currentProjectId);
        };
        let existingProject = null;
        scitran.getProjects({authenticate: true}, (projects) => {
            for (let project of projects) {
                if (project.label === fileTree[0].name && project.group === userId) {
                    project.children = project.files;
                    existingProject  = project;
                    break;
                }
            }

            if (existingProject) {
                this.progressEnd();
                this.currentProjectId = existingProject._id;
                bids.getDatasetTree(existingProject, (oldDataset) => {
                    let newDataset = fileTree[0];
                    diff.datasets(newDataset.children, oldDataset[0].children, (subjectUploads, completedFiles) => {
                        this.completed = this.completed + completedFiles.length;
                        progress({total: this.total, completed: this.completed, currentFiles: this.currentFiles, resumeStart: this.completed});
                        this.uploadSubjects(newDataset.name, subjectUploads, this.currentProjectId);
                    });
                }, {}, (resumeProgress) => {
                    resumeProgress.type = 'resume';
                    progress(resumeProgress);
                });
            } else {
                let body = {
                    label: fileTree[0].name,
                    group: userId
                };
                scitran.createProject(body, (err, res) => {
                    this.handleUploadResponse(err, res, () => {
                        let projectId = res.body._id;
                        scitran.addTag('projects', projectId, 'incomplete', () => {
                            this.uploadSubjects(fileTree[0].name, fileTree[0].children, projectId, validation, summary);
                        });
                    });
                });
            }
        });
    },

    /**
     * Upload Subjects
     *
     */
    uploadSubjects (datasetName, subjects, projectId, validation, summary) {
        this.currentProjectId = projectId;
        for (let subject of subjects) {
            if (subject.children) {
                if (subject.ignore) {
                    this.uploadSessions(subject.children, projectId, subject._id);
                } else {
                    this.progressStart(subject.name);
                    scitran.createSubject(projectId, subject.name, (err, res) => {
                        this.handleUploadResponse(err, res, () => {
                            let subjectId = res.body._id;
                            this.uploadSessions(subject.children, projectId, subjectId);
                        });
                    });
                }
            } else {
                if (subject.name === 'dataset_description.json') {
                    files.read(subject, (contents) => {
                        let description = JSON.parse(contents);
                        description.Name = datasetName;
                        let authors = [];
                        if (description.hasOwnProperty('Authors')) {
                            for (let i = 0; i < description.Authors.length; i++) {
                                let author = description.Authors[i];
                                authors.push({name: author, ORCIDID: ''});
                            }
                        }
                        scitran.updateProject(projectId, {metadata: {authors, validation, summary}}, () => {
                            let file = new File([JSON.stringify(description)], 'dataset_description.json', {type: 'application/json'});
                            this.uploadFile('projects', projectId, file, 'project');
                        });
                    });

                } else {
                    this.uploadFile('projects', projectId, subject, 'project');
                }
            }
        }
    },

    /**
     * Upload Sessions
     *
     */
    uploadSessions (sessions, projectId, subjectId) {
        for (let session of sessions) {
            if (session.children) {
                if (session.ignore) {
                    this.uploadModalities(session.children, session._id);
                } else {
                    this.progressStart(session.name);
                    scitran.createSession(projectId, subjectId, session.name, (err, res) => {
                        this.handleUploadResponse(err, res, () => {
                            this.uploadModalities(session.children, res.body._id);
                        });
                    });
                }
            } else {
                this.uploadFile('sessions', subjectId, session, 'subject');
            }
        }
    },

    /**
     * Upload Modalities
     *
     */
    uploadModalities (modalities, subjectId) {
        for (let modality of modalities) {
            if (modality.children) {
                if (modality.ignore) {
                    this.uploadAcquisitions(modality.children, modality._id);
                } else {
                    this.progressStart(modality.name);
                    scitran.createModality(subjectId, modality.name, (err, res) => {
                        this.handleUploadResponse(err, res, () => {
                            let modalityId = res.body._id;
                            this.uploadAcquisitions(modality.children, modalityId);
                        });
                    });
                }
            } else {
                this.uploadFile('sessions', subjectId, modality, 'session');
            }
        }
    },

    /**
     * Upload Acquisitions
     *
     */
    uploadAcquisitions (acquisitions, modalityId) {
        for (let acquisition of acquisitions) {
            this.uploadFile('acquisitions', modalityId, acquisition, 'modality');
        }
    }

};
<commit_msg>Reset completed progress when new upload is started<commit_after>import scitran from '../utils/scitran';
import bids    from '../utils/bids';
import uploads from '../utils/upload';
import files   from '../utils/files';
import config  from '../../../config';
import diff    from './diff';

export default {

// progress --------------------------------------------------------------------------

    /**
     * Current Project Id
     */
    currentProjectId: null,

    /**
     * Current Files
     *
     * An array of file names that are currently being uploaded.
     */
    currentFiles: [],

    /**
     * Total
     */
    total: 0,

    /**
     * Completed
     */
    completed: 0,

// upload ----------------------------------------------------------------------------

    /**
     * Handle Upload Response
     *
     * A generic response handler for all upload
     * related requests.
     */
    handleUploadResponse (err, res, callback) {
        let name = res.req._data.name;
        this.progressEnd(name);
        if (err) {
            this.error(err, res.req);
        } else {
            callback(err, res);
        }
    },

    /**
     * Upload File
     *
     * Pushes upload details into an upload queue.
     */
    uploadFile (level, id, file, tag) {
        let url = config.scitran.url +  level + '/' + id + '/files';
        uploads.add({url: url, file: file, tags: [tag], progressStart: this.progressStart, progressEnd: this.progressEnd, error: this.error});
    },

    /**
     * Upload
     *
     * Takes an entire bids file tree and and file count
     * and recurses through and uploads all the files.
     * Additionally takes a progress callback that gets
     * updated at the start and end of every file or
     * folder upload request and an error callback.
     */
    upload (userId, fileTree, validation, summary, count, progress, error) {
        this.total = count;
        this.completed = 0;
        this.currentProjectId = null;
        this.progressStart = (filename) => {
            this.currentFiles.push(filename);
            progress({type: 'upload', total: this.total, completed: this.completed, currentFiles: this.currentFiles});
        };
        this.progressEnd = (filename) => {
            let index = this.currentFiles.indexOf(filename);
            this.currentFiles.splice(index, 1);
            this.completed++;
            progress({type: 'upload', total: this.total, completed: this.completed, currentFiles: this.currentFiles}, this.currentProjectId);
        };
        let existingProject = null;
        scitran.getProjects({authenticate: true}, (projects) => {
            for (let project of projects) {
                if (project.label === fileTree[0].name && project.group === userId) {
                    project.children = project.files;
                    existingProject  = project;
                    break;
                }
            }

            if (existingProject) {
                this.progressEnd();
                this.currentProjectId = existingProject._id;
                bids.getDatasetTree(existingProject, (oldDataset) => {
                    let newDataset = fileTree[0];
                    diff.datasets(newDataset.children, oldDataset[0].children, (subjectUploads, completedFiles) => {
                        this.completed = this.completed + completedFiles.length;
                        progress({total: this.total, completed: this.completed, currentFiles: this.currentFiles, resumeStart: this.completed});
                        this.uploadSubjects(newDataset.name, subjectUploads, this.currentProjectId);
                    });
                }, {}, (resumeProgress) => {
                    resumeProgress.type = 'resume';
                    progress(resumeProgress);
                });
            } else {
                let body = {
                    label: fileTree[0].name,
                    group: userId
                };
                scitran.createProject(body, (err, res) => {
                    this.handleUploadResponse(err, res, () => {
                        let projectId = res.body._id;
                        scitran.addTag('projects', projectId, 'incomplete', () => {
                            this.uploadSubjects(fileTree[0].name, fileTree[0].children, projectId, validation, summary);
                        });
                    });
                });
            }
        });
    },

    /**
     * Upload Subjects
     *
     */
    uploadSubjects (datasetName, subjects, projectId, validation, summary) {
        this.currentProjectId = projectId;
        for (let subject of subjects) {
            if (subject.children) {
                if (subject.ignore) {
                    this.uploadSessions(subject.children, projectId, subject._id);
                } else {
                    this.progressStart(subject.name);
                    scitran.createSubject(projectId, subject.name, (err, res) => {
                        this.handleUploadResponse(err, res, () => {
                            let subjectId = res.body._id;
                            this.uploadSessions(subject.children, projectId, subjectId);
                        });
                    });
                }
            } else {
                if (subject.name === 'dataset_description.json') {
                    files.read(subject, (contents) => {
                        let description = JSON.parse(contents);
                        description.Name = datasetName;
                        let authors = [];
                        if (description.hasOwnProperty('Authors')) {
                            for (let i = 0; i < description.Authors.length; i++) {
                                let author = description.Authors[i];
                                authors.push({name: author, ORCIDID: ''});
                            }
                        }
                        scitran.updateProject(projectId, {metadata: {authors, validation, summary}}, () => {
                            let file = new File([JSON.stringify(description)], 'dataset_description.json', {type: 'application/json'});
                            this.uploadFile('projects', projectId, file, 'project');
                        });
                    });

                } else {
                    this.uploadFile('projects', projectId, subject, 'project');
                }
            }
        }
    },

    /**
     * Upload Sessions
     *
     */
    uploadSessions (sessions, projectId, subjectId) {
        for (let session of sessions) {
            if (session.children) {
                if (session.ignore) {
                    this.uploadModalities(session.children, session._id);
                } else {
                    this.progressStart(session.name);
                    scitran.createSession(projectId, subjectId, session.name, (err, res) => {
                        this.handleUploadResponse(err, res, () => {
                            this.uploadModalities(session.children, res.body._id);
                        });
                    });
                }
            } else {
                this.uploadFile('sessions', subjectId, session, 'subject');
            }
        }
    },

    /**
     * Upload Modalities
     *
     */
    uploadModalities (modalities, subjectId) {
        for (let modality of modalities) {
            if (modality.children) {
                if (modality.ignore) {
                    this.uploadAcquisitions(modality.children, modality._id);
                } else {
                    this.progressStart(modality.name);
                    scitran.createModality(subjectId, modality.name, (err, res) => {
                        this.handleUploadResponse(err, res, () => {
                            let modalityId = res.body._id;
                            this.uploadAcquisitions(modality.children, modalityId);
                        });
                    });
                }
            } else {
                this.uploadFile('sessions', subjectId, modality, 'session');
            }
        }
    },

    /**
     * Upload Acquisitions
     *
     */
    uploadAcquisitions (acquisitions, modalityId) {
        for (let acquisition of acquisitions) {
            this.uploadFile('acquisitions', modalityId, acquisition, 'modality');
        }
    }

};
<|endoftext|>


<commit_before>import request from './request';
import async   from 'async';

/**
 * Scitran
 *
 * A library for interactions with the
 * scitran service.
 */
export default  {

// User Management ------------------------------------------------------------------------

    /**
     * Get Users
     *
     * Gets a list of all users
     */
    getUsers (callback) {
        request.get('users', callback);
    },

    /**
     * Verify User
     *
     * Checks if the currently logged in users
     * in in the scitran system and returns a
     * user object.
     */
    verifyUser (callback) {
        request.get('users/self', callback);
    },

    /**
     * Add User
     *
     * Takes an email, first name, and last name
     * add adds the user.
     */
    addUser (userData, callback) {
        let self = this;
        request.post('users', {body: userData}, function (err, res) {
            self.createGroup(userData._id, userData._id, callback);
        });
    },

    /**
     * Remove User
     *
     * Takes a userId and removes the user.
     */
     removeUser (userId, callback) {
        request.del('users/' + userId, function (err, res) {
            request.del('groups/' + userId, function (err, res) {
                callback(err, res);
            });
        });
     },

// Create ---------------------------------------------------------------------------------

    /**
     * Create Group
     *
     * Takes a groupName and a userId and
     * creates a group with that user as the
     * admin.
     */
    createGroup (groupName, userId, callback) {
        let body = {
            _id: groupName,
            roles: [{access: 'admin', _id: userId}]
        };
        request.post('groups', {body: body}, callback);
    },

    /**
     * Create Project
     *
     * Takes a group name and a project name and
     * generates a request to make a project in scitran.
     */
    createProject (groupName, projectName, callback) {
        let self = this;
        let body = {name: projectName};
        request.post('groups/' + groupName + '/projects', {body: body}, callback);
    },

    /**
     * Create Subject
     *
     */
    createSubject (projectId, subjectName, callback) {
        let self = this;
        let body = {label: subjectName, subject_code: 'subject'};
        request.post('projects/' + projectId + '/sessions', {body: body}, callback);
    },

    /**
     * Create Session
     *
     */
    createSession (projectId, subjectId, sessionName, callback) {
        let self = this;
        let body = {label: sessionName, subject_code: subjectId};
        request.post('projects/' + projectId + '/sessions', {body: body}, callback);
    },

    /**
     * Create Modality
     *
     */
    createModality (sessionId, modalityName, callback) {
        let self = this;
        let body = {label: modalityName, datatype: 'modality'};
        request.post('sessions/' + sessionId + '/acquisitions', {body: body}, callback);
    },

// Read -----------------------------------------------------------------------------------

    /**
     * Get Projects
     *
     */
    getProjects (callback) {
        request.get('projects', function (err, res) {
            callback(res.body);
        });
    },

    /**
     * Get Sessions
     *
     */
    getSessions (projectId, callback) {
        request.get('projects/' + projectId + '/sessions', function (err, res) {
            callback(res.body);
        });
    },

    /**
     * Get Acquisitions
     *
     */
    getAcquisitions (sessionId, callback) {
        request.get('sessions/' + sessionId + '/acquisitions', function (err, res) {
            callback(res.body);
        });
    },

    getBIDSSubjects (projectId, callback) {
        this.getSessions(projectId, function (sessions) {
            let subjects = [];
            async.each(sessions, function (session, cb) {
                if (session.subject_code === 'subject') {
                    request.get('sessions/' + session._id, function (err, res) {
                        session.children = res.body.files;
                        session.name = session.label;
                        subjects.push(session);
                        cb();
                    })
                } else {
                    cb();
                }
            }, function () {
                callback(subjects);
            });
        });
    },

    getBIDSSessions (projectId, subjectId, callback) {
        this.getSessions(projectId, function (sciSessions) {
            let sessions = [];
            async.each(sciSessions, function (session, cb) {
                if (session.subject_code === subjectId) {
                    request.get('sessions/' + session._id, function (err, res) {
                        session.children = res.body.files;
                        session.name = session.label;
                        sessions.push(session);
                        cb();
                    })
                } else {
                    cb();
                }
            }, function () {
                callback(sessions);
            });
        });
    },

    getBIDSModalities (sessionId, callback) {
        request.get('sessions/' + sessionId + '/acquisitions', function (err, res) {
            callback(res.body);
        });
    },

    getBIDSDataset (projectId, callback) {
        let self = this;
        let dataset = {};
        request.get('projects/' + projectId, function (err, res) {
            if (res.status !== 200) {return callback(res);}
            for (let file of res.body.files) {file.name = file.filename;}
            dataset.name = res.body.name;
            dataset.type = 'folder';
            dataset.children = res.body.files;
            self.getBIDSSubjects(res.body._id, function (subjects) {
                dataset.children = dataset.children.concat(subjects);
                async.each(subjects, function (subject, cb) {
                    self.getBIDSSessions(projectId, subject._id, function (sessions) {
                        subject.children = subject.children.concat(sessions);
                        async.each(sessions, function (session, cb1) {
                            self.getBIDSModalities(session._id, function (modalities) {
                                session.children = session.children.concat(modalities);
                                async.each(modalities, function (modality, cb2) {
                                    request.get('acquisitions/' + modality._id, function (err, res) {
                                        for (let file of res.body.files) {file.name = file.filename;}
                                        modality.children = res.body.files;
                                        modality.name = modality.label;
                                        cb2();
                                    });
                                }, cb1);
                            });
                        }, cb);
                    });
                }, function () {callback([dataset])});
            });
        });
    },

// Delete ---------------------------------------------------------------------------------

    /**
     * Delete Container
     *
     */
    deleteContainer (type, id, callback) {
        request.del(type + '/' + id, function (err, res) {
            callback();
        });
    },

    deleteDataset (projectId, callback) {
        let self = this;
        this.getSessions(projectId, function (sessions) {
            async.each(sessions, function (session, cb) {
                self.getAcquisitions(session._id, function (acquisitions) {
                    async.each(acquisitions, function (acquisition, cb1) {
                        self.deleteContainer('acquisitions', acquisition._id, cb1);
                    }, function () {
                        self.deleteContainer('sessions', session._id, cb);
                    });
                });
            }, function () {
                self.deleteContainer('projects', projectId, callback);
            });
        });
    }

};<commit_msg>added project update method<commit_after>import request from './request';
import async   from 'async';

/**
 * Scitran
 *
 * A library for interactions with the
 * scitran service.
 */
export default  {

// User Management ------------------------------------------------------------------------

    /**
     * Get Users
     *
     * Gets a list of all users
     */
    getUsers (callback) {
        request.get('users', callback);
    },

    /**
     * Verify User
     *
     * Checks if the currently logged in users
     * in in the scitran system and returns a
     * user object.
     */
    verifyUser (callback) {
        request.get('users/self', callback);
    },

    /**
     * Add User
     *
     * Takes an email, first name, and last name
     * add adds the user.
     */
    addUser (userData, callback) {
        let self = this;
        request.post('users', {body: userData}, function (err, res) {
            self.createGroup(userData._id, userData._id, callback);
        });
    },

    /**
     * Remove User
     *
     * Takes a userId and removes the user.
     */
     removeUser (userId, callback) {
        request.del('users/' + userId, function (err, res) {
            request.del('groups/' + userId, function (err, res) {
                callback(err, res);
            });
        });
     },

// Create ---------------------------------------------------------------------------------

    /**
     * Create Group
     *
     * Takes a groupName and a userId and
     * creates a group with that user as the
     * admin.
     */
    createGroup (groupName, userId, callback) {
        let body = {
            _id: groupName,
            roles: [{access: 'admin', _id: userId}]
        };
        request.post('groups', {body: body}, callback);
    },

    /**
     * Create Project
     *
     * Takes a group name and a project name and
     * generates a request to make a project in scitran.
     */
    createProject (groupName, projectName, callback) {
        let self = this;
        let body = {name: projectName};
        request.post('groups/' + groupName + '/projects', {body: body}, callback);
    },

    /**
     * Create Subject
     *
     */
    createSubject (projectId, subjectName, callback) {
        let self = this;
        let body = {label: subjectName, subject_code: 'subject'};
        request.post('projects/' + projectId + '/sessions', {body: body}, callback);
    },

    /**
     * Create Session
     *
     */
    createSession (projectId, subjectId, sessionName, callback) {
        let self = this;
        let body = {label: sessionName, subject_code: subjectId};
        request.post('projects/' + projectId + '/sessions', {body: body}, callback);
    },

    /**
     * Create Modality
     *
     */
    createModality (sessionId, modalityName, callback) {
        let self = this;
        let body = {label: modalityName, datatype: 'modality'};
        request.post('sessions/' + sessionId + '/acquisitions', {body: body}, callback);
    },

// Read -----------------------------------------------------------------------------------

    /**
     * Get Projects
     *
     */
    getProjects (callback) {
        request.get('projects', function (err, res) {
            callback(res.body);
        });
    },

    /**
     * Get Sessions
     *
     */
    getSessions (projectId, callback) {
        request.get('projects/' + projectId + '/sessions', function (err, res) {
            callback(res.body);
        });
    },

    /**
     * Get Acquisitions
     *
     */
    getAcquisitions (sessionId, callback) {
        request.get('sessions/' + sessionId + '/acquisitions', function (err, res) {
            callback(res.body);
        });
    },

    getBIDSSubjects (projectId, callback) {
        this.getSessions(projectId, function (sessions) {
            let subjects = [];
            async.each(sessions, function (session, cb) {
                if (session.subject_code === 'subject') {
                    request.get('sessions/' + session._id, function (err, res) {
                        session.children = res.body.files;
                        session.name = session.label;
                        subjects.push(session);
                        cb();
                    })
                } else {
                    cb();
                }
            }, function () {
                callback(subjects);
            });
        });
    },

    getBIDSSessions (projectId, subjectId, callback) {
        this.getSessions(projectId, function (sciSessions) {
            let sessions = [];
            async.each(sciSessions, function (session, cb) {
                if (session.subject_code === subjectId) {
                    request.get('sessions/' + session._id, function (err, res) {
                        session.children = res.body.files;
                        session.name = session.label;
                        sessions.push(session);
                        cb();
                    })
                } else {
                    cb();
                }
            }, function () {
                callback(sessions);
            });
        });
    },

    getBIDSModalities (sessionId, callback) {
        request.get('sessions/' + sessionId + '/acquisitions', function (err, res) {
            callback(res.body);
        });
    },

    getBIDSDataset (projectId, callback) {
        let self = this;
        let dataset = {};
        request.get('projects/' + projectId, function (err, res) {
            if (res.status !== 200) {return callback(res);}
            for (let file of res.body.files) {file.name = file.filename;}
            dataset.name = res.body.name;
            dataset.type = 'folder';
            dataset.children = res.body.files;
            self.getBIDSSubjects(res.body._id, function (subjects) {
                dataset.children = dataset.children.concat(subjects);
                async.each(subjects, function (subject, cb) {
                    self.getBIDSSessions(projectId, subject._id, function (sessions) {
                        subject.children = subject.children.concat(sessions);
                        async.each(sessions, function (session, cb1) {
                            self.getBIDSModalities(session._id, function (modalities) {
                                session.children = session.children.concat(modalities);
                                async.each(modalities, function (modality, cb2) {
                                    request.get('acquisitions/' + modality._id, function (err, res) {
                                        for (let file of res.body.files) {file.name = file.filename;}
                                        modality.children = res.body.files;
                                        modality.name = modality.label;
                                        cb2();
                                    });
                                }, cb1);
                            });
                        }, cb);
                    });
                }, function () {callback([dataset])});
            });
        });
    },

// Delete ---------------------------------------------------------------------------------

    /**
     * Delete Container
     *
     */
    deleteContainer (type, id, callback) {
        request.del(type + '/' + id, function (err, res) {
            callback();
        });
    },

    deleteDataset (projectId, callback) {
        let self = this;
        this.getSessions(projectId, function (sessions) {
            async.each(sessions, function (session, cb) {
                self.getAcquisitions(session._id, function (acquisitions) {
                    async.each(acquisitions, function (acquisition, cb1) {
                        self.deleteContainer('acquisitions', acquisition._id, cb1);
                    }, function () {
                        self.deleteContainer('sessions', session._id, cb);
                    });
                });
            }, function () {
                self.deleteContainer('projects', projectId, callback);
            });
        });
    },

// Delete ---------------------------------------------------------------------------------

    updateProject (projectId, body, callback) {
        request.put('projects/' + projectId, body, function (err, res) {
            callback(err, res);
        });
    }

};<|endoftext|>


<commit_before>import { percentPovertyLevel,
    percentStateMedianIncome } from '../../../helpers/helperFunctions';

function getHousingEligibility(client) {
    let percentPov = parseInt(percentStateMedianIncome(parseInt(client.annualIncome), client.householdSize));
    if (client.annualIncome == 0 || percentPov < 70) {
        return {result: 'good', details: 'All good!', benefitValue: 800};
    } else if (percentPov > 70 && percentPov < 80) {
        return {result: 'information', details: `Your income puts you at ${percentPov.toFixed()}% of the federal poverty level, which is close to the 80% limit.`, benefitValue: 800};
    } else {
        return {result: 'warning', details: `Your income puts you at ${percentPov.toFixed()}% of the federal poverty level, which is above the 80% limit.`, benefitValue: 0};
    }
}

export {getHousingEligibility};<commit_msg>Change that was unintended to implement with the data was removed<commit_after>import { percentPovertyLevel,
    percentStateMedianIncome } from '../../../helpers/helperFunctions';

function getHousingEligibility(client) {
    let percentPov = parseInt(percentPovertyLevel(parseInt(client.annualIncome), client.householdSize));
    if (client.annualIncome == 0 || percentPov < 70) {
        return {result: 'good', details: 'All good!', benefitValue: 800};
    } else if (percentPov > 70 && percentPov < 80) {
        return {result: 'information', details: `Your income puts you at ${percentPov.toFixed()}% of the federal poverty level, which is close to the 80% limit.`, benefitValue: 800};
    } else {
        return {result: 'warning', details: `Your income puts you at ${percentPov.toFixed()}% of the federal poverty level, which is above the 80% limit.`, benefitValue: 0};
    }
}

export {getHousingEligibility};<|endoftext|>


<commit_before>
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Author: Bradley Kennedy (bk@co60.ca)
*/

/*
 * This is intended to be the location of the stored queries
 */

var StringManipulation = require('../StringManipulation');
var Client = require('../client/Client');
var ClientFilter = require('./ClientFilter');
var deepcopy = require("lodash.clonedeep");

/* Queries have the following objects:
 * name, which is the display string,
 *
 * obj which contains the query instructions
 *
 * within obj there is remote_request which is the query in JSON
 *
 * filter_revision is a boolean flag for if the query may be filtered
 * by build.revision12, if it is true we will try and find a where clause
 * in that mentions the aformentioned property, if filter_revision isn't set
 * or is false we will not remove the filter but instead not modify the query
 *
 * There is also three functions:
 * processPre(component, data) which allows you to mutate
 *   the state of the component on injestion of data, this may be left null
 *   but may be relatively useless without doing so
 * processHeaders(data) takes in a header array and returns a header array
 *   with modifications to the elements, may be null
 * processBody(data) takes in a array of arrays and returns an array of arrays,
 *   may be null.
 */

var directoryDrillDown = {
  name: 'Directory Drilldown Folders',
  obj:  {
    filter_revision: true,
    drills_down: true,
    drilldown_context: 'chrome://',
    format_headers: true,
    query_override: true,
    remote_request:{
      "from":"coverage-summary",
      "select":[
        {"aggregate":"count"},
        {"value":"source.file.total_uncovered","aggregate":"sum"},
        {"value":"source.file.total_covered","aggregate":"sum"}
      ],
      "where":{"and": [
        {"prefix":{"source.file.name":"chrome://mochikit/content/tests/SimpleTest/"}},
        {"eq":{"build.revision12":"d19d1d2136bb"}},
        {"missing":"test.url"}
      ]},
      "groupby":[{
      "name":"file",
      "value":{
        "left":[
          "source.file.name",
          {"add":[
            1,
            {
              "find":{"source.file.name":"/"},
              "start":43,
              "default":{"length":"source.file.name"}
            }
          ]}
        ]
        }
      }],
      "limit":1000
    },
    drillUp: function(drillDownContext) {
      if (!drillDownContext) {
        return this.drilldown_context;
      }
      return drillDownContext.substr(0, drillDownContext.substr(0,
            drillDownContext.length-1).lastIndexOf("/")+1);
    },
    drillDown: function(selectedRow, drillDownContext) {
      if (!drillDownContext) {
        drillDownContext = this.drilldown_context;
      }

      // This one is used if we want to remove the path
      drillDownContext += selectedRow[0].val;
      //drillDownContext = selectedRow[0].val;

      var remote_request_copy = JSON.parse(JSON.stringify(this.remote_request));
      // TODO(brad) this does NOT set the revision? DOES IT?

      ClientFilter.setProp(remote_request_copy, 'source.file.name',
          drillDownContext);
      return {
        context: drillDownContext, remote_request: remote_request_copy
      };
    },
    override: function(query, context) {
      context = context || "chrome://";

      ClientFilter.setProp(query, "start", context.length);
      ClientFilter.setProp(query, "source.file.name", context);
      return new Promise((res, rej) => {
        Client.makeRequest('activedata.allizom.org', query, (data) => {
          var colours = ["#74c274", "#f2b968", "#de6c69"];
          var levels = [0.9, 0.70, 0.0];
          var headers = [
            "Directory",
            {title: "Bar", type:"bar", colours: colours, levels: levels},
            {title: "Covered %", type:"bg", colours: colours, levels: levels},
            {title: "Covered Lines", type:"bg", colours: colours, levels: levels}
          ];

          var rows = data.data.map((row) => {
            var dir = row[0];
            dir = dir.substr(dir.substr(0, dir.length-1).lastIndexOf("/")+1);
            var cov = row[3];
            var ucov = row[2];
            var lines = cov + ucov;
            return [
              dir,
              cov/lines,
              {text: `${((cov/lines)*100).toPrecision(3)} %`, val: cov/lines},
              {text: `${cov}/${lines}`, val: cov/lines}
            ];
          });

          res({header: headers, data: rows});
        });
      });
    },
    processPre: function(comp, d) {
      comp.setState({
        data: {
          headers: d.header,
          rows: d.data
         }
      });
    },
    processHeaders: function(d) {
      return d.map(StringManipulation.header)
    },
    processBody: null,
  }
};

module.exports = {[directoryDrillDown]};
<commit_msg>Changed name of JS cov<commit_after>
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Author: Bradley Kennedy (bk@co60.ca)
*/

/*
 * This is intended to be the location of the stored queries
 */

var StringManipulation = require('../StringManipulation');
var Client = require('../client/Client');
var ClientFilter = require('./ClientFilter');
var deepcopy = require("lodash.clonedeep");

/* Queries have the following objects:
 * name, which is the display string,
 *
 * obj which contains the query instructions
 *
 * within obj there is remote_request which is the query in JSON
 *
 * filter_revision is a boolean flag for if the query may be filtered
 * by build.revision12, if it is true we will try and find a where clause
 * in that mentions the aformentioned property, if filter_revision isn't set
 * or is false we will not remove the filter but instead not modify the query
 *
 * There is also three functions:
 * processPre(component, data) which allows you to mutate
 *   the state of the component on injestion of data, this may be left null
 *   but may be relatively useless without doing so
 * processHeaders(data) takes in a header array and returns a header array
 *   with modifications to the elements, may be null
 * processBody(data) takes in a array of arrays and returns an array of arrays,
 *   may be null.
 */

var directoryDrillDown = {
  name: 'JavaScript Coverage by Folder',
  obj:  {
    filter_revision: true,
    drills_down: true,
    drilldown_context: 'chrome://',
    format_headers: true,
    query_override: true,
    remote_request:{
      "from":"coverage-summary",
      "select":[
        {"aggregate":"count"},
        {"value":"source.file.total_uncovered","aggregate":"sum"},
        {"value":"source.file.total_covered","aggregate":"sum"}
      ],
      "where":{"and": [
        {"prefix":{"source.file.name":"chrome://mochikit/content/tests/SimpleTest/"}},
        {"eq":{"build.revision12":"d19d1d2136bb"}},
        {"missing":"test.url"}
      ]},
      "groupby":[{
      "name":"file",
      "value":{
        "left":[
          "source.file.name",
          {"add":[
            1,
            {
              "find":{"source.file.name":"/"},
              "start":43,
              "default":{"length":"source.file.name"}
            }
          ]}
        ]
        }
      }],
      "limit":1000
    },
    drillUp: function(drillDownContext) {
      if (!drillDownContext) {
        return this.drilldown_context;
      }
      return drillDownContext.substr(0, drillDownContext.substr(0,
            drillDownContext.length-1).lastIndexOf("/")+1);
    },
    drillDown: function(selectedRow, drillDownContext) {
      if (!drillDownContext) {
        drillDownContext = this.drilldown_context;
      }

      // This one is used if we want to remove the path
      drillDownContext += selectedRow[0].val;
      //drillDownContext = selectedRow[0].val;

      var remote_request_copy = JSON.parse(JSON.stringify(this.remote_request));
      // TODO(brad) this does NOT set the revision? DOES IT?

      ClientFilter.setProp(remote_request_copy, 'source.file.name',
          drillDownContext);
      return {
        context: drillDownContext, remote_request: remote_request_copy
      };
    },
    override: function(query, context) {
      context = context || "chrome://";

      ClientFilter.setProp(query, "start", context.length);
      ClientFilter.setProp(query, "source.file.name", context);
      return new Promise((res, rej) => {
        Client.makeRequest('activedata.allizom.org', query, (data) => {
          var colours = ["#74c274", "#f2b968", "#de6c69"];
          var levels = [0.9, 0.70, 0.0];
          var headers = [
            "Directory",
            {title: "Bar", type:"bar", colours: colours, levels: levels},
            {title: "Covered %", type:"bg", colours: colours, levels: levels},
            {title: "Covered Lines", type:"bg", colours: colours, levels: levels}
          ];

          var rows = data.data.map((row) => {
            var dir = row[0];
            dir = dir.substr(dir.substr(0, dir.length-1).lastIndexOf("/")+1);
            var cov = row[3];
            var ucov = row[2];
            var lines = cov + ucov;
            return [
              dir,
              cov/lines,
              {text: `${((cov/lines)*100).toPrecision(3)} %`, val: cov/lines},
              {text: `${cov}/${lines}`, val: cov/lines}
            ];
          });

          res({header: headers, data: rows});
        });
      });
    },
    processPre: function(comp, d) {
      comp.setState({
        data: {
          headers: d.header,
          rows: d.data
         }
      });
    },
    processHeaders: function(d) {
      return d.map(StringManipulation.header)
    },
    processBody: null,
  }
};

module.exports = {[directoryDrillDown]};
<|endoftext|>