Skip to content

Commit

Permalink
plugins support
Browse files Browse the repository at this point in the history
  • Loading branch information
reruin committed Oct 23, 2018
1 parent 3f440a7 commit 03716e4
Show file tree
Hide file tree
Showing 70 changed files with 2,324 additions and 1,168 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Gitignore by github
## -------------------

.editorconfig
*.css
db.json
config.json
Expand Down
44 changes: 31 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,43 @@
# ShareList

在线挂载 GoogleDrive、OneDrive 的简易工具 , 只需提供分享文件夹ID
在线挂载 GoogleDrive、OneDrive 的简易工具,可通过插件扩展功能

## 特性
1. 支持使用GD,OD文件夹ID挂载网盘
2. 支持列出本地目录
统一使用linux的路径,例如 windows D盘 为 ```/d/```
3. 自定义文件目录
可使用yaml构建目录内容,保存为```目录名.xd```。参考 ```example/download.xd```
4. 支持虚拟目录嵌套
以如下格式重命名文件夹
格式:```显示名称.文件夹id.类型```
类型支持 od(OneDrive) gd(GoogleDrive)
5. 加密目录
- 通过插件支持多种网盘系统。可通过自定义插件提供更多的类型支持
插件请置于plugins目录,自动启用。
- 支持目录嵌套
- 加密目录
在文件夹内新建 ```.密码.passwd``` 命名的文件即可,例如
```.123456.passwd```
不要省略最前方的```.```
6. 国际化支持
- 国际化支持
- 即将支持WebDAV

## 已内置插件
### GoogleDrive
提供对GoogleDrive的访问。协议名 gd,id为 分享文件夹ID
### OneDrive
提供对OneDrive的访问。协议名 od,id为 分享文件夹ID
### HTTP(S)
提供对HTTP链接的访问。协议名 http,id为 uri
### LocalFileSystem
提供对本地文件系统的访问。协议名 fd,id为 文件路径,统一使用linux的路径,例如 windows D盘 为 ```/d/```
### ShareListDrive
ShareListDrive是ShareList内置的一种虚拟文件系统,使用yaml构建。以```xd```作为后缀保存。参考 ```example/download.xd```
### Ln(快捷方式)
提供一种快捷方式的实现。只需要新建类似 ```名称.类型后缀.ln``` 的文件,文件内容为```协议:id``` 即可。
特别的,文件夹将使用```d```这个预设类型后缀。
例子:
1. 重定向到 某个http链接对应的文件 参考 ```example/http_download_ubuntu_18.iso.ln```
2. 重定向到 GoogleDrive的某个目录 参考 ```example/GoogleDrive.d.ln```
3. 重定向到 本地上级目录 参考 ```example/parent_folder.d.ln```


## 插件开发
待补充

## 已知BUG
1. GoogleDrive目录内文件过多时无法完全显示,也无法分页。
1. GoogleDrive插件:目录内文件过多时无法完全显示,也无法分页。


## 安装
Expand Down
133 changes: 68 additions & 65 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,83 +1,86 @@
const Koa = require('koa')
const views = require('koa-views')
const json = require('koa-json')
const onerror = require('koa-onerror')
const bodyparser = require('koa-bodyparser')
const logger = require('koa-logger')
const koaStatic = require('koa-static')
const locales = require('koa-locales')
const i18n = require('koa-i18n')
#!/usr/bin/env node

const session = require('koa-session-minimal')
/**
* Module dependencies.
*/

const less = require('./middleware/koa-less')
const addr = require('./middleware/koa-addr')
const paths = require('./middleware/koa-paths')
const koaXML = require('./middleware/koa-xml')
var app = require('./app/index')
var http = require('http');
var os = require('os')
var config = require('./app/config')
var fs = require('fs')
if(!fs.existsSync('./cache')){
fs.mkdirSync('./cache');
}

const routers = require('./routers/index')
const cors = require('@koa/cors')
const config = require('./config')
/**
* Get port from environment and store in Express.
*/

// const proxy = require('./utils/proxy')
var port = normalizePort(config.port || 33001);

const app = new Koa()
var server = http.createServer(app.callback());

onerror(app)

locales(app, {
dirs: [__dirname + '/locales'],
defaultLocale: 'zh-CN'
})
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

app.use(session({
key: 'USER_SID'
}))

app.use(cors())
function normalizePort(val) {
var port = parseInt(val, 10);

app.use(bodyparser({
enableTypes:['json', 'form', 'text' , 'xml']
}))

app.use(koaXML())

app.use(json())

app.use(addr)

app.use(paths)

// 配置控制台日志中间件
app.use(logger())

//less 中间件
app.use(less(__dirname + '/public'))

// 配置静态资源加载中间件
app.use(koaStatic(__dirname + '/public'))
if (isNaN(port)) {
// named pipe
return val;
}

app.use(async (ctx , next) => {
ctx.state.__ = ctx.__.bind(ctx)
ctx.state._title_ = config.getTitle.bind(ctx)
await next()
})
if (port >= 0) {
// port number
return port;
}

// 配置服务端模板渲染引擎中间件
app.use(views(__dirname + '/views', {
extension: 'pug'
}))
return false;
}

function getIpv4() {
var ifaces = os.networkInterfaces();
for (var dev in ifaces) {
for (var i in ifaces[dev]) {
var details = ifaces[dev][i];
if (/^\d+\./.test(details.address)) {
return details.address;
}
}
}
}

