最新更新於2022年02月24日
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 指定要上傳的(多個)圖片
# 更新:
# 2022-02-24: 更新博客時,如果博客之前有標簽,推送博客保持之前的標簽
# ***************************************************************************
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 __get_mt_keywords(self,post_name):
"""
獲取tag
"""
return self.__cnblogs_api.metaWeblog.getPost(self.__get_post_id(post_name),self.__user,self.__password).get('mt_keywords')
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)
mt_keywords = self.__get_mt_keywords(post_name) if post_id else "" #判斷tag是否存在,存在添加tag
post_info = {
'title':post_name,
'description':blog_content,
'categories':['[]','[Markdown]'],#默認不發送到博客園首頁候選區,默認markdown格式
'mt_keywords':mt_keywords, #添加tag
}
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,自動上傳的哦
3. 原理分析
其實也沒啥原理,主要是以前沒有注意到metaWeblog.newMediaObject
這個接口,這兩天研究了一下,發現這個接口,就把這個腳本重新修改了一下
簡單理解:xmlrpc是一個協議,python實現了這個協議接口
python2的協議接口為:xmlrpclib,python3的協議接口包為:xmlrpc.client
博客園允許你使用這個協議來使用他們提供的接口,而且有個前提,你需要在自己的博客設置里面啟用這個功能
博客設置——其他設置——勾選允許MetaWeblog博客客戶端訪問
Typora又恰好提供了使用命令或者腳本的方式來獲取圖片的url
所以,一切都是那么順其自然,挺幸運
本篇博客就是在deepin系統下,寫完了以后,右鍵發送到博客園的呢,右鍵
發送成功后,deepin上方會有如下圖提示:
最后還是強調,不要把博客平台當作圖床來用,否則后果自負