diff --git a/package.json b/package.json index 483fb31..c5df856 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "element-ui": "^2.0.5", "fs-extra": "^4.0.2", "image-size": "^0.6.1", + "lodash-id": "^0.14.0", "lowdb": "^1.0.0", "qiniu": "^7.1.1", "request": "^2.83.0", diff --git a/src/datastore/index.js b/src/datastore/index.js index 96c1124..3104e6e 100644 --- a/src/datastore/index.js +++ b/src/datastore/index.js @@ -1,4 +1,5 @@ import Datastore from 'lowdb' +import LodashId from 'lodash-id' import FileSync from 'lowdb/adapters/FileSync' import path from 'path' import { remote, app } from 'electron' @@ -9,6 +10,7 @@ const STORE_PATH = APP.getPath('userData') const adapter = new FileSync(path.join(STORE_PATH, '/data.json')) const db = Datastore(adapter) +db._.mixin(LodashId) if (!db.has('uploaded').value()) { db.set('uploaded', []).write() diff --git a/src/index.ejs b/src/index.ejs index fa71385..a217aa2 100644 --- a/src/index.ejs +++ b/src/index.ejs @@ -2,6 +2,7 @@ + PicGo <% if (htmlWebpackPlugin.options.nodeModules) { %> diff --git a/src/main/index.js b/src/main/index.js index f02a2c4..f91fefd 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -1,6 +1,6 @@ 'use strict' -import { weiboUpload } from './utils/weiboUpload.js' +import uploader from './utils/uploader.js' import { app, BrowserWindow, Tray, Menu, Notification, clipboard, ipcMain } from 'electron' import db from '../datastore' import pasteTemplate from './utils/pasteTemplate' @@ -73,10 +73,12 @@ function createTray () { let img = clipboard.readImage() let obj = [] if (!img.isEmpty()) { + // 从剪贴板来的图片默认转为png + const imgUrl = 'data:image/png;base64,' + Buffer.from(img.toPNG(), 'binary').toString('base64') obj.push({ width: img.getSize().width, height: img.getSize().height, - imgUrl: img.toDataURL() + imgUrl }) } toggleWindow() @@ -94,8 +96,8 @@ function createTray () { }) tray.on('drop-files', async (event, files) => { - const pasteStyle = db.read().get('picBed.pasteStyle') || 'markdown' - const imgs = await weiboUpload(files, 'imgFromPath', window.webContents) + const pasteStyle = db.read().get('picBed.pasteStyle').value() || 'markdown' + const imgs = await uploader(files, 'imgFromPath', window.webContents) for (let i in imgs) { clipboard.writeText(pasteTemplate(pasteStyle, imgs[i].imgUrl)) const notification = new Notification({ @@ -193,8 +195,8 @@ const showWindow = () => { } ipcMain.on('uploadClipboardFiles', async (evt, file) => { - const img = await weiboUpload(file, 'imgFromClipboard', window.webContents) - const pasteStyle = db.read().get('picBed.pasteStyle') || 'markdown' + const img = await uploader(file, 'imgFromClipboard', window.webContents) + const pasteStyle = db.read().get('picBed.pasteStyle').value() || 'markdown' clipboard.writeText(pasteTemplate(pasteStyle, img[0].imgUrl)) const notification = new Notification({ title: '上传成功', @@ -202,14 +204,13 @@ ipcMain.on('uploadClipboardFiles', async (evt, file) => { icon: file[0] }) notification.show() - clipboard.clear() window.webContents.send('clipboardFiles', []) window.webContents.send('uploadFiles', img) }) ipcMain.on('uploadChoosedFiles', async (evt, files) => { - const imgs = await weiboUpload(files, 'imgFromUploader', settingWindow.webContents) - const pasteStyle = db.read().get('picBed.pasteStyle') || 'markdown' + const imgs = await uploader(files, 'imgFromUploader', settingWindow.webContents) + const pasteStyle = db.read().get('picBed.pasteStyle').value() || 'markdown' let pasteText = '' for (let i in imgs) { pasteText += pasteTemplate(pasteStyle, imgs[i].imgUrl) + '\r\n' diff --git a/src/main/utils/img2base64.js b/src/main/utils/img2base64.js index e41e588..21ed908 100644 --- a/src/main/utils/img2base64.js +++ b/src/main/utils/img2base64.js @@ -21,8 +21,10 @@ const imgFromPath = async (imgPath) => { const imgFromClipboard = (file) => { let result = [] + const today = new Date().toLocaleString() result.push({ base64Image: file.imgUrl.replace(/^data\S+,/, ''), + fileName: `${today}.png`, width: file.width, height: file.height }) @@ -30,7 +32,6 @@ const imgFromClipboard = (file) => { } const imgFromUploader = async (files) => { - console.log(files) let results = [] await Promise.all(files.map(async item => { let buffer = await fs.readFile(item.path) diff --git a/src/main/utils/qiniuUpload.js b/src/main/utils/qiniuUpload.js new file mode 100644 index 0000000..f1d9e9e --- /dev/null +++ b/src/main/utils/qiniuUpload.js @@ -0,0 +1,78 @@ +import request from 'request-promise' +import * as img2Base64 from './img2base64' +import db from '../../datastore/index' +import * as qiniu from 'qiniu' +import { Notification } from 'electron' + +function postOptions (fileName, token, imgBase64) { + const area = selectArea(db.read().get('picBed.qiniu.area').value() || 'z0') + const base64FileName = Buffer.from(fileName).toString('base64') + return { + method: 'POST', + url: `http://upload${area}.qiniu.com/putb64/-1/key/${base64FileName}`, + headers: { + Authorization: `UpToken ${token}`, + contentType: 'application/octet-stream' + }, + body: imgBase64 + } +} + +function selectArea (area) { + return area === 'z0' ? '' : '-' + area +} + +function getToken () { + const accessKey = db.read().get('picBed.qiniu.accessKey').value() + const secretKey = db.read().get('picBed.qiniu.secretKey').value() + const mac = new qiniu.auth.digest.Mac(accessKey, secretKey) + const options = { + scope: db.read().get('picBed.qiniu.bucket').value() + } + const putPolicy = new qiniu.rs.PutPolicy(options) + return putPolicy.uploadToken(mac) +} + +const qiniuUpload = async function (img, type, webContents) { + try { + webContents.send('uploadProgress', 0) + const imgList = await img2Base64[type](img) + webContents.send('uploadProgress', 30) + const length = imgList.length + for (let i in imgList) { + const options = postOptions(imgList[i].fileName, getToken(), imgList[i].base64Image) + const res = await request(options) + const body = JSON.parse(res) + if (body.key) { + delete imgList[i].base64Image + const baseUrl = db.get('picBed.qiniu.url').value() + const options = db.get('picBed.qiniu.options').value() + imgList[i]['imgUrl'] = `${baseUrl}/${body.key}${options}` + imgList[i]['type'] = 'qiniu' + if (i - length === -1) { + webContents.send('uploadProgress', 60) + } + } else { + webContents.send('uploadProgress', -1) + const notification = new Notification({ + title: '上传失败!', + body: res.body.msg + }) + notification.show() + } + } + webContents.send('uploadProgress', 100) + return imgList + } catch (err) { + webContents.send('uploadProgress', -1) + const error = JSON.parse(err.response.body) + const notification = new Notification({ + title: '上传失败!', + body: error.error + }) + notification.show() + throw new Error(err) + } +} + +export default qiniuUpload diff --git a/src/main/utils/uploader.js b/src/main/utils/uploader.js new file mode 100644 index 0000000..567ff84 --- /dev/null +++ b/src/main/utils/uploader.js @@ -0,0 +1,14 @@ +import weiboUpload from './weiboUpload' +import qiniuUpload from './qiniuUpload' +import db from '../../datastore/index' +const uploader = (img, type, webContents) => { + const uploadType = db.read().get('picBed.current').value() + switch (uploadType) { + case 'weibo': + return weiboUpload(img, type, webContents) + case 'qiniu': + return qiniuUpload(img, type, webContents) + } +} + +export default uploader diff --git a/src/main/utils/weiboUpload.js b/src/main/utils/weiboUpload.js index cfffc61..b09afb4 100644 --- a/src/main/utils/weiboUpload.js +++ b/src/main/utils/weiboUpload.js @@ -70,6 +70,4 @@ const weiboUpload = async function (img, type, webContents) { } } -export { - weiboUpload -} +export default weiboUpload diff --git a/src/renderer/components/SettingView/Upload.vue b/src/renderer/components/SettingView/Upload.vue index ec0793c..7c6503f 100644 --- a/src/renderer/components/SettingView/Upload.vue +++ b/src/renderer/components/SettingView/Upload.vue @@ -109,10 +109,10 @@ export default { this.$electron.ipcRenderer.send('uploadChoosedFiles', sendFiles) }, getPasteStyle () { - this.pasteStyle = this.$db.get('picBed.pasteStyle').value() || 'markdown' + this.pasteStyle = this.$db.read().get('picBed.pasteStyle').value() || 'markdown' }, handlePasteStyleChange (val) { - this.$db.set('picBed.pasteStyle', val) + this.$db.read().set('picBed.pasteStyle', val) .write() } } diff --git a/src/renderer/components/SettingView/Weibo.vue b/src/renderer/components/SettingView/Weibo.vue index bde7d8d..a3a46ed 100644 --- a/src/renderer/components/SettingView/Weibo.vue +++ b/src/renderer/components/SettingView/Weibo.vue @@ -56,7 +56,7 @@ export default { } }, created () { - const config = this.$db.get('picBed.weibo').value() + const config = this.$db.read().get('picBed.weibo').value() if (config) { this.form.username = config.username this.form.password = config.password @@ -67,7 +67,7 @@ export default { confirm (formName) { this.$refs[formName].validate((valid) => { if (valid) { - this.$db.set('picBed.weibo', { + this.$db.read().set('picBed.weibo', { username: this.form.username, password: this.form.password, quality: this.quality diff --git a/src/renderer/components/TrayPage.vue b/src/renderer/components/TrayPage.vue index cacb426..acb2f9e 100644 --- a/src/renderer/components/TrayPage.vue +++ b/src/renderer/components/TrayPage.vue @@ -46,15 +46,19 @@ this.disableDragFile() this.getData() this.$electron.ipcRenderer.on('dragFiles', (event, files) => { - this.$db.get('uploaded').push(...files).write() - this.files = this.$db.get('uploaded').slice().reverse().slice(0, 5).value() + files.forEach(item => { + this.$db.read().get('uploaded').insert(item).write() + }) + this.files = this.$db.read().get('uploaded').slice().reverse().slice(0, 5).value() }) this.$electron.ipcRenderer.on('clipboardFiles', (event, files) => { this.clipboardFiles = files }) this.$electron.ipcRenderer.on('uploadFiles', (event, files) => { - this.$db.get('uploaded').push(...files).write() - this.files = this.$db.get('uploaded').slice().reverse().slice(0, 5).value() + files.forEach(item => { + this.$db.read().get('uploaded').insert(item).write() + }) + this.files = this.$db.read().get('uploaded').slice().reverse().slice(0, 5).value() }) }, beforeDestroy () { @@ -64,7 +68,7 @@ }, methods: { getData () { - this.files = this.$db.get('uploaded').slice().reverse().slice(0, 5).value() + this.files = this.$db.read().get('uploaded').slice().reverse().slice(0, 5).value() }, copyTheLink (item) { this.notification.body = item.imgUrl diff --git a/yarn.lock b/yarn.lock index d2f64cf..052c479 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4939,6 +4939,10 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" +lodash-id@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/lodash-id/-/lodash-id-0.14.0.tgz#baf48934e543a1b5d6346f8c84698b1a8c803896" + lodash._arraycopy@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz#76e7b7c1f1fb92547374878a562ed06a3e50f6e1"