Teambition是一个跨平台的团队协做和项目管理工具,至关于国外的Trello。使用Teambition能够像使用白板与便签纸同样来管理项目进度,以下图所示。python
Teambition虽然便于管理项目,可是若是直接在Teambition上面建立一个项目对应的任务,却容易陷入面对茫茫白板,不知道如何拆分任务的尴尬境地。以下图所示。git
面对这个空荡荡的窗口,应该添加哪些任务进去?直接用脑子现想,恐怕容易出现顾此失彼或者干脆漏掉了任务的状况。github
当我要开始一个项目的时候,我通常不会直接打开Teambition就写任务,而是使用一个大纲工具——Workflowy来梳理思路,切分任务。等任务已经切分好了,在誊写到Teambition中,以下图所示。json
但这样就出现了一个问题:首先在Workflowy上面把须要作的任务写好。而后再打开Teambition,把这些任务又誊写到Teambition中。为了减小“誊写”这一步重复劳动,因而就有了TeamFlowy这个小工具。它的做用是自动誊写Workflowy中的特定条目到Teambition中。浏览器
TeamFlowy是一个Python脚本,运行之后,它会登陆Workflowy帐号,读取上面全部的条目。名为[Teambition]的条目是任务开始的标记,这个条目下面的一级条目会做为任务被添加到Teambition中。若是任务下面还有二级条目,这些二级条目会做为子任务被添加到任务中。因为Teambition是按照项目-Stage-任务-子任务的形式组织一个工程(其中Stage对应了Teambition中工程下面的面板,例如:“待处理”,“进行中”,“完成”。)不会存在子任务的子任务,因此Workflowy中[Teambition]这个条目下面最多出现二级缩进。以下图所示。bash
获取Workflowy上面的条目,须要进行三步操做:网络
打开Chrome监控登陆Wokrflowy的过程,能够看到登陆Workflowy须要访问的接口为:https://workflowy.com/accounts/login/
。使用HTTP POST
方式发送请求,提交的数据包括username
,password
和一个不知道用途的next
。以下图所示。session
使用Python的第三方网络模块requests
向这个模块发送POST
请求,提交用户名和密码便可实现登陆。其代码以下:函数
login_url = 'https://workflowy.com/accounts/login/'
session = requests.Session()
session.post(login_url,
data={'username': '12345@qq.com',
'password': '8888888',
'next': ''})复制代码
使用requests
的session
登陆Workflowy之后,Cookies会被自动保存到session
这个对象里面。因而使用session
继续访问Workfowy就能够以登陆后的身份查看本身的各个条目。工具
经过Chrome能够看到获取全部条目的接口为https://workflowy.com/get_initialization_data?client_version=18
,接口返回的数据是一个包含全部条目的超大型JSON字符串,以下图所示。
使用Python的json模块能够解析这个JSON字符串为字典,并获取全部条目,代码以下:
outline_url = 'https://workflowy.com/get_initialization_data?client_version=18'
outlines_json = session.get(outline_url).text
outlines_dict = json.loads(outlines_json)
project_list = outlines_dict.get('projectTreeData', {})\
.get('mainProjectTreeInfo', {})\
.get('rootProjectChildren', [])复制代码
全部的条目层层嵌套在列表-字典结构中,其基本的形态以下:
{
"ch": [子条目],
"lm": 308496,
"id": "957996b9-67ce-51c7-a796-bfbee44e3d3f",
"nm": "AutoEmo"
}复制代码
其中的nm
为这个条目的名字。若是一个条目有子条目,那么ch
列表中就会有不少个字典,每一个字典的都是这个结构,若是一个条目没有子条目,那么就没有ch
这个key。这样一层一层嵌套下去:
{
"ch": [
{
"lm": 558612,
"id": "5117e20b-25ba-ba91-59e1-790c0636f78e",
"nm": "准备并熟背一段自我介绍,在任何须要自我介绍的场合都有用"
},
{
"lm": 558612,
"id": "4894b23e-6f47-8028-a26a-5fb315fc4e6f",
"nm": "姓名,来自哪里,什么工做",
"ch": [
{"lm": 5435246,
"id": "4894b23e-6f47-8028-a26a-5fbadfasdc4e6f",
"nm": "工做经验"}
]
}
],
"lm": 558612,
"id": "ea282a1c-94f3-1a44-c5b3-7907792e9e6e",
"nm": "自我介绍"
}复制代码
因为条目和子条目的结构是同样的,那么就可使用递归来解析每个条目。因为须要添加到Teambition的任务,从名为[Teambition]的条目开始,因而可使用下面这样一个函数来解析:
task_dict = {}
def extract_task(sections, task_dict, target_section=False):
for section in sections:
name = section['nm']
if target_section:
task_dict[name] = [x['nm'] for x in section.get('ch', [])]
continue
if name == '[Teambition]':
target_section = True
sub_sections = section.get('ch', [])
extract_task(sub_sections, task_dict, target_section=target_section)复制代码
下图所示为一段须要添加到Teambition中的条目,运行这段函数之后,获得的结果为:
{'登陆Workflowy': [], '获取须要添加到Teambition的内容': ['获取任务', '获取子任务'], '调试Teambition API': [], '添加任务到Teambition': []}复制代码
将任务添加到Teambition,须要使用Teambition的Python SDK登陆Teambition并调用API添加任务。Teambition的Python SDK在使用OAuth2
获取access_token
的时候有一个坑,须要特别注意。
Teambition 是使用OAuth2
来进行权限验证的,因此须要获取access_token
。
首先打开Teambition的开发者中心并单击新建应用
,以下图所示。
应用名称能够随便写。建立好应用之后,能够看到应用的信息,须要记录Client ID
和Client Secret
,以下图所示。
点击左侧的OAuth2
配置,填写回调URL,以下图所示。这里的这个URL其实使用任何一个能够访问的网站的域名均可以,这里以个人博客地址为例。
首先在Python中安装Teambition的SDK:
pip install teambition复制代码
接下来,在Python中获取受权URL:
from teambition import Teambition
tb_client_id = '7bfae080-a8dc-11e7-b543-77a936726657'
tb_client_secret = '9830fc8c-81b3-45ed-b3c0-e039ab8f2d8b'
tb = Teambition(tb_client_id,
tb_client_secret)
authorize_url = tb.oauth.get_authorize_url('https://kingname.info')
print(authorize_url)复制代码
代码运行之后,会获得一段形以下面这段URL的受权URL:
https://account.teambition.com/oauth2/authorize?client_id=7bfae080-a8dc-11e7-b543-77a936726657&redirect_uri=https://kingname.info&state=&lang=zh复制代码
在电脑浏览器中人工访问这个URL,会出现下面这样的页面。
单击受权并登陆
,能够看到浏览器上面的网址变为形如:https://kingname.info/?code=Pn7ebs4sZh3NYOz2FvVJQ4uu
,此时,须要记录code=
后面的这一串字符串Pn7ebs4sZh3NYOz2FvVJQ4uu
。
接下来就是Teambition的SDK的坑点了,根据Teambition官方文档的说法,要获取access_token,只须要以下两段代码:
code = 'Pn7ebs4sZh3NYOz2FvVJQ4uu' #前面浏览器中的字符串
tb.oauth.fetch_access_token(code)
# 上面的代码完成受权,接下来直接使用tb.xxxx就能够操做任务了。复制代码
但实际上,上面这一段代码必定会报错。提示grant invaild
。要解决这个问题,就必需使用Teambition的HTTP 接口来人工获取access_token。
code = 'Pn7ebs4sZh3NYOz2FvVJQ4uu' #前面浏览器中的字符串
fetch_result_dict = session.post('https://account.teambition.com/oauth2/access_token',
data={'client_id': tb_client_id,
'client_secret': tb_client_secret,
'code': code,
'grant_type': 'code'}).json()
tb_access_token = fetch_result_dict.get('access_token', '')复制代码
此时获得的access_token是一段很是长的字符串。接下来,从新初始化tb变量:
tb = Teambition(tb_client_id,
tb_client_secret,
access_token=tb_access_token)复制代码
初始化之后,使用tb这个变量,就能够对工程和任务进行各类操做了。
要在某个工程里面建立任务,就须要知道工程的ID。首先在Teambition中手动建立一个工程,在浏览器中打开工程,URL中能够看到工程的ID,以下图所示。
有了工程ID之后,就可使用下面的代码建立任务:
def create_task(task_name, sub_task_list):
tasklist = tb.tasklists.get(project_id='59d396ee1013d919f3348675')[0]
tasklist_id = tasklist['_id']
todo_stage_id = tasklist['stageIds'][0]
task_info = tb.tasks.create(task_name, tasklist_id=tasklist_id, stage_id=todo_stage_id)
if sub_task_list:
task_id = task_info['_id']
for sub_task_name in sub_task_list:
tb.subtasks.create(sub_task_name, task_id=task_id)
print(f'task: {task_name} with sub tasks: {sub_task_list} added.')复制代码
这段代码首先使用tb.tasklists.get()
根据工程ID得到任务组的ID和待处理
这个面板的ID,接下来调用tb.tasks.create()
接口添加任务。从添加任务返回的信息里面拿到任务的ID,再根据任务ID,调用tb.subtasks.create()
添加子任务ID。
上面的代码实现了TeamFlowy的基本逻辑。运行TeamFlowy脚本之后,[Teambition]这个条目下面的任务被成功的添加到了Teambition中,以下图所示。
将代码组合起来并进行完善,让代码更容易使用,完整的代码能够查看github.com/kingname/Te…。完整的代码运行效果以下图所示。