// 初始化路由中间件
app.use(routers.routes()).use(routers.allowedMethods())
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}

var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;

app.use(async (ctx) => {
switch (ctx.status) {
case 404:
await ctx.render('404');
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
})
}


module.exports = app
function onListening() {
console.log(new Date().toISOString())
console.log('App is running at http://'+getIpv4()+':'+config.port+'/')
}
67 changes: 67 additions & 0 deletions app/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
const fs = require('fs')
const os = require('os')
const config_path = process.cwd() +'/cache/config.json'
const port = process.env.PORT || 33001

const providers = [
{name:'GoogleDrive',code:'gd'},
{name:'OneDrive',code:'od'},
{name:'VirtualFile',code:'xd'},
{name:'LocalFileSystem',code:'ld'},
]

//onedrive 链接有效期 10 分钟
var data = {
port ,

enabled_proxy : 0 ,

enabled_proxy_header: 0 ,
//目录刷新时间 15分钟
cache_refresh_dir:15 * 60 * 1000,
//外链 10分钟
cache_refresh_file: 5 * 60 * 1000
}

const save = async (d) => {

for(var i in d){
data[i] = d[i]
}

let str = JSON.stringify( data )

return new Promise((resolve, reject) => {
fs.writeFile(config_path, str, function(err) {
if (err) {
console.log(err,'save config error')
} else {
console.log('save config success')
}
resolve(true)
})
})
}

const installed = () => data.token && data.path

const getTitle = () => data.title || 'ShareList'


try{
let cfg = fs.readFileSync(config_path,'utf-8');
if(cfg){
cfg = JSON.parse(cfg)
for(var i in cfg){
data[i] = cfg[i]
}
}
console.log('Load config from file')
}catch(e){

}


module.exports = {
data, save , installed , port , providers , getTitle
}
File renamed without changes.
File renamed without changes.
33 changes: 15 additions & 18 deletions controllers/sharelist.js → app/controllers/sharelist.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
const service = require('./../models/index')
const base = require('../utils/base')
const http = require('../utils/http')
const {encode , decode} = require('../utils/format')
const fs = require('fs')
const request = require('request')

const service = require('../services/index')
const http = require('../utils/http')
const config = require('../config')
const sendFile = require('../utils/sendfile')
const cache = {}
const parse_path = require('../utils/base').parse_path
const fs = require('fs')
const { parsePath ,checkPasswd, path , encode , decode} = require('../utils/base')

const proxy_header_supports = ['video' , 'audio']
const auth = (data , ctx)=>{
Expand All @@ -18,15 +17,14 @@ const auth = (data , ctx)=>{
const output = async (ctx , data)=>{

let preview = ctx.request.querystring.indexOf('preview') >= 0
let download_url = data.url

let enabled_proxy = config.data.enabled_proxy
let download_url = data.url

if(preview){
if(enabled_proxy){
download_url = ctx.path
}

if(data.fs){
//代理 或者 文件系统
if(enabled_proxy || data.protocol === 'file'){
download_url = ctx.path
}

Expand All @@ -36,7 +34,7 @@ const output = async (ctx , data)=>{
}
// download
else{
if(data.fs){
if(data.protocol === 'file'){
await sendFile(ctx, data.url)
}else{
if(enabled_proxy){
Expand Down Expand Up @@ -70,7 +68,7 @@ const output = async (ctx , data)=>{

module.exports = {
async index(ctx){
let data = await service.path(ctx.paths , ctx.query , ctx.paths_raw)
let data = await service.path(ctx.paths , ctx.query , ctx.paths)
let base_url = ctx.path == '/' ? '' : ctx.path
let parent = ctx.paths.length ? ('/' + ctx.paths.slice(0,-1).join('/')) : ''

Expand All @@ -83,7 +81,7 @@ module.exports = {
}

else if(data.type == 'folder'){
let passwd = base.checkPasswd(data)
let passwd = checkPasswd(data)

if( passwd !== false && !ctx.session.access.has( data.id )){
await ctx.render('auth',{parent , id:data.id , name:decodeURIComponent(decode(ctx.paths[ctx.paths.length-1]))})
Expand All @@ -92,7 +90,7 @@ module.exports = {
let resp = []
data.children.forEach((i)=>{
if(i.ext != 'passwd'){
let href = i.href || base.path(base_url+'/'+ encode(i.pathname|| i.name ))
let href = path(base_url + '/' + (i.url || encode(i.name)))

if(['audio','video','image'].indexOf(i.type) >= 0){
href += (href.indexOf('?')>=0 ? '&' : '?') + 'preview'
Expand All @@ -107,7 +105,6 @@ module.exports = {
}

}else{

await output(ctx , data)
}

Expand All @@ -128,10 +125,10 @@ module.exports = {

async auth(ctx){
let { path , passwd } = ctx.request.body
let [paths , paths_raw] = parse_path(path.substring(1))
let [paths , paths_raw] = parsePath(path.substring(1))

let data = await service.path(paths , ctx.query , paths_raw)
let hit = base.checkPasswd(data)
let hit = checkPasswd(data)
let result = { status : 0 , message:''}

console.log( hit , 'hit')
Expand Down
Loading

0 comments on commit 03716e4

Please sign in to comment.