背景
最近由MAC換成了Windows系統了,在寫博客的時候發現沒有類似于Mac上的iPic這樣好用的圖床工具,本著自己動手豐衣足食的原則,準備自己實現一個,具體過程是在cmd中可以上傳指定圖片,然后生成md格式的圖片路徑,并復制到剪切板,在使用的時候可以直接粘貼即可
用到的技術
本次所用到的技術如下:
- Python3.6
- 阿里云OSS
- 阿里云ECS
- nginx
OSS
首先圖床應用需要選擇圖片存儲的位置,恰好在雙十一的時候,阿里云贈送了40G的OSS資源包,于是就選擇了阿里云的OSS
創建Bucket
阿里云的OSS在使用的時候首先需要創建Bucket,可以簡單的理解為40G是我們硬盤的總大小,而Bucket是磁盤分區,Bucket創建的時候,需要配置訪問權限
這里需要注意的是區域需要選擇和你的ECS服務器是同一個區域的,因為這樣內網訪問才不會走流量,否則按照文檔上的說法,是只能走公網訪問,而讀寫權限這里,我選擇的是公共讀,我的理解是可以訪問圖片,而不能上傳圖片
Python代碼
接下來是Python的代碼部分,需求是上傳圖片,然后將符合MD格式的圖片文本寫入剪切板中,首先是代碼
import oss2
import uuid
import pyperclip #用來操作粘貼板
# 獲取遠程文件名
def get_remote_file_name(local_name):
name = uuid.uuid4().__str__().replace("-", "").upper()
local_name = str(local_name).rsplit(".")
return "pics/%s.%s" % (name, local_name[-1])
BUCKET_NAME = "cfy-pic"
PRE = "http://**.**.**.**:88/img/"
ENDPOINT = "http://oss-cn-beijing.aliyuncs.com"
ACCESS_KEY_ID = "******"
ACCESS_KEY_SECRET = "*************"
PIC_STYLE = "?x-oss-process=style/CfyInfo"
src_file = sys.argv[1] # 獲取文件路徑
auth = oss2.Auth(ACCESS_KEY_ID, ACCESS_KEY_SECRET)
bucket = oss2.Bucket(auth, ENDPOINT, BUCKET_NAME)
remote_file_name = get_remote_file_name(src_file)
bucket.put_object_from_file(remote_file_name, src_file) # 上傳文件
result_str = "" % (PRE, remote_file_name,PIC_STYLE)
pyperclip.copy(result_str) # 將結果復制到粘貼板方便直接使用
print(result_str)
首先解釋一下用到的三個庫
oss2
這是阿里云的pythonsdk,可以通過pip進行安裝
pip install oss2
在這里說明一下我遇到的坑,由于是剛換的Windows,默認的pip路徑是在User/用戶名下的,而我的用戶名設置的是中文的,Python3已經默認是utf8編碼了,但是windows系統的默認編碼是gbk,所以導致pip幾乎不可用的狀態,雖然可以改編碼格式,但是后來我在生成exe文件的時候又遇到坑了,在將用戶名修改為英文的之后就好了
pyperclip
這是一個讀寫剪切板的庫,使用起來非常簡單,但是只能讀寫文本類型
pip install pyperclip
它的核心方法就兩個,一個是paste粘貼,一個copy將文本內容復制剪切板,示例代碼
import pyperclip
pyperclip.copy("Hello World") # 這個時候你可以使用ctrl+v測試一下
s = pyperclip.paste()
print(s)
uuid
這里選擇uuid作為文件名,因為上傳到oss上是基于文件名的,為了防止重名,所以上傳的圖片,都使用uuid進行命名
代碼
pre是我的ECS服務器的IP地址,nginx監聽的是88端口,這后面再說,ENDPOINT和ACCESS_KEY_ID以及ACCESS_KEY_SECRET均可以在阿里云的網站上找到
而最后的參數是圖片的水印
整體的思路就是通過 oss的sdk進行上傳,在上傳時通過uuid生成一個云端的文件名,并最后與ECS的地址進行拼接,最后生成符合MD的格式,寫入到剪切板中
生成EXE
目前的代碼已經能夠使用了,但是使用的時候是Python腳本,需要在終端進入腳本存放的文件夾,很不方便,所以想要生成一個exe文件,并加入到環境變量中,這樣使用起來就會方便很多,關于把python腳本打包成exe文件,使用了Pyinstaller
首先是通過Pip進行安裝
pip install pyinstaller
然后在終端中進入腳本所在的文件夾,執行命令
pyinstaller --onefile upload.py
這樣就會將upload.py打包成exe文件,生成的exe文件目錄在dist文件夾中,接著把這個exe文件復制一份到d:\scripts路徑中,并把這個scripts加入到環境變量中,效果是在任何位置,終端中輸入upload 都可以使用這個命令例如
ps:我的終端使用的cmder,比window自帶的cmd或者powerShell的好處是命令與linux是一樣的,例如顯示當前文件的文件命令是ls,而不是windows下的dir,并且自帶ssh
nginx
最開始完成的時候,并沒有想到要使用nginx進行代理,而是直接使用了oss提供的公網域名,但是用了1天阿里云給我來了短信,告訴我欠費了,后來才知道,資源包只能是文件存儲,而不包括公網流量,阿里云的客服告訴我,上傳時不需要付費的,但是公網訪問是需要按流量付費,但是如果是阿里云的服務器使用內網訪問則不需要付費,恰好我有一個測試用的小服務器,于是配置了一下nginx來進行代理
nginx的安裝
安裝編譯工具及庫文件
yum -y install mak zlib zlib-devel gcc-c++ libtool openssl openssl-devel
安裝PCRE
PCRE作用是讓Nginx支持Rewrite功能
- 下載PCRE安裝包
wget http://downloads.sourceforge.net/project/pcre/pcre/8.35/pcre-8.35.tar.gz
- 解壓安裝包
tar zxvf pcre-8.35.tar.gz
- 進入安裝目錄
cd pcre-8.35
- 編譯安裝
./configure make && make install
安裝Nginx
= 下載Nginx
shell wget http://nginx.org/download/nginx-1.6.2.tar.gz
-
解壓安裝包
tar zxvf nginx-1.6.2.tar.gz
-
進入安裝包目錄
cd nginx-1.6.2
-
編譯安裝
./configure --prefix=/usr/local/webserver/nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre=pcre的安裝路徑/pcre-8.35 make make install
至此Nginx就安裝完了
Nginx的配置
首先創建Nginx運行使用的用戶www
/usr/sbin/groupadd www
/usr/sbin/useradd -g www www
然后是配置nginx,找到你的nginx的配置文件 nginx.conf
user www www;
worker_processes 2; #設置值和CPU核心數一致
error_log /usr/local/webserver/nginx/logs/nginx_error.log crit; #日志位置和日志級別
pid /usr/local/webserver/nginx/nginx.pid;
#Specifies the value for maximum file descriptors that can be opened by this process.
worker_rlimit_nofile 65535;
events
{
use epoll;
worker_connections 65535;
}
http
{
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_for';
#charset gb2312;
server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 8m;
sendfile on;
tcp_nopush on;
keepalive_timeout 60;
tcp_nodelay on;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
#limit_zone crawler $binary_remote_addr 10m;
#下面是server虛擬主機的配置
server {
listen 88;
location /img/ {
proxy_pass http://cfy-pic.oss-cn-beijing-internal.aliyuncs.com/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
重點是server中表示了監聽88端口,然后當路徑是/img/的就會匹配,并通過proxy_pass來轉發到oss的內網地址,這樣就實現了nginx的代理
至此,全部的功能就實現了
常用的Nginx命令
/usr/local/webserver/nginx/sbin/nginx # 啟動Nginx
/usr/local/webserver/nginx/sbin/nginx -t # 檢查配置文件nginx.conf的正確性
/usr/local/webserver/nginx/sbin/nginx -s reload # 重新載入配置文件
/usr/local/webserver/nginx/sbin/nginx -s reopen # 重啟 Nginx
/usr/local/webserver/nginx/sbin/nginx -s stop # 停止 Nginx