LskyPro使用Picgo上传图片

LskyPro使用Picgo上传图片

  1. 安装 Releases · Molunerfinn/PicGo (github.com) 2.3.0 版本。
  2. 启动 PicGo 并安装 lankong 插件,可以直接搜索安装。
LskyPro使用Picgo上传图片
  1. 修改插件源码 index.js
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const https_1 = __importDefault(require("https"));
const UPLOADER = 'lankong';
module.exports = (ctx) => {
    const register = () => {
        ctx.helper.uploader.register(UPLOADER, {
            handle,
            name: UPLOADER,
            config: config
        });
        // 注册同步删除 remove 事件
        ctx.on('remove', onDelete);
    };
    async function onDelete(files, guiApi) {
        let userConfig = ctx.getConfig('picBed.' + UPLOADER);
        const syncDelete = userConfig.syncDelete;
        // 如果同步删除按钮关闭则不执行
        if (!syncDelete) {
            return;
        }

        const VersionId = userConfig.lskyProVersion;
        switch (VersionId) {
            case 'version1':
                {
                    ctx.emit('notification', {
                        title: `V1版本的兰空图床不支持同步删除, 请关闭同步删除选项以抑制此通知`
                    });
                    return;
                }; break;
            case 'version2':
                {

                }; break;
            case 'version3':
                {

                }; break;

        }

        const deleteList = files.filter(each => each.type === UPLOADER);
        if (deleteList.length === 0) {
            return;
        }

        for (let i = 0; i < deleteList.length; i++) {
            const item = deleteList[i];
            const deleteParam = GenDeleteParam(item, userConfig);
            let body = await ctx.Request.request(deleteParam);
            body = JSON.parse(body);
            if (body.status === true) {
                ctx.emit('notification', {
                    title: `${item.imgUrl} 同步删除成功`,
                    body: body.message
                });
            }
            else {
                ctx.emit('notification', {
                    title: `${item.imgUrl} 同步删除失败`,
                    body: body.message
                });
                throw new Error(body.message);
            }
        }

    }
    const GenDeleteParam = (img, userConfig) => {
        const token = userConfig.token;
        const ignoreCertErr = userConfig.ignoreCertErr;
        const serverUrl = userConfig.server;
        const currentImageKey = img.id;
        const v2Headers = {
            'Accept': 'application/json',
            'User-Agent': 'PicGo',
            'Connection': 'keep-alive',
            'Authorization': token || undefined
        };

        // 如果忽略证书错误开关打开则带上 http agent 访问, 否则不需要带(以提高性能)
        if (ignoreCertErr) {
            let requestAgent = new https_1.default.Agent({
                // 此处需要取反 忽略证书错误 拒绝未授权证书选项
                rejectUnauthorized: !ignoreCertErr
            });
            return {
                method: 'DELETE',
                url: `${serverUrl}/api/v1/images/${currentImageKey}`,
                agent: requestAgent,
                headers: v2Headers
            };
        }
        else {
            return {
                method: 'DELETE',
                url: `${serverUrl}/api/v1/images/${currentImageKey}`,
                headers: v2Headers
            };
        }
    };
    // 图片上传
    const postOptions = (userConfig, fileName, image) => {
        const serverUrl = userConfig.server;
        if (serverUrl.endsWith("/")) {
            throw new Error("Server url cannot ends with /");
        }

        const VersionId = userConfig.lskyProVersion;
        const token = userConfig.token;
        const ignoreCertErr = userConfig.ignoreCertErr;

        // LskyProV1需要的配置
        const v1Headers = {
            'Content-Type': 'multipart/form-data',
            'User-Agent': 'PicGo',
            'Connection': 'keep-alive',
            'token': token || undefined
        };
        const v1FormData = {
            image: {
                value: image,
                options: {
                    filename: fileName
                }
            },
            ssl: 'true'
        };

        // LskyProV2需要的配置
        const v2Headers = {
            'Content-Type': 'multipart/form-data',
            'User-Agent': 'PicGo',
            'Connection': 'keep-alive',
            'Accept': 'application/json',
            'Authorization': token || undefined
        };
        const strategyId = userConfig.strategyId;
        const albumId = userConfig.albumId;
        let permission = userConfig.permission.value;
        if (permission === undefined) {
            permission = userConfig.permission;
        }
        const v2FormData = {
            file: {
                value: image,
                options: {
                    filename: fileName
                }
            },
            ssl: 'true',
            strategy_id: strategyId,
            album_id: albumId,
            permission: permission
        };

        // V2版本情况下, 如果用户没有填写策略ID, 删除 v2FormData 中的 key: strategy_id
        if (!strategyId) {
            delete v2FormData.strategy_id;
        }
        if (!albumId) {
            delete v2FormData.album_id;
        }
        if (!(permission === 0 || permission === 1)) {
            delete v2FormData.permission;
        }

        let api_url = `${serverUrl}/api/upload`;
        let Headers = v1Headers;
        let FormData = v1FormData;

        switch (VersionId) {
            case 'version1':
                {
                    api_url = `${serverUrl}/api/upload`;
                    Headers = v1Headers;
                    FormData = v1FormData
                } break;
            case 'version2':
                {
                    api_url = `${serverUrl}/api/v1/upload`;
                    Headers = v2Headers;
                    FormData = v2FormData
                } break;
            case 'version3':
                {
                    api_url = `${serverUrl}/api/v1/upload`;
                    Headers = v2Headers;
                    FormData = v2FormData
                } break;
        }



        // 如果忽略证书错误开关打开则带上 http agent 访问, 否则不需要带(以提高性能)
        if (ignoreCertErr) {
            let requestAgent = new https_1.default.Agent({
                // 此处需要取反 忽略证书错误 拒绝未授权证书选项
                rejectUnauthorized: !ignoreCertErr
            });
            return {
                method: 'POST',
                url: api_url,
                agent: requestAgent,
                headers: Headers,
                formData: FormData
            };
        }
        else {
            return {
                method: 'POST',
                url: api_url,
                headers: Headers,
                formData: FormData
            };
        }
    };

    const handle = async (ctx) => {

        let userConfig = ctx.getConfig('picBed.' + UPLOADER);
        if (!userConfig) {
            throw new Error('Can\'t find uploader config');
        }
        const imgList = ctx.output;
        for (let i in imgList) {
            let image = imgList[i].buffer;
            if (!image && imgList[i].base64Image) {
                image = Buffer.from(imgList[i].base64Image, 'base64');
            }
            const postConfig = postOptions(userConfig, imgList[i].fileName, image);
            let body = await ctx.Request.request(postConfig);
            body = JSON.parse(body);

            let VersionId = userConfig.lskyProVersion;

            switch (VersionId) {
                case 'version1':
                    {
                        let condition = (body.code === 200);
                        if (condition) {
                            delete imgList[i].base64Image;
                            delete imgList[i].buffer;
                            // 图片链接
                            imgList[i]['imgUrl'] = body.data.url;
                        }
                        else {
                            ctx.emit('notification', {
                                title: 'upload failed',
                                body: body.message
                            });
                            throw new Error(body.message);
                        }
                    } break;
                case 'version2':
                    {
                        let condition = (body.status === true);
                        if (condition) {
                            delete imgList[i].base64Image;
                            delete imgList[i].buffer;
                            // 图片链接
                            imgList[i]['imgUrl'] = body.data.links.url;
                            // 图片唯一密钥
                            imgList[i]['id'] = body.data.key;
                        }
                        else {
                            ctx.emit('notification', {
                                title: 'upload failed',
                                body: body.message
                            });
                            throw new Error(body.message);
                        }
                    } break;
                case 'version3':
                    {
                        let condition = (body.status === true);
                        if (condition) {
                            delete imgList[i].base64Image;
                            delete imgList[i].buffer;
                            // 图片链接
                            imgList[i]['imgUrl'] = body.data.links.url;
                            // 图片唯一密钥
                            imgList[i]['id'] = body.data.key;
                        }
                        else {
                            ctx.emit('notification', {
                                title: 'upload failed',
                                body: body.message
                            });
                            throw new Error(body.message);
                        }
                    } break;
            }
        }
        return ctx;
    };

    const config = ctx => {
        let userConfig = ctx.getConfig('picBed.' + UPLOADER);
        if (!userConfig) {
            userConfig = {};
        }
        return [
            {
                name: 'lskyProVersion',
                type: 'list',
                default: userConfig.lskyProVersion || 'version1',
                message: 'Choose a version',
                choices: [
                    {
                        name: 'LskyProV1',
                        value: 'version1'
                    },
                    {
                        name: 'LskyProV2',
                        value: 'version2'
                    },
                    {
                        name: 'LskyProPlusV1',
                        value: 'version3'
                    }
                ],
                required: true,
                alias: 'Lsky Pro Version'
            },
            {
                name: 'server',
                type: 'input',
                default: userConfig.server,
                required: true,
                message: '示例: https://example.com',
                alias: 'Server'
            },
            {
                name: 'token',
                type: 'input',
                default: userConfig.token,
                required: true,
                message: '认证 token 信息',
                alias: 'Auth token'
            },
            {
                name: 'strategyId',
                type: 'input',
                default: userConfig.strategyId,
                required: false,
                message: '选填, V1以及V2使用默认存储策略时请留空',
                alias: 'Strategy ID'
            },
            {
                name: 'albumId',
                type: 'input',
                default: userConfig.albumId,
                required: false,
                message: '选填, V2生效',
                alias: 'Album ID'
            },
            {
                name: 'permission',
                type: 'list',
                default: userConfig.permission || 'private(default)',
                message: 'set permission',
                choices: [
                    {
                        name: 'private(default)',
                        value: 0
                    },
                    {
                        name: 'public',
                        value: 1
                    }
                ],
                required: false,
                alias: 'Permission'
            },
            {
                name: 'ignoreCertErr',
                type: 'confirm',
                default: userConfig.ignoreCertErr || false,
                message: '是否忽略证书错误, 如果上传失败提示证书过期请设为true',
                required: true,
                alias: 'Ignore certificate error'
            },
            {
                name: 'syncDelete',
                type: 'confirm',
                default: userConfig.syncDelete || false,
                message: '是否同步删除, 只支持V2',
                required: true,
                alias: 'Sync Delete'
            }
        ];
    };
    return {
        uploader: UPLOADER,
        config: config,
        register
        // guiMenu
    };
};
  1. 重启PicGo,然后正常配置即可。
