<commit_before>/** @babel */

import path from 'path'
import fs from 'fs-plus'
import FileList from '../lib/file-list'
import HunkLine from '../lib/hunk-line'
import GitService from '../lib/git-service'
import {waitsForPromise} from './async-spec-helpers'
import {copyRepository} from './helpers'

describe('HunkLine', function () {
  let fileList = null
  let repoPath = null

  const fileName = 'README.md'
  let filePath = null

  beforeEach(() => {
    repoPath = copyRepository()

    filePath = path.join(repoPath, fileName)
    fs.writeFileSync(filePath, "i'm new here\n")

    // TODO: This makes me feel gross inside.
    GitService.instance().repoPath = repoPath

    fileList = new FileList()
    waitsForPromise(() => fileList.loadFromGitUtils())
  })

  it('roundtrips toString and HunkLine.fromString', function () {
    let line = '  89 --- - # default, the type it should be, etc. A simple example:'
    let hunkLine = HunkLine.fromString(line)
    expect(hunkLine.toString()).toEqual(line)

    line = '  435 432         scopeDescriptor = options.scope'
    hunkLine = HunkLine.fromString(line)
    expect(hunkLine.toString()).toEqual(line)

    line = '  --- 434 +     # Some new linesssss'
    hunkLine = HunkLine.fromString(line)
    expect(hunkLine.toString()).toEqual(line)

    line = '✓ --- 434 +     # Some new linesssss'
    hunkLine = HunkLine.fromString(line)
    expect(hunkLine.toString()).toEqual(line)

    line = '  85 85   #'
    hunkLine = HunkLine.fromString(line)
    expect(hunkLine.toString()).toEqual(line)
  })

  it('emits and event when HunkLine::fromString() is called', function () {
    let changeHandler = jasmine.createSpy()
    let line = '  89 --- - # default, the type it should be, etc. A simple example:'
    let hunkLine = new HunkLine()

    hunkLine.onDidChange(changeHandler)
    hunkLine.fromString(line)
    expect(changeHandler).toHaveBeenCalled()
    expect(hunkLine.toString()).toEqual(line)
  })

  it('can be staged and unstaged with ::stage() and ::unstage()', function () {
    const diff = fileList.getFileFromPathName(fileName)
    expect(diff).not.toBeUndefined()

    const hunks = diff.getHunks()
    expect(hunks.length).toEqual(1)

    const hunk = hunks[0]
    const lines = hunk.getLines()
    expect(lines.length).toEqual(21)

    const line = lines[0]
    expect(line.isStaged()).toEqual(false)

    line.stage()
    expect(line.isStaged()).toEqual(true)

    line.unstage()
    expect(line.isStaged()).toEqual(false)
  })
})
<commit_msg>Make the tests test something<commit_after>/** @babel */

import path from 'path'
import fs from 'fs-plus'
import FileList from '../lib/file-list'
import HunkLine from '../lib/hunk-line'
import GitService from '../lib/git-service'
import {waitsForPromise, it} from './async-spec-helpers'
import {copyRepository} from './helpers'

describe('HunkLine', () => {
  let fileList = null
  let repoPath = null

  const fileName = 'README.md'
  let filePath = null

  beforeEach(() => {
    repoPath = copyRepository()

    filePath = path.join(repoPath, fileName)
    fs.writeFileSync(filePath, "i'm new here\n")

    // TODO: This makes me feel gross inside.
    GitService.instance().repoPath = repoPath

    fileList = new FileList([], {stageOnChange: true})
    waitsForPromise(() => fileList.loadFromGitUtils())
  })

  it('roundtrips toString and HunkLine.fromString', () => {
    let line = '  89 --- - # default, the type it should be, etc. A simple example:'
    let hunkLine = HunkLine.fromString(line)
    expect(hunkLine.toString()).toEqual(line)

    line = '  435 432         scopeDescriptor = options.scope'
    hunkLine = HunkLine.fromString(line)
    expect(hunkLine.toString()).toEqual(line)

    line = '  --- 434 +     # Some new linesssss'
    hunkLine = HunkLine.fromString(line)
    expect(hunkLine.toString()).toEqual(line)

    line = '✓ --- 434 +     # Some new linesssss'
    hunkLine = HunkLine.fromString(line)
    expect(hunkLine.toString()).toEqual(line)

    line = '  85 85   #'
    hunkLine = HunkLine.fromString(line)
    expect(hunkLine.toString()).toEqual(line)
  })

  it('emits and event when HunkLine::fromString() is called', () => {
    let changeHandler = jasmine.createSpy()
    let line = '  89 --- - # default, the type it should be, etc. A simple example:'
    let hunkLine = new HunkLine()

    hunkLine.onDidChange(changeHandler)
    hunkLine.fromString(line)
    expect(changeHandler).toHaveBeenCalled()
    expect(hunkLine.toString()).toEqual(line)
  })

  fdescribe('staging', () => {
    let getFirstLine
    let changeStagedness

    beforeEach(() => {
      getFirstLine = () => {
        const diff = fileList.getFileFromPathName(fileName)
        expect(diff).not.toBeUndefined()

        const hunks = diff.getHunks()
        const hunk = hunks[0]
        const lines = hunk.getLines()
        return lines[0]
      }

      changeStagedness = (stage) => {
        const line = getFirstLine()
        expect(line.isStaged()).toEqual(!stage)

        const changeHandler = jasmine.createSpy()
        fileList.onDidUserChange(changeHandler)

        if (stage) {
          line.stage()
        } else {
          line.unstage()
        }

        waitsFor(() => changeHandler.callCount === 1)
      }
    })

    describe('.stage()', () => {
      it('stages', () => {
        changeStagedness(true)
        runs(() => {
          fileList = new FileList([])
          waitsForPromise(() => fileList.loadFromGitUtils())
          runs(() => {
            const line = getFirstLine()
            expect(line.isStaged()).toEqual(true)
          })
        })
      })
    })

    describe('.unstage()', () => {
      it('unstages', () => {
        changeStagedness(true)
        runs(() => {
          fileList = new FileList([], {stageOnChange: true})
          waitsForPromise(() => fileList.loadFromGitUtils())
          runs(() => {
            changeStagedness(false)
            runs(() => {
              fileList = new FileList([])
              waitsForPromise(() => fileList.loadFromGitUtils())
              runs(() => {
                const line = getFirstLine()
                expect(line.isStaged()).toEqual(false)
              })
            })
          })
        })
      })
    })
  })
})
<|endoftext|>


<commit_before><commit_msg>@ben @ricardo running all tests now<commit_after><|endoftext|>


<commit_before>import React, {PropTypes} from 'react'
import {withRouter} from 'react-router'

import AutoRefreshDropdown from 'shared/components/AutoRefreshDropdown'
import TimeRangeDropdown from '../../shared/components/TimeRangeDropdown'
import SourceIndicator from '../../shared/components/SourceIndicator'
import GraphTips from '../../shared/components/GraphTips'

const {
  func,
  number,
  shape,
  string,
} = PropTypes

const Header = React.createClass({
  propTypes: {
    autoRefresh: number.isRequired,
    timeRange: shape({
      upper: string,
      lower: string,
    }).isRequired,
    actions: shape({
      handleChooseAutoRefresh: func.isRequired,
      setTimeRange: func.isRequired,
    }),
  },

  contextTypes: {
    source: shape({
      name: string,
    }),
  },

  handleChooseTimeRange(bounds) {
    this.props.actions.setTimeRange(bounds)
  },

  render() {
    const {autoRefresh, actions: {handleChooseAutoRefresh}, timeRange} = this.props

    return (

Explorer

            <GraphTips />
            <SourceIndicator sourceName={this.context.source.name} />
            <AutoRefreshDropdown onChoose={handleChooseAutoRefresh} selected={autoRefresh} iconName="refresh" />
            <TimeRangeDropdown onChooseTimeRange={this.handleChooseTimeRange} selected={timeRange} />

    )
  },
})

export default withRouter(Header)
<commit_msg>Change DE page title to match corresponding navbar label<commit_after>import React, {PropTypes} from 'react'
import {withRouter} from 'react-router'

import AutoRefreshDropdown from 'shared/components/AutoRefreshDropdown'
import TimeRangeDropdown from '../../shared/components/TimeRangeDropdown'
import SourceIndicator from '../../shared/components/SourceIndicator'
import GraphTips from '../../shared/components/GraphTips'

const {
  func,
  number,
  shape,
  string,
} = PropTypes

const Header = React.createClass({
  propTypes: {
    autoRefresh: number.isRequired,
    timeRange: shape({
      upper: string,
      lower: string,
    }).isRequired,
    actions: shape({
      handleChooseAutoRefresh: func.isRequired,
      setTimeRange: func.isRequired,
    }),
  },

  contextTypes: {
    source: shape({
      name: string,
    }),
  },

  handleChooseTimeRange(bounds) {
    this.props.actions.setTimeRange(bounds)
  },

  render() {
    const {autoRefresh, actions: {handleChooseAutoRefresh}, timeRange} = this.props

    return (

Data Explorer

            <GraphTips />
            <SourceIndicator sourceName={this.context.source.name} />
            <AutoRefreshDropdown onChoose={handleChooseAutoRefresh} selected={autoRefresh} iconName="refresh" />
            <TimeRangeDropdown onChooseTimeRange={this.handleChooseTimeRange} selected={timeRange} />

    )
  },
})

export default withRouter(Header)
<|endoftext|>


