<commit_before>import {getFaucet, getTestFaucet} from "../branding";

export const blockTradesAPIs = {
    BASE: "https://api.blocktrades.us/v2",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/active-wallets",
    TRADING_PAIRS: "/trading-pairs",
    DEPOSIT_LIMIT: "/deposit-limits",
    ESTIMATE_OUTPUT: "/estimate-output-amount",
    ESTIMATE_INPUT: "/estimate-input-amount"
};

export const openledgerAPIs = {
    BASE: "https://ol-api1.openledger.info/api/v0/ol/support",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/active-wallets",
    TRADING_PAIRS: "/trading-pairs",
    DEPOSIT_LIMIT: "/deposit-limits",
    ESTIMATE_OUTPUT: "/estimate-output-amount",
    ESTIMATE_INPUT: "/estimate-input-amount",
    RPC_URL: "https://openledger.info/api/"
};

export const rudexAPIs = {
    BASE: "https://gateway.rudex.org/api/rudex",
    COINS_LIST: "/coins",
    NEW_DEPOSIT_ADDRESS: "/simple-api/initiate-trade"
};

export const bitsparkAPIs = {
    BASE: "https://dex-api.bitspark.io/api/v1",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/active-wallets",
    TRADING_PAIRS: "/trading-pairs",
    DEPOSIT_LIMIT: "/deposit-limits",
    ESTIMATE_OUTPUT: "/estimate-output-amount",
    ESTIMATE_INPUT: "/estimate-input-amount"
};

export const cryptoBridgeAPIs = {
    BASE: "https://api.crypto-bridge.org/api/v1",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/wallets",
    MARKETS: "/markets",
    TRADING_PAIRS: "/trading-pairs"
};

export const citadelAPIs = {
    BASE: "https://citadel.li/trade",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/active-wallets",
    TRADING_PAIRS: "/trading-pairs",
    DEPOSIT_LIMIT: "/deposit-limits",
    ESTIMATE_OUTPUT: "/estimate-output-amount",
    ESTIMATE_INPUT: "/estimate-input-amount"
};

export const gdex2APIs = {
    BASE: "https://api.52bts.net/adjust",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/active-wallets",
    TRADING_PAIRS: "/trading-pairs"
};

// Legacy Deposit/Withdraw
export const gdexAPIs = {
    BASE: "https://api.52bts.net",
    ASSET_LIST: "/gateway/asset/assetList",
    ASSET_DETAIL: "/gateway/asset/assetDetail",
    GET_DEPOSIT_ADDRESS: "/gateway/address/getAddress",
    CHECK_WITHDRAY_ADDRESS: "/gateway/address/checkAddress",
    DEPOSIT_RECORD_LIST: "/gateway/deposit/recordList",
    DEPOSIT_RECORD_DETAIL: "/gateway/deposit/recordDetail",
    WITHDRAW_RECORD_LIST: "/gateway/withdraw/recordList",
    WITHDRAW_RECORD_DETAIL: "/gateway/withdraw/recordDetail",
    GET_USER_INFO: "/gateway/user/getUserInfo",
    USER_AGREEMENT: "/gateway/user/isAgree",
    WITHDRAW_RULE: "/gateway/withdraw/rule"
};

export const xbtsxAPIs = {
    BASE: "https://apis.xbts.io/api/v1",
    COINS_LIST: "/coin"
};

export const nodeRegions = [
    // region of the node follows roughly https://en.wikipedia.org/wiki/Subregion#/media/File:United_Nations_geographical_subregions.png
    "Northern Europe",
    "Western Europe",
    "Southern Europe",
    "Eastern Europe",
    "Northern Asia",
    "Western Asia",
    "Southern Asia",
    "Eastern Asia",
    "Central Asia",
    "Southeastern Asia",
    "Australia and New Zealand",
    "Melanesia",
    "Polynesia",
    "Micronesia",
    "Northern Africa",
    "Western Africa",
    "Middle Africa",
    "Eastern Africa",
    "Southern Africa",
    "Northern America",
    "Central America",
    "Caribbean",
    "South America"
];

export const settingsAPIs = {
    // If you want a location to be translated, add the translation to settings in locale-xx.js
    // and use an object {translate: key} in WS_NODE_LIST
    DEFAULT_WS_NODE: "wss://fake.automatic-selection.com",
    WS_NODE_LIST: [
        {
            url: "wss://fake.automatic-selection.com",
            location: {translate: "settings.api_closest"}
        },
        {
            url: "ws://127.0.0.1:8090",
            location: "Locally hosted"
        },
        {
            url: "wss://nexus01.co.uk/ws",
            region: "Northern Europe",
            country: "England",
            location: "Gloucester",
            operator: "Witness: nexus01",
            contact: "telegram:rosswlkr"
        },
        {
            url: "wss://dex.iobanker.com/ws",
            region: "Western Europe",
            country: "Germany",
            location: "Frankfurt",
            operator: "Witness: iobanker-core",
            contact: "email:admin@iobanker.com"
        },
        {
            url: "wss://ws.gdex.top",
            region: "Eastern Asia",
            country: "China",
            location: "Shanghai",
            operator: "Witness: gdex-witness",
            contact: "telegram:BrianZhang"
        },
        {
            url: "wss://api.weaccount.cn",
            region: "Eastern Asia",
            country: "China",
            location: "Hangzhou",
            operator: "Witness: btspp-witness",
            contact: "telegram:btsplusplus"
        },
        {
            url: "wss://api.bts.mobi/ws",
            region: "Northern America",
            country: "U.S.A.",
            location: "Virginia",
            operator: "Witness: in.abit",
            contact: "telegram:abitmore"
        },
        {
            url: "wss://btsws.roelandp.nl/ws",
            region: "Northern Europe",
            country: "Finland",
            location: "Helsinki",
            operator: "Witness: roelandp",
            contact: "telegram:roelandp"
        },
        {
            url: "wss://api.bitshares.bhuz.info/ws",
            region: "Northern America",
            country: "Canada",
            operator: "Witness: bhuz",
            contact: "telegram:bhuzor"
        },
        {
            url: "wss://api.btsgo.net/ws",
            region: "Southeastern Asia",
            location: "Singapore",
            operator: "Witness: xn-delegate",
            contact: "wechat:Necklace"
        },
        {
            url: "wss://bts.open.icowallet.net/ws",
            region: "Eastern Asia",
            country: "China",
            location: "Hangzhou",
            operator: "Witness: magicwallet.witness",
            contact: "telegram:plus_wave"
        },
        {
            url: "wss://freedom.bts123.cc:15138/",
            region: "Eastern Asia",
            country: "China",
            location: "Changsha",
            operator: "Witness: delegate.freedom",
            contact: "telegram:eggplant"
        },
        {
            url: "wss://bitshares.bts123.cc:15138/",
            region: "Eastern Asia",
            country: "China",
            location: "Hangzhou",
            operator: "Witness: delegate.freedom",
            contact: "telegram:eggplant"
        },
        // TODO the owner said it's temporarily closed. Recheck later.
        //{
        //    url: "wss://api.bts.ai",
        //    region: "Eastern Asia",
        //    country: "China",
        //    location: "Beijing",
        //    operator: "Witness: witness.hiblockchain",
        //    contact: "telegram:vianull;wechat:strugglingl"
        //},
        {
            url: "wss://bts-seoul.clockwork.gr",
            region: "Southeastern Asia",
            country: "Korea",
            location: "Seoul",
            operator: "Witness: clockwork",
            contact: "telegram:clockworkgr"
        },
        {
            url: "wss://api.61bts.com",
            region: "Eastern Asia",
            country: "China",
            location: "Shandong",
            operator: "Witness: liuye",
            contact: "email:work@akawa.ink"
        },
        {
            url: "wss://api-us.61bts.com",
            region: "Northern America",
            country: "USA",
            location: "St. Louis",
            operator: "Witness: liuye",
            contact: "email:work@akawa.ink"
        },
        {
            url: "wss://api.dex.trading/",
            region: "Western Europe",
            country: "France",
            location: "Paris",
            operator: "Witness: zapata42-witness",
            contact: "telegram:Zapata_42"
        },
        {
            url: "wss://api.bitshares.org/ws",
            region: "Western Europe",
            country: "France",
            location: "",
            operator: "bitshares.org",
            contact: ""
        },
        {
            url: "wss://us.api.bitshares.org/ws",
            region: "Western Europe",
            country: "France",
            location: "",
            operator: "bitshares.org",
            contact: ""
        },
        {
            url: "wss://asia.api.bitshares.org/ws",
            region: "Western Europe",
            country: "France",
            location: "",
            operator: "bitshares.org",
            contact: ""
        },
        // TODO node is out of sync, recheck later
        //{
        //    url: "wss://citadel.li/node",
        //    region: "Western Europe",
        //    country: "Iceland",
        //    location: "Reykjavik",
        //    operator: "CITADEL",
        //    contact: "email:citadel.li;support"
        //},
        {
            url: "wss://api-bts.liondani.com/ws",
            region: "Western Europe",
            country: "Germany",
            location: "Falkenstein",
            operator: "Witness: liondani",
            contact: "telegram:liondani"
        },
        {
            url: "wss://public.xbts.io/ws",
            region: "Western Europe",
            country: "Germany",
            location: "Nuremberg",
            operator: "Witness: xbtsio-wallet",
            contact: "telegram: xbtsio"
        },
        {
            url: "wss://cloud.xbts.io/ws",
            region: "Northern America",
            country: "U.S.A.",
            location: "VG, Ashburn",
            operator: "Witness: xbtsio-wallet",
            contact: "telegram: xbtsio"
        },
        {
            url: "wss://node.xbts.io/ws",
            region: "Western Europe",
            country: "Germany",
            location: "Falkenstein",
            operator: "Witness: xbtsio-wallet",
            contact: "telegram: xbtsio"
        },
        {
            url: "wss://api.gbacenter.org/ws",
            region: "Northern America",
            country: "U.S.A.",
            location: "Fremont, CA",
            operator: "Witness: gbac-ety001",
            contact: "email:work@domyself.me"
        },
        {
            url: "wss://api.cnvote.vip:888/",
            region: "Eastern Asia",
            country: "China",
            location: "Zhejiang",
            operator: "Witness: ioex",
            contact: "wechat:xiaoyuan_409"
        },
        {
            url: "wss://hongkong.bitshares.im/ws",
            region: "East Asia",
            country: "China",
            location: "Hong Kong",
            operator: "Witness: clone",
            contact: "telegram: yexiao"
        },
        {
            url: "wss://singapore.bitshares.im/ws",
            region: "Southeast Asia",
            country: "Singapore",
            location: "Singapore",
            operator: "Witness: clone",
            contact: "telegram: yexiao"
        },
        {
            url: "wss://newyork.bitshares.im/ws",
            region: "Northern America",
            country: "U.S.A.",
            location: "New York",
            operator: "Witness: clone",
            contact: "telegram: yexiao"
        },
        {
            url: "wss://api.iamredbar.com/ws",
            region: "Northern America",
            country: "U.S.A.",
            location: "Minnesota",
            operator: "Witness: iamredbar",
            contact: "telegram: iamredbar"
        },
        // Testnet
        {
            url: "wss://node.testnet.bitshares.eu",
            region: "TESTNET - Western Europe",
            country: "Germany",
            location: "Frankfurt",
            operator: "BitShares Europe",
            contact: "telegram:xeroc"
        },
        {
            url: "wss://testnet.dex.trading/",
            region: "TESTNET - Western Europe",
            country: "France",
            location: "Paris",
            operator: "Witness: zapata42-witness",
            contact: "telegram:Zapata_42"
        },
        {
            url: "wss://testnet.xbts.io/ws",
            region: "TESTNET - Europe",
            country: "Germany",
            location: "Nuremberg",
            operator: "Witness: xbtsio-wallet",
            contact: "telegram: xbtsio"
        },
        {
            url: "wss://testnet.bitshares.im/ws",
            region: "Eastern Asia",
            country: "Japan",
            location: "Tokyo",
            operator: "Witness: clone",
            contact: "telegram: yexiao"
        },
        {
            url: "wss://api-testnet.61bts.com/ws",
            region: "Eastern Asia",
            country: "China",
            location: "Shandong",
            operator: "Witness: liuye",
            contact: "email:work@akawa.ink"
        },
        {
            url: "wss://api-us-testnet.61bts.com/ws",
            region: "Northern America",
            country: "USA",
            location: "St. Louis",
            operator: "Witness: liuye",
            contact: "email:work@akawa.ink"
        }
    ],
    ES_WRAPPER_LIST: [
        {
            url: "https://api.bitshares.ws/openexplorer",
            region: "Western Europe",
            country: "Germany",
            operator: "blocksights.info",
            contact: "bitshares:blocksights"
        }
    ],
    DEFAULT_FAUCET: getFaucet().url,
    TESTNET_FAUCET: getTestFaucet().url
};
<commit_msg>Remove iamredbar's API node<commit_after>import {getFaucet, getTestFaucet} from "../branding";

