<commit_before>// ==UserScript==
// @name           Marktplaats; enkel de zoekresultaten.
// @version        1.0
// @namespace      Marktplaats
// @description    * Verbergt bedrijf/webshop advertenties
// @description    * Verbergt betaalde advertenties
// @description    * Schoont pagina's op door verbergen van nutteloze onderdelen
// @description    * Voegt een link toe naar de locatie van de adverteerder
// @description    * Navigeer gemakkelijker doormiddel van sneltoetsen
// @description    * eBay style zoekveld focus op Home
// @description    * In-code mogelijkheid om gemakkelijk een blacklist samen te stellen
// @include        http://www.marktplaats.nl/z.html?*
// @include        http://www.marktplaats.nl/z/*.html?*
// @include        http://www.marktplaats.nl/*
// @include        https://www.marktplaats.nl/*
// @copyright      2019 Arnold de Ruiter (Arndroid)
// @license        MIT License
// @require        https://code.jquery.com/jquery-3.4.1.min.js
// @require        https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant    GM_addStyle
// ==/UserScript==
/* globals jQuery, $, waitForKeyElements */
/*- The @grant directive is needed for GreaseMonkey users.
    A work around for a design change introduced in GM 1.0. It restores the sandbox.
*/

function alterHome() {
    // Laat op Home de checkbox "Zoek in titel en beschrijving" zien als optie.
    $("mp-header.x-scope.mp-header-0.u-stickyHeader").addClass("expandSearchBar mp-Header--expandSearchBar");

    // Automatische focus op de zoekblak, zoals eBay dit heeft
    $('.mp-SearchForm-query #input').focus();
}
waitForKeyElements("mp-header.x-scope.mp-header-0.u-stickyHeader", alterHome);

function preventLoginNudge() {
    localStorage.SeenLoginGate = true;
    var dt = new Date();
    date = dt.getDate();
    dt.setMonth(dt.getMonth() + 1, 1);
    dt.setHours(dt.getHours() -1, 1);
    var date = dt.getFullYear() + "-" + dt.getMonth() + "-" + date + "T";
    var time = dt.getHours() + ":" + dt.getMinutes() + ":" + dt.getSeconds() + "." + dt.getMilliseconds() + "Z";
    localStorage.MpLoginNudgeDismissDate = '["'+date+time+'"]';
}
if (localStorage.getItem("SeenLoginGate") === null) {
    preventLoginNudge();
}

function alterElsewhere() {
    // Laat elders de checkbox "Zoek in titel en beschrijving" zien als optie.
    $('header.u-stickyHeader').attr("data-expanded","true");
    $("div.mp-Header.mp-text-paragraph.mp-cloak").addClass("mp-Header--expandSearchBar");
}
waitForKeyElements("header.u-stickyHeader div.mp-Header.mp-text-paragraph.mp-cloak", alterElsewhere);

function alterSearchResults() {
    // Verberg betaalde advertenties en bedrijven
    $('.mp-Listing--list-item').filter(":contains(Bezorgt in)").hide();
    $('.mp-Listing--list-item').filter(":contains(Topadvertentie)").hide();
    $('.mp-Listing--list-item').filter(":contains(Dagtopper)").hide();
    $('.mp-Listing--list-item').filter(":contains(Heel Nederland)").hide();
    $('.mp-Listing--list-item').filter(":contains(Bezoek website)").hide();

    // Nutteloze "Deze adverteerder heeft meer advertenties" elementen verbergen
    $(".mp-Listing--other-seller").hide();

    // Adverteerders blokkeren
    $('.mp-Listing--list-item').filter(":contains(Example Name 123)").hide();

    // Geef het zoekveld voorrang op functie toetsen hierna
    $('.mp-SearchForm-query #input').on('keyup', function (e) {
        if (e.keyCode == 13) {
            $("button.mp-SearchForm-search").click();
        }
    });

    // Functies binden aan toetsen; volgende, vorige, zoekveld focus.
    $("body").keyup(function(event) {
        // Negeer wanneer er een veld in gebruik is
        if ($(event.target).is('input, textarea')) {
            return;
        }

        // Naar de volgende pagina, met de rechter pijltoets
        if (event.which == '39') {
            $('a.mp-Button--round .mp-svg-arrow-right-white').click();

        // Naar de vorige pagina, met de linker pijltoets
        } else if (event.which == '37') {
            $('a.mp-Button--round .mp-svg-arrow-left-white').click();

        // Focus en selecteer direct het zoekveld door op '\' te drukken (want '/' is in gebruik door Firefox)
        } else if (event.which == '220' ) {
            $('.mp-SearchForm-query #input').select();
        }
    });
}
waitForKeyElements(".mp-Listing--list-item", alterSearchResults);

function addMaps() {
    // Maak locatie klikbaar, met OpenStreetMaps
    var osmUrl = "https://www.openstreetmap.org/search?query="+$("#vip-seller-location span.name").text();
    $("#vip-seller-location .heading span").replaceWith(''+$("#vip-seller-location span.name").text()+'');
}
waitForKeyElements("#vip-seller-location .heading span", addMaps);

function hideDetailCluter() {
    // Opschonen van pagina, waar een ad blocker ruimtes achterlaat.
    $(".cas-other-items").hide();
    $(".banner-viptop").hide();
}
waitForKeyElements(".cas-other-items", hideDetailCluter);

function hideResultCluter() {
    // Opschonen van pagina, waar een ad blocker ruimtes achterlaat.
    $(".mp-Banner").hide();
    $(".mp-Listings__admarktTitle").hide()
}
waitForKeyElements(".mp-Banner", hideResultCluter);
<commit_msg>coreccting the preventing login nudge key value<commit_after>// ==UserScript==
// @name           Marktplaats; enkel de zoekresultaten.
// @version        1.0
// @namespace      Marktplaats
// @description    * Verbergt bedrijf/webshop advertenties
// @description    * Verbergt betaalde advertenties
// @description    * Schoont pagina's op door verbergen van nutteloze onderdelen
// @description    * Voegt een link toe naar de locatie van de adverteerder
// @description    * Navigeer gemakkelijker doormiddel van sneltoetsen
// @description    * eBay style zoekveld focus op Home
// @description    * In-code mogelijkheid om gemakkelijk een blacklist samen te stellen
// @include        http://www.marktplaats.nl/z.html?*
// @include        http://www.marktplaats.nl/z/*.html?*
// @include        http://www.marktplaats.nl/*
// @include        https://www.marktplaats.nl/*
// @copyright      2019 Arnold de Ruiter (Arndroid)
// @license        MIT License
// @require        https://code.jquery.com/jquery-3.4.1.min.js
// @require        https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant    GM_addStyle
// ==/UserScript==
/* globals jQuery, $, waitForKeyElements */
/*- The @grant directive is needed for GreaseMonkey users.
    A work around for a design change introduced in GM 1.0. It restores the sandbox.
*/

function alterHome() {
    // Laat op Home de checkbox "Zoek in titel en beschrijving" zien als optie.
    $("mp-header.x-scope.mp-header-0.u-stickyHeader").addClass("expandSearchBar mp-Header--expandSearchBar");

    // Automatische focus op de zoekblak, zoals eBay dit heeft
    $('.mp-SearchForm-query #input').focus();
}
waitForKeyElements("mp-header.x-scope.mp-header-0.u-stickyHeader", alterHome);

function preventLoginNudge() {
    localStorage.SeenLoginGate = true;
    var dt = new Date();
    date = dt.getDate();
    var minutes = dt.getMinutes();
    minutes = minutes > 9 ? minutes : '0' + minutes;
    var seconds = dt.getSeconds();
    seconds = seconds > 9 ? seconds : '0' + seconds;
    var ms = dt.getMilliseconds();
    ms = ms > 99 ? ms : ms > 9 ? '0' + ms : '00' + ms;
    dt.setMonth(dt.getMonth() + 1, 1);
    dt.setHours(dt.getHours() -1, 1);
    var date = dt.getFullYear() + "-" + dt.getMonth() + "-" + date + "T";
    var time = dt.getHours() + ":" + minutes + ":" + seconds + "." + dt.getMilliseconds() + "Z";
    console.log(date+time);
    localStorage.MpLoginNudgeDismissDate = '["'+date+time+'"]';
}
if (localStorage.getItem("SeenLoginGate") === null) {
    preventLoginNudge();
}

function alterElsewhere() {
    // Laat elders de checkbox "Zoek in titel en beschrijving" zien als optie.
    $('header.u-stickyHeader').attr("data-expanded","true");
    $("div.mp-Header.mp-text-paragraph.mp-cloak").addClass("mp-Header--expandSearchBar");
}
waitForKeyElements("header.u-stickyHeader div.mp-Header.mp-text-paragraph.mp-cloak", alterElsewhere);

function alterSearchResults() {
    // Verberg betaalde advertenties en bedrijven
    $('.mp-Listing--list-item').filter(":contains(Bezorgt in)").hide();
    $('.mp-Listing--list-item').filter(":contains(Topadvertentie)").hide();
    $('.mp-Listing--list-item').filter(":contains(Dagtopper)").hide();
    $('.mp-Listing--list-item').filter(":contains(Heel Nederland)").hide();
    $('.mp-Listing--list-item').filter(":contains(Bezoek website)").hide();

    // Nutteloze "Deze adverteerder heeft meer advertenties" elementen verbergen
    $(".mp-Listing--other-seller").hide();

    // Adverteerders blokkeren
    $('.mp-Listing--list-item').filter(":contains(Example Name 123)").hide();

    // Geef het zoekveld voorrang op functie toetsen hierna
    $('.mp-SearchForm-query #input').on('keyup', function (e) {
        if (e.keyCode == 13) {
            $("button.mp-SearchForm-search").click();
        }
    });

    // Functies binden aan toetsen; volgende, vorige, zoekveld focus.
    $("body").keyup(function(event) {
        // Negeer wanneer er een veld in gebruik is
        if ($(event.target).is('input, textarea')) {
            return;
        }

        // Naar de volgende pagina, met de rechter pijltoets
        if (event.which == '39') {
            $('a.mp-Button--round .mp-svg-arrow-right-white').click();

        // Naar de vorige pagina, met de linker pijltoets
        } else if (event.which == '37') {
            $('a.mp-Button--round .mp-svg-arrow-left-white').click();

        // Focus en selecteer direct het zoekveld door op '\' te drukken (want '/' is in gebruik door Firefox)
        } else if (event.which == '220' ) {
            $('.mp-SearchForm-query #input').select();
        }
    });
}
waitForKeyElements(".mp-Listing--list-item", alterSearchResults);

