Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

add mit license file

  • Loading branch information...
commit 0b1d48953408d7ba77467a912681957a01f74351 1 parent 88cf417
@andelf authored
View
20 LICENSE
@@ -0,0 +1,20 @@
+MIT License
+Copyright (c) 2011 andelf <andelf@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
View
20 LICENSE.tweepy
@@ -0,0 +1,20 @@
+MIT License
+Copyright (c) 2009-2010 Joshua Roesslein
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
View
16 example.py
@@ -1,11 +1,11 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# FileName : example.py
-# Author : Feather.et.ELF <andelf@139.com>
-# Created : Mon Apr 04 01:12:20 2011 by Feather.et.ELF
-# Copyright : Feather Workshop (c) 2011
-# Description : A example file
-# Time-stamp: <2011-04-07 13:31:59 andelf>
+# FileName : example.py
+# Author : Feather.et.ELF <andelf@139.com>
+# Created : Mon Apr 04 01:12:20 2011 by Feather.et.ELF
+# Copyright : Feather Workshop (c) 2011
+# Description : A example file
+# Time-stamp: <2011-04-08 10:43:28 andelf>
import sys
@@ -100,7 +100,7 @@ def dumpMsg(msgs):
print api.info()
# TEST: unkown, bad, must use all parameter
-#print api.update(introduction=u'just a test')
+#print api.update(introduction=u'just a test')
# TEST: ok
#print api.update_head(ur'C:\Documents and Settings\Administrator\My Documents\My Pictures\me\无标题3453.JPG')
@@ -166,7 +166,7 @@ def dumpMsg(msgs):
print '-'* 20
# TEST: fail, access rate limit
-#print api.userbytag(u'python', 15)
+#print api.userbytag(u'python', 15)
#print api.ht()
View
61 qqweibo/api.py
@@ -160,21 +160,21 @@ def add_pic(self, filename, content, clientip, jing=None, wei=None):
headers, post_data = API._pack_image(filename, 1024, content=content, clientip=clientip, jing=jing, wei=wei, contentname="pic")
args = [content, clientip]
allowed_param = ['content', 'clientip']
-
+
if jing is not None:
args.append(jing)
allowed_param.append('jing')
-
+
if wei is not None:
args.append(wei)
allowed_param.append('wei')
-
+
return bind_api(
path = '/api/t/add_pic',
method = 'POST',
payload_type = 'json',
require_auth = True,
- allowed_param = allowed_param
+ allowed_param = allowed_param
)(self, *args, post_data=post_data, headers=headers)
""" 7.t/re_count 转播数或点评数 """ # FIXME
@@ -224,7 +224,7 @@ def add_pic(self, filename, content, clientip, jing=None, wei=None):
'url'], # supports: youku,tudou,ku6
require_auth = True
)
-
+
""" 12.t/getvideoinfo 获取视频信息 """
getvideoinfo = bind_api(
path = '/api/t/getvideoinfo',
@@ -258,12 +258,12 @@ def update_head(self, filename):
headers, post_data = API._pack_image(filename, 1024, contentname="pic")
args = []
allowed_param = []
-
+
return bind_api(
path = '/api/user/update_head',
method = 'POST',
require_auth = True,
- allowed_param = allowed_param
+ allowed_param = allowed_param
)(self, *args, post_data=post_data, headers=headers)
""" 4.user/other_info 获取其他人资料 """
@@ -297,7 +297,7 @@ def update_head(self, filename):
payload_type = 'user', payload_list = True,
allowed_param = ['reqnum', 'startindex'],
require_auth = True
- )
+ )
""" 4.Friends/speciallist 特别收听列表 """
speciallist = bind_api(
@@ -305,7 +305,7 @@ def update_head(self, filename):
payload_type = 'user', payload_list = True,
allowed_param = ['reqnum', 'startindex'],
require_auth = True
- )
+ )
""" 5.friends/add 收听某个用户 """
@@ -315,7 +315,7 @@ def update_head(self, filename):
method = 'POST',
allowed_param = ['name'],
require_auth = True
- )
+ )
""" 6.friends/del取消收听某个用户 """
# TODO: fix confilicts with add message
@@ -324,7 +324,7 @@ def update_head(self, filename):
method = 'POST',
allowed_param = ['name'],
require_auth = True
- )
+ )
""" 7.friends/addspecial 特别收听某个用户 """
addspecial = bind_api(
@@ -332,7 +332,7 @@ def update_head(self, filename):
method = 'POST',
allowed_param = ['name'],
require_auth = True
- )
+ )
""" 8.friends/delspecial 取消特别收听某个用户 """
delspecial = bind_api(
@@ -340,7 +340,7 @@ def update_head(self, filename):
method = 'POST',
allowed_param = ['name'],
require_auth = True
- )
+ )
""" 9.friends/addblacklist 添加某个用户到黑名单 """
addblacklist = bind_api(
@@ -348,7 +348,7 @@ def update_head(self, filename):
method = 'POST',
allowed_param = ['name'],
require_auth = True
- )
+ )
""" 10.friends/delblacklist 从黑名单中删除某个用户 """
delblacklist = bind_api(
@@ -356,8 +356,7 @@ def update_head(self, filename):
method = 'POST',
allowed_param = ['name'],
require_auth = True
- )
-
+ )
""" 11.friends/check 检测是否我的听众或收听的人 """
check = bind_api(
@@ -365,7 +364,7 @@ def update_head(self, filename):
payload_type = 'tweet', payload_list = True,
allowed_param = ['names', 'flag'],
require_auth = True
- )
+ )
""" 12.friends/user_fanslist 其他帐户听众列表 """
user_fanslist = bind_api(
@@ -389,15 +388,15 @@ def update_head(self, filename):
payload_type = 'user', payload_list = True,
allowed_param = ['name', 'reqnum', 'startindex'],
require_auth = True
- )
+ )
- ## 私信相关 ""
+ ## 私信相关 ##
""" 1.private/add 发私信 """
padd = bind_api(
path = '/api/private/add',
method = 'POST',
- payload_type = 'tweet', payload_list = True,
+ payload_type = 'json',
allowed_param = ['content', 'clientip', 'jing',
'wei', 'name'],
require_auth = True
@@ -407,7 +406,7 @@ def update_head(self, filename):
pdel = bind_api(
path = '/api/private/del',
method = 'POST',
- payload_type = 'tweet', payload_list = True,
+ payload_type = 'json',
allowed_param = ['id'],
require_auth = True
)
@@ -416,8 +415,7 @@ def update_head(self, filename):
recv = bind_api(
path = '/api/private/recv',
payload_type = 'tweet', payload_list = True,
- allowed_param = ['pageflag', 'pagetime', 'reqnum',
- 'lastid'],
+ allowed_param = ['pageflag', 'pagetime', 'reqnum', 'lastid'],
require_auth = True
)
@@ -434,7 +432,7 @@ def update_head(self, filename):
""" 1.Search/user 搜索用户 """
user = bind_api(
path = '/api/search/user',
- payload_type = 'tweet', payload_list = True,
+ payload_type = 'user', payload_list = True,
allowed_param = ['keyword', 'pagesize', 'page'],
require_auth = True
)
@@ -450,11 +448,12 @@ def update_head(self, filename):
""" 3.Search/userbytag 通过标签搜索用户 """
userbytag = bind_api(
path = '/api/search/userbytag',
- payload_type = 'tweet', payload_list = True,
+ payload_type = 'user', payload_list = True,
allowed_param = ['keyword', 'pagesize', 'page'],
require_auth = True
)
+ # TODO: model parser
## 热度,趋势 ##
""" 1.trends/ht 话题热榜 """
ht = bind_api(
@@ -577,7 +576,7 @@ def update_head(self, filename):
####################
-
+
""" Get the authenticated user """
def me(self):
return self.get_user(screen_name=self.auth.get_username())
@@ -607,7 +606,7 @@ def _pack_image(filename, max_size, content=None, clientip=None, jing=None, wei=
fp = open(filename, 'rb')
BOUNDARY = 'QqWeIbObYaNdElF'
body = []
- if content is not None:
+ if content is not None:
body.append('--' + BOUNDARY)
body.append('Content-Disposition: form-data; name="content"')
body.append('Content-Type: text/plain; charset=UTF-8')
@@ -616,21 +615,21 @@ def _pack_image(filename, max_size, content=None, clientip=None, jing=None, wei=
if isinstance(content, unicode):
content = content.encode('utf-8')
body.append(content)
- if clientip is not None:
+ if clientip is not None:
body.append('--' + BOUNDARY)
body.append('Content-Disposition: form-data; name="clientip"')
body.append('Content-Type: text/plain; charset=US-ASCII')
body.append('Content-Transfer-Encoding: 8bit')
body.append('')
body.append(clientip)
- if jing is not None:
+ if jing is not None:
body.append('--' + BOUNDARY)
body.append('Content-Disposition: form-data; name="jing"')
body.append('Content-Type: text/plain; charset=US-ASCII')
body.append('Content-Transfer-Encoding: 8bit')
body.append('')
body.append(jing)
- if wei is not None:
+ if wei is not None:
body.append('--' + BOUNDARY)
body.append('Content-Disposition: form-data; name="wei"')
body.append('Content-Type: text/plain; charset=US-ASCII')
@@ -645,7 +644,7 @@ def _pack_image(filename, max_size, content=None, clientip=None, jing=None, wei=
body.append(fp.read())
body.append('--' + BOUNDARY + '--')
body.append('')
- fp.close()
+ fp.close()
body.append('--' + BOUNDARY + '--')
body.append('')
body = '\r\n'.join(body)
View
14 qqweibo/auth.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright 2009-2010 Joshua Roesslein
-# Copyright 2010 andelf<andelf@gmail.com>
+# Copyright 2010 andelf <andelf@gmail.com>
# See LICENSE for details.
from urllib2 import Request, urlopen
@@ -37,7 +37,7 @@ def __init__(self, username, password):
def apply_auth(self, url, method, headers, parameters):
headers['Authorization'] = 'Basic %s' % self._b64up
-
+
def get_username(self):
return self.username
@@ -132,20 +132,20 @@ def get_access_token(self, verifier=None):
)
request.sign_request(self._sigmethod, self._consumer, self.request_token)
- # send request
+ # send request
resp = urlopen(Request(request.to_url())) # must
self.access_token = oauth.OAuthToken.from_string(resp.read())
-
+
print 'Access token key: '+ str(self.access_token.key)
print 'Access token secret: '+ str(self.access_token.secret)
-
+
return self.access_token
except Exception, e:
raise WeibopError(e)
-
+
def setToken(self, token, tokenSecret):
self.access_token = oauth.OAuthToken(token, tokenSecret)
-
+
def get_username(self):
if self.username is None:
api = API(self)
View
16 qqweibo/binder.py
@@ -18,14 +18,14 @@
def bind_api(**config):
class APIMethod(object):
-
+
path = config['path']
payload_type = config.get('payload_type', None)
payload_list = config.get('payload_list', False)
allowed_param = config.get('allowed_param', [])
method = config.get('method', 'GET')
require_auth = config.get('require_auth', False)
-
+
def __init__(self, api, args, kargs):
# If authentication is required and no credentials
# are provided, throw an error.
@@ -44,7 +44,7 @@ def __init__(self, api, args, kargs):
# self.api_root = api.search_root
#else:
self.api_root = api.api_root
-
+
# Perform any path variable substitution
self.build_path()
@@ -94,14 +94,14 @@ def execute(self):
url = self.api_root + self.path
#if self.api.source is not None:
# self.parameters.setdefault('source',self.api.source)
-
+
if len(self.parameters):
if self.method == 'GET':
url = '%s?%s' % (url, urllib.urlencode(self.parameters))
else:
self.headers.setdefault("User-Agent","python")
if self.post_data is None:
- self.headers.setdefault("Accept","text/html")
+ self.headers.setdefault("Accept","text/html")
self.headers.setdefault("Content-Type","application/x-www-form-urlencoded")
self.post_data = urllib.urlencode(self.parameters)
# Query the cache if one is available
@@ -167,9 +167,9 @@ def execute(self):
ret_code = json['ret']
error = json['msg']
errcode = json.get('errcode', 0)
- error_msg = 'ret_code: %s, %s ' % (errcode, error)
+ error_msg = 'ret_code: %s, %s' % (errcode, error)
if errcode:
- error_msg += 'errcode: %s' % errcode
+ error_msg += ' errcode: %s' % errcode
except Exception as e:
ret_code = -1
print e
@@ -177,7 +177,7 @@ def execute(self):
finally:
if ret_code!= 0: # fixed
raise WeibopError(error_msg)
-
+
# Parse the response payload
result = self.api.parser.parse(self, body)
View
96 qqweibo/models.py
@@ -1,7 +1,7 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright 2009-2010 Joshua Roesslein
-# Copyright 2011 andelf<andelf@gmail.com>
+# Copyright 2011 andelf <andelf@gmail.com>
# See LICENSE for details.
from utils import parse_datetime, parse_html_value, parse_a_href, \
@@ -76,7 +76,7 @@ def reply(self, content, clientip='127.0.0.1', jing=None, wei=None):
def comment(self, content, clientip='127.0.0.1', jing=None, wei=None):
return self._api.comment(content, clientip, reid=self.id)
-
+
#def retweets(self):
# return self._api.retweets(self.id)
@@ -112,7 +112,7 @@ def parse(cls, api, json):
return source
else:
return None
-
+
class User(Model):
def __repr__(self):
@@ -143,7 +143,7 @@ def parse(cls, api, json):
setattr(user, 'self', False) # is this myself?
else:
setattr(user, 'self', True)
-
+
return user
def update(self, **kwargs):
@@ -169,33 +169,67 @@ def timeline(self, **kargs):
# def followers(self, **kargs):
# return self._api.followers(user_id=self.id, **kargs)
- def follow(self):
+ def add(self):
+ """收听某个用户"""
assert not bool(self.self), "you can't follow your self"
if self.ismyidol:
return # already flollowed
else:
self._api.add(name=self.name)
- add = flollow
- def unfollow(self):
+ follow = add
+ def del_(self):
+ """取消收听某个用户"""
assert not bool(self.self), "you can't unfollow your self"
if self.ismyidol:
self._api.del_(name=self.name)
else:
pass
- del_ = unfollow
-
-
-
- def lists_subscriptions(self, *args, **kargs):
- return self._api.lists_subscriptions(user=self.screen_name, *args, **kargs)
-
- def lists(self, *args, **kargs):
- return self._api.lists(user=self.screen_name, *args, **kargs)
+ unfollow = del_
+
+ def addspecial(self):
+ """特别收听某个用户"""
+ assert not bool(self.self), "you can't follow yourself"
+ self._api.addspecial(name=self.name)
+
+ def delspecial(self):
+ """取消特别收听某个用户"""
+ assert not bool(self.self), "you can't follow yourself"
+ self._api.delspecial(name=self.name)
+
+ def addblacklist(self):
+ """添加某个用户到黑名单"""
+ assert not bool(self.self), "you can't block yourself"
+ self._api.addblacklist(name=self.name)
+ block = addblacklist
+
+ def delblacklist(self):
+ """从黑名单中删除某个用户"""
+ assert not bool(self.self), "you can't block yourself"
+ self._api.delblacklist(name=self.name)
+ unblock = delblacklist
+
+ def fanslist(self, *args, **kwargs):
+ """帐户听众列表, 自己或者别人"""
+ if self.self:
+ return self._api.fanslist(*args, **kwargs)
+ else:
+ return self._api.user_fanslist(self.name, *args, **kwargs)
- def followers_ids(self, *args, **kargs):
- return self._api.followers_ids(user_id=self.id, *args, **kargs)
+ def idollist(self, *args, **kwargs):
+ """帐户收听的人列表, 自己或者别人"""
+ if self.self:
+ return self._api.idollist(*args, **kwargs)
+ else:
+ return self._api.user_idollist(self.name, *args, **kwargs)
+ def speciallist(self, *args, **kwargs):
+ """帐户特别收听的人列表, 自己或者别人"""
+ if self.self:
+ return self._api.speciallist(*args, **kwargs)
+ else:
+ return self._api.user_speciallist(self.name, *args, **kwargs)
+
class DirectMessage(Model):
@classmethod
def parse(cls, api, json):
@@ -213,7 +247,7 @@ class Friendship(Model):
@classmethod
def parse(cls, api, json):
-
+
source = cls(api)
for k, v in json['source'].items():
setattr(source, k, v)
@@ -332,17 +366,21 @@ def __repr__(self):
@classmethod
def parse(cls, api, json):
lst = JSONModel(api)
- for k,v in json.items():
- setattr(lst, k, v)
+ for k, v in json.items():
+ if k == 'tweetid':
+ setattr(lst, k, v)
+ setattr(lst, 'id', v) # make `id` always useable
+ else:
+ setattr(lst, k, v)
return lst
-class VideoModel(Model):
+class Video(Model):
def __repr__(self):
- return "<VideoModel object #%s>" % self.real
+ return "<Video object #%s>" % self.real
@classmethod
def parse(cls, api, json):
- lst = VideoModel(api)
+ lst = Video(api)
for k,v in json.items():
setattr(lst, k, v)
return lst
@@ -355,18 +393,18 @@ class IDSModel(Model):
@classmethod
def parse(cls, api, json):
ids = IDSModel(api)
- for k, v in json.items():
+ for k, v in json.items():
setattr(ids, k, v)
return ids
-
+
class Counts(Model):
@classmethod
def parse(cls, api, json):
ids = Counts(api)
- for k, v in json.items():
+ for k, v in json.items():
setattr(ids, k, v)
return ids
-
+
class ModelFactory(object):
"""
Used by parsers for creating instances
@@ -381,7 +419,7 @@ class ModelFactory(object):
saved_search = SavedSearch
search_result = SearchResult
list = List
- video = VideoModel
+ video = Video
json = JSONModel
ids_list = IDSModel
counts = Counts
View
2  qqweibo/utils.py
@@ -1,7 +1,7 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright 2010 Joshua Roesslein
-# Copyright 2011 andelf<andelf@gmail.com>
+# Copyright 2011 andelf <andelf@gmail.com>
# See LICENSE for details.
from datetime import datetime
Please sign in to comment.
Something went wrong with that request. Please try again.