`
phyeas
  • 浏览: 161777 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

JE API的Python实现

阅读更多

距上一篇文章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[i])
        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")
    

 如有需要可下载附件,欢迎各位拍砖。。

夜深了,睡觉去咯。

分享到:
评论
2 楼 phyeas 2009-03-19  
还测试的哦,这个版本有很多问题,准备再测一下,修改些东西再上传新的
1 楼 woods 2009-03-19  
下载了 楼主动作很快...刚有这想法...

相关推荐

    Python库 | je_api_testka_dev-0.0.21-py3-none-any.whl

    资源分类:Python库 所属语言:Python 资源全名:je_api_testka_dev-0.0.21-py3-none-any.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    Python库 | je_api_testka-0.0.45.tar.gz

    资源分类:Python库 所属语言:Python 资源全名:je_api_testka-0.0.45.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    Python库 | je_api_testka-0.0.59.tar.gz

    资源分类:Python库 所属语言:Python 资源全名:je_api_testka-0.0.59.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    ziptastic:这是一个用于获取邮政编码的 Python API

    可用国家代码:AD、AR、AS、AT、AU、BD、BE、BG、BR、CA、CH、CZ、DE、DK、DO、ES、FI、FO、FR、GB、GF、GG、GL、 GP、GT、GU、GY、HR、HU、IM、IN、IS、IT、JE、JP、LI、LK、LT、LU、MC、MD、MH、MK、MP、MQ、MX、...

    il-manque-du-beurre:Python上的API实例,六角形结构及其他资源管理器,TDD内外

    帕为例,s'il manque杜Beurre黄油àLa Maison酒店,JE peux放任联合国POST河畔乐produit manquant 'beurre'等欧莱雅L'API enregistre。 套间,TOUTE personne杜门厅peut咨询者LES PRODUITS manquantsàacheter EN ...

    ci-utils:CI工具

    knuth ci-utils Knuth的持续集成中使用的一组功能。要求对于jenkins_utils(debian) apt-get updateapt-get install build-essential -yapt-get install gcc -yapt-get ...用法jenkins_dependencies.py python je

    mcipc:Minecraft服务器进程间通信库

    一个实现和协议的Minecraft进程间通信API。 新闻 2020-12-21-mcipc-2.0 好消息: mcipc现在在版本2中可用。 版本2更新包括将RCON协议和客户端实现外包到。 这允许RCON库独立于mcipc使用,例如用于支持RCON协议的...

    塔罗克

    重击$ export FLASK_APP=server.py 电源外壳PS C:\...\src\api&gt; $env:FLASK_APP = "server.py" python server.py 规范 大堂: Zbere se skupina 3-4 igralcev(Tarok za 3,Tarok za 4),vsizačnejoz 0 radelci...

    jesuisautocomplete:自动完成的搜索查询的语料库分析

    使用文本语料库“ Je Suis Autocomplete”进行语法分析/信息检索在过去的两年中,来自Google和Bings Autocomplete Api的文本数据已保存在“ Je Suis Autocomplete”项目中。 现在将在此处检查这些文本首先,应该提出...

    artbook-neo4j:Craft.io学概论

    Esteéum je pessoal,技术原则,美术师的艺术API,Solar o Framework Flask,com持久性banco de dados grafo Neo4J。 一个域驱动设计的概念结构,由六角形组合而成。 工作进行中,supresents com asdas作为suas ...

Global site tag (gtag.js) - Google Analytics