function addMaps() {
    // Maak locatie klikbaar, met OpenStreetMaps
    var osmUrl = "https://www.openstreetmap.org/search?query="+$("#vip-seller-location span.name").text();
    $("#vip-seller-location .heading span").replaceWith(''+$("#vip-seller-location span.name").text()+'');
}
waitForKeyElements("#vip-seller-location .heading span", addMaps);

function hideDetailCluter() {
    // Opschonen van pagina, waar een ad blocker ruimtes achterlaat.
    $(".cas-other-items").hide();
    $(".banner-viptop").hide();
}
waitForKeyElements(".cas-other-items", hideDetailCluter);

function hideResultCluter() {
    // Opschonen van pagina, waar een ad blocker ruimtes achterlaat.
    $(".mp-Banner").hide();
    $(".mp-Listings__admarktTitle").hide()
}
waitForKeyElements(".mp-Banner", hideResultCluter);
<|endoftext|>


<commit_before>/**************************** EXTERNAL IMPORTS *******************************/

var underscore = require("underscore");

/**************************** INTERNAL IMPORTS *******************************/

var ex = require("../exception.js");
var log = require("../log.js");

/**************************** MODULE CONSTANTS *******************************/

var URL_PATH_SEPARATOR = "/"; // To reduce string creation ever so slightly - this may be a bit anal
var DEFAULT_API_ROOT = "/sauce/apis"; // What the api specific routes will get prepended with, if its not overridden
var DEFAULT_REDIRECT_ROUTE_SUFFIX = "/redirect"; // What we suffix redirect api routes with, if its not overridden

/*************************** OBJECT DEFINITIONS ******************************/

/* The base API type that specific implementations will extends. Supports all
 * the methods required by Sauce API's, but its specifically geared for OAuth
 * 2.0 compliance. This function is a constructor.
 *
 * @param apiName name of the api implementation e.g. 'google' or 'dropbox'
 * @param sauceConfigMap general sauce configuration object e.g. 'config.apiRoot' or 'config.isLoggingDebug'
 *      Properties of sauceConfigMap:
 *          - apiRoot - the url fragment that prepends api routes; defaults to '/sauce/apis'
 * @param apiConfigMap api-specific configuration object e.g. 'config.clientId' or 'config.clientSecret'
 *      Properties of apiConfigMap:
 *          - clientId - String - Client Secret as defined by the api service
 *          - clientSecret - String - Client Id as defined by the api service
 *          - scopes* - String - the permissions for api use; some apis don't use this
 * @param extensionMap settings for pseudo-inheritance - because javascript inheritance is junk e.g. 'config.additionalTokenRequestHeaders'
 *      Properties of extensionMap:
 *          - requiresScopes - Boolean - true if this api needs apiConfigMap.scopes to be defined
 *
 */
module.exports.OAuth2API = function(apiName, sauceConfigMap, apiConfigMap, extensionMap) {
    /********************* INSTANCE VARIABLES *********************/

    if (!apiName) throw new ex.IllegalArgumentException("The name parameter was null.");
    // First check that apiConfigMap was defines
    if (!apiConfigMap) throw new ex.IllegalArgumentException("The api config map parameter was null.");
    // Create the standard auth params
    var clientId = apiConfigMap.clientId; // OAuth Client ID; everyone needs this
    var clientSecret = apiConfigMap.clientSecret; // OAuth Client Secret; everyone needs this too
    var scopes = apiConfigMap.scopes; // OAuth Scopes; not everyone needs this
    // We need to make sure we have at least id and secret
    if (!clientId) throw new ex.IllegalArgumentException("The api config map had a null 'clientId' field.");
    if (!underscore.isString(clientId)) throw new ex.IllegalArgumentException("The api config map 'clientId' field must be a string.");
    if (!clientSecret) throw new ex.IllegalArgumentException("The api config map had a null 'clientSecret' field.");
    if (!underscore.isString(clientSecret)) throw new ex.IllegalArgumentException("The api config map 'clientSecret' field must be a string.");
    // We need to check extension property for 'requiresScopes' - so, of course, the extensionMap has to exist first
    if (!extensionMap) throw new ex.IllegalArgumentException("The extension map parameter was null.");
    // Slap them on the wrist for not having scopes
    if (extensionMap.requiresScopes) {
        if (!scopes) throw new ex.IllegalArgumentException("The '" + apiName + "' api requires the 'scopes' parameter in the api config map, but it was null.");
        else if (!underscore.isString(scopes)) throw new ex.IllegalArgumentException("The '" + apiName + "' api requires the 'scopes' parameter in the api config map, but it has to be a string.");
    }
    // Moving on, lets create the more general config-specific instance variables
    if (!sauceConfigMap) throw new ex.IllegalArgumentException("The sauce config map parameter was null.");
    var apiRoot = (sauceConfigMap.apiRoot) ? sauceConfigMap.apiRoot : DEFAULT_API_ROOT;
    // Some api root corrections for later (never trust the user) - the root must start with a '/' but not end with one
    if (apiRoot.charAt(0) !== URL_PATH_SEPARATOR) apiRoot = URL_PATH_SEPARATOR + apiRoot;
    if (apiRoot.charAt(apiRoot.length) === URL_PATH_SEPARATOR) apiRoot = apiRoot.slice(0, apiRoot.length - 1);
    // Setup the redirect route url up here for ease of reuse
    var redirectRouteUrl = apiRoot + URL_PATH_SEPARATOR + apiName + DEFAULT_REDIRECT_ROUTE_SUFFIX;
    // Now we check the extension map for api urls: we need an 'authUrl', a 'tokenUrl' and, finally, a 'requestUrl'
    var authUrl = extensionMap.authUrl;
    var tokenUrl = extensionMap.tokenUrl;
    var requestUrl = extensionMap.requestUrl;
    // Ugh, more parameter checking
    if (!authUrl) throw new ex.IllegalArgumentException("The extension map had a null 'authUrl' field.");
    if (!underscore.isString(authUrl)) throw new ex.IllegalArgumentException("The extension map 'authUrl' field must be a string.");
    if (!tokenUrl) throw new ex.IllegalArgumentException("The extension map had a null 'tokenUrl' field.");
    if (!underscore.isString(tokenUrl)) throw new ex.IllegalArgumentException("The extension map 'tokenUrl' field must be a string.");
    if (!requestUrl) throw new ex.IllegalArgumentException("The extension map had a null 'requestUrl' field.");
    if (!underscore.isString(authUrl)) throw new ex.IllegalArgumentException("The extension map 'requestUrl' field must be a string.");
    // Ok, we got this far, sweet, we need soome basic state flags
    var routed = false;

    /********************** INSTANCE METHODS **********************/

    // Identifies this API with a human readable string. Doesn't necessarily
    // have to be the apiName.
    this.identity = function() {
        return apiName;
    };
    // Creates all routes required by the OAuth 2.0 roundtrip. This involves creating a redirect
    // route that requests the authentication token.
    this.route = function() {}

}<commit_msg>finished the route method<commit_after>/**************************** EXTERNAL IMPORTS *******************************/

var underscore = require("underscore");

/**************************** INTERNAL IMPORTS *******************************/

var ex = require("../exception.js");
var log = require("../log.js");

/**************************** MODULE CONSTANTS *******************************/

var HTTP_PROTOCOL_PREFIX = "http://"; // Do I really need to explain this
var OAUTH_GRANT_TYPE = "grant_type";
var HTTP_POST_METHOD = "POST"; // Do I really need to explain this
var URL_PATH_SEPARATOR = "/"; // To reduce string creation ever so slightly - this may be a bit anal
var DEFAULT_API_ROOT = "/sauce/apis"; // What the api specific routes will get prepended with, if its not overridden
var DEFAULT_REDIRECT_ROUTE_SUFFIX = "/redirect"; // What we suffix redirect api routes with, if its not overridden
var SAUCE_SESSION_KEY_PREFIX = "_sauce";
var SAUCE_SESSION_AUTH_RETURN_URL_KEY = SAUCE_SESSION_KEY_PREFIX + "ApiAuthReturnUrl"; // This is where we go after OAuth loop has finished

/*************************** OBJECT DEFINITIONS ******************************/

/* The base API type that specific implementations will extends. Supports all
 * the methods required by Sauce API's, but its specifically geared for OAuth
 * 2.0 compliance. This function is a constructor.
 *
 * @param apiName name of the api implementation e.g. 'google' or 'dropbox'
 * @param sauceConfigMap general sauce configuration object e.g. 'config.apiRoot' or 'config.isLoggingDebug'
 *      Properties of sauceConfigMap:
 *          - apiRoot - the url fragment that prepends api routes; defaults to '/sauce/apis'
 * @param apiConfigMap api-specific configuration object e.g. 'config.clientId' or 'config.clientSecret'
 *      Properties of apiConfigMap:
 *          - clientId - String - Client Secret as defined by the api service
 *          - clientSecret - String - Client Id as defined by the api service
 *          - scopes* - String - the permissions for api use; some apis don't use this
 * @param extensionMap settings for pseudo-inheritance - because javascript inheritance is junk e.g. 'config.additionalTokenRequestHeaders'
 *      Properties of extensionMap:
 *          - requiresScopes - Boolean - true if this api needs apiConfigMap.scopes to be defined
 *          - excludesRedirectUri - Boolean - true if this api SHOULD NOT include redirect_uri in token request
 *          - authTokenGrantType - String - Specifies the grant_type parameter for the token request
 *
 */
