<commit_before>//
// Copyright (c) 2013 Jean Alexandre Iragne (https://github.com/Iragne)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

var is_array = function(a){
	"use strict";
    return Array.isArray(a);
};

var is_object = function(obj){
	"use strict";
    return obj === Object(obj);
};

var is_string = function(str){
	"use strict";
	return typeof str == 'string' || str instanceof String;
};

var is_number = function(n){
	"use strict";
	return typeof n === 'number' && parseFloat(n) == parseInt(n, 10) && !isNaN(n);
};
var is_int = function(n) {
	"use strict";
	return parseInt(n,10) === n;
};

var is_float = function(n) {
	"use strict";
	return is_number(n) && ! is_int(n);
};

var renderOutputModel = module.exports.renderOutputModel = function (format,models,original,url_params){
	"use strict";
	var ret = {};
	var i = 0;
	try {
		if (format.type){
			if (is_array(format.type)){
				ret = [];
				for (i = 0; i < parseInt(format.number,10); i++) {
					ret.push(renderOutputModel(format.model,models,original,url_params));
				}
			}
		}else{
			if (is_object(format)){
				for (i = 0; i < Object.keys(format).length; i++) {
					var attr = Object.keys(format)[i];
					ret[attr] = renderOutputModel(format[attr],models,original,url_params);
				}
			}else{
				if (is_string(format)){
					if (models[format])
						return models[format]({params:url_params});
					else{
						console.log("renderOutputModel",original);
						throw "Error Model "+format;
					}
				}else{
					console.log("renderOutputModel",original);
					throw "Error Model "+format;
				}
			}
		}
	}catch (e){
		console.log("renderOutputModel",e,e.stack);
		return null;
	}

	return ret;
};

var is_model = function (obj,models){
	"use strict";
	for (var i = 0; i < Object.keys(models).length; i++) {
		//console.log(obj,models);
		var attr = Object.keys(models)[i];
		var found = true;
		if (Object.keys(obj).length != Object.keys(models[attr]()).length)
			found = false;
		for (var j = 0; found && j < Object.keys(models[attr]()).length; j++) {
			//console.log(obj);
			var at = Object.keys(models[attr]())[j];
			if (obj[at] === undefined){
				found = false;
				break;
			}
		}

		if(found)
			return attr;
	}
	//console.log("FOUND",obj);
	return false;
};

var rendermodel = function (model,models){
	"use strict";
	var ret = {};
	//console.log("Model",model);
	for (var i = 0; i < Object.keys(model).length; i++) {
		var attr = Object.keys(model)[i];
		var val = model[attr];
		if (is_number(val)){
			if (is_int(val)){
				ret[attr] = "Int";
			}else{
				ret[attr] = "Float";
			}
		}else{
			if (is_string(val) || val === null){
				ret[attr] = "String";
			}else{
				if (is_array(val)){
					var m = "Undefined";
					if (val.length){
						m = is_model(val[0],models);
					}
					ret[attr] = "array<"+m+">";
				}else{
					//console.log(val);
					var my_model = is_model(val,models);
					if (is_object(val) && !my_model){
						ret[attr] = "Undefined model";//rendermodel(val, models);
					}else{
						ret[attr] = my_model;
					}
				}
			}
		}
	}
	return ret;
};

var renderModelsHtml = module.exports.renderModelsHtml = function(models){
	"use strict";
	var r_models = [];
	for (var i = 0; i < Object.keys(models).length; i++) {
		var attr = Object.keys(models)[i];
		if (attr.indexOf("incomplete") < 0){
			console.log("PROCESS",attr);
			var mod = models[attr]();
			if (mod === null){
				console.log(attr, "model not found");
			}else{
				var r_m = {name:attr,def:rendermodel(mod,models)};
				r_models.push(r_m);
			}
		}
	}
	return r_models;
};

<commit_msg>Add index in options for output using number<commit_after>//
// Copyright (c) 2013 Jean Alexandre Iragne (https://github.com/Iragne)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

var is_array = function(a){
	"use strict";
    return Array.isArray(a);
};

var is_object = function(obj){
	"use strict";
    return obj === Object(obj);
};

var is_string = function(str){
	"use strict";
	return typeof str == 'string' || str instanceof String;
};

var is_number = function(n){
	"use strict";
	return typeof n === 'number' && parseFloat(n) == parseInt(n, 10) && !isNaN(n);
};
var is_int = function(n) {
	"use strict";
	return parseInt(n,10) === n;
};

var is_float = function(n) {
	"use strict";
	return is_number(n) && ! is_int(n);
};

var renderOutputModel = module.exports.renderOutputModel = function (format,models,original,url_params){
	"use strict";
	var ret = {};
	var i = 0;
	try {
		if (format.type){
			if (is_array(format.type)){
				ret = [];
				for (i = 0; i < parseInt(format.number,10); i++) {
					var url_params2 = url_params || {};
					url_params2.index = i;
					ret.push(renderOutputModel(format.model,models,original,url_params2));
				}
			}
		}else{
			if (is_object(format)){
				for (i = 0; i < Object.keys(format).length; i++) {
					var attr = Object.keys(format)[i];
					ret[attr] = renderOutputModel(format[attr],models,original,url_params);
				}
			}else{
				if (is_string(format)){
					//console.log("renderOutputModel",original);
					if (models[format])
						return models[format]({params:url_params});
					else{
						console.log("renderOutputModel",original);
						throw "Error Model "+format;
					}
				}else{
					console.log("renderOutputModel",original);
					throw "Error Model "+format;
				}
			}
		}
	}catch (e){
		console.log("renderOutputModel",e,e.stack);
		return null;
	}

	return ret;
};

var is_model = function (obj,models){
	"use strict";
	for (var i = 0; i < Object.keys(models).length; i++) {
		//console.log(obj,models);
		var attr = Object.keys(models)[i];
		var found = true;
		if (Object.keys(obj).length != Object.keys(models[attr]()).length)
			found = false;
		for (var j = 0; found && j < Object.keys(models[attr]()).length; j++) {
			//console.log(obj);
			var at = Object.keys(models[attr]())[j];
			if (obj[at] === undefined){
				found = false;
				break;
			}
		}

		if(found)
			return attr;
	}
	//console.log("FOUND",obj);
	return false;
};

var rendermodel = function (model,models){
	"use strict";
	var ret = {};
	//console.log("Model",model);
	for (var i = 0; i < Object.keys(model).length; i++) {
		var attr = Object.keys(model)[i];
		var val = model[attr];
		if (is_number(val)){
			if (is_int(val)){
				ret[attr] = "Int";
			}else{
				ret[attr] = "Float";
			}
		}else{
			if (is_string(val) || val === null || val === undefined){
				ret[attr] = "String";
			}else{
				if (is_array(val)){
					var m = "Undefined";
					if (val.length){
						m = is_model(val[0],models);
					}
					ret[attr] = "array<"+m+">";
				}else{
					//console.log(val);
					var my_model = is_model(val,models);
					if (is_object(val) && !my_model){
						ret[attr] = "Undefined model";//rendermodel(val, models);
					}else{
						ret[attr] = my_model;
					}
				}
			}
		}
	}
	return ret;
};

var renderModelsHtml = module.exports.renderModelsHtml = function(models){
	"use strict";
	var r_models = [];
	for (var i = 0; i < Object.keys(models).length; i++) {
		var attr = Object.keys(models)[i];
		if (attr.indexOf("incomplete") < 0){
			console.log("PROCESS",attr);
			var mod = models[attr]();
			if (mod === null){
				console.log(attr, "model not found");
			}else{
				var r_m = {name:attr,def:rendermodel(mod,models)};
				r_models.push(r_m);
			}
		}
	}
	return r_models;
};

<|endoftext|>


<commit_before>import { EnvironmentNames, PropertyNames, URLNames, VariableNames } from 'data/enum/configNames';

const config = {
  environments: {
    [EnvironmentNames.PRODUCTION]: {
      variables: {},
      urls: {},
    },
    [EnvironmentNames.STAGING]: {
      extends: EnvironmentNames.PRODUCTION,
      variables: {},
      urls: {},
    },
    [EnvironmentNames.DEVELOPMENT]: {
      extends: EnvironmentNames.STAGING,
      variables: {},
      urls: {},
    },
    [EnvironmentNames.LOCAL]: {
      extends: EnvironmentNames.DEVELOPMENT,
      variables: {},
      urls: {},
    },
  },
  variables: {
    [VariableNames.LOCALE_ENABLED]: false,
    [VariableNames.LOCALE_ROUTING_ENABLED]: false,
    [VariableNames.VERSIONED_STATIC_ROOT]:
      (window.webpackPublicPath || process.env.PUBLIC_PATH) + process.env.VERSIONED_STATIC_ROOT,
    [VariableNames.STATIC_ROOT]:
      (window.webpackPublicPath || process.env.PUBLIC_PATH) + process.env.STATIC_ROOT,
    [VariableNames.PUBLIC_PATH]: window.webpackPublicPath || process.env.PUBLIC_PATH,
  },
  urls: {
    [URLNames.LOCALE]: `${VariableNames.VERSIONED_STATIC_ROOT}locale/{locale}.json`,
    [URLNames.API]: `${process.env.PUBLIC_PATH}api/`,
  },
  properties: {
    [PropertyNames.DEFAULT_LOCALE]: 'en-gb',
    [PropertyNames.AVAILABLE_LOCALES]: ['en-gb'],
    [PropertyNames.WHITELISTED_QUERY_PARAMS]: [],
  },
};

let environment = EnvironmentNames.PRODUCTION;
const { host } = document.location;

switch (host.split(':').shift()) {
  case 'localhost': {
    environment = EnvironmentNames.LOCAL;
    break;
  }
  default: {
    environment = EnvironmentNames.PRODUCTION;
    break;
  }
}

export default {
  config,
  environment,
};
<commit_msg>use variable in locale path<commit_after>import { EnvironmentNames, PropertyNames, URLNames, VariableNames } from 'data/enum/configNames';

const config = {
  environments: {
    [EnvironmentNames.PRODUCTION]: {
      variables: {},
      urls: {},
    },
    [EnvironmentNames.STAGING]: {
      extends: EnvironmentNames.PRODUCTION,
      variables: {},
      urls: {},
    },
    [EnvironmentNames.DEVELOPMENT]: {
      extends: EnvironmentNames.STAGING,
      variables: {},
      urls: {},
    },
    [EnvironmentNames.LOCAL]: {
      extends: EnvironmentNames.DEVELOPMENT,
      variables: {},
      urls: {},
    },
  },
  variables: {
    [VariableNames.LOCALE_ENABLED]: false,
    [VariableNames.LOCALE_ROUTING_ENABLED]: false,
    [VariableNames.VERSIONED_STATIC_ROOT]:
      (window.webpackPublicPath || process.env.PUBLIC_PATH) + process.env.VERSIONED_STATIC_ROOT,
    [VariableNames.STATIC_ROOT]:
      (window.webpackPublicPath || process.env.PUBLIC_PATH) + process.env.STATIC_ROOT,
    [VariableNames.PUBLIC_PATH]: window.webpackPublicPath || process.env.PUBLIC_PATH,
  },
  urls: {
    [URLNames.LOCALE]: `{${VariableNames.VERSIONED_STATIC_ROOT}}locale/{locale}.json`,
    [URLNames.API]: `${process.env.PUBLIC_PATH}api/`,
  },
  properties: {
    [PropertyNames.DEFAULT_LOCALE]: 'en-gb',
    [PropertyNames.AVAILABLE_LOCALES]: ['en-gb'],
    [PropertyNames.WHITELISTED_QUERY_PARAMS]: [],
  },
};

