OneList 绑定多个OneDrive网盘的极简目录列表

OneList以前介绍过,主要的特色就是解决了因OneDrive API抽风导致的很多问题,稳定性和访问速度都是不错的。不过由于使用Python写的,而Py单线程容易阻塞,响应不够迅速,刷新缓存时,Web端请求基本不可用,所以在整体性能上有点瑕疵。基于Golang的性能更好,效率更高,多盘并发缓存等众多好处,于是萌咖大佬就弃用Python版本,使用Golang重写了OneList,同时支持国际版、个人免费版(家庭版)、中国版(世纪互联)及多网盘绑定。

功能

支持国际版、个人免费版(家庭版)、中国版(世纪互联)。

支持同时列出多个盘的目录。(要求每个盘的SubPath唯一)

支持文件夹内超过200个项目。

支持后台自动刷新缓存。

支持路径中含有特殊字符。

数据储存在内存中,响应更加迅速。

安装

1、授权认证

点击右侧URL登录并授权,授权【国际版、个人版(家庭版)】、【中国版(世纪互联)】。

授权后会获取一个localhost开头打不开的链接,这里复制好整个链接地址,包括localhost。

2、安装OneList

#新建并进入OneList目录
mkdir /opt/OneList && cd $_

#64位系统下载
wget https://raw.githubusercontent.com/MoeClub/OneList/master/Rewrite/amd64/linux/OneList
#32位系统下载
wget https://raw.githubusercontent.com/MoeClub/OneList//master/Rewrite/i386/linux/OneList
#arm架构下载
wget https://raw.githubusercontent.com/MoeClub/OneList/master/Rewrite/arm/linux/OneList
    
#给予权限
chmod +x OneList

3、使用命令

Usage of OneList:
  -a string
        // 初始化配置文件,添加新配置
        Setup and Init auth.json.
  -bind string
        // 绑定IP地址(公网: 0.0.0.0)
        Bind Address (default "127.0.0.1")
  -port string
        // 绑定端口(HTTP:80)
        Port (default "5288")
  -s string
        // 设置 SubPath 项, 需要与 -a 一起使用.
        Set SubPath. [unique per account] (default "/")
  -c string
        // 配置文件
        Config file. (default "config.json")
  -t string
        // Index.html 目录样式文件
        Index file. (default "index.html")
  -cn
        // 开关
        // 授权中国版(世纪互联), 需要此参数.
        OneDrive by 21Vianet.
  -ms
        // 开关
        // 授权个人版(家庭版), 需要此参数.
        OneDrive by Microsoft.

4、生成配置文件

#国际版,将url换成你上面复制的授权地址,包括http://loaclhost。
./OneList -a "url" -s "/onedrive01"

#个人版(家庭版),将url换成你上面复制的授权地址,包括http://loaclhost。
./OneList -ms -a "url" -s "/onedrive02"

#中国版(世纪互联),将url换成你上面复制的授权地址,包括http://loaclhost。
./OneList -cn -a "url" -s "/onedrive03"

提示Success! Add config. ‘/path/to/config.json’信息,则添加成功。

这里要注意的是:

1、授权url地址只能用一次,超过需要重新授权。

2、命令中的/onedrive01参数为指定网盘地址后缀,比如http://domain.com/onedrive01。

3、授权多个网盘的话,重复授权多次即可,参数均会添加到一个配置文件,且后缀不能重复。

4、地址后缀填错了的,可以稍后在配置文件中修改。

本文默认的配置文件路径/opt/OneList/config.json,参数详解,可自行修改:

[
  {
    // 如果是家庭版或者个人免费版, 此项应为 true.
    "MSAccount": false,
    // 如果是中国版(世纪互联), 此项应为 true.
    "MainLand": false,
    // 授权令牌
    "RefreshToken": "1234564567890ABCDEF",
    // 单配置文件中,此项要唯一.将此OneDrive中设置为`RootPath`目录映射在`http://127.0.0.1:5288/onedrive` 下.
    // (只推荐一个盘位的时候使用根目录"/".)
    "SubPath": "/onedrive",
    // 读取OneDrive的某个目录作为根目录. (支持根目录"/")
    "RootPath": "/Test",
    // 隐藏OneDrive目录中的文件夹和文件, 条目间使用 "|" 分割. (跳过缓存设置的条目.)
    "HidePath": "/Test/Obj01|/Test/Obj02",
    // 使用用户名和密码加密OneDrive目录. 目录和用户名密码间使用 "?" 分割, 用户名密码使用 ":" 分割, 条目间使用 "|" 分割. 无效条目将跳过.
    "AuthPath": "/Test/Auth01?user01:pwd01|/Test/Auth02?user02:pwd02",
    // 缓存刷新间隔.(所有项目中的刷新时间取最小值为有效刷新间隔)
    "RefreshInterval": 900
  }
]