module.exports.OAuth2API = function(apiName, sauceConfigMap, apiConfigMap, extensionMap) {
    /********************* INSTANCE VARIABLES *********************/

    if (!apiName) throw new ex.IllegalArgumentException("The api name parameter was null.");
    // Lets put session keys together
    var authTokenSessionKey = SAUCE_SESSION_KEY_PREFIX + apiName.charAt(0).toUpperCase() + apiName.slice(1) + "AuthToken";
    // First check that apiConfigMap was defines
    if (!apiConfigMap) throw new ex.IllegalArgumentException("The api config map parameter was null.");
    // Create the standard auth params
    var clientId = apiConfigMap.clientId; // OAuth Client ID; everyone needs this
    var clientSecret = apiConfigMap.clientSecret; // OAuth Client Secret; everyone needs this too
    var scopes = apiConfigMap.scopes; // OAuth Scopes; not everyone needs this
    // We need to make sure we have at least id and secret
    if (!clientId) throw new ex.IllegalArgumentException("The api config map had a null 'clientId' field.");
    if (!underscore.isString(clientId)) throw new ex.IllegalArgumentException("The api config map 'clientId' field must be a string.");
    if (!clientSecret) throw new ex.IllegalArgumentException("The api config map had a null 'clientSecret' field.");
    if (!underscore.isString(clientSecret)) throw new ex.IllegalArgumentException("The api config map 'clientSecret' field must be a string.");
    // We need to check extension property for 'requiresScopes' - so, of course, the extensionMap has to exist first
    if (!extensionMap) throw new ex.IllegalArgumentException("The extension map parameter was null.");
    // Slap them on the wrist for not having scopes
    if (extensionMap.requiresScopes) {
        if (!scopes) throw new ex.IllegalArgumentException("The '" + apiName + "' api requires the 'scopes' parameter in the api config map, but it was null.");
        else if (!underscore.isString(scopes)) throw new ex.IllegalArgumentException("The '" + apiName + "' api requires the 'scopes' parameter in the api config map, but it has to be a string.");
    }
    // Moving on, lets create the more general config-specific instance variables
    if (!sauceConfigMap) throw new ex.IllegalArgumentException("The sauce config map parameter was null.");
    var apiRoot = (sauceConfigMap.apiRoot) ? sauceConfigMap.apiRoot : DEFAULT_API_ROOT;
    // Some api root corrections for later (never trust the user) - the root must start with a '/' but not end with one
    if (apiRoot.charAt(0) !== URL_PATH_SEPARATOR) apiRoot = URL_PATH_SEPARATOR + apiRoot;
    if (apiRoot.charAt(apiRoot.length) === URL_PATH_SEPARATOR) apiRoot = apiRoot.slice(0, apiRoot.length - 1);
    // Setup the redirect route url up here for ease of reuse
    var redirectRouteUrl = apiRoot + URL_PATH_SEPARATOR + apiName + DEFAULT_REDIRECT_ROUTE_SUFFIX;
    // Now we check the extension map for api urls: we need an 'authUrl', a 'tokenUrl' and, finally, a 'requestUrl'
    var authUrl = extensionMap.authUrl;
    var tokenUrl = extensionMap.tokenUrl;
    var requestUrl = extensionMap.requestUrl;
    // Ugh, more parameter checking
    if (!authUrl) throw new ex.IllegalArgumentException("The extension map had a null 'authUrl' field.");
    if (!underscore.isString(authUrl)) throw new ex.IllegalArgumentException("The extension map 'authUrl' field must be a string.");
    if (!tokenUrl) throw new ex.IllegalArgumentException("The extension map had a null 'tokenUrl' field.");
    if (!underscore.isString(tokenUrl)) throw new ex.IllegalArgumentException("The extension map 'tokenUrl' field must be a string.");
    if (!requestUrl) throw new ex.IllegalArgumentException("The extension map had a null 'requestUrl' field.");
    if (!underscore.isString(authUrl)) throw new ex.IllegalArgumentException("The extension map 'requestUrl' field must be a string.");
    // Ok, we got this far, sweet, we need soome basic state flags
    var routed = false;

    /********************** INSTANCE METHODS **********************/

    // Identifies this API with a human readable string. Doesn't necessarily
    // have to be the apiName.
    this.identity = function() {
        return apiName;
    };
    // Creates all routes required by the OAuth 2.0 roundtrip. This involves creating a redirect
    // route that requests the authentication token.
    this.route = function(app) {
        // Only route if its our first time
        if (!routed) {
            // Gotta make sure we have the app defined
            if (!app) throw new ex.IllegalArgumentException("The express app parameter was null.");
            // Now we register the redirect route
            app.get(redirectRouteUrl, function(req, res) {
                var code = req.param("code");
                // Make sure we have code before we go anywhere
                if (!code) {
                    // TODO we need failure callback here
                    log.e("The 'code' parameter received in '" + apiName + "' api redirect was null.");
                    // Go back to where we came from, because this didn't work
                    if (req.session[SAUCE_SESSION_AUTH_RETURN_URL_KEY]) res.redirect(req.session[SAUCE_SESSION_AUTH_RETURN_URL_KEY]);
                    else {
                        // Uh oh, return url wasn't provided - that's not fun
                        log.e("The sauce return url was null after finishing authnetication for '" + apiName + "' api, so we have to send a 404.");
                        res.send(404);
                    }
                    return;
                } else {
                    // Next, we need to make the form query tring map for the token request
                    var tokenRequestParams = {};
                    tokenRequestParams["code"] = code;
                    tokenRequestParams["client_id"] = clientId;
                    tokenRequestParams["client_secret"] = clientSecret;
                    // Means we need to define grant_type
                    if (!extensionMap.excludesRedirectUri) {
                        tokenRequestParams["redirect_uri"] = HTTP_PROTOCOL_PREFIX + req.get("host") + redirectRouteUrl;
                    }
                    if (extensionMap.authTokenGrantType) {
                        if (underscore.isString(extensionMap.authTokenGrantType)) {
                            tokenRequestParams[OAUTH_GRANT_TYPE] = extensionMap.authTokenGrantType;
                        } else {
                            log.w("The extension map 'authTokenGrantType' field was defined, but not as a string.");
                        }
                    }
                    // Time to make the request!
                    request({
                        url: tokenUrl,
                        form: tokenRequestParams,
                        method: HTTP_POST_METHOD
                    }, function(error, response, body) {
                        if (error || response.statusCode > 299) {
                            if (!error) error = new ex.APICallFailureException("API call to URL '" + tokenUrl + "' failed with status code " + response.statusCode + ". The body was as follows: \n" + body);
                            log.e("'" + apiName + "' api authentication failed: " + error);
                            // TODO we need failure callback here
                        } else {
                            // Successfully got the token, lets boogie
                            var payload = JSON.parse(body);
                            req.session[authTokenSessionKey] = payload.access_token;
                            // Check if there is a timeout, if so, we need to set a timer
                            if (payload.expires_in) {
                                setTimeout(function() {
                                    req.session[authTokenSessionKey] = null;
                                }, payload.expires_in * 1000);
                                log.d("'" + apiName + "' api authentication token expires in " + (payload.expires_in / 60) + " minutes.");
                            }
                            log.d("'" + apiName + "' api authentication token '" + payload.access_token + "' obtained successfully.");
                        }
                        // We're done, lets go home
                        if (req.session[SAUCE_SESSION_AUTH_RETURN_URL_KEY]) {
                            res.redirect(req.session[SAUCE_SESSION_AUTH_RETURN_URL_KEY]);
                            req.session[SAUCE_SESSION_AUTH_RETURN_URL_KEY] = null;
                        } else {
                            // Uh oh, return url wasn't provided - that's not fun
                            log.e("The sauce return url was null after finishing authnetication for '" + apiName + "' api, so we have to send a 404.");
                            res.send(404);
                        }
                    });
                };
            });
        } else {
            throw new ex.APIAlreadyRoutedException(apiName);
        }
    }

}<|endoftext|>


<commit_before>import * as path from 'path';
import * as fs from 'fs';
import gulp from 'gulp';
import { env } from 'gulp-util';
import gulpif from 'gulp-if';
import uglify from 'gulp-uglify';
import babel from 'gulp-babel';
import babelHelpers from 'gulp-babel-external-helpers';
import concat from 'gulp-concat';
import data from 'gulp-data';
import del from 'del';
import merge from 'merge-stream';
import mkdirp from 'mkdirp';
import rename from 'gulp-rename';
import rjs from 'requirejs';
import runseq from 'run-sequence';
import template from 'gulp-template';
import zip from 'gulp-zip';
import webpack from 'webpack';
import packg from './package.json';

gulp.task('clean-lib', () => del('lib'));
gulp.task('clean-build', () => del('build'));
gulp.task('clean', ['clean-lib', 'clean-build']);

gulp.task('babel', () =>
  gulp.src('src/**/*.js')
    .pipe(babel({
      presets: ['extplug'],
      plugins: ['external-helpers'],
    }))
    .pipe(babelHelpers('_babelHelpers.js', 'var'))
    .pipe(gulp.dest('lib/'))
);

function createWebpackConfig(options) {
  return {
    context: path.join(__dirname, './src'),
    entry: ['./ExtPlug'],
    watch: !!options.watch,

    module: {
      loaders: [
        { test: /\.json$/, loader: 'json' },
        {
          test: /\.js$/,
          exclude: /node_modules/,
          loader: 'babel',
          query: {
            presets: 'extplug',
            plugins: 'external-helpers',
          },
        },
      ],
    },

    output: {
      path: path.join(__dirname, './build'),
      filename: 'source.js',
      library: 'extplug/__internalExtPlug__',
      libraryTarget: 'amd',
    },

    resolve: {
      alias: {
        extplug: path.join(__dirname, './src'),
      },
    },

    externals: [
      'jquery',
      'underscore',
      'backbone',
      'plug-modules',
      'lang/Lang',
      (context, request, cb) => {
        if (/^plug\//.test(request)) {
          cb(null, `amd plug-modules!${request}`);
        } else {
          cb();
        }
      },
    ],

    plugins: [
      options.minify && new webpack.optimize.UglifyJsPlugin(),
    ].filter(Boolean)
  };
}

