UNPKG

novel-opds-now

Version:

按需生成 epub,此模組不使用排程任務來生成 epub

344 lines 14.7 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.setIPFSToCache = exports.getIPFSFromCache = exports.useIPFSFromCache = exports.getIPFS = exports._info = exports._useIPFS = exports.searchIpfs = exports.useIPFS = void 0; const tslib_1 = require("tslib"); require("../util/processHandle"); const processExit_1 = (0, tslib_1.__importDefault)(require("../util/processExit")); const ipfs_util_lib_1 = require("ipfs-util-lib"); const cloneDeep_1 = (0, tslib_1.__importDefault)(require("lodash/cloneDeep")); const bluebird_1 = (0, tslib_1.__importStar)(require("bluebird")); const logger_1 = (0, tslib_1.__importDefault)(require("debug-color2/logger")); const package_json_1 = (0, tslib_1.__importDefault)(require("../../package.json")); const computer_info_1 = (0, tslib_1.__importDefault)(require("computer-info")); const terminal_link_1 = (0, tslib_1.__importDefault)(require("terminal-link")); const ipfs_http_client_1 = require("@bluelovers/ipfs-http-client"); const util_1 = require("@bluelovers/ipfs-http-client/util"); const cors_1 = (0, tslib_1.__importDefault)(require("ipfs-util-lib/lib/ipfs/config/cors")); const multiaddr_to_url_1 = require("multiaddr-to-url"); const unlinkIPFSApi_1 = require("fix-ipfs/lib/ipfsd-ctl/unlinkIPFSApi"); const fs_extra_1 = require("fs-extra"); const rimraf_1 = require("rimraf"); const path_1 = require("path"); const port_1 = require("./use/port"); const peer_1 = require("./peer"); const util_2 = require("util"); const index_1 = require("./pubsub/index"); const repoExists_1 = require("./repoExists"); const back_up_identity_1 = require("./util/back-up-identity"); const daemonFactory_1 = require("./util/daemonFactory"); const envDisposable_1 = require("./util/envDisposable"); const initHello_1 = require("./use/initHello"); const initHelloCheck_1 = require("./use/initHelloCheck"); const saveMutableFileSystemRoots_1 = require("./mfs/saveMutableFileSystemRoots"); const deepEntryListMap_1 = require("./mfs/deepEntryListMap"); const repo_config_1 = require("@lazy-ipfs/repo-config"); (_a = util_2.inspect.defaultOptions) !== null && _a !== void 0 ? _a : (util_2.inspect.defaultOptions = {}); util_2.inspect.defaultOptions.colors = logger_1.default.enabledColor; let _cache; let _waiting; let _timeout; let _failed_count = 0; function useIPFS(options) { return bluebird_1.default.resolve().then(() => { var _a, _b; if ((_b = (_a = _waiting === null || _waiting === void 0 ? void 0 : _waiting.isPending) === null || _a === void 0 ? void 0 : _a.call(_waiting)) !== null && _b !== void 0 ? _b : _waiting) { logger_1.default.info(`[IPFS]`, `IPFS 仍在啟動中,請稍後...`); } return _waiting; }).then(async () => { var _a; if (typeof _waiting !== 'undefined') { _waiting = void 0; } if (_cache) { if (((_a = _cache.ipfsd) === null || _a === void 0 ? void 0 : _a.started) !== false && await (0, ipfs_util_lib_1.checkIPFS)(_cache.ipfs).catch(e => null)) { return _cache; } await _cache.stopAsync().catch(e => null); _cache = void 0; logger_1.default.warn(`[IPFS]`, `IPFS 伺服器已斷線`); } if (_timeout || _failed_count > 5) { logger_1.default.error(`[IPFS]`, `IPFS 無法啟動,請手動重新啟動伺服器`); return Promise.reject(null); } _waiting = _useIPFS(options) .tap(v => _cache = v) .tap(_handle) .tap(async ({ ipfsd, ipfs, path, }) => { let info = await (0, ipfs_util_lib_1.ipfsAddresses)(ipfs).catch(e => null); logger_1.default.info(`[IPFS]`, `IPFS 已啟動`, info, path); return (0, cors_1.default)(ipfs).catch(e => null); }); return _waiting .tap(async ({ ipfs, ipfsd, }) => { return (0, index_1.pubsubSubscribe)(ipfs) .tap(async () => { (0, deepEntryListMap_1.loadDeepEntryListMapFromMixin)(); (0, initHello_1.initHello)(ipfs); (0, initHelloCheck_1.initHelloCheck)(ipfs, ipfsd); }) .catch(e => { logger_1.default.error(`[IPFS]`, `連接 pubsub 時發生錯誤`); logger_1.default.error(e); }); }); }) .catch(e => { if (e !== null || !_timeout) { logger_1.default.error(`[IPFS]`, `啟動 IPFS 時發生錯誤,可能無法正常連接至 IPFS 網路`); logger_1.default.error(e); _failed_count++; } return null; }); } exports.useIPFS = useIPFS; function _handle(cache) { return bluebird_1.default.resolve(cache).then((_cache) => { return bluebird_1.default.props({ ipfs: _cache.ipfs, id: _cache.ipfs.id(), version: _cache.ipfs.version(), }); }) .then(async (data) => { const { ipfs } = data; const { id, agentVersion, protocolVersion } = data.id; _info({ ipfs: { id, agentVersion, protocolVersion, version: data.version.version, }, }); let info = await (0, ipfs_util_lib_1.ipfsAddresses)(ipfs) .then(info => { let u = (0, multiaddr_to_url_1.multiaddrToURL)(info.API); u.pathname = 'webui'; return u; }) .catch(e => null); logger_1.default.success(`IPFS Web UI available at`, (0, terminal_link_1.default)(`webui`, `https://dev.webui.ipfs.io/`), info ? (0, terminal_link_1.default)(`webui`, info) : ''); }); } function searchIpfs() { return bluebird_1.default.resolve().then(async () => { logger_1.default.info(`[IPFS]`, `搜尋可用的 IPFS 伺服器...`, `可使用 IPFS_ADDRESSES_API 來指定特定伺服器`); let ipfsServerList = (0, util_1.getDefaultServerList)(); let ipfs = await (0, ipfs_http_client_1.findIpfsClient)(ipfsServerList); if (!await (0, ipfs_util_lib_1.checkIPFS)(ipfs).catch(e => null)) { return Promise.reject(new Error); } return { ipfsd: undefined, ipfs, async stop(...argv) { return (0, ipfs_util_lib_1.ipfsAddresses)(ipfs) .then(addr => { logger_1.default.warn(`[IPFS]`, `IPFS 伺服器可能仍在執行中,請自行停止伺服器`, addr); }) .catch(e => null); }, }; }); } exports.searchIpfs = searchIpfs; function _useIPFS(options) { logger_1.default.info(`[IPFS]`, `嘗試啟動或連接至 IPFS ...`); const disposable = (0, envDisposable_1.envDisposable)(options === null || options === void 0 ? void 0 : options.disposable); let _temp; return bluebird_1.default .resolve(disposable ? Promise.reject() : searchIpfs()) .catch(async () => { var _a, _b; var _c; logger_1.default.info(`[IPFS]`, `嘗試啟動 IPFS 伺服器...`, `可使用 IPFS_GO_EXEC 指定執行檔路徑`, `IPFS_PATH 指定 repo 路徑`); const { ipfsd } = await (0, daemonFactory_1.daemonFactory)(disposable, options); if (disposable) { let Addresses = await (0, port_1.findFreeAddresses)(ipfsd.opts); (_a = (_c = ipfsd.opts.ipfsOptions).config) !== null && _a !== void 0 ? _a : (_c.config = {}); ipfsd.opts.ipfsOptions.config.Addresses = { ...ipfsd.opts.ipfsOptions.config.Addresses, ...Addresses, }; logger_1.default.dir(ipfsd.env, { depth: null, }); logger_1.default.dir(ipfsd.opts.ipfsOptions, { depth: null, }); } await (0, fs_extra_1.ensureDir)(ipfsd.path); if (/[\/\\](?:\.?te?mp)[\/\\]+.+/i.test(ipfsd.path)) { ipfsd.disposable = disposable; } logger_1.default.debug(`[IPFS]`, `ipfsd`, _temp = { repo: ipfsd.path, ipfsBin: ipfsd.opts.ipfsBin, disposable: ipfsd.disposable, }); if (!ipfsd.started) { let oldExists = await (0, repoExists_1.repoExists)(ipfsd.path); logger_1.default.debug(`[IPFS]`, `ipfsd`, `init`); await ipfsd.init((_b = ipfsd.opts.ipfsOptions) === null || _b === void 0 ? void 0 : _b.init); if (!disposable && await (0, repoExists_1.repoExists)(ipfsd.path)) { let bool = await (0, fs_extra_1.pathExists)(back_up_identity_1.FILE_IDENTITY); if (!oldExists && bool) { ipfsd.isNewRepo = true; await (0, back_up_identity_1.restoreIdentity)(ipfsd); await (0, fs_extra_1.readJSON)((0, path_1.join)(ipfsd.path, 'config')) .then(config => { config["API"] = { "HTTPHeaders": { "Access-Control-Allow-Credentials": [ "true" ], "Access-Control-Allow-Headers": [ "Authorization" ], "Access-Control-Allow-Methods": [ "HEAD", "PUT", "GET", "POST", "OPTIONS" ], "Access-Control-Allow-Origin": [ "*", "http://webui.ipfs.io.ipns.localhost:8080", "http://webui.ipfs.io.ipns.localhost:9090", "http://localhost:3000", "http://127.0.0.1:5001", "http://127.0.0.1:5002", "https://webui.ipfs.io", "https://dev.webui.ipfs.io" ], "Access-Control-Expose-Headers": [ "Location" ] } }; return (0, repo_config_1.writeRepoConfig)(ipfsd.path, config); }); } else if (!bool) { await (0, back_up_identity_1.backupIdentity)(ipfsd); } } } if (!ipfsd.started) { logger_1.default.debug(`[IPFS]`, `ipfsd`, `start`); await ipfsd.start() .catch(async (e) => { e && logger_1.default.warn(`[IPFS]`, `ipfsd`, `start`, String(e)); logger_1.default.debug(`[IPFS]`, `ipfsd`, `start`, `retry`); await (0, unlinkIPFSApi_1.unlinkIPFSApiAsync)(ipfsd.path).catch(e => null); return ipfsd.start(); }); } const ipfs = ipfsd.api; const stop = async (...argv) => { logger_1.default.debug(`[IPFS]`, `ipfsd`, `stop`); if (!ipfsd.disposable) { await (0, saveMutableFileSystemRoots_1.saveMutableFileSystemRoots)(ipfs).catch(e => null); } let ls = [ipfsd.stop(...argv)]; if (ipfsd.disposable && /[\/\\](?:\.?te?mp)[\/\\]+.+/i.test(ipfsd.path)) { logger_1.default.debug(`[IPFS]`, `ipfsd`, `cleanup`); ls.push((0, rimraf_1.sync)(ipfsd.path)); ls.push(ipfsd.cleanup()); } return Promise.all(ls); }; await (0, ipfs_util_lib_1.assertCheckIPFS)(ipfs).tapCatch(stop); return { ipfsd, ipfs, stop, }; }) .timeout(60 * 1000) .tapCatch(bluebird_1.TimeoutError, e => { _timeout = true; logger_1.default.error(`[IPFS]`, `啟動時間過長,請檢查或刪除 IPFS repo 路徑後重新執行`, _temp); _temp = void 0; }) .then(async ({ ipfsd, ipfs, stop: _stop, }) => { const path = ipfsd === null || ipfsd === void 0 ? void 0 : ipfsd.path; const stop = (done) => { logger_1.default.info(`[IPFS]`, `useIPFS:stop`); peer_1.peerAbortController.abort(); return Promise.all([ _stop === null || _stop === void 0 ? void 0 : _stop({ timeout: 2000, }), (0, index_1.pubsubUnSubscribe)(ipfs), ]).then(done !== null && done !== void 0 ? done : (() => null)); }; const ret = { ipfsd, path, get ipfs() { return ipfs; }, async address() { let addr = await (0, ipfs_util_lib_1.ipfsAddresses)(ipfs); return (0, cloneDeep_1.default)(addr); }, stop, stopAsync() { return new bluebird_1.default((resolve, reject) => { try { _cache.stop(resolve); } catch (e) { reject(e); } }); }, }; (0, processExit_1.default)(ret.stop); return ret; }); } exports._useIPFS = _useIPFS; function _info(data) { if (_info.disable) { return; } let { osystem, ram, cpu, arch, node, } = (0, computer_info_1.default)(); logger_1.default.info({ ...data, osystem, ram, cpu, arch, node, [package_json_1.default.name]: package_json_1.default.version, }); _info.disable = true; } exports._info = _info; function getIPFS() { return useIPFS().then(m => m.ipfs).catch(e => null); } exports.getIPFS = getIPFS; function useIPFSFromCache() { return bluebird_1.default.resolve(_cache); } exports.useIPFSFromCache = useIPFSFromCache; function getIPFSFromCache() { return useIPFSFromCache().then(m => m.ipfs).catch(e => null); } exports.getIPFSFromCache = getIPFSFromCache; function setIPFSToCache(ipfs) { _cache !== null && _cache !== void 0 ? _cache : (_cache = {}); _cache.ipfs = ipfs; } exports.setIPFSToCache = setIPFSToCache; //# sourceMappingURL=use.js.map