• deepin优雅地创作和分享技术博客


    1. 闲言碎语

    好记性不如烂笔头。我们很多人喜欢写技术博客,构建知识库,然后把它们分享到网络平台,比如自建博客,主流博客平台,又或者记录在自己的笔记软件。

    以下是我个人观点:

    写技术博客,博文格式首选markdown。写makrdown,博文内容所见即所得比预览或者人脑渲染更爽。

    博客发布平台,首选比较干净整洁的博客园。其他比如CSDN,简书,开源中国。很多人喜欢多平台一起发布,也没啥问题。

    把博客当作代码,托管在github/gitee。把博客当作知识库,放在个人博客网站,笔记软件,导图软件,都是主流选择。

    实际上我也想这么做,还没有付出更多的实际行动。

    有人说,使用windowns系列操作系统+写作或者笔记软件来写,或者在线写不香吗?或者离线写好,同步软件同步,粘贴到在线平台不香吗?

    实话说,挺香。

    选择【创作】【保存】【同步】【分享】的组合方式很多,但是我还是喜欢找到适合自己的舒服的方式。

    用typora写好了,右键分享一下,就能发布到博客,也挺香

    我个人的组合方式:deepin+typora+cnblogs+wiznote

    当然typora已经收费,wiznote已经发布Linux版本。更多更好的替代,都在排着队......

    ===================================================================

    着重和正式强调:不要拿博客平台当图床用,后果自负!!!

    ===================================================================

    2. 正式入题

    之前也写过一篇比较全面的博客《Deepin15和20使用命令行快捷键鼠标右键发布博客至博客园和为知笔记》

    在上面这篇博客中,你能在deepin上,用快捷键,用命令行,用右键三种姿势,来分享你的博客

    但是今天,我把代码改了改,2.0版本出来了。最重要的就是,能够上传图片了,香不香?

    2.1 python3+xmrpc.client实现代码

    以下是主要的代码:

    #!/usr/bin/env python3
    # -*- coding:utf-8 -*-
    # ***************************************************************************
    # * 
    # * @file:send_to_cnblogs.py 
    # * @author:liwanliang 
    # * @date:2021-12-08
    # * @version 2.0  
    # * @description: Python Script 
    # * @Copyright (c)  all right reserved 
    # * 
    # ***************************************************************************
    # 本脚本发送博客至www.cnblogs.com
    # --file 指定要上传的markdown博客文件
    # --upload 指定要上传的(多个)图片
    # ***************************************************************************
    
    import sys
    import xmlrpc.client #{'python3':"xmlrpc.client",'python2':"xmlrpclib"}
    import mimetypes
    import os
    import json
    import subprocess
    from optparse import OptionParser
    
    class CnblogsAPI():
        """
        从配置文件读取用户的:url,帐号,密码
        """
        def __init__(self,config_json):
            self.__url,self.__user,self.__password = self.__read_config(config_json)
            self.__cnblogs_api = xmlrpc.client.ServerProxy(self.__url)
            self.__user_info = self.__cnblogs_api.blogger.getUsersBlogs('',self.__user,self.__password)
            self.__user_blogid = self.__user_info[0].get('blogid')
    
        def __read_config(self,config):
            try:
                with open(config,'r') as f:
                    data = json.load(f)
                    url = data.get('url')
                    user = data.get('user')
                    password = data.get('password')
                    if not all([url,user,password]):
                        print("配置文件未正确指定:url,user,password")
                        sys.exit(0)
            except IOError:
                print("未指定配置文件")
                sys.exit(0)
            return (url,user,password)
                    
        def get_all_blogs(self):
            """
            获取全部博客:{title:postid}
            """
            blogs_title_postid = {}
            all_blogs = self.__cnblogs_api.metaWeblog.getRecentPosts(self.__user_blogid,self.__user,self.__password,0)
            for blog in all_blogs:
                blogs_title_postid.update({blog.get('title'):blog.get('postid')})
            return blogs_title_postid
    
        def __get_post_id(self,post_name):
            """
            通过博客标题获取博客的post_id
            """
            return self.get_all_blogs().get(post_name)
    
        def upload_image_get_url(self,image):
            """
            指定图片上传图片,返回图片的url
            """
            with open(image,'rb') as f:
                image_bits = xmlrpc.client.Binary(f.read())
            image_type = mimetypes.guess_type(image)[0]
            image_name = os.path.basename(image)
            url = self.__cnblogs_api.metaWeblog.newMediaObject(
                	self.__user_blogid,
                	self.__user,
                	self.__password,
                	dict(bits=image_bits,name=image_name,type=image_type))
            return url.get('url')
    
        def edit_post(self,blog_file):
            """
            指定博客文件上传,发送通知到操作系统
            """
            with open(blog_file,'r') as blog:
                blog_content = blog.read()
    
            post_name = os.path.basename(blog_file)
            post_id = self.__get_post_id(post_name)
            post_info = {
                'title':post_name,
                'description':blog_content,
                'categories':['[]','[Markdown]'],#默认不发送到博客园首页候选区,默认markdown格式
            }
    
            if post_id:
                return self.__cnblogs_api.metaWeblog.editPost(
                    	post_id,
                    	self.__user,
                    	self.__password,
                    	post_info,True)
            else:
                return self.__cnblogs_api.metaWeblog.newPost(
                    	self.__user_blogid,
                    	self.__user,
                    	self.__password,
                    	post_info,True)
    
    #****************************************************************************#
    #上面的代码,主要是封装接口,复用性很强,ctrl+c,ctrl+v拿走就行。
    # 下面的代码,就是个性化功能配置了
    # 我个人的配置文件:
    # 帐号密码配置文件,/home/liwl/.liwl/deepin/scripts/cnblogs.json
    # conblogs.json内容:
    #{
    #	"url":xxxx,
    #	"user":xxxx,
    #	"password":xxxx,
    #}
    # deepin分享博客成功后,发送一个系统通知,其icon图片
    # /home/liwl/.liwl/deepin/picture/cnblogs.png
    #****************************************************************************#
    if __name__ == "__main__":
        #脚本参数
        parser = OptionParser()
        parser.add_option("-f","--file",dest="filename")
        parser.add_option("-u","--upload",dest="image",action="append")
        (options,args) = parser.parse_args()
    
        #加载配置文件
        liwl_cnblogs = CnblogsAPI('/home/liwl/.liwl/deepin/scripts/cnblogs.json')
    
        #获取markdown博客
        markdown_blog = options.filename
        if options.filename:
            if liwl_cnblogs.edit_post(markdown_blog):
                subprocess.run('notify-send -i /home/liwl/.liwl/deepin/picture/cnblogs.png "创建/更新博客,成功"',shell=True)
            else:
                subprocess.run('notify-send -i /home/liwl/.liwl/deepin/picture/cnblogs.png "创建/更新博客,失败"',shell=True)
    
        #以下适合命令行发送
        #else:
            #subprocess.run('notify-send -i /home/liwl/.liwl/deepin/picture/cnblogs.png "未指定博客文件"',shell=True)
            
    
        #获取多个图片
        if options.image:
            for img in options.image + args:
                print(liwl_cnblogs.upload_image_get_url(img))
        #以下代码适合命令行发送
        #else:
            #subprocess.run('notify-send -i /home/liwl/.liwl/deepin/picture/cnblogs.png "未指定(多个)图片"',shell=True)
    

    上面的代码,保存到一个路径下:/home/liwl/.liwl/deepin/scripts/send_to_cnblogs.py

    注意赋予一个执行权限:chmod +x /home/liwl/.liwl/deepin/scripts/send_to_cnblogs.py

    2.2 deepin配置右键发送

    创建一个desktop文件:

    sudo vim /usr/share/deepin/dde-file-manager/oem-menuextensions/deepin-send.desktop

    内容如下:

    [Desktop Entry]
    Type=Application
    Name=发布文档到
    Actions=SendTocnblogs;SendTonsccwx;SendTowiznote
    X-DFM-MenuTypes=SingleFile
    MimeType=text/markdown
    
    [Desktop Action SendTocnblogs]
    Name=博客园
    Exec=python3 /home/liwl/.liwl/deepin/scripts/send_to_cnblogs.py --file %U
    Icon=send-to
    

    2.3 Typora配置上传图片

    如下图配置即可

    需要注意的是,【上传服务设定】-【命令】要写脚本绝对路径和参数,如下:

    python3 /home/liwl/.liwl/deepin/scripts/send_to_cnblogs.py --upload

    下面这张图,就是我截图之后,粘贴在typora,自动上传的哦

    image-20211208145559890

    3. 原理分析

    其实也没啥原理,主要是以前没有注意到metaWeblog.newMediaObject这个接口,这两天研究了一下,发现这个接口,就把这个脚本重新修改了一下

    简单理解:xmlrpc是一个协议,python实现了这个协议接口

    python2的协议接口为:xmlrpclib,python3的协议接口包为:xmlrpc.client

    博客园允许你使用这个协议来使用他们提供的接口,而且有个前提,你需要在自己的博客设置里面启用这个功能

    博客设置——其他设置——勾选允许MetaWeblog博客客户端访问

    Typora又恰好提供了使用命令或者脚本的方式来获取图片的url

    所以,一切都是那么顺其自然,挺幸运

    本篇博客就是在deepin系统下,写完了以后,右键发送到博客园的呢,右键

    image-20211208152257579

    发送成功后,deepin上方会有如下图提示:

    image-20211208150658598


    最后还是强调,不要把博客平台当作图床来用,否则后果自负

    【 欢迎交流探讨!邮箱:yunweinote@126.com】
  • 相关阅读:
    C# json转对象
    sit、qas、dev、pet
    vs professional 2019 离线安装包下载方法
    C# SHA512和Base64加解密方法
    C#获取客户端Ip工具类
    C#xml泛型序列化
    C#对象转换工具类
    C#记录日志到本地文件工具类
    05 Activity生命周期
    05 利用Appliction 传值Activity
  • 原文地址:https://www.cnblogs.com/liwanliangblog/p/15661783.html
Copyright © 2020-2023  润新知