gulp.task('build:source', done => {
  webpack(createWebpackConfig({
    minify: !!env.minify
  }), done);
});

gulp.task('build:loader', ['babel'], done => {
  rjs.optimize({
    baseUrl: './',
    name: 'extplug/loader',
    paths: {
      jquery: 'empty:',
      underscore: 'empty:',
      backbone: 'empty:',
      plug: 'empty:',
      'extplug/loader': 'lib/main',
      'plug-modules': 'node_modules/plug-modules/plug-modules',
    },
    optimize: 'none',
    out(text) {
      mkdirp('build', e => {
        if (e) {
          done(e);
        } else {
          fs.writeFile('build/loader.js', text, done);
        }
      });
    },
  });
});

gulp.task('concat', ['babel', 'build:loader', 'build:source'], () =>
  gulp.src(['lib/_babelHelpers.js', 'build/loader.js', 'build/source.js'])
    .pipe(concat('extplug.code.js'))
    .pipe(gulp.dest('build/'))
);

gulp.task('build', ['concat'], () =>
  gulp.src('src/loader.js.template')
    .pipe(data((file, cb) => {
      fs.readFile('build/extplug.code.js', 'utf8', (e, c) => {
        if (e) cb(e);
        else cb(null, { code: c });
      });
    }))
    .pipe(template())
    .pipe(gulpif(!!env.minify, uglify({
      compress: {
        screw_ie8: true,
        pure_getters: true,
        unsafe: true,
      },
      output: { screw_ie8: true },
      mangle: { toplevel: true },
    })))
    .pipe(rename('extplug.js'))
    .pipe(gulp.dest('build/'))
);

gulp.task('chrome-unpacked', () => merge(
  gulp.src(['extensions/chrome/main.js', 'extensions/chrome/manifest.json'])
    .pipe(template(packg))
    .pipe(gulp.dest('build/chrome/')),

  gulp.src(['img/icon*.png'])
    .pipe(gulp.dest('build/chrome/img/')),

  gulp.src(['build/extplug.js'])
    .pipe(concat('extplug.js'))
    .pipe(gulp.dest('build/chrome/'))
));

gulp.task('chrome-pack', () =>
  gulp.src('build/chrome/*')
    .pipe(zip('extplug.chrome.zip'))
    .pipe(gulp.dest('build/'))
);

gulp.task('chrome', cb => {
  runseq('chrome-unpacked', 'chrome-pack', cb);
});

gulp.task('firefox', () => merge(
  gulp.src(['extensions/firefox/*'])
    .pipe(template(packg))
    .pipe(gulp.dest('build/firefox/')),

  gulp.src(['build/extplug.js'])
    .pipe(gulp.dest('build/firefox/data/'))
));

gulp.task('userscript-meta', () =>
  gulp.src(['extensions/userscript/extplug.user.js'])
    .pipe(template(packg))
    .pipe(rename('extplug.meta.user.js'))
    .pipe(gulp.dest('build/'))
);

gulp.task('userscript', ['userscript-meta'], () =>
  gulp.src(['build/extplug.meta.user.js', 'build/extplug.js'])
    .pipe(concat('extplug.user.js'))
    .pipe(gulp.dest('build/'))
);

gulp.task('default', cb => {
  runseq(
    'clean-build',
    'build',
    ['chrome', 'firefox', 'userscript'],
    cb
  );
});
<commit_msg>fix commas<commit_after>import * as path from 'path';
import * as fs from 'fs';
import gulp from 'gulp';
import { env } from 'gulp-util';
import gulpif from 'gulp-if';
import uglify from 'gulp-uglify';
import babel from 'gulp-babel';
import babelHelpers from 'gulp-babel-external-helpers';
import concat from 'gulp-concat';
import data from 'gulp-data';
import del from 'del';
import merge from 'merge-stream';
import mkdirp from 'mkdirp';
import rename from 'gulp-rename';
import rjs from 'requirejs';
import runseq from 'run-sequence';
import template from 'gulp-template';
import zip from 'gulp-zip';
import webpack from 'webpack';
import packg from './package.json';

gulp.task('clean-lib', () => del('lib'));
gulp.task('clean-build', () => del('build'));
gulp.task('clean', ['clean-lib', 'clean-build']);

gulp.task('babel', () =>
  gulp.src('src/**/*.js')
    .pipe(babel({
      presets: ['extplug'],
      plugins: ['external-helpers'],
    }))
    .pipe(babelHelpers('_babelHelpers.js', 'var'))
    .pipe(gulp.dest('lib/'))
);

function createWebpackConfig(options) {
  return {
    context: path.join(__dirname, './src'),
    entry: ['./ExtPlug'],
    watch: !!options.watch,

    module: {
      loaders: [
        { test: /\.json$/, loader: 'json' },
        {
          test: /\.js$/,
          exclude: /node_modules/,
          loader: 'babel',
          query: {
            presets: 'extplug',
            plugins: 'external-helpers',
          },
        },
      ],
    },

    output: {
      path: path.join(__dirname, './build'),
      filename: 'source.js',
      library: 'extplug/__internalExtPlug__',
      libraryTarget: 'amd',
    },

    resolve: {
      alias: {
        extplug: path.join(__dirname, './src'),
      },
    },

    externals: [
      'jquery',
      'underscore',
      'backbone',
      'plug-modules',
      'lang/Lang',
      (context, request, cb) => {
        if (/^plug\//.test(request)) {
          cb(null, `amd plug-modules!${request}`);
        } else {
          cb();
        }
      },
    ],

    plugins: [
      options.minify && new webpack.optimize.UglifyJsPlugin(),
    ].filter(Boolean),
  };
}

gulp.task('build:source', done => {
  webpack(createWebpackConfig({
    minify: !!env.minify,
  }), done);
});

gulp.task('build:loader', ['babel'], done => {
  rjs.optimize({
    baseUrl: './',
    name: 'extplug/loader',
    paths: {
      jquery: 'empty:',
      underscore: 'empty:',
      backbone: 'empty:',
      plug: 'empty:',
      'extplug/loader': 'lib/main',
      'plug-modules': 'node_modules/plug-modules/plug-modules',
    },
    optimize: 'none',
    out(text) {
      mkdirp('build', e => {
        if (e) {
          done(e);
        } else {
          fs.writeFile('build/loader.js', text, done);
        }
      });
    },
  });
});

gulp.task('concat', ['babel', 'build:loader', 'build:source'], () =>
  gulp.src(['lib/_babelHelpers.js', 'build/loader.js', 'build/source.js'])
    .pipe(concat('extplug.code.js'))
    .pipe(gulp.dest('build/'))
);

gulp.task('build', ['concat'], () =>
  gulp.src('src/loader.js.template')
    .pipe(data((file, cb) => {
      fs.readFile('build/extplug.code.js', 'utf8', (e, c) => {
        if (e) cb(e);
        else cb(null, { code: c });
      });
    }))
    .pipe(template())
    .pipe(gulpif(!!env.minify, uglify({
      compress: {
        screw_ie8: true,
        pure_getters: true,
        unsafe: true,
      },
      output: { screw_ie8: true },
      mangle: { toplevel: true },
    })))
    .pipe(rename('extplug.js'))
    .pipe(gulp.dest('build/'))
);

gulp.task('chrome-unpacked', () => merge(
  gulp.src(['extensions/chrome/main.js', 'extensions/chrome/manifest.json'])
    .pipe(template(packg))
    .pipe(gulp.dest('build/chrome/')),

  gulp.src(['img/icon*.png'])
    .pipe(gulp.dest('build/chrome/img/')),

  gulp.src(['build/extplug.js'])
    .pipe(concat('extplug.js'))
    .pipe(gulp.dest('build/chrome/'))
));

gulp.task('chrome-pack', () =>
  gulp.src('build/chrome/*')
    .pipe(zip('extplug.chrome.zip'))
    .pipe(gulp.dest('build/'))
);

gulp.task('chrome', cb => {
  runseq('chrome-unpacked', 'chrome-pack', cb);
});

gulp.task('firefox', () => merge(
  gulp.src(['extensions/firefox/*'])
    .pipe(template(packg))
    .pipe(gulp.dest('build/firefox/')),

  gulp.src(['build/extplug.js'])
    .pipe(gulp.dest('build/firefox/data/'))
));

gulp.task('userscript-meta', () =>
  gulp.src(['extensions/userscript/extplug.user.js'])
    .pipe(template(packg))
    .pipe(rename('extplug.meta.user.js'))
    .pipe(gulp.dest('build/'))
);

gulp.task('userscript', ['userscript-meta'], () =>
  gulp.src(['build/extplug.meta.user.js', 'build/extplug.js'])
    .pipe(concat('extplug.user.js'))
    .pipe(gulp.dest('build/'))
);

gulp.task('default', cb => {
  runseq(
    'clean-build',
    'build',
    ['chrome', 'firefox', 'userscript'],
    cb
  );
});
<|endoftext|>


<commit_before>var tests = [
    'tests/vendor/jasmine/jasmine-jquery',
    // Load mocks and vendor init
    //'tests/mocks/init',

    'tests/spec/rich-application',
    'tests/spec/rich-autolayout-constraints',
    'tests/spec/rich-autolayout-modifiers',
    'tests/spec/rich-autolayout-utils',
    'tests/spec/rich-autolayout',
    'tests/spec/rich-collectionview',
    'tests/spec/rich-itemview-events',
    'tests/spec/rich-region',
    // 'tests/spec/rich-scrollview',
    'tests/spec/rich-utils',
    'tests/spec/rich-vfl',
    'tests/spec/rich-view-animate',
    'tests/spec/rich-view-className',
    'tests/spec/rich-view-constraints',
    'tests/spec/rich-view-core',
    'tests/spec/rich-view-size',
    'tests/spec/rich-view-subviews',
    'tests/spec/rich-view-zindex',

];