export const blockTradesAPIs = {
    BASE: "https://api.blocktrades.us/v2",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/active-wallets",
    TRADING_PAIRS: "/trading-pairs",
    DEPOSIT_LIMIT: "/deposit-limits",
    ESTIMATE_OUTPUT: "/estimate-output-amount",
    ESTIMATE_INPUT: "/estimate-input-amount"
};

export const openledgerAPIs = {
    BASE: "https://ol-api1.openledger.info/api/v0/ol/support",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/active-wallets",
    TRADING_PAIRS: "/trading-pairs",
    DEPOSIT_LIMIT: "/deposit-limits",
    ESTIMATE_OUTPUT: "/estimate-output-amount",
    ESTIMATE_INPUT: "/estimate-input-amount",
    RPC_URL: "https://openledger.info/api/"
};

export const rudexAPIs = {
    BASE: "https://gateway.rudex.org/api/rudex",
    COINS_LIST: "/coins",
    NEW_DEPOSIT_ADDRESS: "/simple-api/initiate-trade"
};

export const bitsparkAPIs = {
    BASE: "https://dex-api.bitspark.io/api/v1",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/active-wallets",
    TRADING_PAIRS: "/trading-pairs",
    DEPOSIT_LIMIT: "/deposit-limits",
    ESTIMATE_OUTPUT: "/estimate-output-amount",
    ESTIMATE_INPUT: "/estimate-input-amount"
};

export const cryptoBridgeAPIs = {
    BASE: "https://api.crypto-bridge.org/api/v1",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/wallets",
    MARKETS: "/markets",
    TRADING_PAIRS: "/trading-pairs"
};

export const citadelAPIs = {
    BASE: "https://citadel.li/trade",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/active-wallets",
    TRADING_PAIRS: "/trading-pairs",
    DEPOSIT_LIMIT: "/deposit-limits",
    ESTIMATE_OUTPUT: "/estimate-output-amount",
    ESTIMATE_INPUT: "/estimate-input-amount"
};

export const gdex2APIs = {
    BASE: "https://api.52bts.net/adjust",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/active-wallets",
    TRADING_PAIRS: "/trading-pairs"
};

// Legacy Deposit/Withdraw
export const gdexAPIs = {
    BASE: "https://api.52bts.net",
    ASSET_LIST: "/gateway/asset/assetList",
    ASSET_DETAIL: "/gateway/asset/assetDetail",
    GET_DEPOSIT_ADDRESS: "/gateway/address/getAddress",
    CHECK_WITHDRAY_ADDRESS: "/gateway/address/checkAddress",
    DEPOSIT_RECORD_LIST: "/gateway/deposit/recordList",
    DEPOSIT_RECORD_DETAIL: "/gateway/deposit/recordDetail",
    WITHDRAW_RECORD_LIST: "/gateway/withdraw/recordList",
    WITHDRAW_RECORD_DETAIL: "/gateway/withdraw/recordDetail",
    GET_USER_INFO: "/gateway/user/getUserInfo",
    USER_AGREEMENT: "/gateway/user/isAgree",
    WITHDRAW_RULE: "/gateway/withdraw/rule"
};

export const xbtsxAPIs = {
    BASE: "https://apis.xbts.io/api/v1",
    COINS_LIST: "/coin"
};

export const nodeRegions = [
    // region of the node follows roughly https://en.wikipedia.org/wiki/Subregion#/media/File:United_Nations_geographical_subregions.png
    "Northern Europe",
    "Western Europe",
    "Southern Europe",
    "Eastern Europe",
    "Northern Asia",
    "Western Asia",
    "Southern Asia",
    "Eastern Asia",
    "Central Asia",
    "Southeastern Asia",
    "Australia and New Zealand",
    "Melanesia",
    "Polynesia",
    "Micronesia",
    "Northern Africa",
    "Western Africa",
    "Middle Africa",
    "Eastern Africa",
    "Southern Africa",
    "Northern America",
    "Central America",
    "Caribbean",
    "South America"
];