let environment = EnvironmentNames.PRODUCTION;
const { host } = document.location;

switch (host.split(':').shift()) {
  case 'localhost': {
    environment = EnvironmentNames.LOCAL;
    break;
  }
  default: {
    environment = EnvironmentNames.PRODUCTION;
    break;
  }
}

export default {
  config,
  environment,
};
<|endoftext|>


<commit_before>import React, {PropTypes} from 'react';
import LayoutRenderer from '../components/LayoutRenderer';
import TimeRangeDropdown from '../../shared/components/TimeRangeDropdown';
import timeRanges from 'hson!../../shared/data/timeRanges.hson';
import {getMappings, getAppsForHosts, fetchLayouts} from '../apis';

export const HostPage = React.createClass({
  propTypes: {
    source: PropTypes.shape({
      links: PropTypes.shape({
        proxy: PropTypes.string.isRequired,
      }).isRequired,
    }),
    params: PropTypes.shape({
      hostID: PropTypes.string.isRequired,
    }).isRequired,
    location: PropTypes.shape({
      query: PropTypes.shape({
        app: PropTypes.string,
      }),
    }),
  },

  getInitialState() {
    const fifteenMinutesIndex = 1;

    return {
      layouts: [],
      timeRange: timeRanges[fifteenMinutesIndex],
    };
  },

  componentDidMount() {
    const hosts = {[this.props.params.hostID]: {name: this.props.params.hostID}};

    // fetching layouts and mappings can be done at the same time
    fetchLayouts().then(({data: {layouts}}) => {
      getMappings().then(({data: {mappings}}) => {
        getAppsForHosts(this.props.source.links.proxy, hosts, mappings).then((newHosts) => {
          const host = newHosts[this.props.params.hostID];
          const filteredLayouts = layouts.filter((layout) => {
            const focusedApp = this.props.location.query.app;
            if (focusedApp) {
              return layout.app === focusedApp;
            }
            return host.apps && host.apps.includes(layout.app);
          });
          this.setState({layouts: filteredLayouts});
        });
      });
    });
  },

  handleChooseTimeRange({lower}) {
    const timeRange = timeRanges.find((range) => range.queryValue === lower);
    this.setState({timeRange});
  },

  renderLayouts(layouts) {
    const autoRefreshMs = 15000;
    const {timeRange} = this.state;
    const source = this.props.source.links.proxy;

    let layoutCells = [];
    layouts.forEach((layout) => {
      layoutCells = layoutCells.concat(layout.cells);
    });

    layoutCells.forEach((cell, i) => {
      cell.queries.forEach((q) => {
        q.text = q.query;
        q.database = q.db;
      });
      cell.x = (i * 4 % 12); // eslint-disable-line no-magic-numbers
      cell.y = 0;
    });

    return (
      <LayoutRenderer
        timeRange={timeRange}
        cells={layoutCells}
        autoRefreshMs={autoRefreshMs}
        source={source}
        host={this.props.params.hostID}
      />
    );
  },

  render() {
    const hostID = this.props.params.hostID;
    const {layouts, timeRange} = this.state;

    return (

{hostID}

              <TimeRangeDropdown onChooseTimeRange={this.handleChooseTimeRange} selected={timeRange.inputValue} />

            { (layouts.length > 0) ? this.renderLayouts(layouts) : '' }

    );
  },
});

export default HostPage;
<commit_msg>Host view gets a fixed nav too, cuz we don't forget host view<commit_after>import React, {PropTypes} from 'react';
import LayoutRenderer from '../components/LayoutRenderer';
import TimeRangeDropdown from '../../shared/components/TimeRangeDropdown';
import timeRanges from 'hson!../../shared/data/timeRanges.hson';
import {getMappings, getAppsForHosts, fetchLayouts} from '../apis';

export const HostPage = React.createClass({
  propTypes: {
    source: PropTypes.shape({
      links: PropTypes.shape({
        proxy: PropTypes.string.isRequired,
      }).isRequired,
    }),
    params: PropTypes.shape({
      hostID: PropTypes.string.isRequired,
    }).isRequired,
    location: PropTypes.shape({
      query: PropTypes.shape({
        app: PropTypes.string,
      }),
    }),
  },

  getInitialState() {
    const fifteenMinutesIndex = 1;

    return {
      layouts: [],
      timeRange: timeRanges[fifteenMinutesIndex],
    };
  },

  componentDidMount() {
    const hosts = {[this.props.params.hostID]: {name: this.props.params.hostID}};

    // fetching layouts and mappings can be done at the same time
    fetchLayouts().then(({data: {layouts}}) => {
      getMappings().then(({data: {mappings}}) => {
        getAppsForHosts(this.props.source.links.proxy, hosts, mappings).then((newHosts) => {
          const host = newHosts[this.props.params.hostID];
          const filteredLayouts = layouts.filter((layout) => {
            const focusedApp = this.props.location.query.app;
            if (focusedApp) {
              return layout.app === focusedApp;
            }
            return host.apps && host.apps.includes(layout.app);
          });
          this.setState({layouts: filteredLayouts});
        });
      });
    });
  },

  handleChooseTimeRange({lower}) {
    const timeRange = timeRanges.find((range) => range.queryValue === lower);
    this.setState({timeRange});
  },

  renderLayouts(layouts) {
    const autoRefreshMs = 15000;
    const {timeRange} = this.state;
    const source = this.props.source.links.proxy;

    let layoutCells = [];
    layouts.forEach((layout) => {
      layoutCells = layoutCells.concat(layout.cells);
    });

    layoutCells.forEach((cell, i) => {
      cell.queries.forEach((q) => {
        q.text = q.query;
        q.database = q.db;
      });
      cell.x = (i * 4 % 12); // eslint-disable-line no-magic-numbers
      cell.y = 0;
    });

    return (
      <LayoutRenderer
        timeRange={timeRange}
        cells={layoutCells}
        autoRefreshMs={autoRefreshMs}
        source={source}
        host={this.props.params.hostID}
      />
    );
  },

  render() {
    const hostID = this.props.params.hostID;
    const {layouts, timeRange} = this.state;

    return (

{hostID}

Range:

              <TimeRangeDropdown onChooseTimeRange={this.handleChooseTimeRange} selected={timeRange.inputValue} />

              { (layouts.length > 0) ? this.renderLayouts(layouts) : '' }

    );
  },
});

export default HostPage;
<|endoftext|>


<commit_before>var router = new require('routes').Router(),
    routil = require('routil'),
    sessions = require('./helpers/sessions'),
    isDefined = require('./helpers/objects').isDefined;

var Router = {
    // registers a route
    add: function(uri, fn) {
        router.addRoute(uri, fn);
    },

    // match a route and execute its related function
    match: function(req, res) {
        // matching a route
        var route = router.match(req.url);

        // if one is matched, executing the reponse function
        if (route) {
            route.fn(req, res, route.params, route.splats);
        } else {
            // TOTODB: send 404 here with routil
            // routil.errorPage(req, res, [404 new Error("send error")])
        }
    },

    // gets a requested action, and handles its parameters
    getAction: function(controller, action, parameters) {
        var that = this;

        return function(req, res) {
            var controllerObject = that.controllers[controller];

            if (isDefined(parameters)) {
                if (isDefined(parameters.checkIfAuthorized)) {
                    sessions.checkIfAuthorized(req, res);
                }
            }

            return controllerObject[action](req, res);
        };
    }
};

module.exports = Router;<commit_msg>added 404 routil<commit_after>var router = new require('routes').Router(),
    routil = require('routil'),
    sessions = require('./helpers/sessions'),
    isDefined = require('./helpers/objects').isDefined;

var Router = {
    // registers a route
    add: function(uri, fn) {
        router.addRoute(uri, fn);
    },

    // match a route and execute its related function
    match: function(req, res) {
        // matching a route
        var route = router.match(req.url);

        // if one is matched, executing the reponse function
        if (route) {
            route.fn(req, res, route.params, route.splats);
        } else {
            routil.errorPage(req, res, 404);
        }
    },

    // gets a requested action, and handles its parameters
    getAction: function(controller, action, parameters) {
        var that = this;

        return function(req, res) {
            var controllerObject = that.controllers[controller];

            if (isDefined(parameters)) {
                if (isDefined(parameters.checkIfAuthorized)) {
                    sessions.checkIfAuthorized(req, res);
                }
            }

            return controllerObject[action](req, res);
        };
    }
};

module.exports = Router;<|endoftext|>


<commit_before>'use strict';

const path = require('path');

const { HumanInfo } = require('../libs/types.js');

const CRAWLERS = {
    "minnano-av": require('./crawlers/minnano-av.js'),

    "javmodel": require('./crawlers/javmodel.js'),
}

const SEARCH_TEMPLATE_URL = {
    "minnano-av": "http://www.minnano-av.com/search_result.php?search_scope=actress&search_word={code}",
}

const ID_TEMPLATE_URL = {
    "minnano-av": "http://www.minnano-av.com/{code}",

    "javmodel": "http://javmodel.com/jav/{code}/",
}

function prepare(crawlerName, type, params) {
    let crawler = CRAWLERS[crawlerName];
    let url = "";

    switch(type) {
        case "search":
            url = SEARCH_TEMPLATE_URL[crawlerName]
            if (params["code"])
                url = url.replace('{code}', encodeURIComponent(params["code"]));
        case "id":
            url = ID_TEMPLATE_URL[crawlerName]
            if (params["code"])
                url = url.replace('{code}', encodeURIComponent(params["code"]));
    }

    return { crawler, url };
}

function crawlHuman (crawler, url) {
    return crawler.crawl(url)
    .then(d => {
        if (d instanceof HumanInfo) {
            var param = d.transname.split('/')[1].split(' ');

            var infoid = param[0];
            if (param.length > 1) {
                infoid = param[1] + '-' + param[0];
            }
            infoid = infoid.toLowerCase();

            // get crawler
            let { crawler, url } = prepare('javmodel', 'id', {
                "code": encodeURIComponent(infoid)
            });

            return crawler.crawl(url)
            .then(dd => {
                if (dd != null) {
                    if (dd.photos.length > 0) {
                        d.photos = dd.photos;
                    }

                    if (dd.tags.length > 0) {
                        d.tags = dd.tags;
                    }
                }

                return d;
            });
        }
    });
}

function crawl (type, code) {
    switch (type) {
        case "human":
            // get crawler
            var { crawler, url } = prepare('minnano-av', 'search', {
                "code": encodeURIComponent(code)
            });

            return crawlHuman(crawler, url);

        case "human-id":
            // get crawler
            var { crawler, url } = prepare('minnano-av', 'id', {
                "code": encodeURIComponent(code)
            });

            return crawlHuman(crawler, url);

        default:
            throw new Error('No crawler has found!');
    }
}

module.exports.crawl = crawl;
<commit_msg>fix wrong generating info id<commit_after>'use strict';

const path = require('path');

const { HumanInfo } = require('../libs/types.js');

const CRAWLERS = {
    "minnano-av": require('./crawlers/minnano-av.js'),

    "javmodel": require('./crawlers/javmodel.js'),
}

const SEARCH_TEMPLATE_URL = {
    "minnano-av": "http://www.minnano-av.com/search_result.php?search_scope=actress&search_word={code}",
}

const ID_TEMPLATE_URL = {
    "minnano-av": "http://www.minnano-av.com/{code}",

    "javmodel": "http://javmodel.com/jav/{code}/",
}