<commit_before>describe('Javascript: ', function() {

	describe('Data types:', function() {

		it('should have 5 primitive types: undefined, null, boolean, number, string; and a complex type, object: ', function() {
			var isUndefined;
			var bool = true;
			var str = 'hello world';
			var num = 5;
			var obj = {};

			expect(typeof isUndefined).toBe('undefined');
			expect(typeof bool).toBe('boolean');
			expect(typeof str).toBe('string');
			expect(typeof num).toBe('number');
			expect(typeof obj).toBe('object');

		});

		describe('Undefined: ', function() {
			it('should have typeof null return object because null is an empty object reference', function() {
				var somethingNull = null;
				expect(typeof obj).not.toBe(undefined);
				expect(typeof somethingNull).toBe('object');
			});

			it('should have undefined type for variables that are declared but not initialized', function() {
				var foo; // foo is declared without initializing it
				expect(foo).toBe(undefined);

				// var bar is declared, and initialized to be undefined.  this is unnecessary, because uninitialized
				// variables get the value of undefined automaticlaly
				var bar = undefined;
				expect(bar).toBe(undefined);
			});

			it("should have variables containing the value undefined to be different from variables that haven't been declared", function() {

				var foo; // var foo is declared, but has value of undefined
				// var bar; // COMMENT OUT THIS LINE to make sure that this variable isn't declared

				expect(foo).toBe(undefined); // foo will have value of undeclared, whereas
				expect(function(){bar}).toThrow(new ReferenceError("bar is not defined")); //bar will throw an error
			});

			it("however, typeof should return undefined on both unintialized variables and also undeclared variables", function() {
				var foo; // var foo is decalred but has value of undefined

				// var bar; // var foo is not declared;

				expect(typeof foo).toBe('undefined');
				expect(typeof bar).toBe('undefined');
			});

		});

		describe("Null: ", function() {

			it("should return object when typeof is used on it because the null value is an empty object pointer", function() {
				var foo = null;
				expect(typeof foo).not.toBe("null");
				expect(typeof foo).toBe("object");
			});

			it("is superficially equal to undefined, because undefined is a derivative of null", function() {
				expect(null == undefined).toBeTruthy();
			});
		});

		describe("Boolean: ", function() {
			describe("can convert other data types to a boolean value with the Boolean() casting function: ", function() {

				it("Non-empty strings are true, empty strings are false", function() {
					var str = "foo";
					var emptyStr = "";
					expect(Boolean(str)).toBe(true);
					expect(Boolean(emptyStr)).toBe(false);
				});

				it("Non-zero numbers are true, 0 and NaN are false", function() {
					var positiveNum = 1;
					var negativeNum = -1;
					var zero = 0;
					var notANumber = NaN;

					expect(Boolean(positiveNum)).toBe(true);
					expect(Boolean(negativeNum)).toBe(true);
					expect(Boolean(zero)).toBe(false);
					expect(Boolean(notANumber)).toBe(false);
				});

				it("objects are true, null is false", function() {
					var obj = {};
					var nullObj = null;

					expect(Boolean(obj)).toBe(true);
					expect(Boolean(nullObj)).toBe(false);
				});

				it("undefined cannot be true, it is always converted to false", function() {
					var foo = undefined;
					expect(Boolean(foo)).toBe(false);
				});
			});

		});

	});
});<commit_msg>Number type. mostly NaN, parseInt is ToDo<commit_after>describe('Javascript: ', function() {

	describe('Data types:', function() {

		it('should have 5 primitive types: undefined, null, boolean, number, string; and a complex type, object: ', function() {
			var isUndefined;
			var bool = true;
			var str = 'hello world';
			var num = 5;
			var obj = {};

			expect(typeof isUndefined).toBe('undefined');
			expect(typeof bool).toBe('boolean');
			expect(typeof str).toBe('string');
			expect(typeof num).toBe('number');
			expect(typeof obj).toBe('object');

		});

		describe('Undefined: ', function() {
			it('should have typeof null return object because null is an empty object reference', function() {
				var somethingNull = null;
				expect(typeof obj).not.toBe(undefined);
				expect(typeof somethingNull).toBe('object');
			});

			it('should have undefined type for variables that are declared but not initialized', function() {
				var foo; // foo is declared without initializing it
				expect(foo).toBe(undefined);

				// var bar is declared, and initialized to be undefined.  this is unnecessary, because uninitialized
				// variables get the value of undefined automaticlaly
				var bar = undefined;
				expect(bar).toBe(undefined);
			});

			it("should have variables containing the value undefined to be different from variables that haven't been declared", function() {

				var foo; // var foo is declared, but has value of undefined
				// var bar; // COMMENT OUT THIS LINE to make sure that this variable isn't declared

				expect(foo).toBe(undefined); // foo will have value of undeclared, whereas
				expect(function(){bar}).toThrow(new ReferenceError("bar is not defined")); //bar will throw an error
			});

			it("however, typeof should return undefined on both unintialized variables and also undeclared variables", function() {
				var foo; // var foo is decalred but has value of undefined

				// var bar; // var foo is not declared;

				expect(typeof foo).toBe('undefined');
				expect(typeof bar).toBe('undefined');
			});

		});

		describe("Null: ", function() {

			it("should return object when typeof is used on it because the null value is an empty object pointer", function() {
				var foo = null;
				expect(typeof foo).not.toBe("null");
				expect(typeof foo).toBe("object");
			});

			it("is superficially equal to undefined, because undefined is a derivative of null", function() {
				expect(null == undefined).toBeTruthy();
			});
		});

		describe("Boolean: ", function() {
			describe("can convert other data types to a boolean value with the Boolean() casting function: ", function() {

				it("Non-empty strings are true, empty strings are false", function() {
					var str = "foo";
					var emptyStr = "";
					expect(Boolean(str)).toBe(true);
					expect(Boolean(emptyStr)).toBe(false);
				});

				it("Non-zero numbers are true, 0 and NaN are false", function() {
					var positiveNum = 1;
					var negativeNum = -1;
					var zero = 0;
					var notANumber = NaN;

					expect(Boolean(positiveNum)).toBe(true);
					expect(Boolean(negativeNum)).toBe(true);
					expect(Boolean(zero)).toBe(false);
					expect(Boolean(notANumber)).toBe(false);
				});

				it("objects are true, null is false", function() {
					var obj = {};
					var nullObj = null;

					expect(Boolean(obj)).toBe(true);
					expect(Boolean(nullObj)).toBe(false);
				});

				it("undefined cannot be true, it is always converted to false", function() {
					var foo = undefined;
					expect(Boolean(foo)).toBe(false);
				});
			});

			describe("Number: ", function() {

	// TODO
	// describe("parseInt", function() {

	// });

				describe("NaN (Not a Number): ", function() {
					it(" will return NaN in any operation involving NaN", function() {
						expect(NaN / 10).toEqual(NaN);
					});

					it(" is not equal to any value, including NaN", function() {
						expect(NaN == NaN).toEqual(false);
					});

					it(" has a isNaN() function that accepts a single argument of any data type to determine if value is NaN", function() {
						// isNaN will first attempt to convert any value into a number
						expect(isNaN(NaN)).toBe(true); // NaN is not a number
						expect(isNaN(1)).toBe(false); // number 1
						expect(isNaN("1")).toBe(false); // string "1" is converted
						expect(isNaN("foo")).toBe(true); // can't convert "foo" to a number
						expect(isNaN(true)).toBe(false); // true can convert to 1
					});

				});

			});

		});

	});
});<|endoftext|>


<commit_before>module.exports = (function(){
    'use strict';

    var mongoose = require('mongoose'),
        q = require('q'),
        error = require('../../utils/error'),
        async = require('async'),
        crud = require('./mixins/crud'),
        _ = require('underscore'),
        collectionName = 'users',
        filterFactory = require('./search/filterFactory'),
        schema = require('./schemas/user');

    function handleUser(err, doc, deferred){
        if(err) {
            deferred.reject(error(err));
        }
        else if (doc !== null) {
            deferred.resolve(doc);
        }
        else {
            deferred.reject(error(404));
        }
    }

    var user = Object.create(crud, {
        model: {value: mongoose.model(collectionName, schema)},
        privateFields: {value: ['salt', 'pass_hash','identities.basic.pass_hash']}
    });

    user.getByEmail = function(email) {
        var deferred = q.defer();

        this.model.findOne({email: email}, this.buildIncludes()).lean().exec(function(err, doc){
            handleUser(err, doc, deferred);
        });

        return deferred.promise;
    };

    user.basicAuthentication = function(login, password){
        var deferred = q.defer();

        this.model.findOne({'identities.basic.login': login}, function(err, doc){
            var valid = (doc !== null) ? doc.authenticate(password) : false;

            if(!valid){
                handleUser(null, null, deferred);
            }
            else {
                handleUser(err, doc, deferred);
            }
        });

        return deferred.promise;
    };

    user.savePermissions = function(userId, nodeid, role){
        var deferred = q.defer();

        this.model.findOne({_id: userId}, function(err, doc){
            if(err){
                deferred.reject(error(err));
            }
            else {
                var permissions = (!doc.permissions) ? [] : _.filter(doc.permissions, function(permission) {
                    return permission.nodeid.toString() != nodeid;
                });

                permissions[permissions.length] = {nodeid: nodeid, role: role};

                doc.permissions = permissions;
                doc.save(function(err){
                    if(err){
                        deferred.reject(error(err));
                    } else {
                        deferred.resolve('Success');
                    }
                });
            }
        });

        return deferred.promise;
    };

    user.deletePermission = function(userId, nodeId){
        var deferred = q.defer();

        this.model.findOne({_id: userId}, function(err, doc){
            if(err){
                deferred.reject(error(err));
            }
            else {
                doc.permissions = (!doc.permissions) ? [] : _.filter(doc.permissions, function(permission) {
                    return permission.nodeid.toString() != nodeId;
                });

                doc.save(function(err){
                    if(err){
                        deferred.reject(error(err));
                    } else {
                        deferred.resolve('Success');
                    }
                });
            }
        });

        return deferred.promise;
    };

    user.query = function(filters, options){
        var qry = {},
            deferred = q.defer(),
            self = this;

        filterFactory.createQuery(filters, qry);

        async.parallel(
            [
                function(cb){
                    self.model.find(qry, self.buildIncludes(options)).lean().exec(function(err, data){
                        if(err){
                            cb(err);
                        } else {
                            cb(null, data);
                        }
                    });
                },
                function(cb){
                    self.model.count(qry).lean().exec(function (err, data) {
                        if (err) {
                            cb(err);
                        }
                        else {
                            cb(null, data);
                        }
                    });
                }
            ],function(err, results){
                var result;

                if(err){
                    deferred.reject(err);
                }
                else {

                    result = {
                        total: _.isUndefined(results[1]) ? 0 : results[1],
                        limit: options.limit,
                        skip: options.skip,
                        results: results[0]
                    };

                    deferred.resolve(result);
                }
            }
        );

        return deferred.promise;
    };

    return user;
})();<commit_msg>Renamed authentication method to "basicAuthentication" and added new fields to ignore list for security.<commit_after>module.exports = (function(){
    'use strict';

    var mongoose = require('mongoose'),
        q = require('q'),
        error = require('../../utils/error'),
        async = require('async'),
        crud = require('./mixins/crud'),
        _ = require('underscore'),
        collectionName = 'users',
        filterFactory = require('./search/filterFactory'),
        schema = require('./schemas/user');

    function handleUser(err, doc, deferred){
        if(err) {
            deferred.reject(error(err));
        }
        else if (doc !== null) {
            deferred.resolve(doc);
        }
        else {
            deferred.reject(error(404));
        }
    }

    var user = Object.create(crud, {
        model: {value: mongoose.model(collectionName, schema)},
        privateFields: {value: ['salt', 'pass_hash','identities.basic.hash','identities.basic.salt']}
    });

    user.getByEmail = function(email) {
        var deferred = q.defer();

        this.model.findOne({email: email}, this.buildIncludes()).lean().exec(function(err, doc){
            handleUser(err, doc, deferred);
        });

        return deferred.promise;
    };

    user.basicAuthentication = function(login, password){
        var deferred = q.defer();

        this.model.findOne({'identities.basic.login': login}, function(err, doc){
            var valid = (doc !== null) ? doc.basicAuthentication(password) : false;

            if(!valid){
                handleUser(null, null, deferred);
            }
            else {
                handleUser(err, doc, deferred);
            }
        });

        return deferred.promise;
    };

    user.savePermissions = function(userId, nodeid, role){
        var deferred = q.defer();

        this.model.findOne({_id: userId}, function(err, doc){
            if(err){
                deferred.reject(error(err));
            }
            else {
                var permissions = (!doc.permissions) ? [] : _.filter(doc.permissions, function(permission) {
                    return permission.nodeid.toString() != nodeid;
                });

                permissions[permissions.length] = {nodeid: nodeid, role: role};

                doc.permissions = permissions;
                doc.save(function(err){
                    if(err){
                        deferred.reject(error(err));
                    } else {
                        deferred.resolve('Success');
                    }
                });
            }
        });

        return deferred.promise;
    };

    user.deletePermission = function(userId, nodeId){
        var deferred = q.defer();

        this.model.findOne({_id: userId}, function(err, doc){
            if(err){
                deferred.reject(error(err));
            }
            else {
                doc.permissions = (!doc.permissions) ? [] : _.filter(doc.permissions, function(permission) {
                    return permission.nodeid.toString() != nodeId;
                });

                doc.save(function(err){
                    if(err){
                        deferred.reject(error(err));
                    } else {
                        deferred.resolve('Success');
                    }
                });
            }
        });

        return deferred.promise;
    };

    user.query = function(filters, options){
        var qry = {},
            deferred = q.defer(),
            self = this;

        filterFactory.createQuery(filters, qry);

        async.parallel(
            [
                function(cb){
                    self.model.find(qry, self.buildIncludes(options)).lean().exec(function(err, data){
                        if(err){
                            cb(err);
                        } else {
                            cb(null, data);
                        }
                    });
                },
                function(cb){
                    self.model.count(qry).lean().exec(function (err, data) {
                        if (err) {
                            cb(err);
                        }
                        else {
                            cb(null, data);
                        }
                    });
                }
            ],function(err, results){
                var result;

                if(err){
                    deferred.reject(err);
                }
                else {

                    result = {
                        total: _.isUndefined(results[1]) ? 0 : results[1],
                        limit: options.limit,
                        skip: options.skip,
                        results: results[0]
                    };

                    deferred.resolve(result);
                }
            }
        );

        return deferred.promise;
    };

    return user;
})();<|endoftext|>