这里注意,挂载多个盘符的时候,SubPath参数请不要为/,单个网盘建议为/。

5、运行OneList

#下载默认的index.html主题,与config.json同目录,即本文默认的/opt/OneList
wget https://raw.githubusercontent.com/MoeClub/OneList/master/Rewrite/index.html -P /opt/OneList

#监听8000地址,自行修改
/opt/OneList/OneList -bind 0.0.0.0 -port 8000

最后打开ip:端口访问即可,如果你挂载网盘的时候SubPath为/,那么直接通过根目录查看,如果为/onedrive1,那么通过ip:端口/onedrive1查看,如果该路径不存在,则会提示No Found.。

且首次运行会异步缓存,也就是至少有一个盘缓存成功了,才会显示。

6、开机自启

这里新建一个简单的systemd配置文件,适用CentOS 7、Debian 8+、Ubuntu 16+。

使用命令:

#设置你的运行监听端口,即你可以通过ip:端口访问程序,这里默认8000。
port="8000"

#将以下代码一起复制到SSH运行
cat > /etc/systemd/system/onelist.service <<EOF
[Unit]
Description=onelist
After=network.target

[Service]
Type=simple
ExecStart=/opt/OneList/OneList -bind 0.0.0.0 -port ${port}
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

#启动并设置开机自启
systemctl start onelist
systemctl enable onelist

更换主题

提示:下载主题的index.html文件,覆盖默认index.html文件,本文默认存放/opt/OneList,然后重启程序即可

主题单页看下方代码,复制成index.html即可

1、HaorWu

#特点
支持移动端自适应
支持当页搜索
支持按文件名, 日期, 大小排序
支持主动查看图片
支持在线播放视频

