OnePoint API 文档

in 映射网盘 with 2 comments

其他

在读本文档之前,首先需要了解几个概念:

几个概念

scf:无服务器云函数

scf 是腾讯提供的无服务器云函数服务,它强调无服务器,即用户不需要关心服务器是什么配置,只需要负责好业务处理模块。用户需要提供一组函数代码,并设定特定的触发方式。当有事件产生并且该事件符合该触发方式时,服务器会自动调用用户提供的函数,并完成特定功能。

我们这次将要使用的事件是 api 网关事件。当特定网址被访问时,scf 会自动调用用户提供的函数。关于价格,对于个人来说,scf 提供的免费额度完全够用(具体额度参考 官网 )。

免费额度

资源类型每月免费额度
资源使用量40 万 GBs
调用次数100 万次

由于 api 网关从 2019 年 12 月 4 日起开始商用,无免费额度,故我又对 onepoint 进行了一些修改,让它能够部署到其他地方。

映射网盘

首先这词可能是我原创的,百度不到。顾名思义,映射网盘并不是一个真正的网盘,它需要有其他网盘作为底层网盘。当用户访问映射网盘时,映射网盘负责请求转换,使得用户实际上访问的是其他网盘。

举个例子,oneindex 就是一个映射网盘,它的底层网盘是 onedrive 。

OnePoint

oneindex 项目很棒 ,但它只能运行在服务器上,代价太高。所以我们考虑用 scf 运行这一套服务,于是就有了 onedrive_scf 。但遗憾的是,这两个项目都对 onedrive 账号有要求,账号必须要能够开通 api 才行,像国内教育邮箱( edu.cn )注册的账号根本无法使用此功能。但 edu.cn 邮箱注册的 onedrive 又是最安全的,所以我就利用 sharepoint 的分享功能创造出了 onepoint,因此可以支持几乎所有的onedrive账户。

关于 onedrive 账号的问题,以后有时间了可以给大家再讲讲。

概述

OnePoint 是对原有 OnePoint (SharePoint 版本) 的扩展。原有的 OnePoint 通过路径映射的方式支持多个onedrive 网盘。这一次我把映射的对象改为了不同的网盘,忽略了网盘之间的差异性,只提取其文件名、大小、修改时间、类型、下载链接等共有信息,将其按照约定的数据类型排列,使得在通过映射网盘访问各个网盘时几乎感受不到差别。因为有了控制和数据的分离,因此,我们也就可以统一风格,让我们的网盘看起来更加规整,更加和谐,更加多样化。

基本流程

  1. 请求接口适配
  2. 路径映射
  3. 调用网盘函数,获取文件信息
  4. 调用渲染函数,获取 html

路径映射

一般来说,我们把请求的 url 按照这样的格式分割。

http://<; ph >/< p0 >/< p1 >/< p2 >

为了便于说明,我们将单个映射后的网盘简称为网盘,将所有网盘组成的整体称为网盘组。

http://example.com/release/mmx/a/b/c 为例,各个部分意义如下:

当一个 http 请求出现后,我们首先将路径中与云盘组无关的内容(p0)处理掉,剩下的p1+p2就是我们的网盘组的请求路径,我们将其简称为 p_12 。

而 p_12 再按照预先配置好的映射表,按照最长匹配原则分割得到 p1 和 p2 ,其中 p1 由映射的键决定,剩下的就是 p2 。

p2 就是单个网盘的请求路径。一个网盘处理函数只需要处理 p2 即可。

路径映射表格式如下:

const DRIVE_MAP = {
    "/": {//映射路径
        func: MS_OD,//该映射将会调用的函数, 由开发者提供
        spConfig: {},//上面func函数需要的专用配置数据, 开发者决定其结构
        cache: {},//开发者自行组织, 数据cache统一放到该对象下, 便于管理
        password: "",//保留 
    }
}

网盘函数

调用形式

func(spConfig, cache, event);
let event = {
    method,//GET POST
    headers,//http headers
    body,//http body,数据为 json 格式
    cookie,//解析自 headers, json 格式
    query,//解析自 headers, json 格式
    sourceIp,//访问 ip
    splitPath:{
        ph,p0,p_12,p_h01,p2//请求路径信息,与路径映射部分给出的定义相同
    }
}
//@depressed 原 request 格式
//let request = {
//   httpMethod,//get post
//    url_ph01,// //ph/p0/p1, 例如 //release/mmx
//    url_p2,// p2, 路径信息,查询该路径下的文件列表或文件。例如 /a/b/c
//    queryString,//scf event 提供
//    headers,//scf event 提供
//    body,//scf event 提供
//    sourceIp//访问源ip
//}

一些约定

一些建议

返回值结构

下面是返回对象的结构表,实际使用中只需要返回指定的部分值,具体构成参考下面的具体返回。