requirejs.config({
    baseUrl: '/base',

    shim: {
        'tests/vendor/jasmine/jasmine-jquery': {
            'deps': ['jquery']
        },
    },

    deps: tests,

    callback: function(){
        jasmine.getFixtures().fixturesPath = '/base/tests/fixtures';
        window.__karma__.start();
    }
});
<commit_msg>enables scrollview tests<commit_after>var tests = [
    'tests/vendor/jasmine/jasmine-jquery',
    // Load mocks and vendor init
    //'tests/mocks/init',

    'tests/spec/rich-application',
    'tests/spec/rich-autolayout-constraints',
    'tests/spec/rich-autolayout-modifiers',
    'tests/spec/rich-autolayout-utils',
    'tests/spec/rich-autolayout',
    'tests/spec/rich-collectionview',
    'tests/spec/rich-itemview-events',
    'tests/spec/rich-region',
    'tests/spec/rich-scrollview',
    'tests/spec/rich-utils',
    'tests/spec/rich-vfl',
    'tests/spec/rich-view-animate',
    'tests/spec/rich-view-className',
    'tests/spec/rich-view-constraints',
    'tests/spec/rich-view-core',
    'tests/spec/rich-view-size',
    'tests/spec/rich-view-subviews',
    'tests/spec/rich-view-zindex',

];

requirejs.config({
    baseUrl: '/base',

    shim: {
        'tests/vendor/jasmine/jasmine-jquery': {
            'deps': ['jquery']
        },
    },

    deps: tests,

    callback: function(){
        jasmine.getFixtures().fixturesPath = '/base/tests/fixtures';
        window.__karma__.start();
    }
});
<|endoftext|>


<commit_before>(function (module) {
    module.controller('CreateProcessController', CreateProcessController);
    CreateProcessController.$inject = ["projectsService", "$stateParams", "selectItems",
        "template", "$modal", "processEdit", "$previousState", "$state"];

    function CreateProcessController(projectsService, $stateParams, selectItems, template,
                                     $modal, processEdit, $previousState, $state) {
        var ctrl = this;
        ctrl.process = template;
        ctrl.chooseSamples = chooseSamples;
        ctrl.chooseInputFiles = chooseInputFiles;
        ctrl.chooseOutputFiles = chooseOutputFiles;
        ctrl.linkFilesToSample = linkFilesToSample;
        ctrl.cancel = gotoPreviousState;
        ctrl.submit = submit;
        ctrl.submitAndAnother = submitAndAnother;
        ctrl.remove = removeById;
        ctrl.submitSample = submitSample;
        ctrl.doc = {value: []};
        ctrl.sample = {
            name: '',
            description: '',
            old_properties: [],
            new_properties: [],
            files: []
        };

        ctrl.sampleGroupSizing = 'set-size';
        ctrl.sampleGroupSize = 10;
        ctrl.sampleGroup = false;

        setPreviousStateMemo();

        /////////////////////////

        function chooseSamples() {
            selectItems.open('samples').then(function (item) {
                var uniqueSamples = differenceById(item.samples, ctrl.process.input_samples);
                uniqueSamples.forEach(function (sample) {
                    ctrl.process.input_samples.push({
                        id: sample.id,
                        name: sample.name,
                        old_properties: [],
                        new_properties: [],
                        property_set_id: sample.property_set_id,
                        files: []
                    });
                });
            });
        }

        function chooseInputFiles() {
            selectItems.open('files').then(function (item) {
                var uniqueFiles = differenceById(item.files, ctrl.process.input_files);
                uniqueFiles.forEach(function (file) {
                    ctrl.process.input_files.push({
                        id: file.id,
                        name: file.name,
                        mediatype: file.mediatype
                    });
                });
            });
        }

        function chooseOutputFiles() {
            selectItems.open('files').then(function (item) {
                var uniqueFiles = differenceById(item.files, ctrl.process.output_files);
                uniqueFiles.forEach(function (file) {
                    ctrl.process.output_files.push({
                        id: file.id,
                        name: file.name,
                        mediatype: file.mediatype
                    });
                });
            });
        }

        function gotoPreviousState() {
            $previousState.go('processes_previous');
            $previousState.forget('processes_previous');
        }

        function submitAndAnother() {
            if (ctrl.process.process_name === 'As Received') {
                filloutSampleProperties();
            }
            projectsService.createProjectProcess($stateParams.id, ctrl.process).then(function () {
                ctrl.doc.value.length = 0;
                $state.go('projects.project.processes.create', {process: p.process_name, process_id: p.id});
            });
        }

        function submit() {
            projectsService.createProjectProcess($stateParams.id, ctrl.process).then(
                function success() {
                    ctrl.doc.value.length = 0;
                    gotoPreviousState();
                },

                function failure(e) {
                    console.log('failed to save process', e);
                }
            );
        }

        function submitSample() {
            filloutSampleProperties();
            submit();
        }

        function filloutSampleProperties() {
            if (ctrl.doc.value.length) {
                var composition = ctrl.doc.value.map(function(c) {
                    return {
                        element: c.element,
                        value: c.value
                    };
                });
                var measurement = {
                    name: 'Composition',
                    attribute: 'composition',
                    measurements: [
                        {
                            is_best_measure: true,
                            value: composition,
                            unit: ctrl.doc.unit,
                            _type: 'composition'
                        }
                    ]
                };
                ctrl.sample.new_properties.push(measurement);
            }
            ctrl.sample.has_group = ctrl.sampleGroup;
            if (ctrl.sampleGroupSizing == 'set-size') {
                ctrl.sample.group_size = ctrl.sampleGroupSize;
            } else {
                ctrl.sample.group_size = 0;
            }
            ctrl.process.output_samples.push(ctrl.sample);
        }

        // setPreviousStateMemo sets the process_previous memo to the previous state. It
        // only sets the memo if the previous state doesn't exist. If it does exist that
        // means that create has been entered multiple times.
        function setPreviousStateMemo() {
            var previousMemo = $previousState.get('processes_previous');
            var previousState = $previousState.get();
            if (!previousMemo) {
                $previousState.memo('processes_previous');
            } else {
                // previousMemo is not null, but the user may not have cancelled to clear
                // the previousMemo. That is they may have gone to the tabs rather than
                // the cancel button to get out of a create.
                if (previousState.state.name !== 'projects.project.processes.create') {
                    // User did not cancel, so we have an old state. Save new previous state
                    // so user will go where they expect if they press the cancel button.
                    $previousState.memo('processes_previous');
                }
            }
        }

        function linkFilesToSample(sample, input_files, output_files) {
            var modal = $modal.open({
                templateUrl: 'application/core/projects/project/processes/link-files-to-sample.html',
                controller: 'LinkFilesToSampleController',
                controllerAs: 'sample',
                resolve: {
                    files: function () {
                        var files = input_files.concat(output_files);
                        var linkedFilesById = _.indexBy(sample.files, 'id');
                        var setLinked = function (f) {
                            f.linked = (f.id in linkedFilesById);
                            return f;
                        };

                        return files.map(setLinked);
                    },

                    sample: function () {
                        return sample;
                    },

                    project: function () {
                        return {};
                    }
                }
            });
            modal.result.then(function (linkedFiles) {
                sample = processEdit.refreshSample(linkedFiles, sample);
            });
        }
    }
}(angular.module('materialscommons')));<commit_msg>Check that the sample has a name.<commit_after>(function (module) {
    module.controller('CreateProcessController', CreateProcessController);
    CreateProcessController.$inject = ["projectsService", "$stateParams", "selectItems",
        "template", "$modal", "processEdit", "$previousState", "$state", "toastr"];

    function CreateProcessController(projectsService, $stateParams, selectItems, template,
                                     $modal, processEdit, $previousState, $state, toastr) {
        var ctrl = this;
        ctrl.process = template;
        ctrl.chooseSamples = chooseSamples;
        ctrl.chooseInputFiles = chooseInputFiles;
        ctrl.chooseOutputFiles = chooseOutputFiles;
        ctrl.linkFilesToSample = linkFilesToSample;
        ctrl.cancel = gotoPreviousState;
        ctrl.submit = submit;
        ctrl.submitAndAnother = submitAndAnother;
        ctrl.remove = removeById;
        ctrl.submitSample = submitSample;
        ctrl.doc = {value: []};
        ctrl.sample = {
            name: '',
            description: '',
            old_properties: [],
            new_properties: [],
            files: []
        };

        ctrl.sampleGroupSizing = 'set-size';
        ctrl.sampleGroupSize = 10;
        ctrl.sampleGroup = false;

        setPreviousStateMemo();

        /////////////////////////

        function chooseSamples() {
            selectItems.open('samples').then(function (item) {
                var uniqueSamples = differenceById(item.samples, ctrl.process.input_samples);
                uniqueSamples.forEach(function (sample) {
                    ctrl.process.input_samples.push({
                        id: sample.id,
                        name: sample.name,
                        old_properties: [],
                        new_properties: [],
                        property_set_id: sample.property_set_id,
                        files: []
                    });
                });
            });
        }

        function chooseInputFiles() {
            selectItems.open('files').then(function (item) {
                var uniqueFiles = differenceById(item.files, ctrl.process.input_files);
                uniqueFiles.forEach(function (file) {
                    ctrl.process.input_files.push({
                        id: file.id,
                        name: file.name,
                        mediatype: file.mediatype
                    });
                });
            });
        }

        function chooseOutputFiles() {
            selectItems.open('files').then(function (item) {
                var uniqueFiles = differenceById(item.files, ctrl.process.output_files);
                uniqueFiles.forEach(function (file) {
                    ctrl.process.output_files.push({
                        id: file.id,
                        name: file.name,
                        mediatype: file.mediatype
                    });
                });
            });
        }

        function gotoPreviousState() {
            $previousState.go('processes_previous');
            $previousState.forget('processes_previous');
        }

        function submitAndAnother() {
            if (ctrl.process.process_name === 'As Received' && ctrl.sample.name === '') {
                toastr.error("You must specify a sample name", 'Error', {closeButton: true});
                return;
            }
            if (ctrl.process.process_name === 'As Received') {
                filloutSampleProperties();
            }
            projectsService.createProjectProcess($stateParams.id, ctrl.process).then(function () {
                ctrl.doc.value.length = 0;
                $state.go('projects.project.processes.create', {process: p.process_name, process_id: p.id});
            });
        }

        function submit() {
            projectsService.createProjectProcess($stateParams.id, ctrl.process).then(
                function success() {
                    ctrl.doc.value.length = 0;
                    gotoPreviousState();
                },

                function failure(e) {
                    console.log('failed to save process', e);
                }
            );
        }

        function submitSample() {
            if (ctrl.sample.name === '') {
                toastr.error("You must specify a sample name", 'Error', {closeButton: true});
                return;
            }
            filloutSampleProperties();
            submit();
        }

        function filloutSampleProperties() {
            if (ctrl.doc.value.length) {
                var composition = ctrl.doc.value.map(function(c) {
                    return {
                        element: c.element,
                        value: c.value
                    };
                });
                var measurement = {
                    name: 'Composition',
                    attribute: 'composition',
                    measurements: [
                        {
                            is_best_measure: true,
                            value: composition,
                            unit: ctrl.doc.unit,
                            _type: 'composition'
                        }
                    ]
                };
                ctrl.sample.new_properties.push(measurement);
            }
            ctrl.sample.has_group = ctrl.sampleGroup;
            if (ctrl.sampleGroupSizing == 'set-size') {
                ctrl.sample.group_size = ctrl.sampleGroupSize;
            } else {
                ctrl.sample.group_size = 0;
            }
            ctrl.process.output_samples.push(ctrl.sample);
        }

        // setPreviousStateMemo sets the process_previous memo to the previous state. It
        // only sets the memo if the previous state doesn't exist. If it does exist that
        // means that create has been entered multiple times.
        function setPreviousStateMemo() {
            var previousMemo = $previousState.get('processes_previous');
            var previousState = $previousState.get();
            if (!previousMemo) {
                $previousState.memo('processes_previous');
            } else {
                // previousMemo is not null, but the user may not have cancelled to clear
                // the previousMemo. That is they may have gone to the tabs rather than
                // the cancel button to get out of a create.
                if (previousState.state.name !== 'projects.project.processes.create') {
                    // User did not cancel, so we have an old state. Save new previous state
                    // so user will go where they expect if they press the cancel button.
                    $previousState.memo('processes_previous');
                }
            }
        }

        function linkFilesToSample(sample, input_files, output_files) {
            var modal = $modal.open({
                templateUrl: 'application/core/projects/project/processes/link-files-to-sample.html',
                controller: 'LinkFilesToSampleController',
                controllerAs: 'sample',
                resolve: {
                    files: function () {
                        var files = input_files.concat(output_files);
                        var linkedFilesById = _.indexBy(sample.files, 'id');
                        var setLinked = function (f) {
                            f.linked = (f.id in linkedFilesById);
                            return f;
                        };

                        return files.map(setLinked);
                    },

                    sample: function () {
                        return sample;
                    },

                    project: function () {
                        return {};
                    }
                }
            });
            modal.result.then(function (linkedFiles) {
                sample = processEdit.refreshSample(linkedFiles, sample);
            });
        }
    }
}(angular.module('materialscommons')));<|endoftext|>