LskyPro使用Picgo上传图片
  1. 然后配合 Obsidian 写文章就可以复制粘贴实现自动上传图片了。

Picgo添加图片压缩插件

一般而言直接上传的图片一般比较大,而Picgo的一款插件 picgo-plugin-compress 则可以实现图片自动压缩后上传。

  1. Picgo插件中搜索 compress 并安装。
LskyPro使用Picgo上传图片
  1. 把 compress 插件更新一下。
  2. 配置 compress。
  • tinypng 无损压缩,需要上传到 tinypng。
  • imagemin 压缩过程不需要经过网络,但是图片会有损耗。
  • image2webp 本地有损压缩,支持 GIF 格式有损压缩 注意:有些图床(比如 sm.ms)不支持 webp 图片格式,会上传失败。
类型tinypngimageminimage2webp
原大小1.5 MB1.5 MB1.5 MB
压缩后315 KB411 KB216 KB
  1. 这里我们选择 tinypng 在线压缩方式。
  2. 去tinypng申请一个API账号,然后填写自己的KEY后重启即可。
LskyPro使用Picgo上传图片
  1. 去 tinypng 官网看下使用次数是否增加以确认压缩是否成功。
LskyPro使用Picgo上传图片
  1. 去自己的图床查看图片是否上传成功。
@版权声明 1 本站名称:Liuwei's Blog
2 本站网址:https://www.liuwei.vin
3 本站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
4 本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报。
5 本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。
6 本站所有内容,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

给TA打赏
共{{data.count}}人
人已打赏
个人网站群晖

群晖安装LskyPro企业版图床

2023-1-5 18:10:31

个人网站群晖

群晖自动更新 Let’s Encrypt 证书

2023-1-15 14:14:52

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
有新私信 私信列表
搜索