function prepare(crawlerName, type, params) {
    let crawler = CRAWLERS[crawlerName];
    let url = "";

    switch(type) {
        case "search":
            url = SEARCH_TEMPLATE_URL[crawlerName]
            if (params["code"])
                url = url.replace('{code}', encodeURIComponent(params["code"]));
        case "id":
            url = ID_TEMPLATE_URL[crawlerName]
            if (params["code"])
                url = url.replace('{code}', encodeURIComponent(params["code"]));
    }

    return { crawler, url };
}

function crawlHuman (crawler, url) {
    return crawler.crawl(url)
    .then(d => {
        if (d instanceof HumanInfo) {
            var param = d.transname.split('/')[1].trim().split(' ');

            var infoid = param[0];
            if (param.length > 1) {
                infoid = param[1].trim() + '-' + param[0].trim();
            }
            infoid = infoid.toLowerCase();

            // get crawler
            let { crawler, url } = prepare('javmodel', 'id', {
                "code": encodeURIComponent(infoid)
            });

            return crawler.crawl(url)
            .then(dd => {
                if (dd != null) {
                    if (dd.photos.length > 0) {
                        d.photos = dd.photos;
                    }

                    if (dd.tags.length > 0) {
                        d.tags = dd.tags;
                    }
                }

                return d;
            });
        }
    });
}

function crawl (type, code) {
    switch (type) {
        case "human":
            // get crawler
            var { crawler, url } = prepare('minnano-av', 'search', {
                "code": encodeURIComponent(code)
            });

            return crawlHuman(crawler, url);

        case "human-id":
            // get crawler
            var { crawler, url } = prepare('minnano-av', 'id', {
                "code": encodeURIComponent(code)
            });

            return crawlHuman(crawler, url);

        default:
            throw new Error('No crawler has found!');
    }
}

module.exports.crawl = crawl;
<|endoftext|>


<commit_before>const paths = require('./paths');

// TODO - Verfiy that we don't need eslint-import-resolver-webpack anymore
// const webpackConfig = process.env.NODE_ENV === "development"
//   ? path.join(paths.kickstarterConfig, "webpack.dev.js")
//   : path.join(paths.kickstarterConfig, "webpack.prod.js");

module.exports = {
  parser: 'babel-eslint',
  extends: ['airbnb', 'plugin:flowtype/recommended'],
  env: {
    browser: true,
    node: true,
    es6: true,
  },
  plugins: ['flowtype'],
  rules: {
    // airbnb config modifications
    'no-unused-vars': 'warn', // easier for development
    'linebreak-style': 'off',
    'arrow-parens': 'off', // conflict with Prettier
    'react/prop-types': 'off', // not needed with Flow
    'react/require-default-props': 'off', // not needed with Flow
    'react/jsx-filename-extension': ['error', { extensions: ['.js', '.jsx'] }],

    // flowtype
    'flowtype/delimiter-dangle': ['error', 'always-multiline'],
    'flowtype/no-primitive-constructor-types': 'error',
    'flowtype/object-type-delimiter': ['error', 'comma'],
    'flowtype/require-valid-file-annotation': 'error',
    'flowtype/semi': ['error', 'always'],
    'flowtype/space-before-generic-bracket': ['error', 'never'],
  },
  settings: {
    'import/resolver': {
      // TODO - Verfiy we don't need eslint-import-resolver-webpack anymore
      // "webpack": {
      //   "config": webpackConfig
      // },
      node: {
        paths: [paths.appMain],
      },
    },
  },
};
<commit_msg>Update eslint<commit_after>const paths = require('./paths');

// TODO - Verfiy that we don't need eslint-import-resolver-webpack anymore
// const webpackConfig = process.env.NODE_ENV === "development"
//   ? path.join(paths.kickstarterConfig, "webpack.dev.js")
//   : path.join(paths.kickstarterConfig, "webpack.prod.js");

module.exports = {
  parser: 'babel-eslint',
  extends: ['airbnb', 'plugin:flowtype/recommended'],
  env: {
    browser: true,
    node: true,
    es6: true,
  },
  plugins: ['flowtype'],
  rules: {
    // airbnb config modifications
    'no-unused-vars': 'warn', // easier for development
    'linebreak-style': 'off',
    'arrow-parens': 'off', // conflict with Prettier
    'react/jsx-filename-extension': ['error', { extensions: ['.js', '.jsx'] }],

    // flowtype
    'flowtype/delimiter-dangle': ['error', 'always-multiline'],
    'flowtype/no-primitive-constructor-types': 'error',
    'flowtype/object-type-delimiter': ['error', 'comma'],
    'flowtype/require-valid-file-annotation': 'error',
    'flowtype/semi': ['error', 'always'],
    'flowtype/space-before-generic-bracket': ['error', 'never'],
  },
  settings: {
    'import/resolver': {
      // TODO - Verfiy we don't need eslint-import-resolver-webpack anymore
      // "webpack": {
      //   "config": webpackConfig
      // },
      node: {
        paths: [paths.appMain],
      },
    },
  },
};
<|endoftext|>


<commit_before>/**
 *
 *
 * @TODO Better support to the others HTTP verbs
 */

// Dependencies
import { fetch } from './request';

// Configurations
import { get, set } from './config';

/**
 * Generate the options to make a request
 *
 * @param {String} method The HTTP method (mainly GET or POST)
 * @param {String} path The path that will be used as base
 * @param {Object} data Data passed in the request
 * @param {String} auth The API token (previsouly queried)
 * @param {String} name Store name
 * @param {String} version The API version
 * @param {String} token The API token
 * @return {Object} Base configuration for the request
 */
export const buildRequest = function(method, path, data, auth = get('auth'), store = get('store'), version = get('version'), token = get('token')) {
  // Query String
  let qs = '';

  // Generate the QueryString if its necessary
  if( method === 'GET' && data !== undefined )
    qs = buildParams(data);

  // Request Headers
  let headers = {};

  // Check if a token is passed to be used
  if( token !== undefined )
    headers['Yebo-Token'] = token;

  // Return the request options
  return {
    name: path.split('/').join('-').substring(1),
    method: method,
    url: `${get('protocol')}://${store}.${get('apiURL')}/${version}${path}${qs}`,
    data: method === 'GET' ? {} : data,
    headers: headers,
    content_type: method === 'GET' ? 'application/x-www-form-urlencoded' : 'application/json'
  };
}

/**
 * Build the request that will get the authentication token
 *
 * @param {String} name Store name
 * @param {String} version The API version
 * @param {String} token The API token
 * @return {Object} Request that will return the authentication token
 */
export const buildAuthentication = function(name, version, token) {
  return buildRequest('GET', '/', {}, undefined, name, version, token);
};

/**
 * Execute the Authentication
 *
 * @param {String} name Store name
 * @param {String} version The API version
 * @param {String} token The API token
 * @return {Promise} Result of the authentication
 */
export const authenticate = function(name = get('store'), version = get('version'), token = get('token')) {
  return executeRequest(buildAuthentication(name, version, token));
}

/**
 * Based on an array generate
 *
 * @param {Object/Array} value Values that will be mapped to QueryString
 * @return {String} QueryString itself
 */
export const buildParams = function(value) {
  return _recBuildParams('', value, true, '?').slice(0, -1);
}

/**
 * Execute the generated requestç
 *
 * @param {Object} req Generated request
 * @return {Promise} The HTTP request Promise
 */
export const executeRequest = function(req) {
  const resolver = (res, rej) => {
    // Check if the authentication token is passed
    req.headers['Authorization'] = `Bearer ${get('authToken')}`

    //
    fetch(req.method, req.url, req.data, req.contentType, req.headers).then(res).catch(rej);
  }
  return new Promise((resolve, reject) => {
    //
    if (req.name !== '' && get('expireAt') > Date.now()) {
      // authenticate
      authenticate().then((res) => {
        // res.token
        set('authToken', res.token)

        // res.expire_at
        set('expireAt', res.expire_at)
        // resolver reolve and reject
        resolver(resolve, reject)
      })
    } else {
      resolver(resolve, reject)
    }
  })
}

/**
 * Generate (recursively) the params
 *
 * @param {String} prefix The param prefix
 * @param {Object/Array} value Values that will be mapped to params
 * @param {Boolean} top Check if the value is at top level
 * @param {String} acc Accumulate the result
 * @return {String} The full QueryString (just remember that a last '&' will not be removed)
 */
const _recBuildParams = function(prefix, value, top, acc) {
  // Different treatment to array sources
  if( typeof value === 'object') {
    // Each the value
    for( let i in value ) {
      // Check if its a number
      let nan = isNaN(i);

      // Build the recursion again, setting the accumulator
      acc = _recBuildParams(`${(nan && top) ? i : prefix}${(nan && !top) ? '[' + i + ']' : nan ? '' : '[]'}`, value[i], false, acc);
    }
  } else {
    // Aggregate to the accumulator
    // acc += `${encodeURIComponent(prefix)}=${encodeURIComponent(value)}&`;
    acc += `${prefix}=${encodeURIComponent(value)}&`;
  }

  // Return the accumlator
  return acc;
}
<commit_msg>Spacings<commit_after>/**
 *
 *
 * @TODO Better support to the others HTTP verbs
 */

// Dependencies
import { fetch } from './request';

// Configurations
import { get, set } from './config';

/**
 * Generate the options to make a request
 *
 * @param {String} method The HTTP method (mainly GET or POST)
 * @param {String} path The path that will be used as base
 * @param {Object} data Data passed in the request
 * @param {String} auth The API token (previsouly queried)
 * @param {String} name Store name
 * @param {String} version The API version
 * @param {String} token The API token
 * @return {Object} Base configuration for the request
 */
export const buildRequest = function(method, path, data, auth = get('auth'), store = get('store'), version = get('version'), token = get('token')) {
  // Query String
  let qs = '';

  // Generate the QueryString if its necessary
  if( method === 'GET' && data !== undefined )
    qs = buildParams(data);

  // Request Headers
  let headers = {};

  // Check if a token is passed to be used
  if( token !== undefined )
    headers['Yebo-Token'] = token;

  // Return the request options
  return {
    name: path.split('/').join('-').substring(1),
    method: method,
    url: `${get('protocol')}://${store}.${get('apiURL')}/${version}${path}${qs}`,
    data: method === 'GET' ? {} : data,
    headers: headers,
    content_type: method === 'GET' ? 'application/x-www-form-urlencoded' : 'application/json'
  };
}

/**
 * Build the request that will get the authentication token
 *
 * @param {String} name Store name
 * @param {String} version The API version
 * @param {String} token The API token
 * @return {Object} Request that will return the authentication token
 */
export const buildAuthentication = function(name, version, token) {
  return buildRequest('GET', '/', {}, undefined, name, version, token);
};

/**
 * Execute the Authentication
 *
 * @param {String} name Store name
 * @param {String} version The API version
 * @param {String} token The API token
 * @return {Promise} Result of the authentication
 */
export const authenticate = function(name = get('store'), version = get('version'), token = get('token')) {
  return executeRequest(buildAuthentication(name, version, token));
}

/**
 * Based on an array generate
 *
 * @param {Object/Array} value Values that will be mapped to QueryString
 * @return {String} QueryString itself
 */
export const buildParams = function(value) {
  return _recBuildParams('', value, true, '?').slice(0, -1);
}

/**
 * Execute the generated requestç
 *
 * @param {Object} req Generated request
 * @return {Promise} The HTTP request Promise
 */