export const settingsAPIs = {
    // If you want a location to be translated, add the translation to settings in locale-xx.js
    // and use an object {translate: key} in WS_NODE_LIST
    DEFAULT_WS_NODE: "wss://fake.automatic-selection.com",
    WS_NODE_LIST: [
        {
            url: "wss://fake.automatic-selection.com",
            location: {translate: "settings.api_closest"}
        },
        {
            url: "ws://127.0.0.1:8090",
            location: "Locally hosted"
        },
        {
            url: "wss://nexus01.co.uk/ws",
            region: "Northern Europe",
            country: "England",
            location: "Gloucester",
            operator: "Witness: nexus01",
            contact: "telegram:rosswlkr"
        },
        {
            url: "wss://dex.iobanker.com/ws",
            region: "Western Europe",
            country: "Germany",
            location: "Frankfurt",
            operator: "Witness: iobanker-core",
            contact: "email:admin@iobanker.com"
        },
        {
            url: "wss://ws.gdex.top",
            region: "Eastern Asia",
            country: "China",
            location: "Shanghai",
            operator: "Witness: gdex-witness",
            contact: "telegram:BrianZhang"
        },
        {
            url: "wss://api.weaccount.cn",
            region: "Eastern Asia",
            country: "China",
            location: "Hangzhou",
            operator: "Witness: btspp-witness",
            contact: "telegram:btsplusplus"
        },
        {
            url: "wss://api.bts.mobi/ws",
            region: "Northern America",
            country: "U.S.A.",
            location: "Virginia",
            operator: "Witness: in.abit",
            contact: "telegram:abitmore"
        },
        {
            url: "wss://btsws.roelandp.nl/ws",
            region: "Northern Europe",
            country: "Finland",
            location: "Helsinki",
            operator: "Witness: roelandp",
            contact: "telegram:roelandp"
        },
        {
            url: "wss://api.bitshares.bhuz.info/ws",
            region: "Northern America",
            country: "Canada",
            operator: "Witness: bhuz",
            contact: "telegram:bhuzor"
        },
        {
            url: "wss://api.btsgo.net/ws",
            region: "Southeastern Asia",
            location: "Singapore",
            operator: "Witness: xn-delegate",
            contact: "wechat:Necklace"
        },
        {
            url: "wss://bts.open.icowallet.net/ws",
            region: "Eastern Asia",
            country: "China",
            location: "Hangzhou",
            operator: "Witness: magicwallet.witness",
            contact: "telegram:plus_wave"
        },
        {
            url: "wss://freedom.bts123.cc:15138/",
            region: "Eastern Asia",
            country: "China",
            location: "Changsha",
            operator: "Witness: delegate.freedom",
            contact: "telegram:eggplant"
        },
        {
            url: "wss://bitshares.bts123.cc:15138/",
            region: "Eastern Asia",
            country: "China",
            location: "Hangzhou",
            operator: "Witness: delegate.freedom",
            contact: "telegram:eggplant"
        },
        // TODO the owner said it's temporarily closed. Recheck later.
        //{
        //    url: "wss://api.bts.ai",
        //    region: "Eastern Asia",
        //    country: "China",
        //    location: "Beijing",
        //    operator: "Witness: witness.hiblockchain",
        //    contact: "telegram:vianull;wechat:strugglingl"
        //},
        {
            url: "wss://bts-seoul.clockwork.gr",
            region: "Southeastern Asia",
            country: "Korea",
            location: "Seoul",
            operator: "Witness: clockwork",
            contact: "telegram:clockworkgr"
        },
        {
            url: "wss://api.61bts.com",
            region: "Eastern Asia",
            country: "China",
            location: "Shandong",
            operator: "Witness: liuye",
            contact: "email:work@akawa.ink"
        },
        {
            url: "wss://api-us.61bts.com",
            region: "Northern America",
            country: "USA",
            location: "St. Louis",
            operator: "Witness: liuye",
            contact: "email:work@akawa.ink"
        },
        {
            url: "wss://api.dex.trading/",
            region: "Western Europe",
            country: "France",
            location: "Paris",
            operator: "Witness: zapata42-witness",
            contact: "telegram:Zapata_42"
        },
        {
            url: "wss://api.bitshares.org/ws",
            region: "Western Europe",
            country: "France",
            location: "",
            operator: "bitshares.org",
            contact: ""
        },
        {
            url: "wss://us.api.bitshares.org/ws",
            region: "Western Europe",
            country: "France",
            location: "",
            operator: "bitshares.org",
            contact: ""
        },
        {
            url: "wss://asia.api.bitshares.org/ws",
            region: "Western Europe",
            country: "France",
            location: "",
            operator: "bitshares.org",
            contact: ""
        },
        // TODO node is out of sync, recheck later
        //{
        //    url: "wss://citadel.li/node",
        //    region: "Western Europe",
        //    country: "Iceland",
        //    location: "Reykjavik",
        //    operator: "CITADEL",
        //    contact: "email:citadel.li;support"
        //},
        {
            url: "wss://api-bts.liondani.com/ws",
            region: "Western Europe",
            country: "Germany",
            location: "Falkenstein",
            operator: "Witness: liondani",
            contact: "telegram:liondani"
        },
        {
            url: "wss://public.xbts.io/ws",
            region: "Western Europe",
            country: "Germany",
            location: "Nuremberg",
            operator: "Witness: xbtsio-wallet",
            contact: "telegram: xbtsio"
        },
        {
            url: "wss://cloud.xbts.io/ws",
            region: "Northern America",
            country: "U.S.A.",
            location: "VG, Ashburn",
            operator: "Witness: xbtsio-wallet",
            contact: "telegram: xbtsio"
        },
        {
            url: "wss://node.xbts.io/ws",
            region: "Western Europe",
            country: "Germany",
            location: "Falkenstein",
            operator: "Witness: xbtsio-wallet",
            contact: "telegram: xbtsio"
        },
        {
            url: "wss://api.gbacenter.org/ws",
            region: "Northern America",
            country: "U.S.A.",
            location: "Fremont, CA",
            operator: "Witness: gbac-ety001",
            contact: "email:work@domyself.me"
        },
        {
            url: "wss://api.cnvote.vip:888/",
            region: "Eastern Asia",
            country: "China",
            location: "Zhejiang",
            operator: "Witness: ioex",
            contact: "wechat:xiaoyuan_409"
        },
        {
            url: "wss://hongkong.bitshares.im/ws",
            region: "East Asia",
            country: "China",
            location: "Hong Kong",
            operator: "Witness: clone",
            contact: "telegram: yexiao"
        },
        {
            url: "wss://singapore.bitshares.im/ws",
            region: "Southeast Asia",
            country: "Singapore",
            location: "Singapore",
            operator: "Witness: clone",
            contact: "telegram: yexiao"
        },
        {
            url: "wss://newyork.bitshares.im/ws",
            region: "Northern America",
            country: "U.S.A.",
            location: "New York",
            operator: "Witness: clone",
            contact: "telegram: yexiao"
        },
        // Testnet
        {
            url: "wss://node.testnet.bitshares.eu",
            region: "TESTNET - Western Europe",
            country: "Germany",
            location: "Frankfurt",
            operator: "BitShares Europe",
            contact: "telegram:xeroc"
        },
        {
            url: "wss://testnet.dex.trading/",
            region: "TESTNET - Western Europe",
            country: "France",
            location: "Paris",
            operator: "Witness: zapata42-witness",
            contact: "telegram:Zapata_42"
        },
        {
            url: "wss://testnet.xbts.io/ws",
            region: "TESTNET - Europe",
            country: "Germany",
            location: "Nuremberg",
            operator: "Witness: xbtsio-wallet",
            contact: "telegram: xbtsio"
        },
        {
            url: "wss://testnet.bitshares.im/ws",
            region: "Eastern Asia",
            country: "Japan",
            location: "Tokyo",
            operator: "Witness: clone",
            contact: "telegram: yexiao"
        },
        {
            url: "wss://api-testnet.61bts.com/ws",
            region: "Eastern Asia",
            country: "China",
            location: "Shandong",
            operator: "Witness: liuye",
            contact: "email:work@akawa.ink"
        },
        {
            url: "wss://api-us-testnet.61bts.com/ws",
            region: "Northern America",
            country: "USA",
            location: "St. Louis",
            operator: "Witness: liuye",
            contact: "email:work@akawa.ink"
        }
    ],
    ES_WRAPPER_LIST: [
        {
            url: "https://api.bitshares.ws/openexplorer",
            region: "Western Europe",
            country: "Germany",
            operator: "blocksights.info",
            contact: "bitshares:blocksights"
        }
    ],
    DEFAULT_FAUCET: getFaucet().url,
    TESTNET_FAUCET: getTestFaucet().url
};
<|endoftext|>


<commit_before>
const static_commands = require('./static_commands.js')

// Commands are called in the following manner:
// commands[command](message, config, msg, ...parameters)
// msg is the message content without the prefix or command
module.exports = {
    'ping': (message) => {
        message.edit("pong!");
    },

    // _ denotes arguments we don't care about
    'selfbot_off': (message) => {
        message.edit("Selfbot logging off.").then(() => {
            console.log("Forced to disconnect.");
            process.exit(0);
        });
    },

    'reply': (message, _, msg) => {
        let cb = '```',
            quotes = msg.split(/\.s\./g),
            reply  = quotes.pop();

        message.edit(
            quotes.map(q => `${cb}css\n> ${q}${cb}`)
                .join('')
                .concat(reply)
        );
    },

    // 'shrug': (message, _, msg) => {
    //     message.edit(msg + "¯\\_(ツ)_\/¯");
    // },

    'hideyourshame': (message, config, _, n=0) => {
        n   = parseInt(n) + 1;

        message.channel.fetchMessages( {limit: 99} )
            .then((messages) => {
                messages.array()
                    .filter(m => m.author.id === config.soupmaster)
                    .slice(0,n)
                    .forEach(message => message.delete());
            });
    },

    'eval': (message, config, msg) => {
        try {
        message.channel.send(`Input\n\`\`\`js\n${msg}\`\`\`${''
                            }Output\n\`\`\`js\n${eval(msg)}\`\`\``)
                       .catch(e => message.channel.send(e))
        } catch (e) {
            message.channel.send(e)
        }
    }
}

for(let key in static_commands) {
    module.exports[key] = (message, _, msg) => {
        message.edit(`${msg} ${static_commands[key]}`);
    }
}<commit_msg>Move comments, remove commented code, and change concat<commit_after>
const static_commands = require('./static_commands.js')

// Commands are called in the following manner:
// commands[command](message, config, msg, ...parameters)
// msg is the message content without the prefix or command
module.exports = {
    'ping': (message) => {
        message.edit("pong!");
    },

    'selfbot_off': (message) => {
        message.edit("Selfbot logging off.").then(() => {
            console.log("Forced to disconnect.");
            process.exit(0);
        });
    },

    // _ denotes arguments we don't care about
    'reply': (message, _, msg) => {
        let cb = '```',
            quotes = msg.split(/\.s\./g),
            reply  = quotes.pop();

        message.edit(
            quotes.map(q => `${cb}css\n> ${q}${cb}`)
                .join('')
                .concat(reply)
        );
    },

    'hideyourshame': (message, config, _, n=0) => {
        n   = parseInt(n) + 1;

        message.channel.fetchMessages( {limit: 99} )
            .then((messages) => {
                messages.array()
                    .filter(m => m.author.id === config.soupmaster)
                    .slice(0,n)
                    .forEach(message => message.delete());
            });
    },

    'eval': (message, config, msg) => {
        try {
        message.channel.send(
                            `Input\n\`\`\`js\n${msg}\`\`\``+
                            `Output\n\`\`\`js\n${eval(msg)}\`\`\``
                            )
                       .catch(e => message.channel.send(e))
        } catch (e) {
            message.channel.send(e)
        }
    }
}

for(let key in static_commands) {
    module.exports[key] = (message, _, msg) => {
        message.edit(`${msg} ${static_commands[key]}`);
    }
}<|endoftext|>


<commit_before>'use babel';
'use strict';

import { version } from '../..';
import { stripIndents } from 'common-tags';
import Command from '../command';

export default class AboutCommand extends Command {
	constructor(bot) {
		super(bot, {
			name: 'about',
			module: 'info',
			memberName: 'about',
			description: 'Displays information about the bot.'
		});
	}