<commit_before>import gulp from 'gulp';
import babel from 'gulp-babel';
import uglify from 'gulp-uglify';
import cleancss from 'gulp-clean-css';
import autoprefixer from 'gulp-autoprefixer';
import htmlmin from 'gulp-htmlmin';
import imagemin from 'gulp-imagemin';
import sourcemaps from 'gulp-sourcemaps';

const PATHS = {
    views: 'views/**/*.html',
    stylesheets: 'static/stylesheets/**/*.css',
    javascripts: 'static/javascripts/**/*.js',
    images: 'static/images/**/*',
    fonts: 'static/fonts/**/*',
    manifest: 'static/manifest.json'
};
const BUILD_DIRECTORY = 'build';

gulp.task('buildstyles', _ => {
    return gulp.src(PATHS.stylesheets, { base: '.' })
        .pipe(sourcemaps.init())
        .pipe(autoprefixer())
        .pipe(cleancss())
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest(BUILD_DIRECTORY));
});

gulp.task('buildscripts', _ => {
    return gulp.src(PATHS.javascripts, { base: '.' })
        .pipe(sourcemaps.init())
        .pipe(babel())
        .pipe(uglify())
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest(BUILD_DIRECTORY));
});

gulp.task('buildviews', _ => {
    return gulp.src(PATHS.views, { base: '.' })
        .pipe(htmlmin({
            collapseBooleanAttributes: true,
            collapseWhitespace: true,
            minifyCSS: true,
            minifyJS: true,
            removeComments: true
        }))
        .pipe(gulp.dest(BUILD_DIRECTORY));
});

gulp.task('optimizeimages', _ => {
    return gulp.src(PATHS.images, { base: '.' })
        .pipe(imagemin())
        .pipe(gulp.dest(BUILD_DIRECTORY));
});

gulp.task('copystatic', _ => {
    return gulp.src([PATHS.fonts, PATHS.manifest], { base: '.' })
        .pipe(gulp.dest(BUILD_DIRECTORY));
});

gulp.task('default', [
    'buildstyles',
    'buildscripts',
    'buildviews',
    'optimizeimages',
    'copystatic'
]);
<commit_msg>update source paths in gulpfile<commit_after>import gulp from 'gulp';
import babel from 'gulp-babel';
import uglify from 'gulp-uglify';
import cleancss from 'gulp-clean-css';
import autoprefixer from 'gulp-autoprefixer';
import htmlmin from 'gulp-htmlmin';
import imagemin from 'gulp-imagemin';
import sourcemaps from 'gulp-sourcemaps';

const PATHS = {
    views: 'server/views/**/*.html',
    stylesheets: 'public/stylesheets/**/*.css',
    javascripts: 'public/javascripts/**/*.js',
    images: 'public/images/**/*',
    fonts: 'public/fonts/**/*',
    manifest: 'public/manifest.json'
};
const BUILD_DIRECTORY = 'build';

gulp.task('buildstyles', _ => {
    return gulp.src(PATHS.stylesheets, { base: '.' })
        .pipe(sourcemaps.init())
        .pipe(autoprefixer())
        .pipe(cleancss())
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest(BUILD_DIRECTORY));
});

gulp.task('buildscripts', _ => {
    return gulp.src(PATHS.javascripts, { base: '.' })
        .pipe(sourcemaps.init())
        .pipe(babel())
        .pipe(uglify())
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest(BUILD_DIRECTORY));
});

gulp.task('buildviews', _ => {
    return gulp.src(PATHS.views, { base: '.' })
        .pipe(htmlmin({
            collapseBooleanAttributes: true,
            collapseWhitespace: true,
            minifyCSS: true,
            minifyJS: true,
            removeComments: true
        }))
        .pipe(gulp.dest(BUILD_DIRECTORY));
});

gulp.task('optimizeimages', _ => {
    return gulp.src(PATHS.images, { base: '.' })
        .pipe(imagemin())
        .pipe(gulp.dest(BUILD_DIRECTORY));
});

gulp.task('copystatic', _ => {
    return gulp.src([PATHS.fonts, PATHS.manifest], { base: '.' })
        .pipe(gulp.dest(BUILD_DIRECTORY));
});

gulp.task('default', [
    'buildstyles',
    'buildscripts',
    'buildviews',
    'optimizeimages',
    'copystatic'
]);
<|endoftext|>


<commit_before>var path = require('path');
var webpack = require('./webpack.config');

module.exports = function (config) {
  config.set({
    basePath: '.',
    frameworks: ['mocha'],
    reporters: ['mocha'],
    client: {
      mocha: {
        timeout : 10000, // 10 seconds - upped from 2 seconds
        retries: 3 // Allow for slow server on CI.
      }
    },
    files: [
      {pattern: path.resolve('./build/injector.js'), watched: false},
      {pattern: process.env.KARMA_FILE_PATTERN, watched: false}
    ],
    preprocessors: {
      'build/injector.js': ['webpack'],
      'src/*.spec.ts': ['webpack', 'sourcemap']
    },
    mime: {
      'text/x-typescript': ['ts','tsx']
    },
    webpack: webpack,
    webpackMiddleware: {
      noInfo: true,
      stats: 'errors-only'
    },
    browserNoActivityTimeout: 31000, // 31 seconds - upped from 10 seconds
    browserDisconnectTimeout: 31000, // 31 seconds - upped from 2 seconds
    browserDisconnectTolerance: 2,
    port: 9876,
    colors: true,
    singleRun: true,
    logLevel: config.LOG_INFO
  });
};
<commit_msg>Only show mocha failures.<commit_after>var path = require('path');
var webpack = require('./webpack.config');

module.exports = function (config) {
  config.set({
    basePath: '.',
    frameworks: ['mocha'],
    reporters: ['mocha'],
    client: {
      mocha: {
        timeout : 10000, // 10 seconds - upped from 2 seconds
        retries: 3 // Allow for slow server on CI.
      }
    },
    mochaReporter: {
      output: "minimal"
    },
    files: [
      {pattern: path.resolve('./build/injector.js'), watched: false},
      {pattern: process.env.KARMA_FILE_PATTERN, watched: false}
    ],
    preprocessors: {
      'build/injector.js': ['webpack'],
      'src/*.spec.ts': ['webpack', 'sourcemap']
    },
    mime: {
      'text/x-typescript': ['ts','tsx']
    },
    webpack: webpack,
    webpackMiddleware: {
      noInfo: true,
      stats: 'errors-only'
    },
    browserNoActivityTimeout: 31000, // 31 seconds - upped from 10 seconds
    browserDisconnectTimeout: 31000, // 31 seconds - upped from 2 seconds
    browserDisconnectTolerance: 2,
    port: 9876,
    colors: true,
    singleRun: true,
    logLevel: config.LOG_INFO
  });
};
<|endoftext|>


