背景
最近由MAC換成了Windows系統(tǒng)了,在寫博客的時(shí)候發(fā)現(xiàn)沒(méi)有類似于Mac上的iPic這樣好用的圖床工具,本著自己動(dòng)手豐衣足食的原則,準(zhǔn)備自己實(shí)現(xiàn)一個(gè),具體過(guò)程是在cmd中可以上傳指定圖片,然后生成md格式的圖片路徑,并復(fù)制到剪切板,在使用的時(shí)候可以直接粘貼即可
用到的技術(shù)
本次所用到的技術(shù)如下:
- Python3.6
- 阿里云OSS
- 阿里云ECS
- nginx
OSS
首先圖床應(yīng)用需要選擇圖片存儲(chǔ)的位置,恰好在雙十一的時(shí)候,阿里云贈(zèng)送了40G的OSS資源包,于是就選擇了阿里云的OSS
創(chuàng)建Bucket
阿里云的OSS在使用的時(shí)候首先需要?jiǎng)?chuàng)建Bucket,可以簡(jiǎn)單的理解為40G是我們硬盤的總大小,而B(niǎo)ucket是磁盤分區(qū),Bucket創(chuàng)建的時(shí)候,需要配置訪問(wèn)權(quán)限
這里需要注意的是區(qū)域需要選擇和你的ECS服務(wù)器是同一個(gè)區(qū)域的,因?yàn)檫@樣內(nèi)網(wǎng)訪問(wèn)才不會(huì)走流量,否則按照文檔上的說(shuō)法,是只能走公網(wǎng)訪問(wèn),而讀寫權(quán)限這里,我選擇的是公共讀,我的理解是可以訪問(wèn)圖片,而不能上傳圖片
Python代碼
接下來(lái)是Python的代碼部分,需求是上傳圖片,然后將符合MD格式的圖片文本寫入剪切板中,首先是代碼
import oss2
import uuid
import pyperclip #用來(lái)操作粘貼板
# 獲取遠(yuǎn)程文件名
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 = "![](%s%s%s)" % (PRE, remote_file_name,PIC_STYLE)
pyperclip.copy(result_str) # 將結(jié)果復(fù)制到粘貼板方便直接使用
print(result_str)
首先解釋一下用到的三個(gè)庫(kù)
oss2
這是阿里云的pythonsdk,可以通過(guò)pip進(jìn)行安裝
pip install oss2
在這里說(shuō)明一下我遇到的坑,由于是剛換的Windows,默認(rèn)的pip路徑是在User/用戶名下的,而我的用戶名設(shè)置的是中文的,Python3已經(jīng)默認(rèn)是utf8編碼了,但是windows系統(tǒng)的默認(rèn)編碼是gbk,所以導(dǎo)致pip幾乎不可用的狀態(tài),雖然可以改編碼格式,但是后來(lái)我在生成exe文件的時(shí)候又遇到坑了,在將用戶名修改為英文的之后就好了
pyperclip
這是一個(gè)讀寫剪切板的庫(kù),使用起來(lái)非常簡(jiǎn)單,但是只能讀寫文本類型
pip install pyperclip
它的核心方法就兩個(gè),一個(gè)是paste粘貼,一個(gè)copy將文本內(nèi)容復(fù)制剪切板,示例代碼
import pyperclip
pyperclip.copy("Hello World") # 這個(gè)時(shí)候你可以使用ctrl+v測(cè)試一下
s = pyperclip.paste()
print(s)
uuid
這里選擇uuid作為文件名,因?yàn)樯蟼鞯給ss上是基于文件名的,為了防止重名,所以上傳的圖片,都使用uuid進(jìn)行命名
代碼
pre是我的ECS服務(wù)器的IP地址,nginx監(jiān)聽(tīng)的是88端口,這后面再說(shuō),ENDPOINT和ACCESS_KEY_ID以及ACCESS_KEY_SECRET均可以在阿里云的網(wǎng)站上找到
而最后的參數(shù)是圖片的水印
整體的思路就是通過(guò) oss的sdk進(jìn)行上傳,在上傳時(shí)通過(guò)uuid生成一個(gè)云端的文件名,并最后與ECS的地址進(jìn)行拼接,最后生成符合MD的格式,寫入到剪切板中
生成EXE
目前的代碼已經(jīng)能夠使用了,但是使用的時(shí)候是Python腳本,需要在終端進(jìn)入腳本存放的文件夾,很不方便,所以想要生成一個(gè)exe文件,并加入到環(huán)境變量中,這樣使用起來(lái)就會(huì)方便很多,關(guān)于把python腳本打包成exe文件,使用了Pyinstaller
首先是通過(guò)Pip進(jìn)行安裝
pip install pyinstaller
然后在終端中進(jìn)入腳本所在的文件夾,執(zhí)行命令
pyinstaller --onefile upload.py
這樣就會(huì)將upload.py打包成exe文件,生成的exe文件目錄在dist文件夾中,接著把這個(gè)exe文件復(fù)制一份到d:\scripts路徑中,并把這個(gè)scripts加入到環(huán)境變量中,效果是在任何位置,終端中輸入upload 都可以使用這個(gè)命令例如
ps:我的終端使用的cmder,比window自帶的cmd或者powerShell的好處是命令與linux是一樣的,例如顯示當(dāng)前文件的文件命令是ls,而不是windows下的dir,并且自帶ssh
nginx
最開(kāi)始完成的時(shí)候,并沒(méi)有想到要使用nginx進(jìn)行代理,而是直接使用了oss提供的公網(wǎng)域名,但是用了1天阿里云給我來(lái)了短信,告訴我欠費(fèi)了,后來(lái)才知道,資源包只能是文件存儲(chǔ),而不包括公網(wǎng)流量,阿里云的客服告訴我,上傳時(shí)不需要付費(fèi)的,但是公網(wǎng)訪問(wèn)是需要按流量付費(fèi),但是如果是阿里云的服務(wù)器使用內(nèi)網(wǎng)訪問(wèn)則不需要付費(fèi),恰好我有一個(gè)測(cè)試用的小服務(wù)器,于是配置了一下nginx來(lái)進(jìn)行代理
nginx的安裝
安裝編譯工具及庫(kù)文件
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
- 進(jìn)入安裝目錄
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
-
進(jìn)入安裝包目錄
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的配置
首先創(chuàng)建Nginx運(yùn)行使用的用戶www
/usr/sbin/groupadd www
/usr/sbin/useradd -g www www
然后是配置nginx,找到你的nginx的配置文件 nginx.conf
user www www;
worker_processes 2; #設(shè)置值和CPU核心數(shù)一致
error_log /usr/local/webserver/nginx/logs/nginx_error.log crit; #日志位置和日志級(jí)別
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虛擬主機(jī)的配置
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;
}
}
}
重點(diǎn)是server中表示了監(jiān)聽(tīng)88端口,然后當(dāng)路徑是/img/的就會(huì)匹配,并通過(guò)proxy_pass來(lái)轉(zhuǎn)發(fā)到oss的內(nèi)網(wǎng)地址,這樣就實(shí)現(xiàn)了nginx的代理
至此,全部的功能就實(shí)現(xiàn)了
常用的Nginx命令
/usr/local/webserver/nginx/sbin/nginx # 啟動(dòng)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