	async run(message) {
		const config = this.bot.config.values;
		const owner = message.client.users.get(this.bot.config.values.owner);
		const guilds = message.client.guilds.length.toLocaleString(), users = message.client.users.length.toLocaleString();
		const guildsLabel = guilds !== 1 ? 'guilds' : 'guild', usersLabel = users !== 1 ? 'users' : 'user';
		const uptime = process.uptime();
		const days = Math.floor(uptime / 60 / 60 / 24), hours = Math.floor(uptime / 60 / 60 % 24), minutes = Math.floor(uptime / 60 % 60);
		const daysLabel = days !== 1 ? 'days' : 'day', hoursLabel = hours !== 1 ? 'hours' : 'hour', minutesLabel = minutes !== 1 ? 'minutes' : 'minute';
		const daysStr = `${days.toLocaleString()} ${daysLabel}`, hoursStr = `${hours.toLocaleString()} ${hoursLabel}`, minutesStr = `${minutes.toLocaleString()} ${minutesLabel}`;
		return {
			direct: stripIndents`
				${config.about || ''}

				This bot ${owner ? `is owned by ${owner.name}#${owner.discriminator}, and ` : ''}is serving ${users} ${usersLabel} across ${guilds} ${guildsLabel}.
				It has been running without interruption for ${days > 0 ? `${daysStr} ` : ''}${hours > 0 ? `${hoursStr} ` : ''}${minutesStr}.
				${config.invite ? `For bot feedback/help, use this invite: ${config.invite}` : ''}

				Based on Discord GRAF v${version}: https://github.com/Gawdl3y/discord-graf
			`,
			reply: 'Sent a DM to you with information.'
		};
	}
}
<commit_msg>Fixed owner name in about<commit_after>'use babel';
'use strict';

import { version } from '../..';
import { stripIndents } from 'common-tags';
import Command from '../command';

export default class AboutCommand extends Command {
	constructor(bot) {
		super(bot, {
			name: 'about',
			module: 'info',
			memberName: 'about',
			description: 'Displays information about the bot.'
		});
	}

	async run(message) {
		const config = this.bot.config.values;
		const owner = message.client.users.get(this.bot.config.values.owner);
		const guilds = message.client.guilds.length.toLocaleString(), users = message.client.users.length.toLocaleString();
		const guildsLabel = guilds !== 1 ? 'guilds' : 'guild', usersLabel = users !== 1 ? 'users' : 'user';
		const uptime = process.uptime();
		const days = Math.floor(uptime / 60 / 60 / 24), hours = Math.floor(uptime / 60 / 60 % 24), minutes = Math.floor(uptime / 60 % 60);
		const daysLabel = days !== 1 ? 'days' : 'day', hoursLabel = hours !== 1 ? 'hours' : 'hour', minutesLabel = minutes !== 1 ? 'minutes' : 'minute';
		const daysStr = `${days.toLocaleString()} ${daysLabel}`, hoursStr = `${hours.toLocaleString()} ${hoursLabel}`, minutesStr = `${minutes.toLocaleString()} ${minutesLabel}`;
		return {
			direct: stripIndents`
				${config.about || ''}

				This bot ${owner ? `is owned by ${owner.username}#${owner.discriminator}, and ` : ''}is serving ${users} ${usersLabel} across ${guilds} ${guildsLabel}.
				It has been running without interruption for ${days > 0 ? `${daysStr} ` : ''}${hours > 0 ? `${hoursStr} ` : ''}${minutesStr}.
				${config.invite ? `For bot feedback/help, use this invite: ${config.invite}` : ''}

				Based on Discord GRAF v${version}: https://github.com/Gawdl3y/discord-graf
			`,
			reply: 'Sent a DM to you with information.'
		};
	}
}
<|endoftext|>


<commit_before>// ==========================================================================
// Project:   SproutCore - JavaScript Application Framework
// Copyright: ©2006-2009 Sprout Systems, Inc. and contributors.
//            Portions ©2008-2009 Apple Inc. All rights reserved.
// License:   Licened under MIT license (see license.js)
// ==========================================================================
/*globals ie7userdata openDatabase*/
/**
  @class

  The UserDefaults object provides an easy way to store user preferences in
  your application on the local machine.  You use this by providing built-in
  defaults using the SC.userDefaults.defaults() method.  You can also
  implement the UserDefaultsDelegate interface to be notified whenever a
  default is required.

  You should also set the userDomain property on the defaults on page load.
  This will allow the UserDefaults application to store/fetch keys from
  localStorage for the correct user.

  You can also set an appDomain property if you want.  This will be
  automatically prepended to key names with no slashes in them.

  SC.userDefaults.getPath("global:contactInfo.userName");

  @extends SC.Object
  @since SproutCore 1.0
*/
SC.UserDefaults = SC.Object.extend(/** @scope SC.UserDefaults.prototype */ {

  ready: NO,

  /**
    the default domain for the user.  This will be used to store keys in
    local storage.  If you do not set this property, the wrong values may be
    returned.
  */
  userDomain: null,

  /**
    The default app domain for the user.  Any keys that do not include a
    slash will be prefixed with this app domain key when getting/setting.
  */
  appDomain: null,

  /** @private
    Defaults.  These will be used if not defined on localStorage.
  */
  _defaults: null,

  _safari3DB: null,

  /**
    Invoke this method to set the builtin defaults.  This will cause all
    properties to change.
  */
  defaults: function(newDefaults) {
    this._defaults = newDefaults ;
    this.allPropertiesDidChange();
  },

  /**
    Attempts to read a user default from local storage.  If not found on
    localStorage, use the the local defaults, if defined.  If the key passed
    does not include a slash, then add the appDomain or use "app/".

    @param {String} keyName
    @returns {Object} read value
  */
  readDefault: function(keyName) {
    var ret= undefined, userKeyName, localStorage, key, del, storageSafari3;

    // namespace keyname
    keyName = this._normalizeKeyName(keyName);
    userKeyName = this._userKeyName(keyName);

    // look into recently written values
    if (this._written) ret = this._written[userKeyName];

    // attempt to read from localStorage

    if(SC.browser.msie=="7.0"){
       localStorage=ie7userdata;
       try{
         localStorage.load("SC.UserDefaults");
       }catch(e){}
    }else if(this.HTML5DB_noLocalStorage){
         storageSafari3 = this._safari3DB;
    }else{
       localStorage = window.localStorage ;
       if (!localStorage && window.globalStorage) {
         localStorage = window.globalStorage[window.location.hostname];
       }
    }
    if (localStorage || storageSafari3) {
      key=["SC.UserDefaults",userKeyName].join('-at-');
      if(SC.browser.msie=="7.0"){
        ret=localStorage.getAttribute(key.replace(/\W/gi, ''));
      }else if(storageSafari3){
        ret = this.dataHash[key];
      }else{
        ret = localStorage[key];
      }
      if (!SC.none(ret)) {
        try {
          ret = SC.json.decode(ret);
        }
        catch(ex) {
          ret = undefined;
        }
      } else ret = undefined;
    }

    // if not found in localStorage, try to notify delegate
    del =this.delegate ;
    if (del && del.userDefaultsNeedsDefault) {
      ret = del.userDefaultsNeedsDefault(this, keyName, userKeyName);
    }

    // if not found in localStorage or delegate, try to find in defaults
    if ((ret===undefined) && this._defaults) {
      ret = this._defaults[userKeyName] || this._defaults[keyName];
    }

    return ret ;
  },

  /**
    Attempts to write the user default to local storage or at least saves them
    for now.  Also notifies that the value has changed.

    @param {String} keyName
    @param {Object} value
    @returns {SC.UserDefault} receiver
  */
  writeDefault: function(keyName, value) {
    var userKeyName, written, localStorage, key, del, storageSafari3;

    keyName = this._normalizeKeyName(keyName);
    userKeyName = this._userKeyName(keyName);

    // save to local hash
    written = this._written ;
    if (!written) written = this._written = {};
    written[userKeyName] = value ;

    // save to local storage

    if(SC.browser.msie=="7.0"){
      localStorage=ie7userdata;
    }else if(this.HTML5DB_noLocalStorage){
      storageSafari3 = this._safari3DB;
    }else{
       localStorage = window.localStorage ;
       if (!localStorage && window.globalStorage) {
         localStorage = window.globalStorage[window.location.hostname];
       }
    }
    key=["SC.UserDefaults",userKeyName].join('-at-');
    if (localStorage || storageSafari3) {
      var encodedValue = SC.json.encode(value);
      if(SC.browser.msie=="7.0"){
        localStorage.setAttribute(key.replace(/\W/gi, ''), encodedValue);
        localStorage.save("SC.UserDefaults");
      }else if(storageSafari3){
        var obj = this;
        storageSafari3.transaction(
          function (t) {
            t.executeSql("delete from SCLocalStorage where key = ?", [key],
              function (){
                t.executeSql("insert into SCLocalStorage(key, value)"+
                            " VALUES ('"+key+"', '"+encodedValue+"');",
                            [], obj._nullDataHandler, obj.killTransaction
                );
              }
            );
          }
        );
        this.dataHash[key] = encodedValue;
      }else{

        localStorage[key] = encodedValue;
      }
    }

    // also notify delegate
    del = this.delegate;
    if (del && del.userDefaultsDidChange) {
      del.userDefaultsDidChange(this, keyName, value, userKeyName);
    }

    return this ;
  },

  /**
    Removed the passed keyName from the written hash and local storage.

    @param {String} keyName
    @returns {SC.UserDefaults} receiver
  */
  resetDefault: function(keyName) {
    var fullKeyName, userKeyName, written, localStorage, key, storageSafari3;
    fullKeyName = this._normalizeKeyName(keyName);
    userKeyName = this._userKeyName(fullKeyName);

    this.propertyWillChange(keyName);
    this.propertyWillChange(fullKeyName);

    written = this._written;
    if (written) delete written[userKeyName];

    if(SC.browser.msie=="7.0"){
       localStorage=ie7userdata;
    }else if(this.HTML5DB_noLocalStorage){
         storageSafari3 = this._safari3DB;
    }else{
       localStorage = window.localStorage ;
       if (!localStorage && window.globalStorage) {
         localStorage = window.globalStorage[window.location.hostname];
       }
    }

    key=["SC.UserDefaults",userKeyName].join('-at-');

    if (localStorage) {
      if(SC.browser.msie=="7.0"){
        localStorage.setAttribute(key.replace(/\W/gi, ''), null);
        localStorage.save("SC.UserDefaults");
      } else if(storageSafari3){
        var obj = this;
        storageSafari3.transaction(
          function (t) {
            t.executeSql("delete from SCLocalStorage where key = ?", [key], null);
          }
        );
        delete this.dataHash[key];
      }else{
        delete localStorage[key];
      }
    }

    this.propertyDidChange(keyName);
    this.propertyDidChange(fullKeyName);
    return this ;
  },

  /**
    Is called whenever you .get() or .set() values on this object

    @param {Object} key
    @param {Object} value
    @returns {Object}
  */
  unknownProperty: function(key, value) {
    if (value === undefined) {
      return this.readDefault(key) ;
    } else {
      this.writeDefault(key, value);
      return value ;
    }
  },

  /**
    Normalize the passed key name.  Used by all accessors to automatically
    insert an appName if needed.
  */
  _normalizeKeyName: function(keyName) {
    if (keyName.indexOf(':')<0) {
      var domain = this.get('appDomain') || 'app';
      keyName = [domain, keyName].join(':');
    }
    return keyName;
  },

  /**
    Builds a user key name from the passed key name
  */
  _userKeyName: function(keyName) {
    var user = this.get('userDomain') || '(anonymous)' ;
    return [user,keyName].join('-at-');
  },

  _domainDidChange: function() {
    var didChange = NO;
    if (this.get("userDomain") !== this._scud_userDomain) {
      this._scud_userDomain = this.get('userDomain');
      didChange = YES;
    }

    if (this.get('appDomain') !== this._scud_appDomain) {
      this._scud_appDomain = this.get('appDomain');
      didChange = YES;
    }

    if (didChange) this.allPropertiesDidChange();
  }.observes('userDomain', 'appDomain'),

  init: function() {
    sc_super();
    this._scud_userDomain = this.get('userDomain');
    this._scud_appDomain  = this.get('appDomain');
    if(SC.browser.msie=="7.0"){
      var el = document.createElement('div');

      // set element properties
      el.id = "ie7userdata";
      el.style.display = 'none';
      el.addBehavior('#default#userData');

      // append element to body
      document.body.appendChild(el);
    }
    this.HTML5DB_noLocalStorage = ((parseInt(SC.browser.safari, 0)>523) && (parseInt(SC.browser.safari, 0)<528));
    if(this.HTML5DB_noLocalStorage){
      var myDB;
      try {
        if (!window.openDatabase) {
          console.error("Trying to load a database with safari version 3.1 "+
                  "to get SC.UserDefaults to work. You are either in a"+
                  " previous version or there is a problem with your browser.");
          return;
        } else {
          var shortName = 'scdb',
              version = '1.0',
              displayName = 'SproutCore database',
              maxSize = 65536; // in bytes,
          myDB = openDatabase(shortName, version, displayName, maxSize);

          // You should have a database instance in myDB.

        }
      } catch(e) {
        console.error("Trying to load a database with safari version 3.1 "+
                "to get SC.UserDefaults to work. You are either in a"+
                " previous version or there is a problem with your browser.");
        return;
      }

      if(myDB){
        var obj = this;
        myDB.transaction(
          function (transaction) {
            transaction.executeSql('CREATE TABLE IF NOT EXISTS SCLocalStorage'+
              '(key TEXT NOT NULL PRIMARY KEY, value TEXT NOT NULL);',
              [], obj._nullDataHandler, obj.killTransaction);
          }
        );
        myDB.transaction(
          function (transaction) {
            transaction.parent = obj;
            transaction.executeSql('SELECT * from SCLocalStorage;',
                [], function(transaction, results){
                  var hash={}, row;
                  for(var i=0, iLen=results.rows.length; i<iLen; i++){
                    row=results.rows.item(i);
                    hash[row['key']]=row['value'];
                  }
                  transaction.parent.dataHash = hash;
                  SC.userDefaults.set('ready', YES);
                }, obj.killTransaction);
          }
        );
        this._safari3DB=myDB;
      }
    }else{
      this.set('ready', YES);
    }
  },

  //Private methods to use if user defaults uses the database in safari 3
  _killTransaction: function(transaction, error){
    return true; // fatal transaction error
  },

  _nullDataHandler: function(transaction, results){},

  readyCallback: function(ob, func){
    this.func = func;
    this.ob = ob;
  },

  readyChanged: function(){
    if(this.ready===YES){
      var f = this.func;
      if(f) f.apply(this.ob);
    }
  }.observes('ready')
});

/** global user defaults. */
SC.userDefaults = SC.UserDefaults.create();<commit_msg>Fixing SC.UserDefaults for IE7. Instead of doing the storage in a dinamically created element I add the behavior directly to the body. That solved the inconsistent behavior in different apps.<commit_after>// ==========================================================================
// Project:   SproutCore - JavaScript Application Framework
// Copyright: ©2006-2009 Sprout Systems, Inc. and contributors.
//            Portions ©2008-2009 Apple Inc. All rights reserved.
// License:   Licened under MIT license (see license.js)
// ==========================================================================
/*globals ie7userdata openDatabase*/
/**
  @class

  The UserDefaults object provides an easy way to store user preferences in
  your application on the local machine.  You use this by providing built-in
  defaults using the SC.userDefaults.defaults() method.  You can also
  implement the UserDefaultsDelegate interface to be notified whenever a
  default is required.

  You should also set the userDomain property on the defaults on page load.
  This will allow the UserDefaults application to store/fetch keys from
  localStorage for the correct user.

  You can also set an appDomain property if you want.  This will be
  automatically prepended to key names with no slashes in them.

  SC.userDefaults.getPath("global:contactInfo.userName");

  @extends SC.Object
  @since SproutCore 1.0
*/
SC.UserDefaults = SC.Object.extend(/** @scope SC.UserDefaults.prototype */ {

  ready: NO,

  /**
    the default domain for the user.  This will be used to store keys in
    local storage.  If you do not set this property, the wrong values may be
    returned.
  */
  userDomain: null,

  /**
    The default app domain for the user.  Any keys that do not include a
    slash will be prefixed with this app domain key when getting/setting.
  */
  appDomain: null,

  /** @private
    Defaults.  These will be used if not defined on localStorage.
  */
  _defaults: null,

  _safari3DB: null,

  /**
    Invoke this method to set the builtin defaults.  This will cause all
    properties to change.
  */
  defaults: function(newDefaults) {
    this._defaults = newDefaults ;
    this.allPropertiesDidChange();
  },

  /**
    Attempts to read a user default from local storage.  If not found on
    localStorage, use the the local defaults, if defined.  If the key passed
    does not include a slash, then add the appDomain or use "app/".

    @param {String} keyName
    @returns {Object} read value
  */
  readDefault: function(keyName) {
    var ret= undefined, userKeyName, localStorage, key, del, storageSafari3;

    // namespace keyname
    keyName = this._normalizeKeyName(keyName);
    userKeyName = this._userKeyName(keyName);

    // look into recently written values
    if (this._written) ret = this._written[userKeyName];

    // attempt to read from localStorage

    if(SC.browser.msie=="7.0"){
       localStorage=document.body;
       try{
         localStorage.load("SC.UserDefaults");
       }catch(e){
         console.err("Couldn't load userDefaults in IE7: "+e.description);
       }
    }else if(this.HTML5DB_noLocalStorage){
         storageSafari3 = this._safari3DB;
    }else{
       localStorage = window.localStorage ;
       if (!localStorage && window.globalStorage) {
         localStorage = window.globalStorage[window.location.hostname];
       }
    }
    if (localStorage || storageSafari3) {
      key=["SC.UserDefaults",userKeyName].join('-at-');
      if(SC.browser.msie=="7.0"){
        ret=localStorage.getAttribute(key.replace(/\W/gi, ''));
      }else if(storageSafari3){
        ret = this.dataHash[key];
      }else{
        ret = localStorage[key];
      }
      if (!SC.none(ret)) {
        try {
          ret = SC.json.decode(ret);
        }
        catch(ex) {
          ret = undefined;
        }
      } else ret = undefined;
    }

    // if not found in localStorage, try to notify delegate
    del =this.delegate ;
    if (del && del.userDefaultsNeedsDefault) {
      ret = del.userDefaultsNeedsDefault(this, keyName, userKeyName);
    }

    // if not found in localStorage or delegate, try to find in defaults
    if ((ret===undefined) && this._defaults) {
      ret = this._defaults[userKeyName] || this._defaults[keyName];
    }

    return ret ;
  },

  /**
    Attempts to write the user default to local storage or at least saves them
    for now.  Also notifies that the value has changed.

    @param {String} keyName
    @param {Object} value
    @returns {SC.UserDefault} receiver
  */
  writeDefault: function(keyName, value) {
    var userKeyName, written, localStorage, key, del, storageSafari3;

    keyName = this._normalizeKeyName(keyName);
    userKeyName = this._userKeyName(keyName);

    // save to local hash
    written = this._written ;
    if (!written) written = this._written = {};
    written[userKeyName] = value ;

    // save to local storage

    if(SC.browser.msie=="7.0"){
      localStorage=document.body;
    }else if(this.HTML5DB_noLocalStorage){
      storageSafari3 = this._safari3DB;
    }else{
       localStorage = window.localStorage ;
       if (!localStorage && window.globalStorage) {
         localStorage = window.globalStorage[window.location.hostname];
       }
    }
    key=["SC.UserDefaults",userKeyName].join('-at-');
    if (localStorage || storageSafari3) {
      var encodedValue = SC.json.encode(value);
      if(SC.browser.msie=="7.0"){
        localStorage.setAttribute(key.replace(/\W/gi, ''), encodedValue);
        localStorage.save("SC.UserDefaults");
      }else if(storageSafari3){
        var obj = this;
        storageSafari3.transaction(
          function (t) {
            t.executeSql("delete from SCLocalStorage where key = ?", [key],
              function (){
                t.executeSql("insert into SCLocalStorage(key, value)"+
                            " VALUES ('"+key+"', '"+encodedValue+"');",
                            [], obj._nullDataHandler, obj.killTransaction
                );
              }
            );
          }
        );
        this.dataHash[key] = encodedValue;
      }else{

        localStorage[key] = encodedValue;
      }
    }

    // also notify delegate
    del = this.delegate;
    if (del && del.userDefaultsDidChange) {
      del.userDefaultsDidChange(this, keyName, value, userKeyName);
    }

    return this ;
  },

  /**
    Removed the passed keyName from the written hash and local storage.

    @param {String} keyName
    @returns {SC.UserDefaults} receiver
  */
  resetDefault: function(keyName) {
    var fullKeyName, userKeyName, written, localStorage, key, storageSafari3;
    fullKeyName = this._normalizeKeyName(keyName);
    userKeyName = this._userKeyName(fullKeyName);

    this.propertyWillChange(keyName);
    this.propertyWillChange(fullKeyName);

    written = this._written;
    if (written) delete written[userKeyName];

    if(SC.browser.msie=="7.0"){
       localStorage=document.body;
    }else if(this.HTML5DB_noLocalStorage){
         storageSafari3 = this._safari3DB;
    }else{
       localStorage = window.localStorage ;
       if (!localStorage && window.globalStorage) {
         localStorage = window.globalStorage[window.location.hostname];
       }
    }

    key=["SC.UserDefaults",userKeyName].join('-at-');

    if (localStorage) {
      if(SC.browser.msie=="7.0"){
        localStorage.setAttribute(key.replace(/\W/gi, ''), null);
        localStorage.save("SC.UserDefaults");
      } else if(storageSafari3){
        var obj = this;
        storageSafari3.transaction(
          function (t) {
            t.executeSql("delete from SCLocalStorage where key = ?", [key], null);
          }
        );
        delete this.dataHash[key];
      }else{
        delete localStorage[key];
      }
    }

    this.propertyDidChange(keyName);
    this.propertyDidChange(fullKeyName);
    return this ;
  },

  /**
    Is called whenever you .get() or .set() values on this object

    @param {Object} key
    @param {Object} value
    @returns {Object}
  */
  unknownProperty: function(key, value) {
    if (value === undefined) {
      return this.readDefault(key) ;
    } else {
      this.writeDefault(key, value);
      return value ;
    }
  },

  /**
    Normalize the passed key name.  Used by all accessors to automatically
    insert an appName if needed.
  */
  _normalizeKeyName: function(keyName) {
    if (keyName.indexOf(':')<0) {
      var domain = this.get('appDomain') || 'app';
      keyName = [domain, keyName].join(':');
    }
    return keyName;
  },

  /**
    Builds a user key name from the passed key name
  */
  _userKeyName: function(keyName) {
    var user = this.get('userDomain') || '(anonymous)' ;
    return [user,keyName].join('-at-');
  },

  _domainDidChange: function() {
    var didChange = NO;
    if (this.get("userDomain") !== this._scud_userDomain) {
      this._scud_userDomain = this.get('userDomain');
      didChange = YES;
    }

    if (this.get('appDomain') !== this._scud_appDomain) {
      this._scud_appDomain = this.get('appDomain');
      didChange = YES;
    }

    if (didChange) this.allPropertiesDidChange();
  }.observes('userDomain', 'appDomain'),

  init: function() {
    sc_super();
    this._scud_userDomain = this.get('userDomain');
    this._scud_appDomain  = this.get('appDomain');
    if(SC.browser.msie=="7.0"){
      //Add user behavior userData. This works in all versions of IE.
      //Adding to the body as is the only element never removed.
      document.body.addBehavior('#default#userData');
    }
    this.HTML5DB_noLocalStorage = ((parseInt(SC.browser.safari, 0)>523) && (parseInt(SC.browser.safari, 0)<528));
    if(this.HTML5DB_noLocalStorage){
      var myDB;
      try {
        if (!window.openDatabase) {
          console.error("Trying to load a database with safari version 3.1 "+
                  "to get SC.UserDefaults to work. You are either in a"+
                  " previous version or there is a problem with your browser.");
          return;
        } else {
          var shortName = 'scdb',
              version = '1.0',
              displayName = 'SproutCore database',
              maxSize = 65536; // in bytes,
          myDB = openDatabase(shortName, version, displayName, maxSize);

          // You should have a database instance in myDB.

        }
      } catch(e) {
        console.error("Trying to load a database with safari version 3.1 "+
                "to get SC.UserDefaults to work. You are either in a"+
                " previous version or there is a problem with your browser.");
        return;
      }

      if(myDB){
        var obj = this;
        myDB.transaction(
          function (transaction) {
            transaction.executeSql('CREATE TABLE IF NOT EXISTS SCLocalStorage'+
              '(key TEXT NOT NULL PRIMARY KEY, value TEXT NOT NULL);',
              [], obj._nullDataHandler, obj.killTransaction);
          }
        );
        myDB.transaction(
          function (transaction) {
            transaction.parent = obj;
            transaction.executeSql('SELECT * from SCLocalStorage;',
                [], function(transaction, results){
                  var hash={}, row;
                  for(var i=0, iLen=results.rows.length; i<iLen; i++){
                    row=results.rows.item(i);
                    hash[row['key']]=row['value'];
                  }
                  transaction.parent.dataHash = hash;
                  SC.userDefaults.set('ready', YES);
                }, obj.killTransaction);
          }
        );
        this._safari3DB=myDB;
      }
    }else{
      this.set('ready', YES);
    }
  },

  //Private methods to use if user defaults uses the database in safari 3
  _killTransaction: function(transaction, error){
    return true; // fatal transaction error
  },

  _nullDataHandler: function(transaction, results){},

  readyCallback: function(ob, func){
    this.func = func;
    this.ob = ob;
  },

  readyChanged: function(){
    if(this.ready===YES){
      var f = this.func;
      if(f) f.apply(this.ob);
    }
  }.observes('ready')
});

/** global user defaults. */
SC.userDefaults = SC.UserDefaults.create();<|endoftext|>


<commit_before>const dbConnection = require('../common/connection');
const util = require('util');
const query = util.promisify(dbConnection.query).bind(dbConnection);

const axios = require('axios');

class EducatorEntity {

    static async getUserInfoByToken(token) {
        try {
            const user = await axios({
                method: "get",
                headers: { Authorization: `Bearer ${token}` },
                url: `https://www.googleapis.com/oauth2/v1/userinfo`
            })
            const userData = user.data;
            return userData;
        } catch (error) {
            console.log(error);
            //res.send('Invalid user').status(400);
        }
    }

    static async createPlaylist(body) {
        const sql = `INSERT INTO playlist (title,educatorId) VALUES ('${body.title}',${body.educatorId});`;
        console.log(sql);
        /* dbConnection.query(sql, function (err, result, fields) {
            return result;
        });*/
        const data = await query(sql);
        const lastRowId = await query(`SELECT * FROM playlist where playlistId=${data.insertId};`);
        console.log('last row id' + JSON.stringify(lastRowId));
        body.playlists.forEach(async (video) => {
            /*const insertQuery = `INSERT INTO video (videoId,playlistId,title,description,channelTitle,thumbnail,youtubeLink,duration) VALUES ('${video.videoId}',${lastRowId[0].playlistId},'${video.title}','${video.description}','${video.channelTitle}','${video.thumbnail}','${video.youtubeLink ? video.youtubeLink : null}','${video.duration}');`;
            dbConnection.query(insertQuery, function (err) {
                if (err) console.log('Insert video table:' + err)
            });*/

            var sql = "INSERT INTO video SET ?";
            // Connection attained as listed above.
            dbConnection.query(sql, {
                videoId: video.videoId, playlistId: (lastRowId[0].playlistId), title: video.title,
                description: video.description, channelTitle: video.channelTitle, thumbnail: video.thumbnail, youtubeLink: video.youtubeLink ? video.youtubeLink : null, duration: video.duration
            }, function (err) {
                // check result if err is undefined.
                if (err) {
                    console.log('Insert video error:', err);
                }
            });

        })

        return lastRowId;
    }

    static async getAllVideos(playlistId) {
        dbConnection.query(`SELECT * FROM video where playlistId=${playlistId};`, function (err, result) {
            return result;
        });
    }

    static async getAllPlaylist() {
        const data = await query('SELECT * FROM playlist;');
        const respArray = [];
        for (let i = 0; i < data.length; i++) {
            const response = {
                playlistId: data[i].playlistId,
                title: data[i].title,
                videos: Object.values(JSON.parse(JSON.stringify(await this.getPlaylist(data[i].playlistId)))),
                count: Object.values(JSON.parse(JSON.stringify(await this.getPlaylist(data[i].playlistId)))).length
            }
            respArray.push(response);
        }

        return respArray;
    }

    static async getPlaylist(playlistId) {
        const data = await query(`SELECT * FROM video where playlistId=${playlistId};`);
        return data;
    }

    static async createEducator(body) {
        const sql = `INSERT INTO educators (email,firstName,lastName) VALUES ('${body.email}','${body.firstName}','${body.lastName}');`;
        console.log(sql);
        try {
            const data = await query(sql);
            return data;
        } catch (err) {
            if (err.code === 'ER_DUP_ENTRY') {
                return await query(`SELECT * FROM educators where email='${body.email}';`);
            }
            return err;
        }

    }

    static async assignTask(token, body) {
        const tasks = Object.values(JSON.parse(JSON.stringify(await query(`SELECT * FROM tasks where playlistId =${body.playlistId} AND courseId =${body.courseId} ;`))));
        if (tasks.length > 0) {
            return {
                status: 400,
                msg: 'Task already assigned for the selected course'
            }
        }

        try {
            const video = Object.values(JSON.parse(JSON.stringify(await query(`SELECT * FROM video where playlistId=${body.playlistId} LIMIT 1;`))));
            const result = await axios({
                method: "POST",
                headers: { Authorization: `Bearer ${token}` },
                url: `https://classroom.googleapis.com/v1/courses/${body.courseId}/courseWork`,
                data: {
                    assigneeMode: "ALL_STUDENTS",
                    courseId: body.courseId,
                    title: body.taskName,
                    maxPoints: 100,
                    workType: "ASSIGNMENT",
                    state: "PUBLISHED",
                    materials: [
                        {
                            link: {
                                url: `${process.env.STD_PORTAL}?courseId=${body.courseId}&videoId=${video[0].videoId}`
                            }
                        }
                    ]
                }
            })

            console.log(result.data);
            body.classRoomTaskId = result.data.id;
        } catch (error) {
            console.log(error);
            return {
               status: error.response.status,
               msg: error.response.statusText
            }
            //res.send(error).status(400);
        }

        const sql = `INSERT INTO tasks(taskName,playlistId,courseId,studentId,classRoomTaskId) VALUES ('${body.taskName}',${body.playlistId},'${body.courseId}',${body.studentId ? body.studentId : null},'${body.classRoomTaskId}');`;
        console.log(sql);
        const data = await query(sql);

        const lastRowId = await query(`SELECT * FROM tasks where taskId=${data.insertId};`);
        body.taskId = lastRowId[0].taskId;
        const playlistId = body.playlistId;

        if (body.studentId && (body.courseId === null || body.courseId === undefined)) {
            body.status = 'NotStarted';
            await this.taskStatus(body);
        }
        if (body.courseId && (body.studentId === null || body.studentId === undefined)) {
            const students = await query(`SELECT * FROM students;`);
            dbConnection.query(
                'INSERT INTO tasks_status(taskId,studentId,status,courseId,classRoomTaskId) VALUES ?',
                [students.map(item => [body.taskId, item.studentId, 'NotStarted', body.courseId, body.classRoomTaskId])],
                (error) => {
                    console.log(error)
                }
            );

            const videos = Object.values(JSON.parse(JSON.stringify(await this.getPlaylist(playlistId))));
            for (let i = 0; i < videos.length; i++) {
                dbConnection.query(
                    'INSERT INTO student_analytics(videoId,studentId,videoStatus,videoProgress,playlistId,courseId,classRoomTaskId) VALUES ?',
                    [students.map(item => [videos[i].id, item.studentId, 'NotStarted', '00', playlistId, body.courseId, body.classRoomTaskId])],
                    (error) => {
                        console.log(error)
                    }
                );
            }
        }
        return {
            status: 201,
            msg: data
        };
    }

    static async taskStatus(body) {
        if (body.status === 'NotStarted' || body.status === 'Inprogress' || body.status === 'Completed') {
            const sql = `INSERT INTO tasks_status(taskId,studentId,status) VALUES (${body.taskId},${body.studentId},'${body.status}');`;
            console.log(sql);
            const data = await query(sql);
            return data;
        } else {
            return {
                status: 400,
                reason: "Invalid task status"
            }
        }

    }

    static async updateTaskStatus(taskId, studentId, status) {
        if (status === 'NotStarted' || status === 'Inprogress' || status === 'Completed') {
            const sql = `UPDATE tasks_status SET status = '${status}' WHERE taskId = ${taskId} AND studentId = ${studentId};`;
            console.log(sql);
            const data = await query(sql);
            console.log(data);
            return data;
        } else {
            return {
                status: 400,
                reason: "Invalid task status"
            }
        }

    }

    static async addVideosToPlaylist(playlistId, body) {
        body.playlists.forEach((video) => {
            const insertQuery = `INSERT INTO video (videoId,playlistId,title,description,channelTitle,thumbnail,youtubeLink,duration) VALUES ('${video.videoId}',${playlistId},'${video.title}','${video.description}','${video.channelTitle}','${video.thumbnail}','${video.youtubeLink ? video.youtubeLink : null}','${video.duration}');`;
            dbConnection.query(insertQuery, function (err) {
                if (err) console.log('Insert video table:' + err)
            });
        })
        return await this.getPlaylist(playlistId);
    }

    static async getEducatorByEmail(email) {
        const sql = `SELECT * FROM educators where email = '${email}'`;
        console.log('query:', sql);
        const data = await query(sql);
        return data;
    }

    static async pullCourseDataFromClassRoomApi(token) {
        let courses;
        let userData;
        try {
            const result = await axios({
                method: "get",
                headers: { Authorization: `Bearer ${token}` },
                url: 'https://classroom.googleapis.com/v1/courses?courseStates=ACTIVE'
            })
            courses = result.data.courses;
        } catch (error) {
            console.log(error);
            return error.response.status;
            //res.send(error).status(400);
        }

        try {
            const user = await axios({
                method: "get",
                headers: { Authorization: `Bearer ${token}` },
                url: `https://www.googleapis.com/oauth2/v1/userinfo`
            })
            userData = user.data;
        } catch (error) {
            console.log(error);
            //res.send('Invalid user').status(400);
        }

        await query(`DELETE FROM courses WHERE creator='${userData.email}';`);

        await query('INSERT INTO courses(courseId,name,descriptionHeading,ownerId,creator,courseState,creationTime) VALUES ?',
            [courses.map(item => [item.id, item.name, item.descriptionHeading, item.ownerId, userData.email, item.courseState, new Date(item.creationTime).toJSON().slice(0, 19).replace('T', ' ')])]);

        const result = await query(`SELECT * FROM courses WHERE creator='${userData.email}';`);
        return result;
    }

    static async invitation(token, body) {
        try {
            const result = await axios({
                method: "POST",
                headers: { Authorization: `Bearer ${token}` },
                url: `https://classroom.googleapis.com/v1/invitations`,
                data: {
                    userId: body.studentId,
                    courseId: body.courseId,
                    role: 'STUDENT'
                }
            })

            console.log(result.data);
            if (result.data) {
                await query(`INSERT INTO invitations(invitationId,userId,courseId,role) VALUES('${result.data.id}','${result.data.userId}','${result.data.courseId}','${result.data.role}');`);
                return result.data
            }
        } catch (error) {
            console.log(error);
            return error.response.status;
            //res.send(error).status(400);
        }
    }

    static async enrollStudentToCourse(token, body) {
        try {
            const result = await axios({
                method: "POST",
                headers: { Authorization: `Bearer ${token}` },
                url: `https://classroom.googleapis.com/v1/courses/${body.courseId}/students`,
                data: {
                    userId: body.studentId,
                    courseId: body.courseId,
                }
            })

            return result.data;
        } catch (error) {
            console.log(error);
            return error.response.status;
            //res.send(error).status(400);
        }
    }

    static async deletePlaylistId(playlistId, token) {
        try {
            const tasks = Object.values(JSON.parse(JSON.stringify(await query(`SELECT taskId,courseId,classRoomTaskId FROM tasks where playlistId=${playlistId};`))));
            if (tasks.length > 0) {
                const taskIds = [];
                tasks.forEach((obj) => {
                    taskIds.push(obj.taskId);
                });
                const taskIdString = taskIds.join();
                const delTask_status = `DELETE FROM tasks_status WHERE taskId IN(${taskIdString});`;
                await query(delTask_status);
                await query(`DELETE FROM student_analytics WHERE playlistId=${playlistId};`);
                await query(`DELETE FROM video WHERE playlistId = ${playlistId};`);
                await query(`DELETE FROM tasks WHERE playlistId=${playlistId};`);
                await query(`DELETE FROM playlist WHERE playlistId=${playlistId};`);

                if (token) {
                    console.log('token present');
                    tasks.forEach(async (task) => {
                        try {
                            await axios({
                                method: "DELETE",
                                headers: { Authorization: `Bearer ${token}` },
                                url: `https://classroom.googleapis.com/v1/courses/${task.courseId}/courseWork/${task.classRoomTaskId}`
                            })
                        } catch (error) {
                            console.log(error.response)
                        }

                    })
                }
                return {
                    msg: 'Playlist deleted successfully',
                    status: 200
                };
            } else {
                const playlist = Object.values(JSON.parse(JSON.stringify(await query(`SELECT * FROM playlist where playlistId=${playlistId};`))));
                if (playlist.length > 0) {
                    await query(`DELETE FROM video WHERE playlistId = ${playlistId};`);
                    await query(`DELETE FROM playlist WHERE playlistId=${playlistId};`);
                    return {
                        msg: 'Playlist deleted successfully',
                        status: 200
                    };
                }
                return {
                    msg: 'Invalid playlist id',
                    status: 400
                }
            }
        } catch (error) {
            console.log(error);
            return {
                msg: error,
                status: 500
            }
        }
    }

}
module.exports = EducatorEntity;<commit_msg>Updated error msg<commit_after>const dbConnection = require('../common/connection');
const util = require('util');
const query = util.promisify(dbConnection.query).bind(dbConnection);

