设为首页 收藏本站
查看: 702|回复: 0

[经验分享] JE API的Python实现

[复制链接]

尚未签到

发表于 2017-4-28 13:08:10 | 显示全部楼层 |阅读模式
  距上一篇文章10小时,我终于把API的主要功能实现了一遍。但未经测试。
  废话少说,上代码:
  首先是__init__.py
  就是定义API的URL:

'''
初始化jetallker包的配置
Created on 2009-3-15
@author: phy
'''
JE_URL = "http://www.iteye.com/"
JE_API_HOME = JE_URL + "api/"
"""以下是闲聊API"""
JE_AUTH_URL = JE_API_HOME + "auth/verify"   #认证
JE_CHAT_LIST = JE_API_HOME + "twitters/list"   #闲聊列表
JE_CHAT_REPLIES = JE_API_HOME + "twitters/replies"   #@我的
JE_CHAT_ALL = JE_API_HOME + "twitters/all"   #全站闲聊
JE_CHAT_CREATE = JE_API_HOME + "witters/create"   #发布新闲聊
JE_CHAT_DELETE = JE_API_HOME + "twitters/destroy"   #删除闲聊
JE_CHAT_BY_ID = JE_API_HOME + "twitters/show"     #根据ID获取闲聊
#其他……
  再来,到utils.py,定义一些urllib2的简单工具方法

