前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >校园网内简易p2p文件分享平台的手动实现 - wuuconix's blog

校园网内简易p2p文件分享平台的手动实现 - wuuconix's blog

作者头像
wuuconix
发布2023-03-14 15:35:30
4770
发布2023-03-14 15:35:30
举报
文章被收录于专栏:wuuconixwuuconix

背景

开学一个多月了,由于繁重的学业和懒惰,都没怎么更新有意思的博客。

前几天突然想到了一个想法。同学之间平常用网络分享一个文件,大部分都是用的qq。但是qq看起来把文件拖到聊天框点击发送就发给对面同学了。但是实际上是先上传到了腾讯的服务器,然后对面的同学再从服务器上下载。

这一上传一下载就很耽误时间。我就想在我的电脑上开一个文件上传服务,别的同学直接上传到我的机械革命上,上传完毕,我就得到了这个文件,不用再下载一遍。而且由于是校园网内的服务,速度也有保障。

语言选择

由于前几天做了几道python flask模板注入的题目,便打算拿flask来当后端练练手,提供http服务。

前端的话还是利用漂亮且方便易用的fomantic-ui解决html和css样式问题,再配合上大大简化js编程的Jquery来写效果和功能。

遇到的困难

单纯的文件上传十分简单。对付小文件还好,但是大文件就会出现页面停滞的情况,而用户收不到任何反馈,不知道到底是在上传还是崩溃了。我们需要设置一个上传进度条来给以用户友善的提示。所以这里就有一个问题,如何获得上传的进度?

查询资料过后,我发现XMLHttpRequest能够获取进度。然后我又发现Jquery中封装的$.ajax能够更加简单的实现。参考链接 https://stackoverflow.com/questions/13203231/is-there-any-way-to-get-jquery-ajax-upload-progress

代码

文件目录
文件目录
代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf8" />
  <script src="https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/fomantic-ui@2.8.8/dist/semantic.min.css" />
  <script src="https://cdn.jsdelivr.net/npm/fomantic-ui@2.8.8/dist/semantic.min.js"></script>
  <title>wuuconix's page</title>
</head>
<body>
    <div style="padding-top: 5em;"></div>
    <div class="ui text container">
        <div class="ui placeholder segment">
            {% if filelist == [] %}
                <div class="ui icon header">
                    <i class="pdf file outline icon"></i>
                    目前文件夹里空空如也
                </div>
            {% else %}
                <div class="ui list">
                {% for file in filelist%}
                    <div class="item">
                        <i class="file icon"></i>
                        <div class="content">
                            <a class="header" href="download/{{file}}" data-content="点击下载{{file}}" id="files">{{file}}</a>
                        </div>
                    </div>
                {% endfor %}
                </div>
            {% endif %}
            <div class="ui buttons">
                <button class="ui primary button" id="button_choose">选择文件</button>
                <button class="ui positive button" id="button_submit">上传</button>
            </div>
            <form action="/upload" method="post" enctype="multipart/form-data" id="form">
                <input type="file" id="input_file" style="display: none;" name="file">
            </form>
            <div class="ui divider"></div>
            <div class="ui indicating progress" id="progress" data-value="0" data-total="100"> 
                <div class="bar">
                    <div class="progress"></div>
                </div>
                <div class="label"></div>
            </div>
        </div>
    </div>
</body>

<script>
    $(document).ready(function(){
        $("#progress").hide();
        $("#button_submit").attr("disabled", true);
    });
    $("#button_choose").click(function()
    {
        $("#input_file").click();
    });
    $("#input_file").bind("input propertychange",function(){
        var name = ($(this).prop('files')[0]['name']);
        $("#button_submit").attr("disabled", false);
        $('#button_choose')[0].innerHTML=name;
    });
    $("#button_submit").click(function()
    {
        $("#progress").show();
        var formdata = new FormData($("#form")[0]); 
        $.ajax({
            url:'/upload', 
            type:'post', 
            xhr: function () {
                var xhr = $.ajaxSettings.xhr();
                var starttime = Math.ceil(new Date().getTime() / 1000);
                xhr.upload.onprogress = function (e) {
                    if (e.lengthComputable) {
                        var uploaded = Math.ceil(e.loaded / Math.pow(1024,2));
                        var spenttime = Math.ceil(new Date().getTime() / 1000) - starttime;
                        var speed = (uploaded / spenttime).toFixed(2);
                        var progress = Math.ceil(e.loaded / e.total * 100);
                        $("#progress").attr('data-value', progress);
                        $("#progress").progress('update progress', progress);
                        $("#progress").progress('set label', speed + "MB/s");
                    }
                };
                return xhr;
            },
            processData:false, 
            contentType:false, 
            data:formdata,
            success:function (data) {
                $('body').toast({
                    title: '恭喜你',
                    message: "你已经成功将 《" + $('#button_choose')[0].innerHTML + "》 上传至了武丑兄的机械革命。页面即将自动刷新",
                    showProgress: 'bottom',
                    classProgress: 'red'
                });
                setTimeout("location.reload();", 3000)  
            }
        })
    });
    $('#progress').progress({
        label: 'percent',
    });
    $('a').popup({
        on: 'hover'
    });
    $("#button_submit").popup({
        on: 'hover'
    });
</script>
代码语言:javascript
复制
from flask import render_template, Flask, request, make_response, send_from_directory
import os

def get_filelist():
    filelist = os.listdir("upload/")
    return filelist

app = Flask(__name__)

@app.route('/')
def hello(filelist=[]):
    return render_template("index.html", filelist=get_filelist())

@app.route('/upload',methods=['GET','POST'])
def upload():
    if request.method == 'POST':
        f = request.files['file']
        print(request.files)
        f.save(f"upload/{f.filename}")
        filelist = get_filelist()
        return render_template("index.html", filelist=filelist)
    else:
        return render_template("index.html", filelist=get_filelist())

@app.route('/download/<filename>',methods=['GET'])
def download(filename):
    response = make_response(send_from_directory("upload", filename, as_attachment=True))
    response.headers["Content-Disposition"] = "attachment; filename={}".format(filename.encode().decode('latin-1'))
    return response
    
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)

效果

界面
界面
上传1
上传1
上传2
上传2
上传3
上传3
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021年10月12日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 语言选择
  • 遇到的困难
  • 代码
  • 效果
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档