export const executeRequest = function(req) {
  const resolver = (res, rej) => {
    // Check if the authentication token is passed
    req.headers['Authorization'] = `Bearer ${get('authToken')}`

    //
    fetch(req.method, req.url, req.data, req.contentType, req.headers).then(res).catch(rej);
  }
  return new Promise((resolve, reject) => {
    //
    if (req.name !== '' && get('expireAt') > Date.now()) {
      // authenticate
      authenticate().then((res) => {
        // res.token
        set('authToken', res.token)
        // res.expire_at
        set('expireAt', res.expire_at)
        // resolver reolve and reject
        resolver(resolve, reject)
      })
    } else {
      resolver(resolve, reject)
    }
  })
}

/**
 * Generate (recursively) the params
 *
 * @param {String} prefix The param prefix
 * @param {Object/Array} value Values that will be mapped to params
 * @param {Boolean} top Check if the value is at top level
 * @param {String} acc Accumulate the result
 * @return {String} The full QueryString (just remember that a last '&' will not be removed)
 */
const _recBuildParams = function(prefix, value, top, acc) {
  // Different treatment to array sources
  if( typeof value === 'object') {
    // Each the value
    for( let i in value ) {
      // Check if its a number
      let nan = isNaN(i);

      // Build the recursion again, setting the accumulator
      acc = _recBuildParams(`${(nan && top) ? i : prefix}${(nan && !top) ? '[' + i + ']' : nan ? '' : '[]'}`, value[i], false, acc);
    }
  } else {
    // Aggregate to the accumulator
    // acc += `${encodeURIComponent(prefix)}=${encodeURIComponent(value)}&`;
    acc += `${prefix}=${encodeURIComponent(value)}&`;
  }

  // Return the accumlator
  return acc;
}
<|endoftext|>


<commit_before>import {STROKE_WIDTH} from 'src/shared/constants';
/**
 * Accepts an array of raw influxdb responses and returns a format
 * that Dygraph understands.
 */

// activeQueryIndex is an optional argument that indicated which query's series
// we want highlighted.
export default function timeSeriesToDygraph(raw = [], activeQueryIndex, isInDataExplorer) {
  const labels = []; // all of the effective field names (i.e. <measurement>.<field>)
  const fieldToIndex = {}; // see parseSeries
  const dates = {}; // map of date as string to date value to minimize string coercion
  const dygraphSeries = {}; // dygraphSeries is a graph legend label and its corresponding y-axis e.g. {legendLabel1: 'y', legendLabel2: 'y2'};

  /**
   * dateToFieldValue will look like:
   *
   * {
   *   Date1: {
   *     effectiveFieldName_1: ValueForField1AtDate1,
   *     effectiveFieldName_2: ValueForField2AtDate1,
   *     ...
   *   },
   *   Date2: {
   *     effectiveFieldName_1: ValueForField1AtDate2,
   *     effectiveFieldName_2: ValueForField2AtDate2,
   *     ...
   *   }
   * }
   */
  const dateToFieldValue = {};

  raw.forEach(({response}, queryIndex) => {
    // If a response is an empty result set or a query returned an error
    // from InfluxDB, don't try and parse.
    if (response.results.length) {
      if (isEmpty(response) || hasError(response)) {
        return;
      }
    }

    /**
     * response looks like:
     * {
     *   results: [
     *     { series: [...] },
     *     { series: [...] },
     *   ]
     * }
     */
    response.results.forEach(parseResult);

    function parseResult(s) {
      /*
       * s looks like:
       * {
       *   series: [
       *     {
       *       name: "<measurement>",
       *       columns: ["time", "<field name 1>", "<field name 2>", ...],
       *       values: [<time>, <value of field 1>, <value of field 2>, ...],
       *     },
       * }
       */
      s.series.forEach(parseSeries);
    }

    function parseSeries(series) {
      /*
       * series looks like:
       * {
       *   name: "<measurement>",
       *   columns: ["time", "<field name 1>", "<field name 2>", ...],
       *   values: [
       *    [<time1>, <value of field 1 @ time1>, <value of field 2 @ time1>, ...],
       *    [<time2>, <value of field 1 @ time2>, <value of field 2 @ time2>, ...],
       *   ]
       * }
       */
      const measurementName = series.name;
      const columns = series.columns;

      // Tags are only included in an influxdb response under certain circumstances, e.g.
      // when a query is using GROUP BY (<tag key>).
      const tags = Object.keys(series.tags || {}).map((key) => {
        return `[${key}=${series.tags[key]}]`;
      }).sort().join('');

      columns.slice(1).forEach((fieldName) => {
        const effectiveFieldName = `${measurementName}.${fieldName}${tags}`;

        // Given a field name, identify which column in the timeSeries result should hold the field's value
        // ex given this timeSeries [Date, 10, 20, 30] field index at 2 would correspond to value 20
        fieldToIndex[effectiveFieldName] = labels.length + 1;
        labels.push(effectiveFieldName);

        const {light, heavy} = STROKE_WIDTH;

        // only want to set multiple axes for precanned dashboards
        if (isInDataExplorer) {
          dygraphSeries[effectiveFieldName] = {
            strokeWidth: queryIndex === activeQueryIndex ? heavy : light,
          };
        } else {
          dygraphSeries[effectiveFieldName] = {
            axis: queryIndex === 0 ? 'y' : 'y2',
            strokeWidth: queryIndex === activeQueryIndex ? heavy : light,
          };
        }
      });

      (series.values || []).forEach(parseRow);

      function parseRow(row) {
        /**
         * row looks like:
         *   [<time1>, <value of field 1 @ time1>, <value of field 2 @ time1>, ...]
         */
        const date = row[0];
        const dateString = date.toString();
        row.forEach((value, index) => {
          if (index === 0) {
            // index 0 in a row is always the timestamp
            if (!dateToFieldValue[dateString]) {
              dateToFieldValue[dateString] = {};
              dates[dateString] = date;
            }
            return;
          }

          const fieldName = columns[index];
          const effectiveFieldName = `${measurementName}.${fieldName}${tags}`;
          dateToFieldValue[dateString][effectiveFieldName] = value;
        });
      }
    }
  });

  function buildTimeSeries() {
    const allDates = Object.keys(dateToFieldValue);
    allDates.sort((a, b) => a - b);
    const rowLength = labels.length + 1;
    return allDates.map((date) => {
      const row = new Array(rowLength);

      row.fill(null);
      row[0] = new Date(dates[date]);

      const fieldsForRow = dateToFieldValue[date];
      Object.keys(fieldsForRow).forEach((effectiveFieldName) => {
        row[fieldToIndex[effectiveFieldName]] = fieldsForRow[effectiveFieldName];
      });

      return row;
    });
  }

  return {
    labels: ['time', ...labels.sort()],
    timeSeries: buildTimeSeries(),
    dygraphSeries,
  };
}

function isEmpty(resp) {
  return !resp.results[0].series;
}

function hasError(resp) {
  return !!resp.results[0].error;
}

<commit_msg>Handle multiple responses with identical field and measurement names<commit_after>import {STROKE_WIDTH} from 'src/shared/constants';
/**
 * Accepts an array of raw influxdb responses and returns a format
 * that Dygraph understands.
 */

// activeQueryIndex is an optional argument that indicated which query's series
// we want highlighted.
export default function timeSeriesToDygraph(raw = [], activeQueryIndex, isInDataExplorer) {
  const labels = []; // all of the effective field names (i.e. <measurement>.<field>)
  const fieldToIndex = {}; // see parseSeries
  const dates = {}; // map of date as string to date value to minimize string coercion
  const dygraphSeries = {}; // dygraphSeries is a graph legend label and its corresponding y-axis e.g. {legendLabel1: 'y', legendLabel2: 'y2'};

  /**
   * dateToFieldValue will look like:
   *
   * {
   *   Date1: {
   *     effectiveFieldName_1: ValueForField1AtDate1,
   *     effectiveFieldName_2: ValueForField2AtDate1,
   *     ...
   *   },
   *   Date2: {
   *     effectiveFieldName_1: ValueForField1AtDate2,
   *     effectiveFieldName_2: ValueForField2AtDate2,
   *     ...
   *   }
   * }
   */
  const dateToFieldValue = {};

  raw.forEach(({response}, queryIndex) => {
    // If a response is an empty result set or a query returned an error
    // from InfluxDB, don't try and parse.
    if (response.results.length) {
      if (isEmpty(response) || hasError(response)) {
        return;
      }
    }

    /**
     * response looks like:
     * {
     *   results: [
     *     { series: [...] },
     *     { series: [...] },
     *   ]
     * }
     */
    response.results.forEach(parseResult);

    function parseResult(s) {
      /*
       * s looks like:
       * {
       *   series: [
       *     {
       *       name: "<measurement>",
       *       columns: ["time", "<field name 1>", "<field name 2>", ...],
       *       values: [<time>, <value of field 1>, <value of field 2>, ...],
       *     },
       * }
       */
      s.series.forEach(parseSeries);
    }

    function parseSeries(series) {
      /*
       * series looks like:
       * {
       *   name: "<measurement>",
       *   columns: ["time", "<field name 1>", "<field name 2>", ...],
       *   values: [
       *    [<time1>, <value of field 1 @ time1>, <value of field 2 @ time1>, ...],
       *    [<time2>, <value of field 1 @ time2>, <value of field 2 @ time2>, ...],
       *   ]
       * }
       */
      const measurementName = series.name;
      const columns = series.columns;

      // Tags are only included in an influxdb response under certain circumstances, e.g.
      // when a query is using GROUP BY (<tag key>).
      const tags = Object.keys(series.tags || {}).map((key) => {
        return `[${key}=${series.tags[key]}]`;
      }).sort().join('');

      columns.slice(1).forEach((fieldName) => {
        let effectiveFieldName = `${measurementName}.${fieldName}${tags}`;

        // If there are duplicate effectiveFieldNames identify them by their queryIndex
        if (effectiveFieldName in dygraphSeries) {
          effectiveFieldName = `${effectiveFieldName}-${queryIndex}`;
        }

        // Given a field name, identify which column in the timeSeries result should hold the field's value
        // ex given this timeSeries [Date, 10, 20, 30] field index at 2 would correspond to value 20
        fieldToIndex[effectiveFieldName] = labels.length + 1;
        labels.push(effectiveFieldName);

        const {light, heavy} = STROKE_WIDTH;

        // only want to set multiple axes for precanned dashboards
        if (isInDataExplorer) {
          dygraphSeries[effectiveFieldName] = {
            strokeWidth: queryIndex === activeQueryIndex ? heavy : light,
          };
        } else {
          dygraphSeries[effectiveFieldName] = {
            axis: queryIndex === 0 ? 'y' : 'y2',
            strokeWidth: queryIndex === activeQueryIndex ? heavy : light,
          };
        }
      });

      (series.values || []).forEach(parseRow);

      function parseRow(row) {
        /**
         * row looks like:
         *   [<time1>, <value of field 1 @ time1>, <value of field 2 @ time1>, ...]
         */
        const date = row[0];
        const dateString = date.toString();
        row.forEach((value, index) => {
          if (index === 0) {
            // index 0 in a row is always the timestamp
            if (!dateToFieldValue[dateString]) {
              dateToFieldValue[dateString] = {};
              dates[dateString] = date;
            }
            return;
          }

          const fieldName = columns[index];
          let effectiveFieldName = `${measurementName}.${fieldName}${tags}`;

          // If there are duplicate effectiveFieldNames identify them by their queryIndex
          if (effectiveFieldName in dateToFieldValue[dateString]) {
            effectiveFieldName = `${effectiveFieldName}-${queryIndex}`;
          }

          dateToFieldValue[dateString][effectiveFieldName] = value;
        });
      }
    }
  });

  function buildTimeSeries() {
    const allDates = Object.keys(dateToFieldValue);
    allDates.sort((a, b) => a - b);
    const rowLength = labels.length + 1;
    return allDates.map((date) => {
      const row = new Array(rowLength);

      row.fill(null);
      row[0] = new Date(dates[date]);

      const fieldsForRow = dateToFieldValue[date];
      Object.keys(fieldsForRow).forEach((effectiveFieldName) => {
        row[fieldToIndex[effectiveFieldName]] = fieldsForRow[effectiveFieldName];
      });

      return row;
    });
  }

  return {
    labels: ['time', ...labels.sort()],
    timeSeries: buildTimeSeries(),
    dygraphSeries,
  };
}

