免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 6820 | 回复: 25
打印 上一主题 下一主题

Python写的饭否客户端 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-08-26 17:41 |只看该作者 |倒序浏览
目前只有基本的框架,还需再修改修改。发出来共同学习了,嘿嘿。

#encoding=UTF-8
import base64
import re
import httplib, urllib
from xml.dom import minidom
from datetime import datetime

_dateReg = re.compile(r"\+\d{4}\s")
_defaultTimeFormat = "%Y-%m-%d %H:%M:%S"
_FANFOU_API_ADDRESS="api.fanfou.com"
_SEND_MSG="/statuses/update.xml"
_MY_MSG="/statuses/user_timeline.xml?id=%s&count=%d"
_FRIENDS_MSG="/statuses/friends_timeline.xml?id=%s&count=%d"
_PUBLIC_MSG="/statuses/public_timeline.xml?count=%d"

##################################General purpose functions###################################
def __fanfouGet__(url):
    """Use HTTP get method to retrieve data from an url. Returns an instanse of HTTPResponse."""
    conn = httplib.HTTPConnection(_FANFOU_API_ADDRESS)
    conn.request("GET",url)
    response = conn.getresponse()
    if response.status != 200:
        raise HttpError(response.status, response.reason)
    else:
        return response
   
def __fanfouPost__(url, headers, params):
    """Use HTTP post method to send some data to the fanfou. Return an instance of HTTPResponse."""
    conn = httplib.HTTPConnection(_FANFOU_API_ADDRESS)
    conn.request("POST",_SEND_MSG,params,headers)
    response = conn.getresponse()
    if response.status != 200:
        raise HttpError(response.status, response.reason)
    else:
        return response



def __parseTextNode__(nodeList):
    """Parse an XML node, and extract the texts."""
    result = ""
    for node in nodeList:
        if node.nodeType == node.TEXT_NODE:
            result = result + node.data
    return result

def __parseStatus__(statusNode):
    """Pase an  node of Fanfou XML data. Returns an instanse of Status"""
    createdTime = __parseTextNode__(statusNode.getElementsByTagName("created_at")[0].childNodes);
    realTime = datetime.strptime(_dateReg.sub("",createdTime),"%a %b %d %H:%M:%S %Y")
    text = __parseTextNode__(statusNode.getElementsByTagName("text")[0].childNodes);
    return Status(text,realTime)

class Error(Exception):
    """Base Error class of this pyfanfou module"""
    pass

class HttpError(Error):
    """HttpError represents an Http error with an error code(e.g. 404) and a reason"""
    def __init__(self,code,reason):
        self.errorCode = code
        self.errorReason = reason

    def __str__(self):
        return "Http Communication Error(status:%d, reason:%s)" % (self.errorCode, self.errorReason)



class Status:
    """Status represents an Status object of Fanfou. Refer to http://help.fanfou.com/api.html"""
    text = ""
    createdTime = ""

    def __init__(self,text,createdTime):
        self.text = text
        self.createdTime = createdTime

    def printMe(self):
        print "-"*20
        print "Text: %s" % (self.text)
        print "Created at: %s" % (datetime.strftime(self.createdTime,_defaultTimeFormat))



class FanfouClient:
   
    def __init__(self,username,password):
        self.username = username
        self.password = password
        self._authStr = base64.b64encode(username + ":" + password);
        #饭否API使用HTTP Basic认证,用户名和密码用base64编码
        print "[Authentication][Encoded] ", self._authStr

    def __parseFanfouXML__(self,reader):
        xmldoc = minidom.parse(reader)
        print xmldoc
        nodes = xmldoc.getElementsByTagName("status")
        list = [__parseStatus__(node) for node in nodes]
        return list

        
    def sendMessage(self,message):
        headers = {"Content-type": "application/x-www-form-urlencoded",
                "Accept": "text/xml",
                "Authorization": "Basic " + self._authStr}
        params = urllib.urlencode({"status": message})
        __fanfouPost__(_SEND_MSG, headers, params)        

    def getMyMessages(self,count=10):
        response = __fanfouGet__(_MY_MSG %( self.username,count))
        return self.__parseFanfouXML__(response)

    def getFriendsMessages(self, count=10):
        response = __fanfouGet__(_FRIENDS_MSG %(self.username, count))
        return self.__parseFanfouXML__(response)

    def getPublicMessages(self, count=10):
        response = __fanfouGet__(_PUBLIC_MSG % (count))
        return self.__parseFanfouXML__(response)
            
def testSendMessage(client):
    msg = ""
    while msg == "":
        msg = raw_input("Input some message:")
    client.sendMessage(msg)

def testMyMessage(client):
    msgs = client.getMyMessages()
    for a in msgs:
        a.printMe()

def testFriendsMessage(client):
    msgs = client.getFriendsMessages()
    for a in msgs:
        a.printMe()

def testPublicMessage(client):
    msgs = client.getPublicMessages()
    for a in msgs:
        a.printMe()

if __name__ == "__main__":
    username = 'xxxxxxx'
    password = 'xxxxxxx'
    client = FanfouClient(username,password)
    print "My messages","="*20
    testMyMessage(client)
    print "Friends' and my messages", "="*20
    testFriendsMessage(client)
    print "Public messages", "="*20
    testPublicMessage(client)


[ 本帖最后由 moonranger 于 2008-8-28 08:54 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-08-27 09:47 |只看该作者
感谢分享

论坛徽章:
0
3 [报告]
发表于 2008-08-27 10:15 |只看该作者
对饭否的相关协议不是太了解,要是有更多注释就好了。
呵呵,感谢分享~

论坛徽章:
0
4 [报告]
发表于 2008-08-27 11:23 |只看该作者

回复 #3 jjj137 的帖子

觉得这算不上什么协议吧,就是HTTP加上XML解析

论坛徽章:
0
5 [报告]
发表于 2008-08-27 11:37 |只看该作者
原帖由 可可熊 于 2008-8-27 11:23 发表
觉得这算不上什么协议吧,就是HTTP加上XML解析

呵呵,我说的不是狭义的协议,就是客户端与服务器之间的交流方法,比如哪个xml是干什么的之类的……

论坛徽章:
0
6 [报告]
发表于 2008-08-27 12:18 |只看该作者
可以去:http://help.fanfou.com/api.html看看哦

论坛徽章:
0
7 [报告]
发表于 2008-08-27 12:56 |只看该作者
呵呵,原来饭否还提供API……以前都不知道……研究研究~

论坛徽章:
0
8 [报告]
发表于 2008-08-27 13:28 |只看该作者
不好意思,匆匆忙忙写出来的,没加太多注释,回头有时间加上。
初学Python,想拿这个练练手,学学httplib和minidom这些库。

P.S. 感觉Python的文档用起来不太方便,感觉有一点点乱,要是想Javadoc那样就太好了。

论坛徽章:
0
9 [报告]
发表于 2008-08-27 13:40 |只看该作者
class FanfouClient:
    username = ""
    password = ""
    _authStr = ""

下面这三句是没有必要的吧……类属性是用来实例中共享数据的。

[ 本帖最后由 jjj137 于 2008-8-27 13:45 编辑 ]

论坛徽章:
0
10 [报告]
发表于 2008-08-27 20:12 |只看该作者
原帖由 jjj137 于 2008-8-27 13:40 发表
class FanfouClient:
    username = ""
    password = ""
    _authStr = ""
下面这三句是没有必要的吧……类属性是用来实例中共享数据的。


这样写是静态属性是吗? 整个类都共享? 那实例的属性岂不非要在写成self.xxx这样,放到__init__中?
果然只是初学,有点自以为是了,不好意思。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP