<commit_before>import {
  cmsOperations,
  abeExtend,
  cmsData,
  Manager,
  config
} from '../../../../cli'

var route = function(req, res, next){
  abeExtend.hooks.instance.trigger('beforeRoute', req, res, next)
  if(typeof res._header !== 'undefined' && res._header !== null) return

  var operation = cmsData.regex.getWorkflowFromOperationsUrl(req.originalUrl)

  var p = cmsOperations.post.submit(
    operation.postUrl,
    req.body.json,
    operation.workflow
  )

  p.then((result) => {
    // Auto-republish if the config is setup and the posts limit is not reached
    if(operation.workflow === 'publish' && config.publish['auto-republish'] && config.publish['auto-republish'].active){
      var nbPosts = Manager.instance.getList().length
      if(config.publish['auto-republish'].limit >= nbPosts){
        var proc = abeExtend.process('generate-posts', [''], (data) => {
          res.app.emit("generate-posts", data)
        })
        if (proc) {
          res.app.emit("generate-posts", {percent: 0, time: "00:00sec"})
          console.log('generate-posts emitted')
        }
      }
    }
    res.app.emit("activity-stream", {operation: operation.workflow, post: operation.postUrl, user: res.user.username})
    res.set('Content-Type', 'application/json')
    res.send(JSON.stringify(result))
  },
  (result) => {
    res.set('Content-Type', 'application/json')
    res.send(JSON.stringify(result))
  }).catch(function(e) {
    console.error('[ERROR] submit.js', e)
  })
}

export default route<commit_msg>fix: activity stream when anonymous is set<commit_after>import {
  cmsOperations,
  abeExtend,
  cmsData,
  Manager,
  config
} from '../../../../cli'

var route = function(req, res, next){
  abeExtend.hooks.instance.trigger('beforeRoute', req, res, next)
  if(typeof res._header !== 'undefined' && res._header !== null) return

  var operation = cmsData.regex.getWorkflowFromOperationsUrl(req.originalUrl)

  var p = cmsOperations.post.submit(
    operation.postUrl,
    req.body.json,
    operation.workflow
  )

  p.then((result) => {
    // Auto-republish if the config is setup and the posts limit is not reached
    if(operation.workflow === 'publish' && config.publish['auto-republish'] && config.publish['auto-republish'].active){
      var nbPosts = Manager.instance.getList().length
      if(config.publish['auto-republish'].limit >= nbPosts){
        var proc = abeExtend.process('generate-posts', [''], (data) => {
          res.app.emit("generate-posts", data)
        })
        if (proc) {
          res.app.emit("generate-posts", {percent: 0, time: "00:00sec"})
          console.log('generate-posts emitted')
        }
      }
    }
    var username = ''
    if(res.user && res.user.username){
      username = res.user.username
    }
    res.app.emit("activity-stream", {operation: operation.workflow, post: operation.postUrl, user: username})
    res.set('Content-Type', 'application/json')
    res.send(JSON.stringify(result))
  },
  (result) => {
    res.set('Content-Type', 'application/json')
    res.send(JSON.stringify(result))
  }).catch(function(e) {
    console.error('[ERROR] submit.js', e)
  })
}

export default route<|endoftext|>


<commit_before>import {createSelector} from 'reselect'
import {STATUS} from './constants'
import {getGridLayoutUtil} from  './utils'

const getCells = state => state.game.cells
const getSettings = state => state.game.settings

export const getGridLayout = createSelector(
  getSettings,
  getGridLayoutUtil
)

const getCellCounts = createSelector(
  getSettings,
  getCells,
  (settings, cells) => {
    return Object.keys(cells).reduce((counts, id) => {
      return Object.assign({}, counts, {
        openCellCount: cells[id].open ? counts.openCellCount + 1 : counts.openCellCount,
        openingCellCount: cells[id].opening ? counts.openingCellCount + 1 : counts.openingCellCount,
        flaggedCellCount: cells[id].flagged ? counts.flaggedCellCount + 1 : counts.flaggedCellCount,
        detonatedCellCount: cells[id].detonated ? counts.detonatedCellCount + 1 : counts.detonatedCellCount
      })}, {
      openCellCount: 0,
      openingCellCount: 0,
      flaggedCellCount: 0,
      detonatedCellCount: 0,
      totalCellCount: settings.rowCount * settings.colCount
    })
  }
)

export const getStatus = createSelector(
  getSettings,
  getCellCounts,
  ({mineCount}, cellCounts) => {
    if (cellCounts.detonatedCellCount > 0) return STATUS.FAILED
    if (cellCounts.openCellCount === cellCounts.totalCellCount - mineCount) return STATUS.CLEARED
    if (cellCounts.openingCellCount > 0) return STATUS.DANGER
    return STATUS.NEUTRAL
  }
)

export const getRemainingFlagsCount = createSelector(
  getSettings,
  getCellCounts,
  ({mineCount}, {flaggedCellCount}) => Math.max(mineCount - flaggedCellCount, 0)
)

export const getGameOver = createSelector(
  getStatus,
  status => status === STATUS.CLEARED || status === STATUS.FAILED
)

export const getStarted = createSelector(
  getCellCounts,
  cellCounts => cellCounts.openCount > 0
)<commit_msg>update cleared status selector logic<commit_after>import {createSelector} from 'reselect'
import {STATUS} from './constants'
import {getGridLayoutUtil} from  './utils'

const getCells = state => state.game.cells
const getSettings = state => state.game.settings

export const getGridLayout = createSelector(
  getSettings,
  getGridLayoutUtil
)

const getCellCounts = createSelector(
  getSettings,
  getCells,
  (settings, cells) => {
    return Object.keys(cells).reduce((counts, id) => {
      return Object.assign({}, counts, {
        openCellCount: cells[id].open ? counts.openCellCount + 1 : counts.openCellCount,
        openingCellCount: cells[id].opening ? counts.openingCellCount + 1 : counts.openingCellCount,
        flaggedCellCount: cells[id].flagged ? counts.flaggedCellCount + 1 : counts.flaggedCellCount,
        detonatedCellCount: cells[id].detonated ? counts.detonatedCellCount + 1 : counts.detonatedCellCount
      })}, {
      openCellCount: 0,
      openingCellCount: 0,
      flaggedCellCount: 0,
      detonatedCellCount: 0,
      totalCellCount: settings.rowCount * settings.colCount
    })
  }
)

export const getStatus = createSelector(
  getSettings,
  getCellCounts,
  ({mineCount}, cellCounts) => {
    if (cellCounts.detonatedCellCount > 0) return STATUS.FAILED
    if (cellCounts.openCellCount >= cellCounts.totalCellCount - mineCount) return STATUS.CLEARED
    if (cellCounts.openingCellCount > 0) return STATUS.DANGER
    return STATUS.NEUTRAL
  }
)

export const getRemainingFlagsCount = createSelector(
  getSettings,
  getCellCounts,
  ({mineCount}, {flaggedCellCount}) => Math.max(mineCount - flaggedCellCount, 0)
)

export const getGameOver = createSelector(
  getStatus,
  status => status === STATUS.CLEARED || status === STATUS.FAILED
)

export const getStarted = createSelector(
  getCellCounts,
  cellCounts => cellCounts.openCount > 0
)<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';

export class ManualFileEncodingSetting extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            manEncodingMode: false
        }

        this.manCheckboxChanged = this.manCheckboxChanged.bind(this);
    }

    manCheckboxChanged(e) {
        const checkboxElm = e.target;
        if (checkboxElm.checked) {
            this.setState({ manEncodingMode: true });
        } else {
            this.setState({ manEncodingMode: false });
        }
    }

    render() {
        const { subId } = this.props;
        return (
            <div
                id={`manual_file_encoding_setting_${subId}`}>

                    <label htmlFor={`manual_encoding_detection_${subId}`} className="form-check-label">
                        <input
                            type="checkbox"
                            onChange={this.manCheckboxChanged}
                            className="manual_encoding_detection form-check-input"
                            value=""
                            id={`manual_encoding_detection_${subId}`} />
                        I want to set file encoding manually

                {
                    (this.state.manEncodingMode) ?
                        (
                            <div
                                className="manual_encoding_selection"
                                id={`manual_encoding_selection_${subId}`}>

                                    Please chose an encoding from the list or
                                    type one in the box below and then load
                                    your subtitle in the open subtitle section

                                <select id={`encoding_select_${subId}`}>
                                    <option value="UTF-8">UTF-8 (default)</option>
                                    <option value="CP1251">CP1251</option>
                                    <option value="ANSI">ANSI</option>
                                    <option value="ISO-8859-1">ISO-8859-1</option>
                                    <option value="windows-1252">Windows 1252 (Western Latin)</option>
                                    <option value="windows-1256">Windows 1256 (Arabic)</option>
                                </select>

                                <input
                                    id={`manual_encoding_input_${subId}`}
                                    type="text"
                                    placeholder="or enter it here (ex. windows-1252)" />

                        ) : null
                }

        )
    }
}<commit_msg>p instead of span for smaller font size (bootstrap)<commit_after>import React from 'react';
import ReactDOM from 'react-dom';

export class ManualFileEncodingSetting extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            manEncodingMode: false
        }

        this.manCheckboxChanged = this.manCheckboxChanged.bind(this);
    }

    manCheckboxChanged(e) {
        const checkboxElm = e.target;
        if (checkboxElm.checked) {
            this.setState({ manEncodingMode: true });
        } else {
            this.setState({ manEncodingMode: false });
        }
    }

    render() {
        const { subId } = this.props;
        return (
            <div
                id={`manual_file_encoding_setting_${subId}`}>

                    <label htmlFor={`manual_encoding_detection_${subId}`} className="form-check-label">
                        <input
                            type="checkbox"
                            onChange={this.manCheckboxChanged}
                            className="manual_encoding_detection form-check-input"
                            value=""
                            id={`manual_encoding_detection_${subId}`} />
                        I want to set file encoding manually

                {
                    (this.state.manEncodingMode) ?
                        (
                            <div
                                className="manual_encoding_selection"
                                id={`manual_encoding_selection_${subId}`}>

                                    Please chose an encoding from the list or
                                    type one in the box below and then load
                                    your subtitle in the open subtitle section

                                <select id={`encoding_select_${subId}`}>
                                    <option value="UTF-8">UTF-8 (default)</option>
                                    <option value="CP1251">CP1251</option>
                                    <option value="ANSI">ANSI</option>
                                    <option value="ISO-8859-1">ISO-8859-1</option>
                                    <option value="windows-1252">Windows 1252 (Western Latin)</option>
                                    <option value="windows-1256">Windows 1256 (Arabic)</option>
                                </select>

                                <input
                                    id={`manual_encoding_input_${subId}`}
                                    type="text"
                                    placeholder="or enter it here (ex. windows-1252)" />

                        ) : null
                }

        )
    }
}<|endoftext|>