function isEmpty(resp) {
  return !resp.results[0].series;
}

function hasError(resp) {
  return !!resp.results[0].error;
}

<|endoftext|>


<commit_before>const winston = require('winston');
// Add the logger
const logger = new (winston.Logger)({
  transports: [
    // colorize the output to the console
    new (winston.transports.Console)({ colorize: true }),
  ],
});

module.exports = function init() {
  // This function reads in all configs and merges them
  /* eslint-disable global-require */
  const defaultConfig = require('./defaults');
  let customConfig = {};
  try {
    customConfig = require('../../config');
  } catch (err) {
    // Do nothing
  }
  /* eslint-enable global-require */
  const cliConfig = {};
  if (process.env.LOG_LEVEL) {
    cliConfig.logLevel = process.env.LOG_LEVEL;
  }
  if (process.env.RENOVATE_TOKEN) {
    cliConfig.token = process.env.RENOVATE_TOKEN;
  }
  // Check if repository name and package file are provided via CLI
  const repoName = process.argv[2];
  const packageFile = process.argv[3] || 'package.json';
  if (repoName) {
    cliConfig.repositories = [
      {
        name: repoName,
        packageFiles: [packageFile],
      },
    ];
  }
  const config = Object.assign(defaultConfig, customConfig, cliConfig);
  // First, convert any strings to objects
  config.repositories.forEach((repo, index) => {
    if (typeof repo === 'string') {
      config.repositories[index] = { name: repo };
    }
  });
  // Add 'package.json' if missing
  config.repositories.forEach((repo, index) => {
    if (!repo.packageFiles || !repo.packageFiles.length) {
      config.repositories[index].packageFiles = ['package.json'];
    }
  });

  // Winston log level can be controlled via config or env
  if (config.logLevel) {
    logger.level = config.logLevel;
  }
  logger.verbose(config);
  config.logger = logger;

  // token must be defined
  if (typeof config.token === 'undefined') {
    logger.error('Error: A GitHub token must be configured');
    process.exit(1);
  }
  // We also need a repository
  if (!config.repositories || config.repositories.length === 0) {
    logger.error('Error: At least one repository must be configured');
  }

  return config;
};
<commit_msg>Add disable for import/no-unresolved<commit_after>const winston = require('winston');
// Add the logger
const logger = new (winston.Logger)({
  transports: [
    // colorize the output to the console
    new (winston.transports.Console)({ colorize: true }),
  ],
});

module.exports = function init() {
  // This function reads in all configs and merges them
  /* eslint-disable global-require */
  const defaultConfig = require('./defaults');
  let customConfig = {};
  try {
    customConfig = require('../../config'); // eslint-disable-line import/no-unresolved
  } catch (err) {
    // Do nothing
  }
  /* eslint-enable global-require */
  const cliConfig = {};
  if (process.env.LOG_LEVEL) {
    cliConfig.logLevel = process.env.LOG_LEVEL;
  }
  if (process.env.RENOVATE_TOKEN) {
    cliConfig.token = process.env.RENOVATE_TOKEN;
  }
  // Check if repository name and package file are provided via CLI
  const repoName = process.argv[2];
  const packageFile = process.argv[3] || 'package.json';
  if (repoName) {
    cliConfig.repositories = [
      {
        name: repoName,
        packageFiles: [packageFile],
      },
    ];
  }
  const config = Object.assign(defaultConfig, customConfig, cliConfig);
  // First, convert any strings to objects
  config.repositories.forEach((repo, index) => {
    if (typeof repo === 'string') {
      config.repositories[index] = { name: repo };
    }
  });
  // Add 'package.json' if missing
  config.repositories.forEach((repo, index) => {
    if (!repo.packageFiles || !repo.packageFiles.length) {
      config.repositories[index].packageFiles = ['package.json'];
    }
  });

  // Winston log level can be controlled via config or env
  if (config.logLevel) {
    logger.level = config.logLevel;
  }
  logger.verbose(config);
  config.logger = logger;

  // token must be defined
  if (typeof config.token === 'undefined') {
    logger.error('Error: A GitHub token must be configured');
    process.exit(1);
  }
  // We also need a repository
  if (!config.repositories || config.repositories.length === 0) {
    logger.error('Error: At least one repository must be configured');
  }

  return config;
};
<|endoftext|>


<commit_before>/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/
var et = require('elementtree'),
    xml= require('./xml-helpers'),
    fs = require('fs');

function config_parser(path) {
    this.path = path;
    this.doc = xml.parseElementtreeSync(path);
    this.access = new access(this);
    this.preference = new preference(this);
}

config_parser.prototype = {
    packageName:function(id) {
        if (id) {
            this.doc.getroot().attrib.id = id;
            this.update();
        } else return this.doc.getroot().attrib.id;
    },
    name:function(name) {
        if (name) {
            this.doc.find('name').text = name;
            this.update();
        } else return this.doc.find('name').text;
    },
    version:function(version) {
        if (version) {
            this.doc.getroot().attrib.version = version;
            this.update();
        } else return this.doc.getroot().attrib.version;
    },
    content: function(src) {
        var content = this.doc.find('content');
        if (src) {
            content = content || new et.Element('content');
            content.attrib.src = src;
            this.update();
        } else {
            if (!content) {
                content = new et.Element('content');
                content.attrib.src = 'index.html';
                this.doc.getroot().append(content);
                this.update();
            }
            return content.attrib.src;
        }
    },
    author: function (name) {
        if (name) {
            var author = this.doc.find('author');
            if (!author) {
                author = new et.Element('author');
                this.doc.getroot().append(author);
            }

            author.text = name;
            this.update();
        }
        else {
            var author = this.doc.find('author');
            return author ? author.text : '';
        }
    },
    update:function() {
        fs.writeFileSync(this.path, this.doc.write({indent: 4}), 'utf-8');
    },
    merge_with: function (cfg, platform, clobber) {
        var BLACKLIST = ["platform"],
            SINGLETONS = ["content", "author"];
        mergeXml(cfg.doc.getroot(), this.doc.getroot(), platform, clobber);
        this.update();

        function mergeXml(src, dest, platform, clobber) {
            if (BLACKLIST.indexOf(src.tag) === -1) {
                //Handle attributes
                Object.getOwnPropertyNames(src.attrib).forEach(function (attribute) {
                    if (clobber || !dest.attrib[attribute]) {
                        dest.attrib[attribute] = src.attrib[attribute];
                    }
                });
                //Handle text
                if (src.text && (clobber || !dest.text)) {
                    dest.text = src.text;
                }
                //Handle platform
                if (platform) {
                    src.findall('platform[@name="' + platform + '"]').forEach(function (platformElement) {
                        platformElement.getchildren().forEach(mergeChild);
                    });
                }

                //Handle children
                src.getchildren().forEach(mergeChild);

                function mergeChild (srcChild) {
                    var srcTag = srcChild.tag,
                        destChild = new et.Element(srcTag),
                        foundChild,
                        query = srcTag + "",
                        shouldMerge = true;

                    if (BLACKLIST.indexOf(srcTag) === -1) {
                        if (SINGLETONS.indexOf(srcTag) !== -1) {
                            foundChild = dest.find(query);
                            if (foundChild) {
                                destChild = foundChild;
                                dest.remove(0, destChild);
                            }
                        } else {
                            //Check for an exact match and if you find one don't add
                            Object.getOwnPropertyNames(srcChild.attrib).forEach(function (attribute) {
                                query += "[@" + attribute + '="' + srcChild.attrib[attribute] + '"]';
                            });
                            foundChild = dest.find(query);
                            if (foundChild && textMatch(srcChild, foundChild)) {
                                destChild = foundChild;
                                dest.remove(0, destChild);
                                shouldMerge = false;
                            }
                        }

                        mergeXml(srcChild, destChild, platform, clobber && shouldMerge);
                        dest.append(destChild);
                    }
                }

                function textMatch(elm1, elm2) {
                    var text1 = elm1.text ? elm1.text.replace(/\s+/, "") : "",
                        text2 = elm2.text ? elm2.text.replace(/\s+/, "") : "";
                    return (text1 === "" || text1 === text2);
                }
            }
        }
    }
};

function access(cfg) {
    this.config = cfg;
};

access.prototype = {
    add:function(uri, subdomain) {
        var el = new et.Element('access');
        el.attrib.origin = uri;
        if (typeof subdomain !== "undefined") el.attrib.subdomains = subdomain;
        this.config.doc.getroot().append(el);
        this.config.update();
    },
    remove:function(uri) {
        var self = this;
        var els = [];
        if (uri) els = this.config.doc.findall('access[@origin="' + uri + '"]');
        else els = this.config.doc.findall('access');
        els.forEach(function(a) {
            self.config.doc.getroot().remove(0, a);
        });
        this.config.update();
    },
    get:function() {
        return this.config.doc.findall('access').map(function(a) { return a.attrib.origin || a.attrib.uri; });
    },
    getAttributes:function() {
        return this.config.doc.findall('access').map(function(a) { return a.attrib; });
    }
};

function preference(cfg) {
    this.config = cfg;
};

preference.prototype = {
    add:function(pref) {
        var el = new et.Element('preference');
        el.attrib.name = pref.name;
        el.attrib.value = pref.value;
        this.config.doc.getroot().append(el);
        this.config.update();
    },
    remove:function(name) {
        var self = this;
        var els = [];
        if (name) els = this.config.doc.findall('preference[@name="' + name + '"]');
        else els = this.config.doc.findall('preference');
        els.forEach(function(a) {
            self.config.doc.getroot().remove(0, a);
        });
        this.config.update();
    },
    get:function() {
        return this.config.doc.findall('preference').map(function(a) {
            return {
                name:a.attrib.name,
                value:a.attrib.value
            };
        });
    }
};

module.exports = config_parser;
<commit_msg>removes traling spaces when reads author from config.xml<commit_after>/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/
var et = require('elementtree'),
    xml= require('./xml-helpers'),
    fs = require('fs');

function config_parser(path) {
    this.path = path;
    this.doc = xml.parseElementtreeSync(path);
    this.access = new access(this);
    this.preference = new preference(this);
}

