file-uploader-cli源码修改

注:可以直接跳到最下面看需要修改的部分

最近由于Gitee的开源审查,导致其无法再作为图床使用。在对比了多家OSS服务后,决定使用京东云作为新图床,并使用file-uploader-cli来进行图片和文件的上传,其中Typora只使用其进行博客图片的上传。但查看了file-uploader-cli对于京东云的相关配置,并且进行多次测试后,发现它只能将文件上传到图床的根目录中。而如果在bucket参数中加入根目录中的文件夹,返回的值就会出错。这很不利于Typora在将图片自动转为网络地址后进行展示。查询解决办法无果后,只能将其源码进行修改。

Typora图片自动上传至博客图片文件夹

分析配置文件(具体配置可查看原作者的README)

file-uploader-cli给京东云的配置参数如下

{"bucket": "*","region": "*","accessKeyId": "*","secretAccessKey": "*"
}

其中bucket是用来配置图床地址的,比如我的是rezc404-img-hostregion是服务所在地,官网中的Bucket域名也会写到,如cn-north-1;后两个是京东云提供的访问京东云API的密钥,可以在官网自行添加和删除。

可以在任意位置编写完此JSON文件后使用fuc -t 配置类型 -c 文件名.json,比如fuc -t jdcloud -c jdcloud.json,此时打开file-uploader-cli安装目录中的config.json文件就会发现程序添加了一段配置

{"default": "jdcloud","jdcloud": {"bucket": "rezc404-img-host","region": "cn-east-2","accessKeyId": "*","secretAccessKey": "*"}
}

其中jdcloud对象中的参数就是之前配置的参数。此时随便找张截图,使用fuc 文件绝对路径,就可以将文件上传至图床,并返回网络地址

现在我想将上传至图床中的对象进行分类,图片放一起,文件放一起,可又因为上传后京东云OSS服务不支持文件的移动,这就要求我们必须在上传时选好路径。

可以在配置bucket时加上文件夹路径,比如 rezc404-img-host/blog-img,这时虽然可以上传,但是返回的网络地址rezc404-img-host/blog-img.s3.cn-east-2.jdcloud-oss.com/test.png却是错误的,这导致直接在Typora中设定自定义命令fuc后自动更改的网络地址也是错误的。

而在网站中查看外链则是rezc404-img-host.s3.cn-east-2.jdcloud-oss.com/blog-img/test.png

可以看到文件夹路径在上传时是可以放在bucket中,但最后网络地址的结构是Bucket域名/文件夹名/文件名,所以并不能简单的在bucket参数中加入文件夹。

那该如何将文件上传至指定的文件夹中,且返回地址也正确呢?

答:参考file-uploader-cli关于github的配置,添加这个path参数

分析源码

查看关于jdcloud的源代码jdcloud.js

#!/usr/bin/env node
const sharp = require('sharp')
const fs = require('fs')
const stream = require('stream')
const AWS = require('aws-sdk')
const path = require('path')
const FileType = require('file-type')
const mimeTypes = require('mime-types')
const { supportImages } = require('./util')async function upload (config, fileList){const { accessKeyId, secretAccessKey, region, bucket, webp, quality } = config   //1.获取config.json中关于jdcloud的参数const s3 = new AWS.S3()s3.endpoint = `https://s3.${region}.jdcloud-oss.com`                           s3.config.update({accessKeyId,secretAccessKey,s3ForcePathStyle: true,region,signatureVersion: "v4"})async function put (filePath) {const mime = (await FileType.fromFile(filePath) || {}).mime || mimeTypes.lookup(filePath)try {let name = null, data = null;if(webp && supportImages.indexOf(path.extname(filePath)) > -1){name = `${path.basename(filePath,path.extname(filePath))}.webp`data = await sharp(filePath).webp({ quality: quality || 75 }).toBuffer();// 创建一个bufferstreamfilePath = path.basename(filePath, path.extname(filePath)) + '.webp'readableStream = new stream.PassThrough()//将Buffer写入readableStream.end(data)}else{name = path.basename(filePath)data = fs.createReadStream(filePath)}var params = {Body: data, Bucket: bucket,    //2.上传的地址为config中叫bucket的参数,在后面加入"/文件夹名"就行ContentType: mime,Key: name,}s3.putObject(params, function(err, data) {if(err) console.log(err)!err && console.log(`https://${bucket}.s3.${region}.jdcloud-oss.com/${name}`)  //3.返回的网络地址格式,其中bucket是直接插入其中,所以如果将文件夹名也加入bucket中,那么返回的结果也将是错的});} catch (e) {console.log(e);}}for(let i = 0; i < fileList.length; i++){        await put(fileList[i])}
}module.exports = upload

