Typora配置插件使用API自动上传Chevereto图床

折腾记录
1036 0

原插件 typora-plugins-win-img 因为不兼容老版本的 所以魔改了一下.详情见文章底部附件

配置教程

1.将下载的插件包里面的plugins复制到Typora目录下的Typora\resources\appsrc之中
2.修改window.html 为安全起见,建议先将window.html备份一份
用编辑工具打开windows.html搜索
window/frame.js" defer="defer"></script>
在其后面添加

<script src="./appsrc/plugins/image/upload.js" defer="defer"></script>

修改代码

编辑安装目录/resources/app/plugins/upload.js

(function($){
    // 配置信息
    var setting = {
        target:'self',        
        //target=self 时涉及的配置参数
        self: {
            url: 'http://your_website/api/1/upload/',   //这里填你图床的api地址
            key: 'YOUR API KEY',    //这里填你的APIKEY
            action: 'upload',
            //自定义请求头,做校验,防止其他人随意调接口
        },

        //==============回调函数==============
        // 上传成功
        onSuccess: function(url){
            //替换图片位置
            setting.element.removeAttr(locked).attr('src', url);
            setting.element.
                parent('span[md-inline="image"]').
                data('src', url).
                find('.md-image-src-span').
                html(url);
            //提醒
            var text = '图片上传成功:'+ url;
            $('#'+noticeEle).
            css({
                'background':'rgba(0,166,90,0.7)',
            }).
            html(text).
            show().
            delay(5000).
            fadeOut();
        },
        // 上传失败
        onFailure: function(text){
            setting.element.removeAttr(locked);
            $('#'+noticeEle).
            css({
                'background':'rgba(255,0,0,0.7)'
            }).
            html(text).
            show().
            delay(10000).
            fadeOut();
        }
    };

    var helper = {
        // 将base64转文件流
        base64ToBlob: function(base64) {
            var arr = base64.split(',');
            var mime = arr[0].match(/:(.*?);/)[1] || 'image/png';
            // 去掉url的头,并转化为byte
            var bytes = window.atob(arr[1]);
            // 处理异常,将ascii码小于0的转换为大于0
            var ab = new ArrayBuffer(bytes.length);
            // 生成视图(直接针对内存):8位无符号整数,长度1个字节
            var ia = new Uint8Array(ab);

            for (var i = 0; i < bytes.length; i++) {
                ia[i] = bytes.charCodeAt(i);
            }

            return new Blob([ab], {
                type: mime
            });
        },
        // 根据base64获取文件扩展名
        extension: function(base64){
            var ext = base64.split(',')[0].match(/data:image\/(.*?);base64/)[1] || 'png';
            console.log("the file ext is: "+ext);
            return ext;
        },
        // 根据base64获取图片内容
        content: function(base64){
            var content = base64.split(',')[1];
            return content;
        },
        mine: function(base64){
            var arr  = base64.split(',');
            var mime = arr[0].match(/:(.*?);/)[1] || 'image/png';
            console.log("the file mime is: "+mime);
            return mime;
        },
        // 时间格式化函数
        dateFormat: function (date, fmt) {
            var o = {
                "M+": date.getMonth() + 1, //月份
                "d+": date.getDate(), //日
                "H+": date.getHours(), //小时
                "m+": date.getMinutes(), //分
                "s+": date.getSeconds(), //秒
                "q+": Math.floor((date.getMonth() + 3) / 3), //季度
                "S": date.getMilliseconds() //毫秒
            };
            if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
            for (var k in o)
            if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
            return fmt;
        }
    };

    // 上传文件的方法
    var upload = {
        // 自建服务器存储时,适用的上传方法
        self : function(fileData, successCall, failureCall){

            var filename = helper.dateFormat((new Date()),'yyyyMMddHHmmss-')+Math.floor(Math.random() * Math.floor(999999))+'.'+helper.extension(fileData);
            var fileData = helper.base64ToBlob(fileData);
            var formData = new FormData();
            formData.append('source', fileData);
            formData.append('filename', filename);
            $.ajax({
                type: "POST",
                url: setting.self.url+'?key='+setting.self.key+'&upload='+setting.self.action,
                processData:false,
                data:formData,
                contentType: false,
                success: function(result) {
                    //奇葩的阿里云,响应内容为空
                    console.log(result);
                    successCall(result.image.url);
                },
                error:function(result){
                    console.log(result);
                    failureCall('服务响应解析失败,请稍后再试');
                }
            });
        },

    };

    //读取文件为base64,再回调上传函数将文件发到服务器
    var loadImgAndSend = function(url){
        var xhr = new XMLHttpRequest();
        xhr.onload = function() {
            var reader = new FileReader();
            reader.onloadend = function() {
                switch (setting.target) {
                    case 'self':
                        upload.self(reader.result, setting.onSuccess, setting.onFailure);
                        break;
                    default:
                        setting.onFailure('配置错误,不支持的图片上传方式,可选方式:self/tencent/aliyun/qiniu/github');
                } 
            }
            reader.readAsDataURL(xhr.response);
        };
        xhr.open('GET', url);
        xhr.responseType = 'blob';
        xhr.send();
    }

    // 核心方法
    var locked = 'doing';
    var noticeEle = 'image-result-notice';    
    $.image = {};
    $.image.init = function(options){
        options = options||{};
        setting.target = options.target||setting.target;
        setting.self = options.self||setting.self;

        // 监听鼠标事件
        $('#write').on('mouseleave click', 'img', function(e){
            try{
                var src = e.target.src;
                if( /^(https?:)?\/\//i.test(src) ){
                    console.log('The image already upload to server, url:' + src);
                    return false;
                }
                setting.element = element = $(e.target);
                var doing = element.attr(locked)=='1';
                if( doing ){
                    console.log('uploading...');
                    return false;
                }else{
                    element.attr(locked, '1');
                }
                $('content').prepend('<div id="'+noticeEle+'" style="position:fixed;height:40px;line-height:40px;padding:0 15px;overflow-y:auto;overflow-x:hidden;z-index:10;color:#fff;width:100%;display:none;"></div>');
                //转换成普通的图片地址
                //src = src.substring(8, src.indexOf('?last'));
                loadImgAndSend(src);
            }catch(e){console.log(e);};
        });
    };
})(jQuery);

