这次终于要做一个 Pro 版本里没有的功能啦!这次是完全没有任何外援啦!
需求分析
众所周知,现在很多网盘都自带离线下载功能,简单来说就是丢一个链接给云盘系统,然后系统会自动在后台把文件下载到服务器上,然后在界面上呈现。
简单分析了一下所需要的需求:
- 用户提供链接,创建离线下载任务
- 用户查看任务历史记录
- 对用户提供的链接进行下载,并存储到 SeafileFS
初步考虑,我打算把下载任务放在 seafevents 里面,模仿 statistics 的事件系统和 virus-scan 的外部程序调用系统,并开单独线程来完成这些操作。调用的系统嘛。。。就选 Aria2 了,据说这玩意用来下载东西还挺好用的?
解决前端(1)
前端咱们一直以来都是在找 isPro 和去除 isPro,现在终于轮到咱们自己写界面了。
我首先打算的就是在这里加一个新的按钮,用于打开离线下载对话框:
找到对应的文件 frontend/src/components/toolbar/dir-operation-toolbar.js
,并在 render() 函数中添加:
<li className="dropdown-item" onClick={this.onOfflineUpload}>{gettext('Offline Upload')}</li>
然后我们要添加一下翻译文件条目,在 locale/en/LC_MESSAGES/djangojs.po
中:
msgid "Offline Upload"
msgstr ""
locale/zh_CN/LC_MESSAGES/djangojs.po
中:
msgid "Offline Upload"
msgstr "离线上传"
然后注意啦,我们刚才添加了一个条目,对应的按钮相应事件也需要加上:
onOfflineUpload = (e) => {
this.setState({isUploadMenuShow: false});
this.props.onOfflineUpload(e);
}
我们这里是模仿了上传文件和上传文件夹的写法。那么,需要在 propTypes
里面加上:
onOfflineUpload: PropTypes.func.isRequired,
这里其实就相当于为 React Component 加了一个必备参数,要求传入离线下载按钮被单击后的执行函数。根据 IDEA 分析,只有 lib-content-toolbar.js
使用了 DirOperationToolbar
,那么我们找到它的调用位置:
<DirOperationToolBar
path={this.props.path}
repoID={this.props.repoID}
repoName={this.props.repoName}
repoEncrypted={this.props.repoEncrypted}
direntList={this.props.direntList}
showShareBtn={this.props.showShareBtn}
enableDirPrivateShare={this.props.enableDirPrivateShare}
userPerm={this.props.userPerm}
isGroupOwnedRepo={this.props.isGroupOwnedRepo}
onAddFile={this.props.onAddFile}
onAddFolder={this.props.onAddFolder}
onUploadFile={this.props.onUploadFile}
onUploadFolder={this.props.onUploadFolder}
currentMode={this.props.currentMode}
switchViewMode={this.props.switchViewMode}
/>
我们加上一个新的参数:
onOfflineUpload={this.props.onOfflineUpload}
那么这里相当于又给 LibContentToolbar
加了一个参数,先加在 propTypes
里:
onOfflineUpload: PropTypes.func.isRequired,
然后再通过 IDEA 分析,发现是 lib-content-view.js
使用了 LibContentToolbar
,那么我们又找到了那个使用的地方,又如法炮制加上了调用参数。不过这里不一样的是,我们不再把它作为参数加入 LibContentView
,而是直接在这里处理它。
先在这个文件里添加一个函数:
onOfflineUpload = (e) => {
e.nativeEvent.stopImmediatePropagation();
// TODO: Open offline download dialog
}
然后我们要做那个对话框。再此之前,我们先进行打包和测试,发现我们想要的效果已经达到了。
今天先做这么多,因为有别的事情(考试啊啊啊啊啊