修改源码

其中12行,42行和48行是重点:

  1. 12行中的变量对应的正是配置文件中的参数,所以只需要在其中添加一个路径参数cloudPath即可

    const { accessKeyId, secretAccessKey, cloudPath, region, bucket, webp, quality } = config
    
  2. 42行中Bucket为上传地址,value值中的bucket如果带上文件夹,就会传入图床中的文件夹,所以这里只需将value改为

    bucket + cloudPath,
    

    即可

  3. 48行打印出来的是图片上传后的网络地址,不难看出如果bucket中带文件夹,返回的地址就不会正确,所以只需要把cloudPath参数加在文件名前即可

    !err && console.log(`https://${bucket}.s3.${region}.jdcloud-oss.com${cloudPath}/${name}`)
    
  4. 最后只需要在配置文件中加入cloudPath 即可(注:如果想放在根目录就只需要"",如果要放入文件夹前面必须要加/)

    {"default": "jdcloud","jdcloud": {"bucket": "rezc404-img-host","region": "cn-east-2","cloudPath": "/blog-img","accessKeyId": "*","secretAccessKey": "*"}
    }
    

这时返回的地址就是正确的地址,在Typora中自动转换的路径也是正确的

博客中上传的图片会传入blog-img文件夹中。如果我想向别的文件夹上传文件,比如博客的缩略图文件夹,那该怎么办呢?

答:多创建几个配置配置对象即可

不同文件上传至指定文件夹

分析源码

因为我目前只使用京东云作为图床,所以只需要添加另一段配置,然后使用同一个的上传代码,也就是jdcloud.js就可以了。

配置文件

{"default": "jdcloud","jdcloud": {"bucket": "rezc404-img-host","region": "cn-east-2","cloudPath": "/blog-img","accessKeyId": "*","secretAccessKey": "*"}
}

修改成如下

{"default": "jdcloud-img","jdcloud-img": {"bucket": "rezc404-img-host","region": "cn-east-2","cloudPath": "/blog-img","accessKeyId": "*","secretAccessKey": "*"},"jdcloud-thn": {"bucket": "rezc404-img-host","region": "cn-east-2","cloudPath": "/blog-thumbnails","accessKeyId": "*","secretAccessKey": "*"}
}

但此时因为index.js

#!/usr/bin/env node
const { program } = require('commander')
const helpOptions = require('./lib/core/help')
const generateConfig = require('./lib/core/generateConfig')
const pkg = require('./package.json')
const configOperate = require('./lib/core/configOperate')
const { readConfig, absolutePath, supportList } = require('./lib/util')helpOptions()program.version(pkg.version).parse(process.argv);configOperate()const config = generateConfig()
const options = program.opts()
const type = options['type'] || readConfig()['default']
if(supportList.indexOf(type) > -1){  //const supportList = ['github', 'ali-oss', 'qiniu', 'ftp', 'cos', 'jdcloud']if(options.length === 0 && program.args.length === 0){console.log('please specify the file to upload')return}const fileList = absolutePath(program.args)if(fileList.length > 0 && (!config || Object.keys(config).length === 0)){console.log("can't find configuration")return}fileList.length > 0 && require(`./lib/${type}`)(config,fileList)
}

supportList里没有jdcloud-imgjdcloud-thn,所以程序找不到上传的入口。

修改源码

解决办法有两种:

  1. supportList中添加这两个type,并复制**\file-uploader-cli\lib**中的jdcloud.js,改名成配置名jdcloud-img.js jdcloud-thn.js
  2. 修改源码,将传入的type的”-“后的部分去掉

我选择了第二种,在19行后添加

const minusIndex = type.indexOf('-')
const typeStr = minusIndex > -1 ? type.substring(0, minusIndex) : type

并把下面的type都换成typeStr

本来认为已经可以使用了,没想到第17行的generateConfig()函数报错,进去查看

const { program } = require('commander')
const { updateFile, readOptionConfig, readConfig } = require('../util')const generateConfig = () => {let config = nullconst options = program.opts()// 如果指定配置  使用当前指定if(options.config){if(!options.type){throw new Error('configuration needs to specify the type')}else{config = readOptionConfig(options.config)//具体函数在下面updateFile(options.type, config)}}else if(options.type){config = readConfig()[options.type]}else{const setting = readConfig()config = setting[setting.default]}return config
}module.exports = generateConfig
// 读取选项指定配置
const readOptionConfig = (file) => {createConfigFile()console.log(path.resolve(process.cwd(), file))const config = JSON.parse(readFileSync(path.resolve(process.cwd(), file), 'utf8'));return config
}