config_parser.prototype = {
    packageName:function(id) {
        if (id) {
            this.doc.getroot().attrib.id = id;
            this.update();
        } else return this.doc.getroot().attrib.id;
    },
    name:function(name) {
        if (name) {
            this.doc.find('name').text = name;
            this.update();
        } else return this.doc.find('name').text;
    },
    version:function(version) {
        if (version) {
            this.doc.getroot().attrib.version = version;
            this.update();
        } else return this.doc.getroot().attrib.version;
    },
    content: function(src) {
        var content = this.doc.find('content');
        if (src) {
            content = content || new et.Element('content');
            content.attrib.src = src;
            this.update();
        } else {
            if (!content) {
                content = new et.Element('content');
                content.attrib.src = 'index.html';
                this.doc.getroot().append(content);
                this.update();
            }
            return content.attrib.src;
        }
    },
    author: function (name) {
        if (name) {
            var author = this.doc.find('author');
            if (!author) {
                author = new et.Element('author');
                this.doc.getroot().append(author);
            }

            author.text = name;
            this.update();
        }
        else {
            var author = this.doc.find('author');
            return author ? author.text.trim() : '';
        }
    },
    update:function() {
        fs.writeFileSync(this.path, this.doc.write({indent: 4}), 'utf-8');
    },
    merge_with: function (cfg, platform, clobber) {
        var BLACKLIST = ["platform"],
            SINGLETONS = ["content", "author"];
        mergeXml(cfg.doc.getroot(), this.doc.getroot(), platform, clobber);
        this.update();

        function mergeXml(src, dest, platform, clobber) {
            if (BLACKLIST.indexOf(src.tag) === -1) {
                //Handle attributes
                Object.getOwnPropertyNames(src.attrib).forEach(function (attribute) {
                    if (clobber || !dest.attrib[attribute]) {
                        dest.attrib[attribute] = src.attrib[attribute];
                    }
                });
                //Handle text
                if (src.text && (clobber || !dest.text)) {
                    dest.text = src.text;
                }
                //Handle platform
                if (platform) {
                    src.findall('platform[@name="' + platform + '"]').forEach(function (platformElement) {
                        platformElement.getchildren().forEach(mergeChild);
                    });
                }

                //Handle children
                src.getchildren().forEach(mergeChild);

                function mergeChild (srcChild) {
                    var srcTag = srcChild.tag,
                        destChild = new et.Element(srcTag),
                        foundChild,
                        query = srcTag + "",
                        shouldMerge = true;

                    if (BLACKLIST.indexOf(srcTag) === -1) {
                        if (SINGLETONS.indexOf(srcTag) !== -1) {
                            foundChild = dest.find(query);
                            if (foundChild) {
                                destChild = foundChild;
                                dest.remove(0, destChild);
                            }
                        } else {
                            //Check for an exact match and if you find one don't add
                            Object.getOwnPropertyNames(srcChild.attrib).forEach(function (attribute) {
                                query += "[@" + attribute + '="' + srcChild.attrib[attribute] + '"]';
                            });
                            foundChild = dest.find(query);
                            if (foundChild && textMatch(srcChild, foundChild)) {
                                destChild = foundChild;
                                dest.remove(0, destChild);
                                shouldMerge = false;
                            }
                        }

                        mergeXml(srcChild, destChild, platform, clobber && shouldMerge);
                        dest.append(destChild);
                    }
                }

                function textMatch(elm1, elm2) {
                    var text1 = elm1.text ? elm1.text.replace(/\s+/, "") : "",
                        text2 = elm2.text ? elm2.text.replace(/\s+/, "") : "";
                    return (text1 === "" || text1 === text2);
                }
            }
        }
    }
};

function access(cfg) {
    this.config = cfg;
};

access.prototype = {
    add:function(uri, subdomain) {
        var el = new et.Element('access');
        el.attrib.origin = uri;
        if (typeof subdomain !== "undefined") el.attrib.subdomains = subdomain;
        this.config.doc.getroot().append(el);
        this.config.update();
    },
    remove:function(uri) {
        var self = this;
        var els = [];
        if (uri) els = this.config.doc.findall('access[@origin="' + uri + '"]');
        else els = this.config.doc.findall('access');
        els.forEach(function(a) {
            self.config.doc.getroot().remove(0, a);
        });
        this.config.update();
    },
    get:function() {
        return this.config.doc.findall('access').map(function(a) { return a.attrib.origin || a.attrib.uri; });
    },
    getAttributes:function() {
        return this.config.doc.findall('access').map(function(a) { return a.attrib; });
    }
};

function preference(cfg) {
    this.config = cfg;
};

preference.prototype = {
    add:function(pref) {
        var el = new et.Element('preference');
        el.attrib.name = pref.name;
        el.attrib.value = pref.value;
        this.config.doc.getroot().append(el);
        this.config.update();
    },
    remove:function(name) {
        var self = this;
        var els = [];
        if (name) els = this.config.doc.findall('preference[@name="' + name + '"]');
        else els = this.config.doc.findall('preference');
        els.forEach(function(a) {
            self.config.doc.getroot().remove(0, a);
        });
        this.config.update();
    },
    get:function() {
        return this.config.doc.findall('preference').map(function(a) {
            return {
                name:a.attrib.name,
                value:a.attrib.value
            };
        });
    }
};

module.exports = config_parser;
<|endoftext|>


<commit_before>// @if TARGET='app'
import { execSync } from 'child_process';
import isDev from 'electron-is-dev';
import { ipcRenderer, remote } from 'electron';
// @endif
import path from 'path';
import * as ACTIONS from 'constants/action_types';
import * as MODALS from 'constants/modal_types';
import {
  Lbry,
  doBalanceSubscribe,
  doFetchFileInfosAndPublishedClaims,
  doError,
  makeSelectClaimForUri,
  makeSelectClaimIsMine,
  doPopulateSharedUserState,
  doFetchChannelListMine,
  doClearPublish,
  doPreferenceGet,
  doToast,
  doClearSupport,
  SHARED_PREFERENCES,
} from 'lbry-redux';
import Native from 'native';
import { doFetchDaemonSettings, doSetAutoLaunch, doSetDaemonSetting } from 'redux/actions/settings';
import {
  selectIsUpgradeSkipped,
  selectUpdateUrl,
  selectUpgradeDownloadItem,
  selectUpgradeDownloadPath,
  selectUpgradeFilename,
  selectAutoUpdateDeclined,
  selectRemoteVersion,
  selectUpgradeTimer,
  selectModal,
  selectAllowAnalytics,
} from 'redux/selectors/app';
import { selectDaemonSettings } from 'redux/selectors/settings';
import { doAuthenticate, doGetSync } from 'lbryinc';
import { lbrySettings as config, version as appVersion } from 'package.json';
import analytics, { SHARE_INTERNAL } from 'analytics';
import { doSignOutCleanup, deleteSavedPassword, getSavedPassword } from 'util/saved-passwords';

// @if TARGET='app'
const { autoUpdater } = remote.require('electron-updater');
const { download } = remote.require('electron-dl');
const Fs = remote.require('fs');
// @endif

const CHECK_UPGRADE_INTERVAL = 10 * 60 * 1000;

export function doOpenModal(id, modalProps = {}) {
  return {
    type: ACTIONS.SHOW_MODAL,
    data: {
      id,
      modalProps,
    },
  };
}

export function doHideModal() {
  return {
    type: ACTIONS.HIDE_MODAL,
  };
}

export function doUpdateDownloadProgress(percent) {
  return {
    type: ACTIONS.UPGRADE_DOWNLOAD_PROGRESSED,
    data: {
      percent,
    },
  };
}

export function doSkipUpgrade() {
  return {
    type: ACTIONS.SKIP_UPGRADE,
  };
}

export function doStartUpgrade() {
  return (dispatch, getState) => {
    const state = getState();
    const upgradeDownloadPath = selectUpgradeDownloadPath(state);

    ipcRenderer.send('upgrade', upgradeDownloadPath);
  };
}

export function doDownloadUpgrade() {
  return (dispatch, getState) => {
    // @if TARGET='app'
    const state = getState();
    // Make a new directory within temp directory so the filename is guaranteed to be available
    const dir = Fs.mkdtempSync(remote.app.getPath('temp') + path.sep);
    const upgradeFilename = selectUpgradeFilename(state);

    const options = {
      onProgress: p => dispatch(doUpdateDownloadProgress(Math.round(p * 100))),
      directory: dir,
    };
    download(remote.getCurrentWindow(), selectUpdateUrl(state), options).then(downloadItem => {
      /**
       * TODO: get the download path directly from the download object. It should just be
       * downloadItem.getSavePath(), but the copy on the main process is being garbage collected
       * too soon.
       */

      dispatch({
        type: ACTIONS.UPGRADE_DOWNLOAD_COMPLETED,
        data: {
          downloadItem,
          path: path.join(dir, upgradeFilename),
        },
      });
    });

    dispatch({
      type: ACTIONS.UPGRADE_DOWNLOAD_STARTED,
    });
    dispatch(doHideModal());
    dispatch(doOpenModal(MODALS.DOWNLOADING));
    // @endif
  };
}

export function doDownloadUpgradeRequested() {
  // This means the user requested an upgrade by clicking the "upgrade" button in the navbar.
  // If on Mac and Windows, we do some new behavior for the auto-update system.
  // This will probably be reorganized once we get auto-update going on Linux and remove
  // the old logic.

  return dispatch => {
    if (['win32', 'darwin'].includes(process.platform) || !!process.env.APPIMAGE) {
      // electron-updater behavior
      dispatch(doOpenModal(MODALS.AUTO_UPDATE_DOWNLOADED));
    } else {
      // Old behavior for Linux
      dispatch(doDownloadUpgrade());
    }
  };
}

export function doClearUpgradeTimer() {
  return (dispatch, getState) => {
    const state = getState();

    if (selectUpgradeTimer(state)) {
      clearInterval(selectUpgradeTimer(state));
      dispatch({
        type: ACTIONS.CLEAR_UPGRADE_TIMER,
      });
    }
  };
}

export function doAutoUpdate() {
  return dispatch => {
    dispatch({
      type: ACTIONS.AUTO_UPDATE_DOWNLOADED,
    });

    dispatch(doOpenModal(MODALS.AUTO_UPDATE_DOWNLOADED));

    dispatch(doClearUpgradeTimer());
  };
}

export function doAutoUpdateDeclined() {
  return dispatch => {
    dispatch(doClearUpgradeTimer());

    dispatch({
      type: ACTIONS.AUTO_UPDATE_DECLINED,
    });
  };
}

export function doCancelUpgrade() {
  return (dispatch, getState) => {
    const state = getState();
    const upgradeDownloadItem = selectUpgradeDownloadItem(state);

    if (upgradeDownloadItem) {
      /*
       * Right now the remote reference to the download item gets garbage collected as soon as the
       * the download is over (maybe even earlier), so trying to cancel a finished download may
       * throw an error.
       */
      try {
        upgradeDownloadItem.cancel();
      } catch (err) {
        console.error(err); // eslint-disable-line no-console
      }
    }

    dispatch({ type: ACTIONS.UPGRADE_CANCELLED });
  };
}

export function doCheckUpgradeAvailable() {
  return (dispatch, getState) => {
    const state = getState();
    dispatch({
      type: ACTIONS.CHECK_UPGRADE_START,
    });

    if (['win32', 'darwin'].includes(process.platform) || !!process.env.APPIMAGE) {
      // On Windows, Mac, and AppImage, updates happen silently through
      // electron-updater.
      const autoUpdateDeclined = selectAutoUpdateDeclined(state);

      if (!autoUpdateDeclined && !isDev) {
        autoUpdater.checkForUpdates();
      }
      return;
    }

    const success = ({ remoteVersion, upgradeAvailable }) => {
      dispatch({
        type: ACTIONS.CHECK_UPGRADE_SUCCESS,
        data: {
          upgradeAvailable,
          remoteVersion,
        },
      });

      if (
        upgradeAvailable &&
        !selectModal(state) &&
        (!selectIsUpgradeSkipped(state) || remoteVersion !== selectRemoteVersion(state))
      ) {
        dispatch(doOpenModal(MODALS.UPGRADE));
      }
    };

    const fail = () => {
      dispatch({
        type: ACTIONS.CHECK_UPGRADE_FAIL,
      });
    };

    Native.getAppVersionInfo().then(success, fail);
  };
}

/*
  Initiate a timer that will check for an app upgrade every 10 minutes.
 */
