<commit_before>/**
 * A REST HTTP Calls output plugin
 *
 * (c) 2014 Edouard Lafargue, ed@lafargue.name
 * All rights reserved.
 */

var querystring = require('querystring'),
    utils = require('../utils.js'),
    dbs = require('../pouch-config'),
    http = require('http');

module.exports = function rest() {

    var mappings = null;
    var settings = null;
    var post_options = {};
    var regexpath = "";
    var regexargs = "";
    var output_ref = null;

    var matchTempl = function(str, args) {
        return str.replace(/<%=(.*?)%>/g, function(match, field) {
            return args[field] || match;
        });
    }

    var decompUrl = function(str) {
        if (str == undefined)
            return false;
        // Straight from RFC 3986 Appendix B
        var decomp = str.match(/(([^:/?#]+):\/\/([^/?#]*))?(([^?#]*)(\?([^#]*))?(#(.*))?)/);
        return {
            proto: decomp[2],
            host: decomp[3],
            path: decomp[5],
            args: decomp[7],
            ref: decomp[9]
        }
    }

    // Load the settings for this plugin
    this.setup = function(output) {

        console.log("[REST Output plugin] Setup a new instance");
        mappings = output.mappings;
        settings = output.metadata;
        output_ref = output;

        // Prepare the post options:
        post_options = {
            host: decompUrl(settings.resturl).host,
            port: 80,
            method: (settings.httprequest == "get") ? 'GET':'POST',
            // we don't set path here because it is templated
            headers: {
                'X-Datalogger': 'wizkers.io server-mode REST plugin'
            }
        };

        // We test on "!= get" because settings.httprequest can be empty and we want to default
        // to POST
        if (settings.httprequest != "get")
            post_options['headers']['Content-Type'] = 'application/x-www-form-urlencoded';

        regexpath = decompUrl(settings.resturl).path;
        regexargs = decompUrl(settings.resturl).args;

    };

    this.resolveMapping = function(key,data) {
        var m = mappings[key];
        if (typeof m == 'undefined')
            return undefined;
        // Static mappings start with "__"
        if (m.indexOf("__")==0)
            return m.substr(2);
        return utils.JSONflatten(data)[mappings[key]];
    };

    this.sendData = function(data) {
        var self = this;
        var post_data = '';

        console.log("[REST Output plugin] Send data");

        // Step one: prepare the structure
        var fields = {};
        for (var mapping in mappings) {
            fields[mapping] = self.resolveMapping(mapping, data);
        };

        post_options.path = matchTempl(regexpath, fields);
        if (regexargs != undefined)
            post_data = matchTempl(regexargs, fields);

        // If we do a GET, aggregate the path and post_data
        if (post_options.method == "GET") {
            post_options.path = post_options.path + '?' + post_data;
        }

        output_ref.last = new Date().getTime();
        var post_request = http.request(post_options, function(res) {
            var err = true;
            console.log("[REST Output Plugin] REST Request result");
            // this is the xmlhttprequest
            switch (res.statusCode) {
                    case 0:  // Cannot connect
                        output_ref.lastmessage = 'Cannot connect to host';
                        break;
                    case 200:
                    case 201: // success
                        output_ref.lastsuccess = new Date().getTime();
                        err = false;
                        break;
                    default:
                        break;
            }
            // self.trigger('outputTriggered', { 'name': 'rest', 'error': err, 'message': this.statusText } );
            dbs.outputs.get(output_ref._id, function(err,result) {
                output_ref._rev = result._rev;
                dbs.outputs.put(output_ref, function(err,result) {
                });
            });
            output_ref.save();
            res.on('data', function(data) {
                console.log("API Request result");
                console.log(data);
                output_ref.lastmessage = data;
                dbs.outputs.get(output_ref._id, function(err,result) {
                    output_ref._rev = result._rev;
                    dbs.outputs.put(output_ref, function(err,result) {
                });
            });
            });

        });
        if (post_options.method == 'POST') {
            post_request.write(post_data);
        }
        post_request.end();
    };

};

<commit_msg>Bugfix rest output<commit_after>/**
 * A REST HTTP Calls output plugin
 *
 * (c) 2014 Edouard Lafargue, ed@lafargue.name
 * All rights reserved.
 */

var querystring = require('querystring'),
    utils = require('../utils.js'),
    dbs = require('../pouch-config'),
    http = require('http');

module.exports = function rest() {

    var mappings = null;
    var settings = null;
    var post_options = {};
    var regexpath = "";
    var regexargs = "";
    var output_ref = null;

    var matchTempl = function(str, args) {
        return str.replace(/<%=(.*?)%>/g, function(match, field) {
            return args[field] || match;
        });
    }

    var decompUrl = function(str) {
        if (str == undefined)
            return false;
        // Straight from RFC 3986 Appendix B
        var decomp = str.match(/(([^:/?#]+):\/\/([^/?#]*))?(([^?#]*)(\?([^#]*))?(#(.*))?)/);
        return {
            proto: decomp[2],
            host: decomp[3],
            path: decomp[5],
            args: decomp[7],
            ref: decomp[9]
        }
    }

    // Load the settings for this plugin
    this.setup = function(output) {

        console.log("[REST Output plugin] Setup a new instance");
        mappings = output.mappings;
        settings = output.metadata;
        output_ref = output;

        // Prepare the post options:
        post_options = {
            host: decompUrl(settings.resturl).host,
            port: 80,
            method: (settings.httprequest == "get") ? 'GET':'POST',
            // we don't set path here because it is templated
            headers: {
                'X-Datalogger': 'wizkers.io server-mode REST plugin'
            }
        };

        // We test on "!= get" because settings.httprequest can be empty and we want to default
        // to POST
        if (settings.httprequest != "get")
            post_options['headers']['Content-Type'] = 'application/x-www-form-urlencoded';

        regexpath = decompUrl(settings.resturl).path;
        regexargs = decompUrl(settings.resturl).args;

    };

    this.resolveMapping = function(key,data) {
        var m = mappings[key];
        if (typeof m == 'undefined')
            return undefined;
        // Static mappings start with "__"
        if (m.indexOf("__")==0)
            return m.substr(2);
        return utils.JSONflatten(data)[mappings[key]];
    };

    this.sendData = function(data) {
        var self = this;
        var post_data = '';

        console.log("[REST Output plugin] Send data");

        // Step one: prepare the structure
        var fields = {};
        for (var mapping in mappings) {
            fields[mapping] = self.resolveMapping(mapping, data);
        };

        post_options.path = matchTempl(regexpath, fields);
        if (regexargs != undefined)
            post_data = matchTempl(regexargs, fields);

        // If we do a GET, aggregate the path and post_data
        if (post_options.method == "GET") {
            post_options.path = post_options.path + '?' + post_data;
        }

        output_ref.last = new Date().getTime();
        var post_request = http.request(post_options, function(res) {
            var err = true;
            console.log("[REST Output Plugin] REST Request result");
            // this is the xmlhttprequest
            switch (res.statusCode) {
                    case 0:  // Cannot connect
                        output_ref.lastmessage = 'Cannot connect to host';
                        break;
                    case 200:
                    case 201: // success
                        output_ref.lastsuccess = new Date().getTime();
                        err = false;
                        break;
                    default:
                        break;
            }
            // self.trigger('outputTriggered', { 'name': 'rest', 'error': err, 'message': this.statusText } );
            dbs.outputs.get(output_ref._id, function(err,result) {
                output_ref._rev = result._rev;
                dbs.outputs.put(output_ref, function(err,result) {
                });
            });

            res.on('data', function(data) {
                console.log("API Request result");
                console.log(data);
                output_ref.lastmessage = data;
                dbs.outputs.get(output_ref._id, function(err,result) {
                    output_ref._rev = result._rev;
                    dbs.outputs.put(output_ref, function(err,result) {
                });
            });
            });

        });
        if (post_options.method == 'POST') {
            post_request.write(post_data);
        }
        post_request.end();
    };

};

<|endoftext|>


<commit_before>$(function() {

    if(localStorage.getItem('__alert_updete_0.0.4') == undefined) {
        alert("Seu Unicesumar Extend foi atualizado para nova versao, 0.0.4 com sucesso!. \n\n\n Agora a sua frenquencia é mostrado na tabela junto com as notas!\n\n\n Unicesumar Extend criado por Rafael Dantas");
        localStorage.setItem('__alert_updete_0.0.4', true);
    }

    // Coleção que ira receber as notas de todas as materias
    var entityCollection = [];

    // Define a media anual para cada bimestre.
    var mediaTotal = {
        bin1: 0,
        bin2: 0,
        bin3: 0,
        bin4: 0
    };

    // Tabela das notas (a quarta!)
    var $table = $("table:eq(3)");
    // Percorre todas as colunas, cada coluna é um bimestre
    $table.find('tr:gt(0)').each(function(k, j) {

        // Cria um objeto vazio para gravar as notas dessa materia
        var entity = {};
        $tr = $(this);

        // Salva o nome da materia
        entity.name = $tr.find("td:eq(0)").text();
        // Salva o elemento da materia
        entity.element = $(this);

            // helper para obter a nota a partir da coluna (caso - trasforma em undefined).
        var getNote = function(position) {
            return ($tr.find('td:eq('+ position +')').text() != '-') ? parseFloat($tr.find('td:eq('+ position +')').text()) : undefined;
        };

        entity.notes = {
            bin1: {
                element: $tr.find('td:eq(1)'), // Elemento
                note: getNote(1) // A nota
            },
            subBin1: {
                element: $tr.find('td:eq(3)'),
                note: getNote(3)
            },
            bin2: {
                element: $tr.find('td:eq(2)'),
                note: getNote(2)
            },
            subBin2: {
                element: $tr.find('td:eq(4)'),
                note: getNote(4)
            },
            bin3: {
                element: $tr.find('td:eq(5)'),
                note: getNote(5)
            },
            subBin3: {
                element: $tr.find('td:eq(7)'),
                note: getNote(7)
            },
            bin4: {
                element: $tr.find('td:eq(6)'),
                note: getNote(6)
            },
            subBin4: {
                element: $tr.find('td:eq(8)'),
                note: getNote(8)
            }
        };

        // Adiciona essa materia na collection
        entityCollection.push(entity);
    });

    // Funcao calcula e determina a media de cada materia, adicionando na coluna
    function determineMedia(entity, total, notes) {
        var result = total - 24.0; // Calcula o quanto falta para media
        var divide = (notes > 0) ? notes : 0; // Define o divisor
        var toPass = result / ( 4 - divide ); // Divide o divisor pelo que falta, para definir quantos falta passar em cada bimestre
        var color = (toPass > 0) ? 'green' : 'red'; // Define uma cor, verde para exesso ou vermelho para falta.

        if(Math.abs(toPass) > 10.0 && toPass < 0) {  // Verifica se absoluto é maior que cem e a nota é negativa
            entity.element.css('background', '#F75D59'); // Descata a linha de vermelho
            color = 'white';
        } else if(toPass > 0) {  // Verifica se a nota é positiva
            entity.element.css('background', '#59E817'); // Destaca a linha de verde
            color = 'black';
        }

        var entity = entity.notes; // Helper :)

        toPass = Math.abs(toPass).toFixed(1); // Transforma o numero em absoluto e com uma casa decimal
        var changeNote = function(bin) {
            entity[bin].element.html(toPass).css('color', color);   // helper
        };

        subBin1 = entity.subBin1.note;
        subBin2 = entity.subBin2.note;
        if(notes > 2 && notes < 4) { // Se esta no terceiro bimestre, calcular o que precisa para sub
            if(subBin1 !== undefined && subBin2 !== undefined) { // se ja nao definido
                alert("Ainda não calcula o valor que você precisa para sub, em breve!");
            }
        }

        subBin3 = entity.subBin3.note;
        subBin4 = entity.subBin4.note;
        if(notes >= 4) { // Se esta no quarto bimestre, define os valores da sub
            if(subBin3 !== undefined && subBin4 !== undefined) {
                alert("Ainda não calcula o valor que você precisa para sub, em breve!");
            }
        }

        for(i=notes+1;i<4;i++) {
            changeNote( "bin" + i ); // usa o helper para todos os bimestre
        }
    }
    // Adiciona o titulo de media final
    $table.find('tr:eq(0)').append("TOTAL	");
    $table.find('tr:eq(0)').append("FREQUENCIAS	");

    // percorre todas as notas
    $.each(entityCollection, function(index, value) {
       var bin1 = value.notes.bin1.note;
       var bin2 = value.notes.bin2.note;
       var subBin1 = value.notes.subBin1.note;
       var subBin2 = value.notes.subBin2.note;

       var bin3 = value.notes.bin3.note;
       var bin4 = value.notes.bin4.note;
       var subBin3 = value.notes.subBin3.note;
       var subBin4 = value.notes.subBin4.note;

       var total, notes;

       // Trocar a nota do bin pela sub
       if(bin2 !== undefined) {
           if(subBin1 !== undefined) {
               if(subBin1 > bin1) bin1 = subBin1;
           }

           if(subBin2 !== undefined) {
               if(subBin2 > bin2) bin2 = subBin2;
           }
       }

       if(bin4 !== undefined) {
           if(subBin3 !== undefined) {
               if(subBin3 > bin3) bin3 = subBin3;
           }

           if(subBin4 !== undefined) {
               if(subBin4 > bin4) bin4 = subBin4;
           }
       }

       if(bin1 == undefined) {
          total = 0;
          notes = 0;
       } else if(bin2 == undefined) {
          total = bin1;
          notes = 1;
      } else if(bin3 == undefined) {
          total = bin1 + bin2;
          notes = 2;
       } else if(bin4 == undefined) {
          total = bin1 + bin2 + bin3;
          notes = 3;
       }  else {
          total = bin1 + bin2 + bin3 + bin4;
          notes = 4;
       }

       // Define os total das medias depois que ja trocou as subs pelos os bins :)
       mediaTotal.bin1 += (bin1 !== undefined) ? bin1 : 0;
       mediaTotal.bin2 += (bin2 !== undefined) ? bin2 : 0;
       mediaTotal.bin3 += (bin1 !== undefined) ? bin3 : 0;
       mediaTotal.bin4 += (bin1 !== undefined) ? bin4 : 0;

       determineMedia(value, total, notes);

       // Add media total da materia
       var $totalMedias = value.element.find('td:eq(-1)');
       var htmlAppend = $totalMedias.text(total).clone();
       value.element.append(htmlAppend);
       var $frequencia = value.element.find('td:eq(-1)'); // Adicionado no append em cima, modificou os indexs dos elementos no DOM
       obterFrequencia(value, $frequencia);

    });

    // Adiciona a coluna de media do bimistre
    var lastTableHtml = $table.find('tr').last().clone();
    $table.append( lastTableHtml );
    var lastTable = $table.find('tr').last();
    lastTable.hide();

    lastTable.css('background', 'rgba(63, 135, 193, 0.41)');

    var setColumnText = function(column, text) {
        lastTable.find('td:eq('+ column +')').text(text);
    };

    setColumnText(0, "Media total das materias");
    if(mediaTotal.bin1 !== undefined) setColumnText(1, (mediaTotal.bin1 / (entityCollection.length - 1) ).toFixed(1) );
    if(mediaTotal.bin2 !== undefined) setColumnText(2, (mediaTotal.bin2 / (entityCollection.length - 1) ).toFixed(1) );
    if(mediaTotal.bin3 !== undefined) setColumnText(5, (mediaTotal.bin3 / (entityCollection.length - 1) ).toFixed(1) );
    if(mediaTotal.bin4 !== undefined) setColumnText(6, (mediaTotal.bin4 / (entityCollection.length - 1) ).toFixed(1) );
    setColumnText(3, '-');
    setColumnText(4, '-');
    setColumnText(7, '-');
    setColumnText(8, '-');
    setColumnText(9, '-');
    setColumnText(10, '-');

    lastTable.fadeIn(500);

    $table.append('

Unicesumar Extend - Extesão não oficial, criado por Rafael Dantas (rafael@webdantas.com.br)
 Código no github
');

    function obterFrequencia(entity, element) {
        element.text("Carregando...").css('background', 'white');
        var cod = entity.name.split('-');
        cod = $.trim( cod[ cod.length - 1 ] );

        $.ajax({
            url: "ti_resumo_aulas.asp",
            method: "GET",
            data: {
                disc: cod
            },
            success: function(data) {
                $buffer = $( data );

                var $tr = $buffer.find('.disciplina tr:eq(-1) td');
                var allow = $tr.first().text();
                var total = $tr.last().text();

                if(total == 0) total = '0';
                if(total.length == 1) total = '0' + total;

                element.text( total + '/' + allow  );
                $buffer.remove();
            },
            error: function() {
                element.text("FALHA");
            }
        });
    }

});
<commit_msg>correção aplicar estilo para nota total com 24.0<commit_after>$(function() {

    if(localStorage.getItem('__alert_updete_0.0.4') == undefined) {
        alert("Seu Unicesumar Extend foi atualizado para nova versao, 0.0.4 com sucesso!. \n\n\n Agora a sua frenquencia é mostrado na tabela junto com as notas!\n\n\n Unicesumar Extend criado por Rafael Dantas");
        localStorage.setItem('__alert_updete_0.0.4', true);
    }

    // Coleção que ira receber as notas de todas as materias
    var entityCollection = [];

    // Define a media anual para cada bimestre.
    var mediaTotal = {
        bin1: 0,
        bin2: 0,
        bin3: 0,
        bin4: 0
    };

    // Tabela das notas (a quarta!)
    var $table = $("table:eq(3)");
    // Percorre todas as colunas, cada coluna é um bimestre
    $table.find('tr:gt(0)').each(function(k, j) {

        // Cria um objeto vazio para gravar as notas dessa materia
        var entity = {};
        $tr = $(this);

        // Salva o nome da materia
        entity.name = $tr.find("td:eq(0)").text();
        // Salva o elemento da materia
        entity.element = $(this);

            // helper para obter a nota a partir da coluna (caso - trasforma em undefined).
        var getNote = function(position) {
            return ($tr.find('td:eq('+ position +')').text() != '-') ? parseFloat($tr.find('td:eq('+ position +')').text()) : undefined;
        };

        entity.notes = {
            bin1: {
                element: $tr.find('td:eq(1)'), // Elemento
                note: getNote(1) // A nota
            },
            subBin1: {
                element: $tr.find('td:eq(3)'),
                note: getNote(3)
            },
            bin2: {
                element: $tr.find('td:eq(2)'),
                note: getNote(2)
            },
            subBin2: {
                element: $tr.find('td:eq(4)'),
                note: getNote(4)
            },
            bin3: {
                element: $tr.find('td:eq(5)'),
                note: getNote(5)
            },
            subBin3: {
                element: $tr.find('td:eq(7)'),
                note: getNote(7)
            },
            bin4: {
                element: $tr.find('td:eq(6)'),
                note: getNote(6)
            },
            subBin4: {
                element: $tr.find('td:eq(8)'),
                note: getNote(8)
            }
        };

        // Adiciona essa materia na collection
        entityCollection.push(entity);
    });

    // Funcao calcula e determina a media de cada materia, adicionando na coluna
    function determineMedia(entity, total, notes) {
        var result = total - 24.0; // Calcula o quanto falta para media
        var divide = (notes > 0) ? notes : 0; // Define o divisor
        var toPass = result / ( 4 - divide ); // Divide o divisor pelo que falta, para definir quantos falta passar em cada bimestre
        var color = (toPass > 0) ? 'green' : 'red'; // Define uma cor, verde para exesso ou vermelho para falta.

        if(Math.abs(toPass) > 10.0 && toPass < 0) {  // Verifica se absoluto é maior que cem e a nota é negativa
            entity.element.css('background', '#F75D59'); // Descata a linha de vermelho
            color = 'white';
        } else if(toPass >= 0) {  // Verifica se a nota é positiva
            entity.element.css('background', '#59E817'); // Destaca a linha de verde
            color = 'black';
        }

        var entity = entity.notes; // Helper :)

        toPass = Math.abs(toPass).toFixed(1); // Transforma o numero em absoluto e com uma casa decimal
        var changeNote = function(bin) {
            entity[bin].element.html(toPass).css('color', color);   // helper
        };

        subBin1 = entity.subBin1.note;
        subBin2 = entity.subBin2.note;
        if(notes > 2 && notes < 4) { // Se esta no terceiro bimestre, calcular o que precisa para sub
            if(subBin1 !== undefined && subBin2 !== undefined) { // se ja nao definido
                alert("Ainda não calcula o valor que você precisa para sub, em breve!");
            }
        }

        subBin3 = entity.subBin3.note;
        subBin4 = entity.subBin4.note;
        if(notes >= 4) { // Se esta no quarto bimestre, define os valores da sub
            if(subBin3 !== undefined && subBin4 !== undefined) {
                alert("Ainda não calcula o valor que você precisa para sub, em breve!");
            }
        }

        for(i=notes+1;i<4;i++) {
            changeNote( "bin" + i ); // usa o helper para todos os bimestre
        }
    }
    // Adiciona o titulo de media final
    $table.find('tr:eq(0)').append("TOTAL	");
    $table.find('tr:eq(0)').append("FREQUENCIAS	");

    // percorre todas as notas
    $.each(entityCollection, function(index, value) {
       var bin1 = value.notes.bin1.note;
       var bin2 = value.notes.bin2.note;
       var subBin1 = value.notes.subBin1.note;
       var subBin2 = value.notes.subBin2.note;

       var bin3 = value.notes.bin3.note;
       var bin4 = value.notes.bin4.note;
       var subBin3 = value.notes.subBin3.note;
       var subBin4 = value.notes.subBin4.note;

       var total, notes;

       // Trocar a nota do bin pela sub
       if(bin2 !== undefined) {
           if(subBin1 !== undefined) {
               if(subBin1 > bin1) bin1 = subBin1;
           }

           if(subBin2 !== undefined) {
               if(subBin2 > bin2) bin2 = subBin2;
           }
       }

       if(bin4 !== undefined) {
           if(subBin3 !== undefined) {
               if(subBin3 > bin3) bin3 = subBin3;
           }

           if(subBin4 !== undefined) {
               if(subBin4 > bin4) bin4 = subBin4;
           }
       }

       if(bin1 == undefined) {
          total = 0;
          notes = 0;
       } else if(bin2 == undefined) {
          total = bin1;
          notes = 1;
      } else if(bin3 == undefined) {
          total = bin1 + bin2;
          notes = 2;
       } else if(bin4 == undefined) {
          total = bin1 + bin2 + bin3;
          notes = 3;
       }  else {
          total = bin1 + bin2 + bin3 + bin4;
          notes = 4;
       }

       // Define os total das medias depois que ja trocou as subs pelos os bins :)
       mediaTotal.bin1 += (bin1 !== undefined) ? bin1 : 0;
       mediaTotal.bin2 += (bin2 !== undefined) ? bin2 : 0;
       mediaTotal.bin3 += (bin1 !== undefined) ? bin3 : 0;
       mediaTotal.bin4 += (bin1 !== undefined) ? bin4 : 0;

       determineMedia(value, total, notes);

       // Add media total da materia
       var $totalMedias = value.element.find('td:eq(-1)');
       var htmlAppend = $totalMedias.text(total).clone();
       value.element.append(htmlAppend);
       var $frequencia = value.element.find('td:eq(-1)'); // Adicionado no append em cima, modificou os indexs dos elementos no DOM
       obterFrequencia(value, $frequencia);

    });

    // Adiciona a coluna de media do bimistre
    var lastTableHtml = $table.find('tr').last().clone();
    $table.append( lastTableHtml );
    var lastTable = $table.find('tr').last();
    lastTable.hide();

    lastTable.css('background', 'rgba(63, 135, 193, 0.41)');

    var setColumnText = function(column, text) {
        lastTable.find('td:eq('+ column +')').text(text);
    };

    setColumnText(0, "Media total das materias");
    if(mediaTotal.bin1 !== undefined) setColumnText(1, (mediaTotal.bin1 / (entityCollection.length - 1) ).toFixed(1) );
    if(mediaTotal.bin2 !== undefined) setColumnText(2, (mediaTotal.bin2 / (entityCollection.length - 1) ).toFixed(1) );
    if(mediaTotal.bin3 !== undefined) setColumnText(5, (mediaTotal.bin3 / (entityCollection.length - 1) ).toFixed(1) );
    if(mediaTotal.bin4 !== undefined) setColumnText(6, (mediaTotal.bin4 / (entityCollection.length - 1) ).toFixed(1) );
    setColumnText(3, '-');
    setColumnText(4, '-');
    setColumnText(7, '-');
    setColumnText(8, '-');
    setColumnText(9, '-');
    setColumnText(10, '-');

    lastTable.fadeIn(500);

    $table.append('

Unicesumar Extend - Extesão não oficial, criado por Rafael Dantas (rafael@webdantas.com.br)
 Código no github
');

    function obterFrequencia(entity, element) {
        element.text("Carregando...").css('background', 'white');
        var cod = entity.name.split('-');
        cod = $.trim( cod[ cod.length - 1 ] );

        $.ajax({
            url: "ti_resumo_aulas.asp",
            method: "GET",
            data: {
                disc: cod
            },
            success: function(data) {
                $buffer = $( data );

                var $tr = $buffer.find('.disciplina tr:eq(-1) td');
                var allow = $tr.first().text();
                var total = $tr.last().text();

                if(total == 0) total = '0';
                if(total.length == 1) total = '0' + total;

                element.text( total + '/' + allow  );
                $buffer.remove();
            },
            error: function() {
                element.text("FALHA");
            }
        });
    }

});
<|endoftext|>


<commit_before>$(function () {

    /* Functions */
    var modalIsCreated = false;

    var loadForm = function () {
        var btn = $(this);
        if (!modalIsCreated){
        $.ajax({
            url: btn.attr("data-url"),
            type: 'get',
            dataType: 'json',
            async: true,
            success: function (data) {
                $("#modal-prescription .modal-content").html("");
                $("#modal-prescription").modal("show");
                modalIsCreated = true;
                $("#modal-prescription .modal-content").html(data.html_form);
            }
        });
      }else{
        $("#modal-prescription").modal("show");
      }
    };

    var saveForm = function () {
        var form = $(this);
        $.ajax({
            url: form.attr("action"),
            data: form.serialize(),
            type: form.attr("method"),
            dataType: 'json',
            async: true,
            success: function (data) {
                if (data.form_is_valid) {
                  modalIsCreated = false;
                  $("#modal-prescription").modal("hide");
                }
                else {
                    $("#modal-prescription").modal("show");
                    $("#modal-prescription .modal-content").html(data.html_form);
                }
            }
        });
        return false;
    };

    /* Binding */

    // Create prescription
    $(".js-create-prescription").click(loadForm);
    $("#modal-prescription").on("submit", ".js-prescription-create-form", saveForm);

    // Update prescription
    $("#prescription-table").on("click", ".js-update-prescription", loadForm);
    $("#modal-prescription").on("submit", ".js-prescription-update-form", saveForm);

    // Delete prescription
    $("#prescription-table").on("click", ".js-delete-prescription", loadForm);
    $("#modal-prescription").on("submit", ".js-prescription-delete-form", saveForm);

});
<commit_msg> #162 - Updating prescription modal to open jsonresponse.<commit_after>$(function () {

    /* Functions */
    var modalIsCreated = false;

    var loadForm = function () {
        var btn = $(this);
        if (!modalIsCreated){
        $.ajax({
            url: btn.attr("data-url"),
            type: 'get',
            dataType: 'json',
            async: true,
            success: function (data) {
                $("#modal-prescription .modal-content").html("");
                $("#modal-prescription").modal("show");
                modalIsCreated = true;
                $("#modal-prescription .modal-content").html(data.html_form);
            }
        });
      }else{
        $("#modal-prescription").modal("show");
      }
    };

    var saveForm = function () {
        var form = $(this);
        $.ajax({
            url: form.attr("action"),
            data: form.serialize(),
            type: form.attr("method"),
            dataType: 'json',
            async: true,
            success: function (data) {
                if (data.form_is_valid) {
                  modalIsCreated = false;
                  $("#modal-prescription").modal("hide");
                }
                else {
                    $("#modal-prescription").modal("show");
                    $("#modal-prescription .modal-content").html(data.html_form);
                }
            }
        });
        return false;
    };

    /* Binding */

    // Create prescription
    $(".js-create-prescription").click(loadForm);
    $("#modal-prescription").on("submit", ".js-prescription-create-form", saveForm);

    // Update prescription
    $("#prescription-table").on("click", ".js-update-prescription", loadForm);
    $("#modal-prescription").on("submit", ".js-prescription-update-form", saveForm);

    // Delete prescription
    $("#prescription-table").on("click", ".js-delete-prescription", loadForm);
    $("#modal-prescription").on("submit", ".js-prescription-delete-form", saveForm);

    $(".js-show-prescription").click(loadForm)

});
<|endoftext|>


<commit_before>/* This file is part of Indico.
 * Copyright (C) 2002 - 2016 European Organization for Nuclear Research (CERN).
 *
 * Indico is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * Indico is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Indico; if not, see <http://www.gnu.org/licenses/>.
 */

(function(global) {
    'use strict';

    global.handleAjaxError = function handleAjaxError(data) {
        if (data.responseText) {
            // $.ajax error callback, so data is the xhr object
            try {
                data = JSON.parse(data.responseText);
            } catch(e) {
                IndicoUI.Dialogs.Util.error({
                    code: data.status,
                    type: 'unknown',
                    message: data.statusText.toLowerCase(),
                    data: {},
                    inner: null,
                    requestInfo: {
                        url: data._requestURL  // set in beforeSend callback
                    }
                });
                return true;
            }
        }
        // data.data.error is only needed for angular error handlers
        var error = data.error || (data.data && data.data.error);
        if (error) {
            IndicoUI.Dialogs.Util.error(error);
            return true;
        }
    };

    // Select the field of an i-form which has an error and display the tooltip.
    global.showFormErrors = function showFormErrors(context) {
        context = context || $('body');
        context.find(".i-form .has-error > .form-field, .i-form .has-error > .form-subfield").each(function() {
            var $this = $(this);
            // Try a custom tooltip anchor
            var input = $this.find('[data-tooltip-anchor]');

            if (!input.length) {
                // Try the first non-hidden input field
                input = $this.children(':input:not(:hidden)').eq(0);
            }

            if (!input.length) {
                // Try the first element that's not a hidden input
                input = $this.children(':not(:input:hidden)').eq(0);
            }
            input.stickyTooltip('danger', function() {
                return $this.data('error');
            });
        });
    };
})(window);
<commit_msg>Silently ignore AJAX failures when navigating away<commit_after>/* This file is part of Indico.
 * Copyright (C) 2002 - 2016 European Organization for Nuclear Research (CERN).
 *
 * Indico is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * Indico is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Indico; if not, see <http://www.gnu.org/licenses/>.
 */

(function(global) {
    'use strict';

    global.handleAjaxError = function handleAjaxError(data) {
        if ('responseText' in data && data.readyState === 0 && data.status === 0 && !data.responseText) {
            // if data is an XHR object and we don't have any readyState, status or response text
            // the request most likely failed due to a page change so we just ignore the failure.
            // this is not 100% reliable, an interrupted connection could yield the same result.
            // since showing an error dialog in that case won't be very useful either this drawback
            // is acceptable.
            return true;
        }
        if (data.responseText) {
            // $.ajax error callback, so data is the xhr object
            try {
                data = JSON.parse(data.responseText);
            } catch(e) {
                IndicoUI.Dialogs.Util.error({
                    code: data.status,
                    type: 'unknown',
                    message: data.statusText.toLowerCase(),
                    data: {},
                    inner: null,
                    requestInfo: {
                        url: data._requestURL  // set in beforeSend callback
                    }
                });
                return true;
            }
        }
        // data.data.error is only needed for angular error handlers
        var error = data.error || (data.data && data.data.error);
        if (error) {
            IndicoUI.Dialogs.Util.error(error);
            return true;
        }
    };

    // Select the field of an i-form which has an error and display the tooltip.
    global.showFormErrors = function showFormErrors(context) {
        context = context || $('body');
        context.find(".i-form .has-error > .form-field, .i-form .has-error > .form-subfield").each(function() {
            var $this = $(this);
            // Try a custom tooltip anchor
            var input = $this.find('[data-tooltip-anchor]');

            if (!input.length) {
                // Try the first non-hidden input field
                input = $this.children(':input:not(:hidden)').eq(0);
            }

            if (!input.length) {
                // Try the first element that's not a hidden input
                input = $this.children(':not(:input:hidden)').eq(0);
            }
            input.stickyTooltip('danger', function() {
                return $this.data('error');
            });
        });
    };
})(window);
<|endoftext|>


<commit_before>/** File: candy.js
 * Candy - Chats are not dead yet.
 *
 * Authors
 *   - Jonatan Männchen <jonatan.maennchen@amiadogroup.com>
 */

/* global Candy, jQuery */

var CandyShop = (function(self) { return self; }(CandyShop || {}));

/** Class: InlineVideos
 * If a user posts a URL to a video, that video gets rendered directly
 * inside of Candy.
 */
CandyShop.InlineVideos = (function(self, Candy, $) {
	/** Function: init
	 * Initializes the inline-videos plugin with the default settings.
	 *
	 * Parameters:
	 *   (Object) options - An options packet to apply to this plugin
	 */
	self.init = function() {
		// add a listener to these events
		$(Candy).on('candy:view.message.before-show', self.handleBeforeShow);
	};

	/** Function: handleBeforeShow
	 * Handles the beforeShow event of a message.
	 *
	 * Parameters:
	 *   (String) message - the message to process
	 *
	 * Returns:
	 *   (String)
	 */
	self.handleBeforeShow = function(e, args) {
		args.message = args.message.replace(/\>(https?:\/\/w{0,3}\.?youtube.com\/watch\?v=([^\s^&]*)([^\s]*))\<\/a\>/i, '>$1

');
	};

	return self;
}(CandyShop.InlineVideos || {}, Candy, jQuery));
<commit_msg>first attempt at #148 - t= and list= support<commit_after>/** File: candy.js
 * Candy - Chats are not dead yet.
 *
 * Authors
 *   - Jonatan Männchen <jonatan.maennchen@amiadogroup.com>
 *   - Sudrien <_+github@sudrien.net>
 */

/* global Candy, jQuery */

var CandyShop = (function(self) { return self; }(CandyShop || {}));

/** Class: InlineVideos
 * If a user posts a URL to a video, that video gets rendered directly
 * inside of Candy.
 */
CandyShop.InlineVideos = (function(self, Candy, $) {
	/** Function: init
	 * Initializes the inline-videos plugin with the default settings.
	 *
	 * Parameters:
	 *   (Object) options - An options packet to apply to this plugin
	 */
	self.init = function() {
		// add a listener to these events
		$(Candy).on('candy:view.message.before-show', self.handleBeforeShow);
	};

	/** Function: timeToSeconds
	 * converts youtube's t= parameter value to seconds
	 *
	 * Parameters:
	 *   (String) timeString - either seconds os 00h00m00s format
	 *
	 * Returns:
	 *   (Integer) - seconds
	 */
	var timeToSeconds = function(timeString) {
		var ret = 0;
		if(timeString == null) {
			return ret;
		}
		var times = timeString[1].match(/((\d+)h)?((\d+)m)?((\d+)s)?(\d+)?/);
		if(times[7]) {
			ret += parseInt(times[7]); //seconds only
		}
		else {
			ret += times[2] ? parseInt(times[2]) * 60 * 60 : 0; //hours
			ret += times[4] ? parseInt(times[4]) * 60 : 0; //minutes
			ret += times[6] ? parseInt(times[6]) : 0; //seconds
		}
		console.info(timeString, times, ret);
		return ret;
	};

	/** Function: handleBeforeShow
	 * Handles the beforeShow event of a message.
	 *
	 * Parameters:
	 *   (String) message - the message to process
	 *
	 * Returns:
	 *   (String)
	 */
	self.handleBeforeShow = function(e, args) {
		args.message = jQuery.parseHTML(args.message).map(function(a) {
			if(a.outerHTML){ //dom element of any sort
				switch(a.hostname) { // a link with an href
				case "youtube.com":
				case "www.youtube.com":
					if(a.pathname == "/watch") {
						var v = a.search.match(/v=([a-zA-Z0-9_-]{11})/);
						if(v) {
							var start = timeToSeconds(a.search.match(/t=([hms0-9]+)/));
							var list = a.search.match(/list=([^&]+)/);
							var main_url = "https://youtu.be/" + (v ? v[1] : "") + "?start=" + (start ? start : "") + "&list=" + (list ? list[1] : "");
							var embed_url = "https://www.youtube.com/embed/" + (v ? v[1] : "") + "?start=" + (start ? start[1] : "") + "&list=" + (list ? list[1] : "");
							return "" + main_url + "
";
						}
						else {
							return a.outerHTML;
						}
					}
					else {
						return a.outerHTML;
					}
					break;
				case "youtu.be":
					var v = a.pathname.match(/\/([a-zA-Z0-9_-]{11})/);
					var start = timeToSeconds(a.search.match(/t=([hms0-9]+)/));
					var list = a.search.match(/list=([^&]+)/);
					var main_url = "https://youtu.be/" + (v ? v[1] : "") + "?start=" + (start ? start : "") + "&list=" + (list ? list[1] : "");
					var embed_url = "https://www.youtube.com/embed/" + (v ? v[1] : "") + "?start=" + (start ? start[1] : "") + "&list=" + (list ? list[1] : "");
					return "" + main_url + "
";
					break;
				default:  //undefined - not a link
					return a.outerHTML;
				}
			}
			else { //this is a string that has to be wrapped in somthing
				return a.textContent;
			}
		}).join("");
	};

	return self;
}(CandyShop.InlineVideos || {}, Candy, jQuery));

<|endoftext|>


<commit_before>/*! @copyright (c) 2015 KNJ | THE MIT License | https://github.com/KNJ/cloz/blob/master/LICENSE */

var cloz = function(base, ex){
	base = base || {};
	var derived = {};
	var o = Object.create(base);
	var isStr = function(prop){
		if (Object.prototype.toString.call(prop) === '[object String]') {
			return true;
		}
		return false;
	};
	var isObj = function(prop){
		if (Object.prototype.toString.call(prop) === '[object Object]') {
			return true;
		}
		return false;
	};

	derived.get = function(prop){
		if (!isStr(prop)) {
			throw new Error('The first argument of cloz.get() must be string.');
		}
		if (typeof o[prop] === 'undefined') {
			if (base.hasOwnProperty('get')) {
				return base.get.apply(this, arguments);
			}
			else {
				throw new Error('Cannot find property "' + prop + '"');
			}
		}
		else if (typeof o[prop] === 'function') {
			var args = [];
			for (var i = 1; i < arguments.length; i++) {
				args.push(arguments[i]);
			}
			return o[prop].apply(this, args);
		}
		else {
			return o[prop];
		}
	};
	derived.gain = function(prop, val){
		if (!isStr(prop)) {
			throw new Error('The first argument of cloz.gain() must be string');
		}
		if (typeof o[prop] === 'undefined') {
			if (base.hasOwnProperty('get')) {
				return base.gain.apply(this, arguments);
			}
			else {
				val = val || null;
				return val;
			}
		}
		else if (typeof o[prop] === 'function') {
			var args = [];
			for (var i = 2; i < arguments.length; i++) {
				args.push(arguments[i]);
			}
			return o[prop].apply(this, args);
		}
		else {
			return o[prop];
		}
	};
	derived.getAll = function(){
		return o;
	};
	derived.set = function(prop, val){
		if (isStr(prop)) {
			o[prop] = val;
			return o[prop];
		}
		if (isObj(prop)) {
			for (var p in prop) {
				o[p] = prop[p];
			}
			return prop;
		}
		throw new Error('The first argument of cloz.set() must be string or object');
	};
	derived.extend = function(prop, obj){
		if (!isStr(prop)) {
			throw new Error('The first argument of cloz.extend() must be string');
		}
		o[prop] = cloz(this.get(prop), obj);
		return o[prop];
	};

	if (typeof ex === 'object' && ex !== null) {
		for (var p in ex) {
			derived.set(p, ex[p]);
		}
		if (ex.hasOwnProperty('__cloz')) {
			ex.__cloz();
		}
		if (ex.hasOwnProperty('_cloz')) {
			ex._cloz();
		}
		else {
			derived.gain('_cloz');
		}
	}
	else {
		derived.gain('_cloz');
	}

	return derived;
};<commit_msg>Remove conditional branch<commit_after>/*! @copyright (c) 2015 KNJ | THE MIT License | https://github.com/KNJ/cloz/blob/master/LICENSE */

var cloz = function(base, ex){
	base = base || {};
	var derived = {};
	var o = Object.create(base);
	var isStr = function(prop){
		return Object.prototype.toString.call(prop) === '[object String]';
	};
	var isObj = function(prop){
		return Object.prototype.toString.call(prop) === '[object Object]';
	};

	derived.get = function(prop){
		if (!isStr(prop)) {
			throw new Error('The first argument of cloz.get() must be string.');
		}
		if (typeof o[prop] === 'undefined') {
			if (base.hasOwnProperty('get')) {
				return base.get.apply(this, arguments);
			}
			else {
				throw new Error('Cannot find property "' + prop + '"');
			}
		}
		else if (typeof o[prop] === 'function') {
			var args = [];
			for (var i = 1; i < arguments.length; i++) {
				args.push(arguments[i]);
			}
			return o[prop].apply(this, args);
		}
		else {
			return o[prop];
		}
	};
	derived.gain = function(prop, val){
		if (!isStr(prop)) {
			throw new Error('The first argument of cloz.gain() must be string');
		}
		if (typeof o[prop] === 'undefined') {
			if (base.hasOwnProperty('get')) {
				return base.gain.apply(this, arguments);
			}
			else {
				val = val || null;
				return val;
			}
		}
		else if (typeof o[prop] === 'function') {
			var args = [];
			for (var i = 2; i < arguments.length; i++) {
				args.push(arguments[i]);
			}
			return o[prop].apply(this, args);
		}
		else {
			return o[prop];
		}
	};
	derived.getAll = function(){
		return o;
	};
	derived.set = function(prop, val){
		if (isStr(prop)) {
			o[prop] = val;
			return o[prop];
		}
		if (isObj(prop)) {
			for (var p in prop) {
				o[p] = prop[p];
			}
			return prop;
		}
		throw new Error('The first argument of cloz.set() must be string or object');
	};
	derived.extend = function(prop, obj){
		if (!isStr(prop)) {
			throw new Error('The first argument of cloz.extend() must be string');
		}
		o[prop] = cloz(this.get(prop), obj);
		return o[prop];
	};

	if (typeof ex === 'object' && ex !== null) {
		for (var p in ex) {
			derived.set(p, ex[p]);
		}
		if (ex.hasOwnProperty('__cloz')) {
			ex.__cloz();
		}
		if (ex.hasOwnProperty('_cloz')) {
			ex._cloz();
		}
		else {
			derived.gain('_cloz');
		}
	}
	else {
		derived.gain('_cloz');
	}

	return derived;
};
<|endoftext|>


<commit_before>'use strict';

const es = require('vinyl-elasticsearch');

class ElasticSearchSource {
  constructor() {
    this._opts = {};
    this._missing = [];
    this._sort = [];
    this._term = [];
    this._notTerm = [];
  }

  host(host) {
    this._opts.host = host;

    return this;
  }

  amazonES(amazonES) {
    this._opts.amazonES = amazonES;

    return this;
  }

  retries(retries) {
    this._opts.retries = retries;

    return this;
  }

  size(size) {
    this._size = size;

    return this;
  }

  index(index) {
    this._index = index;

    return this;
  }

  type(type) {
    this._type = type;

    return this;
  }

  sort(field, order) {
    this._sort.push({
      [field]: {
        order: order || 'asc'
      }
    });

    return this;
  }

  term(field, value) {
    this._term.push({[field]: value});

    return this;
  }

  missing(field) {
    this._missing.push({field: field});

    return this;
  }

  notTerm(field, value) {
    this._notTerm.push({[field]: value});

    return this;
  }

  getStream() {
    let glob = {
      index: this._index,
      body: {
        query: {
          filtered: {
            filter: {
              bool: {
                'must': [
                  {
                    type: {
                      value: this._type
                    }
                  }
                ]
              }
            }
          }
        }
      }
    }

    if (this._size) {
      glob.size = this._size;
    }

    this._missing.forEach(m => {
      glob.body.query.filtered.filter.bool.must.push({
        missing: m
      });
    })

    if (this._sort.length) {
      glob.body.sort = [];

      this._sort.forEach(sort => {
        glob.body.sort.push(sort);
      })
    }

    this._term.forEach(term => {
      glob.body.query.filtered.filter.bool.must.push({
        term: term
      });
    })

    this._notTerm.forEach(term => {
      glob.body.query.filtered.filter.bool.must.push({
        not: {
          term: term
        }
      });
    })

    return es.src(glob, this._opts);
  }
}

module.exports = ElasticSearchSource;
<commit_msg>don't check 'size' option in ES queries since prevents use of '0'<commit_after>'use strict';

const es = require('vinyl-elasticsearch');

class ElasticSearchSource {
  constructor() {
    this._opts = {};
    this._missing = [];
    this._sort = [];
    this._term = [];
    this._notTerm = [];
  }

  host(host) {
    this._opts.host = host;

    return this;
  }

  amazonES(amazonES) {
    this._opts.amazonES = amazonES;

    return this;
  }

  retries(retries) {
    this._opts.retries = retries;

    return this;
  }

  size(size) {
    this._size = size;

    return this;
  }

  index(index) {
    this._index = index;

    return this;
  }

  type(type) {
    this._type = type;

    return this;
  }

  sort(field, order) {
    this._sort.push({
      [field]: {
        order: order || 'asc'
      }
    });

    return this;
  }

  term(field, value) {
    this._term.push({[field]: value});

    return this;
  }

  missing(field) {
    this._missing.push({field: field});

    return this;
  }

  notTerm(field, value) {
    this._notTerm.push({[field]: value});

    return this;
  }

  getStream() {
    let glob = {
      index: this._index,
      body: {
        query: {
          filtered: {
            filter: {
              bool: {
                'must': [
                  {
                    type: {
                      value: this._type
                    }
                  }
                ]
              }
            }
          }
        }
      }
    }

    glob.size = this._size;

    this._missing.forEach(m => {
      glob.body.query.filtered.filter.bool.must.push({
        missing: m
      });
    })

    if (this._sort.length) {
      glob.body.sort = [];

      this._sort.forEach(sort => {
        glob.body.sort.push(sort);
      })
    }

    this._term.forEach(term => {
      glob.body.query.filtered.filter.bool.must.push({
        term: term
      });
    })

    this._notTerm.forEach(term => {
      glob.body.query.filtered.filter.bool.must.push({
        not: {
          term: term
        }
      });
    })

    return es.src(glob, this._opts);
  }
}

module.exports = ElasticSearchSource;
<|endoftext|>


<commit_before>$(document).ready(function() {
  $('#myChart').createPH(280, 40, 7);
  resetDB(function(res) {
	});
  update();
});

function update() {
	queue()
    .defer(d3.json, "/api/data")
    .await(makeGraphs);
}
update();
//SET TO UPDATE EVERY 10 SECONDS
//IN THE FUTURE SHOULD UPDATE BASED ON REAL TIME FOR WHEN THE DATA IS RECEIVED
setInterval(update, 100000000);

function makeGraphs(error, apiData) {

/********* Start Transformations *********/
	var dataSet = apiData;

	//Fill data array with 100 values from apiData; graphs only plot 100 values
	// most recent data is at 0 index?
	var data = [];
	// var dateFormat = d3.time.format("%Y-%m-%dT%H:%M:%SZ"); //pos uneccessary
	// apiData.forEach(function(d) {
	// 	d.timestamp = dateFormat.parse(d.timestamp); //slow down
	// });
	for (var i = 0; i < dataSet.length; i++) {
		data.push(apiData[i]);
	}
	// converts to Date object (just take substring .000Z)
	var parser = d3.time.format("%Y-%m-%dT%H:%M:%S.000Z");
	data.forEach(function(d) {
		d.timestamp = parser.parse(d.timestamp);
		// d.timestamp = d3.time.day(d.timestamp);
		// console.log(d.timestamp);
	});

/********* END *********/

/********* Create a Crossfilter instance and All *********/

	var trial = crossfilter(data);
	var all = trial.groupAll();

/********* END *********/

/********* Define Dimensions *********/
	// Dimensions are only for later filters (construct a dim on type and apply filters on type)

	// Later use dateDim to sort based on certain dates
	// var tempDim = trial.dimension(function (d) { return d.temperature; });
	var dateDim = trial.dimension(function (d) { return d.timestamp; });
	var minDate = dateDim.bottom(1)[0].timestamp;
	var maxDate = dateDim.top(1)[0].timestamp;
/********* END *********/

/********* Groups *********/
/* Uncomment only one section */
	// var turbidity = tempDim.group().reduceSum(function (d) { return d.turbidity; });
	// var conductivity = tempDim.group().reduceSum(function (d) { return d.conductivity; });
	// var pH = tempDim.group().reduceSum(function(d) { return d.pH; });
	// var temp = tempDim.group().reduceSum(function (d) { return d.temperature; });

	var turbidity = dateDim.group().reduceSum(function (d) {
		return d.turbidity;
	});
	var conductivity = dateDim.group().reduceSum(function (d) { return d.conductivity; });
	var pH = dateDim.group().reduceSum(function(d) { return d.pH; });
	var temp = dateDim.group().reduceSum(function (d) { return d.temperature; });

/********* END *********/

/********* Chart Declaration *********/

	// var overalllineChart = dc.lineChart("#dc-line-chart");
	var overalllineChart = dc.compositeChart("#dc-line-chart");
	var compositeChart1 = dc.compositeChart('#chart-container1');
	var conductivityChart = dc.pieChart("#dc-pie-chart");

/********* END *********/

/******* Overlayed line chart *******/

	overalllineChart
	    .width(768)
	    .height(480)
	    .x(d3.time.scale().domain([minDate, maxDate]))
	    .margins({top: 30, right: 50, bottom: 25, left: 60})
	    .brushOn(true)
	    .clipPadding(10)
	    .yAxisLabel("This is the Y Axis")
	    .elasticY(true)
	    .renderLabel(true)
	    .label(function (p) {
            return p.key;
        })

	    .round(d3.time.day.round) // select only day ranges
	    .dimension(dateDim)

		.compose([
			dc.lineChart(overalllineChart)
				.group(turbidity, 'Turbidity')
	// 			May need this later... (also .keyAccessor)
	//			 .valueAccessor(function (p) {
    //         		return p.value;
    //     		})
				.ordinalColors(["#FFC914"]), //line orange
			dc.lineChart(overalllineChart)
				.group(temp, 'Temperature')
				.ordinalColors(["#17BEBB"]),
			dc.lineChart(overalllineChart)
				.group(pH, 'pH')
				.ordinalColors(["#E4572E"]),
			dc.lineChart(overalllineChart)
				.group(conductivity, 'Conductivity')
				.ordinalColors(["#76B041"])
			])
<<<<<<< HEAD
	// conductivityChart
	// 	.width(250)
	// 	.height(250)
	// 	.radius(100)
	// 	.innerRadius(0)
	// 	.dimension(dateDim)
	// 	.group(conductivity)
	// 	// .title(function (d) { return d.value; });

	var gauge1 = loadLiquidFillGauge("turbidity-graph", data[dataSet.length-1].turbidity);
	var config1 = liquidFillGaugeDefaultSettings();
	config1.circleColor = "#FF7777";
	config1.textColor = "#FF4444";
	config1.waveTextColor = "#FFAAAA";
	config1.circleThickness = 0.2;
	config1.textVertPosition = 0.2;
	config1.waveAnimateTime = 1000;
	config1.displayPercent = false;
	config1.minValue = 0;
	config1.maxValue = 10;
	console.log(data[dataSet.length-1].turbidity * 1.5);
=======

	conductivityChart
		.width(250)
		.height(250)
		.radius(100)
		.innerRadius(0)
		.dimension(dateDim)
		.group(conductivity)
		// .title(function (d) { return d.value; });

var gauge1 = loadLiquidFillGauge("turbidity-graph", 7);
var config1 = liquidFillGaugeDefaultSettings();
config1.circleColor = "#FF7777";
config1.textColor = "#FF4444";
config1.waveTextColor = "#FFAAAA";
config1.circleThickness = 0.2;
config1.textVertPosition = 0.2;
config1.waveAnimateTime = 1000;
config1.displayPercent = false;
config1.minValue = 0;
config1.maxValue = 10;
>>>>>>> 8a2b3f21f58fa516a77b4b03df902573b735efb8

/********* Draw Graphs *********/

   dc.renderAll();
   dc.redrawAll();

/********* END *********/

};<commit_msg>pH updates<commit_after>$(document).ready(function() {
  $('#myChart').createPH(280, 40, 7);
  resetDB(function(res) {
	});
  update();
});

function update() {
	queue()
    .defer(d3.json, "/api/data")
    .await(makeGraphs);
}
update();
//SET TO UPDATE EVERY 10 SECONDS
//IN THE FUTURE SHOULD UPDATE BASED ON REAL TIME FOR WHEN THE DATA IS RECEIVED
setInterval(update, 100000000);

function makeGraphs(error, apiData) {

/********* Start Transformations *********/
	var dataSet = apiData;

	//Fill data array with 100 values from apiData; graphs only plot 100 values
	// most recent data is at 0 index?
	var data = [];
	// var dateFormat = d3.time.format("%Y-%m-%dT%H:%M:%SZ"); //pos uneccessary
	// apiData.forEach(function(d) {
	// 	d.timestamp = dateFormat.parse(d.timestamp); //slow down
	// });
	for (var i = 0; i < dataSet.length; i++) {
		data.push(apiData[i]);
	}
	// converts to Date object (just take substring .000Z)
	var parser = d3.time.format("%Y-%m-%dT%H:%M:%S.000Z");
	data.forEach(function(d) {
		d.timestamp = parser.parse(d.timestamp);
		// d.timestamp = d3.time.day(d.timestamp);
		// console.log(d.timestamp);
	});

/********* END *********/

/********* Create a Crossfilter instance and All *********/

	var trial = crossfilter(data);
	var all = trial.groupAll();

/********* END *********/

/********* Define Dimensions *********/
	// Dimensions are only for later filters (construct a dim on type and apply filters on type)

	// Later use dateDim to sort based on certain dates
	// var tempDim = trial.dimension(function (d) { return d.temperature; });
	var dateDim = trial.dimension(function (d) { return d.timestamp; });
	var minDate = dateDim.bottom(1)[0].timestamp;
	var maxDate = dateDim.top(1)[0].timestamp;
/********* END *********/

/********* Groups *********/
/* Uncomment only one section */
	// var turbidity = tempDim.group().reduceSum(function (d) { return d.turbidity; });
	// var conductivity = tempDim.group().reduceSum(function (d) { return d.conductivity; });
	// var pH = tempDim.group().reduceSum(function(d) { return d.pH; });
	// var temp = tempDim.group().reduceSum(function (d) { return d.temperature; });

	var turbidity = dateDim.group().reduceSum(function (d) {
		return d.turbidity;
	});
	var conductivity = dateDim.group().reduceSum(function (d) { return d.conductivity; });
	var pH = dateDim.group().reduceSum(function(d) { return d.pH; });
	var temp = dateDim.group().reduceSum(function (d) { return d.temperature; });

/********* END *********/

/********* Chart Declaration *********/

	// var overalllineChart = dc.lineChart("#dc-line-chart");
	var overalllineChart = dc.compositeChart("#dc-line-chart");
	var compositeChart1 = dc.compositeChart('#chart-container1');
	var conductivityChart = dc.pieChart("#dc-pie-chart");

/********* END *********/

/******* Overlayed line chart *******/

	overalllineChart
	    .width(768)
	    .height(480)
	    .x(d3.time.scale().domain([minDate, maxDate]))
	    .margins({top: 30, right: 50, bottom: 25, left: 60})
	    .brushOn(true)
	    .clipPadding(10)
	    .yAxisLabel("This is the Y Axis")
	    .elasticY(true)
	    .renderLabel(true)
	    .label(function (p) {
            return p.key;
        })

	    .round(d3.time.day.round) // select only day ranges
	    .dimension(dateDim)

		.compose([
			dc.lineChart(overalllineChart)
				.group(turbidity, 'Turbidity')
	// 			May need this later... (also .keyAccessor)
	//			 .valueAccessor(function (p) {
    //         		return p.value;
    //     		})
				.ordinalColors(["#FFC914"]), //line orange
			dc.lineChart(overalllineChart)
				.group(temp, 'Temperature')
				.ordinalColors(["#17BEBB"]),
			dc.lineChart(overalllineChart)
				.group(pH, 'pH')
				.ordinalColors(["#E4572E"]),
			dc.lineChart(overalllineChart)
				.group(conductivity, 'Conductivity')
				.ordinalColors(["#76B041"])
			])

	// conductivityChart
	// 	.width(250)
	// 	.height(250)
	// 	.radius(100)
	// 	.innerRadius(0)
	// 	.dimension(dateDim)
	// 	.group(conductivity)
	// 	// .title(function (d) { return d.value; });

	var gauge1 = loadLiquidFillGauge("turbidity-graph", data[dataSet.length-1].turbidity);
	var config1 = liquidFillGaugeDefaultSettings();
	config1.circleColor = "#FF7777";
	config1.textColor = "#FF4444";
	config1.waveTextColor = "#FFAAAA";
	config1.circleThickness = 0.2;
	config1.textVertPosition = 0.2;
	config1.waveAnimateTime = 1000;
	config1.displayPercent = false;
	config1.minValue = 0;
	config1.maxValue = 10;
	console.log(data[dataSet.length-1].pH)
	$('#myChart').updatePH(data[dataSet.length-1].pH);

	conductivityChart
		.width(250)
		.height(250)
		.radius(100)
		.innerRadius(0)
		.dimension(dateDim)
		.group(conductivity)
		// .title(function (d) { return d.value; });

var gauge1 = loadLiquidFillGauge("turbidity-graph", 7);
var config1 = liquidFillGaugeDefaultSettings();
config1.circleColor = "#FF7777";
config1.textColor = "#FF4444";
config1.waveTextColor = "#FFAAAA";
config1.circleThickness = 0.2;
config1.textVertPosition = 0.2;
config1.waveAnimateTime = 1000;
config1.displayPercent = false;
config1.minValue = 0;
config1.maxValue = 10;

/********* Draw Graphs *********/

   dc.renderAll();
   dc.redrawAll();

/********* END *********/

};<|endoftext|>


<commit_before>import Ember from 'ember';
import ValidatableMixin from 'ember-validation/mixins/validatable';
import AttributeMediator from 'ember-validation/mediators/attribute';
import ValidatorMediator from 'ember-validation/mediators/validator';
import ProxyMediator from 'ember-validation/mediators/proxy';
import Errors from 'ember-validation/core/errors';
import Config from 'ember-validation/configuration';
import { lookupValidator, lookupPreset } from 'ember-validation/utils/lookup';

const { RSVP, computed, get, assert, Logger, getWithDefault, getProperties, tryInvoke } = Ember;

var findMediators = function(...names) {
    assert("You should provide at least one attribute name", !Ember.isEmpty(names));

    // Iterating over the names (of attributes) and getting mediators.
    const mediators = Ember.A(names).map((name) => {
      let mediator = this.get("mediators").findBy("attribute", name);
      assert("Mediator for attribute named `" + name + "` not found", mediator);
      return mediator;
    });

    return mediators;
};

/**
  @module
  @augments module:ember/Mixin
  @augments module:addon/mixins/validatable
  @public
*/
export default Ember.Mixin.create(ValidatableMixin, Ember.Evented, {

  /**
    Defines the properties that will be merged from the superclass
    (instead of overridden).
    @type Array
    @default null
    @public
  */
  mergedProperties: ["validationScheme"],

  /**
    A collection that contains all validators of the class instance that
    implements current mixin. The property fills up by the `initValidation`
    method from `validationScheme` (contains instruction to create validators).
    @type {Array}
  */
  mediators: computed(() => Ember.A()),

  /**
    This is an instruction for creating validators for an object that implements
    current mixin. The structure of it is following:

    @example:
      validationScheme
        attribute
          options: ATTRIBUTE_VALIDATION_OPTIONS,
          validators[]
            { name: VALIDATOR_NAME, options: VALIDATOR_OPTIONS }

    The method fills `validators` collection by validators and invoke each of
    them on `validate` method.

    @type Object
    @protected
  */
  validationScheme: computed(() => { return {}; }),

  init() {
    this.initErrors();
    this.initValidation();
    this.initStates();
    return this._super(...arguments);
  },

  initStates() {
      // The class already has a state, it means that the class has isValid and
      // isInvalid states as well.
      if (this.get("currentState")) {
          return;
      }

      Ember.defineProperty(this, "isValid", computed("errors.length", () => {
        return this.get("errors.length") === 0;
      }));

      Ember.defineProperty(this, "isInvalid", computed.not("isValid"));
  },

  initErrors() {
    this.get("errors") || this.set("errors", Errors.create());
  },

  /**
    Method creates validators for every object's attribute from the
    `validationScheme`. Validators are gets from the registry by names. Default
    namespace for them is `validator:`, that means that they are should be
    placed in the `validators/` project directory.

    Validators creates and wrappes by an attribute mediator. It has the same
    interface as they are. The mediators triggers events every time when they
    called.

    @method initValidation
    @private
  */
  initValidation() {

    const validationScheme = this.get("validationScheme");

    if (Ember.isBlank(Object.keys(validationScheme))) {
      // The object doesn't have a validation scheme. Probably it has validation
      // schemes on every it's attribute.
      var attributes = get(this.constructor, "attributes");

      attributes && attributes.forEach(item => {
        Config.LOG_VALIDATION && Logger.log("Validation : <<mixin>> : Validation : looking preset for type %s", item.type);
        let { type, name, options } = item;
        if (options && get(options, "preset")) {
          type = get(options, "preset");
        }
        if (!options.isValidatable) { return; }
        let preset = lookupPreset(type, get(this, "container"));
        Config.LOG_VALIDATION && Logger.log("Validation : <<mixin>> : Validation : preset found %o", preset.create(item));
        validationScheme[name] = preset.create(item).evolve();
      });
    }

    return this._initValidationByScheme(validationScheme);
  },

  _initValidationByScheme(validationScheme) {

    // Getting the object's properties that should have validation.
    const attributes = Ember.A(Object.keys(validationScheme));

    attributes.forEach((attribute) => {

      // Instruction to create validators for the attribute
      let validation = get(validationScheme, attribute);

      assert("Every validation should contain validators", validation);

      // A list of the validator instances
      let validatorHashes = this._createValidators(attribute, validation);

      let options = getWithDefault(validation, "options", {});
      let groupMediator = null;

      if (options.proxy) {
        groupMediator = ProxyMediator.extend(options).create({ context: this, attribute, options });
      } else {
        groupMediator = this._createGroupMediator(attribute, options);
      }

      // Iterating over the attribute's validators and wrap each of them by a
      // mediator, that has the same interface then they are.
      validatorHashes.forEach((hash) => {
        let options = get(hash, "options");
        let validator = get(hash, "validator");
        let validatorMediator = this._createValidatorMediator(attribute, validator, options);
        groupMediator.pushObject(validatorMediator);
      });

      groupMediator.on("passed", () => {
        Config.LOG_VALIDATION && Logger.log("Validation : <<mixin>> : Validation : %cevent::Mediator.passed%c on attribute '%s'", "color: #090", null, attribute);
        this.get("errors").remove(attribute);
      });

      groupMediator.on("failed", (message) => {
        Config.LOG_VALIDATION && Logger.log("Validation : <<mixin>> : Validation : %cevent::Mediator.failed%c on attribute '%s' with errors %o", "color: #900", null, attribute, message);
        // To prevent occurring of the inconsistent state error
        // this.transitionTo && this.transitionTo("updated.uncommitted");
        if (!get(message, "options.proxy")) {
          this.get("errors").remove(attribute);
          this.get("errors").add(attribute, message);
          this.get("errors").arrayContentDidChange();
        }
      });

      // @todo: It's broken for proxy validation.
      // groupMediator.on("conditionChanged", () => {
      //   Config.LOG_VALIDATION && Logger.log("Validation : <<mixin>> : Validation : event::Mediator.conditionChanged on attribute '%s'", attribute);
      //   this.get("errors").remove(attribute);
      // });

      // mediators.pushObject(groupMediator);
      this.addMediator(groupMediator);
    });

  },

  /**
    Add mediator to mediators list and fire event

    @method addMediator
    @param Mediator
    @trigger mediatorDidAdd
    @return undefined
  */
  addMediator(mediator) {
    const attrName = get(mediator, "attribute");
    this.get("mediators").pushObject(mediator);
    this.trigger('mediatorDidAdd', mediator);
    Config.LOG_VALIDATION && Logger.log("Validation : <<mixin>> : Validation : addMediator %o for '%s'", mediator, attrName || get(mediator, "validate-path"), get(mediator, 'view.element') );
  },

  /**
    remove mediator from mediators list and fire event

    @method removeMediator
    @param Mediator
    @trigger mediatorWillRemove
    @return undefined
  */
  removeMediator(mediator) {
    const mediators = this.get("mediators");
    const attrName = get(mediator, "attribute");

    if (mediators.indexOf(mediator) !== -1) {
      this.trigger("mediatorWillRemove", mediator);
      mediators.removeObject(mediator);
      mediator.destroy();
      Config.LOG_VALIDATION && Logger.log("Validation : <<mixin>> : Validation : removeMediator %o for '%s'", mediator, attrName);
    }
  },

  /**
    Iterates over the elements of a validation collection, calls `validate` on
    each them, collect result of evaluation and put it into the `errors`
    property of the object.
    @method validate
    @return {Ember.RSVP.Promise}
  */
  validate() {
    if (Ember.isEmpty(arguments)) {
      return this._runMediators("validate", this.get("mediators"));
    } else {
      Ember.warn('You probably want to call `validateByName`', Ember.isEmpty(arguments));
      return this.validateByName(...arguments);
    }
  },

  /**
    This method the same as `validate`, only difference is that the `validate`
    fills errors of the object. This method may be helpful to you, if you want
    to check the object validation, but do not want fill it with errors.
    @method check
    @return {Ember.RSVP.Promise}
  */
  check() {
    if (Ember.isEmpty(arguments)) {
      return this._runMediators("check", this.get("mediators"));
    } else {
      Ember.warn('You probably want to call `checkByName`', Ember.isEmpty(arguments));
      return this.validateByName(...arguments);
    }
  },

  /**
    Method searching mediators by name and executes validation on each of them.
    May be helpful if you'd like to validate just few attributes of the object,
    not all of them.

    @example:
      // Validate only one field
      var promise = user.validateByName("firstName");

      // Validate few fields
      var promise = user.validateByName("firstName", "lastName", "birthday");

    @method validateByName
    @param {String[]} names
    @return {Ember.RSVP.Promise}
  */
  validateByName(...names) {
    return this._runMediators("validate", findMediators.call(this, ...names));
  },

  /**
    Method searching mediators by name and executes check method on each of them.
    May be helpful if you'd like to check just few attributes of the object,
    not all of them.

    @example:
      // Validate field
      var promise = user.checkByName("firstName", "lastName");

    @method checkByName
    @param {String[]} names
    @return {Ember.RSVP.Promise}
  */
  checkByName(...names) {
    return this._runMediators("check", findMediators.call(this, ...names));
  },

  /**
    @method clearErrors
  */
  clearErrors() {
    this.get("errors").clear();
  },

  /**
    @method clearErrorsByName
    @param {String} name
  */
  clearErrorsByName(name) {
    const attributeErrors = this.get("errors").filterBy("attribute", name);
    var errors = this.get("errors");
    attributeErrors.forEach((attr) => {
      errors = errors.without(attr);
    });
    this.set("errors", errors);
  },

  /**
    Iterating over the validators in collection and calling validate method
    each of them to fill object by errors.
    @method _runMediators
    @params {Array} mediators
    @private
    @return {Ember.RSVP.Promise}
  */
  _runMediators(method, mediators) {

    const deferred = RSVP.defer();
    const promise = deferred.promise;

    var promises = mediators.map((mediator) => tryInvoke(mediator, method));
        promises = promises.reduce((previous, item) => previous.concat(item), Ember.A());

    const settledPromise = RSVP.allSettled(promises);

    settledPromise.then((results) => {
      const rejected = Ember.A(results).filterBy("state", "rejected");
      if (rejected.length === 0) {
        Config.LOG_VALIDATION && Logger.log("Validation : <<mixin>> : Validation : _runMediators %c✓ passed", "color: #090");
        deferred.resolve();
      } else {
        Config.LOG_VALIDATION && Logger.log("Validation : <<mixin>> : Validation : _runMediators %c✘ failed", "color: #900");
        deferred.reject(Ember.A(rejected).mapBy("reason"));
      }
    });

    promise.then(() => {}, () => {});
    promise.finally(() => {
      mediators.forEach((mediator) => {
        this.get('errors').notifyPropertyChange(get(mediator, 'attribute'));
      });
    }).then(() => {}, () => {});

    return promise;
  },

  /**
    @method _createValidators
    @param {String} attribute
    @param {Object} validation
    @return {Array}
  */
  _createValidators(attribute, validation) {
    return Ember.A( get(validation, "validators") ).map((description) => {
      const { name, options } = getProperties(description, ["name", "options"]);
      const validator = lookupValidator(name, get(this, "container"));
      return { options, validator };
    });
  },

  /**
    @method _createGroupMediator
    @param {String} attribute
    @param {Object} options
    @param {Object} context
    @return {Array}
  */
  _createGroupMediator(attribute, options={}, context=this) {
    return AttributeMediator.extend(options).create({ context, attribute, options });
  },

  /**
    @method _createValidatorMediator
    @param {Validator} validator
    @param {Object} options
    @param {Object} context
    @return {Array}
  */
  _createValidatorMediator(attribute, validator, options={}, context=this) {
    return ValidatorMediator.extend(options).create({ context, attribute, validator, options });
  },

});
<commit_msg>Add error to required attributes validated by proxy mediator<commit_after>import Ember from 'ember';
import ValidatableMixin from 'ember-validation/mixins/validatable';
import AttributeMediator from 'ember-validation/mediators/attribute';
import ValidatorMediator from 'ember-validation/mediators/validator';
import ProxyMediator from 'ember-validation/mediators/proxy';
import Errors from 'ember-validation/core/errors';
import Config from 'ember-validation/configuration';
import { lookupValidator, lookupPreset } from 'ember-validation/utils/lookup';

const { RSVP, computed, get, assert, Logger, getWithDefault, getProperties, tryInvoke } = Ember;

var findMediators = function(...names) {
    assert("You should provide at least one attribute name", !Ember.isEmpty(names));

    // Iterating over the names (of attributes) and getting mediators.
    const mediators = Ember.A(names).map((name) => {
      let mediator = this.get("mediators").findBy("attribute", name);
      assert("Mediator for attribute named `" + name + "` not found", mediator);
      return mediator;
    });

    return mediators;
};

/**
  @module
  @augments module:ember/Mixin
  @augments module:addon/mixins/validatable
  @public
*/
export default Ember.Mixin.create(ValidatableMixin, Ember.Evented, {

  /**
    Defines the properties that will be merged from the superclass
    (instead of overridden).
    @type Array
    @default null
    @public
  */
  mergedProperties: ["validationScheme"],

  /**
    A collection that contains all validators of the class instance that
    implements current mixin. The property fills up by the `initValidation`
    method from `validationScheme` (contains instruction to create validators).
    @type {Array}
  */
  mediators: computed(() => Ember.A()),

  /**
    This is an instruction for creating validators for an object that implements
    current mixin. The structure of it is following:

    @example:
      validationScheme
        attribute
          options: ATTRIBUTE_VALIDATION_OPTIONS,
          validators[]
            { name: VALIDATOR_NAME, options: VALIDATOR_OPTIONS }

    The method fills `validators` collection by validators and invoke each of
    them on `validate` method.

    @type Object
    @protected
  */
  validationScheme: computed(() => { return {}; }),

  init() {
    this.initErrors();
    this.initValidation();
    this.initStates();
    return this._super(...arguments);
  },

  initStates() {
      // The class already has a state, it means that the class has isValid and
      // isInvalid states as well.
      if (this.get("currentState")) {
          return;
      }

      Ember.defineProperty(this, "isValid", computed("errors.length", () => {
        return this.get("errors.length") === 0;
      }));

      Ember.defineProperty(this, "isInvalid", computed.not("isValid"));
  },

  initErrors() {
    this.get("errors") || this.set("errors", Errors.create());
  },

  /**
    Method creates validators for every object's attribute from the
    `validationScheme`. Validators are gets from the registry by names. Default
    namespace for them is `validator:`, that means that they are should be
    placed in the `validators/` project directory.

    Validators creates and wrappes by an attribute mediator. It has the same
    interface as they are. The mediators triggers events every time when they
    called.

    @method initValidation
    @private
  */
  initValidation() {

    const validationScheme = this.get("validationScheme");

    if (Ember.isBlank(Object.keys(validationScheme))) {
      // The object doesn't have a validation scheme. Probably it has validation
      // schemes on every it's attribute.
      var attributes = get(this.constructor, "attributes");

      attributes && attributes.forEach(item => {
        Config.LOG_VALIDATION && Logger.log("Validation : <<mixin>> : Validation : looking preset for type %s", item.type);
        let { type, name, options } = item;
        if (options && get(options, "preset")) {
          type = get(options, "preset");
        }
        if (!options.isValidatable) { return; }
        let preset = lookupPreset(type, get(this, "container"));
        Config.LOG_VALIDATION && Logger.log("Validation : <<mixin>> : Validation : preset found %o", preset.create(item));
        validationScheme[name] = preset.create(item).evolve();
      });
    }

    return this._initValidationByScheme(validationScheme);
  },

  _initValidationByScheme(validationScheme) {

    // Getting the object's properties that should have validation.
    const attributes = Ember.A(Object.keys(validationScheme));

    attributes.forEach((attribute) => {

      // Instruction to create validators for the attribute
      let validation = get(validationScheme, attribute);

      assert("Every validation should contain validators", validation);

      // A list of the validator instances
      let validatorHashes = this._createValidators(attribute, validation);

      let options = getWithDefault(validation, "options", {});
      let groupMediator = null;

      if (options.proxy) {
        groupMediator = ProxyMediator.extend(options).create({ context: this, attribute, options });
      } else {
        groupMediator = this._createGroupMediator(attribute, options);
      }

      // Iterating over the attribute's validators and wrap each of them by a
      // mediator, that has the same interface then they are.
      validatorHashes.forEach((hash) => {
        let options = get(hash, "options");
        let validator = get(hash, "validator");
        let validatorMediator = this._createValidatorMediator(attribute, validator, options);
        groupMediator.pushObject(validatorMediator);
      });

      groupMediator.on("passed", () => {
        Config.LOG_VALIDATION && Logger.log("Validation : <<mixin>> : Validation : %cevent::Mediator.passed%c on attribute '%s'", "color: #090", null, attribute);
        this.get("errors").remove(attribute);
      });

      groupMediator.on("failed", (message) => {
        Config.LOG_VALIDATION && Logger.log("Validation : <<mixin>> : Validation : %cevent::Mediator.failed%c on attribute '%s' with errors %o", "color: #900", null, attribute, message);
        // To prevent occurring of the inconsistent state error
        // this.transitionTo && this.transitionTo("updated.uncommitted");
        if (!get(message, "options.proxy") || (get(message, "options.proxy") && get(message, "options.required"))) {
          this.get("errors").remove(attribute);
          this.get("errors").add(attribute, message);
          this.get("errors").arrayContentDidChange();
        }
      });

      // @todo: It's broken for proxy validation.
      // groupMediator.on("conditionChanged", () => {
      //   Config.LOG_VALIDATION && Logger.log("Validation : <<mixin>> : Validation : event::Mediator.conditionChanged on attribute '%s'", attribute);
      //   this.get("errors").remove(attribute);
      // });

      // mediators.pushObject(groupMediator);
      this.addMediator(groupMediator);
    });

  },

  /**
    Add mediator to mediators list and fire event

    @method addMediator
    @param Mediator
    @trigger mediatorDidAdd
    @return undefined
  */
  addMediator(mediator) {
    const attrName = get(mediator, "attribute");
    this.get("mediators").pushObject(mediator);
    this.trigger('mediatorDidAdd', mediator);
    Config.LOG_VALIDATION && Logger.log("Validation : <<mixin>> : Validation : addMediator %o for '%s'", mediator, attrName || get(mediator, "validate-path"), get(mediator, 'view.element') );
  },

  /**
    remove mediator from mediators list and fire event

    @method removeMediator
    @param Mediator
    @trigger mediatorWillRemove
    @return undefined
  */
  removeMediator(mediator) {
    const mediators = this.get("mediators");
    const attrName = get(mediator, "attribute");

    if (mediators.indexOf(mediator) !== -1) {
      this.trigger("mediatorWillRemove", mediator);
      mediators.removeObject(mediator);
      mediator.destroy();
      Config.LOG_VALIDATION && Logger.log("Validation : <<mixin>> : Validation : removeMediator %o for '%s'", mediator, attrName);
    }
  },

  /**
    Iterates over the elements of a validation collection, calls `validate` on
    each them, collect result of evaluation and put it into the `errors`
    property of the object.
    @method validate
    @return {Ember.RSVP.Promise}
  */
  validate() {
    if (Ember.isEmpty(arguments)) {
      return this._runMediators("validate", this.get("mediators"));
    } else {
      Ember.warn('You probably want to call `validateByName`', Ember.isEmpty(arguments));
      return this.validateByName(...arguments);
    }
  },

  /**
    This method the same as `validate`, only difference is that the `validate`
    fills errors of the object. This method may be helpful to you, if you want
    to check the object validation, but do not want fill it with errors.
    @method check
    @return {Ember.RSVP.Promise}
  */
  check() {
    if (Ember.isEmpty(arguments)) {
      return this._runMediators("check", this.get("mediators"));
    } else {
      Ember.warn('You probably want to call `checkByName`', Ember.isEmpty(arguments));
      return this.validateByName(...arguments);
    }
  },

  /**
    Method searching mediators by name and executes validation on each of them.
    May be helpful if you'd like to validate just few attributes of the object,
    not all of them.

    @example:
      // Validate only one field
      var promise = user.validateByName("firstName");

      // Validate few fields
      var promise = user.validateByName("firstName", "lastName", "birthday");

    @method validateByName
    @param {String[]} names
    @return {Ember.RSVP.Promise}
  */
  validateByName(...names) {
    return this._runMediators("validate", findMediators.call(this, ...names));
  },

  /**
    Method searching mediators by name and executes check method on each of them.
    May be helpful if you'd like to check just few attributes of the object,
    not all of them.

    @example:
      // Validate field
      var promise = user.checkByName("firstName", "lastName");

    @method checkByName
    @param {String[]} names
    @return {Ember.RSVP.Promise}
  */
  checkByName(...names) {
    return this._runMediators("check", findMediators.call(this, ...names));
  },

  /**
    @method clearErrors
  */
  clearErrors() {
    this.get("errors").clear();
  },

  /**
    @method clearErrorsByName
    @param {String} name
  */
  clearErrorsByName(name) {
    const attributeErrors = this.get("errors").filterBy("attribute", name);
    var errors = this.get("errors");
    attributeErrors.forEach((attr) => {
      errors = errors.without(attr);
    });
    this.set("errors", errors);
  },

  /**
    Iterating over the validators in collection and calling validate method
    each of them to fill object by errors.
    @method _runMediators
    @params {Array} mediators
    @private
    @return {Ember.RSVP.Promise}
  */
  _runMediators(method, mediators) {

    const deferred = RSVP.defer();
    const promise = deferred.promise;

    var promises = mediators.map((mediator) => tryInvoke(mediator, method));
        promises = promises.reduce((previous, item) => previous.concat(item), Ember.A());

    const settledPromise = RSVP.allSettled(promises);

    settledPromise.then((results) => {
      const rejected = Ember.A(results).filterBy("state", "rejected");
      if (rejected.length === 0) {
        Config.LOG_VALIDATION && Logger.log("Validation : <<mixin>> : Validation : _runMediators %c✓ passed", "color: #090");
        deferred.resolve();
      } else {
        Config.LOG_VALIDATION && Logger.log("Validation : <<mixin>> : Validation : _runMediators %c✘ failed", "color: #900");
        deferred.reject(Ember.A(rejected).mapBy("reason"));
      }
    });

    promise.then(() => {}, () => {});
    promise.finally(() => {
      mediators.forEach((mediator) => {
        this.get('errors').notifyPropertyChange(get(mediator, 'attribute'));
      });
    }).then(() => {}, () => {});

    return promise;
  },

  /**
    @method _createValidators
    @param {String} attribute
    @param {Object} validation
    @return {Array}
  */
  _createValidators(attribute, validation) {
    return Ember.A( get(validation, "validators") ).map((description) => {
      const { name, options } = getProperties(description, ["name", "options"]);
      const validator = lookupValidator(name, get(this, "container"));
      return { options, validator };
    });
  },

  /**
    @method _createGroupMediator
    @param {String} attribute
    @param {Object} options
    @param {Object} context
    @return {Array}
  */
  _createGroupMediator(attribute, options={}, context=this) {
    return AttributeMediator.extend(options).create({ context, attribute, options });
  },

  /**
    @method _createValidatorMediator
    @param {Validator} validator
    @param {Object} options
    @param {Object} context
    @return {Array}
  */
  _createValidatorMediator(attribute, validator, options={}, context=this) {
    return ValidatorMediator.extend(options).create({ context, attribute, validator, options });
  },

});
<|endoftext|>


<commit_before>#!/usr/bin/env node
/**
 * Usage:
 * ./get-issues.js "project" "milestone ID"
 *
 * Example:
 *  ./get-issues.js macbre/phantomas 7
 */
var api = require('github'),
	log = require('npmlog'),
	format = require('util').format,
	github;

var argv = process.argv.slice(2),
	user = argv[0].split('/')[0],
	project = argv[0].split('/')[1],
	milestone = parseInt(argv[1], 10);

log.info('GIT', 'Getting closed issues from %s/%s for milestone #%d', user, project, milestone);

github = new api({
	version: "3.0.0",
});

github.issues.repoIssues({
	user: user,
	repo: project,
	milestone: milestone,
	state: 'closed',
	direction: 'asc'
}, function(err, issues) {
	if (err) {
		log.error('API', '#%d: %s', err.code, err.message);
		return;
	}

	var ret = [];

	issues.forEach(function(issue) {
		ret.push(format('* #%d - %s%s',
			issue.number,
			issue.title,
			(issue.user.login !== user ? (' (by @' + issue.user.login + ')') : '')
		));
	});

	console.log(ret.join("\n"));
});
<commit_msg>get-issues: update API call<commit_after>#!/usr/bin/env node
/**
 * Usage:
 * ./get-issues.js "project" "milestone ID"
 *
 * Example:
 *  ./get-issues.js macbre/phantomas 7
 */
var api = require('github'),
	log = require('npmlog'),
	format = require('util').format,
	github;

var argv = process.argv.slice(2),
	user = argv[0].split('/')[0],
	project = argv[0].split('/')[1],
	milestone = parseInt(argv[1], 10);

log.info('GIT', 'Getting closed issues from %s/%s for milestone #%d', user, project, milestone);

github = new api({
	version: "3.0.0",
});

github.issues.getForRepo({
	owner: user,
	repo: project,
	milestone: milestone,
	state: 'closed',
	direction: 'asc'
}, function(err, issues) {
	if (err) {
		log.error('API', '#%d: %s', err.code, err.message);
		return;
	}

	var ret = [];

	issues.forEach(function(issue) {
		var type = issue.labels[0].name; // .reduce((label, acc) => label.name);
		ret.push(format('* #%d [%s] - %s%s',
			issue.number,
			type,
			issue.title,
			(issue.user.login !== user ? (' (by @' + issue.user.login + ')') : '')
		));
	});

	console.log(ret.join("\n"));
});
<|endoftext|>