van - Fanfou SDK for Human Documents

Quick Start & Installation

Van [1] 是一个 Python 编写的 饭否 SDK ,基于 饭否官方API 。Van 对官方 API 做了合理的抽象和封装,开发者可以使用简洁优雅的接口,轻松操作用户在饭否上的数据。

Van 计划添加一些数据获取接口和任务调度功能,使饭否 Bot 开发更简单。

Quick Start Demo

下面是一个极简的使用 Demo, 附有简单的注释, 具体的使用我们会在后文详细说明。

from van import Fan

# 实例化 Fan 类
fan = Fan(consumer_key, consumer_secret)

# 使用 xauth 授权方式
fan.xauth(username,password)

# 或者使用 oauth 授权方式
# url = fan.authorization_url()
# 访问此 url 并复制 PIN 码 (或重定向后的 URL)
# fan.oauth(pin_code)

# 调用 API
fan.update_status('你好啊,李银河!')

Installation

van 只支持 Python3, 请前往官网下载安装 Python 3.5 以上版本。

如果你是开发者,你也可以帮助我兼容 Python2

之后可以使用 pip 安装:

pip3 install van

或者下载源码安装:

git clone https://github.com/j178/van
cd van
pip3 install . --user

申请应用

要使用 van 你还需要在饭否中申请一个应用:

  1. http://fanfou.com/apps 中创建新应用
  2. 应用名称、主页、描述等信息可以随意填写
  3. 记录下 Consumer KeyConsumer Secret

P.S.

[1]vanfan 在舌头打结时的发音

Explanation

总体设计

van 的所有功能分布在四个类中, FanUserStatusTimeline.

User - 猜猜我是谁?

User 是对 API 接口返回的 user 对象的封装,可以通过它访问用户的属性,比如 User.id, User.name, User.location 等。 它还有一些所有用户共有的操作,比如获取用户的消息列表 User.statuses 、关注者列表 User.followers 、好友列表 User.friends 等。

timeline 返回此用户看到的时间线
statues 返回此用户已发送的消息
photos 浏览此用户发送的图片
followers 返回此用户的关注者
friends 返回此用户的关注对象
favorites 浏览此用户收藏的消息
relationship() 返回此用户与 other 的关系

Fan - 我才是老大!

Fan 是整个程序的开始点和其他API访问的入口点。程序需要先实例化一个 Fan 对象,然后通过 Fan 对象访问其他 API。

me 获取授权用户的信息
draft_box 显示发送失败的消息列表
mentions 返回提到当前用户的20条消息
replies 返回当前用户收到的回复
blocked_users 返回黑名单上用户列表
public_timeline 返回公共时间线
follow_requests 返回请求关注当前用户的列表
update_status() 更新状态
follow() 关注用户
unfollow() 取消关注用户
accept_follower() 接受关注请求
deny_follower() 拒绝关注请求
block() 屏蔽用户
unblock() 解除屏蔽
is_blocked() 检查是否屏蔽用户

Status - 我的实例最多~

没错,Status 是程序运行时创建最多的对象。 它与 User 一样,是对 API 数据的封装,但是它上面也部署了一些符合语义的方法,比如 回复消息 Status.reply()、转发消息 Status.repost()、 收藏消息 Status.favorite() (是不是挺像在御饭中左滑消息时的操作?)

photo Photo 对象,拥有 url, largeurl, imageurl, thumburl, originurl, type 属性
user User 对象,此消息的作者
context 按照时间先后顺序显示消息上下文
send() 发送此消息
delete() 删除此消息
reply() 回复这条消息
repost() 转发这条消息
favorite() 收藏此消息
unfavorite() 取消收藏此消息

Timeline - 天生优雅

Timeline 即时间线,或者说一组按时间排序的 Status 的列表: [ 最新的消息, ..., 稍旧的消息 ]

在原始 API 中,我们为了获取一段时间内的时间线,需要提供 since_idmax_id 两个参数来控制时间线的区间,我们需要经常记录并更新这两个值,比较麻烦。

在 Timeline 的实现中,van 将时间线模拟成一个文件对象,内部维护一个可用的消息数组,一个游标表示当前消息在数组中的位置。 调用 read() 方法,向后移动游标,返回一个消息数组,表示读取了一部分消息。

最神奇的地方在于,如果内部数组被消耗完了, Timeline 会自动获取消息填充。所以,完全可以将 Timeline 看作是一个无穷的数组,不用去关心 since_idmax_id 等问题,也不用手动获取新的状态, 只要像数组一样随意读取、遍历即可。

