基于flask和fomantic-ui的简易p2p文件分享平台的手动实现

背景

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

前几天突然想到了一个想法。同学之间平常用网络分享一个文件,大部分都是用的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

代码

文件目录

文件目录

文件目录

<!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>
from flask import render_template, Flask, request, make_response, send_from_directory
import osdef get_filelist():filelist = os.listdir("upload/")return filelistapp = 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 responseif __name__ == '__main__':app.run(host='0.0.0.0', port=80)

效果

界面

界面

界面

上传1

上传1

上传2

上传2

上传3

上传3

转载申明

本文转载自腾讯博客,转载请注明出处:365文档网

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/177247.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HCIE-灾备技术和安全服务

灾备技术 灾备包含两个概念&#xff1a;容灾、备份 备份是为了保证数据的完整性&#xff0c;数据不丢失。全量备份、增量备份&#xff0c;备份数据还原。 容灾是为了保证业务的连续性&#xff0c;尽可能不断业务。 快照&#xff1a;保存的不是底层块数据&#xff0c;保存的是逻…

相关关系与因果关系

本文来自&#xff1a;https://towardsdatascience.com/a-step-by-step-guide-in-detecting-causal-relationships-using-bayesian-structure-learning-in-python-c20c6b31cee5 作者&#xff1a;Erdogan Taskesen 在机器学任务中&#xff0c;确定变量间的因果关系&#xff08;c…

Linux下MSSQL (SQL Server)数据库无法启动故障处理

有同事反馈一套CentOS7下的mssql server2017无法启动需要我帮忙看看&#xff0c;启动报错情况如下 检查日志并没有更新日志信息 乍一看mssql-server服务有问题&#xff0c;检查mssql也确实没有进程 既然服务有问题&#xff0c;那么我们用一种方式直接手工后台启动mssql引擎来…

webpack工作原理

目录 合并代码模块化webpack 的打包webpack 的结构webpack 的源码addEntry 和 _addModuleChainbuildModuleCompilation 的钩子产出构建结果 了解 webpack 实现原理&#xff0c;掌握 webpack 基础的工作流程&#xff0c;在平时使用 webpack 遇见问题时&#xff0c;能够帮助我们洞…

IDEA创建JavaFX项目

1、New -> Project 2、选择JavaFX 配置项目名&#xff0c;包名&#xff0c;lib包管理工具&#xff0c;JDK版本&#xff08;注&#xff0c;JDK版本最低需要11&#xff09; 3、选择lib包 根据自己需求选择 lib包介绍 BootstrapFX&#xff1a;BootstrapFX 是一个为 JavaFX 提…

Django 基于ORM的CURD、外键关联,请求的生命周期

文章目录 基于ORM进行的CURDORM外键关联Django请求的生命周期流程图 基于ORM进行的CURD 本质上就是通过面向对象的方式&#xff0c;对数据库的数据进行增、删、改、查。 这里将会将我们之前所有内容结合到一起&#xff0c;首先确保基于上序操作已经建立好了UserInfo表&#xff…

2023最新版本 从零基础入门C++与QT(学习笔记) -5- 动态内存分配(new)

&#x1f38f;C的动态内存要比C方便 &#x1f384;注意C申请内存的时候可以直接的初始化&#xff01;&#xff01;&#xff01; &#x1f384;格式&#xff08;申请一块内存&#xff09; &#x1f388;new(关键字) 变量类型 &#x1f384;格式&#xff08;申请多块内存&am…

Docker - 网络

Docker - 网络 理解Docker0 # 我们发现这个容器带来网卡&#xff0c;都是一对对的 # evth-pair 就是一对的虚拟设备接口&#xff0c;他们都是成对出现的&#xff0c;一段连着协议&#xff0c;一段彼此相连 # 正因为有了这个特性&#xff0c;evth-pair 充当一个桥梁&#xff0…

时分复用(Time Division Multiplexing, TDM)介绍(同步时分复用、异步时分复用(统计时分复用))

文章目录 时分复用技术: 原理与应用概述1. 时分复用的基本原理1.1 定义和工作方式1.2 同步与异步时分复用 2. 时分复用的技术特点2.1 优点2.2 缺点 3. 时分复用的应用3.1 电信网络3.2 数字视频广播3.3 光纤通信 4. 时分复用模拟代码参考文献总结 时分复用技术: 原理与应用 概述…

VMware 安装CentOS7

一、软件准备 VMware 虚拟机安装 官网下载链接&#xff1a;VMware pro 17 下载链接 下载 VMware Workstation Pro | CN vm安装教学就不在细说&#xff0c;纯傻瓜式安装 Centos 7镜像文件下载 下载地址&#xff1a; Index of /centos/ | 清华大学开源软件镜像站 | Tsinghua O…

【Effect C++ 笔记】(四)设计与声明

【四】设计与声明 条款18 &#xff1a; 让接口容易被正确使用&#xff0c;不易被误用 Item 18: 让接口容易被正确使用&#xff0c;不易被误用 Make interfaces easy to use correctly and hard to use incorrectly. “让接口容易被正确使用&#xff0c;不易被误用”&#xff0…

(十一)Flask模板引擎jinja2

模板引擎Jinja2 一、简介及基本使用&#xff1a; Flask使用Jinja2作为默认的模板引擎。Jinja2是一个功能强大且易于使用的模板引擎&#xff0c;它允许我们在HTML中嵌入Python代码&#xff0c;并通过将模板和数据进行渲染来生成动态内容。 实战之在Flask中使用Jinja2模板引擎…