Skip to content

Commit

Permalink
✨ Feature: add upload image from URL support
Browse files Browse the repository at this point in the history
  • Loading branch information
Molunerfinn committed Feb 23, 2020
1 parent 7975f73 commit 0d87342
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 16 deletions.
Binary file added logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 5 additions & 2 deletions src/plugins/commander/upload.ts
Original file line number Diff line number Diff line change
@@ -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 => {
Expand All @@ -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.`)
}
Expand Down
55 changes: 42 additions & 13 deletions src/plugins/transformer/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<PicGo> => {
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<IPathTransformedImgInfo> => {
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
}
1 change: 1 addition & 0 deletions src/utils/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const isUrl = (url: string): boolean => (url.startsWith('http://') || url.startsWith('https://'))
60 changes: 60 additions & 0 deletions src/utils/getURLFile.ts
Original file line number Diff line number Diff line change
@@ -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<IPathTransformedImgInfo> => {
const requestOptions = {
method: 'GET',
url,
encoding: null
}
let isImage = false
let extname = ''
let timeoutId
// tslint:disable-next-line: typedef
const requestPromise = new Promise<IPathTransformedImgInfo>(async (resolve): Promise<void> => {
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<IPathTransformedImgInfo>((resolve): void => {
timeoutId = setTimeout(() => {
resolve({
success: false,
reason: `request ${url} timeout`
})
}, 10000)
})
return Promise.race([requestPromise, timeoutPromise])
}
7 changes: 6 additions & 1 deletion src/utils/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ interface ImgInfo {
[propName: string]: any
}

interface IPathTransformedImgInfo extends ImgInfo {
success: boolean
}

/**
* for config options
*/
Expand Down Expand Up @@ -105,5 +109,6 @@ export {
ImgSize,
Options,
ClipboardImage,
ProcessEnv
ProcessEnv,
IPathTransformedImgInfo
}

0 comments on commit 0d87342

Please sign in to comment.