<commit_before>/**
 * Convert a single file-input element into a 'multiple' input list
 *
 * Usage:
 *
 *   1. Create a file input element (no name)
 *      eg. <input type="file" id="first_file_element">
 *
 *   2. Create a DIV for the output to be written to
 *      eg.

 *
 *   3. Instantiate a MultiSelector object, passing in the DIV and (optionally) the maximum number of files and a boolean
 *      that specifies if the multiple attribute should be used.
 *      eg. var multi_selector = new MultiSelector( document.getElementById( 'files_list' ), 3, true );
 *
 *   4. Add the first element
 *      eg. multi_selector.addElement( document.getElementById( 'first_file_element' ) );
 *
 *   5. That's it.
 *
 *   You might (will) want to play around with the addListRow() method to make the output prettier.
 *
 *   You might also want to change the line
 *       element.name = 'file_' + this.count;
 *   ...to a naming convention that makes more sense to you.
 *
 * Licence:
 *   Use this however/wherever you like, just don't blame me if it breaks anything.
 *
 * Credit:
 *   If you're nice, you'll leave this bit:
 *
 *   Class by Stickman -- http://www.the-stickman.com
 *      with thanks to:
 *      [for Safari fixes]
 *         Luis Torrefranca -- http://www.law.pitt.edu
 *         and
 *         Shawn Parker & John Pennypacker -- http://www.fuzzycoconut.com
 *      [for duplicate name bug]
 *         'neal'
 *      [for multiple HTML5 attribute use]
 *         'Andrei Costescu'
 */
function MultiSelector( eprefix, list_target, max, useMultipleAttr, del_label ){
	"use strict";

	// Where to write the list
	this.list_target = list_target;
	// How many elements?
	this.count = 0;
	// How many elements?
	this.id = 0;
	// Is there a maximum?
	if( max ){
		this.max = max;
	} else {
		this.max = -1;
	}
	this.useMultipleAttr = useMultipleAttr;

	this.delete_label=del_label;
	this.element_name_prefix=eprefix;

	/**
	 * Add a new file input element
	 */
	this.addElement = function( element ){

		// Make sure it's a file input element
		if( element.tagName.toLowerCase() === 'input' && element.type.toLowerCase() === 'file' ){

			if (this.useMultipleAttr) {
				element.multiple = this.useMultipleAttr;
				if (Wicket.Browser.isOpera()) {
					// in Opera 12.02, changing 'multiple' this way does not update the field
					element.type = 'button';
					element.type = 'file';
				}
			}

			// Element name -- what number am I?
			element.name = this.element_name_prefix + "_mf_"+this.id++;

			// Add reference to this object
			element.multi_selector = this;

			// What to do when a file is selected
			element.onchange = function(){

				// New file input
				var new_element = document.createElement( 'input' );
				new_element.type = 'file';

				// Add new element
				this.parentNode.insertBefore( new_element, this );

				// Apply 'update' to element
				this.multi_selector.addElement( new_element );

				// Update list
				this.multi_selector.addListRow( this );

				// Hide this: we can't use display:none because Safari doesn't like it
				this.style.position = 'fixed';
				this.style.left = '-1000px';

			};
			// If we've reached maximum number, disable input element
			if( this.max !== -1 && this.count >= this.max ){
				element.disabled = true;
			}

			// File element counter
			this.count++;
			// Most recent element
			this.current_element = element;

		} else if (Wicket && Wicket.Log) {
			// This can only be applied to file input elements!
			Wicket.Log.error( 'Error: not a file input element' );
		}

	};

	/**
	 * Add a new row to the list of files
	 */
	this.addListRow = function( element ){

		// Row div
		var new_row = document.createElement('tr');
		var contentsColumn = document.createElement('td');
		var buttonColumn = document.createElement('td');

		// Delete button
		var new_row_button = document.createElement( 'input' );
		new_row_button.type = 'button';
		new_row_button.value = this.delete_label;

		// References
		new_row.element = element;

		// Delete function
		new_row_button.onclick= function(){

			// Remove element from form
			this.parentNode.parentNode.element.parentNode.removeChild( this.parentNode.parentNode.element );

			// Remove this row from the list
			this.parentNode.parentNode.parentNode.removeChild( this.parentNode.parentNode );

			// Decrement counter
			this.parentNode.parentNode.element.multi_selector.count--;

			// Re-enable input element (if it's disabled)
			this.parentNode.parentNode.element.multi_selector.current_element.disabled = false;

			// Appease Safari
			//    without it Safari wants to reload the browser window
			//    which nixes your already queued uploads
			return false;
		};

		// Set row value
		contentsColumn.innerHTML = this.getOnlyFileNames(element);
		new_row.appendChild( contentsColumn );

		// Add button
		new_row_button.style.marginLeft = '20px';
		buttonColumn.appendChild( new_row_button );
		new_row.appendChild( buttonColumn );

		// Add it to the list
		this.list_target.appendChild( new_row );

	};

	this.getOnlyFileNames = function(inputElement)
	{
		if (inputElement.files && inputElement.files.length > 0)
		{
			var files = inputElement.files;
			var retVal = "";
			for (var i = 0; i < files.length; i++)
			{
				retVal += this.getOnlyFileName(files[i].name) + '
';
			}
			return retVal.slice(0, retVal.length - 4);
		}
		else
		{
			return this.getOnlyFileName(inputElement.value);
		}
	};

	this.getOnlyFileName = function(stringValue)
	{
		var separatorIndex1 = stringValue.lastIndexOf('\\');
		var separatorIndex2 = stringValue.lastIndexOf('/');
		separatorIndex1 = Math.max(separatorIndex1, separatorIndex2);
		return separatorIndex1 >= 0 ? stringValue.slice(separatorIndex1 + 1, stringValue.length) : stringValue;
	};

}<commit_msg>WICKET-5335 After selecting a file MultiFileUploadField does not render properly input field<commit_after>/**
 * Convert a single file-input element into a 'multiple' input list
 *
 * Usage:
 *
 *   1. Create a file input element (no name)
 *      eg. <input type="file" id="first_file_element">
 *
 *   2. Create a DIV for the output to be written to
 *      eg.

 *
 *   3. Instantiate a MultiSelector object, passing in the DIV and (optionally) the maximum number of files and a boolean
 *      that specifies if the multiple attribute should be used.
 *      eg. var multi_selector = new MultiSelector( document.getElementById( 'files_list' ), 3, true );
 *
 *   4. Add the first element
 *      eg. multi_selector.addElement( document.getElementById( 'first_file_element' ) );
 *
 *   5. That's it.
 *
 *   You might (will) want to play around with the addListRow() method to make the output prettier.
 *
 *   You might also want to change the line
 *       element.name = 'file_' + this.count;
 *   ...to a naming convention that makes more sense to you.
 *
 * Licence:
 *   Use this however/wherever you like, just don't blame me if it breaks anything.
 *
 * Credit:
 *   If you're nice, you'll leave this bit:
 *
 *   Class by Stickman -- http://www.the-stickman.com
 *      with thanks to:
 *      [for Safari fixes]
 *         Luis Torrefranca -- http://www.law.pitt.edu
 *         and
 *         Shawn Parker & John Pennypacker -- http://www.fuzzycoconut.com
 *      [for duplicate name bug]
 *         'neal'
 *      [for multiple HTML5 attribute use]
 *         'Andrei Costescu'
 */