#主题代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge, Chrome=1">
    <meta name="renderer" content="webkit">
    <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1,viewport-fit=cover">
    <title>storage - /</title>
    <link href="//s0.pstatp.com/cdn/expire-1-M/mdui/0.4.2/css/mdui.min.css" rel="stylesheet">
    <link href="//s0.pstatp.com/cdn/expire-1-M/dplayer/1.25.0/DPlayer.min.css" rel="stylesheet">
    <style>
    body{background-color:#f2f5fa}.nexmoe-item{margin:15px 0 !important;padding:15px !important;border-radius:5px;background-color:#fff;-webkit-box-shadow:0 .5em 3em rgba(161,177,204,.4);box-shadow:0 .5em 3em rgba(161,177,204,.4);background-color:#fff}.mdui-img-fluid,.mdui-video-fluid{border-radius:5px;border:1px solid #eee}.mdui-list{padding:0}.mdui-list-item{margin:0 !important;border-radius:5px;padding:0 10px 0 5px !important;border-bottom:1px solid #eee;margin-bottom:10px !important}.mdui-list-item:last-child{margin-bottom:0 !important}.mdui-toolbar{width:auto}.mdui-appbar .mdui-toolbar{height:56px;font-size:16px}.mdui-toolbar>*{padding:0 6px;margin:0 2px}.mdui-toolbar>.mdui-typo-headline{padding:0 16px 0 0}.mdui-toolbar>i{padding:0}.mdui-toolbar h3.title{padding:0 16px;line-height:30px;border-radius:30px;border:1px solid #eee;opacity:1;background-color:#1e89f2;color:#ffff}.mdui-toolbar>a:hover,a.mdui-typo-headline,a.active{opacity:1}.mdui-list>.th{background-color:initial}.mdui-list-item>a{width:100%;line-height:48px}.mdui-toolbar>a{padding:0 16px;line-height:30px;border-radius:30px;border:1px solid #eee}.mdui-toolbar>a:last-child{opacity:1;background-color:#1e89f2;color:#ffff}@media screen and (max-width:980px){.mdui-list-item .mdui-text-right{display:none}.mdui-container{width:100% !important;margin:0}.mdui-toolbar>a:last-child,.mdui-toolbar>.mdui-typo-headline,.mdui-toolbar>i:first-child{display:block}}#main-page{cursor:pointer}.nav-a{text-decoration:none;color:#333}.nav-a:hover{text-decoration:underline}.file{width:100%;display:flex;align-items:center}.file a{color:unset;width:100%}#text-input,#close{display:none}#text-input{width:40%}#dplayerContainer{position:relative;background-color:#000;display:none;padding:10px}.close-icon{color:#fff}#viewerContainer{width:100%;height:100%}.viewer-img{width:450px;position:relative;left:30%;z-index:1000}span.overlay{position:fixed;top:0;right:0;bottom:0;left:0;background-color:rgba(0,0,0,.8);z-index:999}#viewerClose{z-index:1000;color:#fff;background:rgba(255,255,255,.12);display:inline-block;position:absolute;bottom:0;cursor:pointer}@media screen and (max-width:768px){.viewer-img{width:60%;position:relative;left:20%;z-index:1000}}
    </style>
</head>
<body>
    <div class="container mdui-container">
        <div class="mdui-container-fluid">
            <div class="mdui-toolbar nexmoe-item nav">
                <i class="mdui-list-item-icon mdui-icon material-icons mdui-text-color-blue" id="main-page" onclick="goto(rootPath)">home</i>
                <span id="path">/</span>
                <div class="mdui-toolbar-spacer"></div>
                <input type="text" id="text-input" class="mdui-textfield-input" oninput="search(this)" placeholder="请输入关键字">
                <button type="button" id="close" class="mdui-textfield-close mdui-btn mdui-btn-icon"><i class="mdui-icon material-icons">close</i></button>
                <button type="button" id="btn" class="mdui-textfield-icon mdui-btn mdui-btn-icon"><i class="mdui-icon material-icons">search</i></button>
            </div>
        </div>
        <div class="mdui-container-fluid">
            <div class="list-wrapper nexmoe-item">
                <div class="list-header">
                    <div class="file mdui-list-item th">
                        <span class="name mdui-col-xs-12 mdui-col-sm-7" onclick="view('name')">列表</span>
                        <span class="time mdui-col-sm-3 mdui-text-right" onclick="view('date')">时间</span>
                        <span class="size mdui-col-sm-2 mdui-text-right" onclick="view('size')">大小</span>
                    </div>
                </div>
                <div id="file-list"></div>
            </div>
        </div>
    </div>
    <script src="//s0.pstatp.com/cdn/expire-1-M/??mdui/0.4.0/js/mdui.min.js,dplayer/1.25.0/DPlayer.min.js"></script>
    <script>
    let domain = window.location.host,
        rootPath = "{{.RootPath}}",
        currentPath = "{{.CurrentPath}}",
        rawData = "{{.RawData}}",
        title = 'storage - ',
        $$ = mdui.JQ;
    if (currentPath === "/") {
        currentPath = "";
    }
    let reverse = false,
        pageData = JSON.parse(window.atob(rawData)),
        arrayPath = new Array(),
        arrayFloder = new Array(),
        arryVideo = new Array(),
        arrayFile = new Array();
    for (let item in pageData) {
        if (item.indexOf("@") == 0) {
            continue
        }
        if (getFileType(decodeURIComponent(pageData[item]['name'])) == "video") {
            arryVideo.push(decodeURIComponent(pageData[item]['name']))
        }
        if (pageData[item]['@type'] == 'file') {
            arrayFile.push(pageData[item])
        } else if (pageData[item]['@type'] == 'folder') {
            arrayFloder.push(pageData[item])
        }
    }
    function goto(thePath) {
        window.location.href = thePath
    }
    function sizeNum(Size) {
        let dataArray = Size.split(" ", 2),
            dataNum = 0;
        switch (dataArray[1]) {
            case "B":
                dataNum = Math.pow(2, 0) * dataArray[0];
                break;
            case "KB":
                dataNum = Math.pow(2, 10) * dataArray[0];
                break;
            case "MB":
                dataNum = Math.pow(2, 20) * dataArray[0];
                break;
            case "GB":
                dataNum = Math.pow(2, 30) * dataArray[0];
                break;
            case "TB":
                dataNum = Math.pow(2, 40) * dataArray[0];
                break;
            case "PB":
                dataNum = Math.pow(2, 50) * dataArray[0];
                break;
            default:
                dataNum = 2 ** 50 * dataArray[0]
        }
        return dataNum
    }
    function compare(property) {
        if (property === "size") {
            return function(a, b) {
                let value0 = sizeNum(a[property].toUpperCase());
                let value1 = sizeNum(b[property].toUpperCase());
                return value0 - value1
            }
        } else {
            return function(a, b) {
                let value0 = a[property].toLowerCase();
                let value1 = b[property].toLowerCase();
                return value0.localeCompare(value1)
            }
        }
    }
    function clear() {
        let classList = new Array("file-wrapper");
        for (let item in classList) {
            let obj = document.getElementsByClassName(classList[item]);
            for (let i = obj.length - 1; i >= 0; i--) {
                obj[i].parentNode.removeChild(obj[i])
            }
        }
        let nav = document.getElementById("path"),
            pathSpan = document.createElement("span"),
            locPath = currentPath.trim().replace(/^\//, "").replace(/\/$/, "");
        locArray = new Array('');
        if (nav.innerHTML.length > 0) {
            nav.innerHTML = ''
        }
        if (locPath !== "") {
            let locPathArr = locPath.split("/"),
                localHref = "";
            for (let j = 0; j < locPathArr.length; j++) {
                localHref += "/" + locPathArr[j];
                if (j === 0 && rootPath !== "/") {
                    continue
                }
                navTemp = `<a class="nav-a" href="//${window.location.host}${localHref}">${locPathArr[j]}</a>`;
                locArray.push(navTemp)
            }
        }
        pathSpan.innerHTML = locArray.join("/");
        nav.appendChild(pathSpan);
        navText = (nav.innerHTML.length === 0) ? '/' : pathSpan.innerHTML.replace(/<[^>]+>/g, "");
        document.title += navText.substr(1);
        arrayPath = locArray
    }
    function search(obj) {
        let searchVal = obj.value;
        if (searchVal === undefined) {
            return
        } else {
            searchVal = searchVal.toString().toLowerCase()
        }
        let showArray = document.getElementsByClassName("file-wrapper");
        for (let i = 0; i < showArray.length; i++) {
            let content = showArray[i].children[0].querySelector("span.mdui-text-truncate").innerText;
            if (content !== undefined && content.length > 0) {
                let newAttr = '';
                if (content.toLowerCase().indexOf(searchVal) < 0) {
                    newAttr = "none"
                }
                showArray[i].style.display = newAttr
            }
        }
    }
    function view(Property) {
        arrayFloder.sort(compare(Property));
        arrayFile.sort(compare(Property));
        if (reverse) {
            arrayFloder.reverse();
            arrayFile.reverse();
        }
        reverse = !(reverse);
        clear();
        let obj = document.getElementById('file-list'),
            items = arrayFloder.concat(arrayFile);
        for (let item in items) {
            let newChild = document.createElement("div"),
                icon = (items[item]['@type'] == 'folder') ? 'folder_open' : 'image_aspect_ratio',
                itemName = decodeURIComponent(items[item]['name']),
                protocol  = (document.location.protocol == 'https:') ? 'https:' : 'http:';
            let href = protocol + '//' + domain + currentPath + '/' + itemName;
            let fileType = getFileType(itemName);
            if (icon == 'image_aspect_ratio') {
                icon = getFileIcon(fileType)
            }
            newChild.setAttribute('class', 'row file-wrapper mdui-list-item mdui-ripple');
            newChild.innerHTML = `
            <div class="file">
                <i class="mdui-icon material-icons">${icon}</i>
                <a href="javascript:;">
                    <span class="name mdui-col-xs-12 mdui-col-sm-7 mdui-text-truncate">${itemName}</span>
                    <span class="time mdui-col-sm-3 mdui-text-right">${items[item]['date']}</span>
                    <span class="size mdui-col-sm-2 mdui-text-right">${items[item]['size']}</span>
                </a>
            </div>`;
            obj.appendChild(newChild);
            newChild.addEventListener('click',function(e){
                if (fileType == "video") {
                    let dplayerContainer = `
                        <div id="dplayerContainer" class="mdui-container-fluid">
                            <div align="right">
                                <button type="button" id="closevideo" onclick="dpClose()" class="mdui-textfield-close mdui-btn mdui-btn-icon"><i class="mdui-icon material-icons close-icon">close</i></button>
                            </div>
                            <div id="dplayer"></div>
                        </div>`;
                    $$('#dplayerContainer').remove();
                    $$(newChild).after(dplayerContainer);
                    dpOpen(href)
                }else if(fileType == "image"){
                    let imgEle = `
                        <div id="viewerContainer" onclick="$$(this).remove()">
                            <span class="overlay"></span>
                            <img class="viewer-img" src="${href}">
                        </div>
                        `;
                    $$('#viewerContainer').remove();
                    $$(newChild).after(imgEle)
                }else{
                    window.location.href = href
                }
            },false)
            newChild.oncontextmenu = function() {
                $$(newChild).find('a').attr('href', href)
            }
        }
    }
    function getFileType(name) {
        if (!name) return false;
        let imgType = ['gif', 'jpeg', 'jpg', 'bmp', 'png'],
            videoType = ['avi', 'wmv', 'mkv', 'mp4', 'mov', '3gp', 'flv', 'mpg', 'rmvb'],
            textType = ['txt', 'pdf', 'css', 'js', 'text', 'doc', 'docx', 'ppt', 'xml'],
            musicType = ['wav', 'acc', 'flac', 'ape', 'ogg', 'mp3'];
        if (RegExp("\.(" + imgType.join("|") + ")$", "i").test(name.toLowerCase())) {
            return 'image'
        }else if (RegExp("\.(" + videoType.join("|") + ")$", "i").test(name.toLowerCase())) {
            return 'video'
        }else if (RegExp("\.(" + textType.join("|") + ")$", "i").test(name.toLowerCase())) {
            return 'text'
        }else if (RegExp("\.(" + musicType.join("|") + ")$", "i").test(name.toLowerCase())) {
            return 'music'
        } else {
            return false
        }
    }
    function getFileIcon(fileType){
        switch(fileType) {
            case 'image':
                icon = 'image';
                break;
            case 'video':
                icon = 'ondemand_video';
                break;
            case 'music':
                icon = 'music_video';
                break;
            case 'text':
                icon = 'text_fields';
                break;
            default:
                icon = 'insert_drive_file';
                break;
        }
        return icon
    }
    function dpClose() {
        $$('#dplayerContainer').remove();
        if (dp) {dp.destroy()}
    }
    function dpOpen(link) {
        $$('#dplayerContainer').show();
        dp = new DPlayer({
            container: document.getElementById('dplayer'),
            autoplay: true,
            video: {
                url: link,
            },
        })
    }
    $$('#btn').on('click', function(event) {
        event.preventDefault();
        $$('#text-input').show();
        $$('#close').show()
        $$('#btn').hide()
    });
    $$('#close').on('click', function(event) {
        event.preventDefault();
        $$('#text-input').hide();
        $$('#close').hide();
        $$('#btn').show()
    });
    window.onload = view("name")
    </script>
</body>
</html>

2、jackjieYYY

#特点
支持移动端自适应
支持当页搜索
支持按文件名, 日期, 大小排序
支持在线播放视频

#主题代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge, Chrome=1">
    <meta name="robots" content="noindex,nofollow">
    <meta name="renderer" content="webkit">
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
    <title>嘤嘤嘤 - /</title>
    <link rel="stylesheet" href="//s2.pstatp.com/cdn/expire-1-M/mdui/0.4.0/css/mdui.min.css">
    <script src="//www.mdui.org/source/dist/js/mdui.min.js"></script>
    <link href="https://cdn.bootcss.com/dplayer/1.25.0/DPlayer.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/dplayer/1.25.0/DPlayer.min.js"></script>
    <style>
        body {
            background-color: #f2f5fa
        }

        .nexmoe-item {
            margin: 15px 0 !important;
            padding: 15px !important;
            border-radius: 5px;
            background-color: #fff;
            -webkit-box-shadow: 0 .5em 3em rgba(161, 177, 204, .4);
            box-shadow: 0 .5em 3em rgba(161, 177, 204, .4);
            background-color: #fff
        }

        .mdui-img-fluid,
        .mdui-video-fluid {
            border-radius: 5px;
            border: 1px solid #eee
        }

        .mdui-list {
            padding: 0
        }

        .mdui-list-item {
            margin: 0 !important;
            border-radius: 5px;
            padding: 0 10px 0 5px !important;
            border-bottom: 1px solid #eee;
            margin-bottom: 10px !important
        }

        .mdui-list-item:last-child {
            margin-bottom: 0 !important
        }

        .mdui-toolbar {
            width: auto
        }

        .mdui-appbar .mdui-toolbar {
            height: 56px;
            font-size: 16px
        }

        .mdui-toolbar>* {
            padding: 0 6px;
            margin: 0 2px
        }

        .mdui-toolbar>.mdui-typo-headline {
            padding: 0 16px 0 0
        }

        .mdui-toolbar>i {
            padding: 0
        }

        .mdui-toolbar h3.title {
            padding: 0 16px;
            line-height: 30px;
            border-radius: 30px;
            border: 1px solid #eee;
            opacity: 1;
            background-color: #1e89f2;
            color: #ffff
        }

        .mdui-toolbar>a:hover,
        a.mdui-typo-headline,
        a.active {
            opacity: 1
        }

        .mdui-list>.th {
            background-color: initial
        }

        .mdui-list-item>a {
            width: 100%;
            line-height: 48px
        }

        .mdui-toolbar>a {
            padding: 0 16px;
            line-height: 30px;
            border-radius: 30px;
            border: 1px solid #eee
        }

        .mdui-toolbar>a:last-child {
            opacity: 1;
            background-color: #1e89f2;
            color: #ffff
        }

        @media screen and (max-width:980px) {
            .mdui-list-item .mdui-text-right {
                display: none
            }

            .mdui-container {
                width: 100% !important;
                margin: 0
            }

            .mdui-toolbar>a:last-child,
            .mdui-toolbar>.mdui-typo-headline,
            .mdui-toolbar>i:first-child {
                display: block
            }
        }

        #main-page {
            cursor: pointer
        }

        .nav-a {
            text-decoration: none;
            color: #333;
        }

        .nav-a:hover {
            text-decoration: underline
        }

        .file {
            width: 100%;
            display: flex;
            align-items: center
        }

        .file a {
            width: 100%;
            color: unset;
        }

        .loading-wrapper {
            display: none;
            position: fixed;
            height: 2em;
            line-height: 2em;
            margin-top: .5em;
            width: 100%;
            z-index: 1
        }

        .loading {
            color: white;
            background: #dad7d7;
            height: 100%;
            width: 8em;
            margin: 0 auto;
            text-align: center;
            border-radius: 1em
        }

        .markdown-body {
            min-width: 200px;
            margin: 0 auto;
            padding: .7em 1em;
            font-size: 1em
        }

        .markdown-body h1,
        h2,
        h3,
        h4,
        h5,
        h6 {
            margin-top: 0
        }

        .markdown-body img {
            max-width: 90%;
            max-height: 800px;
            width: auto;
            height: auto;
            display: block;
            margin: 0 auto
        }

        .password {
            display: flex;
            align-items: center;
            margin: 0 auto;
            padding-top: 1em;
            display: none
        }

        #text-input,
        #close {
            display: none;
        }

        #closevideo {
            display: none;
        }


        #text-input {
            width: 40%;
        }
    </style>