<commit_before>var http = require('http');

port = 3000;
host = '127.0.0.1';

server = http.createServer( function(req, res) {

    if (req.method == 'POST') {
        console.log("Handling POST request...");
        res.writeHead(200, {'Content-Type': 'text/html'});

        var body = '';
        req.on('data', function (data) {
            body += data;
        });
        req.on('end', function () {
            console.log("POST payload: " + body);
        	res.end( '' );
        });
    }
    else
    {
        console.log("Not expecting other request types...");
        res.writeHead(200, {'Content-Type': 'text/html'});
		var html = 'HTTP Server at http://' + host + ':' + port + '';
        res.end(html);
    }

});

server.listen(port, host);
console.log('Listening at http://' + host + ':' + port);
<commit_msg>finished basic json endpoint<commit_after>var http = require('http');

///////////////////////////////////////////
// Prerequisites for running the server. //
///////////////////////////////////////////

// Obtain local ip address to create an appropriate server.

var os = require('os');
var ifaces = os.networkInterfaces();

var myHost = null;

Object.keys(ifaces).forEach(function (ifname) {
    ifaces[ifname].forEach(function (iface) {
        if (iface.internal || iface.family == 'IPv6')
            return;
        else
            myHost = iface.address;
    });
});

// TODO: Find an open port to use
port = 8099;

var dataObj = null;

server = http.createServer( function(req, res) {
    if (req.method == 'POST')
    {
        res.writeHead(200, {'Content-Type': 'text/html'});

        var body = '';
        req.on('data', function (data) {
            body += data;
        });

        req.on('end', function () {
            dataObj = JSON.parse(body);
        });
    }
    else
    {
        res.writeHead(200, {'Content-Type': 'application/json'});

        if (dataObj)
        {
            res.end(JSON.stringify(dataObj));
        }
        else
        {
            res.end(JSON.stringify({ data: null }));
        }
    }
});

try {
    // Listen to both external ips and internal ips
    // External ip used by Device connected with Pebble
    server.listen(port, myHost);

    // Internal ip used by CSGO to connect.
    server.listen(port);

    // Verbose statements
    console.log('Listening at http://' + myHost + ':' + port);
    console.log('Please go to the pebble watch settings and insert: http://' + myHost + ':' + port);
}
catch (e)
{
    console.log('Could not obtain an open port at ' + port + '. Please try again.');
}
<|endoftext|>


<commit_before>import foursquareApi from '@haroenv/react-foursquare';
import {
  REACT_APP_FOURSQUARE_ID,
  REACT_APP_FOURSQUARE_SECRET,
} from 'react-native-dotenv';

const foursquare = foursquareApi({
  clientID: REACT_APP_FOURSQUARE_ID,
  clientSecret: REACT_APP_FOURSQUARE_SECRET,
});

export const FOURSQUARE_CATEGORIES = [
  '4d4b7104d754a06370d81259',
  '4bf58dd8d48988d12d941735',
];

export type VenueType = {
  name: string,
  id: string,
};

export async function getVenues({
  latitude,
  longitude,
  blacklist = [],
  ...query
}): Array<VenueType> {
  const { response: { venues } } = await foursquare.venues.getVenues({
    ll: `${latitude},${longitude}`,
    ...query,
  });

  const filtered =
    venues.length > 0
      ? venues.filter(({ id }) => blacklist.indexOf(id) === -1)
      : venues;

  return filtered.map(
    ({
      id,
      name,
      stats,
      location: { lat, lng, distance: dist },
      categories,
    }) => ({
      id,
      name,
      location: { latitude: lat, longitude: lng },
      distance: dist,
      score: getScore(stats),
      category: categories[0].name,
    })
  );
}

export const getVenuePhoto = id =>
  foursquare.venues.getVenuePhotos({
    venue_id: id,
    limit: 1,
  });

export function getScore({ checkinsCount, usersCount, tipCount }) {
  const weightedCheckins = checkinsCount / 400000.0;
  const weightedTips = tipCount / 2000.0 * 1.5;
  const weightedUsers = usersCount / 400000.0;

  const weightedScore = weightedCheckins + weightedTips + weightedUsers;
  return Math.max(1, Math.ceil(Math.pow(weightedScore * 10000000, 0.3)));
}

const toRadians = degrees => degrees * Math.PI / 180;

export function calculateHeading({ from, to, userHeading }) {
  const R = 6371e3; // metres
  const φ1 = toRadians(from.latitude);
  const φ2 = toRadians(to.latitude);
  const Δφ = toRadians(to.latitude - from.latitude);
  const Δλ = toRadians(to.longitude - from.longitude);

  const a =
    Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
    Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ / 2) * Math.sin(Δλ / 2);
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

  const d = R * c;

  return d - toRadians(userHeading);
}

export function distance(first, second) {
  const R = 6371e3; // metres
  const p = Math.PI / 180;
  const a =
    0.5 -
    Math.cos((second.latitude - first.latitude) * p) / 2 +
    Math.cos(first.latitude * p) *
      Math.cos(second.latitude * p) *
      (1 - Math.cos((second.longitude - first.longitude) * p)) /
      2;

  return R * Math.asin(Math.sqrt(a));
}
<commit_msg>better venue type<commit_after>import foursquareApi from '@haroenv/react-foursquare';
import {
  REACT_APP_FOURSQUARE_ID,
  REACT_APP_FOURSQUARE_SECRET,
} from 'react-native-dotenv';

const foursquare = foursquareApi({
  clientID: REACT_APP_FOURSQUARE_ID,
  clientSecret: REACT_APP_FOURSQUARE_SECRET,
});

export const FOURSQUARE_CATEGORIES = [
  '4d4b7104d754a06370d81259',
  '4bf58dd8d48988d12d941735',
];

export type VenueType = {
  name: string,
  id: string,
  location: {
    latitude: number,
    longitude: number,
  },
  distance: number,
  score: number,
  category: string,
};

export async function getVenues({
  latitude,
  longitude,
  blacklist = [],
  ...query
}): Array<VenueType> {
  const { response: { venues } } = await foursquare.venues.getVenues({
    ll: `${latitude},${longitude}`,
    ...query,
  });

  const filtered =
    venues.length > 0
      ? venues.filter(({ id }) => blacklist.indexOf(id) === -1)
      : venues;

  return filtered.map(
    ({
      id,
      name,
      stats,
      location: { lat, lng, distance: dist },
      categories,
    }) => ({
      id,
      name,
      location: { latitude: lat, longitude: lng },
      distance: dist,
      score: getScore(stats),
      category: categories[0].name,
    })
  );
}

export const getVenuePhoto = id =>
  foursquare.venues.getVenuePhotos({
    venue_id: id,
    limit: 1,
  });

export function getScore({ checkinsCount, usersCount, tipCount }) {
  const weightedCheckins = checkinsCount / 400000.0;
  const weightedTips = tipCount / 2000.0 * 1.5;
  const weightedUsers = usersCount / 400000.0;

  const weightedScore = weightedCheckins + weightedTips + weightedUsers;
  return Math.max(1, Math.ceil(Math.pow(weightedScore * 10000000, 0.3)));
}

const toRadians = degrees => degrees * Math.PI / 180;

export function calculateHeading({ from, to, userHeading }) {
  const R = 6371e3; // metres
  const φ1 = toRadians(from.latitude);
  const φ2 = toRadians(to.latitude);
  const Δφ = toRadians(to.latitude - from.latitude);
  const Δλ = toRadians(to.longitude - from.longitude);

  const a =
    Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
    Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ / 2) * Math.sin(Δλ / 2);
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

  const d = R * c;

  return d - toRadians(userHeading);
}

export function distance(first, second) {
  const R = 6371e3; // metres
  const p = Math.PI / 180;
  const a =
    0.5 -
    Math.cos((second.latitude - first.latitude) * p) / 2 +
    Math.cos(first.latitude * p) *
      Math.cos(second.latitude * p) *
      (1 - Math.cos((second.longitude - first.longitude) * p)) /
      2;

  return R * Math.asin(Math.sqrt(a));
}
<|endoftext|>


<commit_before>/**
 *
 * @authors liwb (you@example.org)
 * @date    2017/11/13 11:13
 * @version $ https://github.com/mzabriskie/axios
 * 安卓4.4.3一下的手机还是不支持Promise的,需要引入npm install babel-polyfill和npm install babel-runtime，在入口文件上加上即可
 * import 'babel-polyfill';
 */

/* name module */
import Qs from 'qs';
import axios from 'axios';
import autoMatchBaseUrl from './autoMatchBaseUrl';

// 添加一个请求拦截器 （于transformRequest之前处理）
axios.interceptors.request.use(function (config) {
  // 以下代码，鉴权token,可根据具体业务增删。
  // demo示例:
  if (~config['url'].indexOf('operatorQry')) {
    config.headers['accessToken'] = 'de4738c67e1bb450be71b660f0716aa4675860cec1ff9bc23d800efb40519cf3';
  }
  return config;
}, function (error) {
  // 当出现请求错误是做一些处理
  return Promise.reject(error);
});

// 添加一个返回拦截器 （于transformResponse之后处理）
// 返回的数据类型默认是json，若是其他类型（text）就会出现问题，因此用try,catch捕获异常
axios.interceptors.response.use(function (response) {
  return response;
}, function (error) {
  // 对返回的错误进行一些处理
  return Promise.reject(error);
});