export function doCheckUpgradeSubscribe() {
  return dispatch => {
    const checkUpgradeTimer = setInterval(() => dispatch(doCheckUpgradeAvailable()), CHECK_UPGRADE_INTERVAL);
    dispatch({
      type: ACTIONS.CHECK_UPGRADE_SUBSCRIBE,
      data: { checkUpgradeTimer },
    });
  };
}

export function doCheckDaemonVersion() {
  return dispatch => {
    // @if TARGET='app'
    Lbry.version().then(({ lbrynet_version: lbrynetVersion }) => {
      // Avoid the incompatible daemon modal if running in dev mode
      // Lets you  run a different daemon than the one specified in package.json
      if (config.lbrynetDaemonVersion === lbrynetVersion || process.env.NODE_ENV !== 'production') {
        return dispatch({
          type: ACTIONS.DAEMON_VERSION_MATCH,
        });
      }

      dispatch({
        type: ACTIONS.DAEMON_VERSION_MISMATCH,
      });
      if (process.env.NODE_ENV === 'production') {
        return dispatch(doOpenModal(MODALS.INCOMPATIBLE_DAEMON));
      }
    });
    // @endif
    // @if TARGET='web'
    dispatch({
      type: ACTIONS.DAEMON_VERSION_MATCH,
    });
    // @endif
  };
}

export function doNotifyEncryptWallet() {
  return dispatch => {
    dispatch(doOpenModal(MODALS.WALLET_ENCRYPT));
  };
}

export function doNotifyDecryptWallet() {
  return dispatch => {
    dispatch(doOpenModal(MODALS.WALLET_DECRYPT));
  };
}

export function doNotifyUnlockWallet() {
  return dispatch => {
    dispatch(doOpenModal(MODALS.WALLET_UNLOCK));
  };
}

export function doNotifyForgetPassword(props) {
  return dispatch => {
    dispatch(doOpenModal(MODALS.WALLET_PASSWORD_UNSAVE, props));
  };
}

export function doAlertError(errorList) {
  return dispatch => {
    dispatch(doError(errorList));
  };
}

export function doDaemonReady() {
  return (dispatch, getState) => {
    const state = getState();

    // TODO: call doFetchDaemonSettings, then get usage data, and call doAuthenticate once they are loaded into the store
    const shareUsageData = window.localStorage.getItem(SHARE_INTERNAL) === 'true';

    dispatch(doAuthenticate(appVersion, undefined, undefined, shareUsageData));
    dispatch({ type: ACTIONS.DAEMON_READY });

    // @if TARGET='app'
    dispatch(doBalanceSubscribe());
    dispatch(doSetAutoLaunch());
    dispatch(doFetchDaemonSettings());
    dispatch(doFetchFileInfosAndPublishedClaims());
    if (!selectIsUpgradeSkipped(state)) {
      dispatch(doCheckUpgradeAvailable());
    }
    dispatch(doCheckUpgradeSubscribe());
    // @endif
  };
}

export function doClearCache() {
  return dispatch => {
    // Need to update this to work with new version of redux-persist
    // Leaving for now
    // const reducersToClear = whiteListedReducers.filter(reducerKey => reducerKey !== 'tags');
    // window.cacheStore.purge(reducersToClear);
    window.localStorage.clear();
    dispatch(doClearSupport());
    return dispatch(doClearPublish());
  };
}

export function doQuit() {
  return () => {
    // @if TARGET='app'
    remote.app.quit();
    // @endif
  };
}

export function doQuitAnyDaemon() {
  return dispatch => {
    // @if TARGET='app'
    Lbry.stop()
      .catch(() => {
        try {
          if (process.platform === 'win32') {
            execSync('taskkill /im lbrynet.exe /t /f');
          } else {
            execSync('pkill lbrynet');
          }
        } catch (error) {
          dispatch(doAlertError(`Quitting daemon failed due to: ${error.message}`));
        }
      })
      .finally(() => {
        dispatch(doQuit());
      });
    // @endif
  };
}

export function doChangeVolume(volume) {
  return dispatch => {
    dispatch({
      type: ACTIONS.VOLUME_CHANGED,
      data: {
        volume,
      },
    });
  };
}

export function doChangeMute(muted) {
  return dispatch => {
    dispatch({
      type: ACTIONS.VOLUME_MUTED,
      data: {
        muted,
      },
    });
  };
}

export function doClickCommentButton() {
  return {
    type: ACTIONS.ADD_COMMENT,
  };
}

export function doToggleSearchExpanded() {
  return {
    type: ACTIONS.TOGGLE_SEARCH_EXPANDED,
  };
}

export function doAnalyticsView(uri, timeToStart) {
  return (dispatch, getState) => {
    const state = getState();
    const { txid, nout, claim_id: claimId } = makeSelectClaimForUri(uri)(state);
    const claimIsMine = makeSelectClaimIsMine(uri)(state);
    const outpoint = `${txid}:${nout}`;

    if (claimIsMine) {
      return Promise.resolve();
    }

    return analytics.apiLogView(uri, outpoint, claimId, timeToStart);
  };
}

export function doSignIn() {
  return (dispatch, getState) => {
    // @if TARGET='web'
    dispatch(doBalanceSubscribe());
    dispatch(doFetchChannelListMine());
    // @endif
  };
}

export function doSignOut() {
  return dispatch => {
    doSignOutCleanup()
      .then(() => {
        // @if TARGET='web'
        window.persistor.purge();
        // @endif
      })
      .then(() => {
        setTimeout(() => {
          location.reload();
        });
      })
      .catch(() => location.reload());
  };
}

export function doSetWelcomeVersion(version) {
  return {
    type: ACTIONS.SET_WELCOME_VERSION,
    data: version,
  };
}

export function doToggle3PAnalytics(allowParam, doNotDispatch) {
  return (dispatch, getState) => {
    const state = getState();
    const allowState = selectAllowAnalytics(state);
    const allow = allowParam !== undefined && allowParam !== null ? allowParam : allowState;
    analytics.toggleThirdParty(allow);
    if (!doNotDispatch) {
      return dispatch({
        type: ACTIONS.SET_ALLOW_ANALYTICS,
        data: allow,
      });
    }
  };
}

export function doGetAndPopulatePreferences() {
  return (dispatch, getState) => {
    function successCb(savedPreferences) {
      const state = getState();
      const daemonSettings = selectDaemonSettings(state);

      if (savedPreferences !== null) {
        dispatch(doPopulateSharedUserState(savedPreferences));
        // @if TARGET='app'
        const { settings, sharing_3P: sharing3P } = savedPreferences.value;
        // apply daemonSettings (todo: separate function)
        Object.entries(settings).forEach(([key, val]) => {
          if (val !== null && daemonSettings[key] !== val) {
            if (key === SHARED_PREFERENCES.WALLET_SERVERS) {
              const hasSavedServers = Array.isArray(val) && val.length > 0;
              if (hasSavedServers) {
                // Ignore this key if there are no actual saved servers in the list
                const servers = val.map(item => `${item[0]}:${item[1]}`);
                dispatch(doSetDaemonSetting(key, servers, true));
              }
            } else {
              dispatch(doSetDaemonSetting(key, val, true));
            }
          }
        });
        if (sharing3P !== undefined) {
          doToggle3PAnalytics(sharing3P, true);
        }
        // @endif
      }
    }

    function failCb() {
      deleteSavedPassword().then(() => {
        dispatch(
          doToast({
            isError: true,
            message: __('Unable to load your saved preferences.'),
          })
        );
      });
    }

    doPreferenceGet('shared', successCb, failCb);
  };
}

export function doSyncWithPreferences() {
  return dispatch => {
    function handleSyncComplete() {
      // we just got sync data, better update our channels
      dispatch(doFetchChannelListMine());
      dispatch(doGetAndPopulatePreferences());
    }

    return getSavedPassword().then(password => {
      const passwordArgument = password === null ? '' : password;

      dispatch(doGetSync(passwordArgument, handleSyncComplete));
    });
  };
}
<commit_msg>comment out broken preference sync code<commit_after>// @if TARGET='app'
import { execSync } from 'child_process';
import isDev from 'electron-is-dev';
import { ipcRenderer, remote } from 'electron';
// @endif
import path from 'path';
import * as ACTIONS from 'constants/action_types';
import * as MODALS from 'constants/modal_types';
import {
  Lbry,
  doBalanceSubscribe,
  doFetchFileInfosAndPublishedClaims,
  doError,
  makeSelectClaimForUri,
  makeSelectClaimIsMine,
  doPopulateSharedUserState,
  doFetchChannelListMine,
  doClearPublish,
  doPreferenceGet,
  doToast,
  doClearSupport,
  // SHARED_PREFERENCES,
} from 'lbry-redux';
import Native from 'native';
import {
  doFetchDaemonSettings,
  doSetAutoLaunch,
  //  doSetDaemonSetting
} from 'redux/actions/settings';
import {
  selectIsUpgradeSkipped,
  selectUpdateUrl,
  selectUpgradeDownloadItem,
  selectUpgradeDownloadPath,
  selectUpgradeFilename,
  selectAutoUpdateDeclined,
  selectRemoteVersion,
  selectUpgradeTimer,
  selectModal,
  selectAllowAnalytics,
} from 'redux/selectors/app';
// import { selectDaemonSettings } from 'redux/selectors/settings';
import { doAuthenticate, doGetSync } from 'lbryinc';
import { lbrySettings as config, version as appVersion } from 'package.json';
import analytics, { SHARE_INTERNAL } from 'analytics';
import { doSignOutCleanup, deleteSavedPassword, getSavedPassword } from 'util/saved-passwords';

// @if TARGET='app'
const { autoUpdater } = remote.require('electron-updater');
const { download } = remote.require('electron-dl');
const Fs = remote.require('fs');
// @endif

const CHECK_UPGRADE_INTERVAL = 10 * 60 * 1000;

export function doOpenModal(id, modalProps = {}) {
  return {
    type: ACTIONS.SHOW_MODAL,
    data: {
      id,
      modalProps,
    },
  };
}

export function doHideModal() {
  return {
    type: ACTIONS.HIDE_MODAL,
  };
}

export function doUpdateDownloadProgress(percent) {
  return {
    type: ACTIONS.UPGRADE_DOWNLOAD_PROGRESSED,
    data: {
      percent,
    },
  };
}

export function doSkipUpgrade() {
  return {
    type: ACTIONS.SKIP_UPGRADE,
  };
}

export function doStartUpgrade() {
  return (dispatch, getState) => {
    const state = getState();
    const upgradeDownloadPath = selectUpgradeDownloadPath(state);

    ipcRenderer.send('upgrade', upgradeDownloadPath);
  };
}

export function doDownloadUpgrade() {
  return (dispatch, getState) => {
    // @if TARGET='app'
    const state = getState();
    // Make a new directory within temp directory so the filename is guaranteed to be available
    const dir = Fs.mkdtempSync(remote.app.getPath('temp') + path.sep);
    const upgradeFilename = selectUpgradeFilename(state);

    const options = {
      onProgress: p => dispatch(doUpdateDownloadProgress(Math.round(p * 100))),
      directory: dir,
    };
    download(remote.getCurrentWindow(), selectUpdateUrl(state), options).then(downloadItem => {
      /**
       * TODO: get the download path directly from the download object. It should just be
       * downloadItem.getSavePath(), but the copy on the main process is being garbage collected
       * too soon.
       */

      dispatch({
        type: ACTIONS.UPGRADE_DOWNLOAD_COMPLETED,
        data: {
          downloadItem,
          path: path.join(dir, upgradeFilename),
        },
      });
    });

    dispatch({
      type: ACTIONS.UPGRADE_DOWNLOAD_STARTED,
    });
    dispatch(doHideModal());
    dispatch(doOpenModal(MODALS.DOWNLOADING));
    // @endif
  };
}