#!/usr/bin/env python
#coding=UTF-8
'''
Created on 2009-3-15
@author: phy
'''
import urllib2, gzip, base64
from StringIO import StringIO
DEFAULT_USER_AGENT = "PJETallker/0.1"
class SmartRedirectHandler(urllib2.HTTPRedirectHandler):
def http_error_301(self, req, fp, code, msg, headers):
result = urllib2.HTTPRedirectHandler.http_error_301(self, req, fp, code, msg, headers)
result.status = code
return result
def http_error_302(self, req, fp, code, msg, headers):
result = urllib2.HTTPRedirectHandler.http_error_302(self, req, fp, code, msg, headers)
result.status = code
return result
class DefaultErrorHandler(urllib2.HTTPDefaultErrorHandler):
def http_error_default(self, req, fp, code, msg, headers):
result = urllib2.HTTPError(req.get_full_url(), code, msg, headers, fp)
result.status = code
return result
def initHeaders(username, pwd):
return {"Authorization": "Basic " + encodeUser(username, pwd)}
def read(f):
'''读取数据,支持gzip
@param f:
'''
data = f.read()
if(hasattr(f, "headers") and f.headers.get("content-encoding", '') == 'zip'):
data = gzip.GzipFile(fileobj=StringIO(data)).read()
return data
def sendRequest(request, auth=None):
'''发送请求
@param request: urllib2.Request对象
@param auth: 验证字符串,经过encodeUser处理的用户名与密码
@see:jetallker.utils.encodeUser
'''
if(auth):
request.add_header("Authorization", auth)
request.add_header('Accept-encoding', 'gzip')
request.add_header('User-Agent', DEFAULT_USER_AGENT)
request.add_header('Content-Type', "application/x-www-form-urlencoded; charset=UTF-8")
opener = urllib2.build_opener(SmartRedirectHandler(), DefaultErrorHandler())
f = None
try:
f = opener.open(request)
result = {}
result["data"] = read(f)
if(hasattr(f, "headers")):
result["etag"] = f.headers.get("ETag")
result["lastmodified"] = f.headers.get("Last-Modified")
if hasattr(f, "url"):
result["url"] = f.url
result["status"] = 200
if hasattr(f, "status"):
result["status"] = f.status
except e:
raise e
finally:
f.close()
return result
def evalJson(json):
'''将json转为Python对象,处理json时将null替换为None   
@param json:
'''
json = json.replace("null", "None")
return eval(json)
def encodeUser(name, pwd, keyStr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="):
'''将用户名密码加密
@param name:用户名
@param pwd:密码
@param keyStr:
'''
output, input = "", name + ":" + pwd;
enc1 = enc2 = enc3 = enc4 = chr1 = chr2 = chr3 = '';
i = 0;
while (i < len(input)):
chr1 = ord(input)
chr2 = ord(input[i + 1]) if i + 1 < len(input) else 0
chr3 = ord(input[i + 2]) if i + 2 < len(input) else 0
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if not chr2:
enc3 = enc4 = 64
elif not chr3:
enc4 = 64;
output = output + keyStr[enc1] + keyStr[enc2] + keyStr[enc3] + keyStr[enc4];
i = i + 3
return output;
  最后是core.py,定义API的实际访问,包括登录验证,闲聊,收藏等。。

#!/usr/bin/env python
#coding=UTF-8
'''
Created on 2009-3-15
@author: phy
'''
from __init__ import *
from utils import *
from urllib2 import Request
class JECore(object):
'''JavaEye Python API
@author: phyeas
'''
def __init__(self, username=None, pwd=None):
self.isLogin = False
self.__authKey = None
self.user = None
if(username and pwd):
login(username, pwd)
def login(self, username, pwd):
'''登录验证
@param username: 用户名
@param pwd:密码
@return: 返回一个元组(登录是否成功,消息)
'''
if not (username and pwd):
return False, "未输入用户名和密码"
request = Request(JE_AUTH_URL, headers=initHeaders(username, pwd))
result = sendRequest(request)
if result["status"] == 401 and result["data"] == "error.auth.fail":
return False, "用户名或密码错误"
elif result["status"] == 401  and result["data"] == "error.auth.over.limit":
return False, "已连续6此验证失败,系统自动禁止登录,请一个小时后重试"
elif result["status"] == 400 and result["data"] == "error.api.over.limit":
return False, "您登录的次数太多了"
elif result["status"] == 200:
self.isLogin = True
self.__authKey = encodeUser(username, pwd)
self.user = evalJson(result["data"])
#print self.__user
return True, "验证成功"
return False, "未知错误,请通知管理员"
def request(self, url, data=None):
'''通用 web请求方法
@param url:请求的url
@param data:要提交的数据
@raise NoLoginError: 如果用户未登录调用该方法将引发NoLoginError
@raise JEAccessError: 如果返回状态不等于200则引发此异常(跳转也不行)
'''
if not(self.isLogin):
raise NoLoginError()
request = Request(url, data=data)
result = sendRequest(request, self.__authKey)
if result["status"] == 200:
try:
return evalJson(result["data"])
except:
pass
raise JEAccessError(result["data"], result["status"])
def request2(self, url, data=None):
if not(self.isLogin):
raise NoLoginError()
request = Request(url, data=data)
return sendRequest(request, self.__authKey)
def getList(self, url, last_id=None, page=None):
'''通用获取闲聊的列表的方法
@param last_id:最后获取到的闲聊ID
@param url: URL
@param page:抓取第N页记录
@raise NoLoginError: 如果用户未登录调用该方法将引发NoLoginError
@raise JEAccessError: 返回结果不正常时引发此异常
'''
data = {"last_id":last_id, "page":page} if last_id and page else None
return self.request(url, data)
def listTalk(self, last_id=None, page=None):
'''获取"闲聊一下 "的列表
@param last_id:最后获取到的闲聊ID
@param page:抓取第N页记录
@raise NoLoginError: 如果用户未登录调用该方法将引发NoLoginError
@raise JEAccessError: 返回结果不正常时引发此异常
'''
return self.getList(JE_CHAT_LIST, last_id, page)
def repliesTalk(self, last_id=None, page=None):
'''获取我的回复列表  --针对闲聊
@param last_id:最后获取到的闲聊ID
@param page:抓取第N页记录
@raise NoLoginError: 如果用户未登录调用该方法将引发NoLoginError
@raise JEAccessError: 返回结果不正常时引发此异常
'''
return self.getList(JE_CHAT_REPLIES, last_id, page)
def allTalk(self, last_id=None, page=None):
'''获取"全站闲聊 "列表
@param last_id:最后获取到的闲聊ID
@param page:抓取第N页记录
@raise NoLoginError: 如果用户未登录调用该方法将引发NoLoginError
@raise JEAccessError: 返回结果不正常时引发此异常
'''
return self.getList(JE_CHAT_ALL, last_id, page)
def createTalk(self, body, reply_to_id=None, via="PJETalker"):
'''创建一个闲聊
@param body:闲聊内容
@param reply_to_id:回复闲聊的ID
'''
data = {"body":body, "reply_to_id":reply_to_id, "via":via}
return self.request(JE_CHAT_CREATE, data)
def deleteTalk(self, id):
'''删除闲聊      
@param id:
'''
return self.request2(JE_CHAT_DELETE, {"id":id})
def showTalk(self, id):
'''根据id获取闲聊,id可以为逗号分割值,如"1,2,3"   
@param id:
'''
data = {"id":id}
return self.request(JE_CHAT_BY_ID, data)
def listFavorites(self):
'''获取用户收藏列表 '''
return self.request(JE_FA_LIST)
def saveFavorites(self, **data):
'''保存用户收藏(添加或更新)'''
return self.request(JE_FA_ADD, data)
def deleteFavorites(self, id):
'''删除用户收藏
@param id:
'''
return self.request2(JE_FA_DELETE, {"id":id})
def listInbox(self, last_id=None, page=None):
'''获取收件箱列表
@param last_id:最后一条信息的id
@param page:抓取第N页记录
@raise NoLoginError: 如果用户未登录调用该方法将引发NoLoginError
@raise JEAccessError: 返回结果不正常时引发此异常
'''
return self.getList(JE_MSG_INBOX, last_id, page)
def sendMsg(self, title, body, receiver_name=None, reply_id=None):
'''发送(或回复)站内消息
@param title:标题
@param body:内容
@param receiver_name:接收人用户名,如为回复则不填
@param reply_id:回复某条消息的ID,如消息为发送则不填
'''
if receiver_name is not None and reply_id is None:
return self.request(JE_MSG_CREATE, data={"title":title, "body":body, "receiver_name":receiver_name})
elif reply_id is not None and receiver_name is None:
return self.request(JE_MSG_REPLY, data={"title":title, "body":body, "id":reply_id})
raise JEAccessError("receiver_name or reply_id must be not null!",0)
def deleteMsg(self,id):
'''删除站内短信
@param id:
'''
return self.request2(JE_MSG_DELETE, {"id":id})
def logOut(self):
'''退出登录'''
self.isLogin, self.__authKey, self.user = False, None, None
class NoLoginError(Exception):
'''用户未登录异常 '''
def __init__(self, message):
self.message = message
def __init__(self):
self.message = "error.auth.fail"
def __str__(self):
return self.message
class JEAccessError(Exception):
'''一般异常:如error.api.over.limit '''
def __init__(self, message, status):
self.message = message
self.status = status
def __str__(self):
return ""
if __name__ == "__main__":
talker = JECore()
success, message = talker.login("username", "pwd")

  如有需要可下载附件,欢迎各位拍砖。。
  夜深了,睡觉去咯。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-370470-1-1.html 上篇帖子: Python与Perl不能说的秘密 下篇帖子: python 自带小爬虫
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表