function checkStatus(response) {
  // loading
  // 如果http状态码正常，则直接返回数据
  if (response) {
    const status = response.status;
    if (status === 200 || status === 304 || status === 400) {
      // 如果不需要除了data之外的数据，可以直接 return response.data
      return response;
    } else {
      let errorInfo = '';
      switch (status) {
        case -1:
          errorInfo = '远程服务响应失败,请稍后重试';
          break;
        case 400:
          errorInfo = '400: 错误请求';
          break;
        case 401:
          errorInfo = '401: 访问令牌无效或已过期';
          break;
        case 403:
          errorInfo = '403: 拒绝访问';
          break;
        case 404:
          errorInfo = '404：资源不存在';
          break;
        case 405:
          errorInfo = '405: 请求方法未允许'
          break;
        case 408:
          errorInfo = '408: 请求超时'
          break;
        case 500:
          errorInfo = '500：访问服务失败';
          break;
        case 501:
          errorInfo = '501：未实现';
          break;
        case 502:
          errorInfo = '502：无效网关';
          break;
        case 503:
          errorInfo = '503: 服务不可用'
          break;
        default:
          errorInfo = `连接错误${status}`
      }
      return {
        status,
        msg: errorInfo
      }
    }
  }
  // 异常状态下，把错误信息返回去
  return {
    status: -404,
    msg: '网络异常'
  };
}

function checkCode(res) {
  // 如果code异常(这里已经包括网络错误，服务器错误，后端抛出的错误)，可以弹出一个错误提示，告诉用户
  // if (res.status === -404) {
  //   console.log(res.msg);
  // }
  // if (res.data && (!res.data.success)) {
  //   console.log(res.data.error_msg);
  // }
  return res;
}

/**
 * 基于axios ajax请求
 * @param url
 * @param method
 * @param timeout
 * @param prefix 用来拼接url地址
 * @param data
 * @param headers
 * @param dataType
 * @returns {Promise.<T>}
 * @private
 */
export default function _Axios(url, {
  method = 'post',
  timeout = 10000,
  prefix = window.CT.OPEN_PREFIX,
  data = {},
  headers = {},
  dataType = 'json'
}) {
  const baseURL = autoMatchBaseUrl(prefix);

  headers = Object.assign(method === 'get' ? {
    'X-Requested-With': 'XMLHttpRequest',
    'Accept': 'application/json',
    'Content-Type': 'application/json; charset=UTF-8'
  } : {
    'X-Requested-With': 'XMLHttpRequest',
    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
  }, headers);

  const defaultConfig = {
    baseURL,
    url,
    method,
    params: data,
    data: data,
    timeout,
    headers,
    responseType: dataType
  };

  if (method === 'get') {
    delete defaultConfig.data;
  } else {
    delete defaultConfig.params;
  }

  const contentType = headers['Content-Type'];

  if (typeof contentType !== 'undefined') {
    if (~contentType.indexOf('multipart')) {
      // 类型 `multipart/form-data;`
      defaultConfig.data = data;
    } else if (~contentType.indexOf('json')) {
      // 类型 `application/json`
      // 服务器收到的raw body(原始数据) "{name:"jhon",sex:"man"}"（普通字符串）
      defaultConfig.data = JSON.stringify(data);
    } else {
      // 类型 `application/x-www-form-urlencoded`
      // 服务器收到的raw body(原始数据) name=homeway&key=nokey
      defaultConfig.data = Qs.stringify(data);
    }
  }

  return axios(defaultConfig)
    .then((response) => {
      return checkStatus(response);
    })
    .then((res) => {
      return checkCode(res);
    });
}
<commit_msg>[build] 2.1.2<commit_after>/**
 *
 * @authors liwb (you@example.org)
 * @date    2017/11/13 11:13
 * @version $ https://github.com/mzabriskie/axios
 * 安卓4.4.3一下的手机还是不支持Promise的,需要引入npm install babel-polyfill和npm install babel-runtime，在入口文件上加上即可
 * import 'babel-polyfill';
 */

/* name module */
import Qs from 'qs';
import axios from 'axios';
import autoMatchBaseUrl from './autoMatchBaseUrl';

// 添加一个请求拦截器 （于transformRequest之前处理）
axios.interceptors.request.use(function (config) {
  // 以下代码，鉴权token,可根据具体业务增删。
  // demo示例:
  if (~config['url'].indexOf('operatorQry')) {
    config.headers['accessToken'] = 'de4738c67e1bb450be71b660f0716aa4675860cec1ff9bc23d800efb40519cf3';
  }
  return config;
}, function (error) {
  // 当出现请求错误是做一些处理
  return Promise.reject(error);
});

// 添加一个返回拦截器 （于transformResponse之后处理）
// 返回的数据类型默认是json，若是其他类型（text）就会出现问题，因此用try,catch捕获异常
axios.interceptors.response.use(function (response) {
  return response;
}, function (error) {
  // 对返回的错误进行一些处理
  return Promise.reject(error);
});

function checkStatus(response) {
  // loading
  // 如果http状态码正常，则直接返回数据
  if (response) {
    const status = response.status;
    if (status === 200 || status === 304 || status === 400) {
      // 如果不需要除了data之外的数据，可以直接 return response.data
      return response.data;
    } else {
      let errorInfo = '';
      switch (status) {
        case -1:
          errorInfo = '远程服务响应失败,请稍后重试';
          break;
        case 400:
          errorInfo = '400: 错误请求';
          break;
        case 401:
          errorInfo = '401: 访问令牌无效或已过期';
          break;
        case 403:
          errorInfo = '403: 拒绝访问';
          break;
        case 404:
          errorInfo = '404：资源不存在';
          break;
        case 405:
          errorInfo = '405: 请求方法未允许'
          break;
        case 408:
          errorInfo = '408: 请求超时'
          break;
        case 500:
          errorInfo = '500：访问服务失败';
          break;
        case 501:
          errorInfo = '501：未实现';
          break;
        case 502:
          errorInfo = '502：无效网关';
          break;
        case 503:
          errorInfo = '503: 服务不可用'
          break;
        default:
          errorInfo = `连接错误${status}`
      }
      return {
        status,
        msg: errorInfo
      }
    }
  }
  // 异常状态下，把错误信息返回去
  return {
    status: -404,
    msg: '网络异常'
  };
}

/**
 * 基于axios ajax请求
 * @param url
 * @param method
 * @param timeout
 * @param prefix 用来拼接url地址
 * @param data
 * @param headers
 * @param dataType
 * @returns {Promise.<T>}
 * @private
 */
export default function _Axios(url, {
  method = 'post',
  timeout = 10000,
  prefix = window.CT.OPEN_PREFIX,
  data = {},
  headers = {},
  dataType = 'json'
}) {
  const baseURL = autoMatchBaseUrl(prefix);

  headers = Object.assign(method === 'get' ? {
    'X-Requested-With': 'XMLHttpRequest',
    'Accept': 'application/json',
    'Content-Type': 'application/json; charset=UTF-8'
  } : {
    'X-Requested-With': 'XMLHttpRequest',
    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
  }, headers);

  const defaultConfig = {
    baseURL,
    url,
    method,
    params: data,
    data: data,
    timeout,
    headers,
    responseType: dataType
  };

  if (method === 'get') {
    delete defaultConfig.data;
  } else {
    delete defaultConfig.params;
  }

  const contentType = headers['Content-Type'];

  if (typeof contentType !== 'undefined') {
    if (~contentType.indexOf('multipart')) {
      // 类型 `multipart/form-data;`
      defaultConfig.data = data;
    } else if (~contentType.indexOf('json')) {
      // 类型 `application/json`
      // 服务器收到的raw body(原始数据) "{name:"jhon",sex:"man"}"（普通字符串）
      defaultConfig.data = JSON.stringify(data);
    } else {
      // 类型 `application/x-www-form-urlencoded`
      // 服务器收到的raw body(原始数据) name=homeway&key=nokey
      defaultConfig.data = Qs.stringify(data);
    }
  }

  return axios(defaultConfig)
    .then((response) => {
      return checkStatus(response);
    });
}
<|endoftext|>


<commit_before>import Logger from './Logger'
import Tool from '../DevTools/Tool'
import { noop, evalCss, $, Emitter } from '../lib/util'
import emitter from '../lib/emitter'
import Settings from '../Settings/Settings'
import stringify from './stringify'
import libStringify from '../lib/stringify'