发现如果上传使用指定配置,程序会判断此配置中是否说明其种类,只有含有种类的配置程序才会在config.json中找到它。但改写之后配置一没有种类,二在运行readOptionConfig()函数中process.cwd()返回的路径也是错误的。我认为反正我目前也只使用京东云这一种配置,就索性把判断种类这一步去掉,并使用最后一个else中的逻辑

 if(options.config){const setting = readConfig()config = setting[options.config]}

这是返回的config就是所选的配置,而且图片也成功上传

至此,对file-uploader-cli的源码修改已经全部结束。

修改部分汇总

  1. \file-uploader-cli\lib\jdcloud.js

    #!/usr/bin/env node
    const sharp = require('sharp')
    const fs = require('fs')
    const stream = require('stream')
    const AWS = require('aws-sdk')
    const path = require('path')
    const FileType = require('file-type')
    const mimeTypes = require('mime-types')
    const { supportImages } = require('./util')async function upload(config, fileList) {const { accessKeyId, secretAccessKey, cloudPath, region, bucket, webp, quality } = configconst s3 = new AWS.S3()s3.endpoint = `https://s3.${region}.jdcloud-oss.com`s3.config.update({accessKeyId,secretAccessKey,s3ForcePathStyle: true,region,signatureVersion: "v4"})async function put(filePath) {const mime = (await FileType.fromFile(filePath) || {}).mime || mimeTypes.lookup(filePath)try {let name = null, data = null;if (webp && supportImages.indexOf(path.extname(filePath)) > -1) {name = `${path.basename(filePath, path.extname(filePath))}.webp`data = await sharp(filePath).webp({ quality: quality || 75 }).toBuffer();// 创建一个bufferstreamfilePath = path.basename(filePath, path.extname(filePath)) + '.webp'readableStream = new stream.PassThrough()//将Buffer写入readableStream.end(data)} else {name = path.basename(filePath)data = fs.createReadStream(filePath)}var params = {Body: data,Bucket: bucket + cloudPath,ContentType: mime,Key: name,}s3.putObject(params, function (err, data) {if (err) console.log(err)!err && console.log(`https://${bucket}.s3.${region}.jdcloud-oss.com${cloudPath}/${name}`)});} catch (e) {console.log(e);}}for (let i = 0; i < fileList.length; i++) {await put(fileList[i])}
    }module.exports = upload
    

    修改第12行,42行和48行

  2. \config.json

    {"default": "jdcloud","jdcloud": {"bucket": "rezc404-img-host","region": "cn-east-2","cloudPath": "/blog-img","accessKeyId": "*","secretAccessKey": "*"}
    }
    

    添加第6行

  3. \file-uploader-cli\index.js

    #!/usr/bin/env node
    const { program } = require('commander')
    const helpOptions = require('./lib/core/help')
    const generateConfig = require('./lib/core/generateConfig')
    const pkg = require('./package.json')
    const configOperate = require('./lib/core/configOperate')
    const { readConfig, absolutePath, supportList } = require('./lib/util')helpOptions()program.version(pkg.version).parse(process.argv);configOperate()const config = generateConfig()
    const options = program.opts()
    const type = options['type'] || readConfig()['default']
    const minusIndex = type.indexOf('-')
    const typeStr = minusIndex > -1 ? type.substring(0, minusIndex) : type
    if (supportList.indexOf(typeStr) > -1) {if (options.length === 0 && program.args.length === 0) {console.log('please specify the file to upload')return}const fileList = absolutePath(program.args)if (fileList.length > 0 && (!config || Object.keys(config).length === 0)) {console.log("can't find configuration")return}fileList.length > 0 && require(`./lib/${typeStr}`)(config, fileList)
    }
    

    添加第19,20行

  4. \file-uploader-cli\lib\core\generateConfig.js

    const { program } = require('commander')
    const { updateFile, readOptionConfig, readConfig } = require('../util')const generateConfig = () => {let config = nullconst options = program.opts()// 如果指定配置  使用当前指定if(options.config){const setting = readConfig()config = setting[options.config]}else if(options.type){config = readConfig()[options.type]}else{const setting = readConfig()config = setting[setting.default]}return config
    }module.exports = generateConfig
    

    修改第8行后if里的代码

file-uploader-cli 关于上传至京东云中文件夹问题的源码修改相关推荐

  1. [共享]一个文件上传的控件,绝对是精品源码

    [共享]一个文件上传的控件,绝对是精品源码 前段时候在www.codeproject.com上看到一个文件上传的控件,觉得很好,共享给园子里的朋友. 原文链接:http://www.codeproje ...

  2. hadoop HDFS的文件夹创建、文件上传、文件下载、文件夹删除,文件更名、文件详细信息、文件类型判断(文件夹或者文件)

    摘要: 本篇文章主要介绍的是hadoop hdfs的基础api的使用.包括Windows端依赖配置,Maven依赖配置.最后就是进行实际的操作,包括:获取远程hadoop hdfs连接,并对其进行的一 ...

  3. Windows系统下上传到Linux指定文件夹

    一.准备环境 SecureCRT已成功连接虚拟机Linux系统. 二.打开"SFTP" 三.将Windows下文件直接拖入,有如下显示 四.进入Linux系统查看文件位置,并移动到 ...

  4. JS同时上传表单图片和表单信息并把上传信息存入数据库,带php后端源码

    微信小程序开发交流qq群   581478349    承接微信小程序开发.扫码加微信. 利用JQ,jquery.form.js,bootstrap实现上传表单图片和表单信息并把上传的图片地址,inp ...

  5. springboot:实现文件上传下载实时进度条功能【附带源码】

    0. 引言 记得刚入行的时候,做了一个文件上传的功能,因为上传时间较久,为了用户友好性,想要添加一个实时进度条,显示进度.奈何当时技术有限,查了许久也没用找到解决方案,最后不了了之. 近来偶然想到这个 ...

  6. nodejs,处理表单提交文件和普通参数(enctype=“multipart/form-data“),使用插件multiparty,将图片上传到服务器的文件夹中

    目录 1. 页面form是有text类型和file类型输入框,所以需要将form提交类型设置为enctype="multipart/form-data" method=" ...

  7. vue对文件夹进行拖拽上传完整流程(文件夹中超出100个文件)

    前言 上个文章介绍了多图片压缩,多图片可以通过直接多选图片进行拖拽,也可以通过直接拖拽文件夹进行解析得到多图片,接下来直接上代码 先展示文件拖拽后对文件的解析效果 图片文件夹 图片文件夹解析 大文件夹 ...

  8. 用ftp上传到服务器视频文件夹,ftp 上传文件夹到服务器

    ftp 上传文件夹到服务器 内容精选 换一换 上传的文件和上传的文件夹中包含的文件支持的格式请参见支持的文件格式.文件上传:从本地上传:在Projects Explorer视图中选中一个文件夹,依次单 ...

  9. Asp.NetCoreWebApi图片上传接口(二)集成IdentityServer4授权访问(附源码)

    写在前面 本文地址:http://www.cnblogs.com/yilezhu/p/9315644.html 作者:yilezhu 上一篇关于Asp.Net Core Web Api图片上传的文章使 ...

最新文章

  1. python课时费_python(课时1)
  2. JavaScript笔记 基础知识总结2
  3. 【模拟退火】解决【TSP】问题
  4. Blazor University (6)组件 — 组件事件
  5. javafx html5_JavaFX技巧5:可观察
  6. 解释java程序中的异常机制_Java编程中的异常机制
  7. 孙正义重申:计划在五年内将芯片设计公司Arm重新上市
  8. 重新解释i++和++i
  9. 如何设置硬盘安装linux,linux用硬盘安装时所设置选项
  10. android触摸屏idc,android4.0触摸屏滑鼠模式解决方法-添加idc文件
  11. Luogu3942 将军令
  12. 如何删除本地mysql的数据库_如何完全卸载 mysql 数据库
  13. 最速下降法python_最速下降法python实现
  14. 评价模型——层次分析法
  15. 服务器常见基本故障+排查方法,很实用!
  16. 英文论文查重规则是什么?
  17. Ubuntu 建立局域网
  18. 哈工大计算机网络week4学习总结
  19. Android单元测试技巧
  20. Linux(二) 常用工具

热门文章

  1. uni-app 商城 的sku算法(vue)
  2. THANK YOU FOR YOUR CONCERN, SIOBAN AND ANTHONY
  3. 对计算机的认识与感想
  4. Java打印杨辉三角
  5. 算法思想理解系列 -- 检索排序学习之pairwise类型
  6. 执行matlab 部分程序
  7. 架设局域网升级服务器 用WSUS打补丁
  8. C#中WorkBook的操作
  9. python安装opencc包失败
  10. Mysql隐式类型转换