diff --git a/logo.png b/logo.png new file mode 100644 index 0000000..5c5eefb Binary files /dev/null and b/logo.png differ diff --git a/src/plugins/commander/upload.ts b/src/plugins/commander/upload.ts index 846f65f..7d41b10 100644 --- a/src/plugins/commander/upload.ts +++ b/src/plugins/commander/upload.ts @@ -1,6 +1,7 @@ import PicGo from '../../core/PicGo' import path from 'path' import fs from 'fs-extra' +import { isUrl } from '../../utils/common' export default { handle: (ctx: PicGo): void => { @@ -12,9 +13,11 @@ export default { .alias('u') .action(async (input: string[]) => { const inputList = input - .map((item: string) => path.resolve(item)) + .map((item: string) => { + return isUrl(item) ? item : path.resolve(item) + }) .filter((item: string) => { - const exist = fs.existsSync(item) + const exist = fs.existsSync(item) || isUrl(item) if (!exist) { ctx.log.warn(`${item} does not exist.`) } diff --git a/src/plugins/transformer/path.ts b/src/plugins/transformer/path.ts index 27def9f..df47860 100644 --- a/src/plugins/transformer/path.ts +++ b/src/plugins/transformer/path.ts @@ -2,26 +2,55 @@ import probe from 'probe-image-size' import path from 'path' import fs from 'fs-extra' import PicGo from '../../core/PicGo' +import { getURLFile } from '../../utils/getURLFile' +import { isUrl } from '../../utils/common' +import { IPathTransformedImgInfo, ImgInfo } from '../../utils/interfaces' const handle = async (ctx: PicGo): Promise => { - let results = ctx.output + let results: ImgInfo[] = ctx.output await Promise.all(ctx.input.map(async (item: string) => { - let fileName = path.basename(item) - let buffer = await fs.readFile(item) - // let base64Image = Buffer.from(buffer).toString('base64') - let imgSize = probe.sync(buffer) - results.push({ - buffer, - // base64Image, - fileName, - width: imgSize.width, - height: imgSize.height, - extname: path.extname(item) - }) + let info: IPathTransformedImgInfo + if (isUrl(item)) { + info = await getURLFile(ctx, item) + } else { + info = await getFSFile(item) + } + if (info.success) { + try { + const imgSize = probe.sync(info.buffer) + results.push({ + buffer: info.buffer, + fileName: info.fileName, + width: imgSize.width, + height: imgSize.height, + extname: path.extname(item) + }) + } catch (e) { + ctx.log.error(e) + } + } else { + ctx.log.error(info.reason) + } })) return ctx } +const getFSFile = async (item: string): Promise => { + try { + return { + extname: path.extname(item), + fileName: path.basename(item), + buffer: await fs.readFile(item), + success: true + } + } catch { + return { + reason: `read file ${item} error`, + success: false + } + } +} + export default { handle } diff --git a/src/utils/common.ts b/src/utils/common.ts new file mode 100644 index 0000000..36762c4 --- /dev/null +++ b/src/utils/common.ts @@ -0,0 +1 @@ +export const isUrl = (url: string): boolean => (url.startsWith('http://') || url.startsWith('https://')) diff --git a/src/utils/getURLFile.ts b/src/utils/getURLFile.ts new file mode 100644 index 0000000..3e3fcfd --- /dev/null +++ b/src/utils/getURLFile.ts @@ -0,0 +1,60 @@ +import PicGo from '../core/PicGo' +import request from 'request' +import path from 'path' +import { IPathTransformedImgInfo } from './interfaces' +import fs from 'fs' + +export const getURLFile = async (ctx: PicGo, url: string): Promise => { + const requestOptions = { + method: 'GET', + url, + encoding: null + } + let isImage = false + let extname = '' + let timeoutId + // tslint:disable-next-line: typedef + const requestPromise = new Promise(async (resolve): Promise => { + try { + const res = await ctx.Request.request(requestOptions) + .on('response', (response: request.Response): void => { + const contentType = response.headers['content-type'] + if (contentType.includes('image')) { + isImage = true + extname = `.${contentType.split('image/')[1]}` + } + }) + clearTimeout(timeoutId) + if (isImage) { + fs.writeFileSync('./logo.png', res) + resolve({ + buffer: res, + fileName: path.basename(requestOptions.url.split('?')[0]), + extname, + success: true + }) + } else { + resolve({ + success: false, + reason: `${url} is not image` + }) + } + } catch { + clearTimeout(timeoutId) + resolve({ + success: false, + reason: `request ${url} error` + }) + } + }) + // tslint:disable-next-line: typedef + const timeoutPromise = new Promise((resolve): void => { + timeoutId = setTimeout(() => { + resolve({ + success: false, + reason: `request ${url} timeout` + }) + }, 10000) + }) + return Promise.race([requestPromise, timeoutPromise]) +} diff --git a/src/utils/interfaces.ts b/src/utils/interfaces.ts index db4a5fa..964883c 100644 --- a/src/utils/interfaces.ts +++ b/src/utils/interfaces.ts @@ -36,6 +36,10 @@ interface ImgInfo { [propName: string]: any } +interface IPathTransformedImgInfo extends ImgInfo { + success: boolean +} + /** * for config options */ @@ -105,5 +109,6 @@ export { ImgSize, Options, ClipboardImage, - ProcessEnv + ProcessEnv, + IPathTransformedImgInfo }