export default class Console extends Tool {
  constructor() {
    super()

    Emitter.mixin(this)

    this.name = 'console'
    this._scale = 1

    this._registerListener()
  }
  init($el, container) {
    super.init($el)
    this._container = container

    this._appendTpl()

    this._initLogger()
    this._exposeLogger()
    this._rejectionHandler = e => this._logger.error(e.reason)

    this._initCfg()
    this._bindEvent()
  }
  show() {
    super.show()

    this._logger.render()
  }
  overrideConsole() {
    let origConsole = (this._origConsole = {}),
      winConsole = window.console

    CONSOLE_METHOD.forEach(name => {
      let origin = (origConsole[name] = noop)
      if (winConsole[name]) {
        origin = origConsole[name] = winConsole[name].bind(winConsole)
      }

      winConsole[name] = (...args) => {
        this[name](...args)
        origin(...args)
      }
    })

    return this
  }
  restoreConsole() {
    if (!this._origConsole) return this

    CONSOLE_METHOD.forEach(
      name => (window.console[name] = this._origConsole[name])
    )
    delete this._origConsole

    return this
  }
  catchGlobalErr() {
    this._origOnerror = window.onerror

    window.onerror = (errMsg, url, lineNum, column, errObj) => {
      this._logger.error(errObj ? errObj : errMsg)
    }
    window.addEventListener('unhandledrejection', this._rejectionHandler)

    return this
  }
  ignoreGlobalErr() {
    if (this._origOnerror) {
      window.onerror = this._origOnerror
      delete this._origOnerror
    }
    window.removeEventListener('unhandledrejection', this._rejectionHandler)

    return this
  }
  destroy() {
    this._logger.destroy()
    super.destroy()

    evalCss.remove(this._style)
    this.ignoreGlobalErr()
    this.restoreConsole()
    this._unregisterListener()
    this._rmCfg()
  }
  _registerListener() {
    this._scaleListener = scale => (this._scale = scale)

    emitter.on(emitter.SCALE, this._scaleListener)
  }
  _unregisterListener() {
    emitter.off(emitter.SCALE, this._scaleListener)
  }
  _appendTpl() {
    let $el = this._$el

    this._style = evalCss(require('./Console.scss'))
    $el.append(require('./Console.hbs')())

    let _$inputContainer = $el.find('.eruda-js-input'),
      _$input = _$inputContainer.find('textarea'),
      _$inputBtns = _$inputContainer.find('.eruda-buttons')

    Object.assign(this, {
      _$control: $el.find('.eruda-control'),
      _$logs: $el.find('.eruda-logs'),
      _$inputContainer,
      _$input,
      _$inputBtns
    })
  }
  _initLogger() {
    let $filter = this._$control.find('.eruda-filter')
    let logger = (this._logger = new Logger(this._$logs, this))

    logger.on('filter', filter =>
      $filter.each(function() {
        let $this = $(this),
          isMatch = $this.data('filter') === filter

        $this[isMatch ? 'addClass' : 'rmClass']('eruda-active')
      })
    )
  }
  _exposeLogger() {
    let logger = this._logger,
      methods = ['filter', 'html'].concat(CONSOLE_METHOD)

    methods.forEach(
      name =>
        (this[name] = (...args) => {
          logger[name](...args)
          this.emit(name, ...args)

          return this
        })
    )
  }
  _bindEvent() {
    let container = this._container
    let $input = this._$input,
      $inputBtns = this._$inputBtns,
      $control = this._$control,
      logger = this._logger,
      config = this.config

    $control
      .on('click', '.eruda-clear-console', () => logger.clear())
      .on('click', '.eruda-filter', function() {
        logger.filter($(this).data('filter'))
      })
      .on('click', '.eruda-help', () => logger.help())

    $inputBtns
      .on('click', '.eruda-cancel', () => this._hideInput())
      .on('click', '.eruda-execute', () => {
        let jsInput = $input.val().trim()
        if (jsInput === '') return

        logger.input(jsInput)
        $input
          .val('')
          .get(0)
          .blur()
        this._hideInput()
      })

    $input.on('focusin', () => this._showInput())

    logger
      .on('viewJson', data => {
        let sources = container.get('sources')
        if (!sources) return

        sources.set('json', data)
        container.showTool('sources')
      })
      .on('insert', log => {
        let autoShow = log.type === 'error' && config.get('displayIfErr')

        if (autoShow) container.showTool('console').show()
      })
  }
  _hideInput() {
    this._$inputContainer.css({
      paddingTop: 0,
      height: 40 * this._scale
    })

    this._$inputBtns.hide()
  }
  _showInput() {
    this._$inputContainer.css({
      paddingTop: 40 * this._scale,
      height: '100%'
    })

    this._$inputBtns.show()
  }
  _rmCfg() {
    let cfg = this.config

    let settings = this._container.get('settings')
    if (!settings) return

    settings
      .remove(cfg, 'catchGlobalErr')
      .remove(cfg, 'overrideConsole')
      .remove(cfg, 'displayExtraInfo')
      .remove(cfg, 'displayUnenumerable')
      .remove(cfg, 'displayGetterVal')
      .remove(cfg, 'lazyEvaluation')
      .remove(cfg, 'viewLogInSources')
      .remove(cfg, 'displayIfErr')
      .remove(cfg, 'useWorker')
      .remove(cfg, 'maxLogNum')
      .remove('Console')
  }
  _initCfg() {
    let container = this._container
    let sources = container.get('sources')
    let logger = this._logger

    let cfg = (this.config = Settings.createCfg('console', {
      catchGlobalErr: true,
      overrideConsole: true,
      displayExtraInfo: false,
      displayUnenumerable: true,
      displayGetterVal: false,
      lazyEvaluation: true,
      viewLogInSources: false,
      displayIfErr: false,
      useWorker: true,
      maxLogNum: 'infinite'
    }))

    let isWorkerSupported = !!window.Worker

    let maxLogNum = cfg.get('maxLogNum')
    maxLogNum = maxLogNum === 'infinite' ? maxLogNum : +maxLogNum

    if (cfg.get('catchGlobalErr')) this.catchGlobalErr()
    if (cfg.get('overrideConsole')) this.overrideConsole()
    if (cfg.get('useWorker') && isWorkerSupported) stringify.useWorker = true
    logger.displayHeader(cfg.get('displayExtraInfo'))
    logger.displayUnenumerable(cfg.get('displayUnenumerable'))
    logger.displayGetterVal(cfg.get('displayGetterVal'))
    logger.lazyEvaluation(cfg.get('lazyEvaluation'))
    if (sources) logger.viewLogInSources(cfg.get('viewLogInSources'))
    logger.maxNum(maxLogNum)

    cfg.on('change', (key, val) => {
      switch (key) {
        case 'catchGlobalErr':
          return val ? this.catchGlobalErr() : this.ignoreGlobalErr()
        case 'overrideConsole':
          return val ? this.overrideConsole() : this.restoreConsole()
        case 'maxLogNum':
          return logger.maxNum(val === 'infinite' ? val : +val)
        case 'displayExtraInfo':
          return logger.displayHeader(val)
        case 'displayUnenumerable':
          return logger.displayUnenumerable(val)
        case 'displayGetterVal':
          return logger.displayGetterVal(val)
        case 'lazyEvaluation':
          return logger.lazyEvaluation(val)
        case 'viewLogInSources':
          return logger.viewLogInSources(val)
        case 'useWorker':
          stringify.useWorker = val
          return
      }
    })

    let settings = container.get('settings')

    settings
      .text('Console')
      .switch(cfg, 'catchGlobalErr', 'Catch Global Errors')
      .switch(cfg, 'overrideConsole', 'Override Console')
      .switch(cfg, 'displayIfErr', 'Auto Display If Error Occurs')
      .switch(cfg, 'displayExtraInfo', 'Display Extra Information')
      .switch(cfg, 'displayUnenumerable', 'Display Unenumerable Properties')
      .switch(cfg, 'displayGetterVal', 'Access Getter Value')
      .switch(cfg, 'lazyEvaluation', 'Lazy Evaluation')

    if (isWorkerSupported) settings.switch(cfg, 'useWorker', 'Use Web Worker')
    if (sources) {
      settings.switch(cfg, 'viewLogInSources', 'View Log In Sources Panel')
    }

    settings
      .select(cfg, 'maxLogNum', 'Max Log Number', [
        'infinite',
        '250',
        '125',
        '100',
        '50',
        '10'
      ])
      .separator()
  }
}

Console.stringify = libStringify

const CONSOLE_METHOD = [
  'log',
  'error',
  'info',
  'warn',
  'dir',
  'time',
  'timeEnd',
  'clear',
  'table',
  'assert',
  'count',
  'debug'
]
<commit_msg>Disable empty log<commit_after>import Logger from './Logger'
import Tool from '../DevTools/Tool'
import { noop, evalCss, $, Emitter } from '../lib/util'
import emitter from '../lib/emitter'
import Settings from '../Settings/Settings'
import stringify from './stringify'
import libStringify from '../lib/stringify'