<commit_before>// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Swift mode created by Michael Kaminsky https://github.com/mkaminsky11

(function(mod) {
  if (typeof exports == "object" && typeof module == "object")
    mod(require("../../lib/codemirror"))
  else if (typeof define == "function" && define.amd)
    define(["../../lib/codemirror"], mod)
  else
    mod(CodeMirror)
})(function(CodeMirror) {
  "use strict"

  function trim(str) { return /^\s*(.*?)\s*$/.exec(str)[1] }

  var separators = [" ","\\\+","\\\-","\\\(","\\\)","\\\*","/",":","\\\?","\\\<","\\\>"," ","\\\."]
  var tokens = new RegExp(separators.join("|"),"g")

  function getWord(string, pos) {
    var index = -1, count = 1
    var words = string.split(tokens)
    for (var i = 0; i < words.length; i++) {
      for(var j = 1; j <= words[i].length; j++) {
        if (count==pos) index = i
        count++
      }
      count++
    }
    var ret = ["", ""]
    if (pos == 0) {
      ret[1] = words[0]
      ret[0] = null
    } else {
      ret[1] = words[index]
      ret[0] = words[index-1]
    }
    return ret
  }

  CodeMirror.defineMode("swift", function() {
    var keywords=["var","let","class","deinit","enum","extension","func","import","init","let","protocol","static","struct","subscript","typealias","var","as","dynamicType","is","new","super","self","Self","Type","__COLUMN__","__FILE__","__FUNCTION__","__LINE__","break","case","continue","default","do","else","fallthrough","if","in","for","return","switch","where","while","associativity","didSet","get","infix","inout","left","mutating","none","nonmutating","operator","override","postfix","precedence","prefix","right","set","unowned","unowned(safe)","unowned(unsafe)","weak","willSet"]
    var commonConstants=["Infinity","NaN","undefined","null","true","false","on","off","yes","no","nil","null","this","super"]
    var types=["String","bool","int","string","double","Double","Int","Float","float","public","private","extension"]
    var numbers=["0","1","2","3","4","5","6","7","8","9"]
    var operators=["+","-","/","*","%","=","|","&","<",">"]
    var punc=[";",",",".","(",")","{","}","[","]"]
    var delimiters=/^(?:[()\[\]{},:`=;]|\.\.?\.?)/
    var identifiers=/^[_A-Za-z$][_A-Za-z$0-9]*/
    var properties=/^(@|this\.)[_A-Za-z$][_A-Za-z$0-9]*/
    var regexPrefixes=/^(\/{3}|\/)/

    return {
      startState: function() {
        return {
          prev: false,
          string: false,
          escape: false,
          inner: false,
          comment: false,
          num_left: 0,
          num_right: 0,
          doubleString: false,
          singleString: false
        }
      },
      token: function(stream, state) {
        if (stream.eatSpace()) return null

        var ch = stream.next()
        if (state.string) {
          if (state.escape) {
            state.escape = false
            return "string"
          } else {
            if ((ch == "\"" && (state.doubleString && !state.singleString) ||
                 (ch == "'" && (!state.doubleString && state.singleString))) &&
                !state.escape) {
              state.string = false
              state.doubleString = false
              state.singleString = false
              return "string"
            } else if (ch == "\\" && stream.peek() == "(") {
              state.inner = true
              state.string = false
              return "keyword"
            } else if (ch == "\\" && stream.peek() != "(") {
              state.escape = true
              state.string = true
              return "string"
            } else {
              return "string"
            }
          }
        } else if (state.comment) {
          if (ch == "*" && stream.peek() == "/") {
            state.prev = "*"
            return "comment"
          } else if (ch == "/" && state.prev == "*") {
            state.prev = false
            state.comment = false
            return "comment"
          }
          return "comment"
        } else {
          if (ch == "/") {
            if (stream.peek() == "/") {
              stream.skipToEnd()
              return "comment"
            }
            if (stream.peek() == "*") {
              state.comment = true
              return "comment"
            }
          }
          if (ch == "(" && state.inner) {
            state.num_left++
            return null
          }
          if (ch == ")" && state.inner) {
            state.num_right++
            if (state.num_left == state.num_right) {
              state.inner=false
              state.string=true
            }
            return null
          }

          var ret = getWord(stream.string, stream.pos)
          var the_word = ret[1]
          var prev_word = ret[0]

          if (operators.indexOf(ch + "") > -1) return "operator"
          if (punc.indexOf(ch) > -1) return "punctuation"

          if (typeof the_word != "undefined") {
            the_word = trim(the_word)
            if (typeof prev_word != "undefined") prev_word = trim(prev_word)
            if (the_word.charAt(0) == "#") return null

            if (types.indexOf(the_word) > -1) return "def"
            if (commonConstants.indexOf(the_word) > -1) return "atom"
            if (numbers.indexOf(the_word) > -1) return "number"

            if ((numbers.indexOf(the_word.charAt(0) + "") > -1 ||
                 operators.indexOf(the_word.charAt(0) + "") > -1) &&
                numbers.indexOf(ch) > -1) {
              return "number"
            }

            if (keywords.indexOf(the_word) > -1 ||
                keywords.indexOf(the_word.split(tokens)[0]) > -1)
              return "keyword"
            if (keywords.indexOf(prev_word) > -1) return "def"
          }
          if (ch == '"' && !state.doubleString) {
            state.string = true
            state.doubleString = true
            return "string"
          }
          if (ch == "'" && !state.singleString) {
            state.string = true
            state.singleString = true
            return "string"
          }
          if (ch == "(" && state.inner)
            state.num_left++
          if (ch == ")" && state.inner) {
            state.num_right++
            if (state.num_left == state.num_right) {
              state.inner = false
              state.string = true
            }
            return null
          }
          if (stream.match(/^-?[0-9\.]/, false)) {
            if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i) ||
                stream.match(/^-?\d+\.\d*/) ||
                stream.match(/^-?\.\d+/)) {
              if (stream.peek() == ".") stream.backUp(1)
              return "number"
            }
            if (stream.match(/^-?0x[0-9a-f]+/i) ||
                stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/) ||
                stream.match(/^-?0(?![\dx])/i))
              return "number"
          }
          if (stream.match(regexPrefixes)) {
            if (stream.current()!="/" || stream.match(/^.*\//,false)) return "string"
            else stream.backUp(1)
          }
          if (stream.match(delimiters)) return "punctuation"
          if (stream.match(identifiers)) return "variable"
          if (stream.match(properties)) return "property"
          return "variable"
        }
      }
    }
  })

  CodeMirror.defineMIME("text/x-swift","swift")
})
<commit_msg>fixed path for swift.js in mode<commit_after>// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Swift mode created by Michael Kaminsky https://github.com/mkaminsky11

(function(mod) {
  if (typeof exports == "object" && typeof module == "object")
    mod(require("../../lib/codemirror"))
  else if (typeof define == "function" && define.amd)
    define(["codemirror-lib"], mod)
  else
    mod(CodeMirror)
})(function(CodeMirror) {
  "use strict"

  function trim(str) { return /^\s*(.*?)\s*$/.exec(str)[1] }

  var separators = [" ","\\\+","\\\-","\\\(","\\\)","\\\*","/",":","\\\?","\\\<","\\\>"," ","\\\."]
  var tokens = new RegExp(separators.join("|"),"g")

  function getWord(string, pos) {
    var index = -1, count = 1
    var words = string.split(tokens)
    for (var i = 0; i < words.length; i++) {
      for(var j = 1; j <= words[i].length; j++) {
        if (count==pos) index = i
        count++
      }
      count++
    }
    var ret = ["", ""]
    if (pos == 0) {
      ret[1] = words[0]
      ret[0] = null
    } else {
      ret[1] = words[index]
      ret[0] = words[index-1]
    }
    return ret
  }

  CodeMirror.defineMode("swift", function() {
    var keywords=["var","let","class","deinit","enum","extension","func","import","init","let","protocol","static","struct","subscript","typealias","var","as","dynamicType","is","new","super","self","Self","Type","__COLUMN__","__FILE__","__FUNCTION__","__LINE__","break","case","continue","default","do","else","fallthrough","if","in","for","return","switch","where","while","associativity","didSet","get","infix","inout","left","mutating","none","nonmutating","operator","override","postfix","precedence","prefix","right","set","unowned","unowned(safe)","unowned(unsafe)","weak","willSet"]
    var commonConstants=["Infinity","NaN","undefined","null","true","false","on","off","yes","no","nil","null","this","super"]
    var types=["String","bool","int","string","double","Double","Int","Float","float","public","private","extension"]
    var numbers=["0","1","2","3","4","5","6","7","8","9"]
    var operators=["+","-","/","*","%","=","|","&","<",">"]
    var punc=[";",",",".","(",")","{","}","[","]"]
    var delimiters=/^(?:[()\[\]{},:`=;]|\.\.?\.?)/
    var identifiers=/^[_A-Za-z$][_A-Za-z$0-9]*/
    var properties=/^(@|this\.)[_A-Za-z$][_A-Za-z$0-9]*/
    var regexPrefixes=/^(\/{3}|\/)/

    return {
      startState: function() {
        return {
          prev: false,
          string: false,
          escape: false,
          inner: false,
          comment: false,
          num_left: 0,
          num_right: 0,
          doubleString: false,
          singleString: false
        }
      },
      token: function(stream, state) {
        if (stream.eatSpace()) return null

        var ch = stream.next()
        if (state.string) {
          if (state.escape) {
            state.escape = false
            return "string"
          } else {
            if ((ch == "\"" && (state.doubleString && !state.singleString) ||
                 (ch == "'" && (!state.doubleString && state.singleString))) &&
                !state.escape) {
              state.string = false
              state.doubleString = false
              state.singleString = false
              return "string"
            } else if (ch == "\\" && stream.peek() == "(") {
              state.inner = true
              state.string = false
              return "keyword"
            } else if (ch == "\\" && stream.peek() != "(") {
              state.escape = true
              state.string = true
              return "string"
            } else {
              return "string"
            }
          }
        } else if (state.comment) {
          if (ch == "*" && stream.peek() == "/") {
            state.prev = "*"
            return "comment"
          } else if (ch == "/" && state.prev == "*") {
            state.prev = false
            state.comment = false
            return "comment"
          }
          return "comment"
        } else {
          if (ch == "/") {
            if (stream.peek() == "/") {
              stream.skipToEnd()
              return "comment"
            }
            if (stream.peek() == "*") {
              state.comment = true
              return "comment"
            }
          }
          if (ch == "(" && state.inner) {
            state.num_left++
            return null
          }
          if (ch == ")" && state.inner) {
            state.num_right++
            if (state.num_left == state.num_right) {
              state.inner=false
              state.string=true
            }
            return null
          }

          var ret = getWord(stream.string, stream.pos)
          var the_word = ret[1]
          var prev_word = ret[0]

          if (operators.indexOf(ch + "") > -1) return "operator"
          if (punc.indexOf(ch) > -1) return "punctuation"

          if (typeof the_word != "undefined") {
            the_word = trim(the_word)
            if (typeof prev_word != "undefined") prev_word = trim(prev_word)
            if (the_word.charAt(0) == "#") return null

            if (types.indexOf(the_word) > -1) return "def"
            if (commonConstants.indexOf(the_word) > -1) return "atom"
            if (numbers.indexOf(the_word) > -1) return "number"

            if ((numbers.indexOf(the_word.charAt(0) + "") > -1 ||
                 operators.indexOf(the_word.charAt(0) + "") > -1) &&
                numbers.indexOf(ch) > -1) {
              return "number"
            }

            if (keywords.indexOf(the_word) > -1 ||
                keywords.indexOf(the_word.split(tokens)[0]) > -1)
              return "keyword"
            if (keywords.indexOf(prev_word) > -1) return "def"
          }
          if (ch == '"' && !state.doubleString) {
            state.string = true
            state.doubleString = true
            return "string"
          }
          if (ch == "'" && !state.singleString) {
            state.string = true
            state.singleString = true
            return "string"
          }
          if (ch == "(" && state.inner)
            state.num_left++
          if (ch == ")" && state.inner) {
            state.num_right++
            if (state.num_left == state.num_right) {
              state.inner = false
              state.string = true
            }
            return null
          }
          if (stream.match(/^-?[0-9\.]/, false)) {
            if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i) ||
                stream.match(/^-?\d+\.\d*/) ||
                stream.match(/^-?\.\d+/)) {
              if (stream.peek() == ".") stream.backUp(1)
              return "number"
            }
            if (stream.match(/^-?0x[0-9a-f]+/i) ||
                stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/) ||
                stream.match(/^-?0(?![\dx])/i))
              return "number"
          }
          if (stream.match(regexPrefixes)) {
            if (stream.current()!="/" || stream.match(/^.*\//,false)) return "string"
            else stream.backUp(1)
          }
          if (stream.match(delimiters)) return "punctuation"
          if (stream.match(identifiers)) return "variable"
          if (stream.match(properties)) return "property"
          return "variable"
        }
      }
    }
  })

  CodeMirror.defineMIME("text/x-swift","swift")
})
<|endoftext|>