const axios = require('axios');

class EducatorEntity {

    static async getUserInfoByToken(token) {
        try {
            const user = await axios({
                method: "get",
                headers: { Authorization: `Bearer ${token}` },
                url: `https://www.googleapis.com/oauth2/v1/userinfo`
            })
            const userData = user.data;
            return userData;
        } catch (error) {
            console.log(error);
            //res.send('Invalid user').status(400);
        }
    }

    static async createPlaylist(body) {
        const sql = `INSERT INTO playlist (title,educatorId) VALUES ('${body.title}',${body.educatorId});`;
        console.log(sql);
        /* dbConnection.query(sql, function (err, result, fields) {
            return result;
        });*/
        const data = await query(sql);
        const lastRowId = await query(`SELECT * FROM playlist where playlistId=${data.insertId};`);
        console.log('last row id' + JSON.stringify(lastRowId));
        body.playlists.forEach(async (video) => {
            /*const insertQuery = `INSERT INTO video (videoId,playlistId,title,description,channelTitle,thumbnail,youtubeLink,duration) VALUES ('${video.videoId}',${lastRowId[0].playlistId},'${video.title}','${video.description}','${video.channelTitle}','${video.thumbnail}','${video.youtubeLink ? video.youtubeLink : null}','${video.duration}');`;
            dbConnection.query(insertQuery, function (err) {
                if (err) console.log('Insert video table:' + err)
            });*/

            var sql = "INSERT INTO video SET ?";
            // Connection attained as listed above.
            dbConnection.query(sql, {
                videoId: video.videoId, playlistId: (lastRowId[0].playlistId), title: video.title,
                description: video.description, channelTitle: video.channelTitle, thumbnail: video.thumbnail, youtubeLink: video.youtubeLink ? video.youtubeLink : null, duration: video.duration
            }, function (err) {
                // check result if err is undefined.
                if (err) {
                    console.log('Insert video error:', err);
                }
            });

        })

        return lastRowId;
    }

