diff --git a/.gitignore b/.gitignore index 5f14585b..05a1b20a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ *.py[cod] +my-test-env.sh ## ## from https://github.com/github/gitignore/blob/master/Python.gitignore diff --git a/.travis.yml b/.travis.yml index da6b5dd2..a44b995b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,10 @@ python: - "2.6" - "2.7" before_script: - - source env.sh + - export QINIU_ACCESS_KEY="X0XpjFmLMTJpHB_ESHjeolCtipk-1U3Ok7LVTdoN" + - export QINIU_SECRET_KEY="wenlwkU1AYwNBf7Q9cCoG4VT_GYyrHE9AS_R2u81" + - export QINIU_TEST_BUCKET="pysdk" + - export QINIU_TEST_DOMAIN="pysdk.qiniudn.com" - export PYTHONPATH="$PYTHONPATH:." script: - python setup.py nosetests diff --git a/CHANGELOG.md b/CHANGELOG.md index 75937c9e..c9488412 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,11 @@ ## CHANGE LOG -### v6.0.2 +### v6.1.0 2013-07-03 issue [#53](https://github.com/qiniu/python-sdk/pull/53) - 实现最新版的上传API, + - io.PutExtra更新,废弃callback_params,bucket,和custom_meta,新增params - 修复[#16](https://github.com/qiniu/python-sdk/issues/16) - put接口可以传入类文件对象(file-like object) - 修复[#52](https://github.com/qiniu/python-sdk/issues/52) diff --git a/docs/demo.py b/docs/demo.py index 9c326f97..78afaf05 100644 --- a/docs/demo.py +++ b/docs/demo.py @@ -51,9 +51,9 @@ def _setup(): if access_key is None: exit("请配置环境变量 QINIU_ACCESS_KEY") secret_key = getenv("QINIU_SECRET_KEY") - bucket_name = getenv("QINIU_BUCKET_NAME") - domain = getenv("QINIU_DOMAIN") - pickey = getenv("QINIU_PIC_KEY") + bucket_name = getenv("QINIU_TEST_BUCKET") + domain = getenv("QINIU_TEST_DOMAIN") + pickey = 'QINIU_UNIT_TEST_PIC' setup(access_key, secret_key, bucket_name, domain, pickey) def getenv(name): diff --git a/env.sh b/env.sh deleted file mode 100644 index 027451ce..00000000 --- a/env.sh +++ /dev/null @@ -1,6 +0,0 @@ -export QINIU_ACCESS_KEY="X0XpjFmLMTJpHB_ESHjeolCtipk-1U3Ok7LVTdoN" -export QINIU_SECRET_KEY="wenlwkU1AYwNBf7Q9cCoG4VT_GYyrHE9AS_R2u81" -export QINIU_PIC_KEY="hello_jpg" -export QINIU_NOEXIST_PIC_KEY="no_exist" -export QINIU_BUCKET_NAME="pysdk" -export QINIU_DOMAIN="pysdk.qiniudn.com" diff --git a/qiniu/__init__.py b/qiniu/__init__.py index 4af2da42..8f4fd410 100644 --- a/qiniu/__init__.py +++ b/qiniu/__init__.py @@ -7,4 +7,4 @@ ''' # -*- coding: utf-8 -*- -__version__ = '6.0.1' +__version__ = '6.1.0' diff --git a/qiniu/io.py b/qiniu/io.py index 821b25ff..ff4214e4 100644 --- a/qiniu/io.py +++ b/qiniu/io.py @@ -32,8 +32,8 @@ def put(uptoken, key, data, extra=None): extra = PutExtra() if extra.params: - for key in extra.params: - fields[key] = str(extra.params[key]) + for k in extra.params: + fields[k] = str(extra.params[k]) if extra.check_crc: fields["crc32"] = str(extra.crc32) diff --git a/qiniu/rpc.py b/qiniu/rpc.py index f5dc7599..d250dba4 100644 --- a/qiniu/rpc.py +++ b/qiniu/rpc.py @@ -110,7 +110,8 @@ def encode_multipart_formdata(self, fields, files): L.append('') L.append('--' + BOUNDARY) disposition = "Content-Disposition: form-data;" - L.append('%s name="file"; filename="%s"' % (disposition, file_info.get('filename'))) + filename = _qiniu_escape(file_info.get('filename')) + L.append('%s name="file"; filename="%s"' % (disposition, filename)) L.append('Content-Type: %s' % file_info.get('content_type', 'application/octet-stream')) L.append('') L.append('') @@ -127,6 +128,12 @@ def encode_multipart_formdata(self, fields, files): content_type = 'multipart/form-data; boundary=%s' % BOUNDARY return content_type, MultiReader(readers) +def _qiniu_escape(s): + edits = [('\\', '\\\\'), ('\"', '\\\"')] + for (search, replace) in edits: + s = s.replace(search, replace) + return s + class MultiReader(object): """ class MultiReader([readers...]) diff --git a/qiniu/rs/test/__init__.py b/qiniu/rs/test/__init__.py index e5d9c4d3..f290dd77 100644 --- a/qiniu/rs/test/__init__.py +++ b/qiniu/rs/test/__init__.py @@ -7,12 +7,12 @@ import qiniu.conf pic = "http://cheneya.qiniudn.com/hello_jpg" +key = 'QINIU_UNIT_TEST_PIC' def setUp(): qiniu.conf.ACCESS_KEY = os.getenv("QINIU_ACCESS_KEY") qiniu.conf.SECRET_KEY = os.getenv("QINIU_SECRET_KEY") - key = os.getenv("QINIU_PIC_KEY") - bucket_name = os.getenv("QINIU_BUCKET_NAME") + bucket_name = os.getenv("QINIU_TEST_BUCKET") policy = qiniu.rs.PutPolicy(bucket_name) uptoken = policy.token() diff --git a/qiniu/rs/test/rs_test.py b/qiniu/rs/test/rs_test.py index a4cd7e48..a18cec66 100644 --- a/qiniu/rs/test/rs_test.py +++ b/qiniu/rs/test/rs_test.py @@ -13,9 +13,9 @@ def r(length): conf.ACCESS_KEY = os.getenv("QINIU_ACCESS_KEY") conf.SECRET_KEY = os.getenv("QINIU_SECRET_KEY") -key = os.getenv("QINIU_PIC_KEY") -bucket_name = os.getenv("QINIU_BUCKET_NAME") -noexist_key = os.getenv("QINIU_NOEXIST_PIC_KEY") +key = 'QINIU_UNIT_TEST_PIC' +bucket_name = os.getenv("QINIU_TEST_BUCKET") +noexist_key = 'QINIU_UNIT_TEST_NOEXIST' + r(30) key2 = "rs_demo_test_key_1_" + r(5) key3 = "rs_demo_test_key_2_" + r(5) key4 = "rs_demo_test_key_3_" + r(5) diff --git a/qiniu/rs/test/rs_token_test.py b/qiniu/rs/test/rs_token_test.py index e2fcd842..eb09f3c1 100644 --- a/qiniu/rs/test/rs_token_test.py +++ b/qiniu/rs/test/rs_token_test.py @@ -14,9 +14,9 @@ conf.ACCESS_KEY = os.getenv("QINIU_ACCESS_KEY") conf.SECRET_KEY = os.getenv("QINIU_SECRET_KEY") -bucket_name = os.getenv("QINIU_BUCKET_NAME") -domain = os.getenv("QINIU_DOMAIN") -key = os.getenv("QINIU_PIC_KEY") +bucket_name = os.getenv("QINIU_TEST_BUCKET") +domain = os.getenv("QINIU_TEST_DOMAIN") +key = 'QINIU_UNIT_TEST_PIC' class TestToken(unittest.TestCase): def test_put_policy(self): diff --git a/qiniu/test/io_test.py b/qiniu/test/io_test.py index 4d2f7ee6..1fe23408 100644 --- a/qiniu/test/io_test.py +++ b/qiniu/test/io_test.py @@ -16,11 +16,12 @@ conf.ACCESS_KEY = os.getenv("QINIU_ACCESS_KEY") conf.SECRET_KEY = os.getenv("QINIU_SECRET_KEY") -bucket_name = os.getenv("QINIU_BUCKET_NAME") +bucket_name = os.getenv("QINIU_TEST_BUCKET") policy = rs.PutPolicy(bucket_name) extra = io.PutExtra() extra.mime_type = "text/plain" +extra.params = {'x:a':'a'} def r(length): lib = string.ascii_uppercase @@ -36,6 +37,7 @@ def test_put(): extra.crc32 = binascii.crc32(data) & 0xFFFFFFFF ret, err = io.put(policy.token(), key, data, extra) assert err is None + assert ret['key'] == key def test_put_same_crc(): key = "test_%s" % r(9) @@ -43,16 +45,33 @@ def test_put_same_crc(): extra.check_crc = 2 ret, err = io.put(policy.token(), key, data, extra) assert err is None + assert ret['key'] == key def test_put_no_key(): data = r(100) - ret, err = io.put(policy.token(), key=None, data=data) + extra.check_crc = 0 + ret, err = io.put(policy.token(), key=None, data=data, extra=extra) assert err is None + assert ret['hash'] == ret['key'] + + def test_put_quote_key(): + data = r(100) + key = 'a\\b\\c"你好' + r(9) + ret, err = io.put(policy.token(), key, data) + print err + assert err is None + assert ret['key'].encode('utf8') == key + + data = r(100) + key = u'a\\b\\c"你好' + r(9) + ret, err = io.put(policy.token(), key, data) + assert err is None + assert ret['key'] == key def test_put_unicode1(): key = "test_%s" % r(9) + '你好' data = key - ret, err = io.put(policy.token(), key, data) + ret, err = io.put(policy.token(), key, data, extra) assert err is None assert ret[u'key'].endswith(u'你好') @@ -86,12 +105,14 @@ def test_put_StringIO(): data = cStringIO.StringIO('hello buddy!') ret, err = io.put(policy.token(), key, data) assert err is None + assert ret['key'] == key def test_put_urlopen(): key = "test_%s" % r(9) data = urllib.urlopen('http://cheneya.qiniudn.com/hello_jpg') ret, err = io.put(policy.token(), key, data) assert err is None + assert ret['key'] == key def test_put_no_length(): class test_reader(object): @@ -113,10 +134,12 @@ def read(self, n=None): extra.crc32 = binascii.crc32('abc') & 0xFFFFFFFF ret, err = io.put(policy.token(), key, data, extra) assert err is None + assert ret['key'] == key test_put() test_put_same_crc() test_put_no_key() + test_put_quote_key() test_put_unicode1() test_put_unicode2() test_put_unicode3() @@ -132,7 +155,7 @@ def test_put_file(self): extra.check_crc = 1 ret, err = io.put_file(policy.token(), key, localfile, extra) assert err is None - assert ret is not None + assert ret['key'] == key def test_put_crc_fail(self): key = "test_%s" % r(9) diff --git a/qiniu/test/resumable_io_test.py b/qiniu/test/resumable_io_test.py index 579ac046..0f03b0aa 100644 --- a/qiniu/test/resumable_io_test.py +++ b/qiniu/test/resumable_io_test.py @@ -16,7 +16,7 @@ from qiniu import resumable_io from qiniu import rs -bucket = os.getenv("QINIU_BUCKET_NAME") +bucket = os.getenv("QINIU_TEST_BUCKET") conf.ACCESS_KEY = os.getenv("QINIU_ACCESS_KEY") conf.SECRET_KEY = os.getenv("QINIU_SECRET_KEY") diff --git a/qiniu/test/rsf_test.py b/qiniu/test/rsf_test.py index 1aa24d1a..1ad002a5 100644 --- a/qiniu/test/rsf_test.py +++ b/qiniu/test/rsf_test.py @@ -6,7 +6,7 @@ import os conf.ACCESS_KEY = os.getenv("QINIU_ACCESS_KEY") conf.SECRET_KEY = os.getenv("QINIU_SECRET_KEY") -bucket_name = os.getenv("QINIU_BUCKET_NAME") +bucket_name = os.getenv("QINIU_TEST_BUCKET") class TestRsf(unittest.TestCase): def test_list_prefix(self): diff --git a/test-env.sh b/test-env.sh new file mode 100644 index 00000000..cb40c24b --- /dev/null +++ b/test-env.sh @@ -0,0 +1,4 @@ +export QINIU_ACCESS_KEY="" +export QINIU_SECRET_KEY="" +export QINIU_TEST_BUCKET="" +export QINIU_TEST_DOMAIN=""