<commit_before>/**
 * @license
 * Copyright 2018 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.dao',
  name: 'FileJournal',
  extends: 'foam.dao.AbstractJournal',
  flags: ['java'],

  javaImports: [
    'foam.core.FObject',
    'foam.core.PropertyInfo',
    'foam.core.ProxyX',
    'foam.lib.json.ExprParser',
    'foam.lib.json.JSONParser',
    'foam.lib.json.Outputter',
    'foam.lib.StoragePropertyPredicate',
    'foam.lib.parse.*',
    'foam.nanos.auth.LastModifiedByAware',
    'foam.nanos.auth.User',
    'foam.nanos.fs.Storage',
    'foam.nanos.logger.Logger',
    'foam.nanos.logger.PrefixLogger',
    'foam.nanos.logger.StdoutLogger',
    'foam.util.SafetyUtil',
    'java.io.BufferedReader',
    'java.io.BufferedWriter',
    'java.io.InputStreamReader',
    'java.io.File',
    'java.io.FileReader',
    'java.io.FileWriter',
    'java.text.SimpleDateFormat',
    'java.util.Calendar',
    'java.util.Iterator',
    'java.util.List',
    'java.util.TimeZone',
    'java.util.regex.Pattern'
  ],

  axioms: [
    {
      name: 'javaExtras',
      buildJavaClass: function (cls) {
        cls.extras.push(`
          protected static Pattern COMMENT = Pattern.compile("(/\\\\*([^*]|[\\\\r\\\\n]|(\\\\*+([^*/]|[\\\\r\\\\n])))*\\\\*+/)|(//.*)");

          protected static ThreadLocal<StringBuilder> sb = new ThreadLocal<StringBuilder>() {
            @Override
            protected StringBuilder initialValue() {
              return new StringBuilder();
            }
            @Override
            public StringBuilder get() {
              StringBuilder b = super.get();
              b.setLength(0);
              return b;
            }
          };

          protected static final ThreadLocal<SimpleDateFormat> sdf = new ThreadLocal<SimpleDateFormat>() {
            @Override
            protected SimpleDateFormat initialValue() {
              SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
              sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
              return sdf;
            }
          };
        `);
      }
    }
  ],

  properties: [
    {
      class: 'Object',
      name: 'outputter',
      javaType: 'foam.lib.json.Outputter',
      javaFactory: `return new Outputter(getX()).setPropertyPredicate(new StoragePropertyPredicate());`
    },
    {
      class: 'Object',
      name: 'parser',
      javaType: 'foam.lib.json.JSONParser',
      javaFactory: `return getX().create(JSONParser.class);`
    },
    {
      class: 'Boolean',
      name: 'multiLine',
      value: true
    },
    {
      class: 'foam.dao.DAOProperty',
      name: 'dao'
    },
    {
      class: 'FObjectProperty',
      of: 'foam.nanos.logger.Logger',
      name: 'logger',
      javaFactory: `
        Logger logger = (Logger) getX().get("logger");
        if ( logger == null ) {
          logger = new StdoutLogger();
        }
        return new PrefixLogger(new Object[] { "[JDAO]", getFilename() }, logger);
      `
    },
    {
      class: 'String',
      name: 'filename',
      required: true
    },
    {
      class: 'Boolean',
      name: 'createFile',
      documentation: 'Flag to create file if not present',
      value: true,
    },
    {
      class: 'Object',
      name: 'file',
      javaType: 'java.io.File',
      javaFactory: `
        try {
          getLogger().log("Loading file: " + getFilename());
          File file = getX().get(Storage.class).get(getFilename());
          if ( ! file.exists() ) {
            getLogger().warning("Journal not found:" + getFilename());

            if ( getCreateFile() ) {
              // if output journal does not exist, create one
              File dir = file.getAbsoluteFile().getParentFile();
              if ( ! dir.exists() ) {
                getLogger().log("Create dir: " + dir.getAbsolutePath());
                dir.mkdirs();
              }

              getLogger().log("Create file: " + getFilename());
              file.getAbsoluteFile().createNewFile();
            }
          }
          return file;
        } catch ( Throwable t ) {
          getLogger().error("Failed to read from journal", t);
          throw new RuntimeException(t);
        }
      `
    },
    // reader uses a getter because we want a new reader on file replay
    {
      class: 'Object',
      name: 'reader',
      javaType: 'java.io.BufferedReader',
      javaGetter: `
      try {
        Storage storage = (Storage) getX().get(Storage.class);
        if ( storage.isResource() ) {
          return new BufferedReader(new InputStreamReader(storage.getResourceAsStream(getFilename())));
        } else {
          return new BufferedReader(new FileReader(getFile()));
        }
      } catch ( Throwable t ) {
        getLogger().error("Failed to read from journal", t);
        throw new RuntimeException(t);
      }
      `
    },
    // writer uses a factory because we want to use one writer for the lifetime of this journal object
    {
      class: 'Object',
      name: 'writer',
      javaType: 'java.io.BufferedWriter',
      javaFactory: `
        try {
          BufferedWriter writer = new BufferedWriter(new FileWriter(getFile(), true), 16 * 1024);
          writer.newLine();
          return writer;
        } catch ( Throwable t ) {
          getLogger().error("Failed to create writer", t);
          throw new RuntimeException(t);
        }
      `
    }
  ],

  methods: [
    {
      name: 'put_',
      synchronized: true,
      javaCode: `
        try {
          String record = ( old != null ) ?
            getOutputter().stringifyDelta(old, nu) :
            getOutputter().stringify(nu);

          if ( ! foam.util.SafetyUtil.isEmpty(record) ) {
            writeComment_(x, nu);
            write_(sb.get()
              .append("p(")
              .append(record)
              .append(")")
              .toString());
          }
        } catch ( Throwable t ) {
          getLogger().error("Failed to write put entry to journal", t);
          throw new RuntimeException(t);
        }
      `
    },
    {
      name: 'remove',
      synchronized: true,
      javaCode: `
        try {
          // TODO: Would be more efficient to output the ID portion of the object.  But
          // if ID is an alias or multi part id we should only output the
          // true properties that ID/MultiPartID maps too.
          FObject toWrite = (FObject) obj.getClassInfo().newInstance();
          toWrite.setProperty("id", obj.getProperty("id"));
          String record = getOutputter().stringify(toWrite);

          if ( ! foam.util.SafetyUtil.isEmpty(record) ) {
            writeComment_(x, obj);
            write_(sb.get()
              .append("r(")
              .append(record)
              .append(")")
              .toString());
          }
        } catch ( Throwable t ) {
          getLogger().error("Failed to write remove entry to journal", t);
          throw new RuntimeException(t);
        }
      `
    },
    {
      name: 'write_',
      synchronized: true,
      javaThrows: [
        'java.io.IOException'
      ],
      args: [
        {
          class: 'String',
          name: 'data'
        }
      ],
      javaCode: `
        BufferedWriter writer = getWriter();
        writer.write(data);
        writer.newLine();
        writer.flush();
      `
    },
    {
      name: 'writeComment_',
      synchronized: true,
      javaThrows: [
        'java.io.IOException'
      ],
      args: [
        {
          name: 'x',
          type: 'Context'
        },
        {
          name: 'obj',
          type: 'foam.core.FObject'
        }
      ],
      javaCode: `
        if ( x.get("user") == null || ((User) x.get("user")).getId() <= 1 ) return;
        if ( obj instanceof LastModifiedByAware && ((LastModifiedByAware) obj).getLastModifiedBy() != 0L ) return;

        User user = (User) x.get("user");
        Calendar now = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
        write_(sb.get()
          .append("// Modified by ")
          .append(user.label())
          .append(" (")
          .append(user.getId())
          .append(") at ")
          .append(sdf.get().format(now.getTime()))
          .toString());
      `
    },
    {
      name: 'getEntry',
      documentation: 'retrieves ameaningful unit of text from the journal',
      type: 'String',
      args: [
        {
          name: 'reader',
          type: 'BufferedReader'
        }
      ],
      javaCode: `
        try {
          String line = reader.readLine();
          if ( ! getMultiLine() ) return line;
          if ( line == null ) return null;
          StringBuilder sb = new StringBuilder();
          sb.append(line);
          while( ! line.trim().endsWith("})") ) {
            if ( (line = reader.readLine()) == null ) break;
            sb.append("\\n");
            sb.append(line);
          }
          return sb.toString().trim();
        } catch (Throwable t) {
          getLogger().error("Failed to read from journal", t);
          return null;
        }
      `
    },
    {
      name: 'replay',
      documentation: 'Replays the journal file',
      javaCode: `
        // count number of lines successfully read
        int successReading = 0;
        JSONParser parser = getParser();

        try ( BufferedReader reader = getReader() ) {
          for ( String line ; ( line = getEntry(reader) ) != null ; ) {
            if ( SafetyUtil.isEmpty(line)        ) continue;
            if ( COMMENT.matcher(line).matches() ) continue;

            try {
              char operation = line.charAt(0);
              int length = line.length();
              line = line.substring(2, length - 1);

              FObject obj = parser.parseString(line);
              if ( obj == null ) {
                getLogger().error("Parse error", getParsingErrorMessage(line), "line:", line);
                continue;
              }

              switch ( operation ) {
                case 'p':
                  foam.core.FObject old = dao.find(obj.getProperty("id"));
                  dao.put(old != null ? mergeFObject(old, obj) : obj);
                  break;

                case 'r':
                  dao.remove(obj);
                  break;
              }

              successReading++;
            } catch ( Throwable t ) {
              getLogger().error("Error replaying journal line:", line, t);
            }
          }
        } catch ( Throwable t) {
          getLogger().error("Failed to read from journal", t);
        } finally {
          getLogger().log("Successfully read " + successReading + " entries from file: " + getFilename());
        }
      `
    },
    {
      name: 'getParsingErrorMessage',
      documentation: 'Gets the result of a failed parsing of a journal line',
      type: 'String',
      args: [
        {
          class: 'String',
          name: 'line'
        }
      ],
      javaCode: `
        Parser        parser = new ExprParser();
        PStream       ps     = new StringPStream();
        ParserContext x      = new ParserContextImpl();

        ((StringPStream) ps).setString(line);
        x.set("X", ( getX() == null ) ? new ProxyX() : getX());

        ErrorReportingPStream eps = new ErrorReportingPStream(ps);
        ps = eps.apply(parser, x);
        return eps.getMessage();
      `
    },
    {
      name: 'mergeFObject',
      type: 'foam.core.FObject',
      documentation: 'Add diff property to old property',
      args: [
        {
          name: 'oldFObject',
          type: 'FObject'
        },
        {
          name: 'diffFObject',
          type: 'FObject'
        }
      ],
      javaCode: `
        //get PropertyInfos
        List list = oldFObject.getClassInfo().getAxiomsByClass(PropertyInfo.class);
        Iterator e = list.iterator();

        while( e.hasNext() ) {
          PropertyInfo prop = (PropertyInfo) e.next();
          mergeProperty(oldFObject, diffFObject, prop);
        }
        return oldFObject;
      `
    },
    {
      name: 'mergeProperty',
      args: [
        {
          name: 'oldFObject',
          type: 'FObject'
        },
        {
          name: 'diffFObject',
          type: 'FObject'
        },
        {
          name: 'prop',
          javaType: 'foam.core.PropertyInfo'
        }
      ],
      javaCode: `
        if ( prop.isSet(diffFObject) ) {
          prop.set(oldFObject, prop.get(diffFObject));
        }
      `
    }
  ]
});
<commit_msg>changed some of the semantics of file journal to make various features possible<commit_after>/**
 * @license
 * Copyright 2018 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.dao',
  name: 'FileJournal',
  extends: 'foam.dao.AbstractJournal',
  flags: ['java'],

  javaImports: [
    'foam.core.FObject',
    'foam.core.PropertyInfo',
    'foam.core.ProxyX',
    'foam.lib.json.ExprParser',
    'foam.lib.json.JSONParser',
    'foam.lib.json.Outputter',
    'foam.lib.StoragePropertyPredicate',
    'foam.lib.parse.*',
    'foam.nanos.auth.LastModifiedByAware',
    'foam.nanos.auth.User',
    'foam.nanos.fs.Storage',
    'foam.nanos.logger.Logger',
    'foam.nanos.logger.PrefixLogger',
    'foam.nanos.logger.StdoutLogger',
    'foam.util.SafetyUtil',
    'java.io.BufferedReader',
    'java.io.BufferedWriter',
    'java.io.InputStreamReader',
    'java.io.File',
    'java.io.FileReader',
    'java.io.FileWriter',
    'java.text.SimpleDateFormat',
    'java.util.Calendar',
    'java.util.Iterator',
    'java.util.List',
    'java.util.TimeZone',
    'java.util.regex.Pattern'
  ],

  axioms: [
    {
      name: 'javaExtras',
      buildJavaClass: function (cls) {
        cls.extras.push(`
          protected static Pattern COMMENT = Pattern.compile("(/\\\\*([^*]|[\\\\r\\\\n]|(\\\\*+([^*/]|[\\\\r\\\\n])))*\\\\*+/)|(//.*)");

          protected static ThreadLocal<StringBuilder> sb = new ThreadLocal<StringBuilder>() {
            @Override
            protected StringBuilder initialValue() {
              return new StringBuilder();
            }
            @Override
            public StringBuilder get() {
              StringBuilder b = super.get();
              b.setLength(0);
              return b;
            }
          };

          protected static final ThreadLocal<SimpleDateFormat> sdf = new ThreadLocal<SimpleDateFormat>() {
            @Override
            protected SimpleDateFormat initialValue() {
              SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
              sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
              return sdf;
            }
          };
        `);
      }
    }
  ],

  properties: [
    {
      class: 'Object',
      name: 'outputter',
      javaType: 'foam.lib.json.Outputter',
      javaFactory: `return new Outputter(getX()).setPropertyPredicate(new StoragePropertyPredicate());`
    },
    {
      class: 'Object',
      name: 'parser',
      javaType: 'foam.lib.json.JSONParser',
      javaFactory: `return getX().create(JSONParser.class);`
    },
    {
      class: 'foam.dao.DAOProperty',
      name: 'dao'
    },
    {
      class: 'FObjectProperty',
      of: 'foam.nanos.logger.Logger',
      name: 'logger',
      javaFactory: `
        Logger logger = (Logger) getX().get("logger");
        if ( logger == null ) {
          logger = new StdoutLogger();
        }
        return new PrefixLogger(new Object[] { "[JDAO]", getFilename() }, logger);
      `
    },
    {
      class: 'String',
      name: 'filename',
      required: true
    },
    {
      class: 'Boolean',
      name: 'createFile',
      documentation: 'Flag to create file if not present',
      value: true,
    },
    {
      class: 'Object',
      name: 'file',
      javaType: 'java.io.File',
      javaFactory: `
        try {
          getLogger().log("Loading file: " + getFilename());
          File file = getX().get(Storage.class).get(getFilename());
          if ( ! file.exists() ) {
            getLogger().warning("Journal not found:" + getFilename());

            if ( getCreateFile() ) {
              // if output journal does not exist, create one
              File dir = file.getAbsoluteFile().getParentFile();
              if ( ! dir.exists() ) {
                getLogger().log("Create dir: " + dir.getAbsolutePath());
                dir.mkdirs();
              }

              getLogger().log("Create file: " + getFilename());
              file.getAbsoluteFile().createNewFile();
            }
          }
          return file;
        } catch ( Throwable t ) {
          getLogger().error("Failed to read from journal", t);
          throw new RuntimeException(t);
        }
      `
    },
    // reader uses a getter because we want a new reader on file replay
    {
      class: 'Object',
      name: 'reader',
      javaType: 'java.io.BufferedReader',
      javaGetter: `
      try {
        Storage storage = (Storage) getX().get(Storage.class);
        if ( storage.isResource() ) {
          return new BufferedReader(new InputStreamReader(storage.getResourceAsStream(getFilename())));
        } else {
          return new BufferedReader(new FileReader(getFile()));
        }
      } catch ( Throwable t ) {
        getLogger().error("Failed to read from journal", t);
        throw new RuntimeException(t);
      }
      `
    },
    // writer uses a factory because we want to use one writer for the lifetime of this journal object
    {
      class: 'Object',
      name: 'writer',
      javaType: 'java.io.BufferedWriter',
      javaFactory: `
        try {
          BufferedWriter writer = new BufferedWriter(new FileWriter(getFile(), true), 16 * 1024);
          writer.newLine();
          return writer;
        } catch ( Throwable t ) {
          getLogger().error("Failed to create writer", t);
          throw new RuntimeException(t);
        }
      `
    }
  ],

  methods: [
    {
      name: 'put_',
      synchronized: true,
      javaCode: `
        try {
          String record = ( old != null ) ?
            getOutputter().stringifyDelta(old, nu) :
            getOutputter().stringify(nu);

          if ( ! foam.util.SafetyUtil.isEmpty(record) ) {
            writeComment_(x, nu);
            write_(sb.get()
              .append("p(")
              .append(record)
              .append(")")
              .toString());
          }
        } catch ( Throwable t ) {
          getLogger().error("Failed to write put entry to journal", t);
          throw new RuntimeException(t);
        }
      `
    },
    {
      name: 'remove',
      synchronized: true,
      javaCode: `
        try {
          // TODO: Would be more efficient to output the ID portion of the object.  But
          // if ID is an alias or multi part id we should only output the
          // true properties that ID/MultiPartID maps too.
          FObject toWrite = (FObject) obj.getClassInfo().newInstance();
          toWrite.setProperty("id", obj.getProperty("id"));
          String record = getOutputter().stringify(toWrite);

          if ( ! foam.util.SafetyUtil.isEmpty(record) ) {
            writeComment_(x, obj);
            write_(sb.get()
              .append("r(")
              .append(record)
              .append(")")
              .toString());
          }
        } catch ( Throwable t ) {
          getLogger().error("Failed to write remove entry to journal", t);
          throw new RuntimeException(t);
        }
      `
    },
    {
      name: 'write_',
      synchronized: true,
      javaThrows: [
        'java.io.IOException'
      ],
      args: [
        {
          class: 'String',
          name: 'data'
        }
      ],
      javaCode: `
        BufferedWriter writer = getWriter();
        writer.write(data);
        writer.newLine();
        writer.flush();
      `
    },
    {
      name: 'writeComment_',
      synchronized: true,
      javaThrows: [
        'java.io.IOException'
      ],
      args: [
        {
          name: 'x',
          type: 'Context'
        },
        {
          name: 'obj',
          type: 'foam.core.FObject'
        }
      ],
      javaCode: `
        if ( x.get("user") == null || ((User) x.get("user")).getId() <= 1 ) return;
        if ( obj instanceof LastModifiedByAware && ((LastModifiedByAware) obj).getLastModifiedBy() != 0L ) return;

        User user = (User) x.get("user");
        Calendar now = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
        write_(sb.get()
          .append("// Modified by ")
          .append(user.label())
          .append(" (")
          .append(user.getId())
          .append(") at ")
          .append(sdf.get().format(now.getTime()))
          .toString());
      `
    },
    {
      name: 'getEntry',
      documentation: 'retrieves ameaningful unit of text from the journal',
      type: 'String',
      args: [
        {
          name: 'reader',
          type: 'BufferedReader'
        }
      ],
      javaCode: `
        try {
          String line = reader.readLine();
          if ( ! line.equals("p({") ) return line;
          if ( line == null ) return null;
          StringBuilder sb = new StringBuilder();
          sb.append(line);
          while( ! line.equals("})") ) {
            if ( (line = reader.readLine()) == null ) break;
            sb.append("\\n");
            sb.append(line);
          }
          return sb.toString().trim();
        } catch (Throwable t) {
          getLogger().error("Failed to read from journal", t);
          return null;
        }
      `
    },
    {
      name: 'replay',
      documentation: 'Replays the journal file',
      javaCode: `
        // count number of lines successfully read
        int successReading = 0;
        JSONParser parser = getParser();

        try ( BufferedReader reader = getReader() ) {
          for ( String line ; ( line = getEntry(reader) ) != null ; ) {
            if ( SafetyUtil.isEmpty(line)        ) continue;
            if ( COMMENT.matcher(line).matches() ) continue;

            try {
              char operation = line.charAt(0);
              int length = line.length();
              line = line.substring(2, length - 1);

              FObject obj = parser.parseString(line);
              if ( obj == null ) {
                getLogger().error("Parse error", getParsingErrorMessage(line), "line:", line);
                continue;
              }

              switch ( operation ) {
                case 'p':
                  foam.core.FObject old = dao.find(obj.getProperty("id"));
                  dao.put(old != null ? mergeFObject(old, obj) : obj);
                  break;

                case 'r':
                  dao.remove(obj);
                  break;
              }

              successReading++;
            } catch ( Throwable t ) {
              getLogger().error("Error replaying journal line:", line, t);
            }
          }
        } catch ( Throwable t) {
          getLogger().error("Failed to read from journal", t);
        } finally {
          getLogger().log("Successfully read " + successReading + " entries from file: " + getFilename());
        }
      `
    },
    {
      name: 'getParsingErrorMessage',
      documentation: 'Gets the result of a failed parsing of a journal line',
      type: 'String',
      args: [
        {
          class: 'String',
          name: 'line'
        }
      ],
      javaCode: `
        Parser        parser = new ExprParser();
        PStream       ps     = new StringPStream();
        ParserContext x      = new ParserContextImpl();

        ((StringPStream) ps).setString(line);
        x.set("X", ( getX() == null ) ? new ProxyX() : getX());

        ErrorReportingPStream eps = new ErrorReportingPStream(ps);
        ps = eps.apply(parser, x);
        return eps.getMessage();
      `
    },
    {
      name: 'mergeFObject',
      type: 'foam.core.FObject',
      documentation: 'Add diff property to old property',
      args: [
        {
          name: 'oldFObject',
          type: 'FObject'
        },
        {
          name: 'diffFObject',
          type: 'FObject'
        }
      ],
      javaCode: `
        //get PropertyInfos
        List list = oldFObject.getClassInfo().getAxiomsByClass(PropertyInfo.class);
        Iterator e = list.iterator();

        while( e.hasNext() ) {
          PropertyInfo prop = (PropertyInfo) e.next();
          mergeProperty(oldFObject, diffFObject, prop);
        }
        return oldFObject;
      `
    },
    {
      name: 'mergeProperty',
      args: [
        {
          name: 'oldFObject',
          type: 'FObject'
        },
        {
          name: 'diffFObject',
          type: 'FObject'
        },
        {
          name: 'prop',
          javaType: 'foam.core.PropertyInfo'
        }
      ],
      javaCode: `
        if ( prop.isSet(diffFObject) ) {
          prop.set(oldFObject, prop.get(diffFObject));
        }
      `
    }
  ]
});
<|endoftext|>


<commit_before>app.directive("numberline", function(){
    /* name of directive have to be its name without _  (replaced by "") */
    return {
        restrict: "E",
        scope: {
            data: "=data",              // json data from database
            interface: "=interface"     // interface of loader
        },
        templateUrl: static_url + "simulators/numberline/simulator.html",  // html
        controller: function($scope){

            $scope.selected_number = null;

            $scope.settings = {
                width: 800,
                height: 50,
                offset: 50,
                top: 15,
                hover_size: 30
            };

            // pseudo random range
            var str = "salt"+$scope.data.question;
            var hash = 0, chr;
            for (var i = 0; i < str.length; i++ ){
                chr = str.charCodeAt(i);
                hash  = ((hash << 5) - hash) + chr;
                hash |= 0;
            }
            hash = Math.abs(hash);

            var bound = Math.ceil($scope.data.answer/10)*10;
            if (18 > $scope.data.answer > 7) bound += 10 * (hash % 2);
            if ($scope.data.answer > 17) bound += 10 * (hash % 3);

            $scope.points = [];
            $scope.range = [0, bound];

            $scope.populate_points = function(){
                var line_length = $scope.settings.width - 2 * $scope.settings.offset;
                var delta = line_length / ($scope.range[1] - $scope.range[0]);
                for (var i=$scope.range[0]; i<=$scope.range[1]; i++){
                    var point = {};
                    point.number = $scope.range[0] + i;
                    point.x = $scope.settings.offset + i * delta;
                    point.y = $scope.settings.top;
                    point.r = 3;
                    if (point.number % 5 == 0) point.r = 4;
                    if (point.number % 10 == 0) point.r = 5;
                    point.display = "none";
                    if (i == $scope.range[0] || i == $scope.range[1]) point.display = "block";
                    $scope.points.push(point);
                }
            };

            $scope.select = function(point){
                if ($scope.nokShow || $scope.okShow) return;
                var number = parseInt(point.id.replace("point", ""));
                point = $(point);
                $("g").attr("class", $("g").attr("class").replace(" selected", ""));
                if (number != $scope.selected_number) {
                    $scope.selected_number = number;
                    point.attr("class", point.attr('class')+" selected");
                    $scope.interface.log(number+" selected")
                }else{
                    $scope.selected_number = null;
                    $scope.interface.log("unselected")
                }

                $scope.$apply();

            };

            $scope.check_answer = function(){
                var correct = $scope.selected_number == $scope.data.answer;
                $(".numberline-point text").show();
                $("#point"+$scope.data.answer+" text").css("font-weight", "bold");
                $("#point"+$scope.data.answer+" circle.shadow").css("opacity", 1).css("fill", "green");
                $("#point"+$scope.data.answer+" circle.point").css("fill", "green");
                $scope.okShow = correct;
                $scope.nokShow = !correct;
                $scope.interface.finish(correct, 1500);
            };

            $scope.populate_points();

        }
    }
});
<commit_msg>resizeable number-line<commit_after>app.directive("numberline", function(){
    /* name of directive have to be its name without _  (replaced by "") */
    return {
        restrict: "E",
        scope: {
            data: "=data",              // json data from database
            interface: "=interface"     // interface of loader
        },
        templateUrl: static_url + "simulators/numberline/simulator.html",  // html
        controller: function($scope){

            $scope.selected_number = null;

            $scope.settings = {
                width: $("#playground").width(),
                height: 50,
                offset: 50,
                top: 15,
                hover_size: 30
            };

            // pseudo random range
            var str = "salt"+$scope.data.question;
            var hash = 0, chr;
            for (var i = 0; i < str.length; i++ ){
                chr = str.charCodeAt(i);
                hash  = ((hash << 5) - hash) + chr;
                hash |= 0;
            }
            hash = Math.abs(hash);

            var bound = Math.ceil($scope.data.answer/10)*10;
            if (18 > $scope.data.answer > 7) bound += 10 * (hash % 2);
            if ($scope.data.answer > 17) bound += 10 * (hash % 3);

            $scope.points = [];
            $scope.range = [0, bound];

            $scope.populate_points = function(){
                var line_length = $scope.settings.width - 2 * $scope.settings.offset;
                var delta = line_length / ($scope.range[1] - $scope.range[0]);
                for (var i=$scope.range[0]; i<=$scope.range[1]; i++){
                    var point = {};
                    point.number = $scope.range[0] + i;
                    point.x = $scope.settings.offset + i * delta;
                    point.y = $scope.settings.top;
                    point.r = 3;
                    if (point.number % 5 == 0) point.r = 4;
                    if (point.number % 10 == 0) point.r = 5;
                    point.display = "none";
                    if (i == $scope.range[0] || i == $scope.range[1]) point.display = "block";
                    $scope.points.push(point);
                }
            };

            $scope.select = function(point){
                if ($scope.nokShow || $scope.okShow) return;
                var number = parseInt(point.id.replace("point", ""));
                point = $(point);
                $("g").attr("class", $("g").attr("class").replace(" selected", ""));
                if (number != $scope.selected_number) {
                    $scope.selected_number = number;
                    point.attr("class", point.attr('class')+" selected");
                    $scope.interface.log(number+" selected")
                }else{
                    $scope.selected_number = null;
                    $scope.interface.log("unselected")
                }

                $scope.$apply();

            };

            $scope.check_answer = function(){
                var correct = $scope.selected_number == $scope.data.answer;
                $(".numberline-point text").show();
                $("#point"+$scope.data.answer+" text").css("font-weight", "bold");
                $("#point"+$scope.data.answer+" circle.shadow").css("opacity", 1).css("fill", "green");
                $("#point"+$scope.data.answer+" circle.point").css("fill", "green");
                $scope.okShow = correct;
                $scope.nokShow = !correct;
                $scope.interface.finish(correct, 1500);
            };

            $scope.populate_points();

        }
    }
});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.cron',
  name: 'Cron',
  extends: 'foam.nanos.script.Script',

  imports: [ 'cronDAO as scriptDAO' ],

  javaImports: [
    'foam.dao.DAO',
    'foam.util.SafetyUtil',
    'foam.nanos.notification.Notification',
    'java.util.Date',
    'java.util.Calendar'
  ],

  documentation: 'FOAM class that models a Cron script',

  tableColumns: [
    'id', 'enabled', 'server', 'description', 'lastDuration', 'status', 'run'
  ],

  searchColumns: ['id', 'description'],

  properties: [
    {
      class: 'FObjectProperty',
      of: 'foam.nanos.cron.Schedule',
      name: 'schedule'
    },
    {
      class: 'DateTime',
      name: 'scheduledTime',
      documentation: `Scheduled time to run Cron script.`,
      javaFactory: 'return getNextScheduledTime();'
    },
    {
      class: 'Boolean',
      name: 'enabled',
      value: false
    }
  ],

  methods: [
    {
      name: 'runScript',
      args: [
        {
          name: 'x',
          type: 'Context'
        }
      ],
      type: 'Void',
      javaCode:
`DAO notification = (DAO) x.get("notificationDAO");

Notification cronStartNotify = new Notification();
cronStartNotify.setBody("Cron STARTED - " + this.getId() + " " + this.getDescription());
notification.put(cronStartNotify);

super.runScript(x);

Notification cronEndNotify = new Notification();
cronEndNotify.setBody("Cron ENDED - " + this.getId() + " " + this.getDescription());
notification.put(cronEndNotify);

setScheduledTime(getNextScheduledTime());`
    },
    {
      name: 'getNextScheduledTime',
      type: 'Date',
      javaCode:
`
return getSchedule().getNextScheduledTime(
  new Date(System.currentTimeMillis())
);
`
    }
  ]
});
<commit_msg>Update Cron.js imports<commit_after>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.cron',
  name: 'Cron',
  extends: 'foam.nanos.script.Script',

  imports: [ 'cronDAO as scriptDAO' ],

  javaImports: [
    'foam.dao.DAO',
    'foam.nanos.notification.Notification',
    'foam.util.SafetyUtil',
    'java.util.Date'
  ],

  documentation: 'FOAM class that models a Cron script',

  tableColumns: [
    'id', 'enabled', 'server', 'description', 'lastDuration', 'status', 'run'
  ],

  searchColumns: ['id', 'description'],

  properties: [
    {
      class: 'FObjectProperty',
      of: 'foam.nanos.cron.Schedule',
      name: 'schedule'
    },
    {
      class: 'DateTime',
      name: 'scheduledTime',
      documentation: `Scheduled time to run Cron script.`,
      javaFactory: 'return getNextScheduledTime();'
    },
    {
      class: 'Boolean',
      name: 'enabled',
      value: false
    }
  ],

  methods: [
    {
      name: 'runScript',
      args: [
        {
          name: 'x',
          type: 'Context'
        }
      ],
      type: 'Void',
      javaCode:
`DAO notification = (DAO) x.get("notificationDAO");

Notification cronStartNotify = new Notification();
cronStartNotify.setBody("Cron STARTED - " + this.getId() + " " + this.getDescription());
notification.put(cronStartNotify);

super.runScript(x);

Notification cronEndNotify = new Notification();
cronEndNotify.setBody("Cron ENDED - " + this.getId() + " " + this.getDescription());
notification.put(cronEndNotify);

setScheduledTime(getNextScheduledTime());`
    },
    {
      name: 'getNextScheduledTime',
      type: 'Date',
      javaCode:
`
return getSchedule().getNextScheduledTime(
  new Date(System.currentTimeMillis())
);
`
    }
  ]
});
<|endoftext|>


<commit_before>(function(){

    xtag.register('detector-ZDS', {
        extends: 'detector-template',
        lifecycle: {
            created: function() {
                var URLs = [this.thresholdServer,    //threshold server
                            this.rateServer,             //rate server
                            'http://'+this.MIDAS+'/?cmd=jcopy&odb0=Equipment/&encoding=json-p-nokeys&callback=fetchODBEquipment'];  //ODB Equipment tree

                //deploy the standard stuff
                this.viewNames = ['ZDS'];
                this.channelNames = ['ZDS01XN00X'];

                initializeDetector.bind(this, 'ZDS', 'ZDS')();

                //////////////////////////////////////
                //ZDS specific drawing parameters
                //////////////////////////////////////
                this.x0 = this.width/2;
                this.y0 = 0.4*this.height + this.frameLineWidth;
                this.radius = 0.5*this.y0;

                /////////////////////////////
                //Initialize visualization
                /////////////////////////////
                //generate the color scale
                this.generateColorScale();
                //initialize all the cells:
                this.instantiateCells();
                this.populate();
            },
            inserted: function() {},
            removed: function() {},
            attributeChanged: function() {}
        },
        events: {

        },
        accessors: {
            'MIDAS':{
                attribute: {} //this just needs to be declared
            }
        },
        methods: {
            'instantiateCells': function(){
                var i;

                //ZDS cells
                //each channel listed in this.channelNames gets an entry in this.cells as a Kinetic object:
                for(i=0; i<this.channelNames.length; i++){
                    this.cells[this.channelNames[i]] = new Kinetic.Circle({
                        radius: this.radius,
                        x: this.x0,
                        y: this.y0,
                        fill: '#000000',
                        fillPatternOffsetX: 100*Math.random(),
                        fillPatternOffsetY: 100*Math.random(),
                        stroke: this.frameColor,
                        strokeWidth: this.frameLineWidth,
                        closed: true,
                        listening: true
                    });

                    this.mainLayer[0].add(this.cells[i]);
                }

                //add the layers to the stage
                this.stage[0].add(this.mainLayer[0]);
            },

        }
    });

})();
<commit_msg>ZDS bugs<commit_after>(function(){

    xtag.register('detector-ZDS', {
        extends: 'detector-template',
        lifecycle: {
            created: function() {
                var URLs = [this.thresholdServer,    //threshold server
                            this.rateServer,             //rate server
                            'http://'+this.MIDAS+'/?cmd=jcopy&odb0=Equipment/&encoding=json-p-nokeys&callback=fetchODBEquipment'];  //ODB Equipment tree

                //deploy the standard stuff
                this.viewNames = ['ZDS'];
                this.channelNames = ['ZDS01XN00X'];

                initializeDetector.bind(this, 'ZDS', 'ZDS')();

                //////////////////////////////////////
                //ZDS specific drawing parameters
                //////////////////////////////////////
                this.x0 = this.width/2;
                this.y0 = 0.4*this.height + this.frameLineWidth;
                this.radius = 0.5*this.y0;

                /////////////////////////////
                //Initialize visualization
                /////////////////////////////
                //generate the color scale
                this.generateColorScale();
                //initialize all the cells:
                this.instantiateCells();
                this.populate();
            },
            inserted: function() {},
            removed: function() {},
            attributeChanged: function() {}
        },
        events: {

        },
        accessors: {
            'MIDAS':{
                attribute: {} //this just needs to be declared
            }
        },
        methods: {
            'instantiateCells': function(){
                var i;

                //ZDS cells
                //each channel listed in this.channelNames gets an entry in this.cells as a Kinetic object:
                for(i=0; i<this.channelNames.length; i++){
                    this.cells[this.channelNames[i]] = new Kinetic.Circle({
                        radius: this.radius,
                        x: this.x0,
                        y: this.y0,
                        fill: '#000000',
                        fillPatternOffsetX: 100*Math.random(),
                        fillPatternOffsetY: 100*Math.random(),
                        stroke: this.frameColor,
                        strokeWidth: this.frameLineWidth,
                        closed: true,
                        listening: true
                    });

                    //this.mainLayer[0].add(this.cells[i]);
                }

                //add the layers to the stage
                this.stage[0].add(this.mainLayer[0]);
            },

        }
    });

})();
<|endoftext|>


<commit_before>var fs = require('fs');
var StreamNg = require('../dist/stream-ng.js');
var stream = require('stream');
var out = fs.openSync('./out', 'w');
var out2 = fs.openSync('./out2', 'w');

function testStreamNG(callback) {
  var time = Date.now();

  var writable = new StreamNg.Stream({ objectMode: true, write: (chunk, next) => {
    fs.write(out, chunk, 0, chunk.length, next);
  }});

  writable.then(() => {
    var end = Date.now();
    console.log('StreamNG Done: ' + (end - time) + 'ms');
    setImmediate(callback);
  }).catch((error) => {
    throw error;
  });

  /*
  writable.open(() => {
    console.log('Open');
  }).close(() => {
    console.log('Close');
  }).drain(() => {
    console.log('Drain');
  }).pause(() => {
    console.log('Pause');
  }).resume(() => {
    console.log('Resume');
  });
  */

  for (var index = 0; index < 1024; index++) {
    writable.write(new Buffer(1024 * 10 + index));
  }

  writable.end('Done!');
}

function testStream(callback) {
  var time = Date.now();

  var writable = new stream.Writable({ objectMode: true, write: function(chunk, encoding, next) {
    fs.write(out2, chunk, 0, chunk.length, next);
  }});

  writable.on('finish', function() {
    var end = Date.now();
    console.log('Stream Done: ' + (end - time) + 'ms');
    setImmediate(callback);
  });

  for (var index = 0; index < 1024; index++) {
    writable.write(new Buffer(1024 * 10 + index));
  }

  writable.end();
}

testStream(function() {
  testStreamNG(function() {
    fs.closeSync(out);
    fs.closeSync(out2);
  });
});
<commit_msg>Update compare test<commit_after>var fs = require('fs');
var StreamNg = require('../dist/stream-ng.js');
var stream = require('stream');
var out = fs.openSync('./out', 'w');
var out2 = fs.openSync('./out2', 'w');

function testStreamNG(callback) {
  var time = Date.now();

  var writable = new StreamNg.Stream({ objectMode: true, write: (chunk, next) => {
    fs.write(out, chunk, 0, chunk.length, next);
  }});

  writable.then((arg) => {
    var end = Date.now();
    console.log('StreamNG Done: ' + (end - time) + 'ms');
    setImmediate(callback);
  }).catch((error) => {
    throw error;
  });

  writable.open(() => {
    console.log('Open');
  }).close(() => {
    console.log('Close');
  }).drain(() => {
    console.log('Drain');
  }).pause(() => {
    console.log('Pause');
  }).resume(() => {
    console.log('Resume');
  });

  for (var index = 0; index < 1024; index++) {
    writable.write(new Buffer(1024 * 10 + index));
  }

  writable.end('Done!');
}

function testStream(callback) {
  var time = Date.now();

  var writable = new stream.Writable({ objectMode: true, write: function(chunk, encoding, next) {
    fs.write(out2, chunk, 0, chunk.length, next);
  }});

  writable.on('finish', function() {
    var end = Date.now();
    console.log('Stream Done: ' + (end - time) + 'ms');
    setImmediate(callback);
  });

  for (var index = 0; index < 1024; index++) {
    writable.write(new Buffer(1024 * 10 + index));
  }

  writable.end();
}

testStream(function() {
  testStreamNG(function() {
    fs.closeSync(out);
    fs.closeSync(out2);
  });
});
<|endoftext|>


<commit_before>/*jshint evil:true*/
/*global window, document, $ */
var PhantomJS = require('node-phantom-simple');

function PhantomClient () {
	this.headers = {};
	this.getData = function () {};
	this.listener = function () {};
	this.domTimeout = 5000;
	this.phantomSettings = {
		parameters: {
			'load-images': 'no',
			'ignore-ssl-errors': 'yes'
		}
	};
}
/**
 * Sets an HTTP Proxy
 *
 * @param {string} domain
 *   An http proxy domain
 *   Unsets the proxy if an empty string is provided
 * @param {string} port (optional)
 *   Applies a port number if specified
 * @param {string} username (optional)
 * @param {string} password (optional)
 * @return this - for chaining
 */
PhantomClient.prototype.setProxy = function (domain, port, username, password) {
	if (domain) {
		this.phantomSettings.parameters.proxy = domain;
		this.phantomSettings.parameters.proxy += port ? ':' + port : '';
		if (username) {
			this.phantomSettings.parameters['proxy-auth'] = username;
		  this.phantomSettings.parameters['proxy-auth'] += typeof password === 'string' ? ':' + password : '';
	  }
	}
	else {
		delete this.phantomSettings.parameters.proxy;
	}
	return this;
};
/**
 * Sets if we should check SSL certs are valid
 *
 * @param
 */
PhantomClient.prototype.setStrictSSL = function (strictSSL) {
	this.requestSettings['ignore-ssl-errors'] = strictSSL ? 'no' : 'yes';
	return this;
};
/**
 * Sets HTTP Headers
 *
 * @param {object} headers
 *   HTTP Headers provided with header names as object keys
 * @return this - for chaining
 */
PhantomClient.prototype.setHeaders = function (headers) {
	this.headers = headers;
	return this;
};
/**
 * Sets HTTP Headers
 *
 * @param {string} name - HTTP Header Name
 * @param {string} value - HTTP Header Value
 * @return this - for chaining
 */
PhantomClient.prototype.setHeader = function (name, val) {
	this.headers[name] = val;
	return this;
};
/**
 * Sets PhantomJS options
 *
 * @see http://phantomjs.org/api/command-line.html
 * @param {string} name - PhantomJS Command Line Option Name
 * @param {string} value - PhantomJS Command Line Option Value
 * @return this - for chaining
 */
PhantomClient.prototype.setClient = function (name, val) {
	this.phantomSettings.parameters[name] = val;
	return this;
};
/**
 * Sets a listening function for all events
 * Note: unlike traditional listeners, this may only have one listener function
 *
 * @param {function} listener
 *   Called when an event is fired
 * @return this - for chaining
 */
PhantomClient.prototype.setListener = function (listener) {
	this.emit = listener;
	return this;
};
/**
 * Placeholder event listener
 * Just in case a listener is not set
 *
 * @param {string} eventName - name of the event to fire
 * @param {…string|object} data - arguments from event
 * @return this - for chaining
 */
PhantomClient.prototype.emit = function (eventName) {
	console.log(eventName, arguments);
};
/**
 * Instantiates a PhantomJS Client
 *   Will re-insantiate Phantom if called again
 */
PhantomClient.prototype.init = function () {
	var thisClient = this;
	if (thisClient.phantom) {
		this.phantom.exit();
		this.phantom = null;
	}
	PhantomJS.create(function(err, phantom) {
		if (err || !phantom) {
			return thisClient.emit('error', 'phantom.create', err);
		}
		thisClient.phantom = phantom;
		thisClient.isReady = true;
		thisClient._get();
	}, this.phantomSettings);
	thisClient.isInitialized = true;
};
/**
 * Retreive a web page
 *
 * @param {string} uri
 *   The URI to request
 * @param {function} getData
 *   Called called once the uri has been reached
 *   Will be passed jQuery, the page uri and the window object
 */
PhantomClient.prototype.get = function (uri, getData) {
	this.uri = uri || this.uri;
	this.getData = getData || this.getData;
	if (!this.isReady && !this.isInitialized) {
		this.init();
	}
	else if (this.isReady) {
		this._get();
	}
	// Else you asked for something while PhantomJS process is starting.
	// We'll just ignore you for now.
	return this;
};
/**
 * Actually, retreive a web page. In the previous function we are delayed,
 * waiting for PhantomJS to startup.  Now, we actually retreive the page.
 */
PhantomClient.prototype._get = function () {
	var thisClient = this;
	var clientFunction = new Function([
		'var $ = window.$PhantomClient;',
		'var uri = ' + JSON.stringify(this.uri) + ';',
		'var getData = ' + this.getData.toString() + ';',
		'var data = getData.call(this, $, uri, window);',
		'return data;',
	].join("\n"));
	// Tell PhantomJS to start a new session (browser window)
	this.phantom.createPage(function(err, page) {
		if (err || !page) {
			return thisClient.emit('error', 'phatom.createPage', err, page);
		}
		thisClient.page = page;
		thisClient.emit('request', thisClient.uri);
		// Tell PhantomJS to open a web page uri
		return page.open(thisClient.uri, function(err, status) {
			if (err || status !== "success") {
				return thisClient.emit('error', 'phatom.page.open', err, status);
			}
			// Tell PhantomJS to inject jQuery script on the page
			page.includeJs('//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js', function (err) {
				if (err) {
					return thisClient.emit('error', 'phatom.page.includeJs', err);
				}
				// Tell PhantomJS to set a variable once the DOM is loaded.
				thisClient.clientEval(function () {
					window.$PhantomClient = $.noConflict();
					window.$PhantomClient(document).ready(function(){
						window.PhantomClientReady = true;
					});
				});
				waitFor(
					// Keep checking the web page DOM for the variabe to be true
					function (onDone) {
						thisClient.clientEval(function () {
							return window.PhantomClientReady;
						}, function (result) {
							if (result === true) {
								onDone();
							}
						});
					},
					// Now that it's true, call the provided getData function
					function(){
						thisClient.clientEval(clientFunction, function (data) {
							thisClient.emit('data', data, thisClient.uri);
						});
					},
					// Taking too long, just bail out
					function(){
						thisClient.emit('error', 'DOM timeout');
					},
					thisClient.domTimeout
				);
			});
		});
	});
};
/**
 * Tell the PhantomJS process to call a function
 *
 * @param {function} clientFn
 *   Called on client web page DOM
 * @param {function} onSuccess
 *   Called once clientFn returns
 */
PhantomClient.prototype.clientEval = function (clientFn, onSuccess) {
	var thisClient = this;
	if (!onSuccess) {
		onSuccess = function () {};
	}
	thisClient.page.evaluate(clientFn, function (err, result) {
		if (err) {
			thisClient.emit('error', 'EVAL', err);
		}
		else if (onSuccess) {
			onSuccess(result);
		}
	});
};
/**
 * Kills the underlying PhantomJS process
 */
PhantomClient.prototype.destroy = function () {
	if (this.phantom) {
		this.phantom.exit();
		this.phantom = null;
	}
};
/**
 * From https://github.com/ariya/phantomjs/blob/master/examples/waitfor.js
 *
 * Wait until the test condition is true or a timeout occurs. Useful for waiting
 * on a server response or for a ui change (fadeIn, etc.) to occur.
 *
 * @param {function} testCondition
 *   Evaluates to a boolean, true if we are ready
 * @param {function} onReady
 *   Called when testCondition condition is fulfilled
 * @param {function} onTimeout
 *   Called when testCondition has not been fullfilled, and time exceeds timeout
 * @param {int} (optional) timeout
 *   Max amout of time, in milliseconds to wait, default 3000ms
 * @param {int} (optional) attemptFrequency
 *   Time, in milliseconds, to wait before attempting again, default 250ms
 */
function waitFor (testCondition, onReady, onTimeout, timeout, attemptFrequency) {
	// Default Max Timout is 3s
	// {int} How frequently to check back in.
	var start = Date.now();
	var success = false;
	var isTimedOut = false;
	attemptFrequency = attemptFrequency || 250;
	timeout = timeout || 3000;
	var interval = setInterval(function() {
		var now = Date.now();
		var sinceStart = now - start;
		// If we've achieved success, then fantastic - stop the loop
		if (success) {
			clearInterval(interval);
		}
		// Check if we've timed out, in which case, bail
		else if ( sinceStart >= timeout ) {
			clearInterval(interval);
			isTimedOut = true;
			onTimeout();
		}
		// If not fulfilled, but we've got time on the clock, then retest
		else {
			testCondition(readyCallback);
		}
	}, attemptFrequency);

	function readyCallback () {
		if (!isTimedOut) {
			success = true;
			clearInterval(interval);
			onReady();
		}
	}
}

module.exports = PhantomClient;
<commit_msg>Fix errors when using Phantom client<commit_after>/*jshint evil:true*/
/*global window, document, $ */
var PhantomJS = require('node-phantom-simple');

function PhantomClient () {
	this.headers = {};
	this.getData = function () {};
	this.listener = function () {};
	this.domTimeout = 5000;
	this.phantomSettings = {
		parameters: {
			'load-images': 'no',
			'ignore-ssl-errors': 'yes'
		}
	};
}
/**
 * Sets an HTTP Proxy
 *
 * @param {string} domain
 *   An http proxy domain
 *   Unsets the proxy if an empty string is provided
 * @param {string} port (optional)
 *   Applies a port number if specified
 * @param {string} username (optional)
 * @param {string} password (optional)
 * @return this - for chaining
 */
PhantomClient.prototype.setProxy = function (domain, port, username, password) {
	if (domain) {
		this.phantomSettings.parameters.proxy = domain;
		this.phantomSettings.parameters.proxy += port ? ':' + port : '';
		if (username) {
			this.phantomSettings.parameters['proxy-auth'] = username;
		  this.phantomSettings.parameters['proxy-auth'] += typeof password === 'string' ? ':' + password : '';
	  }
	}
	else {
		delete this.phantomSettings.parameters.proxy;
	}
	return this;
};
/**
 * Sets if we should check SSL certs are valid
 *
 * @param
 */
PhantomClient.prototype.setStrictSSL = function (strictSSL) {
	this.phantomSettings.parameters['ignore-ssl-errors'] = strictSSL ? 'no' : 'yes';
	return this;
};
/**
 * Sets HTTP Headers
 *
 * @param {object} headers
 *   HTTP Headers provided with header names as object keys
 * @return this - for chaining
 */
PhantomClient.prototype.setHeaders = function (headers) {
	this.headers = headers;
	return this;
};
/**
 * Sets HTTP Headers
 *
 * @param {string} name - HTTP Header Name
 * @param {string} value - HTTP Header Value
 * @return this - for chaining
 */
PhantomClient.prototype.setHeader = function (name, val) {
	this.headers[name] = val;
	return this;
};
/**
 * Sets PhantomJS options
 *
 * @see http://phantomjs.org/api/command-line.html
 * @param {string} name - PhantomJS Command Line Option Name
 * @param {string} value - PhantomJS Command Line Option Value
 * @return this - for chaining
 */
PhantomClient.prototype.setClient = function (name, val) {
	this.phantomSettings.parameters[name] = val;
	return this;
};
/**
 * Sets a listening function for all events
 * Note: unlike traditional listeners, this may only have one listener function
 *
 * @param {function} listener
 *   Called when an event is fired
 * @return this - for chaining
 */
PhantomClient.prototype.setListener = function (listener) {
	this.emit = listener;
	return this;
};
/**
 * Placeholder event listener
 * Just in case a listener is not set
 *
 * @param {string} eventName - name of the event to fire
 * @param {…string|object} data - arguments from event
 * @return this - for chaining
 */
PhantomClient.prototype.emit = function (eventName) {
	console.log(eventName, arguments);
};
/**
 * Instantiates a PhantomJS Client
 *   Will re-insantiate Phantom if called again
 */
PhantomClient.prototype.init = function () {
	var thisClient = this;
	if (thisClient.phantom) {
		this.phantom.exit();
		this.phantom = null;
	}
	PhantomJS.create(function(err, phantom) {
		if (err || !phantom) {
			return thisClient.emit('error', 'phantom.create', err);
		}
		thisClient.phantom = phantom;
		thisClient.isReady = true;
		thisClient._get();
	}, this.phantomSettings);
	thisClient.isInitialized = true;
};
/**
 * Retreive a web page
 *
 * @param {string} uri
 *   The URI to request
 * @param {function} getData
 *   Called called once the uri has been reached
 *   Will be passed jQuery, the page uri and the window object
 */
PhantomClient.prototype.get = function (uri, getData) {
	this.uri = uri || this.uri;
	this.getData = getData || this.getData;
	if (!this.isReady && !this.isInitialized) {
		this.init();
	}
	else if (this.isReady) {
		this._get();
	}
	// Else you asked for something while PhantomJS process is starting.
	// We'll just ignore you for now.
	return this;
};
/**
 * Actually, retreive a web page. In the previous function we are delayed,
 * waiting for PhantomJS to startup.  Now, we actually retreive the page.
 */
PhantomClient.prototype._get = function () {
	var thisClient = this;
	var clientFunction = new Function([
		'var $ = window.$PhantomClient;',
		'var uri = ' + JSON.stringify(this.uri) + ';',
		'var getData = ' + this.getData.toString() + ';',
		'var data = getData.call(this, $, uri, window);',
		'return data;',
	].join("\n"));
	// Tell PhantomJS to start a new session (browser window)
	this.phantom.createPage(function(err, page) {
		if (err || !page) {
			return thisClient.emit('error', 'phatom.createPage', err, page);
		}
		thisClient.page = page;
		thisClient.emit('request', thisClient.uri);
		// Tell PhantomJS to open a web page uri
		return page.open(thisClient.uri, function(err, status) {
			if (err || status !== "success") {
				return thisClient.emit('error', 'phatom.page.open', err, status);
			}
			// Tell PhantomJS to inject jQuery script on the page
			page.includeJs('//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js', function (err) {
				if (err) {
					return thisClient.emit('error', 'phatom.page.includeJs', err);
				}
				// Tell PhantomJS to set a variable once the DOM is loaded.
				thisClient.clientEval(function () {
					window.$PhantomClient = $.noConflict();
					window.$PhantomClient(document).ready(function(){
						window.PhantomClientReady = true;
					});
				});
				waitFor(
					// Keep checking the web page DOM for the variabe to be true
					function (onDone) {
						thisClient.clientEval(function () {
							return window.PhantomClientReady;
						}, function (result) {
							if (result === true) {
								onDone();
							}
						});
					},
					// Now that it's true, call the provided getData function
					function(){
						thisClient.clientEval(clientFunction, function (data) {
							thisClient.emit('data', data, thisClient.uri);
						});
					},
					// Taking too long, just bail out
					function(){
						thisClient.emit('error', 'DOM timeout');
					},
					thisClient.domTimeout
				);
			});
		});
	});
};
/**
 * Tell the PhantomJS process to call a function
 *
 * @param {function} clientFn
 *   Called on client web page DOM
 * @param {function} onSuccess
 *   Called once clientFn returns
 */
PhantomClient.prototype.clientEval = function (clientFn, onSuccess) {
	var thisClient = this;
	if (!onSuccess) {
		onSuccess = function () {};
	}
	thisClient.page.evaluate(clientFn, function (err, result) {
		if (err) {
			thisClient.emit('error', 'EVAL', err);
		}
		else if (onSuccess) {
			onSuccess(result);
		}
	});
};
/**
 * Kills the underlying PhantomJS process
 */
PhantomClient.prototype.destroy = function () {
	if (this.phantom) {
		this.phantom.exit();
		this.phantom = null;
	}
};
/**
 * From https://github.com/ariya/phantomjs/blob/master/examples/waitfor.js
 *
 * Wait until the test condition is true or a timeout occurs. Useful for waiting
 * on a server response or for a ui change (fadeIn, etc.) to occur.
 *
 * @param {function} testCondition
 *   Evaluates to a boolean, true if we are ready
 * @param {function} onReady
 *   Called when testCondition condition is fulfilled
 * @param {function} onTimeout
 *   Called when testCondition has not been fullfilled, and time exceeds timeout
 * @param {int} (optional) timeout
 *   Max amout of time, in milliseconds to wait, default 3000ms
 * @param {int} (optional) attemptFrequency
 *   Time, in milliseconds, to wait before attempting again, default 250ms
 */
function waitFor (testCondition, onReady, onTimeout, timeout, attemptFrequency) {
	// Default Max Timout is 3s
	// {int} How frequently to check back in.
	var start = Date.now();
	var success = false;
	var isTimedOut = false;
	attemptFrequency = attemptFrequency || 250;
	timeout = timeout || 3000;
	var interval = setInterval(function() {
		var now = Date.now();
		var sinceStart = now - start;
		// If we've achieved success, then fantastic - stop the loop
		if (success) {
			clearInterval(interval);
		}
		// Check if we've timed out, in which case, bail
		else if ( sinceStart >= timeout ) {
			clearInterval(interval);
			isTimedOut = true;
			onTimeout();
		}
		// If not fulfilled, but we've got time on the clock, then retest
		else {
			testCondition(readyCallback);
		}
	}, attemptFrequency);

	function readyCallback () {
		if (!isTimedOut) {
			success = true;
			clearInterval(interval);
			onReady();
		}
	}
}

module.exports = PhantomClient;
<|endoftext|>


<commit_before>//Organizations.js: Client for the zendesk API.

var util        = require('util'),
    Client      = require('./client').Client,
    defaultgroups = require('./helpers').defaultgroups;

var Organizations = exports.Organizations = function (options) {
  this.jsonAPINames = [ 'organizations', 'organization' ];
  Client.call(this, options);
};

// Inherit from Client base object
util.inherits(Organizations, Client);

// ######################################################## Organizations
// ====================================== Listing Organizations
Organizations.prototype.list = function (cb) {
  this.requestAll('GET', ['organizations'], cb);//all
};

// ====================================== Viewing Organizations

Organizations.prototype.show = function (organizationID, cb) {
  this.request('GET', ['organizations', organizationID], cb);
};

// ====================================== Creating Organizations
Organizations.prototype.create = function (organization, cb) {
  this.request('POST', ['organizations'], organization, cb);
};

// ====================================== Updating Organizations

Organizations.prototype.update = function (organizationID, organization, cb) {
  this.request('PUT', ['organizations', organizationID], organization, cb);
};

// ====================================== Deleting Organizations
Organizations.prototype.delete = function (organizationID, cb) {
  this.request('DELETE', ['organizations', organizationID],  cb);
};

// ====================================== Search Organizations
Organizations.prototype.search = function (params, cb) {
  this.requestAll('GET', ['organizations', 'search', params], cb);
};

// ====================================== Autocomplete Organizations
Organizations.prototype.autocomplete = function (params, cb) {
  this.requestAll('GET', ['organizations', 'autocomplete', params], cb);
};

//  ====================================== New Incremental Organization Export with include
Organizations.prototype.incrementalInclude = function (startTime, include, cb) {
  this.request('GET', ['incremental', 'organizations', {start_time: startTime, include: include}],  cb);
};

//  ====================================== New Incremental Organization Export
Organizations.prototype.incremental = function (startTime, cb) {
  this.request('GET', ['incremental', 'organizations', {start_time: startTime}],  cb);
};
//  ====================================== New Incremental Organization Export Sample
Organizations.prototype.incrementalSample = function (startTime, cb) {
  this.request('GET', ['incremental', 'organizations', 'sample', {start_time: startTime}],  cb);
};

<commit_msg>Add support for organizations.createOrUpdate<commit_after>//Organizations.js: Client for the zendesk API.

var util        = require('util'),
    Client      = require('./client').Client,
    defaultgroups = require('./helpers').defaultgroups;

var Organizations = exports.Organizations = function (options) {
  this.jsonAPINames = [ 'organizations', 'organization' ];
  Client.call(this, options);
};

// Inherit from Client base object
util.inherits(Organizations, Client);

// ######################################################## Organizations
// ====================================== Listing Organizations
Organizations.prototype.list = function (cb) {
  this.requestAll('GET', ['organizations'], cb);//all
};

// ====================================== Viewing Organizations

Organizations.prototype.show = function (organizationID, cb) {
  this.request('GET', ['organizations', organizationID], cb);
};

// ====================================== Creating Organizations
Organizations.prototype.create = function (organization, cb) {
  this.request('POST', ['organizations'], organization, cb);
};

// ====================================== Creating Or Updating Organizations
Organizations.prototype.createOrUpdate = function (organization, cb) {
  this.request('POST', ['organizations', 'create_or_update'], organization, cb);
};

// ====================================== Updating Organizations

Organizations.prototype.update = function (organizationID, organization, cb) {
  this.request('PUT', ['organizations', organizationID], organization, cb);
};

// ====================================== Deleting Organizations
Organizations.prototype.delete = function (organizationID, cb) {
  this.request('DELETE', ['organizations', organizationID],  cb);
};

// ====================================== Search Organizations
Organizations.prototype.search = function (params, cb) {
  this.requestAll('GET', ['organizations', 'search', params], cb);
};

// ====================================== Autocomplete Organizations
Organizations.prototype.autocomplete = function (params, cb) {
  this.requestAll('GET', ['organizations', 'autocomplete', params], cb);
};

//  ====================================== New Incremental Organization Export with include
Organizations.prototype.incrementalInclude = function (startTime, include, cb) {
  this.request('GET', ['incremental', 'organizations', {start_time: startTime, include: include}],  cb);
};

//  ====================================== New Incremental Organization Export
Organizations.prototype.incremental = function (startTime, cb) {
  this.request('GET', ['incremental', 'organizations', {start_time: startTime}],  cb);
};
//  ====================================== New Incremental Organization Export Sample
Organizations.prototype.incrementalSample = function (startTime, cb) {
  this.request('GET', ['incremental', 'organizations', 'sample', {start_time: startTime}],  cb);
};

<|endoftext|>


<commit_before>'use strict';
const fs = require("fs");
const utils = require("../../../utils/utils.js");
const async = require("async");
const infraColname = 'infra';

function checkIfError(soajs, mainCb, data, cb) {
	utils.checkErrorReturn(soajs, mainCb, data, cb);
}

var BL = {
	model: null,

	/**
	 * Scale a deployed service (SOAJS content or custom)
	 *
	 * @param  {Object}   config
	 * @param  {Object}   soajs
	 * @param  {Object}   deployer
	 * @param  {Function} cbMain
	 */
	"scaleService": function (config, soajs, deployer, cbMain) {
		async.auto({
			"getEnvironment": (mCb) => {
				utils.getEnvironment(soajs, BL.model, soajs.inputmaskData.env.toUpperCase(), (error, envRecord) => {
					checkIfError(soajs, mCb, {config: config, error: error || !envRecord, code: 600}, () => {
						return mCb(null, envRecord);
					});
				});
			},
			"callDeployer": ["getEnvironment", (info, mCb) => {
				let options = utils.buildDeployerOptions(info.getEnvironment, soajs, BL, null);
				options.params = {
					id: soajs.inputmaskData.serviceId,
					scale: soajs.inputmaskData.scale
				};
				deployer.execute({
					'type': 'container',
					'driver': options.strategy
				}, 'scaleService', options, (error) => {
					checkIfError(soajs, mCb, {config: config, error: error}, mCb);
				});
			}]
		}, (error) => {
			checkIfError(soajs, cbMain, {config: config, error: error, code: (error) ? error.code : 600}, function () {
				return cbMain(null, true); //  @mike, plz confirm
			});
		});
	},

	/**
	 * Delete a deployed service (SOAJS content or custom)
	 * @param  {Object}   config
	 * @param  {Object}   req
	 * @param  {Object}   deployer
	 * @param  {Function} cbMain
	 */
	"deleteService": function (config, req, deployer, cbMain) {
		async.auto({
			"getEnvironment": (mCb) => {
				utils.getEnvironment(req.soajs, BL.model, req.soajs.inputmaskData.env.toUpperCase(), (error, envRecord) => {
					checkIfError(req.soajs, mCb, {config: config, error: error || !envRecord, code: 600}, () => {
						return mCb(null, envRecord);
					});
				});
			},
			"getInfra": ["getEnvironment", (results, mCb) => {
				checkIfError(soajs, mCb, {
					config: config,
					error: !result.getEnvironment.restriction || !Object.keys(results.getEnvironment.restriction).length > 0,
					code: 520
				}, () => {
					soajs.inputmaskData.id = Object.keys(results.getEnvironment.restriction)[0];
					BL.model.validateId(req.soajs, (err) => {
						checkIfError(req.soajs, mCb, {config: config, error: err, code: 490}, () => {
							let opts = {
								collection: infraColname,
								conditions: {
									_id: req.soajs.inputmaskData.id
								}
							};
							BL.model.findEntry(req.soajs, opts, function (err, infraRecord) {
								checkIfError(req.soajs, mCb, {config: config, error: err, code: 600}, () => {
									checkIfError(req.soajs, mCb, {
										config: config,
										error: !infraRecord,
										code: 600
									}, () => {
										return mCb(null, infraRecord);
									});
								});
							});
						});
					});
				});
			}],
			"callDeployer": ["getEnvironment", "getInfra", (info, mCb) => {
				let options = utils.buildDeployerOptions(info.getEnvironment, req.soajs, BL);
				options.infra = info.getInfra;
				//need to supply the stack if infra has more than drivers

				let infraInfo = utils.getDeploymentFromInfra(options.infra, info.getEnvironment.code);
				options.infra.info = infraInfo;
				let technology = req.soajs.inputmaskData.technology || options.strategy;
				checkIfError(req.soajs, mCb, {
					config: config,
					error: technology !== "vm" && !options.infra.stack && (!infraInfo || !Array.isArray(infraInfo) || infraInfo.length === 0),
					code: 497
				}, () => {
					let infraId = Object.keys(info.getEnvironment.restriction)[0];
					checkIfError(soajs, cbMain, {
						config: config,
						error: technology === "vm" && (!info.getEnvironment.restriction[infraId]
							|| !Object.keys(info.getEnvironment.restriction[infraId]).length > 0
							|| !info.getEnvironment.restriction[infraId][Object.keys(result.getEnvironment.restriction[infraId])[0]]),
						code: 520
					}, () => {
						options.infra.stack = infraInfo ? infraInfo[0] : null;
						let region = Object.keys(info.getEnvironment.restriction[infraId])[0]
						options.params = {
							id: req.soajs.inputmaskData.serviceId,
							mode: req.soajs.inputmaskData.mode,
							group: info.getEnvironment.restriction[infraId][region].group,
							region: region
						};

						deployer.execute({
							'type': 'infra',
							'driver': info.getInfra.name,
							'technology': technology
						}, 'deleteService', options, (error) => {
							if (error) {
								req.soajs.log.error(error);
							}
							else {
								//once service is deleted, if options.infra contains a stack entry
								if (options.infra.stack) {
									delete options.infra.stack;
									delete options.infra.info;
									BL.model.saveEntry(req.soajs, {
										collection: 'infra',
										record: options.infra
									}, (error) => {
										if (error) {
											req.soajs.log.error(error);
										}
									});
								}
							}
						});
						return mCb();
					});
				});
			}]
		}, (error) => {
			if (error) {
				req.soajs.log.error(error);
			}
			checkIfError(req.soajs, cbMain, {
				config: config,
				error: error,
				code: (error) ? error.code : 600
			}, function () {
				return cbMain(null, true);
			});
		});
	},

	/**
	 * Check if resource is deployed
	 * @param  {Object}   config
	 * @param  {Object}   soajs
	 * @param  {Object}   deployer
	 * @param  {Function} cbMain
	 *
	 */
	"checkResource": function (config, soajs, deployer, cbMain) {
		let deployed = false;
		async.auto({
			"getEnvironment": (mCb) => {
				utils.getEnvironment(soajs, BL.model, soajs.inputmaskData.env.toUpperCase(), (error, envRecord) => {
					checkIfError(soajs, mCb, {config: config, error: error || !envRecord, code: 600}, () => {
						return mCb(null, envRecord);
					});
				});
			},
			"callDeployer": ["getEnvironment", (info, mCb) => {
				let options = utils.buildDeployerOptions(info.getEnvironment, soajs, BL);
				options.params = {
					id: soajs.inputmaskData.serviceId,
					scale: soajs.inputmaskData.scale
				};
				deployer.execute({
					'type': 'container',
					'driver': options.strategy
				}, 'listKubeServices', options, (error, services) => {
					checkIfError(soajs, mCb, {config: config, error: error}, () => {
						async.detect(services, (oneService, callback) => {
							return callback(null, oneService && oneService.metadata && oneService.metadata.name === soajs.inputmaskData.resource && oneService.metadata.namespace === soajs.inputmaskData.namespace);
						}, (error, service) => {
							//no error to be handled
							deployed = !!(service && Object.keys(service).length > 0);
							return mCb(null, true);
						});
					});
				});
			}]
		}, (error) => {
			checkIfError(soajs, cbMain, {config: config, error: error, code: (error) ? error.code : 600}, () => {
				return cbMain(null, {"deployed": deployed});
			});
		});
	},

	/**
	 * List all deployed services from cluster, SOAJS content + custom deployments/services
	 *
	 * @param  {Object}   config
	 * @param  {Object}   soajs
	 * @param  {Object}   deployer
	 * @param  {Function} cbMain
	 */
	"listServices": function (config, soajs, deployer, cbMain) {
		async.auto({
			"getEnvironment": (mCb) => {
				utils.getEnvironment(soajs, BL.model, soajs.inputmaskData.env.toUpperCase(), (error, envRecord) => {
					checkIfError(soajs, mCb, {config: config, error: error || !envRecord, code: 600}, () => {
						return mCb(null, envRecord);
					});
				});
			},
			"getInfra": (mCb) => {
				let opts = {
					collection: infraColname,
					conditions: {
						"deployments.environments": {"$in": [soajs.inputmaskData.env.toUpperCase()]}
					}
				};
				BL.model.findEntry(soajs, opts, function (err, infraRecord) {
					checkIfError(soajs, mCb, {config: config, error: err}, () => {
						checkIfError(soajs, mCb, {config: config, error: !infraRecord, code: 600}, () => {
							return mCb(null, infraRecord);
						});
					});
				});
			},
			"callDeployer": ["getEnvironment", "getInfra", (info, mCb) => {
				let options = utils.buildDeployerOptions(info.getEnvironment, soajs, BL);
				options.infra = info.getInfra;
				//need to supply the stack if infra has more than drivers
				options.infra.stack = utils.getDeploymentFromInfra(options.infra, info.getEnvironment.code)[0];

				async.series({
					"getEnvServices": (vCb) => {
						options.params = {env: soajs.inputmaskData.env.toLowerCase()};
						deployer.execute({
							'type': 'infra',
							'driver': info.getInfra.name,
							'technology': options.strategy
						}, 'listServices', options, vCb);
					},
					"getCustomServices": (vCb) => {
						options.params = {custom: true};
						deployer.execute({
							'type': 'infra',
							'driver': info.getInfra.name,
							'technology': options.strategy
						}, 'listServices', options, vCb);
					}
				}, mCb);
			}]
		}, (error, results) => {
			checkIfError(soajs, cbMain, {config: config, error: error}, () => {
				let services = results.callDeployer.getEnvServices;
				let customServices = results.callDeployer.getCustomServices;

				if (!services) services = [];
				if (customServices && customServices.length > 0) {
					services = services.concat(customServices);
				}

				let blackList = config.HA.blacklist;
				if (soajs.servicesConfig && soajs.servicesConfig.dashboard && soajs.servicesConfig.dashboard.HA && soajs.servicesConfig.dashboard.HA.blacklist) {
					blackList = soajs.servicesConfig.dashboard.HA.blacklist;
				}
				services.forEach(function (oneService) {
					if (oneService.env) {
						for (let e = 0; e < oneService.env.length; e++) {
							let envName = oneService.env[e].split("=")[0];
							if (blackList.indexOf(envName.toLowerCase()) !== -1) {
								oneService.env[e] = envName + "=******************";
							}
						}
					}
				});

				return cbMain(null, services);
			});
		});
	}
};

module.exports = {
	"init": function (modelName, cb) {
		var modelPath;

		if (!modelName) {
			return cb(new Error("No Model Requested!"));
		}

		modelPath = __dirname + "/../../../models/" + modelName + ".js";
		return requireModel(modelPath, cb);

		/**
		 * checks if model file exists, requires it and returns it.
		 * @param filePath
		 * @param cb
		 */
		function requireModel(filePath, cb) {
			//check if file exist. if not return error
			fs.exists(filePath, function (exists) {
				if (!exists) {
					return cb(new Error("Requested Model Not Found!"));
				}

				BL.model = require(filePath);
				return cb(null, BL);
			});
		}
	}
};
<commit_msg>fixed syntax errors<commit_after>'use strict';
const fs = require("fs");
const utils = require("../../../utils/utils.js");
const async = require("async");
const infraColname = 'infra';

function checkIfError(soajs, mainCb, data, cb) {
	utils.checkErrorReturn(soajs, mainCb, data, cb);
}

var BL = {
	model: null,

	/**
	 * Scale a deployed service (SOAJS content or custom)
	 *
	 * @param  {Object}   config
	 * @param  {Object}   soajs
	 * @param  {Object}   deployer
	 * @param  {Function} cbMain
	 */
	"scaleService": function (config, soajs, deployer, cbMain) {
		async.auto({
			"getEnvironment": (mCb) => {
				utils.getEnvironment(soajs, BL.model, soajs.inputmaskData.env.toUpperCase(), (error, envRecord) => {
					checkIfError(soajs, mCb, {config: config, error: error || !envRecord, code: 600}, () => {
						return mCb(null, envRecord);
					});
				});
			},
			"callDeployer": ["getEnvironment", (info, mCb) => {
				let options = utils.buildDeployerOptions(info.getEnvironment, soajs, BL, null);
				options.params = {
					id: soajs.inputmaskData.serviceId,
					scale: soajs.inputmaskData.scale
				};
				deployer.execute({
					'type': 'container',
					'driver': options.strategy
				}, 'scaleService', options, (error) => {
					checkIfError(soajs, mCb, {config: config, error: error}, mCb);
				});
			}]
		}, (error) => {
			checkIfError(soajs, cbMain, {config: config, error: error, code: (error) ? error.code : 600}, function () {
				return cbMain(null, true); //  @mike, plz confirm
			});
		});
	},

	/**
	 * Delete a deployed service (SOAJS content or custom)
	 * @param  {Object}   config
	 * @param  {Object}   req
	 * @param  {Object}   deployer
	 * @param  {Function} cbMain
	 */
	"deleteService": function (config, req, deployer, cbMain) {
		async.auto({
			"getEnvironment": (mCb) => {
				utils.getEnvironment(req.soajs, BL.model, req.soajs.inputmaskData.env.toUpperCase(), (error, envRecord) => {
					checkIfError(req.soajs, mCb, {config: config, error: error || !envRecord, code: 600}, () => {
						return mCb(null, envRecord);
					});
				});
			},
			"getInfra": ["getEnvironment", (results, mCb) => {
				checkIfError(req.soajs, mCb, {
					config: config,
					error: !results.getEnvironment.restriction || !Object.keys(results.getEnvironment.restriction).length > 0,
					code: 520
				}, () => {
					req.soajs.inputmaskData.id = Object.keys(results.getEnvironment.restriction)[0];
					BL.model.validateId(req.soajs, (err) => {
						checkIfError(req.soajs, mCb, {config: config, error: err, code: 490}, () => {
							let opts = {
								collection: infraColname,
								conditions: {
									_id: req.soajs.inputmaskData.id
								}
							};
							BL.model.findEntry(req.soajs, opts, function (err, infraRecord) {
								checkIfError(req.soajs, mCb, {config: config, error: err, code: 600}, () => {
									checkIfError(req.soajs, mCb, {
										config: config,
										error: !infraRecord,
										code: 600
									}, () => {
										return mCb(null, infraRecord);
									});
								});
							});
						});
					});
				});
			}],
			"callDeployer": ["getEnvironment", "getInfra", (info, mCb) => {
				let options = utils.buildDeployerOptions(info.getEnvironment, req.soajs, BL);
				options.infra = info.getInfra;
				//need to supply the stack if infra has more than drivers

				let infraInfo = utils.getDeploymentFromInfra(options.infra, info.getEnvironment.code);
				options.infra.info = infraInfo;
				let technology = req.soajs.inputmaskData.technology || options.strategy;
				checkIfError(req.soajs, mCb, {
					config: config,
					error: technology !== "vm" && !options.infra.stack && (!infraInfo || !Array.isArray(infraInfo) || infraInfo.length === 0),
					code: 497
				}, () => {
					let infraId = Object.keys(info.getEnvironment.restriction)[0];
					checkIfError(soajs, cbMain, {
						config: config,
						error: technology === "vm" && (!info.getEnvironment.restriction[infraId]
							|| !Object.keys(info.getEnvironment.restriction[infraId]).length > 0
							|| !info.getEnvironment.restriction[infraId][Object.keys(result.getEnvironment.restriction[infraId])[0]]),
						code: 520
					}, () => {
						options.infra.stack = infraInfo ? infraInfo[0] : null;
						let region = Object.keys(info.getEnvironment.restriction[infraId])[0]
						options.params = {
							id: req.soajs.inputmaskData.serviceId,
							mode: req.soajs.inputmaskData.mode,
							group: info.getEnvironment.restriction[infraId][region].group,
							region: region
						};

						deployer.execute({
							'type': 'infra',
							'driver': info.getInfra.name,
							'technology': technology
						}, 'deleteService', options, (error) => {
							if (error) {
								req.soajs.log.error(error);
							}
							else {
								//once service is deleted, if options.infra contains a stack entry
								if (options.infra.stack) {
									delete options.infra.stack;
									delete options.infra.info;
									BL.model.saveEntry(req.soajs, {
										collection: 'infra',
										record: options.infra
									}, (error) => {
										if (error) {
											req.soajs.log.error(error);
										}
									});
								}
							}
						});
						return mCb();
					});
				});
			}]
		}, (error) => {
			if (error) {
				req.soajs.log.error(error);
			}
			checkIfError(req.soajs, cbMain, {
				config: config,
				error: error,
				code: (error) ? error.code : 600
			}, function () {
				return cbMain(null, true);
			});
		});
	},

	/**
	 * Check if resource is deployed
	 * @param  {Object}   config
	 * @param  {Object}   soajs
	 * @param  {Object}   deployer
	 * @param  {Function} cbMain
	 *
	 */
	"checkResource": function (config, soajs, deployer, cbMain) {
		let deployed = false;
		async.auto({
			"getEnvironment": (mCb) => {
				utils.getEnvironment(soajs, BL.model, soajs.inputmaskData.env.toUpperCase(), (error, envRecord) => {
					checkIfError(soajs, mCb, {config: config, error: error || !envRecord, code: 600}, () => {
						return mCb(null, envRecord);
					});
				});
			},
			"callDeployer": ["getEnvironment", (info, mCb) => {
				let options = utils.buildDeployerOptions(info.getEnvironment, soajs, BL);
				options.params = {
					id: soajs.inputmaskData.serviceId,
					scale: soajs.inputmaskData.scale
				};
				deployer.execute({
					'type': 'container',
					'driver': options.strategy
				}, 'listKubeServices', options, (error, services) => {
					checkIfError(soajs, mCb, {config: config, error: error}, () => {
						async.detect(services, (oneService, callback) => {
							return callback(null, oneService && oneService.metadata && oneService.metadata.name === soajs.inputmaskData.resource && oneService.metadata.namespace === soajs.inputmaskData.namespace);
						}, (error, service) => {
							//no error to be handled
							deployed = !!(service && Object.keys(service).length > 0);
							return mCb(null, true);
						});
					});
				});
			}]
		}, (error) => {
			checkIfError(soajs, cbMain, {config: config, error: error, code: (error) ? error.code : 600}, () => {
				return cbMain(null, {"deployed": deployed});
			});
		});
	},

	/**
	 * List all deployed services from cluster, SOAJS content + custom deployments/services
	 *
	 * @param  {Object}   config
	 * @param  {Object}   soajs
	 * @param  {Object}   deployer
	 * @param  {Function} cbMain
	 */
	"listServices": function (config, soajs, deployer, cbMain) {
		async.auto({
			"getEnvironment": (mCb) => {
				utils.getEnvironment(soajs, BL.model, soajs.inputmaskData.env.toUpperCase(), (error, envRecord) => {
					checkIfError(soajs, mCb, {config: config, error: error || !envRecord, code: 600}, () => {
						return mCb(null, envRecord);
					});
				});
			},
			"getInfra": (mCb) => {
				let opts = {
					collection: infraColname,
					conditions: {
						"deployments.environments": {"$in": [soajs.inputmaskData.env.toUpperCase()]}
					}
				};
				BL.model.findEntry(soajs, opts, function (err, infraRecord) {
					checkIfError(soajs, mCb, {config: config, error: err}, () => {
						checkIfError(soajs, mCb, {config: config, error: !infraRecord, code: 600}, () => {
							return mCb(null, infraRecord);
						});
					});
				});
			},
			"callDeployer": ["getEnvironment", "getInfra", (info, mCb) => {
				let options = utils.buildDeployerOptions(info.getEnvironment, soajs, BL);
				options.infra = info.getInfra;
				//need to supply the stack if infra has more than drivers
				options.infra.stack = utils.getDeploymentFromInfra(options.infra, info.getEnvironment.code)[0];

				async.series({
					"getEnvServices": (vCb) => {
						options.params = {env: soajs.inputmaskData.env.toLowerCase()};
						deployer.execute({
							'type': 'infra',
							'driver': info.getInfra.name,
							'technology': options.strategy
						}, 'listServices', options, vCb);
					},
					"getCustomServices": (vCb) => {
						options.params = {custom: true};
						deployer.execute({
							'type': 'infra',
							'driver': info.getInfra.name,
							'technology': options.strategy
						}, 'listServices', options, vCb);
					}
				}, mCb);
			}]
		}, (error, results) => {
			checkIfError(soajs, cbMain, {config: config, error: error}, () => {
				let services = results.callDeployer.getEnvServices;
				let customServices = results.callDeployer.getCustomServices;

				if (!services) services = [];
				if (customServices && customServices.length > 0) {
					services = services.concat(customServices);
				}

				let blackList = config.HA.blacklist;
				if (soajs.servicesConfig && soajs.servicesConfig.dashboard && soajs.servicesConfig.dashboard.HA && soajs.servicesConfig.dashboard.HA.blacklist) {
					blackList = soajs.servicesConfig.dashboard.HA.blacklist;
				}
				services.forEach(function (oneService) {
					if (oneService.env) {
						for (let e = 0; e < oneService.env.length; e++) {
							let envName = oneService.env[e].split("=")[0];
							if (blackList.indexOf(envName.toLowerCase()) !== -1) {
								oneService.env[e] = envName + "=******************";
							}
						}
					}
				});

				return cbMain(null, services);
			});
		});
	}
};

module.exports = {
	"init": function (modelName, cb) {
		var modelPath;

		if (!modelName) {
			return cb(new Error("No Model Requested!"));
		}

		modelPath = __dirname + "/../../../models/" + modelName + ".js";
		return requireModel(modelPath, cb);

		/**
		 * checks if model file exists, requires it and returns it.
		 * @param filePath
		 * @param cb
		 */
		function requireModel(filePath, cb) {
			//check if file exist. if not return error
			fs.exists(filePath, function (exists) {
				if (!exists) {
					return cb(new Error("Requested Model Not Found!"));
				}

				BL.model = require(filePath);
				return cb(null, BL);
			});
		}
	}
};
<|endoftext|>


<commit_before>// Daniele Tabellini @fupete © 2017 MIT License
// P5js retrieve data from Google Spreadsheets/JSON | Firenze, IT | 4.2017
// Educational purpose, made for DSII2017 lab @UniRSM

// example inspired on Gist https://gist.github.com/claytical/6a929f14964c867e07d8 by @claytical

// link del doc google spreasheets, deve essere pubblico su web,
// va copiato la parte di indice nell'url nel formato sotto:
// https://spreadsheets.google.com/feeds/list/
// + KEY_URL + /od6/public/values?alt=json
//

var url = "https://spreadsheets.google.com/feeds/list/1yhy6cM59YdNsU22tNpWQHGkziLC7EzlMl_vcjFE4lJo/od6/public/values?alt=json";

 // array per contenere i dati/oggetto
var dati = [];

function setup() {
  pixelDensity(displayDensity());
  createCanvas(windowWidth, windowHeight);

  // richiedi i dati formato JSON e poi chiama la funzione gotSpreadsheet
  loadJSON(url, gotSpreadsheet);
  //print("ciao");
  colorMode(HSB);
  rectMode(CENTER);
} // setup()

function draw() {
  // piccolo loop per verificare di avere i dati,
  // stampa su schermo cerchi con i colori presenti nel google doc
  background(0,0,21);
  var padding = width/(dati.length+1);
  for (var i = 0; i < dati.length; i++) {
    fill(dati[i].hue,dati[i].saturation,dati[i].brightness,dati[i].alpha/100);
    if (dati[i].forma == "quadrato") {
      rect(padding + i * padding, height/2, padding*1.2,padding*1.2);
    } else if (dati[i].forma == "cerchio") {
      ellipse(padding + i * padding, height/2, padding*1.2,padding*1.2);
    }
    noStroke();
    fill(255);
    textAlign(LEFT, CENTER);
    text(dati[i].colore, padding + (i * padding),height/3);
  }
} // draw()

function gotSpreadsheet(colori) {
  println(colori.feed.entry.length); // < debug, numero righe della tabella
  for (var i = 0; i < colori.feed.entry.length; i++) {
    // costruzione dell'oggetto singolo, la riga
    var colore = {
                  // dati, nomi delle colonne, i parametri
                  "colore": colori.feed.entry[i].gsx$colore.$t,
                  "hue": colori.feed.entry[i].gsx$hue.$t,
                  "saturation": colori.feed.entry[i].gsx$saturation.$t,
                  "brightness": colori.feed.entry[i].gsx$brightness.$t,
                  "alpha": colori.feed.entry[i].gsx$alpha.$t,
                  "forma": colori.feed.entry[i].gsx$forma.$t
              }
              println(colore); // < debug, verifica oggetto 1x1
    dati.push(colore); // < inserimento nell'array del dato
  }
} // gotSpreadsheet(colori)

// se ridimensiona la finestra ricalcola width e height canvas
function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
}
<commit_msg>Update sketch.js<commit_after>// Daniele Tabellini @fupete © 2017 MIT License
// P5js retrieve data from Google Spreadsheets/JSON | Firenze, IT | 4.2017
// Educational purpose, made for DSII2017 lab @UniRSM

// example inspired on Gist https://gist.github.com/claytical/6a929f14964c867e07d8 by @claytical

// link del doc google spreasheets, deve essere pubblico su web,
// va copiato la parte di indice nell'url nel formato sotto:
// https://spreadsheets.google.com/feeds/list/
// + KEY_URL + /od6/public/values?alt=json
//

var url = "https://docs.google.com/spreadsheets/d/1CXyV9zoplZxuiSkvL5GO7Ktr35S3yz_5u6fpCIzPdCM/pubhtml";

 // array per contenere i dati/oggetto
var dati = [];

function setup() {
  pixelDensity(displayDensity());
  createCanvas(windowWidth, windowHeight);

  // richiedi i dati formato JSON e poi chiama la funzione gotSpreadsheet
  loadJSON(url, gotSpreadsheet);
  //print("ciao");
  colorMode(HSB);
  rectMode(CENTER);
} // setup()

function draw() {
  // piccolo loop per verificare di avere i dati,
  // stampa su schermo cerchi con i colori presenti nel google doc
  background(0,0,21);
  var padding = width/(dati.length+1);
  for (var i = 0; i < dati.length; i++) {
    fill(dati[i].hue,dati[i].saturation,dati[i].brightness,dati[i].alpha/100);
    if (dati[i].forma == "quadrato") {
      rect(padding + i * padding, height/2, padding*1.2,padding*1.2);
    } else if (dati[i].forma == "cerchio") {
      ellipse(padding + i * padding, height/2, padding*1.2,padding*1.2);
    }
    noStroke();
    fill(255);
    textAlign(LEFT, CENTER);
    text(dati[i].colore, padding + (i * padding),height/3);
  }
} // draw()

function gotSpreadsheet(colori) {
  println(colori.feed.entry.length); // < debug, numero righe della tabella
  for (var i = 0; i < colori.feed.entry.length; i++) {
    // costruzione dell'oggetto singolo, la riga
    var colore = {
                  // dati, nomi delle colonne, i parametri
                  "colore": colori.feed.entry[i].gsx$colore.$t,
                  "hue": colori.feed.entry[i].gsx$hue.$t,
                  "saturation": colori.feed.entry[i].gsx$saturation.$t,
                  "brightness": colori.feed.entry[i].gsx$brightness.$t,
                  "alpha": colori.feed.entry[i].gsx$alpha.$t,
                  "forma": colori.feed.entry[i].gsx$forma.$t
              }
              println(colore); // < debug, verifica oggetto 1x1
    dati.push(colore); // < inserimento nell'array del dato
  }
} // gotSpreadsheet(colori)

// se ridimensiona la finestra ricalcola width e height canvas
function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
}
<|endoftext|>