    static async getAllVideos(playlistId) {
        dbConnection.query(`SELECT * FROM video where playlistId=${playlistId};`, function (err, result) {
            return result;
        });
    }

    static async getAllPlaylist() {
        const data = await query('SELECT * FROM playlist;');
        const respArray = [];
        for (let i = 0; i < data.length; i++) {
            const response = {
                playlistId: data[i].playlistId,
                title: data[i].title,
                videos: Object.values(JSON.parse(JSON.stringify(await this.getPlaylist(data[i].playlistId)))),
                count: Object.values(JSON.parse(JSON.stringify(await this.getPlaylist(data[i].playlistId)))).length
            }
            respArray.push(response);
        }

        return respArray;
    }

    static async getPlaylist(playlistId) {
        const data = await query(`SELECT * FROM video where playlistId=${playlistId};`);
        return data;
    }

    static async createEducator(body) {
        const sql = `INSERT INTO educators (email,firstName,lastName) VALUES ('${body.email}','${body.firstName}','${body.lastName}');`;
        console.log(sql);
        try {
            const data = await query(sql);
            return data;
        } catch (err) {
            if (err.code === 'ER_DUP_ENTRY') {
                return await query(`SELECT * FROM educators where email='${body.email}';`);
            }
            return err;
        }

    }