export default class Console extends Tool {
  constructor() {
    super()

    Emitter.mixin(this)

    this.name = 'console'
    this._scale = 1

    this._registerListener()
  }
  init($el, container) {
    super.init($el)
    this._container = container

    this._appendTpl()

    this._initLogger()
    this._exposeLogger()
    this._rejectionHandler = e => this._logger.error(e.reason)

    this._initCfg()
    this._bindEvent()
  }
  show() {
    super.show()

    this._logger.render()
  }
  overrideConsole() {
    let origConsole = (this._origConsole = {})
    let winConsole = window.console

    CONSOLE_METHOD.forEach(name => {
      let origin = (origConsole[name] = noop)
      if (winConsole[name]) {
        origin = origConsole[name] = winConsole[name].bind(winConsole)
      }

      winConsole[name] = (...args) => {
        if (args.length > 0) {
          this[name](...args)
        }
        origin(...args)
      }
    })

    return this
  }
  restoreConsole() {
    if (!this._origConsole) return this

    CONSOLE_METHOD.forEach(
      name => (window.console[name] = this._origConsole[name])
    )
    delete this._origConsole

    return this
  }
  catchGlobalErr() {
    this._origOnerror = window.onerror

    window.onerror = (errMsg, url, lineNum, column, errObj) => {
      this._logger.error(errObj ? errObj : errMsg)
    }
    window.addEventListener('unhandledrejection', this._rejectionHandler)

    return this
  }
  ignoreGlobalErr() {
    if (this._origOnerror) {
      window.onerror = this._origOnerror
      delete this._origOnerror
    }
    window.removeEventListener('unhandledrejection', this._rejectionHandler)

    return this
  }
  destroy() {
    this._logger.destroy()
    super.destroy()

    evalCss.remove(this._style)
    this.ignoreGlobalErr()
    this.restoreConsole()
    this._unregisterListener()
    this._rmCfg()
  }
  _registerListener() {
    this._scaleListener = scale => (this._scale = scale)

    emitter.on(emitter.SCALE, this._scaleListener)
  }
  _unregisterListener() {
    emitter.off(emitter.SCALE, this._scaleListener)
  }
  _appendTpl() {
    let $el = this._$el

    this._style = evalCss(require('./Console.scss'))
    $el.append(require('./Console.hbs')())

    let _$inputContainer = $el.find('.eruda-js-input'),
      _$input = _$inputContainer.find('textarea'),
      _$inputBtns = _$inputContainer.find('.eruda-buttons')

    Object.assign(this, {
      _$control: $el.find('.eruda-control'),
      _$logs: $el.find('.eruda-logs'),
      _$inputContainer,
      _$input,
      _$inputBtns
    })
  }
  _initLogger() {
    let $filter = this._$control.find('.eruda-filter')
    let logger = (this._logger = new Logger(this._$logs, this))

    logger.on('filter', filter =>
      $filter.each(function() {
        let $this = $(this),
          isMatch = $this.data('filter') === filter

        $this[isMatch ? 'addClass' : 'rmClass']('eruda-active')
      })
    )
  }
  _exposeLogger() {
    let logger = this._logger,
      methods = ['filter', 'html'].concat(CONSOLE_METHOD)

    methods.forEach(
      name =>
        (this[name] = (...args) => {
          logger[name](...args)
          this.emit(name, ...args)

          return this
        })
    )
  }
  _bindEvent() {
    let container = this._container
    let $input = this._$input,
      $inputBtns = this._$inputBtns,
      $control = this._$control,
      logger = this._logger,
      config = this.config

    $control
      .on('click', '.eruda-clear-console', () => logger.clear())
      .on('click', '.eruda-filter', function() {
        logger.filter($(this).data('filter'))
      })
      .on('click', '.eruda-help', () => logger.help())

    $inputBtns
      .on('click', '.eruda-cancel', () => this._hideInput())
      .on('click', '.eruda-execute', () => {
        let jsInput = $input.val().trim()
        if (jsInput === '') return

        logger.input(jsInput)
        $input
          .val('')
          .get(0)
          .blur()
        this._hideInput()
      })

    $input.on('focusin', () => this._showInput())

    logger
      .on('viewJson', data => {
        let sources = container.get('sources')
        if (!sources) return

        sources.set('json', data)
        container.showTool('sources')
      })
      .on('insert', log => {
        let autoShow = log.type === 'error' && config.get('displayIfErr')

        if (autoShow) container.showTool('console').show()
      })
  }
  _hideInput() {
    this._$inputContainer.css({
      paddingTop: 0,
      height: 40 * this._scale
    })

    this._$inputBtns.hide()
  }
  _showInput() {
    this._$inputContainer.css({
      paddingTop: 40 * this._scale,
      height: '100%'
    })

    this._$inputBtns.show()
  }
  _rmCfg() {
    let cfg = this.config

    let settings = this._container.get('settings')
    if (!settings) return

    settings
      .remove(cfg, 'catchGlobalErr')
      .remove(cfg, 'overrideConsole')
      .remove(cfg, 'displayExtraInfo')
      .remove(cfg, 'displayUnenumerable')
      .remove(cfg, 'displayGetterVal')
      .remove(cfg, 'lazyEvaluation')
      .remove(cfg, 'viewLogInSources')
      .remove(cfg, 'displayIfErr')
      .remove(cfg, 'useWorker')
      .remove(cfg, 'maxLogNum')
      .remove('Console')
  }
  _initCfg() {
    let container = this._container
    let sources = container.get('sources')
    let logger = this._logger

    let cfg = (this.config = Settings.createCfg('console', {
      catchGlobalErr: true,
      overrideConsole: true,
      displayExtraInfo: false,
      displayUnenumerable: true,
      displayGetterVal: false,
      lazyEvaluation: true,
      viewLogInSources: false,
      displayIfErr: false,
      useWorker: true,
      maxLogNum: 'infinite'
    }))

    let isWorkerSupported = !!window.Worker

    let maxLogNum = cfg.get('maxLogNum')
    maxLogNum = maxLogNum === 'infinite' ? maxLogNum : +maxLogNum

    if (cfg.get('catchGlobalErr')) this.catchGlobalErr()
    if (cfg.get('overrideConsole')) this.overrideConsole()
    if (cfg.get('useWorker') && isWorkerSupported) stringify.useWorker = true
    logger.displayHeader(cfg.get('displayExtraInfo'))
    logger.displayUnenumerable(cfg.get('displayUnenumerable'))
    logger.displayGetterVal(cfg.get('displayGetterVal'))
    logger.lazyEvaluation(cfg.get('lazyEvaluation'))
    if (sources) logger.viewLogInSources(cfg.get('viewLogInSources'))
    logger.maxNum(maxLogNum)

    cfg.on('change', (key, val) => {
      switch (key) {
        case 'catchGlobalErr':
          return val ? this.catchGlobalErr() : this.ignoreGlobalErr()
        case 'overrideConsole':
          return val ? this.overrideConsole() : this.restoreConsole()
        case 'maxLogNum':
          return logger.maxNum(val === 'infinite' ? val : +val)
        case 'displayExtraInfo':
          return logger.displayHeader(val)
        case 'displayUnenumerable':
          return logger.displayUnenumerable(val)
        case 'displayGetterVal':
          return logger.displayGetterVal(val)
        case 'lazyEvaluation':
          return logger.lazyEvaluation(val)
        case 'viewLogInSources':
          return logger.viewLogInSources(val)
        case 'useWorker':
          stringify.useWorker = val
          return
      }
    })

    let settings = container.get('settings')

    settings
      .text('Console')
      .switch(cfg, 'catchGlobalErr', 'Catch Global Errors')
      .switch(cfg, 'overrideConsole', 'Override Console')
      .switch(cfg, 'displayIfErr', 'Auto Display If Error Occurs')
      .switch(cfg, 'displayExtraInfo', 'Display Extra Information')
      .switch(cfg, 'displayUnenumerable', 'Display Unenumerable Properties')
      .switch(cfg, 'displayGetterVal', 'Access Getter Value')
      .switch(cfg, 'lazyEvaluation', 'Lazy Evaluation')

    if (isWorkerSupported) settings.switch(cfg, 'useWorker', 'Use Web Worker')
    if (sources) {
      settings.switch(cfg, 'viewLogInSources', 'View Log In Sources Panel')
    }

    settings
      .select(cfg, 'maxLogNum', 'Max Log Number', [
        'infinite',
        '250',
        '125',
        '100',
        '50',
        '10'
      ])
      .separator()
  }
}

Console.stringify = libStringify

const CONSOLE_METHOD = [
  'log',
  'error',
  'info',
  'warn',
  'dir',
  'time',
  'timeEnd',
  'clear',
  'table',
  'assert',
  'count',
  'debug'
]
<|endoftext|>


<commit_before>"use strict";
let express = require('express')
let db = require('./db')
let utils = require('./utils');

let router = express.Router();

const respondError = (res, err) => {
    let msg = {error: "" + err};
    if (err.stack) msg.stack = err.stack;
    res.status(400).json(msg);
};

const respondJson = (req, res, p) => {
    let logPrefix = req.method + " " + req.path + ":";
    p.then(r => {
        //console.log(logPrefix, r);
        if (utils.isJsonp(req)) {
            res.header('Content-type', 'application/javascript; charset=UTF-8');
            res.send(req.query.callback + '(' + JSON.stringify(r || {}) + ');');
        } else {
            res.json(r || {});
        }
    }).catch(err => {
        console.error(logPrefix, err + err.stack);
        respondError(res, err);
    });
};

const collection = (req) => (
    db.collection(req.params.db, req.params.collection)
);

const v_id = db.v_id;

const v_addUid = (req, v) => {
    v.uid = req.user.id;
    return v;
};

const v_removeUid = (v) => {
    if (v) { delete v.uid; }
    return v;
};

const array2map = (l) => {
    let m = {};
    l.forEach(v => {
        m[v.id] = v;
        delete v.id;
    });
    return m;
};

const getAll = (req) => collection(req).then(collection => (
    db.find(collection, {}).then(array2map)
));
const get = (req) => collection(req).then(collection => (
    db.get(collection, v_id(req.params.id))
));
const delete_ = (req) => collection(req).then(collection => (
    db.delete(collection, v_id(req.params.id))
));
const put = (req) => collection(req).then(collection => (
    db.save(collection, v_id(req.params.id), req.body)
));
const add = (req) => collection(req).then(collection => (
    db.save(collection, v_id(null), req.body)
));

const getAllWithUid = (req) => collection(req).then(collection => (
    db.find(collection, v_addUid(req, {})).then(l => array2map(l.map(v_removeUid)))
));
const getWithUid = (req) => collection(req).then(collection => (
    db.get(collection, v_addUid(req, v_id(req.params.id))).then(v_removeUid)
));
const deleteWithUid = (req) => collection(req).then(collection => (
    db.delete(collection, v_addUid(req, v_id(req.params.id)))
));
const putWithUid = (req) => collection(req).then(collection => (
    db.save(collection, v_addUid(req, v_id(req.params.id)), req.body)
));
const addWithUid = (req) => collection(req).then(collection => (
    db.save(collection, v_addUid(req, v_id(null)), req.body)
));

const with_acl = (f) => (req, res) => (
    req.user && req.user.id /* TODO */
        ? respondJson(req, res, f(req))
        : respondError(res, "Unauthorized")
);

const login = (req, res) => (
    req.user && req.user.id
        ? res.redirect(req.query.then)
        : respondError(res, "Unauthorized")
);

router.use("/.files", express.static(__dirname + '/../client'));
router.get("/.login", login);

router.get("/:db/:collection/\\$user/:id", with_acl(getWithUid));
router.put('/:db/:collection/\\$user/:id', with_acl(putWithUid));
router.delete('/:db/:collection/\\$user/:id', with_acl(deleteWithUid));
router.post('/:db/:collection/\\$user', with_acl(addWithUid));
router.get('/:db/:collection/\\$user', with_acl(getAllWithUid));
router.get("/:db/:collection/:id", with_acl(get));
router.put("/:db/:collection/:id", with_acl(put));
router.delete("/:db/:collection/:id", with_acl(delete_));
router.post("/:db/:collection", with_acl(add));
router.get("/:db/:collection", with_acl(getAll));

module.exports = router;
<commit_msg>for errors, respond with jsonp if needed<commit_after>"use strict";
let express = require('express')
let db = require('./db')
let utils = require('./utils');

let router = express.Router();

const respondError = (req, res, err) => {
    let msg = {error: "" + err};
    if (err.stack) msg.stack = err.stack;
    res.status(400);
    respondJsonRaw(req, res, msg);
};

const respondJsonRaw = (req, res, json) => {
    if (utils.isJsonp(req)) {
        res.header('Content-type', 'application/javascript; charset=UTF-8');
        res.send(req.query.callback + '(' + JSON.stringify(json || {}) + ');');
    } else {
        res.json(json || {});
    }
};

const respondJson = (req, res, p) => {
    let logPrefix = req.method + " " + req.path + ":";
    p.then(r => {
        //console.log(logPrefix, r);
        respondJsonRaw(req, res, r);
    }).catch(err => {
        console.error(logPrefix, err + err.stack);
        respondError(req, res, err);
    });
};

const collection = (req) => (
    db.collection(req.params.db, req.params.collection)
);

const v_id = db.v_id;

const v_addUid = (req, v) => {
    v.uid = req.user.id;
    return v;
};

const v_removeUid = (v) => {
    if (v) { delete v.uid; }
    return v;
};

const array2map = (l) => {
    let m = {};
    l.forEach(v => {
        m[v.id] = v;
        delete v.id;
    });
    return m;
};

const getAll = (req) => collection(req).then(collection => (
    db.find(collection, {}).then(array2map)
));
const get = (req) => collection(req).then(collection => (
    db.get(collection, v_id(req.params.id))
));
const delete_ = (req) => collection(req).then(collection => (
    db.delete(collection, v_id(req.params.id))
));
const put = (req) => collection(req).then(collection => (
    db.save(collection, v_id(req.params.id), req.body)
));
const add = (req) => collection(req).then(collection => (
    db.save(collection, v_id(null), req.body)
));