<commit_before>// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Yacas mode copyright (c) 2015 by Grzegorz Mazur
// Loosely based on mathematica mode by Calin Barbat

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.defineMode('yacas', function(_config, _parserConfig) {

  // patterns
  var pFloatForm  = "(?:(?:\\.\\d+|\\d+\\.\\d*|\\d+)(?:[eE][+-]?\\d+)?)";
  var pIdentifier = "(?:[a-zA-Z\\$'][a-zA-Z0-9\\$']*)";

  // regular expressions
  var reFloatForm    = new RegExp(pFloatForm);
  var reIdentifier   = new RegExp(pIdentifier);
  var rePattern      = new RegExp(pIdentifier + "?_" + pIdentifier);
  var reFunctionLike = new RegExp(pIdentifier + "\\s*\\(");

  function tokenBase(stream, state) {
    var ch;

    // get next character
    ch = stream.next();

    // string
    if (ch === '"') {
      state.tokenize = tokenString;
      return state.tokenize(stream, state);
    }

    // comment
    if (ch === '/') {
      if (stream.eat('*')) {
        state.tokenize = tokenComment;
        return state.tokenize(stream, state);
      }
      if (stream.eat("/")) {
        stream.skipToEnd();
        return "comment";
      }
    }

    // go back one character
    stream.backUp(1);

    // look for ordered rules
    if (stream.match(/\d+ *#/, true, false)) {
      return 'qualifier';
    }

    // look for numbers
    if (stream.match(reFloatForm, true, false)) {
      return 'number';
    }

    // look for placeholders
    if (stream.match(rePattern, true, false)) {
      return 'variable-3';
    }

    // match all braces separately
    if (stream.match(/(?:\[|\]|{|}|\(|\))/, true, false)) {
      return 'bracket';
    }

    // literals looking like function calls
    if (stream.match(reFunctionLike, true, false)) {
      stream.backUp(1);
      return 'variable';
    }

    // all other identifiers
    if (stream.match(reIdentifier, true, false)) {
      return 'variable-2';
    }

    // operators; note that operators like @@ or /; are matched separately for each symbol.
    if (stream.match(/(?:\\|\+|\-|\*|\/|,|;|\.|:|@|~|=|>|<|&|\||_|`|'|\^|\?|!|%)/, true, false)) {
      return 'operator';
    }

    // everything else is an error
    return 'error';
  }

  function tokenString(stream, state) {
    var next, end = false, escaped = false;
    while ((next = stream.next()) != null) {
      if (next === '"' && !escaped) {
        end = true;
        break;
      }
      escaped = !escaped && next === '\\';
    }
    if (end && !escaped) {
      state.tokenize = tokenBase;
    }
    return 'string';
  };

  function tokenComment(stream, state) {
    var prev, next;
    while((next = stream.next()) != null) {
      if (prev === '*' && next === '/')
        break;
      prev = next;
    }
    state.tokenize = tokenBase;
    return 'comment';
  }

  return {
    startState: function() {return {tokenize: tokenBase, commentLevel: 0};},
    token: function(stream, state) {
      if (stream.eatSpace()) return null;
      return state.tokenize(stream, state);
    },
    blockCommentStart: "/*",
    blockCommentEnd: "*/",
    lineComment: "//"
  };
});

CodeMirror.defineMIME('text/x-yacas', {
  name: 'yacas'
});

});
<commit_msg>[yacas mode] fix multiline comments<commit_after>// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Yacas mode copyright (c) 2015 by Grzegorz Mazur
// Loosely based on mathematica mode by Calin Barbat

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.defineMode('yacas', function(_config, _parserConfig) {

  // patterns
  var pFloatForm  = "(?:(?:\\.\\d+|\\d+\\.\\d*|\\d+)(?:[eE][+-]?\\d+)?)";
  var pIdentifier = "(?:[a-zA-Z\\$'][a-zA-Z0-9\\$']*)";

  // regular expressions
  var reFloatForm    = new RegExp(pFloatForm);
  var reIdentifier   = new RegExp(pIdentifier);
  var rePattern      = new RegExp(pIdentifier + "?_" + pIdentifier);
  var reFunctionLike = new RegExp(pIdentifier + "\\s*\\(");

  function tokenBase(stream, state) {
    var ch;

    // get next character
    ch = stream.next();

    // string
    if (ch === '"') {
      state.tokenize = tokenString;
      return state.tokenize(stream, state);
    }

    // comment
    if (ch === '/') {
      if (stream.eat('*')) {
        state.tokenize = tokenComment;
        return state.tokenize(stream, state);
      }
      if (stream.eat("/")) {
        stream.skipToEnd();
        return "comment";
      }
    }

    // go back one character
    stream.backUp(1);

    // look for ordered rules
    if (stream.match(/\d+ *#/, true, false)) {
      return 'qualifier';
    }

    // look for numbers
    if (stream.match(reFloatForm, true, false)) {
      return 'number';
    }

    // look for placeholders
    if (stream.match(rePattern, true, false)) {
      return 'variable-3';
    }

    // match all braces separately
    if (stream.match(/(?:\[|\]|{|}|\(|\))/, true, false)) {
      return 'bracket';
    }

    // literals looking like function calls
    if (stream.match(reFunctionLike, true, false)) {
      stream.backUp(1);
      return 'variable';
    }

    // all other identifiers
    if (stream.match(reIdentifier, true, false)) {
      return 'variable-2';
    }

    // operators; note that operators like @@ or /; are matched separately for each symbol.
    if (stream.match(/(?:\\|\+|\-|\*|\/|,|;|\.|:|@|~|=|>|<|&|\||_|`|'|\^|\?|!|%)/, true, false)) {
      return 'operator';
    }

    // everything else is an error
    return 'error';
  }

  function tokenString(stream, state) {
    var next, end = false, escaped = false;
    while ((next = stream.next()) != null) {
      if (next === '"' && !escaped) {
        end = true;
        break;
      }
      escaped = !escaped && next === '\\';
    }
    if (end && !escaped) {
      state.tokenize = tokenBase;
    }
    return 'string';
  };

  function tokenComment(stream, state) {
    var prev, next;
    while((next = stream.next()) != null) {
      if (prev === '*' && next === '/') {
        state.tokenize = tokenBase;
        break;
      }
      prev = next;
    }
    return 'comment';
  }

  return {
    startState: function() {return {tokenize: tokenBase, commentLevel: 0};},
    token: function(stream, state) {
      if (stream.eatSpace()) return null;
      return state.tokenize(stream, state);
    },
    blockCommentStart: "/*",
    blockCommentEnd: "*/",
    lineComment: "//"
  };
});

CodeMirror.defineMIME('text/x-yacas', {
  name: 'yacas'
});

});
<|endoftext|>


<commit_before>/*
 * Licensed to Cloudkick, Inc ('Cloudkick') under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * Cloudkick licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var path = require('path');
var spawn = require('child_process').spawn;
var util = require('util');

var async = require('async');
var sprintf = require('sprintf').sprintf;

var dotfiles = require('util/client_dotfiles');
var log = require('util/log');
var constants = require('deployment/constants');
var misc = require('util/misc');
var Errorf = misc.Errorf;

/**
 * Base hook class.
 * @constructor
 *
 * {String} type Hook type (pre / post).
 * {String} name Hook name.
 * {String} hookPath Path to the hook file.
 * {String} cwd Hook working directory.
 * {Boolean} errOnInexistent Throw an error if the hook file doesn't exist
 *                           (defaults to False)
 * {Object} baseEnv Base environment which is set for the hook.
 */
function Hook(type, name, hookPath, cwd, errOnInexistent, baseEnv) {
  this.type = type;
  this.path = hookPath;
  this.cwd = cwd;
  this.errOnInexistent = errOnInexistent || false;
  this.baseEnv = baseEnv || {};
}

/**
 * Execute a hook script.
 * {Number} timeout Number of milliseconds after which hook is killed if it
 *                  hasn't exited yet.
 * {Array} args Arguments to the specified hook
 * {Function} callback A callback fired with (err, killed, stderr, stdout)
 */
Hook.prototype.execute = function(timeout, args, callback) {
  var self = this;
  var env = this._getEnvironment(this.baseEnv);
  var timeout_ = timeout || constants.timeouts[this.hookName];

  var hookExists = false;

  async.waterfall([
    // See if the hook exists
    function(callback) {
      path.exists(self.path, function(exists) {
        hookExists = exists;
        callback();
      });
    },

    // If the hook does exist, execute it
    function(callback) {
      if (!hookExists) {
        var err = null;

        if (self.errOnInexistent) {
          err = new Errorf('hook %s does not exist', self.path);
        }

        callback(err, false, null, null);
        return;
      }

      var opts = {
        cwd: self.cwd,
        env: env
      };

      var stdout = '';
      var stderr = '';
      var hookRunning = false;

      log.info(sprintf('executing hook: %s', self.path));

      var hookProc = spawn(self.path, args, opts);
      hookRunning = true;

      var hookTimeoutId = setTimeout(function() {
        if (hookRunning) {
          hookProc.kill('SIGTERM');
        }
      }, timeout_);

      hookProc.stdout.on('data', function(chunk) {
        stdout += chunk;
      });

      hookProc.stderr.on('data', function(chunk) {
        stderr += chunk;
      });

      hookProc.on('exit', function(code) {
        var err = null;
        var killed = this.killed;

        if (!killed) {
          clearTimeout(hookTimeoutId);
        }

        if (killed) {
          err = new Errorf('hook %s was killed because a timeout' +
                           ' of %s ms was reached ', self.path, timeout);
        }
        else if (code !== 0) {
          var err_msg = sprintf('hook %s exited with status %s', self.path, code);
          err = new Error(err_msg);
          log.info(err_msg);
        }
        else {
          log.info(sprintf('hook %s exited cleanly', self.path));
        }

        callback(err, killed, stdout, stderr);
      });
    }
  ],

  function(err, killed, stdout, stderr) {
    callback(err, killed, stdout, stderr);
  });
};

Hook.prototype._getEnvironment = function(baseEnv) {
  var env = misc.merge({}, baseEnv);
  var k;

  // This whole thing is a dirty hack because process.env doesn't have a
  // hasOwnProperty() method - misc.merge won't work, and we need a condional
  // to keep jslint happy...
  for (k in process.env) {
    if (true) {
      env[k] = process.env[k];
    }
  }

  return env;
};

/**
 * Instance hook class.
 * @constructor
 *
 * {String} type Hook type (pre / post).
 * {String} name Hook name.
 * {String} instanceVersionPath Path to the instance version root.
 * {Boolean} errOnInexistent Throw an error if the hook file doesn't exist
 *                           (defaults to False)
 * {Object} baseEnv Base environment which is set for the hook.
 */
function InstanceHook(type, name, instanceVersionPath, errOnInexistent, baseEnv) {
  var hookPath = path.join(instanceVersionPath, '.cast-project', 'hooks',
                           name);
  Hook.call(this, type, name, hookPath, instanceVersionPath, errOnInexistent,
            baseEnv);
  this.instanceVersionPath = instanceVersionPath;
}

util.inherits(InstanceHook, Hook);

exports.Hook = Hook;
exports.InstanceHook = InstanceHook;
<commit_msg>more informative hook error logging<commit_after>/*
 * Licensed to Cloudkick, Inc ('Cloudkick') under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * Cloudkick licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var path = require('path');
var spawn = require('child_process').spawn;
var util = require('util');

var async = require('async');
var sprintf = require('sprintf').sprintf;

var dotfiles = require('util/client_dotfiles');
var log = require('util/log');
var constants = require('deployment/constants');
var misc = require('util/misc');
var Errorf = misc.Errorf;

/**
 * Base hook class.
 * @constructor
 *
 * {String} type Hook type (pre / post).
 * {String} name Hook name.
 * {String} hookPath Path to the hook file.
 * {String} cwd Hook working directory.
 * {Boolean} errOnInexistent Throw an error if the hook file doesn't exist
 *                           (defaults to False)
 * {Object} baseEnv Base environment which is set for the hook.
 */
function Hook(type, name, hookPath, cwd, errOnInexistent, baseEnv) {
  this.type = type;
  this.path = hookPath;
  this.cwd = cwd;
  this.errOnInexistent = errOnInexistent || false;
  this.baseEnv = baseEnv || {};
}

/**
 * Execute a hook script.
 * {Number} timeout Number of milliseconds after which hook is killed if it
 *                  hasn't exited yet.
 * {Array} args Arguments to the specified hook
 * {Function} callback A callback fired with (err, killed, stderr, stdout)
 */
Hook.prototype.execute = function(timeout, args, callback) {
  var self = this;
  var env = this._getEnvironment(this.baseEnv);
  var timeout_ = timeout || constants.timeouts[this.hookName];

  var hookExists = false;

  async.waterfall([
    // See if the hook exists
    function(callback) {
      path.exists(self.path, function(exists) {
        hookExists = exists;
        callback();
      });
    },

    // If the hook does exist, execute it
    function(callback) {
      if (!hookExists) {
        var err = null;

        if (self.errOnInexistent) {
          err = new Errorf('hook %s does not exist', self.path);
        }

        callback(err, false, null, null);
        return;
      }

      var opts = {
        cwd: self.cwd,
        env: env
      };

      var stdout = '';
      var stderr = '';
      var hookRunning = false;

      log.info(sprintf('executing hook: %s', self.path));

      var hookProc = spawn(self.path, args, opts);
      hookRunning = true;

      var hookTimeoutId = setTimeout(function() {
        if (hookRunning) {
          hookProc.kill('SIGTERM');
        }
      }, timeout_);

      hookProc.stdout.on('data', function(chunk) {
        stdout += chunk;
      });

      hookProc.stderr.on('data', function(chunk) {
        stderr += chunk;
      });

      hookProc.on('exit', function(code) {
        var err = null;
        var killed = this.killed;

        if (!killed) {
          clearTimeout(hookTimeoutId);
        }

        if (killed) {
          err = new Errorf('hook %s was killed because a timeout' +
                           ' of %s ms was reached ', self.path, timeout);
        }
        else if (code !== 0) {
          var err_msg = sprintf('hook %s exited with status %s', self.path, code);
          err = new Error(err_msg);
          log.info(err_msg);
          log.info(sprintf('stdout:\n%s', stdout));
          log.info(sprintf('stderr:\n%s', stderr));
        }
        else {
          log.info(sprintf('hook %s exited cleanly', self.path));
        }

        callback(err, killed, stdout, stderr);
      });
    }
  ],

  function(err, killed, stdout, stderr) {
    callback(err, killed, stdout, stderr);
  });
};

Hook.prototype._getEnvironment = function(baseEnv) {
  var env = misc.merge({}, baseEnv);
  var k;

  // This whole thing is a dirty hack because process.env doesn't have a
  // hasOwnProperty() method - misc.merge won't work, and we need a condional
  // to keep jslint happy...
  for (k in process.env) {
    if (true) {
      env[k] = process.env[k];
    }
  }

  return env;
};

/**
 * Instance hook class.
 * @constructor
 *
 * {String} type Hook type (pre / post).
 * {String} name Hook name.
 * {String} instanceVersionPath Path to the instance version root.
 * {Boolean} errOnInexistent Throw an error if the hook file doesn't exist
 *                           (defaults to False)
 * {Object} baseEnv Base environment which is set for the hook.
 */
function InstanceHook(type, name, instanceVersionPath, errOnInexistent, baseEnv) {
  var hookPath = path.join(instanceVersionPath, '.cast-project', 'hooks',
                           name);
  Hook.call(this, type, name, hookPath, instanceVersionPath, errOnInexistent,
            baseEnv);
  this.instanceVersionPath = instanceVersionPath;
}

util.inherits(InstanceHook, Hook);

exports.Hook = Hook;
exports.InstanceHook = InstanceHook;
<|endoftext|>


<commit_before>/**
 * Декларировать аргументы функции callback
 * и вернуть строку декларации
 *
 * @param {(!Array|string)} parts - строка аргументов или массив параметров директивы
 * @return {string}
 */
DirObj.prototype.declCallbackArgs = function (parts) {
	var args = ((Array.isArray(parts) ? parts[2] || parts[1] : parts) || '').split(','),
		scope;

	for (let i = -1; ++i < args.length;) {
		let el = args[i].trim(),
			mod = scopeModRgxp.test(el);

		if (mod) {
			if (scope) {
				this.error(`invalid "${this.name}" declaration`);

			} else {
				el = el.replace(scopeModRgxp, '');
			}
		}

		if (el) {
			args[i] = this.declVar(el, true);

			if (mod) {
				scope = args[i];
			}
		}
	}

	if (scope) {
		this.scope.push(scope);
		this.structure.params._scope = true;
	}

	return args.join(',');
};

Snakeskin.addDirective(
	'callback',

	{
		block: true,
		group: 'callback',
		replacers: {
			'()': (cmd) => cmd.replace('()', 'callback ')
		}
	},

	function (command) {
		var parts = command.split('=>');

		if (!parts.length || parts.length > 2) {
			return this.error(`invalid "${this.name}" declaration`);
		}

		this.startDir();
		if (this.isReady()) {
			let async = this.getGroup('async'),
				parent = this.structure.parent;

			this.structure.params.insideAsync = async[parent.name];
			var children = parent.children,
				length = 0;

			for (let i = -1; ++i < children.length;) {
				if (children[i].name === 'callback') {
					length++;
				}

				if (length > 1) {
					break;
				}
			}

			this.append(/* cbws */`
				${async[parent.name] && length > 1 ? ', ' : ''}(function (${this.declCallbackArgs(parts)}) {
					${this.declArguments()}
			`);
		}
	},

	function () {
		this.append('})' + (this.structure.params.insideAsync ? '' : ';'));
	}
);

Snakeskin.addDirective(
	'final',

	{
		block: true,
		group: [
			'callback',
			'basicAsync'
		],

		chain: [
			'parallel',
			'series',
			'waterfall'
		]
	},

	function (command) {
		var async = this.getGroup('series');

		if (!async[this.structure.name]) {
			return this.error(`directive "${this.name}" can be used only with a "${groupsList['series'].join(', ')}"`);
		}

		var parts = command.split('=>');

		if (!parts.length || parts.length > 2) {
			return this.error(`invalid "${this.name}" declaration`);
		}

		this.startDir();
		if (this.isReady()) {
			this.append(/* cbws */`
				], function (${this.declCallbackArgs(parts)}) {
					${this.declArguments()}
			`);
		}
	},

	function () {
		this.append('});');
		this.endDir();
	}
);

(() => {
	var series = ['parallel', 'series', 'waterfall'];

	for (let i = -1; ++i < series.length;) {
		Snakeskin.addDirective(
			series[i],

			{
				block: true,
				group: [
					'async',
					'Async',
					'series'
				],

				inside: {
					'callback': true,
					'final': true
				}
			},

			function (command, commandLength, type) {
				this.startDir();
				this.append(`${this.prepareOutput('async', true)}.${type}([`);
			},

			function () {
				this.append(']);');
			}
		);
	}

	var async = ['whilst', 'doWhilst', 'forever'];

	for (let i = -1; ++i < async.length;) {
		Snakeskin.addDirective(
			async[i],

			{
				block: true,
				group: [
					'async',
					'Async'
				],

				inside: {
					'callback': true
				}
			},

			function (command, commandLength, type) {
				this.startDir();
				this.append(`${this.prepareOutput('async', true)}.${type}(`);
			},

			function () {
				this.append(');');
			}
		);
	}
})();

Snakeskin.addDirective(
	'when',

	{
		block: true,
		notEmpty: true,

		group: [
			'async',
			'basicAsync'
		],

		inside: {
			'callback': true
		}
	},

	function (command) {
		this.startDir();
		this.append(`${this.prepareOutput(command, true)}.then(`);
	},

	function () {
		this.append(');');
	}
);
<commit_msg>Исправление ошибки<commit_after>/**
 * Декларировать аргументы функции callback
 * и вернуть строку декларации
 *
 * @param {(!Array|string)} parts - строка аргументов или массив параметров директивы
 * @return {string}
 */
DirObj.prototype.declCallbackArgs = function (parts) {
	var args = ((Array.isArray(parts) ? parts[2] || parts[1] : parts) || '').split(','),
		scope;

	for (let i = -1; ++i < args.length;) {
		let el = args[i].trim(),
			mod = scopeModRgxp.test(el);

		if (mod) {
			if (scope) {
				this.error(`invalid "${this.name}" declaration`);

			} else {
				el = el.replace(scopeModRgxp, '');
			}
		}

		if (el) {
			args[i] = this.declVar(el, true);

			if (mod) {
				scope = args[i];
			}
		}
	}

	if (scope) {
		this.scope.push(scope);
		this.structure.params._scope = true;
	}

	return args.join(',');
};

Snakeskin.addDirective(
	'callback',

	{
		block: true,
		group: 'callback',
		replacers: {
			'()': (cmd) => cmd.replace('()', 'callback ')
		}
	},

	function (command) {
		var parts = command.split('=>');

		if (!parts.length || parts.length > 2) {
			return this.error(`invalid "${this.name}" declaration`);
		}

		this.startDir();
		if (this.isReady()) {
			let async = this.getGroup('async'),
				parent = this.structure.parent;

			this.structure.params.insideAsync = async[parent.name];
			let children = parent.children,
				length = 0;

			for (let i = -1; ++i < children.length;) {
				if (children[i].name === 'callback') {
					length++;
				}

				if (length > 1) {
					break;
				}
			}

			this.append(/* cbws */`
				${async[parent.name] && length > 1 ? ', ' : ''}(function (${this.declCallbackArgs(parts)}) {
					${this.declArguments()}
			`);
		}
	},

	function () {
		this.append('})' + (this.structure.params.insideAsync ? '' : ';'));
	}
);

Snakeskin.addDirective(
	'final',

	{
		block: true,
		group: [
			'callback',
			'basicAsync'
		],

		chain: [
			'parallel',
			'series',
			'waterfall'
		]
	},

	function (command) {
		var async = this.getGroup('series');

		if (!async[this.structure.name]) {
			return this.error(`directive "${this.name}" can be used only with a "${groupsList['series'].join(', ')}"`);
		}

		var parts = command.split('=>');

		if (!parts.length || parts.length > 2) {
			return this.error(`invalid "${this.name}" declaration`);
		}

		this.startDir();
		if (this.isReady()) {
			this.append(/* cbws */`
				], function (${this.declCallbackArgs(parts)}) {
					${this.declArguments()}
			`);
		}
	},

	function () {
		this.append('});');
		this.endDir();
	}
);

(() => {
	var series = ['parallel', 'series', 'waterfall'];

	for (let i = -1; ++i < series.length;) {
		Snakeskin.addDirective(
			series[i],

			{
				block: true,
				group: [
					'async',
					'Async',
					'series'
				],

				inside: {
					'callback': true,
					'final': true
				}
			},

			function (command, commandLength, type) {
				this.startDir();
				this.append(`${this.prepareOutput('async', true)}.${type}([`);
			},

			function () {
				this.append(']);');
			}
		);
	}

	var async = ['whilst', 'doWhilst', 'forever'];

	for (let i = -1; ++i < async.length;) {
		Snakeskin.addDirective(
			async[i],

			{
				block: true,
				group: [
					'async',
					'Async'
				],

				inside: {
					'callback': true
				}
			},

			function (command, commandLength, type) {
				this.startDir();
				this.append(`${this.prepareOutput('async', true)}.${type}(`);
			},

			function () {
				this.append(');');
			}
		);
	}
})();

Snakeskin.addDirective(
	'when',

	{
		block: true,
		notEmpty: true,

		group: [
			'async',
			'basicAsync'
		],

		inside: {
			'callback': true
		}
	},

	function (command) {
		this.startDir();
		this.append(`${this.prepareOutput(command, true)}.then(`);
	},

	function () {
		this.append(');');
	}
);
<|endoftext|>


<commit_before>var mongoose = require('mongoose');
var Schema   = mongoose.Schema;

var userSchema = new Schema({
	"email" : String,
	"avatar" : String
});

module.exports = mongoose.model('user', userSchema);<commit_msg>Update userModel.js<commit_after>var mongoose = require('mongoose');
var Schema   = mongoose.Schema;

var userSchema = new Schema({
	"email" : String,
	"avatar" : String,
	"galleries": Array
});

module.exports = mongoose.model('user', userSchema);
<|endoftext|>


<commit_before>angular.module('aurora.services', [])

//Local storage services
.factory('$localstorage', ['$window', function($window) {
	return {
		set: function(key, value) {
			$window.localStorage[key] = JSON.stringify(value);
		},
		get: function(key, defaultValue) {
			var temp = $window.localStorage[key];
			if (typeof temp != 'undefined')
				return JSON.parse(temp);
			else return defaultValue;
		},
		setObject: function(key, value) {
			$window.localStorage[key] = JSON.stringify(value);
		},
		getObject: function(key) {
			return JSON.parse($window.localStorage[key] || '{}');
		},
		remove: function(key) {
			localStorage.removeItem(key);
		}
	};
}])

//Push notification services
.factory('$push', function($http, $location, $localstorage, $kpAPI, $geolocation) {
	var push     = false;
	var gcmID    = '638344930515';

	var initData = {
		'android': {
			'senderID': gcmID
		},
		'ios': {
			'alert': true,
			'badge': true,
			'sound': true,
			'clearBage': true
		},
		'windows': {

		}
	};

	var postToPushServer = function(params, onSuccess, onFailure) {
		$http.post("http://aurora.cs.uaf.edu/notification_service", params)
			.then(onSuccess, onFailure);
	};

	var update = function(info) {
        info.token = $localstorage.get('pushToken');
        info.mode  = 'update';

		postToPushServer(info, function() {
			console.log("AURORA: Info changed.");
		}, function() {
			console.log("AURORA: Could not change info.");
		});
	};

	var receivedNotification = function(data) {
		var message   = JSON.parse(data.message);
		var kpTrigger = message.kpTrigger;
		$kpAPI.setNow(kpTrigger);

		console.log("AURORA: " + kpTrigger);
		console.log("AURORA: " + data.title);
		console.log("AURORA: " + data.count);
		console.log("AURORA: " + data.sound);
		console.log("AURORA: " + data.image);
		console.log("AURORA: " + data.additionalData);
	};

	var receivedError = function(data) {
		console.log("AURORA: " + e.message);
	};

	var notificationServiceRegistered = function(data) {
        var postData  = {};
        var kpTrigger = $localstorage.get('kpTrigger', 6);
        var info      = {};

		var getGeolocation = function() {
			$geolocation.getInfo(info, function(lat, lon) {
				console.log('AURORA: Setting geolocation information.');
				update(info);
			});
		};

		if (ionic.Platform.isAndroid()) {
            postData.mode      = "register";
            postData.service   = "gcm";
            postData.token     = data.registrationId;
            postData.kpTrigger = kpTrigger;
		}
		else if (ionic.Platform.isIOS()) {
            postData.mode      = "register";
            postData.service   = "apns";
            postData.token     = data.registrationId;
            postData.kpTrigger = kpTrigger;
		}

		console.log('AURORA: ' + postData);
		console.log('AURORA: ' + JSON.stringify(postData));

		postToPushServer(postData, function(response) {
			if (response.status == 200) {
				console.log("AURORA: " + "Key has been added to push server!");
				$localstorage.set('pushToken', data.registrationId);
				console.log("AURORA: Your token: " + data.registrationId);
				getGeolocation();
			}
		}, function(response) {
			console.log("AURORA: " + "Key has not been added to the push server!");
			console.log("AURORA: Failure status: " + response.status);
		});
	};

	return {
		requestTestPushNotification: function() {
			if (ionic.Platform.isAndroid()) {
				postData = {
                    "test_push" : true,
                    "kpTrigger" : "",
                    "service"   : "gcm",
                    "method"    : "all",
                    "token"     : ""
				};
			} else if (ionic.Platform.isIOS()) {
				postData = {
                    "test_push" : true,
                    "kpTrigger" : "",
                    "service"   : "apns",
                    "method"    : "all",
                    "token"     : ""
				};
			}

			postToPushServer(postData, function(response) {
				if (response.status == 200) {
					console.log("AURORA: " + "You should receive a notification momentarily.");
				}
			}, function(response) {
				console.log("AURORA: " + "Request was denied.");
				console.log("AURORA: Failure status: " + response.status);
			});
		},
		initPushNotifications: function(callback) {
			push = PushNotification.init(initData);

			if (push) {
				console.log("AURORA: " + "Push notification service successfully initialized.");
			} else {
				console.log("AURORA: " + "Push notification service NOT initialized.");
			}

			push.on('registration', notificationServiceRegistered);

			PushNotification.hasPermission(function(data) {
				if (data.isEnabled) {
					console.log("AURORA: " + "Push notifications enabled.");
				} else {
					console.log("AURORA: " + "Push notifications disabled.");
				}
			});

			push.on('notification', receivedNotification);

			push.on('error', receivedError);

			if (callback)
				callback();
		},
		register: function() {
			var token           = $localstorage.get('pushToken');
			var notifyStartTime = $localstorage.get('quietHoursStartTime_1');
			var notifyStopTime  = $localstorage.get('quietHoursStopTime_1');

			notificationServiceRegistered({
				registrationId      : token,
				'notify_start_time' : notifyStartTime,
				'notify_stop_time'  : notifyStopTime
			});
		},
		unregister: function() {
			var info   = {};
			info.token = $localstorage.get('pushToken');
			info.mode  = 'remove';

			postToPushServer(info, function() {
				console.log("AURORA: Push notifications disabled.");
			}, function() {
				console.log("AURORA: Could not disable push notifications.");
			});
		},
		updateInfo: update
	};
})

//Geolocation services
.factory('$geolocation', function($localstorage, $http) {
	var getInfoFromCoordinates = function(info, callback) {
		var apiURL = 'http://maps.googleapis.com/maps/api/geocode/json?latlng=';
		apiURL += info.latitude + ',' + info.longitude + '&sensor=false';

		console.log('AURORA: Getting country from: ' + apiURL);

		$http.get(apiURL + info.latitude + ',' + info.longitude + '&sensor=false')
		.success(function(data) {
			info.city    = data.results[0].address_components[2].short_name;
			info.state   = data.results[0].address_components[4].short_name;
			info.country = data.results[0].address_components[5].short_name;

			$localstorage.set('geoInfo', JSON.stringify(info));

			if(callback)
				callback(info);
		}).error(function(error) {
			//Finish writing
			console.log('AURORA: Error: ' + error);
		});
	};

	return {
		showGeoLocationInfo: function() {
			var gps = $localstorage.get('gps', false);
			if (gps) {
				var options = {
					enableHighAccuracy: true,
					timeout: 15000,
					maximumAge: 1000 * 60 * 5 //Five minutes
				};

				navigator.geolocation.getCurrentPosition(function(position) {
					alert('Latitude: ' + position.coords.latitude + '\n' +
						'Longitude: ' + position.coords.longitude + '\n' +
						'Altitude: ' + position.coords.altitude + '\n' +
						'Accuracy: ' + position.coords.accuracy + '\n' +
						'Altitude Accuracy: ' + position.coords.altitudeAccuracy + '\n' +
						'Heading: ' + position.coords.heading + '\n' +
						'Speed: ' + position.coords.speed + '\n' +
						'Timestamp: ' + position.timestamp + '\n');

				}, function(error) {
					alert('Code: ' + error.code + '\n' +
						'Message: ' + error.message + '\n');
				}, options);
			}
		},
		getInfo: function(params, callback) {
			var gps = $localstorage.get('gps', false);

			if (gps) {
				var options = {
					enableHighAccuracy: true,
					timeout: 15000,
					maximumAge: 1000 * 60 * 5 //Five minutes
				};

				navigator.geolocation.getCurrentPosition(function(position) {
                    params.latitude  = position.coords.latitude;
                    params.longitude = position.coords.longitude;

					console.log('AURORA: Set lat and long.');

					getInfoFromCoordinates(params, callback);
				});
			}
		}
	};
})

//GI API service
.factory('$kpAPI', function($http, $localstorage) {
	var latestForecast = {};
	var apiURL         = 'http://cs472.gi.alaska.edu/kp.php?';

	var loadForecastFromStorage = function() {
		latestForecast = $localstorage.getObject('forecast');

		if (typeof latestForecast == 'undefined' || Object.keys(latestForecast).length === 0)
			updateForecast();
	};

	var saveForecast = function(forecast) {
		$localstorage.remove('forecast');
		$localstorage.setObject('forecast', forecast);
	};

	var formatTime = function(timeStr) {
		// source: http://stackoverflow.com/questions/14638018/current-time-formatting-with-javascript

        var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
        var days   = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

		// timeStr is in format:
		//      2016-04-17T21:01:00.0+00:00
		// which is UTC
		var apiDate  = new Date(timeStr);

		var theDate  = apiDate.getDate();
		var theMonth = months[apiDate.getMonth()];
		var theDay   = days[apiDate.getDay()];
		var theHour  = apiDate.getHours();

		var ampm = theHour < 12 ? "am" : "pm";
		if (theHour > 12) {
			theHour -= 12;
		} else if (theHour < 12) {
			theHour[0] = "";
		}

		if (theHour == '0') {
			theHour = "12";
		}

		var theMin = apiDate.getMinutes();
		if (theMin < 10) {
			theMin = "00";
		}

		var time = theHour + ":" + theMin + ampm;
		var date = theDay + "," + theMonth + " " + theDate;

		return {
			'time': time,
			'date': date
		};
	};

	var getForecastData = function(callback) {
		$http.get(apiURL + 'd=d&f=t').success(function(data) {
			if (data.data[0] != 'undefined') {
				var jsonData = {};

				for (var i = 0; i < data.data.length; i++) {
					jsonData['kp' + i]    = {};
					jsonData['kp' + i].kp = data.data[i].kp;

					var time = formatTime(data.data[i].predicted_time);

					jsonData['kp' + i].time = time.time;
					jsonData['kp' + i].date = time.date;
				}

				latestForecast = jsonData;

				saveForecast(latestForecast);

				if(callback)
					callback();
			}
		}).error(function(error) {
			console.log('AURORA: Error: ' + error);
		});
	};

	var getNowData = function(callback) {
		$http.get(apiURL + 'd=n&f=t').success(function(data) {
			if (data.data[0] != 'undefined') {
				latestForecast.now = Math.ceil(data.data[0].kp);
				saveForecast(latestForecast);

				if(callback) {
					callback();
				}
			}
		}).error(function(error) {
			console.log('AURORA: Error: ' + error);
		});
	};

	return {
		updateForecast : function(callback) {
			getForecastData(function() {
				getNowData(function() {
					callback(latestForecast);
				});
			});
		},
		setNow: function(kpNow) {
			if (typeof latestForecast == 'undefined')
				loadForecastFromStorage();

			latestForecast.now = kpNow;
			saveForecast(latestForecast);
		}
	};
})

.factory('$background', function($kpAPI) {
	var backgroundlist = [{
		id: 1,
		url: "img/background-none.jpg"
	}, {
		id: 2,
		url: "img/background-low.jpg"
	}, {
		id: 3,
		url: "img/background-moderate.jpg"
	}, {
		id: 4,
		url: "img/background-high.jpg"
	}];

	return {
		getBackgroundUrl: function(callback) {
	    	$kpAPI.updateForecast(function(forecast) {
	    		var url  = null;
				switch (forecast.now) {
					case 1:
					case 2:
					case 3:
						url = backgroundlist[0].url;
						break;
					case 4:
					case 5:
						url = backgroundlist[1].url;
						break;
					case 6:
					case 7:
						url = backgroundlist[2].url;
						break;
					case 8:
					case 9:
						url = backgroundlist[3].url;
						break;
					default:
						url = backgroundlist[0].url;
						break;
				}

				callback(url);
	    	});
		}
	};
});
<commit_msg>Updated to set default info for now kp.<commit_after>angular.module('aurora.services', [])

//Local storage services
.factory('$localstorage', ['$window', function($window) {
	return {
		set: function(key, value) {
			$window.localStorage[key] = JSON.stringify(value);
		},
		get: function(key, defaultValue) {
			var temp = $window.localStorage[key];
			if (typeof temp != 'undefined')
				return JSON.parse(temp);
			else return defaultValue;
		},
		setObject: function(key, value) {
			$window.localStorage[key] = JSON.stringify(value);
		},
		getObject: function(key) {
			return JSON.parse($window.localStorage[key] || '{}');
		},
		remove: function(key) {
			localStorage.removeItem(key);
		}
	};
}])

//Push notification services
.factory('$push', function($http, $location, $localstorage, $kpAPI, $geolocation) {
	var push     = false;
	var gcmID    = '638344930515';

	var initData = {
		'android': {
			'senderID': gcmID
		},
		'ios': {
			'alert': true,
			'badge': true,
			'sound': true,
			'clearBage': true
		},
		'windows': {

		}
	};

	var postToPushServer = function(params, onSuccess, onFailure) {
		$http.post("http://aurora.cs.uaf.edu/notification_service", params)
			.then(onSuccess, onFailure);
	};

	var update = function(info) {
        info.token = $localstorage.get('pushToken');
        info.mode  = 'update';

		postToPushServer(info, function() {
			console.log("AURORA: Info changed.");
		}, function() {
			console.log("AURORA: Could not change info.");
		});
	};

	var receivedNotification = function(data) {
		var message   = JSON.parse(data.message);
		var kpTrigger = message.kpTrigger;
		$kpAPI.setNow(kpTrigger);

		console.log("AURORA: " + kpTrigger);
		console.log("AURORA: " + data.title);
		console.log("AURORA: " + data.count);
		console.log("AURORA: " + data.sound);
		console.log("AURORA: " + data.image);
		console.log("AURORA: " + data.additionalData);
	};

	var receivedError = function(data) {
		console.log("AURORA: " + e.message);
	};

	var notificationServiceRegistered = function(data) {
        var postData  = {};
        var kpTrigger = $localstorage.get('kpTrigger', 6);

		var getGeolocation = function() {
			$geolocation.getInfo({}, function(position) {
				console.log('AURORA: Setting geolocation information.');
				update(position);
			});
		};

		if (ionic.Platform.isAndroid()) {
            postData.mode      = "register";
            postData.service   = "gcm";
            postData.token     = data.registrationId;
            postData.kpTrigger = kpTrigger;
		}
		else if (ionic.Platform.isIOS()) {
            postData.mode      = "register";
            postData.service   = "apns";
            postData.token     = data.registrationId;
            postData.kpTrigger = kpTrigger;
		}

		console.log('AURORA: ' + postData);
		console.log('AURORA: ' + JSON.stringify(postData));

		postToPushServer(postData, function(response) {
			if (response.status == 200) {
				console.log("AURORA: " + "Key has been added to push server!");
				$localstorage.set('pushToken', data.registrationId);
				console.log("AURORA: Your token: " + data.registrationId);
				getGeolocation();
			}
		}, function(response) {
			console.log("AURORA: " + "Key has not been added to the push server!");
			console.log("AURORA: Failure status: " + response.status);
		});
	};

	return {
		requestTestPushNotification: function() {
			if (ionic.Platform.isAndroid()) {
				postData = {
                    "test_push" : true,
                    "kpTrigger" : "",
                    "service"   : "gcm",
                    "method"    : "all",
                    "token"     : ""
				};
			} else if (ionic.Platform.isIOS()) {
				postData = {
                    "test_push" : true,
                    "kpTrigger" : "",
                    "service"   : "apns",
                    "method"    : "all",
                    "token"     : ""
				};
			}

			postToPushServer(postData, function(response) {
				if (response.status == 200) {
					console.log("AURORA: " + "You should receive a notification momentarily.");
				}
			}, function(response) {
				console.log("AURORA: " + "Request was denied.");
				console.log("AURORA: Failure status: " + response.status);
			});
		},
		initPushNotifications: function(callback) {
			push = PushNotification.init(initData);

			if (push) {
				console.log("AURORA: " + "Push notification service successfully initialized.");
			} else {
				console.log("AURORA: " + "Push notification service NOT initialized.");
			}

			push.on('registration', notificationServiceRegistered);

			PushNotification.hasPermission(function(data) {
				if (data.isEnabled) {
					console.log("AURORA: " + "Push notifications enabled.");
				} else {
					console.log("AURORA: " + "Push notifications disabled.");
				}
			});

			push.on('notification', receivedNotification);

			push.on('error', receivedError);

			if (callback)
				callback();
		},
		register: function() {
			var token           = $localstorage.get('pushToken');
			var notifyStartTime = $localstorage.get('quietHoursStartTime_1');
			var notifyStopTime  = $localstorage.get('quietHoursStopTime_1');

			notificationServiceRegistered({
				registrationId      : token,
				'notify_start_time' : notifyStartTime,
				'notify_stop_time'  : notifyStopTime
			});
		},
		unregister: function() {
			var info   = {};
			info.token = $localstorage.get('pushToken');
			info.mode  = 'remove';

			postToPushServer(info, function() {
				console.log("AURORA: Push notifications disabled.");
			}, function() {
				console.log("AURORA: Could not disable push notifications.");
			});
		},
		updateInfo: update
	};
})

//Geolocation services
.factory('$geolocation', function($localstorage, $http) {
	var getInfoFromCoordinates = function(info, callback) {
		var apiURL = 'http://maps.googleapis.com/maps/api/geocode/json?latlng=';
		apiURL += info.latitude + ',' + info.longitude + '&sensor=false';

		$http.get(apiURL + info.latitude + ',' + info.longitude + '&sensor=false')
		.success(function(data) {
			info.city    = data.results[0].address_components[2].short_name;
			info.state   = data.results[0].address_components[4].short_name;
			info.country = data.results[0].address_components[5].short_name;

			$localstorage.set('geoInfo', JSON.stringify(info));

			if(callback)
				callback(info);
		}).error(function(error) {
			//Finish writing
			console.log('AURORA: Error: ' + error);
		});
	};

	return {
		showGeoLocationInfo: function() {
			var gps = $localstorage.get('gps', false);
			if (gps) {
				var options = {
					enableHighAccuracy: true,
					timeout: 15000,
					maximumAge: 1000 * 60 * 5 //Five minutes
				};

				navigator.geolocation.getCurrentPosition(function(position) {
					alert('Latitude: ' + position.coords.latitude + '\n' +
						'Longitude: ' + position.coords.longitude + '\n' +
						'Altitude: ' + position.coords.altitude + '\n' +
						'Accuracy: ' + position.coords.accuracy + '\n' +
						'Altitude Accuracy: ' + position.coords.altitudeAccuracy + '\n' +
						'Heading: ' + position.coords.heading + '\n' +
						'Speed: ' + position.coords.speed + '\n' +
						'Timestamp: ' + position.timestamp + '\n');

				}, function(error) {
					alert('Code: ' + error.code + '\n' +
						'Message: ' + error.message + '\n');
				}, options);
			}
		},
		getInfo: function(params, callback) {
			var gps = $localstorage.get('gps', false);

			if (gps) {
				var options = {
					enableHighAccuracy: true,
					timeout: 15000,
					maximumAge: 1000 * 60 * 5 //Five minutes
				};

				navigator.geolocation.getCurrentPosition(function(position) {
                    params.latitude  = position.coords.latitude;
                    params.longitude = position.coords.longitude;

					getInfoFromCoordinates(params, callback);
				});
			}
		}
	};
})

//GI API service
.factory('$kpAPI', function($http, $localstorage) {
	var latestForecast = {};
	var apiURL         = 'http://cs472.gi.alaska.edu/kp.php?';

	var loadForecastFromStorage = function() {
		latestForecast = $localstorage.getObject('forecast');

		if (typeof latestForecast == 'undefined' || Object.keys(latestForecast).length === 0)
			updateForecast();
	};

	var saveForecast = function(forecast) {
		$localstorage.remove('forecast');
		$localstorage.setObject('forecast', forecast);
	};

	var formatTime = function(timeStr) {
		// source: http://stackoverflow.com/questions/14638018/current-time-formatting-with-javascript

        var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
        var days   = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

		// timeStr is in format:
		//      2016-04-17T21:01:00.0+00:00
		// which is UTC
		var apiDate  = new Date(timeStr);

		var theDate  = apiDate.getDate();
		var theMonth = months[apiDate.getMonth()];
		var theDay   = days[apiDate.getDay()];
		var theHour  = apiDate.getHours();

		var ampm = theHour < 12 ? "am" : "pm";
		if (theHour > 12) {
			theHour -= 12;
		} else if (theHour < 12) {
			theHour[0] = "";
		}

		if (theHour == '0') {
			theHour = "12";
		}

		var theMin = apiDate.getMinutes();
		if (theMin < 10) {
			theMin = "00";
		}

		var time = theHour + ":" + theMin + ampm;
		var date = theDay + "," + theMonth + " " + theDate;

		return {
			'time': time,
			'date': date
		};
	};

	var getForecastData = function(callback) {
		$http.get(apiURL + 'd=d&f=t').success(function(data) {
			if (data.data[0] != 'undefined') {
				var jsonData = {};

				for (var i = 0; i < data.data.length; i++) {
					jsonData['kp' + i]    = {};
					jsonData['kp' + i].kp = data.data[i].kp;

					var time = formatTime(data.data[i].predicted_time);

					jsonData['kp' + i].time = time.time;
					jsonData['kp' + i].date = time.date;
				}

				latestForecast = jsonData;

				saveForecast(latestForecast);

				if(callback)
					callback();
			}
		}).error(function(error) {
			console.log('AURORA: Error: ' + error);
		});
	};

	var getNowData = function(callback) {
		$http.get(apiURL + 'd=n&f=t').success(function(data) {
			if (data.data[0] != 'undefined') {
				latestForecast.now       = Math.ceil(data.data[0].kp);

				var today                = new Date();
				today                    = formatTime(today.getTime()).date;
				latestForecast.dateToday = today;
			}
			else latestForecast.error = "There has been an error getting the 'now' KP value. Please try again later.";

			saveForecast(latestForecast);

			if(callback) {
				callback();
			}
		}).error(function(error) {
			console.log('AURORA: Error: ' + error);
		});
	};

	return {
		updateForecast : function(callback) {
			getForecastData(function() {
				getNowData(function() {
					callback(latestForecast);
				});
			});
		},
		setNow: function(kpNow) {
			if (typeof latestForecast == 'undefined')
				loadForecastFromStorage();

			latestForecast.now = kpNow;
			saveForecast(latestForecast);
		}
	};
})

.factory('$background', function($kpAPI) {
	var backgroundlist = [{
		id: 1,
		url: "img/background-none.jpg"
	}, {
		id: 2,
		url: "img/background-low.jpg"
	}, {
		id: 3,
		url: "img/background-moderate.jpg"
	}, {
		id: 4,
		url: "img/background-high.jpg"
	}];

	return {
		getBackgroundUrl: function(callback) {
	    	$kpAPI.updateForecast(function(forecast) {
	    		var url  = null;
				switch (forecast.now) {
					case 1:
					case 2:
					case 3:
						url = backgroundlist[0].url;
						break;
					case 4:
					case 5:
						url = backgroundlist[1].url;
						break;
					case 6:
					case 7:
						url = backgroundlist[2].url;
						break;
					case 8:
					case 9:
						url = backgroundlist[3].url;
						break;
					default:
						url = backgroundlist[0].url;
						break;
				}

				callback(url);
	    	});
		}
	};
});
<|endoftext|>