    static async assignTask(token, body) {
        const tasks = Object.values(JSON.parse(JSON.stringify(await query(`SELECT * FROM tasks where playlistId =${body.playlistId} AND courseId =${body.courseId} ;`))));
        if (tasks.length > 0) {
            return {
                status: 400,
                msg: 'Selected playlist already assigned to the selected course'
            }
        }

        try {
            const video = Object.values(JSON.parse(JSON.stringify(await query(`SELECT * FROM video where playlistId=${body.playlistId} LIMIT 1;`))));
            const result = await axios({
                method: "POST",
                headers: { Authorization: `Bearer ${token}` },
                url: `https://classroom.googleapis.com/v1/courses/${body.courseId}/courseWork`,
                data: {
                    assigneeMode: "ALL_STUDENTS",
                    courseId: body.courseId,
                    title: body.taskName,
                    maxPoints: 100,
                    workType: "ASSIGNMENT",
                    state: "PUBLISHED",
                    materials: [
                        {
                            link: {
                                url: `${process.env.STD_PORTAL}?courseId=${body.courseId}&videoId=${video[0].videoId}`
                            }
                        }
                    ]
                }
            })

            console.log(result.data);
            body.classRoomTaskId = result.data.id;
        } catch (error) {
            console.log(error);
            return {
               status: error.response.status,
               msg: error.response.statusText
            }
            //res.send(error).status(400);
        }

        const sql = `INSERT INTO tasks(taskName,playlistId,courseId,studentId,classRoomTaskId) VALUES ('${body.taskName}',${body.playlistId},'${body.courseId}',${body.studentId ? body.studentId : null},'${body.classRoomTaskId}');`;
        console.log(sql);
        const data = await query(sql);

        const lastRowId = await query(`SELECT * FROM tasks where taskId=${data.insertId};`);
        body.taskId = lastRowId[0].taskId;
        const playlistId = body.playlistId;

        if (body.studentId && (body.courseId === null || body.courseId === undefined)) {
            body.status = 'NotStarted';
            await this.taskStatus(body);
        }
        if (body.courseId && (body.studentId === null || body.studentId === undefined)) {
            const students = await query(`SELECT * FROM students;`);
            dbConnection.query(
                'INSERT INTO tasks_status(taskId,studentId,status,courseId,classRoomTaskId) VALUES ?',
                [students.map(item => [body.taskId, item.studentId, 'NotStarted', body.courseId, body.classRoomTaskId])],
                (error) => {
                    console.log(error)
                }
            );

            const videos = Object.values(JSON.parse(JSON.stringify(await this.getPlaylist(playlistId))));
            for (let i = 0; i < videos.length; i++) {
                dbConnection.query(
                    'INSERT INTO student_analytics(videoId,studentId,videoStatus,videoProgress,playlistId,courseId,classRoomTaskId) VALUES ?',
                    [students.map(item => [videos[i].id, item.studentId, 'NotStarted', '00', playlistId, body.courseId, body.classRoomTaskId])],
                    (error) => {
                        console.log(error)
                    }
                );
            }
        }
        return {
            status: 201,
            msg: data
        };
    }