const getAllWithUid = (req) => collection(req).then(collection => (
    db.find(collection, v_addUid(req, {})).then(l => array2map(l.map(v_removeUid)))
));
const getWithUid = (req) => collection(req).then(collection => (
    db.get(collection, v_addUid(req, v_id(req.params.id))).then(v_removeUid)
));
const deleteWithUid = (req) => collection(req).then(collection => (
    db.delete(collection, v_addUid(req, v_id(req.params.id)))
));
const putWithUid = (req) => collection(req).then(collection => (
    db.save(collection, v_addUid(req, v_id(req.params.id)), req.body)
));
const addWithUid = (req) => collection(req).then(collection => (
    db.save(collection, v_addUid(req, v_id(null)), req.body)
));

const with_acl = (f) => (req, res) => (
    req.user && req.user.id /* TODO */
        ? respondJson(req, res, f(req))
        : respondError(req, res, "Unauthorized")
);

const login = (req, res) => (
    req.user && req.user.id
        ? res.redirect(req.query.then)
        : respondError(req, res, "Unauthorized")
);

router.use("/.files", express.static(__dirname + '/../client'));
router.get("/.login", login);

router.get("/:db/:collection/\\$user/:id", with_acl(getWithUid));
router.put('/:db/:collection/\\$user/:id', with_acl(putWithUid));
router.delete('/:db/:collection/\\$user/:id', with_acl(deleteWithUid));
router.post('/:db/:collection/\\$user', with_acl(addWithUid));
router.get('/:db/:collection/\\$user', with_acl(getAllWithUid));
router.get("/:db/:collection/:id", with_acl(get));
router.put("/:db/:collection/:id", with_acl(put));
router.delete("/:db/:collection/:id", with_acl(delete_));
router.post("/:db/:collection", with_acl(add));
router.get("/:db/:collection", with_acl(getAll));

module.exports = router;
<|endoftext|>


<commit_before>

define([

	'underscore',
	'backbone',
	'marionette',
	'bootstrap',
	'templates',
	'settings',
	'osm-auth',
],
function (

	_,
	Backbone,
	Marionette,
	Bootstrap,
	templates,
	settings,
	osmAuth
) {

	'use strict';

	return Marionette.LayoutView.extend({

		template: JST['editPoiDataColumn.html'],
		templateField: JST['editPoiDataField.html'],

		behaviors: {

			'l20n': {},
			'column': {},
		},

		ui: {

			'column': '#edit_poi_data_column',
			'fields': '.fields',
		},

		events: {

			'submit': 'onSubmit',
			'reset': 'onReset',
		},

		initialize: function () {

			this._radio = Backbone.Wreqr.radio.channel('global');

			if ( !this._radio.reqres.request('var', 'isLogged') ) {

				return false;
			}

			var self = this,
			user = this._radio.reqres.request('model', 'user');

			this._auth = osmAuth({

				'oauth_consumer_key': settings.oauthConsumerKey,
				'oauth_secret': settings.oauthSecret,
				'oauth_token': user.get('token'),
				'oauth_token_secret': user.get('tokenSecret'),
			});
		},

		open: function () {

			this._radio.vent.trigger('column:closeAll');
			this._radio.vent.trigger('widget:closeAll');

			this.triggerMethod('open');
		},

		close: function () {

			this.triggerMethod('close');
		},

		onRender: function () {

			if ( !this.options.poiLayerModel.get('dataEditable') ) {

				return this;
			}

			if ( !this._radio.reqres.request('var', 'isLogged') ) {

				return this;
			}

			var tag,
			self = this,
			html = '',
			dataFromOSM = this.options.dataFromOSM,
			poiLayerModel = this.options.poiLayerModel,
			popupContent = poiLayerModel.get('popupContent'),
			re = new RegExp('{(.*?)}', 'g'),
			tags = popupContent.match(re);

			for (var i in tags) {

				tag = tags[i].replace( /\{(.*?)\}/g, '$1' );

				html += this.templateField({

					'tag': tag,
					'value': dataFromOSM.tags[tag],
				});
			}

			this.ui.fields.html( html );
		},

		onSubmit: function (e) {

			if ( !this._radio.reqres.request('var', 'isLogged') ) {

				return false;
			}

			e.preventDefault();

			var self = this,
			newTags = {};

			this.ui.fields
			.find('input')
			.each(function (i, input) {

				var tag = $(input).data('tag');

				newTags[tag] = input.value;
			});

			$.ajax({

				'method': 'GET',
				'dataType': 'xml',
				'url': 'https://api.openstreetmap.org/api/0.6/node/'+ this.options.dataFromOSM.id,
				'success': function (nodeXml, jqXHR, textStatus) {

					var oldTags = {},
					parentNode = nodeXml.getElementsByTagName('node')[0],
					tags = nodeXml.documentElement.getElementsByTagName('tag');

					for (var j in tags) {

						if ( !tags[j].getAttribute ) {

							continue;
						}

						oldTags[ tags[j].getAttribute('k') ] = tags[j];
					}

					for (var k in newTags) {

						if ( !newTags[k] ) {

							if ( oldTags[k] ) {

								parentNode.removeChild( oldTags[k] );

								delete self.options.dataFromOSM.tags[k];
							}

							continue;
						}

						if ( oldTags[k] ) {

							oldTags[k].setAttribute('v', newTags[k]);
						}
						else {

							var newTag = nodeXml.createElement('tag');

							newTag.setAttribute('k', k);
							newTag.setAttribute('v', newTags[k]);

							parentNode.appendChild(newTag);
						}

						self.options.dataFromOSM.tags[k] = newTags[k];
					}

					self.sendNewXml( nodeXml );
				},
				'error': function (jqXHR, textStatus, error) {

					console.error('FIXME');
				},
			});
		},

		sendNewXml: function (nodeXml) {

			var self = this,
			changesetId = sessionStorage.getItem('changesetId'),
			xmlChangeset = '<osm><changeset><tag k="created_by" v="Rudomap"/><tag k="comment" v="Test from Rudomap (developpement in progress)"/></changeset></osm>';

			if ( changesetId ) {

				this.sendXml(nodeXml, changesetId);
			}
			else {

				this._auth.xhr({

					'method': 'PUT',
					'path': '/api/0.6/changeset/create',
					'options': { 'header': { 'Content-Type': 'text/xml' } },
					'content': xmlChangeset
				},
				function(err, changesetId) {

					if (err) {

						console.log('ERROR on put changeset: ' + err.response);
						return;
					}

					sessionStorage.setItem('changesetId', changesetId);

					self.sendXml(nodeXml, changesetId);
				});
			}
		},

		sendXml: function (nodeXml, changesetId) {

			var data,
			self = this,
			node = nodeXml.documentElement.getElementsByTagName('node')[0],
			serializer = new XMLSerializer();

			node.setAttribute('changeset', changesetId);

			data = serializer.serializeToString(nodeXml);

			this._auth.xhr({

				'method': 'PUT',
				'path': '/api/0.6/node/'+ this.options.dataFromOSM.id,
				'options': { 'header': { 'Content-Type': 'text/xml' } },
				'content': data,
			},
			function(err, res) {

				if (err) {

					console.log('ERROR on put node/way : '+ err.response);
					return;
				}

				self._radio.commands.execute('map:updatePoiPopup', self.options.poiLayerModel, self.options.dataFromOSM);
			});

			this.close();
		},

		onReset: function () {

			this.close();
		},
	});
});
<commit_msg>In contribution: Don't force the node type ad increment the version number of elements<commit_after>

define([

	'underscore',
	'backbone',
	'marionette',
	'bootstrap',
	'templates',
	'settings',
	'osm-auth',
],
function (

	_,
	Backbone,
	Marionette,
	Bootstrap,
	templates,
	settings,
	osmAuth
) {

	'use strict';

	return Marionette.LayoutView.extend({

		template: JST['editPoiDataColumn.html'],
		templateField: JST['editPoiDataField.html'],

		behaviors: {

			'l20n': {},
			'column': {},
		},

		ui: {

			'column': '#edit_poi_data_column',
			'fields': '.fields',
		},

		events: {

			'submit': 'onSubmit',
			'reset': 'onReset',
		},

		initialize: function () {

			this._radio = Backbone.Wreqr.radio.channel('global');

			if ( !this._radio.reqres.request('var', 'isLogged') ) {

				return false;
			}

			var self = this,
			user = this._radio.reqres.request('model', 'user');

			this._auth = osmAuth({

				'oauth_consumer_key': settings.oauthConsumerKey,
				'oauth_secret': settings.oauthSecret,
				'oauth_token': user.get('token'),
				'oauth_token_secret': user.get('tokenSecret'),
			});
		},

		open: function () {

			this._radio.vent.trigger('column:closeAll');
			this._radio.vent.trigger('widget:closeAll');

			this.triggerMethod('open');
		},

		close: function () {

			this.triggerMethod('close');
		},

		onRender: function () {

			if ( !this.options.poiLayerModel.get('dataEditable') ) {

				return this;
			}

			if ( !this._radio.reqres.request('var', 'isLogged') ) {

				return this;
			}

			var tag,
			self = this,
			html = '',
			dataFromOSM = this.options.dataFromOSM,
			poiLayerModel = this.options.poiLayerModel,
			popupContent = poiLayerModel.get('popupContent'),
			re = new RegExp('{(.*?)}', 'g'),
			tags = popupContent.match(re);

			for (var i in tags) {

				tag = tags[i].replace( /\{(.*?)\}/g, '$1' );

				html += this.templateField({

					'tag': tag,
					'value': dataFromOSM.tags[tag],
				});
			}

			this.ui.fields.html( html );
		},

		onSubmit: function (e) {

			if ( !this._radio.reqres.request('var', 'isLogged') ) {

				return false;
			}

			e.preventDefault();

			var self = this,
			id = this.options.dataFromOSM.id,
			type = this.options.dataFromOSM.type,
			newTags = {};

			this.ui.fields
			.find('input')
			.each(function (i, input) {

				var tag = $(input).data('tag');

				newTags[tag] = input.value;
			});

			$.ajax({

				'method': 'GET',
				'dataType': 'xml',
				'url': 'https://api.openstreetmap.org/api/0.6/'+ type +'/'+ id,
				'success': function (xml, jqXHR, textStatus) {

					var oldTags = {},
					parentElement = xml.getElementsByTagName(type)[0],
					tags = xml.documentElement.getElementsByTagName('tag');

					for (var j in tags) {

						if ( !tags[j].getAttribute ) {

							continue;
						}

						oldTags[ tags[j].getAttribute('k') ] = tags[j];
					}

					for (var k in newTags) {

						if ( !newTags[k] ) {

							if ( oldTags[k] ) {

								parentElement.removeChild( oldTags[k] );

								delete self.options.dataFromOSM.tags[k];
							}

							continue;
						}

						if ( oldTags[k] ) {

							oldTags[k].setAttribute('v', newTags[k]);
						}
						else {

							var newTag = xml.createElement('tag');

							newTag.setAttribute('k', k);
							newTag.setAttribute('v', newTags[k]);

							parentElement.appendChild(newTag);
						}

						self.options.dataFromOSM.tags[k] = newTags[k];
					}

					self.sendNewXml( xml );
				},
				'error': function (jqXHR, textStatus, error) {

					console.error('FIXME');
				},
			});
		},

		sendNewXml: function (xml) {

			var self = this,
			changesetId = sessionStorage.getItem('changesetId'),
			xmlChangeset = '<osm><changeset><tag k="created_by" v="Rudomap"/><tag k="comment" v="Test from Rudomap (developpement in progress)"/></changeset></osm>';

			if ( changesetId ) {

				this.sendXml(xml, changesetId);
			}
			else {

				this._auth.xhr({

					'method': 'PUT',
					'path': '/api/0.6/changeset/create',
					'options': { 'header': { 'Content-Type': 'text/xml' } },
					'content': xmlChangeset
				},
				function(err, changesetId) {

					if (err) {

						console.log('ERROR on put changeset: ' + err.response);
						return;
					}

					sessionStorage.setItem('changesetId', changesetId);

					self.sendXml(xml, changesetId);
				});
			}
		},

		sendXml: function (xml, changesetId) {

			var data,
			self = this,
			id = this.options.dataFromOSM.id,
			type = this.options.dataFromOSM.type,
			parentElement = xml.getElementsByTagName(type)[0],
			version = parseInt( parentElement.getAttribute('version') ),
			serializer = new XMLSerializer();

			parentElement.setAttribute('version', version + 1);
			parentElement.setAttribute('changeset', changesetId);

			data = serializer.serializeToString(xml);

			this._auth.xhr({

				'method': 'PUT',
				'path': '/api/0.6/'+ type +'/'+ id,
				'options': { 'header': { 'Content-Type': 'text/xml' } },
				'content': data,
			},
			function(err, res) {

				if (err) {

					console.log('ERROR on put node/way : '+ err.response);
					return;
				}

				self._radio.commands.execute('map:updatePoiPopup', self.options.poiLayerModel, self.options.dataFromOSM);
			});

			this.close();
		},

		onReset: function () {

			this.close();
		},
	});
});
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';

