版本:qiniu==7.0.8
環境:Mac os 10.12.3
最近寫了一套七牛上傳的工具包,涉及到中文歌曲路徑,就會報錯:
File "/Users/ouyang/PycharmProjects/myApp/venv/lib/python2.7/site-packages/qiniu/services/storage/upload_progress_recorder.py", line 34, in get_upload_record
record_file_name = base64.b64encode(key.encode('utf-8')).decode('utf-8')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 5: ordinal not in range(128)
查看問題代碼位於/Users/ouyang/PycharmProjects/myApp/venv/lib/python2.7/site-packages/qiniu/services/storage/uploader.py”:
def get_upload_record(self, file_name, key):
key = '{0}/{1}'.format(key, file_name)
record_file_name = base64.b64encode(key.encode('utf-8')).decode('utf-8')
upload_record_file_path = os.path.join(self.record_folder,
record_file_name)
if not os.path.isfile(upload_record_file_path):
return None
with open(upload_record_file_path, 'r') as f:
json_data = json.load(f)
return json_data
上面的file_name是unicode字符串,但key='{0}/{1}’.format(key, file_name)這裏是容不下unicode字符串的。
解決方案一
我們自己把所有的設計unicode的編碼都手動改成utf-8,然後保證傳進來的都是utf-8即可。
只需要修改兩個文件的部分代碼即可:
upload_process_recorder.py:
# -*- coding: utf-8 -*-
import base64
import json
import os
import tempfile
class UploadProgressRecorder(object):
"""持久化上傳記錄類
該類默認保存每個文件的上傳記錄到文件系統中,用於斷點續傳
上傳記錄爲json格式:
{
"size": file_size,
"offset": upload_offset,
"modify_time": file_modify_time,
"contexts": contexts
}
Attributes:
record_folder: 保存上傳記錄的目錄
"""
def __init__(self, record_folder=tempfile.gettempdir()):
self.record_folder = record_folder
def get_upload_record(self, file_name, key):
if type(file_name) is unicode:
file_name = file_name.encode('utf-8')
key = '{0}/{1}'.format(key, file_name)
# record_file_name = base64.b64encode(key.encode('utf-8')).decode('utf-8')
record_file_name = base64.b64encode(key)
record_file_name = record_file_name.replace('/', '_') # 去掉/字符的出現在路徑的可能性
upload_record_file_path = os.path.join(self.record_folder,
record_file_name)
print record_file_name
if not os.path.isfile(upload_record_file_path):
return None
with open(upload_record_file_path, 'r') as f:
json_data = json.load(f)
return json_data
def set_upload_record(self, file_name, key, data):
if type(file_name) is unicode:
file_name = file_name.encode('utf-8')
key = '{0}/{1}'.format(key, file_name)
# record_file_name = base64.b64encode(key.encode('utf-8')).decode('utf-8')
record_file_name = base64.b64encode(key)
record_file_name = record_file_name.replace('/', '_')
upload_record_file_path = os.path.join(self.record_folder,
record_file_name)
with open(upload_record_file_path, 'w') as f:
json.dump(data, f)
def delete_upload_record(self, file_name, key):
if type(file_name) is unicode:
file_name = file_name.encode('utf-8')
key = '{0}/{1}'.format(key, file_name)
record_file_name = base64.b64encode(key)
record_file_name = record_file_name.replace('/', '_')
# record_file_name = base64.b64encode(key.encode('utf-8')).decode('utf-8')
record_file_path = os.path.join(self.record_folder,
record_file_name)
os.remove(record_file_path)
uploader.py:
這個只加了兩行(143-144):
if type(self.file_name) is unicode:
self.file_name = self.file_name.encode('utf-8')
解決方案二
# 修改文件名爲非中文,不然七牛那邊好麻煩...歌曲上傳到七牛
song_path = full_file_path.replace(single_name, 'a.mp3')
os.rename(full_file_path, full_file_path.replace(single_name, 'a.mp3’))
# 再把文件名改回去...
os.rename(full_file_path.replace(single_name, 'a.mp3'), full_file_path)