export function doDownloadUpgradeRequested() {
  // This means the user requested an upgrade by clicking the "upgrade" button in the navbar.
  // If on Mac and Windows, we do some new behavior for the auto-update system.
  // This will probably be reorganized once we get auto-update going on Linux and remove
  // the old logic.

  return dispatch => {
    if (['win32', 'darwin'].includes(process.platform) || !!process.env.APPIMAGE) {
      // electron-updater behavior
      dispatch(doOpenModal(MODALS.AUTO_UPDATE_DOWNLOADED));
    } else {
      // Old behavior for Linux
      dispatch(doDownloadUpgrade());
    }
  };
}

export function doClearUpgradeTimer() {
  return (dispatch, getState) => {
    const state = getState();

    if (selectUpgradeTimer(state)) {
      clearInterval(selectUpgradeTimer(state));
      dispatch({
        type: ACTIONS.CLEAR_UPGRADE_TIMER,
      });
    }
  };
}

export function doAutoUpdate() {
  return dispatch => {
    dispatch({
      type: ACTIONS.AUTO_UPDATE_DOWNLOADED,
    });

    dispatch(doOpenModal(MODALS.AUTO_UPDATE_DOWNLOADED));

    dispatch(doClearUpgradeTimer());
  };
}

export function doAutoUpdateDeclined() {
  return dispatch => {
    dispatch(doClearUpgradeTimer());

    dispatch({
      type: ACTIONS.AUTO_UPDATE_DECLINED,
    });
  };
}

export function doCancelUpgrade() {
  return (dispatch, getState) => {
    const state = getState();
    const upgradeDownloadItem = selectUpgradeDownloadItem(state);

    if (upgradeDownloadItem) {
      /*
       * Right now the remote reference to the download item gets garbage collected as soon as the
       * the download is over (maybe even earlier), so trying to cancel a finished download may
       * throw an error.
       */
      try {
        upgradeDownloadItem.cancel();
      } catch (err) {
        console.error(err); // eslint-disable-line no-console
      }
    }

    dispatch({ type: ACTIONS.UPGRADE_CANCELLED });
  };
}

export function doCheckUpgradeAvailable() {
  return (dispatch, getState) => {
    const state = getState();
    dispatch({
      type: ACTIONS.CHECK_UPGRADE_START,
    });

    if (['win32', 'darwin'].includes(process.platform) || !!process.env.APPIMAGE) {
      // On Windows, Mac, and AppImage, updates happen silently through
      // electron-updater.
      const autoUpdateDeclined = selectAutoUpdateDeclined(state);

      if (!autoUpdateDeclined && !isDev) {
        autoUpdater.checkForUpdates();
      }
      return;
    }

    const success = ({ remoteVersion, upgradeAvailable }) => {
      dispatch({
        type: ACTIONS.CHECK_UPGRADE_SUCCESS,
        data: {
          upgradeAvailable,
          remoteVersion,
        },
      });

      if (
        upgradeAvailable &&
        !selectModal(state) &&
        (!selectIsUpgradeSkipped(state) || remoteVersion !== selectRemoteVersion(state))
      ) {
        dispatch(doOpenModal(MODALS.UPGRADE));
      }
    };

    const fail = () => {
      dispatch({
        type: ACTIONS.CHECK_UPGRADE_FAIL,
      });
    };

    Native.getAppVersionInfo().then(success, fail);
  };
}

/*
  Initiate a timer that will check for an app upgrade every 10 minutes.
 */
export function doCheckUpgradeSubscribe() {
  return dispatch => {
    const checkUpgradeTimer = setInterval(() => dispatch(doCheckUpgradeAvailable()), CHECK_UPGRADE_INTERVAL);
    dispatch({
      type: ACTIONS.CHECK_UPGRADE_SUBSCRIBE,
      data: { checkUpgradeTimer },
    });
  };
}

export function doCheckDaemonVersion() {
  return dispatch => {
    // @if TARGET='app'
    Lbry.version().then(({ lbrynet_version: lbrynetVersion }) => {
      // Avoid the incompatible daemon modal if running in dev mode
      // Lets you  run a different daemon than the one specified in package.json
      if (config.lbrynetDaemonVersion === lbrynetVersion || process.env.NODE_ENV !== 'production') {
        return dispatch({
          type: ACTIONS.DAEMON_VERSION_MATCH,
        });
      }

      dispatch({
        type: ACTIONS.DAEMON_VERSION_MISMATCH,
      });
      if (process.env.NODE_ENV === 'production') {
        return dispatch(doOpenModal(MODALS.INCOMPATIBLE_DAEMON));
      }
    });
    // @endif
    // @if TARGET='web'
    dispatch({
      type: ACTIONS.DAEMON_VERSION_MATCH,
    });
    // @endif
  };
}

export function doNotifyEncryptWallet() {
  return dispatch => {
    dispatch(doOpenModal(MODALS.WALLET_ENCRYPT));
  };
}

export function doNotifyDecryptWallet() {
  return dispatch => {
    dispatch(doOpenModal(MODALS.WALLET_DECRYPT));
  };
}

export function doNotifyUnlockWallet() {
  return dispatch => {
    dispatch(doOpenModal(MODALS.WALLET_UNLOCK));
  };
}

export function doNotifyForgetPassword(props) {
  return dispatch => {
    dispatch(doOpenModal(MODALS.WALLET_PASSWORD_UNSAVE, props));
  };
}

export function doAlertError(errorList) {
  return dispatch => {
    dispatch(doError(errorList));
  };
}

export function doDaemonReady() {
  return (dispatch, getState) => {
    const state = getState();

    // TODO: call doFetchDaemonSettings, then get usage data, and call doAuthenticate once they are loaded into the store
    const shareUsageData = window.localStorage.getItem(SHARE_INTERNAL) === 'true';

    dispatch(doAuthenticate(appVersion, undefined, undefined, shareUsageData));
    dispatch({ type: ACTIONS.DAEMON_READY });

    // @if TARGET='app'
    dispatch(doBalanceSubscribe());
    dispatch(doSetAutoLaunch());
    dispatch(doFetchDaemonSettings());
    dispatch(doFetchFileInfosAndPublishedClaims());
    if (!selectIsUpgradeSkipped(state)) {
      dispatch(doCheckUpgradeAvailable());
    }
    dispatch(doCheckUpgradeSubscribe());
    // @endif
  };
}

export function doClearCache() {
  return dispatch => {
    // Need to update this to work with new version of redux-persist
    // Leaving for now
    // const reducersToClear = whiteListedReducers.filter(reducerKey => reducerKey !== 'tags');
    // window.cacheStore.purge(reducersToClear);
    window.localStorage.clear();
    dispatch(doClearSupport());
    return dispatch(doClearPublish());
  };
}

export function doQuit() {
  return () => {
    // @if TARGET='app'
    remote.app.quit();
    // @endif
  };
}

export function doQuitAnyDaemon() {
  return dispatch => {
    // @if TARGET='app'
    Lbry.stop()
      .catch(() => {
        try {
          if (process.platform === 'win32') {
            execSync('taskkill /im lbrynet.exe /t /f');
          } else {
            execSync('pkill lbrynet');
          }
        } catch (error) {
          dispatch(doAlertError(`Quitting daemon failed due to: ${error.message}`));
        }
      })
      .finally(() => {
        dispatch(doQuit());
      });
    // @endif
  };
}

export function doChangeVolume(volume) {
  return dispatch => {
    dispatch({
      type: ACTIONS.VOLUME_CHANGED,
      data: {
        volume,
      },
    });
  };
}

export function doChangeMute(muted) {
  return dispatch => {
    dispatch({
      type: ACTIONS.VOLUME_MUTED,
      data: {
        muted,
      },
    });
  };
}

export function doClickCommentButton() {
  return {
    type: ACTIONS.ADD_COMMENT,
  };
}

export function doToggleSearchExpanded() {
  return {
    type: ACTIONS.TOGGLE_SEARCH_EXPANDED,
  };
}

export function doAnalyticsView(uri, timeToStart) {
  return (dispatch, getState) => {
    const state = getState();
    const { txid, nout, claim_id: claimId } = makeSelectClaimForUri(uri)(state);
    const claimIsMine = makeSelectClaimIsMine(uri)(state);
    const outpoint = `${txid}:${nout}`;

    if (claimIsMine) {
      return Promise.resolve();
    }

    return analytics.apiLogView(uri, outpoint, claimId, timeToStart);
  };
}

export function doSignIn() {
  return (dispatch, getState) => {
    // @if TARGET='web'
    dispatch(doBalanceSubscribe());
    dispatch(doFetchChannelListMine());
    // @endif
  };
}

export function doSignOut() {
  return dispatch => {
    doSignOutCleanup()
      .then(() => {
        // @if TARGET='web'
        window.persistor.purge();
        // @endif
      })
      .then(() => {
        setTimeout(() => {
          location.reload();
        });
      })
      .catch(() => location.reload());
  };
}

export function doSetWelcomeVersion(version) {
  return {
    type: ACTIONS.SET_WELCOME_VERSION,
    data: version,
  };
}

export function doToggle3PAnalytics(allowParam, doNotDispatch) {
  return (dispatch, getState) => {
    const state = getState();
    const allowState = selectAllowAnalytics(state);
    const allow = allowParam !== undefined && allowParam !== null ? allowParam : allowState;
    analytics.toggleThirdParty(allow);
    if (!doNotDispatch) {
      return dispatch({
        type: ACTIONS.SET_ALLOW_ANALYTICS,
        data: allow,
      });
    }
  };
}

export function doGetAndPopulatePreferences() {
  return (dispatch, getState) => {
    function successCb(savedPreferences) {
      // const state = getState();
      // const daemonSettings = selectDaemonSettings(state);

      if (savedPreferences !== null) {
        dispatch(doPopulateSharedUserState(savedPreferences));
        // @if TARGET='app'
        // const { settings, sharing_3P: sharing3P } = savedPreferences.value;
        // // apply daemonSettings (todo: separate function)
        // Object.entries(settings).forEach(([key, val]) => {
        //   if (val !== null && daemonSettings[key] !== val) {
        //     if (key === SHARED_PREFERENCES.WALLET_SERVERS) {
        //       const hasSavedServers = Array.isArray(val) && val.length > 0;
        //       if (hasSavedServers) {
        //         // Ignore this key if there are no actual saved servers in the list
        //         const servers = val.map(item => `${item[0]}:${item[1]}`);
        //         dispatch(doSetDaemonSetting(key, servers, true));
        //       }
        //     } else {
        //       dispatch(doSetDaemonSetting(key, val, true));
        //     }
        //   }
        // });
        // if (sharing3P !== undefined) {
        //   doToggle3PAnalytics(sharing3P, true);
        // }
        // @endif
      }
    }

    function failCb() {
      deleteSavedPassword().then(() => {
        dispatch(
          doToast({
            isError: true,
            message: __('Unable to load your saved preferences.'),
          })
        );
      });
    }

    doPreferenceGet('shared', successCb, failCb);
  };
}

export function doSyncWithPreferences() {
  return dispatch => {
    function handleSyncComplete() {
      // we just got sync data, better update our channels
      dispatch(doFetchChannelListMine());
      dispatch(doGetAndPopulatePreferences());
    }

    return getSavedPassword().then(password => {
      const passwordArgument = password === null ? '' : password;

      dispatch(doGetSync(passwordArgument, handleSyncComplete));
    });
  };
}
<|endoftext|>