版本: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)