解决v2.0.0公测版大家反馈的问题
This commit is contained in:
parent
78ab2ed495
commit
6a63ea8e85
@ -1,13 +1,13 @@
|
|||||||
var authConfig = {
|
var authConfig = {
|
||||||
"siteName": "Achirou's Cloud", // 网站名称
|
siteName: "Achirou's Cloud", // 网站名称
|
||||||
"version" : "1.1.0", // 程序版本
|
version: "1.1.0", // 程序版本
|
||||||
"theme" : "acrou",
|
theme: "acrou",
|
||||||
/*"client_id": "202264815644.apps.googleusercontent.com",
|
/*"client_id": "202264815644.apps.googleusercontent.com",
|
||||||
"client_secret": "X4Z3ca8xfWDb1Voo-F9a7ZxJ",*/
|
"client_secret": "X4Z3ca8xfWDb1Voo-F9a7ZxJ",*/
|
||||||
// 强烈推荐使用自己的 client_id 和 client_secret
|
// 强烈推荐使用自己的 client_id 和 client_secret
|
||||||
"client_id": "",
|
client_id: "",
|
||||||
"client_secret": "",
|
client_secret: "",
|
||||||
"refresh_token": "", // 授权 token
|
refresh_token: "", // 授权 token
|
||||||
/**
|
/**
|
||||||
* 设置要显示的多个云端硬盘;按格式添加多个
|
* 设置要显示的多个云端硬盘;按格式添加多个
|
||||||
* [id]: 可以是 团队盘id、子文件夹id、或者"root"(代表个人盘根目录);
|
* [id]: 可以是 团队盘id、子文件夹id、或者"root"(代表个人盘根目录);
|
||||||
@ -21,7 +21,7 @@ var authConfig = {
|
|||||||
* 不需要 Basic Auth 的盘,保持 user 和 pass 同时为空即可。(直接不设置也可以)
|
* 不需要 Basic Auth 的盘,保持 user 和 pass 同时为空即可。(直接不设置也可以)
|
||||||
* 【注意】对于id设置为为子文件夹id的盘将不支持搜索功能(不影响其他盘)。
|
* 【注意】对于id设置为为子文件夹id的盘将不支持搜索功能(不影响其他盘)。
|
||||||
*/
|
*/
|
||||||
"roots": [
|
roots: [
|
||||||
{
|
{
|
||||||
id: "",
|
id: "",
|
||||||
name: "TeamDrive",
|
name: "TeamDrive",
|
||||||
@ -30,45 +30,52 @@ var authConfig = {
|
|||||||
{
|
{
|
||||||
id: "root",
|
id: "root",
|
||||||
name: "PrivateDrive",
|
name: "PrivateDrive",
|
||||||
user: '',
|
user: "",
|
||||||
pass: "",
|
pass: "",
|
||||||
protect_file_link: true
|
protect_file_link: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "",
|
id: "",
|
||||||
name: "folder1",
|
name: "folder1",
|
||||||
pass: "",
|
pass: "",
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"default_gd": 0,
|
default_gd: 0,
|
||||||
/**
|
/**
|
||||||
* 文件列表页面每页显示的数量。【推荐设置值为 100 到 1000 之间】;
|
* 文件列表页面每页显示的数量。【推荐设置值为 100 到 1000 之间】;
|
||||||
* 如果设置大于1000,会导致请求 drive api 时出错;
|
* 如果设置大于1000,会导致请求 drive api 时出错;
|
||||||
* 如果设置的值过小,会导致文件列表页面滚动条增量加载(分页加载)失效;
|
* 如果设置的值过小,会导致文件列表页面滚动条增量加载(分页加载)失效;
|
||||||
* 此值的另一个作用是,如果目录内文件数大于此设置值(即需要多页展示的),将会对首次列目录结果进行缓存。
|
* 此值的另一个作用是,如果目录内文件数大于此设置值(即需要多页展示的),将会对首次列目录结果进行缓存。
|
||||||
*/
|
*/
|
||||||
"files_list_page_size": 50,
|
files_list_page_size: 50,
|
||||||
/**
|
/**
|
||||||
* 搜索结果页面每页显示的数量。【推荐设置值为 50 到 1000 之间】;
|
* 搜索结果页面每页显示的数量。【推荐设置值为 50 到 1000 之间】;
|
||||||
* 如果设置大于1000,会导致请求 drive api 时出错;
|
* 如果设置大于1000,会导致请求 drive api 时出错;
|
||||||
* 如果设置的值过小,会导致搜索结果页面滚动条增量加载(分页加载)失效;
|
* 如果设置的值过小,会导致搜索结果页面滚动条增量加载(分页加载)失效;
|
||||||
* 此值的大小影响搜索操作的响应速度。
|
* 此值的大小影响搜索操作的响应速度。
|
||||||
*/
|
*/
|
||||||
"search_result_list_page_size": 50,
|
search_result_list_page_size: 50,
|
||||||
// 确认有 cors 用途的可以开启
|
// 确认有 cors 用途的可以开启
|
||||||
"enable_cors_file_down": false,
|
enable_cors_file_down: false,
|
||||||
/**
|
/**
|
||||||
* 上面的 basic auth 已经包含了盘内全局保护的功能。所以默认不再去认证 .password 文件内的密码;
|
* 上面的 basic auth 已经包含了盘内全局保护的功能。所以默认不再去认证 .password 文件内的密码;
|
||||||
* 如果在全局认证的基础上,仍需要给某些目录单独进行 .password 文件内的密码验证的话,将此选项设置为 true;
|
* 如果在全局认证的基础上,仍需要给某些目录单独进行 .password 文件内的密码验证的话,将此选项设置为 true;
|
||||||
* 【注意】如果开启了 .password 文件密码验证,每次列目录都会额外增加查询目录内 .password 文件是否存在的开销。
|
* 【注意】如果开启了 .password 文件密码验证,每次列目录都会额外增加查询目录内 .password 文件是否存在的开销。
|
||||||
*/
|
*/
|
||||||
"enable_password_file_verify": true
|
enable_password_file_verify: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
var themeOptions = {
|
var themeOptions = {
|
||||||
//可选默认系统语言:en/zh-chs/zh-cht
|
//可选默认系统语言:en/zh-chs/zh-cht
|
||||||
languages: 'en'
|
languages: "en",
|
||||||
}
|
render: {
|
||||||
|
head_md: false,
|
||||||
|
readme_md: false,
|
||||||
|
// 是否显示文件/文件夹描述(默认不显示)
|
||||||
|
// Show file/folder description or not (not shown by default)
|
||||||
|
desc: false
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* global functions
|
* global functions
|
||||||
@ -77,15 +84,15 @@ const FUNCS = {
|
|||||||
/**
|
/**
|
||||||
* 转换成针对谷歌搜索词法相对安全的搜索关键词
|
* 转换成针对谷歌搜索词法相对安全的搜索关键词
|
||||||
*/
|
*/
|
||||||
formatSearchKeyword: function (keyword) {
|
formatSearchKeyword: function(keyword) {
|
||||||
let nothing = "";
|
let nothing = "";
|
||||||
let space = " ";
|
let space = " ";
|
||||||
if (!keyword) return nothing;
|
if (!keyword) return nothing;
|
||||||
return keyword.replace(/(!=)|['"=<>/\\:]/g, nothing)
|
return keyword
|
||||||
|
.replace(/(!=)|['"=<>/\\:]/g, nothing)
|
||||||
.replace(/[,,|(){}]/g, space)
|
.replace(/[,,|(){}]/g, space)
|
||||||
.trim()
|
.trim();
|
||||||
}
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -93,16 +100,16 @@ const FUNCS = {
|
|||||||
* @type {{folder_mime_type: string, default_file_fields: string, gd_root_type: {share_drive: number, user_drive: number, sub_folder: number}}}
|
* @type {{folder_mime_type: string, default_file_fields: string, gd_root_type: {share_drive: number, user_drive: number, sub_folder: number}}}
|
||||||
*/
|
*/
|
||||||
const CONSTS = new (class {
|
const CONSTS = new (class {
|
||||||
default_file_fields = 'parents,id,name,mimeType,modifiedTime,createdTime,fileExtension,size';
|
default_file_fields =
|
||||||
|
"parents,id,name,mimeType,modifiedTime,createdTime,fileExtension,size";
|
||||||
gd_root_type = {
|
gd_root_type = {
|
||||||
user_drive: 0,
|
user_drive: 0,
|
||||||
share_drive: 1,
|
share_drive: 1,
|
||||||
sub_folder: 2
|
sub_folder: 2,
|
||||||
};
|
};
|
||||||
folder_mime_type = 'application/vnd.google-apps.folder';
|
folder_mime_type = "application/vnd.google-apps.folder";
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
// gd instances
|
// gd instances
|
||||||
var gds = [];
|
var gds = [];
|
||||||
|
|
||||||
@ -118,8 +125,14 @@ function html(current_drive_order = 0, model = {}) {
|
|||||||
@import url(https://cloud.jsonpop.cn/go2index/v2.0.0_beta/dist/style.css);
|
@import url(https://cloud.jsonpop.cn/go2index/v2.0.0_beta/dist/style.css);
|
||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
window.gdconfig = JSON.parse('${JSON.stringify({version: authConfig.version,themeOptions: themeOptions})}');
|
window.gdconfig = JSON.parse('${JSON.stringify({
|
||||||
window.gds = JSON.parse('${JSON.stringify(authConfig.roots.map(it => it.name))}');
|
version: authConfig.version,
|
||||||
|
themeOptions: themeOptions,
|
||||||
|
})}');
|
||||||
|
window.themeOptions = JSON.parse('${JSON.stringify(themeOptions)}');
|
||||||
|
window.gds = JSON.parse('${JSON.stringify(
|
||||||
|
authConfig.roots.map((it) => it.name)
|
||||||
|
)}');
|
||||||
window.MODEL = JSON.parse('${JSON.stringify(model)}');
|
window.MODEL = JSON.parse('${JSON.stringify(model)}');
|
||||||
window.current_drive_order = ${current_drive_order};
|
window.current_drive_order = ${current_drive_order};
|
||||||
</script>
|
</script>
|
||||||
@ -130,9 +143,9 @@ function html(current_drive_order = 0, model = {}) {
|
|||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
`;
|
`;
|
||||||
};
|
}
|
||||||
|
|
||||||
addEventListener('fetch', event => {
|
addEventListener("fetch", (event) => {
|
||||||
event.respondWith(handleRequest(event.request));
|
event.respondWith(handleRequest(event.request));
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -145,11 +158,11 @@ async function handleRequest(request) {
|
|||||||
for (let i = 0; i < authConfig.roots.length; i++) {
|
for (let i = 0; i < authConfig.roots.length; i++) {
|
||||||
const gd = new googleDrive(authConfig, i);
|
const gd = new googleDrive(authConfig, i);
|
||||||
await gd.init();
|
await gd.init();
|
||||||
gds.push(gd)
|
gds.push(gd);
|
||||||
}
|
}
|
||||||
// 这个操作并行,提高效率
|
// 这个操作并行,提高效率
|
||||||
let tasks = [];
|
let tasks = [];
|
||||||
gds.forEach(gd => {
|
gds.forEach((gd) => {
|
||||||
tasks.push(gd.initRootType());
|
tasks.push(gd.initRootType());
|
||||||
});
|
});
|
||||||
for (let task of tasks) {
|
for (let task of tasks) {
|
||||||
@ -168,13 +181,16 @@ async function handleRequest(request) {
|
|||||||
* @returns {Response}
|
* @returns {Response}
|
||||||
*/
|
*/
|
||||||
function redirectToIndexPage() {
|
function redirectToIndexPage() {
|
||||||
return new Response('', {status: 301, headers: {'Location': `/${authConfig.default_gd}:/`}});
|
return new Response("", {
|
||||||
|
status: 301,
|
||||||
|
headers: { Location: `/${authConfig.default_gd}:/` },
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path == '/') return redirectToIndexPage();
|
if (path == "/") return redirectToIndexPage();
|
||||||
if (path.toLowerCase() == '/favicon.ico') {
|
if (path.toLowerCase() == "/favicon.ico") {
|
||||||
// 后面可以找一个 favicon
|
// 后面可以找一个 favicon
|
||||||
return new Response('', {status: 404})
|
return new Response("", { status: 404 });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 特殊命令格式
|
// 特殊命令格式
|
||||||
@ -187,46 +203,48 @@ async function handleRequest(request) {
|
|||||||
if (order >= 0 && order < gds.length) {
|
if (order >= 0 && order < gds.length) {
|
||||||
gd = gds[order];
|
gd = gds[order];
|
||||||
} else {
|
} else {
|
||||||
return redirectToIndexPage()
|
return redirectToIndexPage();
|
||||||
}
|
}
|
||||||
// basic auth
|
// basic auth
|
||||||
for (const r = gd.basicAuthResponse(request); r;) return r;
|
for (const r = gd.basicAuthResponse(request); r; ) return r;
|
||||||
command = match.groups.command;
|
command = match.groups.command;
|
||||||
|
|
||||||
// 搜索
|
// 搜索
|
||||||
if (command === 'search') {
|
if (command === "search") {
|
||||||
if (request.method === 'POST') {
|
if (request.method === "POST") {
|
||||||
// 搜索结果
|
// 搜索结果
|
||||||
return handleSearch(request, gd);
|
return handleSearch(request, gd);
|
||||||
} else {
|
} else {
|
||||||
const params = url.searchParams;
|
const params = url.searchParams;
|
||||||
// 搜索页面
|
// 搜索页面
|
||||||
return new Response(html(gd.order, {
|
return new Response(
|
||||||
q: params.get("q") || '',
|
html(gd.order, {
|
||||||
|
q: params.get("q") || "",
|
||||||
is_search_page: true,
|
is_search_page: true,
|
||||||
root_type: gd.root_type
|
root_type: gd.root_type,
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
status: 200,
|
status: 200,
|
||||||
headers: {'Content-Type': 'text/html; charset=utf-8'}
|
headers: { "Content-Type": "text/html; charset=utf-8" },
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} else if (command === 'id2path' && request.method === 'POST') {
|
);
|
||||||
return handleId2Path(request, gd)
|
}
|
||||||
} else if (command === 'view'){
|
} else if (command === "id2path" && request.method === "POST") {
|
||||||
|
return handleId2Path(request, gd);
|
||||||
|
} else if (command === "view") {
|
||||||
const params = url.searchParams;
|
const params = url.searchParams;
|
||||||
return gd.view(params.get("url"), request.headers.get('Range'));
|
return gd.view(params.get("url"), request.headers.get("Range"));
|
||||||
} else if (command!=='down' && request.method === 'GET'){
|
} else if (command !== "down" && request.method === "GET") {
|
||||||
return new Response(html(gd.order, {root_type: gd.root_type}), {
|
return new Response(html(gd.order, { root_type: gd.root_type }), {
|
||||||
status: 200,
|
status: 200,
|
||||||
headers: {'Content-Type': 'text/html; charset=utf-8'}
|
headers: { "Content-Type": "text/html; charset=utf-8" },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const reg = new RegExp(`^(/\\d+:)${command}/`, 'g');
|
const reg = new RegExp(`^(/\\d+:)${command}/`, "g");
|
||||||
path = path.replace(reg,(p1,p2)=>{
|
path = path.replace(reg, (p1, p2) => {
|
||||||
return p2+'/'
|
return p2 + "/";
|
||||||
})
|
});
|
||||||
// 期望的 path 格式
|
// 期望的 path 格式
|
||||||
const common_reg = /^\/\d+:\/.*$/g;
|
const common_reg = /^\/\d+:\/.*$/g;
|
||||||
try {
|
try {
|
||||||
@ -238,56 +256,67 @@ async function handleRequest(request) {
|
|||||||
if (order >= 0 && order < gds.length) {
|
if (order >= 0 && order < gds.length) {
|
||||||
gd = gds[order];
|
gd = gds[order];
|
||||||
} else {
|
} else {
|
||||||
return redirectToIndexPage()
|
return redirectToIndexPage();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return redirectToIndexPage()
|
return redirectToIndexPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
// basic auth
|
// basic auth
|
||||||
// for (const r = gd.basicAuthResponse(request); r;) return r;
|
// for (const r = gd.basicAuthResponse(request); r;) return r;
|
||||||
const basic_auth_res = gd.basicAuthResponse(request);
|
const basic_auth_res = gd.basicAuthResponse(request);
|
||||||
path = path.replace(gd.url_path_prefix, '') || '/';
|
path = path.replace(gd.url_path_prefix, "") || "/";
|
||||||
if (request.method == 'POST') {
|
if (request.method == "POST") {
|
||||||
return basic_auth_res || apiRequest(request, gd);
|
return basic_auth_res || apiRequest(request, gd);
|
||||||
}
|
}
|
||||||
|
|
||||||
let action = url.searchParams.get('a');
|
let action = url.searchParams.get("a");
|
||||||
|
|
||||||
if (path.substr(-1) == '/' || action != null) {
|
if (path.substr(-1) == "/" || action != null) {
|
||||||
return basic_auth_res || new Response(html(gd.order, {root_type: gd.root_type}), {
|
return (
|
||||||
|
basic_auth_res ||
|
||||||
|
new Response(html(gd.order, { root_type: gd.root_type }), {
|
||||||
status: 200,
|
status: 200,
|
||||||
headers: {'Content-Type': 'text/html; charset=utf-8'}
|
headers: { "Content-Type": "text/html; charset=utf-8" },
|
||||||
});
|
})
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
if (path.split('/').pop().toLowerCase() == ".password") {
|
if (
|
||||||
return basic_auth_res || new Response("", {status: 404});
|
path
|
||||||
|
.split("/")
|
||||||
|
.pop()
|
||||||
|
.toLowerCase() == ".password"
|
||||||
|
) {
|
||||||
|
return basic_auth_res || new Response("", { status: 404 });
|
||||||
}
|
}
|
||||||
let file = await gd.file(path);
|
let file = await gd.file(path);
|
||||||
let range = request.headers.get('Range');
|
let range = request.headers.get("Range");
|
||||||
if (gd.root.protect_file_link && basic_auth_res) return basic_auth_res;
|
if (gd.root.protect_file_link && basic_auth_res) return basic_auth_res;
|
||||||
const is_down = !(command && command=='down');
|
const is_down = !(command && command == "down");
|
||||||
return gd.down(file.id, range, is_down);
|
return gd.down(file.id, range, is_down);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function apiRequest(request, gd) {
|
async function apiRequest(request, gd) {
|
||||||
let url = new URL(request.url);
|
let url = new URL(request.url);
|
||||||
let path = url.pathname;
|
let path = url.pathname;
|
||||||
path = path.replace(gd.url_path_prefix, '') || '/';
|
path = path.replace(gd.url_path_prefix, "") || "/";
|
||||||
|
|
||||||
let option = {status: 200, headers: {'Access-Control-Allow-Origin': '*'}}
|
let option = { status: 200, headers: { "Access-Control-Allow-Origin": "*" } };
|
||||||
|
|
||||||
if (path.substr(-1) == '/') {
|
if (path.substr(-1) == "/") {
|
||||||
let deferred_pass = gd.password(path);
|
let deferred_pass = gd.password(path);
|
||||||
let body = await request.text();
|
let body = await request.text();
|
||||||
body = JSON.parse(body);
|
body = JSON.parse(body);
|
||||||
// 这样可以提升首次列目录时的速度。缺点是,如果password验证失败,也依然会产生列目录的开销
|
// 这样可以提升首次列目录时的速度。缺点是,如果password验证失败,也依然会产生列目录的开销
|
||||||
let deferred_list_result = gd.list(path, body.page_token, Number(body.page_index));
|
let deferred_list_result = gd.list(
|
||||||
|
path,
|
||||||
|
body.page_token,
|
||||||
|
Number(body.page_index)
|
||||||
|
);
|
||||||
|
|
||||||
// check .password file, if `enable_password_file_verify` is true
|
// check .password file, if `enable_password_file_verify` is true
|
||||||
if (authConfig['enable_password_file_verify']) {
|
if (authConfig["enable_password_file_verify"]) {
|
||||||
let password = await gd.password(path);
|
let password = await gd.password(path);
|
||||||
// console.log("dir password", password);
|
// console.log("dir password", password);
|
||||||
if (password && password.replace("\n", "") !== body.password) {
|
if (password && password.replace("\n", "") !== body.password) {
|
||||||
@ -300,18 +329,24 @@ async function apiRequest(request, gd) {
|
|||||||
return new Response(JSON.stringify(list_result), option);
|
return new Response(JSON.stringify(list_result), option);
|
||||||
} else {
|
} else {
|
||||||
let file = await gd.file(path);
|
let file = await gd.file(path);
|
||||||
let range = request.headers.get('Range');
|
let range = request.headers.get("Range");
|
||||||
return new Response(JSON.stringify(file));
|
return new Response(JSON.stringify(file));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理 search
|
// 处理 search
|
||||||
async function handleSearch(request, gd) {
|
async function handleSearch(request, gd) {
|
||||||
const option = {status: 200, headers: {'Access-Control-Allow-Origin': '*'}};
|
const option = {
|
||||||
|
status: 200,
|
||||||
|
headers: { "Access-Control-Allow-Origin": "*" },
|
||||||
|
};
|
||||||
let body = await request.text();
|
let body = await request.text();
|
||||||
body = JSON.parse(body);
|
body = JSON.parse(body);
|
||||||
let search_result = await
|
let search_result = await gd.search(
|
||||||
gd.search(body.q || '', body.page_token, Number(body.page_index));
|
body.q || "",
|
||||||
|
body.page_token,
|
||||||
|
Number(body.page_index)
|
||||||
|
);
|
||||||
return new Response(JSON.stringify(search_result), option);
|
return new Response(JSON.stringify(search_result), option);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,11 +357,14 @@ async function handleSearch(request, gd) {
|
|||||||
* @returns {Promise<Response>} 【注意】如果从前台接收的id代表的项目不在目标gd盘下,那么response会返回给前台一个空字符串""
|
* @returns {Promise<Response>} 【注意】如果从前台接收的id代表的项目不在目标gd盘下,那么response会返回给前台一个空字符串""
|
||||||
*/
|
*/
|
||||||
async function handleId2Path(request, gd) {
|
async function handleId2Path(request, gd) {
|
||||||
const option = {status: 200, headers: {'Access-Control-Allow-Origin': '*'}};
|
const option = {
|
||||||
|
status: 200,
|
||||||
|
headers: { "Access-Control-Allow-Origin": "*" },
|
||||||
|
};
|
||||||
let body = await request.text();
|
let body = await request.text();
|
||||||
body = JSON.parse(body);
|
body = JSON.parse(body);
|
||||||
let path = await gd.findPathById(body.id);
|
let path = await gd.findPathById(body.id);
|
||||||
return new Response(path || '', option);
|
return new Response(path || "", option);
|
||||||
}
|
}
|
||||||
|
|
||||||
class googleDrive {
|
class googleDrive {
|
||||||
@ -346,8 +384,8 @@ class googleDrive {
|
|||||||
this.passwords = [];
|
this.passwords = [];
|
||||||
// id <-> path
|
// id <-> path
|
||||||
this.id_path_cache = {};
|
this.id_path_cache = {};
|
||||||
this.id_path_cache[this.root['id']] = '/';
|
this.id_path_cache[this.root["id"]] = "/";
|
||||||
this.paths["/"] = this.root['id'];
|
this.paths["/"] = this.root["id"];
|
||||||
/*if (this.root['pass'] != "") {
|
/*if (this.root['pass'] != "") {
|
||||||
this.passwords['/'] = this.root['pass'];
|
this.passwords['/'] = this.root['pass'];
|
||||||
}*/
|
}*/
|
||||||
@ -370,9 +408,9 @@ class googleDrive {
|
|||||||
})();*/
|
})();*/
|
||||||
// 等待 user_drive_real_root_id ,只获取1次
|
// 等待 user_drive_real_root_id ,只获取1次
|
||||||
if (authConfig.user_drive_real_root_id) return;
|
if (authConfig.user_drive_real_root_id) return;
|
||||||
const root_obj = await (gds[0] || this).findItemById('root');
|
const root_obj = await (gds[0] || this).findItemById("root");
|
||||||
if (root_obj && root_obj.id) {
|
if (root_obj && root_obj.id) {
|
||||||
authConfig.user_drive_real_root_id = root_obj.id
|
authConfig.user_drive_real_root_id = root_obj.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,9 +419,9 @@ class googleDrive {
|
|||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async initRootType() {
|
async initRootType() {
|
||||||
const root_id = this.root['id'];
|
const root_id = this.root["id"];
|
||||||
const types = CONSTS.gd_root_type;
|
const types = CONSTS.gd_root_type;
|
||||||
if (root_id === 'root' || root_id === authConfig.user_drive_real_root_id) {
|
if (root_id === "root" || root_id === authConfig.user_drive_real_root_id) {
|
||||||
this.root_type = types.user_drive;
|
this.root_type = types.user_drive;
|
||||||
} else {
|
} else {
|
||||||
const obj = await this.getShareDriveObjById(root_id);
|
const obj = await this.getShareDriveObjById(root_id);
|
||||||
@ -397,65 +435,72 @@ class googleDrive {
|
|||||||
* @returns {Response|null}
|
* @returns {Response|null}
|
||||||
*/
|
*/
|
||||||
basicAuthResponse(request) {
|
basicAuthResponse(request) {
|
||||||
const user = this.root.user || '',
|
const user = this.root.user || "",
|
||||||
pass = this.root.pass || '',
|
pass = this.root.pass || "",
|
||||||
_401 = new Response('Unauthorized', {
|
_401 = new Response("Unauthorized", {
|
||||||
headers: {'WWW-Authenticate': `Basic realm="goindex:drive:${this.order}"`},
|
headers: {
|
||||||
status: 401
|
"WWW-Authenticate": `Basic realm="goindex:drive:${this.order}"`,
|
||||||
|
},
|
||||||
|
status: 401,
|
||||||
});
|
});
|
||||||
if (user || pass) {
|
if (user || pass) {
|
||||||
const auth = request.headers.get('Authorization')
|
const auth = request.headers.get("Authorization");
|
||||||
if (auth) {
|
if (auth) {
|
||||||
try {
|
try {
|
||||||
const [received_user, received_pass] = atob(auth.split(' ').pop()).split(':');
|
const [received_user, received_pass] = atob(
|
||||||
return (received_user === user && received_pass === pass) ? null : _401;
|
auth.split(" ").pop()
|
||||||
|
).split(":");
|
||||||
|
return received_user === user && received_pass === pass ? null : _401;
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
} else return null;
|
} else return null;
|
||||||
return _401;
|
return _401;
|
||||||
}
|
}
|
||||||
|
|
||||||
async view(url, range = '', inline = true) {
|
async view(url, range = "", inline = true) {
|
||||||
let requestOption = await this.requestOption();
|
let requestOption = await this.requestOption();
|
||||||
requestOption.headers['Range'] = range;
|
requestOption.headers["Range"] = range;
|
||||||
let res = await fetch(url, requestOption);
|
let res = await fetch(url, requestOption);
|
||||||
const {headers} = res = new Response(res.body, res)
|
const { headers } = (res = new Response(res.body, res));
|
||||||
this.authConfig.enable_cors_file_down && headers.append('Access-Control-Allow-Origin', '*');
|
this.authConfig.enable_cors_file_down &&
|
||||||
inline === true && headers.set('Content-Disposition', 'inline');
|
headers.append("Access-Control-Allow-Origin", "*");
|
||||||
|
inline === true && headers.set("Content-Disposition", "inline");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
async down(id, range = '', inline = false) {
|
async down(id, range = "", inline = false) {
|
||||||
let url = `https://www.googleapis.com/drive/v3/files/${id}?alt=media`;
|
let url = `https://www.googleapis.com/drive/v3/files/${id}?alt=media`;
|
||||||
let requestOption = await this.requestOption();
|
let requestOption = await this.requestOption();
|
||||||
requestOption.headers['Range'] = range;
|
requestOption.headers["Range"] = range;
|
||||||
let res = await fetch(url, requestOption);
|
let res = await fetch(url, requestOption);
|
||||||
const {headers} = res = new Response(res.body, res)
|
const { headers } = (res = new Response(res.body, res));
|
||||||
this.authConfig.enable_cors_file_down && headers.append('Access-Control-Allow-Origin', '*');
|
this.authConfig.enable_cors_file_down &&
|
||||||
inline === true && headers.set('Content-Disposition', 'inline');
|
headers.append("Access-Control-Allow-Origin", "*");
|
||||||
|
inline === true && headers.set("Content-Disposition", "inline");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
async file(path) {
|
async file(path) {
|
||||||
if (typeof this.files[path] == 'undefined') {
|
if (typeof this.files[path] == "undefined") {
|
||||||
this.files[path] = await this._file(path);
|
this.files[path] = await this._file(path);
|
||||||
}
|
}
|
||||||
return this.files[path];
|
return this.files[path];
|
||||||
}
|
}
|
||||||
|
|
||||||
async _file(path) {
|
async _file(path) {
|
||||||
let arr = path.split('/');
|
let arr = path.split("/");
|
||||||
let name = arr.pop();
|
let name = arr.pop();
|
||||||
name = decodeURIComponent(name).replace(/\'/g, "\\'");
|
name = decodeURIComponent(name).replace(/\'/g, "\\'");
|
||||||
let dir = arr.join('/') + '/';
|
let dir = arr.join("/") + "/";
|
||||||
// console.log(name, dir);
|
// console.log(name, dir);
|
||||||
let parent = await this.findPathId(dir);
|
let parent = await this.findPathId(dir);
|
||||||
// console.log(parent);
|
// console.log(parent);
|
||||||
let url = 'https://www.googleapis.com/drive/v3/files';
|
let url = "https://www.googleapis.com/drive/v3/files";
|
||||||
let params = {'includeItemsFromAllDrives': true, 'supportsAllDrives': true};
|
let params = { includeItemsFromAllDrives: true, supportsAllDrives: true };
|
||||||
params.q = `'${parent}' in parents and name = '${name}' and trashed = false`;
|
params.q = `'${parent}' in parents and name = '${name}' and trashed = false`;
|
||||||
params.fields = "files(id, name, mimeType, size ,createdTime, modifiedTime, iconLink, thumbnailLink)";
|
params.fields =
|
||||||
url += '?' + this.enQuery(params);
|
"files(id, name, mimeType, size ,createdTime, modifiedTime, iconLink, thumbnailLink)";
|
||||||
|
url += "?" + this.enQuery(params);
|
||||||
let requestOption = await this.requestOption();
|
let requestOption = await this.requestOption();
|
||||||
let response = await fetch(url, requestOption);
|
let response = await fetch(url, requestOption);
|
||||||
let obj = await response.json();
|
let obj = await response.json();
|
||||||
@ -470,15 +515,16 @@ class googleDrive {
|
|||||||
this.path_children_cache = {};
|
this.path_children_cache = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.path_children_cache[path]
|
if (
|
||||||
&& this.path_children_cache[path][page_index]
|
this.path_children_cache[path] &&
|
||||||
&& this.path_children_cache[path][page_index].data
|
this.path_children_cache[path][page_index] &&
|
||||||
|
this.path_children_cache[path][page_index].data
|
||||||
) {
|
) {
|
||||||
let child_obj = this.path_children_cache[path][page_index];
|
let child_obj = this.path_children_cache[path][page_index];
|
||||||
return {
|
return {
|
||||||
nextPageToken: child_obj.nextPageToken || null,
|
nextPageToken: child_obj.nextPageToken || null,
|
||||||
curPageIndex: page_index,
|
curPageIndex: page_index,
|
||||||
data: child_obj.data
|
data: child_obj.data,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,18 +534,17 @@ class googleDrive {
|
|||||||
// 对有多页的,进行缓存
|
// 对有多页的,进行缓存
|
||||||
if (result.nextPageToken && data.files) {
|
if (result.nextPageToken && data.files) {
|
||||||
if (!Array.isArray(this.path_children_cache[path])) {
|
if (!Array.isArray(this.path_children_cache[path])) {
|
||||||
this.path_children_cache[path] = []
|
this.path_children_cache[path] = [];
|
||||||
}
|
}
|
||||||
this.path_children_cache[path][Number(result.curPageIndex)] = {
|
this.path_children_cache[path][Number(result.curPageIndex)] = {
|
||||||
nextPageToken: result.nextPageToken,
|
nextPageToken: result.nextPageToken,
|
||||||
data: data
|
data: data,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async _ls(parent, page_token = null, page_index = 0) {
|
async _ls(parent, page_token = null, page_index = 0) {
|
||||||
// console.log("_ls", parent);
|
// console.log("_ls", parent);
|
||||||
|
|
||||||
@ -507,17 +552,18 @@ class googleDrive {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
let obj;
|
let obj;
|
||||||
let params = {'includeItemsFromAllDrives': true, 'supportsAllDrives': true};
|
let params = { includeItemsFromAllDrives: true, supportsAllDrives: true };
|
||||||
params.q = `'${parent}' in parents and trashed = false AND name !='.password'`;
|
params.q = `'${parent}' in parents and trashed = false AND name !='.password'`;
|
||||||
params.orderBy = 'folder,name,modifiedTime desc';
|
params.orderBy = "folder,name,modifiedTime desc";
|
||||||
params.fields = "nextPageToken, files(id, name, mimeType, size , modifiedTime, thumbnailLink, description)";
|
params.fields =
|
||||||
|
"nextPageToken, files(id, name, mimeType, size , modifiedTime, thumbnailLink, description)";
|
||||||
params.pageSize = this.authConfig.files_list_page_size;
|
params.pageSize = this.authConfig.files_list_page_size;
|
||||||
|
|
||||||
if (page_token) {
|
if (page_token) {
|
||||||
params.pageToken = page_token;
|
params.pageToken = page_token;
|
||||||
}
|
}
|
||||||
let url = 'https://www.googleapis.com/drive/v3/files';
|
let url = "https://www.googleapis.com/drive/v3/files";
|
||||||
url += '?' + this.enQuery(params);
|
url += "?" + this.enQuery(params);
|
||||||
let requestOption = await this.requestOption();
|
let requestOption = await this.requestOption();
|
||||||
let response = await fetch(url, requestOption);
|
let response = await fetch(url, requestOption);
|
||||||
obj = await response.json();
|
obj = await response.json();
|
||||||
@ -525,7 +571,7 @@ class googleDrive {
|
|||||||
return {
|
return {
|
||||||
nextPageToken: obj.nextPageToken || null,
|
nextPageToken: obj.nextPageToken || null,
|
||||||
curPageIndex: page_index,
|
curPageIndex: page_index,
|
||||||
data: obj
|
data: obj,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*do {
|
/*do {
|
||||||
@ -540,7 +586,6 @@ class googleDrive {
|
|||||||
files.push(...obj.files);
|
files.push(...obj.files);
|
||||||
pageToken = obj.nextPageToken;
|
pageToken = obj.nextPageToken;
|
||||||
} while (pageToken);*/
|
} while (pageToken);*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async password(path) {
|
async password(path) {
|
||||||
@ -550,7 +595,7 @@ class googleDrive {
|
|||||||
|
|
||||||
// console.log("load", path, ".password", this.passwords[path]);
|
// console.log("load", path, ".password", this.passwords[path]);
|
||||||
|
|
||||||
let file = await this.file(path + '.password');
|
let file = await this.file(path + ".password");
|
||||||
if (file == undefined) {
|
if (file == undefined) {
|
||||||
this.passwords[path] = null;
|
this.passwords[path] = null;
|
||||||
} else {
|
} else {
|
||||||
@ -563,7 +608,6 @@ class googleDrive {
|
|||||||
return this.passwords[path];
|
return this.passwords[path];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过 id 获取 share drive 信息
|
* 通过 id 获取 share drive 信息
|
||||||
* @param any_id
|
* @param any_id
|
||||||
@ -571,7 +615,7 @@ class googleDrive {
|
|||||||
*/
|
*/
|
||||||
async getShareDriveObjById(any_id) {
|
async getShareDriveObjById(any_id) {
|
||||||
if (!any_id) return null;
|
if (!any_id) return null;
|
||||||
if ('string' !== typeof any_id) return null;
|
if ("string" !== typeof any_id) return null;
|
||||||
|
|
||||||
let url = `https://www.googleapis.com/drive/v3/drives/${any_id}`;
|
let url = `https://www.googleapis.com/drive/v3/drives/${any_id}`;
|
||||||
let requestOption = await this.requestOption();
|
let requestOption = await this.requestOption();
|
||||||
@ -579,10 +623,9 @@ class googleDrive {
|
|||||||
let obj = await res.json();
|
let obj = await res.json();
|
||||||
if (obj && obj.id) return obj;
|
if (obj && obj.id) return obj;
|
||||||
|
|
||||||
return null
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 搜索
|
* 搜索
|
||||||
* @returns {Promise<{data: null, nextPageToken: null, curPageIndex: number}>}
|
* @returns {Promise<{data: null, nextPageToken: null, curPageIndex: number}>}
|
||||||
@ -595,7 +638,7 @@ class googleDrive {
|
|||||||
const empty_result = {
|
const empty_result = {
|
||||||
nextPageToken: null,
|
nextPageToken: null,
|
||||||
curPageIndex: page_index,
|
curPageIndex: page_index,
|
||||||
data: null
|
data: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!is_user_drive && !is_share_drive) {
|
if (!is_user_drive && !is_share_drive) {
|
||||||
@ -607,15 +650,17 @@ class googleDrive {
|
|||||||
return empty_result;
|
return empty_result;
|
||||||
}
|
}
|
||||||
let words = keyword.split(/\s+/);
|
let words = keyword.split(/\s+/);
|
||||||
let name_search_str = `name contains '${words.join("' AND name contains '")}'`;
|
let name_search_str = `name contains '${words.join(
|
||||||
|
"' AND name contains '"
|
||||||
|
)}'`;
|
||||||
|
|
||||||
// corpora 为 user 是个人盘 ,为 drive 是团队盘。配合 driveId
|
// corpora 为 user 是个人盘 ,为 drive 是团队盘。配合 driveId
|
||||||
let params = {};
|
let params = {};
|
||||||
if (is_user_drive) {
|
if (is_user_drive) {
|
||||||
params.corpora = 'user'
|
params.corpora = "user";
|
||||||
}
|
}
|
||||||
if (is_share_drive) {
|
if (is_share_drive) {
|
||||||
params.corpora = 'drive';
|
params.corpora = "drive";
|
||||||
params.driveId = this.root.id;
|
params.driveId = this.root.id;
|
||||||
// This parameter will only be effective until June 1, 2020. Afterwards shared drive items will be included in the results.
|
// This parameter will only be effective until June 1, 2020. Afterwards shared drive items will be included in the results.
|
||||||
params.includeItemsFromAllDrives = true;
|
params.includeItemsFromAllDrives = true;
|
||||||
@ -625,12 +670,13 @@ class googleDrive {
|
|||||||
params.pageToken = page_token;
|
params.pageToken = page_token;
|
||||||
}
|
}
|
||||||
params.q = `trashed = false AND name !='.password' AND (${name_search_str})`;
|
params.q = `trashed = false AND name !='.password' AND (${name_search_str})`;
|
||||||
params.fields = "nextPageToken, files(id, name, mimeType, size , modifiedTime, thumbnailLink, description)";
|
params.fields =
|
||||||
|
"nextPageToken, files(id, name, mimeType, size , modifiedTime, thumbnailLink, description)";
|
||||||
params.pageSize = this.authConfig.search_result_list_page_size;
|
params.pageSize = this.authConfig.search_result_list_page_size;
|
||||||
// params.orderBy = 'folder,name,modifiedTime desc';
|
// params.orderBy = 'folder,name,modifiedTime desc';
|
||||||
|
|
||||||
let url = 'https://www.googleapis.com/drive/v3/files';
|
let url = "https://www.googleapis.com/drive/v3/files";
|
||||||
url += '?' + this.enQuery(params);
|
url += "?" + this.enQuery(params);
|
||||||
// console.log(params)
|
// console.log(params)
|
||||||
let requestOption = await this.requestOption();
|
let requestOption = await this.requestOption();
|
||||||
let response = await fetch(url, requestOption);
|
let response = await fetch(url, requestOption);
|
||||||
@ -639,11 +685,10 @@ class googleDrive {
|
|||||||
return {
|
return {
|
||||||
nextPageToken: res_obj.nextPageToken || null,
|
nextPageToken: res_obj.nextPageToken || null,
|
||||||
curPageIndex: page_index,
|
curPageIndex: page_index,
|
||||||
data: res_obj
|
data: res_obj,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 一层一层的向上获取这个文件或文件夹的上级文件夹的 file 对象。注意:会很慢!!!
|
* 一层一层的向上获取这个文件或文件夹的上级文件夹的 file 对象。注意:会很慢!!!
|
||||||
* 最多向上寻找到当前 gd 对象的根目录 (root id)
|
* 最多向上寻找到当前 gd 对象的根目录 (root id)
|
||||||
@ -696,7 +741,7 @@ class googleDrive {
|
|||||||
}
|
}
|
||||||
await addItsFirstParent(child_obj);
|
await addItsFirstParent(child_obj);
|
||||||
|
|
||||||
return meet_top ? parent_files : null
|
return meet_top ? parent_files : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -710,20 +755,27 @@ class googleDrive {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const p_files = await this.findParentFilesRecursion(child_id);
|
const p_files = await this.findParentFilesRecursion(child_id);
|
||||||
if (!p_files || p_files.length < 1) return '';
|
if (!p_files || p_files.length < 1) return "";
|
||||||
|
|
||||||
let cache = [];
|
let cache = [];
|
||||||
// 把查出来的每一级的path和id都缓存一下
|
// 把查出来的每一级的path和id都缓存一下
|
||||||
p_files.forEach((value, idx) => {
|
p_files.forEach((value, idx) => {
|
||||||
const is_folder = idx === 0 ? (p_files[idx].mimeType === CONSTS.folder_mime_type) : true;
|
const is_folder =
|
||||||
let path = '/' + p_files.slice(idx).map(it => it.name).reverse().join('/');
|
idx === 0 ? p_files[idx].mimeType === CONSTS.folder_mime_type : true;
|
||||||
if (is_folder) path += '/';
|
let path =
|
||||||
cache.push({id: p_files[idx].id, path: path})
|
"/" +
|
||||||
|
p_files
|
||||||
|
.slice(idx)
|
||||||
|
.map((it) => it.name)
|
||||||
|
.reverse()
|
||||||
|
.join("/");
|
||||||
|
if (is_folder) path += "/";
|
||||||
|
cache.push({ id: p_files[idx].id, path: path });
|
||||||
});
|
});
|
||||||
|
|
||||||
cache.forEach((obj) => {
|
cache.forEach((obj) => {
|
||||||
this.id_path_cache[obj.id] = obj.path;
|
this.id_path_cache[obj.id] = obj.path;
|
||||||
this.paths[obj.path] = obj.id
|
this.paths[obj.path] = obj.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
/*const is_folder = p_files[0].mimeType === CONSTS.folder_mime_type;
|
/*const is_folder = p_files[0].mimeType === CONSTS.folder_mime_type;
|
||||||
@ -733,25 +785,26 @@ class googleDrive {
|
|||||||
return cache[0].path;
|
return cache[0].path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 根据id获取file item
|
// 根据id获取file item
|
||||||
async findItemById(id) {
|
async findItemById(id) {
|
||||||
const is_user_drive = this.root_type === CONSTS.gd_root_type.user_drive;
|
const is_user_drive = this.root_type === CONSTS.gd_root_type.user_drive;
|
||||||
let url = `https://www.googleapis.com/drive/v3/files/${id}?fields=${CONSTS.default_file_fields}${is_user_drive ? '' : '&supportsAllDrives=true'}`;
|
let url = `https://www.googleapis.com/drive/v3/files/${id}?fields=${
|
||||||
|
CONSTS.default_file_fields
|
||||||
|
}${is_user_drive ? "" : "&supportsAllDrives=true"}`;
|
||||||
let requestOption = await this.requestOption();
|
let requestOption = await this.requestOption();
|
||||||
let res = await fetch(url, requestOption);
|
let res = await fetch(url, requestOption);
|
||||||
return await res.json()
|
return await res.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
async findPathId(path) {
|
async findPathId(path) {
|
||||||
let c_path = '/';
|
let c_path = "/";
|
||||||
let c_id = this.paths[c_path];
|
let c_id = this.paths[c_path];
|
||||||
|
|
||||||
let arr = path.trim('/').split('/');
|
let arr = path.trim("/").split("/");
|
||||||
for (let name of arr) {
|
for (let name of arr) {
|
||||||
c_path += name + '/';
|
c_path += name + "/";
|
||||||
|
|
||||||
if (typeof this.paths[c_path] == 'undefined') {
|
if (typeof this.paths[c_path] == "undefined") {
|
||||||
let id = await this._findDirId(c_id, name);
|
let id = await this._findDirId(c_id, name);
|
||||||
this.paths[c_path] = id;
|
this.paths[c_path] = id;
|
||||||
}
|
}
|
||||||
@ -774,11 +827,11 @@ class googleDrive {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = 'https://www.googleapis.com/drive/v3/files';
|
let url = "https://www.googleapis.com/drive/v3/files";
|
||||||
let params = {'includeItemsFromAllDrives': true, 'supportsAllDrives': true};
|
let params = { includeItemsFromAllDrives: true, supportsAllDrives: true };
|
||||||
params.q = `'${parent}' in parents and mimeType = 'application/vnd.google-apps.folder' and name = '${name}' and trashed = false`;
|
params.q = `'${parent}' in parents and mimeType = 'application/vnd.google-apps.folder' and name = '${name}' and trashed = false`;
|
||||||
params.fields = "nextPageToken, files(id, name, mimeType)";
|
params.fields = "nextPageToken, files(id, name, mimeType)";
|
||||||
url += '?' + this.enQuery(params);
|
url += "?" + this.enQuery(params);
|
||||||
let requestOption = await this.requestOption();
|
let requestOption = await this.requestOption();
|
||||||
let response = await fetch(url, requestOption);
|
let response = await fetch(url, requestOption);
|
||||||
let obj = await response.json();
|
let obj = await response.json();
|
||||||
@ -790,7 +843,10 @@ class googleDrive {
|
|||||||
|
|
||||||
async accessToken() {
|
async accessToken() {
|
||||||
console.log("accessToken");
|
console.log("accessToken");
|
||||||
if (this.authConfig.expires == undefined || this.authConfig.expires < Date.now()) {
|
if (
|
||||||
|
this.authConfig.expires == undefined ||
|
||||||
|
this.authConfig.expires < Date.now()
|
||||||
|
) {
|
||||||
const obj = await this.fetchAccessToken();
|
const obj = await this.fetchAccessToken();
|
||||||
if (obj.access_token != undefined) {
|
if (obj.access_token != undefined) {
|
||||||
this.authConfig.accessToken = obj.access_token;
|
this.authConfig.accessToken = obj.access_token;
|
||||||
@ -804,19 +860,19 @@ class googleDrive {
|
|||||||
console.log("fetchAccessToken");
|
console.log("fetchAccessToken");
|
||||||
const url = "https://www.googleapis.com/oauth2/v4/token";
|
const url = "https://www.googleapis.com/oauth2/v4/token";
|
||||||
const headers = {
|
const headers = {
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
};
|
};
|
||||||
const post_data = {
|
const post_data = {
|
||||||
'client_id': this.authConfig.client_id,
|
client_id: this.authConfig.client_id,
|
||||||
'client_secret': this.authConfig.client_secret,
|
client_secret: this.authConfig.client_secret,
|
||||||
'refresh_token': this.authConfig.refresh_token,
|
refresh_token: this.authConfig.refresh_token,
|
||||||
'grant_type': 'refresh_token'
|
grant_type: "refresh_token",
|
||||||
}
|
};
|
||||||
|
|
||||||
let requestOption = {
|
let requestOption = {
|
||||||
'method': 'POST',
|
method: "POST",
|
||||||
'headers': headers,
|
headers: headers,
|
||||||
'body': this.enQuery(post_data)
|
body: this.enQuery(post_data),
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await fetch(url, requestOption);
|
const response = await fetch(url, requestOption);
|
||||||
@ -836,36 +892,39 @@ class googleDrive {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
async requestOption(headers = {}, method = 'GET') {
|
async requestOption(headers = {}, method = "GET") {
|
||||||
const accessToken = await this.accessToken();
|
const accessToken = await this.accessToken();
|
||||||
headers['authorization'] = 'Bearer ' + accessToken;
|
headers["authorization"] = "Bearer " + accessToken;
|
||||||
return {'method': method, 'headers': headers};
|
return { method: method, headers: headers };
|
||||||
}
|
}
|
||||||
|
|
||||||
enQuery(data) {
|
enQuery(data) {
|
||||||
const ret = [];
|
const ret = [];
|
||||||
for (let d in data) {
|
for (let d in data) {
|
||||||
ret.push(encodeURIComponent(d) + '=' + encodeURIComponent(data[d]));
|
ret.push(encodeURIComponent(d) + "=" + encodeURIComponent(data[d]));
|
||||||
}
|
}
|
||||||
return ret.join('&');
|
return ret.join("&");
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep(ms) {
|
sleep(ms) {
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
setTimeout(function () {
|
setTimeout(function() {
|
||||||
console.log('sleep' + ms);
|
console.log("sleep" + ms);
|
||||||
i++;
|
i++;
|
||||||
if (i >= 2) reject(new Error('i>=2'));
|
if (i >= 2) reject(new Error("i>=2"));
|
||||||
else resolve(i);
|
else resolve(i);
|
||||||
}, ms);
|
}, ms);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String.prototype.trim = function (char) {
|
String.prototype.trim = function(char) {
|
||||||
if (char) {
|
if (char) {
|
||||||
return this.replace(new RegExp('^\\' + char + '+|\\' + char + '+$', 'g'), '');
|
return this.replace(
|
||||||
|
new RegExp("^\\" + char + "+|\\" + char + "+$", "g"),
|
||||||
|
""
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return this.replace(/^\s+|\s+$/g, '');
|
return this.replace(/^\s+|\s+$/g, "");
|
||||||
};
|
};
|
||||||
|
2
package-lock.json
generated
2
package-lock.json
generated
@ -12677,7 +12677,7 @@
|
|||||||
},
|
},
|
||||||
"webpack-bundle-analyzer": {
|
"webpack-bundle-analyzer": {
|
||||||
"version": "3.7.0",
|
"version": "3.7.0",
|
||||||
"resolved": "https://registry.npm.taobao.org/webpack-bundle-analyzer/download/webpack-bundle-analyzer-3.7.0.tgz?cache=0&sync_timestamp=1586846559504&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-bundle-analyzer%2Fdownload%2Fwebpack-bundle-analyzer-3.7.0.tgz",
|
"resolved": "https://registry.npm.taobao.org/webpack-bundle-analyzer/download/webpack-bundle-analyzer-3.7.0.tgz?cache=0&sync_timestamp=1586846510646&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-bundle-analyzer%2Fdownload%2Fwebpack-bundle-analyzer-3.7.0.tgz",
|
||||||
"integrity": "sha1-hNpDTolEKJm4hNmtOORm0NsCpW8=",
|
"integrity": "sha1-hNpDTolEKJm4hNmtOORm0NsCpW8=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||||
<script>
|
<script>
|
||||||
var authConfig = {
|
var authConfig = {
|
||||||
version: '1.0.0',
|
version: '1.1.0',
|
||||||
roots: [
|
roots: [
|
||||||
{
|
{
|
||||||
id: "0AEofxddwF4bAUk9PVA",
|
id: "0AEofxddwF4bAUk9PVA",
|
||||||
@ -26,18 +26,31 @@
|
|||||||
name: "PriveDrive",
|
name: "PriveDrive",
|
||||||
pass: "",
|
pass: "",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "1ZUli0boWXTpAedKDzE_IF9CWT10G6V86",
|
||||||
|
name: "folder1",
|
||||||
|
pass: "",
|
||||||
|
}
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
var themeOptions = {
|
var themeOptions = {
|
||||||
// en/zh-chs/zh-cht
|
// en/zh-chs/zh-cht
|
||||||
languages: 'en'
|
languages: 'en',
|
||||||
|
render: {
|
||||||
|
head_md: false,
|
||||||
|
readme_md: false,
|
||||||
|
// 是否显示文件/文件夹描述(默认不显示)
|
||||||
|
// Show file/folder description or not (not shown by default)
|
||||||
|
desc: false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
window.gdconfig = JSON.parse(JSON.stringify({ version: authConfig.version, themeOptions: themeOptions }));
|
window.gdconfig = JSON.parse(JSON.stringify({ version: authConfig.version, themeOptions: themeOptions }));
|
||||||
|
window.themeOptions = themeOptions;
|
||||||
window.gds = JSON.parse(
|
window.gds = JSON.parse(
|
||||||
JSON.stringify(authConfig.roots.map((it) => it.name))
|
JSON.stringify(authConfig.roots.map((it) => it.name))
|
||||||
);
|
);
|
||||||
window.current_drive_order = 0;
|
window.current_drive_order = 0;
|
||||||
// window.MODEL = { q: "the" };
|
// window.MODEL = { q: "the",root_type: 1 };
|
||||||
</script>
|
</script>
|
||||||
<!-- 使用 CDN 加速的 JS 文件,配置在 vue.config.js 下 -->
|
<!-- 使用 CDN 加速的 JS 文件,配置在 vue.config.js 下 -->
|
||||||
<% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %>
|
<% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %>
|
||||||
|
@ -1,37 +1,34 @@
|
|||||||
import axios from "@utils/axios";
|
import axios from "@utils/axios";
|
||||||
let Base64 = require("js-base64").Base64;
|
let Base64 = require("js-base64").Base64;
|
||||||
|
|
||||||
// const exts = [
|
const text_exts = [
|
||||||
// "html",
|
"html",
|
||||||
// "php",
|
"php",
|
||||||
// "css",
|
"css",
|
||||||
// "go",
|
"go",
|
||||||
// "java",
|
"java",
|
||||||
// "js",
|
"js",
|
||||||
// "json",
|
"json",
|
||||||
// "py",
|
"txt",
|
||||||
// "txt",
|
"sh",
|
||||||
// "sh",
|
"md",
|
||||||
// "md",
|
];
|
||||||
// "mp4",
|
const video_exts = ["mp4", "webm", "mkv", "m3u8"];
|
||||||
// "webm",
|
const image_exts = ["bmp", "jpg", "jpeg", "png", "gif"];
|
||||||
// "mkv",
|
const pdf_exts = ["pdf"];
|
||||||
// "bmp",
|
|
||||||
// "jpg",
|
|
||||||
// "jpeg",
|
|
||||||
// "png",
|
|
||||||
// "gif",
|
|
||||||
// ];
|
|
||||||
|
|
||||||
export const encodePath = (path) => {
|
export const encodePath = (path) => {
|
||||||
return path.replace(/(.*)/, (p1, p2) => {
|
return path.replace(/(.*)/, (p1, p2) => {
|
||||||
return p2.replace().replace(/\//g, "%2F").replace(/#/g, "%23")
|
return p2
|
||||||
})
|
.replace()
|
||||||
|
.replace(/\//g, "%2F")
|
||||||
|
.replace(/#/g, "%23");
|
||||||
|
});
|
||||||
//return path.replace().replace("/", "%2F").replace("#", "%23")
|
//return path.replace().replace("/", "%2F").replace("#", "%23")
|
||||||
}
|
};
|
||||||
|
|
||||||
export const checkoutPath = (path, file) => {
|
export const checkoutPath = (path, file) => {
|
||||||
path = encodePath(path)
|
path = encodePath(path);
|
||||||
if (file.mimeType === "application/vnd.google-apps.folder") {
|
if (file.mimeType === "application/vnd.google-apps.folder") {
|
||||||
if (path.substr(-1) !== "/") {
|
if (path.substr(-1) !== "/") {
|
||||||
path += "/";
|
path += "/";
|
||||||
@ -47,25 +44,25 @@ export const checkView = (path) => {
|
|||||||
.pop()
|
.pop()
|
||||||
.toLowerCase();
|
.toLowerCase();
|
||||||
let base64Path = encode64(path);
|
let base64Path = encode64(path);
|
||||||
if ("|html|php|css|go|java|js|json|txt|sh|md|".indexOf(`|${ext}|`) >= 0) {
|
if (text_exts.indexOf(`${ext}`) != -1) {
|
||||||
path = path.replace(/\/(\d+:)\/.*/, (p1, p2) => {
|
path = path.replace(/\/(\d+:)\/.*/, (p1, p2) => {
|
||||||
return `/${p2}text/${base64Path}`;
|
return `/${p2}text/${base64Path}`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("|pdf|".indexOf(`|${ext}|`) >= 0) {
|
if (pdf_exts.indexOf(`${ext}`) != -1) {
|
||||||
path = path.replace(/\/(\d+:)\/.*/, (p1, p2) => {
|
path = path.replace(/\/(\d+:)\/.*/, (p1, p2) => {
|
||||||
return `/${p2}pdf/${base64Path}`;
|
return `/${p2}pdf/${base64Path}`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("|mp4|webm|mkv|".indexOf(`|${ext}|`) >= 0) {
|
if (video_exts.indexOf(`${ext}`) != -1) {
|
||||||
path = path.replace(/\/(\d+:)\/.*/, (p1, p2) => {
|
path = path.replace(/\/(\d+:)\/.*/, (p1, p2) => {
|
||||||
return `/${p2}video/${base64Path}`;
|
return `/${p2}video/${base64Path}`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("|bmp|jpg|jpeg|png|gif|".indexOf(`|${ext}|`) >= 0) {
|
if (image_exts.indexOf(`${ext}`) != -1) {
|
||||||
path = path.replace(/\/(\d+:)\/.*/, (p1, p2) => {
|
path = path.replace(/\/(\d+:)\/.*/, (p1, p2) => {
|
||||||
return `/${p2}image/${base64Path}`;
|
return `/${p2}image/${base64Path}`;
|
||||||
});
|
});
|
||||||
@ -73,27 +70,16 @@ export const checkView = (path) => {
|
|||||||
return path;
|
return path;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getQueryString = (path, param) => {
|
export const checkExtends = (path) => {
|
||||||
if (!path) {
|
let name = path.split("/").pop();
|
||||||
return "";
|
let ext = name
|
||||||
}
|
.split(".")
|
||||||
var args = getURLParameters(path);
|
.pop()
|
||||||
return args[param] ? args[param] : "";
|
.toLowerCase();
|
||||||
|
let exts = text_exts.concat(...video_exts,...image_exts,...pdf_exts);
|
||||||
|
return exts.indexOf(`${ext}`) != -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getURLParameters = (url) =>
|
|
||||||
url
|
|
||||||
.match(/([^?=&]+)(=([^&]*))/g)
|
|
||||||
.reduce(
|
|
||||||
(a, v) => (
|
|
||||||
(a[v.slice(0, v.indexOf("="))] = v.slice(v.indexOf("=") + 1)), a
|
|
||||||
), {}
|
|
||||||
);
|
|
||||||
|
|
||||||
// console.log(getURLParameters("/Movies/xx.mp4?a=view&y=123"));
|
|
||||||
|
|
||||||
//console.log(getQueryString("/Movies/xx.mp4?a=view&y=123", "y"));
|
|
||||||
|
|
||||||
export const encode64 = (str) => {
|
export const encode64 = (str) => {
|
||||||
return Base64.encodeURI(str);
|
return Base64.encodeURI(str);
|
||||||
};
|
};
|
||||||
@ -182,7 +168,6 @@ export function formatFileSize(bytes) {
|
|||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** 日期格式化
|
/** 日期格式化
|
||||||
* @param {Number String Date}
|
* @param {Number String Date}
|
||||||
* @param {String} 'YYYY-MM-DD HH:mm:ss EEE' 年(Y)、月(M)、日(D)、12小时(h)、24小时(H)、分(m)、秒(s)、毫秒(S)、周(E)、季度(q)
|
* @param {String} 'YYYY-MM-DD HH:mm:ss EEE' 年(Y)、月(M)、日(D)、12小时(h)、24小时(H)、分(m)、秒(s)、毫秒(S)、周(E)、季度(q)
|
||||||
@ -190,42 +175,55 @@ export function formatFileSize(bytes) {
|
|||||||
* @example XDate.format(new Date(), "YYYY-MM-DD") ==> 2017-08-23
|
* @example XDate.format(new Date(), "YYYY-MM-DD") ==> 2017-08-23
|
||||||
*/
|
*/
|
||||||
export function formatDate(date, fmt) {
|
export function formatDate(date, fmt) {
|
||||||
fmt = fmt || 'YYYY-MM-DD HH:mm:ss';
|
fmt = fmt || "YYYY-MM-DD HH:mm:ss";
|
||||||
if (typeof date === 'string') {
|
if (typeof date === "string") {
|
||||||
// date = new Date(date.replace(/-/g, '/'))
|
// date = new Date(date.replace(/-/g, '/'))
|
||||||
date = new Date(date)
|
date = new Date(date);
|
||||||
}
|
}
|
||||||
if (typeof date === 'number') {
|
if (typeof date === "number") {
|
||||||
date = new Date(date)
|
date = new Date(date);
|
||||||
}
|
}
|
||||||
var o = {
|
var o = {
|
||||||
'M+': date.getMonth() + 1,
|
"M+": date.getMonth() + 1,
|
||||||
'D+': date.getDate(),
|
"D+": date.getDate(),
|
||||||
'h+': date.getHours() % 12 === 0 ? 12 : date.getHours() % 12,
|
"h+": date.getHours() % 12 === 0 ? 12 : date.getHours() % 12,
|
||||||
'H+': date.getHours(),
|
"H+": date.getHours(),
|
||||||
'm+': date.getMinutes(),
|
"m+": date.getMinutes(),
|
||||||
's+': date.getSeconds(),
|
"s+": date.getSeconds(),
|
||||||
'q+': Math.floor((date.getMonth() + 3) / 3),
|
"q+": Math.floor((date.getMonth() + 3) / 3),
|
||||||
'S': date.getMilliseconds()
|
S: date.getMilliseconds(),
|
||||||
}
|
};
|
||||||
var week = {
|
var week = {
|
||||||
'0': '\u65e5',
|
"0": "\u65e5",
|
||||||
'1': '\u4e00',
|
"1": "\u4e00",
|
||||||
'2': '\u4e8c',
|
"2": "\u4e8c",
|
||||||
'3': '\u4e09',
|
"3": "\u4e09",
|
||||||
'4': '\u56db',
|
"4": "\u56db",
|
||||||
'5': '\u4e94',
|
"5": "\u4e94",
|
||||||
'6': '\u516d'
|
"6": "\u516d",
|
||||||
}
|
};
|
||||||
if (/(Y+)/.test(fmt)) {
|
if (/(Y+)/.test(fmt)) {
|
||||||
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
|
fmt = fmt.replace(
|
||||||
|
RegExp.$1,
|
||||||
|
(date.getFullYear() + "").substr(4 - RegExp.$1.length)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (/(E+)/.test(fmt)) {
|
if (/(E+)/.test(fmt)) {
|
||||||
fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? '\u661f\u671f' : '\u5468') : '') + week[date.getDay() + ''])
|
fmt = fmt.replace(
|
||||||
|
RegExp.$1,
|
||||||
|
(RegExp.$1.length > 1
|
||||||
|
? RegExp.$1.length > 2
|
||||||
|
? "\u661f\u671f"
|
||||||
|
: "\u5468"
|
||||||
|
: "") + week[date.getDay() + ""]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
for (var k in o) {
|
for (var k in o) {
|
||||||
if (new RegExp('(' + k + ')').test(fmt)) {
|
if (new RegExp("(" + k + ")").test(fmt)) {
|
||||||
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
|
fmt = fmt.replace(
|
||||||
|
RegExp.$1,
|
||||||
|
RegExp.$1.length === 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fmt;
|
return fmt;
|
||||||
|
@ -108,6 +108,13 @@ export default {
|
|||||||
// height: 100%;
|
// height: 100%;
|
||||||
padding: 10px 0.75em;
|
padding: 10px 0.75em;
|
||||||
}
|
}
|
||||||
|
.level-left {
|
||||||
|
width: 95%;
|
||||||
|
.level-item {
|
||||||
|
display: initial;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
.level-right {
|
.level-right {
|
||||||
.level-item {
|
.level-item {
|
||||||
// border-radius: 50%;
|
// border-radius: 50%;
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
<div class="navbar-end">
|
<div class="navbar-end">
|
||||||
<!-- is-hidden-desktop -->
|
<!-- is-hidden-desktop -->
|
||||||
<div class="navbar-item">
|
<div class="navbar-item" v-show="showSearch">
|
||||||
<div class="field is-grouped">
|
<div class="field is-grouped">
|
||||||
<p class="control has-icons-left is-dark" style="width:100%;">
|
<p class="control has-icons-left is-dark" style="width:100%;">
|
||||||
<input
|
<input
|
||||||
@ -71,8 +71,11 @@
|
|||||||
<i class="fab fa-github"></i>
|
<i class="fab fa-github"></i>
|
||||||
</a>
|
</a>
|
||||||
<header-setting />
|
<header-setting />
|
||||||
<a class="navbar-item is-hidden-desktop" @click.stop="$refs.viewMode.toggleMode">
|
<a
|
||||||
<view-mode ref="viewMode"/>
|
class="navbar-item is-hidden-desktop"
|
||||||
|
@click.stop="$refs.viewMode.toggleMode"
|
||||||
|
>
|
||||||
|
<view-mode ref="viewMode" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -144,6 +147,10 @@ export default {
|
|||||||
getCurrGD() {
|
getCurrGD() {
|
||||||
return this.gds.filter((item) => item.name !== this.currgd.name);
|
return this.gds.filter((item) => item.name !== this.currgd.name);
|
||||||
},
|
},
|
||||||
|
showSearch() {
|
||||||
|
// 文件夹不支持搜索
|
||||||
|
return window.MODEL ? window.MODEL.root_type < 2 : true
|
||||||
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
"$route.params.id": "chooseGD",
|
"$route.params.id": "chooseGD",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<headmd :option="headmd" v-if="headmd.display"></headmd>
|
<headmd :option="headmd" v-if="renderHeadMD && headmd.display"></headmd>
|
||||||
<div
|
<div
|
||||||
class="golist"
|
class="golist"
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
@ -8,7 +8,13 @@
|
|||||||
infinite-scroll-disabled="busy"
|
infinite-scroll-disabled="busy"
|
||||||
infinite-scroll-distance="10"
|
infinite-scroll-distance="10"
|
||||||
>
|
>
|
||||||
<list-view :data="buildFiles" v-if="mode === 'list'" :icons="getIcon" :go="go" :copy="copy" />
|
<list-view
|
||||||
|
:data="buildFiles"
|
||||||
|
v-if="mode === 'list'"
|
||||||
|
:icons="getIcon"
|
||||||
|
:go="go"
|
||||||
|
:copy="copy"
|
||||||
|
/>
|
||||||
<grid-view
|
<grid-view
|
||||||
class="g2-content"
|
class="g2-content"
|
||||||
:data="buildFiles"
|
:data="buildFiles"
|
||||||
@ -17,7 +23,10 @@
|
|||||||
:go="go"
|
:go="go"
|
||||||
:thum="thum"
|
:thum="thum"
|
||||||
/>
|
/>
|
||||||
<div v-show="files.length === 0" class="has-text-centered no-content"></div>
|
<div
|
||||||
|
v-show="files.length === 0"
|
||||||
|
class="has-text-centered no-content"
|
||||||
|
></div>
|
||||||
<center>
|
<center>
|
||||||
<div :class="!busy ? 'is-hidden' : ''">
|
<div :class="!busy ? 'is-hidden' : ''">
|
||||||
<i class="fa fa-spinner fa-pulse fa-2x fa-fw"></i>
|
<i class="fa fa-spinner fa-pulse fa-2x fa-fw"></i>
|
||||||
@ -28,8 +37,13 @@
|
|||||||
</span>-->
|
</span>-->
|
||||||
</center>
|
</center>
|
||||||
</div>
|
</div>
|
||||||
<div class="is-divider" :data-content="$t('list.total')+' '+files.length+' ' + $t('list.item')"></div>
|
<div
|
||||||
<readmemd :option="readmemd" v-if="readmemd.display"></readmemd>
|
class="is-divider"
|
||||||
|
:data-content="
|
||||||
|
$t('list.total') + ' ' + files.length + ' ' + $t('list.item')
|
||||||
|
"
|
||||||
|
></div>
|
||||||
|
<readmemd :option="readmemd" v-if="renderReadMeMD && readmemd.display"></readmemd>
|
||||||
|
|
||||||
<viewer
|
<viewer
|
||||||
v-if="viewer && images && images.length > 0"
|
v-if="viewer && images && images.length > 0"
|
||||||
@ -57,6 +71,7 @@ import {
|
|||||||
formatFileSize,
|
formatFileSize,
|
||||||
checkoutPath,
|
checkoutPath,
|
||||||
checkView,
|
checkView,
|
||||||
|
checkExtends,
|
||||||
} from "@utils/AcrouUtil";
|
} from "@utils/AcrouUtil";
|
||||||
import axios from "@/utils/axios";
|
import axios from "@/utils/axios";
|
||||||
import { mapState } from "vuex";
|
import { mapState } from "vuex";
|
||||||
@ -71,7 +86,7 @@ export default {
|
|||||||
Headmd: Markdown,
|
Headmd: Markdown,
|
||||||
Readmemd: Markdown,
|
Readmemd: Markdown,
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function() {
|
||||||
return {
|
return {
|
||||||
busy: false,
|
busy: false,
|
||||||
page: {
|
page: {
|
||||||
@ -112,7 +127,7 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState("acrou/view", ["mode"]),
|
...mapState("acrou/view", ["mode"]),
|
||||||
buildFiles () {
|
buildFiles() {
|
||||||
var path = this.$route.path;
|
var path = this.$route.path;
|
||||||
return this.files
|
return this.files
|
||||||
.map((item) => {
|
.map((item) => {
|
||||||
@ -134,22 +149,28 @@ export default {
|
|||||||
return a.isFolder ? -1 : 1;
|
return a.isFolder ? -1 : 1;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
images () {
|
images() {
|
||||||
return this.buildFiles.filter(
|
return this.buildFiles.filter(
|
||||||
(file) => file.mimeType.indexOf("image") != -1
|
(file) => file.mimeType.indexOf("image") != -1
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
renderHeadMD() {
|
||||||
|
return window.themeOptions.render.head_md || false;
|
||||||
},
|
},
|
||||||
created () {
|
renderReadMeMD() {
|
||||||
|
return window.themeOptions.render.readme_md || false;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
this.render();
|
this.render();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
pageLoad () {
|
pageLoad() {
|
||||||
if (!this.page.page_token) return;
|
if (!this.page.page_token) return;
|
||||||
this.page.page_index++;
|
this.page.page_index++;
|
||||||
this.render("scroll");
|
this.render("scroll");
|
||||||
},
|
},
|
||||||
render (scroll) {
|
render(scroll) {
|
||||||
if (scroll) {
|
if (scroll) {
|
||||||
this.busy = true;
|
this.busy = true;
|
||||||
} else {
|
} else {
|
||||||
@ -201,7 +222,7 @@ export default {
|
|||||||
this.$router.go(-1);
|
this.$router.go(-1);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
checkPassword (path) {
|
checkPassword(path) {
|
||||||
var pass = prompt(this.$t("list.auth"), "");
|
var pass = prompt(this.$t("list.auth"), "");
|
||||||
localStorage.setItem("password" + path, pass);
|
localStorage.setItem("password" + path, pass);
|
||||||
if (pass != null && pass != "") {
|
if (pass != null && pass != "") {
|
||||||
@ -210,7 +231,7 @@ export default {
|
|||||||
this.$router.go(-1);
|
this.$router.go(-1);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
copy (path) {
|
copy(path) {
|
||||||
let origin = window.location.origin;
|
let origin = window.location.origin;
|
||||||
path = origin + encodeURI(path);
|
path = origin + encodeURI(path);
|
||||||
this.$copyText(path)
|
this.$copyText(path)
|
||||||
@ -228,17 +249,17 @@ export default {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
thum (url) {
|
thum(url) {
|
||||||
return url ? `/${this.$route.params.id}:view?url=${url}` : "";
|
return url ? `/${this.$route.params.id}:view?url=${url}` : "";
|
||||||
},
|
},
|
||||||
inited (viewer) {
|
inited(viewer) {
|
||||||
this.$viewer = viewer;
|
this.$viewer = viewer;
|
||||||
},
|
},
|
||||||
go (file, target) {
|
go(file, target) {
|
||||||
if (file.mimeType.indexOf("image") != -1) {
|
if (file.mimeType.indexOf("image") != -1) {
|
||||||
this.viewer = true;
|
this.viewer = true;
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
let index = this.images.findIndex(item => item.path === file.path)
|
let index = this.images.findIndex((item) => item.path === file.path);
|
||||||
this.$viewer.view(index);
|
this.$viewer.view(index);
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -253,7 +274,7 @@ export default {
|
|||||||
window.open(path);
|
window.open(path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (target === "down") {
|
if (target === "down" || (!checkExtends(path) && !file.isFolder)) {
|
||||||
let temp_path = this.$route.params.path ? this.$route.params.path : "";
|
let temp_path = this.$route.params.path ? this.$route.params.path : "";
|
||||||
location.href = `/${this.$route.params.id}:down/${temp_path}/${file.name}`;
|
location.href = `/${this.$route.params.id}:down/${temp_path}/${file.name}`;
|
||||||
return;
|
return;
|
||||||
@ -271,7 +292,7 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
renderMd (files, path) {
|
renderMd(files, path) {
|
||||||
var cmd = this.$route.params.cmd;
|
var cmd = this.$route.params.cmd;
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
return;
|
return;
|
||||||
@ -295,7 +316,7 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
goSearchResult (file, target) {
|
goSearchResult(file, target) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
let cur = window.current_drive_order;
|
let cur = window.current_drive_order;
|
||||||
axios
|
axios
|
||||||
@ -320,7 +341,7 @@ export default {
|
|||||||
console.log(e);
|
console.log(e);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getIcon (type) {
|
getIcon(type) {
|
||||||
return "#" + (this.icon[type] ? this.icon[type] : "icon-weizhi");
|
return "#" + (this.icon[type] ? this.icon[type] : "icon-weizhi");
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -32,7 +32,11 @@
|
|||||||
<use :xlink:href="icons(file.mimeType)" />
|
<use :xlink:href="icons(file.mimeType)" />
|
||||||
</svg>
|
</svg>
|
||||||
{{ file.name }}
|
{{ file.name }}
|
||||||
<span class="has-text-grey g2-file-desc" v-html="file.description"></span>
|
<span
|
||||||
|
class="has-text-grey g2-file-desc"
|
||||||
|
v-if="isShowDesc"
|
||||||
|
v-html="file.description"
|
||||||
|
></span>
|
||||||
</td>
|
</td>
|
||||||
<td class="is-hidden-mobile is-hidden-touch">
|
<td class="is-hidden-mobile is-hidden-touch">
|
||||||
{{ file.modifiedTime }}
|
{{ file.modifiedTime }}
|
||||||
@ -107,6 +111,9 @@ export default {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
isShowDesc() {
|
||||||
|
return window.themeOptions.render.desc || false;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
Reference in New Issue
Block a user