{
    noRender:true,//如果为true ,则必须与 statusCode headers html 配合使用
    html:"",//noRender 为true时有效
    statusCode: 200,//200 301 302 401 403 404 500,
    type: 1, //0_file 1_dir 2_info #200 
    data: { // #200
        content: [
            {
                nodeType: 0, //type: 0_file 1_dir 3_drive, drive 类型由系统自动生成。
                name: "文件名或文件夹名或云盘名",
                fileType: "txt",//文件类型,不带点,nodeType为0时有效
                url_p2: "/a/b/c", //以p2为基准的根目录
                size: "文件大小xx MB,文件夹 XX 个项目 或 xx MB",
                modified: "最近修改日期,文件夹或云盘可为空",
                otherInfo: {} //此项不用,留给开发者存放其他信息 //可为 undefined
            }
        ],
        prevHref: "", //上一页,以p2为基准的请求 可为 undefined
        nextHref: "", //可为 undefined

        fileInfo: {
            downloadUrl: "https://example.com/abc.txt",//直链
            name: "abc.txt",//文件夹名
            fileType: "mp4",//文件类型,不带点
            url_p2: "/a/b/c/abc.txt",//以p2为基准的根目录
            size: "XX MB",//XX items 或 xx MB
            modified: "2019-01-02 15:02:44",//最近修改日期,固定格式
            otherInfo: {},//此项不用,留给开发者存放其他信息 可为 undefined
            mimeType: "",//保留, 此项不用 可为 undefined
        }
    },
    headers:{// info
        location:'http://example.com',//# 301 302
        'set-cookie':cookiecookie
    },
    info: "", //all
    readMe: { //all
        type: 0, //0空,1链接,前端实现加载, 2 md文本,建议不要过长
        txt: ""
    },
    script: "" //all
}

200_文件列表

{
    statusCode: 200,//固定值
    type: 1,//1_dir 固定值
    data: {// #200
        content: [
            {
                nodeType: 0,//type: 0_file 
                name: "abc.txt",//文件名
                fileType: "txt",//文件类型,不带点
                url_p2: "/a/b/c/abc.txt",//以p2为基准的根目录
                size: "10.32 MB",//文件大小xx.xx MB, 保留两位小数,中间空格不可少
                modified: "2019-01-02 15:02:44",//最近修改日期,固定格式
                otherInfo: {}//此项不用,留给开发者存放其他信息 可为 undefined
            },
            {
                nodeType: 1,//1_dir
                name: "d",//文件夹名
                fileType: "",// 为 "" 或 undefined
                url_p2: "/a/b/c/d/",//以p2为基准的根目录
                size: "XX items",//XX items 或 xx MB
                modified: "2019-01-02 15:02:44",//最近修改日期, 固定格式
                otherInfo: {}//此项不用,留给开发者存放其他信息 可为 undefined
            }
        ],
        prevHref: "/a/b/c/?page=5",//上一页, 以p2为基准的请求, 留空则表示无上一页 可为 undefined
        nextHref: "" //可为 undefined
    },
    readMe: {//all
        type: 0,//0空, 1链接 由前端实现加载, 2文本 建议不要过长
        txt: ""
    },
    script: ""//all
}

200_文件信息

{
    statusCode: 200,//固定值
    type: 0,//0_file 固定值
    data: {// #200
        fileInfo: {
            downloadUrl: "https://example.com/abc.txt",//直链
            name: "abc.txt",//文件夹名
            fileType: "mp4",//文件类型,不带点
            url_p2: "/a/b/c/abc.txt",//以p2为基准的根目录
            size: "XX MB",//XX items 或 xx MB
            modified: "2019-01-02 15:02:44",//最近修改日期,固定格式
            otherInfo: {},//此项不用,留给开发者存放其他信息 可为 undefined
            mimeType: "",//保留, 此项不用 可为 undefined
        }
    },
    readMe: {//all
        type: 0,//0空,1链接,前端实现加载,2文本,建议不要过长
        txt: ""
    },
    script: ""//all
}

200_消息通知

{
    statusCode: 200,//固定值
    type: 2,//2_info, //固定值
    info: "访问文件不存在",
    headers:{},
    readMe: {//all
        type: 0,//0空,1链接,前端实现加载,2文本,建议不要过长
        txt: ""
    },
    script: ""//all
}

3xx_重定向

{
    statusCode: 301,//301 302 固定值
    info: "重定向",//
    headers:{},
    readMe: {//all
        type: 0, //0空,1链接,前端实现加载,2文本,建议不要过长
        txt: ""
    },
    script: ""//all
}

4xx_5xx_info

{
    statusCode: 404,//401 403 404 500 固定值
    info: "访问文件不存在",//#401 403 404 500
    headers:{},
    readMe: {//all
        type: 0, //0空,1链接,前端实现加载,2文本,建议不要过长
        txt: ""
    },
    script: ""//all
}

noRender

{
    noRender:true,
    statusCode: xxx,
    headers:{},
    html:""
}

渲染函数

view 层:

四个函数

文件列表,文件预览,信息通知,密码认证

r200_list(data, readMe, script, splitPath, G_CONFIG);
r200_file(fileInfo, readMe, script, splitPath, G_CONFIG);
r401_auth(info, readMe, script, splitPath, G_CONFIG);
rxxx_info(info, readMe, script, splitPath, G_CONFIG);

其中 splitPath, G_CONFIG 分别为:

let splitPath = { 
    "host": "//" + host, 
    "p0": p0, 
    "p1": p1,
    "p2": p2
};
let G_CONFIG = {
    "enablePreview": true,
    "site_title": "onePoint Demo",
    "site_icon": "",
    "site_keywords": "onePoint",
    "site_description": "onePoint description",
    "site_script": ""//统计代码之类的可以放这里
};

渲染函数相对来说就比较自由,但仍需要遵守下面的规则。

一些规定

编码建议:

建议 node,其他也可,但需要符合返回值格式。

更新日志:

191201

修改 request 为 event

191110

request 新增 sourceIp, req_cookie_json, req_body_json
新增 noRender html 返回项

191101

修改 func(spConfig, cache, p2, query, body);
整合p2 queryString body 至 request 中, p2改名为 url_p2;整合 redirectUrl 至 headers

191029

初次发布

Responses
  1. 小屁孩

    有没有视频教程

    Reply
    1. @小屁孩

      暂时还没有

      Reply