UserFan 中符合 Timeline 特征的都是 Timeline 对象。

__call__()

调用内部 _fetch 方法获取数据。

可以自己提供 since_id, max_idcount 参数,获取的结果不加入内部数组。

__iter__() 可以在 for 循环中使用此对象
tell() 返回当前游标的位置
rewind() 获取最新的状态插入到时间线的头部,并将指针置为0(指向最新的状态)
seek() 移动游标的位置
read() 从当前游标位置处往后读取消息

Streamming API

Demo

from van import Config, Fan, Stream, Event

class MyConfig(Config):
    consumer_key = 'xxxx'
    consumer_secret = 'xxx'

Fan.setup(MyConfig())
s = Stream()

@s.on(Event.MESSAGE)
def handle_message(event):
    print(event.object.text)

@s.on(Event.USER | Event.MESSAGE_CREATE)
def handle_something(event):
    do_something(event)

@s.on(Event.ALL)
def handle_all(event):
    print(event.object)

if __name__ == '__main__':
    s.start()

API Reference

Fan

class van.Fan(consumer_key, consumer_secret, oauth_token=None, mobile=False)

API操作入口

accept_follower(user)

接受关注请求

参数:user (User|str) -- User对象,或id,或 loginname
返回类型:(bool, User)
authorization_url(oauth_callback='oob')

引导用户访问的授权页面URL 当 oauth_callback = 'oob' 时表示使用 PIN码授权

authorized

当前会话是否已授权

block(user)

屏蔽用户

参数:user (str|User) -- 被屏蔽的用户User对象或者id,loginname
返回类型:(bool, User)
blocked_users

返回黑名单上用户列表

返回类型:(bool, [User])
blocked_users_id

获取用户黑名单id列表

返回类型:(bool, [str])
deny_follower(user)

拒绝关注请求

参数:user (User|str) -- User对象,或id,或 loginname
返回类型:(bool, User)
follow(user)

关注用户

参数:user (User|str) -- 被关注的用户, User对象,或id,或 loginname
follow_requests

返回请求关注当前用户的列表

返回类型:(bool, [User])
is_blocked(user)

检查是否屏蔽用户

参数:user (str|User) -- 用户User对象或者id,loginname
返回类型:(bool, str)
me

获取授权用户的信息

oauth(pin_code=None, redirect_url=None)

通过授权后的PIN码或者浏览器重定向的URL获取最终的token

request(method, endpoint, params=None, data=None, files=None, **kwargs)

发出请求

session

获取session

unblock(user)

解除屏蔽

参数:user (str|User) -- 被屏蔽的用户User对象或者id,loginname
返回类型:(bool, str)
unfollow(user)

取消关注用户

参数:user (User|str) -- 被关注的用户, User对象,或id,或 loginname
update_status(status, photo=None, in_reply_to_user_id=None, in_reply_to_status_id=None, repost_status_id=None, location=None, source=None)

发表新状态,Status.send() 的快捷方式。

参数:
  • text (str) -- 文字
  • photo (str) -- 照片路径或者URL
  • in_reply_to_user_id (str) -- 要回复的用户ID
  • in_reply_to_status_id (str) -- 要回复的消息ID
  • repost_status_id (str) -- 要转发的消息ID
  • location (str) -- 位置信息,使用'地点名称' 或 '一个半角逗号分隔的经纬度坐标'
  • source (str) -- source 消息来源

User

class van.User(fan, **kwargs)

用户类

favorites

浏览此用户收藏的消息

followers

返回此用户的关注者 此用户为当前用户的关注对象或未设置隐私

参数:count (int) -- 每次获取的数量
followers_id

返回此用户关注者的id列表

参数:count (int) -- 每次获取的数量
friends

返回此用户的关注对象 此用户为当前用户的关注对象或未设置隐私

friends_id

返回此用户关注对象的id列表

relationship(other)

返回此用户与 other 的关系: 是否屏蔽,是否关注,是否被关注

参数:other (str|User) -- 其他用户
返回类型:(a_blocked_b, a_following_b, a_followed_b)

Status

class van.Status(fan, **kwargs)

消息类

context

按照时间先后顺序显示消息上下文

delete()

删除此消息(当前用户发出的消息)

favorite()

收藏此消息

reply(response, photo=None, location=None, format='@{poster} {response}', **kwargs)