const propTypes = {
  items: PropTypes.arrayOf(
    PropTypes.shape({

    })).isRequired,
};

const List = ({ items }) => (

    {
      items.map(item => (

            {item.name}

            Quantity: {item.quantity}

            Total price: ${ item.price * item.quantity }

))
    }

);

List.propTypes = propTypes;

export default List;
<commit_msg>Payment: added a total to pay<commit_after>import React from 'react';
import PropTypes from 'prop-types';

const propTypes = {
  items: PropTypes.arrayOf(
    PropTypes.shape({

    })).isRequired,
};

const List = ({ items }) => (

    {
      items.map(item => (

            {item.name}

            Quantity: {item.quantity}

            Total price: R${ item.price * item.quantity }

))
    }
    {

        Total price: R${items.reduce((prev, next) => prev + (next.price * next.quantity), 0)}

    }

);

List.propTypes = propTypes;

export default List;
<|endoftext|>


<commit_before>(function(angular){
    "use strict";
    angular.module("mfl.filtering.services", ["sil.api.wrapper"])

    .service("filteringApi", ["api", function(api){
        this.filters = api.setBaseUrl("api/common/filtering_summaries");
        this.facilities = api.setBaseUrl("api/facilities/facilities");
        this.constituencies = api.setBaseUrl("api/common/constituencies");
        this.wards = api.setBaseUrl("api/common/wards");
        this.counties = api.setBaseUrl("api/common/counties");
        this.towns = api.setBaseUrl("api/common/towns");
        this.operation_status = api.setBaseUrl("api/facilities/facility_status");
        this.owners = api.setBaseUrl("api/facilities/owners");
        this.officers = api.setBaseUrl("api/facilities/officers");
        this.facility_types = api.setBaseUrl("api/facilities/facility_types");
        this.service_category = api.setBaseUrl("api/facilities/service_categories");
    }]);
})(angular);
<commit_msg>added optimized facilities endpoint<commit_after>(function(angular){
    "use strict";
    angular.module("mfl.filtering.services", ["sil.api.wrapper"])

    .service("filteringApi", ["api", function(api){
        this.filters = api.setBaseUrl("api/common/filtering_summaries");
        this.facilities = api.setBaseUrl("api/facilities/facilities_list");
        this.constituencies = api.setBaseUrl("api/common/constituencies");
        this.wards = api.setBaseUrl("api/common/wards");
        this.counties = api.setBaseUrl("api/common/counties");
        this.towns = api.setBaseUrl("api/common/towns");
        this.operation_status = api.setBaseUrl("api/facilities/facility_status");
        this.owners = api.setBaseUrl("api/facilities/owners");
        this.officers = api.setBaseUrl("api/facilities/officers");
        this.facility_types = api.setBaseUrl("api/facilities/facility_types");
        this.service_category = api.setBaseUrl("api/facilities/service_categories");
    }]);
})(angular);
<|endoftext|>


<commit_before>//META{"name":"BetterReplyer"}*//

class BetterReplyer {
	getName() {
		return "BetterReplyer";
	}
	getDescription() {
		return "Reply to people using their ID with a button. Inspired by Replyer by @Hammock#3110, @Natsulus#0001 & @Zerebos#7790. Using getInternalInstance by @noodlebox#0155.";
	}
	getVersion() {
		return "2.2.3";
	}
	getAuthor() {
		return "Zerthox";
	}
	getSettingsPanel() {
		return null;
	}
	start() {
		BdApi.injectCSS(this.getName(), this.css);
		this.insert();
		console.log("[BetterReplyer] Started");
	}
	stop() {
		$(".message-group .replyer").remove();
		BdApi.clearCSS(this.getName());
		console.log("[BetterReplyer] Stopped");
	}
	observer(e) {
		var a = $(e.addedNodes),
			r = $(e.removedNodes);
		if (a.is(".message") || a.find(".message").length > 0 || r.is(".replyer") || r.find(".replyer").length > 0) {
			this.insert();
		}
	}
	insert() {
		var self = this;
		$(".messages .message-group").each(function() {
			if ($(this).find(".replyer").length === 0) {
				$(this).find(".timestamp").after("Reply");
				$(this).find(".replyer").click(function() {
					var id = self.messageAuthor($(this).parents(".message-group")[0]).id;
					$(".content [class*='channelTextArea-'] textarea").each(function() {
						var mention = "<@!" + id + "> ";
						this.focus();
						var start = this.selectionStart + mention.length,
							end = this.selectionEnd + mention.length;
						this.selectionStart = this.selectionEnd = 0;
						document.execCommand("insertText", false, mention);
						this.selectionStart = start;
						this.selectionEnd = end;
					});
				});
			}
		});
	}
	reactInternalInstance(e) {
		// getInternalInstance by @noodlebox#0155
		return e[Object.keys(e).find(k => k.startsWith("__reactInternalInstance"))];
	}
	messageAuthor(message) {
		return this.reactInternalInstance(message).child.child.memoizedProps.user;
	}
	get css() {
		var r = `.replyer {
			position: relative;
			top: -1px;
			margin-left: 5px;
			padding: 3px 5px;
			background: rgba(0, 0, 0, 0.4);
			border-radius: 3px;
			color: #fff !important;
			font-size: 10px;
			text-transform: uppercase;
			cursor: pointer;
		}
		.message-group:not(:hover) .replyer {
			visibility: hidden;
		}`;
		return r;
	}
	unload() {
		this.stop();
	}
	onMessage() {}
	onSwitch() {}
	load() {}
}<commit_msg>Update BetterReplyer<commit_after>//META{"name":"BetterReplyer"}*//

class BetterReplyer {
	getName() {
		return "BetterReplyer";
	}
	getDescription() {
		return "Reply to people using their ID with a button. Inspired by Replyer by @Hammock#3110, @Natsulus#0001 & @Zerebos#7790. Using getInternalInstance by @noodlebox#0155.";
	}
	getVersion() {
		return "2.3";
	}
	getAuthor() {
		return "Zerthox";
	}
	getSettingsPanel() {
		return null;
	}
	start() {
		BdApi.injectCSS(this.getName(), this.css);
		this.insert();
		console.log("[BetterReplyer] Started");
	}
	stop() {
		$(".container-1YxwTf .replyer").remove();
		BdApi.clearCSS(this.getName());
		console.log("[BetterReplyer] Stopped");
	}
	observer(e) {
		var a = $(e.addedNodes),
			r = $(e.removedNodes);
		if (a.is(".container-1YxwTf") || a.find(".container-1YxwTf").length > 0 || r.is(".replyer") || r.find(".replyer").length > 0) {
			this.insert();
		}
	}
	insert() {
		var self = this;
		$(".chat-3bRxxu .container-1YxwTf").each(function() {
			if ($(this).find(".replyer").length === 0) {
				$(this).find(".timestampCozy-2hLAPV").after("Reply");
				$(this).find(".replyer").click(function() {
					var id = self.messageAuthor($(this).parents(".container-1YxwTf")[0]).id;
					$(".textArea-2Spzkt").each(function() {
						var mention = "<@!" + id + "> ";
						this.focus();
						var start = this.selectionStart + mention.length,
							end = this.selectionEnd + mention.length;
						this.selectionStart = this.selectionEnd = 0;
						document.execCommand("insertText", false, mention);
						this.selectionStart = start;
						this.selectionEnd = end;
					});
				});
			}
		});
	}
	reactInternalInstance(e) {
		// getInternalInstance by @noodlebox#0155
		return e[Object.keys(e).find(k => k.startsWith("__reactInternalInstance"))];
	}
	messageAuthor(message) {
		return this.reactInternalInstance(message).child.child.memoizedProps.message.author;
	}
	get css() {
		var r = `.replyer {
			position: relative;
			top: -1px;
			margin-left: 5px;
			padding: 3px 5px;
			background: rgba(0, 0, 0, 0.4);
			border-radius: 3px;
			color: #fff !important;
			font-size: 10px;
			text-transform: uppercase;
			cursor: pointer;
		}
		.container-1YxwTf:not(:hover) .replyer {
			visibility: hidden;
		}`;
		return r;
	}
	unload() {
		this.stop();
	}
	onMessage() {}
	onSwitch() {}
	load() {}
}<|endoftext|>