function MultiSelector( eprefix, list_target, max, useMultipleAttr, del_label ){
	"use strict";

	// Where to write the list
	this.list_target = list_target;
	// How many elements?
	this.count = 0;
	// How many elements?
	this.id = 0;
	// Is there a maximum?
	if( max ){
		this.max = max;
	} else {
		this.max = -1;
	}
	this.useMultipleAttr = useMultipleAttr;

	this.delete_label=del_label;
	this.element_name_prefix=eprefix;

	/**
	 * Add a new file input element
	 */
	this.addElement = function( element ){

		// Make sure it's a file input element
		if( element.tagName.toLowerCase() === 'input' && element.type.toLowerCase() === 'file' ){

			if (this.useMultipleAttr) {
				element.multiple = this.useMultipleAttr;
				if (Wicket.Browser.isOpera()) {
					// in Opera 12.02, changing 'multiple' this way does not update the field
					element.type = 'button';
					element.type = 'file';
				}
			}

			// Element name -- what number am I?
			element.name = this.element_name_prefix + "_mf_"+this.id++;

			// Add reference to this object
			element.multi_selector = this;

			// What to do when a file is selected
			element.onchange = function(){

				// New file input
				var new_element = document.createElement( 'input' );
				new_element.type = 'file';
				new_element.style.display = "block";

				// Add new element
				this.parentNode.insertBefore( new_element, this );

				// Apply 'update' to element
				this.multi_selector.addElement( new_element );

				// Update list
				this.multi_selector.addListRow( this );

				// Hide this: we can't use display:none because Safari doesn't like it
				this.style.position = 'fixed';
				this.style.left = '-1000px';

			};
			// If we've reached maximum number, disable input element
			if( this.max !== -1 && this.count >= this.max ){
				element.disabled = true;
			}

			// File element counter
			this.count++;
			// Most recent element
			this.current_element = element;

		} else if (Wicket && Wicket.Log) {
			// This can only be applied to file input elements!
			Wicket.Log.error( 'Error: not a file input element' );
		}

	};

	/**
	 * Add a new row to the list of files
	 */
	this.addListRow = function( element ){

		// Row div
		var new_row = document.createElement('tr');
		var contentsColumn = document.createElement('td');
		var buttonColumn = document.createElement('td');

		// Delete button
		var new_row_button = document.createElement( 'input' );
		new_row_button.type = 'button';
		new_row_button.value = this.delete_label;

		// References
		new_row.element = element;

		// Delete function
		new_row_button.onclick= function(){

			// Remove element from form
			this.parentNode.parentNode.element.parentNode.removeChild( this.parentNode.parentNode.element );

			// Remove this row from the list
			this.parentNode.parentNode.parentNode.removeChild( this.parentNode.parentNode );

			// Decrement counter
			this.parentNode.parentNode.element.multi_selector.count--;

			// Re-enable input element (if it's disabled)
			this.parentNode.parentNode.element.multi_selector.current_element.disabled = false;

			// Appease Safari
			//    without it Safari wants to reload the browser window
			//    which nixes your already queued uploads
			return false;
		};

		// Set row value
		contentsColumn.innerHTML = this.getOnlyFileNames(element);
		new_row.appendChild( contentsColumn );

		// Add button
		new_row_button.style.marginLeft = '20px';
		buttonColumn.appendChild( new_row_button );
		new_row.appendChild( buttonColumn );

		// Add it to the list
		this.list_target.appendChild( new_row );

	};

	this.getOnlyFileNames = function(inputElement)
	{
		if (inputElement.files && inputElement.files.length > 0)
		{
			var files = inputElement.files;
			var retVal = "";
			for (var i = 0; i < files.length; i++)
			{
				retVal += this.getOnlyFileName(files[i].name) + '
';
			}
			return retVal.slice(0, retVal.length - 4);
		}
		else
		{
			return this.getOnlyFileName(inputElement.value);
		}
	};

	this.getOnlyFileName = function(stringValue)
	{
		var separatorIndex1 = stringValue.lastIndexOf('\\');
		var separatorIndex2 = stringValue.lastIndexOf('/');
		separatorIndex1 = Math.max(separatorIndex1, separatorIndex2);
		return separatorIndex1 >= 0 ? stringValue.slice(separatorIndex1 + 1, stringValue.length) : stringValue;
	};

}
<|endoftext|>


<commit_before>/**
 * lib/badcache.js - Module for pseudo-caching system.
 *
 * Authors: Ian McGaunn; Dave Zimmelman
 * Modified: 13 Apr 15
 */

var Podcasts = require('./podcasts');
var request = require('request');

var toString = function (data) {
    return String(data);
};

var aggregate_helper = function (pcasts, subs, fail, pass) {
    if (subs) {
        Podcasts.getPodcasts(subs, fail, function (fcasts) {
            pass([pcasts, fcasts]);
        });
    }
    else {
        pass([pcasts, []]);
    }
};

var filter_out = function (source, filter, cast_func) {
    var i, index;
    if (filter) {
        for (i in filter) {
            index = source.indexOf(cast_func(filter[i]));
            if (index !== -1) source.splice(index, 1);
        }
    }
    return source;
};

var Cache = {
    _count : 100,
    browse : {},
    search : {},
    top100: [],
    aggregate_cat : function (cat, subs, fail, pass) {
        var p, i, j, filter = false, limit = 25;
        if (subs && subs[cat] && subs[cat].length > 0) filter = subs[cat];
        if (cat == 0) {
            p = this.top100.slice();
            if (filter) p = filter_out(p, filter, toString);
            p = p.slice(0, limit);
            Podcasts.getPodcasts(p, fail, function (pcasts) {
                aggregate_helper(pcasts, false, fail, pass);
            });
        } else {
            if (filter) limit -= filter.length;
            if (limit < 1) limit = 1;
            Podcasts.getByCategory(cat, limit, filter, function (pcasts) {
                aggregate_helper(pcasts, filter, fail, pass);
            });
        }
    },
    update_top100 : function () {
        // WARNING: No safe-check for bad results!
        //      Assumes itunes API will work correctly.
        Cache.top100 = [];
        var apiUrl = "https://itunes.apple.com/us/rss/toppodcasts/limit=" + Cache._count + "/explicit=true/json";
        request(apiUrl, function (error, response, body) {
            var id, genre, results = JSON.parse(body).feed.entry;
            if (!results) {
                Cache._count++;
                return Cache.update_top100();
            }
            for (podcast in results) {
                id = results[podcast].id.attributes['im:id'];
                // Every time a podcast is in the top100 list,
                //     increase its popularity.
                Podcasts.modifyPodcastPoints(id, 1);
                Cache.top100.push(id);
            }
            Podcasts.podcastForceCache(Cache.top100);
        });
    }
};

module.exports = Cache;<commit_msg>[Debug] Added debug information for top100 update<commit_after>/**
 * lib/badcache.js - Module for pseudo-caching system.
 *
 * Authors: Ian McGaunn; Dave Zimmelman
 * Modified: 13 Apr 15
 */

var Podcasts = require('./podcasts');
var request = require('request');

var toString = function (data) {
    return String(data);
};

var aggregate_helper = function (pcasts, subs, fail, pass) {
    if (subs) {
        Podcasts.getPodcasts(subs, fail, function (fcasts) {
            pass([pcasts, fcasts]);
        });
    }
    else {
        pass([pcasts, []]);
    }
};

var filter_out = function (source, filter, cast_func) {
    var i, index;
    if (filter) {
        for (i in filter) {
            index = source.indexOf(cast_func(filter[i]));
            if (index !== -1) source.splice(index, 1);
        }
    }
    return source;
};

var Cache = {
    _count : 100,
    browse : {},
    search : {},
    top100: [],
    aggregate_cat : function (cat, subs, fail, pass) {
        var p, i, j, filter = false, limit = 25;
        if (subs && subs[cat] && subs[cat].length > 0) filter = subs[cat];
        if (cat == 0) {
            p = this.top100.slice();
            if (filter) p = filter_out(p, filter, toString);
            p = p.slice(0, limit);
            Podcasts.getPodcasts(p, fail, function (pcasts) {
                aggregate_helper(pcasts, false, fail, pass);
            });
        } else {
            if (filter) limit -= filter.length;
            if (limit < 1) limit = 1;
            Podcasts.getByCategory(cat, limit, filter, function (pcasts) {
                aggregate_helper(pcasts, filter, fail, pass);
            });
        }
    },
    update_top100 : function () {
        // WARNING: No safe-check for bad results!
        //      Assumes itunes API will work correctly.
        console.log('Requesting iTunes top100...');
        Cache.top100 = [];
        var apiUrl = "https://itunes.apple.com/us/rss/toppodcasts/limit=" + Cache._count + "/explicit=true/json";
        request(apiUrl, function (error, response, body) {
            var id, genre, results = JSON.parse(body).feed.entry;
            if (!results) {
                console.log('\tFailed; Retrying.');
                Cache._count++;
                return Cache.update_top100();
            }
            for (podcast in results) {
                id = results[podcast].id.attributes['im:id'];
                // Every time a podcast is in the top100 list,
                //     increase its popularity.
                Podcasts.modifyPodcastPoints(id, 1);
                Cache.top100.push(id);
            }
            console.log('\tCompleted. Updating cache with top100 list.');
            Podcasts.podcastForceCache(Cache.top100);
        });
    }
};

module.exports = Cache;<|endoftext|>


<commit_before>import _ from 'lodash';
import gulp from 'gulp';
import requireDir from 'require-dir';
import runSequence from 'run-sequence';

const loadGulpTasks = () => {
    // Require all tasks in gulp/tasks, including subfolders
    const tasks = requireDir('./gulp/tasks', { recurse: true });

    // Get environment, for environment-specific activities
    const env = process.env.NODE_ENV || 'production';

    _.each(tasks, (task, relativePath) => {
        if (_.isObject(task) && _.isFunction(task.default)) {
            task = task.default;
        }

        console.assert(_.isFunction(task),
            'gulp/tasks/%s: module\'s export is not a function', relativePath);

        task({ env: env, watch: false });
    });
};

loadGulpTasks();

gulp.task('default', ['prod']);
gulp.task('prod', ['production']);
gulp.task('dev', ['development']);

gulp.task('development', (callback) => {
    runSequence(
        'clean',
        'bower',
        ['app:build-dev', 'web:build-dev'],
        ['app:i18n', 'web:i18n'],
        ['app:dist', 'web:dist'],
        callback
    );
});

gulp.task('production', (callback) => {
    runSequence(
        'clean',
        'bower',
        ['app:build', 'web:build'],
        ['app:i18n', 'web:i18n'],
        ['app:dist', 'web:dist'],
        callback
    );
});
<commit_msg>Update gulpfile.babel.js<commit_after>import _ from 'lodash';
import gulp from 'gulp';
import requireDir from 'require-dir';
import runSequence from 'run-sequence';

const loadGulpTasks = () => {
    // Require all tasks in gulp/tasks, including subfolders
    const tasks = requireDir('./gulp/tasks', { recurse: true });

    // Get environment, for environment-specific activities
    const env = process.env.NODE_ENV || 'production';

    _.each(tasks, (task, relativePath) => {
        if (_.isObject(task) && _.isFunction(task.default)) {
            task = task.default;
        }

        console.assert(_.isFunction(task),
            'gulp/tasks/%s: module\'s export is not a function', relativePath);

        task({ env: env, watch: false });
    });
};

loadGulpTasks();

gulp.task('default', ['prod']);
gulp.task('prod', ['production']);
gulp.task('dev', ['development']);

gulp.task('development', (callback) => {
    runSequence(
        'clean',
        'bower',
        ['web:build-dev'],
        ['app:i18n', 'web:i18n'],
        ['app:dist', 'web:dist'],
        callback
    );
});

gulp.task('production', (callback) => {
    runSequence(
        'clean',
        'bower',
        ['app:build-prod', 'web:build-prod'],
        ['app:i18n', 'web:i18n'],
        ['app:dist', 'web:dist'],
        callback
    );
});
<|endoftext|>