回复这条消息

repost(repost, photo=None, location=None, format='{repost}{repost_style_left}@{name} {origin}{repost_style_right}', **kwargs)

转发这条消息

unfavorite()

取消收藏此消息

Timeline

class van.Timeline(fan, user_id, endpoint)

时间线管理类

__iter__()

从当前游标位置开始获取消息,可以像普通数组一样在循环中使用。 :return: Status

fetch(since_id=None, max_id=None, count=60)

调用 API 获取数据。 可以自己控制 since_id, max_idcount 参数,获取的结果不加入内部缓存。

参数:
  • since_id -- 开始的消息ID
  • max_id -- 结束的消息ID
  • count -- 获取数量,最大为60
返回:

Status 数组

返回类型:

[Status]

read(count=10)

从当前游标位置处往后读取 count 条消息, 数组长度可能小于要求的大小。

参数:count (int) -- 读取数量
返回:Status 数组
返回类型:[Status]
rewind()

获取最新的状态插入到时间线的头部,并将指针置为0(指向最新的状态)

返回类型:int
seek(offset=None, whence=0)

移动游标的位置

参数:
  • offset (int) -- 偏移量
  • whence (int) --

    相对位置

    • 0 -- 相对于时间线开始位置,偏移量必须 >= 0
    • 1 -- 相对于当前游标位置,偏移量可正可负,超出范围的偏移量会被纠正为边界值
    • 2 -- 相对于时间线结尾,偏移量 <=0

注意

此函数只能在有限范围满足索引要求,超出范围太多的偏移量会被自动纠正为合法值。

返回:移动后的游标位置
返回类型:int
tell()

返回当前游标的位置

返回类型:int
user_id = None

User 时间线的主人

Base

class van.Base(fan, **kwargs)

UserStatus 的基类。 为子类提供对象缓存和自动加载功能。

Stream

class van.Stream(fan)

Streamming API, 实时监测用户动作

install_listener(listener)

添加新的监听器 :param Listener listener: Listener 对象

on(event, ttl=None)

作为装饰器使用,添加新的监听器

参数:event -- 监听的事件, 多个事件请用 | 连接。如 Event.MESSAGE | Event.FREIENDS

:param int priority:监听器的优先级,数字越小优先级越高 :param int ttl: 此监听器执行的次数,None 表示不限次数

run()

开始监听事件

stop()

停止监听事件

Event

class van.Event(fan, type, data=None)

事件对象,模拟一个事件发生时相关的数据

每个事件都有一个类型,当前可用的类型有:

  • MESSAGE_CREATE: 当前用户发布一条状态。source为当前用户,如果消息中@其他人,则target为被提及用户,object为发布的状态
  • MESSAGE_DELETE: 当前用户删除一条状态
  • MESSAGE: 与 MESSAGE 相关的所有类型的事件,即 MESSAGE_CREATEMESSAGE_DELETE 的合事件。
  • FRIENDS_CREATE:当前用户关注其他用户。source为当前用户,target为被关注的对象
  • FRIENDS_DELETE: 当前用户取消关注其他用户
  • FRIENDS_REQUEST: 当前用户对其他用户发起关注请求
  • FRIENDS:FRIENDS 相关的所有类型的事件
  • FAV_CREATE:当前用户收藏一条状态。 source 为发起收藏操作的用户,target为状态被收藏的用户,object为被收藏的状态
  • FAV_DELETE:当前用户取消收藏一条状态
  • FAV:FAV 相关的所有事件
  • DM_CREATE: 用户收到一条私信
  • USER_UPDATE_PROFILE:当前用户更新个人资料
  • ALL:所有事件

Listener

监听器对象

class van.Listener(on, func, ttl=None)
on

此监听器监听的事件类型,可用的值均为 Event 类中的属性,如 Event.MESSAGE 表示监听消息相关的事件。 多个事件可以使用 | 连接,组合为一个事件,如 Event.MESSAGE | Event.FREIENDS

func

一个可调用对象,接受一个 Event 对象,当 on 中监听的事件发生时被调用。

ttl

计算机术语,Time To Live。在这里表示此监听器最多工作的次数,超过次数之后就不再调用此监听器。

Misc

van.Photo = <class 'van.Photo'>

https://www.mtyun.com/doc/api/mss/mss/tu-pian-chu-li-fu-wu-api#图片处理服务状态码

Todo

  1. 完善文档
  2. Stream API
  3. 编写 bot sdk