$.image.init();

然后将自己的APIKEY及图床地址填入代码开头对应位置即可,由于本文用不到其余图床的代码,所以这里删掉了。 然后保存退出,重新打开typora,粘贴图片进去就可以自动上传了。 typora不支持直接粘贴gif图片,所以插入动图需要ctrl+shift+i,然后手动选择动图添加,之后也会自动上传替换。

自定义chevereto上传用户和上传相册(可选)

chevereto的api默认会新建一个相册,但是会有bug,就是在相册菜单下找不到这个相册,只能从图片菜单下去打开,所以可以按照下面的方法修改api上传的默认相册和用户。 打开chevereto的web目录,将默认的app/routes/route.api.php的文件复制到 app/routes/overrides/route.api.php文件夹

把这段代码:CHV\Image::uploadToWebsite($source);

改成这个:(将user更换成目标用户名或用户id)

// 这里的user是要传的用户,'album_id'=>4是对应的相册id,按需修改
CHV\Image::uploadToWebsite($source, 'user', array('album_id'=>4));

然后保存即可。 也可以在api中指定用户和相册,只需要在uploadToWebsite()方法前增加几个request字段就行了,不知道官方为啥不提供,可能是出于安全性考虑的吧。

PS:使用过程中的BUG

如果在使用过程中多次点击图片或者来回切换源代码模式,会造成图片频繁重复上传.这点儿不是很好玩儿.

附件下载

plugins.zip

https://blog.fxb.cc/68.html
最后更新 2022-01-06
评论 ( 0 )
问:肆 + 贰 = ?
OωO
隐私评论