<commit_before>import React from 'react';
import { Router, Route, IndexRedirect, browserHistory } from "react-router";
import axios from '../axios-config';

import ActiveForBystander from '../active/active-for-bystander/ActiveForBystander';
import ActiveForPlayer from '../active/active-for-player/ActiveForPlayer';
import App from './App';
import Create from '../create/Create';
import Friend from '../friend/Friend';
import Login from './Login';
import LudoEdit from '../ludo-edit/LudoEdit';
import OpenedForStarter from '../opened/opened-for-starter/OpenedForStarter';
import OpenedForBystander from '../opened/opened-for-bystander/OpenedForBystander';
import Playground from '../playground/Playground';
import Profile from '../profile/Profile';

const ludoPageArray = [OpenedForBystander, OpenedForStarter, OpenedForBystander, ActiveForPlayer, ActiveForPlayer, ActiveForBystander, ActiveForBystander];
const ludoPageArrayForEdit = [OpenedForBystander, LudoEdit, OpenedForBystander, ActiveForPlayer, ActiveForPlayer, ActiveForBystander, ActiveForBystander];

const isLoggedIn = (nextState, replace, callback) => {
    /* TODO: Look up the detail usage of replace function */
    axios.get('/apis/user')
    .then((response) => {
        if(response.data.status != '200') {
            replace(`/login`);
        }
        callback();
    })
    .catch((error) => {
        console.error('AppRouter isloggedin error');
        callback(error);
    })
};

let router_ludoPageIndex = null;
let router_currentFormValue = {};

const ludoRedirect = (nextState, replace, callback) => {
    const { ludo_id }= nextState.params;
    axios.get(`/apis/ludo/${ludo_id}`)
    .then((response) => {
        if(response.data.status === '200') {
            router_ludoPageIndex = response.data.auth;
            router_currentFormValue = response.data.ludo;
            callback();
        } else {
            window.alert('取得Ludo時發生錯誤，請重試一次；若問題還是發生，請聯絡開發團隊');
            console.error('AppRouter ludoRedirect getCurrentLudoData else response from server: ', response);
            console.error('AppRouter ludoRedirect getCurrentLudoData else message from server: ', response.data.message);
            if (response.data.err) {
                console.error('AppRouter ludoRedirect getCurrentLudoData else error from server: ', response.data.err);
            }
        }
    })
    .catch((error) => {
        window.alert('取得Ludo時發生錯誤，請重試一次；若問題還是發生，請聯絡開發團隊');
        console.error('AppRouter ludoRedirect getCurrentLudoData error', error);
    });
};

const ludoEditRedirect = (nextState, replace, callback) => {
    const { ludo_id }= nextState.params;
    axios.get(`/apis/ludo/${ludo_id}`)
    .then((response) => {
        if(response.data.status === '200') {
            if(response.data.auth != 1) {
                /* TODO: Figure out how to use same url redirect to other component */
                callback();
                browserHistory.push(`/ludo/${ludo_id}`);
            } else {
                router_ludoPageIndex = response.data.auth;
                router_currentFormValue = response.data.ludo;
                callback();
            }
        } else {
            window.alert('取得Ludo時發生錯誤，請重試一次；若問題還是發生，請聯絡開發團隊');
            console.error('AppRouter ludoRedirect getCurrentLudoData else response from server: ', response);
            console.error('AppRouter ludoRedirect getCurrentLudoData else message from server: ', response.data.message);
            if (response.data.err) {
                console.error('AppRouter ludoRedirect getCurrentLudoData else error from server: ', response.data.err);
            }
        }
    })
    .catch((error) => {
        window.alert('取得Ludo時發生錯誤，請重試一次；若問題還是發生，請聯絡開發團隊');
        console.error('AppRouter ludoRedirect getCurrentLudoData error', error);
    });
};

/* TODO: find out usage of getComponent callback */
export default class AppRouter extends React.Component {
    render() {
        return (
            <Router history={browserHistory}>
                <Route path="/" component={App}>
                    <IndexRedirect to="playground"></IndexRedirect>
                    <Route path="create" component={Create} onEnter={isLoggedIn}></Route>
                    <Route path="friend" component={Friend}></Route>
                    <Route path="login" component={Login}></Route>
                    <Route path="ludo/:ludo_id" getComponent={(nextState, cb) => {
                        const Component = ludoPageArray[router_ludoPageIndex];
                        cb(null, props => <Component {...props} router_currentFormValue={router_currentFormValue} />);
                    }} onEnter={ludoRedirect}></Route>
                    <Route path="ludo-edit/:ludo_id" getComponent={(nextState, cb) => {
                        const Component = ludoPageArrayForEdit[router_ludoPageIndex];
                        cb(null, props => <Component {...props} router_currentFormValue={router_currentFormValue} />);
                    }} onEnter={isLoggedIn, ludoEditRedirect} OnLeave={ludoRedirect}></Route>
                    <Route path="playground" component={Playground}></Route>
                    <Route path="profile/:userId" component={Profile} onEnter={isLoggedIn}></Route>
                </Route>
            </Router>
        );
    }
}<commit_msg>[Fix bug] redirect to login page when click menu of friend and profile<commit_after>import React from 'react';
import { Router, Route, IndexRedirect, browserHistory } from "react-router";
import axios from '../axios-config';

import ActiveForBystander from '../active/active-for-bystander/ActiveForBystander';
import ActiveForPlayer from '../active/active-for-player/ActiveForPlayer';
import App from './App';
import Create from '../create/Create';
import Friend from '../friend/Friend';
import Login from './Login';
import LudoEdit from '../ludo-edit/LudoEdit';
import OpenedForStarter from '../opened/opened-for-starter/OpenedForStarter';
import OpenedForBystander from '../opened/opened-for-bystander/OpenedForBystander';
import Playground from '../playground/Playground';
import Profile from '../profile/Profile';

const ludoPageArray = [OpenedForBystander, OpenedForStarter, OpenedForBystander, ActiveForPlayer, ActiveForPlayer, ActiveForBystander, ActiveForBystander];
const ludoPageArrayForEdit = [OpenedForBystander, LudoEdit, OpenedForBystander, ActiveForPlayer, ActiveForPlayer, ActiveForBystander, ActiveForBystander];

const isLoggedIn = (nextState, replace, callback) => {
    /* TODO: Look up the detail usage of replace function */
    axios.get('/apis/user')
    .then((response) => {
        if(response.data.status != '200') {
            replace(`/login`);
        }
        callback();
    })
    .catch((error) => {
        console.error('AppRouter isloggedin error');
        callback(error);
    })
};

let router_ludoPageIndex = null;
let router_currentFormValue = {};

const ludoRedirect = (nextState, replace, callback) => {
    const { ludo_id }= nextState.params;
    axios.get(`/apis/ludo/${ludo_id}`)
    .then((response) => {
        if(response.data.status === '200') {
            router_ludoPageIndex = response.data.auth;
            router_currentFormValue = response.data.ludo;
            callback();
        } else {
            window.alert('取得Ludo時發生錯誤，請重試一次；若問題還是發生，請聯絡開發團隊');
            console.error('AppRouter ludoRedirect getCurrentLudoData else response from server: ', response);
            console.error('AppRouter ludoRedirect getCurrentLudoData else message from server: ', response.data.message);
            if (response.data.err) {
                console.error('AppRouter ludoRedirect getCurrentLudoData else error from server: ', response.data.err);
            }
        }
    })
    .catch((error) => {
        window.alert('取得Ludo時發生錯誤，請重試一次；若問題還是發生，請聯絡開發團隊');
        console.error('AppRouter ludoRedirect getCurrentLudoData error', error);
    });
};

const ludoEditRedirect = (nextState, replace, callback) => {
    const { ludo_id }= nextState.params;
    axios.get(`/apis/ludo/${ludo_id}`)
    .then((response) => {
        if(response.data.status === '200') {
            if(response.data.auth != 1) {
                /* TODO: Figure out how to use same url redirect to other component */
                callback();
                browserHistory.push(`/ludo/${ludo_id}`);
            } else {
                router_ludoPageIndex = response.data.auth;
                router_currentFormValue = response.data.ludo;
                callback();
            }
        } else {
            window.alert('取得Ludo時發生錯誤，請重試一次；若問題還是發生，請聯絡開發團隊');
            console.error('AppRouter ludoRedirect getCurrentLudoData else response from server: ', response);
            console.error('AppRouter ludoRedirect getCurrentLudoData else message from server: ', response.data.message);
            if (response.data.err) {
                console.error('AppRouter ludoRedirect getCurrentLudoData else error from server: ', response.data.err);
            }
        }
    })
    .catch((error) => {
        window.alert('取得Ludo時發生錯誤，請重試一次；若問題還是發生，請聯絡開發團隊');
        console.error('AppRouter ludoRedirect getCurrentLudoData error', error);
    });
};

/* TODO: find out usage of getComponent callback */
export default class AppRouter extends React.Component {
    render() {
        return (
            <Router history={browserHistory}>
                <Route path="/" component={App}>
                    <IndexRedirect to="playground"></IndexRedirect>
                    <Route path="create" component={Create} onEnter={isLoggedIn}></Route>
                    <Route path="friend" component={Friend} onEnter={isLoggedIn}></Route>
                    <Route path="login" component={Login}></Route>
                    <Route path="ludo/:ludo_id" getComponent={(nextState, cb) => {
                        const Component = ludoPageArray[router_ludoPageIndex];
                        cb(null, props => <Component {...props} router_currentFormValue={router_currentFormValue} />);
                    }} onEnter={ludoRedirect}></Route>
                    <Route path="ludo-edit/:ludo_id" getComponent={(nextState, cb) => {
                        const Component = ludoPageArrayForEdit[router_ludoPageIndex];
                        cb(null, props => <Component {...props} router_currentFormValue={router_currentFormValue} />);
                    }} onEnter={isLoggedIn, ludoEditRedirect} OnLeave={ludoRedirect}></Route>
                    <Route path="playground" component={Playground}></Route>
                    <Route path="profile(/:userId)" component={Profile} onEnter={isLoggedIn}></Route>
                </Route>
            </Router>
        );
    }
}<|endoftext|>