锁定老帖子 主题:Je Api好写,但不一定好用
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (1)
|
|
---|---|
作者 | 正文 |
发表时间:2009-06-10
最后修改:2009-06-10
#coding:utf-8 __author__="xxx@gmail.com" __version__="0.1" import base64 import md5 import os import simplejson import sys import tempfile import time import urllib import urllib2 import urlparse import jtalk ######################################################################### ## Api Core ######################################################################### class JTalkError(Exception): '''Base error define''' class Api(): DEFAULT_CACHE_TIMEOUT = 60 # cache for 1 minute _API_REALM = 'JavaEye API' def __init__(self, username=None, password=None, input_encoding='utf-8', request_headers=None): self._cache = _FileCache() self._urllib = urllib2 self._cache_timeout = Api.DEFAULT_CACHE_TIMEOUT self._InitializeRequestHeaders(request_headers) self._InitializeUserAgent() self._InitializeJSONParameters() self._input_encoding = input_encoding self.SetCredentials(username, password) def listTalk(self,last_id=None,page=None): '''query talk list''' parameters = {} if last_id: parameters['last_id'] = last_id if page: parameters['page'] = page url = "http://api.iteye.com/api/twitters/list" json = self._FetchUrl(url, parameters=parameters) return simplejson.loads(json) def repliesTalk(self,last_id=None,page=None): '''query my talk replies ''' parameters = {} if last_id: parameters['last_id'] = last_id if page: parameters['page'] = page url = "http://api.iteye.com/api/twitters/replies" json = self._FetchUrl(url, parameters=parameters) return simplejson.loads(json) def allTalk(self,last_id=None,page=None): '''query all talk ''' parameters = {} if last_id: parameters['last_id'] = last_id if page: parameters['page'] = page url = "http://api.iteye.com/api/twitters/replies" json = self._FetchUrl(url, parameters=parameters) return simplejson.loads(json) def createTalk(self,body,reply_to_id=None,via=None): '''query all talk ''' data = {} if not body: raise JTalkError("talk body can not be null") else: data['body']=body if reply_to_id: data['reply_to_id'] = lreply_to_id if via: data['via'] = via url = "http://api.iteye.com/api/twitters/create" json = self._FetchUrl(url, post_data=data) return simplejson.loads(json) def SetCredentials(self, username, password): self._username = username self._password = password def SetUserAgent(self, user_agent): self._request_headers['User-Agent'] = user_agent def _InitializeUserAgent(self): user_agent = 'JTalk/%s' % jtalk.__version__ self.SetUserAgent(user_agent) def _InitializeRequestHeaders(self, request_headers): if request_headers: self._request_headers = request_headers else: self._request_headers = {} def _InitializeJSONParameters(self): self._json_param = {} def _Encode(self, s): if self._input_encoding: return unicode(s, self._input_encoding).encode('utf-8') else: return unicode(s).encode('utf-8') def _EncodeParameters(self, parameters): if parameters is None: return None else: return urllib.urlencode(dict([(k, self._Encode(v)) for k, v in parameters.items() if v is not None])) def _EncodePostData(self, post_data): if post_data is None: return None else: return urllib.urlencode(dict([(k, self._Encode(v)) for k, v in post_data.items()])) def _FetchUrl(self, url, post_data=None, parameters=None, no_cache=None): url = self._BuildUrl(url, extra_params=parameters) opener = self._GetOpener(url, username=self._username, password=self._password) encoded_post_data = self._EncodePostData(post_data) if encoded_post_data or no_cache or not self._cache or not self._cache_timeout: url_data = opener.open(url, encoded_post_data).read() else: if self._username: key = self._username + ':' + url else: key = url last_cached = self._cache.GetCachedTime(key) if not last_cached or time.time() >= last_cached + self._cache_timeout: url_data = opener.open(url, encoded_post_data).read() self._cache.Set(key, url_data) else: url_data = self._cache.Get(key) return url_data def _BuildUrl(self, url, path_elements=None, extra_params=None): (scheme, netloc, path, params, query, fragment) = urlparse.urlparse(url) if path_elements: p = [i for i in path_elements if i] if not path.endswith('/'): path += '/' path += '/'.join(p) if extra_params and len(extra_params) > 0: extra_query = self._EncodeParameters(extra_params) if query: query += '&' + extra_query else: query = extra_query return urlparse.urlunparse((scheme, netloc, path, params, query, fragment)) def _AddAuthorizationHeader(self, username, password): if username and password: basic_auth = base64.encodestring('%s:%s' % (username, password))[:-1] self._request_headers['Authorization'] = 'Basic %s' % basic_auth def _RemoveAuthorizationHeader(self): if self._request_headers and 'Authorization' in self._request_headers: del self._request_headers['Authorization'] def _GetOpener(self, url, username=None, password=None): if username and password: self._AddAuthorizationHeader(username, password) handler = self._urllib.HTTPBasicAuthHandler() (scheme, netloc, path, params, query, fragment) = urlparse.urlparse(url) handler.add_password(Api._API_REALM, netloc, username, password) opener = self._urllib.build_opener(handler) else: opener = self._urllib.build_opener() opener.addheaders = self._request_headers.items() return opener ######################################################################### ## 缓存处理 ######################################################################### class _FileCacheError(Exception): pass class _FileCache(object): DEPTH = 3 def __init__(self,root_directory=None): self._InitializeRootDirectory(root_directory) def Get(self,key): path = self._GetPath(key) if os.path.exists(path): return open(path).read() else: return None def Set(self,key,data): path = self._GetPath(key) directory = os.path.dirname(path) if not os.path.exists(directory): os.makedirs(directory) if not os.path.isdir(directory): raise _FileCacheError('%s exists but is not a directory' % directory) temp_fd, temp_path = tempfile.mkstemp() temp_fp = os.fdopen(temp_fd, 'w') temp_fp.write(data) temp_fp.close() if not path.startswith(self._root_directory): raise _FileCacheError('%s does not appear to live under %s' % (path, self._root_directory)) if os.path.exists(path): os.remove(path) os.rename(temp_path, path) def Remove(self,key): path = self._GetPath(key) if not path.startswith(self._root_directory): raise _FileCacheError('%s does not appear to live under %s' % (path, self._root_directory )) if os.path.exists(path): os.remove(path) def GetCachedTime(self,key): path = self._GetPath(key) if os.path.exists(path): return os.path.getmtime(path) else: return None def _GetUsername(self): '''Attempt to find the username in a cross-platform fashion.''' return os.getenv('USER') or \ os.getenv('LOGNAME') or \ os.getenv('USERNAME') or \ os.getlogin() or \ 'nobody' def _GetTmpCachePath(self): username = self._GetUsername() cache_directory = 'python.cache_' + username return os.path.join(tempfile.gettempdir(), cache_directory) def _InitializeRootDirectory(self, root_directory): if not root_directory: root_directory = self._GetTmpCachePath() root_directory = os.path.abspath(root_directory) if not os.path.exists(root_directory): os.mkdir(root_directory) if not os.path.isdir(root_directory): raise _FileCacheError('%s exists but is not a directory' % root_directory) self._root_directory = root_directory def _GetPath(self,key): hashed_key = md5.new(key).hexdigest() return os.path.join(self._root_directory, self._GetPrefix(hashed_key), hashed_key) def _GetPrefix(self,hashed_key): return os.path.sep.join(hashed_key[0:_FileCache.DEPTH]) ##################################################################### ## 测试 ##################################################################### if __name__ == "__main__": jt = jtalk.Api(username="",password="") print jt.listTalk() 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-06-10
之前写过一个……后来没写下去了
|
|
返回顶楼 | |
发表时间:2009-06-10
如何不稳定阿,说说看
|
|
返回顶楼 | |
发表时间:2009-06-10
这个不稳定主要还是指访问上的问题,就一个月来的观察,波动太大了。
有连续好几天,我用ff搜藏死也搜藏不进去,闲聊插件死也打不开,几天后好了。 感觉的出来应该是系统内部在维护调整,作为bate,无可厚非,但确实很影响用户体验。 对je api提点意见,作为接口应该严谨,消息格式定义应该一致,既然定义了json格式,就应该统一用这个格式,返回错误也应该用这个格式,而不是html或其他txt。 |
|
返回顶楼 | |
发表时间:2009-06-10
jamiesun 写道 这个不稳定主要还是指访问上的问题,就一个月来的观察,波动太大了。
有连续好几天,我用ff搜藏死也搜藏不进去,闲聊插件死也打不开,几天后好了。 感觉的出来应该是系统内部在维护调整,作为bate,无可厚非,但确实很影响用户体验。 对je api提点意见,作为接口应该严谨,消息格式定义应该一致,既然定义了json格式,就应该统一用这个格式,返回错误也应该用这个格式,而不是html或其他txt。 中间有几天做了调整web server的设置,提高了api的处理速度,当时没有发现问题,过了几天才发现web server配置转发有问题,导致某些情况下请求会返回错误页面,发现以后很快就纠正了。 返回错误信息的格式是json,不是html和txt格式的,但如果是非法访问请求,会第一时间被web server拦截,这种情况下就会返回html,对于正常使用,不会返回html格式的出错提示。 不过API确实到现在还只是小范围内测,因为下半年计划升级硬件,来为开放API提供必要的硬件保证。 |
|
返回顶楼 | |
发表时间:2009-06-10
抱歉,是有些情绪化了。
期待更丰富强大的api(包括blog在内),若借助移动平台的波澜推一把,je应该能上一个新的台阶。 |
|
返回顶楼 | |
发表时间:2009-06-10
对啊,期待JE在移动平台上的表现。
|
|
返回顶楼 | |
发表时间:2009-06-10
robbin 写道 jamiesun 写道 这个不稳定主要还是指访问上的问题,就一个月来的观察,波动太大了。....
....
不过API确实到现在还只是小范围内测,因为下半年计划升级硬件,来为开放API提供必要的硬件保证。 期待升级硬件之后的效果,一小时300次API太少了 |
|
返回顶楼 | |
发表时间:2009-06-10
哇 你不怕被和谐呀~ 不过je 硬件升级是什么效果呢 期待
还有je api 有java的么? |
|
返回顶楼 | |
发表时间:2009-06-10
最后修改:2009-06-10
"因为下半年计划升级硬件,来为开放API提供必要的硬件保证"
je要买F5 ? 现在挺好的,访问速度已经挺快了 |
|
返回顶楼 | |