</head>

<body>
    <div class="container mdui-container">
        <div class="mdui-container-fluid">
            <div class="mdui-toolbar nexmoe-item nav">
                <i class="mdui-list-item-icon mdui-icon material-icons mdui-text-color-blue" id="main-page"
                    onclick="goto(rootPath);">home</i>
                <span id="path">/</span>
                <div class="mdui-toolbar-spacer"></div>
                <input type="text" id="text-input" class="mdui-textfield-input" oninput="search(this);"
                    placeholder="请输入关键字">
                <button type="button" id="close" class="mdui-textfield-close mdui-btn mdui-btn-icon"><i
                        class="mdui-icon material-icons">close</i></button>
                <button type="button" id="btn" class="mdui-textfield-icon mdui-btn mdui-btn-icon"><i
                        class="mdui-icon material-icons">search</i></button>
            </div>
        </div>


        <div class="mdui-container-fluid" style="position:relative">
            <div>
                <div align="right">
                    <button type="button" id="closevideo" onclick="dplayerclose()"
                        class="mdui-textfield-close mdui-btn mdui-btn-icon"><i
                            class="mdui-icon material-icons">close</i></button>
                </div>

                <div id="playerRightButton" onmouseover="showControlerButton()" onmouseout="hideControlerButton()"
                    onclick="nextVideo()" style="position:absolute;right:8px;z-index:10;width:100px;display: none">
                </div>

                <div>
                    <div id="rightArea" class="mdui-shadow-24"
                        style="position:absolute;right:8px;z-index:5;width:100px;display: none"></div>
                </div>

                <div id="playerLeftButton" onmouseover="showControlerButton()" onmouseout="hideControlerButton()"
                    onclick="previousVideo()" style="position:absolute;left:8px;z-index:10;width:100px;display: none">
                </div>

                <div>
                    <div id="leftArea" class="mdui-shadow-24"
                        style="position:absolute;left:8px;z-index:5;width:100px;display: none"></div>
                </div>

                <div id="dplayer"></div>
            </div>



        </div>
        <div class="mdui-container-fluid">
            <div class="nexmoe-item list-wrapper">
                <div class="list-header">
                    <div class="file mdui-list-item th">
                        <span class="name mdui-col-xs-12 mdui-col-sm-7" onclick="view('name');">列表</span>
                        <span class="time mdui-col-sm-3 mdui-text-right" onclick="view('date');">时间</span>
                        <span class="size mdui-col-sm-2 mdui-text-right" onclick="view('size');">大小</span>
                    </div>
                </div>
                <div id="file-list">
                </div>
            </div>
        </div>
        </button>
        <script>
            let domain = window.location.host,
                rootPath = "{{.RootPath}}",
                currentPath = "{{.CurrentPath}}",
                rawData = "{{.RawData}}",
                title = 'storage - ',
                downloadLink = '',
                vedioIndex = 0
            if (currentPath === "/") {
                currentPath = ""
            }
            let reverse = false,
                pageData = JSON.parse(window.atob(rawData)),
                arrayPath = new Array(),
                arrayFloder = new Array(),
                arryVideo = new Array(),
                arrayFile = new Array();


            for (let item in pageData) {
                if (item.indexOf("@") == 0) {
                    continue
                }
                if (getFileType(decodeURIComponent(pageData[item]['name'])) == "video") {
                    arryVideo.push(decodeURIComponent(pageData[item]['name']));
                }
                if (pageData[item]['@type'] == 'file') {
                    arrayFile.push(pageData[item]);

                } else if (pageData[item]['@type'] == 'folder') {
                    arrayFloder.push(pageData[item]);
                }
            }
            console.log(arryVideo)

            function goto(thePath) {
                window.location.href = thePath;
            }

            function sizeNum(Size) {
                let dataArray = Size.split(" ", 2),
                    dataNum = 0;
                switch (dataArray[1]) {
                    case "B":
                        dataNum = 2 ** 0 * dataArray[0];
                        break;
                    case "KB":
                        dataNum = 2 ** 10 * dataArray[0];
                        break;
                    case "MB":
                        dataNum = 2 ** 20 * dataArray[0];
                        break;
                    case "GB":
                        dataNum = 2 ** 30 * dataArray[0];
                        break;
                    case "TB":
                        dataNum = 2 ** 40 * dataArray[0];
                        break;
                    default:
                        dataNum = 2 ** 50 * dataArray[0];
                }
                return dataNum;
            }

            function compare(property) {
                if (property === "size") {
                    return function (a, b) {
                        let value0 = sizeNum(a[property].toUpperCase());
                        let value1 = sizeNum(b[property].toUpperCase());
                        return value0 - value1;
                    }
                } else {
                    return function (a, b) {
                        let value0 = a[property].toLowerCase();
                        let value1 = b[property].toLowerCase();
                        return value0.localeCompare(value1);
                    }
                }
            }

            function clear() {
                let classList = new Array("file-wrapper");
                for (let item in classList) {
                    let obj = document.getElementsByClassName(classList[item]);
                    for (let i = obj.length - 1; i >= 0; i--) {
                        obj[i].parentNode.removeChild(obj[i]);
                    }
                }
                let nav = document.getElementById("path"),
                    pathSpan = document.createElement("span"),
                    locPath = currentPath.trim().replace(/^\//, "").replace(/\/$/, "");
                locArray = new Array('');
                if (nav.innerHTML.length > 0) {
                    nav.innerHTML = '';
                }
                if (locPath !== "") {
                    let locPathArr = locPath.split("/"),
                        localHref = "";
                    for (let j = 0; j < locPathArr.length; j++) {
                        localHref += "/" + locPathArr[j];
                        if (j === 0 && rootPath !== "/") {
                            continue
                        }
                        navTemp = `<a class="nav-a" href="//${window.location.host}${localHref}">${locPathArr[j]}</a>`
                        locArray.push(navTemp);
                    }
                }
                pathSpan.innerHTML = locArray.join("/");
                nav.appendChild(pathSpan);
                navText = (nav.innerHTML.length === 0) ? '/' : pathSpan.innerHTML.replace(/<[^>]+>/g, "");
                document.title += navText.substr(1);
                arrayPath = locArray;
            }

            function search(obj) {
                let searchVal = obj.value;
                if (searchVal === undefined) {
                    return;
                } else {
                    searchVal = searchVal.toString().toLowerCase();
                }
                let showArray = document.getElementsByClassName("file-wrapper");
                for (let i = 0; i < showArray.length; i++) {
                    let content = showArray[i].children[0].querySelector("span.mdui-text-truncate").innerText;
                    if (content !== undefined && content.length > 0) {
                        let newAttr = '';
                        if (content.toLowerCase().indexOf(searchVal) < 0) {
                            newAttr = "none";
                        }
                        showArray[i].style.display = newAttr;
                    }
                }
            }

            function view(Property) {
                arrayFloder.sort(compare(Property));
                arrayFile.sort(compare(Property));
                if (reverse) {
                    arrayFloder.reverse();
                    arrayFile.reverse();
                }
                reverse = !(reverse);
                clear();
                let obj = document.getElementById('file-list');
                let items = arrayFloder.concat(arrayFile);
                for (let item in items) {
                    let newChild = document.createElement("div");

                    newChild.setAttribute('class', 'row file-wrapper mdui-list-item mdui-ripple');
                    let itemName = decodeURIComponent(items[item]['name']);
                    let href = 'http://' + domain + currentPath + '/' + itemName;

                    let vediospan = getIcon(href, items[item])
                    newChild.innerHTML = `
                <div class="file">
                    ${vediospan}
                    <a href="${href}">
                        <span class="name mdui-col-xs-12 mdui-col-sm-7 mdui-text-truncate">${itemName}</span>
                        <span class="time mdui-col-sm-3 mdui-text-right">${items[item]['date']}</span>
                        <span class="size mdui-col-sm-2 mdui-text-right">${items[item]['size']}</span>
                    </a>
                </div>`;
                    obj.appendChild(newChild);
                }
            }

            function getIcon(url, item) {
                let icon = "";
                let clickCode = ``
                let itemName = decodeURIComponent(item['name']);
                if (item['@type'] == 'folder') {
                    icon = 'folder_open';
                } else {
                    icon = 'image_aspect_ratio'
                }
                if (getFileType(itemName) == "video") {
                    icon = 'play_circle_filled';
                    clickCode = `onclick="dplayeropen(` + `\'${url}\'` + `)"`
                }

                let code = `<i class="mdui-icon material-icons" ${clickCode}>${icon}</i>`
                return code;

            }

            function getFileType(name) {
                if (!name) return false;
                var imgType = ["gif", "jpeg", "jpg", "bmp", "png"];
                var videoType = ["avi", "wmv", "mkv", "mp4", "mov", "rm", "3gp", "flv", "mpg", "rmvb"];
                if (RegExp("\.(" + imgType.join("|") + ")$", "i").test(name.toLowerCase())) {
                    return 'image';
                } else if (RegExp("\.(" + videoType.join("|") + ")$", "i").test(name.toLowerCase())) {
                    return 'video';
                } else {
                    return false;
                }
            }

            function show(obj) {
                return obj.setAttribute('style', 'display:block');
            }

            function hide(obj) {
                return obj.setAttribute('style', 'display:none');
            }

            function setDisplayNone(obj) {
                document.getElementById(obj).style.display = "none";
            }

            function setDisplayBlock(obj) {
                document.getElementById(obj).style.display = "block";
            }
            let btn = document.getElementById('btn'),
                close = document.getElementById('close'),
                stext = document.getElementById('text-input');

            btn.addEventListener('click', function () {
                show(stext);
                show(close);
                hide(btn);
            }, false);
            close.addEventListener('click', function () {
                hide(stext);
                hide(close);
                show(btn);
            }, false);


            function dplayerclose() {
                setDisplayNone('closevideo');
                setDisplayNone('playerRightButton');
                setDisplayNone('rightArea');
                setDisplayNone('playerLeftButton');
                setDisplayNone('leftArea');
                dp.destroy();
            }

            function dplayeropen(linkurl) {
                document.getElementById('closevideo').style.display = "block";
                if (arryVideo.length > 1) {
                    setDisplayBlock("playerRightButton");
                    setDisplayBlock("rightArea");
                    setDisplayBlock("playerLeftButton");
                    setDisplayBlock("leftArea");
                }
                dp = new DPlayer({
                    container: document.getElementById('dplayer'),
                    autoplay: true,
                    video: {
                        url: linkurl,
                    },
                });
                fixedControlerButton();
            }

            function fixedControlerButton() {
                let div = document.getElementById('dplayer');
                document.getElementById('playerRightButton').style.height = div.offsetHeight - 45 + "px";
                document.getElementById('rightArea').style.height = div.offsetHeight + "px";
                document.getElementById('playerLeftButton').style.height = div.offsetHeight - 45 + "px";
                document.getElementById('leftArea').style.height = div.offsetHeight + "px";

            }

            function showControlerButton() {
                fixedControlerButton();
                setDisplayBlock('rightArea');
                setDisplayBlock('leftArea');
            }

            function hideControlerButton() {
                fixedControlerButton();
                setDisplayNone('rightArea');
                setDisplayNone('leftArea');
            }

            function nextVideo() {
                if (dp == null) return;
                if (vedioIndex < arryVideo.length-1) {
                    vedioIndex = vedioIndex + 1;
                    link = "http://" + domain + currentPath + '/' + arryVideo[vedioIndex];
                    dplayeropen(link);
                }
            }

            function previousVideo() {
                if (dp == null) return;
                if (vedioIndex > 0) {
                    vedioIndex = vedioIndex - 1;
                    link = "http://" + domain + currentPath + '/' + arryVideo[vedioIndex];
                    dplayeropen(link);
                }
            }



            window.onload = view("name");
        </script>
</body>

</html>

相关命令

启动:systemctl start onelist
停止:systemctl stop onelist
重启:systemctl restart onelist
查看状态:systemctl status onelist

卸载

#未设置开机自启
rm -rf /opt/OneList

#设置过开机自启
systemctl stop onelist
systemctl disable onelist
rm -rf /opt/OneList /etc/systemd/system/onelist.service

最后如果我们只想显示网盘的某些文件夹,那么可以分别挂载该网盘的不同目录即可,具体操作看配置文件说明。

如果有发现该程序存在BUG,可以提下,方便修复,有会前端的热心大佬,也可以自荐下,帮忙美化下该前端。

图片[1]-OneList 绑定多个OneDrive网盘的极简目录列表-村少博客
© 版权声明
THE END
喜欢就支持一下吧
点赞12
分享
评论 抢沙发

请登录后发表评论