    static async taskStatus(body) {
        if (body.status === 'NotStarted' || body.status === 'Inprogress' || body.status === 'Completed') {
            const sql = `INSERT INTO tasks_status(taskId,studentId,status) VALUES (${body.taskId},${body.studentId},'${body.status}');`;
            console.log(sql);
            const data = await query(sql);
            return data;
        } else {
            return {
                status: 400,
                reason: "Invalid task status"
            }
        }

    }

    static async updateTaskStatus(taskId, studentId, status) {
        if (status === 'NotStarted' || status === 'Inprogress' || status === 'Completed') {
            const sql = `UPDATE tasks_status SET status = '${status}' WHERE taskId = ${taskId} AND studentId = ${studentId};`;
            console.log(sql);
            const data = await query(sql);
            console.log(data);
            return data;
        } else {
            return {
                status: 400,
                reason: "Invalid task status"
            }
        }

    }

    static async addVideosToPlaylist(playlistId, body) {
        body.playlists.forEach((video) => {
            const insertQuery = `INSERT INTO video (videoId,playlistId,title,description,channelTitle,thumbnail,youtubeLink,duration) VALUES ('${video.videoId}',${playlistId},'${video.title}','${video.description}','${video.channelTitle}','${video.thumbnail}','${video.youtubeLink ? video.youtubeLink : null}','${video.duration}');`;
            dbConnection.query(insertQuery, function (err) {
                if (err) console.log('Insert video table:' + err)
            });
        })
        return await this.getPlaylist(playlistId);
    }

    static async getEducatorByEmail(email) {
        const sql = `SELECT * FROM educators where email = '${email}'`;
        console.log('query:', sql);
        const data = await query(sql);
        return data;
    }

    static async pullCourseDataFromClassRoomApi(token) {
        let courses;
        let userData;
        try {
            const result = await axios({
                method: "get",
                headers: { Authorization: `Bearer ${token}` },
                url: 'https://classroom.googleapis.com/v1/courses?courseStates=ACTIVE'
            })
            courses = result.data.courses;
        } catch (error) {
            console.log(error);
            return error.response.status;
            //res.send(error).status(400);
        }

        try {
            const user = await axios({
                method: "get",
                headers: { Authorization: `Bearer ${token}` },
                url: `https://www.googleapis.com/oauth2/v1/userinfo`
            })
            userData = user.data;
        } catch (error) {
            console.log(error);
            //res.send('Invalid user').status(400);
        }

        await query(`DELETE FROM courses WHERE creator='${userData.email}';`);

        await query('INSERT INTO courses(courseId,name,descriptionHeading,ownerId,creator,courseState,creationTime) VALUES ?',
            [courses.map(item => [item.id, item.name, item.descriptionHeading, item.ownerId, userData.email, item.courseState, new Date(item.creationTime).toJSON().slice(0, 19).replace('T', ' ')])]);

        const result = await query(`SELECT * FROM courses WHERE creator='${userData.email}';`);
        return result;
    }

    static async invitation(token, body) {
        try {
            const result = await axios({
                method: "POST",
                headers: { Authorization: `Bearer ${token}` },
                url: `https://classroom.googleapis.com/v1/invitations`,
                data: {
                    userId: body.studentId,
                    courseId: body.courseId,
                    role: 'STUDENT'
                }
            })

            console.log(result.data);
            if (result.data) {
                await query(`INSERT INTO invitations(invitationId,userId,courseId,role) VALUES('${result.data.id}','${result.data.userId}','${result.data.courseId}','${result.data.role}');`);
                return result.data
            }
        } catch (error) {
            console.log(error);
            return error.response.status;
            //res.send(error).status(400);
        }
    }

    static async enrollStudentToCourse(token, body) {
        try {
            const result = await axios({
                method: "POST",
                headers: { Authorization: `Bearer ${token}` },
                url: `https://classroom.googleapis.com/v1/courses/${body.courseId}/students`,
                data: {
                    userId: body.studentId,
                    courseId: body.courseId,
                }
            })

            return result.data;
        } catch (error) {
            console.log(error);
            return error.response.status;
            //res.send(error).status(400);
        }
    }

    static async deletePlaylistId(playlistId, token) {
        try {
            const tasks = Object.values(JSON.parse(JSON.stringify(await query(`SELECT taskId,courseId,classRoomTaskId FROM tasks where playlistId=${playlistId};`))));
            if (tasks.length > 0) {
                const taskIds = [];
                tasks.forEach((obj) => {
                    taskIds.push(obj.taskId);
                });
                const taskIdString = taskIds.join();
                const delTask_status = `DELETE FROM tasks_status WHERE taskId IN(${taskIdString});`;
                await query(delTask_status);
                await query(`DELETE FROM student_analytics WHERE playlistId=${playlistId};`);
                await query(`DELETE FROM video WHERE playlistId = ${playlistId};`);
                await query(`DELETE FROM tasks WHERE playlistId=${playlistId};`);
                await query(`DELETE FROM playlist WHERE playlistId=${playlistId};`);

                if (token) {
                    console.log('token present');
                    tasks.forEach(async (task) => {
                        try {
                            await axios({
                                method: "DELETE",
                                headers: { Authorization: `Bearer ${token}` },
                                url: `https://classroom.googleapis.com/v1/courses/${task.courseId}/courseWork/${task.classRoomTaskId}`
                            })
                        } catch (error) {
                            console.log(error.response)
                        }

                    })
                }
                return {
                    msg: 'Playlist deleted successfully',
                    status: 200
                };
            } else {
                const playlist = Object.values(JSON.parse(JSON.stringify(await query(`SELECT * FROM playlist where playlistId=${playlistId};`))));
                if (playlist.length > 0) {
                    await query(`DELETE FROM video WHERE playlistId = ${playlistId};`);
                    await query(`DELETE FROM playlist WHERE playlistId=${playlistId};`);
                    return {
                        msg: 'Playlist deleted successfully',
                        status: 200
                    };
                }
                return {
                    msg: 'Invalid playlist id',
                    status: 400
                }
            }
        } catch (error) {
            console.log(error);
            return {
                msg: error,
                status: 500
            }
        }
    }

}
module.exports = EducatorEntity;<|endoftext|>