Open edx笔记系统探究
文章目录
edx笔记系统是很有意思的一个话题
架构
- 前端
- 后端
- 通信方式:RESTful接口
由此可知笔记可以作为一项服务
前端
笔记库:annotator
edx中的依赖
edx中业务逻辑
后端
已废弃
edx-notes-api
lms
其他
RESTful接口
通信相关
在LMS中记条笔记的来龙去脉
在lms里做笔记,观察ajax请求,可以看到笔记以POST方式发往:http://NOTESERVER/api/v1/annotations/
header中带有x-annotator-auth-token
和X-CSRFToken
x-annotator-auth-token
实际上是一个JWT编码的串,放到jwt.io解码完,可看到结果形如
|
|
代码见get_token
上边链接所在的模块就是lms与NOTESERVER通信的模块,通信的url入口为get_internal_endpoint
新技能
这里边有个值得注意的地方是:get_id_token,这个工具是通用的,如果想用jwt来发送受信信息的话
通过JWT,我们可以保证数据是被签名过可信任的。
值得注意的还有当前这部分并不完善,许多地方还是硬编码的,诸如:CLIENT_NAME
观察网络面板,可以看到,发送的数据形如
|
|
相关的前端模型定义在edxnotes/models/note.js
前端note工厂为edxnotes/views/notes_factory.js
user是不是采用了什么编码/加密(和edx的匿名用户id一样吗?)
对此有兴趣的同学可以参考common/templates/edxnotes_wrapper.html,其中关键部分为:
|
|
猜测和edx成绩单中匿名用户的机制一样
出于好奇,追踪到底:anonymous_id_for_user,至此我们揭开了匿名ip的全部谜团
- Return a unique id for a (user, course) pair
- If user is an
AnonymousUser
, returnsNone
核心源码为
|
|
由此可知,登录用户的anonymous_id是唯一的,使其具有唯一性的影响因素包括:
- settings.SECRET_KEY(站点级别)
- course_id
- user.id
心满意足收场
搜索笔记
我们在lms的笔记汇总页面http://LMS/courses/course-v1:edX+DemoX+Demo_Course/edxnotes/
搜索笔记时,发出的http(ajax)请求为http://LMS/courses/course-v1:edX+DemoX+Demo_Course/edxnotes/search/?text=hello
实际上,这个请求实际上是代理了edx-notes-api。
edx-notes-api
我们使用httpie来向edx-notes-api请求笔记数据
http://NOTESERVER/api/v1/search/?user=106ecd878f4148a5cabb6bbb0979b730&usage_id=block-v1%3AedX%2BDemoX%2BDemo_Course%2Btype%40html%2Bblock%4082d599b014b246c7a9b5dfc750dc08a9&course_id=course-v1%3AedX%2BDemoX%2BDemo_Course
url解码完为http://NOTESERVER/api/v1/search/?user=106ecd878f4148a5cabb6bbb0979b730&usage_id=block-v1:edX+DemoX+Demo_Course+type@html+block@82d599b014b246c7a9b5dfc750dc08a9&course_id=course-v1:edX+DemoX+Demo_Course
我们使用httpie测试
http “http://NOTESERVER/api/v1/search/?user=106ecd878f4148a5cabb6bbb0979b730&usage_id=block-v1%3AedX%2BDemoX%2BDemo_Course%2Btype%40html%2Bblock%4082d599b014b246c7a9b5dfc750dc08a9&course_id=course-v1%3AedX%2BDemoX%2BDemo_Course” (注意要url编码!)
得到
|
|
注意其中的ranges
属性,这是定位的关键,end和start是xpath,tags
属性用于存放标签,usage_id
是课程内容的定位符,user是用户匿名化后的结果
架构设计
edx的架构总体而言是采用RESTful api来解耦,笔记模块也不例外
edx的笔记前端模块采用的是openannotation开放出来的annotator,openannotation同时也开放了后端,edX没有采用他们的后端,而是使用django-rest-framework重写了笔记部分的后端,我想应该是出于一致性的考虑,这样一来,整个团队的技术栈是统一的,个人而言我觉得这是个明智的决定,尽管这可能浪费一些时间(这确实浪费了不少时间,要知道笔记系统在birch版本中就准备投入使用的!)。
我之所以会赞同这种做法,可能是因为对论坛模块的恐惧吧,论坛采用ruby写的,想对此做定制优化,就显得艰难(事实证明论坛也的确不够稳定)
保持技术栈的一致,有利于让团队成员更热衷维护它们
如果你有兴趣进一步看笔记的模型,请阅读notesapi/v1/models.py
总结
edx的笔记系统可以单独部署,只要做好oauth2的配置即可
由于笔记系统是基于oauth2的,所以可以为手机端所用,同时如果我们将笔记系统视为一个服务,我们可以将它用在edx之外的网站或app里
后话
我对阅读和笔记偏好有加,想基于以下东西做个工具
- annotator
- firebase
- chrome插件
- 参考划词翻译或者pocket
一个随手摘工具,同时能高亮做过笔记的网页
文章作者 种瓜
上次更新 2016-05-24