Permalink
Browse files

v0.3.7 fix request error, add friends api tests

  • Loading branch information...
1 parent a280352 commit a21df560693dbf95d2add1b4645b802f600871a7 @andelf committed Jun 9, 2011
Showing with 410 additions and 91 deletions.
  1. +7 −0 Changelog
  2. +7 −5 README.md
  3. +25 −3 api.doc.rst
  4. +96 −0 docs/emotions.text
  5. +1 −1 qqweibo/api.py
  6. +36 −21 qqweibo/binder.py
  7. +3 −2 qqweibo/cache.py
  8. +2 −1 qqweibo/error.py
  9. +4 −20 qqweibo/parsers.py
  10. +1 −1 qqweibo/utils.py
  11. +228 −37 tests/test_pyqqweibo.py
View
@@ -1,3 +1,10 @@
+2011-06-08 andelf <andelf@gmail.com>
+ version 0.3.7
+ * qqweibo/binder.py
+ 加入 API 函数 doc string 支持
+ * tests/*
+ 加入单元测试
+
2011-06-05 andelf <andelf@gmail.com>
version 0.3.3
* qqweibo/api.py
View
@@ -7,7 +7,7 @@ By @andelf <andelf@gmail.com>
已经更新到 5.27 日 API 版本.
-我就不吐槽腾讯的 API 了.
+我就不吐槽腾讯的 API 了. 相关吐槽请参考 `api.doc.rst`.
特色
----
@@ -17,15 +17,17 @@ By @andelf <andelf@gmail.com>
* 可以返回 JSON 或 XML 数据(多 Parser 支持)
* 修改所有 API 绑定组织结构参数顺序及返回等
* 支持 Python 3
-
-具体参考 `api.doc.rst` 及 `Changelog`
+* 良好文档支持, 包括 doc string
+* 单元测试
使用方法
--------
-`api.doc.rst` 文件为参考文档.
+具体文档请参考 `api.doc.rst`.
+
+API 使用例子请参考 `tests``example` 目录下文件.
-相关例子请参考 `examples` 目录, 不过已经很过期了.
+简单 API 用法可直接 `help()`.
Further TODO
------------
View
@@ -501,6 +501,7 @@ add 发私信
unicode('请问下您的qqweibo 可以用了么', 'gbk'),
'must_use_real_ip')
<RetId id:495...>
+
delete 删除一条私信
:参数:
(id*)
@@ -641,6 +642,7 @@ add 添加标签
> api.tag.add('python')
<RetId id:7769480420947389987>
+
delete 删除标签
:参数:
(tagid*)
@@ -876,10 +878,14 @@ twitterid
但是事实上带的 url 是视频
* timeline.mentions 返回也有可能是被转发, 即, 不存在 @ 引用用户名
* 文档中关于参数限制很多是错的, 比如 reqnum
- * timeline.users 中 reqnum 最大 40, 否则服务器返回错误
+ * timeline.users 中 reqnum 最大数值不定, 超过某最大数值后服务器返回错误.
+ 一些情况下, 返回正常, 限制为 70
* timeline.userids, timeline.broadcastids, timeline.mentionsids
所返回 tweet 数和 reqnum 对应关系诡异. reqnum > 70 后完全不可控.
最多返回 210 条, reqnum = 210 时, 返回 150 条
+ * 极个别情况下, JSON API 返回 server error 后会在 JSON 数据后追加一个
+ "out of memery". 导致 JSON 解析失败. 一般是 tweet 类, 需要 POST 的 API.
+ * fridends 类 API 有些在添加删除不存在用户时出错, 另些不出错.
------
FAQ
@@ -889,7 +895,9 @@ FAQ
我还不知道.
-由于 Python 2.5 不支持 except ExceptionName as e 的语法. 所以本 SDK 不支持 Python 2.5-. 如有需要, 可以自行修改
+由于 Python 2.5 不支持 except ExceptionName as e 的语法.
+所以本 SDK 不支持 Python 2.5-. 如有需要, 可以自行修改.
+一般来说处理下 __future__ 和 except ... as ... 语法就可以.
-------------
错误代码查询
@@ -902,6 +910,7 @@ RET返回值说明
- Ret=2 频率受限
- Ret=3 鉴权失败
- Ret=4 服务器内部错误
+- Ret=-1 自定义, 用于表示 JSON 解析错误等
发表接口错误字段errcode 说明
@@ -915,6 +924,19 @@ RET返回值说明
- errcode=11 源消息已删除,如转播或回复时
- errcode=12 源消息审核中 errcode=13 重复发表
- errcode=13 重复发表
+
以下部分是我猜的.
-- errcode=18 Tag 已经存在
+- errcode=18 Tag 已经存在, 添加好友时用户名不存在
+- errcode=19
+- errcode=35 添加黑名单时用户不存在
+- errcode=65
+- errcode=89 添加删除特别收听时不是好友
+
+------------
+表情代码说明
+------------
+
+`/表情文字` 建议使用 javascript 处理.
+
+请参考 docs/emotions
View
@@ -0,0 +1,96 @@
+# URL: http://mat1.gtimg.com/www/mb/images/face/[id].gif
+# USEAGE: /emotion_name
+# id emotion_name
+0 惊讶
+1 撇嘴
+2 色
+3 发呆
+4 得意
+5 流泪
+6 害羞
+7 闭嘴
+8 睡
+9 大哭
+11 发怒
+12 调皮
+13 呲牙
+14 微笑
+15 难过
+16 酷
+18 抓狂
+20 偷笑
+21 可爱
+22 白眼
+23 傲慢
+24 饥饿
+25 困
+26 惊恐
+27 流汗
+29 大兵
+30 奋斗
+31 咒骂
+32 疑问
+33 嘘
+34 晕
+35 折磨
+36 衰
+37 骷髅
+38 敲打
+41 发抖
+42 爱情
+43 跳跳
+46 猪头
+53 蛋糕
+55 炸弹
+56 刀
+57 足球
+59 便便
+61 饭
+63 玫瑰
+64 凋谢
+66 爱心
+67 心碎
+69 礼物
+74 太阳
+75 月亮
+76 强
+77 弱
+78 握手
+79 胜利
+85 飞吻
+89 西瓜
+96 冷汗
+97 擦汗
+98 抠鼻
+99 鼓掌
+100 糗大了
+101 坏笑
+102 左哼哼
+104 哈欠
+105 鄙视
+106 委屈
+107 快哭了
+108 阴险
+109 亲亲
+111 可怜
+112 菜刀
+113 啤酒
+114 篮球
+115 乒乓
+116 示爱
+117 瓢虫
+118 抱拳
+119 勾引
+121 差劲
+122 爱你
+123 NO
+124 OK
+125 转圈
+126 磕头
+127 回头
+128 跳绳
+129 挥手
+130 激动
+132 献吻
+133 左太极
+134 右太极
View
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
# Copyright 2011 andelf <andelf@gmail.com>
# See LICENSE for details.
-# Time-stamp: <2011-06-04 19:33:54 andelf>
+# Time-stamp: <2011-06-08 19:24:04 andelf>
import os
import mimetypes
View
@@ -3,7 +3,7 @@
# Copyright 2009-2010 Joshua Roesslein
# Copyright 2011 andelf <andelf@gmail.com>
# See LICENSE for details.
-# Time-stamp: <2011-06-06 15:06:54 andelf>
+# Time-stamp: <2011-06-08 23:21:45 andelf>
import time
import re
@@ -99,11 +99,12 @@ def execute(self):
if self.method == 'GET':
url = '%s?%s' % (url, urlencode(self.parameters))
else:
- self.headers.setdefault("User-Agent", "python")
+ self.headers.setdefault("User-Agent", "pyqqweibo")
if self.post_data is None:
self.headers.setdefault("Accept", "text/html")
self.headers.setdefault("Content-Type", "application/x-www-form-urlencoded")
- self.post_data = urlencode(self.parameters).encode('ascii') # asure in bytes format
+ # asure in bytes format
+ self.post_data = urlencode(self.parameters).encode('ascii')
# Query the cache if one is available
# and this request uses a GET method.
if self.api.cache and self.method == 'GET':
@@ -143,8 +144,8 @@ def execute(self):
req = Request(url_full)
resp = urlopen(req)
except Exception as e:
- raise QWeiboError("Failed to send request: %s url=%s headers=%s" % \
- (e, url, self.headers))
+ raise QWeiboError("Failed to request %s headers=%s %s" % \
+ (url, self.headers, e))
# Exit request loop if non-retry error code
if self.retry_errors:
@@ -166,28 +167,31 @@ def execute(self):
eTime = '%.0f' % ((time.time() - sTime) * 1000)
postData = ""
if self.post_data is not None:
- postData = ",post:" + self.post_data[0:500]
+ postData = ",post:" + self.post_data[:500]
self.api.log.debug("%s, time: %s, %s result: %s" % (requestUrl, eTime, postData, body))
- ret_code = 0
+ retcode = 0
+ errcode = 0
# for py3k, ^_^
if not hasattr(body, 'encode'):
body = str(body, 'utf-8')
- try:
- if self.api.parser.payload_format == 'json':
+ if self.api.parser.payload_format == 'json':
+ try:
+ # BUG: API BUG, refer api.doc.rst
+ if body.endswith('out of memery'):
+ body = body[:body.rfind('}')+1]
json = self.api.parser.parse_error(self, body)
- ret_code = json['ret']
- error = json['msg']
+ retcode = json.get('ret', 0)
+ msg = json.get('msg', '')
+ # only in some post request
errcode = json.get('errcode', 0)
- error_msg = 'ret_code: %s, %s' % (ret_code, error)
- if errcode:
- error_msg += ' errcode: %s' % errcode
- except Exception as e:
- ret_code = -1
- error_msg = "Weibo error response: Error = %s" % e
- finally:
- if ret_code != 0:
- raise QWeiboError(error_msg)
+ except ValueError as e:
+ retcode = -1
+ msg = "Bad json format (%s)" % e
+ finally:
+ if retcode + errcode != 0:
+ raise QWeiboError("Response error: %s. (ret=%s, errcode=%s)" % \
+ (msg, retcode, errcode))
# Parse the response payload
result = self.api.parser.parse(self, body)
@@ -198,9 +202,20 @@ def execute(self):
return result
def _call(api, *args, **kargs):
-
method = APIMethod(api, args, kargs)
return method.execute()
+ # make doc string
+ if config.get('payload_list', False):
+ rettype = '[%s]' % config.get('payload_type', None)
+ else:
+ rettype = str(config.get('payload_type', None))
+ doc_string = """ \
+ Call API Method {:s}
+ ({:s}) => {:s}""".format(config['path'],
+ ', '.join(config.get('allowed_param', [])),
+ rettype)
+ _call.__doc__ = doc_string
+
return _call
View
@@ -2,7 +2,7 @@
# Copyright 2009-2010 Joshua Roesslein
# Copyright 2011 andelf <andelf@gmail.com>
# See LICENSE for details.
-# Time-stamp: <2011-06-03 13:29:22 andelf>
+# Time-stamp: <2011-06-08 15:08:40 andelf>
import time
import threading
@@ -153,7 +153,8 @@ def __init__(self, cache_dir, timeout=60):
def _get_path(self, key):
md5 = hashlib.md5()
- md5.update(key)
+ # fixed for py3.x
+ md5.update(key.encode('utf-8'))
return os.path.join(self.cache_dir, md5.hexdigest())
def _lock_file_dummy(self, path, exclusive=True):
View
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
# Copyright 2010 andelf <andelf@gmail.com>
# See LICENSE for details.
-# Time-stamp: <2011-06-03 13:30:10 andelf>
+# Time-stamp: <2011-06-08 15:15:00 andelf>
class QWeiboError(Exception):
"""basic weibo error class"""
@@ -14,3 +14,4 @@ def assertion(condition, msg):
assert condition, msg
except AssertionError as e:
raise QWeiboError(e.message)
+
Oops, something went wrong.

0 comments on commit a21df56

Please sign in to comment.